summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CONTRIBUTING.md (renamed from CONTRIBUTING.md)5
-rw-r--r--.github/ISSUE_TEMPLATE.md28
-rw-r--r--.gitignore39
-rw-r--r--.vimrc2
-rw-r--r--CODING_STYLE8
-rw-r--r--Makefile-man.am78
-rw-r--r--Makefile.am745
-rw-r--r--NEWS365
-rw-r--r--README10
-rw-r--r--README.md2
-rw-r--r--TODO103
-rwxr-xr-xautogen.sh10
-rw-r--r--build-aux/Makefile.once.head/20-systemd.mk2
-rw-r--r--coccinelle/strjoina.cocci6
-rw-r--r--configure.ac323
-rw-r--r--discard.mk49
-rw-r--r--hwdb/20-OUI.hwdb16971
-rw-r--r--hwdb/20-bluetooth-vendor-product.hwdb421
-rw-r--r--hwdb/20-pci-vendor-model.hwdb1272
-rw-r--r--hwdb/20-usb-vendor-model.hwdb28
-rw-r--r--hwdb/60-evdev.hwdb42
-rw-r--r--hwdb/60-keyboard.hwdb24
-rw-r--r--hwdb/70-mouse.hwdb40
-rw-r--r--man/bootchart.conf.xml172
-rw-r--r--man/bootup.xml7
-rw-r--r--man/busctl.xml1
-rw-r--r--man/coredump.conf.xml25
-rw-r--r--man/coredumpctl.xml60
-rw-r--r--man/daemon.xml16
-rw-r--r--man/halt.xml8
-rw-r--r--man/journalctl.xml21
-rw-r--r--man/journald.conf.xml6
-rw-r--r--man/kernel-command-line.xml9
-rw-r--r--man/loginctl.xml46
-rw-r--r--man/logind.conf.xml66
-rw-r--r--man/machinectl.xml75
-rw-r--r--man/networkctl.xml33
-rw-r--r--man/networkd.conf.xml154
-rw-r--r--man/nss-myhostname.xml39
-rw-r--r--man/nss-mymachines.xml43
-rw-r--r--man/nss-resolve.xml45
-rw-r--r--man/sd_bus_creds_get_pid.xml14
-rw-r--r--man/sd_event_source_set_priority.xml2
-rw-r--r--man/sd_journal_add_match.xml18
-rw-r--r--man/sd_journal_get_data.xml2
-rw-r--r--man/sd_journal_open.xml81
-rw-r--r--man/sd_uid_get_state.xml13
-rw-r--r--man/sd_watchdog_enabled.xml12
-rw-r--r--man/systemctl.xml76
-rw-r--r--man/systemd-ask-password.xml11
-rw-r--r--man/systemd-bootchart.xml323
-rw-r--r--man/systemd-bus-proxyd.service.xml80
-rw-r--r--man/systemd-bus-proxyd.xml108
-rw-r--r--man/systemd-coredump.xml100
-rw-r--r--man/systemd-importd.service.xml82
-rw-r--r--man/systemd-journal-gatewayd.service.xml2
-rw-r--r--man/systemd-nspawn.xml186
-rw-r--r--man/systemd-resolve.xml112
-rw-r--r--man/systemd-resolved.service.xml7
-rw-r--r--man/systemd-run.xml107
-rw-r--r--man/systemd-socket-activate.xml (renamed from src/systemd-activate/systemd-activate.xml)42
-rw-r--r--man/systemd-sysctl.service.xml69
-rw-r--r--man/systemd-system.conf.xml6
-rw-r--r--man/systemd-sysv-generator.xml2
-rw-r--r--man/systemd-tmpfiles.xml10
-rw-r--r--man/systemd.automount.xml23
-rw-r--r--man/systemd.exec.xml154
-rw-r--r--man/systemd.link.xml4
-rw-r--r--man/systemd.mount.xml50
-rw-r--r--man/systemd.netdev.xml22
-rw-r--r--man/systemd.network.xml145
-rw-r--r--man/systemd.nspawn.xml40
-rw-r--r--man/systemd.offline-updates.xml169
-rw-r--r--man/systemd.path.xml16
-rw-r--r--man/systemd.resource-control.xml243
-rw-r--r--man/systemd.service.xml57
-rw-r--r--man/systemd.slice.xml15
-rw-r--r--man/systemd.socket.xml33
-rw-r--r--man/systemd.special.xml19
-rw-r--r--man/systemd.swap.xml25
-rw-r--r--man/systemd.target.xml13
-rw-r--r--man/systemd.timer.xml35
-rw-r--r--man/systemd.unit.xml59
-rw-r--r--man/tmpfiles.d.xml81
-rw-r--r--man/udev_device_get_syspath.xml4
-rwxr-xr-xmove.sh28
-rw-r--r--network/80-container-host0.network6
-rw-r--r--network/80-container-ve.network6
-rw-r--r--network/80-container-vz.network22
-rw-r--r--po/LINGUAS16
-rw-r--r--po/bg.po617
-rw-r--r--po/fr.po106
-rw-r--r--po/hr.po570
-rw-r--r--po/it.po138
-rw-r--r--po/pl.po104
-rw-r--r--po/zh_CN.po141
-rw-r--r--po/zh_TW.po63
-rw-r--r--rules/60-persistent-storage.rules6
-rw-r--r--rules/99-systemd.rules.in6
-rw-r--r--shell-completion/bash/systemctl.in2
-rw-r--r--shell-completion/bash/systemd-nspawn9
-rw-r--r--shell-completion/bash/systemd-resolve64
-rw-r--r--shell-completion/zsh/_coredumpctl2
-rw-r--r--shell-completion/zsh/_networkctl35
-rw-r--r--shell-completion/zsh/_systemctl.in3
-rw-r--r--shell-completion/zsh/_systemd-resolve64
-rw-r--r--src/busctl/busctl.c87
-rw-r--r--src/grp-boot/bootctl/bootctl.c12
-rw-r--r--src/grp-boot/systemd-boot/Makefile19
-rw-r--r--src/grp-boot/systemd-boot/boot.c13
-rw-r--r--src/grp-boot/systemd-boot/measure.c312
-rw-r--r--src/grp-boot/systemd-boot/measure.h21
-rw-r--r--src/grp-boot/systemd-boot/splash.c4
-rw-r--r--src/grp-boot/systemd-boot/stub.c13
-rw-r--r--src/grp-coredump/coredumpctl/coredumpctl.c8
-rw-r--r--src/grp-coredump/systemd-coredump/coredump.c59
-rw-r--r--src/grp-coredump/systemd-coredump/stacktrace.c4
-rw-r--r--src/grp-journal-remote/.gitignore (renamed from src/journal-remote/.gitignore)0
-rw-r--r--src/grp-journal-remote/browse.html (renamed from src/journal-remote/browse.html)2
-rwxr-xr-xsrc/grp-journal-remote/log-generator.py (renamed from src/journal-remote/log-generator.py)0
-rw-r--r--src/grp-journal-remote/microhttpd-util.c (renamed from src/journal-remote/microhttpd-util.c)0
-rw-r--r--src/grp-journal-remote/microhttpd-util.h (renamed from src/journal-remote/microhttpd-util.h)4
-rw-r--r--src/grp-journal-remote/systemd-journal-gatewayd/Makefile (renamed from src/systemd-bus-proxyd/Makefile)56
-rw-r--r--src/grp-journal-remote/systemd-journal-gatewayd/journal-gatewayd.c (renamed from src/journal-remote/journal-gatewayd.c)4
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/Makefile (renamed from src/journal-remote/Makefile)30
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote-parse.c (renamed from src/journal-remote/journal-remote-parse.c)2
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote-parse.h (renamed from src/journal-remote/journal-remote-parse.h)4
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote-write.c (renamed from src/journal-remote/journal-remote-write.c)2
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote-write.h (renamed from src/journal-remote/journal-remote-write.h)5
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote.c (renamed from src/journal-remote/journal-remote.c)6
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote.conf.in (renamed from src/journal-remote/journal-remote.conf.in)0
-rw-r--r--src/grp-journal-remote/systemd-journal-remote/journal-remote.h (renamed from src/journal-remote/journal-remote.h)5
-rw-r--r--src/grp-journal-remote/systemd-journal-upload/Makefile (renamed from src/systemd-bootchart/Makefile)39
-rw-r--r--src/grp-journal-remote/systemd-journal-upload/journal-upload-journal.c (renamed from src/journal-remote/journal-upload-journal.c)37
-rw-r--r--src/grp-journal-remote/systemd-journal-upload/journal-upload.c (renamed from src/journal-remote/journal-upload.c)5
-rw-r--r--src/grp-journal-remote/systemd-journal-upload/journal-upload.conf.in (renamed from src/journal-remote/journal-upload.conf.in)0
-rw-r--r--src/grp-journal-remote/systemd-journal-upload/journal-upload.h (renamed from src/journal-remote/journal-upload.h)3
-rw-r--r--src/grp-journal/.gitignore (renamed from src/journal/.gitignore)0
-rw-r--r--src/grp-journal/Makefile170
-rw-r--r--src/grp-journal/catalog/systemd.be.catalog (renamed from src/journal/catalog/systemd.be.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.be@latin.catalog (renamed from src/journal/catalog/systemd.be@latin.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.bg.catalog324
-rw-r--r--src/grp-journal/catalog/systemd.catalog (renamed from src/journal/catalog/systemd.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.da.catalog (renamed from src/journal/catalog/systemd.da.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.fr.catalog (renamed from src/journal/catalog/systemd.fr.catalog)72
-rw-r--r--src/grp-journal/catalog/systemd.hr.catalog314
-rw-r--r--src/grp-journal/catalog/systemd.hu.catalog (renamed from src/journal/catalog/systemd.hu.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.it.catalog (renamed from src/journal/catalog/systemd.it.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.ko.catalog (renamed from src/journal/catalog/systemd.ko.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.pl.catalog (renamed from src/journal/catalog/systemd.pl.catalog)60
-rw-r--r--src/grp-journal/catalog/systemd.pt_BR.catalog (renamed from src/journal/catalog/systemd.pt_BR.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.ru.catalog (renamed from src/journal/catalog/systemd.ru.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.sr.catalog (renamed from src/journal/catalog/systemd.sr.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.zh_CN.catalog (renamed from src/journal/catalog/systemd.zh_CN.catalog)2
-rw-r--r--src/grp-journal/catalog/systemd.zh_TW.catalog (renamed from src/journal/catalog/systemd.zh_TW.catalog)2
-rw-r--r--src/grp-journal/journalctl/Makefile (renamed from src/libbus-proxy-core/Makefile)35
-rw-r--r--src/grp-journal/journalctl/journalctl.c (renamed from src/journal/journalctl.c)240
-rw-r--r--src/grp-journal/libjournal-core/Makefile56
-rw-r--r--src/grp-journal/libjournal-core/cat.c (renamed from src/journal/cat.c)0
-rw-r--r--src/grp-journal/libjournal-core/journal-qrcode.c (renamed from src/journal/journal-qrcode.c)0
-rw-r--r--src/grp-journal/libjournal-core/journal-qrcode.h (renamed from src/journal/journal-qrcode.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-audit.c (renamed from src/journal/journald-audit.c)6
-rw-r--r--src/grp-journal/libjournal-core/journald-audit.h (renamed from src/journal/journald-audit.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-console.c (renamed from src/journal/journald-console.c)0
-rw-r--r--src/grp-journal/libjournal-core/journald-console.h (renamed from src/journal/journald-console.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-gperf.gperf (renamed from src/journal/journald-gperf.gperf)2
-rw-r--r--src/grp-journal/libjournal-core/journald-kmsg.c (renamed from src/journal/journald-kmsg.c)2
-rw-r--r--src/grp-journal/libjournal-core/journald-kmsg.h (renamed from src/journal/journald-kmsg.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-native.c (renamed from src/journal/journald-native.c)16
-rw-r--r--src/grp-journal/libjournal-core/journald-native.h (renamed from src/journal/journald-native.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-rate-limit.c (renamed from src/journal/journald-rate-limit.c)4
-rw-r--r--src/grp-journal/libjournal-core/journald-rate-limit.h (renamed from src/journal/journald-rate-limit.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-server.c (renamed from src/journal/journald-server.c)92
-rw-r--r--src/grp-journal/libjournal-core/journald-server.h (renamed from src/journal/journald-server.h)2
-rw-r--r--src/grp-journal/libjournal-core/journald-stream.c (renamed from src/journal/journald-stream.c)17
-rw-r--r--src/grp-journal/libjournal-core/journald-stream.h (renamed from src/journal/journald-stream.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-syslog.c (renamed from src/journal/journald-syslog.c)36
-rw-r--r--src/grp-journal/libjournal-core/journald-syslog.h (renamed from src/journal/journald-syslog.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald-wall.c (renamed from src/journal/journald-wall.c)0
-rw-r--r--src/grp-journal/libjournal-core/journald-wall.h (renamed from src/journal/journald-wall.h)0
-rw-r--r--src/grp-journal/libjournal-core/journald.conf (renamed from src/journal/journald.conf)2
-rw-r--r--src/grp-journal/libjournal-core/test-audit-type.c (renamed from src/journal/test-audit-type.c)0
-rw-r--r--src/grp-journal/libjournal-core/test-catalog.c (renamed from src/journal/test-catalog.c)2
-rw-r--r--src/grp-journal/libjournal-core/test-compress-benchmark.c (renamed from src/journal/test-compress-benchmark.c)4
-rw-r--r--src/grp-journal/libjournal-core/test-compress.c (renamed from src/journal/test-compress.c)0
-rw-r--r--src/grp-journal/libjournal-core/test-journal-enum.c (renamed from src/journal/test-journal-enum.c)2
-rw-r--r--src/grp-journal/libjournal-core/test-journal-flush.c (renamed from src/journal/test-journal-flush.c)4
-rw-r--r--src/grp-journal/libjournal-core/test-journal-init.c (renamed from src/journal/test-journal-init.c)0
-rw-r--r--src/grp-journal/libjournal-core/test-journal-interleaving.c (renamed from src/journal/test-journal-interleaving.c)16
-rw-r--r--src/grp-journal/libjournal-core/test-journal-match.c (renamed from src/journal/test-journal-match.c)0
-rw-r--r--src/grp-journal/libjournal-core/test-journal-send.c (renamed from src/journal/test-journal-send.c)0
-rw-r--r--src/grp-journal/libjournal-core/test-journal-stream.c (renamed from src/journal/test-journal-stream.c)12
-rw-r--r--src/grp-journal/libjournal-core/test-journal-syslog.c (renamed from src/journal/test-journal-syslog.c)0
-rw-r--r--src/grp-journal/libjournal-core/test-journal-verify.c (renamed from src/journal/test-journal-verify.c)12
-rw-r--r--src/grp-journal/libjournal-core/test-journal.c (renamed from src/journal/test-journal.c)24
-rw-r--r--src/grp-journal/libjournal-core/test-mmap-cache.c (renamed from src/journal/test-mmap-cache.c)0
-rw-r--r--src/grp-journal/systemd-journald/Makefile94
-rw-r--r--src/grp-journal/systemd-journald/journald.c (renamed from src/journal/journald.c)0
-rw-r--r--src/grp-machine/libmachine-core/Makefile4
-rw-r--r--src/grp-machine/libmachine-core/image-dbus.c73
-rw-r--r--src/grp-machine/libmachine-core/machine-dbus.c162
-rw-r--r--src/grp-machine/libmachine-core/machine-dbus.h1
-rw-r--r--src/grp-machine/libmachine-core/machine.c41
-rw-r--r--src/grp-machine/libmachine-core/machine.h20
-rw-r--r--src/grp-machine/libmachine-core/machined-dbus.c111
-rw-r--r--src/grp-machine/libmachine-core/machined.h4
-rw-r--r--src/grp-machine/libmachine-core/operation.c131
-rw-r--r--src/grp-machine/libmachine-core/operation.h (renamed from src/libcore/bus-endpoint.h)37
-rw-r--r--src/grp-machine/machinectl/machinectl.c298
-rw-r--r--src/grp-machine/nss-mymachines/nss-mymachines.c2
-rw-r--r--src/grp-machine/systemd-machined/machined.c8
-rw-r--r--src/grp-resolve/nss-resolve/nss-resolve.c81
-rw-r--r--src/grp-resolve/systemd-resolved/Makefile113
-rw-r--r--src/grp-resolve/systemd-resolved/RFCs2
-rw-r--r--src/grp-resolve/systemd-resolved/dns-type.c17
-rw-r--r--src/grp-resolve/systemd-resolved/dns-type.h15
-rw-r--r--src/grp-resolve/systemd-resolved/resolve-tool.c346
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-bus.c134
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-conf.c4
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-answer.c14
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-answer.h2
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-cache.c146
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-dnssec.c80
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-packet.c458
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-packet.h6
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-query.c31
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-question.c10
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-rr.c207
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-rr.h33
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-scope.c4
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-server.c9
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-synthesize.c14
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-transaction.c786
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-transaction.h9
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-trust-anchor.c4
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-dns-zone.c39
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-etc-hosts.c6
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-link-bus.c6
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-link-bus.h2
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-link.c2
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-llmnr.c2
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-manager.c10
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-mdns.c2
-rw-r--r--src/grp-resolve/systemd-resolved/resolved-resolv-conf.c4
-rw-r--r--src/grp-resolve/systemd-resolved/resolved.c2
-rw-r--r--src/grp-resolve/systemd-resolved/resolved.conf.in2
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/_443._tcp.fedoraproject.org.pktsbin0 -> 169 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/_openpgpkey.fedoraproject.org.pktsbin0 -> 986 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/fake-caa.pktsbin0 -> 196 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/fedoraproject.org.pktsbin0 -> 1483 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/gandi.net.pktsbin0 -> 1010 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/google.com.pktsbin0 -> 747 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/kyhwana.org.pktsbin0 -> 1803 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/root.pktsbin0 -> 1061 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pktsbin0 -> 330 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/teamits.com.pktsbin0 -> 1021 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-data/zbyszek@fedoraproject.org.pktsbin0 -> 2533 bytes
-rw-r--r--src/grp-resolve/systemd-resolved/test-dns-packet.c114
-rw-r--r--src/grp-resolve/systemd-resolved/test-dnssec.c275
-rw-r--r--src/grp-resolve/systemd-resolved/test-resolve-tables.c37
-rw-r--r--src/grp-system/systemctl/systemctl.c804
-rw-r--r--src/grp-system/systemd/Makefile3
-rw-r--r--src/grp-system/systemd/main.c109
-rw-r--r--src/grp-system/systemd/org.freedesktop.systemd1.conf20
-rw-r--r--src/grp-system/systemd/system.conf3
-rw-r--r--src/grp-system/systemd/triggers.systemd.in2
-rw-r--r--src/grp-system/systemd/user.conf2
-rw-r--r--src/grp-timedate/systemd-timedated/timedated.c48
-rw-r--r--src/grp-timedate/timedatectl/timedatectl.c10
-rw-r--r--src/hostname/hostnamed.c2
-rw-r--r--src/import/Makefile2
-rw-r--r--src/import/aufs-util.c73
-rw-r--r--src/import/curl-util.c4
-rw-r--r--src/import/import-common.c4
-rw-r--r--src/import/importd.c2
-rw-r--r--src/import/pull-common.c2
-rw-r--r--src/import/pull-job.h9
-rw-r--r--src/import/pull-raw.c6
-rw-r--r--src/import/pull-tar.c6
-rw-r--r--src/initctl/initctl.c2
-rw-r--r--src/journal/Makefile348
-rw-r--r--src/libbasic/Makefile7
-rw-r--r--src/libbasic/MurmurHash2.c2
-rw-r--r--src/libbasic/af-list.h16
-rw-r--r--src/libbasic/alloc-util.h22
-rw-r--r--src/libbasic/architecture.c (renamed from src/libshared/architecture.c)5
-rw-r--r--src/libbasic/architecture.h (renamed from src/libshared/architecture.h)26
-rw-r--r--src/libbasic/btrfs-util.h4
-rw-r--r--src/libbasic/c-rbtree.c679
-rw-r--r--src/libbasic/c-rbtree.h297
-rw-r--r--src/libbasic/calendarspec.c22
-rw-r--r--src/libbasic/cgroup-util.c90
-rw-r--r--src/libbasic/cgroup-util.h36
-rw-r--r--src/libbasic/clock-util.c11
-rw-r--r--src/libbasic/clock-util.h2
-rw-r--r--src/libbasic/copy.c121
-rw-r--r--src/libbasic/copy.h1
-rw-r--r--src/libbasic/def.h2
-rw-r--r--src/libbasic/dirent-util.c12
-rw-r--r--src/libbasic/dirent-util.h2
-rw-r--r--src/libbasic/escape.c28
-rw-r--r--src/libbasic/escape.h1
-rw-r--r--src/libbasic/ether-addr-util.c81
-rw-r--r--src/libbasic/ether-addr-util.h12
-rw-r--r--src/libbasic/exit-status.c3
-rw-r--r--src/libbasic/exit-status.h1
-rw-r--r--src/libbasic/extract-word.c14
-rw-r--r--src/libbasic/fd-util.c18
-rw-r--r--src/libbasic/fd-util.h2
-rw-r--r--src/libbasic/fdset.c15
-rw-r--r--src/libbasic/fdset.h1
-rw-r--r--src/libbasic/fileio.c140
-rw-r--r--src/libbasic/fileio.h6
-rw-r--r--src/libbasic/formats-util.h2
-rw-r--r--src/libbasic/fs-util.c33
-rw-r--r--src/libbasic/fs-util.h3
-rw-r--r--src/libbasic/gunicode.h4
-rw-r--r--src/libbasic/hashmap.c24
-rw-r--r--src/libbasic/hexdecoct.c13
-rw-r--r--src/libbasic/hostname-util.c46
-rw-r--r--src/libbasic/hostname-util.h1
-rw-r--r--src/libbasic/io-util.c7
-rw-r--r--src/libbasic/io-util.h2
-rw-r--r--src/libbasic/json.c871
-rw-r--r--src/libbasic/json.h90
-rw-r--r--src/libbasic/list.h14
-rw-r--r--src/libbasic/locale-util.c49
-rw-r--r--src/libbasic/locale-util.h24
-rw-r--r--src/libbasic/log.c6
-rw-r--r--src/libbasic/log.h3
-rw-r--r--src/libbasic/login-util.h4
-rw-r--r--src/libbasic/macro.h15
-rw-r--r--src/libbasic/mempool.h2
-rw-r--r--src/libbasic/missing.h288
-rw-r--r--src/libbasic/missing_syscall.h310
-rw-r--r--src/libbasic/mount-util.c8
-rw-r--r--src/libbasic/nss-util.h43
-rw-r--r--src/libbasic/parse-util.c2
-rw-r--r--src/libbasic/parse-util.h12
-rw-r--r--src/libbasic/path-util.c73
-rw-r--r--src/libbasic/path-util.h20
-rw-r--r--src/libbasic/process-util.c103
-rw-r--r--src/libbasic/process-util.h6
-rw-r--r--src/libbasic/rlimit-util.c52
-rw-r--r--src/libbasic/rm-rf.h9
-rw-r--r--src/libbasic/selinux-util.c34
-rw-r--r--src/libbasic/selinux-util.h2
-rw-r--r--src/libbasic/set.h3
-rw-r--r--src/libbasic/sigbus.h4
-rw-r--r--src/libbasic/signal-util.c2
-rw-r--r--src/libbasic/signal-util.h12
-rw-r--r--src/libbasic/socket-label.c34
-rw-r--r--src/libbasic/socket-util.c80
-rw-r--r--src/libbasic/socket-util.h15
-rw-r--r--src/libbasic/special.h1
-rw-r--r--src/libbasic/stdio-util.h2
-rw-r--r--src/libbasic/strbuf.c9
-rw-r--r--src/libbasic/string-table.h54
-rw-r--r--src/libbasic/string-util.c2
-rw-r--r--src/libbasic/string-util.h1
-rw-r--r--src/libbasic/strv.c40
-rw-r--r--src/libbasic/strv.h1
-rw-r--r--src/libbasic/terminal-util.c19
-rw-r--r--src/libbasic/time-util.c129
-rw-r--r--src/libbasic/time-util.h2
-rw-r--r--src/libbasic/user-util.c1
-rw-r--r--src/libbasic/user-util.h5
-rw-r--r--src/libbasic/utf8.c2
-rw-r--r--src/libbasic/utf8.h1
-rw-r--r--src/libbasic/util.c41
-rw-r--r--src/libbasic/util.h13
-rw-r--r--src/libbasic/virt.c74
-rw-r--r--src/libbasic/xattr-util.c2
-rw-r--r--src/libbus-proxy-core/bus-xml-policy.c1327
-rw-r--r--src/libbus-proxy-core/bus-xml-policy.h147
-rw-r--r--src/libbus-proxy-core/driver.c745
-rw-r--r--src/libbus-proxy-core/proxy.c953
-rw-r--r--src/libbus-proxy-core/proxy.h66
-rw-r--r--src/libbus-proxy-core/synthesize.c225
-rw-r--r--src/libbus-proxy-core/synthesize.h36
-rw-r--r--src/libbus-proxy-core/test-bus-xml-policy.c170
-rw-r--r--src/libcore/Makefile2
-rw-r--r--src/libcore/automount.c122
-rw-r--r--src/libcore/automount.h4
-rw-r--r--src/libcore/bus-endpoint.c135
-rw-r--r--src/libcore/busname.c25
-rw-r--r--src/libcore/busname.h2
-rw-r--r--src/libcore/cgroup.c389
-rw-r--r--src/libcore/cgroup.h30
-rw-r--r--src/libcore/dbus-cgroup.c331
-rw-r--r--src/libcore/dbus-execute.c79
-rw-r--r--src/libcore/dbus-job.c2
-rw-r--r--src/libcore/dbus-kill.c4
-rw-r--r--src/libcore/dbus-manager.c382
-rw-r--r--src/libcore/dbus-socket.c2
-rw-r--r--src/libcore/dbus-timer.c2
-rw-r--r--src/libcore/dbus-unit.c155
-rw-r--r--src/libcore/dbus-unit.h1
-rw-r--r--src/libcore/dbus.c85
-rw-r--r--src/libcore/dbus.h2
-rw-r--r--src/libcore/device.c8
-rw-r--r--src/libcore/execute.c105
-rw-r--r--src/libcore/execute.h10
-rw-r--r--src/libcore/failure-action.c14
-rw-r--r--src/libcore/ima-setup.c2
-rw-r--r--src/libcore/ima-setup.h2
-rw-r--r--src/libcore/job.c60
-rw-r--r--src/libcore/job.h2
-rw-r--r--src/libcore/load-dropin.c15
-rw-r--r--src/libcore/load-dropin.h2
-rw-r--r--src/libcore/load-fragment-gperf.gperf.m417
-rw-r--r--src/libcore/load-fragment.c430
-rw-r--r--src/libcore/load-fragment.h5
-rw-r--r--src/libcore/machine-id-setup.c49
-rw-r--r--src/libcore/manager.c492
-rw-r--r--src/libcore/manager.h21
-rw-r--r--src/libcore/mount-setup.c3
-rw-r--r--src/libcore/mount.c130
-rw-r--r--src/libcore/mount.h1
-rw-r--r--src/libcore/namespace.c97
-rw-r--r--src/libcore/namespace.h1
-rw-r--r--src/libcore/path.c20
-rw-r--r--src/libcore/path.h1
-rw-r--r--src/libcore/scope.c36
-rw-r--r--src/libcore/selinux-access.c5
-rw-r--r--src/libcore/selinux-setup.c2
-rw-r--r--src/libcore/service.c135
-rw-r--r--src/libcore/service.h6
-rw-r--r--src/libcore/shutdown.c9
-rw-r--r--src/libcore/slice.c11
-rw-r--r--src/libcore/smack-setup.c2
-rw-r--r--src/libcore/socket.c332
-rw-r--r--src/libcore/socket.h4
-rw-r--r--src/libcore/swap.c28
-rw-r--r--src/libcore/swap.h1
-rw-r--r--src/libcore/timer.c18
-rw-r--r--src/libcore/timer.h1
-rw-r--r--src/libcore/transaction.c15
-rw-r--r--src/libcore/umount.c5
-rw-r--r--src/libcore/unit-printf.c11
-rw-r--r--src/libcore/unit.c312
-rw-r--r--src/libcore/unit.h21
-rw-r--r--src/libfirewall/firewall-util.c16
-rw-r--r--src/libshared/Makefile9
-rw-r--r--src/libshared/acpi-fpdt.c6
-rw-r--r--src/libshared/ask-password-api.c2
-rw-r--r--src/libshared/bus-unit-util.c1307
-rw-r--r--src/libshared/bus-unit-util.h57
-rw-r--r--src/libshared/bus-util.c899
-rw-r--r--src/libshared/bus-util.h37
-rw-r--r--src/libshared/cgroup-show.c102
-rw-r--r--src/libshared/cgroup-show.h8
-rw-r--r--src/libshared/condition.c2
-rw-r--r--src/libshared/conf-parser.c53
-rw-r--r--src/libshared/conf-parser.h3
-rw-r--r--src/libshared/dns-domain.c8
-rw-r--r--src/libshared/dns-domain.h5
-rw-r--r--src/libshared/dropin.c2
-rw-r--r--src/libshared/gcrypt-util.c71
-rw-r--r--src/libshared/gcrypt-util.h39
-rw-r--r--src/libshared/generator.c16
-rw-r--r--src/libshared/generator.h4
-rw-r--r--src/libshared/gpt.h4
-rw-r--r--src/libshared/install-printf.h4
-rw-r--r--src/libshared/install.c1299
-rw-r--r--src/libshared/install.h132
-rw-r--r--src/libshared/local-addresses.c3
-rw-r--r--src/libshared/logs-show.c51
-rw-r--r--src/libshared/logs-show.h3
-rw-r--r--src/libshared/machine-image.c39
-rw-r--r--src/libshared/machine-image.h26
-rw-r--r--src/libshared/machine-pool.c9
-rw-r--r--src/libshared/output-mode.c37
-rw-r--r--src/libshared/output-mode.h11
-rw-r--r--src/libshared/pager.c5
-rw-r--r--src/libshared/pager.h2
-rw-r--r--src/libshared/path-lookup.c807
-rw-r--r--src/libshared/path-lookup.h78
-rw-r--r--src/libshared/ptyfwd.c5
-rw-r--r--src/libshared/sleep-config.c6
-rw-r--r--src/libshared/sleep-config.h4
-rw-r--r--src/libshared/spawn-polkit-agent.c4
-rw-r--r--src/libshared/tests.c (renamed from src/systemd-bootchart/store.h)29
-rw-r--r--src/libshared/tests.h (renamed from src/import/aufs-util.h)4
-rw-r--r--src/libshared/uid-range.c2
-rw-r--r--src/libsystemd-network/Makefile13
-rw-r--r--src/libsystemd-network/dhcp-identifier.c33
-rw-r--r--src/libsystemd-network/dhcp-identifier.h21
-rw-r--r--src/libsystemd-network/dhcp-internal.h4
-rw-r--r--src/libsystemd-network/dhcp-option.c13
-rw-r--r--src/libsystemd-network/dhcp-packet.c2
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h6
-rw-r--r--src/libsystemd-network/dhcp6-internal.h3
-rw-r--r--src/libsystemd-network/dhcp6-option.c3
-rw-r--r--src/libsystemd-network/dhcp6-protocol.h7
-rw-r--r--src/libsystemd-network/lldp-internal.c360
-rw-r--r--src/libsystemd-network/lldp-internal.h78
-rw-r--r--src/libsystemd-network/lldp-neighbor.c794
-rw-r--r--src/libsystemd-network/lldp-neighbor.h106
-rw-r--r--src/libsystemd-network/lldp-network.c35
-rw-r--r--src/libsystemd-network/lldp-network.h4
-rw-r--r--src/libsystemd-network/lldp-port.c116
-rw-r--r--src/libsystemd-network/lldp-port.h69
-rw-r--r--src/libsystemd-network/lldp-tlv.c638
-rw-r--r--src/libsystemd-network/lldp-tlv.h94
-rw-r--r--src/libsystemd-network/lldp.h126
-rw-r--r--src/libsystemd-network/network-internal.c188
-rw-r--r--src/libsystemd-network/network-internal.h8
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c208
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c2
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c47
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c124
-rw-r--r--src/libsystemd-network/sd-ipv4acd.c8
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c8
-rw-r--r--src/libsystemd-network/sd-lldp.c898
-rw-r--r--src/libsystemd-network/sd-ndisc.c2
-rw-r--r--src/libsystemd-network/test-dhcp-option.c11
-rw-r--r--src/libsystemd-network/test-lldp.c339
-rw-r--r--src/libsystemd/Makefile23
-rw-r--r--src/libsystemd/compat-libs/.gitignore1
-rw-r--r--src/libsystemd/compat-libs/Makefile146
-rw-r--r--src/libsystemd/compat-libs/libsystemd-daemon.pc.in19
-rw-r--r--src/libsystemd/compat-libs/libsystemd-daemon.sym27
-rw-r--r--src/libsystemd/compat-libs/libsystemd-id128.pc.in18
-rw-r--r--src/libsystemd/compat-libs/libsystemd-id128.sym21
-rw-r--r--src/libsystemd/compat-libs/libsystemd-journal.pc.in19
-rw-r--r--src/libsystemd/compat-libs/libsystemd-journal.sym111
-rw-r--r--src/libsystemd/compat-libs/libsystemd-login.pc.in18
-rw-r--r--src/libsystemd/compat-libs/libsystemd-login.sym87
-rw-r--r--src/libsystemd/compat-libs/linkwarning.h35
-rw-r--r--src/libsystemd/include/systemd/_sd-common.h2
-rw-r--r--src/libsystemd/include/systemd/sd-bus-protocol.h2
-rw-r--r--src/libsystemd/include/systemd/sd-bus-vtable.h2
-rw-r--r--src/libsystemd/include/systemd/sd-bus.h4
-rw-r--r--src/libsystemd/include/systemd/sd-device.h1
-rw-r--r--src/libsystemd/include/systemd/sd-dhcp-client.h76
-rw-r--r--src/libsystemd/include/systemd/sd-dhcp-server.h3
-rw-r--r--src/libsystemd/include/systemd/sd-dhcp6-client.h61
-rw-r--r--src/libsystemd/include/systemd/sd-event.h6
-rw-r--r--src/libsystemd/include/systemd/sd-id128.h4
-rw-r--r--src/libsystemd/include/systemd/sd-ipv4acd.h6
-rw-r--r--src/libsystemd/include/systemd/sd-ipv4ll.h6
-rw-r--r--src/libsystemd/include/systemd/sd-journal.h15
-rw-r--r--src/libsystemd/include/systemd/sd-lldp.h156
-rw-r--r--src/libsystemd/include/systemd/sd-login.h2
-rw-r--r--src/libsystemd/include/systemd/sd-messages.h2
-rw-r--r--src/libsystemd/include/systemd/sd-ndisc.h2
-rw-r--r--src/libsystemd/include/systemd/sd-netlink.h6
-rw-r--r--src/libsystemd/include/systemd/sd-network.h12
-rw-r--r--src/libsystemd/include/systemd/sd-resolve.h2
-rw-r--r--src/libsystemd/libsystemd-internal/Makefile6
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.c4
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.h4
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-control.c6
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-dump.c4
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-kernel.c44
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-message.c32
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-objects.c4
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-slot.c2
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-socket.c8
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/bus-track.c2
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/sd-bus.c33
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/test-bus-error.c2
-rw-r--r--src/libsystemd/libsystemd-internal/sd-bus/test-bus-proxy.c117
-rw-r--r--src/libsystemd/libsystemd-internal/sd-daemon/sd-daemon.c6
-rw-r--r--src/libsystemd/libsystemd-internal/sd-device/device-internal.h4
-rw-r--r--src/libsystemd/libsystemd-internal/sd-device/device-private.c6
-rw-r--r--src/libsystemd/libsystemd-internal/sd-device/sd-device.c69
-rw-r--r--src/libsystemd/libsystemd-internal/sd-event/sd-event.c25
-rw-r--r--src/libsystemd/libsystemd-internal/sd-event/test-event.c14
-rw-r--r--src/libsystemd/libsystemd-internal/sd-hwdb/hwdb-internal.h3
-rw-r--r--src/libsystemd/libsystemd-internal/sd-netlink/netlink-message.c29
-rw-r--r--src/libsystemd/libsystemd-internal/sd-netlink/netlink-socket.c12
-rw-r--r--src/libsystemd/libsystemd-internal/sd-netlink/netlink-types.c43
-rw-r--r--src/libsystemd/libsystemd-internal/sd-netlink/rtnl-message.c31
-rw-r--r--src/libsystemd/libsystemd-internal/sd-netlink/sd-netlink.c4
-rw-r--r--src/libsystemd/libsystemd-internal/sd-netlink/test-netlink.c24
-rw-r--r--src/libsystemd/libsystemd-internal/sd-network/sd-network.c105
-rw-r--r--src/libsystemd/libsystemd-internal/sd-path/sd-path.c9
-rw-r--r--src/libsystemd/libsystemd-internal/sd-resolve/sd-resolve.c18
-rw-r--r--src/libsystemd/libsystemd-internal/sd-resolve/test-resolve.c2
-rw-r--r--src/libsystemd/libsystemd-journal-internal/Makefile4
-rw-r--r--src/libsystemd/libsystemd-journal-internal/catalog.c83
-rw-r--r--src/libsystemd/libsystemd-journal-internal/compress.c15
-rw-r--r--src/libsystemd/libsystemd-journal-internal/fsprg.c27
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-authenticate.c15
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-file.c420
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-file.h24
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-internal.h3
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-send.c18
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-vacuum.c8
-rw-r--r--src/libsystemd/libsystemd-journal-internal/journal-verify.c26
-rw-r--r--src/libsystemd/libsystemd-journal-internal/mmap-cache.c8
-rw-r--r--src/libsystemd/libsystemd-journal-internal/sd-journal.c315
-rw-r--r--src/libsystemd/libsystemd.sym6
-rw-r--r--src/libudev/include/libudev.h1
-rw-r--r--src/libudev/src/libudev-device-internal.h4
-rw-r--r--src/libudev/src/libudev-enumerate.c2
-rw-r--r--src/libudev/src/udev.h11
-rw-r--r--src/locale/Makefile2
-rw-r--r--src/locale/language-fallback-map4
-rw-r--r--src/locale/localectl.c20
-rw-r--r--src/locale/localed.c80
-rw-r--r--src/login/.gitignore1
-rw-r--r--src/login/70-uaccess.rules3
-rw-r--r--src/login/Makefile5
-rw-r--r--src/login/loginctl.c98
-rw-r--r--src/login/logind-core.c8
-rw-r--r--src/login/logind-dbus.c57
-rw-r--r--src/login/logind-gperf.gperf2
-rw-r--r--src/login/logind-inhibit.c2
-rw-r--r--src/login/logind-seat-dbus.c2
-rw-r--r--src/login/logind-session-dbus.c52
-rw-r--r--src/login/logind-session.c40
-rw-r--r--src/login/logind-session.h4
-rw-r--r--src/login/logind-user-dbus.c5
-rw-r--r--src/login/logind-user.c15
-rw-r--r--src/login/logind-utmp.c2
-rw-r--r--src/login/logind.c90
-rw-r--r--src/login/logind.conf.in (renamed from src/login/logind.conf)4
-rw-r--r--src/login/logind.h2
-rw-r--r--src/login/org.freedesktop.login1.conf4
-rw-r--r--src/login/org.freedesktop.login1.policy.in8
-rw-r--r--src/login/pam_systemd.c2
-rw-r--r--src/login/sysfs-show.c8
-rw-r--r--src/login/systemd-user.m41
-rw-r--r--src/network/.gitignore1
-rw-r--r--src/network/Makefile15
-rw-r--r--src/network/networkctl.c952
-rw-r--r--src/network/networkd-address-pool.c6
-rw-r--r--src/network/networkd-address-pool.h4
-rw-r--r--src/network/networkd-address.c117
-rw-r--r--src/network/networkd-address.h5
-rw-r--r--src/network/networkd-conf.c111
-rw-r--r--src/network/networkd-conf.h49
-rw-r--r--src/network/networkd-dhcp4.c46
-rw-r--r--src/network/networkd-dhcp6.c25
-rw-r--r--src/network/networkd-fdb.c6
-rw-r--r--src/network/networkd-fdb.h8
-rw-r--r--src/network/networkd-gperf.gperf18
-rw-r--r--src/network/networkd-ipv4ll.c8
-rw-r--r--src/network/networkd-link.c508
-rw-r--r--src/network/networkd-link.h29
-rw-r--r--src/network/networkd-lldp-tx.c416
-rw-r--r--src/network/networkd-lldp-tx.h (renamed from src/systemd-bootchart/svg.h)30
-rw-r--r--src/network/networkd-manager.c27
-rw-r--r--src/network/networkd-ndisc.c37
-rw-r--r--src/network/networkd-netdev-bond.c3
-rw-r--r--src/network/networkd-netdev-bond.h8
-rw-r--r--src/network/networkd-netdev-bridge.c25
-rw-r--r--src/network/networkd-netdev-bridge.h14
-rw-r--r--src/network/networkd-netdev-dummy.h11
-rw-r--r--src/network/networkd-netdev-gperf.gperf14
-rw-r--r--src/network/networkd-netdev-ipvlan.h11
-rw-r--r--src/network/networkd-netdev-macvlan.h6
-rw-r--r--src/network/networkd-netdev-tunnel.c12
-rw-r--r--src/network/networkd-netdev-tunnel.h21
-rw-r--r--src/network/networkd-netdev-tuntap.c10
-rw-r--r--src/network/networkd-netdev-tuntap.h6
-rw-r--r--src/network/networkd-netdev-veth.h5
-rw-r--r--src/network/networkd-netdev-vlan.h5
-rw-r--r--src/network/networkd-netdev-vxlan.c8
-rw-r--r--src/network/networkd-netdev-vxlan.h5
-rw-r--r--src/network/networkd-netdev.c2
-rw-r--r--src/network/networkd-netdev.h57
-rw-r--r--src/network/networkd-network-gperf.gperf11
-rw-r--r--src/network/networkd-network.c37
-rw-r--r--src/network/networkd-network.h40
-rw-r--r--src/network/networkd-route.c119
-rw-r--r--src/network/networkd-route.h5
-rw-r--r--src/network/networkd-wait-online.h4
-rw-r--r--src/network/networkd.c5
-rw-r--r--src/network/networkd.h32
-rw-r--r--src/network/test-network-tables.c2
-rw-r--r--src/network/test-networkd-conf.c142
-rw-r--r--src/nss-myhostname/nss-myhostname.c35
-rw-r--r--src/socket-proxy/socket-proxyd.c19
-rw-r--r--src/systemd-activate/Makefile8
-rw-r--r--src/systemd-activate/activate.c118
-rw-r--r--src/systemd-analyze/analyze-verify.c10
-rw-r--r--src/systemd-analyze/analyze-verify.h6
-rw-r--r--src/systemd-analyze/analyze.c25
-rw-r--r--src/systemd-ask-password/ask-password.c11
-rw-r--r--src/systemd-bootchart/bootchart.c531
-rw-r--r--src/systemd-bootchart/bootchart.conf26
-rw-r--r--src/systemd-bootchart/bootchart.h119
-rw-r--r--src/systemd-bootchart/store.c555
-rw-r--r--src/systemd-bootchart/svg.c1375
-rw-r--r--src/systemd-bus-proxyd/bus-proxyd.c328
-rw-r--r--src/systemd-cgls/cgls.c13
-rw-r--r--src/systemd-cgroups-agent/cgroups-agent.c48
-rw-r--r--src/systemd-cgtop/cgtop.c56
-rw-r--r--src/systemd-cryptsetup/cryptsetup.c8
-rw-r--r--src/systemd-delta/delta.c32
-rw-r--r--src/systemd-firstboot/firstboot.c20
-rw-r--r--src/systemd-fsck/fsck.c2
-rw-r--r--src/systemd-fstab-generator/fstab-generator.c13
-rw-r--r--src/systemd-gpt-auto-generator/gpt-auto-generator.c6
-rw-r--r--src/systemd-nspawn/Makefile17
-rw-r--r--src/systemd-nspawn/nspawn-cgroup.c9
-rw-r--r--src/systemd-nspawn/nspawn-gperf.gperf7
-rw-r--r--src/systemd-nspawn/nspawn-mount.c25
-rw-r--r--src/systemd-nspawn/nspawn-network.c184
-rw-r--r--src/systemd-nspawn/nspawn-network.h5
-rw-r--r--src/systemd-nspawn/nspawn-patch-uid.c469
-rw-r--r--src/systemd-nspawn/nspawn-patch-uid.h (renamed from src/libbus-proxy-core/driver.h)12
-rw-r--r--src/systemd-nspawn/nspawn-register.c1
-rw-r--r--src/systemd-nspawn/nspawn-settings.c124
-rw-r--r--src/systemd-nspawn/nspawn-settings.h17
-rw-r--r--src/systemd-nspawn/nspawn.c592
-rw-r--r--src/systemd-nspawn/test-patch-uid.c61
-rw-r--r--src/systemd-rc-local-generator/rc-local-generator.c2
-rw-r--r--src/systemd-reply-password/reply-password.c8
-rw-r--r--src/systemd-run/run.c41
-rw-r--r--src/systemd-stdio-bridge/Makefile3
-rw-r--r--src/systemd-stdio-bridge/stdio-bridge.c352
-rw-r--r--src/systemd-sysv-generator/sysv-generator.c59
-rw-r--r--src/systemd-timesync/timesyncd.c2
-rw-r--r--src/systemd-tmpfiles/tmpfiles.c99
-rw-r--r--src/systemd-tty-ask-password-agent/tty-ask-password-agent.c9
-rw-r--r--src/systemd-update-done/update-done.c2
-rw-r--r--src/systemd-user-sessions/user-sessions.c2
-rw-r--r--src/systemd-vconsole/vconsole-setup.c8
-rw-r--r--src/sysusers/sysusers.c2
-rw-r--r--src/test/test-alloc-util.c55
-rw-r--r--src/test/test-boot-timestamps.c51
-rw-r--r--src/test/test-calendarspec.c1
-rw-r--r--src/test/test-cgroup-mask.c21
-rw-r--r--src/test/test-clock.c96
-rw-r--r--src/test/test-conf-parser.c9
-rw-r--r--src/test/test-copy.c92
-rw-r--r--src/test/test-cpu-set-util.c143
-rw-r--r--src/test/test-daemon.c10
-rw-r--r--src/test/test-engine.c7
-rw-r--r--src/test/test-env-util.c (renamed from src/test/test-env-replace.c)30
-rw-r--r--src/test/test-escape.c114
-rw-r--r--src/test/test-execute.c91
-rw-r--r--src/test/test-fd-util.c103
-rw-r--r--src/test/test-fileio.c135
-rw-r--r--src/test/test-fs-util.c91
-rw-r--r--src/test/test-fstab-util.c37
-rw-r--r--src/test/test-glob-util.c50
-rw-r--r--src/test/test-hashmap-plain.c15
-rw-r--r--src/test/test-hexdecoct.c387
-rw-r--r--src/test/test-install-root.c108
-rw-r--r--src/test/test-install.c44
-rw-r--r--src/test/test-io-util.c69
-rw-r--r--src/test/test-ipcrm.c11
-rw-r--r--src/test/test-json.c202
-rw-r--r--src/test/test-libudev.c267
-rw-r--r--src/test/test-loopback.c4
-rw-r--r--src/test/test-namespace.c9
-rw-r--r--src/test/test-netlink-manual.c6
-rw-r--r--src/test/test-ns.c1
-rw-r--r--src/test/test-nss.c454
-rw-r--r--src/test/test-path-lookup.c40
-rw-r--r--src/test/test-path-util.c80
-rw-r--r--src/test/test-path.c12
-rw-r--r--src/test/test-proc-cmdline.c52
-rw-r--r--src/test/test-process-util.c26
-rw-r--r--src/test/test-rbtree.c362
-rw-r--r--src/test/test-rlimit-util.c12
-rw-r--r--src/test/test-sched-prio.c7
-rw-r--r--src/test/test-selinux.c122
-rw-r--r--src/test/test-signal-util.c18
-rw-r--r--src/test/test-siphash24.c47
-rw-r--r--src/test/test-sizeof.c53
-rw-r--r--src/test/test-socket-util.c42
-rw-r--r--src/test/test-stat-util.c68
-rw-r--r--src/test/test-string-util.c265
-rw-r--r--src/test/test-strv.c55
-rw-r--r--src/test/test-tables.c3
-rw-r--r--src/test/test-time.c2
-rw-r--r--src/test/test-tmpfiles.c26
-rw-r--r--src/test/test-udev.c46
-rw-r--r--src/test/test-unit-file.c11
-rw-r--r--src/test/test-unit-name.c2
-rw-r--r--src/test/test-user-util.c27
-rw-r--r--src/test/test-util.c1441
-rw-r--r--src/test/test-web-util.c39
-rw-r--r--src/test/test-xattr-util.c69
-rw-r--r--src/udev/Makefile3
-rw-r--r--src/udev/mtd_probe/mtd_probe.h4
-rw-r--r--src/udev/mtd_probe/probe_smartmedia.c2
-rw-r--r--src/udev/net/ethtool-util.h4
-rw-r--r--src/udev/net/link-config.c1
-rw-r--r--src/udev/net/link-config.h4
-rw-r--r--src/udev/scsi_id/scsi.h4
-rw-r--r--src/udev/scsi_id/scsi_id.h4
-rw-r--r--src/udev/udev-builtin-input_id.c2
-rw-r--r--src/udev/udev-builtin-net_id.c28
-rw-r--r--src/udev/udev-builtin-path_id.c2
-rw-r--r--src/udev/udev-ctrl.c2
-rw-r--r--src/udev/udev-rules.c636
-rw-r--r--src/udev/udevadm-monitor.c4
-rw-r--r--src/udev/udevadm-test.c2
-rw-r--r--src/udev/udevadm-util.h4
-rw-r--r--src/udev/udevadm.c2
-rw-r--r--src/udev/udevd.c9
-rw-r--r--sysusers.d/systemd.conf.m41
-rw-r--r--test/Makefile188
-rwxr-xr-xtest/TEST-01-BASIC/test.sh2
-rwxr-xr-xtest/TEST-02-CRYPTSETUP/test.sh2
-rwxr-xr-xtest/TEST-07-ISSUE-1981/test.sh3
-rwxr-xr-xtest/TEST-08-ISSUE-2730/test.sh108
-rwxr-xr-xtest/TEST-09-ISSUE-2691/test.sh76
-rwxr-xr-xtest/TEST-10-ISSUE-2467/test.sh88
-rwxr-xr-xtest/TEST-11-ISSUE-3166/test.sh91
-rwxr-xr-xtest/TEST-12-ISSUE-3171/test.sh106
-rwxr-xr-xtest/networkd-test.py7
-rw-r--r--test/parent.slice2
-rw-r--r--test/sys.tar.xzbin261380 -> 165116 bytes
-rwxr-xr-x[-rw-r--r--]test/sysv-generator-test.py7
-rw-r--r--test/test-execute/exec-capabilityambientset-merge-nfsnobody.service9
-rw-r--r--test/test-execute/exec-capabilityambientset-nfsnobody.service8
-rw-r--r--test/test-execute/exec-group-nfsnobody.service7
-rw-r--r--test/test-execute/exec-runtimedirectory-owner-nfsnobody.service9
-rw-r--r--test/test-execute/exec-spec-interpolation.service6
-rw-r--r--test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service11
-rw-r--r--test/test-execute/exec-systemcallfilter-system-user.service11
-rw-r--r--test/test-execute/exec-user-nfsnobody.service7
-rw-r--r--test/test-functions48
-rwxr-xr-xtest/udev-test.pl69
-rw-r--r--tmpfiles.d/systemd.conf.m437
-rwxr-xr-xtools/make-directive-index.py9
-rw-r--r--units/.gitignore3
-rw-r--r--units/emergency.service.in1
-rw-r--r--units/initrd-root-device.target (renamed from units/systemd-bus-proxyd.socket)11
-rw-r--r--units/initrd.target4
-rw-r--r--units/ldconfig.service2
-rw-r--r--units/rc-local.service.in1
-rw-r--r--units/systemd-bootchart.service.in20
-rw-r--r--units/systemd-bus-proxyd.service.m4.in25
-rw-r--r--units/systemd-fsck@.service.in2
-rw-r--r--units/systemd-importd.service.in1
-rw-r--r--units/systemd-machined.service.in2
-rw-r--r--units/systemd-nspawn@.service.in4
-rw-r--r--units/systemd-resolved.service.m4.in3
-rw-r--r--units/systemd-user-sessions.service.in2
-rw-r--r--units/tmp.mount.m41
-rw-r--r--units/user/.gitignore1
-rw-r--r--units/user/systemd-bus-proxyd.service.in14
-rw-r--r--units/user/systemd-bus-proxyd.socket12
843 files changed, 40861 insertions, 33814 deletions
diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 18081cbb48..60f0fb9bef 100644
--- a/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -24,10 +24,7 @@ right-away for being misfiled.
code. This is a requirement for all code we merge.
* Make sure to run "make check" locally, before posting your PR. We use a CI system, meaning we don't even look at your
PR, if the build and tests don't pass.
-* If you need to update the code in an existing PR, please consider opening a new PR (mentioning in it which old PR it
- replaces) and closing the old PR. This is much preferable over force-pushing a new patch set into the PR's branch, as
- commit comments aren't lost that way. That said, we don't follow this rule ourselves quite often, hence this is
- really just a say as we say, not say as we do...
+* If you need to update the code in an existing PR, force-push into the same branch, overriding old commits with new versions.
## Final Words
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000000..750f9e774d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,28 @@
+### Submission type
+
+ - [ ] 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!*
+
+### Used distribution
+
+> …
+
+### In case of bug report: Expected behaviour you didn't see
+
+> …
+
+### In case of bug report: Unexpected behaviour you saw
+
+> …
+
+### In case of bug report: Steps to reproduce the problem
+
+> …
diff --git a/.gitignore b/.gitignore
index 8135516151..07d205f568 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,6 @@
*.log
*.o
*.plist
-*.pyc
*.stamp
*.swp
*.trs
@@ -41,7 +40,6 @@
/hostnamectl
/install-tree
/journalctl
-/libsystemd-*.c
/libtool
/linuxx64.efi.stub
/localectl
@@ -50,18 +48,14 @@
/mtd_probe
/networkctl
/scsi_id
-/systemadm
/systemctl
/systemd
/systemd-ac-power
-/systemd-activate
/systemd-analyze
/systemd-ask-password
/systemd-backlight
/systemd-binfmt
-/systemd-bootchart
/systemd-bootx64.efi
-/systemd-bus-proxyd
/systemd-cat
/systemd-cgls
/systemd-cgroups-agent
@@ -79,7 +73,6 @@
/systemd-fsck
/systemd-fstab-generator
/systemd-getty-generator
-/systemd-gnome-ask-password-agent
/systemd-gpt-auto-generator
/systemd-hibernate-resume
/systemd-hibernate-resume-generator
@@ -93,7 +86,6 @@
/systemd-journal-remote
/systemd-journal-upload
/systemd-journald
-/systemd-kmsg-syslogd
/systemd-localed
/systemd-logind
/systemd-machine-id-setup
@@ -108,7 +100,6 @@
/systemd-quotacheck
/systemd-random-seed
/systemd-rc-local-generator
-/systemd-remount-api-vfs
/systemd-remount-fs
/systemd-reply-password
/systemd-resolve
@@ -117,6 +108,7 @@
/systemd-run
/systemd-shutdown
/systemd-sleep
+/systemd-socket-activate
/systemd-socket-proxyd
/systemd-stdio-bridge
/systemd-sysctl
@@ -127,7 +119,6 @@
/systemd-timesyncd
/systemd-tmpfiles
/systemd-tty-ask-password-agent
-/systemd-uaccess
/systemd-udevd
/systemd-update-done
/systemd-update-utmp
@@ -137,6 +128,7 @@
/test-acd
/test-acl-util
/test-af-list
+/test-alloc-util
/test-architecture
/test-arphrd-list
/test-ask-password-api
@@ -144,7 +136,7 @@
/test-audit-type
/test-barrier
/test-bitmap
-/test-boot-timestamp
+/test-boot-timestamps
/test-btrfs
/test-bus-benchmark
/test-bus-chat
@@ -159,7 +151,6 @@
/test-bus-match
/test-bus-objects
/test-bus-policy
-/test-bus-proxy
/test-bus-server
/test-bus-signature
/test-bus-zero-copy
@@ -170,6 +161,7 @@
/test-cgroup
/test-cgroup-mask
/test-cgroup-util
+/test-clock
/test-compress
/test-compress-benchmark
/test-condition
@@ -177,6 +169,7 @@
/test-conf-parser
/test-copy
/test-coredump-vacuum
+/test-cpu-set-util
/test-daemon
/test-date
/test-device-nodes
@@ -186,25 +179,32 @@
/test-dhcp-server
/test-dhcp6-client
/test-dns-domain
+/test-dns-packet
/test-dnssec
/test-efi-disk.img
/test-ellipsize
/test-engine
-/test-env-replace
+/test-env-util
+/test-escape
/test-event
/test-execute
/test-extract-word
+/test-fd-util
/test-fdset
/test-fileio
/test-firewall-util
+/test-fs-util
/test-fstab-util
+/test-glob-util
/test-hashmap
+/test-hexdecoct
/test-hostname
/test-hostname-util
/test-id128
/test-inhibit
/test-install
/test-install-root
+/test-io-util
/test-ipcrm
/test-ipv4ll
/test-ipv4ll-manual
@@ -219,7 +219,6 @@
/test-journal-stream
/test-journal-syslog
/test-journal-verify
-/test-json
/test-libsystemd-sym*
/test-libudev
/test-libudev-sym*
@@ -238,32 +237,37 @@
/test-ndisc-rs
/test-netlink
/test-netlink-manual
+/test-networkd-conf
/test-network
/test-network-tables
/test-ns
+/test-nss
/test-parse-util
+/test-patch-uid
/test-path
/test-path-lookup
/test-path-util
/test-prioq
+/test-proc-cmdline
/test-process-util
/test-pty
/test-qcow2
/test-ratelimit
-/test-rbtree
/test-replace-var
/test-resolve
/test-resolve-tables
/test-ring
/test-rlimit-util
/test-sched-prio
+/test-selinux
/test-set
+/test-sizeof
/test-sigbus
/test-signal-util
/test-siphash24
/test-sleep
/test-socket-util
-/test-ssd
+/test-stat-util
/test-strbuf
/test-string-util
/test-strip-tab-ansi
@@ -283,6 +287,8 @@
/test-util
/test-verbs
/test-watchdog
+/test-web-util
+/test-xattr-util
/test-xml
/timedatectl
/udevadm
@@ -290,6 +296,7 @@
/v4l_id
Makefile.in
__pycache__/
+*.py[co]
aclocal.m4
config.h
config.h.in
diff --git a/.vimrc b/.vimrc
index 7b436bd377..284bf88494 100644
--- a/.vimrc
+++ b/.vimrc
@@ -16,5 +16,5 @@ set shiftwidth=8
set expandtab
set makeprg=GCC_COLORS=\ make
set tw=79
-au FileType xml set tw=119
+au BufRead,BufNewFile *.xml set tw=119 shiftwidth=2 smarttab
au FileType c set tw=119
diff --git a/CODING_STYLE b/CODING_STYLE
index 46e366898e..b689355c9a 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -163,7 +163,7 @@
programming error with assert_return() and return a sensible return
code. In all other calls, it is recommended to check for programming
errors with a more brutal assert(). We are more forgiving to public
- users then for ourselves! Note that assert() and assert_return()
+ users than for ourselves! Note that assert() and assert_return()
really only should be used for detecting programming errors, not for
runtime errors. assert() and assert_return() by usage of _likely_()
inform the compiler that he should not expect these checks to fail,
@@ -213,6 +213,7 @@
b) socket() and socketpair() must get SOCK_CLOEXEC passed
c) recvmsg() must get MSG_CMSG_CLOEXEC set
d) F_DUPFD_CLOEXEC should be used instead of F_DUPFD, and so on
+ f) invocations of fopen() should take "e"
- We never use the POSIX version of basename() (which glibc defines it in
libgen.h), only the GNU version (which glibc defines in string.h).
@@ -239,6 +240,11 @@
unlink("/foo/bar/baz");
+ Don't cast function calls to (void) that return no error
+ conditions. Specifically, the various xyz_unref() calls that return a NULL
+ object shouldn't be cast to (void), since not using the return value does not
+ hide any errors.
+
- Don't invoke exit(), ever. It is not replacement for proper error
handling. Please escalate errors up your call chain, and use normal
"return" to exit from the main function of a process. If you
diff --git a/Makefile-man.am b/Makefile-man.am
index 28b5fb6adb..d5b328d267 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -94,12 +94,9 @@ MANPAGES += \
man/shutdown.8 \
man/sysctl.d.5 \
man/systemctl.1 \
- man/systemd-activate.8 \
man/systemd-analyze.1 \
man/systemd-ask-password-console.service.8 \
man/systemd-ask-password.1 \
- man/systemd-bus-proxyd.8 \
- man/systemd-bus-proxyd.service.8 \
man/systemd-cat.1 \
man/systemd-cgls.1 \
man/systemd-cgtop.1 \
@@ -126,6 +123,7 @@ MANPAGES += \
man/systemd-resolve.1 \
man/systemd-run.1 \
man/systemd-sleep.conf.5 \
+ man/systemd-socket-activate.1 \
man/systemd-socket-proxyd.8 \
man/systemd-suspend.service.8 \
man/systemd-sysctl.service.8 \
@@ -146,6 +144,7 @@ MANPAGES += \
man/systemd.link.5 \
man/systemd.mount.5 \
man/systemd.nspawn.5 \
+ man/systemd.offline-updates.7 \
man/systemd.path.5 \
man/systemd.preset.5 \
man/systemd.resource-control.5 \
@@ -243,6 +242,7 @@ MANPAGES_ALIAS += \
man/SD_JOURNAL_INVALIDATE.3 \
man/SD_JOURNAL_LOCAL_ONLY.3 \
man/SD_JOURNAL_NOP.3 \
+ man/SD_JOURNAL_OS_ROOT.3 \
man/SD_JOURNAL_RUNTIME_ONLY.3 \
man/SD_JOURNAL_SUPPRESS_LOCATION.3 \
man/SD_JOURNAL_SYSTEM.3 \
@@ -389,9 +389,10 @@ MANPAGES_ALIAS += \
man/sd_journal_get_timeout.3 \
man/sd_journal_has_persistent_files.3 \
man/sd_journal_next_skip.3 \
- man/sd_journal_open_container.3 \
man/sd_journal_open_directory.3 \
+ man/sd_journal_open_directory_fd.3 \
man/sd_journal_open_files.3 \
+ man/sd_journal_open_files_fd.3 \
man/sd_journal_perror.3 \
man/sd_journal_previous.3 \
man/sd_journal_previous_skip.3 \
@@ -421,7 +422,6 @@ MANPAGES_ALIAS += \
man/systemd-ask-password-console.path.8 \
man/systemd-ask-password-wall.path.8 \
man/systemd-ask-password-wall.service.8 \
- man/systemd-bus-proxyd.socket.8 \
man/systemd-fsck-root.service.8 \
man/systemd-fsck.8 \
man/systemd-hibernate-resume.8 \
@@ -573,6 +573,7 @@ man/SD_JOURNAL_FOREACH_UNIQUE.3: man/sd_journal_query_unique.3
man/SD_JOURNAL_INVALIDATE.3: man/sd_journal_get_fd.3
man/SD_JOURNAL_LOCAL_ONLY.3: man/sd_journal_open.3
man/SD_JOURNAL_NOP.3: man/sd_journal_get_fd.3
+man/SD_JOURNAL_OS_ROOT.3: man/sd_journal_open.3
man/SD_JOURNAL_RUNTIME_ONLY.3: man/sd_journal_open.3
man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3
man/SD_JOURNAL_SYSTEM.3: man/sd_journal_open.3
@@ -719,9 +720,10 @@ man/sd_journal_get_monotonic_usec.3: man/sd_journal_get_realtime_usec.3
man/sd_journal_get_timeout.3: man/sd_journal_get_fd.3
man/sd_journal_has_persistent_files.3: man/sd_journal_has_runtime_files.3
man/sd_journal_next_skip.3: man/sd_journal_next.3
-man/sd_journal_open_container.3: man/sd_journal_open.3
man/sd_journal_open_directory.3: man/sd_journal_open.3
+man/sd_journal_open_directory_fd.3: man/sd_journal_open.3
man/sd_journal_open_files.3: man/sd_journal_open.3
+man/sd_journal_open_files_fd.3: man/sd_journal_open.3
man/sd_journal_perror.3: man/sd_journal_print.3
man/sd_journal_previous.3: man/sd_journal_next.3
man/sd_journal_previous_skip.3: man/sd_journal_next.3
@@ -751,7 +753,6 @@ man/system.conf.d.5: man/systemd-system.conf.5
man/systemd-ask-password-console.path.8: man/systemd-ask-password-console.service.8
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-bus-proxyd.socket.8: man/systemd-bus-proxyd.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
@@ -1037,6 +1038,9 @@ man/SD_JOURNAL_LOCAL_ONLY.html: man/sd_journal_open.html
man/SD_JOURNAL_NOP.html: man/sd_journal_get_fd.html
$(html-alias)
+man/SD_JOURNAL_OS_ROOT.html: man/sd_journal_open.html
+ $(html-alias)
+
man/SD_JOURNAL_RUNTIME_ONLY.html: man/sd_journal_open.html
$(html-alias)
@@ -1475,15 +1479,18 @@ man/sd_journal_has_persistent_files.html: man/sd_journal_has_runtime_files.html
man/sd_journal_next_skip.html: man/sd_journal_next.html
$(html-alias)
-man/sd_journal_open_container.html: man/sd_journal_open.html
+man/sd_journal_open_directory.html: man/sd_journal_open.html
$(html-alias)
-man/sd_journal_open_directory.html: man/sd_journal_open.html
+man/sd_journal_open_directory_fd.html: man/sd_journal_open.html
$(html-alias)
man/sd_journal_open_files.html: man/sd_journal_open.html
$(html-alias)
+man/sd_journal_open_files_fd.html: man/sd_journal_open.html
+ $(html-alias)
+
man/sd_journal_perror.html: man/sd_journal_print.html
$(html-alias)
@@ -1571,9 +1578,6 @@ man/systemd-ask-password-wall.path.html: man/systemd-ask-password-console.servic
man/systemd-ask-password-wall.service.html: man/systemd-ask-password-console.service.html
$(html-alias)
-man/systemd-bus-proxyd.socket.html: man/systemd-bus-proxyd.service.html
- $(html-alias)
-
man/systemd-fsck-root.service.html: man/systemd-fsck@.service.html
$(html-alias)
@@ -1850,29 +1854,27 @@ man/systemd-binfmt.html: man/systemd-binfmt.service.html
endif
-if ENABLE_BOOTCHART
-MANPAGES += \
- man/bootchart.conf.5 \
- man/systemd-bootchart.1
-MANPAGES_ALIAS += \
- man/bootchart.conf.d.5
-man/bootchart.conf.d.5: man/bootchart.conf.5
-man/bootchart.conf.d.html: man/bootchart.conf.html
- $(html-alias)
-
-endif
-
if ENABLE_COREDUMP
MANPAGES += \
man/coredump.conf.5 \
man/coredumpctl.1 \
man/systemd-coredump.8
MANPAGES_ALIAS += \
- man/coredump.conf.d.5
+ man/coredump.conf.d.5 \
+ man/systemd-coredump.socket.8 \
+ man/systemd-coredump@.service.8
man/coredump.conf.d.5: man/coredump.conf.5
+man/systemd-coredump.socket.8: man/systemd-coredump.8
+man/systemd-coredump@.service.8: man/systemd-coredump.8
man/coredump.conf.d.html: man/coredump.conf.html
$(html-alias)
+man/systemd-coredump.socket.html: man/systemd-coredump.html
+ $(html-alias)
+
+man/systemd-coredump@.service.html: man/systemd-coredump.html
+ $(html-alias)
+
endif
if ENABLE_EFI
@@ -1917,6 +1919,17 @@ MANPAGES_ALIAS += \
endif
+if ENABLE_IMPORTD
+MANPAGES += \
+ man/systemd-importd.service.8
+MANPAGES_ALIAS += \
+ man/systemd-importd.8
+man/systemd-importd.8: man/systemd-importd.service.8
+man/systemd-importd.html: man/systemd-importd.service.html
+ $(html-alias)
+
+endif
+
if ENABLE_LOCALED
MANPAGES += \
man/localectl.1 \
@@ -1968,15 +1981,21 @@ endif
if ENABLE_NETWORKD
MANPAGES += \
man/networkctl.1 \
+ man/networkd.conf.5 \
man/systemd-networkd-wait-online.service.8 \
man/systemd-networkd.service.8 \
man/systemd.netdev.5 \
man/systemd.network.5
MANPAGES_ALIAS += \
+ man/networkd.conf.d.5 \
man/systemd-networkd-wait-online.8 \
man/systemd-networkd.8
+man/networkd.conf.d.5: man/networkd.conf.5
man/systemd-networkd-wait-online.8: man/systemd-networkd-wait-online.service.8
man/systemd-networkd.8: man/systemd-networkd.service.8
+man/networkd.conf.d.html: man/networkd.conf.html
+ $(html-alias)
+
man/systemd-networkd-wait-online.html: man/systemd-networkd-wait-online.service.html
$(html-alias)
@@ -2456,7 +2475,6 @@ endif
EXTRA_DIST += \
man/binfmt.d.xml \
- man/bootchart.conf.xml \
man/bootctl.xml \
man/bootup.xml \
man/busctl.xml \
@@ -2488,6 +2506,7 @@ EXTRA_DIST += \
man/machinectl.xml \
man/modules-load.d.xml \
man/networkctl.xml \
+ man/networkd.conf.xml \
man/nss-myhostname.xml \
man/nss-mymachines.xml \
man/nss-resolve.xml \
@@ -2574,15 +2593,11 @@ EXTRA_DIST += \
man/standard-options.xml \
man/sysctl.d.xml \
man/systemctl.xml \
- man/systemd-activate.xml \
man/systemd-analyze.xml \
man/systemd-ask-password-console.service.xml \
man/systemd-ask-password.xml \
man/systemd-backlight@.service.xml \
man/systemd-binfmt.service.xml \
- man/systemd-bootchart.xml \
- man/systemd-bus-proxyd.service.xml \
- man/systemd-bus-proxyd.xml \
man/systemd-cat.xml \
man/systemd-cgls.xml \
man/systemd-cgtop.xml \
@@ -2603,6 +2618,7 @@ EXTRA_DIST += \
man/systemd-hibernate-resume@.service.xml \
man/systemd-hostnamed.service.xml \
man/systemd-hwdb.xml \
+ man/systemd-importd.service.xml \
man/systemd-inhibit.xml \
man/systemd-initctl.service.xml \
man/systemd-journal-gatewayd.service.xml \
@@ -2628,6 +2644,7 @@ EXTRA_DIST += \
man/systemd-rfkill.service.xml \
man/systemd-run.xml \
man/systemd-sleep.conf.xml \
+ man/systemd-socket-activate.xml \
man/systemd-socket-proxyd.xml \
man/systemd-suspend.service.xml \
man/systemd-sysctl.service.xml \
@@ -2655,6 +2672,7 @@ EXTRA_DIST += \
man/systemd.netdev.xml \
man/systemd.network.xml \
man/systemd.nspawn.xml \
+ man/systemd.offline-updates.xml \
man/systemd.path.xml \
man/systemd.preset.xml \
man/systemd.resource-control.xml \
diff --git a/Makefile.am b/Makefile.am
index 9a749f4c1f..b4c1285de9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,27 +49,9 @@ LIBUDEV_REVISION=4
LIBUDEV_AGE=6
#@src/libsystemd/Makefile
-LIBSYSTEMD_CURRENT=14
+LIBSYSTEMD_CURRENT=15
LIBSYSTEMD_REVISION=0
-LIBSYSTEMD_AGE=14
-
-# The following four libraries only exist for compatibility reasons,
-# their version info should not be bumped anymore
-LIBSYSTEMD_LOGIN_CURRENT=9
-LIBSYSTEMD_LOGIN_REVISION=3
-LIBSYSTEMD_LOGIN_AGE=9
-
-LIBSYSTEMD_DAEMON_CURRENT=0
-LIBSYSTEMD_DAEMON_REVISION=12
-LIBSYSTEMD_DAEMON_AGE=0
-
-LIBSYSTEMD_ID128_CURRENT=0
-LIBSYSTEMD_ID128_REVISION=28
-LIBSYSTEMD_ID128_AGE=0
-
-LIBSYSTEMD_JOURNAL_CURRENT=11
-LIBSYSTEMD_JOURNAL_REVISION=5
-LIBSYSTEMD_JOURNAL_AGE=11
+LIBSYSTEMD_AGE=15
#@config.mk.in
# Dirs of external packages
@@ -158,8 +140,12 @@ TEST_EXTENSIONS = .py
PY_LOG_COMPILER = $(PYTHON)
DISABLE_HARD_ERRORS = yes
if ENABLE_TESTS
-noinst_PROGRAMS = $(manual_tests) $(tests)
+noinst_PROGRAMS = $(manual_tests) $(tests) $(unsafe_tests)
TESTS = $(tests)
+if ENABLE_UNSAFE_TESTS
+TESTS += \
+ $(unsafe_tests)
+endif
else
noinst_PROGRAMS =
TESTS =
@@ -465,7 +451,6 @@ rootlibexec_PROGRAMS = \
systemd-ac-power \
systemd-sysctl \
systemd-sleep \
- systemd-bus-proxyd \
systemd-socket-proxyd \
systemd-update-done
@@ -536,6 +521,7 @@ dist_systemunit_DATA = \
units/local-fs-pre.target \
units/initrd.target \
units/initrd-fs.target \
+ units/initrd-root-device.target \
units/initrd-root-fs.target \
units/remote-fs.target \
units/remote-fs-pre.target \
@@ -813,10 +799,9 @@ noinst_LTLIBRARIES += \
libbasic_la_SOURCES = \
src/basic/missing.h \
+ src/basic/missing_syscall.h \
src/basic/capability-util.c \
src/basic/capability-util.h \
- src/basic/c-rbtree.c \
- src/basic/c-rbtree.h \
src/basic/conf-files.c \
src/basic/conf-files.h \
src/basic/stdio-util.h \
@@ -923,6 +908,8 @@ libbasic_la_SOURCES = \
src/basic/exit-status.h \
src/basic/virt.c \
src/basic/virt.h \
+ src/basic/architecture.c \
+ src/basic/architecture.h \
src/basic/smack-util.c \
src/basic/smack-util.h \
src/basic/device-nodes.c \
@@ -967,8 +954,6 @@ libbasic_la_SOURCES = \
src/basic/audit-util.h \
src/basic/xml.c \
src/basic/xml.h \
- src/basic/json.c \
- src/basic/json.h \
src/basic/barrier.c \
src/basic/barrier.h \
src/basic/async.c \
@@ -1032,14 +1017,13 @@ noinst_LTLIBRARIES += \
libshared_la_SOURCES = \
src/shared/output-mode.h \
+ src/shared/output-mode.c \
src/shared/gpt.h \
src/shared/udev-util.h \
src/shared/linux/auto_dev-ioctl.h \
src/shared/initreq.h \
src/shared/dns-domain.c \
src/shared/dns-domain.h \
- src/shared/architecture.c \
- src/shared/architecture.h \
src/shared/efivars.c \
src/shared/efivars.h \
src/shared/fstab-util.c \
@@ -1108,7 +1092,11 @@ libshared_la_SOURCES = \
src/shared/machine-pool.c \
src/shared/machine-pool.h \
src/shared/resolve-util.c \
- src/shared/resolve-util.h
+ src/shared/resolve-util.h \
+ src/shared/bus-unit-util.c \
+ src/shared/bus-unit-util.h \
+ src/shared/tests.h \
+ src/shared/tests.c
if HAVE_UTMP
libshared_la_SOURCES += \
@@ -1190,8 +1178,6 @@ libcore_la_SOURCES = \
src/core/socket.h \
src/core/busname.c \
src/core/busname.h \
- src/core/bus-endpoint.c \
- src/core/bus-endpoint.h \
src/core/bus-policy.c \
src/core/bus-policy.h \
src/core/target.c \
@@ -1414,7 +1400,7 @@ src/journal/audit_type-to-name.h: src/journal/audit_type-list.txt
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)$(AWK) '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" }' <$< >$@
-#@src/journal/Makefile
+#@src/grp-resolve/systemd-resolved/Makefile
src/resolve/dns_type-list.txt: src/resolve/dns-type.h
$(AM_V_at)$(MKDIR_P) $(dir $@)
@@ -1459,6 +1445,9 @@ pkgconfigdata_DATA += \
nodist_rpmmacros_DATA = \
src/core/macros.systemd
+BUILT_SOURCES += \
+ src/core/triggers.systemd
+
EXTRA_DIST += \
src/core/systemd.pc.in \
src/core/macros.systemd.in \
@@ -1468,19 +1457,17 @@ EXTRA_DIST += \
manual_tests += \
test-ns \
- test-loopback \
- test-hostname \
- test-daemon \
test-cgroup \
test-install \
- test-watchdog \
- test-log \
- test-ipcrm \
test-btrfs \
test-acd \
test-ipv4ll-manual \
test-ask-password-api
+unsafe_tests = \
+ test-hostname \
+ test-ipcrm
+
if HAVE_LIBIPTC
manual_tests += \
test-firewall-util
@@ -1492,10 +1479,14 @@ manual_tests += \
endif # HAVE_KMOD
tests += \
+ test-daemon \
+ test-log \
+ test-loopback \
test-engine \
+ test-watchdog \
test-cgroup-mask \
test-job-type \
- test-env-replace \
+ test-env-util \
test-strbuf \
test-strv \
test-path \
@@ -1507,6 +1498,18 @@ tests += \
test-utf8 \
test-ellipsize \
test-util \
+ test-cpu-set-util \
+ test-hexdecoct \
+ test-escape \
+ test-alloc-util \
+ test-proc-cmdline \
+ test-io-util \
+ test-glob-util \
+ test-xattr-util \
+ test-fs-util \
+ test-web-util \
+ test-stat-util \
+ test-fd-util \
test-string-util \
test-extract-word \
test-parse-util \
@@ -1529,6 +1532,7 @@ tests += \
test-prioq \
test-fileio \
test-time \
+ test-clock \
test-hashmap \
test-set \
test-bitmap \
@@ -1537,7 +1541,6 @@ tests += \
test-tables \
test-device-nodes \
test-xml \
- test-json \
test-architecture \
test-socket-util \
test-fdset \
@@ -1548,21 +1551,20 @@ tests += \
test-ratelimit \
test-condition \
test-uid-range \
- test-bus-policy \
test-locale-util \
test-execute \
test-copy \
test-cap-list \
test-sigbus \
- test-rbtree \
test-verbs \
test-af-list \
test-arphrd-list \
test-dns-domain \
- test-resolve-tables \
test-install-root \
test-rlimit-util \
- test-signal-util
+ test-signal-util \
+ test-selinux \
+ test-sizeof
if HAVE_ACL
tests += \
@@ -1625,6 +1627,7 @@ EXTRA_DIST += \
test/test-execute/exec-passenvironment-repeated.service \
test/test-execute/exec-passenvironment.service \
test/test-execute/exec-group.service \
+ test/test-execute/exec-group-nfsnobody.service \
test/test-execute/exec-ignoresigpipe-no.service \
test/test-execute/exec-ignoresigpipe-yes.service \
test/test-execute/exec-personality-x86-64.service \
@@ -1634,12 +1637,16 @@ EXTRA_DIST += \
test/test-execute/exec-privatedevices-yes.service \
test/test-execute/exec-privatetmp-no.service \
test/test-execute/exec-privatetmp-yes.service \
+ test/test-execute/exec-spec-interpolation.service \
test/test-execute/exec-systemcallerrornumber.service \
test/test-execute/exec-systemcallfilter-failing2.service \
test/test-execute/exec-systemcallfilter-failing.service \
test/test-execute/exec-systemcallfilter-not-failing2.service \
test/test-execute/exec-systemcallfilter-not-failing.service \
+ test/test-execute/exec-systemcallfilter-system-user.service \
+ test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service \
test/test-execute/exec-user.service \
+ test/test-execute/exec-user-nfsnobody.service \
test/test-execute/exec-workingdirectory.service \
test/test-execute/exec-umask-0177.service \
test/test-execute/exec-umask-default.service \
@@ -1655,6 +1662,14 @@ EXTRA_DIST += \
test/test-execute/exec-capabilityboundingset-merge.service \
test/test-execute/exec-capabilityboundingset-reset.service \
test/test-execute/exec-capabilityboundingset-simple.service \
+ test/test-execute/exec-capabilityambientset.service \
+ test/test-execute/exec-capabilityambientset-nfsnobody.service \
+ test/test-execute/exec-capabilityambientset-merge.service \
+ test/test-execute/exec-capabilityambientset-merge-nfsnobody.service \
+ test/test-execute/exec-runtimedirectory.service \
+ test/test-execute/exec-runtimedirectory-mode.service \
+ test/test-execute/exec-runtimedirectory-owner.service \
+ test/test-execute/exec-runtimedirectory-owner-nfsnobody.service \
test/bus-policy/hello.conf \
test/bus-policy/methods.conf \
test/bus-policy/ownerships.conf \
@@ -1724,25 +1739,15 @@ test_dns_domain_LDADD = \
libsystemd-network.la \
libshared.la
-test_resolve_tables_SOURCES = \
- src/resolve/test-resolve-tables.c \
- src/shared/test-tables.h \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h \
- src/resolve/dns_type-from-name.h \
- src/resolve/dns_type-to-name.h
-
-test_resolve_tables_LDADD = \
- libshared.la
if ENABLE_EFI
-manual_tests += \
- test-boot-timestamp
+tests += \
+ test-boot-timestamps
-test_boot_timestamp_SOURCES = \
+test_boot_timestamps_SOURCES = \
src/test/test-boot-timestamps.c
-test_boot_timestamp_LDADD = \
+test_boot_timestamps_LDADD = \
libshared.la
endif # ENABLE_EFI
@@ -1804,12 +1809,6 @@ test_sigbus_SOURCES = \
test_sigbus_LDADD = \
libshared.la
-test_rbtree_SOURCES = \
- src/test/test-rbtree.c
-
-test_rbtree_LDADD = \
- libshared.la
-
test_condition_SOURCES = \
src/test/test-condition.c
@@ -1840,6 +1839,78 @@ test_util_SOURCES = \
test_util_LDADD = \
libshared.la
+test_hexdecoct_SOURCES = \
+ src/test/test-hexdecoct.c
+
+test_hexdecoct_LDADD = \
+ libbasic.la
+
+test_alloc_util_SOURCES = \
+ src/test/test-alloc-util.c
+
+test_alloc_util_LDADD = \
+ libbasic.la
+
+test_xattr_util_SOURCES = \
+ src/test/test-xattr-util.c
+
+test_xattr_util_LDADD = \
+ libbasic.la
+
+test_io_util_SOURCES = \
+ src/test/test-io-util.c
+
+test_io_util_LDADD = \
+ libbasic.la
+
+test_glob_util_SOURCES = \
+ src/test/test-glob-util.c
+
+test_glob_util_LDADD = \
+ libbasic.la
+
+test_fs_util_SOURCES = \
+ src/test/test-fs-util.c
+
+test_fs_util_LDADD = \
+ libbasic.la
+
+test_proc_cmdline_SOURCES = \
+ src/test/test-proc-cmdline.c
+
+test_proc_cmdline_LDADD = \
+ libbasic.la
+
+test_fd_util_SOURCES = \
+ src/test/test-fd-util.c
+
+test_fd_util_LDADD = \
+ libbasic.la
+
+test_web_util_SOURCES = \
+ src/test/test-web-util.c
+
+test_web_util_LDADD = \
+ libbasic.la
+
+test_cpu_set_util_SOURCES = \
+ src/test/test-cpu-set-util.c
+
+test_cpu_set_util_LDADD = \
+ libbasic.la
+
+test_stat_util_SOURCES = \
+ src/test/test-stat-util.c
+
+test_stat_util_LDADD = \
+ libbasic.la
+
+test_escape_SOURCES = \
+ src/test/test-escape.c
+
+test_escape_LDADD = \
+ libbasic.la
+
test_string_util_SOURCES = \
src/test/test-string-util.c
@@ -1960,6 +2031,18 @@ test_signal_util_SOURCES = \
test_signal_util_LDADD = \
libshared.la
+test_selinux_SOURCES = \
+ src/test/test-selinux.c
+
+test_selinux_LDADD = \
+ libshared.la
+
+test_sizeof_SOURCES = \
+ src/test/test-sizeof.c
+
+test_sizeof_LDADD = \
+ libshared.la
+
BUILT_SOURCES += \
src/test/test-hashmap-ordered.c
@@ -2000,12 +2083,6 @@ test_xml_SOURCES = \
test_xml_LDADD = \
libshared.la
-test_json_SOURCES = \
- src/test/test-json.c
-
-test_json_LDADD = \
- libshared.la
-
test_list_SOURCES = \
src/test/test-list.c
@@ -2021,14 +2098,11 @@ test_unaligned_SOURCES = \
test_tables_SOURCES = \
src/test/test-tables.c \
src/shared/test-tables.h \
- src/bus-proxyd/bus-xml-policy.c \
- src/bus-proxyd/bus-xml-policy.h \
src/journal/journald-server.c \
src/journal/journald-server.h
test_tables_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -I$(top_srcdir)/src/bus-proxyd
+ $(AM_CPPFLAGS)
test_tables_CFLAGS = \
$(AM_CFLAGS) \
@@ -2058,6 +2132,12 @@ test_time_SOURCES = \
test_time_LDADD = \
libshared.la
+test_clock_SOURCES = \
+ src/test/test-clock.c
+
+test_clock_LDADD = \
+ libshared.la
+
test_architecture_SOURCES = \
src/test/test-architecture.c
@@ -2175,10 +2255,10 @@ test_cgroup_util_SOURCES = \
test_cgroup_util_LDADD = \
libshared.la
-test_env_replace_SOURCES = \
- src/test/test-env-replace.c
+test_env_util_SOURCES = \
+ src/test/test-env-util.c
-test_env_replace_LDADD = \
+test_env_util_LDADD = \
libshared.la
test_strbuf_SOURCES = \
@@ -2269,13 +2349,6 @@ test_conf_parser_SOURCES = \
test_conf_parser_LDADD = \
libshared.la
-test_bus_policy_SOURCES = \
- src/bus-proxyd/test-bus-xml-policy.c
-
-test_bus_policy_LDADD = \
- libbus-proxy-core.la \
- libshared.la
-
test_af_list_SOURCES = \
src/test/test-af-list.c
@@ -2760,6 +2833,7 @@ systemd_boot_headers = \
src/boot/efi/console.h \
src/boot/efi/graphics.h \
src/boot/efi/pefile.h \
+ src/boot/efi/measure.h \
src/boot/efi/disk.h
systemd_boot_sources = \
@@ -2768,6 +2842,7 @@ systemd_boot_sources = \
src/boot/efi/graphics.c \
src/boot/efi/pefile.c \
src/boot/efi/disk.c \
+ src/boot/efi/measure.c \
src/boot/efi/boot.c
EXTRA_DIST += $(systemd_boot_sources) $(systemd_boot_headers)
@@ -2804,6 +2879,7 @@ stub_headers = \
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 = \
@@ -2813,6 +2889,7 @@ stub_sources = \
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
EXTRA_DIST += \
@@ -3004,10 +3081,14 @@ systemd_nspawn_SOURCES = \
src/nspawn/nspawn-setuid.h \
src/nspawn/nspawn-stub-pid1.c \
src/nspawn/nspawn-stub-pid1.h \
+ src/nspawn/nspawn-patch-uid.c \
+ src/nspawn/nspawn-patch-uid.h \
src/core/mount-setup.c \
src/core/mount-setup.h \
src/core/loopback-setup.c \
- src/core/loopback-setup.h
+ src/core/loopback-setup.h \
+ src/core/machine-id-setup.c \
+ src/core/machine-id-setup.h
nodist_systemd_nspawn_SOURCES = \
src/nspawn/nspawn-gperf.c
@@ -3029,70 +3110,31 @@ systemd_nspawn_LDADD += \
libfirewall.la
endif # HAVE_LIBIPTC
-#@src/systemd-run/Makefile -----------------------------------------------------
-systemd_run_SOURCES = \
- src/run/run.c
+test_patch_uid_SOURCES = \
+ src/nspawn/nspawn-patch-uid.c \
+ src/nspawn/nspawn-patch-uid.h \
+ src/nspawn/test-patch-uid.c
-systemd_run_LDADD = \
+test_patch_uid_LDADD = \
libshared.la
-#@src/libbus-proxy-core/Makefile -----------------------------------------------
-noinst_LTLIBRARIES += \
- libbus-proxy-core.la
-
-libbus_proxy_core_la_SOURCES = \
- src/bus-proxyd/bus-xml-policy.c \
- src/bus-proxyd/bus-xml-policy.h \
- src/bus-proxyd/driver.c \
- src/bus-proxyd/driver.h \
- src/bus-proxyd/proxy.c \
- src/bus-proxyd/proxy.h \
- src/bus-proxyd/synthesize.c \
- src/bus-proxyd/synthesize.h
-
-libbus_proxy_core_la_LIBADD = \
- libshared.la
+manual_tests += \
+ test-patch-uid
-#@src/systemd-bus-proxyd/Makefile
-systemd_bus_proxyd_SOURCES = \
- src/bus-proxyd/bus-proxyd.c
+#@src/systemd-run/Makefile -----------------------------------------------------
+systemd_run_SOURCES = \
+ src/run/run.c
-systemd_bus_proxyd_LDADD = \
- libbus-proxy-core.la \
+systemd_run_LDADD = \
libshared.la
-#@src/systemd-stdio-bridge/Makefile
+#@src/systemd-stdio-bridge/Makefile --------------------------------------------
systemd_stdio_bridge_SOURCES = \
- src/bus-proxyd/stdio-bridge.c
+ src/stdio-bridge/stdio-bridge.c
systemd_stdio_bridge_LDADD = \
- libbus-proxy-core.la \
libshared.la
-#@src/systemd-bus-proxyd/Makefile
-nodist_systemunit_DATA += \
- units/systemd-bus-proxyd.service
-
-dist_systemunit_DATA += \
- units/systemd-bus-proxyd.socket
-
-nodist_userunit_DATA += \
- units/user/systemd-bus-proxyd.service
-
-dist_userunit_DATA += \
- units/user/systemd-bus-proxyd.socket
-
-EXTRA_DIST += \
- units/systemd-bus-proxyd.service.m4.in \
- units/user/systemd-bus-proxyd.service.in
-
-if HAVE_SMACK
-bus-proxyd-set-cap-hook:
- -$(SETCAP) cap_mac_admin+ei $(DESTDIR)$(rootlibexecdir)/systemd-bus-proxyd
-
-INSTALL_EXEC_HOOKS += bus-proxyd-set-cap-hook
-endif # HAVE_SMACK
-
#@src/systemd-tty-ask-password-agent/Makefile ----------------------------------
systemd_tty_ask_password_agent_SOURCES = \
src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -3260,7 +3302,6 @@ tests += \
test-bus-cleanup \
test-bus-server \
test-bus-match \
- test-bus-proxy \
test-bus-kernel \
test-bus-kernel-bloom \
test-bus-zero-copy \
@@ -3355,12 +3396,6 @@ test_bus_match_SOURCES = \
test_bus_match_LDADD = \
libshared.la
-test_bus_proxy_SOURCES = \
- src/libsystemd/sd-bus/test-bus-proxy.c
-
-test_bus_proxy_LDADD = \
- libshared.la
-
test_bus_kernel_SOURCES = \
src/libsystemd/sd-bus/test-bus-kernel.c
@@ -3472,15 +3507,11 @@ libsystemd_network_la_SOURCES = \
src/libsystemd-network/sd-dhcp6-lease.c \
src/libsystemd-network/dhcp-identifier.h \
src/libsystemd-network/dhcp-identifier.c \
- src/libsystemd-network/lldp.h \
- src/libsystemd-network/lldp-tlv.h \
- src/libsystemd-network/lldp-tlv.c \
+ src/libsystemd-network/lldp-internal.h \
src/libsystemd-network/lldp-network.h \
src/libsystemd-network/lldp-network.c \
- src/libsystemd-network/lldp-port.h \
- src/libsystemd-network/lldp-port.c \
- src/libsystemd-network/lldp-internal.h \
- src/libsystemd-network/lldp-internal.c \
+ src/libsystemd-network/lldp-neighbor.h \
+ src/libsystemd-network/lldp-neighbor.c \
src/libsystemd-network/sd-lldp.c
libsystemd_network_la_LIBADD = \
@@ -3563,9 +3594,6 @@ test_dhcp6_client_LDADD = \
libshared.la
test_lldp_SOURCES = \
- src/libsystemd-network/lldp.h \
- src/libsystemd-network/lldp-tlv.h \
- src/libsystemd-network/lldp-tlv.c \
src/libsystemd-network/test-lldp.c
test_lldp_LDADD = \
@@ -3641,7 +3669,8 @@ INSTALL_DIRS += \
dist_network_DATA = \
network/99-default.link \
network/80-container-host0.network \
- network/80-container-ve.network
+ network/80-container-ve.network \
+ network/80-container-vz.network
dist_udevrules_DATA += \
rules/50-udev-default.rules \
@@ -3857,8 +3886,10 @@ endif # HAVE_SYSV_COMPAT
endif # HAVE_PYTHON
endif # ENABLE_TESTS
+tests += \
+ test-libudev
+
manual_tests += \
- test-libudev \
test-udev
test_libudev_SOURCES = \
@@ -3881,9 +3912,11 @@ check_DATA += \
endif # ENABLE_TESTS
# packed sysfs test tree
-test/sys:
+test/sys: test/sys.tar.xz
+ -rm -rf test/sys
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)tar -C test/ -xJf $(top_srcdir)/test/sys.tar.xz
+ -touch test/sys
test-sys-distclean:
-rm -rf test/sys
@@ -3982,16 +4015,16 @@ tests += \
#@src/systemd-activate/Makefile ------------------------------------------------
-rootlibexec_PROGRAMS += \
- systemd-activate
+bin_PROGRAMS += \
+ systemd-socket-activate
-systemd_activate_SOURCES = \
+systemd_socket_activate_SOURCES = \
src/activate/activate.c
-systemd_activate_LDADD = \
+systemd_socket_activate_LDADD = \
libshared.la
-#@src/journal/Makefile ---------------------------------------------------------
+#@src/grp-journal/systemd-journald/Makefile ------------------------------------
systemd_journald_SOURCES = \
src/journal/journald.c \
src/journal/journald-server.h
@@ -4006,7 +4039,36 @@ systemd_cat_SOURCES = \
systemd_cat_LDADD = \
libjournal-core.la
-#@src/journal-remote/Makefile
+#@src/grp-journal-remote/systemd-journal-upload/Makefile
+if HAVE_LIBCURL
+rootlibexec_PROGRAMS += \
+ systemd-journal-upload
+
+systemd_journal_upload_SOURCES = \
+ src/journal-remote/journal-upload.h \
+ src/journal-remote/journal-upload.c \
+ src/journal-remote/journal-upload-journal.c
+
+systemd_journal_upload_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(LIBCURL_CFLAGS)
+
+systemd_journal_upload_LDADD = \
+ libshared.la \
+ $(LIBCURL_LIBS)
+
+nodist_systemunit_DATA += \
+ units/systemd-journal-upload.service
+
+nodist_pkgsysconf_DATA += \
+ src/journal-remote/journal-upload.conf
+endif
+
+EXTRA_DIST += \
+ units/systemd-journal-upload.service.in \
+ src/journal-remote/journal-upload.conf.in
+
+#@src/grp-journal-remote/systemd-journal-remote/Makefile
if HAVE_MICROHTTPD
rootlibexec_PROGRAMS += \
systemd-journal-remote
@@ -4066,35 +4128,7 @@ EXTRA_DIST += \
src/journal-remote/log-generator.py
endif # HAVE_MICROHTTPD
-if HAVE_LIBCURL
-rootlibexec_PROGRAMS += \
- systemd-journal-upload
-
-systemd_journal_upload_SOURCES = \
- src/journal-remote/journal-upload.h \
- src/journal-remote/journal-upload.c \
- src/journal-remote/journal-upload-journal.c
-
-systemd_journal_upload_CFLAGS = \
- $(AM_CFLAGS) \
- $(LIBCURL_CFLAGS)
-
-systemd_journal_upload_LDADD = \
- libshared.la \
- $(LIBCURL_LIBS)
-
-nodist_systemunit_DATA += \
- units/systemd-journal-upload.service
-
-nodist_pkgsysconf_DATA += \
- src/journal-remote/journal-upload.conf
-endif # HAVE_LIBCURL
-
-EXTRA_DIST += \
- units/systemd-journal-upload.service.in \
- src/journal-remote/journal-upload.conf.in
-
-#@src/journal/Makefile
+#@src/grp-journal/journalctl/Makefile
# using _CFLAGS = in the conditional below would suppress AM_CFLAGS
journalctl_CFLAGS = \
$(AM_CFLAGS)
@@ -4118,6 +4152,7 @@ journalctl_LDADD += \
$(QRENCODE_LIBS)
endif # HAVE_QRENCODE
+#@src/grp-journal/Makefile
test_journal_SOURCES = \
src/journal/test-journal.c
@@ -4212,6 +4247,7 @@ test_audit_type_SOURCES = \
test_audit_type_LDADD = \
libjournal-core.la
+#@src/grp-journal/libjournal-core/Makefile
libjournal_core_la_SOURCES = \
src/journal/journald-kmsg.c \
src/journal/journald-kmsg.h \
@@ -4242,6 +4278,7 @@ libjournal_core_la_LIBADD = \
noinst_LTLIBRARIES += \
libjournal-core.la
+#@src/grp-journal/Makefile
journal-install-hook:
-$(MKDIR_P) $(DESTDIR)/var/log/journal
-chown 0:0 $(DESTDIR)/var/log/journal
@@ -4271,11 +4308,9 @@ catalog-remove-hook:
UNINSTALL_DATA_HOOKS += \
catalog-remove-hook
-manual_tests += \
- test-journal-enum
-
tests += \
test-journal \
+ test-journal-enum \
test-journal-send \
test-journal-syslog \
test-journal-match \
@@ -4321,7 +4356,9 @@ libsystemd_journal_internal_la_SOURCES = \
src/journal/mmap-cache.h \
src/journal/compress.c \
src/journal/audit-type.h \
- src/journal/audit-type.c
+ src/journal/audit-type.c \
+ src/shared/gcrypt-util.h \
+ src/shared/gcrypt-util.c
nodist_libsystemd_journal_internal_la_SOURCES = \
src/journal/audit_type-to-name.h
@@ -4369,7 +4406,7 @@ endif # HAVE_GCRYPT
noinst_LTLIBRARIES += \
libsystemd-journal-internal.la
-#@src/journal/Makefile
+#@src/grp-journal/systemd-journald/Makefile
rootlibexec_PROGRAMS += \
systemd-journald
@@ -4394,6 +4431,7 @@ dist_pkgsysconf_DATA += \
src/journal/journald.conf
dist_catalog_DATA = \
+ catalog/systemd.bg.catalog \
catalog/systemd.be.catalog \
catalog/systemd.be@latin.catalog \
catalog/systemd.fr.catalog \
@@ -4423,7 +4461,7 @@ EXTRA_DIST += \
gperf_gperf_sources += \
src/journal/journald-gperf.gperf
-# ------------------------------------------------------------------------------
+#@src/grp-journal-remote/systemd-journal-gatewayd/Makefile ---------------------
if HAVE_MICROHTTPD
gatewayddocumentrootdir=$(pkgdatadir)/gatewayd
@@ -4605,32 +4643,6 @@ EXTRA_DIST += \
src/vconsole/90-vconsole.rules.in \
units/systemd-vconsole-setup.service.in
-#@src/systemd-bootchart/Makefile -----------------------------------------------
-if ENABLE_BOOTCHART
-systemd_bootchart_SOURCES = \
- src/bootchart/bootchart.c \
- src/bootchart/bootchart.h \
- src/bootchart/store.c \
- src/bootchart/store.h \
- src/bootchart/svg.c \
- src/bootchart/svg.h
-
-systemd_bootchart_LDADD = \
- libshared.la
-
-rootlibexec_PROGRAMS += \
- systemd-bootchart
-
-dist_pkgsysconf_DATA += \
- src/bootchart/bootchart.conf
-
-nodist_systemunit_DATA += \
- units/systemd-bootchart.service
-endif # ENABLE_BOOTCHART
-
-EXTRA_DIST += \
- units/systemd-bootchart.service.in
-
#@src/systemd-quotacheck/Makefile ----------------------------------------------
if ENABLE_QUOTACHECK
rootlibexec_PROGRAMS += \
@@ -4815,7 +4827,7 @@ systemd_localed_SOURCES = \
systemd_localed_LDADD = \
libshared.la \
- $(XKBCOMMON_LIBS)
+ -ldl
systemd_localed_CFLAGS = \
$(AM_CFLAGS) \
@@ -4970,6 +4982,17 @@ EXTRA_DIST += \
units/systemd-timesyncd.service.in \
src/timesync/timesyncd.conf.in
+#@discard.mk -------------------------------------------------------------------
+test_nss_SOURCES = \
+ src/test/test-nss.c
+
+test_nss_LDADD = \
+ libsystemd-internal.la \
+ -ldl
+
+manual_tests += \
+ test-nss
+
#@src/nss-myhostname/Makefile --------------------------------------------------
if HAVE_MYHOSTNAME
libnss_myhostname_la_SOURCES = \
@@ -5011,7 +5034,9 @@ libmachine_core_la_SOURCES = \
src/machine/machine-dbus.c \
src/machine/machine-dbus.h \
src/machine/image-dbus.c \
- src/machine/image-dbus.h
+ src/machine/image-dbus.h \
+ src/machine/operation.c \
+ src/machine/operation.h
libmachine_core_la_LIBADD = \
libshared.la
@@ -5145,8 +5170,6 @@ systemd_pull_SOURCES = \
src/import/import-compress.h \
src/import/curl-util.c \
src/import/curl-util.h \
- src/import/aufs-util.c \
- src/import/aufs-util.h \
src/import/qcow2-util.c \
src/import/qcow2-util.h
@@ -5274,6 +5297,20 @@ EXTRA_DIST += \
#@src/grp-resolve/systemd-resolved/Makefile ------------------------------------
if ENABLE_RESOLVED
+basic_dns_sources = \
+ src/resolve/resolved-dns-dnssec.c \
+ src/resolve/resolved-dns-dnssec.h \
+ src/resolve/resolved-dns-packet.c \
+ src/resolve/resolved-dns-packet.h \
+ src/resolve/resolved-dns-rr.c \
+ src/resolve/resolved-dns-rr.h \
+ src/resolve/resolved-dns-answer.c \
+ src/resolve/resolved-dns-answer.h \
+ src/resolve/resolved-dns-question.c \
+ src/resolve/resolved-dns-question.h \
+ src/resolve/dns-type.c \
+ src/resolve/dns-type.h
+
systemd_resolved_SOURCES = \
src/resolve/resolved.c \
src/resolve/resolved-manager.c \
@@ -5293,14 +5330,7 @@ systemd_resolved_SOURCES = \
src/resolve/resolved-mdns.h \
src/resolve/resolved-mdns.c \
src/resolve/resolved-def.h \
- src/resolve/resolved-dns-rr.h \
- src/resolve/resolved-dns-rr.c \
- src/resolve/resolved-dns-question.h \
- src/resolve/resolved-dns-question.c \
- src/resolve/resolved-dns-answer.h \
- src/resolve/resolved-dns-answer.c \
- src/resolve/resolved-dns-packet.h \
- src/resolve/resolved-dns-packet.c \
+ $(basic_dns_sources) \
src/resolve/resolved-dns-query.h \
src/resolve/resolved-dns-query.c \
src/resolve/resolved-dns-synthesize.h \
@@ -5319,14 +5349,12 @@ systemd_resolved_SOURCES = \
src/resolve/resolved-dns-zone.c \
src/resolve/resolved-dns-stream.h \
src/resolve/resolved-dns-stream.c \
- src/resolve/resolved-dns-dnssec.h \
- src/resolve/resolved-dns-dnssec.c \
src/resolve/resolved-dns-trust-anchor.h \
src/resolve/resolved-dns-trust-anchor.c \
src/resolve/resolved-etc-hosts.h \
src/resolve/resolved-etc-hosts.c \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h
+ src/shared/gcrypt-util.c \
+ src/shared/gcrypt-util.h
nodist_systemd_resolved_SOURCES = \
src/resolve/dns_type-from-name.h \
@@ -5386,18 +5414,9 @@ lib_LTLIBRARIES += \
systemd_resolve_SOURCES = \
src/resolve/resolve-tool.c \
- src/resolve/resolved-dns-dnssec.c \
- src/resolve/resolved-dns-dnssec.h \
- src/resolve/resolved-dns-packet.c \
- src/resolve/resolved-dns-packet.h \
- src/resolve/resolved-dns-rr.c \
- src/resolve/resolved-dns-rr.h \
- src/resolve/resolved-dns-answer.c \
- src/resolve/resolved-dns-answer.h \
- src/resolve/resolved-dns-question.c \
- src/resolve/resolved-dns-question.h \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h
+ $(basic_dns_sources) \
+ src/shared/gcrypt-util.c \
+ src/shared/gcrypt-util.h
nodist_systemd_resolve_SOURCES = \
src/resolve/dns_type-from-name.h \
@@ -5409,27 +5428,57 @@ systemd_resolve_LDADD = \
bin_PROGRAMS += \
systemd-resolve
+dist_bashcompletion_data += \
+ shell-completion/bash/systemd-resolve
+
+dist_zshcompletion_data += \
+ shell-completion/zsh/_systemd-resolve
+
tests += \
- test-dns-domain \
+ test-dns-packet \
+ test-resolve-tables \
test-dnssec
manual_tests += \
test-dnssec-complex
+test_resolve_tables_SOURCES = \
+ src/resolve/test-resolve-tables.c \
+ src/resolve/dns_type-from-name.h \
+ src/resolve/dns_type-to-name.h \
+ $(basic_dns_sources) \
+ src/shared/test-tables.h
+
+test_resolve_tables_LDADD = \
+ libshared.la
+
+test_dns_packet_SOURCES = \
+ src/resolve/test-dns-packet.c \
+ $(basic_dns_sources)
+
+test_dns_packet_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DRESOLVE_TEST_DIR=\"$(abs_top_srcdir)/src/resolve/test-data\"
+
+test_dns_packet_LDADD = \
+ libshared.la
+
+EXTRA_DIST += \
+ src/resolve/test-data/_openpgpkey.fedoraproject.org.pkts \
+ src/resolve/test-data/fedoraproject.org.pkts \
+ src/resolve/test-data/gandi.net.pkts \
+ src/resolve/test-data/google.com.pkts \
+ src/resolve/test-data/root.pkts \
+ src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts \
+ src/resolve/test-data/teamits.com.pkts \
+ src/resolve/test-data/zbyszek@fedoraproject.org.pkts \
+ src/resolve/test-data/_443._tcp.fedoraproject.org.pkts \
+ src/resolve/test-data/kyhwana.org.pkts \
+ src/resolve/test-data/fake-caa.pkts
+
test_dnssec_SOURCES = \
src/resolve/test-dnssec.c \
- src/resolve/resolved-dns-packet.c \
- src/resolve/resolved-dns-packet.h \
- src/resolve/resolved-dns-rr.c \
- src/resolve/resolved-dns-rr.h \
- src/resolve/resolved-dns-answer.c \
- src/resolve/resolved-dns-answer.h \
- src/resolve/resolved-dns-question.c \
- src/resolve/resolved-dns-question.h \
- src/resolve/resolved-dns-dnssec.c \
- src/resolve/resolved-dns-dnssec.h \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h
+ $(basic_dns_sources)
test_dnssec_LDADD = \
libshared.la
@@ -5479,6 +5528,8 @@ libnetworkd_core_la_CFLAGS = \
libnetworkd_core_la_SOURCES = \
src/libsystemd-network/network-internal.h \
src/network/networkd.h \
+ src/network/networkd-conf.h \
+ src/network/networkd-conf.c \
src/network/networkd-link.h \
src/network/networkd-link.c \
src/network/networkd-netdev.h \
@@ -5522,9 +5573,12 @@ libnetworkd_core_la_SOURCES = \
src/network/networkd-address-pool.h \
src/network/networkd-address-pool.c \
src/network/networkd-util.h \
- src/network/networkd-util.c
+ src/network/networkd-util.c \
+ src/network/networkd-lldp-tx.h \
+ src/network/networkd-lldp-tx.c
nodist_libnetworkd_core_la_SOURCES = \
+ src/network/networkd-gperf.c \
src/network/networkd-network-gperf.c \
src/network/networkd-netdev-gperf.c
@@ -5563,6 +5617,12 @@ networkctl_LDADD = \
dist_bashcompletion_data += \
shell-completion/bash/networkctl
+test_networkd_conf_SOURCES = \
+ src/network/test-networkd-conf.c
+
+test_networkd_conf_LDADD = \
+ libnetworkd-core.la
+
test_network_SOURCES = \
src/network/test-network.c
@@ -5588,6 +5648,7 @@ test_network_tables_LDADD += \
endif # HAVE_LIBIPTC
tests += \
+ test-networkd-conf \
test-network \
test-network-tables
@@ -5621,6 +5682,7 @@ BUSNAMES_TARGET_WANTS += \
endif # ENABLE_NETWORKD
gperf_gperf_sources += \
+ src/network/networkd-gperf.gperf \
src/network/networkd-network-gperf.gperf \
src/network/networkd-netdev-gperf.gperf
@@ -5785,7 +5847,7 @@ dist_dbussystemservice_DATA += \
dist_dbuspolicy_DATA += \
src/login/org.freedesktop.login1.conf
-dist_pkgsysconf_DATA += \
+nodist_pkgsysconf_DATA += \
src/login/logind.conf
polkitpolicy_files += \
@@ -5822,7 +5884,8 @@ gperf_gperf_sources += \
EXTRA_DIST += \
src/login/71-seat.rules.in \
src/login/73-seat-late.rules.in \
- units/systemd-logind.service.in
+ units/systemd-logind.service.in \
+ src/login/logind.conf.in
# ------------------------------------------------------------------------------
if HAVE_PAM
@@ -5875,6 +5938,16 @@ EXTRA_DIST += \
test/TEST-07-ISSUE-1981/Makefile \
test/TEST-07-ISSUE-1981/test-segfault.sh \
test/TEST-07-ISSUE-1981/test.sh \
+ test/TEST-08-ISSUE-2730/Makefile \
+ test/TEST-08-ISSUE-2730/test.sh \
+ test/TEST-09-ISSUE-2691/Makefile \
+ test/TEST-09-ISSUE-2691/test.sh \
+ test/TEST-10-ISSUE-2467/Makefile \
+ test/TEST-10-ISSUE-2467/test.sh \
+ test/TEST-11-ISSUE-3166/Makefile \
+ test/TEST-11-ISSUE-3166/test.sh \
+ test/TEST-12-ISSUE-3171/Makefile \
+ test/TEST-12-ISSUE-3171/test.sh \
test/test-functions
EXTRA_DIST += \
@@ -5885,127 +5958,6 @@ EXTRA_DIST += \
test/loopy.service.d \
test/loopy.service.d/compat.conf
-#@src/libsystemd/compat-libs/Makefile ------------------------------------------
-if ENABLE_COMPAT_LIBS
-libsystemd-%.c: src/compat-libs/libsystemd-%.sym
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)sed -r -n 's/^ +(sd_.*);/obsolete_lib(\1,$(notdir $(basename $<)));/p' <$< >$@
-
-BUILT_SOURCES += \
- libsystemd-journal.c \
- libsystemd-login.c \
- libsystemd-id128.c \
- libsystemd-daemon.c
-
-nodist_libsystemd_journal_la_SOURCES = \
- libsystemd-journal.c
-
-libsystemd_journal_la_SOURCES = \
- src/compat-libs/libsystemd-journal.sym
-
-libsystemd_journal_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_journal_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \
- -Wl,--version-script=$(top_srcdir)/src/compat-libs/libsystemd-journal.sym
-
-libsystemd_journal_la_LIBADD = \
- libsystemd-journal-internal.la \
- libsystemd-internal.la
-
-nodist_libsystemd_login_la_SOURCES = \
- libsystemd-login.c
-
-libsystemd_login_la_SOURCES = \
- src/compat-libs/libsystemd-login.sym
-
-libsystemd_login_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_login_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_LOGIN_CURRENT):$(LIBSYSTEMD_LOGIN_REVISION):$(LIBSYSTEMD_LOGIN_AGE) \
- -Wl,--version-script=$(top_srcdir)/src/compat-libs/libsystemd-login.sym
-
-libsystemd_login_la_LIBADD = \
- libsystemd-internal.la
-
-nodist_libsystemd_id128_la_SOURCES = \
- libsystemd-id128.c
-
-libsystemd_id128_la_SOURCES = \
- src/compat-libs/libsystemd-id128.sym
-
-libsystemd_id128_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_id128_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \
- -Wl,--version-script=$(top_srcdir)/src/compat-libs/libsystemd-id128.sym
-
-libsystemd_id128_la_LIBADD = \
- libsystemd-internal.la
-
-nodist_libsystemd_daemon_la_SOURCES = \
- libsystemd-daemon.c
-
-libsystemd_daemon_la_SOURCES = \
- src/compat-libs/libsystemd-daemon.sym
-
-libsystemd_daemon_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_daemon_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \
- -Wl,--version-script=$(top_srcdir)/src/compat-libs/libsystemd-daemon.sym
-
-libsystemd_daemon_la_LIBADD = \
- libsystemd-internal.la
-
-lib_LTLIBRARIES += \
- libsystemd-journal.la \
- libsystemd-login.la \
- libsystemd-id128.la \
- libsystemd-daemon.la
-
-pkgconfiglib_DATA += \
- src/compat-libs/libsystemd-journal.pc \
- src/compat-libs/libsystemd-login.pc \
- src/compat-libs/libsystemd-id128.pc \
- src/compat-libs/libsystemd-daemon.pc
-
-# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
-compat-lib-install-hook:
- libname=libsystemd-login.so && $(move-to-rootlibdir)
- libname=libsystemd-journal.so && $(move-to-rootlibdir)
- libname=libsystemd-id128.so && $(move-to-rootlibdir)
- libname=libsystemd-daemon.so && $(move-to-rootlibdir)
-
-compat-lib-uninstall-hook:
- rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so*
- rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so*
- rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so*
- rm -f $(DESTDIR)$(rootlibdir)/libsystemd-daemon.so*
-
-INSTALL_EXEC_HOOKS += compat-lib-install-hook
-UNINSTALL_EXEC_HOOKS += compat-lib-uninstall-hook
-endif # ENABLE_COMPAT_LIBS
-
-EXTRA_DIST += \
- src/compat-libs/linkwarning.h \
- src/compat-libs/libsystemd-journal.pc.in \
- src/compat-libs/libsystemd-login.pc.in \
- src/compat-libs/libsystemd-id128.pc.in \
- src/compat-libs/libsystemd-daemon.pc.in
-
#@build-aux/Makefile.once.head/20-systemd.mk -----------------------------------
substitutions = \
'|rootlibexecdir=$(rootlibexecdir)|' \
@@ -6059,6 +6011,8 @@ substitutions = \
'|PYTHON=$(PYTHON)|' \
'|NTP_SERVERS=$(NTP_SERVERS)|' \
'|DNS_SERVERS=$(DNS_SERVERS)|' \
+ '|DEFAULT_DNSSEC_MODE=$(DEFAULT_DNSSEC_MODE)|' \
+ '|KILL_USER_PROCESSES=$(KILL_USER_PROCESSES)|' \
'|systemuidmax=$(SYSTEM_UID_MAX)|' \
'|systemgidmax=$(SYSTEM_GID_MAX)|' \
'|TTY_GID=$(TTY_GID)|' \
@@ -6369,7 +6323,6 @@ DISTCHECK_CONFIGURE_FLAGS += \
endif # ENABLE_SPLIT_USR
.PHONY: dist-check-help
-
dist-check-help: $(rootbin_PROGRAMS) $(bin_PROGRAMS)
for i in $(abspath $^); do \
if $$i --help | grep -v 'default:' | grep -E -q '.{80}.' ; then \
@@ -6378,6 +6331,18 @@ dist-check-help: $(rootbin_PROGRAMS) $(bin_PROGRAMS)
exit 1; \
fi; done
+include_compilers = "$(CC)" "$(CC) -ansi" "$(CC) -std=iso9899:1990"
+public_headers = $(filter-out src/systemd/_sd-common.h, $(pkginclude_HEADERS) $(include_HEADERS))
+.PHONY: dist-check-includes
+dist-check-includes: $(public_headers)
+ @res=0; \
+ for i in $(abspath $^); do \
+ for cc in $(include_compilers); do \
+ echo "$$cc -o/dev/null -c -x c -include "$$i" - </dev/null"; \
+ $$cc -o/dev/null -c -x c -include "$$i" - </dev/null || res=1; \
+ done; \
+ done; exit $$res
+
#@hwdb/Makefile
.PHONY: hwdb-update
hwdb-update:
diff --git a/NEWS b/NEWS
index e7f6bb4593..7c3f99d31c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,27 +1,261 @@
systemd System and Service Manager
+CHANGES WITH 230:
+
+ * DNSSEC is now turned on by default in systemd-resolved (in
+ "allow-downgrade" mode), but may be turned off during compile time by
+ passing "--with-default-dnssec=no" to "configure" (and of course,
+ during runtime with DNSSEC= in resolved.conf). We recommend
+ downstreams to leave this on at least during development cycles and
+ report any issues with the DNSSEC logic upstream. We are very
+ interested in collecting feedback about the DNSSEC validator and its
+ limitations in the wild. Note however, that DNSSEC support is
+ probably nothing downstreams should turn on in stable distros just
+ yet, as it might create incompatibilities with a few DNS servers and
+ networks. We tried hard to make sure we downgrade to non-DNSSEC mode
+ automatically whenever we detect such incompatible setups, but there
+ might be systems we do not cover yet. Hence: please help us testing
+ the DNSSEC code, leave this on where you can, report back, but then
+ again don't consider turning this on in your stable, LTS or
+ production release just yet. (Note that you have to enable
+ nss-resolve in /etc/nsswitch.conf, to actually use systemd-resolved
+ and its DNSSEC mode for host name resolution from local
+ applications.)
+
+ * systemd-resolve conveniently resolves DANE records with the --tlsa
+ option and OPENPGPKEY records with the --openpgp option. It also
+ supports dumping raw DNS record data via the new --raw= switch.
+
+ * systemd-logind will now by default terminate user processes that are
+ part of the user session scope unit (session-XX.scope) when the user
+ logs out. This behavior is controlled by the KillUserProcesses=
+ setting in logind.conf, and the previous default of "no" is now
+ changed to "yes". This means that user sessions will be properly
+ cleaned up after, but additional steps are necessary to allow
+ intentionally long-running processes to survive logout.
+
+ While the user is logged in at least once, user@.service is running,
+ and any service that should survive the end of any individual login
+ session can be started at a user service or scope using systemd-run.
+ systemd-run(1) man page has been extended with an example which shows
+ how to run screen in a scope unit underneath user@.service. The same
+ command works for tmux.
+
+ After the user logs out of all sessions, user@.service will be
+ terminated too, by default, unless the user has "lingering" enabled.
+ To effectively allow users to run long-term tasks even if they are
+ logged out, lingering must be enabled for them. See loginctl(1) for
+ details. The default polkit policy was modified to allow users to
+ set lingering for themselves without authentication.
+
+ Previous defaults can be restored at compile time by the
+ --without-kill-user-processes option to "configure".
+
+ * systemd-logind gained new configuration settings SessionsMax= and
+ InhibitorsMax=, both with a default of 8192. It will not register new
+ user sessions or inhibitors above this limit.
+
+ * systemd-logind will now reload configuration on SIGHUP.
+
+ * The unified cgroup hierarchy added in Linux 4.5 is now supported.
+ Use systemd.unified_cgroup_hierarchy=1 on the kernel command line to
+ enable. Also, support for the "io" cgroup controller in the unified
+ hierarchy has been added, so that the "memory", "pids" and "io" are
+ now the controllers that are supported on the unified hierarchy.
+
+ WARNING: it is not possible to use previous systemd versions with
+ systemd.unified_cgroup_hierarchy=1 and the new kernel. Therefore it
+ is necessary to also update systemd in the initramfs if using the
+ unified hierarchy. An updated SELinux policy is also required.
+
+ * LLDP support has been extended, and both passive (receive-only) and
+ active (sender) modes are supported. Passive mode ("routers-only") is
+ enabled by default in systemd-networkd. Active LLDP mode is enabled
+ by default for containers on the internal network. The "networkctl
+ lldp" command may be used to list information gathered. "networkctl
+ status" will also show basic LLDP information on connected peers now.
+
+ * The IAID and DUID unique identifier sent in DHCP requests may now be
+ configured for the system and each .network file managed by
+ systemd-networkd using the DUIDType=, DUIDRawData=, IAID= options.
+
+ * systemd-networkd gained support for configuring proxy ARP support for
+ each interface, via the ProxyArp= setting in .network files. It also
+ gained support for configuring the multicast querier feature of
+ bridge devices, via the new MulticastQuerier= setting in .netdev
+ files. Similarly, snooping on the IGMP traffic can be controlled
+ via the new setting MulticastSnooping=.
+
+ A new setting PreferredLifetime= has been added for addresses
+ configured in .network file to configure the lifetime intended for an
+ address.
+
+ The systemd-networkd DHCP server gained the option EmitRouter=, which
+ defaults to yes, to configure whether the DHCP Option 3 (Router)
+ should be emitted.
+
+ * The testing tool /usr/lib/systemd/systemd-activate is renamed to
+ systemd-socket-activate and installed into /usr/bin. It is now fully
+ supported.
+
+ * systemd-journald now uses separate threads to flush changes to disk
+ when closing journal files, thus reducing impact of slow disk I/O on
+ logging performance.
+
+ * The sd-journal API gained two new calls
+ sd_journal_open_directory_fd() and sd_journal_open_files_fd() which
+ can be used to open journal files using file descriptors instead of
+ file or directory paths. sd_journal_open_container() has been
+ deprecated, sd_journal_open_directory_fd() should be used instead
+ with the flag SD_JOURNAL_OS_ROOT.
+
+ * journalctl learned a new output mode "-o short-unix" that outputs log
+ lines prefixed by their UNIX time (i.e. seconds since Jan 1st, 1970
+ UTC). It also gained support for a new --no-hostname setting to
+ suppress the hostname column in the family of "short" output modes.
+
+ * systemd-ask-password now optionally skips printing of the password to
+ stdout with --no-output which can be useful in scripts.
+
+ * Framebuffer devices (/dev/fb*) and 3D printers and scanners
+ (devices tagged with ID_MAKER_TOOL) are now tagged with
+ "uaccess" and are available to logged in users.
+
+ * The DeviceAllow= unit setting now supports specifiers (with "%").
+
+ * "systemctl show" gained a new --value switch, which allows print a
+ only the contents of a specific unit property, without also printing
+ the property's name. Similar support was added to "show*" verbs
+ of loginctl and machinectl that output "key=value" lists.
+
+ * A new unit type "generated" was added for files dynamically generated
+ by generator tools. Similarly, a new unit type "transient" is used
+ for unit files created using the runtime API. "systemctl enable" will
+ refuse to operate on such files.
+
+ * A new command "systemctl revert" has been added that may be used to
+ revert to the vendor version of a unit file, in case local changes
+ have been made by adding drop-ins or overriding the unit file.
+
+ * "machinectl clean" gained a new verb to automatically remove all or
+ just hidden container images.
+
+ * systemd-tmpfiles gained support for a new line type "e" for emptying
+ directories, if they exist, without creating them if they don't.
+
+ * systemd-nspawn gained support for automatically patching the UID/GIDs
+ of the owners and the ACLs of all files and directories in a
+ container tree to match the UID/GID user namespacing range selected
+ for the container invocation. This mode is enabled via the new
+ --private-user-chown switch. It also gained support for automatically
+ choosing a free, previously unused UID/GID range when starting a
+ container, via the new --private-users=pick setting (which implies
+ --private-user-chown). Together, these options for the first time
+ make user namespacing for nspawn containers fully automatic and thus
+ deployable. The systemd-nspaw@.service template unit file has been
+ changed to use this functionality by default.
+
+ * systemd-nspawn gained a new --network-zone= switch, that allows
+ creating ad-hoc virtual Ethernet links between multiple containers,
+ that only exist as long as at least one container referencing them is
+ running. This allows easy connecting of multiple containers with a
+ common link that implements an Ethernet broadcast domain. Each of
+ these network "zones" may be named relatively freely by the user, and
+ may be referenced by any number of containers, but each container may
+ only reference one of these "zones". On the lower level, this is
+ implemented by an automatically managed bridge network interface for
+ each zone, that is created when the first container referencing its
+ zone is created and removed when the last one referencing its zone
+ terminates.
+
+ * The default start timeout may now be configured on the kernel command
+ line via systemd.default_timeout_start_sec=. It was already
+ configurable via the DefaultTimeoutStartSec= option in
+ /etc/systemd/system.conf.
+
+ * Socket units gained a new TriggerLimitIntervalSec= and
+ TriggerLimitBurst= setting to configure a limit on the activation
+ rate of the socket unit.
+
+ * The LimitNICE= setting now optionally takes normal UNIX nice values
+ in addition to the raw integer limit value. If the specified
+ parameter is prefixed with "+" or "-" and is in the range -20..19 the
+ value is understood as UNIX nice value. If not prefixed like this it
+ is understood as raw RLIMIT_NICE limit.
+
+ * Note that the effect of the PrivateDevices= unit file setting changed
+ slightly with this release: the per-device /dev file system will be
+ mounted read-only from this version on, and will have "noexec"
+ set. This (minor) change of behavior might cause some (exceptional)
+ legacy software to break, when PrivateDevices=yes is set for its
+ service. Please leave PrivateDevices= off if you run into problems
+ with this.
+
+ * systemd-bootchart has been split out to a separate repository:
+ https://github.com/systemd/systemd-bootchart
+
+ * systemd-bus-proxyd has been removed, as kdbus is unlikely to still be
+ merged into the kernel in its current form.
+
+ * The compatibility libraries libsystemd-daemon.so,
+ libsystemd-journal.so, libsystemd-id128.so, and libsystemd-login.so
+ which have been deprecated since systemd-209 have been removed along
+ with the corresponding pkg-config files. All symbols provided by
+ those libraries are provided by libsystemd.so.
+
+ * The Capabilities= unit file setting has been removed (it is ignored
+ for backwards compatibility). AmbientCapabilities= and
+ CapabilityBoundingSet= should be used instead.
+
+ Contributions from: Alban Crequy, Alexander Kuleshov, Alexander Shopov,
+ Alex Crawford, Andre Klärner, Andrew Eikum, Beniamino Galvani, Benjamin
+ Robin, Biao Lu, Bjørnar Ness, Calvin Owens, Christian Hesse, Clemens
+ Gruber, Colin Guthrie, Daniel Drake, Daniele Medri, Daniel J Walsh,
+ Daniel Mack, Dan Nicholson, daurnimator, David Herrmann, David
+ R. Hedges, Elias Probst, Emmanuel Gil Peyrot, EMOziko, Evgeny
+ Vereshchagin, Federico, Felipe Sateler, Filipe Brandenburger, Franck
+ Bui, frankheckenbach, gdamjan, Georgia Brikis, Harald Hoyer, Hendrik
+ Brueckner, Hristo Venev, Iago López Galeiras, Ian Kelling, Ismo
+ Puustinen, Jakub Wilk, Jaroslav Škarvada, Jeff Huang, Joel Holdsworth,
+ John Paul Adrian Glaubitz, Jonathan Boulle, kayrus, Klearchos
+ Chaloulos, Kyle Russell, Lars Uebernickel, Lennart Poettering, Lubomir
+ Rintel, Lukáš Nykrýn, Mantas Mikulėnas, Marcel Holtmann, Martin Pitt,
+ Michael Biebl, michaelolbrich, Michał Bartoszkiewicz, Michal Koutný,
+ Michal Sekletar, Mike Frysinger, Mike Gilbert, Mingcong Bai, Ming Lin,
+ mulkieran, muzena, Nalin Dahyabhai, Naohiro Aota, Nathan McSween,
+ Nicolas Braud-Santoni, Patrik Flykt, Peter Hutterer, Peter Mattern,
+ Petr Lautrbach, Petros Angelatos, Piotr Drąg, Rabin Vincent, Robert
+ Węcławski, Ronny Chevalier, Samuel Tardieu, Stefan Saraev, Stefan
+ Schallenberg aka nafets227, Steven Siloti, Susant Sahani, Sylvain
+ Plantefève, Taylor Smock, Tejun Heo, Thomas Blume, Thomas Haller,
+ Thomas H. P. Andersen, Tobias Klauser, Tom Gundersen, topimiettinen,
+ Torstein Husebø, Umut Tezduyar Lindskog, Uwe Kleine-König, Victor Toso,
+ Vinay Kulkarni, Vito Caputo, Vittorio G (VittGam), Vladimir Panteleev,
+ Wieland Hoffmann, Wouter Verhelst, Yu Watanabe, Zbigniew
+ Jędrzejewski-Szmek
+
+ — Fairfax, 2016-05-21
+
CHANGES WITH 229:
* The systemd-resolved DNS resolver service has gained a substantial
set of new features, most prominently it may now act as a DNSSEC
validating stub resolver. DNSSEC mode is currently turned off by
- default, but it is expected that this is turned on by default in one
- of the next releases. For now, we invite everybody to test the DNSSEC
- logic by setting DNSSEC=allow-downgrade in
- /etc/systemd/resolved.conf. The service also gained a full set of
- D-Bus interfaces, including calls to configure DNS and DNSSEC
- settings per link (for consumption by external network management
- software). systemd-resolved (and systemd-networkd along with it) now
- know to distinguish between "search" and "routing" domains. The
- former are used to qualify single-label names, the latter are purely
- used for routing lookups within certain domains to specific
- links. resolved will now also synthesize RRs for all entries from
- /etc/hosts.
+ default, but is expected to be turned on by default in one of the
+ next releases. For now, we invite everybody to test the DNSSEC logic
+ by setting DNSSEC=allow-downgrade in /etc/systemd/resolved.conf. The
+ service also gained a full set of D-Bus interfaces, including calls
+ to configure DNS and DNSSEC settings per link (for use by external
+ network management software). systemd-resolved and systemd-networkd
+ now distinguish between "search" and "routing" domains. The former
+ are used to qualify single-label names, the latter are used purely
+ for routing lookups within certain domains to specific links.
+ resolved now also synthesizes RRs for all entries from /etc/hosts.
* The systemd-resolve tool (which is a client utility for
- systemd-resolved, and previously experimental) has been improved
- considerably and is now fully supported and documented. Hence it has
- moved from /usr/lib/systemd to /usr/bin.
+ systemd-resolved) has been improved considerably and is now fully
+ supported and documented. Hence it has moved from /usr/lib/systemd to
+ /usr/bin.
* /dev/disk/by-path/ symlink support has been (re-)added for virtio
devices.
@@ -80,22 +314,22 @@ CHANGES WITH 229:
* systemd-nspawn gained a new --as-pid2 switch that invokes any
specified command line as PID 2 rather than PID 1 in the
- container. In this mode PID 1 will be a minimal stub init process
- that implements the special POSIX and Linux semantics of PID 1
- regarding signal and child process management. Note that this stub
- init process is implemented in nspawn itself and requires no support
- from the container image. This new logic is useful to support running
- arbitrary command lines in the container, as normal processes are
+ container. In this mode PID 1 is a minimal stub init process that
+ implements the special POSIX and Linux semantics of PID 1 regarding
+ signal and child process management. Note that this stub init process
+ is implemented in nspawn itself and requires no support from the
+ container image. This new logic is useful to support running
+ arbitrary commands in the container, as normal processes are
generally not prepared to run as PID 1.
* systemd-nspawn gained a new --chdir= switch for setting the current
working directory for the process started in the container.
- * "journalctl /dev/sda" will now output all kernel log messages from
- the specified device, in addition to all devices that are parents of
- it. This should make log output about devices pretty useful, as long
- as kernel drivers attach enough metadata to the log messages. (The
- usual SATA drivers do.)
+ * "journalctl /dev/sda" will now output all kernel log messages for
+ specified device from the current boot, in addition to all devices
+ that are parents of it. This should make log output about devices
+ pretty useful, as long as kernel drivers attach enough metadata to
+ the log messages. (The usual SATA drivers do.)
* The sd-journal API gained two new calls
sd_journal_has_runtime_files() and sd_journal_has_persistent_files()
@@ -125,7 +359,7 @@ CHANGES WITH 229:
in addition to timesyncd during early boot-up, so that it is enforced
before the first process is spawned by systemd. Note that the logic
in timesyncd remains, as it is more comprehensive and ensures
- montonic clocks by maintaining a persistant timestamp file in
+ clock monotonicity by maintaining a persistent timestamp file in
/var. Since /var is generally not available in earliest boot or the
initrd, this part of the logic remains in timesyncd, and is not done
by PID 1.
@@ -154,18 +388,18 @@ CHANGES WITH 229:
to configure hard and soft limits individually.
* The various libsystemd APIs such as sd-bus or sd-event now publicly
- expose support for gcc's __attribute__((cleanup())) C
- extension. Specifically, for many object destructor functions
- alternative versions whose names are suffixed with "p" have been
- added, which take a pointer to a pointer to the object to destroy,
- instead of just a pointer to the object itself. This is useful because
- these destructor functions may be used directly as parameters to the
- cleanup construct. Internally, systemd has been a heavy user of the
- GCC extension since a long time, and with this change similar support
- is now available to consumers of the library outside of systemd. Note
+ expose support for gcc's __attribute__((cleanup())) C extension.
+ Specifically, for many object destructor functions alternative
+ versions have been added that have names suffixed with "p" and take a
+ pointer to a pointer to the object to destroy, instead of just a
+ pointer to the object itself. This is useful because these destructor
+ functions may be used directly as parameters to the cleanup
+ construct. Internally, systemd has been a heavy user of this GCC
+ extension for a long time, and with this change similar support is
+ now available to consumers of the library outside of systemd. Note
that by using this extension in your sources compatibility with old
- and strictly ANSI compatible C compilers is lost. However, any gcc or
- LLVM version of recent years have supported this extension.
+ and strictly ANSI compatible C compilers is lost. However, all gcc or
+ LLVM versions of recent years support this extension.
* Timer units gained support for a new setting RandomizedDelaySec= that
allows configuring some additional randomized delay to the configured
@@ -217,7 +451,7 @@ CHANGES WITH 229:
Andersen, Tom Gundersen, Torstein Husebø, Umut Tezduyar Lindskog, Vito
Caputo, WaLyong Cho, Yu Watanabe, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2016-02-11
+ — Berlin, 2016-02-11
CHANGES WITH 228:
@@ -348,6 +582,9 @@ CHANGES WITH 228:
https://sourceware.org/bugzilla/show_bug.cgi?id=19108
+ Note that only util-linux versions built with
+ --enable-libmount-force-mountinfo are supported.
+
* Support for the ".snapshot" unit type has been removed. This
feature turned out to be little useful and little used, and
has now been removed from the core and from systemctl.
@@ -415,7 +652,7 @@ CHANGES WITH 228:
Tom Gundersen, Torstein Husebø, Vito Caputo, Zbigniew
Jędrzejewski-Szmek
- -- Berlin, 2015-11-18
+ — Berlin, 2015-11-18
CHANGES WITH 227:
@@ -619,7 +856,7 @@ CHANGES WITH 227:
Andersen, Tom Gundersen, Tom Lyon, Viktar Vauchkevich,
Zbigniew Jędrzejewski-Szmek, Марко М. Костић
- -- Berlin, 2015-10-07
+ — Berlin, 2015-10-07
CHANGES WITH 226:
@@ -739,7 +976,7 @@ CHANGES WITH 226:
Hack, Susant Sahani, Sylvain Pasche, Thomas Hindoe Paaboel
Andersen, Tom Gundersen, Torstein Husebø
- -- Berlin, 2015-09-08
+ — Berlin, 2015-09-08
CHANGES WITH 225:
@@ -812,7 +1049,7 @@ CHANGES WITH 225:
Paaboel Andersen, Thomas Meyer, Tom Gundersen, Vincent Batts,
WaLyong Cho, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2015-08-27
+ — Berlin, 2015-08-27
CHANGES WITH 224:
@@ -827,7 +1064,7 @@ CHANGES WITH 224:
Herrmann, Herman Fries, Johannes Nixdorf, Kay Sievers, Lennart
Poettering, Peter Hutterer, Susant Sahani, Tom Gundersen
- -- Berlin, 2015-07-31
+ — Berlin, 2015-07-31
CHANGES WITH 223:
@@ -892,7 +1129,7 @@ CHANGES WITH 223:
Gundersen, Torstein Husebø, Umut Tezduyar Lindskog, Vito Caputo,
Vivenzio Pagliari, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2015-07-29
+ — Berlin, 2015-07-29
CHANGES WITH 222:
@@ -932,7 +1169,7 @@ CHANGES WITH 222:
Susant Sahani, Thomas Hindoe Paaboel Andersen, Tom Gundersen, Torstein
Husebø, Vedran Miletić, WaLyong Cho, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2015-07-07
+ — Berlin, 2015-07-07
CHANGES WITH 221:
@@ -1010,7 +1247,7 @@ CHANGES WITH 221:
Husebø, Umut Tezduyar Lindskog, Viktar Vauchkevich, Werner
Fink, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2015-06-19
+ — Berlin, 2015-06-19
CHANGES WITH 220:
@@ -1239,7 +1476,7 @@ CHANGES WITH 220:
Gundersen, Torstein Husebø, Umut Tezduyar Lindskog, Will
Woods, Zachary Cook, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2015-05-22
+ — Berlin, 2015-05-22
CHANGES WITH 219:
@@ -1324,7 +1561,7 @@ CHANGES WITH 219:
* machinectl is now able to clone container images
efficiently, if the underlying file system (btrfs) supports
- it, with the new "machinectl list-images" command. It also
+ it, with the new "machinectl clone" command. It also
gained commands for renaming and removing images, as well as
marking them read-only or read-write (supported also on
legacy file systems).
@@ -1563,7 +1800,7 @@ CHANGES WITH 219:
Lindskog, Veres Lajos, Vincent Batts, WaLyong Cho, Wieland
Hoffmann, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2015-02-16
+ — Berlin, 2015-02-16
CHANGES WITH 218:
@@ -1765,7 +2002,7 @@ CHANGES WITH 218:
Torstein Husebø, Umut Tezduyar Lindskog, Vicente Olivert
Riera, WaLyong Cho, Wesley Dawson, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2014-12-10
+ — Berlin, 2014-12-10
CHANGES WITH 217:
@@ -1977,7 +2214,7 @@ CHANGES WITH 217:
Husebø, Umut Tezduyar Lindskog, WaLyong Cho, Zbigniew
Jędrzejewski-Szmek
- -- Berlin, 2014-10-28
+ — Berlin, 2014-10-28
CHANGES WITH 216:
@@ -2179,7 +2416,7 @@ CHANGES WITH 216:
Tobias Geerinckx-Rice, Tomasz Torcz, Tom Gundersen, Umut
Tezduyar Lindskog, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2014-08-19
+ — Berlin, 2014-08-19
CHANGES WITH 215:
@@ -2413,7 +2650,7 @@ CHANGES WITH 215:
Paaboel Andersen, Tom Gundersen, Tom Hirst, Umut Tezduyar
Lindskog, Uoti Urpala, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2014-07-03
+ — Berlin, 2014-07-03
CHANGES WITH 214:
@@ -2607,7 +2844,7 @@ CHANGES WITH 214:
Andersen, Tom Gundersen, Umut Tezduyar Lindskog, Zbigniew
Jędrzejewski-Szmek
- -- Berlin, 2014-06-11
+ — Berlin, 2014-06-11
CHANGES WITH 213:
@@ -2739,7 +2976,7 @@ CHANGES WITH 213:
Lindskog, WaLyong Cho, Will Woods, Zbigniew
Jędrzejewski-Szmek
- -- Beijing, 2014-05-28
+ — Beijing, 2014-05-28
CHANGES WITH 212:
@@ -2888,7 +3125,7 @@ CHANGES WITH 212:
Umut Tezduyar Lindskog, Wieland Hoffmann, Zbigniew
Jędrzejewski-Szmek
- -- Berlin, 2014-03-25
+ — Berlin, 2014-03-25
CHANGES WITH 211:
@@ -3012,7 +3249,7 @@ CHANGES WITH 211:
Gundersen, Umut Tezduyar Lindskog, Uoti Urpala, Zachary Cook,
Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2014-03-12
+ — Berlin, 2014-03-12
CHANGES WITH 210:
@@ -3117,7 +3354,7 @@ CHANGES WITH 210:
Paaboel Andersen, Tom Gundersen, Umut Tezduyar Lindskog,
Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2014-02-24
+ — Berlin, 2014-02-24
CHANGES WITH 209:
@@ -3573,7 +3810,7 @@ CHANGES WITH 209:
Pavlín, Vincent Batts, WaLyong Cho, William Giokas, Yang
Zhiyong, Yin Kangkai, Yuxuan Shui, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2014-02-20
+ — Berlin, 2014-02-20
CHANGES WITH 208:
@@ -3660,7 +3897,7 @@ CHANGES WITH 208:
Michael Scherer, Michał Górny, Mike Gilbert, Patrick McCarty,
Sebastian Ott, Tom Gundersen, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2013-10-02
+ — Berlin, 2013-10-02
CHANGES WITH 207:
@@ -3760,7 +3997,7 @@ CHANGES WITH 207:
Paaboel Andersen, Tom Gundersen, Umut Tezduyar, WANG Chao,
William Giokas, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2013-09-13
+ — Berlin, 2013-09-13
CHANGES WITH 206:
@@ -3859,14 +4096,14 @@ CHANGES WITH 206:
Thomas H.P. Andersen, Tom Gundersen, Tomasz Torcz, William
Giokas, Zbigniew Jędrzejewski-Szmek
- -- Berlin, 2013-07-23
+ — Berlin, 2013-07-23
CHANGES WITH 205:
* Two new unit types have been introduced:
Scope units are very similar to service units, however, are
- created out of pre-existing processes -- instead of PID 1
+ created out of pre-existing processes — instead of PID 1
forking off the processes. By using scope units it is
possible for system services and applications to group their
own child processes (worker processes) in a powerful way
diff --git a/README b/README
index 0a2c0df47d..ca8993cb12 100644
--- a/README
+++ b/README
@@ -35,7 +35,7 @@ LICENSE:
- except src/udev/* which is (currently still) GPLv2, GPLv2+
REQUIREMENTS:
- Linux kernel >= 3.11
+ Linux kernel >= 3.12
Linux kernel >= 4.2 for unified cgroup hierarchy support
Kernel Config Options:
@@ -88,10 +88,6 @@ REQUIREMENTS:
Required for CPUQuota= in resource control unit settings
CONFIG_CFS_BANDWIDTH
- For systemd-bootchart, several proc debug interfaces are required:
- CONFIG_SCHEDSTATS
- CONFIG_SCHED_DEBUG
-
For UEFI systems:
CONFIG_EFIVAR_FS
CONFIG_EFI_PARTITION
@@ -122,6 +118,7 @@ REQUIREMENTS:
glibc >= 2.16
libcap
libmount >= 2.27.1 (from util-linux)
+ (util-linux *must* be built with --enable-libmount-force-mountinfo)
libseccomp >= 1.0.0 (optional)
libblkid >= 2.24 (from util-linux) (optional)
libkmod >= 15 (optional)
@@ -200,9 +197,6 @@ USERS AND GROUPS:
Similarly, the name resolution daemon requires the
"systemd-resolve" system user and group to exist.
- Similarly, the kdbus dbus1 proxy daemon requires the
- "systemd-bus-proxy" system user and group to exist.
-
Similarly, the coredump support requires the
"systemd-coredump" system user and group to exist.
diff --git a/README.md b/README.md
index dcd14ba94f..dc628e8003 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Information about build requirements are provided in the [README file](../master
Consult our [NEWS file](../master/NEWS) for information about what's new in the most recent systemd versions.
-Please see our [Contribution Guidelines](../master/CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests.
+Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests.
When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/CODING_STYLE).
diff --git a/TODO b/TODO
index 7437938bf0..fac9ccf0ed 100644
--- a/TODO
+++ b/TODO
@@ -33,15 +33,55 @@ Janitorial Clean-ups:
Features:
+* make sure bash completion uses journalctl --fields to get fields list
+
+* use phyical_memory() to allow MemoryLimit= configuration based on available system memory
+
+* ProtectKernelLogs= (drops CAP_SYSLOG, add seccomp for syslog() syscall, and DeviceAllow to /dev/kmsg) in service files
+
+* ProtectClock= (drops CAP_SYS_TIMES, adds seecomp filters for settimeofday, adjtimex), sets DeviceAllow o /dev/rtc
+
+* ProtectMount= (drop mount/umount/pivot_root from seccomp, disallow fuse via DeviceAllow, imply Mountflags=slave)
+
+* ProtectDevices= should also take iopl/ioperm/pciaccess away
+
+* ProtectKeyRing= to take keyring calls away
+
+* RestrictNamespaces= or so in services (taking away the ability to create namespaces, with setns, unshare, clone)
+
+* IAID field must move from [Link] to [DHCP] section in .network files
+
+* make sure the ratelimit object can deal with USEC_INFINITY as way to turn off things
+
+* journalctl: make sure -f ends when the container indicated by -M terminates
+
+* rework fopen_temporary() to make use of open_tmpfile_linkable() (problem: the
+ kernel doesn't support linkat() that replaces existing files, currently)
+
+* check if DeviceAllow= should split first, resolve specifiers later
+
+* transient units: don't bother with actually setting unit properties, we
+ reload the unit file anyway
+
+* make sure resolved can be restarted without losing pushed-in dns config
+
+* journald: sigbus API via a signal-handler safe function that people may call
+ from the SIGBUS handler
+
+* when using UTF8, ellipsize with "…" rather than "...", so that we can show more contents before truncating
+
+* move specifier expansion from service_spawn() into load-fragment.c
+
+* optionally, also require WATCHDOG=1 notifications during service start-up and shutdown
+
+* resolved: maybe, after all, implement local listening for DNS packets on port
+ 127.0.0.53:53.
+
* delay activation of logind until somebody logs in, or when /dev/tty0 pulls it
in or lingering is on (so that containers don't bother with it until PAM is used). also exit-on-idle
* cache sd_event_now() result from before the first iteration...
-* remove Capabilities=, after all AmbientCapabilities= and CapabilityBoundingSet= should be enough.
-
-* support for the new copy_file_range() syscall
-
* add systemctl stop --job-mode=triggering that follows TRIGGERED_BY deps and adds them to the same transaction
* Maybe add a way how users can "pin" units into memory, so that they are not subject to automatic GC?
@@ -49,11 +89,9 @@ Features:
* PID1: find a way how we can reload unit file configuration for
specific units only, without reloading the whole of systemd
-* add an explicit parser for LimitNICE= and LimitRTPRIO= that verifies
+* add an explicit parser for LimitRTPRIO= that verifies
the specified range and generates sane error messages for incorrect
- specifications. Also, for LimitNICE= maybe introduce a syntax such
- as "+5" or "-7" in order to make the limits more readable as they
- are otherwise shifted by 20.
+ specifications.
* do something about "/control" subcgroups in the unified cgroup hierarchy
@@ -61,12 +99,6 @@ Features:
* push CPUAffinity= also into the "cpuset" cgroup controller (only after the cpuset controller got ported to the unified hierarchy)
-* add a new command "systemctl revert" or so, that removes all dropin
- snippets in /run and /etc, and all unit files with counterparts in
- /usr, and thus undoes what "systemctl set-property" and "systemctl
- edit" create. Maybe even add "systemctl revert -a" to do this for
- all units.
-
* PID 1 should send out sd_notify("WATCHDOG=1") messages (for usage in the --user mode, and when run via nspawn)
* consider throwing a warning if a service declares it wants to be "Before=" a .device unit.
@@ -80,9 +112,6 @@ Features:
* install: include generator dirs in unit file search paths
-* rework C11 utf8.[ch] to use char32_t instead of uint32_t when referring
- to unicode chars, to make things more expressive.
-
* fstab-generator: default to tmpfs-as-root if only usr= is specified on the kernel cmdline
* docs: bring http://www.freedesktop.org/wiki/Software/systemd/MyServiceCantGetRealtime up to date
@@ -112,7 +141,8 @@ Features:
* implement a per-service firewall based on net_cls
-* Port various tools to make use of verbs.[ch], where applicable
+* Port various tools to make use of verbs.[ch], where applicable: busctl,
+ bootctl, coredumpctl, hostnamectl, localectl, systemd-analyze, timedatectl
* hostnamectl: show root image uuid
@@ -132,8 +162,6 @@ Features:
* as soon as we have kdbus, and sender timestamps, revisit coalescing multiple parallel daemon reloads:
http://lists.freedesktop.org/archives/systemd-devel/2014-December/025862.html
-* the install state probably shouldn't get confused by generated units, think dbus1/kdbus compat!
-
* in systemctl list-unit-files: show the install value the presets would suggest for a service in a third column
* figure out when we can use the coarse timers
@@ -145,8 +173,6 @@ Features:
* firstboot: make it useful to be run immediately after yum --installroot to set up a machine. (most specifically, make --copy-root-password work even if /etc/passwd already exists
-* add infrastructure to allocate dynamic/transient users and UID ranges, for use in user-namespaced containers, per-seat gdm login screens and gdm guest sessions
-
* maybe add support for specifier expansion in user.conf, specifically DefaultEnvironment=
* introduce systemd-timesync-wait.service or so to sync on an NTP fix?
@@ -233,7 +259,7 @@ Features:
CAP_NET_ADMIN is set, more than the loopback device is defined, even
when it is otherwise off
-* MessageQueueMessageSize= and RLimitFSIZE= (and suchlike) should use parse_iec_size().
+* MessageQueueMessageSize= (and suchlike) should use parse_iec_size().
* "busctl status" works only as root on dbus1, since we cannot read
/proc/$PID/exe
@@ -248,7 +274,7 @@ Features:
and passes this back to PID1 via SCM_RIGHTS. This also could be used
to allow Chown/chgrp on sockets without requiring NSS in PID 1.
-* New service property: maximum CPU and wallclock runtime for a service
+* New service property: maximum CPU runtime for a service
* introduce bus call FreezeUnit(s, b), as well as "systemctl freeze
$UNIT" and "systemctl thaw $UNIT" as wrappers around this. The calls
@@ -278,8 +304,6 @@ Features:
* be more careful what we export on the bus as (usec_t) 0 and (usec_t) -1
-* unify dispatch table in systemctl_main() and friends
-
* rfkill,backlight: we probably should run the load tools inside of the udev rules so that the state is properly initialized by the time other software sees it
* After coming back from hibernation reset hibernation swap partition using the /dev/snapshot ioctl APIs
@@ -321,10 +345,6 @@ Features:
- path escaping
- update systemd.special(7) to mention that dbus.socket is only about the compatibility socket now
- test bloom filter generation indexes
- - bus-proxy: when passing messages from kdbus, make sure we properly
- handle the case where a large number of fds is appended that we
- cannot pass into sendmsg() of the AF_UNIX sokcet (which only accepts
- 253 messages)
- kdbus: introduce a concept of "send-only" connections
- kdbus: add counter for refused unicast messages that is passed out via the RECV ioctl. SImilar to the counter for dropped multicast messages we already have.
@@ -374,7 +394,7 @@ Features:
* systemd-inhibit: make taking delay locks useful: support sending SIGINT or SIGTERM on PrepareForSleep()
-* remove any syslog support from log.c -- we probably cannot do this before split-off udev is gone for good
+* remove any syslog support from log.c — we probably cannot do this before split-off udev is gone for good
* shutdown logging: store to EFI var, and store to USB stick?
@@ -494,8 +514,6 @@ Features:
written to as FAIL, but instead show that their are being written to.
- add journalctl -H that talks via ssh to a remote peer and passes through
binary logs data
- - change journalctl -M to acquire fd to journal directory via machined, and
- then operate on that via openat() instead of absolute paths
- add a version of --merge which also merges /var/log/journal/remote
- log accumulated resource usage after each service invocation
- journalctl: -m should access container journals directly by enumerating
@@ -534,7 +552,6 @@ Features:
* unit install:
- "systemctl mask" should find all names by which a unit is accessible
(i.e. by scanning for symlinks to it) and link them all to /dev/null
- - systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so)
* timer units:
- timer units should get the ability to trigger when:
@@ -561,8 +578,6 @@ Features:
- to allow "linking" of nspawn containers, extend --network-bridge= so
that it can dynamically create bridge interfaces that are refcounted
by the containers on them. For each group of containers to link together
- - refuses to boot containers without /etc/machine-id (OK?), and with empty
- /etc/machine-id (not OK).
- nspawn -x should support ephemeral instances of gpt images
- emulate /dev/kmsg using CUSE and turn off the syslog syscall
with seccomp. That should provide us with a useful log buffer that
@@ -583,8 +598,6 @@ Features:
- should send out sd_notify("WATCHDOG=1") messages
- optionally automatically add FORWARD rules to iptables whenever nspawn is
running, remove them when shut down.
- - add a logic for cleaning up read-only, hidden container images in
- /var/lib/machines that are not ancestors of any non-hidden containers
- Improve error message when --bind= is used on a non-existing source
directory
- maybe make copying of /etc/resolv.conf optional, and skip it if --read-only
@@ -628,8 +641,6 @@ Features:
* initialize the hostname from the fs label of /, if /etc/hostname does not exist?
-* rename "userspace" to "core-os"
-
* udev:
- move to LGPL
- kill scsi_id
@@ -744,17 +755,6 @@ Features:
- Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
- consider adding RuntimeDirectoryUser= + RuntimeDirectoryGroup=
-* systemd-python:
- - figure out a simple way to wait for journal events in a way that
- works with ^C
- - add documentation to systemd.daemon
-
-* bootchart:
- - plot per-process IO utilization
- - group processes based on service association (cgroups)
- - document initcall_debug
- - kernel cmdline "bootchart" option for simplicity?
-
* udev-link-config:
- Make sure ID_PATH is always exported and complete for
network devices where possible, so we can safely rely
@@ -776,7 +776,6 @@ Features:
- work with non-Ethernet devices
- add support for more bond options
- dhcp: do we allow configuring dhcp routes on interfaces that are not the one we got the dhcp info from?
- - add LLDP client side support
- the DHCP lease data (such as NTP/DNS) is still made available when
a carrier is lost on a link. It should be removed instantly.
- expose in the API the following bits:
diff --git a/autogen.sh b/autogen.sh
index 607a9682dd..3a0695816e 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -55,16 +55,16 @@ fi
cd $oldpwd
if [ "x$1" = "xc" ]; then
- $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
+ $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
make clean
elif [ "x$1" = "xg" ]; then
- $topdir/configure CFLAGS='-g -Og -ftrapv' --enable-compat-libs --enable-kdbus $args
+ $topdir/configure CFLAGS='-g -Og -ftrapv' --enable-kdbus $args
make clean
elif [ "x$1" = "xa" ]; then
- $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-compat-libs --enable-kdbus $args
+ $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-kdbus $args
make clean
elif [ "x$1" = "xl" ]; then
- $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
+ $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
make clean
elif [ "x$1" = "xs" ]; then
scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' --enable-kdbus $args
@@ -75,6 +75,6 @@ else
echo "Initialized build system. For a common configuration please run:"
echo "----------------------------------------------------------------"
echo
- echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args"
+ echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args"
echo
fi
diff --git a/build-aux/Makefile.once.head/20-systemd.mk b/build-aux/Makefile.once.head/20-systemd.mk
index 6f9d23dc5a..9939919f5e 100644
--- a/build-aux/Makefile.once.head/20-systemd.mk
+++ b/build-aux/Makefile.once.head/20-systemd.mk
@@ -166,6 +166,8 @@ substitutions = \
'|PYTHON=$(PYTHON)|' \
'|NTP_SERVERS=$(NTP_SERVERS)|' \
'|DNS_SERVERS=$(DNS_SERVERS)|' \
+ '|DEFAULT_DNSSEC_MODE=$(DEFAULT_DNSSEC_MODE)|' \
+ '|KILL_USER_PROCESSES=$(KILL_USER_PROCESSES)|' \
'|systemuidmax=$(SYSTEM_UID_MAX)|' \
'|systemgidmax=$(SYSTEM_GID_MAX)|' \
'|TTY_GID=$(TTY_GID)|' \
diff --git a/coccinelle/strjoina.cocci b/coccinelle/strjoina.cocci
new file mode 100644
index 0000000000..a6236eb0f9
--- /dev/null
+++ b/coccinelle/strjoina.cocci
@@ -0,0 +1,6 @@
+@@
+expression n, m;
+expression list s;
+@@
+- n = strjoina(m, s, NULL);
++ n = strjoina(m, s);
diff --git a/configure.ac b/configure.ac
index 0d0c55a0d2..86bb2f10cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
AC_PREREQ([2.64])
AC_INIT([systemd],
- [229],
+ [230],
[http://github.com/systemd/systemd/issues],
[systemd],
[http://www.freedesktop.org/wiki/Software/systemd])
@@ -300,11 +300,20 @@ CAP_LIBS="$LIBS"
LIBS="$save_LIBS"
AC_SUBST(CAP_LIBS)
-AC_CHECK_FUNCS([memfd_create])
AC_CHECK_FUNCS([__secure_getenv secure_getenv])
-AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renameat2,
- kcmp, keyctl, key_serial_t, char16_t, char32_t, LO_FLAGS_PARTSCAN],
- [], [], [[
+AC_CHECK_DECLS([
+ memfd_create,
+ gettid,
+ pivot_root,
+ name_to_handle_at,
+ setns,
+ getrandom,
+ renameat2,
+ kcmp,
+ keyctl,
+ LO_FLAGS_PARTSCAN,
+ copy_file_range],
+ [], [], [[
#include <sys/types.h>
#include <unistd.h>
#include <sys/mount.h>
@@ -314,6 +323,11 @@ AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renamea
#include <linux/random.h>
]])
+AC_CHECK_TYPES([char16_t, char32_t, key_serial_t],
+ [], [], [[
+#include <uchar.h>
+]])
+
AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
IFLA_MACVLAN_FLAGS,
IFLA_IPVLAN_MODE,
@@ -325,8 +339,9 @@ AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
IFLA_IPTUN_ENCAP_DPORT,
IFLA_GRE_ENCAP_DPORT,
IFLA_BRIDGE_VLAN_INFO,
+ IFLA_BRPORT_PROXYARP,
IFLA_BRPORT_LEARNING_SYNC,
- IFLA_BR_PRIORITY,
+ IFLA_BR_VLAN_DEFAULT_PVID,
NDA_IFINDEX,
IFA_FLAGS],
[], [], [[
@@ -368,17 +383,6 @@ AS_IF([test "x$have_utmp" = "xyes"], [AC_DEFINE(HAVE_UTMP, 1, [Define if utmp/wt
AM_CONDITIONAL([HAVE_UTMP], [test "x$have_utmp" = "xyes"])
# ------------------------------------------------------------------------------
-have_compat_libs=no
-AC_ARG_ENABLE([compat_libs], AS_HELP_STRING([--enable-compat-libs],[Enable creation of compatibility libraries]),
- [case "${enableval}" in
- yes) have_compat_libs=yes ;;
- no) have_compat_libs=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-compat-libs) ;;
- esac],
- [have_compat_libs=no])
-AM_CONDITIONAL([ENABLE_COMPAT_LIBS], [test "$have_compat_libs" = "yes"])
-
-# ------------------------------------------------------------------------------
have_coverage=no
AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage], [enable test coverage]))
if test "x$enable_coverage" = "xyes" ; then
@@ -508,6 +512,22 @@ if test "x$enable_apparmor" != "xno"; then
fi
AM_CONDITIONAL(HAVE_APPARMOR, [test "$have_apparmor" = "yes"])
+have_adm_group=no
+AC_ARG_ENABLE(adm-group, AS_HELP_STRING([--disable-adm-group], [disable adm group]))
+AS_IF([test "x$enable_adm_group" != "xno"], [
+ AC_DEFINE(ENABLE_ADM_GROUP, 1, [Define if the ACL for adm group should be enabled])
+ have_adm_group=yes
+ M4_DEFINES="$M4_DEFINES -DENABLE_ADM_GROUP"
+])
+
+have_wheel_group=no
+AC_ARG_ENABLE(wheel-group, AS_HELP_STRING([--disable-wheel-group], [disable wheel group]))
+AS_IF([test "x$enable_wheel_group" != "xno"], [
+ AC_DEFINE(ENABLE_WHEEL_GROUP, 1, [Define if the ACL for wheel group should be enabled])
+ have_wheel_group=yes
+ M4_DEFINES="$M4_DEFINES -DENABLE_WHEEL_GROUP"
+])
+
AC_ARG_WITH(debug-shell,
AS_HELP_STRING([--with-debug-shell=PATH],
@@ -882,7 +902,7 @@ AM_CONDITIONAL(HAVE_MICROHTTPD, [test "$have_microhttpd" = "yes"])
have_libcurl=no
AC_ARG_ENABLE(libcurl, AS_HELP_STRING([--disable-libcurl], [disable libcurl support]))
if test "x$enable_libcurl" != "xno"; then
- PKG_CHECK_MODULES(LIBCURL, [libcurl],
+ PKG_CHECK_MODULES(LIBCURL, [libcurl >= 7.32.0],
[AC_DEFINE(HAVE_LIBCURL, 1, [Define if libcurl is available])
have_libcurl=yes
M4_DEFINES="$M4_DEFINES -DHAVE_LIBCURL"],
@@ -943,14 +963,6 @@ fi
AM_CONDITIONAL(ENABLE_VCONSOLE, [test "$have_vconsole" = "yes"])
# ------------------------------------------------------------------------------
-have_bootchart=no
-AC_ARG_ENABLE(bootchart, AS_HELP_STRING([--disable-bootchart], [disable bootchart tool]))
-if test "x$enable_bootchart" != "xno"; then
- have_bootchart=yes
-fi
-AM_CONDITIONAL(ENABLE_BOOTCHART, [test "$have_bootchart" = "yes"])
-
-# ------------------------------------------------------------------------------
have_quotacheck=no
AC_ARG_ENABLE(quotacheck, AS_HELP_STRING([--disable-quotacheck], [disable quotacheck tools]))
if test "x$enable_quotacheck" != "xno"; then
@@ -1015,14 +1027,24 @@ fi
AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"])
AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_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])])
+AS_IF([test "$with_kill_user_processes" != "no"],
+ [kill_user_processes=true
+ KILL_USER_PROCESSES=yes],
+ [kill_user_processes=false
+ KILL_USER_PROCESSES=no])
+AC_DEFINE_UNQUOTED(KILL_USER_PROCESSES, [$kill_user_processes], [Default KillUserProcesses setting])
+AC_SUBST(KILL_USER_PROCESSES)
+
# ------------------------------------------------------------------------------
have_machined=no
AC_ARG_ENABLE(machined, AS_HELP_STRING([--disable-machined], [disable machine daemon]))
if test "x$enable_machined" != "xno"; then
have_machined=yes
+ AC_DEFINE(HAVE_MACHINED, [1], [systemd-machined is enabled])
fi
AM_CONDITIONAL(ENABLE_MACHINED, [test "$have_machined" = "yes"])
-AS_IF([test "$have_machined" = "yes"], [ AC_DEFINE(HAVE_MACHINED, [1], [Machined support available]) ])
# ------------------------------------------------------------------------------
have_importd=no
@@ -1132,6 +1154,7 @@ AS_IF([test "x$enable_resolved" != "xno"], [
have_resolved=yes
M4_DEFINES="$M4_DEFINES -DENABLE_RESOLVED"
+ AC_DEFINE(HAVE_RESOLVED, [1], [systemd-resolved is enabled])
])
AM_CONDITIONAL(ENABLE_RESOLVED, [test "$have_resolved" = "yes"])
@@ -1144,6 +1167,20 @@ AC_ARG_WITH(dns-servers,
AC_DEFINE_UNQUOTED(DNS_SERVERS, ["$DNS_SERVERS"], [Default DNS Servers])
AC_SUBST(DNS_SERVERS)
+AC_ARG_WITH(default-dnssec,
+ AS_HELP_STRING([--with-default-dnssec=MODE],
+ [Default DNSSEC mode, defaults to "allow-downgrade"]),
+ [DEFAULT_DNSSEC_MODE="$withval"],
+ [DEFAULT_DNSSEC_MODE="allow-downgrade"])
+
+AS_CASE("x${DEFAULT_DNSSEC_MODE}",
+ [xno], [mode=DNSSEC_NO],
+ [xyes], [mode=DNSSEC_YES],
+ [xallow-downgrade], [mode=DNSSEC_ALLOW_DOWNGRADE],
+ AC_MSG_ERROR(Bad DNSSEC mode ${DEFAULT_DNSSEC_MODE}))
+AC_DEFINE_UNQUOTED(DEFAULT_DNSSEC_MODE, [$mode], [Default DNSSEC mode])
+AC_SUBST(DEFAULT_DNSSEC_MODE)
+
# ------------------------------------------------------------------------------
have_networkd=no
AC_ARG_ENABLE(networkd, AS_HELP_STRING([--disable-networkd], [disable networkd]))
@@ -1223,6 +1260,28 @@ AS_IF([test "x$enable_gnuefi" != "xno"], [
AM_CONDITIONAL(HAVE_GNUEFI, [test "x$have_gnuefi" = xyes])
# ------------------------------------------------------------------------------
+have_tpm=no
+AC_ARG_ENABLE([tpm], AS_HELP_STRING([--enable-tpm],[Enable optional TPM support]),
+ [case "${enableval}" in
+ yes) have_tpm=yes ;;
+ no) have_tpm=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-tpm) ;;
+ esac],
+ [have_tpm=no])
+
+if test "x${have_tpm}" != xno ; then
+ AC_DEFINE(SD_BOOT_LOG_TPM, 1, [Define if TPM should be used to log events and extend the registers])
+fi
+
+AC_ARG_WITH(tpm-pcrindex,
+ AS_HELP_STRING([--with-tpm-pcrindex=<NUM>],
+ [TPM PCR register number to use]),
+ [SD_TPM_PCR="$withval"],
+ [SD_TPM_PCR="8"])
+
+AC_DEFINE_UNQUOTED(SD_TPM_PCR, [$SD_TPM_PCR], [TPM PCR register number to use])
+
+# ------------------------------------------------------------------------------
have_kdbus=no
AC_ARG_ENABLE(kdbus, AS_HELP_STRING([--disable-kdbus], [do not connect to kdbus by default]))
if test "x$enable_kdbus" != "xno"; then
@@ -1297,6 +1356,7 @@ if test "x$enable_myhostname" != "xno"; then
AC_CHECK_FUNCS([gethostbyaddr gethostbyname gettimeofday inet_ntoa memset select socket strcspn strdup strerror strncasecmp strcasecmp strspn])
have_myhostname=yes
+ AC_DEFINE(HAVE_MYHOSTNAME, [1], [nss-myhostname is enabled])
fi
AM_CONDITIONAL(HAVE_MYHOSTNAME, [test "$have_myhostname" = "yes"])
@@ -1463,9 +1523,10 @@ AS_IF([test x"$cross_compiling" = "xyes"], [], [
])
AC_ARG_ENABLE(tests,
- [AC_HELP_STRING([--disable-tests], [disable tests])],
+ [AC_HELP_STRING([--disable-tests], [disable tests, or enable extra tests with =unsafe])],
enable_tests=$enableval, enable_tests=yes)
-AM_CONDITIONAL(ENABLE_TESTS, [test x$enable_tests = xyes])
+AM_CONDITIONAL(ENABLE_TESTS, [test x$enable_tests = xyes -o x$enable_tests = xunsafe])
+AM_CONDITIONAL(ENABLE_UNSAFE_TESTS, [test x$enable_tests = xunsafe])
AC_ARG_ENABLE(debug,
[AC_HELP_STRING([--enable-debug@<:@=LIST@:>@], [enable extra debugging (hashmap,mmap-cache)])],
@@ -1529,104 +1590,108 @@ fi
AC_MSG_RESULT([
$PACKAGE_NAME $VERSION
- libcryptsetup: ${have_libcryptsetup}
- PAM: ${have_pam}
- AUDIT: ${have_audit}
- IMA: ${have_ima}
- AppArmor: ${have_apparmor}
- SELinux: ${have_selinux}
- SECCOMP: ${have_seccomp}
- SMACK: ${have_smack}
- ZLIB: ${have_zlib}
- XZ: ${have_xz}
- LZ4: ${have_lz4}
- BZIP2: ${have_bzip2}
- ACL: ${have_acl}
- GCRYPT: ${have_gcrypt}
- QRENCODE: ${have_qrencode}
- MICROHTTPD: ${have_microhttpd}
- GNUTLS: ${have_gnutls}
- libcurl: ${have_libcurl}
- libidn: ${have_libidn}
- libiptc: ${have_libiptc}
- ELFUTILS: ${have_elfutils}
- binfmt: ${have_binfmt}
- vconsole: ${have_vconsole}
- bootchart: ${have_bootchart}
- quotacheck: ${have_quotacheck}
- tmpfiles: ${have_tmpfiles}
- sysusers: ${have_sysusers}
- firstboot: ${have_firstboot}
- randomseed: ${have_randomseed}
- backlight: ${have_backlight}
- rfkill: ${have_rfkill}
- logind: ${have_logind}
- machined: ${have_machined}
- importd: ${have_importd}
- hostnamed: ${have_hostnamed}
- timedated: ${have_timedated}
- timesyncd: ${have_timesyncd}
- default NTP servers: ${NTP_SERVERS}
- time epoch: ${TIME_EPOCH}
- localed: ${have_localed}
- networkd: ${have_networkd}
- resolved: ${have_resolved}
- default DNS servers: ${DNS_SERVERS}
- coredump: ${have_coredump}
- polkit: ${have_polkit}
- efi: ${have_efi}
- gnuefi: ${have_gnuefi}
- efi arch: ${EFI_ARCH}
- EFI machine type: ${EFI_MACHINE_TYPE_NAME}
- EFI CC ${EFI_CC}
- EFI libdir: ${EFI_LIB_DIR}
- EFI ldsdir: ${EFI_LDS_DIR}
- EFI includedir: ${EFI_INC_DIR}
- kmod: ${have_kmod}
- xkbcommon: ${have_xkbcommon}
- blkid: ${have_blkid}
- libmount: ${have_libmount}
- dbus: ${have_dbus}
- nss-myhostname: ${have_myhostname}
- hwdb: ${enable_hwdb}
- kdbus: ${have_kdbus}
- Python: ${have_python}
- man pages: ${have_manpages}
- test coverage: ${have_coverage}
- Split /usr: ${enable_split_usr}
- SysV compatibility: ${SYSTEM_SYSV_COMPAT}
- compatibility libraries: ${have_compat_libs}
- utmp/wtmp support: ${have_utmp}
- ldconfig support: ${enable_ldconfig}
- hibernate support: ${enable_hibernate}
- extra debugging: ${enable_debug}
-
- prefix: ${prefix}
- rootprefix: ${with_rootprefix}
- sysconf dir: ${sysconfdir}
- datarootdir: ${datarootdir}
- includedir: ${includedir}
- lib dir: ${libdir}
- rootlib dir: ${with_rootlibdir}
- SysV init scripts: ${SYSTEM_SYSVINIT_PATH}
- SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH}
- Build Python: ${PYTHON}
- PAM modules dir: ${with_pamlibdir}
- PAM configuration dir: ${with_pamconfdir}
- D-Bus policy dir: ${with_dbuspolicydir}
- D-Bus session dir: ${with_dbussessionservicedir}
- D-Bus system dir: ${with_dbussystemservicedir}
- Bash completions dir: ${with_bashcompletiondir}
- Zsh completions dir: ${with_zshcompletiondir}
- Extra start script: ${RC_LOCAL_SCRIPT_PATH_START}
- Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP}
- Debug shell: ${SUSHELL} @ ${DEBUGTTY}
- TTY GID: ${TTY_GID}
- Maximum System UID: ${SYSTEM_UID_MAX}
- Maximum System GID: ${SYSTEM_GID_MAX}
- Certificate root: ${CERTIFICATEROOT}
-
- CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
- CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
- LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
+ libcryptsetup: ${have_libcryptsetup}
+ PAM: ${have_pam}
+ AUDIT: ${have_audit}
+ IMA: ${have_ima}
+ AppArmor: ${have_apparmor}
+ SELinux: ${have_selinux}
+ SECCOMP: ${have_seccomp}
+ SMACK: ${have_smack}
+ ZLIB: ${have_zlib}
+ XZ: ${have_xz}
+ LZ4: ${have_lz4}
+ BZIP2: ${have_bzip2}
+ ACL: ${have_acl}
+ GCRYPT: ${have_gcrypt}
+ QRENCODE: ${have_qrencode}
+ MICROHTTPD: ${have_microhttpd}
+ GNUTLS: ${have_gnutls}
+ libcurl: ${have_libcurl}
+ libidn: ${have_libidn}
+ libiptc: ${have_libiptc}
+ ELFUTILS: ${have_elfutils}
+ binfmt: ${have_binfmt}
+ vconsole: ${have_vconsole}
+ quotacheck: ${have_quotacheck}
+ tmpfiles: ${have_tmpfiles}
+ sysusers: ${have_sysusers}
+ firstboot: ${have_firstboot}
+ randomseed: ${have_randomseed}
+ backlight: ${have_backlight}
+ rfkill: ${have_rfkill}
+ logind: ${have_logind}
+ Default KillUserProcesses setting: ${KILL_USER_PROCESSES}
+ machined: ${have_machined}
+ importd: ${have_importd}
+ hostnamed: ${have_hostnamed}
+ timedated: ${have_timedated}
+ timesyncd: ${have_timesyncd}
+ Default NTP servers: ${NTP_SERVERS}
+ time epoch: ${TIME_EPOCH}
+ localed: ${have_localed}
+ networkd: ${have_networkd}
+ resolved: ${have_resolved}
+ Default DNS servers: ${DNS_SERVERS}
+ Default DNSSEC mode: ${DEFAULT_DNSSEC_MODE}
+ coredump: ${have_coredump}
+ polkit: ${have_polkit}
+ efi: ${have_efi}
+ gnuefi: ${have_gnuefi}
+ efi arch: ${EFI_ARCH}
+ EFI machine type: ${EFI_MACHINE_TYPE_NAME}
+ EFI CC ${EFI_CC}
+ EFI libdir: ${EFI_LIB_DIR}
+ EFI ldsdir: ${EFI_LDS_DIR}
+ EFI includedir: ${EFI_INC_DIR}
+ kmod: ${have_kmod}
+ xkbcommon: ${have_xkbcommon}
+ blkid: ${have_blkid}
+ libmount: ${have_libmount}
+ dbus: ${have_dbus}
+ nss-myhostname: ${have_myhostname}
+ hwdb: ${enable_hwdb}
+ tpm: ${have_tpm}
+ kdbus: ${have_kdbus}
+ Python: ${have_python}
+ man pages: ${have_manpages}
+ test coverage: ${have_coverage}
+ Split /usr: ${enable_split_usr}
+ SysV compatibility: ${SYSTEM_SYSV_COMPAT}
+ utmp/wtmp support: ${have_utmp}
+ ldconfig support: ${enable_ldconfig}
+ hibernate support: ${enable_hibernate}
+ extra debugging: ${enable_debug}
+ tests: ${enable_tests}
+
+ prefix: ${prefix}
+ rootprefix: ${with_rootprefix}
+ sysconf dir: ${sysconfdir}
+ datarootdir: ${datarootdir}
+ includedir: ${includedir}
+ lib dir: ${libdir}
+ rootlib dir: ${with_rootlibdir}
+ SysV init scripts: ${SYSTEM_SYSVINIT_PATH}
+ SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH}
+ Build Python: ${PYTHON}
+ PAM modules dir: ${with_pamlibdir}
+ PAM configuration dir: ${with_pamconfdir}
+ D-Bus policy dir: ${with_dbuspolicydir}
+ D-Bus session dir: ${with_dbussessionservicedir}
+ D-Bus system dir: ${with_dbussystemservicedir}
+ Bash completions dir: ${with_bashcompletiondir}
+ Zsh completions dir: ${with_zshcompletiondir}
+ Extra start script: ${RC_LOCAL_SCRIPT_PATH_START}
+ Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP}
+ Adm group: ${have_adm_group}
+ Wheel group: ${have_wheel_group}
+ Debug shell: ${SUSHELL} @ ${DEBUGTTY}
+ TTY GID: ${TTY_GID}
+ Maximum System UID: ${SYSTEM_UID_MAX}
+ Maximum System GID: ${SYSTEM_GID_MAX}
+ Certificate root: ${CERTIFICATEROOT}
+
+ CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
+ CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
+ LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
])
diff --git a/discard.mk b/discard.mk
index 5854d519f3..3faf228b6c 100644
--- a/discard.mk
+++ b/discard.mk
@@ -57,8 +57,12 @@ TEST_EXTENSIONS = .py
PY_LOG_COMPILER = $(PYTHON)
DISABLE_HARD_ERRORS = yes
ifneq ($(ENABLE_TESTS),)
-noinst_PROGRAMS = $(manual_tests) $(tests)
+noinst_PROGRAMS = $(manual_tests) $(tests) $(unsafe_tests)
TESTS = $(tests)
+ifneq ($(ENABLE_UNSAFE_TESTS),)
+TESTS += \
+ $(unsafe_tests)
+endif
else
noinst_PROGRAMS =
TESTS =
@@ -290,7 +294,6 @@ libexec_PROGRAMS = \
systemd-ac-power \
systemd-sysctl \
systemd-sleep \
- systemd-bus-proxyd \
systemd-socket-proxyd \
systemd-update-done
@@ -361,6 +364,7 @@ dist_systemunit_DATA = \
units/local-fs-pre.target \
units/initrd.target \
units/initrd-fs.target \
+ units/initrd-root-device.target \
units/initrd-root-fs.target \
units/remote-fs.target \
units/remote-fs-pre.target \
@@ -756,8 +760,10 @@ endif # HAVE_SYSV_COMPAT
endif # HAVE_PYTHON
endif # ENABLE_TESTS
+tests += \
+ test-libudev
+
manual_tests += \
- test-libudev \
test-udev
test_libudev_SOURCES = \
@@ -780,9 +786,11 @@ check_DATA += \
endif # ENABLE_TESTS
# packed sysfs test tree
-$(outdir)/sys:
+$(outdir)/sys: test/sys.tar.xz
+ -rm -rf test/sys
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)tar -C test/ -xJf $(top_srcdir)/test/sys.tar.xz
+ -touch test/sys
test-sys-distclean:
-rm -rf test/sys
@@ -795,6 +803,16 @@ EXTRA_DIST += \
test/sysv-generator-test.py \
test/mocks/fsck
+test_nss_SOURCES = \
+ src/test/test-nss.c
+
+test_nss_LDADD = \
+ libsystemd-internal.la \
+ -ldl
+
+manual_tests += \
+ test-nss
+
EXTRA_DIST += \
test/Makefile \
test/README.testsuite \
@@ -822,6 +840,16 @@ EXTRA_DIST += \
test/TEST-07-ISSUE-1981/Makefile \
test/TEST-07-ISSUE-1981/test-segfault.sh \
test/TEST-07-ISSUE-1981/test.sh \
+ test/TEST-08-ISSUE-2730/Makefile \
+ test/TEST-08-ISSUE-2730/test.sh \
+ test/TEST-09-ISSUE-2691/Makefile \
+ test/TEST-09-ISSUE-2691/test.sh \
+ test/TEST-10-ISSUE-2467/Makefile \
+ test/TEST-10-ISSUE-2467/test.sh \
+ test/TEST-11-ISSUE-3166/Makefile \
+ test/TEST-11-ISSUE-3166/test.sh \
+ test/TEST-12-ISSUE-3171/Makefile \
+ test/TEST-12-ISSUE-3171/test.sh \
test/test-functions
EXTRA_DIST += \
@@ -1109,7 +1137,6 @@ DISTCHECK_CONFIGURE_FLAGS += \
endif # ENABLE_SPLIT_USR
.PHONY: dist-check-help
-
dist-check-help: $(bin_PROGRAMS) $(bin_PROGRAMS)
for i in $(abspath $^); do \
if $$i --help | grep -v 'default:' | grep -E -q '.{80}.' ; then \
@@ -1118,6 +1145,18 @@ dist-check-help: $(bin_PROGRAMS) $(bin_PROGRAMS)
exit 1; \
fi; done
+include_compilers = "$(CC)" "$(CC) -ansi" "$(CC) -std=iso9899:1990"
+public_headers = $(filter-out src/systemd/_sd-common.h, $(pkginclude_HEADERS) $(include_HEADERS))
+.PHONY: dist-check-includes
+dist-check-includes: $(public_headers)
+ @res=0; \
+ for i in $(abspath $^); do \
+ for cc in $(include_compilers); do \
+ echo "$$cc -o/dev/null -c -x c -include "$$i" - </dev/null"; \
+ $$cc -o/dev/null -c -x c -include "$$i" - </dev/null || res=1; \
+ done; \
+ done; exit $$res
+
.PHONY: built-sources
built-sources: $(BUILT_SOURCES)
diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb
index 80f1890714..d852e7b8b3 100644
--- a/hwdb/20-OUI.hwdb
+++ b/hwdb/20-OUI.hwdb
@@ -11,9 +11,6 @@ OUI:70B3D5913*
OUI:70B3D588A*
ID_OUI_FROM_DATABASE=Perceptics, LLC
-OUI:70B3D5FFE*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D5001*
ID_OUI_FROM_DATABASE=SOREDI touch systems GmbH
@@ -293,9 +290,6 @@ OUI:70B3D5417*
OUI:70B3D5CF6*
ID_OUI_FROM_DATABASE=Tornado Modular Systems
-OUI:70B3D5186*
- ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex
-
OUI:70B3D591E*
ID_OUI_FROM_DATABASE=Creotech Instruments S.A.
@@ -365,9 +359,6 @@ OUI:70B3D5EFE*
OUI:70B3D5C60*
ID_OUI_FROM_DATABASE=Aircell Inc
-OUI:70B3D565A*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D5C03*
ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
@@ -848,6 +839,108 @@ OUI:001BC5087*
OUI:70B3D5720*
ID_OUI_FROM_DATABASE=Private
+OUI:70B3D56BF*
+ ID_OUI_FROM_DATABASE=Otto Bihler Maschinenfabrik GmbH & Co. KG
+
+OUI:70B3D5194*
+ ID_OUI_FROM_DATABASE=Husty M.Styczen J.Hupert Sp.J.
+
+OUI:70B3D5742*
+ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd
+
+OUI:70B3D5493*
+ ID_OUI_FROM_DATABASE=Impulse Networks Pte Ltd
+
+OUI:70B3D5BB7*
+ ID_OUI_FROM_DATABASE=Innoflight, Inc.
+
+OUI:70B3D5B31*
+ ID_OUI_FROM_DATABASE=Qwave Inc
+
+OUI:70B3D5DA8*
+ ID_OUI_FROM_DATABASE=Tagarno AS
+
+OUI:70B3D5ADE*
+ ID_OUI_FROM_DATABASE=ISAC SRL
+
+OUI:70B3D5E85*
+ ID_OUI_FROM_DATABASE=Explorer Inc.
+
+OUI:70B3D5F3C*
+ ID_OUI_FROM_DATABASE=Gigaray
+
+OUI:70B3D5F13*
+ ID_OUI_FROM_DATABASE=MEDIAM Sp. z o.o.
+
+OUI:70B3D5295*
+ ID_OUI_FROM_DATABASE=Cello Electronics (UK) Ltd
+
+OUI:70B3D5283*
+ ID_OUI_FROM_DATABASE=TextNinja Co.
+
+OUI:70B3D5D66*
+ ID_OUI_FROM_DATABASE=Ascendent Technology Group
+
+OUI:70B3D53A5*
+ ID_OUI_FROM_DATABASE=KMtronic ltd
+
+OUI:70B3D56A0*
+ ID_OUI_FROM_DATABASE=Active Research Limited
+
+OUI:70B3D5E3E*
+ ID_OUI_FROM_DATABASE=Sol Welding srl
+
+OUI:70B3D54AE*
+ ID_OUI_FROM_DATABASE=Reinhardt System- und Messelectronic GmbH
+
+OUI:70B3D538C*
+ ID_OUI_FROM_DATABASE=MiraeSignal Co., Ltd
+
+OUI:70B3D5B1D*
+ ID_OUI_FROM_DATABASE=Safelet BV
+
+OUI:70B3D504C*
+ ID_OUI_FROM_DATABASE=mapna group
+
+OUI:70B3D56EC*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5ABA*
+ ID_OUI_FROM_DATABASE=CL International
+
+OUI:70B3D565A*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5FFE*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5721*
+ ID_OUI_FROM_DATABASE=Zoe Medical
+
+OUI:70B3D5186*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:70B3D53BC*
+ ID_OUI_FROM_DATABASE=SciTronix
+
+OUI:70B3D5BE6*
+ ID_OUI_FROM_DATABASE=CCII Systems (Pty) Ltd
+
+OUI:70B3D5BD2*
+ ID_OUI_FROM_DATABASE=Burk Technology
+
+OUI:70B3D5925*
+ ID_OUI_FROM_DATABASE=Diamante Lighting Srl
+
+OUI:70B3D5C8B*
+ ID_OUI_FROM_DATABASE=Asia Pacific Satellite Coummunication Inc.
+
+OUI:70B3D57B4*
+ ID_OUI_FROM_DATABASE=Zumbach Electronic AG
+
+OUI:70B3D5B11*
+ ID_OUI_FROM_DATABASE=CAB S.R.L.
+
OUI:70B3D5D60*
ID_OUI_FROM_DATABASE=Flintab AB
@@ -1007,9 +1100,6 @@ OUI:70B3D5B91*
OUI:70B3D54DE*
ID_OUI_FROM_DATABASE=Oso Technologies, Inc.
-OUI:70B3D57CE*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D5916*
ID_OUI_FROM_DATABASE=Techno Mathematical Co.,Ltd
@@ -1100,9 +1190,6 @@ OUI:70B3D544E*
OUI:70B3D513F*
ID_OUI_FROM_DATABASE=Farmobile
-OUI:70B3D510C*
- ID_OUI_FROM_DATABASE=Vocality International
-
OUI:70B3D5D48*
ID_OUI_FROM_DATABASE=HEADROOM Broadcast GmbH
@@ -1181,9 +1268,6 @@ OUI:70B3D5062*
OUI:70B3D571E*
ID_OUI_FROM_DATABASE=Motec Pty Ltd
-OUI:70B3D5FF3*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D58E0*
ID_OUI_FROM_DATABASE=SOUDAX EQUIPEMENTS
@@ -1217,9 +1301,6 @@ OUI:70B3D5709*
OUI:70B3D5682*
ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
-OUI:70B3D5986*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D50A4*
ID_OUI_FROM_DATABASE=Communication Technology Ltd.
@@ -1289,9 +1370,6 @@ OUI:70B3D5B15*
OUI:70B3D5B2A*
ID_OUI_FROM_DATABASE=Myro Control, LLC
-OUI:70B3D5FB0*
- ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
-
OUI:70B3D5433*
ID_OUI_FROM_DATABASE=Flexsolution APS
@@ -1634,9 +1712,114 @@ OUI:70B3D502A*
OUI:70B3D5DE2*
ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
-OUI:70B3D5FFF*
+OUI:70B3D52BB*
+ ID_OUI_FROM_DATABASE=Automation Networks & Solutions LLC
+
+OUI:70B3D5AB4*
+ ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH
+
+OUI:70B3D535A*
+ ID_OUI_FROM_DATABASE=Applied Radar, Inc.
+
+OUI:70B3D5042*
+ ID_OUI_FROM_DATABASE=Coveloz Technologies Inc.
+
+OUI:70B3D5C1B*
+ ID_OUI_FROM_DATABASE=Labinvent JSC
+
+OUI:70B3D5E2E*
+ ID_OUI_FROM_DATABASE=Merz s.r.o.
+
+OUI:70B3D5DE4*
+ ID_OUI_FROM_DATABASE=MAVILI ELEKTRONIK TIC. VE SAN. A.S.
+
+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.
+
+OUI:70B3D5B72*
+ ID_OUI_FROM_DATABASE=UB330.net d.o.o.
+
+OUI:70B3D57D9*
+ ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd.
+
+OUI:70B3D57DE*
+ ID_OUI_FROM_DATABASE=Telaeris, Inc.
+
+OUI:70B3D5A10*
+ ID_OUI_FROM_DATABASE=w-tec AG
+
+OUI:70B3D513E*
+ ID_OUI_FROM_DATABASE=Stara S/A Indústria de Implementos Agrícolas
+
+OUI:70B3D50BA*
+ ID_OUI_FROM_DATABASE=Ayre Acoustics, Inc.
+
+OUI:70B3D5AAE*
+ ID_OUI_FROM_DATABASE=Nuviz Oy
+
+OUI:70B3D5881*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:70B3D51FE*
+ ID_OUI_FROM_DATABASE=MobiPromo
+
+OUI:70B3D5F0B*
+ ID_OUI_FROM_DATABASE=RF Industries
+
+OUI:70B3D5217*
+ ID_OUI_FROM_DATABASE=Tecnint HTE SRL
+
+OUI:70B3D55E6*
+ ID_OUI_FROM_DATABASE=Mechatronics Systems Private Limited
+
+OUI:70B3D588B*
+ ID_OUI_FROM_DATABASE=WUHAN EASYLINKIN TECHNOLOGY co.,LTD
+
+OUI:70B3D549F*
+ ID_OUI_FROM_DATABASE=B.P.A. SRL
+
+OUI:70B3D5C91*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:70B3D5986*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5FF3*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D57CE*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5F4F*
+ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L.
+
+OUI:70B3D54E9*
+ ID_OUI_FROM_DATABASE=ADETEC SAS
+
+OUI:70B3D509D*
+ ID_OUI_FROM_DATABASE=P&S GmbH
+
+OUI:70B3D5FB0*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:70B3D510C*
+ ID_OUI_FROM_DATABASE=Vocality International Ltd
+
+OUI:70B3D5B7D*
+ ID_OUI_FROM_DATABASE=LOGIX ITS Inc
+
+OUI:70B3D5307*
+ ID_OUI_FROM_DATABASE=Energi innovation Aps
+
+OUI:70B3D59FA*
+ ID_OUI_FROM_DATABASE=Ideas srl
+
OUI:70B3D5494*
ID_OUI_FROM_DATABASE=Schildknecht AG
@@ -1856,9 +2039,6 @@ OUI:70B3D5A26*
OUI:70B3D5C87*
ID_OUI_FROM_DATABASE=Siemens AG
-OUI:70B3D55FF*
- ID_OUI_FROM_DATABASE=Vaisala Oyj
-
OUI:70B3D57AE*
ID_OUI_FROM_DATABASE=Exi Flow Measurement Ltd
@@ -1868,9 +2048,6 @@ OUI:70B3D54DF*
OUI:70B3D54AD*
ID_OUI_FROM_DATABASE=GACI
-OUI:70B3D5932*
- ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
-
OUI:70B3D5DF9*
ID_OUI_FROM_DATABASE=Korea Plant Maintenance
@@ -1922,9 +2099,6 @@ OUI:70B3D5EAB*
OUI:70B3D579E*
ID_OUI_FROM_DATABASE=CW2. Gmbh & Co. KG
-OUI:70B3D5E7C*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D5EB1*
ID_OUI_FROM_DATABASE=CP contech electronic GmbH
@@ -1985,9 +2159,6 @@ OUI:70B3D5DF0*
OUI:70B3D5CF3*
ID_OUI_FROM_DATABASE=Mesh Motion Inc
-OUI:70B3D539C*
- ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
-
OUI:70B3D50B3*
ID_OUI_FROM_DATABASE=Reonix Automation
@@ -2030,9 +2201,6 @@ OUI:70B3D585C*
OUI:70B3D5AFA*
ID_OUI_FROM_DATABASE=Power Security Systems Ltd.
-OUI:70B3D53D9*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D577C*
ID_OUI_FROM_DATABASE=HUSTY M.Styczen J.Hupert Sp.J.
@@ -2075,9 +2243,6 @@ OUI:70B3D58CE*
OUI:70B3D523C*
ID_OUI_FROM_DATABASE=Quasonix, LLC
-OUI:70B3D535F*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D579A*
ID_OUI_FROM_DATABASE=Innerspec Technologies Inc.
@@ -2387,6 +2552,129 @@ OUI:70B3D5CF2*
OUI:70B3D59E0*
ID_OUI_FROM_DATABASE=ES Industrial Systems Co., Ltd.
+OUI:70B3D560F*
+ ID_OUI_FROM_DATABASE=Tanaka Information System, LLC.
+
+OUI:70B3D50FA*
+ ID_OUI_FROM_DATABASE=InsideRF Co., Ltd.
+
+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
+
+OUI:70B3D55FF*
+ ID_OUI_FROM_DATABASE=Vaisala Oyj
+
+OUI:70B3D58EF*
+ ID_OUI_FROM_DATABASE=Beeper Communications Ltd.
+
+OUI:70B3D5277*
+ ID_OUI_FROM_DATABASE=Voltaware Limited
+
+OUI:70B3D5179*
+ ID_OUI_FROM_DATABASE=ALTRAN UK
+
+OUI:70B3D574F*
+ ID_OUI_FROM_DATABASE=United States Technologies Inc.
+
+OUI:70B3D5804*
+ ID_OUI_FROM_DATABASE=PMT Corporation
+
+OUI:70B3D5D2B*
+ ID_OUI_FROM_DATABASE=StreamPlay Oy Ltd
+
+OUI:70B3D539C*
+ ID_OUI_FROM_DATABASE=GD Mission Systems
+
+OUI:70B3D5840*
+ ID_OUI_FROM_DATABASE=xm
+
+OUI:70B3D54FE*
+ ID_OUI_FROM_DATABASE=WiTagg, Inc
+
+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.
+
+OUI:70B3D562B*
+ ID_OUI_FROM_DATABASE=Silicann Systems GmbH
+
+OUI:70B3D56B5*
+ ID_OUI_FROM_DATABASE=ART SPA
+
+OUI:70B3D5E7C*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D53D9*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+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.
+
+OUI:70B3D5180*
+ ID_OUI_FROM_DATABASE=LHA Systems (Pty) Ltd
+
+OUI:70B3D5ABE*
+ ID_OUI_FROM_DATABASE=MART NETWORK SOLUTIONS LTD
+
+OUI:70B3D5932*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:70B3D50C4*
+ ID_OUI_FROM_DATABASE=TIAMA
+
+OUI:70B3D58CF*
+ ID_OUI_FROM_DATABASE=Dainichi Denshi Co.,LTD
+
+OUI:70B3D5750*
+ ID_OUI_FROM_DATABASE=Neurio Technology Inc.
+
+OUI:70B3D5FC9*
+ ID_OUI_FROM_DATABASE=Shanghai EICT Global Service Co., Ltd
+
+OUI:70B3D5147*
+ ID_OUI_FROM_DATABASE=ROMO Wind A/S
+
+OUI:70B3D575B*
+ ID_OUI_FROM_DATABASE=Netool LLC
+
+OUI:70B3D578C*
+ ID_OUI_FROM_DATABASE=Survalent Technology Corporation
+
+OUI:70B3D537D*
+ ID_OUI_FROM_DATABASE=The DX Shop Limited
+
+OUI:70B3D5696*
+ ID_OUI_FROM_DATABASE=Open Grow
+
+OUI:70B3D5FCA*
+ ID_OUI_FROM_DATABASE=M2M Cybernetics Pvt Ltd
+
+OUI:70B3D502D*
+ ID_OUI_FROM_DATABASE=NEXTtec srl
+
+OUI:70B3D53D5*
+ ID_OUI_FROM_DATABASE=oxynet Solutions
+
+OUI:70B3D5D11*
+ ID_OUI_FROM_DATABASE=EREE Electronique
+
OUI:70B3D566B*
ID_OUI_FROM_DATABASE=Innitive B.V.
@@ -2396,9 +2684,6 @@ OUI:70B3D58F6*
OUI:70B3D5A06*
ID_OUI_FROM_DATABASE=Kopis Mobile LLC
-OUI:70B3D59F3*
- ID_OUI_FROM_DATABASE=IEEE Registration Authority
-
OUI:70B3D5679*
ID_OUI_FROM_DATABASE=EMAC, Inc.
@@ -2468,9 +2753,6 @@ OUI:70B3D559D*
OUI:70B3D5933*
ID_OUI_FROM_DATABASE=SARL S@TIS
-OUI:70B3D504D*
- ID_OUI_FROM_DATABASE=Sicon srl
-
OUI:70B3D57F2*
ID_OUI_FROM_DATABASE=TCI
@@ -2654,9 +2936,6 @@ OUI:70B3D5E4E*
OUI:70B3D548C*
ID_OUI_FROM_DATABASE=Integrated Systems Engineering, Inc.
-OUI:70B3D536C*
- ID_OUI_FROM_DATABASE=Sicon srl
-
OUI:70B3D5FC6*
ID_OUI_FROM_DATABASE=Tecnint HTE SRL
@@ -2702,9 +2981,6 @@ OUI:70B3D5820*
OUI:70B3D5732*
ID_OUI_FROM_DATABASE=TOFWERK AG
-OUI:70B3D5DAD*
- ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
-
OUI:70B3D507D*
ID_OUI_FROM_DATABASE=PANORAMIC POWER
@@ -2714,9 +2990,6 @@ OUI:70B3D5B9B*
OUI:70B3D5327*
ID_OUI_FROM_DATABASE=Seneco A/S
-OUI:70B3D5243*
- ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
-
OUI:70B3D508E*
ID_OUI_FROM_DATABASE=Beijing CONvision Technology Co.,Ltd
@@ -3110,6 +3383,108 @@ OUI:70B3D5B81*
OUI:70B3D5479*
ID_OUI_FROM_DATABASE=LINEAGE POWER PVT. LTD.
+OUI:70B3D5A66*
+ ID_OUI_FROM_DATABASE=Trapeze Software Group Inc
+
+OUI:70B3D51AB*
+ ID_OUI_FROM_DATABASE=Access Control Systems JSC
+
+OUI:70B3D536C*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D504D*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D5A78*
+ ID_OUI_FROM_DATABASE=Bionics co.,ltd.
+
+OUI:70B3D5E7E*
+ ID_OUI_FROM_DATABASE=Groupe Citypassenger Inc
+
+OUI:70B3D58D3*
+ ID_OUI_FROM_DATABASE=PERFORMANCE CONTROLS, INC.
+
+OUI:70B3D5D63*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5508*
+ ID_OUI_FROM_DATABASE=INSEVIS GmbH
+
+OUI:70B3D5440*
+ ID_OUI_FROM_DATABASE=Discover Video
+
+OUI:70B3D550E*
+ ID_OUI_FROM_DATABASE=Micro Trend Automation Co., LTD
+
+OUI:70B3D5879*
+ ID_OUI_FROM_DATABASE=ZIGPOS GmbH
+
+OUI:70B3D5C9F*
+ ID_OUI_FROM_DATABASE=Triax A/S
+
+OUI:70B3D58E4*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5350*
+ ID_OUI_FROM_DATABASE=Tickster AB
+
+OUI:70B3D52F3*
+ ID_OUI_FROM_DATABASE=Scame Sistemi srl
+
+OUI:70B3D5DAD*
+ ID_OUI_FROM_DATABASE=GD Mission Systems
+
+OUI:70B3D568D*
+ ID_OUI_FROM_DATABASE=Meta-chrom Co. Ltd.
+
+OUI:70B3D591B*
+ ID_OUI_FROM_DATABASE=Dolotron d.o.o.
+
+OUI:70B3D5A96*
+ ID_OUI_FROM_DATABASE=Östling Marking Systems GmbH
+
+OUI:70B3D5367*
+ ID_OUI_FROM_DATABASE=Living Water
+
+OUI:70B3D5114*
+ ID_OUI_FROM_DATABASE=Project H Pty Ltd
+
+OUI:70B3D5906*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5243*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:70B3D59F3*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
+OUI:70B3D5AAC*
+ ID_OUI_FROM_DATABASE=SensoTec GmbH
+
+OUI:70B3D58DB*
+ ID_OUI_FROM_DATABASE=Kratos Analytical Ltd
+
+OUI:70B3D5A4F*
+ ID_OUI_FROM_DATABASE=Weltek Technologies Co. Ltd.
+
+OUI:70B3D51A3*
+ ID_OUI_FROM_DATABASE=Telairity Semiconductor
+
+OUI:70B3D5650*
+ ID_OUI_FROM_DATABASE=GIFAS-ELECTRIC GmbH
+
+OUI:70B3D5C63*
+ ID_OUI_FROM_DATABASE=Xentech Solutions Limited
+
+OUI:70B3D5106*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D56C5*
+ ID_OUI_FROM_DATABASE=CJSC «Russian telecom equipment company» (CJSC RTEC)
+
+OUI:70B3D5FE9*
+ ID_OUI_FROM_DATABASE=Camsat Przemysław Gralak
+
OUI:70B3D58AB*
ID_OUI_FROM_DATABASE=EMAC, Inc.
@@ -3296,9 +3671,6 @@ OUI:70B3D5530*
OUI:70B3D5A27*
ID_OUI_FROM_DATABASE=HDL da Amazônia Industria Eletrônica Ltda
-OUI:70B3D565C*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D57AD*
ID_OUI_FROM_DATABASE=Insitu Inc
@@ -3365,9 +3737,6 @@ OUI:70B3D5917*
OUI:70B3D5EC6*
ID_OUI_FROM_DATABASE=ESII
-OUI:70B3D518B*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D5849*
ID_OUI_FROM_DATABASE=RF-Tuote Oy
@@ -3422,9 +3791,6 @@ OUI:70B3D5DCF*
OUI:70B3D5A25*
ID_OUI_FROM_DATABASE=PulseTor LLC
-OUI:70B3D5296*
- ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
-
OUI:70B3D5D3B*
ID_OUI_FROM_DATABASE=NimbeLink Corp
@@ -3521,18 +3887,12 @@ OUI:70B3D5587*
OUI:70B3D5E27*
ID_OUI_FROM_DATABASE=Woodside Electronics
-OUI:70B3D5B33*
- ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-
OUI:70B3D5346*
ID_OUI_FROM_DATABASE=Ultamation Limited
OUI:70B3D5052*
ID_OUI_FROM_DATABASE=Sudo Premium Engineering
-OUI:70B3D5C27*
- ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
-
OUI:70B3D5F34*
ID_OUI_FROM_DATABASE=MacGray Services
@@ -3833,27 +4193,150 @@ OUI:70B3D5640*
OUI:70B3D5D65*
ID_OUI_FROM_DATABASE=CRDE
+OUI:70B3D5AE1*
+ ID_OUI_FROM_DATABASE=DimoCore Corporation
+
OUI:70B3D53C3*
ID_OUI_FROM_DATABASE=AIMCO
+OUI:70B3D53F6*
+ ID_OUI_FROM_DATABASE=Sycomp Electronic GmbH
+
+OUI:70B3D530C*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D590C*
+ ID_OUI_FROM_DATABASE=ANTEK GmbH
+
+OUI:70B3D510A*
+ ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY
+
+OUI:70B3D547C*
+ ID_OUI_FROM_DATABASE=Par-Tech, Inc.
+
+OUI:70B3D5AC3*
+ ID_OUI_FROM_DATABASE=Novoptel GmbH
+
+OUI:70B3D597C*
+ ID_OUI_FROM_DATABASE=Nu-Tek Power Controls and Automation
+
+OUI:70B3D58F2*
+ ID_OUI_FROM_DATABASE=Rimota Limited
+
+OUI:70B3D50BD*
+ ID_OUI_FROM_DATABASE=Andium
+
+OUI:70B3D5E3D*
+ ID_OUI_FROM_DATABASE=Leo Bodnar Electronics Ltd
+
+OUI:70B3D5B26*
+ ID_OUI_FROM_DATABASE=INTEC International GmbH
+
+OUI:70B3D5643*
+ ID_OUI_FROM_DATABASE=Marques,S.A.
+
+OUI:70B3D5A7C*
+ ID_OUI_FROM_DATABASE=Transelektronik Messgeräte GmbH
+
+OUI:70B3D5C27*
+ ID_OUI_FROM_DATABASE=GD Mission Systems
+
+OUI:70B3D594F*
+ ID_OUI_FROM_DATABASE=MART NETWORK SOLUTIONS LTD
+
+OUI:70B3D5DFF*
+ ID_OUI_FROM_DATABASE=Spanawave Corporation
+
+OUI:70B3D565C*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5B55*
+ ID_OUI_FROM_DATABASE=CTAG - ESG36871424
+
+OUI:70B3D5B33*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D518B*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:70B3D5CCC*
+ ID_OUI_FROM_DATABASE=AEC s.r.l.
+
+OUI:70B3D53B2*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D5387*
+ ID_OUI_FROM_DATABASE=GWF MessSysteme AG
+
+OUI:70B3D551B*
+ ID_OUI_FROM_DATABASE=Vitrea Smart Home Technologies
+
+OUI:70B3D5E9B*
+ ID_OUI_FROM_DATABASE=NUMATA R&D Co.,Ltd
+
+OUI:70B3D5C34*
+ ID_OUI_FROM_DATABASE=Technical Panels Co. Ltd.
+
+OUI:70B3D5200*
+ ID_OUI_FROM_DATABASE=NextEV Co., Ltd.
+
+OUI:70B3D5A2C*
+ ID_OUI_FROM_DATABASE=TLV CO., LTD.
+
+OUI:70B3D5AA1*
+ ID_OUI_FROM_DATABASE=Shenzhen Weema TV Technology Co.,Ltd.
+
+OUI:70B3D50D2*
+ ID_OUI_FROM_DATABASE=UNMANNED SPA
+
+OUI:70B3D5AF1*
+ ID_OUI_FROM_DATABASE=Emka Technologies
+
+OUI:70B3D5296*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:70B3D5167*
+ ID_OUI_FROM_DATABASE=Eiden Co.,Ltd.
+
+OUI:70B3D57B6*
+ ID_OUI_FROM_DATABASE=Amada Miyachi America Inc.
+
+OUI:70B3D555A*
+ ID_OUI_FROM_DATABASE=Sontay Ltd.
+
+OUI:70B3D5CB2*
+ ID_OUI_FROM_DATABASE=SECLAB
+
+OUI:70B3D511C*
+ ID_OUI_FROM_DATABASE=Samriddi Automations Pvt. Ltd.
+
+OUI:70B3D5AE5*
+ ID_OUI_FROM_DATABASE=BeatCraft, Inc.
+
+OUI:70B3D5A91*
+ ID_OUI_FROM_DATABASE=IDEAL INDUSTRIES Ltd t/a Casella
+
+OUI:70B3D51DD*
+ ID_OUI_FROM_DATABASE=RF CREATIONS LTD
+
+OUI:70B3D50AE*
+ ID_OUI_FROM_DATABASE=Norsat International Inc.
+
+OUI:70B3D51DA*
+ ID_OUI_FROM_DATABASE=Promess Inc.
+
+OUI:70B3D555B*
+ ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd
+
OUI:1C8776D*
ID_OUI_FROM_DATABASE=Qivivo
-OUI:CC1BE0F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C87764*
ID_OUI_FROM_DATABASE=RDP.RU
OUI:1C87768*
ID_OUI_FROM_DATABASE=Guangzhou Video-Star Electronics Co.,Ltd.
-OUI:D07650F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:F40E11F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:8439BE5*
ID_OUI_FROM_DATABASE=Neat S.r.l.
@@ -3935,9 +4418,6 @@ OUI:78C2C05*
OUI:B0C5CAB*
ID_OUI_FROM_DATABASE=RISECOMM (HK) TECHNOLOGY CO. LIMITED
-OUI:B0C5CA7*
- ID_OUI_FROM_DATABASE=Shenzhen KTC Technology CO.,LTD.
-
OUI:B0C5CA2*
ID_OUI_FROM_DATABASE=LOWOTEC GmbH
@@ -4250,27 +4730,9 @@ OUI:1C87741*
OUI:1C87743*
ID_OUI_FROM_DATABASE=Silora R&D
-OUI:3C39E7F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:E81863F*
- 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:1C88795*
ID_OUI_FROM_DATABASE=SHENZHENFREELINK ELECTRONIC CO.,LTD
-OUI:1CCAE3F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C8879C*
ID_OUI_FROM_DATABASE=Accriva
@@ -4310,12 +4772,12 @@ OUI:38FDFE5*
OUI:5CF2867*
ID_OUI_FROM_DATABASE=Access IS
-OUI:5CF286C*
- ID_OUI_FROM_DATABASE=Sunpet Industries Limited
-
OUI:5CF2862*
ID_OUI_FROM_DATABASE=Shanghai Notion Information Technology CO.,LTD.
+OUI:5CF286C*
+ ID_OUI_FROM_DATABASE=Sunpet Industries Limited
+
OUI:5CF2866*
ID_OUI_FROM_DATABASE=VPInstruments
@@ -4364,27 +4826,120 @@ OUI:E0B6F5B*
OUI:E0B6F5C*
ID_OUI_FROM_DATABASE=funktel GmbH
-OUI:1C8776C*
- ID_OUI_FROM_DATABASE=Strone Technology
+OUI:C47C8D1*
+ ID_OUI_FROM_DATABASE=LYNX INNOVATION LITIMED
-OUI:1C87795*
- ID_OUI_FROM_DATABASE=BEIDIAN GROUP
+OUI:C47C8D4*
+ ID_OUI_FROM_DATABASE=ROBOSTAR
-OUI:1C8779B*
- ID_OUI_FROM_DATABASE=Beijing Geedeen Technology Co., Ltd
+OUI:C47C8D7*
+ ID_OUI_FROM_DATABASE=Awiselink Co., Ltd.
-OUI:B01F81F*
+OUI:C47C8D3*
+ ID_OUI_FROM_DATABASE=Watec Co., Ltd.
+
+OUI:CCD31E1*
+ ID_OUI_FROM_DATABASE=Rondo Burgdorf AG
+
+OUI:CCD31E6*
+ ID_OUI_FROM_DATABASE=BBPOS International Limited
+
+OUI:CCD31E3*
+ ID_OUI_FROM_DATABASE=KEN A/S
+
+OUI:D0D94F9*
+ ID_OUI_FROM_DATABASE=Hangzhou xiaoben technology co.,Ltd
+
+OUI:D0D94F7*
ID_OUI_FROM_DATABASE=Private
-OUI:0055DAF*
+OUI:D0D94F0*
+ ID_OUI_FROM_DATABASE=Perfant Technology Co., Ltd
+
+OUI:8C192DD*
+ ID_OUI_FROM_DATABASE=Pyras Technology Inc.
+
+OUI:8C192D4*
+ ID_OUI_FROM_DATABASE=Charmlink Tech(HK) Co.,Limited
+
+OUI:8C192DE*
+ ID_OUI_FROM_DATABASE=Elcon AB
+
+OUI:2836384*
+ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
+
+OUI:283638A*
+ ID_OUI_FROM_DATABASE=Bluekey Pty Ltd
+
+OUI:CC1BE0F*
ID_OUI_FROM_DATABASE=Private
-OUI:A43BFAF*
+OUI:F40E11F*
ID_OUI_FROM_DATABASE=Private
-OUI:7C70BCF*
+OUI:D07650F*
ID_OUI_FROM_DATABASE=Private
+OUI:E81863F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:3C39E7F*
+ 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
+
+OUI:F0ACD75*
+ ID_OUI_FROM_DATABASE=PAVO TASARIM URETIM TICARET A.S.
+
+OUI:2836382*
+ ID_OUI_FROM_DATABASE=SHENZHEN GOSPELL SMARTHOME ELECTRONIC CO., LTD.
+
+OUI:F0ACD7D*
+ ID_OUI_FROM_DATABASE=Smart Power Technology Co., Ltd.
+
+OUI:F0ACD77*
+ ID_OUI_FROM_DATABASE=Hanju Network Technologies Co.
+
+OUI:58E8768*
+ ID_OUI_FROM_DATABASE=Chengdu Vision-Zenith Technology Co.,Ltd
+
+OUI:58E8766*
+ ID_OUI_FROM_DATABASE=DivioTec Inc.
+
+OUI:1C8776C*
+ ID_OUI_FROM_DATABASE=Strone Technology
+
+OUI:1C87795*
+ ID_OUI_FROM_DATABASE=BEIDIAN GROUP
+
+OUI:1C8779B*
+ ID_OUI_FROM_DATABASE=Beijing Geedeen Technology Co., Ltd
+
OUI:1C87794*
ID_OUI_FROM_DATABASE=Novetta
@@ -4772,15 +5327,6 @@ OUI:7419F83*
OUI:7419F80*
ID_OUI_FROM_DATABASE=Marmitek
-OUI:100723F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:D02212F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:B0C5CAF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C8779E*
ID_OUI_FROM_DATABASE=ASSYSTEM France
@@ -4892,6 +5438,114 @@ OUI:E0B6F54*
OUI:E0B6F5E*
ID_OUI_FROM_DATABASE=Advatek Lighting Pty Ltd
+OUI:6891D01*
+ ID_OUI_FROM_DATABASE=Multi Alarm Zrt.
+
+OUI:6891D0C*
+ ID_OUI_FROM_DATABASE=Spraying Systems Co.
+
+OUI:C47C8D8*
+ ID_OUI_FROM_DATABASE=GETEMED Medizin- und Informationstechnik AG
+
+OUI:C47C8DB*
+ ID_OUI_FROM_DATABASE=GC AUTOMATION CO,LTD
+
+OUI:C47C8DA*
+ ID_OUI_FROM_DATABASE=Silvus technologies inc
+
+OUI:CCD31E0*
+ ID_OUI_FROM_DATABASE=SAMIM Co
+
+OUI:CCD31EC*
+ ID_OUI_FROM_DATABASE=Fluidic Energy
+
+OUI:CCD31E5*
+ ID_OUI_FROM_DATABASE=NTmore.Co.,Ltd
+
+OUI:CCD31E9*
+ ID_OUI_FROM_DATABASE=Siemens AG, MO MLT BG
+
+OUI:D0D94FB*
+ ID_OUI_FROM_DATABASE=MAX Smart Home, LLC
+
+OUI:D0D94F5*
+ ID_OUI_FROM_DATABASE=Optigo Networks
+
+OUI:D0D94F2*
+ ID_OUI_FROM_DATABASE=Teco Image Systems Co., Ltd.
+
+OUI:8C192D3*
+ ID_OUI_FROM_DATABASE=Greenfield Technology
+
+OUI:8C192D1*
+ ID_OUI_FROM_DATABASE=Shenzhen Huanuo Internet Technology Co.,Ltd
+
+OUI:D02212F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:100723F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B0C5CAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2836383*
+ ID_OUI_FROM_DATABASE=Sabinetek
+
+OUI:2836380*
+ ID_OUI_FROM_DATABASE=Knowles Electronics LLC
+
+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
+
+OUI:2836381*
+ ID_OUI_FROM_DATABASE=Panasonic System Solutions Europe
+
+OUI:F0ACD7B*
+ ID_OUI_FROM_DATABASE=Zhejiang Makepower Electronics,Inc.
+
+OUI:F0ACD72*
+ ID_OUI_FROM_DATABASE=QUANTUM POWER SYSTEMS
+
+OUI:F0ACD71*
+ ID_OUI_FROM_DATABASE=Intenta GmbH
+
+OUI:58E8769*
+ ID_OUI_FROM_DATABASE=TEM Mobile Limited
+
+OUI:58E8765*
+ ID_OUI_FROM_DATABASE=Broad Air Technology Co., LTD.
+
+OUI:C0D3913*
+ ID_OUI_FROM_DATABASE=IXON B.V.
+
+OUI:C0D3916*
+ ID_OUI_FROM_DATABASE=Ernitec
+
+OUI:C0D3912*
+ ID_OUI_FROM_DATABASE=Hofon Automation Co.,Ltd
+
+OUI:C0D391B*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:1C87765*
+ ID_OUI_FROM_DATABASE=Zhuhai MYZR Technology Co.,Ltd
+
+OUI:1C87793*
+ ID_OUI_FROM_DATABASE=Visual Land Inc.
+
OUI:1C87790*
ID_OUI_FROM_DATABASE=Wurm GmbH & Co. KG Elektronische Systeme
@@ -4901,30 +5555,15 @@ OUI:1C87797*
OUI:1C87796*
ID_OUI_FROM_DATABASE=Shenzhen Shouxin Tongda Technology Co.,Ltd
-OUI:BC3400F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:1C87765*
- ID_OUI_FROM_DATABASE=Zhuhai MYZR Technology Co.,Ltd
-
OUI:1C8779C*
ID_OUI_FROM_DATABASE=AllThingsTalk
-OUI:7419F8F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C8776A*
ID_OUI_FROM_DATABASE=Jiangsu ETERN COMMUNICATION Co.,ltd
OUI:40A36B0*
ID_OUI_FROM_DATABASE=Fin Robotics Inc
-OUI:8439BE2*
- ID_OUI_FROM_DATABASE=Cheng Du virtual world Technology Limited.
-
-OUI:1C87793*
- ID_OUI_FROM_DATABASE=Visual Land Inc.
-
OUI:70886B9*
ID_OUI_FROM_DATABASE=Shenzhen Coolhear Information Technology Co., Ltd.
@@ -4937,6 +5576,9 @@ OUI:70886B5*
OUI:70886B0*
ID_OUI_FROM_DATABASE=Veracity UK Ltd
+OUI:8439BE2*
+ ID_OUI_FROM_DATABASE=Cheng Du virtual world Technology Limited.
+
OUI:70886BA*
ID_OUI_FROM_DATABASE=RHXTune Technology Co.,Ltd
@@ -4946,15 +5588,30 @@ OUI:70886BC*
OUI:800A804*
ID_OUI_FROM_DATABASE=LLVISION TECHNOLOGY CO.,LTD
+OUI:1C21D14*
+ ID_OUI_FROM_DATABASE=Scientific-Production Enterprise Dynamics
+
+OUI:1C21D11*
+ ID_OUI_FROM_DATABASE=Ognios GmbH
+
+OUI:DC4427E*
+ ID_OUI_FROM_DATABASE=VerifEye Technologies
+
+OUI:DC44278*
+ ID_OUI_FROM_DATABASE=Wharton Electronics Ltd
+
+OUI:DC44274*
+ ID_OUI_FROM_DATABASE=Nex Technologies PTY LTD
+
+OUI:B0C5CA6*
+ ID_OUI_FROM_DATABASE=SunTech Medical, Inc.
+
OUI:1C21D1E*
ID_OUI_FROM_DATABASE=p2-plus inc.
OUI:1C21D1B*
ID_OUI_FROM_DATABASE=Global Design Solutions Ltd
-OUI:1C21D14*
- ID_OUI_FROM_DATABASE=Scientific-Production Enterprise Dynamics
-
OUI:A03E6B6*
ID_OUI_FROM_DATABASE=Wuhan Rui Ying Tong Network Technology Co., Ltd(China)
@@ -4970,20 +5627,11 @@ OUI:A03E6B0*
OUI:C88ED18*
ID_OUI_FROM_DATABASE=Electronic Controls Design, Inc.
-OUI:1C21D11*
- ID_OUI_FROM_DATABASE=Ognios GmbH
-
-OUI:DC4427E*
- ID_OUI_FROM_DATABASE=VerifEye Technologies
-
-OUI:DC4427D*
- ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
-
-OUI:DC44278*
- ID_OUI_FROM_DATABASE=Wharton Electronics Ltd
+OUI:CC1BE04*
+ ID_OUI_FROM_DATABASE=Laserworld (Switzerland) AG
-OUI:DC44274*
- ID_OUI_FROM_DATABASE=Nex Technologies PTY LTD
+OUI:CC1BE03*
+ ID_OUI_FROM_DATABASE=Shenzhen Vanstor Technology Co.,Ltd
OUI:0055DAE*
ID_OUI_FROM_DATABASE=Victorsure Limited
@@ -5000,8 +5648,8 @@ OUI:0055DA9*
OUI:0055DA3*
ID_OUI_FROM_DATABASE=Novexx Solutions GmbH
-OUI:B0C5CA6*
- ID_OUI_FROM_DATABASE=SunTech Medical, Inc.
+OUI:A03E6BB*
+ ID_OUI_FROM_DATABASE=KoCoS Messtechnik AG
OUI:DC44272*
ID_OUI_FROM_DATABASE=Skywave Technology Co,.Ltd.
@@ -5015,17 +5663,8 @@ OUI:CC1BE0D*
OUI:CC1BE09*
ID_OUI_FROM_DATABASE=MobiStor Technology Inc.
-OUI:CC1BE04*
- ID_OUI_FROM_DATABASE=Laserworld (Switzerland) AG
-
-OUI:CC1BE03*
- ID_OUI_FROM_DATABASE=Shenzhen Vanstor Technology Co.,Ltd
-
-OUI:A03E6BB*
- ID_OUI_FROM_DATABASE=KoCoS Messtechnik AG
-
-OUI:B0C5CA1*
- ID_OUI_FROM_DATABASE=IVK-SAYANY
+OUI:74F8DBA*
+ ID_OUI_FROM_DATABASE=Ballard Technology Inc.
OUI:74F8DB4*
ID_OUI_FROM_DATABASE=WiFi Hotspots, SL
@@ -5039,9 +5678,6 @@ OUI:885D90E*
OUI:885D90C*
ID_OUI_FROM_DATABASE=iRoom GmbH
-OUI:78C2C04*
- ID_OUI_FROM_DATABASE=Ory Laboratory Co., Ltd.
-
OUI:B437D1B*
ID_OUI_FROM_DATABASE=NSI Co., Ltd.
@@ -5057,21 +5693,33 @@ OUI:B437D11*
OUI:74F8DBE*
ID_OUI_FROM_DATABASE=Bernard Krone Holding GmbH & Co. KG
-OUI:74F8DBA*
- ID_OUI_FROM_DATABASE=Ballard Technology Inc.
-
OUI:885D908*
ID_OUI_FROM_DATABASE=Creative Sensor Inc.
OUI:885D902*
ID_OUI_FROM_DATABASE=DAIDONG Industrial System Co., Ltd.
+OUI:B0C5CA1*
+ ID_OUI_FROM_DATABASE=IVK-SAYANY
+
OUI:78C2C0B*
ID_OUI_FROM_DATABASE=Wan Chao An (Beijing) Technology Co., Ltd.
OUI:78C2C07*
ID_OUI_FROM_DATABASE=Guangzhou Hongcai Stage Equipment co.,ltd
+OUI:549A119*
+ ID_OUI_FROM_DATABASE=Alfen BV
+
+OUI:549A116*
+ ID_OUI_FROM_DATABASE=Orient Direct, Inc.
+
+OUI:549A115*
+ ID_OUI_FROM_DATABASE=Elotech Industrieelektronik GmbH
+
+OUI:78C2C04*
+ ID_OUI_FROM_DATABASE=Ory Laboratory Co., Ltd.
+
OUI:80E4DA8*
ID_OUI_FROM_DATABASE=Krizer international Co,. Ltd.
@@ -5084,17 +5732,17 @@ OUI:80E4DA2*
OUI:2CD141D*
ID_OUI_FROM_DATABASE=Private
-OUI:2C6A6F6*
- ID_OUI_FROM_DATABASE=Beep, Inc.
+OUI:807B85B*
+ ID_OUI_FROM_DATABASE=Oliotalo Oy
-OUI:2C6A6F2*
- ID_OUI_FROM_DATABASE=NanChang LangJie Technology Co.,Ltd
+OUI:807B856*
+ ID_OUI_FROM_DATABASE=Quickte Technology Co.,Ltd
-OUI:9802D8C*
- ID_OUI_FROM_DATABASE=AGV spa
+OUI:807B851*
+ ID_OUI_FROM_DATABASE=Hangzhou Synway Information Engineering Co., Ltd
-OUI:9802D88*
- ID_OUI_FROM_DATABASE=Simplo Technology Co.,LTD
+OUI:1CCAE38*
+ ID_OUI_FROM_DATABASE=OxySec S.r.l.
OUI:1CCAE35*
ID_OUI_FROM_DATABASE=TengFeng
@@ -5102,23 +5750,38 @@ OUI:1CCAE35*
OUI:80E4DAE*
ID_OUI_FROM_DATABASE=Akenori PTE LTD
-OUI:807B85B*
- ID_OUI_FROM_DATABASE=Oliotalo Oy
+OUI:9802D86*
+ ID_OUI_FROM_DATABASE=Fritz Kuebler GmbH
-OUI:807B856*
- ID_OUI_FROM_DATABASE=Quickte Technology Co.,Ltd
+OUI:9802D81*
+ ID_OUI_FROM_DATABASE=SHENZHEN ATEKO PHOTOELECTRICITY CO LTD
-OUI:807B851*
- ID_OUI_FROM_DATABASE=Hangzhou Synway Information Engineering Co., Ltd
+OUI:A0BB3EB*
+ ID_OUI_FROM_DATABASE=Beijing Techshino Technology Co., Ltd.
-OUI:549A119*
- ID_OUI_FROM_DATABASE=Alfen BV
+OUI:A0BB3EE*
+ ID_OUI_FROM_DATABASE=Messtechnik Sachs GmbH
-OUI:549A116*
- ID_OUI_FROM_DATABASE=Orient Direct, Inc.
+OUI:2CD1416*
+ ID_OUI_FROM_DATABASE=Bowei Technology Company Limited
-OUI:549A115*
- ID_OUI_FROM_DATABASE=Elotech Industrieelektronik GmbH
+OUI:2CD1413*
+ ID_OUI_FROM_DATABASE=AOptix Technologies, Inc
+
+OUI:2CD1410*
+ ID_OUI_FROM_DATABASE=iCIRROUND Inc
+
+OUI:2C6A6F6*
+ ID_OUI_FROM_DATABASE=Beep, Inc.
+
+OUI:2C6A6F2*
+ ID_OUI_FROM_DATABASE=NanChang LangJie Technology Co.,Ltd
+
+OUI:9802D8C*
+ ID_OUI_FROM_DATABASE=AGV spa
+
+OUI:9802D88*
+ ID_OUI_FROM_DATABASE=Simplo Technology Co.,LTD
OUI:64FB81C*
ID_OUI_FROM_DATABASE=Bridgeport Instruments, LLC
@@ -5129,32 +5792,23 @@ OUI:64FB81B*
OUI:64FB817*
ID_OUI_FROM_DATABASE=Securosys SA
-OUI:2CD1416*
- ID_OUI_FROM_DATABASE=Bowei Technology Company Limited
-
-OUI:2CD1413*
- ID_OUI_FROM_DATABASE=AOptix Technologies, Inc
-
-OUI:2CD1410*
- ID_OUI_FROM_DATABASE=iCIRROUND Inc
-
OUI:90C682D*
ID_OUI_FROM_DATABASE=PowerShield Limited
+OUI:90C6828*
+ ID_OUI_FROM_DATABASE=Teletek Electronics
+
+OUI:90C6823*
+ ID_OUI_FROM_DATABASE=Innovative Electronic Technology
+
OUI:64FB810*
ID_OUI_FROM_DATABASE=SHANGHAI SIMCOM LIMITED
OUI:64FB812*
ID_OUI_FROM_DATABASE=Seven Solutions S.L
-OUI:1CCAE38*
- ID_OUI_FROM_DATABASE=OxySec S.r.l.
-
-OUI:90C6828*
- ID_OUI_FROM_DATABASE=Teletek Electronics
-
-OUI:90C6823*
- ID_OUI_FROM_DATABASE=Innovative Electronic Technology
+OUI:28FD805*
+ ID_OUI_FROM_DATABASE=Xiaocong Network Limited
OUI:2C265FD*
ID_OUI_FROM_DATABASE=E Core Corporation
@@ -5174,32 +5828,17 @@ OUI:2C265F0*
OUI:F80278D*
ID_OUI_FROM_DATABASE=Dueton Systems s.r.o.
-OUI:0CEFAF1*
- ID_OUI_FROM_DATABASE=Goerlitz AG
-
-OUI:A44F29B*
- ID_OUI_FROM_DATABASE=GUANGDONG REAL-DESIGN INTELLIGENT TECHNOLOGY CO.,LTD
-
-OUI:A44F296*
- ID_OUI_FROM_DATABASE=Selektro Power Inc
+OUI:0CEFAFB*
+ ID_OUI_FROM_DATABASE=Hubei Century Network Technology Co .Ltd
OUI:A44F291*
ID_OUI_FROM_DATABASE=Olssen B.V.
-OUI:9802D86*
- ID_OUI_FROM_DATABASE=Fritz Kuebler GmbH
-
-OUI:9802D81*
- ID_OUI_FROM_DATABASE=SHENZHEN ATEKO PHOTOELECTRICITY CO LTD
-
-OUI:A0BB3EB*
- ID_OUI_FROM_DATABASE=Beijing Techshino Technology Co., Ltd.
-
-OUI:A0BB3EE*
- ID_OUI_FROM_DATABASE=Messtechnik Sachs GmbH
+OUI:3C39E79*
+ ID_OUI_FROM_DATABASE=Zone Controls AB
-OUI:A0BB3E7*
- ID_OUI_FROM_DATABASE=SIMTEC Elektronik GmbH
+OUI:3C39E76*
+ ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A
OUI:100723A*
ID_OUI_FROM_DATABASE=TESSERA TECHNOLOGY INC.
@@ -5210,12 +5849,6 @@ OUI:1007236*
OUI:1007233*
ID_OUI_FROM_DATABASE=Tongfang computer co.Ltd.
-OUI:3C39E79*
- ID_OUI_FROM_DATABASE=Zone Controls AB
-
-OUI:3C39E76*
- ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A
-
OUI:F802788*
ID_OUI_FROM_DATABASE=EMBUX Technology Co., Ltd.
@@ -5225,18 +5858,39 @@ OUI:F802783*
OUI:F802781*
ID_OUI_FROM_DATABASE=Reason Tecnologia SA
-OUI:0CEFAFB*
- ID_OUI_FROM_DATABASE=Hubei Century Network Technology Co .Ltd
+OUI:1007230*
+ ID_OUI_FROM_DATABASE=RippleTek Tech Ltd
+
+OUI:D02212C*
+ ID_OUI_FROM_DATABASE=Xperio Labs Ltd.
+
+OUI:0CEFAF1*
+ ID_OUI_FROM_DATABASE=Goerlitz AG
+
+OUI:A44F29B*
+ ID_OUI_FROM_DATABASE=GUANGDONG REAL-DESIGN INTELLIGENT TECHNOLOGY CO.,LTD
+
+OUI:A44F296*
+ ID_OUI_FROM_DATABASE=Selektro Power Inc
+
+OUI:A0BB3E7*
+ ID_OUI_FROM_DATABASE=SIMTEC Elektronik GmbH
OUI:A0BB3E2*
ID_OUI_FROM_DATABASE=DirectOut GmbH
-OUI:28FD805*
- ID_OUI_FROM_DATABASE=Xiaocong Network Limited
+OUI:D022127*
+ ID_OUI_FROM_DATABASE=Cliptech Industria e Comercio Ltda
OUI:E81863C*
ID_OUI_FROM_DATABASE=Shenzhen Hipad Telecommunication Technology Co.,Ltd
+OUI:B01F81C*
+ ID_OUI_FROM_DATABASE=Access Device Integrated Communications Corp.
+
+OUI:B01F816*
+ ID_OUI_FROM_DATABASE=COMOTA Co., Ltd.
+
OUI:58FCDB9*
ID_OUI_FROM_DATABASE=Hi-Target Surveying Instrument Co., Ltd.
@@ -5246,26 +5900,11 @@ OUI:58FCDB5*
OUI:58FCDB2*
ID_OUI_FROM_DATABASE=Beseye Cloud Security Co. Ltd.
-OUI:B01F81C*
- ID_OUI_FROM_DATABASE=Access Device Integrated Communications Corp.
-
-OUI:BC6641E*
- ID_OUI_FROM_DATABASE=Lucent Trans Electronics Co., Ltd
-
-OUI:BC66415*
- ID_OUI_FROM_DATABASE=Scientific Games
-
-OUI:E4956EC*
- ID_OUI_FROM_DATABASE=Shenzhen Arronna Telecom Co.,Ltd
-
-OUI:E4956EB*
- ID_OUI_FROM_DATABASE=iConservo Inc
-
OUI:E4956E5*
ID_OUI_FROM_DATABASE=ELAN SYSTEMS
-OUI:74E14A4*
- ID_OUI_FROM_DATABASE=open joint stock company YUG-SISTEMA plus
+OUI:BC6641E*
+ ID_OUI_FROM_DATABASE=Lucent Trans Electronics Co., Ltd
OUI:E818634*
ID_OUI_FROM_DATABASE=Guangzhou Tianyi Electronics Co., Ltd
@@ -5276,8 +5915,14 @@ OUI:E818633*
OUI:B8D812E*
ID_OUI_FROM_DATABASE=ZheJiang FangTai Electirc Co., Ltd
-OUI:B8D812A*
- ID_OUI_FROM_DATABASE=Kiwigrid GmbH
+OUI:E4956EC*
+ ID_OUI_FROM_DATABASE=Shenzhen Arronna Telecom Co.,Ltd
+
+OUI:E4956EB*
+ ID_OUI_FROM_DATABASE=iConservo Inc
+
+OUI:BC66415*
+ ID_OUI_FROM_DATABASE=Scientific Games
OUI:BC66410*
ID_OUI_FROM_DATABASE=InSync Technology Ltd
@@ -5285,14 +5930,11 @@ OUI:BC66410*
OUI:58FCDBC*
ID_OUI_FROM_DATABASE=Excenon Mobile Technology Co., Ltd.
-OUI:1007230*
- ID_OUI_FROM_DATABASE=RippleTek Tech Ltd
-
-OUI:D02212C*
- ID_OUI_FROM_DATABASE=Xperio Labs Ltd.
+OUI:74E14A4*
+ ID_OUI_FROM_DATABASE=open joint stock company YUG-SISTEMA plus
-OUI:D022127*
- ID_OUI_FROM_DATABASE=Cliptech Industria e Comercio Ltda
+OUI:B8D812A*
+ ID_OUI_FROM_DATABASE=Kiwigrid GmbH
OUI:B8D8127*
ID_OUI_FROM_DATABASE=Neuropace Inc.
@@ -5303,32 +5945,32 @@ OUI:B8D8123*
OUI:74E14AE*
ID_OUI_FROM_DATABASE=Diamond Kinetics
+OUI:A43BFAD*
+ ID_OUI_FROM_DATABASE=JSC “Component-ASU”
+
OUI:A43BFA6*
ID_OUI_FROM_DATABASE=Recognition Systems LLC
OUI:A43BFA3*
ID_OUI_FROM_DATABASE=Circus World Displays Ltd
-OUI:7C70BC4*
- ID_OUI_FROM_DATABASE=K-Vision Technology (Shanghai), Ltd
+OUI:D076509*
+ ID_OUI_FROM_DATABASE=Greenwave Scientific
OUI:BC3400A*
ID_OUI_FROM_DATABASE=AURALIC LIMITED
-OUI:B01F816*
- ID_OUI_FROM_DATABASE=COMOTA Co., Ltd.
-
-OUI:B01F812*
- ID_OUI_FROM_DATABASE=Private
-
OUI:BC34006*
ID_OUI_FROM_DATABASE=Cameron
OUI:BC34002*
ID_OUI_FROM_DATABASE=LifeSmart
-OUI:A43BFAD*
- ID_OUI_FROM_DATABASE=JSC “Component-ASU”
+OUI:7C70BC4*
+ ID_OUI_FROM_DATABASE=K-Vision Technology (Shanghai), Ltd
+
+OUI:B01F812*
+ ID_OUI_FROM_DATABASE=Private
OUI:F40E11D*
ID_OUI_FROM_DATABASE=DXG Technology Corp.
@@ -5336,15 +5978,6 @@ OUI:F40E11D*
OUI:F40E119*
ID_OUI_FROM_DATABASE=Sterna Security
-OUI:F40E113*
- ID_OUI_FROM_DATABASE=Shenzhen headsun technology
-
-OUI:141FBAE*
- ID_OUI_FROM_DATABASE=POS Systema LLC
-
-OUI:141FBAA*
- ID_OUI_FROM_DATABASE=Winsonic Electronics Co., Ltd.
-
OUI:141FBA4*
ID_OUI_FROM_DATABASE=BYZERO
@@ -5354,36 +5987,27 @@ OUI:141FBA0*
OUI:7C70BCA*
ID_OUI_FROM_DATABASE=Ametek VIS
-OUI:7419F8E*
- ID_OUI_FROM_DATABASE=Volacomm Co., Ltd
+OUI:F40E113*
+ ID_OUI_FROM_DATABASE=Shenzhen headsun technology
-OUI:D076509*
- ID_OUI_FROM_DATABASE=Greenwave Scientific
+OUI:141FBAE*
+ ID_OUI_FROM_DATABASE=POS Systema LLC
+
+OUI:141FBAA*
+ ID_OUI_FROM_DATABASE=Winsonic Electronics Co., Ltd.
OUI:7419F88*
ID_OUI_FROM_DATABASE=Quest Payment Systems
+OUI:7419F8E*
+ ID_OUI_FROM_DATABASE=Volacomm Co., Ltd
+
OUI:7419F84*
ID_OUI_FROM_DATABASE=Cloudvue Technologies Corporation
-OUI:C88ED1F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:DC4427F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:1C21D1F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C87742*
ID_OUI_FROM_DATABASE=Nichigaku
-OUI:885D90F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:80E4DAF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C87747*
ID_OUI_FROM_DATABASE=Ing Buero Ziegler
@@ -5408,15 +6032,15 @@ OUI:78CA83D*
OUI:38B8EB3*
ID_OUI_FROM_DATABASE=Aina Wireless Inc
-OUI:38FDFE3*
- ID_OUI_FROM_DATABASE=Siemens AG, PG IE R&D
-
OUI:38FDFED*
ID_OUI_FROM_DATABASE=FUBA Automotive Electronics GmbH
OUI:38FDFE7*
ID_OUI_FROM_DATABASE=Rademacher Geraete-Elektronik GmbH
+OUI:38FDFE3*
+ ID_OUI_FROM_DATABASE=Siemens AG, PG IE R&D
+
OUI:38FDFE0*
ID_OUI_FROM_DATABASE=Edge I&D Co., Ltd.
@@ -5429,12 +6053,12 @@ OUI:7C477C2*
OUI:5CF286D*
ID_OUI_FROM_DATABASE=BrightSky, LLC
-OUI:7C477CB*
- ID_OUI_FROM_DATABASE=Hangzhou Yiyitaidi Information Technology Co., Ltd.
-
OUI:7C477C3*
ID_OUI_FROM_DATABASE=EyeLock LLC
+OUI:7C477CB*
+ ID_OUI_FROM_DATABASE=Hangzhou Yiyitaidi Information Technology Co., Ltd.
+
OUI:986D351*
ID_OUI_FROM_DATABASE=Shenzhen cositea electronics technology co.,LTD
@@ -5462,6 +6086,126 @@ OUI:E0B6F5D*
OUI:E0B6F53*
ID_OUI_FROM_DATABASE=Huizhou GISUN Industrial CO. LTD
+OUI:6891D04*
+ ID_OUI_FROM_DATABASE=G-TECH Instruments Inc.
+
+OUI:6891D00*
+ ID_OUI_FROM_DATABASE=Central Railway Manufacturing
+
+OUI:6891D02*
+ ID_OUI_FROM_DATABASE=Shenzhen NeaTech Intelligence Technology Co., Ltd.
+
+OUI:6891D0A*
+ ID_OUI_FROM_DATABASE=WiseCube
+
+OUI:6891D0B*
+ ID_OUI_FROM_DATABASE=Altis Technology
+
+OUI:C47C8D5*
+ ID_OUI_FROM_DATABASE=PASCAL Co., Ltd.
+
+OUI:C47C8D9*
+ ID_OUI_FROM_DATABASE=Airbus DS - SLC
+
+OUI:C47C8D2*
+ ID_OUI_FROM_DATABASE=Star2Star Communications, LLC
+
+OUI:C47C8D6*
+ ID_OUI_FROM_DATABASE=HHCC Plant Technology Co.,Ltd.
+
+OUI:CCD31EB*
+ ID_OUI_FROM_DATABASE=Elk Products
+
+OUI:CCD31E2*
+ ID_OUI_FROM_DATABASE=Neptune Systems
+
+OUI:CCD31E4*
+ ID_OUI_FROM_DATABASE=PJG Systementwicklung GmbH
+
+OUI:CCD31EE*
+ ID_OUI_FROM_DATABASE=ShenZhenBoryNet Co.,LTD.
+
+OUI:CCD31E7*
+ ID_OUI_FROM_DATABASE=Shenzhen Decnta Technology Co.,LTD.
+
+OUI:D0D94F4*
+ ID_OUI_FROM_DATABASE=peiker CEE
+
+OUI:8C192DC*
+ ID_OUI_FROM_DATABASE=You Zhengcheng co.,ltd
+
+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
+
+OUI:283638B*
+ ID_OUI_FROM_DATABASE=ShangHai Canall Information Technology Co.,Ltd
+
+OUI:DC4427D*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:F0ACD78*
+ ID_OUI_FROM_DATABASE=Telefonix Incorporated
+
+OUI:F0ACD76*
+ ID_OUI_FROM_DATABASE=Suzhou Pairlink Network Technology
+
+OUI:F0ACD79*
+ ID_OUI_FROM_DATABASE=U3storage Technologies Co., Ltd
+
+OUI:F0ACD7C*
+ ID_OUI_FROM_DATABASE=Simprints Technology Ltd
+
+OUI:58E8763*
+ ID_OUI_FROM_DATABASE=McWong International Inc
+
+OUI:58E8767*
+ ID_OUI_FROM_DATABASE=Chronos Technology Ltd.
+
+OUI:58E876C*
+ ID_OUI_FROM_DATABASE=KUSTOM SIGNALS INC
+
+OUI:58E876E*
+ ID_OUI_FROM_DATABASE=Baoruh Electronic Co., Ltd.
+
+OUI:58E876D*
+ ID_OUI_FROM_DATABASE=Xiamen Cacamle Technology Co.,Ltd.
+
+OUI:C0D3915*
+ ID_OUI_FROM_DATABASE=WiTagg, Inc
+
+OUI:C0D391D*
+ ID_OUI_FROM_DATABASE=REGULUS CO.,LTD.
+
+OUI:58E8764*
+ ID_OUI_FROM_DATABASE=PROBIT SRL
+
+OUI:C0D3911*
+ ID_OUI_FROM_DATABASE=B9Creations
+
OUI:1C8776B*
ID_OUI_FROM_DATABASE=Hekatron Vertriebs GmbH
@@ -5474,18 +6218,9 @@ OUI:1C87798*
OUI:1C87763*
ID_OUI_FROM_DATABASE=Unjo AB
-OUI:58FCDBF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A03E6BF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C87767*
ID_OUI_FROM_DATABASE=Corporate Systems Engineering
-OUI:1C87760*
- ID_OUI_FROM_DATABASE=Dspread technology co.,ltd
-
OUI:1C87769*
ID_OUI_FROM_DATABASE=Tokyo Drawing Ltd.
@@ -5927,39 +6662,6 @@ OUI:7419F82*
OUI:1C88793*
ID_OUI_FROM_DATABASE=Shenzhen Xiaoxi Technology Co., Ltd.
-OUI:B8D812F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:74E14AF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:BC6641F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:74F8DBF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:E4956EF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:64FB81F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2C6A6FF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2C265FF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2CD141F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A0BB3EF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:28FD80F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C88798*
ID_OUI_FROM_DATABASE=Toshiba Toko meter systems co., LTD.
@@ -6017,9 +6719,6 @@ OUI:5CF2869*
OUI:7C477C7*
ID_OUI_FROM_DATABASE=BlueSmart Technology Corporation
-OUI:7C477CA*
- ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
-
OUI:7C477CC*
ID_OUI_FROM_DATABASE=annapurnalabs
@@ -6059,6 +6758,126 @@ OUI:2C265FC*
OUI:6891D05*
ID_OUI_FROM_DATABASE=NIPK Electron Co.
+OUI:6891D07*
+ ID_OUI_FROM_DATABASE=Omniimpex GmbH
+
+OUI:6891D08*
+ ID_OUI_FROM_DATABASE=solvimus GmbH
+
+OUI:6891D06*
+ ID_OUI_FROM_DATABASE=femrice
+
+OUI:C47C8DC*
+ ID_OUI_FROM_DATABASE=INOTEC Sicherheitstechnik GmbH
+
+OUI:C47C8D0*
+ ID_OUI_FROM_DATABASE=ATI
+
+OUI:C47C8DD*
+ ID_OUI_FROM_DATABASE=Anhui GuangXing Linked-Video Communication Technology Co, Ltd.
+
+OUI:C47C8DE*
+ ID_OUI_FROM_DATABASE=Labor Strauss Sicherungsanlagenbau GmbH
+
+OUI:CCD31E8*
+ ID_OUI_FROM_DATABASE=inoage GmbH
+
+OUI:CCD31EA*
+ ID_OUI_FROM_DATABASE=Haishu Technology LIMITED
+
+OUI:CCD31ED*
+ ID_OUI_FROM_DATABASE=CUJO LLC
+
+OUI:D0D94FA*
+ ID_OUI_FROM_DATABASE=Shenzhen FDC Electuonic Co.,Ltd.
+
+OUI:D0D94FD*
+ ID_OUI_FROM_DATABASE=DUKSANMECASYS CO., LTD.
+
+OUI:D0D94F1*
+ ID_OUI_FROM_DATABASE=mycable GmbH
+
+OUI:D0D94F3*
+ ID_OUI_FROM_DATABASE=Beijing Yiwangxuntong Technology
+
+OUI:D0D94F8*
+ ID_OUI_FROM_DATABASE=Apption Labs Limited
+
+OUI:D0D94F6*
+ ID_OUI_FROM_DATABASE=Hyundai Autohow
+
+OUI:8C192D0*
+ ID_OUI_FROM_DATABASE=Noritsu Precision Co., Ltd.
+
+OUI:7C477CA*
+ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
+
+OUI:1C87760*
+ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
+
+OUI:8C192D5*
+ ID_OUI_FROM_DATABASE=ELCO(TIANJIN)ELECTRONICS CO.,LTD.
+
+OUI:8C192DA*
+ ID_OUI_FROM_DATABASE=TeleAlarm SA
+
+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
+
+OUI:F0ACD70*
+ ID_OUI_FROM_DATABASE=Guilin glsun Science and Tech Co.,LTD
+
+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
+
OUI:1C87740*
ID_OUI_FROM_DATABASE=Philips Personal Health Solutions
@@ -6068,12 +6887,6 @@ OUI:1C87761*
OUI:1C8779D*
ID_OUI_FROM_DATABASE=Shenzhen Innovaconn Systems Co.,Ltd
-OUI:141FBAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:800A80F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C87766*
ID_OUI_FROM_DATABASE=philandro Software GmbH
@@ -6176,9 +6989,6 @@ OUI:DC44271*
OUI:78C2C0C*
ID_OUI_FROM_DATABASE=Shanghai Hanyi Technologies Co,.Ltd.
-OUI:78C2C06*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
-
OUI:B0C5CA0*
ID_OUI_FROM_DATABASE=EM-Tech
@@ -6488,24 +7298,6 @@ OUI:7419F8D*
OUI:7419F81*
ID_OUI_FROM_DATABASE=Trend-tech Technology Co., Limited
-OUI:B437D1F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A44F29F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:78C2C0F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:0CEFAFF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:807B85F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:549A11F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C8774D*
ID_OUI_FROM_DATABASE=CLABER SPA
@@ -6554,12 +7346,12 @@ OUI:7C477C6*
OUI:7C477CD*
ID_OUI_FROM_DATABASE=Speedifi Inc
-OUI:986D353*
- ID_OUI_FROM_DATABASE=DH Mechatronic AG
-
OUI:986D359*
ID_OUI_FROM_DATABASE=Private
+OUI:986D353*
+ ID_OUI_FROM_DATABASE=DH Mechatronic AG
+
OUI:986D355*
ID_OUI_FROM_DATABASE=PDAHL
@@ -6569,6 +7361,90 @@ OUI:E0B6F59*
OUI:E0B6F51*
ID_OUI_FROM_DATABASE=START TODAY CO.,LTD.
+OUI:6891D09*
+ ID_OUI_FROM_DATABASE=QUANTEX
+
+OUI:6891D0D*
+ ID_OUI_FROM_DATABASE=Fuzhou x-speed information technology Co.,Ltd.
+
+OUI:6891D03*
+ ID_OUI_FROM_DATABASE=Ambitio LLC
+
+OUI:6891D0E*
+ ID_OUI_FROM_DATABASE=Outstanding Technology Co., Ltd.
+
+OUI:D0D94FC*
+ ID_OUI_FROM_DATABASE=ARROWAVE TECHNOLOGIES LIMITED
+
+OUI:2836387*
+ ID_OUI_FROM_DATABASE=Innovative Technology Ltd
+
+OUI:800A80F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B437D1F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:0CEFAFF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A44F29F*
+ 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
+
+OUI:8C192D8*
+ ID_OUI_FROM_DATABASE=Shenzhen Cylan Technology Co.,Ltd
+
+OUI:8C192D2*
+ ID_OUI_FROM_DATABASE=DataRemote Inc.
+
+OUI:D0D94FE*
+ ID_OUI_FROM_DATABASE=APPOTRONICS CO., LTD
+
+OUI:8C192D6*
+ ID_OUI_FROM_DATABASE=smartHome Partner GmbH
+
+OUI:78C2C06*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:8C192DB*
+ ID_OUI_FROM_DATABASE=Abside Networks, Inc.
+
+OUI:F0ACD7A*
+ ID_OUI_FROM_DATABASE=Groupeer Technologies
+
+OUI:F0ACD74*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation.
+
+OUI:58E876B*
+ ID_OUI_FROM_DATABASE=annapurnalabs
+
+OUI:58E876A*
+ ID_OUI_FROM_DATABASE=SHENZHEN DIGISSIN TECHNOLOGY
+
+OUI:58E8762*
+ ID_OUI_FROM_DATABASE=Coala Life AB
+
+OUI:C0D3917*
+ ID_OUI_FROM_DATABASE=ALNETz Co.,LTD
+
+OUI:C0D3918*
+ ID_OUI_FROM_DATABASE=XENA SECURITY LIMITED
+
OUI:E043DB*
ID_OUI_FROM_DATABASE=Shenzhen ViewAt Technology Co.,Ltd.
@@ -6578,18 +7454,6 @@ OUI:2405F5*
OUI:2C3033*
ID_OUI_FROM_DATABASE=NETGEAR
-OUI:847E40*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:78C5E5*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D494A1*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:3C3300*
- ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
-
OUI:3CD92B*
ID_OUI_FROM_DATABASE=Hewlett Packard
@@ -6638,21 +7502,6 @@ OUI:E8F1B0*
OUI:00F871*
ID_OUI_FROM_DATABASE=DGS Denmark A/S
-OUI:D8543A*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:7C8EE4*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:BC0DA5*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:90D7EB*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:001832*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:20BB76*
ID_OUI_FROM_DATABASE=COL GIOVANNI PAOLO SpA
@@ -6662,18 +7511,6 @@ OUI:2C228B*
OUI:348AAE*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:C83E99*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017E5*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017EC*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:FC528D*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
-
OUI:BCEC23*
ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
@@ -6689,9 +7526,6 @@ OUI:C413E2*
OUI:AC06C7*
ID_OUI_FROM_DATABASE=ServerNet S.r.l.
-OUI:04BF6D*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:CC46D6*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -6710,9 +7544,6 @@ OUI:24DF6A*
OUI:009ACD*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0050C2*
- ID_OUI_FROM_DATABASE=IEEE Registration Authority
-
OUI:00CDFE*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -6749,9 +7580,6 @@ OUI:807ABF*
OUI:409F87*
ID_OUI_FROM_DATABASE=Jide Technology (Hong Kong) Limited
-OUI:544E45*
- ID_OUI_FROM_DATABASE=Private
-
OUI:3C5AB4*
ID_OUI_FROM_DATABASE=Google, Inc.
@@ -7154,30 +7982,6 @@ OUI:283152*
OUI:DCD2FC*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0012D2*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:080028*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:6CECEB*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:84EB18*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D4F513*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:A0F6FD*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:209148*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D0B5C2*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:F8A45F*
ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
@@ -7403,9 +8207,6 @@ OUI:84285A*
OUI:80A1AB*
ID_OUI_FROM_DATABASE=Intellisis
-OUI:CC79CF*
- ID_OUI_FROM_DATABASE=Shenzhen RF-LINK Elec&Technology Co.Ltd
-
OUI:44D884*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -7748,9 +8549,6 @@ OUI:FC335F*
OUI:FCC233*
ID_OUI_FROM_DATABASE=Private
-OUI:645D92*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
-
OUI:A8C87F*
ID_OUI_FROM_DATABASE=Roqos, Inc.
@@ -7814,12 +8612,6 @@ OUI:DC3CF6*
OUI:441CA8*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:C4047B*
- ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
-
-OUI:F895C7*
- ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
-
OUI:3C3178*
ID_OUI_FROM_DATABASE=Qolsys Inc.
@@ -7829,9 +8621,6 @@ OUI:F4573E*
OUI:083A5C*
ID_OUI_FROM_DATABASE=Junilab, Inc.
-OUI:E8377A*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:4CAE31*
ID_OUI_FROM_DATABASE=ShengHai Electronics (Shenzhen) Ltd
@@ -7883,18 +8672,12 @@ OUI:1CADD1*
OUI:24E5AA*
ID_OUI_FROM_DATABASE=Philips Oral Healthcare, Inc.
-OUI:741F4A*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:88CBA5*
ID_OUI_FROM_DATABASE=Suzhou Torchstar Intelligent Technology Co.,Ltd
OUI:184F32*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:20F41B*
- ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
-
OUI:046169*
ID_OUI_FROM_DATABASE=MEDIA GLOBAL LINKS CO., LTD.
@@ -7961,12 +8744,6 @@ OUI:B0495F*
OUI:BC6E64*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
-OUI:8C8B83*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:90A210*
- ID_OUI_FROM_DATABASE=United Telecoms Ltd
-
OUI:F44713*
ID_OUI_FROM_DATABASE=Leading Public Performance Co., Ltd.
@@ -8015,9 +8792,6 @@ OUI:ECE2FD*
OUI:88E603*
ID_OUI_FROM_DATABASE=Avotek corporation
-OUI:0C4885*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:74E28C*
ID_OUI_FROM_DATABASE=Microsoft Corporation
@@ -8036,24 +8810,12 @@ OUI:38C70A*
OUI:60E6BC*
ID_OUI_FROM_DATABASE=Sino-Telecom Technology Co.,Ltd.
-OUI:3CCB7C*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
-OUI:F09FC2*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc.
-
-OUI:44D9E7*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc.
-
OUI:F8042E*
ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
OUI:1CA532*
ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-OUI:643AB1*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
-
OUI:486EFB*
ID_OUI_FROM_DATABASE=Davit System Technology Co., Ltd.
@@ -8111,9 +8873,6 @@ OUI:90179B*
OUI:3077CB*
ID_OUI_FROM_DATABASE=Maike Industry(Shenzhen)CO.,LTD
-OUI:88C9D0*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:3428F0*
ID_OUI_FROM_DATABASE=ATN International Limited
@@ -8144,9 +8903,6 @@ OUI:8463D6*
OUI:78B3B9*
ID_OUI_FROM_DATABASE=ShangHai sunup lighting CO.,LTD
-OUI:586AB1*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:F4EE14*
ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
@@ -8231,9 +8987,6 @@ OUI:74547D*
OUI:D48F33*
ID_OUI_FROM_DATABASE=Microsoft Corporation
-OUI:D84A87*
- ID_OUI_FROM_DATABASE=OI ELECTRIC CO.,LTD
-
OUI:1CA2B1*
ID_OUI_FROM_DATABASE=ruwido austria gmbh
@@ -8351,9 +9104,6 @@ OUI:08CD9B*
OUI:28FCF6*
ID_OUI_FROM_DATABASE=Shenzhen Xin KingBrand enterprises Co.,Ltd
-OUI:2C54CF*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:4C26E7*
ID_OUI_FROM_DATABASE=Welgate Co., Ltd.
@@ -8363,9 +9113,6 @@ OUI:94D60E*
OUI:7C6AC3*
ID_OUI_FROM_DATABASE=GatesAir, Inc
-OUI:D8E56D*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
OUI:3CCD5A*
ID_OUI_FROM_DATABASE=Technische Alternative GmbH
@@ -8606,9 +9353,6 @@ OUI:00E3B2*
OUI:30D6C9*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:107BEF*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:8CCDA2*
ID_OUI_FROM_DATABASE=ACTP, Inc.
@@ -8651,9 +9395,6 @@ OUI:3C18A0*
OUI:4CB81C*
ID_OUI_FROM_DATABASE=SAM Electronics GmbH
-OUI:2C3731*
- ID_OUI_FROM_DATABASE=ShenZhen Yifang Digital Technology Co.,LTD
-
OUI:041A04*
ID_OUI_FROM_DATABASE=WaveIP
@@ -8696,9 +9437,6 @@ OUI:BC2D98*
OUI:7C72E4*
ID_OUI_FROM_DATABASE=Unikey Technologies
-OUI:8048A5*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOM CO.,LTD
-
OUI:181BEB*
ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
@@ -8708,9 +9446,6 @@ OUI:CC7498*
OUI:7C6AB3*
ID_OUI_FROM_DATABASE=IBC TECHNOLOGIES INC.
-OUI:309BAD*
- ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.,
-
OUI:F0321A*
ID_OUI_FROM_DATABASE=Mita-Teknik A/S
@@ -8783,9 +9518,6 @@ OUI:C0F1C4*
OUI:D858D7*
ID_OUI_FROM_DATABASE=CZ.NIC, z.s.p.o.
-OUI:BC307D*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:10B713*
ID_OUI_FROM_DATABASE=Private
@@ -8816,9 +9548,6 @@ OUI:C81479*
OUI:54FB58*
ID_OUI_FROM_DATABASE=WISEWARE, Lda
-OUI:A42940*
- ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
-
OUI:C0A0BB*
ID_OUI_FROM_DATABASE=D-Link International
@@ -8975,9 +9704,6 @@ OUI:E8D4E0*
OUI:3889DC*
ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V.
-OUI:88124E*
- ID_OUI_FROM_DATABASE=Qualcomm Atheros
-
OUI:681D64*
ID_OUI_FROM_DATABASE=Sunwave Communications Co., Ltd
@@ -9035,9 +9761,6 @@ OUI:BC79AD*
OUI:581CBD*
ID_OUI_FROM_DATABASE=Affinegy
-OUI:649C81*
- ID_OUI_FROM_DATABASE=Qualcomm iSkoot, Inc.
-
OUI:F82BC8*
ID_OUI_FROM_DATABASE=Jiangsu Switter Co., Ltd
@@ -9059,9 +9782,6 @@ OUI:28DB81*
OUI:9CB793*
ID_OUI_FROM_DATABASE=Creatcomm Technology Inc.
-OUI:C4438F*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:A0B100*
ID_OUI_FROM_DATABASE=ShenZhen Cando Electronics Co.,Ltd
@@ -9353,9 +10073,6 @@ OUI:00DB1E*
OUI:74943D*
ID_OUI_FROM_DATABASE=AgJunction
-OUI:0CDA41*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:080C0B*
ID_OUI_FROM_DATABASE=SysMik GmbH Dresden
@@ -9476,9 +10193,6 @@ OUI:3CC12C*
OUI:0CCDFB*
ID_OUI_FROM_DATABASE=EDIC Systems Inc.
-OUI:3092F6*
- ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD
-
OUI:2CE2A8*
ID_OUI_FROM_DATABASE=DeviceDesign
@@ -9584,9 +10298,6 @@ OUI:681CA2*
OUI:7C092B*
ID_OUI_FROM_DATABASE=Bekey A/S
-OUI:E892A4*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:D808F5*
ID_OUI_FROM_DATABASE=Arcadia Networks Co. Ltd.
@@ -9623,9 +10334,6 @@ OUI:D43D7E*
OUI:64517E*
ID_OUI_FROM_DATABASE=LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD.
-OUI:A816B2*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:18E2C2*
ID_OUI_FROM_DATABASE=Samsung Electronics
@@ -9680,9 +10388,6 @@ OUI:747B7A*
OUI:1C7C45*
ID_OUI_FROM_DATABASE=Vitek Industrial Video Products, Inc.
-OUI:FC94E3*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
OUI:C8AE9C*
ID_OUI_FROM_DATABASE=Shanghai TYD Elecronic Technology Co. Ltd
@@ -9788,9 +10493,6 @@ OUI:549D85*
OUI:5CEE79*
ID_OUI_FROM_DATABASE=Global Digitech Co LTD
-OUI:80F62E*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:9CE10E*
ID_OUI_FROM_DATABASE=NCTech Ltd
@@ -9974,9 +10676,6 @@ OUI:38A851*
OUI:90185E*
ID_OUI_FROM_DATABASE=Apex Tool Group GmbH & Co OHG
-OUI:14825B*
- ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
-
OUI:7CE9D3*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
@@ -10019,9 +10718,6 @@ OUI:C49300*
OUI:4C3910*
ID_OUI_FROM_DATABASE=Newtek Electronics co., Ltd.
-OUI:5866BA*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:5808FA*
ID_OUI_FROM_DATABASE=Fiber Optic & telecommunication INC.
@@ -10064,9 +10760,6 @@ OUI:983571*
OUI:B05CE5*
ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:4813F3*
- ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.
-
OUI:CC6BF1*
ID_OUI_FROM_DATABASE=Sound Masking Inc.
@@ -10103,9 +10796,6 @@ OUI:94DE0E*
OUI:A429B7*
ID_OUI_FROM_DATABASE=bluesky
-OUI:700514*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:7C6B33*
ID_OUI_FROM_DATABASE=Tenyu Tech Co. Ltd.
@@ -10151,9 +10841,6 @@ OUI:48A6D2*
OUI:186D99*
ID_OUI_FROM_DATABASE=Adanis Inc.
-OUI:047D7B*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc.
-
OUI:D44B5E*
ID_OUI_FROM_DATABASE=TAIYO YUDEN CO., LTD.
@@ -10439,9 +11126,6 @@ OUI:CC051B*
OUI:688470*
ID_OUI_FROM_DATABASE=eSSys Co.,Ltd
-OUI:3CBDD8*
- ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
-
OUI:F08BFE*
ID_OUI_FROM_DATABASE=COSTEL.,CO.LTD
@@ -10613,9 +11297,6 @@ OUI:E84040*
OUI:0C8112*
ID_OUI_FROM_DATABASE=Private
-OUI:3822D6*
- ID_OUI_FROM_DATABASE=H3C Technologies Co., Limited
-
OUI:7C7D41*
ID_OUI_FROM_DATABASE=Jinmuyu Electronics Co., Ltd.
@@ -10709,9 +11390,6 @@ OUI:E05B70*
OUI:043604*
ID_OUI_FROM_DATABASE=Gyeyoung I&T
-OUI:50CE75*
- ID_OUI_FROM_DATABASE=Measy Electronics Ltd
-
OUI:34F968*
ID_OUI_FROM_DATABASE=ATEK Products, LLC
@@ -10874,9 +11552,6 @@ OUI:94F720*
OUI:5C6D20*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:E02A82*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:EC2368*
ID_OUI_FROM_DATABASE=IntelliVoice Co.,Ltd.
@@ -10919,9 +11594,6 @@ OUI:7C3E9D*
OUI:4C60D5*
ID_OUI_FROM_DATABASE=airPointe of New Hampshire
-OUI:48F8E1*
- ID_OUI_FROM_DATABASE=Alcatel Lucent WT
-
OUI:D45297*
ID_OUI_FROM_DATABASE=nSTREAMS Technologies, Inc.
@@ -10955,9 +11627,6 @@ OUI:08512E*
OUI:9CF61A*
ID_OUI_FROM_DATABASE=UTC Fire and Security
-OUI:80A1D7*
- ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
-
OUI:C802A6*
ID_OUI_FROM_DATABASE=Beijing Newmine Technology
@@ -10979,18 +11648,12 @@ OUI:3037A6*
OUI:ACEA6A*
ID_OUI_FROM_DATABASE=GENIX INFOCOMM CO., LTD.
-OUI:7C2064*
- ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
-
OUI:5C35DA*
ID_OUI_FROM_DATABASE=There Corporation Oy
OUI:005218*
ID_OUI_FROM_DATABASE=Wuxi Keboda Electron Co.Ltd
-OUI:C09134*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
-
OUI:F07BCB*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
@@ -11000,9 +11663,6 @@ OUI:08F2F4*
OUI:68EFBD*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:5CFF35*
- ID_OUI_FROM_DATABASE=Wistron Corporation
-
OUI:183BD2*
ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd.
@@ -11141,18 +11801,12 @@ OUI:448E81*
OUI:2046F9*
ID_OUI_FROM_DATABASE=Advanced Network Devices (dba:AND)
-OUI:6CD68A*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
-
OUI:681FD8*
ID_OUI_FROM_DATABASE=Advanced Telemetry
OUI:0C8230*
ID_OUI_FROM_DATABASE=SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD
-OUI:049F81*
- ID_OUI_FROM_DATABASE=Netscout Systems, Inc.
-
OUI:50934F*
ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda.
@@ -11291,9 +11945,6 @@ OUI:D8C3FB*
OUI:201257*
ID_OUI_FROM_DATABASE=Most Lucky Trading Ltd
-OUI:2021A5*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
-
OUI:D49C28*
ID_OUI_FROM_DATABASE=JayBird LLC
@@ -11360,9 +12011,6 @@ OUI:0026F5*
OUI:002632*
ID_OUI_FROM_DATABASE=Instrumentation Technologies d.d.
-OUI:00262D*
- ID_OUI_FROM_DATABASE=Wistron Corporation
-
OUI:00262C*
ID_OUI_FROM_DATABASE=IKT Advanced Technologies s.r.o.
@@ -11465,9 +12113,6 @@ OUI:0026EF*
OUI:0026E9*
ID_OUI_FROM_DATABASE=SP Corp
-OUI:0026E2*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:0026DC*
ID_OUI_FROM_DATABASE=Optical Systems Design
@@ -11843,18 +12488,12 @@ OUI:0022BA*
OUI:00239D*
ID_OUI_FROM_DATABASE=Mapower Electronics Co., Ltd
-OUI:002397*
- ID_OUI_FROM_DATABASE=Westell Technologies Inc.
-
OUI:002392*
ID_OUI_FROM_DATABASE=Proteus Industries Inc.
OUI:00238D*
ID_OUI_FROM_DATABASE=Techno Design Co., Ltd.
-OUI:002389*
- ID_OUI_FROM_DATABASE=HANGZHOU H3C Technologies Co., Ltd.
-
OUI:002388*
ID_OUI_FROM_DATABASE=V.T. Telematica S.p.a.
@@ -11936,9 +12575,6 @@ OUI:00227A*
OUI:00226B*
ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
-OUI:002261*
- ID_OUI_FROM_DATABASE=Frontier Silicon Ltd
-
OUI:00225D*
ID_OUI_FROM_DATABASE=Digicable Network India Pvt. Ltd.
@@ -11951,9 +12587,6 @@ OUI:00216F*
OUI:002169*
ID_OUI_FROM_DATABASE=Prologix, LLC.
-OUI:002162*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:002156*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -12254,9 +12887,6 @@ OUI:001FE8*
OUI:001FDC*
ID_OUI_FROM_DATABASE=Mobile Safe Track Ltd
-OUI:001FE3*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:001FD7*
ID_OUI_FROM_DATABASE=TELERAD SA
@@ -12305,9 +12935,6 @@ OUI:001FD2*
OUI:001FBF*
ID_OUI_FROM_DATABASE=Fulhua Microelectronics Corp. Taiwan Branch
-OUI:001FBA*
- ID_OUI_FROM_DATABASE=BoYoung Tech. & Marketing, Inc.
-
OUI:001FAC*
ID_OUI_FROM_DATABASE=Goodmill Systems Ltd
@@ -12389,9 +13016,6 @@ OUI:001E50*
OUI:001E4A*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001E40*
- ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd.
-
OUI:001D85*
ID_OUI_FROM_DATABASE=Call Direct Cellular Solutions
@@ -12446,9 +13070,6 @@ OUI:001E7A*
OUI:001E79*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001E75*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:001E6F*
ID_OUI_FROM_DATABASE=Magna-Power Electronics, Inc.
@@ -12533,9 +13154,6 @@ OUI:001E2D*
OUI:001E26*
ID_OUI_FROM_DATABASE=Digifriends Co. Ltd
-OUI:001E21*
- ID_OUI_FROM_DATABASE=Qisda Co.
-
OUI:001E1A*
ID_OUI_FROM_DATABASE=Best Source Taiwan Inc.
@@ -12632,9 +13250,6 @@ OUI:001C8D*
OUI:001C88*
ID_OUI_FROM_DATABASE=TRANSYSTEM INC.
-OUI:001C7E*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:001C83*
ID_OUI_FROM_DATABASE=New Level Telecom Co., Ltd.
@@ -12713,9 +13328,6 @@ OUI:001B3E*
OUI:001B37*
ID_OUI_FROM_DATABASE=Computec Oy
-OUI:001B32*
- ID_OUI_FROM_DATABASE=QLogic Corporation
-
OUI:001B2B*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -12740,9 +13352,6 @@ OUI:001BB8*
OUI:001BAC*
ID_OUI_FROM_DATABASE=Curtiss Wright Controls Embedded Computing
-OUI:001BB1*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:001BB2*
ID_OUI_FROM_DATABASE=Intellect International NV
@@ -12755,9 +13364,6 @@ OUI:001BA0*
OUI:001B99*
ID_OUI_FROM_DATABASE=KS System GmbH
-OUI:001C14*
- ID_OUI_FROM_DATABASE=VMware, Inc
-
OUI:001C1B*
ID_OUI_FROM_DATABASE=Hyperstone GmbH
@@ -12836,9 +13442,6 @@ OUI:001A9B*
OUI:001A8A*
ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
-OUI:001A8F*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001A94*
ID_OUI_FROM_DATABASE=Votronic GmbH
@@ -12920,9 +13523,6 @@ OUI:001994*
OUI:00198F*
ID_OUI_FROM_DATABASE=Alcatel Bell N.V.
-OUI:0019E1*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:0019E8*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -13118,18 +13718,12 @@ OUI:001981*
OUI:001983*
ID_OUI_FROM_DATABASE=CCT R&D Limited
-OUI:001988*
- ID_OUI_FROM_DATABASE=Wi2Wi, Inc
-
OUI:001975*
ID_OUI_FROM_DATABASE=Beijing Huisen networks technology Inc
OUI:00197C*
ID_OUI_FROM_DATABASE=Riedel Communications GmbH
-OUI:001969*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001970*
ID_OUI_FROM_DATABASE=Z-Com, Inc.
@@ -13265,9 +13859,6 @@ OUI:0016D1*
OUI:0016C3*
ID_OUI_FROM_DATABASE=BA Systems Inc
-OUI:0016CA*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:0016BE*
ID_OUI_FROM_DATABASE=INFRANET, Inc.
@@ -13289,9 +13880,6 @@ OUI:0016A6*
OUI:0017C8*
ID_OUI_FROM_DATABASE=KYOCERA Document Solutions Inc.
-OUI:0017CA*
- ID_OUI_FROM_DATABASE=Qisda Corporation
-
OUI:0017CF*
ID_OUI_FROM_DATABASE=iMCA-GmbH
@@ -13658,9 +14246,6 @@ OUI:0015A7*
OUI:001599*
ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
-OUI:00159B*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001594*
ID_OUI_FROM_DATABASE=BIXOLON CO.,LTD
@@ -13673,9 +14258,6 @@ OUI:001588*
OUI:0014CC*
ID_OUI_FROM_DATABASE=Zetec, Inc.
-OUI:0014D1*
- ID_OUI_FROM_DATABASE=TRENDnet
-
OUI:0014C0*
ID_OUI_FROM_DATABASE=Symstream Technology Group Ltd
@@ -13691,9 +14273,6 @@ OUI:0014AF*
OUI:0014A8*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001641*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:00163C*
ID_OUI_FROM_DATABASE=Rebox B.V.
@@ -13829,9 +14408,6 @@ OUI:001415*
OUI:001414*
ID_OUI_FROM_DATABASE=Jumpnode Systems LLC.
-OUI:00140E*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001405*
ID_OUI_FROM_DATABASE=OpenIB, Inc.
@@ -14180,9 +14756,6 @@ OUI:000FE9*
OUI:000FDD*
ID_OUI_FROM_DATABASE=SORDIN AB
-OUI:000FE2*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd.
-
OUI:000FD6*
ID_OUI_FROM_DATABASE=Sarotech Co., Ltd
@@ -14231,9 +14804,6 @@ OUI:000F6B*
OUI:000F5F*
ID_OUI_FROM_DATABASE=Nicety Technologies Inc. (NTS)
-OUI:000F59*
- ID_OUI_FROM_DATABASE=Phonak Communications AG
-
OUI:000F5A*
ID_OUI_FROM_DATABASE=Peribit Networks
@@ -14354,18 +14924,12 @@ OUI:000F19*
OUI:000F0D*
ID_OUI_FROM_DATABASE=Hunt Electronic Co., Ltd.
-OUI:000F06*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000F01*
ID_OUI_FROM_DATABASE=DIGITALKS INC
OUI:000EFA*
ID_OUI_FROM_DATABASE=Optoway Technology Incorporation
-OUI:000EF4*
- ID_OUI_FROM_DATABASE=Kasda Networks Inc
-
OUI:000EF3*
ID_OUI_FROM_DATABASE=Smarthome
@@ -14426,9 +14990,6 @@ OUI:000EC4*
OUI:000EC3*
ID_OUI_FROM_DATABASE=Logic Controls, Inc.
-OUI:000EB6*
- ID_OUI_FROM_DATABASE=Riverbed Technology, Inc.
-
OUI:000EBD*
ID_OUI_FROM_DATABASE=Burdick, a Quinton Compny
@@ -14978,12 +15539,6 @@ OUI:000AF1*
OUI:000AF6*
ID_OUI_FROM_DATABASE=Emerson Climate Technologies Retail Solutions, Inc.
-OUI:000AEB*
- ID_OUI_FROM_DATABASE=Shenzhen Tp-Link Technology Co; Ltd.
-
-OUI:000AE4*
- ID_OUI_FROM_DATABASE=Wistron Corp.
-
OUI:000A0E*
ID_OUI_FROM_DATABASE=Invivo Research Inc.
@@ -15014,9 +15569,6 @@ OUI:0009E2*
OUI:0009DB*
ID_OUI_FROM_DATABASE=eSpace
-OUI:000B6B*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:000B70*
ID_OUI_FROM_DATABASE=Load Technology, Inc.
@@ -15086,9 +15638,6 @@ OUI:000B42*
OUI:000B47*
ID_OUI_FROM_DATABASE=Advanced Energy
-OUI:000B34*
- ID_OUI_FROM_DATABASE=ShangHai Broadband Technologies CO.LTD
-
OUI:000B36*
ID_OUI_FROM_DATABASE=Productivity Systems, Inc.
@@ -16289,9 +16838,6 @@ OUI:000352*
OUI:00034E*
ID_OUI_FROM_DATABASE=Pos Data Company, Ltd.
-OUI:000342*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:0002C3*
ID_OUI_FROM_DATABASE=Arelnet Ltd.
@@ -16463,9 +17009,6 @@ OUI:00029C*
OUI:00B009*
ID_OUI_FROM_DATABASE=Grass Valley, A Belden Brand
-OUI:00B0B3*
- ID_OUI_FROM_DATABASE=Xstreamis PLC
-
OUI:00B09D*
ID_OUI_FROM_DATABASE=Point Grey Research Inc.
@@ -16988,9 +17531,6 @@ OUI:00500A*
OUI:00D027*
ID_OUI_FROM_DATABASE=APPLIED AUTOMATION, INC.
-OUI:00D0F6*
- ID_OUI_FROM_DATABASE=Alcatel Canada
-
OUI:00D0F1*
ID_OUI_FROM_DATABASE=SEGA ENTERPRISES, LTD.
@@ -17003,9 +17543,6 @@ OUI:00D080*
OUI:00D084*
ID_OUI_FROM_DATABASE=NEXCOMM SYSTEMS, INC.
-OUI:00D0B2*
- ID_OUI_FROM_DATABASE=XIOTECH CORPORATION
-
OUI:00D0E6*
ID_OUI_FROM_DATABASE=IBOND INC.
@@ -17261,9 +17798,6 @@ OUI:00604D*
OUI:006048*
ID_OUI_FROM_DATABASE=EMC CORPORATION
-OUI:00600F*
- ID_OUI_FROM_DATABASE=WESTELL, INC.
-
OUI:0060E5*
ID_OUI_FROM_DATABASE=FUJI AUTOMATION CO., LTD.
@@ -17462,9 +17996,6 @@ OUI:00A02E*
OUI:00A0E2*
ID_OUI_FROM_DATABASE=Keisokugiken Corporation
-OUI:00A0C5*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:00A058*
ID_OUI_FROM_DATABASE=GLORY, LTD.
@@ -17549,9 +18080,6 @@ OUI:00E0D2*
OUI:00E04E*
ID_OUI_FROM_DATABASE=SANYO DENKI CO., LTD.
-OUI:00E0DD*
- ID_OUI_FROM_DATABASE=ZENITH ELECTRONICS CORPORATION
-
OUI:00E0D0*
ID_OUI_FROM_DATABASE=NETSPEED, INC.
@@ -18263,9 +18791,6 @@ OUI:0080C5*
OUI:0080AC*
ID_OUI_FROM_DATABASE=IMLOGIX, DIVISION OF GENESYS
-OUI:00808C*
- ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
-
OUI:000052*
ID_OUI_FROM_DATABASE=Intrusion.com, Inc.
@@ -18317,9 +18842,6 @@ OUI:08008C*
OUI:080089*
ID_OUI_FROM_DATABASE=Kinetics
-OUI:080087*
- ID_OUI_FROM_DATABASE=XYPLEX
-
OUI:080084*
ID_OUI_FROM_DATABASE=TOMEN ELECTRONICS CORP.
@@ -18548,9 +19070,6 @@ OUI:1C7508*
OUI:8C0EE3*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-OUI:884AEA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:3829DD*
ID_OUI_FROM_DATABASE=ONvocal Inc
@@ -19178,35 +19697,29 @@ OUI:001DBC*
OUI:001F32*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-OUI:544408*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:D8FB5E*
ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
-OUI:1886AC*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:0021FE*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:544408*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:001DFD*
+OUI:0017B0*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001EA3*
+OUI:001BEE*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:002266*
+OUI:1886AC*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:0017B0*
+OUI:0021FE*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001BEE*
+OUI:002266*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:002548*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:DCB3B4*
+ ID_OUI_FROM_DATABASE=Honeywell Environmental & Combustion Controls (Tianjin) Co., Ltd.
OUI:C8D10B*
ID_OUI_FROM_DATABASE=Nokia Corporation
@@ -19217,26 +19730,32 @@ OUI:C8979F*
OUI:F4F5A5*
ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:DCB3B4*
- ID_OUI_FROM_DATABASE=Honeywell Environmental & Combustion Controls (Tianjin) Co., Ltd.
+OUI:3CC243*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:001D98*
+OUI:0015A0*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:00119F*
+OUI:001A16*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:0015A0*
+OUI:0022FC*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001A16*
+OUI:002548*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:0022FC*
+OUI:001DFD*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:3CC243*
- ID_OUI_FROM_DATABASE=Nokia Corporation
+OUI:001EA3*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001D98*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00119F*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
OUI:18A6F7*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
@@ -19259,6 +19778,9 @@ OUI:38B54D*
OUI:90A62F*
ID_OUI_FROM_DATABASE=NAVER
+OUI:F4ED5F*
+ ID_OUI_FROM_DATABASE=SHENZHEN KTC TECHNOLOGY GROUP
+
OUI:9476B7*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -19268,14 +19790,11 @@ OUI:8C1ABF*
OUI:B47443*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:30CBF8*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:000BA2*
ID_OUI_FROM_DATABASE=Sumitomo Electric Industries,Ltd
-OUI:F4ED5F*
- ID_OUI_FROM_DATABASE=SHENZHEN KTC TECHNOLOGY GROUP
+OUI:30CBF8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:2C4D79*
ID_OUI_FROM_DATABASE=GoerTek Inc.
@@ -19286,56 +19805,20 @@ OUI:40D357*
OUI:A4F1E8*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:F03404*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
-OUI:AC9B0A*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:FC0FE6*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:709E29*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:00351A*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:9CD48B*
- ID_OUI_FROM_DATABASE=Innolux Technology Europe BV
-
OUI:00A0B8*
ID_OUI_FROM_DATABASE=NetApp
-OUI:DCE838*
- ID_OUI_FROM_DATABASE=CK Telecom (Shenzhen) Limited
+OUI:9CD48B*
+ ID_OUI_FROM_DATABASE=Innolux Technology Europe BV
OUI:545AA6*
ID_OUI_FROM_DATABASE=Espressif Inc.
-OUI:BC8D0E*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:E48184*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:94E98C*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:84262B*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:98B039*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:A47B2C*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:BC6B4D*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:B0754D*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
+OUI:DCE838*
+ ID_OUI_FROM_DATABASE=CK Telecom (Shenzhen) Limited
OUI:00CCFC*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -19358,15 +19841,6 @@ OUI:1C5F2B*
OUI:D8803C*
ID_OUI_FROM_DATABASE=Anhui Huami Information Technology Company Limited
-OUI:A8E3EE*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:001FA7*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:001315*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:703C03*
ID_OUI_FROM_DATABASE=RadiAnt Co.,Ltd
@@ -19430,12 +19904,12 @@ OUI:B0E2E5*
OUI:AC0D1B*
ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
-OUI:5CC7D7*
- ID_OUI_FROM_DATABASE=AZROAD TECHNOLOGY COMPANY LIMITED
-
OUI:A0043E*
ID_OUI_FROM_DATABASE=Parker Hannifin Manufacturing Germany GmbH & Co. KG
+OUI:5CC7D7*
+ ID_OUI_FROM_DATABASE=AZROAD TECHNOLOGY COMPANY LIMITED
+
OUI:001706*
ID_OUI_FROM_DATABASE=Techfaithwireless Communication Technology Limited.
@@ -19454,9 +19928,6 @@ OUI:00BD82*
OUI:603ECA*
ID_OUI_FROM_DATABASE=Cambridge Medical Robotics Ltd
-OUI:E4A1E6*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:54489C*
ID_OUI_FROM_DATABASE=CDOUBLES ELECTRONICS CO. LTD.
@@ -19520,18 +19991,18 @@ OUI:003A7D*
OUI:844076*
ID_OUI_FROM_DATABASE=Drivenets
-OUI:E80959*
- ID_OUI_FROM_DATABASE=Guoguang Electric Co.,Ltd
+OUI:0010E0*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
OUI:00144F*
ID_OUI_FROM_DATABASE=Oracle Corporation
+OUI:E80959*
+ ID_OUI_FROM_DATABASE=Guoguang Electric Co.,Ltd
+
OUI:541379*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:0010E0*
- ID_OUI_FROM_DATABASE=Oracle Corporation
-
OUI:0090AE*
ID_OUI_FROM_DATABASE=ITALTEL S.p.A/RF-UP-I
@@ -19556,12 +20027,15 @@ OUI:00239C*
OUI:80711F*
ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:28C0DA*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:BCAD28*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
OUI:28F366*
ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
-OUI:D44165*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
-
OUI:8828B3*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -19571,27 +20045,639 @@ OUI:C4F081*
OUI:801382*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:648788*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:A8D0E5*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:0881F4*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:6C3B6B*
+ ID_OUI_FROM_DATABASE=Routerboard.com
+
+OUI:7C738B*
+ ID_OUI_FROM_DATABASE=Cocoon Alarm Ltd
+
+OUI:000FE2*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:002389*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:3822D6*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:80F62E*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:5866BA*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:0CDA41*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:586AB1*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:741F4A*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:3CCB7C*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:F03404*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:D8E56D*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:90C1C6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:70A2B3*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:4C57CA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:68FB7E*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:442C05*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+
+OUI:10BEF5*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:7C6AF3*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:C41CFF*
+ ID_OUI_FROM_DATABASE=Vizio, Inc
+
+OUI:444450*
+ ID_OUI_FROM_DATABASE=OttoQ
+
+OUI:FC55DC*
+ ID_OUI_FROM_DATABASE=Baltic Latvian Universal Electronics LLC
+
+OUI:941882*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:000EB6*
+ ID_OUI_FROM_DATABASE=Riverbed Technology, Inc.
+
+OUI:D0FCCC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:045604*
+ ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co.,Ltd.
+
+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
+
+OUI:3C6816*
+ ID_OUI_FROM_DATABASE=VXi Corporation
+
+OUI:C0A1A2*
+ ID_OUI_FROM_DATABASE=MarqMetrix
+
+OUI:00F663*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
OUI:341290*
ID_OUI_FROM_DATABASE=Treeview Co.,Ltd.
-OUI:BCAD28*
- ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+OUI:F40A4A*
+ ID_OUI_FROM_DATABASE=INDUSNET Communication Technology Co.,LTD
+
+OUI:E8377A*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:04BF6D*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:00A0C5*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:107BEF*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:C0C976*
+ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
+
+OUI:14C913*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:680715*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:A09E1A*
+ ID_OUI_FROM_DATABASE=Polar Electro Oy
OUI:3CB6B7*
ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-OUI:28C0DA*
- ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:D0B2C4*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
-OUI:648788*
- ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:FC94E3*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
-OUI:A8D0E5*
- ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:FC528D*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
-OUI:0881F4*
+OUI:D84A87*
+ ID_OUI_FROM_DATABASE=OI ELECTRIC CO.,LTD
+
+OUI:BC307D*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:643AB1*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:D44165*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:645D92*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:8048A5*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:5410EC*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
+OUI:00262D*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:5CFF35*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:000AE4*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:309BAD*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:001BB1*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:000B6B*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:AC9B0A*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:4813F3*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:74B472*
+ ID_OUI_FROM_DATABASE=CIESSE
+
+OUI:483C0C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:4C6641*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+
+OUI:C8755B*
+ ID_OUI_FROM_DATABASE=Quantify Technology Pty. Ltd.
+
+OUI:1C57D8*
+ ID_OUI_FROM_DATABASE=Kraftway Corporation PLC
+
+OUI:002397*
+ ID_OUI_FROM_DATABASE=Westell Technologies Inc.
+
+OUI:00600F*
+ ID_OUI_FROM_DATABASE=Westell Technologies Inc.
+
+OUI:00E0DD*
+ ID_OUI_FROM_DATABASE=Zenith Electronics Corporation
+
+OUI:50CE75*
+ ID_OUI_FROM_DATABASE=Measy Electronics Co., Ltd.
+
+OUI:047D7B*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:88124E*
+ ID_OUI_FROM_DATABASE=Qualcomm Inc.
+
+OUI:649C81*
+ ID_OUI_FROM_DATABASE=Qualcomm Inc.
+
+OUI:001B32*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:001E21*
+ ID_OUI_FROM_DATABASE=Qisda Corporation
+
+OUI:0017CA*
+ ID_OUI_FROM_DATABASE=Qisda Corporation
+
+OUI:0014D1*
+ ID_OUI_FROM_DATABASE=TRENDnet, Inc.
+
+OUI:001C7E*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:001C14*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:90A210*
+ ID_OUI_FROM_DATABASE=United Telecoms Ltd
+
+OUI:E02A82*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:001641*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:44D9E7*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:F09FC2*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:4C334E*
+ ID_OUI_FROM_DATABASE=HIGHTECH
+
+OUI:60E3AC*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:001315*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:001FA7*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:A8E3EE*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:709E29*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:FC0FE6*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:0050C2*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
+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.
+
+OUI:7CFC3C*
+ ID_OUI_FROM_DATABASE=Visteon Corporation
+
+OUI:58BC8F*
+ ID_OUI_FROM_DATABASE=Cognitive Systems Corp.
+
+OUI:54DC1D*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:3CBDD8*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:0C4885*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:88C9D0*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:700514*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:E892A4*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:A816B2*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:C4438F*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:2021A5*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:6CD68A*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:001E75*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0026E2*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:001FE3*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:2C54CF*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:F895C7*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:4888CA*
+ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
+
+OUI:74B57E*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:540955*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:88A6C6*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:000F59*
+ ID_OUI_FROM_DATABASE=Phonak AG
+
+OUI:000EF4*
+ ID_OUI_FROM_DATABASE=Kasda Networks Inc
+
+OUI:000AEB*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:2C3731*
+ ID_OUI_FROM_DATABASE=SHENZHEN YIFANG DIGITAL TECHNOLOGY CO.,LTD.
+
+OUI:001FBA*
+ ID_OUI_FROM_DATABASE=Boyoung Tech
+
+OUI:C4047B*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:A42940*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:3C3300*
+ ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+
+OUI:20F41B*
+ ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+
+OUI:3092F6*
+ ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD
+
+OUI:7C2064*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:48F8E1*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:00D0F6*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:E4A1E6*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:000B34*
+ ID_OUI_FROM_DATABASE=ShangHai Broadband Technologies CO.LTD
+
+OUI:B0754D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:BC8D0E*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:E48184*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:94E98C*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:84262B*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:98B039*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:A47B2C*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:BC6B4D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:38256B*
+ ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
+
+OUI:203AEF*
+ ID_OUI_FROM_DATABASE=Sivantos GmbH
+
+OUI:001E40*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
+
+OUI:80A1D7*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
+
+OUI:D8FB68*
+ ID_OUI_FROM_DATABASE=Cloud Corner Ltd.
+
+OUI:C09134*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:4CB21C*
+ ID_OUI_FROM_DATABASE=Maxphotonics Co.,Ltd
+
+OUI:D8C46A*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:849866*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:002162*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000F06*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000342*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00159B*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00140E*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0016CA*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001969*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0019E1*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001A8F*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:E89309*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:00D0B2*
+ ID_OUI_FROM_DATABASE=19514
+
+OUI:001988*
+ ID_OUI_FROM_DATABASE=Wi2Wi, Inc
+
+OUI:4CFACA*
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+
+OUI:2C9D1E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C88D83*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:080087*
+ ID_OUI_FROM_DATABASE=Xyplex, Inc.
+
+OUI:00B0B3*
+ ID_OUI_FROM_DATABASE=XSTREAMIS PLC
+
+OUI:14825B*
+ ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
+
+OUI:00549F*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:00562B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:24F57E*
+ ID_OUI_FROM_DATABASE=HWH CO., LTD.
+
+OUI:943DC9*
+ ID_OUI_FROM_DATABASE=Asahi Net, Inc.
+
+OUI:080028*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0012D2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D494A1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:78C5E5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:847E40*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001832*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:90D7EB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:BC0DA5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7C8EE4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D8543A*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:884AEA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B09122*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:209148*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:A0F6FD*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D4F513*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017EC*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C83E99*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:8C8B83*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D0B5C2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:84EB18*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:6CECEB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:985DAD*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:E8EB11*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D43639*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:A8A648*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:A043DB*
+ ID_OUI_FROM_DATABASE=Sitael S.p.A.
+
+OUI:E4BEED*
+ ID_OUI_FROM_DATABASE=Netcore Technology Inc.
+
+OUI:84EF18*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:84C1C1*
ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:305890*
+ ID_OUI_FROM_DATABASE=Frontier Silicon Ltd
+
+OUI:002261*
+ ID_OUI_FROM_DATABASE=Frontier Silicon Ltd
+
+OUI:049F81*
+ ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
+
+OUI:00808C*
+ ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
+
+OUI:C4F5A5*
+ ID_OUI_FROM_DATABASE=Kumalift Co., Ltd.
+
+OUI:98F058*
+ ID_OUI_FROM_DATABASE=Lynxspring, Incl.
+
+OUI:24E43F*
+ ID_OUI_FROM_DATABASE=Wenzhou Kunmei Communication Technology Co.,Ltd.
+
OUI:0C6F9C*
ID_OUI_FROM_DATABASE=Shaw Communications Inc.
@@ -19685,30 +20771,6 @@ OUI:ACF1DF*
OUI:FC7516*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:E0D7BA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:B8FFFE*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:78DEE4*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:00182F*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:001834*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017E3*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017EA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:001783*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:7C18CD*
ID_OUI_FROM_DATABASE=E-TRON Co.,Ltd.
@@ -19727,9 +20789,6 @@ OUI:E498D6*
OUI:606944*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:08952A*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
-
OUI:001977*
ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
@@ -19895,15 +20954,6 @@ OUI:88CF98*
OUI:6CE3B6*
ID_OUI_FROM_DATABASE=Nera Telecommunications Ltd.
-OUI:8030DC*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:CC78AB*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:A4D578*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:942CB3*
ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
@@ -20096,27 +21146,6 @@ OUI:04BD70*
OUI:18C58A*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:405FC2*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:20CD39*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D8DDFD*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:544A16*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:EC1127*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:247189*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:987BF3*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:04C06F*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -20600,9 +21629,6 @@ OUI:4C8ECC*
OUI:3CEF8C*
ID_OUI_FROM_DATABASE=ZHEJIANG DAHUA TECHNOLOGY CO.,LTD.
-OUI:64BC0C*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:98F428*
ID_OUI_FROM_DATABASE=zte corporation
@@ -20663,18 +21689,12 @@ OUI:3095E3*
OUI:401B5F*
ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-OUI:BC307E*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp
-
OUI:4040A7*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
OUI:54BE53*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:588BF3*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:A01E0B*
ID_OUI_FROM_DATABASE=MINIX Technology Limited
@@ -20723,9 +21743,6 @@ OUI:AC60B6*
OUI:F4E926*
ID_OUI_FROM_DATABASE=Tianjin Zanpu Technology Inc.
-OUI:D03742*
- ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt
-
OUI:04C23E*
ID_OUI_FROM_DATABASE=HTC Corporation
@@ -20774,9 +21791,6 @@ OUI:0C756C*
OUI:5C5188*
ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
-OUI:A039F7*
- ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
-
OUI:689AB7*
ID_OUI_FROM_DATABASE=Atelier Vision Corporation
@@ -20939,18 +21953,9 @@ OUI:E4CE70*
OUI:EC5A86*
ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
-OUI:802AA8*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc.
-
OUI:F87AEF*
ID_OUI_FROM_DATABASE=Rosonix Technology, Inc.
-OUI:10E878*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:BC6010*
- ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd
-
OUI:C43ABE*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
@@ -21020,9 +22025,6 @@ OUI:28D98A*
OUI:BC4DFB*
ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
-OUI:6C25B9*
- ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.,
-
OUI:7429AF*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
@@ -21095,9 +22097,6 @@ OUI:EC8009*
OUI:64002D*
ID_OUI_FROM_DATABASE=Powerlinq Co., LTD
-OUI:486B2C*
- ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.,
-
OUI:101218*
ID_OUI_FROM_DATABASE=Korins Inc.
@@ -21143,9 +22142,6 @@ OUI:908C09*
OUI:1C7E51*
ID_OUI_FROM_DATABASE=3bumen.com
-OUI:E41D2D*
- ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
-
OUI:60C798*
ID_OUI_FROM_DATABASE=Verifone, Inc.
@@ -21170,9 +22166,6 @@ OUI:C40006*
OUI:789CE7*
ID_OUI_FROM_DATABASE=Shenzhen Aikede Technology Co., Ltd
-OUI:64899A*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:5C2ED2*
ID_OUI_FROM_DATABASE=ABC(XiSheng) Electronics Co.,Ltd
@@ -21371,9 +22364,6 @@ OUI:205A00*
OUI:0C2026*
ID_OUI_FROM_DATABASE=noax Technologies AG
-OUI:240A11*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
OUI:880FB6*
ID_OUI_FROM_DATABASE=Jabil Circuits India Pvt Ltd,-EHTP unit
@@ -21383,9 +22373,6 @@ OUI:C4626B*
OUI:74F85D*
ID_OUI_FROM_DATABASE=Berkeley Nucleonics Corp
-OUI:08D833*
- ID_OUI_FROM_DATABASE=Shenzhen RF Technology Co,.Ltd
-
OUI:48EE07*
ID_OUI_FROM_DATABASE=Silver Palm Technologies LLC
@@ -21521,9 +22508,6 @@ OUI:30B5C2*
OUI:F85C45*
ID_OUI_FROM_DATABASE=IC Nexus Co. Ltd.
-OUI:88F7C7*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
OUI:04DB8A*
ID_OUI_FROM_DATABASE=Suntech International Ltd.
@@ -21614,9 +22598,6 @@ OUI:7060DE*
OUI:FCFE77*
ID_OUI_FROM_DATABASE=Hitachi Reftechno, Inc.
-OUI:24E271*
- ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd
-
OUI:70533F*
ID_OUI_FROM_DATABASE=Alfa Instrumentos Eletronicos Ltda.
@@ -21737,9 +22718,6 @@ OUI:74D435*
OUI:840F45*
ID_OUI_FROM_DATABASE=Shanghai GMT Digital Technologies Co., Ltd
-OUI:58A2B5*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:D8270C*
ID_OUI_FROM_DATABASE=MaxTronic International Co., Ltd.
@@ -21761,9 +22739,6 @@ OUI:70188B*
OUI:3C77E6*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:5CDD70*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:883612*
ID_OUI_FROM_DATABASE=SRC Computers, LLC
@@ -21782,9 +22757,6 @@ OUI:CCF407*
OUI:BC2BD7*
ID_OUI_FROM_DATABASE=Revogi Innovation Co., Ltd.
-OUI:3C404F*
- ID_OUI_FROM_DATABASE=Guangdong Pisen Electronics Co. Ltd.
-
OUI:24ECD6*
ID_OUI_FROM_DATABASE=CSG Science & Technology Co.,Ltd.Hefei
@@ -22088,9 +23060,6 @@ OUI:2481AA*
OUI:789966*
ID_OUI_FROM_DATABASE=Musilab Electronics (DongGuan)Co.,Ltd.
-OUI:D8B02E*
- ID_OUI_FROM_DATABASE=Guangzhou Zonerich Business Machine Co., Ltd
-
OUI:EC2C49*
ID_OUI_FROM_DATABASE=University of Tokyo
@@ -22190,9 +23159,6 @@ OUI:748E08*
OUI:B8C855*
ID_OUI_FROM_DATABASE=Shanghai GBCOM Communication Technology Co.,Ltd.
-OUI:54A619*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:C47DFE*
ID_OUI_FROM_DATABASE=A.N. Solutions GmbH
@@ -22226,9 +23192,6 @@ OUI:905692*
OUI:0C2AE7*
ID_OUI_FROM_DATABASE=Beijing General Research Institute of Mining and Metallurgy
-OUI:4439C4*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co.,Ltd
-
OUI:DCD52A*
ID_OUI_FROM_DATABASE=Sunny Heart Limited
@@ -22238,9 +23201,6 @@ OUI:C4C755*
OUI:9C79AC*
ID_OUI_FROM_DATABASE=Suntec Software(Shanghai) Co., Ltd.
-OUI:6488FF*
- ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
-
OUI:F8DFA8*
ID_OUI_FROM_DATABASE=zte corporation
@@ -22289,9 +23249,6 @@ OUI:E4E409*
OUI:004D32*
ID_OUI_FROM_DATABASE=Andon Health Co.,Ltd.
-OUI:8C04FF*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
OUI:C46DF1*
ID_OUI_FROM_DATABASE=DataGravity
@@ -22346,9 +23303,6 @@ OUI:984CD3*
OUI:8C4CDC*
ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
-OUI:10683F*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:D063B4*
ID_OUI_FROM_DATABASE=SolidRun Ltd.
@@ -22448,9 +23402,6 @@ OUI:449B78*
OUI:D052A8*
ID_OUI_FROM_DATABASE=Physical Graph Corporation
-OUI:EC43F6*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:34F62D*
ID_OUI_FROM_DATABASE=SHARP Corporation
@@ -22496,9 +23447,6 @@ OUI:50465D*
OUI:74BFA1*
ID_OUI_FROM_DATABASE=HYUNTECK
-OUI:FCF528*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:F8AA8A*
ID_OUI_FROM_DATABASE=Axview Technology (Shenzhen) Co.,Ltd
@@ -22538,9 +23486,6 @@ OUI:E43FA2*
OUI:00FD4C*
ID_OUI_FROM_DATABASE=NEVATEC
-OUI:E09DB8*
- ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
-
OUI:6045BD*
ID_OUI_FROM_DATABASE=Microsoft
@@ -22580,9 +23525,6 @@ OUI:647C34*
OUI:649FF7*
ID_OUI_FROM_DATABASE=Kone OYj
-OUI:B86B23*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:4C068A*
ID_OUI_FROM_DATABASE=Basler Electric Company
@@ -22631,9 +23573,6 @@ OUI:58C232*
OUI:D8C691*
ID_OUI_FROM_DATABASE=Hichan Technology Corp.
-OUI:8CFDF0*
- ID_OUI_FROM_DATABASE=QUALCOMM Incorporated
-
OUI:7C02BC*
ID_OUI_FROM_DATABASE=Hansung Electronics Co. LTD
@@ -22742,9 +23681,6 @@ OUI:38F8B7*
OUI:B48255*
ID_OUI_FROM_DATABASE=Research Products Corporation
-OUI:C84544*
- ID_OUI_FROM_DATABASE=Shanghai Enlogic Electric Technology Co., Ltd.
-
OUI:2C750F*
ID_OUI_FROM_DATABASE=Shanghai Dongzhou-Lawton Communication Technology Co. Ltd.
@@ -23579,9 +24515,6 @@ OUI:448C52*
OUI:686359*
ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA
-OUI:B8E779*
- ID_OUI_FROM_DATABASE=9Solutions Oy
-
OUI:4018D7*
ID_OUI_FROM_DATABASE=Smartronix, Inc.
@@ -23663,9 +24596,6 @@ OUI:948D50*
OUI:94E226*
ID_OUI_FROM_DATABASE=D. ORtiz Consulting, LLC
-OUI:74A722*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:78D6F0*
ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
@@ -23831,9 +24761,6 @@ OUI:5CD998*
OUI:D46CDA*
ID_OUI_FROM_DATABASE=CSM GmbH
-OUI:60EB69*
- ID_OUI_FROM_DATABASE=Quanta computer Inc.
-
OUI:C4F464*
ID_OUI_FROM_DATABASE=Spica international
@@ -23915,9 +24842,6 @@ OUI:B407F9*
OUI:7CED8D*
ID_OUI_FROM_DATABASE=Microsoft
-OUI:1880F5*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:54FDBF*
ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH
@@ -24038,9 +24962,6 @@ OUI:80B289*
OUI:14A62C*
ID_OUI_FROM_DATABASE=S.M. Dezac S.A.
-OUI:C80AA9*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc.
-
OUI:A8F470*
ID_OUI_FROM_DATABASE=Fujian Newland Communication Science Technologies Co.,Ltd.
@@ -24215,9 +25136,6 @@ OUI:20D906*
OUI:404022*
ID_OUI_FROM_DATABASE=ZIV
-OUI:70F395*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:74F726*
ID_OUI_FROM_DATABASE=Neuron Robotics
@@ -24242,9 +25160,6 @@ OUI:4001C6*
OUI:608D17*
ID_OUI_FROM_DATABASE=Sentrus Government Systems Division, Inc
-OUI:24BF74*
- ID_OUI_FROM_DATABASE=Private
-
OUI:80912A*
ID_OUI_FROM_DATABASE=Lih Rong electronic Enterprise Co., Ltd.
@@ -24287,9 +25202,6 @@ OUI:98D88C*
OUI:C8873B*
ID_OUI_FROM_DATABASE=Net Optics
-OUI:6CBEE9*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
-
OUI:B0E97E*
ID_OUI_FROM_DATABASE=Advanced Micro Peripherals
@@ -24314,9 +25226,6 @@ OUI:00271B*
OUI:002718*
ID_OUI_FROM_DATABASE=Suzhou NEW SEAUNION Video Technology Co.,Ltd
-OUI:002713*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:00270C*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -24548,9 +25457,6 @@ OUI:0025D6*
OUI:0025CA*
ID_OUI_FROM_DATABASE=LS Research, LLC
-OUI:0025C3*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:0025BE*
ID_OUI_FROM_DATABASE=Tektrap Systems Inc.
@@ -24695,9 +25601,6 @@ OUI:0024B4*
OUI:0024AF*
ID_OUI_FROM_DATABASE=EchoStar Technologies
-OUI:0024A8*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
-
OUI:0024AD*
ID_OUI_FROM_DATABASE=Adolf Thies Gmbh & Co. KG
@@ -24914,9 +25817,6 @@ OUI:002344*
OUI:002343*
ID_OUI_FROM_DATABASE=TEM AG
-OUI:00233E*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
-
OUI:002337*
ID_OUI_FROM_DATABASE=Global Star Solutions ULC
@@ -24941,9 +25841,6 @@ OUI:002393*
OUI:00238F*
ID_OUI_FROM_DATABASE=NIDEC COPAL CORPORATION
-OUI:00238B*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc.
-
OUI:002385*
ID_OUI_FROM_DATABASE=ANTIPODE
@@ -24977,9 +25874,6 @@ OUI:00222D*
OUI:00222E*
ID_OUI_FROM_DATABASE=maintech GmbH
-OUI:002363*
- ID_OUI_FROM_DATABASE=Zhuhai RaySharp Technology Co., Ltd.
-
OUI:002364*
ID_OUI_FROM_DATABASE=Power Instruments Pte Ltd
@@ -25082,9 +25976,6 @@ OUI:002192*
OUI:00218C*
ID_OUI_FROM_DATABASE=TopControl GMBH
-OUI:002186*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd
-
OUI:00217F*
ID_OUI_FROM_DATABASE=Intraco Technology Pte Ltd
@@ -25232,9 +26123,6 @@ OUI:0021AD*
OUI:0021A6*
ID_OUI_FROM_DATABASE=Videotec Spa
-OUI:001F16*
- ID_OUI_FROM_DATABASE=Wistron Corporation
-
OUI:001F11*
ID_OUI_FROM_DATABASE=OPENMOKO, INC.
@@ -25268,9 +26156,6 @@ OUI:001F75*
OUI:001F64*
ID_OUI_FROM_DATABASE=Beijing Autelan Technology Inc.
-OUI:001F6B*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:001F5E*
ID_OUI_FROM_DATABASE=Dyna Technology Co.,Ltd.
@@ -25304,9 +26189,6 @@ OUI:001F8A*
OUI:001F83*
ID_OUI_FROM_DATABASE=Teleplan Technology Services Sdn Bhd
-OUI:001E37*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:001E30*
ID_OUI_FROM_DATABASE=Shireen Inc
@@ -25427,9 +26309,6 @@ OUI:001ED6*
OUI:001ECF*
ID_OUI_FROM_DATABASE=PHILIPS ELECTRONICS UK LTD
-OUI:001ECA*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001C96*
ID_OUI_FROM_DATABASE=Linkwise Technology Pte Ltd
@@ -25475,9 +26354,6 @@ OUI:001D48*
OUI:001D41*
ID_OUI_FROM_DATABASE=Hardy Instruments
-OUI:001D42*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001D3C*
ID_OUI_FROM_DATABASE=Muscle Corporation
@@ -25613,15 +26489,9 @@ OUI:001D03*
OUI:001CFE*
ID_OUI_FROM_DATABASE=Quartics Inc
-OUI:001CFD*
- ID_OUI_FROM_DATABASE=Universal Electronics
-
OUI:001CF7*
ID_OUI_FROM_DATABASE=AudioScience
-OUI:001CEB*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001CE6*
ID_OUI_FROM_DATABASE=INNES
@@ -25769,9 +26639,6 @@ OUI:001C5E*
OUI:001C46*
ID_OUI_FROM_DATABASE=QTUM
-OUI:001C4D*
- ID_OUI_FROM_DATABASE=Aplix IP Holdings Corporation
-
OUI:001C3A*
ID_OUI_FROM_DATABASE=Element Labs, Inc.
@@ -26069,9 +26936,6 @@ OUI:00198C*
OUI:001985*
ID_OUI_FROM_DATABASE=IT Watchdogs, Inc
-OUI:001972*
- ID_OUI_FROM_DATABASE=Plexus (Xiamen) Co.,ltd
-
OUI:00196B*
ID_OUI_FROM_DATABASE=Danpex Corporation
@@ -26090,9 +26954,6 @@ OUI:0019DE*
OUI:0019EA*
ID_OUI_FROM_DATABASE=TeraMage Technologies Co., Ltd.
-OUI:0019CB*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:0019D0*
ID_OUI_FROM_DATABASE=Cathexis
@@ -26438,9 +27299,6 @@ OUI:0016DD*
OUI:0016E2*
ID_OUI_FROM_DATABASE=American Fibertek, Inc.
-OUI:0016D3*
- ID_OUI_FROM_DATABASE=Wistron Corporation
-
OUI:0016D8*
ID_OUI_FROM_DATABASE=Senea AB
@@ -26543,9 +27401,6 @@ OUI:0016CC*
OUI:0016C0*
ID_OUI_FROM_DATABASE=Semtech Corporation
-OUI:0016B9*
- ID_OUI_FROM_DATABASE=ProCurve Networking
-
OUI:0016B4*
ID_OUI_FROM_DATABASE=Private
@@ -26609,9 +27464,6 @@ OUI:001579*
OUI:001574*
ID_OUI_FROM_DATABASE=Horizon Semiconductors Ltd.
-OUI:00156D*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc.
-
OUI:001566*
ID_OUI_FROM_DATABASE=A-First Technology Co., Ltd.
@@ -26930,9 +27782,6 @@ OUI:00137E*
OUI:00136C*
ID_OUI_FROM_DATABASE=TomTom
-OUI:001365*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:00136B*
ID_OUI_FROM_DATABASE=E-TEC
@@ -27158,9 +28007,6 @@ OUI:001201*
OUI:001202*
ID_OUI_FROM_DATABASE=Decrane Aerospace - Audio International Inc.
-OUI:0011FC*
- ID_OUI_FROM_DATABASE=HARTING Electric Gmbh & Co.KG
-
OUI:0011C7*
ID_OUI_FROM_DATABASE=Raymarine UK Ltd
@@ -27299,9 +28145,6 @@ OUI:000E7C*
OUI:000E76*
ID_OUI_FROM_DATABASE=GEMSOC INNOVISION INC.
-OUI:000E7B*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:000E6E*
ID_OUI_FROM_DATABASE=MAT S.A. (Mircrelec Advanced Technology)
@@ -27314,9 +28157,6 @@ OUI:000E68*
OUI:000E67*
ID_OUI_FROM_DATABASE=Eltis Microelectronics Ltd.
-OUI:000E62*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000FE7*
ID_OUI_FROM_DATABASE=Lutron Electronics Co., Inc.
@@ -27332,9 +28172,6 @@ OUI:000FD4*
OUI:000FD9*
ID_OUI_FROM_DATABASE=FlexDSL Telecommunications AG
-OUI:000FCD*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000EEA*
ID_OUI_FROM_DATABASE=Shadong Luneng Jicheng Electronics,Co.,Ltd
@@ -27356,9 +28193,6 @@ OUI:000ECE*
OUI:000ED3*
ID_OUI_FROM_DATABASE=Epicenter, Inc.
-OUI:000EC0*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000EC7*
ID_OUI_FROM_DATABASE=Motorola Korea
@@ -27875,9 +28709,6 @@ OUI:000C43*
OUI:000C45*
ID_OUI_FROM_DATABASE=Animation Technologies Inc.
-OUI:000C29*
- ID_OUI_FROM_DATABASE=VMware, Inc.
-
OUI:000C3C*
ID_OUI_FROM_DATABASE=MediaChorus, Inc.
@@ -28064,18 +28895,12 @@ OUI:00099E*
OUI:000992*
ID_OUI_FROM_DATABASE=InterEpoch Technology,INC.
-OUI:000997*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000991*
ID_OUI_FROM_DATABASE=GE Fanuc Automation Manufacturing, Inc.
OUI:00098B*
ID_OUI_FROM_DATABASE=Entropic Communications, Inc.
-OUI:000AAB*
- ID_OUI_FROM_DATABASE=Toyota Technical Development Corporation
-
OUI:000AB0*
ID_OUI_FROM_DATABASE=LOYTEC electronics GmbH
@@ -28439,9 +29264,6 @@ OUI:0007C7*
OUI:00047D*
ID_OUI_FROM_DATABASE=Pelco
-OUI:0007BA*
- ID_OUI_FROM_DATABASE=UTStarcom, Inc.
-
OUI:00047E*
ID_OUI_FROM_DATABASE=Siqura B.V.
@@ -28457,9 +29279,6 @@ OUI:0007AE*
OUI:0007B4*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0007A6*
- ID_OUI_FROM_DATABASE=Home Automation, Inc.
-
OUI:00079A*
ID_OUI_FROM_DATABASE=Verint Systems Inc
@@ -28904,9 +29723,6 @@ OUI:0004EC*
OUI:0004E6*
ID_OUI_FROM_DATABASE=Banyan Network Private Limited
-OUI:0004DC*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:0004E1*
ID_OUI_FROM_DATABASE=Infinior Microsystems
@@ -29966,9 +30782,6 @@ OUI:0050B3*
OUI:0050B7*
ID_OUI_FROM_DATABASE=BOSER TECHNOLOGY CO., LTD.
-OUI:005056*
- ID_OUI_FROM_DATABASE=VMware, Inc.
-
OUI:00908D*
ID_OUI_FROM_DATABASE=VICKERS ELECTRONICS SYSTEMS
@@ -30017,9 +30830,6 @@ OUI:0090E4*
OUI:009013*
ID_OUI_FROM_DATABASE=SAMSAN CORP.
-OUI:0090CC*
- ID_OUI_FROM_DATABASE=Planex Communications
-
OUI:009004*
ID_OUI_FROM_DATABASE=3COM EUROPE LTD.
@@ -30200,9 +31010,6 @@ OUI:0010B3*
OUI:001037*
ID_OUI_FROM_DATABASE=CYQ've Technology Co., Ltd.
-OUI:0010CA*
- ID_OUI_FROM_DATABASE=Telco Systems, Inc.
-
OUI:001051*
ID_OUI_FROM_DATABASE=CMICRO CORPORATION
@@ -30233,9 +31040,6 @@ OUI:00104D*
OUI:00E0E0*
ID_OUI_FROM_DATABASE=SI ELECTRONICS, LTD.
-OUI:00E00F*
- ID_OUI_FROM_DATABASE=SHANGHAI BAUD DATA
-
OUI:00E0D1*
ID_OUI_FROM_DATABASE=TELSIS LIMITED
@@ -30647,9 +31451,6 @@ OUI:0020A0*
OUI:00C0A3*
ID_OUI_FROM_DATABASE=DUAL ENTERPRISES CORPORATION
-OUI:00C095*
- ID_OUI_FROM_DATABASE=ZNYX
-
OUI:0070B0*
ID_OUI_FROM_DATABASE=M/A-COM INC. COMPANIES
@@ -30887,18 +31688,12 @@ OUI:00C04C*
OUI:00C01C*
ID_OUI_FROM_DATABASE=INTERLINK COMMUNICATIONS LTD.
-OUI:00C017*
- ID_OUI_FROM_DATABASE=Fluke Corporation
-
OUI:00C086*
ID_OUI_FROM_DATABASE=THE LYNK CORPORATION
OUI:00C08D*
ID_OUI_FROM_DATABASE=TRONIX PRODUCT DEVELOPMENT
-OUI:00C0AB*
- ID_OUI_FROM_DATABASE=Telco Systems, Inc.
-
OUI:00C0A2*
ID_OUI_FROM_DATABASE=INTERMEDIUM A/S
@@ -31106,9 +31901,6 @@ OUI:008002*
OUI:00805C*
ID_OUI_FROM_DATABASE=AGILIS CORPORATION
-OUI:0080C7*
- ID_OUI_FROM_DATABASE=XIRCOM
-
OUI:0080E7*
ID_OUI_FROM_DATABASE=LYNWOOD SCIENTIFIC DEV. LTD.
@@ -31172,9 +31964,6 @@ OUI:0000D4*
OUI:0000E1*
ID_OUI_FROM_DATABASE=GRID SYSTEMS
-OUI:000031*
- ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS PTY LTD
-
OUI:000044*
ID_OUI_FROM_DATABASE=CASTELLE CORPORATION
@@ -31232,18 +32021,12 @@ OUI:0040B2*
OUI:004071*
ID_OUI_FROM_DATABASE=ATM COMPUTER GMBH
-OUI:0080F7*
- ID_OUI_FROM_DATABASE=ZENITH ELECTRONICS
-
OUI:0080BF*
ID_OUI_FROM_DATABASE=TAKAOKA ELECTRIC MFG. CO. LTD.
OUI:0080F6*
ID_OUI_FROM_DATABASE=SYNERGY MICROSYSTEMS
-OUI:00001F*
- ID_OUI_FROM_DATABASE=Telco Systems, Inc.
-
OUI:000058*
ID_OUI_FROM_DATABASE=RACORE COMPUTER PRODUCTS INC.
@@ -31349,9 +32132,6 @@ OUI:080061*
OUI:08005D*
ID_OUI_FROM_DATABASE=GOULD INC.
-OUI:080051*
- ID_OUI_FROM_DATABASE=EXPERDATA
-
OUI:08004E*
ID_OUI_FROM_DATABASE=3COM EUROPE LTD.
@@ -31409,9 +32189,6 @@ OUI:000006*
OUI:0001C8*
ID_OUI_FROM_DATABASE=THOMAS CONRAD CORP.
-OUI:02E6D3*
- ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORPORATION
-
OUI:00DD0E*
ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
@@ -31544,12 +32321,6 @@ OUI:208984*
OUI:247C4C*
ID_OUI_FROM_DATABASE=Herman Miller
-OUI:ACDE48*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:00A085*
- ID_OUI_FROM_DATABASE=Private
-
OUI:180373*
ID_OUI_FROM_DATABASE=Dell Inc.
@@ -32234,9 +33005,6 @@ OUI:3CBEE1*
OUI:047E4A*
ID_OUI_FROM_DATABASE=moobox CO., Ltd.
-OUI:104FA8*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:F01B6C*
ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
@@ -32267,12 +33035,6 @@ OUI:546D52*
OUI:CCB3AB*
ID_OUI_FROM_DATABASE=shenzhen Biocare Bio-Medical Equipment Co.,Ltd.
-OUI:4CC94F*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:48F7F1*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:E4B318*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -32321,18 +33083,9 @@ OUI:10DA43*
OUI:001625*
ID_OUI_FROM_DATABASE=Impinj, Inc.
-OUI:1CEA1B*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:DC1AC5*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:60EE5C*
ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD
-OUI:BC60A7*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:58D67A*
ID_OUI_FROM_DATABASE=TCPlink
@@ -32357,9 +33110,6 @@ OUI:18A3E8*
OUI:741E93*
ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-OUI:F0C77F*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:00A0F4*
ID_OUI_FROM_DATABASE=GE
@@ -32552,56 +33302,629 @@ OUI:006CBC*
OUI:DC3752*
ID_OUI_FROM_DATABASE=GE
-OUI:F08261*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+OUI:B4D5BD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:D084B0*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+OUI:7CB0C2*
+ ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:5846E1*
- ID_OUI_FROM_DATABASE=Baxter International Inc
+OUI:98AA3C*
+ ID_OUI_FROM_DATABASE=Will i-tech Co., Ltd.
-OUI:00D0BD*
- ID_OUI_FROM_DATABASE=Lattice Semiconductor Corp. (LPA)
+OUI:449F7F*
+ ID_OUI_FROM_DATABASE=DataCore Software Corporation
-OUI:001F3A*
- ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+OUI:0011FC*
+ ID_OUI_FROM_DATABASE=HARTING Electronics GmbH
-OUI:647BD4*
+OUI:5CDD70*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:24BF74*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B8E779*
+ ID_OUI_FROM_DATABASE=9Solutions Oy
+
+OUI:240A11*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:78B84B*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:C84544*
+ ID_OUI_FROM_DATABASE=Asia Pacific CIS (Wuxi) Co, Ltd
+
+OUI:E8A7F2*
+ ID_OUI_FROM_DATABASE=sTraffic
+
+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.
+
+OUI:24F094*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:90B0ED*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C4B301*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E05F45*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:483B38*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E47B3F*
+ ID_OUI_FROM_DATABASE=BEIJING CO-CLOUD TECHNOLOGY LTD.
+
+OUI:A0415E*
+ ID_OUI_FROM_DATABASE=Opsens Solution Inc.
+
+OUI:1C6E76*
+ ID_OUI_FROM_DATABASE=Quarion Technology Inc
+
+OUI:000AAB*
+ ID_OUI_FROM_DATABASE=Toyota Technical Development Corporation
+
+OUI:44D1FA*
+ ID_OUI_FROM_DATABASE=Shenzhen Yunlink Technology Co., Ltd
+
+OUI:08C021*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:48435A*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:9CE374*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:40F420*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:6C0EE6*
+ ID_OUI_FROM_DATABASE=Chengdu Xiyida Electronic Technology Co,.Ltd
+
+OUI:78FFCA*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:F03EBF*
+ ID_OUI_FROM_DATABASE=GOGORO TAIWAN LIMITED
+
+OUI:50AB3E*
+ ID_OUI_FROM_DATABASE=Qibixx AG
+
+OUI:A8BB50*
+ ID_OUI_FROM_DATABASE=WiZ IoT Company Limited
+
+OUI:005F86*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:E46251*
+ ID_OUI_FROM_DATABASE=HAO CHENG GROUP LIMITED
+
+OUI:8850DD*
+ ID_OUI_FROM_DATABASE=Infiniband Trade Association
+
+OUI:DC7834*
+ ID_OUI_FROM_DATABASE=LOGICOM SA
+
+OUI:54F201*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A06090*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:3876CA*
+ ID_OUI_FROM_DATABASE=Shenzhen Smart Intelligent Technology Co.Ltd
+
+OUI:D0577B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B824F0*
+ ID_OUI_FROM_DATABASE=SOYO Technology Development Co., Ltd.
+
+OUI:B456B9*
+ ID_OUI_FROM_DATABASE=Teraspek Technologies Co.,Ltd
+
+OUI:A009ED*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:68B35E*
+ ID_OUI_FROM_DATABASE=Shenzhen Neostra Technology Co.Ltd
+
+OUI:24E271*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:BC6010*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:AC3743*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:603197*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:0019CB*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:FCF528*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:588BF3*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:EC43F6*
+ ID_OUI_FROM_DATABASE=5420
+
+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
+
+OUI:A020A6*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:88F7C7*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:08952A*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:C4BB4C*
+ ID_OUI_FROM_DATABASE=Zebra Information Tech Co. Ltd
+
+OUI:8C04FF*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:104FA8*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:6C25B9*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:486B2C*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:00001F*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:0016D3*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:001F16*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:BC307E*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:00C0AB*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:0010CA*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:0C2576*
+ ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
+
+OUI:0007A6*
+ ID_OUI_FROM_DATABASE=Leviton Manufacturing Co., Inc.
+
+OUI:208756*
+ ID_OUI_FROM_DATABASE=SIEMENS AG
+
+OUI:B08900*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+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.
+
+OUI:F0421C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:C0E42D*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:18D6C7*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:B8BB23*
+ ID_OUI_FROM_DATABASE=Guangdong Nufront CSC Co., Ltd
+
+OUI:EC26FB*
+ ID_OUI_FROM_DATABASE=TECC CO.,LTD.
+
+OUI:10683F*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:A039F7*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:64BC0C*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0090CC*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:E09DB8*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:64899A*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:58A2B5*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:74A722*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:001F6B*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:903AE6*
+ ID_OUI_FROM_DATABASE=PARROT SA
+
+OUI:00E00F*
+ ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd.
+
+OUI:3C404F*
+ ID_OUI_FROM_DATABASE=GUANGDONG PISEN ELECTRONICS CO.,LTD
+
+OUI:1CEA1B*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:00233E*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:6CBEE9*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:4CC94F*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:0080F7*
+ ID_OUI_FROM_DATABASE=Zenith Electronics Corporation
+
+OUI:00C095*
+ ID_OUI_FROM_DATABASE=ZNYX Networks, Inc.
+
+OUI:60EB69*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:C80AA9*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:00238B*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:0007BA*
+ ID_OUI_FROM_DATABASE=UTStarcom Inc
+
+OUI:4439C4*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:70F395*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:001E37*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:002713*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:002186*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:802AA8*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:00156D*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:8CFDF0*
+ ID_OUI_FROM_DATABASE=Qualcomm Inc.
+
+OUI:000031*
+ ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS, LTD.
+
+OUI:000E7B*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:B86B23*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:000C29*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:005056*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:9C6121*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:001C4D*
+ ID_OUI_FROM_DATABASE=Aplix IP Holdings Corporation
+
+OUI:D0052A*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
+OUI:F485C6*
+ ID_OUI_FROM_DATABASE=FDT Technologies
+
+OUI:BC60A7*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:08D833*
+ ID_OUI_FROM_DATABASE=Shenzhen RF Technology Co., Ltd
+
+OUI:94D469*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:385610*
+ ID_OUI_FROM_DATABASE=CANDY HOUSE, Inc.
+
+OUI:20F543*
+ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD
+
+OUI:685388*
+ ID_OUI_FROM_DATABASE=P&S Technology
+
+OUI:48F7F1*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:10E878*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:54A619*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:1880F5*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:001972*
+ ID_OUI_FROM_DATABASE=Plexus (Xiamen) Co.,ltd.
+
+OUI:6488FF*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:005979*
+ ID_OUI_FROM_DATABASE=Networked Energy Services
+
+OUI:000997*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000E62*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000EC0*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000FCD*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0004DC*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:02E6D3*
+ ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORP.
+
+OUI:0016B9*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:0024A8*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:CC3ADF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:141F78*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:006F64*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:DC6672*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0025C3*
+ ID_OUI_FROM_DATABASE=21168
+
+OUI:001365*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001ECA*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001D42*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001CEB*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002363*
+ ID_OUI_FROM_DATABASE=Zhuhai Raysharp Technology Co.,Ltd
+
+OUI:D03742*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:001CFD*
+ ID_OUI_FROM_DATABASE=Universal Electronics, Inc.
+
+OUI:080051*
+ ID_OUI_FROM_DATABASE=ExperData
+
+OUI:0080C7*
+ ID_OUI_FROM_DATABASE=XIRCOM
+
+OUI:049FCA*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C81FBE*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:203DB2*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:48D539*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:10E68F*
+ ID_OUI_FROM_DATABASE=KWANGSUNG ELECTRONICS KOREA CO.,LTD.
+
+OUI:1899F5*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:E41D2D*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:B80018*
+ ID_OUI_FROM_DATABASE=Htel
+
+OUI:0081C4*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:E8FD90*
+ ID_OUI_FROM_DATABASE=Turbostor
+
+OUI:0017EA*
ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:102EAF*
+OUI:0017E3*
ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:CC8CE3*
+OUI:001834*
ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:B4EED4*
+OUI:00182F*
ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:D08CB5*
+OUI:78DEE4*
ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:0030C5*
- ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS, INC.
+OUI:B8FFFE*
+ ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:00FEC8*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:E0D7BA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:BC5436*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:405FC2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:0CC731*
- ID_OUI_FROM_DATABASE=Currant, Inc.
+OUI:8030DC*
+ ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:00142F*
- ID_OUI_FROM_DATABASE=Savvius
+OUI:CC78AB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:70CA4D*
- ID_OUI_FROM_DATABASE=Shenzhen lnovance Technology Co.,Ltd.
+OUI:A4D578*
+ ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:DCC0EB*
- ID_OUI_FROM_DATABASE=ASSA ABLOY CÔTE PICARDE
+OUI:544A16*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D8DDFD*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:20CD39*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:987BF3*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:247189*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:EC1127*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:F0C77F*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:F45EAB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001783*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:400D10*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A81B6A*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:9884E3*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:38D269*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C8FD19*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:508CB1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:04BBF9*
+ ID_OUI_FROM_DATABASE=Pavilion Data Systems Inc
+
+OUI:B0F893*
+ ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd.
+
+OUI:00C017*
+ ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
+
+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
+
+OUI:5846E1*
+ ID_OUI_FROM_DATABASE=Baxter International Inc
+
+OUI:00D0BD*
+ ID_OUI_FROM_DATABASE=Lattice Semiconductor Corp. (LPA)
+
+OUI:001F3A*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:F08261*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:D084B0*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:00FEC8*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:0030C5*
+ ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS, INC.
+
+OUI:EC2280*
+ ID_OUI_FROM_DATABASE=D-Link International
OUI:047863*
ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd.
@@ -32612,24 +33935,33 @@ OUI:24BA13*
OUI:24DA11*
ID_OUI_FROM_DATABASE=NO NDA Inc
-OUI:BCD1D3*
- ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
+OUI:70CA4D*
+ ID_OUI_FROM_DATABASE=Shenzhen lnovance Technology Co.,Ltd.
-OUI:BC4434*
- ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
+OUI:DCC0EB*
+ ID_OUI_FROM_DATABASE=ASSA ABLOY CÔTE PICARDE
-OUI:0041D2*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:001735*
+ ID_OUI_FROM_DATABASE=Intel Wireless Network Group
-OUI:4CFB45*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:9CDFB1*
+ ID_OUI_FROM_DATABASE=Shenzhen Crave Communication Co., LTD
-OUI:A4BA76*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:5CF938*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:3871DE*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:BC5436*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0CC731*
+ ID_OUI_FROM_DATABASE=Currant, Inc.
+
+OUI:00142F*
+ ID_OUI_FROM_DATABASE=Savvius
+
OUI:2CDDA3*
ID_OUI_FROM_DATABASE=Point Grey Research Inc.
@@ -32648,23 +33980,23 @@ OUI:F4F5E8*
OUI:F88FCA*
ID_OUI_FROM_DATABASE=Google, Inc.
-OUI:14D64D*
- ID_OUI_FROM_DATABASE=D-Link International
+OUI:BCD1D3*
+ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
-OUI:C8BE19*
- ID_OUI_FROM_DATABASE=D-Link International
+OUI:BC4434*
+ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
-OUI:BCF685*
- ID_OUI_FROM_DATABASE=D-Link International
+OUI:0041D2*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:CCB255*
- ID_OUI_FROM_DATABASE=D-Link International
+OUI:4CFB45*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:84C9B2*
- ID_OUI_FROM_DATABASE=D-Link International
+OUI:A4BA76*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:EC2280*
- ID_OUI_FROM_DATABASE=D-Link International
+OUI:003676*
+ ID_OUI_FROM_DATABASE=Pace plc
OUI:78E3B5*
ID_OUI_FROM_DATABASE=Hewlett Packard
@@ -32678,41 +34010,32 @@ OUI:68B599*
OUI:0C47C9*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-OUI:001831*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0023D4*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:3C2DB7*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:40984E*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:14D64D*
+ ID_OUI_FROM_DATABASE=D-Link International
-OUI:3C7DB1*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:C8BE19*
+ ID_OUI_FROM_DATABASE=D-Link International
-OUI:505663*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:BCF685*
+ ID_OUI_FROM_DATABASE=D-Link International
-OUI:B0B448*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:CCB255*
+ ID_OUI_FROM_DATABASE=D-Link International
-OUI:0017E6*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:84C9B2*
+ ID_OUI_FROM_DATABASE=D-Link International
-OUI:0017E8*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:DCD321*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
-OUI:9059AF*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:CC4EEC*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
-OUI:E0C79D*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:DC330D*
+ ID_OUI_FROM_DATABASE=Qingdao Haier Telecom Co.,Ltd
-OUI:003676*
- ID_OUI_FROM_DATABASE=Pace plc
+OUI:0080E1*
+ ID_OUI_FROM_DATABASE=STMicroelectronics SRL
OUI:58DC6D*
ID_OUI_FROM_DATABASE=Exceptional Innovation, Inc.
@@ -32744,9 +34067,6 @@ OUI:18686A*
OUI:0C0535*
ID_OUI_FROM_DATABASE=Juniper Systems
-OUI:E0885D*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
-
OUI:8CF228*
ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
@@ -32756,6 +34076,18 @@ OUI:08EA44*
OUI:78F882*
ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+OUI:8851FB*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:AC162D*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:A0B3CC*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:E4115B*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
OUI:C8CBB8*
ID_OUI_FROM_DATABASE=Hewlett Packard
@@ -32777,29 +34109,8 @@ OUI:D48564*
OUI:3C4A92*
ID_OUI_FROM_DATABASE=Hewlett Packard
-OUI:0080E1*
- ID_OUI_FROM_DATABASE=STMicroelectronics SRL
-
-OUI:2C6E85*
- ID_OUI_FROM_DATABASE=Intel Corporate
-
-OUI:00D0B7*
- ID_OUI_FROM_DATABASE=Intel Corporation
-
-OUI:0015D1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001735*
- ID_OUI_FROM_DATABASE=Intel Wireless Network Group
-
-OUI:9CDFB1*
- ID_OUI_FROM_DATABASE=Shenzhen Crave Communication Co., LTD
-
-OUI:5CF938*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:780AC7*
+ ID_OUI_FROM_DATABASE=Baofeng TV Co., Ltd.
OUI:001D73*
ID_OUI_FROM_DATABASE=BUFFALO.INC
@@ -32825,6 +34136,21 @@ OUI:001B78*
OUI:001E0B*
ID_OUI_FROM_DATABASE=Hewlett Packard
+OUI:2C6E85*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00D0B7*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0015D1*
+ 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:0002B3*
ID_OUI_FROM_DATABASE=Intel Corporation
@@ -32843,9 +34169,6 @@ OUI:9049FA*
OUI:C8348E*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:780AC7*
- ID_OUI_FROM_DATABASE=Baofeng TV Co., Ltd.
-
OUI:00508B*
ID_OUI_FROM_DATABASE=Hewlett Packard
@@ -32864,17 +34187,8 @@ OUI:A0481C*
OUI:A01D48*
ID_OUI_FROM_DATABASE=Hewlett Packard
-OUI:8851FB*
- ID_OUI_FROM_DATABASE=Hewlett Packard
-
-OUI:AC162D*
- ID_OUI_FROM_DATABASE=Hewlett Packard
-
-OUI:A0B3CC*
- ID_OUI_FROM_DATABASE=Hewlett Packard
-
-OUI:E4115B*
- ID_OUI_FROM_DATABASE=Hewlett Packard
+OUI:001DD3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:E8892C*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -32891,29 +34205,41 @@ OUI:8C09F4*
OUI:3CDFA9*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:C005C2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:94B2CC*
+ ID_OUI_FROM_DATABASE=PIONEER CORPORATION
-OUI:6455B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:887F03*
+ ID_OUI_FROM_DATABASE=Comper Technology Investment Limited
-OUI:DCD321*
- ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+OUI:E06066*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation
-OUI:CC4EEC*
- ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+OUI:0019E0*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:88C255*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:0023CD*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:DC330D*
- ID_OUI_FROM_DATABASE=Qingdao Haier Telecom Co.,Ltd
+OUI:002719*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:94B2CC*
- ID_OUI_FROM_DATABASE=PIONEER CORPORATION
+OUI:40169F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:887F03*
- ID_OUI_FROM_DATABASE=Comper Technology Investment Limited
+OUI:940C6D*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:74EA3A*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:90F652*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:10FEED*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:C46E1F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
OUI:50FA84*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
@@ -32942,11 +34268,23 @@ OUI:1C994C*
OUI:F02765*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-OUI:88308A*
- ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+OUI:D4970B*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
-OUI:44A7CF*
- ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+OUI:F48B32*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:20A783*
+ ID_OUI_FROM_DATABASE=miControl GmbH
+
+OUI:005053*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:00500F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:048A15*
+ ID_OUI_FROM_DATABASE=Avaya Inc
OUI:44322A*
ID_OUI_FROM_DATABASE=Avaya Inc
@@ -32978,77 +34316,11 @@ OUI:200BC7*
OUI:104780*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:30D17E*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:9C28EF*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:E06066*
- ID_OUI_FROM_DATABASE=Sercomm Corporation
-
-OUI:0019E0*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:0023CD*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:002719*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:40169F*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:940C6D*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:74EA3A*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:90F652*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:10FEED*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:C46E1F*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:68A0F6*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:5CF96A*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:B43052*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:88CEFA*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:582AF7*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:F48E92*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:40CBA8*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:087A4C*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:D46E5C*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:2469A5*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:C8D15E*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:88308A*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-OUI:F83DFF*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:44A7CF*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
OUI:0013E0*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
@@ -33110,29 +34382,41 @@ OUI:88E3AB*
OUI:00664B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:7C6097*
+OUI:68A0F6*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:60DE44*
+OUI:5CF96A*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:3400A3*
+OUI:B43052*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:643E8C*
+OUI:88CEFA*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0012D1*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:582AF7*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:70FF76*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:F48E92*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:B4994C*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:40CBA8*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:507224*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:087A4C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:D46E5C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:2469A5*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C8D15E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:F83DFF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
OUI:308730*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -33158,26 +34442,77 @@ OUI:A4251B*
OUI:6CA849*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:048A15*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:30D17E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:D4970B*
- ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+OUI:9C28EF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:F48B32*
- ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+OUI:7C6097*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:20A783*
- ID_OUI_FROM_DATABASE=miControl GmbH
+OUI:60DE44*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:005053*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:3400A3*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:00500F*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:643E8C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0050A2*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:00C610*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:70DEE2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:182032*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:6CC26B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:1040F3*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:FC253F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:183451*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C0847A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:64200C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:74E1B6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0C771A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:00F4B9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C8334B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B8F6B1*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C09F42*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:189EFC*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:6C3E6D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0016FE*
+ ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
OUI:0498F3*
ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
@@ -33209,50 +34544,11 @@ OUI:80E86F*
OUI:E4AA5D*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:203A07*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:34A84E*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:E4D3F1*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:1CE6C7*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:E02F6D*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:8478AC*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:4403A7*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:6886A7*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:B4E9B0*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:000832*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:B0FAEB*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:500604*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:70105C*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:C067AF*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:000389*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-OUI:64E950*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:0CE0E4*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
OUI:B0AA77*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -33278,35 +34574,47 @@ OUI:602AD0*
OUI:001BFB*
ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
-OUI:0016FE*
- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
+OUI:00E08F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:3C08F6*
+OUI:203A07*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:D072DC*
+OUI:34A84E*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:28C7CE*
+OUI:E4D3F1*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:6CFA89*
+OUI:1CE6C7*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:58F39C*
+OUI:E02F6D*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:346288*
+OUI:8478AC*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:881DFC*
+OUI:4403A7*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000389*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+OUI:6886A7*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0CE0E4*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+OUI:B4E9B0*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:000832*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:B0FAEB*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:500604*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:70105C*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:7CFADF*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -33341,6 +34649,30 @@ OUI:002500*
OUI:60FB42*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:14DAE9*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:3C08F6*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:D072DC*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:28C7CE*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:6CFA89*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:58F39C*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:346288*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:881DFC*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
OUI:F81EDF*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -33368,31 +34700,10 @@ OUI:A4D1D2*
OUI:406C8F*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:00C610*
- ID_OUI_FROM_DATABASE=Apple, Inc.
-
-OUI:70DEE2*
- ID_OUI_FROM_DATABASE=Apple, Inc.
-
-OUI:0050F0*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:00905F*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:00902B*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:00100B*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:00100D*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:001014*
+OUI:C067AF*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00E08F*
+OUI:64E950*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:189C5D*
@@ -33410,93 +34721,102 @@ OUI:002618*
OUI:00248C*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:14DAE9*
- ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+OUI:0050A2*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:182032*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:0050F0*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:6CC26B*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:00905F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:1040F3*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:00902B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:FC253F*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:00100B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:183451*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:00100D*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:C0847A*
+OUI:001014*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:649ABE*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:64200C*
+OUI:94E96A*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:74E1B6*
+OUI:AC293A*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:0C771A*
+OUI:10417F*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:00F4B9*
+OUI:7014A6*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:C8334B*
+OUI:A8667F*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:B8F6B1*
+OUI:D02598*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:C09F42*
+OUI:CC29F5*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:189EFC*
+OUI:6C709F*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:6C3E6D*
+OUI:0C3E9F*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:8C2DAA*
+OUI:34E2FD*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:444C0C*
+OUI:609217*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:84FCFE*
+OUI:8863DF*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:E48B7F*
+OUI:80E650*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:94E96A*
+OUI:006171*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:AC293A*
+OUI:90FD61*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:10417F*
+OUI:5C97F3*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:7014A6*
+OUI:6C4008*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:A8667F*
+OUI:24A074*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:D02598*
+OUI:F02475*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:CC29F5*
+OUI:20A2E4*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:802994*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
+OUI:5CF5DA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:D4B8FF*
ID_OUI_FROM_DATABASE=Home Control Singapore Pte Ltd
+OUI:28E14C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:54E43A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
OUI:C8E0EB*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -33524,68 +34844,62 @@ OUI:B03495*
OUI:848E0C*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:6C709F*
- ID_OUI_FROM_DATABASE=Apple, Inc.
-
-OUI:0C3E9F*
- ID_OUI_FROM_DATABASE=Apple, Inc.
-
-OUI:34E2FD*
+OUI:8C2DAA*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:609217*
+OUI:444C0C*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:8863DF*
+OUI:84FCFE*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:80E650*
+OUI:E48B7F*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:006171*
+OUI:5C969D*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:90FD61*
+OUI:A8FAD8*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:5C97F3*
+OUI:949426*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:6C4008*
+OUI:E0F5C6*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:24A074*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:AC6462*
+ ID_OUI_FROM_DATABASE=zte corporation
-OUI:F02475*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:C08488*
+ ID_OUI_FROM_DATABASE=Finis Inc
-OUI:20A2E4*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:68E8EB*
+ ID_OUI_FROM_DATABASE=Linktel Technologies Co.,Ltd
-OUI:5CF5DA*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:20C3A4*
+ ID_OUI_FROM_DATABASE=RetailNext
-OUI:649ABE*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:780541*
+ ID_OUI_FROM_DATABASE=Queclink Wireless Solutions Co., Ltd
-OUI:5C969D*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:C02DEE*
+ ID_OUI_FROM_DATABASE=Cuff
-OUI:A8FAD8*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:54A3FA*
+ ID_OUI_FROM_DATABASE=BQT Solutions (Australia)Pty Ltd
-OUI:949426*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:30F772*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:E0F5C6*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:9023EC*
+ ID_OUI_FROM_DATABASE=Availink, Inc.
-OUI:28E14C*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:7467F7*
+ ID_OUI_FROM_DATABASE=Zebra Technologoes
-OUI:54E43A*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:3891D5*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
OUI:90DFFB*
ID_OUI_FROM_DATABASE=HOMERIDER SYSTEMS
@@ -33596,14 +34910,8 @@ OUI:3C831E*
OUI:381C23*
ID_OUI_FROM_DATABASE=Hilan Technology CO.,LTD
-OUI:AC6462*
- ID_OUI_FROM_DATABASE=zte corporation
-
-OUI:C08488*
- ID_OUI_FROM_DATABASE=Finis Inc
-
-OUI:8C99E6*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
+OUI:E03676*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
OUI:3CB72B*
ID_OUI_FROM_DATABASE=PLUMgrid Inc
@@ -33614,26 +34922,8 @@ OUI:243184*
OUI:24DA9B*
ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
-OUI:7467F7*
- ID_OUI_FROM_DATABASE=Zebra Technologoes
-
-OUI:3891D5*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
-OUI:68E8EB*
- ID_OUI_FROM_DATABASE=Linktel Technologies Co.,Ltd
-
-OUI:20C3A4*
- ID_OUI_FROM_DATABASE=RetailNext
-
-OUI:B844D9*
- ID_OUI_FROM_DATABASE=Apple, Inc.
-
-OUI:DC2B2A*
- ID_OUI_FROM_DATABASE=Apple, Inc.
-
-OUI:8C10D4*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+OUI:3052CB*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
OUI:B8B2EB*
ID_OUI_FROM_DATABASE=Googol Technology (HK) Limited
@@ -33644,17 +34934,20 @@ OUI:C40049*
OUI:50A9DE*
ID_OUI_FROM_DATABASE=Smartcom - Bulgaria AD
-OUI:C02DEE*
- ID_OUI_FROM_DATABASE=Cuff
+OUI:8809AF*
+ ID_OUI_FROM_DATABASE=Masimo Corp.
-OUI:54A3FA*
- ID_OUI_FROM_DATABASE=BQT Solutions (Australia)Pty Ltd
+OUI:E8DED6*
+ ID_OUI_FROM_DATABASE=Intrising Networks, Inc.
-OUI:30F772*
- ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+OUI:B844D9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:9023EC*
- ID_OUI_FROM_DATABASE=Availink, Inc.
+OUI:DC2B2A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:8C10D4*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:203D66*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -33665,26 +34958,11 @@ OUI:B83A9D*
OUI:089B4B*
ID_OUI_FROM_DATABASE=iKuai Networks
-OUI:780541*
- ID_OUI_FROM_DATABASE=Queclink Wireless Solutions Co., Ltd
-
OUI:3C7873*
ID_OUI_FROM_DATABASE=Airsonics
-OUI:3052CB*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
-OUI:54AB3A*
- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
-
-OUI:8809AF*
- ID_OUI_FROM_DATABASE=Masimo Corp.
-
-OUI:E8DED6*
- ID_OUI_FROM_DATABASE=Intrising Networks, Inc.
-
-OUI:E03676*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:BC5FF6*
+ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
OUI:C8F9C8*
ID_OUI_FROM_DATABASE=NewSharp Technology(SuZhou)Co,Ltd
@@ -33695,38 +34973,20 @@ OUI:3C5CC3*
OUI:A8741D*
ID_OUI_FROM_DATABASE=PHOENIX CONTACT Electronics GmbH
-OUI:F4C613*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
-OUI:D404CD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:EC0133*
- ID_OUI_FROM_DATABASE=TRINUS SYSTEMS INC.
-
-OUI:90D8F3*
- ID_OUI_FROM_DATABASE=zte corporation
-
-OUI:D84710*
- ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
-
-OUI:444CA8*
- ID_OUI_FROM_DATABASE=Arista Networks
-
OUI:A4C138*
ID_OUI_FROM_DATABASE=Telink Semiconductor (Taipei) Co. Ltd.
-OUI:683E34*
- ID_OUI_FROM_DATABASE=Meizu Technology Co., LTD
-
OUI:48E244*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
OUI:D8EFCD*
ID_OUI_FROM_DATABASE=Nokia
-OUI:BC5FF6*
- ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+OUI:D404CD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:EC0133*
+ ID_OUI_FROM_DATABASE=TRINUS SYSTEMS INC.
OUI:1C56FE*
ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
@@ -33755,9 +35015,33 @@ OUI:94F278*
OUI:E8BDD1*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:3481F4*
+ ID_OUI_FROM_DATABASE=SST Taiwan Ltd.
+
+OUI:F4B8A7*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:58F102*
+ ID_OUI_FROM_DATABASE=BLU Products Inc.
+
+OUI:B869C2*
+ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd.
+
+OUI:2CC548*
+ ID_OUI_FROM_DATABASE=IAdea Corporation
+
OUI:307CB2*
ID_OUI_FROM_DATABASE=ANOV FRANCE
+OUI:90D8F3*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:444CA8*
+ ID_OUI_FROM_DATABASE=Arista Networks
+
+OUI:FCE33C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
OUI:BC6A2F*
ID_OUI_FROM_DATABASE=Henge Docks LLC
@@ -33770,29 +35054,32 @@ OUI:48066A*
OUI:1CF03E*
ID_OUI_FROM_DATABASE=Wearhaus Inc.
-OUI:BCF811*
- ID_OUI_FROM_DATABASE=Xiamen DNAKE Technology Co.,Ltd
+OUI:DCDB70*
+ ID_OUI_FROM_DATABASE=Tonfunk Systementwicklung und Service GmbH
-OUI:A8827F*
- ID_OUI_FROM_DATABASE=CIBN Oriental Network(Beijing) CO.,Ltd
+OUI:C47D46*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
-OUI:609C9F*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+OUI:68EDA4*
+ ID_OUI_FROM_DATABASE=Shenzhen Seavo Technology Co.,Ltd
-OUI:249EAB*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:B899B0*
+ ID_OUI_FROM_DATABASE=Cohere Technologies
-OUI:DC56E6*
- ID_OUI_FROM_DATABASE=Shenzhen Bococom Technology Co.,LTD
+OUI:2CC5D3*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
-OUI:5CA178*
- ID_OUI_FROM_DATABASE=TableTop Media (dba Ziosk)
+OUI:80C5E6*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
-OUI:A0B437*
- ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSEMS
+OUI:D85DEF*
+ ID_OUI_FROM_DATABASE=Busch-Jaeger Elektro GmbH
-OUI:B89ACD*
- ID_OUI_FROM_DATABASE=ELITE OPTOELECTRONIC(ASIA)CO.,LTD
+OUI:10DF8B*
+ ID_OUI_FROM_DATABASE=Shenzhen CareDear Communication Technology Co.,Ltd
+
+OUI:00A784*
+ ID_OUI_FROM_DATABASE=ITX security
OUI:800184*
ID_OUI_FROM_DATABASE=HTC Corporation
@@ -33809,53 +35096,44 @@ OUI:C02567*
OUI:B46D35*
ID_OUI_FROM_DATABASE=Dalian Seasky Automation Co;Ltd
-OUI:FCE33C*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:68EDA4*
- ID_OUI_FROM_DATABASE=Shenzhen Seavo Technology Co.,Ltd
-
-OUI:B899B0*
- ID_OUI_FROM_DATABASE=Cohere Technologies
-
-OUI:2CC5D3*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
+OUI:B89ACD*
+ ID_OUI_FROM_DATABASE=ELITE OPTOELECTRONIC(ASIA)CO.,LTD
-OUI:80C5E6*
- ID_OUI_FROM_DATABASE=Microsoft Corporation
+OUI:241C04*
+ ID_OUI_FROM_DATABASE=SHENZHEN JEHE TECHNOLOGY DEVELOPMENT CO., LTD.
-OUI:D85DEF*
- ID_OUI_FROM_DATABASE=Busch-Jaeger Elektro GmbH
+OUI:F8CFC5*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
-OUI:10DF8B*
- ID_OUI_FROM_DATABASE=Shenzhen CareDear Communication Technology Co.,Ltd
+OUI:BCF811*
+ ID_OUI_FROM_DATABASE=Xiamen DNAKE Technology Co.,Ltd
-OUI:00A784*
- ID_OUI_FROM_DATABASE=ITX security
+OUI:A8827F*
+ ID_OUI_FROM_DATABASE=CIBN Oriental Network(Beijing) CO.,Ltd
-OUI:3481F4*
- ID_OUI_FROM_DATABASE=SST Taiwan Ltd.
+OUI:609C9F*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-OUI:F4B8A7*
- ID_OUI_FROM_DATABASE=zte corporation
+OUI:900A39*
+ ID_OUI_FROM_DATABASE=Wiio, Inc.
-OUI:58F102*
- ID_OUI_FROM_DATABASE=BLU Products Inc.
+OUI:C4693E*
+ ID_OUI_FROM_DATABASE=Turbulence Design Inc.
-OUI:B869C2*
- ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd.
+OUI:1C8341*
+ ID_OUI_FROM_DATABASE=Hefei Bitland Information Technology Co.Ltd
-OUI:2CC548*
- ID_OUI_FROM_DATABASE=IAdea Corporation
+OUI:4011DC*
+ ID_OUI_FROM_DATABASE=Sonance
-OUI:84DBFC*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
+OUI:249EAB*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:DCDB70*
- ID_OUI_FROM_DATABASE=Tonfunk Systementwicklung und Service GmbH
+OUI:DC56E6*
+ ID_OUI_FROM_DATABASE=Shenzhen Bococom Technology Co.,LTD
-OUI:C47D46*
- ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+OUI:5CA178*
+ ID_OUI_FROM_DATABASE=TableTop Media (dba Ziosk)
OUI:702A7D*
ID_OUI_FROM_DATABASE=EpSpot AB
@@ -33866,30 +35144,12 @@ OUI:B8B3DC*
OUI:347A60*
ID_OUI_FROM_DATABASE=Pace plc
-OUI:C4EA1D*
- ID_OUI_FROM_DATABASE=Technicolor
-
-OUI:900A39*
- ID_OUI_FROM_DATABASE=Wiio, Inc.
-
-OUI:C4693E*
- ID_OUI_FROM_DATABASE=Turbulence Design Inc.
-
-OUI:1C8341*
- ID_OUI_FROM_DATABASE=Hefei Bitland Information Technology Co.Ltd
-
OUI:6C1E70*
ID_OUI_FROM_DATABASE=Guangzhou YBDS IT Co.,Ltd
OUI:C8E130*
ID_OUI_FROM_DATABASE=Milkyway Group Ltd
-OUI:20E407*
- ID_OUI_FROM_DATABASE=Spark srl
-
-OUI:887384*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:8833BE*
ID_OUI_FROM_DATABASE=Ivenix, Inc.
@@ -33902,8 +35162,20 @@ OUI:144146*
OUI:F41563*
ID_OUI_FROM_DATABASE=F5 Networks, Inc.
-OUI:4011DC*
- ID_OUI_FROM_DATABASE=Sonance
+OUI:C4EA1D*
+ ID_OUI_FROM_DATABASE=Technicolor
+
+OUI:20E407*
+ ID_OUI_FROM_DATABASE=Spark srl
+
+OUI:887384*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:584704*
+ ID_OUI_FROM_DATABASE=Shenzhen Webridge Technology Co.,Ltd
+
+OUI:1C14B3*
+ ID_OUI_FROM_DATABASE=Pinyon Technologies
OUI:749CE3*
ID_OUI_FROM_DATABASE=Art2Wave Canada Inc.
@@ -33914,12 +35186,6 @@ OUI:B856BD*
OUI:107873*
ID_OUI_FROM_DATABASE=Shenzhen Jinkeyi Communication Co., Ltd.
-OUI:7CC709*
- ID_OUI_FROM_DATABASE=Shenzhen RF-LINK Elec&Technology.,Ltd
-
-OUI:3C8C40*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:D45556*
ID_OUI_FROM_DATABASE=Fiber Mountain Inc.
@@ -33941,9 +35207,6 @@ OUI:08D34B*
OUI:C808E9*
ID_OUI_FROM_DATABASE=LG Electronics
-OUI:589B0B*
- ID_OUI_FROM_DATABASE=Shineway Technologies, Inc.
-
OUI:78ACBF*
ID_OUI_FROM_DATABASE=Igneous Systems
@@ -33959,12 +35222,6 @@ OUI:844BB7*
OUI:148F21*
ID_OUI_FROM_DATABASE=Garmin International
-OUI:1C7D22*
- ID_OUI_FROM_DATABASE=Fuji Xerox Co., Ltd.
-
-OUI:ACD1B8*
- ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-
OUI:3C6A9D*
ID_OUI_FROM_DATABASE=Dexatek Technology LTD.
@@ -33974,20 +35231,20 @@ OUI:14893E*
OUI:60F189*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-OUI:241C04*
- ID_OUI_FROM_DATABASE=SHENZHEN JEHE TECHNOLOGY DEVELOPMENT CO., LTD.
+OUI:74A34A*
+ ID_OUI_FROM_DATABASE=ZIMI CORPORATION
-OUI:F8CFC5*
- ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+OUI:98F5A9*
+ ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO.,LTD.
-OUI:7C11CD*
- ID_OUI_FROM_DATABASE=QianTang Technology
+OUI:D89341*
+ ID_OUI_FROM_DATABASE=General Electric Global Research
-OUI:0492EE*
- ID_OUI_FROM_DATABASE=iway AG
+OUI:F4645D*
+ ID_OUI_FROM_DATABASE=Toshiba
-OUI:B04519*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
+OUI:30D587*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:1436C6*
ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
@@ -34001,23 +35258,8 @@ OUI:2C337A*
OUI:844464*
ID_OUI_FROM_DATABASE=ServerU Inc
-OUI:78312B*
- ID_OUI_FROM_DATABASE=zte corporation
-
-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
-
-OUI:F4645D*
- ID_OUI_FROM_DATABASE=Toshiba
-
-OUI:30D587*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:589B0B*
+ ID_OUI_FROM_DATABASE=Shineway Technologies, Inc.
OUI:A48CDB*
ID_OUI_FROM_DATABASE=Lenovo
@@ -34028,20 +35270,32 @@ OUI:4062B6*
OUI:3C2C94*
ID_OUI_FROM_DATABASE=杭州德澜科技有限公司(HangZhou Delan Technology Co.,Ltd)
-OUI:48A9D2*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
+OUI:78312B*
+ ID_OUI_FROM_DATABASE=zte corporation
-OUI:F02A23*
- ID_OUI_FROM_DATABASE=Creative Next Design
+OUI:C035C5*
+ ID_OUI_FROM_DATABASE=Prosoft Systems LTD
-OUI:584704*
- ID_OUI_FROM_DATABASE=Shenzhen Webridge Technology Co.,Ltd
+OUI:F8B2F3*
+ ID_OUI_FROM_DATABASE=GUANGZHOU BOSMA TECHNOLOGY CO.,LTD
-OUI:1C14B3*
- ID_OUI_FROM_DATABASE=Pinyon Technologies
+OUI:1C7D22*
+ ID_OUI_FROM_DATABASE=Fuji Xerox Co., Ltd.
-OUI:A0E4CB*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+OUI:ACD1B8*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:7C11CD*
+ ID_OUI_FROM_DATABASE=QianTang Technology
+
+OUI:0492EE*
+ ID_OUI_FROM_DATABASE=iway AG
+
+OUI:F02A23*
+ ID_OUI_FROM_DATABASE=Creative Next Design
+
+OUI:8C9109*
+ ID_OUI_FROM_DATABASE=Toyoshima Electric Technoeogy(Suzhou) Co.,Ltd.
OUI:307350*
ID_OUI_FROM_DATABASE=Inpeco SA
@@ -34052,17 +35306,32 @@ OUI:E8CC18*
OUI:B09137*
ID_OUI_FROM_DATABASE=ISis ImageStream Internet Solutions, Inc
-OUI:745C9F*
- ID_OUI_FROM_DATABASE=TCT mobile ltd.
-
OUI:3C1E13*
ID_OUI_FROM_DATABASE=HANGZHOU SUNRISE TECHNOLOGY CO., LTD
OUI:B4A828*
ID_OUI_FROM_DATABASE=Shenzhen Concox Information Technology Co., Ltd
-OUI:50F43C*
- ID_OUI_FROM_DATABASE=Leeo Inc
+OUI:A41242*
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
+
+OUI:404EEB*
+ ID_OUI_FROM_DATABASE=Higher Way Electronic Co., Ltd.
+
+OUI:50BD5F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:147590*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:ECB907*
+ ID_OUI_FROM_DATABASE=CloudGenix Inc
+
+OUI:5CF9F0*
+ ID_OUI_FROM_DATABASE=Atomos Engineering P/L
+
+OUI:F409D8*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
OUI:FCDBB3*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
@@ -34088,8 +35357,8 @@ OUI:C0EEFB*
OUI:E00DB9*
ID_OUI_FROM_DATABASE=Private
-OUI:A41242*
- ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
+OUI:108A1B*
+ ID_OUI_FROM_DATABASE=RAONIX Inc.
OUI:8CF813*
ID_OUI_FROM_DATABASE=ORANGE POLSKA
@@ -34109,8 +35378,26 @@ OUI:C401CE*
OUI:D01242*
ID_OUI_FROM_DATABASE=BIOS Corporation
-OUI:6CBFB5*
- ID_OUI_FROM_DATABASE=Noon Technology Co., Ltd
+OUI:50F43C*
+ ID_OUI_FROM_DATABASE=Leeo Inc
+
+OUI:B43934*
+ ID_OUI_FROM_DATABASE=Pen Generations, Inc.
+
+OUI:C03896*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+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.
+
+OUI:CC10A3*
+ ID_OUI_FROM_DATABASE=Beijing Nan Bao Technology Co., Ltd.
OUI:2CA30E*
ID_OUI_FROM_DATABASE=POWER DRAGON DEVELOPMENT LIMITED
@@ -34136,50 +35423,8 @@ OUI:CC3080*
OUI:F82441*
ID_OUI_FROM_DATABASE=Yeelink
-OUI:108A1B*
- ID_OUI_FROM_DATABASE=RAONIX Inc.
-
-OUI:94B40F*
- ID_OUI_FROM_DATABASE=Aruba Networks
-
-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.
-
-OUI:CC3F1D*
- ID_OUI_FROM_DATABASE=Intesis Software SL
-
-OUI:902181*
- ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd
-
-OUI:D062A0*
- ID_OUI_FROM_DATABASE=China Essence Technology (Zhumadian) Co., Ltd.
-
-OUI:CC10A3*
- ID_OUI_FROM_DATABASE=Beijing Nan Bao Technology Co., Ltd.
-
-OUI:B43934*
- ID_OUI_FROM_DATABASE=Pen Generations, Inc.
-
-OUI:C03896*
- ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-
-OUI:DCC622*
- ID_OUI_FROM_DATABASE=BUHEUNG SYSTEM
-
-OUI:5C2BF5*
- ID_OUI_FROM_DATABASE=Vivint
-
-OUI:6C0B84*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co.,Ltd.
-
-OUI:600417*
- ID_OUI_FROM_DATABASE=POSBANK CO.,LTD
+OUI:6CBFB5*
+ ID_OUI_FROM_DATABASE=Noon Technology Co., Ltd
OUI:489D18*
ID_OUI_FROM_DATABASE=Flashbay Limited
@@ -34199,17 +35444,26 @@ OUI:E4C62B*
OUI:80F8EB*
ID_OUI_FROM_DATABASE=RayTight
-OUI:F409D8*
- ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+OUI:94B40F*
+ ID_OUI_FROM_DATABASE=Aruba Networks
-OUI:C035C5*
- ID_OUI_FROM_DATABASE=Prosoft Systems LTD
+OUI:4C2C83*
+ ID_OUI_FROM_DATABASE=Zhejiang KaNong Network Technology Co.,Ltd.
-OUI:F8B2F3*
- ID_OUI_FROM_DATABASE=GUANGZHOU BOSMA TECHNOLOGY CO.,LTD
+OUI:BCC342*
+ ID_OUI_FROM_DATABASE=Panasonic System Networks Co., Ltd.
-OUI:8C9109*
- ID_OUI_FROM_DATABASE=Toyoshima Electric Technoeogy(Suzhou) Co.,Ltd.
+OUI:E89606*
+ ID_OUI_FROM_DATABASE=testo Instruments (Shenzhen) Co., Ltd.
+
+OUI:CC3F1D*
+ ID_OUI_FROM_DATABASE=Intesis Software SL
+
+OUI:902181*
+ ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd
+
+OUI:600417*
+ ID_OUI_FROM_DATABASE=POSBANK CO.,LTD
OUI:A44AD3*
ID_OUI_FROM_DATABASE=ST Electronics(Shanghai) Co.,Ltd
@@ -34238,11 +35492,23 @@ OUI:907EBA*
OUI:488244*
ID_OUI_FROM_DATABASE=Life Fitness / Div. of Brunswick
-OUI:D85DFB*
- ID_OUI_FROM_DATABASE=Private
+OUI:A8F7E0*
+ ID_OUI_FROM_DATABASE=PLANET Technology Corporation
-OUI:7CC4EF*
- ID_OUI_FROM_DATABASE=Devialet
+OUI:2C5BE1*
+ ID_OUI_FROM_DATABASE=Centripetal Networks, Inc
+
+OUI:D87EB1*
+ ID_OUI_FROM_DATABASE=x.o.ware, inc.
+
+OUI:4045DA*
+ ID_OUI_FROM_DATABASE=Spreadtrum Communications (Shanghai) Co., Ltd.
+
+OUI:98BE94*
+ ID_OUI_FROM_DATABASE=IBM
+
+OUI:D4B43E*
+ ID_OUI_FROM_DATABASE=Messcomp Datentechnik GmbH
OUI:A8E539*
ID_OUI_FROM_DATABASE=Moimstone Co.,Ltd
@@ -34253,27 +35519,21 @@ OUI:98F170*
OUI:04C991*
ID_OUI_FROM_DATABASE=Phistek INC.
-OUI:404EEB*
- ID_OUI_FROM_DATABASE=Higher Way Electronic Co., Ltd.
-
-OUI:50BD5F*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:147590*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:ECB907*
- ID_OUI_FROM_DATABASE=CloudGenix Inc
-
-OUI:5CF9F0*
- ID_OUI_FROM_DATABASE=Atomos Engineering P/L
-
OUI:581F67*
ID_OUI_FROM_DATABASE=Open-m technology limited
OUI:BC25F0*
ID_OUI_FROM_DATABASE=3D Display Technologies Co., Ltd.
+OUI:7CE524*
+ ID_OUI_FROM_DATABASE=Quirky, Inc.
+
+OUI:D85DFB*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CC4EF*
+ ID_OUI_FROM_DATABASE=Devialet
+
OUI:94AEE3*
ID_OUI_FROM_DATABASE=Belden Hirschmann Industries (Suzhou) Ltd.
@@ -34286,6 +35546,15 @@ OUI:705B2E*
OUI:0C8C8F*
ID_OUI_FROM_DATABASE=Kamo Technology Limited
+OUI:F4FD2B*
+ ID_OUI_FROM_DATABASE=ZOYI Company
+
+OUI:FCAA14*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:50FEF2*
+ ID_OUI_FROM_DATABASE=Sify Technologies Ltd
+
OUI:3CD9CE*
ID_OUI_FROM_DATABASE=Eclipse WiFi
@@ -34307,27 +35576,6 @@ OUI:ECD9D1*
OUI:748F4D*
ID_OUI_FROM_DATABASE=MEN Mikro Elektronik GmbH
-OUI:F4FD2B*
- ID_OUI_FROM_DATABASE=ZOYI Company
-
-OUI:FCAA14*
- ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
-
-OUI:50FEF2*
- ID_OUI_FROM_DATABASE=Sify Technologies Ltd
-
-OUI:7CE524*
- ID_OUI_FROM_DATABASE=Quirky, Inc.
-
-OUI:7CD30A*
- ID_OUI_FROM_DATABASE=INVENTEC Corporation
-
-OUI:3481C4*
- ID_OUI_FROM_DATABASE=AVM GmbH
-
-OUI:885BDD*
- ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
-
OUI:A47E39*
ID_OUI_FROM_DATABASE=zte corporation
@@ -34340,23 +35588,17 @@ OUI:ACA9A0*
OUI:A8A668*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:A8F7E0*
- ID_OUI_FROM_DATABASE=PLANET Technology Corporation
-
-OUI:2C5BE1*
- ID_OUI_FROM_DATABASE=Centripetal Networks, Inc
-
-OUI:D87EB1*
- ID_OUI_FROM_DATABASE=x.o.ware, inc.
+OUI:60E327*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:4045DA*
- ID_OUI_FROM_DATABASE=Spreadtrum Communications (Shanghai) Co., Ltd.
+OUI:E4D332*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:98BE94*
- ID_OUI_FROM_DATABASE=IBM
+OUI:A0DA92*
+ ID_OUI_FROM_DATABASE=Nanjing Glarun Atten Technology Co. Ltd.
-OUI:D4B43E*
- ID_OUI_FROM_DATABASE=Messcomp Datentechnik GmbH
+OUI:6828BA*
+ ID_OUI_FROM_DATABASE=Dejai
OUI:48D18E*
ID_OUI_FROM_DATABASE=Metis Communication Co.,Ltd
@@ -34364,6 +35606,18 @@ OUI:48D18E*
OUI:A49F85*
ID_OUI_FROM_DATABASE=Lyve Minds, Inc
+OUI:7CD30A*
+ ID_OUI_FROM_DATABASE=INVENTEC Corporation
+
+OUI:3481C4*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:885BDD*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
+
+OUI:085700*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
OUI:888914*
ID_OUI_FROM_DATABASE=All Components Incorporated
@@ -34376,8 +35630,8 @@ OUI:A06518*
OUI:748F1B*
ID_OUI_FROM_DATABASE=MasterImage 3D
-OUI:684898*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:F03A4B*
+ ID_OUI_FROM_DATABASE=Bloombase, Inc.
OUI:E4121D*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -34442,20 +35696,17 @@ OUI:50B695*
OUI:B48547*
ID_OUI_FROM_DATABASE=Amptown System Company GmbH
-OUI:085700*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
-OUI:60E327*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:3C25D7*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:E4D332*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:1889DF*
+ ID_OUI_FROM_DATABASE=CerebrEX Inc.
-OUI:A0DA92*
- ID_OUI_FROM_DATABASE=Nanjing Glarun Atten Technology Co. Ltd.
+OUI:30A8DB*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
-OUI:6828BA*
- ID_OUI_FROM_DATABASE=Dejai
+OUI:CC9F35*
+ ID_OUI_FROM_DATABASE=Transbit Sp. z o.o.
OUI:407875*
ID_OUI_FROM_DATABASE=IMBEL - Industria de Material Belico do Brasil
@@ -34487,29 +35738,23 @@ OUI:88E8F8*
OUI:2C073C*
ID_OUI_FROM_DATABASE=DEVLINE LIMITED
-OUI:F015A0*
- ID_OUI_FROM_DATABASE=KyungDong One Co., Ltd.
-
-OUI:ECF72B*
- ID_OUI_FROM_DATABASE=HD DIGITAL TECH CO., LTD.
-
-OUI:D8B6D6*
- ID_OUI_FROM_DATABASE=Blu Tether Limited
+OUI:7CE4AA*
+ ID_OUI_FROM_DATABASE=Private
-OUI:847207*
- ID_OUI_FROM_DATABASE=I&C Technology
+OUI:1820A6*
+ ID_OUI_FROM_DATABASE=Sage Co., Ltd.
-OUI:3C25D7*
- ID_OUI_FROM_DATABASE=Nokia Corporation
+OUI:BCF61C*
+ ID_OUI_FROM_DATABASE=Geomodeling Wuxi Technology Co. Ltd.
-OUI:1889DF*
- ID_OUI_FROM_DATABASE=CerebrEX Inc.
+OUI:083F3E*
+ ID_OUI_FROM_DATABASE=WSH GmbH
-OUI:30A8DB*
- ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+OUI:6C09D6*
+ ID_OUI_FROM_DATABASE=Digiquest Electronics LTD
-OUI:CC9F35*
- ID_OUI_FROM_DATABASE=Transbit Sp. z o.o.
+OUI:684898*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:8C569D*
ID_OUI_FROM_DATABASE=Imaging Solutions Group
@@ -34532,27 +35777,6 @@ OUI:4CE1BB*
OUI:8CDE99*
ID_OUI_FROM_DATABASE=Comlab Inc.
-OUI:085AE0*
- ID_OUI_FROM_DATABASE=Recovision Technology Co., Ltd.
-
-OUI:7CE4AA*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:1820A6*
- ID_OUI_FROM_DATABASE=Sage Co., Ltd.
-
-OUI:BCF61C*
- ID_OUI_FROM_DATABASE=Geomodeling Wuxi Technology Co. Ltd.
-
-OUI:083F3E*
- ID_OUI_FROM_DATABASE=WSH GmbH
-
-OUI:6C09D6*
- ID_OUI_FROM_DATABASE=Digiquest Electronics LTD
-
-OUI:F03A4B*
- ID_OUI_FROM_DATABASE=Bloombase, Inc.
-
OUI:2C9AA4*
ID_OUI_FROM_DATABASE=NGI SpA
@@ -34565,50 +35789,32 @@ OUI:283B96*
OUI:80D433*
ID_OUI_FROM_DATABASE=LzLabs GmbH
-OUI:687CC8*
- ID_OUI_FROM_DATABASE=Measurement Systems S. de R.L.
-
-OUI:38BF2F*
- ID_OUI_FROM_DATABASE=Espec Corp.
-
-OUI:182012*
- ID_OUI_FROM_DATABASE=Aztech Associates Inc.
-
-OUI:34BE00*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:343111*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:0CBD51*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
-OUI:C0F991*
- ID_OUI_FROM_DATABASE=GME Standard Communications P/L
+OUI:085AE0*
+ ID_OUI_FROM_DATABASE=Recovision Technology Co., Ltd.
-OUI:14EDA5*
- ID_OUI_FROM_DATABASE=Wächter GmbH Sicherheitssysteme
+OUI:BCEE7B*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:E056F4*
- ID_OUI_FROM_DATABASE=AxesNetwork Solutions inc.
+OUI:FC09D8*
+ ID_OUI_FROM_DATABASE=ACTEON Group
-OUI:B8C1A2*
- ID_OUI_FROM_DATABASE=Dragon Path Technologies Co., Limited
+OUI:0C1262*
+ ID_OUI_FROM_DATABASE=zte corporation
-OUI:50ED78*
- ID_OUI_FROM_DATABASE=Changzhou Yongse Infotech Co.,Ltd
+OUI:687CC8*
+ ID_OUI_FROM_DATABASE=Measurement Systems S. de R.L.
-OUI:8CB7F7*
- ID_OUI_FROM_DATABASE=Shenzhen UniStrong Science & Technology Co., Ltd
+OUI:F015A0*
+ ID_OUI_FROM_DATABASE=KyungDong One Co., Ltd.
-OUI:085240*
- ID_OUI_FROM_DATABASE=EbV Elektronikbau- und Vertriebs GmbH
+OUI:ECF72B*
+ ID_OUI_FROM_DATABASE=HD DIGITAL TECH CO., LTD.
-OUI:80F25E*
- ID_OUI_FROM_DATABASE=Kyynel
+OUI:D8B6D6*
+ ID_OUI_FROM_DATABASE=Blu Tether Limited
-OUI:94DF4E*
- ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd.
+OUI:847207*
+ ID_OUI_FROM_DATABASE=I&C Technology
OUI:E0AEB2*
ID_OUI_FROM_DATABASE=Bender GmbH &amp; Co.KG
@@ -34622,15 +35828,27 @@ OUI:B43E3B*
OUI:F854AF*
ID_OUI_FROM_DATABASE=ECI Telecom Ltd.
-OUI:7C0623*
- ID_OUI_FROM_DATABASE=Ultra Electronics, CIS
-
OUI:2464EF*
ID_OUI_FROM_DATABASE=CYG SUNRI CO.,LTD.
OUI:50B888*
ID_OUI_FROM_DATABASE=wi2be Tecnologia S/A
+OUI:B8C1A2*
+ ID_OUI_FROM_DATABASE=Dragon Path Technologies Co., Limited
+
+OUI:50ED78*
+ ID_OUI_FROM_DATABASE=Changzhou Yongse Infotech Co.,Ltd
+
+OUI:8CB7F7*
+ ID_OUI_FROM_DATABASE=Shenzhen UniStrong Science & Technology Co., Ltd
+
+OUI:085240*
+ ID_OUI_FROM_DATABASE=EbV Elektronikbau- und Vertriebs GmbH
+
+OUI:80F25E*
+ ID_OUI_FROM_DATABASE=Kyynel
+
OUI:844F03*
ID_OUI_FROM_DATABASE=Ablelink Electronics Ltd
@@ -34664,11 +35882,59 @@ OUI:D46867*
OUI:68692E*
ID_OUI_FROM_DATABASE=Zycoo Co.,Ltd
-OUI:1C63B7*
- ID_OUI_FROM_DATABASE=OpenProducts 237 AB
+OUI:A875E2*
+ ID_OUI_FROM_DATABASE=Aventura Technologies, Inc.
-OUI:A0A23C*
- ID_OUI_FROM_DATABASE=GPMS
+OUI:38BF2F*
+ ID_OUI_FROM_DATABASE=Espec Corp.
+
+OUI:182012*
+ ID_OUI_FROM_DATABASE=Aztech Associates Inc.
+
+OUI:34BE00*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:343111*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C0F991*
+ ID_OUI_FROM_DATABASE=GME Standard Communications P/L
+
+OUI:14EDA5*
+ ID_OUI_FROM_DATABASE=Wächter GmbH Sicherheitssysteme
+
+OUI:E056F4*
+ ID_OUI_FROM_DATABASE=AxesNetwork Solutions inc.
+
+OUI:385AA8*
+ ID_OUI_FROM_DATABASE=Beijing Zhongdun Security Technology Development Co.
+
+OUI:FC3FAB*
+ ID_OUI_FROM_DATABASE=Henan Lanxin Technology Co., Ltd
+
+OUI:F8FF5F*
+ ID_OUI_FROM_DATABASE=Shenzhen Communication Technology Co.,Ltd
+
+OUI:DCC422*
+ ID_OUI_FROM_DATABASE=Systembase Limited
+
+OUI:F4BD7C*
+ ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD
+
+OUI:C8F36B*
+ ID_OUI_FROM_DATABASE=Yamato Scale Co.,Ltd.
+
+OUI:6C90B1*
+ ID_OUI_FROM_DATABASE=SanLogic Inc
+
+OUI:845C93*
+ ID_OUI_FROM_DATABASE=Chabrier Services
+
+OUI:D44C9C*
+ ID_OUI_FROM_DATABASE=Shenzhen YOOBAO Technology Co.Ltd
+
+OUI:A88D7B*
+ ID_OUI_FROM_DATABASE=SunDroid Global limited.
OUI:A03B1B*
ID_OUI_FROM_DATABASE=Inspire Tech
@@ -34691,47 +35957,17 @@ OUI:6C4B7F*
OUI:0CCB8D*
ID_OUI_FROM_DATABASE=ASCO Numatics GmbH
-OUI:FC019E*
- ID_OUI_FROM_DATABASE=VIEVU
-
-OUI:34AA8B*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:F45F69*
- ID_OUI_FROM_DATABASE=Matsufu Electronics distribution Company
-
-OUI:F4A294*
- ID_OUI_FROM_DATABASE=EAGLE WORLD DEVELOPMENT CO., LIMITED
-
-OUI:2CCD69*
- ID_OUI_FROM_DATABASE=Aqavi.com
-
-OUI:947C3E*
- ID_OUI_FROM_DATABASE=Polewall Norge AS
-
-OUI:385AA8*
- ID_OUI_FROM_DATABASE=Beijing Zhongdun Security Technology Development Co.
-
-OUI:FC3FAB*
- ID_OUI_FROM_DATABASE=Henan Lanxin Technology Co., Ltd
-
OUI:2847AA*
ID_OUI_FROM_DATABASE=Nokia Corporation
OUI:682DDC*
ID_OUI_FROM_DATABASE=Wuhan Changjiang Electro-Communication Equipment CO.,LTD
-OUI:FCB0C4*
- ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd
-
-OUI:9CBB98*
- ID_OUI_FROM_DATABASE=Shen Zhen RND Electronic Co.,LTD
-
-OUI:345C40*
- ID_OUI_FROM_DATABASE=Cargt Holdings LLC
+OUI:1C63B7*
+ ID_OUI_FROM_DATABASE=OpenProducts 237 AB
-OUI:34885D*
- ID_OUI_FROM_DATABASE=Logitech Far East
+OUI:A0A23C*
+ ID_OUI_FROM_DATABASE=GPMS
OUI:708D09*
ID_OUI_FROM_DATABASE=Nokia Corporation
@@ -34745,8 +35981,14 @@ OUI:38B74D*
OUI:A0E5E9*
ID_OUI_FROM_DATABASE=enimai Inc
-OUI:A88D7B*
- ID_OUI_FROM_DATABASE=SunDroid Global limited.
+OUI:9CBB98*
+ ID_OUI_FROM_DATABASE=Shen Zhen RND Electronic Co.,LTD
+
+OUI:345C40*
+ ID_OUI_FROM_DATABASE=Cargt Holdings LLC
+
+OUI:34885D*
+ ID_OUI_FROM_DATABASE=Logitech Far East
OUI:6064A1*
ID_OUI_FROM_DATABASE=RADiflow Ltd.
@@ -34766,20 +36008,23 @@ OUI:FC1BFF*
OUI:AC5036*
ID_OUI_FROM_DATABASE=Pi-Coral Inc
-OUI:BCEE7B*
- ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+OUI:FC019E*
+ ID_OUI_FROM_DATABASE=VIEVU
-OUI:8C3AE3*
- ID_OUI_FROM_DATABASE=LG Electronics
+OUI:34AA8B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:FC09D8*
- ID_OUI_FROM_DATABASE=ACTEON Group
+OUI:F45F69*
+ ID_OUI_FROM_DATABASE=Matsufu Electronics distribution Company
-OUI:0C1262*
- ID_OUI_FROM_DATABASE=zte corporation
+OUI:F4A294*
+ ID_OUI_FROM_DATABASE=EAGLE WORLD DEVELOPMENT CO., LIMITED
-OUI:A875E2*
- ID_OUI_FROM_DATABASE=Aventura Technologies, Inc.
+OUI:2CCD69*
+ ID_OUI_FROM_DATABASE=Aqavi.com
+
+OUI:947C3E*
+ ID_OUI_FROM_DATABASE=Polewall Norge AS
OUI:E0D1E6*
ID_OUI_FROM_DATABASE=Aliph dba Jawbone
@@ -34805,35 +36050,17 @@ OUI:306112*
OUI:A0C6EC*
ID_OUI_FROM_DATABASE=ShenZhen ANYK Technology Co.,LTD
-OUI:6405BE*
- ID_OUI_FROM_DATABASE=NEW LIGHT LED
-
-OUI:F8FF5F*
- ID_OUI_FROM_DATABASE=Shenzhen Communication Technology Co.,Ltd
-
-OUI:DCC422*
- ID_OUI_FROM_DATABASE=Systembase Limited
-
-OUI:F4BD7C*
- ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD
-
-OUI:C8F36B*
- ID_OUI_FROM_DATABASE=Yamato Scale Co.,Ltd.
-
-OUI:6C90B1*
- ID_OUI_FROM_DATABASE=SanLogic Inc
-
-OUI:845C93*
- ID_OUI_FROM_DATABASE=Chabrier Services
+OUI:C80258*
+ ID_OUI_FROM_DATABASE=ITW GSE ApS
-OUI:D44C9C*
- ID_OUI_FROM_DATABASE=Shenzhen YOOBAO Technology Co.Ltd
+OUI:1001CA*
+ ID_OUI_FROM_DATABASE=Ashley Butterworth
-OUI:68E166*
- ID_OUI_FROM_DATABASE=Private
+OUI:246AAB*
+ ID_OUI_FROM_DATABASE=IT-IS International
-OUI:60FEF9*
- ID_OUI_FROM_DATABASE=Thomas & Betts
+OUI:28F532*
+ ID_OUI_FROM_DATABASE=ADD-Engineering BV
OUI:FC4BBC*
ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd.
@@ -34871,35 +36098,26 @@ OUI:E8519D*
OUI:00B78D*
ID_OUI_FROM_DATABASE=Nanjing Shining Electric Automation Co., Ltd
-OUI:882364*
- ID_OUI_FROM_DATABASE=Watchnet DVR Inc
-
-OUI:A05B21*
- ID_OUI_FROM_DATABASE=ENVINET GmbH
-
-OUI:50B8A2*
- ID_OUI_FROM_DATABASE=ImTech Technologies LLC,
-
-OUI:A41566*
- ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
+OUI:68E166*
+ ID_OUI_FROM_DATABASE=Private
-OUI:B04C05*
- ID_OUI_FROM_DATABASE=Fresenius Medical Care Deutschland GmbH
+OUI:60FEF9*
+ ID_OUI_FROM_DATABASE=Thomas & Betts
-OUI:A0EC80*
- ID_OUI_FROM_DATABASE=zte corporation
+OUI:78FE41*
+ ID_OUI_FROM_DATABASE=Socus networks
-OUI:9046B7*
- ID_OUI_FROM_DATABASE=Vadaro Pte Ltd
+OUI:083571*
+ ID_OUI_FROM_DATABASE=CASwell INC.
-OUI:1C08C1*
- ID_OUI_FROM_DATABASE=Lg Innotek
+OUI:DCF755*
+ ID_OUI_FROM_DATABASE=SITRONIK
-OUI:201D03*
- ID_OUI_FROM_DATABASE=Elatec GmbH
+OUI:ACCA8E*
+ ID_OUI_FROM_DATABASE=ODA Technologies
-OUI:C06C6D*
- ID_OUI_FROM_DATABASE=MagneMotion, Inc.
+OUI:6405BE*
+ ID_OUI_FROM_DATABASE=NEW LIGHT LED
OUI:E03E4A*
ID_OUI_FROM_DATABASE=Cavanagh Group International
@@ -34910,9 +36128,6 @@ OUI:D890E8*
OUI:24C696*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:30766F*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:6CB350*
ID_OUI_FROM_DATABASE=Anhui comhigher tech co.,ltd
@@ -34925,32 +36140,35 @@ OUI:1C86AD*
OUI:28D93E*
ID_OUI_FROM_DATABASE=Telecor Inc.
-OUI:C80258*
- ID_OUI_FROM_DATABASE=ITW GSE ApS
+OUI:882364*
+ ID_OUI_FROM_DATABASE=Watchnet DVR Inc
-OUI:1001CA*
- ID_OUI_FROM_DATABASE=Ashley Butterworth
+OUI:A05B21*
+ ID_OUI_FROM_DATABASE=ENVINET GmbH
-OUI:246AAB*
- ID_OUI_FROM_DATABASE=IT-IS International
+OUI:50B8A2*
+ ID_OUI_FROM_DATABASE=ImTech Technologies LLC,
-OUI:28F532*
- ID_OUI_FROM_DATABASE=ADD-Engineering BV
+OUI:A41566*
+ ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
-OUI:78FE41*
- ID_OUI_FROM_DATABASE=Socus networks
+OUI:B04C05*
+ ID_OUI_FROM_DATABASE=Fresenius Medical Care Deutschland GmbH
-OUI:083571*
- ID_OUI_FROM_DATABASE=CASwell INC.
+OUI:A0EC80*
+ ID_OUI_FROM_DATABASE=zte corporation
-OUI:DCF755*
- ID_OUI_FROM_DATABASE=SITRONIK
+OUI:9046B7*
+ ID_OUI_FROM_DATABASE=Vadaro Pte Ltd
-OUI:E42D02*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
+OUI:1C08C1*
+ ID_OUI_FROM_DATABASE=Lg Innotek
-OUI:ACCA8E*
- ID_OUI_FROM_DATABASE=ODA Technologies
+OUI:201D03*
+ ID_OUI_FROM_DATABASE=Elatec GmbH
+
+OUI:C06C6D*
+ ID_OUI_FROM_DATABASE=MagneMotion, Inc.
OUI:74CA25*
ID_OUI_FROM_DATABASE=Calxeda, Inc.
@@ -34961,6 +36179,42 @@ OUI:181EB0*
OUI:CCBD35*
ID_OUI_FROM_DATABASE=Steinel GmbH
+OUI:788DF7*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:6CECA1*
+ ID_OUI_FROM_DATABASE=SHENZHEN CLOU ELECTRONICS CO. LTD.
+
+OUI:D862DB*
+ ID_OUI_FROM_DATABASE=Eno Inc.
+
+OUI:68DB67*
+ ID_OUI_FROM_DATABASE=Nantong Coship Electronics Co., Ltd
+
+OUI:BC261D*
+ ID_OUI_FROM_DATABASE=HONG KONG TECON TECHNOLOGY
+
+OUI:888964*
+ ID_OUI_FROM_DATABASE=GSI Electronics Inc.
+
+OUI:4C82CF*
+ ID_OUI_FROM_DATABASE=Echostar Technologies
+
+OUI:9CA577*
+ ID_OUI_FROM_DATABASE=Osorno Enterprises Inc.
+
+OUI:C0C3B6*
+ ID_OUI_FROM_DATABASE=Automatic Systems
+
+OUI:A8294C*
+ ID_OUI_FROM_DATABASE=Precision Optical Transceivers, Inc.
+
+OUI:D0EB03*
+ ID_OUI_FROM_DATABASE=Zhehua technology limited
+
+OUI:A0861D*
+ ID_OUI_FROM_DATABASE=Chengdu Fuhuaxin Technology co.,Ltd
+
OUI:9498A2*
ID_OUI_FROM_DATABASE=Shanghai LISTEN TECH.LTD
@@ -34979,89 +36233,89 @@ OUI:D82916*
OUI:6472D8*
ID_OUI_FROM_DATABASE=GooWi Technology Co.,Limited
-OUI:3C081E*
- ID_OUI_FROM_DATABASE=Beijing Yupont Electric Power Technology Co.,Ltd
+OUI:84ACA4*
+ ID_OUI_FROM_DATABASE=Beijing Novel Super Digital TV Technology Co., Ltd
-OUI:7CA15D*
- ID_OUI_FROM_DATABASE=GN ReSound A/S
+OUI:3C6FF7*
+ ID_OUI_FROM_DATABASE=EnTek Systems, Inc.
-OUI:B4DD15*
- ID_OUI_FROM_DATABASE=ControlThings Oy Ab
+OUI:B838CA*
+ ID_OUI_FROM_DATABASE=Kyokko Tsushin System CO.,LTD
-OUI:F8FEA8*
- ID_OUI_FROM_DATABASE=Technico Japan Corporation
+OUI:380FE4*
+ ID_OUI_FROM_DATABASE=Dedicated Network Partners Oy
-OUI:A8154D*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:847A88*
+ ID_OUI_FROM_DATABASE=HTC Corporation
-OUI:D05099*
- ID_OUI_FROM_DATABASE=ASRock Incorporation
+OUI:0808C2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:78A106*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:5461EA*
+ ID_OUI_FROM_DATABASE=Zaplox AB
-OUI:A49EDB*
- ID_OUI_FROM_DATABASE=AutoCrib, Inc.
+OUI:78324F*
+ ID_OUI_FROM_DATABASE=Millennium Group, Inc.
-OUI:282CB2*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:F05DC8*
+ ID_OUI_FROM_DATABASE=Duracell Powermat
-OUI:D43A65*
- ID_OUI_FROM_DATABASE=IGRS Engineering Lab Ltd.
+OUI:48F925*
+ ID_OUI_FROM_DATABASE=Maestronic
-OUI:D0EB03*
- ID_OUI_FROM_DATABASE=Zhehua technology limited
+OUI:C0885B*
+ ID_OUI_FROM_DATABASE=SnD Tech Co., Ltd.
-OUI:A0861D*
- ID_OUI_FROM_DATABASE=Chengdu Fuhuaxin Technology co.,Ltd
+OUI:64C667*
+ ID_OUI_FROM_DATABASE=Barnes&Noble
-OUI:888964*
- ID_OUI_FROM_DATABASE=GSI Electronics Inc.
+OUI:C47DCC*
+ ID_OUI_FROM_DATABASE=Zebra Technologies Inc
-OUI:4C82CF*
- ID_OUI_FROM_DATABASE=Echostar Technologies
+OUI:64535D*
+ ID_OUI_FROM_DATABASE=Frauscher Sensortechnik
-OUI:9CA577*
- ID_OUI_FROM_DATABASE=Osorno Enterprises Inc.
+OUI:105F06*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
-OUI:C0C3B6*
- ID_OUI_FROM_DATABASE=Automatic Systems
+OUI:841715*
+ ID_OUI_FROM_DATABASE=GP Electronics (HK) Ltd.
-OUI:A8294C*
- ID_OUI_FROM_DATABASE=Precision Optical Transceivers, Inc.
+OUI:087999*
+ ID_OUI_FROM_DATABASE=AIM GmbH
-OUI:3C86A8*
- ID_OUI_FROM_DATABASE=Sangshin elecom .co,, LTD
+OUI:84C2E4*
+ ID_OUI_FROM_DATABASE=Jiangsu Qinheng Co., Ltd.
-OUI:FCDD55*
- ID_OUI_FROM_DATABASE=Shenzhen WeWins wireless Co.,Ltd
+OUI:C0B8B1*
+ ID_OUI_FROM_DATABASE=BitBox Ltd
-OUI:CC0DEC*
- ID_OUI_FROM_DATABASE=Cisco SPVTG
+OUI:0C722C*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:68B094*
- ID_OUI_FROM_DATABASE=INESA ELECTRON CO.,LTD
+OUI:B01408*
+ ID_OUI_FROM_DATABASE=LIGHTSPEED INTERNATIONAL CO.
-OUI:40E730*
- ID_OUI_FROM_DATABASE=DEY Storage Systems, Inc.
+OUI:F8FEA8*
+ ID_OUI_FROM_DATABASE=Technico Japan Corporation
-OUI:F05DC8*
- ID_OUI_FROM_DATABASE=Duracell Powermat
+OUI:A8154D*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:6C8686*
- ID_OUI_FROM_DATABASE=Technonia
+OUI:D05099*
+ ID_OUI_FROM_DATABASE=ASRock Incorporation
-OUI:4432C8*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
+OUI:78A106*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:78521A*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:A49EDB*
+ ID_OUI_FROM_DATABASE=AutoCrib, Inc.
-OUI:68DB67*
- ID_OUI_FROM_DATABASE=Nantong Coship Electronics Co., Ltd
+OUI:282CB2*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:BC261D*
- ID_OUI_FROM_DATABASE=HONG KONG TECON TECHNOLOGY
+OUI:D43A65*
+ ID_OUI_FROM_DATABASE=IGRS Engineering Lab Ltd.
OUI:10B9FE*
ID_OUI_FROM_DATABASE=Lika srl
@@ -35084,47 +36338,38 @@ OUI:30CDA7*
OUI:104D77*
ID_OUI_FROM_DATABASE=Innovative Computer Engineering
-OUI:788DF7*
- ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
-
-OUI:6CECA1*
- ID_OUI_FROM_DATABASE=SHENZHEN CLOU ELECTRONICS CO. LTD.
-
-OUI:D862DB*
- ID_OUI_FROM_DATABASE=Eno Inc.
-
-OUI:A8D236*
- ID_OUI_FROM_DATABASE=Lightware Visual Engineering
+OUI:3C081E*
+ ID_OUI_FROM_DATABASE=Beijing Yupont Electric Power Technology Co.,Ltd
-OUI:48F925*
- ID_OUI_FROM_DATABASE=Maestronic
+OUI:7CA15D*
+ ID_OUI_FROM_DATABASE=GN ReSound A/S
-OUI:C0885B*
- ID_OUI_FROM_DATABASE=SnD Tech Co., Ltd.
+OUI:B4DD15*
+ ID_OUI_FROM_DATABASE=ControlThings Oy Ab
-OUI:64C667*
- ID_OUI_FROM_DATABASE=Barnes&Noble
+OUI:3C86A8*
+ ID_OUI_FROM_DATABASE=Sangshin elecom .co,, LTD
-OUI:C47DCC*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc
+OUI:FCDD55*
+ ID_OUI_FROM_DATABASE=Shenzhen WeWins wireless Co.,Ltd
-OUI:64535D*
- ID_OUI_FROM_DATABASE=Frauscher Sensortechnik
+OUI:CC0DEC*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
-OUI:105F06*
- ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+OUI:68B094*
+ ID_OUI_FROM_DATABASE=INESA ELECTRON CO.,LTD
-OUI:00B56D*
- ID_OUI_FROM_DATABASE=David Electronics Co., LTD.
+OUI:40E730*
+ ID_OUI_FROM_DATABASE=DEY Storage Systems, Inc.
-OUI:B461FF*
- ID_OUI_FROM_DATABASE=Lumigon A/S
+OUI:A8D236*
+ ID_OUI_FROM_DATABASE=Lightware Visual Engineering
-OUI:9038DF*
- ID_OUI_FROM_DATABASE=Changzhou Tiannengbo System Co. Ltd.
+OUI:6C8686*
+ ID_OUI_FROM_DATABASE=Technonia
-OUI:CC593E*
- ID_OUI_FROM_DATABASE=TOUMAZ LTD
+OUI:78521A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:84E714*
ID_OUI_FROM_DATABASE=Liang Herng Enterprise,Co.Ltd.
@@ -35132,6 +36377,15 @@ OUI:84E714*
OUI:303D08*
ID_OUI_FROM_DATABASE=GLINTT TES S.A.
+OUI:9C541C*
+ ID_OUI_FROM_DATABASE=Shenzhen My-power Technology Co.,Ltd
+
+OUI:90187C*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+
+OUI:FC1F19*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD.
+
OUI:E496AE*
ID_OUI_FROM_DATABASE=ALTOGRAPHICS Inc.
@@ -35144,9 +36398,6 @@ OUI:48B9C2*
OUI:D046DC*
ID_OUI_FROM_DATABASE=Southwest Research Institute
-OUI:F8F082*
- ID_OUI_FROM_DATABASE=Orion Networks International, Inc
-
OUI:046E49*
ID_OUI_FROM_DATABASE=TaiYear Electronic Technology (Suzhou) Co., Ltd
@@ -35162,6 +36413,63 @@ OUI:ECB541*
OUI:D40057*
ID_OUI_FROM_DATABASE=MC Technologies GmbH
+OUI:48B8DE*
+ ID_OUI_FROM_DATABASE=HOMEWINS TECHNOLOGY CO.,LTD.
+
+OUI:20D5BF*
+ ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
+
+OUI:1065CF*
+ ID_OUI_FROM_DATABASE=IQSIM
+
+OUI:B877C3*
+ ID_OUI_FROM_DATABASE=Decagon Devices, Inc.
+
+OUI:849DC5*
+ ID_OUI_FROM_DATABASE=Centera Photonics Inc.
+
+OUI:580943*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:547FA8*
+ ID_OUI_FROM_DATABASE=TELCO systems, s.r.o.
+
+OUI:5474E6*
+ ID_OUI_FROM_DATABASE=Webtech Wireless
+
+OUI:AC5D10*
+ ID_OUI_FROM_DATABASE=Pace Americas
+
+OUI:88F490*
+ ID_OUI_FROM_DATABASE=Jetmobile Pte Ltd
+
+OUI:E8A364*
+ ID_OUI_FROM_DATABASE=Signal Path International / Peachtree Audio
+
+OUI:D0D6CC*
+ ID_OUI_FROM_DATABASE=Wintop
+
+OUI:101D51*
+ ID_OUI_FROM_DATABASE=ON-Q LLC dba ON-Q Mesh Networks
+
+OUI:34C99D*
+ ID_OUI_FROM_DATABASE=EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.
+
+OUI:8C4AEE*
+ ID_OUI_FROM_DATABASE=GIGA TMS INC
+
+OUI:F46DE2*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:04F8C2*
+ ID_OUI_FROM_DATABASE=Flaircomm Microelectronics, Inc.
+
+OUI:0C93FB*
+ ID_OUI_FROM_DATABASE=BNS Solutions
+
+OUI:38B5BD*
+ ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger
+
OUI:B85AF7*
ID_OUI_FROM_DATABASE=Ouya, Inc
@@ -35180,11 +36488,17 @@ OUI:F0219D*
OUI:F8D7BF*
ID_OUI_FROM_DATABASE=REV Ritter GmbH
-OUI:AC5D10*
- ID_OUI_FROM_DATABASE=Pace Americas
+OUI:00B56D*
+ ID_OUI_FROM_DATABASE=David Electronics Co., LTD.
-OUI:88F490*
- ID_OUI_FROM_DATABASE=Jetmobile Pte Ltd
+OUI:B461FF*
+ ID_OUI_FROM_DATABASE=Lumigon A/S
+
+OUI:9038DF*
+ ID_OUI_FROM_DATABASE=Changzhou Tiannengbo System Co. Ltd.
+
+OUI:CC593E*
+ ID_OUI_FROM_DATABASE=TOUMAZ LTD
OUI:AC8D14*
ID_OUI_FROM_DATABASE=Smartrove Inc
@@ -35210,104 +36524,113 @@ OUI:38192F*
OUI:141BF0*
ID_OUI_FROM_DATABASE=Intellimedia Systems Ltd
-OUI:101D51*
- ID_OUI_FROM_DATABASE=ON-Q LLC dba ON-Q Mesh Networks
+OUI:E45614*
+ ID_OUI_FROM_DATABASE=Suttle Apparatus
-OUI:34C99D*
- ID_OUI_FROM_DATABASE=EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.
+OUI:842BBC*
+ ID_OUI_FROM_DATABASE=Modelleisenbahn GmbH
-OUI:8C4AEE*
- ID_OUI_FROM_DATABASE=GIGA TMS INC
+OUI:E856D6*
+ ID_OUI_FROM_DATABASE=NCTech Ltd
-OUI:F46DE2*
- ID_OUI_FROM_DATABASE=zte corporation
+OUI:4088E0*
+ ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Limited Shenzhen Branch
-OUI:B838CA*
- ID_OUI_FROM_DATABASE=Kyokko Tsushin System CO.,LTD
+OUI:1CF4CA*
+ ID_OUI_FROM_DATABASE=Private
-OUI:380FE4*
- ID_OUI_FROM_DATABASE=Dedicated Network Partners Oy
+OUI:F490EA*
+ ID_OUI_FROM_DATABASE=Deciso B.V.
-OUI:847A88*
- ID_OUI_FROM_DATABASE=HTC Corporation
+OUI:942197*
+ ID_OUI_FROM_DATABASE=Stalmart Technology Limited
-OUI:0808C2*
- ID_OUI_FROM_DATABASE=Samsung Electronics
+OUI:AC9403*
+ ID_OUI_FROM_DATABASE=Envision Peripherals Inc
-OUI:5461EA*
- ID_OUI_FROM_DATABASE=Zaplox AB
+OUI:A865B2*
+ ID_OUI_FROM_DATABASE=DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED
-OUI:78324F*
- ID_OUI_FROM_DATABASE=Millennium Group, Inc.
+OUI:60B982*
+ ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A.
-OUI:38B5BD*
- ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger
+OUI:B46238*
+ ID_OUI_FROM_DATABASE=Exablox
-OUI:841715*
- ID_OUI_FROM_DATABASE=GP Electronics (HK) Ltd.
+OUI:40704A*
+ ID_OUI_FROM_DATABASE=Power Idea Technology Limited
-OUI:087999*
- ID_OUI_FROM_DATABASE=AIM GmbH
+OUI:A40BED*
+ ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd
-OUI:84C2E4*
- ID_OUI_FROM_DATABASE=Jiangsu Qinheng Co., Ltd.
+OUI:0CD996*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:C0B8B1*
- ID_OUI_FROM_DATABASE=BitBox Ltd
+OUI:D82DE1*
+ ID_OUI_FROM_DATABASE=Tricascade Inc.
-OUI:0C722C*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:C438D3*
+ ID_OUI_FROM_DATABASE=TAGATEC CO.,LTD
-OUI:B01408*
- ID_OUI_FROM_DATABASE=LIGHTSPEED INTERNATIONAL CO.
+OUI:547398*
+ ID_OUI_FROM_DATABASE=Toyo Electronics Corporation
-OUI:84ACA4*
- ID_OUI_FROM_DATABASE=Beijing Novel Super Digital TV Technology Co., Ltd
+OUI:E0AAB0*
+ ID_OUI_FROM_DATABASE=GENERAL VISION ELECTRONICS CO. LTD.
-OUI:3C6FF7*
- ID_OUI_FROM_DATABASE=EnTek Systems, Inc.
+OUI:68B43A*
+ ID_OUI_FROM_DATABASE=WaterFurnace International, Inc.
-OUI:48B8DE*
- ID_OUI_FROM_DATABASE=HOMEWINS TECHNOLOGY CO.,LTD.
+OUI:543968*
+ ID_OUI_FROM_DATABASE=Edgewater Networks Inc
-OUI:20D5BF*
- ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
+OUI:985E1B*
+ ID_OUI_FROM_DATABASE=ConversDigital Co., Ltd.
-OUI:6CD032*
- ID_OUI_FROM_DATABASE=LG Electronics
+OUI:B8B7D7*
+ ID_OUI_FROM_DATABASE=2GIG Technologies
-OUI:1065CF*
- ID_OUI_FROM_DATABASE=IQSIM
+OUI:1048B1*
+ ID_OUI_FROM_DATABASE=Beijing Duokan Technology Limited
-OUI:B877C3*
- ID_OUI_FROM_DATABASE=Decagon Devices, Inc.
+OUI:005D03*
+ ID_OUI_FROM_DATABASE=Xilinx, Inc
-OUI:849DC5*
- ID_OUI_FROM_DATABASE=Centera Photonics Inc.
+OUI:24EE3A*
+ ID_OUI_FROM_DATABASE=Chengdu Yingji Electronic Hi-tech Co Ltd
-OUI:580943*
- ID_OUI_FROM_DATABASE=Private
+OUI:F82285*
+ ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD.
-OUI:547FA8*
- ID_OUI_FROM_DATABASE=TELCO systems, s.r.o.
+OUI:8482F4*
+ ID_OUI_FROM_DATABASE=Beijing Huasun Unicreate Technology Co., Ltd
-OUI:5474E6*
- ID_OUI_FROM_DATABASE=Webtech Wireless
+OUI:0CC47E*
+ ID_OUI_FROM_DATABASE=EUCAST Co., Ltd.
-OUI:E8A364*
- ID_OUI_FROM_DATABASE=Signal Path International / Peachtree Audio
+OUI:CCE798*
+ ID_OUI_FROM_DATABASE=My Social Stuff
-OUI:D0D6CC*
- ID_OUI_FROM_DATABASE=Wintop
+OUI:50724D*
+ ID_OUI_FROM_DATABASE=BEG Brueck Electronic GmbH
-OUI:FC1F19*
- ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD.
+OUI:B898B0*
+ ID_OUI_FROM_DATABASE=Atlona Inc.
-OUI:9C541C*
- ID_OUI_FROM_DATABASE=Shenzhen My-power Technology Co.,Ltd
+OUI:1C66AA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:90187C*
- ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+OUI:2C625A*
+ ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd
+
+OUI:2074CF*
+ ID_OUI_FROM_DATABASE=Shenzhen Voxtech Co.,Ltd
+
+OUI:ACBD0B*
+ ID_OUI_FROM_DATABASE=IMAC CO.,LTD
+
+OUI:D8D27C*
+ ID_OUI_FROM_DATABASE=JEMA ENERGY, SA
OUI:10F3DB*
ID_OUI_FROM_DATABASE=Gridco Systems, Inc.
@@ -35330,42 +36653,6 @@ OUI:044A50*
OUI:A4466B*
ID_OUI_FROM_DATABASE=EOC Technology
-OUI:7C386C*
- ID_OUI_FROM_DATABASE=Real Time Logic
-
-OUI:D8AF3B*
- ID_OUI_FROM_DATABASE=Hangzhou Bigbright Integrated communications system Co.,Ltd
-
-OUI:78D34F*
- ID_OUI_FROM_DATABASE=Pace-O-Matic, Inc.
-
-OUI:D857EF*
- ID_OUI_FROM_DATABASE=Samsung Electronics
-
-OUI:647657*
- ID_OUI_FROM_DATABASE=Innovative Security Designs
-
-OUI:60455E*
- ID_OUI_FROM_DATABASE=Liptel s.r.o.
-
-OUI:944A09*
- ID_OUI_FROM_DATABASE=BitWise Controls
-
-OUI:E8102E*
- ID_OUI_FROM_DATABASE=Really Simple Software, Inc
-
-OUI:D48CB5*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:24A43C*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks, INC
-
-OUI:D41E35*
- ID_OUI_FROM_DATABASE=TOHO Electronics INC.
-
-OUI:700BC0*
- ID_OUI_FROM_DATABASE=Dewav Technology Company
-
OUI:3CF392*
ID_OUI_FROM_DATABASE=Virtualtek. Co. Ltd
@@ -35378,23 +36665,17 @@ OUI:149FE8*
OUI:70B599*
ID_OUI_FROM_DATABASE=Embedded Technologies s.r.o.
-OUI:547398*
- ID_OUI_FROM_DATABASE=Toyo Electronics Corporation
-
-OUI:E0AAB0*
- ID_OUI_FROM_DATABASE=GENERAL VISION ELECTRONICS CO. LTD.
-
-OUI:68B43A*
- ID_OUI_FROM_DATABASE=WaterFurnace International, Inc.
+OUI:EC4C4D*
+ ID_OUI_FROM_DATABASE=ZAO NPK RoTeK
-OUI:543968*
- ID_OUI_FROM_DATABASE=Edgewater Networks Inc
+OUI:E8D483*
+ ID_OUI_FROM_DATABASE=ULTIMATE Europe Transportation Equipment GmbH
-OUI:C041F6*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
+OUI:ACD9D6*
+ ID_OUI_FROM_DATABASE=tci GmbH
-OUI:985E1B*
- ID_OUI_FROM_DATABASE=ConversDigital Co., Ltd.
+OUI:7493A4*
+ ID_OUI_FROM_DATABASE=Zebra Technologies Corp.
OUI:9C0DAC*
ID_OUI_FROM_DATABASE=Tymphany HK Limited
@@ -35402,41 +36683,35 @@ OUI:9C0DAC*
OUI:8CD3A2*
ID_OUI_FROM_DATABASE=VisSim AS
-OUI:24EE3A*
- ID_OUI_FROM_DATABASE=Chengdu Yingji Electronic Hi-tech Co Ltd
+OUI:647657*
+ ID_OUI_FROM_DATABASE=Innovative Security Designs
-OUI:F82285*
- ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD.
+OUI:60455E*
+ ID_OUI_FROM_DATABASE=Liptel s.r.o.
-OUI:8482F4*
- ID_OUI_FROM_DATABASE=Beijing Huasun Unicreate Technology Co., Ltd
+OUI:944A09*
+ ID_OUI_FROM_DATABASE=BitWise Controls
-OUI:0CC47E*
- ID_OUI_FROM_DATABASE=EUCAST Co., Ltd.
+OUI:E8102E*
+ ID_OUI_FROM_DATABASE=Really Simple Software, Inc
-OUI:CCE798*
- ID_OUI_FROM_DATABASE=My Social Stuff
+OUI:D48CB5*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:50724D*
- ID_OUI_FROM_DATABASE=BEG Brueck Electronic GmbH
+OUI:D41E35*
+ ID_OUI_FROM_DATABASE=TOHO Electronics INC.
-OUI:B898B0*
- ID_OUI_FROM_DATABASE=Atlona Inc.
+OUI:700BC0*
+ ID_OUI_FROM_DATABASE=Dewav Technology Company
-OUI:1C66AA*
+OUI:58C38B*
ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:2C625A*
- ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd
-
-OUI:2074CF*
- ID_OUI_FROM_DATABASE=Shenzhen Voxtech Co.,Ltd
-
-OUI:ACBD0B*
- ID_OUI_FROM_DATABASE=IMAC CO.,LTD
+OUI:2CD444*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
-OUI:D8D27C*
- ID_OUI_FROM_DATABASE=JEMA ENERGY, SA
+OUI:EC1A59*
+ ID_OUI_FROM_DATABASE=Belkin International Inc.
OUI:60CBFB*
ID_OUI_FROM_DATABASE=AirScape Inc.
@@ -35456,48 +36731,18 @@ OUI:407074*
OUI:58BFEA*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:E856D6*
- ID_OUI_FROM_DATABASE=NCTech Ltd
-
-OUI:4088E0*
- ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Limited Shenzhen Branch
-
-OUI:1CF4CA*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:EC4C4D*
- ID_OUI_FROM_DATABASE=ZAO NPK RoTeK
-
-OUI:E8D483*
- ID_OUI_FROM_DATABASE=ULTIMATE Europe Transportation Equipment GmbH
-
-OUI:089E01*
- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+OUI:7C386C*
+ ID_OUI_FROM_DATABASE=Real Time Logic
-OUI:ACD9D6*
- ID_OUI_FROM_DATABASE=tci GmbH
+OUI:D8AF3B*
+ ID_OUI_FROM_DATABASE=Hangzhou Bigbright Integrated communications system Co.,Ltd
-OUI:7493A4*
- ID_OUI_FROM_DATABASE=Zebra Technologies Corp.
+OUI:78D34F*
+ ID_OUI_FROM_DATABASE=Pace-O-Matic, Inc.
-OUI:58C38B*
+OUI:D857EF*
ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:2CD444*
- ID_OUI_FROM_DATABASE=FUJITSU LIMITED
-
-OUI:EC1A59*
- ID_OUI_FROM_DATABASE=Belkin International Inc.
-
-OUI:04F8C2*
- ID_OUI_FROM_DATABASE=Flaircomm Microelectronics, Inc.
-
-OUI:0C93FB*
- ID_OUI_FROM_DATABASE=BNS Solutions
-
-OUI:E45614*
- ID_OUI_FROM_DATABASE=Suttle Apparatus
-
OUI:784405*
ID_OUI_FROM_DATABASE=FUJITU(HONG KONG) ELECTRONIC Co.,LTD.
@@ -35507,65 +36752,74 @@ OUI:C03F2A*
OUI:5001BB*
ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:A40BED*
- ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd
+OUI:44B382*
+ ID_OUI_FROM_DATABASE=Kuang-chi Institute of Advanced Technology
-OUI:0CD996*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:D80DE3*
+ ID_OUI_FROM_DATABASE=FXI TECHNOLOGIES AS
-OUI:D82DE1*
- ID_OUI_FROM_DATABASE=Tricascade Inc.
+OUI:1CE165*
+ ID_OUI_FROM_DATABASE=Marshal Corporation
-OUI:C438D3*
- ID_OUI_FROM_DATABASE=TAGATEC CO.,LTD
+OUI:0CC0C0*
+ ID_OUI_FROM_DATABASE=MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO
-OUI:842BBC*
- ID_OUI_FROM_DATABASE=Modelleisenbahn GmbH
+OUI:AC40EA*
+ ID_OUI_FROM_DATABASE=C&T Solution Inc.
-OUI:B8B7D7*
- ID_OUI_FROM_DATABASE=2GIG Technologies
+OUI:BC8B55*
+ ID_OUI_FROM_DATABASE=NPP ELIKS America Inc. DBA T&M Atlantic
-OUI:1048B1*
- ID_OUI_FROM_DATABASE=Beijing Duokan Technology Limited
+OUI:202598*
+ ID_OUI_FROM_DATABASE=Teleview
-OUI:005D03*
- ID_OUI_FROM_DATABASE=Xilinx, Inc
+OUI:844915*
+ ID_OUI_FROM_DATABASE=vArmour Networks, Inc.
-OUI:20FABB*
- ID_OUI_FROM_DATABASE=Cambridge Executive Limited
+OUI:A04CC1*
+ ID_OUI_FROM_DATABASE=Helixtech Corp.
-OUI:1C0B52*
- ID_OUI_FROM_DATABASE=EPICOM S.A
+OUI:1CB243*
+ ID_OUI_FROM_DATABASE=TDC A/S
-OUI:747E2D*
- ID_OUI_FROM_DATABASE=Beijing Thomson CITIC Digital Technology Co. LTD.
+OUI:1C51B5*
+ ID_OUI_FROM_DATABASE=Techaya LTD
-OUI:E80C75*
- ID_OUI_FROM_DATABASE=Syncbak, Inc.
+OUI:80DB31*
+ ID_OUI_FROM_DATABASE=Power Quotient International Co., Ltd.
-OUI:BC8B55*
- ID_OUI_FROM_DATABASE=NPP ELIKS America Inc. DBA T&M Atlantic
+OUI:AC0142*
+ ID_OUI_FROM_DATABASE=Uriel Technologies SIA
-OUI:D8EB97*
- ID_OUI_FROM_DATABASE=TRENDnet, Inc.
+OUI:A007B6*
+ ID_OUI_FROM_DATABASE=Advanced Technical Support, Inc.
-OUI:202598*
- ID_OUI_FROM_DATABASE=Teleview
+OUI:542A9C*
+ ID_OUI_FROM_DATABASE=LSY Defense, LLC.
-OUI:44B382*
- ID_OUI_FROM_DATABASE=Kuang-chi Institute of Advanced Technology
+OUI:D487D8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:D80DE3*
- ID_OUI_FROM_DATABASE=FXI TECHNOLOGIES AS
+OUI:F89955*
+ ID_OUI_FROM_DATABASE=Fortress Technology Inc
-OUI:1CE165*
- ID_OUI_FROM_DATABASE=Marshal Corporation
+OUI:B827EB*
+ ID_OUI_FROM_DATABASE=Raspberry Pi Foundation
-OUI:0CC0C0*
- ID_OUI_FROM_DATABASE=MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO
+OUI:E88DF5*
+ ID_OUI_FROM_DATABASE=ZNYX Networks, Inc.
-OUI:AC40EA*
- ID_OUI_FROM_DATABASE=C&T Solution Inc.
+OUI:48EA63*
+ ID_OUI_FROM_DATABASE=Zhejiang Uniview Technologies Co., Ltd.
+
+OUI:0CE5D3*
+ ID_OUI_FROM_DATABASE=DH electronics GmbH
+
+OUI:C47130*
+ ID_OUI_FROM_DATABASE=Fon Technology S.L.
+
+OUI:48D7FF*
+ ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH
OUI:F47F35*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -35591,20 +36845,32 @@ OUI:5C0A5B*
OUI:6CA96F*
ID_OUI_FROM_DATABASE=TransPacket AS
-OUI:AC0142*
- ID_OUI_FROM_DATABASE=Uriel Technologies SIA
+OUI:48ED80*
+ ID_OUI_FROM_DATABASE=daesung eltec
-OUI:A007B6*
- ID_OUI_FROM_DATABASE=Advanced Technical Support, Inc.
+OUI:A086EC*
+ ID_OUI_FROM_DATABASE=SAEHAN HITEC Co., Ltd
-OUI:542A9C*
- ID_OUI_FROM_DATABASE=LSY Defense, LLC.
+OUI:BC4B79*
+ ID_OUI_FROM_DATABASE=SensingTek
-OUI:D487D8*
- ID_OUI_FROM_DATABASE=Samsung Electronics
+OUI:2818FD*
+ ID_OUI_FROM_DATABASE=Aditya Infotech Ltd.
-OUI:F89955*
- ID_OUI_FROM_DATABASE=Fortress Technology Inc
+OUI:E42C56*
+ ID_OUI_FROM_DATABASE=Lilee Systems, Ltd.
+
+OUI:50008C*
+ ID_OUI_FROM_DATABASE=Hong Kong Telecommunications (HKT) Limited
+
+OUI:DCA8CF*
+ ID_OUI_FROM_DATABASE=New Spin Golf, LLC.
+
+OUI:34BA9A*
+ ID_OUI_FROM_DATABASE=Asiatelco Technologies Co.
+
+OUI:642DB7*
+ ID_OUI_FROM_DATABASE=SEUNGIL ELECTRONICS
OUI:008DDA*
ID_OUI_FROM_DATABASE=Link One Co., Ltd.
@@ -35627,110 +36893,59 @@ OUI:AC3D05*
OUI:F48E09*
ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:882012*
- ID_OUI_FROM_DATABASE=LMI Technologies
-
-OUI:800A06*
- ID_OUI_FROM_DATABASE=COMTEC co.,ltd
-
-OUI:B827EB*
- ID_OUI_FROM_DATABASE=Raspberry Pi Foundation
-
-OUI:E88DF5*
- ID_OUI_FROM_DATABASE=ZNYX Networks, Inc.
-
-OUI:48EA63*
- ID_OUI_FROM_DATABASE=Zhejiang Uniview Technologies Co., Ltd.
-
-OUI:0CE5D3*
- ID_OUI_FROM_DATABASE=DH electronics GmbH
-
-OUI:C47130*
- ID_OUI_FROM_DATABASE=Fon Technology S.L.
-
-OUI:90CF7D*
- ID_OUI_FROM_DATABASE=Qingdao Hisense Electric Co.,Ltd.
-
-OUI:48D7FF*
- ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH
-
-OUI:18D66A*
- ID_OUI_FROM_DATABASE=Inmarsat
-
-OUI:C85645*
- ID_OUI_FROM_DATABASE=Intermas France
-
-OUI:F490EA*
- ID_OUI_FROM_DATABASE=Deciso B.V.
-
-OUI:942197*
- ID_OUI_FROM_DATABASE=Stalmart Technology Limited
-
-OUI:AC9403*
- ID_OUI_FROM_DATABASE=Envision Peripherals Inc
-
-OUI:A865B2*
- ID_OUI_FROM_DATABASE=DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED
-
-OUI:60B982*
- ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A.
-
-OUI:B46238*
- ID_OUI_FROM_DATABASE=Exablox
-
-OUI:40704A*
- ID_OUI_FROM_DATABASE=Power Idea Technology Limited
+OUI:D443A8*
+ ID_OUI_FROM_DATABASE=Changzhou Haojie Electric Co., Ltd.
-OUI:F0FDA0*
- ID_OUI_FROM_DATABASE=Acurix Networks LP
+OUI:BCB852*
+ ID_OUI_FROM_DATABASE=Cybera, Inc.
-OUI:D8BF4C*
- ID_OUI_FROM_DATABASE=Victory Concept Electronics Limited
+OUI:70D6B6*
+ ID_OUI_FROM_DATABASE=Metrum Technologies
-OUI:C0DF77*
- ID_OUI_FROM_DATABASE=Conrad Electronic SE
+OUI:28D576*
+ ID_OUI_FROM_DATABASE=Premier Wireless, Inc.
-OUI:C86000*
- ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+OUI:6CE907*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:645299*
- ID_OUI_FROM_DATABASE=The Chamberlain Group, Inc
+OUI:94DF58*
+ ID_OUI_FROM_DATABASE=IJ Electron CO.,Ltd.
-OUI:BC125E*
- ID_OUI_FROM_DATABASE=Beijing WisVideo INC.
+OUI:8C0CA3*
+ ID_OUI_FROM_DATABASE=Amper
-OUI:C80718*
- ID_OUI_FROM_DATABASE=TDSi
+OUI:28940F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:48ED80*
- ID_OUI_FROM_DATABASE=daesung eltec
+OUI:5CEB4E*
+ ID_OUI_FROM_DATABASE=R. STAHL HMI Systems GmbH
-OUI:A086EC*
- ID_OUI_FROM_DATABASE=SAEHAN HITEC Co., Ltd
+OUI:B8DAF7*
+ ID_OUI_FROM_DATABASE=Advanced Photonics, Inc.
-OUI:BC4B79*
- ID_OUI_FROM_DATABASE=SensingTek
+OUI:2C36A0*
+ ID_OUI_FROM_DATABASE=Capisco Limited
-OUI:2818FD*
- ID_OUI_FROM_DATABASE=Aditya Infotech Ltd.
+OUI:800A06*
+ ID_OUI_FROM_DATABASE=COMTEC co.,ltd
-OUI:9003B7*
- ID_OUI_FROM_DATABASE=PARROT
+OUI:20FABB*
+ ID_OUI_FROM_DATABASE=Cambridge Executive Limited
-OUI:844915*
- ID_OUI_FROM_DATABASE=vArmour Networks, Inc.
+OUI:1C0B52*
+ ID_OUI_FROM_DATABASE=EPICOM S.A
-OUI:A04CC1*
- ID_OUI_FROM_DATABASE=Helixtech Corp.
+OUI:747E2D*
+ ID_OUI_FROM_DATABASE=Beijing Thomson CITIC Digital Technology Co. LTD.
-OUI:1CB243*
- ID_OUI_FROM_DATABASE=TDC A/S
+OUI:E80C75*
+ ID_OUI_FROM_DATABASE=Syncbak, Inc.
-OUI:1C51B5*
- ID_OUI_FROM_DATABASE=Techaya LTD
+OUI:18D66A*
+ ID_OUI_FROM_DATABASE=Inmarsat
-OUI:80DB31*
- ID_OUI_FROM_DATABASE=Power Quotient International Co., Ltd.
+OUI:C85645*
+ ID_OUI_FROM_DATABASE=Intermas France
OUI:8C604F*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -35753,26 +36968,23 @@ OUI:34FC6F*
OUI:C0B357*
ID_OUI_FROM_DATABASE=Yoshiki Electronics Industry Ltd.
-OUI:642DB7*
- ID_OUI_FROM_DATABASE=SEUNGIL ELECTRONICS
-
-OUI:A898C6*
- ID_OUI_FROM_DATABASE=Shinbo Co., Ltd.
+OUI:D8BF4C*
+ ID_OUI_FROM_DATABASE=Victory Concept Electronics Limited
-OUI:006BA0*
- ID_OUI_FROM_DATABASE=SHENZHEN UNIVERSAL INTELLISYS PTE LTD
+OUI:C0DF77*
+ ID_OUI_FROM_DATABASE=Conrad Electronic SE
-OUI:502690*
- ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+OUI:C86000*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:B4211D*
- ID_OUI_FROM_DATABASE=Beijing GuangXin Technology Co., Ltd
+OUI:645299*
+ ID_OUI_FROM_DATABASE=The Chamberlain Group, Inc
-OUI:E039D7*
- ID_OUI_FROM_DATABASE=Plexxi, Inc.
+OUI:BC125E*
+ ID_OUI_FROM_DATABASE=Beijing WisVideo INC.
-OUI:FC946C*
- ID_OUI_FROM_DATABASE=UBIVELOX
+OUI:C80718*
+ ID_OUI_FROM_DATABASE=TDSi
OUI:B4944E*
ID_OUI_FROM_DATABASE=WeTelecom Co., Ltd.
@@ -35786,30 +36998,6 @@ OUI:988BAD*
OUI:4050E0*
ID_OUI_FROM_DATABASE=Milton Security Group LLC
-OUI:E42C56*
- ID_OUI_FROM_DATABASE=Lilee Systems, Ltd.
-
-OUI:50008C*
- ID_OUI_FROM_DATABASE=Hong Kong Telecommunications (HKT) Limited
-
-OUI:DCA8CF*
- ID_OUI_FROM_DATABASE=New Spin Golf, LLC.
-
-OUI:34BA9A*
- ID_OUI_FROM_DATABASE=Asiatelco Technologies Co.
-
-OUI:D443A8*
- ID_OUI_FROM_DATABASE=Changzhou Haojie Electric Co., Ltd.
-
-OUI:BCB852*
- ID_OUI_FROM_DATABASE=Cybera, Inc.
-
-OUI:70D6B6*
- ID_OUI_FROM_DATABASE=Metrum Technologies
-
-OUI:28D576*
- ID_OUI_FROM_DATABASE=Premier Wireless, Inc.
-
OUI:C87CBC*
ID_OUI_FROM_DATABASE=Valink Co., Ltd.
@@ -35822,35 +37010,23 @@ OUI:C87D77*
OUI:A078BA*
ID_OUI_FROM_DATABASE=Pantech Co., Ltd.
-OUI:20BBC6*
- ID_OUI_FROM_DATABASE=Jabil Circuit Hungary Ltd.
-
-OUI:2C9717*
- ID_OUI_FROM_DATABASE=I.C.Y. B.V.
-
-OUI:64E84F*
- ID_OUI_FROM_DATABASE=Serialway Communication Technology Co. Ltd
-
-OUI:6CE907*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
-OUI:94DF58*
- ID_OUI_FROM_DATABASE=IJ Electron CO.,Ltd.
+OUI:D4507A*
+ ID_OUI_FROM_DATABASE=CEIVA Logic, Inc
-OUI:8C0CA3*
- ID_OUI_FROM_DATABASE=Amper
+OUI:184617*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:28940F*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:9CC7D1*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
-OUI:5CEB4E*
- ID_OUI_FROM_DATABASE=R. STAHL HMI Systems GmbH
+OUI:00B9F6*
+ ID_OUI_FROM_DATABASE=Shenzhen Super Rich Electronics Co.,Ltd
-OUI:B8DAF7*
- ID_OUI_FROM_DATABASE=Advanced Photonics, Inc.
+OUI:9C5C8D*
+ ID_OUI_FROM_DATABASE=FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOS LTDA
-OUI:2C36A0*
- ID_OUI_FROM_DATABASE=Capisco Limited
+OUI:E01E07*
+ ID_OUI_FROM_DATABASE=Anite Telecoms US. Inc
OUI:B06CBF*
ID_OUI_FROM_DATABASE=3ality Digital Systems GmbH
@@ -35879,6 +37055,69 @@ OUI:70704C*
OUI:F47ACC*
ID_OUI_FROM_DATABASE=SolidFire, Inc.
+OUI:24BC82*
+ ID_OUI_FROM_DATABASE=Dali Wireless, Inc.
+
+OUI:64C5AA*
+ ID_OUI_FROM_DATABASE=South African Broadcasting Corporation
+
+OUI:64ED62*
+ ID_OUI_FROM_DATABASE=WOORI SYSTEMS Co., Ltd
+
+OUI:C4237A*
+ ID_OUI_FROM_DATABASE=WhizNets Inc.
+
+OUI:8430E5*
+ ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC
+
+OUI:2C002C*
+ ID_OUI_FROM_DATABASE=UNOWHY
+
+OUI:0481AE*
+ ID_OUI_FROM_DATABASE=Clack Corporation
+
+OUI:C09132*
+ ID_OUI_FROM_DATABASE=Patriot Memory
+
+OUI:A898C6*
+ ID_OUI_FROM_DATABASE=Shinbo Co., Ltd.
+
+OUI:006BA0*
+ ID_OUI_FROM_DATABASE=SHENZHEN UNIVERSAL INTELLISYS PTE LTD
+
+OUI:502690*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
+OUI:B4211D*
+ ID_OUI_FROM_DATABASE=Beijing GuangXin Technology Co., Ltd
+
+OUI:E039D7*
+ ID_OUI_FROM_DATABASE=Plexxi, Inc.
+
+OUI:FC946C*
+ ID_OUI_FROM_DATABASE=UBIVELOX
+
+OUI:38DE60*
+ ID_OUI_FROM_DATABASE=Mohlenhoff GmbH
+
+OUI:2839E7*
+ ID_OUI_FROM_DATABASE=Preceno Technology Pte.Ltd.
+
+OUI:28D997*
+ ID_OUI_FROM_DATABASE=Yuduan Mobile Co., Ltd.
+
+OUI:886B76*
+ ID_OUI_FROM_DATABASE=CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD
+
+OUI:A0CF5B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:18C451*
+ ID_OUI_FROM_DATABASE=Tucson Embedded Systems
+
+OUI:582EFE*
+ ID_OUI_FROM_DATABASE=Lighting Science Group
+
OUI:F8D3A9*
ID_OUI_FROM_DATABASE=AXAN Networks
@@ -35897,6 +37136,15 @@ OUI:CCA374*
OUI:50F61A*
ID_OUI_FROM_DATABASE=Kunshan JADE Technologies co., Ltd.
+OUI:20BBC6*
+ ID_OUI_FROM_DATABASE=Jabil Circuit Hungary Ltd.
+
+OUI:2C9717*
+ ID_OUI_FROM_DATABASE=I.C.Y. B.V.
+
+OUI:64E84F*
+ ID_OUI_FROM_DATABASE=Serialway Communication Technology Co. Ltd
+
OUI:941D1C*
ID_OUI_FROM_DATABASE=TLab West Systems AB
@@ -35912,27 +37160,6 @@ OUI:7C6B52*
OUI:48C1AC*
ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-OUI:D826B9*
- ID_OUI_FROM_DATABASE=Guangdong Coagent Electronics S &T Co., Ltd.
-
-OUI:24BC82*
- ID_OUI_FROM_DATABASE=Dali Wireless, Inc.
-
-OUI:F80CF3*
- ID_OUI_FROM_DATABASE=LG Electronics
-
-OUI:64C5AA*
- ID_OUI_FROM_DATABASE=South African Broadcasting Corporation
-
-OUI:64ED62*
- ID_OUI_FROM_DATABASE=WOORI SYSTEMS Co., Ltd
-
-OUI:C4237A*
- ID_OUI_FROM_DATABASE=WhizNets Inc.
-
-OUI:8430E5*
- ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC
-
OUI:046D42*
ID_OUI_FROM_DATABASE=Bryston Ltd.
@@ -35948,14 +37175,14 @@ OUI:644D70*
OUI:807693*
ID_OUI_FROM_DATABASE=Newag SA
-OUI:2C002C*
- ID_OUI_FROM_DATABASE=UNOWHY
+OUI:FC1794*
+ ID_OUI_FROM_DATABASE=InterCreative Co., Ltd
-OUI:0481AE*
- ID_OUI_FROM_DATABASE=Clack Corporation
+OUI:181420*
+ ID_OUI_FROM_DATABASE=TEB SAS
-OUI:C09132*
- ID_OUI_FROM_DATABASE=Patriot Memory
+OUI:D03110*
+ ID_OUI_FROM_DATABASE=Ingenic Semiconductor Co.,Ltd
OUI:AC81F3*
ID_OUI_FROM_DATABASE=Nokia Corporation
@@ -35972,17 +37199,20 @@ OUI:80971B*
OUI:1071F9*
ID_OUI_FROM_DATABASE=Cloud Telecomputers, LLC
-OUI:B8B42E*
- ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co,Ltd.ShenZhen
+OUI:C47B2F*
+ ID_OUI_FROM_DATABASE=Beijing JoinHope Image Technology Ltd.
-OUI:A84041*
- ID_OUI_FROM_DATABASE=Dragino Technology Co., Limited
+OUI:18F650*
+ ID_OUI_FROM_DATABASE=Multimedia Pacific Limited
-OUI:DCF05D*
- ID_OUI_FROM_DATABASE=Letta Teknoloji
+OUI:704AAE*
+ ID_OUI_FROM_DATABASE=Xstream Flow (Pty) Ltd
-OUI:D05A0F*
- ID_OUI_FROM_DATABASE=I-BT DIGITAL CO.,LTD
+OUI:9C934E*
+ ID_OUI_FROM_DATABASE=Xerox Corporation
+
+OUI:3C26D5*
+ ID_OUI_FROM_DATABASE=Sotera Wireless
OUI:FC2E2D*
ID_OUI_FROM_DATABASE=Lorom Industrial Co.LTD.
@@ -35996,53 +37226,56 @@ OUI:B4C799*
OUI:70B921*
ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-OUI:C47B2F*
- ID_OUI_FROM_DATABASE=Beijing JoinHope Image Technology Ltd.
-
-OUI:18F650*
- ID_OUI_FROM_DATABASE=Multimedia Pacific Limited
+OUI:948FEE*
+ ID_OUI_FROM_DATABASE=Hughes Telematics, Inc.
-OUI:38DE60*
- ID_OUI_FROM_DATABASE=Mohlenhoff GmbH
+OUI:E8C320*
+ ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
-OUI:2839E7*
- ID_OUI_FROM_DATABASE=Preceno Technology Pte.Ltd.
+OUI:D8973B*
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
-OUI:28D997*
- ID_OUI_FROM_DATABASE=Yuduan Mobile Co., Ltd.
+OUI:008D4E*
+ ID_OUI_FROM_DATABASE=CJSC NII STT
-OUI:886B76*
- ID_OUI_FROM_DATABASE=CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD
+OUI:10C586*
+ ID_OUI_FROM_DATABASE=BIO SOUND LAB CO., LTD.
-OUI:A0CF5B*
+OUI:E8BA70*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:18C451*
- ID_OUI_FROM_DATABASE=Tucson Embedded Systems
+OUI:6473E2*
+ ID_OUI_FROM_DATABASE=Arbiter Systems, Inc.
-OUI:582EFE*
- ID_OUI_FROM_DATABASE=Lighting Science Group
+OUI:00A1DE*
+ ID_OUI_FROM_DATABASE=ShenZhen ShiHua Technology CO.,LTD
-OUI:D4507A*
- ID_OUI_FROM_DATABASE=CEIVA Logic, Inc
+OUI:04E1C8*
+ ID_OUI_FROM_DATABASE=IMS Soluções em Energia Ltda.
-OUI:184617*
- ID_OUI_FROM_DATABASE=Samsung Electronics
+OUI:E4DD79*
+ ID_OUI_FROM_DATABASE=En-Vision America, Inc.
-OUI:9CC7D1*
- ID_OUI_FROM_DATABASE=SHARP Corporation
+OUI:60190C*
+ ID_OUI_FROM_DATABASE=RRAMAC
-OUI:AC9CE4*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+OUI:34A709*
+ ID_OUI_FROM_DATABASE=Trevil srl
-OUI:00B9F6*
- ID_OUI_FROM_DATABASE=Shenzhen Super Rich Electronics Co.,Ltd
+OUI:F80332*
+ ID_OUI_FROM_DATABASE=Khomp
-OUI:9C5C8D*
- ID_OUI_FROM_DATABASE=FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOS LTDA
+OUI:C40F09*
+ ID_OUI_FROM_DATABASE=Hermes electronic GmbH
-OUI:E01E07*
- ID_OUI_FROM_DATABASE=Anite Telecoms US. Inc
+OUI:908D1D*
+ ID_OUI_FROM_DATABASE=GH Technologies
+
+OUI:CCB55A*
+ ID_OUI_FROM_DATABASE=Fraunhofer ITWM
+
+OUI:587521*
+ ID_OUI_FROM_DATABASE=CJSC RTSoft
OUI:64D989*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -36056,9 +37289,6 @@ OUI:24DAB6*
OUI:B8F5E7*
ID_OUI_FROM_DATABASE=WayTools, LLC
-OUI:980C82*
- ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
-
OUI:148A70*
ID_OUI_FROM_DATABASE=ADS GmbH
@@ -36074,26 +37304,17 @@ OUI:644346*
OUI:FCE892*
ID_OUI_FROM_DATABASE=Hangzhou Lancable Technology Co.,Ltd
-OUI:FC1794*
- ID_OUI_FROM_DATABASE=InterCreative Co., Ltd
-
-OUI:181420*
- ID_OUI_FROM_DATABASE=TEB SAS
-
-OUI:D03110*
- ID_OUI_FROM_DATABASE=Ingenic Semiconductor Co.,Ltd
-
-OUI:48C862*
- ID_OUI_FROM_DATABASE=Simo Wireless,Inc.
+OUI:B8B42E*
+ ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co,Ltd.ShenZhen
-OUI:3C26D5*
- ID_OUI_FROM_DATABASE=Sotera Wireless
+OUI:A84041*
+ ID_OUI_FROM_DATABASE=Dragino Technology Co., Limited
-OUI:704AAE*
- ID_OUI_FROM_DATABASE=Xstream Flow (Pty) Ltd
+OUI:DCF05D*
+ ID_OUI_FROM_DATABASE=Letta Teknoloji
-OUI:9C934E*
- ID_OUI_FROM_DATABASE=Xerox Corporation
+OUI:D05A0F*
+ ID_OUI_FROM_DATABASE=I-BT DIGITAL CO.,LTD
OUI:9439E5*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
@@ -36110,6 +37331,18 @@ OUI:9C7BD2*
OUI:900D66*
ID_OUI_FROM_DATABASE=Digimore Electronics Co., Ltd
+OUI:980C82*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
+
+OUI:48C862*
+ ID_OUI_FROM_DATABASE=Simo Wireless,Inc.
+
+OUI:0CF3EE*
+ ID_OUI_FROM_DATABASE=EM Microelectronic
+
+OUI:F0C27C*
+ ID_OUI_FROM_DATABASE=Mianyang Netop Telecom Equipment Co.,Ltd.
+
OUI:BC35E5*
ID_OUI_FROM_DATABASE=Hydro Systems Company
@@ -36128,18 +37361,6 @@ OUI:A433D1*
OUI:84DE3D*
ID_OUI_FROM_DATABASE=Crystal Vision Ltd
-OUI:F87B8C*
- ID_OUI_FROM_DATABASE=Amped Wireless
-
-OUI:44D2CA*
- ID_OUI_FROM_DATABASE=Anvia TV Oy
-
-OUI:4C1A3A*
- ID_OUI_FROM_DATABASE=PRIMA Research And Production Enterprise Ltd.
-
-OUI:AC0613*
- ID_OUI_FROM_DATABASE=Senselogix Ltd
-
OUI:B4AA4D*
ID_OUI_FROM_DATABASE=Ensequence, Inc.
@@ -36173,53 +37394,50 @@ OUI:D8DF0D*
OUI:D8C068*
ID_OUI_FROM_DATABASE=Netgenetech.co.,ltd.
-OUI:3C9157*
- ID_OUI_FROM_DATABASE=Hangzhou Yulong Conmunication Co.,Ltd
-
OUI:50E549*
ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
OUI:A8FCB7*
ID_OUI_FROM_DATABASE=Consolidated Resource Imaging
-OUI:6400F1*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:F87B8C*
+ ID_OUI_FROM_DATABASE=Amped Wireless
-OUI:04C5A4*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:44D2CA*
+ ID_OUI_FROM_DATABASE=Anvia TV Oy
-OUI:E4DD79*
- ID_OUI_FROM_DATABASE=En-Vision America, Inc.
+OUI:4C1A3A*
+ ID_OUI_FROM_DATABASE=PRIMA Research And Production Enterprise Ltd.
-OUI:60190C*
- ID_OUI_FROM_DATABASE=RRAMAC
+OUI:AC0613*
+ ID_OUI_FROM_DATABASE=Senselogix Ltd
-OUI:34A709*
- ID_OUI_FROM_DATABASE=Trevil srl
+OUI:CCF67A*
+ ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD
-OUI:F80332*
- ID_OUI_FROM_DATABASE=Khomp
+OUI:00BB8E*
+ ID_OUI_FROM_DATABASE=HME Co., Ltd.
-OUI:C40F09*
- ID_OUI_FROM_DATABASE=Hermes electronic GmbH
+OUI:C0A26D*
+ ID_OUI_FROM_DATABASE=Abbott Point of Care
-OUI:908D1D*
- ID_OUI_FROM_DATABASE=GH Technologies
+OUI:205B2A*
+ ID_OUI_FROM_DATABASE=Private
-OUI:CCB55A*
- ID_OUI_FROM_DATABASE=Fraunhofer ITWM
+OUI:18B430*
+ ID_OUI_FROM_DATABASE=Nest Labs Inc.
-OUI:587521*
- ID_OUI_FROM_DATABASE=CJSC RTSoft
+OUI:F8769B*
+ ID_OUI_FROM_DATABASE=Neopis Co., Ltd.
-OUI:948FEE*
- ID_OUI_FROM_DATABASE=Hughes Telematics, Inc.
+OUI:08E672*
+ ID_OUI_FROM_DATABASE=JEBSEE ELECTRONICS CO.,LTD.
-OUI:E8C320*
- ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
+OUI:58E476*
+ ID_OUI_FROM_DATABASE=CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD
-OUI:D8973B*
- ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
+OUI:B435F7*
+ ID_OUI_FROM_DATABASE=Zhejiang Pearmain Electronics Co.ltd.
OUI:0C6E4F*
ID_OUI_FROM_DATABASE=PrimeVOLT Co., Ltd.
@@ -36233,39 +37451,9 @@ OUI:983000*
OUI:F81D93*
ID_OUI_FROM_DATABASE=Longdhua(Beijing) Controls Technology Co.,Ltd
-OUI:CC5D4E*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:D0EB9E*
ID_OUI_FROM_DATABASE=Seowoo Inc.
-OUI:BC99BC*
- ID_OUI_FROM_DATABASE=FonSee Technology Inc.
-
-OUI:986022*
- ID_OUI_FROM_DATABASE=EMW Co., Ltd.
-
-OUI:80B32A*
- ID_OUI_FROM_DATABASE=Alstom Grid
-
-OUI:803457*
- ID_OUI_FROM_DATABASE=OT Systems Limited
-
-OUI:B83D4E*
- ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch
-
-OUI:3CA72B*
- ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD
-
-OUI:EC55F9*
- ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-
-OUI:F4D9FB*
- ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
-
-OUI:584C19*
- ID_OUI_FROM_DATABASE=Chongqing Guohong Technology Development Company Limited
-
OUI:8C5FDF*
ID_OUI_FROM_DATABASE=Beijing Railway Signal Factory
@@ -36302,30 +37490,6 @@ OUI:7C6C39*
OUI:9C5D95*
ID_OUI_FROM_DATABASE=VTC Electronics Corp.
-OUI:0CF3EE*
- ID_OUI_FROM_DATABASE=EM Microelectronic
-
-OUI:F0C27C*
- ID_OUI_FROM_DATABASE=Mianyang Netop Telecom Equipment Co.,Ltd.
-
-OUI:008D4E*
- ID_OUI_FROM_DATABASE=CJSC NII STT
-
-OUI:10C586*
- ID_OUI_FROM_DATABASE=BIO SOUND LAB CO., LTD.
-
-OUI:E8BA70*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:6473E2*
- ID_OUI_FROM_DATABASE=Arbiter Systems, Inc.
-
-OUI:00A1DE*
- ID_OUI_FROM_DATABASE=ShenZhen ShiHua Technology CO.,LTD
-
-OUI:04E1C8*
- ID_OUI_FROM_DATABASE=IMS Soluções em Energia Ltda.
-
OUI:DC05ED*
ID_OUI_FROM_DATABASE=Nabtesco Corporation
@@ -36338,71 +37502,68 @@ OUI:94E848*
OUI:AC5E8C*
ID_OUI_FROM_DATABASE=Utillink
-OUI:CCF3A5*
- ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc
-
-OUI:C4242E*
- ID_OUI_FROM_DATABASE=Galvanic Applied Sciences Inc
-
OUI:549B12*
ID_OUI_FROM_DATABASE=Samsung Electronics
OUI:CC7EE7*
ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-OUI:58E476*
- ID_OUI_FROM_DATABASE=CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD
+OUI:BC99BC*
+ ID_OUI_FROM_DATABASE=FonSee Technology Inc.
-OUI:B435F7*
- ID_OUI_FROM_DATABASE=Zhejiang Pearmain Electronics Co.ltd.
+OUI:986022*
+ ID_OUI_FROM_DATABASE=EMW Co., Ltd.
-OUI:346F92*
- ID_OUI_FROM_DATABASE=White Rodgers Division
+OUI:80B32A*
+ ID_OUI_FROM_DATABASE=Alstom Grid
-OUI:8CDB25*
- ID_OUI_FROM_DATABASE=ESG Solutions
+OUI:803457*
+ ID_OUI_FROM_DATABASE=OT Systems Limited
-OUI:641A22*
- ID_OUI_FROM_DATABASE=Heliospectra AB
+OUI:B83D4E*
+ ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch
-OUI:BC20BA*
- ID_OUI_FROM_DATABASE=Inspur (Shandong) Electronic Information Co., Ltd
+OUI:CCF3A5*
+ ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc
-OUI:249442*
- ID_OUI_FROM_DATABASE=OPEN ROAD SOLUTIONS , INC.
+OUI:C4242E*
+ ID_OUI_FROM_DATABASE=Galvanic Applied Sciences Inc
-OUI:E0F379*
- ID_OUI_FROM_DATABASE=Vaddio
+OUI:6400F1*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:B09AE2*
- ID_OUI_FROM_DATABASE=STEMMER IMAGING GmbH
+OUI:04C5A4*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:E441E6*
- ID_OUI_FROM_DATABASE=Ottec Technology GmbH
+OUI:3CA72B*
+ ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD
-OUI:10E2D5*
- ID_OUI_FROM_DATABASE=Qi Hardware Inc.
+OUI:EC55F9*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:7CDA84*
- ID_OUI_FROM_DATABASE=Dongnian Networks Inc.
+OUI:F4D9FB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
-OUI:A036FA*
- ID_OUI_FROM_DATABASE=Ettus Research LLC
+OUI:584C19*
+ ID_OUI_FROM_DATABASE=Chongqing Guohong Technology Development Company Limited
-OUI:EC836C*
- ID_OUI_FROM_DATABASE=RM Tech Co., Ltd.
+OUI:D0A311*
+ ID_OUI_FROM_DATABASE=Neuberger Gebäudeautomation GmbH
-OUI:BC71C1*
- ID_OUI_FROM_DATABASE=XTrillion, Inc.
+OUI:3C5A37*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:0C469D*
- ID_OUI_FROM_DATABASE=MS Sedco
+OUI:10A13B*
+ ID_OUI_FROM_DATABASE=FUJIKURA RUBBER LTD.
-OUI:E0E8E8*
- ID_OUI_FROM_DATABASE=Olive Telecommunication Pvt. Ltd
+OUI:F4E142*
+ ID_OUI_FROM_DATABASE=Delta Elektronika BV
-OUI:0C3C65*
- ID_OUI_FROM_DATABASE=Dome Imaging Inc
+OUI:F00248*
+ ID_OUI_FROM_DATABASE=SmarteBuilding
+
+OUI:2CDD0C*
+ ID_OUI_FROM_DATABASE=Discovergy GmbH
OUI:40B2C8*
ID_OUI_FROM_DATABASE=Nortel Networks
@@ -36428,26 +37589,68 @@ OUI:088DC8*
OUI:D491AF*
ID_OUI_FROM_DATABASE=Electroacustica General Iberica, S.A.
-OUI:CCF67A*
- ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD
+OUI:1CDF0F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00BB8E*
- ID_OUI_FROM_DATABASE=HME Co., Ltd.
+OUI:34DF2A*
+ ID_OUI_FROM_DATABASE=Fujikon Industrial Co.,Limited
-OUI:C0A26D*
- ID_OUI_FROM_DATABASE=Abbott Point of Care
+OUI:C88447*
+ ID_OUI_FROM_DATABASE=Beautiful Enterprise Co., Ltd
-OUI:205B2A*
- ID_OUI_FROM_DATABASE=Private
+OUI:C88B47*
+ ID_OUI_FROM_DATABASE=Nolangroup S.P.A con Socio Unico
-OUI:18B430*
- ID_OUI_FROM_DATABASE=Nest Labs Inc.
+OUI:24BA30*
+ ID_OUI_FROM_DATABASE=Technical Consumer Products, Inc.
-OUI:F8769B*
- ID_OUI_FROM_DATABASE=Neopis Co., Ltd.
+OUI:74D675*
+ ID_OUI_FROM_DATABASE=WYMA Tecnologia
-OUI:08E672*
- ID_OUI_FROM_DATABASE=JEBSEE ELECTRONICS CO.,LTD.
+OUI:D01CBB*
+ ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd.
+
+OUI:9481A4*
+ ID_OUI_FROM_DATABASE=Azuray Technologies
+
+OUI:BCE09D*
+ ID_OUI_FROM_DATABASE=Eoslink
+
+OUI:346F92*
+ ID_OUI_FROM_DATABASE=White Rodgers Division
+
+OUI:8CDB25*
+ ID_OUI_FROM_DATABASE=ESG Solutions
+
+OUI:641A22*
+ ID_OUI_FROM_DATABASE=Heliospectra AB
+
+OUI:30142D*
+ ID_OUI_FROM_DATABASE=Piciorgros GmbH
+
+OUI:E441E6*
+ ID_OUI_FROM_DATABASE=Ottec Technology GmbH
+
+OUI:10E2D5*
+ ID_OUI_FROM_DATABASE=Qi Hardware Inc.
+
+OUI:7CDA84*
+ ID_OUI_FROM_DATABASE=Dongnian Networks Inc.
+
+OUI:A036FA*
+ ID_OUI_FROM_DATABASE=Ettus Research LLC
+
+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.
+
+OUI:80D019*
+ ID_OUI_FROM_DATABASE=Embed, Inc
OUI:D41296*
ID_OUI_FROM_DATABASE=Anobit Technologies Ltd.
@@ -36467,17 +37670,17 @@ OUI:649B24*
OUI:0475F5*
ID_OUI_FROM_DATABASE=CSST
-OUI:10A13B*
- ID_OUI_FROM_DATABASE=FUJIKURA RUBBER LTD.
+OUI:BC20BA*
+ ID_OUI_FROM_DATABASE=Inspur (Shandong) Electronic Information Co., Ltd
-OUI:F4E142*
- ID_OUI_FROM_DATABASE=Delta Elektronika BV
+OUI:249442*
+ ID_OUI_FROM_DATABASE=OPEN ROAD SOLUTIONS , INC.
-OUI:F00248*
- ID_OUI_FROM_DATABASE=SmarteBuilding
+OUI:E0F379*
+ ID_OUI_FROM_DATABASE=Vaddio
-OUI:2CDD0C*
- ID_OUI_FROM_DATABASE=Discovergy GmbH
+OUI:B09AE2*
+ ID_OUI_FROM_DATABASE=STEMMER IMAGING GmbH
OUI:CCD811*
ID_OUI_FROM_DATABASE=Aiconn Technology Corporation
@@ -36497,14 +37700,8 @@ OUI:44599F*
OUI:3C2F3A*
ID_OUI_FROM_DATABASE=SFORZATO Corp.
-OUI:C0C520*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
-OUI:6083B2*
- ID_OUI_FROM_DATABASE=GkWare e.K.
-
-OUI:80D019*
- ID_OUI_FROM_DATABASE=Embed, Inc
+OUI:EC9233*
+ ID_OUI_FROM_DATABASE=Eddyfi NDT Inc
OUI:ECE90B*
ID_OUI_FROM_DATABASE=SISTEMA SOLUCOES ELETRONICAS LTDA - EASYTECH
@@ -36533,8 +37730,17 @@ OUI:6C33A9*
OUI:08B7EC*
ID_OUI_FROM_DATABASE=Wireless Seismic
-OUI:30142D*
- ID_OUI_FROM_DATABASE=Piciorgros GmbH
+OUI:BC71C1*
+ ID_OUI_FROM_DATABASE=XTrillion, Inc.
+
+OUI:0C469D*
+ ID_OUI_FROM_DATABASE=MS Sedco
+
+OUI:E0E8E8*
+ ID_OUI_FROM_DATABASE=Olive Telecommunication Pvt. Ltd
+
+OUI:0C3C65*
+ ID_OUI_FROM_DATABASE=Dome Imaging Inc
OUI:942053*
ID_OUI_FROM_DATABASE=Nokia Corporation
@@ -36551,23 +37757,32 @@ OUI:2CB0DF*
OUI:5CF3FC*
ID_OUI_FROM_DATABASE=IBM Corp
-OUI:D01CBB*
- ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd.
+OUI:D43D67*
+ ID_OUI_FROM_DATABASE=Carma Industries Inc.
-OUI:9481A4*
- ID_OUI_FROM_DATABASE=Azuray Technologies
+OUI:00BD27*
+ ID_OUI_FROM_DATABASE=Exar Corp.
-OUI:BCE09D*
- ID_OUI_FROM_DATABASE=Eoslink
+OUI:C8A729*
+ ID_OUI_FROM_DATABASE=SYStronics Co., Ltd.
-OUI:D0A311*
- ID_OUI_FROM_DATABASE=Neuberger Gebäudeautomation GmbH
+OUI:6C9CE9*
+ ID_OUI_FROM_DATABASE=Nimble Storage
-OUI:3C5A37*
+OUI:700258*
+ ID_OUI_FROM_DATABASE=01DB-METRAVIB
+
+OUI:D4E8B2*
ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:EC9233*
- ID_OUI_FROM_DATABASE=Eddyfi NDT Inc
+OUI:20FDF1*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD
+
+OUI:389592*
+ ID_OUI_FROM_DATABASE=Beijing Tendyron Corporation
+
+OUI:705EAA*
+ ID_OUI_FROM_DATABASE=Action Target, Inc.
OUI:0C8D98*
ID_OUI_FROM_DATABASE=TOP EIGHT IND CORP
@@ -36575,14 +37790,17 @@ OUI:0C8D98*
OUI:30493B*
ID_OUI_FROM_DATABASE=Nanjing Z-Com Wireless Co.,Ltd
-OUI:785712*
- ID_OUI_FROM_DATABASE=Mobile Integration Workgroup
+OUI:68DB96*
+ ID_OUI_FROM_DATABASE=OPWILL Technologies CO .,LTD
-OUI:380A0A*
- ID_OUI_FROM_DATABASE=Sky-City Communication and Electronics Limited Company
+OUI:00F860*
+ ID_OUI_FROM_DATABASE=PT. Panggung Electric Citrabuana
-OUI:38521A*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent 7705
+OUI:FCEDB9*
+ ID_OUI_FROM_DATABASE=Arrayent
+
+OUI:44ED57*
+ ID_OUI_FROM_DATABASE=Longicorn, inc.
OUI:C8A1B6*
ID_OUI_FROM_DATABASE=Shenzhen Longway Technologies Co., Ltd
@@ -36593,20 +37811,11 @@ OUI:641E81*
OUI:88ACC1*
ID_OUI_FROM_DATABASE=Generiton Co., Ltd.
-OUI:700258*
- ID_OUI_FROM_DATABASE=01DB-METRAVIB
-
-OUI:D4E8B2*
- ID_OUI_FROM_DATABASE=Samsung Electronics
-
-OUI:20FDF1*
- ID_OUI_FROM_DATABASE=3COM EUROPE LTD
-
-OUI:389592*
- ID_OUI_FROM_DATABASE=Beijing Tendyron Corporation
+OUI:785712*
+ ID_OUI_FROM_DATABASE=Mobile Integration Workgroup
-OUI:705EAA*
- ID_OUI_FROM_DATABASE=Action Target, Inc.
+OUI:380A0A*
+ ID_OUI_FROM_DATABASE=Sky-City Communication and Electronics Limited Company
OUI:141BBD*
ID_OUI_FROM_DATABASE=Volex Inc.
@@ -36626,9 +37835,6 @@ OUI:F0F842*
OUI:78A714*
ID_OUI_FROM_DATABASE=Amphenol
-OUI:F0DEF1*
- ID_OUI_FROM_DATABASE=Wistron InfoComm (Kunshan)Co
-
OUI:F450EB*
ID_OUI_FROM_DATABASE=Telechips Inc
@@ -36638,65 +37844,44 @@ OUI:988EDD*
OUI:98FC11*
ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
-OUI:A40CC3*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:34E0D7*
- ID_OUI_FROM_DATABASE=DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD
+OUI:180C77*
+ ID_OUI_FROM_DATABASE=Westinghouse Electric Company, LLC
-OUI:40520D*
- ID_OUI_FROM_DATABASE=Pico Technology
+OUI:ACA016*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:8C7CB5*
+OUI:78E400*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:543131*
- ID_OUI_FROM_DATABASE=Raster Vision Ltd
-
-OUI:90E0F0*
- ID_OUI_FROM_DATABASE=IEEE 1722a Working Group
-
-OUI:1C6F65*
- ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
-
-OUI:F0AD4E*
- ID_OUI_FROM_DATABASE=Globalscale Technologies, Inc.
-
-OUI:903D5A*
- ID_OUI_FROM_DATABASE=Shenzhen Wision Technology Holding Limited
-
-OUI:609AA4*
- ID_OUI_FROM_DATABASE=GVI SECURITY INC.
-
-OUI:F0ED1E*
- ID_OUI_FROM_DATABASE=Bilkon Bilgisayar Kontrollu Cih. Im.Ltd.
+OUI:E4AD7D*
+ ID_OUI_FROM_DATABASE=SCL Elements
-OUI:206A8A*
- ID_OUI_FROM_DATABASE=Wistron InfoComm Manufacturing(Kunshan)Co.,Ltd.
+OUI:40D40E*
+ ID_OUI_FROM_DATABASE=Biodata Ltd
-OUI:F80F41*
- ID_OUI_FROM_DATABASE=Wistron InfoComm(ZhongShan) Corporation
+OUI:7C051E*
+ ID_OUI_FROM_DATABASE=RAFAEL LTD.
-OUI:1CDF0F*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:58570D*
+ ID_OUI_FROM_DATABASE=Danfoss Solar Inverters
-OUI:34DF2A*
- ID_OUI_FROM_DATABASE=Fujikon Industrial Co.,Limited
+OUI:E47CF9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
-OUI:C88447*
- ID_OUI_FROM_DATABASE=Beautiful Enterprise Co., Ltd
+OUI:0C826A*
+ ID_OUI_FROM_DATABASE=Wuhan Huagong Genuine Optics Technology Co., Ltd
-OUI:C88B47*
- ID_OUI_FROM_DATABASE=Nolangroup S.P.A con Socio Unico
+OUI:5C0E8B*
+ ID_OUI_FROM_DATABASE=Zebra Technologies Inc
-OUI:24BA30*
- ID_OUI_FROM_DATABASE=Technical Consumer Products, Inc.
+OUI:38C7BA*
+ ID_OUI_FROM_DATABASE=CS Services Co.,Ltd.
-OUI:74D675*
- ID_OUI_FROM_DATABASE=WYMA Tecnologia
+OUI:70D57E*
+ ID_OUI_FROM_DATABASE=Scalar Corporation
-OUI:D43D67*
- ID_OUI_FROM_DATABASE=Carma Industries Inc.
+OUI:7866AE*
+ ID_OUI_FROM_DATABASE=ZTEC Instruments, Inc.
OUI:78818F*
ID_OUI_FROM_DATABASE=Server Racks Australia Pty Ltd
@@ -36722,15 +37907,69 @@ OUI:68E41F*
OUI:84F64C*
ID_OUI_FROM_DATABASE=Cross Point BV
-OUI:180C77*
- ID_OUI_FROM_DATABASE=Westinghouse Electric Company, LLC
+OUI:90513F*
+ ID_OUI_FROM_DATABASE=Elettronica Santerno SpA
-OUI:ACA016*
+OUI:7CA29B*
+ ID_OUI_FROM_DATABASE=D.SignT GmbH & Co. KG
+
+OUI:34AAEE*
+ ID_OUI_FROM_DATABASE=Mikrovisatos Servisas UAB
+
+OUI:A40CC3*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:78E400*
+OUI:34E0D7*
+ ID_OUI_FROM_DATABASE=DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD
+
+OUI:40520D*
+ ID_OUI_FROM_DATABASE=Pico Technology
+
+OUI:8C7CB5*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+OUI:543131*
+ ID_OUI_FROM_DATABASE=Raster Vision Ltd
+
+OUI:90E0F0*
+ ID_OUI_FROM_DATABASE=IEEE 1722a Working Group
+
+OUI:1C6F65*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:F0AD4E*
+ ID_OUI_FROM_DATABASE=Globalscale Technologies, Inc.
+
+OUI:903D5A*
+ ID_OUI_FROM_DATABASE=Shenzhen Wision Technology Holding Limited
+
+OUI:609AA4*
+ ID_OUI_FROM_DATABASE=GVI SECURITY INC.
+
+OUI:F0ED1E*
+ ID_OUI_FROM_DATABASE=Bilkon Bilgisayar Kontrollu Cih. Im.Ltd.
+
+OUI:24A937*
+ ID_OUI_FROM_DATABASE=PURE Storage
+
+OUI:348302*
+ ID_OUI_FROM_DATABASE=iFORCOM Co., Ltd
+
+OUI:949C55*
+ ID_OUI_FROM_DATABASE=Alta Data Technologies
+
+OUI:389F83*
+ ID_OUI_FROM_DATABASE=OTN Systems N.V.
+
+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.
+
OUI:905446*
ID_OUI_FROM_DATABASE=TES ELECTRONIC SOLUTIONS
@@ -36749,41 +37988,11 @@ OUI:A4BE61*
OUI:E06290*
ID_OUI_FROM_DATABASE=Jinan Jovision Science & Technology Co., Ltd.
-OUI:68DB96*
- ID_OUI_FROM_DATABASE=OPWILL Technologies CO .,LTD
-
-OUI:00F860*
- ID_OUI_FROM_DATABASE=PT. Panggung Electric Citrabuana
-
-OUI:FCEDB9*
- ID_OUI_FROM_DATABASE=Arrayent
-
-OUI:44ED57*
- ID_OUI_FROM_DATABASE=Longicorn, inc.
-
-OUI:90513F*
- ID_OUI_FROM_DATABASE=Elettronica Santerno SpA
-
-OUI:7CA29B*
- ID_OUI_FROM_DATABASE=D.SignT GmbH & Co. KG
-
-OUI:34AAEE*
- ID_OUI_FROM_DATABASE=Mikrovisatos Servisas UAB
-
-OUI:7866AE*
- ID_OUI_FROM_DATABASE=ZTEC Instruments, Inc.
-
-OUI:24AF4A*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
-
-OUI:00BD27*
- ID_OUI_FROM_DATABASE=Exar Corp.
-
-OUI:C8A729*
- ID_OUI_FROM_DATABASE=SYStronics Co., Ltd.
+OUI:A01859*
+ ID_OUI_FROM_DATABASE=Shenzhen Yidashi Electronics Co Ltd
-OUI:6C9CE9*
- ID_OUI_FROM_DATABASE=Nimble Storage
+OUI:042234*
+ ID_OUI_FROM_DATABASE=Wireless Standard Extensions
OUI:7812B8*
ID_OUI_FROM_DATABASE=ORANTEK LIMITED
@@ -36815,81 +38024,12 @@ OUI:CC69B0*
OUI:2872C5*
ID_OUI_FROM_DATABASE=Smartmatic Corp
-OUI:E4AD7D*
- ID_OUI_FROM_DATABASE=SCL Elements
-
-OUI:40D40E*
- ID_OUI_FROM_DATABASE=Biodata Ltd
-
-OUI:7C051E*
- ID_OUI_FROM_DATABASE=RAFAEL LTD.
-
-OUI:58570D*
- ID_OUI_FROM_DATABASE=Danfoss Solar Inverters
-
-OUI:E47CF9*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
-
-OUI:0C826A*
- ID_OUI_FROM_DATABASE=Wuhan Huagong Genuine Optics Technology Co., Ltd
-
-OUI:5C0E8B*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc
-
-OUI:38C7BA*
- ID_OUI_FROM_DATABASE=CS Services Co.,Ltd.
-
-OUI:70D57E*
- ID_OUI_FROM_DATABASE=Scalar Corporation
-
-OUI:24A937*
- ID_OUI_FROM_DATABASE=PURE Storage
-
-OUI:348302*
- ID_OUI_FROM_DATABASE=iFORCOM Co., Ltd
-
-OUI:949C55*
- ID_OUI_FROM_DATABASE=Alta Data Technologies
-
-OUI:70D5E7*
- ID_OUI_FROM_DATABASE=Wellcore Corporation
-
-OUI:3CF72A*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
-OUI:FCE192*
- ID_OUI_FROM_DATABASE=Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd
-
-OUI:F8912A*
- ID_OUI_FROM_DATABASE=GLP German Light Products GmbH
-
-OUI:E02630*
- ID_OUI_FROM_DATABASE=Intrigue Technologies, Inc.
-
-OUI:8C9236*
- ID_OUI_FROM_DATABASE=Aus.Linx Technology Co., Ltd.
-
-OUI:F445ED*
- ID_OUI_FROM_DATABASE=Portable Innovation Technology Ltd.
-
-OUI:6C32DE*
- ID_OUI_FROM_DATABASE=Indieon Technologies Pvt. Ltd.
-
-OUI:FCCF62*
- ID_OUI_FROM_DATABASE=IBM Corp
-
-OUI:D8E72B*
- ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
-
OUI:B8A3E0*
ID_OUI_FROM_DATABASE=BenRui Technology Co.,Ltd
OUI:B8F732*
ID_OUI_FROM_DATABASE=Aryaka Networks Inc
-OUI:0CD502*
- ID_OUI_FROM_DATABASE=Westell
-
OUI:70828E*
ID_OUI_FROM_DATABASE=OleumTech Corporation
@@ -36908,23 +38048,14 @@ OUI:506313*
OUI:A8995C*
ID_OUI_FROM_DATABASE=aizo ag
-OUI:4012E4*
- ID_OUI_FROM_DATABASE=Compass-EOS
-
-OUI:F8DC7A*
- ID_OUI_FROM_DATABASE=Variscite LTD
-
-OUI:EC4476*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:9CEBE8*
- ID_OUI_FROM_DATABASE=BizLink (Kunshan) Co.,Ltd
+OUI:F445ED*
+ ID_OUI_FROM_DATABASE=Portable Innovation Technology Ltd.
-OUI:A01859*
- ID_OUI_FROM_DATABASE=Shenzhen Yidashi Electronics Co Ltd
+OUI:6C32DE*
+ ID_OUI_FROM_DATABASE=Indieon Technologies Pvt. Ltd.
-OUI:042234*
- ID_OUI_FROM_DATABASE=Wireless Standard Extensions
+OUI:FCCF62*
+ ID_OUI_FROM_DATABASE=IBM Corp
OUI:B09074*
ID_OUI_FROM_DATABASE=Fulan Electronics Limited
@@ -36932,9 +38063,6 @@ OUI:B09074*
OUI:2CA835*
ID_OUI_FROM_DATABASE=RIM
-OUI:3CE5A6*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd.
-
OUI:94F692*
ID_OUI_FROM_DATABASE=Geminico co.,Ltd.
@@ -36944,29 +38072,35 @@ OUI:8C736E*
OUI:30EFD1*
ID_OUI_FROM_DATABASE=Alstom Strongwish (Shenzhen) Co., Ltd.
-OUI:7C2CF3*
- ID_OUI_FROM_DATABASE=Secure Electrans Ltd
+OUI:C835B8*
+ ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K
-OUI:304174*
- ID_OUI_FROM_DATABASE=ALTEC LANSING LLC
+OUI:243C20*
+ ID_OUI_FROM_DATABASE=Dynamode Group
-OUI:7830E1*
- ID_OUI_FROM_DATABASE=UltraClenz, LLC
+OUI:70D5E7*
+ ID_OUI_FROM_DATABASE=Wellcore Corporation
-OUI:FCFBFB*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:3CF72A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:1C129D*
- ID_OUI_FROM_DATABASE=IEEE PES PSRC/SUB
+OUI:FCE192*
+ ID_OUI_FROM_DATABASE=Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd
-OUI:B40832*
- ID_OUI_FROM_DATABASE=TC Communications
+OUI:F8912A*
+ ID_OUI_FROM_DATABASE=GLP German Light Products GmbH
-OUI:B42CBE*
- ID_OUI_FROM_DATABASE=Direct Payment Solutions Limited
+OUI:E02630*
+ ID_OUI_FROM_DATABASE=Intrigue Technologies, Inc.
-OUI:F47626*
- ID_OUI_FROM_DATABASE=Viltechmeda UAB
+OUI:8C9236*
+ ID_OUI_FROM_DATABASE=Aus.Linx Technology Co., Ltd.
+
+OUI:4012E4*
+ ID_OUI_FROM_DATABASE=Compass-EOS
+
+OUI:F8DC7A*
+ ID_OUI_FROM_DATABASE=Variscite LTD
OUI:003A9C*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -36986,50 +38120,17 @@ OUI:0494A1*
OUI:2C3427*
ID_OUI_FROM_DATABASE=ERCO & GENER
-OUI:389F83*
- ID_OUI_FROM_DATABASE=OTN Systems N.V.
-
-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.
-
-OUI:C835B8*
- ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K
-
-OUI:243C20*
- ID_OUI_FROM_DATABASE=Dynamode Group
-
-OUI:E09153*
- ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
-
-OUI:CC0080*
- ID_OUI_FROM_DATABASE=BETTINI SRL
-
-OUI:644BC3*
- ID_OUI_FROM_DATABASE=Shanghai WOASiS Telecommunications Ltd., Co.
-
-OUI:0CE709*
- ID_OUI_FROM_DATABASE=Fox Crypto B.V.
-
-OUI:002720*
- ID_OUI_FROM_DATABASE=NEW-SOL COM
-
-OUI:00271C*
- ID_OUI_FROM_DATABASE=MERCURY CORPORATION
+OUI:B42CBE*
+ ID_OUI_FROM_DATABASE=Direct Payment Solutions Limited
-OUI:002712*
- ID_OUI_FROM_DATABASE=MaxVision LLC
+OUI:F47626*
+ ID_OUI_FROM_DATABASE=Viltechmeda UAB
-OUI:00270F*
- ID_OUI_FROM_DATABASE=Envisionnovation Inc
+OUI:EC4476*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:002703*
- ID_OUI_FROM_DATABASE=Testech Electronics Pte Ltd
+OUI:9CEBE8*
+ ID_OUI_FROM_DATABASE=BizLink (Kunshan) Co.,Ltd
OUI:88ED1C*
ID_OUI_FROM_DATABASE=Cudo Communication Co., Ltd.
@@ -37037,9 +38138,6 @@ OUI:88ED1C*
OUI:B05B1F*
ID_OUI_FROM_DATABASE=THERMO FISHER SCIENTIFIC S.P.A.
-OUI:404A03*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:743256*
ID_OUI_FROM_DATABASE=NT-ware Systemprg GmbH
@@ -37058,68 +38156,47 @@ OUI:C87E75*
OUI:889821*
ID_OUI_FROM_DATABASE=TERAON
-OUI:0026FD*
- ID_OUI_FROM_DATABASE=Interactive Intelligence
-
-OUI:0026F6*
- ID_OUI_FROM_DATABASE=Military Communication Institute
-
-OUI:0026F0*
- ID_OUI_FROM_DATABASE=cTrixs International GmbH.
-
-OUI:0026EA*
- ID_OUI_FROM_DATABASE=Cheerchip Electronic Technology (ShangHai) Co., Ltd.
-
-OUI:0026E3*
- ID_OUI_FROM_DATABASE=DTI
-
-OUI:0026DD*
- ID_OUI_FROM_DATABASE=Fival Science & Technology Co.,Ltd.
-
-OUI:0026DE*
- ID_OUI_FROM_DATABASE=FDI MATELEC
-
-OUI:0026D7*
- ID_OUI_FROM_DATABASE=KM Electornic Technology Co., Ltd.
+OUI:CC5076*
+ ID_OUI_FROM_DATABASE=Ocom Communications, Inc.
-OUI:0026D1*
- ID_OUI_FROM_DATABASE=S Squared Innovations Inc.
+OUI:705812*
+ ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-OUI:54B620*
- ID_OUI_FROM_DATABASE=SUHDOL E&C Co.Ltd.
+OUI:7C2CF3*
+ ID_OUI_FROM_DATABASE=Secure Electrans Ltd
-OUI:C4AAA1*
- ID_OUI_FROM_DATABASE=SUMMIT DEVELOPMENT, spol.s r.o.
+OUI:304174*
+ ID_OUI_FROM_DATABASE=ALTEC LANSING LLC
-OUI:78C40E*
- ID_OUI_FROM_DATABASE=H&D Wireless
+OUI:7830E1*
+ ID_OUI_FROM_DATABASE=UltraClenz, LLC
-OUI:9C5B96*
- ID_OUI_FROM_DATABASE=NMR Corporation
+OUI:FCFBFB*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:E4FFDD*
- ID_OUI_FROM_DATABASE=ELECTRON INDIA
+OUI:1C129D*
+ ID_OUI_FROM_DATABASE=IEEE PES PSRC/SUB
-OUI:6C8CDB*
- ID_OUI_FROM_DATABASE=Otus Technologies Ltd
+OUI:B40832*
+ ID_OUI_FROM_DATABASE=TC Communications
-OUI:B4417A*
- ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd
+OUI:002720*
+ ID_OUI_FROM_DATABASE=NEW-SOL COM
-OUI:401597*
- ID_OUI_FROM_DATABASE=Protect America, Inc.
+OUI:00271C*
+ ID_OUI_FROM_DATABASE=MERCURY CORPORATION
-OUI:F852DF*
- ID_OUI_FROM_DATABASE=VNL Europe AB
+OUI:002712*
+ ID_OUI_FROM_DATABASE=MaxVision LLC
-OUI:1CF061*
- ID_OUI_FROM_DATABASE=SCAPS GmbH
+OUI:00270F*
+ ID_OUI_FROM_DATABASE=Envisionnovation Inc
-OUI:A893E6*
- ID_OUI_FROM_DATABASE=JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD
+OUI:0026D7*
+ ID_OUI_FROM_DATABASE=KM Electornic Technology Co., Ltd.
-OUI:7825AD*
- ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD.
+OUI:0026D1*
+ ID_OUI_FROM_DATABASE=S Squared Innovations Inc.
OUI:0026CB*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -37145,6 +38222,30 @@ OUI:0026A8*
OUI:0026A7*
ID_OUI_FROM_DATABASE=CONNECT SRL
+OUI:0026A1*
+ ID_OUI_FROM_DATABASE=Megger
+
+OUI:0026A2*
+ ID_OUI_FROM_DATABASE=Instrumentation Technology Systems
+
+OUI:00269B*
+ ID_OUI_FROM_DATABASE=SOKRAT Ltd.
+
+OUI:002695*
+ ID_OUI_FROM_DATABASE=ZT Group Int'l Inc
+
+OUI:00268F*
+ ID_OUI_FROM_DATABASE=MTA SpA
+
+OUI:6C8CDB*
+ ID_OUI_FROM_DATABASE=Otus Technologies Ltd
+
+OUI:B4417A*
+ ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd
+
+OUI:401597*
+ ID_OUI_FROM_DATABASE=Protect America, Inc.
+
OUI:60391F*
ID_OUI_FROM_DATABASE=ABB Ltd
@@ -37169,41 +38270,98 @@ OUI:10BAA5*
OUI:586ED6*
ID_OUI_FROM_DATABASE=Private
-OUI:CC5076*
- ID_OUI_FROM_DATABASE=Ocom Communications, Inc.
+OUI:E09153*
+ ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
-OUI:705812*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
+OUI:CC0080*
+ ID_OUI_FROM_DATABASE=BETTINI SRL
-OUI:002648*
- ID_OUI_FROM_DATABASE=Emitech Corp.
+OUI:644BC3*
+ ID_OUI_FROM_DATABASE=Shanghai WOASiS Telecommunications Ltd., Co.
-OUI:002644*
- ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+OUI:0CE709*
+ ID_OUI_FROM_DATABASE=Fox Crypto B.V.
-OUI:00263E*
- ID_OUI_FROM_DATABASE=Trapeze Networks
+OUI:002703*
+ ID_OUI_FROM_DATABASE=Testech Electronics Pte Ltd
-OUI:002638*
- ID_OUI_FROM_DATABASE=Xia Men Joyatech Co., Ltd.
+OUI:0026FD*
+ ID_OUI_FROM_DATABASE=Interactive Intelligence
-OUI:00263D*
- ID_OUI_FROM_DATABASE=MIA Corporation
+OUI:0026F6*
+ ID_OUI_FROM_DATABASE=Military Communication Institute
-OUI:002631*
- ID_OUI_FROM_DATABASE=COMMTACT LTD
+OUI:0026F0*
+ ID_OUI_FROM_DATABASE=cTrixs International GmbH.
-OUI:00262B*
- ID_OUI_FROM_DATABASE=Wongs Electronics Co. Ltd.
+OUI:0026EA*
+ ID_OUI_FROM_DATABASE=Cheerchip Electronic Technology (ShangHai) Co., Ltd.
-OUI:002625*
- ID_OUI_FROM_DATABASE=MediaSputnik
+OUI:0026E3*
+ ID_OUI_FROM_DATABASE=DTI
-OUI:00261E*
- ID_OUI_FROM_DATABASE=QINGBANG ELEC(SZ) CO., LTD
+OUI:0026DD*
+ ID_OUI_FROM_DATABASE=Fival Science & Technology Co.,Ltd.
-OUI:002619*
- ID_OUI_FROM_DATABASE=FRC
+OUI:0026DE*
+ ID_OUI_FROM_DATABASE=FDI MATELEC
+
+OUI:7825AD*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD.
+
+OUI:54B620*
+ ID_OUI_FROM_DATABASE=SUHDOL E&C Co.Ltd.
+
+OUI:C4AAA1*
+ ID_OUI_FROM_DATABASE=SUMMIT DEVELOPMENT, spol.s r.o.
+
+OUI:78C40E*
+ ID_OUI_FROM_DATABASE=H&D Wireless
+
+OUI:9C5B96*
+ ID_OUI_FROM_DATABASE=NMR Corporation
+
+OUI:E4FFDD*
+ ID_OUI_FROM_DATABASE=ELECTRON INDIA
+
+OUI:F852DF*
+ ID_OUI_FROM_DATABASE=VNL Europe AB
+
+OUI:1CF061*
+ ID_OUI_FROM_DATABASE=SCAPS GmbH
+
+OUI:A893E6*
+ ID_OUI_FROM_DATABASE=JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD
+
+OUI:00267C*
+ ID_OUI_FROM_DATABASE=Metz-Werke GmbH & Co KG
+
+OUI:002676*
+ ID_OUI_FROM_DATABASE=COMMidt AS
+
+OUI:00266F*
+ ID_OUI_FROM_DATABASE=Coordiwise Technology Corp.
+
+OUI:002670*
+ ID_OUI_FROM_DATABASE=Cinch Connectors
+
+OUI:002663*
+ ID_OUI_FROM_DATABASE=Shenzhen Huitaiwei Tech. Ltd, co.
+
+OUI:00265D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:0025CD*
+ ID_OUI_FROM_DATABASE=Skylane Optics
+
+OUI:0025C8*
+ ID_OUI_FROM_DATABASE=S-Access GmbH
+
+OUI:0025C7*
+ ID_OUI_FROM_DATABASE=altek Corporation
+
+OUI:0025C1*
+ ID_OUI_FROM_DATABASE=Nawoo Korea Corp.
OUI:0025BA*
ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
@@ -37220,6 +38378,36 @@ OUI:0025A8*
OUI:0025A7*
ID_OUI_FROM_DATABASE=Comverge, Inc.
+OUI:00262B*
+ ID_OUI_FROM_DATABASE=Wongs Electronics Co. Ltd.
+
+OUI:002625*
+ ID_OUI_FROM_DATABASE=MediaSputnik
+
+OUI:00261E*
+ ID_OUI_FROM_DATABASE=QINGBANG ELEC(SZ) CO., LTD
+
+OUI:002619*
+ ID_OUI_FROM_DATABASE=FRC
+
+OUI:002612*
+ ID_OUI_FROM_DATABASE=Space Exploration Technologies
+
+OUI:00260B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:00260C*
+ ID_OUI_FROM_DATABASE=Dataram
+
+OUI:0025FF*
+ ID_OUI_FROM_DATABASE=CreNova Multimedia Co., Ltd
+
+OUI:002606*
+ ID_OUI_FROM_DATABASE=RAUMFELD GmbH
+
+OUI:0025F9*
+ ID_OUI_FROM_DATABASE=GMK electronic design GmbH
+
OUI:0025A2*
ID_OUI_FROM_DATABASE=Alta Definicion LINCEO S.L.
@@ -37232,122 +38420,104 @@ OUI:00259B*
OUI:002595*
ID_OUI_FROM_DATABASE=Northwest Signal Supply, Inc
-OUI:002542*
- ID_OUI_FROM_DATABASE=Pittasoft
+OUI:00258F*
+ ID_OUI_FROM_DATABASE=Trident Microsystems, Inc.
-OUI:002530*
- ID_OUI_FROM_DATABASE=Aetas Systems Inc.
+OUI:002585*
+ ID_OUI_FROM_DATABASE=KOKUYO S&T Co., Ltd.
-OUI:002529*
- ID_OUI_FROM_DATABASE=COMELIT GROUP S.P.A
+OUI:00257B*
+ ID_OUI_FROM_DATABASE=STJ ELECTRONICS PVT LTD
-OUI:002522*
- ID_OUI_FROM_DATABASE=ASRock Incorporation
+OUI:002574*
+ ID_OUI_FROM_DATABASE=KUNIMI MEDIA DEVICE Co., Ltd.
-OUI:00251D*
- ID_OUI_FROM_DATABASE=DSA Encore, LLC
+OUI:00264F*
+ ID_OUI_FROM_DATABASE=Krüger &Gothe GmbH
-OUI:002518*
- ID_OUI_FROM_DATABASE=Power PLUS Communications AG
+OUI:002648*
+ ID_OUI_FROM_DATABASE=Emitech Corp.
-OUI:002513*
- ID_OUI_FROM_DATABASE=CXP DIGITAL BV
+OUI:002644*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
-OUI:0026A1*
- ID_OUI_FROM_DATABASE=Megger
+OUI:00263E*
+ ID_OUI_FROM_DATABASE=Trapeze Networks
-OUI:0026A2*
- ID_OUI_FROM_DATABASE=Instrumentation Technology Systems
+OUI:002638*
+ ID_OUI_FROM_DATABASE=Xia Men Joyatech Co., Ltd.
-OUI:00269B*
- ID_OUI_FROM_DATABASE=SOKRAT Ltd.
+OUI:00263D*
+ ID_OUI_FROM_DATABASE=MIA Corporation
-OUI:002695*
- ID_OUI_FROM_DATABASE=ZT Group Int'l Inc
+OUI:002631*
+ ID_OUI_FROM_DATABASE=COMMTACT LTD
-OUI:00268F*
- ID_OUI_FROM_DATABASE=MTA SpA
+OUI:00256F*
+ ID_OUI_FROM_DATABASE=Dantherm Power
-OUI:00267C*
- ID_OUI_FROM_DATABASE=Metz-Werke GmbH & Co KG
+OUI:002562*
+ ID_OUI_FROM_DATABASE=interbro Co. Ltd.
OUI:00255C*
ID_OUI_FROM_DATABASE=NEC Corporation
-OUI:002550*
- ID_OUI_FROM_DATABASE=Riverbed Technology
-
-OUI:002555*
- ID_OUI_FROM_DATABASE=Visonic Technologies 1993 Ltd
-
OUI:00254F*
ID_OUI_FROM_DATABASE=ELETTROLAB Srl
-OUI:002549*
- ID_OUI_FROM_DATABASE=Jeorich Tech. Co.,Ltd.
-
-OUI:002538*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Memory Division
-
-OUI:002676*
- ID_OUI_FROM_DATABASE=COMMidt AS
-
-OUI:00266F*
- ID_OUI_FROM_DATABASE=Coordiwise Technology Corp.
-
-OUI:002670*
- ID_OUI_FROM_DATABASE=Cinch Connectors
+OUI:002518*
+ ID_OUI_FROM_DATABASE=Power PLUS Communications AG
-OUI:002663*
- ID_OUI_FROM_DATABASE=Shenzhen Huitaiwei Tech. Ltd, co.
+OUI:002513*
+ ID_OUI_FROM_DATABASE=CXP DIGITAL BV
-OUI:00265D*
- ID_OUI_FROM_DATABASE=Samsung Electronics
+OUI:00250C*
+ ID_OUI_FROM_DATABASE=Enertrac
-OUI:00264F*
- ID_OUI_FROM_DATABASE=Krüger &Gothe GmbH
+OUI:002505*
+ ID_OUI_FROM_DATABASE=eks Engel GmbH & Co. KG
-OUI:0025E0*
- ID_OUI_FROM_DATABASE=CeedTec Sdn Bhd
+OUI:0024F9*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0025DA*
- ID_OUI_FROM_DATABASE=Secura Key
+OUI:0024F2*
+ ID_OUI_FROM_DATABASE=Uniphone Telecommunication Co., Ltd.
-OUI:0025D9*
- ID_OUI_FROM_DATABASE=DataFab Systems Inc.
+OUI:0024ED*
+ ID_OUI_FROM_DATABASE=YT Elec. Co,.Ltd.
-OUI:0025D4*
- ID_OUI_FROM_DATABASE=Fortress Technologies
+OUI:0024E6*
+ ID_OUI_FROM_DATABASE=In Motion Technology Inc.
-OUI:0025CD*
- ID_OUI_FROM_DATABASE=Skylane Optics
+OUI:0024E1*
+ ID_OUI_FROM_DATABASE=Convey Computer Corp.
-OUI:0025C8*
- ID_OUI_FROM_DATABASE=S-Access GmbH
+OUI:0024DF*
+ ID_OUI_FROM_DATABASE=Digitalbox Europe GmbH
-OUI:0025C7*
- ID_OUI_FROM_DATABASE=altek Corporation
+OUI:0024DA*
+ ID_OUI_FROM_DATABASE=Innovar Systems Limited
-OUI:0025C1*
- ID_OUI_FROM_DATABASE=Nawoo Korea Corp.
+OUI:002549*
+ ID_OUI_FROM_DATABASE=Jeorich Tech. Co.,Ltd.
-OUI:002612*
- ID_OUI_FROM_DATABASE=Space Exploration Technologies
+OUI:002538*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Memory Division
-OUI:00260B*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:002542*
+ ID_OUI_FROM_DATABASE=Pittasoft
-OUI:00260C*
- ID_OUI_FROM_DATABASE=Dataram
+OUI:002530*
+ ID_OUI_FROM_DATABASE=Aetas Systems Inc.
-OUI:0025FF*
- ID_OUI_FROM_DATABASE=CreNova Multimedia Co., Ltd
+OUI:002529*
+ ID_OUI_FROM_DATABASE=COMELIT GROUP S.P.A
-OUI:002606*
- ID_OUI_FROM_DATABASE=RAUMFELD GmbH
+OUI:002522*
+ ID_OUI_FROM_DATABASE=ASRock Incorporation
-OUI:0025F9*
- ID_OUI_FROM_DATABASE=GMK electronic design GmbH
+OUI:00251D*
+ ID_OUI_FROM_DATABASE=DSA Encore, LLC
OUI:0025F5*
ID_OUI_FROM_DATABASE=DVS Korea, Co., Ltd
@@ -37361,29 +38531,20 @@ OUI:0025EA*
OUI:0025E4*
ID_OUI_FROM_DATABASE=OMNI-WiFi, LLC
-OUI:00258F*
- ID_OUI_FROM_DATABASE=Trident Microsystems, Inc.
-
-OUI:00258B*
- ID_OUI_FROM_DATABASE=Mellanox Technologies Ltd
-
-OUI:002585*
- ID_OUI_FROM_DATABASE=KOKUYO S&T Co., Ltd.
-
-OUI:00257B*
- ID_OUI_FROM_DATABASE=STJ ELECTRONICS PVT LTD
+OUI:0025E0*
+ ID_OUI_FROM_DATABASE=CeedTec Sdn Bhd
-OUI:002574*
- ID_OUI_FROM_DATABASE=KUNIMI MEDIA DEVICE Co., Ltd.
+OUI:0025DA*
+ ID_OUI_FROM_DATABASE=Secura Key
-OUI:00256F*
- ID_OUI_FROM_DATABASE=Dantherm Power
+OUI:0025D9*
+ ID_OUI_FROM_DATABASE=DataFab Systems Inc.
-OUI:002562*
- ID_OUI_FROM_DATABASE=interbro Co. Ltd.
+OUI:002410*
+ ID_OUI_FROM_DATABASE=NUETEQ Technology,Inc.
-OUI:002561*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+OUI:002409*
+ ID_OUI_FROM_DATABASE=The Toro Company
OUI:0023F7*
ID_OUI_FROM_DATABASE=Private
@@ -37400,8 +38561,26 @@ OUI:0023EC*
OUI:0023E7*
ID_OUI_FROM_DATABASE=Hinke A/S
-OUI:0023E0*
- ID_OUI_FROM_DATABASE=INO Therapeutics LLC
+OUI:002387*
+ ID_OUI_FROM_DATABASE=ThinkFlood, Inc.
+
+OUI:002381*
+ ID_OUI_FROM_DATABASE=Lengda Technology(Xiamen) Co.,Ltd.
+
+OUI:00237B*
+ ID_OUI_FROM_DATABASE=WHDI LLC
+
+OUI:002372*
+ ID_OUI_FROM_DATABASE=MORE STAR INDUSTRIAL GROUP LIMITED
+
+OUI:0024CE*
+ ID_OUI_FROM_DATABASE=Exeltech Inc
+
+OUI:0024D3*
+ ID_OUI_FROM_DATABASE=QUALICA Inc.
+
+OUI:0024C7*
+ ID_OUI_FROM_DATABASE=Mobilarm Ltd
OUI:0024C2*
ID_OUI_FROM_DATABASE=Asumo Co.,Ltd.
@@ -37424,6 +38603,39 @@ OUI:00249A*
OUI:00249F*
ID_OUI_FROM_DATABASE=RIM Testing Services
+OUI:002487*
+ ID_OUI_FROM_DATABASE=Blackboard Inc.
+
+OUI:002498*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:002485*
+ ID_OUI_FROM_DATABASE=ConteXtream Ltd
+
+OUI:002480*
+ ID_OUI_FROM_DATABASE=Meteocontrol GmbH
+
+OUI:002454*
+ ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
+
+OUI:002448*
+ ID_OUI_FROM_DATABASE=SpiderCloud Wireless, Inc
+
+OUI:00244A*
+ ID_OUI_FROM_DATABASE=Voyant International
+
+OUI:002449*
+ ID_OUI_FROM_DATABASE=Shen Zhen Lite Star Electronics Technology Co., Ltd
+
+OUI:002443*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002439*
+ ID_OUI_FROM_DATABASE=Digital Barriers Advanced Technologies
+
+OUI:002479*
+ ID_OUI_FROM_DATABASE=Optec Displays, Inc.
+
OUI:00246D*
ID_OUI_FROM_DATABASE=Weinzierl Engineering GmbH
@@ -37445,53 +38657,32 @@ OUI:00245C*
OUI:00244F*
ID_OUI_FROM_DATABASE=Asantron Technologies Ltd.
-OUI:002454*
- ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
-
-OUI:002448*
- ID_OUI_FROM_DATABASE=SpiderCloud Wireless, Inc
-
-OUI:00244A*
- ID_OUI_FROM_DATABASE=Voyant International
-
-OUI:002449*
- ID_OUI_FROM_DATABASE=Shen Zhen Lite Star Electronics Technology Co., Ltd
-
-OUI:00250C*
- ID_OUI_FROM_DATABASE=Enertrac
-
-OUI:002505*
- ID_OUI_FROM_DATABASE=eks Engel GmbH & Co. KG
-
-OUI:0024F9*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:0024F2*
- ID_OUI_FROM_DATABASE=Uniphone Telecommunication Co., Ltd.
+OUI:0023BB*
+ ID_OUI_FROM_DATABASE=Schmitt Industries
-OUI:0024ED*
- ID_OUI_FROM_DATABASE=YT Elec. Co,.Ltd.
+OUI:0023BA*
+ ID_OUI_FROM_DATABASE=Chroma
-OUI:0024E6*
- ID_OUI_FROM_DATABASE=In Motion Technology Inc.
+OUI:0023B5*
+ ID_OUI_FROM_DATABASE=ORTANA LTD
-OUI:0024E1*
- ID_OUI_FROM_DATABASE=Convey Computer Corp.
+OUI:0023A8*
+ ID_OUI_FROM_DATABASE=Marshall Electronics
-OUI:0024DF*
- ID_OUI_FROM_DATABASE=Digitalbox Europe GmbH
+OUI:00239B*
+ ID_OUI_FROM_DATABASE=Elster Solutions, LLC
-OUI:0024DA*
- ID_OUI_FROM_DATABASE=Innovar Systems Limited
+OUI:002396*
+ ID_OUI_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION
-OUI:0024CE*
- ID_OUI_FROM_DATABASE=Exeltech Inc
+OUI:002391*
+ ID_OUI_FROM_DATABASE=Maxian
-OUI:0024D3*
- ID_OUI_FROM_DATABASE=QUALICA Inc.
+OUI:00238C*
+ ID_OUI_FROM_DATABASE=Private
-OUI:0024C7*
- ID_OUI_FROM_DATABASE=Mobilarm Ltd
+OUI:002432*
+ ID_OUI_FROM_DATABASE=Neostar Technology Co.,LTD
OUI:002429*
ID_OUI_FROM_DATABASE=MK MASTER INC.
@@ -37505,35 +38696,8 @@ OUI:002428*
OUI:002416*
ID_OUI_FROM_DATABASE=Any Use
-OUI:002410*
- ID_OUI_FROM_DATABASE=NUETEQ Technology,Inc.
-
-OUI:002409*
- ID_OUI_FROM_DATABASE=The Toro Company
-
-OUI:002487*
- ID_OUI_FROM_DATABASE=Blackboard Inc.
-
-OUI:002498*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:002485*
- ID_OUI_FROM_DATABASE=ConteXtream Ltd
-
-OUI:002480*
- ID_OUI_FROM_DATABASE=Meteocontrol GmbH
-
-OUI:002479*
- ID_OUI_FROM_DATABASE=Optec Displays, Inc.
-
-OUI:002443*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
-OUI:002439*
- ID_OUI_FROM_DATABASE=Digital Barriers Advanced Technologies
-
-OUI:002432*
- ID_OUI_FROM_DATABASE=Neostar Technology Co.,LTD
+OUI:0023E0*
+ ID_OUI_FROM_DATABASE=INO Therapeutics LLC
OUI:0023DA*
ID_OUI_FROM_DATABASE=Industrial Computer Source (Deutschland)GmbH
@@ -37547,53 +38711,23 @@ OUI:0023C7*
OUI:0023C1*
ID_OUI_FROM_DATABASE=Securitas Direct AB
-OUI:0023BB*
- ID_OUI_FROM_DATABASE=Schmitt Industries
-
-OUI:0023BA*
- ID_OUI_FROM_DATABASE=Chroma
-
-OUI:0023B5*
- ID_OUI_FROM_DATABASE=ORTANA LTD
-
-OUI:002381*
- ID_OUI_FROM_DATABASE=Lengda Technology(Xiamen) Co.,Ltd.
-
-OUI:002382*
- ID_OUI_FROM_DATABASE=Lih Rong Electronic Enterprise Co., Ltd.
-
-OUI:00237B*
- ID_OUI_FROM_DATABASE=WHDI LLC
-
-OUI:002372*
- ID_OUI_FROM_DATABASE=MORE STAR INDUSTRIAL GROUP LIMITED
-
-OUI:002366*
- ID_OUI_FROM_DATABASE=Beijing Siasun Electronic System Co.,Ltd.
-
-OUI:00236B*
- ID_OUI_FROM_DATABASE=Xembedded, Inc.
-
-OUI:002359*
- ID_OUI_FROM_DATABASE=Benchmark Electronics ( Thailand ) Public Company Limited
-
-OUI:00235F*
- ID_OUI_FROM_DATABASE=Silicon Micro Sensors GmbH
+OUI:0021DC*
+ ID_OUI_FROM_DATABASE=TECNOALARM S.r.l.
-OUI:002353*
- ID_OUI_FROM_DATABASE=F E T Elettronica snc
+OUI:0021D6*
+ ID_OUI_FROM_DATABASE=LXI Consortium
-OUI:002347*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+OUI:0021CF*
+ ID_OUI_FROM_DATABASE=The Crypto Group
-OUI:00234C*
- ID_OUI_FROM_DATABASE=KTC AB
+OUI:0021C9*
+ ID_OUI_FROM_DATABASE=Wavecom Asia Pacific Limited
-OUI:00233A*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:0021CA*
+ ID_OUI_FROM_DATABASE=ART System Co., Ltd.
-OUI:002339*
- ID_OUI_FROM_DATABASE=Samsung Electronics
+OUI:0021C3*
+ ID_OUI_FROM_DATABASE=CORNELL Communications, Inc.
OUI:002334*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -37622,68 +38756,65 @@ OUI:002317*
OUI:002310*
ID_OUI_FROM_DATABASE=LNC Technology Co., Ltd.
-OUI:002304*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:002236*
- ID_OUI_FROM_DATABASE=VECTOR SP. Z O.O.
+OUI:002273*
+ ID_OUI_FROM_DATABASE=Techway
-OUI:002230*
- ID_OUI_FROM_DATABASE=FutureLogic Inc.
+OUI:002274*
+ ID_OUI_FROM_DATABASE=FamilyPhone AB
-OUI:002229*
- ID_OUI_FROM_DATABASE=Compumedics Ltd
+OUI:00226F*
+ ID_OUI_FROM_DATABASE=3onedata Technology Co. Ltd.
-OUI:00221D*
- ID_OUI_FROM_DATABASE=Freegene Technology LTD
+OUI:00226A*
+ ID_OUI_FROM_DATABASE=Honeywell
-OUI:002224*
- ID_OUI_FROM_DATABASE=Good Will Instrument Co., Ltd.
+OUI:002260*
+ ID_OUI_FROM_DATABASE=AFREEY Inc.
-OUI:002223*
- ID_OUI_FROM_DATABASE=TimeKeeping Systems, Inc.
+OUI:00225B*
+ ID_OUI_FROM_DATABASE=Teradici Corporation
-OUI:002216*
- ID_OUI_FROM_DATABASE=SHIBAURA VENDING MACHINE CORPORATION
+OUI:002256*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:002217*
- ID_OUI_FROM_DATABASE=Neat Electronics
+OUI:002255*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:002211*
- ID_OUI_FROM_DATABASE=Rohati Systems
+OUI:00224D*
+ ID_OUI_FROM_DATABASE=MITAC INTERNATIONAL CORP.
-OUI:00220A*
- ID_OUI_FROM_DATABASE=OnLive, Inc
+OUI:002252*
+ ID_OUI_FROM_DATABASE=ZOLL Lifecor Corporation
-OUI:002295*
- ID_OUI_FROM_DATABASE=SGM Technology for lighting spa
+OUI:002246*
+ ID_OUI_FROM_DATABASE=Evoc Intelligent Technology Co.,Ltd.
-OUI:00228E*
- ID_OUI_FROM_DATABASE=TV-NUMERIC
+OUI:002366*
+ ID_OUI_FROM_DATABASE=Beijing Siasun Electronic System Co.,Ltd.
-OUI:002289*
- ID_OUI_FROM_DATABASE=Optosecurity Inc.
+OUI:00236B*
+ ID_OUI_FROM_DATABASE=Xembedded, Inc.
-OUI:002282*
- ID_OUI_FROM_DATABASE=8086 Consultancy
+OUI:002359*
+ ID_OUI_FROM_DATABASE=Benchmark Electronics ( Thailand ) Public Company Limited
-OUI:00227C*
- ID_OUI_FROM_DATABASE=Woori SMT Co.,ltd
+OUI:00235F*
+ ID_OUI_FROM_DATABASE=Silicon Micro Sensors GmbH
-OUI:002279*
- ID_OUI_FROM_DATABASE=Nippon Conlux Co., Ltd.
+OUI:002353*
+ ID_OUI_FROM_DATABASE=F E T Elettronica snc
-OUI:002273*
- ID_OUI_FROM_DATABASE=Techway
+OUI:00234C*
+ ID_OUI_FROM_DATABASE=KTC AB
-OUI:002274*
- ID_OUI_FROM_DATABASE=FamilyPhone AB
+OUI:00233A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:00226F*
- ID_OUI_FROM_DATABASE=3onedata Technology Co. Ltd.
+OUI:002339*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:00226A*
- ID_OUI_FROM_DATABASE=Honeywell
+OUI:002304*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:0022F3*
ID_OUI_FROM_DATABASE=SHARP Corporation
@@ -37703,125 +38834,104 @@ OUI:0022E2*
OUI:0022DB*
ID_OUI_FROM_DATABASE=Translogic Corporation
-OUI:0022CF*
- ID_OUI_FROM_DATABASE=PLANEX Communications INC
-
-OUI:0022D4*
- ID_OUI_FROM_DATABASE=ComWorth Co., Ltd.
-
-OUI:0022CA*
- ID_OUI_FROM_DATABASE=Anviz Biometric Tech. Co., Ltd.
+OUI:0022A1*
+ ID_OUI_FROM_DATABASE=Huawei Symantec Technologies Co.,Ltd.
-OUI:0022C5*
- ID_OUI_FROM_DATABASE=INFORSON Co,Ltd.
+OUI:00229B*
+ ID_OUI_FROM_DATABASE=AverLogic Technologies, Inc.
-OUI:002260*
- ID_OUI_FROM_DATABASE=AFREEY Inc.
+OUI:00229C*
+ ID_OUI_FROM_DATABASE=Verismo Networks Inc
-OUI:00225B*
- ID_OUI_FROM_DATABASE=Teradici Corporation
+OUI:002295*
+ ID_OUI_FROM_DATABASE=SGM Technology for lighting spa
-OUI:002256*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:00228E*
+ ID_OUI_FROM_DATABASE=TV-NUMERIC
-OUI:002255*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:002289*
+ ID_OUI_FROM_DATABASE=Optosecurity Inc.
-OUI:00224D*
- ID_OUI_FROM_DATABASE=MITAC INTERNATIONAL CORP.
+OUI:002282*
+ ID_OUI_FROM_DATABASE=8086 Consultancy
-OUI:002252*
- ID_OUI_FROM_DATABASE=ZOLL Lifecor Corporation
+OUI:00227C*
+ ID_OUI_FROM_DATABASE=Woori SMT Co.,ltd
-OUI:002246*
- ID_OUI_FROM_DATABASE=Evoc Intelligent Technology Co.,Ltd.
+OUI:002279*
+ ID_OUI_FROM_DATABASE=Nippon Conlux Co., Ltd.
OUI:00223C*
ID_OUI_FROM_DATABASE=RATIO Entwicklungen GmbH
-OUI:0022C0*
- ID_OUI_FROM_DATABASE=Shenzhen Forcelink Electronic Co, Ltd
-
-OUI:0022BB*
- ID_OUI_FROM_DATABASE=beyerdynamic GmbH & Co. KG
-
-OUI:0022AE*
- ID_OUI_FROM_DATABASE=Mattel Inc.
-
-OUI:0022AD*
- ID_OUI_FROM_DATABASE=TELESIS TECHNOLOGIES, INC.
-
-OUI:0022A8*
- ID_OUI_FROM_DATABASE=Ouman Oy
-
-OUI:0022A1*
- ID_OUI_FROM_DATABASE=Huawei Symantec Technologies Co.,Ltd.
+OUI:002236*
+ ID_OUI_FROM_DATABASE=VECTOR SP. Z O.O.
-OUI:00229B*
- ID_OUI_FROM_DATABASE=AverLogic Technologies, Inc.
+OUI:002230*
+ ID_OUI_FROM_DATABASE=FutureLogic Inc.
-OUI:00229C*
- ID_OUI_FROM_DATABASE=Verismo Networks Inc
+OUI:002229*
+ ID_OUI_FROM_DATABASE=Compumedics Ltd
-OUI:0023A8*
- ID_OUI_FROM_DATABASE=Marshall Electronics
+OUI:00221D*
+ ID_OUI_FROM_DATABASE=Freegene Technology LTD
-OUI:00239B*
- ID_OUI_FROM_DATABASE=Elster Solutions, LLC
+OUI:002224*
+ ID_OUI_FROM_DATABASE=Good Will Instrument Co., Ltd.
-OUI:002396*
- ID_OUI_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION
+OUI:002223*
+ ID_OUI_FROM_DATABASE=TimeKeeping Systems, Inc.
-OUI:002391*
- ID_OUI_FROM_DATABASE=Maxian
+OUI:002216*
+ ID_OUI_FROM_DATABASE=SHIBAURA VENDING MACHINE CORPORATION
-OUI:00238C*
- ID_OUI_FROM_DATABASE=Private
+OUI:002217*
+ ID_OUI_FROM_DATABASE=Neat Electronics
-OUI:002387*
- ID_OUI_FROM_DATABASE=ThinkFlood, Inc.
+OUI:002211*
+ ID_OUI_FROM_DATABASE=Rohati Systems
-OUI:0021D6*
- ID_OUI_FROM_DATABASE=LXI Consortium
+OUI:00220A*
+ ID_OUI_FROM_DATABASE=OnLive, Inc
-OUI:0021CF*
- ID_OUI_FROM_DATABASE=The Crypto Group
+OUI:002204*
+ ID_OUI_FROM_DATABASE=KORATEK
-OUI:0021C9*
- ID_OUI_FROM_DATABASE=Wavecom Asia Pacific Limited
+OUI:0021FF*
+ ID_OUI_FROM_DATABASE=Cyfrowy Polsat SA
-OUI:0021CA*
- ID_OUI_FROM_DATABASE=ART System Co., Ltd.
+OUI:0021F5*
+ ID_OUI_FROM_DATABASE=Western Engravers Supply, Inc.
-OUI:0021C3*
- ID_OUI_FROM_DATABASE=CORNELL Communications, Inc.
+OUI:0021EF*
+ ID_OUI_FROM_DATABASE=Kapsys
-OUI:0021BC*
- ID_OUI_FROM_DATABASE=ZALA COMPUTER
+OUI:0021EE*
+ ID_OUI_FROM_DATABASE=Full Spectrum Inc.
-OUI:0021B7*
- ID_OUI_FROM_DATABASE=Lexmark International Inc.
+OUI:0022D4*
+ ID_OUI_FROM_DATABASE=ComWorth Co., Ltd.
-OUI:002152*
- ID_OUI_FROM_DATABASE=General Satellite Research & Development Limited
+OUI:0022CA*
+ ID_OUI_FROM_DATABASE=Anviz Biometric Tech. Co., Ltd.
-OUI:002157*
- ID_OUI_FROM_DATABASE=National Datacast, Inc.
+OUI:0022C5*
+ ID_OUI_FROM_DATABASE=INFORSON Co,Ltd.
-OUI:00214B*
- ID_OUI_FROM_DATABASE=Shenzhen HAMP Science & Technology Co.,Ltd
+OUI:0022C0*
+ ID_OUI_FROM_DATABASE=Shenzhen Forcelink Electronic Co, Ltd
-OUI:002145*
- ID_OUI_FROM_DATABASE=Semptian Technologies Ltd.
+OUI:0022BB*
+ ID_OUI_FROM_DATABASE=beyerdynamic GmbH & Co. KG
-OUI:002144*
- ID_OUI_FROM_DATABASE=SS Telecoms
+OUI:0022AE*
+ ID_OUI_FROM_DATABASE=Mattel Inc.
-OUI:00213C*
- ID_OUI_FROM_DATABASE=AliphCom
+OUI:0022AD*
+ ID_OUI_FROM_DATABASE=TELESIS TECHNOLOGIES, INC.
-OUI:00213B*
- ID_OUI_FROM_DATABASE=Berkshire Products, Inc
+OUI:0022A8*
+ ID_OUI_FROM_DATABASE=Ouman Oy
OUI:002132*
ID_OUI_FROM_DATABASE=Masterclock, Inc.
@@ -37832,14 +38942,20 @@ OUI:00212C*
OUI:002131*
ID_OUI_FROM_DATABASE=Blynke Inc.
-OUI:001FD1*
- ID_OUI_FROM_DATABASE=OPTEX CO.,LTD.
+OUI:00211F*
+ ID_OUI_FROM_DATABASE=SHINSUNG DELTATECH CO.,LTD.
-OUI:001FCA*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:002120*
+ ID_OUI_FROM_DATABASE=Sequel Technologies
-OUI:001FBE*
- ID_OUI_FROM_DATABASE=Shenzhen Mopnet Industrial Co.,Ltd
+OUI:002125*
+ ID_OUI_FROM_DATABASE=KUK JE TONG SHIN Co.,LTD
+
+OUI:002119*
+ ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics
+
+OUI:002112*
+ ID_OUI_FROM_DATABASE=WISCOM SYSTEM CO.,LTD
OUI:001FB9*
ID_OUI_FROM_DATABASE=Paltronics
@@ -37853,35 +38969,44 @@ OUI:001FB8*
OUI:001FB2*
ID_OUI_FROM_DATABASE=Sontheim Industrie Elektronik GmbH
-OUI:00211F*
- ID_OUI_FROM_DATABASE=SHINSUNG DELTATECH CO.,LTD.
+OUI:001FAB*
+ ID_OUI_FROM_DATABASE=I.S HIGH TECH.INC
-OUI:002120*
- ID_OUI_FROM_DATABASE=Sequel Technologies
+OUI:001FA6*
+ ID_OUI_FROM_DATABASE=Stilo srl
-OUI:002125*
- ID_OUI_FROM_DATABASE=KUK JE TONG SHIN Co.,LTD
+OUI:001FA1*
+ ID_OUI_FROM_DATABASE=Gtran Inc
-OUI:002119*
- ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics
+OUI:001F9C*
+ ID_OUI_FROM_DATABASE=LEDCO
-OUI:002112*
- ID_OUI_FROM_DATABASE=WISCOM SYSTEM CO.,LTD
+OUI:00215E*
+ ID_OUI_FROM_DATABASE=IBM Corp
-OUI:002103*
- ID_OUI_FROM_DATABASE=GHI Electronics, LLC
+OUI:002151*
+ ID_OUI_FROM_DATABASE=Millinet Co., Ltd.
-OUI:0021B0*
- ID_OUI_FROM_DATABASE=Tyco Telecommunications
+OUI:002152*
+ ID_OUI_FROM_DATABASE=General Satellite Research & Development Limited
-OUI:0021A4*
- ID_OUI_FROM_DATABASE=Dbii Networks
+OUI:002157*
+ ID_OUI_FROM_DATABASE=National Datacast, Inc.
-OUI:00219A*
- ID_OUI_FROM_DATABASE=Cambridge Visual Networks Ltd
+OUI:00214B*
+ ID_OUI_FROM_DATABASE=Shenzhen HAMP Science & Technology Co.,Ltd
-OUI:002196*
- ID_OUI_FROM_DATABASE=Telsey S.p.A.
+OUI:002145*
+ ID_OUI_FROM_DATABASE=Semptian Technologies Ltd.
+
+OUI:002144*
+ ID_OUI_FROM_DATABASE=SS Telecoms
+
+OUI:00213C*
+ ID_OUI_FROM_DATABASE=AliphCom
+
+OUI:00213B*
+ ID_OUI_FROM_DATABASE=Berkshire Products, Inc
OUI:002190*
ID_OUI_FROM_DATABASE=Goliath Solutions
@@ -37895,24 +39020,6 @@ OUI:002184*
OUI:002183*
ID_OUI_FROM_DATABASE=VATECH HYDRO
-OUI:001FFA*
- ID_OUI_FROM_DATABASE=Coretree, Co, Ltd
-
-OUI:001FF5*
- ID_OUI_FROM_DATABASE=Kongsberg Defence & Aerospace
-
-OUI:001FF4*
- ID_OUI_FROM_DATABASE=Power Monitors, Inc.
-
-OUI:001FEE*
- ID_OUI_FROM_DATABASE=ubisys technologies GmbH
-
-OUI:001FE7*
- ID_OUI_FROM_DATABASE=Simet
-
-OUI:001FDB*
- ID_OUI_FROM_DATABASE=Network Supply Corp.,
-
OUI:00217D*
ID_OUI_FROM_DATABASE=PYXIS S.R.L.
@@ -37928,98 +39035,59 @@ OUI:002171*
OUI:002164*
ID_OUI_FROM_DATABASE=Special Design Bureau for Seismic Instrumentation
-OUI:00215E*
- ID_OUI_FROM_DATABASE=IBM Corp
-
-OUI:002151*
- ID_OUI_FROM_DATABASE=Millinet Co., Ltd.
-
-OUI:002204*
- ID_OUI_FROM_DATABASE=KORATEK
-
-OUI:0021FF*
- ID_OUI_FROM_DATABASE=Cyfrowy Polsat SA
-
-OUI:0021FB*
- ID_OUI_FROM_DATABASE=LG Electronics
-
-OUI:0021F5*
- ID_OUI_FROM_DATABASE=Western Engravers Supply, Inc.
-
-OUI:0021EF*
- ID_OUI_FROM_DATABASE=Kapsys
-
-OUI:0021EE*
- ID_OUI_FROM_DATABASE=Full Spectrum Inc.
-
-OUI:0021DC*
- ID_OUI_FROM_DATABASE=TECNOALARM S.r.l.
-
-OUI:0021E2*
- ID_OUI_FROM_DATABASE=Creative Electronic GmbH
-
-OUI:001FAB*
- ID_OUI_FROM_DATABASE=I.S HIGH TECH.INC
-
-OUI:001FA6*
- ID_OUI_FROM_DATABASE=Stilo srl
-
-OUI:001FA1*
- ID_OUI_FROM_DATABASE=Gtran Inc
-
-OUI:001F9C*
- ID_OUI_FROM_DATABASE=LEDCO
+OUI:002103*
+ ID_OUI_FROM_DATABASE=GHI Electronics, LLC
-OUI:001F8E*
- ID_OUI_FROM_DATABASE=Metris USA Inc.
+OUI:001FFA*
+ ID_OUI_FROM_DATABASE=Coretree, Co, Ltd
-OUI:001E41*
- ID_OUI_FROM_DATABASE=Microwave Communication & Component, Inc.
+OUI:001FF5*
+ ID_OUI_FROM_DATABASE=Kongsberg Defence & Aerospace
-OUI:001E2E*
- ID_OUI_FROM_DATABASE=SIRTI S.p.A.
+OUI:001FF4*
+ ID_OUI_FROM_DATABASE=Power Monitors, Inc.
-OUI:001E27*
- ID_OUI_FROM_DATABASE=SBN TECH Co.,Ltd.
+OUI:001FEE*
+ ID_OUI_FROM_DATABASE=ubisys technologies GmbH
-OUI:001E28*
- ID_OUI_FROM_DATABASE=Lumexis Corporation
+OUI:001FE7*
+ ID_OUI_FROM_DATABASE=Simet
-OUI:001E22*
- ID_OUI_FROM_DATABASE=ARVOO Imaging Products BV
+OUI:001FDB*
+ ID_OUI_FROM_DATABASE=Network Supply Corp.,
-OUI:001E1B*
- ID_OUI_FROM_DATABASE=Digital Stream Technology, Inc.
+OUI:001FD1*
+ ID_OUI_FROM_DATABASE=OPTEX CO.,LTD.
-OUI:001E16*
- ID_OUI_FROM_DATABASE=Keytronix
+OUI:001FCA*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001E15*
- ID_OUI_FROM_DATABASE=Beech Hill Electronics
+OUI:001FBE*
+ ID_OUI_FROM_DATABASE=Shenzhen Mopnet Industrial Co.,Ltd
-OUI:001E11*
- ID_OUI_FROM_DATABASE=ELELUX INTERNATIONAL LTD
+OUI:001F62*
+ ID_OUI_FROM_DATABASE=JSC Stilsoft
-OUI:001E05*
- ID_OUI_FROM_DATABASE=Xseed Technologies & Computing
+OUI:001F67*
+ ID_OUI_FROM_DATABASE=Hitachi,Ltd.
-OUI:001E0C*
- ID_OUI_FROM_DATABASE=Sherwood Information Partners, Inc.
+OUI:001F55*
+ ID_OUI_FROM_DATABASE=Honeywell Security (China) Co., Ltd.
-OUI:001DFE*
- ID_OUI_FROM_DATABASE=Palm, Inc
+OUI:001F56*
+ ID_OUI_FROM_DATABASE=DIGITAL FORECAST
-OUI:001DF9*
- ID_OUI_FROM_DATABASE=Cybiotronics (Far East) Limited
+OUI:001F4F*
+ ID_OUI_FROM_DATABASE=Thinkware Co. Ltd.
-OUI:001DF2*
- ID_OUI_FROM_DATABASE=Netflix, Inc.
+OUI:001F48*
+ ID_OUI_FROM_DATABASE=Mojix Inc.
-OUI:001DEB*
- ID_OUI_FROM_DATABASE=DINEC International
+OUI:001F43*
+ ID_OUI_FROM_DATABASE=ENTES ELEKTRONIK
-OUI:001DEC*
- ID_OUI_FROM_DATABASE=Marusys
+OUI:001F8E*
+ ID_OUI_FROM_DATABASE=Metris USA Inc.
OUI:001F88*
ID_OUI_FROM_DATABASE=FMS Force Measuring Systems AG
@@ -38039,74 +39107,68 @@ OUI:001F6E*
OUI:001F68*
ID_OUI_FROM_DATABASE=Martinsson Elektronik AB
-OUI:001F62*
- ID_OUI_FROM_DATABASE=JSC Stilsoft
-
-OUI:001F67*
- ID_OUI_FROM_DATABASE=Hitachi,Ltd.
-
-OUI:001F55*
- ID_OUI_FROM_DATABASE=Honeywell Security (China) Co., Ltd.
+OUI:0021BC*
+ ID_OUI_FROM_DATABASE=ZALA COMPUTER
-OUI:001E9B*
- ID_OUI_FROM_DATABASE=San-Eisha, Ltd.
+OUI:0021B7*
+ ID_OUI_FROM_DATABASE=Lexmark International Inc.
-OUI:001E94*
- ID_OUI_FROM_DATABASE=SUPERCOM TECHNOLOGY CORPORATION
+OUI:0021B0*
+ ID_OUI_FROM_DATABASE=Tyco Telecommunications
-OUI:001E8F*
- ID_OUI_FROM_DATABASE=CANON INC.
+OUI:0021A4*
+ ID_OUI_FROM_DATABASE=Dbii Networks
-OUI:001E87*
- ID_OUI_FROM_DATABASE=Realease Limited
+OUI:00219A*
+ ID_OUI_FROM_DATABASE=Cambridge Visual Networks Ltd
-OUI:001E80*
- ID_OUI_FROM_DATABASE=Last Mile Ltd.
+OUI:002196*
+ ID_OUI_FROM_DATABASE=Telsey S.p.A.
-OUI:001E7B*
- ID_OUI_FROM_DATABASE=R.I.CO. S.r.l.
+OUI:001E4B*
+ ID_OUI_FROM_DATABASE=City Theatrical
-OUI:001E76*
- ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+OUI:001E47*
+ ID_OUI_FROM_DATABASE=PT. Hariff Daya Tunggal Engineering
-OUI:001E6A*
- ID_OUI_FROM_DATABASE=Beijing Bluexon Technology Co.,Ltd
+OUI:001E41*
+ ID_OUI_FROM_DATABASE=Microwave Communication & Component, Inc.
-OUI:001F56*
- ID_OUI_FROM_DATABASE=DIGITAL FORECAST
+OUI:001E2E*
+ ID_OUI_FROM_DATABASE=SIRTI S.p.A.
-OUI:001F4F*
- ID_OUI_FROM_DATABASE=Thinkware Co. Ltd.
+OUI:001E27*
+ ID_OUI_FROM_DATABASE=SBN TECH Co.,Ltd.
-OUI:001F48*
- ID_OUI_FROM_DATABASE=Mojix Inc.
+OUI:001E28*
+ ID_OUI_FROM_DATABASE=Lumexis Corporation
-OUI:001F43*
- ID_OUI_FROM_DATABASE=ENTES ELEKTRONIK
+OUI:001DF2*
+ ID_OUI_FROM_DATABASE=Netflix, Inc.
-OUI:001F2E*
- ID_OUI_FROM_DATABASE=Triangle Research Int'l Pte Ltd
+OUI:001DEB*
+ ID_OUI_FROM_DATABASE=DINEC International
-OUI:001F2D*
- ID_OUI_FROM_DATABASE=Electro-Optical Imaging, Inc.
+OUI:001DEC*
+ ID_OUI_FROM_DATABASE=Marusys
-OUI:001F27*
+OUI:001DE6*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001EF5*
- ID_OUI_FROM_DATABASE=Hitek Automated Inc.
+OUI:001DDA*
+ ID_OUI_FROM_DATABASE=Mikroelektronika spol. s r. o.
-OUI:001EFB*
- ID_OUI_FROM_DATABASE=Trio Motion Technology Ltd
+OUI:001DDF*
+ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd.
-OUI:001EE9*
- ID_OUI_FROM_DATABASE=Stoneridge Electronics AB
+OUI:001DCC*
+ ID_OUI_FROM_DATABASE=Hetra Secure Solutions
-OUI:001EEE*
- ID_OUI_FROM_DATABASE=ETL Systems Ltd
+OUI:001DC7*
+ ID_OUI_FROM_DATABASE=L-3 Communications Geneva Aerospace
-OUI:001EE2*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:001DC0*
+ ID_OUI_FROM_DATABASE=Enphase Energy
OUI:001ED8*
ID_OUI_FROM_DATABASE=Digital United Inc.
@@ -38123,9 +39185,6 @@ OUI:001ECC*
OUI:001EC5*
ID_OUI_FROM_DATABASE=Middle Atlantic Products Inc
-OUI:001EC0*
- ID_OUI_FROM_DATABASE=Microchip Technology Inc.
-
OUI:001EBF*
ID_OUI_FROM_DATABASE=Haas Automation Inc.
@@ -38135,6 +39194,54 @@ OUI:001EB9*
OUI:001EB2*
ID_OUI_FROM_DATABASE=LG innotek
+OUI:001F2E*
+ ID_OUI_FROM_DATABASE=Triangle Research Int'l Pte Ltd
+
+OUI:001F2D*
+ ID_OUI_FROM_DATABASE=Electro-Optical Imaging, Inc.
+
+OUI:001F27*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:001F14*
+ ID_OUI_FROM_DATABASE=NexG
+
+OUI:001F1B*
+ ID_OUI_FROM_DATABASE=RoyalTek Company Ltd.
+
+OUI:001F0D*
+ ID_OUI_FROM_DATABASE=L3 Communications - Telemetry West
+
+OUI:001F0E*
+ ID_OUI_FROM_DATABASE=Japan Kyastem Co., Ltd
+
+OUI:001E22*
+ ID_OUI_FROM_DATABASE=ARVOO Imaging Products BV
+
+OUI:001E1B*
+ ID_OUI_FROM_DATABASE=Digital Stream Technology, Inc.
+
+OUI:001E16*
+ ID_OUI_FROM_DATABASE=Keytronix
+
+OUI:001E15*
+ ID_OUI_FROM_DATABASE=Beech Hill Electronics
+
+OUI:001E11*
+ ID_OUI_FROM_DATABASE=ELELUX INTERNATIONAL LTD
+
+OUI:001E05*
+ ID_OUI_FROM_DATABASE=Xseed Technologies & Computing
+
+OUI:001E0C*
+ ID_OUI_FROM_DATABASE=Sherwood Information Partners, Inc.
+
+OUI:001DFE*
+ ID_OUI_FROM_DATABASE=Palm, Inc
+
+OUI:001DF9*
+ ID_OUI_FROM_DATABASE=Cybiotronics (Far East) Limited
+
OUI:001EAD*
ID_OUI_FROM_DATABASE=Wingtech Group Limited
@@ -38147,20 +39254,20 @@ OUI:001EA7*
OUI:001EA1*
ID_OUI_FROM_DATABASE=Brunata a/s
-OUI:001F20*
- ID_OUI_FROM_DATABASE=Logitech Europe SA
+OUI:001E9B*
+ ID_OUI_FROM_DATABASE=San-Eisha, Ltd.
-OUI:001F14*
- ID_OUI_FROM_DATABASE=NexG
+OUI:001E94*
+ ID_OUI_FROM_DATABASE=SUPERCOM TECHNOLOGY CORPORATION
-OUI:001F1B*
- ID_OUI_FROM_DATABASE=RoyalTek Company Ltd.
+OUI:001E8F*
+ ID_OUI_FROM_DATABASE=CANON INC.
-OUI:001F0D*
- ID_OUI_FROM_DATABASE=L3 Communications - Telemetry West
+OUI:001E87*
+ ID_OUI_FROM_DATABASE=Realease Limited
-OUI:001F0E*
- ID_OUI_FROM_DATABASE=Japan Kyastem Co., Ltd
+OUI:001E80*
+ ID_OUI_FROM_DATABASE=Last Mile Ltd.
OUI:001EFC*
ID_OUI_FROM_DATABASE=JSC MASSA-K
@@ -38168,6 +39275,30 @@ OUI:001EFC*
OUI:001F08*
ID_OUI_FROM_DATABASE=RISCO LTD
+OUI:001EF5*
+ ID_OUI_FROM_DATABASE=Hitek Automated Inc.
+
+OUI:001EFB*
+ ID_OUI_FROM_DATABASE=Trio Motion Technology Ltd
+
+OUI:001EE9*
+ ID_OUI_FROM_DATABASE=Stoneridge Electronics AB
+
+OUI:001EEE*
+ ID_OUI_FROM_DATABASE=ETL Systems Ltd
+
+OUI:001EE2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001E7B*
+ ID_OUI_FROM_DATABASE=R.I.CO. S.r.l.
+
+OUI:001E76*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+
+OUI:001E6A*
+ ID_OUI_FROM_DATABASE=Beijing Bluexon Technology Co.,Ltd
+
OUI:001E71*
ID_OUI_FROM_DATABASE=MIrcom Group of Companies
@@ -38183,11 +39314,26 @@ OUI:001E57*
OUI:001E51*
ID_OUI_FROM_DATABASE=Converter Industry Srl
-OUI:001E4B*
- ID_OUI_FROM_DATABASE=City Theatrical
+OUI:001DB9*
+ ID_OUI_FROM_DATABASE=Wellspring Wireless
-OUI:001E47*
- ID_OUI_FROM_DATABASE=PT. Hariff Daya Tunggal Engineering
+OUI:001DB4*
+ ID_OUI_FROM_DATABASE=KUMHO ENG CO.,LTD
+
+OUI:001D9E*
+ ID_OUI_FROM_DATABASE=AXION TECHNOLOGIES
+
+OUI:001DA3*
+ ID_OUI_FROM_DATABASE=SabiOso
+
+OUI:001D9D*
+ ID_OUI_FROM_DATABASE=ARTJOY INTERNATIONAL LIMITED
+
+OUI:001D45*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:001D3E*
+ ID_OUI_FROM_DATABASE=SAKA TECHNO SCIENCE CO.,LTD
OUI:001D37*
ID_OUI_FROM_DATABASE=Thales-Panda Transportation System
@@ -38213,8 +39359,32 @@ OUI:001D25*
OUI:001D1A*
ID_OUI_FROM_DATABASE=OvisLink S.A.
-OUI:001D14*
- ID_OUI_FROM_DATABASE=SPERADTONE INFORMATION TECHNOLOGY LIMITED
+OUI:001D7A*
+ ID_OUI_FROM_DATABASE=Wideband Semiconductor, Inc.
+
+OUI:001D74*
+ ID_OUI_FROM_DATABASE=Tianjin China-Silicon Microelectronics Co., Ltd.
+
+OUI:001D62*
+ ID_OUI_FROM_DATABASE=InPhase Technologies
+
+OUI:001D61*
+ ID_OUI_FROM_DATABASE=BIJ Corporation
+
+OUI:001D5B*
+ ID_OUI_FROM_DATABASE=Tecvan Informática Ltda
+
+OUI:001D54*
+ ID_OUI_FROM_DATABASE=Sunnic Technology & Merchandise INC.
+
+OUI:001D4A*
+ ID_OUI_FROM_DATABASE=Carestream Health, Inc.
+
+OUI:001CE8*
+ ID_OUI_FROM_DATABASE=Cummins Inc
+
+OUI:001CE4*
+ ID_OUI_FROM_DATABASE=EleSy JSC
OUI:001CDD*
ID_OUI_FROM_DATABASE=COWBELL ENGINEERING CO., LTD.
@@ -38234,6 +39404,24 @@ OUI:001CCB*
OUI:001CC5*
ID_OUI_FROM_DATABASE=3Com Ltd
+OUI:001D14*
+ ID_OUI_FROM_DATABASE=SPERADTONE INFORMATION TECHNOLOGY LIMITED
+
+OUI:001D07*
+ ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Co.,Ltd
+
+OUI:001D01*
+ ID_OUI_FROM_DATABASE=Neptune Digital
+
+OUI:001CFA*
+ ID_OUI_FROM_DATABASE=Alarm.com
+
+OUI:001CEE*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
+OUI:001CF5*
+ ID_OUI_FROM_DATABASE=Wiseblue Technology Limited
+
OUI:001CB9*
ID_OUI_FROM_DATABASE=KWANG SUNG ELECTRONICS CO., LTD.
@@ -38243,6 +39431,57 @@ OUI:001CAF*
OUI:001CB4*
ID_OUI_FROM_DATABASE=Iridium Satellite LLC
+OUI:001C9F*
+ ID_OUI_FROM_DATABASE=Razorstream, LLC
+
+OUI:001C99*
+ ID_OUI_FROM_DATABASE=Shunra Software Ltd.
+
+OUI:001C8C*
+ ID_OUI_FROM_DATABASE=DIAL TECHNOLOGY LTD.
+
+OUI:001C93*
+ ID_OUI_FROM_DATABASE=ExaDigm Inc
+
+OUI:001C87*
+ ID_OUI_FROM_DATABASE=Uriver Inc.
+
+OUI:001C82*
+ ID_OUI_FROM_DATABASE=Genew Technologies
+
+OUI:001C1A*
+ ID_OUI_FROM_DATABASE=Thomas Instrumentation, Inc
+
+OUI:001C0E*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:001C13*
+ ID_OUI_FROM_DATABASE=OPTSYS TECHNOLOGY CO., LTD.
+
+OUI:001C07*
+ ID_OUI_FROM_DATABASE=Cwlinux Limited
+
+OUI:001C00*
+ ID_OUI_FROM_DATABASE=Entry Point, LLC
+
+OUI:001BF4*
+ ID_OUI_FROM_DATABASE=KENWIN INDUSTRIAL(HK) LTD.
+
+OUI:001BEF*
+ ID_OUI_FROM_DATABASE=Blossoms Digital Technology Co.,Ltd.
+
+OUI:001BE2*
+ ID_OUI_FROM_DATABASE=AhnLab,Inc.
+
+OUI:001C7D*
+ ID_OUI_FROM_DATABASE=Excelpoint Manufacturing Pte Ltd
+
+OUI:001C73*
+ ID_OUI_FROM_DATABASE=Arista Networks, Inc.
+
+OUI:001C78*
+ ID_OUI_FROM_DATABASE=WYPLAY SAS
+
OUI:001C65*
ID_OUI_FROM_DATABASE=JoeScan, Inc.
@@ -38273,128 +39512,95 @@ OUI:001C37*
OUI:001C3C*
ID_OUI_FROM_DATABASE=Seon Design Inc.
-OUI:001DE6*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:001DDA*
- ID_OUI_FROM_DATABASE=Mikroelektronika spol. s r. o.
-
-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
-
-OUI:001DC0*
- ID_OUI_FROM_DATABASE=Enphase Energy
-
-OUI:001DB9*
- ID_OUI_FROM_DATABASE=Wellspring Wireless
-
-OUI:001D07*
- ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Co.,Ltd
-
-OUI:001D01*
- ID_OUI_FROM_DATABASE=Neptune Digital
-
-OUI:001CFA*
- ID_OUI_FROM_DATABASE=Alarm.com
+OUI:001C30*
+ ID_OUI_FROM_DATABASE=Mode Lighting (UK ) Ltd.
-OUI:001CEE*
- ID_OUI_FROM_DATABASE=SHARP Corporation
+OUI:001C2B*
+ ID_OUI_FROM_DATABASE=Alertme.com Limited
-OUI:001CF5*
- ID_OUI_FROM_DATABASE=Wiseblue Technology Limited
+OUI:001C2A*
+ ID_OUI_FROM_DATABASE=Envisacor Technologies Inc.
-OUI:001CE8*
- ID_OUI_FROM_DATABASE=Cummins Inc
+OUI:001C29*
+ ID_OUI_FROM_DATABASE=CORE DIGITAL ELECTRONICS CO., LTD
-OUI:001CE4*
- ID_OUI_FROM_DATABASE=EleSy JSC
+OUI:001C24*
+ ID_OUI_FROM_DATABASE=Formosa Wireless Systems Corp.
-OUI:001C9F*
- ID_OUI_FROM_DATABASE=Razorstream, LLC
+OUI:001C1F*
+ ID_OUI_FROM_DATABASE=Quest Retail Technology Pty Ltd
-OUI:001C99*
- ID_OUI_FROM_DATABASE=Shunra Software Ltd.
+OUI:001D97*
+ ID_OUI_FROM_DATABASE=Alertus Technologies LLC
-OUI:001C8C*
- ID_OUI_FROM_DATABASE=DIAL TECHNOLOGY LTD.
+OUI:001D90*
+ ID_OUI_FROM_DATABASE=EMCO Flow Systems
-OUI:001C93*
- ID_OUI_FROM_DATABASE=ExaDigm Inc
+OUI:001D84*
+ ID_OUI_FROM_DATABASE=Gateway, Inc.
-OUI:001C87*
- ID_OUI_FROM_DATABASE=Uriver Inc.
+OUI:001D67*
+ ID_OUI_FROM_DATABASE=AMEC
-OUI:001C82*
- ID_OUI_FROM_DATABASE=Genew Technologies
+OUI:001A93*
+ ID_OUI_FROM_DATABASE=ERCO Leuchten GmbH
-OUI:001C7D*
- ID_OUI_FROM_DATABASE=Excelpoint Manufacturing Pte Ltd
+OUI:001A98*
+ ID_OUI_FROM_DATABASE=Asotel Communication Limited Taiwan Branch
-OUI:001C73*
- ID_OUI_FROM_DATABASE=Arista Networks, Inc.
+OUI:001A8E*
+ ID_OUI_FROM_DATABASE=3Way Networks Ltd
-OUI:001C78*
- ID_OUI_FROM_DATABASE=WYPLAY SAS
+OUI:001A7D*
+ ID_OUI_FROM_DATABASE=cyber-blue(HK)Ltd
-OUI:001D62*
- ID_OUI_FROM_DATABASE=InPhase Technologies
+OUI:001A82*
+ ID_OUI_FROM_DATABASE=PROBA Building Automation Co.,LTD
-OUI:001D61*
- ID_OUI_FROM_DATABASE=BIJ Corporation
+OUI:001A7C*
+ ID_OUI_FROM_DATABASE=Hirschmann Multimedia B.V.
-OUI:001D5B*
- ID_OUI_FROM_DATABASE=Tecvan Informática Ltda
+OUI:001A78*
+ ID_OUI_FROM_DATABASE=ubtos
-OUI:001D54*
- ID_OUI_FROM_DATABASE=Sunnic Technology & Merchandise INC.
+OUI:001A7B*
+ ID_OUI_FROM_DATABASE=Teleco, Inc.
-OUI:001D4A*
- ID_OUI_FROM_DATABASE=Carestream Health, Inc.
+OUI:001A71*
+ ID_OUI_FROM_DATABASE=Diostech Co., Ltd.
-OUI:001D45*
+OUI:001A6C*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001D3E*
- ID_OUI_FROM_DATABASE=SAKA TECHNO SCIENCE CO.,LTD
-
-OUI:001D90*
- ID_OUI_FROM_DATABASE=EMCO Flow Systems
-
-OUI:001D84*
- ID_OUI_FROM_DATABASE=Gateway, Inc.
+OUI:001A65*
+ ID_OUI_FROM_DATABASE=Seluxit
-OUI:001D67*
- ID_OUI_FROM_DATABASE=AMEC
+OUI:001B7D*
+ ID_OUI_FROM_DATABASE=CXR Anderson Jacobson
-OUI:001D7A*
- ID_OUI_FROM_DATABASE=Wideband Semiconductor, Inc.
+OUI:001B71*
+ ID_OUI_FROM_DATABASE=Telular Corp.
-OUI:001D74*
- ID_OUI_FROM_DATABASE=Tianjin China-Silicon Microelectronics Co., Ltd.
+OUI:001B6A*
+ ID_OUI_FROM_DATABASE=Powerwave Technologies Sweden AB
-OUI:001DB4*
- ID_OUI_FROM_DATABASE=KUMHO ENG CO.,LTD
+OUI:001B65*
+ ID_OUI_FROM_DATABASE=China Gridcom Co., Ltd
-OUI:001DAF*
- ID_OUI_FROM_DATABASE=Nortel
+OUI:001B5E*
+ ID_OUI_FROM_DATABASE=BPL Limited
-OUI:001D9E*
- ID_OUI_FROM_DATABASE=AXION TECHNOLOGIES
+OUI:001B57*
+ ID_OUI_FROM_DATABASE=SEMINDIA SYSTEMS PRIVATE LIMITED
-OUI:001DA3*
- ID_OUI_FROM_DATABASE=SabiOso
+OUI:001B46*
+ ID_OUI_FROM_DATABASE=Blueone Technology Co.,Ltd
-OUI:001D9D*
- ID_OUI_FROM_DATABASE=ARTJOY INTERNATIONAL LIMITED
+OUI:001B4B*
+ ID_OUI_FROM_DATABASE=SANION Co., Ltd.
-OUI:001D97*
- ID_OUI_FROM_DATABASE=Alertus Technologies LLC
+OUI:001BAD*
+ ID_OUI_FROM_DATABASE=iControl Incorporated
OUI:001BA6*
ID_OUI_FROM_DATABASE=intotech inc.
@@ -38426,32 +39632,11 @@ OUI:001B8A*
OUI:001B84*
ID_OUI_FROM_DATABASE=Scan Engineering Telecom
-OUI:001B7D*
- ID_OUI_FROM_DATABASE=CXR Anderson Jacobson
-
-OUI:001B71*
- ID_OUI_FROM_DATABASE=Telular Corp.
-
-OUI:001B6A*
- ID_OUI_FROM_DATABASE=Powerwave Technologies Sweden AB
-
-OUI:001B65*
- ID_OUI_FROM_DATABASE=China Gridcom Co., Ltd
-
-OUI:001B5E*
- ID_OUI_FROM_DATABASE=BPL Limited
-
-OUI:001B57*
- ID_OUI_FROM_DATABASE=SEMINDIA SYSTEMS PRIVATE LIMITED
-
-OUI:001B46*
- ID_OUI_FROM_DATABASE=Blueone Technology Co.,Ltd
-
-OUI:001B4B*
- ID_OUI_FROM_DATABASE=SANION Co., Ltd.
+OUI:001BD1*
+ ID_OUI_FROM_DATABASE=SOGESTMATIC
-OUI:001B3F*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+OUI:001BD6*
+ ID_OUI_FROM_DATABASE=Kelvin Hughes Ltd
OUI:001BCF*
ID_OUI_FROM_DATABASE=Dataupia Corporation
@@ -38471,8 +39656,32 @@ OUI:001BBE*
OUI:001BB4*
ID_OUI_FROM_DATABASE=Airvod Limited
-OUI:001BAD*
- ID_OUI_FROM_DATABASE=iControl Incorporated
+OUI:001B14*
+ ID_OUI_FROM_DATABASE=Carex Lighting Equipment Factory
+
+OUI:001B0D*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:001B06*
+ ID_OUI_FROM_DATABASE=Ateliers R. LAUMONIER
+
+OUI:001B08*
+ ID_OUI_FROM_DATABASE=Danfoss Drives A/S
+
+OUI:001B01*
+ ID_OUI_FROM_DATABASE=Applied Radio Technologies
+
+OUI:001AF5*
+ ID_OUI_FROM_DATABASE=PENTAONE. CO., LTD.
+
+OUI:001AFA*
+ ID_OUI_FROM_DATABASE=Welch Allyn, Inc.
+
+OUI:001AE4*
+ ID_OUI_FROM_DATABASE=Medicis Technologies Corporation
+
+OUI:001ADD*
+ ID_OUI_FROM_DATABASE=PePWave Ltd
OUI:001AD1*
ID_OUI_FROM_DATABASE=FARGO CO., LTD.
@@ -38495,59 +39704,32 @@ OUI:001ABB*
OUI:001AC0*
ID_OUI_FROM_DATABASE=JOYBIEN TECHNOLOGIES CO., LTD.
-OUI:001AB4*
- ID_OUI_FROM_DATABASE=FFEI Ltd.
-
-OUI:001AAF*
- ID_OUI_FROM_DATABASE=BLUSENS TECHNOLOGY
-
-OUI:001C07*
- ID_OUI_FROM_DATABASE=Cwlinux Limited
-
-OUI:001C00*
- ID_OUI_FROM_DATABASE=Entry Point, LLC
-
-OUI:001BF4*
- ID_OUI_FROM_DATABASE=KENWIN INDUSTRIAL(HK) LTD.
-
-OUI:001BEF*
- ID_OUI_FROM_DATABASE=Blossoms Digital Technology Co.,Ltd.
-
-OUI:001BE2*
- ID_OUI_FROM_DATABASE=AhnLab,Inc.
-
-OUI:001BD1*
- ID_OUI_FROM_DATABASE=SOGESTMATIC
-
-OUI:001BD6*
- ID_OUI_FROM_DATABASE=Kelvin Hughes Ltd
-
-OUI:001C30*
- ID_OUI_FROM_DATABASE=Mode Lighting (UK ) Ltd.
+OUI:001A60*
+ ID_OUI_FROM_DATABASE=Wave Electronics Co.,Ltd.
-OUI:001C2B*
- ID_OUI_FROM_DATABASE=Alertme.com Limited
+OUI:001A55*
+ ID_OUI_FROM_DATABASE=ACA-Digital Corporation
-OUI:001C2A*
- ID_OUI_FROM_DATABASE=Envisacor Technologies Inc.
+OUI:001A5A*
+ ID_OUI_FROM_DATABASE=Korea Electric Power Data Network (KDN) Co., Ltd
-OUI:001C29*
- ID_OUI_FROM_DATABASE=CORE DIGITAL ELECTRONICS CO., LTD
+OUI:001A4E*
+ ID_OUI_FROM_DATABASE=NTI AG / LinMot
-OUI:001C24*
- ID_OUI_FROM_DATABASE=Formosa Wireless Systems Corp.
+OUI:001A53*
+ ID_OUI_FROM_DATABASE=Zylaya
-OUI:001C1F*
- ID_OUI_FROM_DATABASE=Quest Retail Technology Pty Ltd
+OUI:001A42*
+ ID_OUI_FROM_DATABASE=Techcity Technology co., Ltd.
-OUI:001C1A*
- ID_OUI_FROM_DATABASE=Thomas Instrumentation, Inc
+OUI:001A47*
+ ID_OUI_FROM_DATABASE=Agami Systems, Inc.
-OUI:001C0E*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:001A3B*
+ ID_OUI_FROM_DATABASE=Doah Elecom Inc.
-OUI:001C13*
- ID_OUI_FROM_DATABASE=OPTSYS TECHNOLOGY CO., LTD.
+OUI:001B3F*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
OUI:001B3A*
ID_OUI_FROM_DATABASE=SIMS Corp.
@@ -38558,20 +39740,17 @@ OUI:001B2C*
OUI:001B27*
ID_OUI_FROM_DATABASE=Merlin CSI
-OUI:001B25*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001B20*
ID_OUI_FROM_DATABASE=TPine Technology
OUI:001B19*
ID_OUI_FROM_DATABASE=IEEE I&M Society TC9
-OUI:001B14*
- ID_OUI_FROM_DATABASE=Carex Lighting Equipment Factory
+OUI:001AB4*
+ ID_OUI_FROM_DATABASE=FFEI Ltd.
-OUI:001B0D*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:001AAF*
+ ID_OUI_FROM_DATABASE=BLUSENS TECHNOLOGY
OUI:001AA8*
ID_OUI_FROM_DATABASE=Mamiya Digital Imaging Co., Ltd.
@@ -38582,38 +39761,8 @@ OUI:001A9F*
OUI:001AA6*
ID_OUI_FROM_DATABASE=Telefunken Radio Communication Systems GmbH &CO.KG
-OUI:001A93*
- ID_OUI_FROM_DATABASE=ERCO Leuchten GmbH
-
-OUI:001A98*
- ID_OUI_FROM_DATABASE=Asotel Communication Limited Taiwan Branch
-
-OUI:001A8E*
- ID_OUI_FROM_DATABASE=3Way Networks Ltd
-
-OUI:001B06*
- ID_OUI_FROM_DATABASE=Ateliers R. LAUMONIER
-
-OUI:001B08*
- ID_OUI_FROM_DATABASE=Danfoss Drives A/S
-
-OUI:001B01*
- ID_OUI_FROM_DATABASE=Applied Radio Technologies
-
-OUI:001AF5*
- ID_OUI_FROM_DATABASE=PENTAONE. CO., LTD.
-
-OUI:001AFA*
- ID_OUI_FROM_DATABASE=Welch Allyn, Inc.
-
-OUI:001AF0*
- ID_OUI_FROM_DATABASE=Alcatel - IPD
-
-OUI:001AE4*
- ID_OUI_FROM_DATABASE=Medicis Technologies Corporation
-
-OUI:001ADD*
- ID_OUI_FROM_DATABASE=PePWave Ltd
+OUI:00193F*
+ ID_OUI_FROM_DATABASE=RDI technology(Shenzhen) Co.,LTD
OUI:001933*
ID_OUI_FROM_DATABASE=Strix Systems, Inc.
@@ -38642,8 +39791,11 @@ OUI:001915*
OUI:00191A*
ID_OUI_FROM_DATABASE=IRLINK
-OUI:00199D*
- ID_OUI_FROM_DATABASE=VIZIO, Inc.
+OUI:001993*
+ ID_OUI_FROM_DATABASE=Changshu Switchgear MFG. Co.,Ltd. (Former Changshu Switchgea
+
+OUI:001998*
+ ID_OUI_FROM_DATABASE=SATO CORPORATION
OUI:00198E*
ID_OUI_FROM_DATABASE=Oticon A/S
@@ -38678,57 +39830,6 @@ OUI:001946*
OUI:001944*
ID_OUI_FROM_DATABASE=Fossil Partners, L.P.
-OUI:00193F*
- ID_OUI_FROM_DATABASE=RDI technology(Shenzhen) Co.,LTD
-
-OUI:001A7D*
- ID_OUI_FROM_DATABASE=cyber-blue(HK)Ltd
-
-OUI:001A82*
- ID_OUI_FROM_DATABASE=PROBA Building Automation Co.,LTD
-
-OUI:001A7C*
- ID_OUI_FROM_DATABASE=Hirschmann Multimedia B.V.
-
-OUI:001A78*
- ID_OUI_FROM_DATABASE=ubtos
-
-OUI:001A7B*
- ID_OUI_FROM_DATABASE=Teleco, Inc.
-
-OUI:001A71*
- ID_OUI_FROM_DATABASE=Diostech Co., Ltd.
-
-OUI:001A6C*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:001A65*
- ID_OUI_FROM_DATABASE=Seluxit
-
-OUI:001A60*
- ID_OUI_FROM_DATABASE=Wave Electronics Co.,Ltd.
-
-OUI:001A55*
- ID_OUI_FROM_DATABASE=ACA-Digital Corporation
-
-OUI:001A5A*
- ID_OUI_FROM_DATABASE=Korea Electric Power Data Network (KDN) Co., Ltd
-
-OUI:001A4E*
- ID_OUI_FROM_DATABASE=NTI AG / LinMot
-
-OUI:001A53*
- ID_OUI_FROM_DATABASE=Zylaya
-
-OUI:001A42*
- ID_OUI_FROM_DATABASE=Techcity Technology co., Ltd.
-
-OUI:001A47*
- ID_OUI_FROM_DATABASE=Agami Systems, Inc.
-
-OUI:001A3B*
- ID_OUI_FROM_DATABASE=Doah Elecom Inc.
-
OUI:001A2F*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -38738,33 +39839,6 @@ OUI:001A36*
OUI:001A25*
ID_OUI_FROM_DATABASE=DELTA DORE
-OUI:0019C3*
- ID_OUI_FROM_DATABASE=Qualitrol
-
-OUI:0019BE*
- ID_OUI_FROM_DATABASE=Altai Technologies Limited
-
-OUI:0019BC*
- ID_OUI_FROM_DATABASE=ELECTRO CHANCE SRL
-
-OUI:0019A4*
- ID_OUI_FROM_DATABASE=Austar Technology (hang zhou) Co.,Ltd
-
-OUI:0019A9*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:0019AB*
- ID_OUI_FROM_DATABASE=Raycom CO ., LTD
-
-OUI:0019B0*
- ID_OUI_FROM_DATABASE=HanYang System
-
-OUI:001993*
- ID_OUI_FROM_DATABASE=Changshu Switchgear MFG. Co.,Ltd. (Former Changshu Switchgea
-
-OUI:001998*
- ID_OUI_FROM_DATABASE=SATO CORPORATION
-
OUI:001A17*
ID_OUI_FROM_DATABASE=Teak Technologies, Inc.
@@ -38780,11 +39854,29 @@ OUI:001A0B*
OUI:001A06*
ID_OUI_FROM_DATABASE=OpVista, Inc.
-OUI:0019FA*
- ID_OUI_FROM_DATABASE=Cable Vision Electronics CO., LTD.
+OUI:0018CD*
+ ID_OUI_FROM_DATABASE=Erae Electronics Industry Co., Ltd
-OUI:0019FF*
- ID_OUI_FROM_DATABASE=Finnzymes
+OUI:0018D2*
+ ID_OUI_FROM_DATABASE=High-Gain Antennas LLC
+
+OUI:0018D9*
+ ID_OUI_FROM_DATABASE=Santosha Internatonal, Inc
+
+OUI:0018C1*
+ ID_OUI_FROM_DATABASE=Almitec Informática e Comércio
+
+OUI:0018C8*
+ ID_OUI_FROM_DATABASE=ISONAS Inc.
+
+OUI:0018BC*
+ ID_OUI_FROM_DATABASE=ZAO NVP Bolid
+
+OUI:0018B5*
+ ID_OUI_FROM_DATABASE=Magna Carta
+
+OUI:0018AE*
+ ID_OUI_FROM_DATABASE=TVT CO.,LTD
OUI:001902*
ID_OUI_FROM_DATABASE=Cambridge Consultants Ltd
@@ -38807,11 +39899,59 @@ OUI:0018EC*
OUI:0018E5*
ID_OUI_FROM_DATABASE=Adhoco AG
-OUI:0018CD*
- ID_OUI_FROM_DATABASE=Erae Electronics Industry Co., Ltd
+OUI:0018A2*
+ ID_OUI_FROM_DATABASE=XIP Technology AB
-OUI:0018D2*
- ID_OUI_FROM_DATABASE=High-Gain Antennas LLC
+OUI:0018A9*
+ ID_OUI_FROM_DATABASE=Ethernet Direct Corporation
+
+OUI:00189D*
+ ID_OUI_FROM_DATABASE=Navcast Inc.
+
+OUI:001893*
+ ID_OUI_FROM_DATABASE=SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD
+
+OUI:001898*
+ ID_OUI_FROM_DATABASE=KINGSTATE ELECTRONICS CORPORATION
+
+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.
+
+OUI:0019C8*
+ ID_OUI_FROM_DATABASE=AnyDATA Corporation
+
+OUI:0019C3*
+ ID_OUI_FROM_DATABASE=Qualitrol
+
+OUI:0019BE*
+ ID_OUI_FROM_DATABASE=Altai Technologies Limited
+
+OUI:0019BC*
+ ID_OUI_FROM_DATABASE=ELECTRO CHANCE SRL
+
+OUI:0019A4*
+ ID_OUI_FROM_DATABASE=Austar Technology (hang zhou) Co.,Ltd
+
+OUI:0019A9*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:0019AB*
+ ID_OUI_FROM_DATABASE=Raycom CO ., LTD
+
+OUI:0019B0*
+ ID_OUI_FROM_DATABASE=HanYang System
+
+OUI:0019FA*
+ ID_OUI_FROM_DATABASE=Cable Vision Electronics CO., LTD.
+
+OUI:0019FF*
+ ID_OUI_FROM_DATABASE=Finnzymes
OUI:0019EC*
ID_OUI_FROM_DATABASE=Sagamore Systems, Inc.
@@ -38837,8 +39977,8 @@ OUI:0019D4*
OUI:0019D9*
ID_OUI_FROM_DATABASE=Zeutschel GmbH
-OUI:0019C8*
- ID_OUI_FROM_DATABASE=AnyDATA Corporation
+OUI:001823*
+ ID_OUI_FROM_DATABASE=Delta Electronics, Inc.
OUI:001817*
ID_OUI_FROM_DATABASE=D. E. Shaw Research, LLC
@@ -38858,14 +39998,11 @@ OUI:00180B*
OUI:001805*
ID_OUI_FROM_DATABASE=Beijing InHand Networking Technology Co.,Ltd.
-OUI:0017F4*
- ID_OUI_FROM_DATABASE=ZERON ALLIANCE
-
-OUI:0017F9*
- ID_OUI_FROM_DATABASE=Forcom Sp. z o.o.
+OUI:0017B8*
+ ID_OUI_FROM_DATABASE=NOVATRON CO., LTD.
-OUI:001800*
- ID_OUI_FROM_DATABASE=UNIGRAND LTD
+OUI:0017BD*
+ ID_OUI_FROM_DATABASE=Tibetsystem
OUI:0017B1*
ID_OUI_FROM_DATABASE=ACIST Medical Systems, Inc.
@@ -38885,41 +40022,32 @@ OUI:0017A0*
OUI:00179B*
ID_OUI_FROM_DATABASE=Chant Sincere CO., LTD.
-OUI:00178F*
- ID_OUI_FROM_DATABASE=NINGBO YIDONG ELECTRONIC CO.,LTD.
-
-OUI:001794*
+OUI:00170F*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00178D*
- ID_OUI_FROM_DATABASE=Checkpoint Systems, Inc.
-
-OUI:0018D9*
- ID_OUI_FROM_DATABASE=Santosha Internatonal, Inc
-
-OUI:0018C1*
- ID_OUI_FROM_DATABASE=Almitec Informática e Comércio
+OUI:001705*
+ ID_OUI_FROM_DATABASE=Methode Electronics
-OUI:0018C8*
- ID_OUI_FROM_DATABASE=ISONAS Inc.
+OUI:00170A*
+ ID_OUI_FROM_DATABASE=INEW DIGITAL COMPANY
-OUI:0018BC*
- ID_OUI_FROM_DATABASE=ZAO NVP Bolid
+OUI:0016F9*
+ ID_OUI_FROM_DATABASE=CETRTA POT, d.o.o., Kranj
-OUI:0018B5*
- ID_OUI_FROM_DATABASE=Magna Carta
+OUI:0016F7*
+ ID_OUI_FROM_DATABASE=L-3 Communications, Aviation Recorders
-OUI:0018B0*
- ID_OUI_FROM_DATABASE=Nortel
+OUI:0016E6*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
-OUI:0018AE*
- ID_OUI_FROM_DATABASE=TVT CO.,LTD
+OUI:00178F*
+ ID_OUI_FROM_DATABASE=NINGBO YIDONG ELECTRONIC CO.,LTD.
-OUI:0018A2*
- ID_OUI_FROM_DATABASE=XIP Technology AB
+OUI:001794*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0018A9*
- ID_OUI_FROM_DATABASE=Ethernet Direct Corporation
+OUI:00178D*
+ ID_OUI_FROM_DATABASE=Checkpoint Systems, Inc.
OUI:00177C*
ID_OUI_FROM_DATABASE=Smartlink Network Systems Limited
@@ -38942,30 +40070,9 @@ OUI:001775*
OUI:001760*
ID_OUI_FROM_DATABASE=Naito Densei Machida MFG.CO.,LTD
-OUI:001765*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001767*
ID_OUI_FROM_DATABASE=Earforce AS
-OUI:001759*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:001880*
- ID_OUI_FROM_DATABASE=Maxim Integrated Products
-
-OUI:00186D*
- ID_OUI_FROM_DATABASE=Zhenjiang Sapphire Electronic Industry CO.
-
-OUI:001872*
- ID_OUI_FROM_DATABASE=Expertise Engineering
-
-OUI:001874*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:001879*
- ID_OUI_FROM_DATABASE=dSys
-
OUI:00185A*
ID_OUI_FROM_DATABASE=uControl, Inc.
@@ -39005,8 +40112,8 @@ OUI:00182A*
OUI:001836*
ID_OUI_FROM_DATABASE=Reliance Electric Limited
-OUI:001823*
- ID_OUI_FROM_DATABASE=Delta Electronics, Inc.
+OUI:001759*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:001754*
ID_OUI_FROM_DATABASE=Arkino HiTOP Corporation Limited
@@ -39032,6 +40139,30 @@ OUI:00173A*
OUI:00172E*
ID_OUI_FROM_DATABASE=FXC Inc.
+OUI:001727*
+ ID_OUI_FROM_DATABASE=Thermo Ramsey Italia s.r.l.
+
+OUI:001722*
+ ID_OUI_FROM_DATABASE=Hanazeder Electronic GmbH
+
+OUI:00171B*
+ ID_OUI_FROM_DATABASE=Innovation Lab Corp.
+
+OUI:001714*
+ ID_OUI_FROM_DATABASE=BR Controls Nederland bv
+
+OUI:001716*
+ ID_OUI_FROM_DATABASE=Qno Technology Inc.
+
+OUI:0017F4*
+ ID_OUI_FROM_DATABASE=ZERON ALLIANCE
+
+OUI:0017F9*
+ ID_OUI_FROM_DATABASE=Forcom Sp. z o.o.
+
+OUI:001800*
+ ID_OUI_FROM_DATABASE=UNIGRAND LTD
+
OUI:0017ED*
ID_OUI_FROM_DATABASE=WooJooIT Ltd.
@@ -39053,29 +40184,23 @@ OUI:0017D0*
OUI:0017C4*
ID_OUI_FROM_DATABASE=Quanta Microsystems, INC.
-OUI:0017B8*
- ID_OUI_FROM_DATABASE=NOVATRON CO., LTD.
-
-OUI:0017BD*
- ID_OUI_FROM_DATABASE=Tibetsystem
-
-OUI:00189D*
- ID_OUI_FROM_DATABASE=Navcast Inc.
+OUI:001880*
+ ID_OUI_FROM_DATABASE=Maxim Integrated Products
-OUI:001893*
- ID_OUI_FROM_DATABASE=SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD
+OUI:00186D*
+ ID_OUI_FROM_DATABASE=Zhenjiang Sapphire Electronic Industry CO.
-OUI:001898*
- ID_OUI_FROM_DATABASE=KINGSTATE ELECTRONICS CORPORATION
+OUI:001872*
+ ID_OUI_FROM_DATABASE=Expertise Engineering
-OUI:001891*
- ID_OUI_FROM_DATABASE=Zhongshan General K-mate Electronics Co., Ltd
+OUI:001874*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001885*
- ID_OUI_FROM_DATABASE=Avigilon Corporation
+OUI:001879*
+ ID_OUI_FROM_DATABASE=dSys
-OUI:00188C*
- ID_OUI_FROM_DATABASE=Mobile Action Technology Inc.
+OUI:001686*
+ ID_OUI_FROM_DATABASE=Karl Storz Imaging
OUI:00167F*
ID_OUI_FROM_DATABASE=Bluebird Soft Inc.
@@ -39083,18 +40208,12 @@ OUI:00167F*
OUI:001681*
ID_OUI_FROM_DATABASE=Vector Informatik GmbH
-OUI:00167A*
- ID_OUI_FROM_DATABASE=Skyworth Overseas Dvelopment Ltd.
-
OUI:001674*
ID_OUI_FROM_DATABASE=EuroCB (Phils.), Inc.
OUI:00166B*
ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:00166D*
- ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt
-
OUI:001672*
ID_OUI_FROM_DATABASE=Zenway enterprise ltd
@@ -39107,86 +40226,35 @@ OUI:001666*
OUI:00165F*
ID_OUI_FROM_DATABASE=Fairmount Automation
-OUI:00165A*
- ID_OUI_FROM_DATABASE=Harman Specialty Group
-
-OUI:001653*
- ID_OUI_FROM_DATABASE=LEGO System A/S IE Electronics Division
-
-OUI:0016DF*
- ID_OUI_FROM_DATABASE=Lundinova AB
-
-OUI:0016DA*
- ID_OUI_FROM_DATABASE=Futronic Technology Co. Ltd.
-
-OUI:0016D5*
- ID_OUI_FROM_DATABASE=Synccom Co., Ltd
-
-OUI:0016C9*
- ID_OUI_FROM_DATABASE=NAT Seattle, Inc.
-
-OUI:0016D0*
- ID_OUI_FROM_DATABASE=ATech elektronika d.o.o.
-
-OUI:0016BD*
- ID_OUI_FROM_DATABASE=ATI Industrial Automation
-
-OUI:0016C2*
- ID_OUI_FROM_DATABASE=Avtec Systems Inc
-
-OUI:0016BB*
- ID_OUI_FROM_DATABASE=Law-Chain Computer Technology Co Ltd
-
OUI:0016AA*
ID_OUI_FROM_DATABASE=Kei Communication Technology Inc.
OUI:0016AF*
ID_OUI_FROM_DATABASE=Shenzhen Union Networks Equipment Co.,Ltd.
-OUI:00162A*
- ID_OUI_FROM_DATABASE=Antik computers & communications s.r.o.
-
-OUI:001623*
- ID_OUI_FROM_DATABASE=Interval Media
-
-OUI:001617*
- ID_OUI_FROM_DATABASE=MSI
-
-OUI:00161E*
- ID_OUI_FROM_DATABASE=Woojinnet
-
-OUI:00160D*
- ID_OUI_FROM_DATABASE=Be Here Corporation
-
-OUI:001606*
- ID_OUI_FROM_DATABASE=Ideal Industries
-
-OUI:0015FA*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:0015F5*
- ID_OUI_FROM_DATABASE=Sustainable Energy Systems
+OUI:0016A5*
+ ID_OUI_FROM_DATABASE=Tandberg Storage ASA
-OUI:0015F4*
- ID_OUI_FROM_DATABASE=Eventide
+OUI:001699*
+ ID_OUI_FROM_DATABASE=Tonic DVB Marketing Ltd
-OUI:001705*
- ID_OUI_FROM_DATABASE=Methode Electronics
+OUI:0016A0*
+ ID_OUI_FROM_DATABASE=Auto-Maskin
-OUI:00170A*
- ID_OUI_FROM_DATABASE=INEW DIGITAL COMPANY
+OUI:001692*
+ ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc.
-OUI:0016F9*
- ID_OUI_FROM_DATABASE=CETRTA POT, d.o.o., Kranj
+OUI:001694*
+ ID_OUI_FROM_DATABASE=Sennheiser Communications A/S
-OUI:0016F2*
- ID_OUI_FROM_DATABASE=Dmobile System Co., Ltd.
+OUI:00168D*
+ ID_OUI_FROM_DATABASE=KORWIN CO., Ltd.
-OUI:0016F7*
- ID_OUI_FROM_DATABASE=L-3 Communications, Aviation Recorders
+OUI:00165A*
+ ID_OUI_FROM_DATABASE=Harman Specialty Group
-OUI:0016E6*
- ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+OUI:001653*
+ ID_OUI_FROM_DATABASE=LEGO System A/S IE Electronics Division
OUI:00164C*
ID_OUI_FROM_DATABASE=PLANET INT Co., Ltd
@@ -39200,9 +40268,6 @@ OUI:001642*
OUI:00163D*
ID_OUI_FROM_DATABASE=Tsinghua Tongfang Legend Silicon Tech. Co., Ltd.
-OUI:001636*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc.
-
OUI:001631*
ID_OUI_FROM_DATABASE=Xteam
@@ -39212,26 +40277,11 @@ OUI:00162F*
OUI:001630*
ID_OUI_FROM_DATABASE=Vativ Technologies
-OUI:0016A5*
- ID_OUI_FROM_DATABASE=Tandberg Storage ASA
-
-OUI:001699*
- ID_OUI_FROM_DATABASE=Tonic DVB Marketing Ltd
-
-OUI:0016A0*
- ID_OUI_FROM_DATABASE=Auto-Maskin
-
-OUI:001692*
- ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc.
-
-OUI:001694*
- ID_OUI_FROM_DATABASE=Sennheiser Communications A/S
-
-OUI:00168D*
- ID_OUI_FROM_DATABASE=KORWIN CO., Ltd.
+OUI:0015F5*
+ ID_OUI_FROM_DATABASE=Sustainable Energy Systems
-OUI:001686*
- ID_OUI_FROM_DATABASE=Karl Storz Imaging
+OUI:0015F4*
+ ID_OUI_FROM_DATABASE=Eventide
OUI:0015EE*
ID_OUI_FROM_DATABASE=Omnex Control Systems
@@ -39254,68 +40304,122 @@ OUI:0015D8*
OUI:0015CA*
ID_OUI_FROM_DATABASE=TeraRecon, Inc.
-OUI:0015BC*
- ID_OUI_FROM_DATABASE=Develco
+OUI:001598*
+ ID_OUI_FROM_DATABASE=Kolektor group
-OUI:0015B5*
- ID_OUI_FROM_DATABASE=CI Network Corp.
+OUI:001593*
+ ID_OUI_FROM_DATABASE=U4EA Technologies Inc.
-OUI:0015B0*
- ID_OUI_FROM_DATABASE=AUTOTELENET CO.,LTD
+OUI:00158C*
+ ID_OUI_FROM_DATABASE=Liab ApS
-OUI:0015AB*
- ID_OUI_FROM_DATABASE=PRO CO SOUND INC
+OUI:001586*
+ ID_OUI_FROM_DATABASE=Xiamen Overseas Chinese Electronic Co., Ltd.
-OUI:0015A6*
- ID_OUI_FROM_DATABASE=Digital Electronics Products Ltd.
+OUI:001585*
+ ID_OUI_FROM_DATABASE=Aonvision Technolopy Corp.
-OUI:00159F*
- ID_OUI_FROM_DATABASE=Terascala, Inc.
+OUI:001587*
+ ID_OUI_FROM_DATABASE=Takenaka Seisakusho Co.,Ltd
-OUI:001598*
- ID_OUI_FROM_DATABASE=Kolektor group
+OUI:001580*
+ ID_OUI_FROM_DATABASE=U-WAY CORPORATION
-OUI:001727*
- ID_OUI_FROM_DATABASE=Thermo Ramsey Italia s.r.l.
+OUI:00157B*
+ ID_OUI_FROM_DATABASE=Leuze electronic GmbH + Co. KG
-OUI:001722*
- ID_OUI_FROM_DATABASE=Hanazeder Electronic GmbH
+OUI:001576*
+ ID_OUI_FROM_DATABASE=LABiTec - Labor Biomedical Technologies GmbH
-OUI:00171B*
- ID_OUI_FROM_DATABASE=Innovation Lab Corp.
+OUI:00156A*
+ ID_OUI_FROM_DATABASE=DG2L Technologies Pvt. Ltd.
-OUI:001714*
- ID_OUI_FROM_DATABASE=BR Controls Nederland bv
+OUI:00156F*
+ ID_OUI_FROM_DATABASE=Xiranet Communications GmbH
-OUI:001716*
- ID_OUI_FROM_DATABASE=Qno Technology Inc.
+OUI:0016DF*
+ ID_OUI_FROM_DATABASE=Lundinova AB
-OUI:00170F*
+OUI:0016DA*
+ ID_OUI_FROM_DATABASE=Futronic Technology Co. Ltd.
+
+OUI:0016D5*
+ ID_OUI_FROM_DATABASE=Synccom Co., Ltd
+
+OUI:0016C9*
+ ID_OUI_FROM_DATABASE=NAT Seattle, Inc.
+
+OUI:0016D0*
+ ID_OUI_FROM_DATABASE=ATech elektronika d.o.o.
+
+OUI:0016BD*
+ ID_OUI_FROM_DATABASE=ATI Industrial Automation
+
+OUI:0016C2*
+ ID_OUI_FROM_DATABASE=Avtec Systems Inc
+
+OUI:0016BB*
+ ID_OUI_FROM_DATABASE=Law-Chain Computer Technology Co Ltd
+
+OUI:00162A*
+ ID_OUI_FROM_DATABASE=Antik computers & communications s.r.o.
+
+OUI:001623*
+ ID_OUI_FROM_DATABASE=Interval Media
+
+OUI:001617*
+ ID_OUI_FROM_DATABASE=MSI
+
+OUI:00161E*
+ ID_OUI_FROM_DATABASE=Woojinnet
+
+OUI:00160D*
+ ID_OUI_FROM_DATABASE=Be Here Corporation
+
+OUI:001606*
+ ID_OUI_FROM_DATABASE=Ideal Industries
+
+OUI:0015FA*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0014AA*
- ID_OUI_FROM_DATABASE=Ashly Audio, Inc.
+OUI:001563*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00149D*
- ID_OUI_FROM_DATABASE=Sound ID Inc.
+OUI:001557*
+ ID_OUI_FROM_DATABASE=Olivetti
-OUI:001498*
- ID_OUI_FROM_DATABASE=Viking Design Technology
+OUI:00155C*
+ ID_OUI_FROM_DATABASE=Dresser Wayne
-OUI:00148A*
- ID_OUI_FROM_DATABASE=Elin Ebg Traction Gmbh
+OUI:00154B*
+ ID_OUI_FROM_DATABASE=Wonde Proud Technology Co., Ltd
-OUI:001491*
- ID_OUI_FROM_DATABASE=Daniels Electronics Ltd. dbo Codan Rado Communications
+OUI:001550*
+ ID_OUI_FROM_DATABASE=Nits Technology Inc
-OUI:001485*
- ID_OUI_FROM_DATABASE=Giga-Byte
+OUI:001545*
+ ID_OUI_FROM_DATABASE=SEECODE Co., Ltd.
-OUI:00147E*
- ID_OUI_FROM_DATABASE=InnerWireless
+OUI:00153E*
+ ID_OUI_FROM_DATABASE=Q-Matic Sweden AB
-OUI:001478*
- ID_OUI_FROM_DATABASE=ShenZhen TP-LINK Technologies Co., Ltd.
+OUI:0015BC*
+ ID_OUI_FROM_DATABASE=Develco
+
+OUI:0015B5*
+ ID_OUI_FROM_DATABASE=CI Network Corp.
+
+OUI:0015B0*
+ ID_OUI_FROM_DATABASE=AUTOTELENET CO.,LTD
+
+OUI:0015AB*
+ ID_OUI_FROM_DATABASE=PRO CO SOUND INC
+
+OUI:0015A6*
+ ID_OUI_FROM_DATABASE=Digital Electronics Products Ltd.
+
+OUI:00159F*
+ ID_OUI_FROM_DATABASE=Terascala, Inc.
OUI:001532*
ID_OUI_FROM_DATABASE=Consumer Technologies Group, LLC
@@ -39347,11 +40451,8 @@ OUI:001515*
OUI:001510*
ID_OUI_FROM_DATABASE=Techsphere Co., Ltd
-OUI:001502*
- ID_OUI_FROM_DATABASE=BETA tech
-
-OUI:001509*
- ID_OUI_FROM_DATABASE=Plus Technology Co., Ltd
+OUI:001453*
+ ID_OUI_FROM_DATABASE=ADVANTECH TECHNOLOGIES CO.,LTD
OUI:00144E*
ID_OUI_FROM_DATABASE=SRISA
@@ -39374,59 +40475,53 @@ OUI:00143B*
OUI:001436*
ID_OUI_FROM_DATABASE=Qwerty Elektronik AB
-OUI:001423*
- ID_OUI_FROM_DATABASE=J-S Co. NEUROCOM
-
-OUI:001593*
- ID_OUI_FROM_DATABASE=U4EA Technologies Inc.
-
-OUI:00158C*
- ID_OUI_FROM_DATABASE=Liab ApS
+OUI:0014AB*
+ ID_OUI_FROM_DATABASE=Senhai Electronic Technology Co., Ltd.
-OUI:001586*
- ID_OUI_FROM_DATABASE=Xiamen Overseas Chinese Electronic Co., Ltd.
+OUI:0014B0*
+ ID_OUI_FROM_DATABASE=Naeil Community
-OUI:001585*
- ID_OUI_FROM_DATABASE=Aonvision Technolopy Corp.
+OUI:0014A9*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001587*
- ID_OUI_FROM_DATABASE=Takenaka Seisakusho Co.,Ltd
+OUI:0014AA*
+ ID_OUI_FROM_DATABASE=Ashly Audio, Inc.
-OUI:001580*
- ID_OUI_FROM_DATABASE=U-WAY CORPORATION
+OUI:00149D*
+ ID_OUI_FROM_DATABASE=Sound ID Inc.
-OUI:00157B*
- ID_OUI_FROM_DATABASE=Leuze electronic GmbH + Co. KG
+OUI:001498*
+ ID_OUI_FROM_DATABASE=Viking Design Technology
-OUI:001576*
- ID_OUI_FROM_DATABASE=LABiTec - Labor Biomedical Technologies GmbH
+OUI:00148A*
+ ID_OUI_FROM_DATABASE=Elin Ebg Traction Gmbh
-OUI:00156A*
- ID_OUI_FROM_DATABASE=DG2L Technologies Pvt. Ltd.
+OUI:001491*
+ ID_OUI_FROM_DATABASE=Daniels Electronics Ltd. dbo Codan Rado Communications
-OUI:00156F*
- ID_OUI_FROM_DATABASE=Xiranet Communications GmbH
+OUI:001485*
+ ID_OUI_FROM_DATABASE=Giga-Byte
-OUI:001563*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:00147E*
+ ID_OUI_FROM_DATABASE=InnerWireless
-OUI:0014FD*
- ID_OUI_FROM_DATABASE=Thecus Technology Corp.
+OUI:001477*
+ ID_OUI_FROM_DATABASE=Nertec Inc.
-OUI:0014EF*
- ID_OUI_FROM_DATABASE=TZero Technologies, Inc.
+OUI:001472*
+ ID_OUI_FROM_DATABASE=China Broadband Wireless IP Standard Group
-OUI:0014F1*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:001466*
+ ID_OUI_FROM_DATABASE=Kleinhenz Elektronik GmbH
-OUI:0014F0*
- ID_OUI_FROM_DATABASE=Business Security OL AB
+OUI:00146B*
+ ID_OUI_FROM_DATABASE=Anagran, Inc.
-OUI:0014EA*
- ID_OUI_FROM_DATABASE=S Digm Inc. (Safe Paradigm Inc.)
+OUI:00145F*
+ ID_OUI_FROM_DATABASE=ADITEC CO. LTD
-OUI:0014E5*
- ID_OUI_FROM_DATABASE=Alticast
+OUI:001458*
+ ID_OUI_FROM_DATABASE=HS Automatic ApS
OUI:0014E6*
ID_OUI_FROM_DATABASE=AIM Infrarotmodule GmbH
@@ -39455,56 +40550,56 @@ OUI:0014BA*
OUI:0014B5*
ID_OUI_FROM_DATABASE=PHYSIOMETRIX,INC
-OUI:0014AB*
- ID_OUI_FROM_DATABASE=Senhai Electronic Technology Co., Ltd.
+OUI:0013C7*
+ ID_OUI_FROM_DATABASE=IONOS Co.,Ltd.
-OUI:0014B0*
- ID_OUI_FROM_DATABASE=Naeil Community
+OUI:0013C0*
+ ID_OUI_FROM_DATABASE=Trix Tecnologia Ltda.
-OUI:0014B4*
- ID_OUI_FROM_DATABASE=General Dynamics United Kingdom Ltd
+OUI:0013B6*
+ ID_OUI_FROM_DATABASE=Sling Media, Inc.
-OUI:0014A9*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:0013AF*
+ ID_OUI_FROM_DATABASE=NUMA Technology,Inc.
-OUI:001557*
- ID_OUI_FROM_DATABASE=Olivetti
+OUI:0013B0*
+ ID_OUI_FROM_DATABASE=Jablotron
-OUI:00155C*
- ID_OUI_FROM_DATABASE=Dresser Wayne
+OUI:0013AA*
+ ID_OUI_FROM_DATABASE=ALS & TEC Ltd.
-OUI:00154B*
- ID_OUI_FROM_DATABASE=Wonde Proud Technology Co., Ltd
+OUI:0013A3*
+ ID_OUI_FROM_DATABASE=Siemens Com CPE Devices
-OUI:001550*
- ID_OUI_FROM_DATABASE=Nits Technology Inc
+OUI:00139E*
+ ID_OUI_FROM_DATABASE=Ciara Technologies Inc.
-OUI:001545*
- ID_OUI_FROM_DATABASE=SEECODE Co., Ltd.
+OUI:001502*
+ ID_OUI_FROM_DATABASE=BETA tech
-OUI:00153E*
- ID_OUI_FROM_DATABASE=Q-Matic Sweden AB
+OUI:001509*
+ ID_OUI_FROM_DATABASE=Plus Technology Co., Ltd
-OUI:001477*
- ID_OUI_FROM_DATABASE=Nertec Inc.
+OUI:0014FD*
+ ID_OUI_FROM_DATABASE=Thecus Technology Corp.
-OUI:001472*
- ID_OUI_FROM_DATABASE=China Broadband Wireless IP Standard Group
+OUI:0014EF*
+ ID_OUI_FROM_DATABASE=TZero Technologies, Inc.
-OUI:001466*
- ID_OUI_FROM_DATABASE=Kleinhenz Elektronik GmbH
+OUI:0014F1*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00146B*
- ID_OUI_FROM_DATABASE=Anagran, Inc.
+OUI:0014F0*
+ ID_OUI_FROM_DATABASE=Business Security OL AB
-OUI:00145F*
- ID_OUI_FROM_DATABASE=ADITEC CO. LTD
+OUI:0014EA*
+ ID_OUI_FROM_DATABASE=S Digm Inc. (Safe Paradigm Inc.)
-OUI:001458*
- ID_OUI_FROM_DATABASE=HS Automatic ApS
+OUI:0014E5*
+ ID_OUI_FROM_DATABASE=Alticast
-OUI:001453*
- ID_OUI_FROM_DATABASE=ADVANTECH TECHNOLOGIES CO.,LTD
+OUI:001423*
+ ID_OUI_FROM_DATABASE=J-S Co. NEUROCOM
OUI:001419*
ID_OUI_FROM_DATABASE=SIDSA
@@ -39512,9 +40607,6 @@ OUI:001419*
OUI:001412*
ID_OUI_FROM_DATABASE=S-TEC electronics AG
-OUI:00140D*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001409*
ID_OUI_FROM_DATABASE=MAGNETI MARELLI S.E. S.p.A.
@@ -39530,38 +40622,17 @@ OUI:0013F8*
OUI:0013F1*
ID_OUI_FROM_DATABASE=AMOD Technology Co., Ltd.
-OUI:00135C*
- ID_OUI_FROM_DATABASE=OnSite Systems, Inc.
-
-OUI:001355*
- ID_OUI_FROM_DATABASE=TOMEN Cyber-business Solutions, Inc.
-
-OUI:001356*
- ID_OUI_FROM_DATABASE=FLIR Radiation Inc
-
-OUI:001350*
- ID_OUI_FROM_DATABASE=Silver Spring Networks, Inc
-
-OUI:001344*
- ID_OUI_FROM_DATABASE=Fargo Electronics Inc.
-
-OUI:001349*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
-OUI:001343*
- ID_OUI_FROM_DATABASE=Matsushita Electronic Components (Europe) GmbH
-
-OUI:00133D*
- ID_OUI_FROM_DATABASE=Micro Memory Curtiss Wright Co
+OUI:0013F7*
+ ID_OUI_FROM_DATABASE=SMC Networks, Inc.
-OUI:00132A*
- ID_OUI_FROM_DATABASE=Sitronics Telecom Solutions
+OUI:0013E7*
+ ID_OUI_FROM_DATABASE=Halcro
-OUI:001331*
- ID_OUI_FROM_DATABASE=CellPoint Connect
+OUI:0013DB*
+ ID_OUI_FROM_DATABASE=SHOEI Electric Co.,Ltd
-OUI:001336*
- ID_OUI_FROM_DATABASE=Tianjin 712 Communication Broadcasting co., ltd.
+OUI:0013CC*
+ ID_OUI_FROM_DATABASE=Tall Maple Systems
OUI:001284*
ID_OUI_FROM_DATABASE=Lab33 Srl
@@ -39587,75 +40658,57 @@ OUI:001264*
OUI:00125A*
ID_OUI_FROM_DATABASE=Microsoft Corporation
-OUI:0012FA*
- ID_OUI_FROM_DATABASE=THX LTD
+OUI:00125F*
+ ID_OUI_FROM_DATABASE=AWIND Inc.
-OUI:001301*
- ID_OUI_FROM_DATABASE=IronGate S.L.
+OUI:001255*
+ ID_OUI_FROM_DATABASE=NetEffect Incorporated
-OUI:001307*
- ID_OUI_FROM_DATABASE=Paravirtual Corporation
+OUI:00124E*
+ ID_OUI_FROM_DATABASE=XAC AUTOMATION CORP.
-OUI:0012F5*
- ID_OUI_FROM_DATABASE=Imarda New Zealand Limited
+OUI:001247*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
-OUI:0012EB*
- ID_OUI_FROM_DATABASE=PDH Solutions, LLC
+OUI:001248*
+ ID_OUI_FROM_DATABASE=EMC Corporation (Kashya)
-OUI:0012DE*
- ID_OUI_FROM_DATABASE=Radio Components Sweden AB
+OUI:001242*
+ ID_OUI_FROM_DATABASE=Millennial Net
-OUI:0012DD*
- ID_OUI_FROM_DATABASE=Shengqu Information Technology (Shanghai) Co., Ltd.
+OUI:001236*
+ ID_OUI_FROM_DATABASE=ConSentry Networks
-OUI:0012E4*
- ID_OUI_FROM_DATABASE=ZIEHL industrie-electronik GmbH + Co KG
+OUI:00123B*
+ ID_OUI_FROM_DATABASE=KeRo Systems ApS
-OUI:0012D8*
- ID_OUI_FROM_DATABASE=International Games System Co., Ltd.
+OUI:001368*
+ ID_OUI_FROM_DATABASE=Saab Danmark A/S
-OUI:0013B6*
- ID_OUI_FROM_DATABASE=Sling Media, Inc.
+OUI:00135C*
+ ID_OUI_FROM_DATABASE=OnSite Systems, Inc.
-OUI:0013AF*
- ID_OUI_FROM_DATABASE=NUMA Technology,Inc.
+OUI:001355*
+ ID_OUI_FROM_DATABASE=TOMEN Cyber-business Solutions, Inc.
-OUI:0013B0*
- ID_OUI_FROM_DATABASE=Jablotron
+OUI:001356*
+ ID_OUI_FROM_DATABASE=FLIR Radiation Inc
-OUI:0013AA*
- ID_OUI_FROM_DATABASE=ALS & TEC Ltd.
+OUI:001350*
+ ID_OUI_FROM_DATABASE=Silver Spring Networks, Inc
-OUI:0013A3*
- ID_OUI_FROM_DATABASE=Siemens Com CPE Devices
+OUI:001344*
+ ID_OUI_FROM_DATABASE=Fargo Electronics Inc.
-OUI:00139E*
- ID_OUI_FROM_DATABASE=Ciara Technologies Inc.
+OUI:001343*
+ ID_OUI_FROM_DATABASE=Matsushita Electronic Components (Europe) GmbH
+
+OUI:00133D*
+ ID_OUI_FROM_DATABASE=Micro Memory Curtiss Wright Co
OUI:00139D*
ID_OUI_FROM_DATABASE=Marvell Hispana S.L.
-OUI:0012A8*
- ID_OUI_FROM_DATABASE=intec GmbH
-
-OUI:0012A2*
- ID_OUI_FROM_DATABASE=VITA
-
-OUI:0012A1*
- ID_OUI_FROM_DATABASE=BluePacket Communications Co., Ltd.
-
-OUI:00129C*
- ID_OUI_FROM_DATABASE=Yulinet
-
-OUI:001290*
- ID_OUI_FROM_DATABASE=KYOWA Electric & Machinery Corp.
-
-OUI:001295*
- ID_OUI_FROM_DATABASE=Aiware Inc.
-
-OUI:001283*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:00138B*
ID_OUI_FROM_DATABASE=Phantom Technologies LLC
@@ -39683,44 +40736,59 @@ OUI:001375*
OUI:001363*
ID_OUI_FROM_DATABASE=Verascape, Inc.
-OUI:001368*
- ID_OUI_FROM_DATABASE=Saab Danmark A/S
+OUI:0012FA*
+ ID_OUI_FROM_DATABASE=THX LTD
-OUI:0013F7*
- ID_OUI_FROM_DATABASE=SMC Networks, Inc.
+OUI:001301*
+ ID_OUI_FROM_DATABASE=IronGate S.L.
-OUI:0013E7*
- ID_OUI_FROM_DATABASE=Halcro
+OUI:001307*
+ ID_OUI_FROM_DATABASE=Paravirtual Corporation
-OUI:0013DB*
- ID_OUI_FROM_DATABASE=SHOEI Electric Co.,Ltd
+OUI:0012F5*
+ ID_OUI_FROM_DATABASE=Imarda New Zealand Limited
-OUI:0013CC*
- ID_OUI_FROM_DATABASE=Tall Maple Systems
+OUI:0012EB*
+ ID_OUI_FROM_DATABASE=PDH Solutions, LLC
-OUI:0013C7*
- ID_OUI_FROM_DATABASE=IONOS Co.,Ltd.
+OUI:0012DE*
+ ID_OUI_FROM_DATABASE=Radio Components Sweden AB
-OUI:0013C0*
- ID_OUI_FROM_DATABASE=Trix Tecnologia Ltda.
+OUI:0012DD*
+ ID_OUI_FROM_DATABASE=Shengqu Information Technology (Shanghai) Co., Ltd.
-OUI:0012CB*
- ID_OUI_FROM_DATABASE=CSS Inc.
+OUI:0012E4*
+ ID_OUI_FROM_DATABASE=ZIEHL industrie-electronik GmbH + Co KG
-OUI:0012C5*
- ID_OUI_FROM_DATABASE=V-Show Technology (China) Co.,Ltd
+OUI:0012AF*
+ ID_OUI_FROM_DATABASE=ELPRO Technologies
-OUI:0012CC*
- ID_OUI_FROM_DATABASE=Bitatek CO., LTD
+OUI:0012A8*
+ ID_OUI_FROM_DATABASE=intec GmbH
-OUI:0012B4*
- ID_OUI_FROM_DATABASE=Work Microwave GmbH
+OUI:0012A2*
+ ID_OUI_FROM_DATABASE=VITA
-OUI:0012BB*
- ID_OUI_FROM_DATABASE=Telecommunications Industry Association TR-41 Committee
+OUI:0012A1*
+ ID_OUI_FROM_DATABASE=BluePacket Communications Co., Ltd.
-OUI:0012AF*
- ID_OUI_FROM_DATABASE=ELPRO Technologies
+OUI:00129C*
+ ID_OUI_FROM_DATABASE=Yulinet
+
+OUI:001290*
+ ID_OUI_FROM_DATABASE=KYOWA Electric & Machinery Corp.
+
+OUI:001295*
+ ID_OUI_FROM_DATABASE=Aiware Inc.
+
+OUI:00132A*
+ ID_OUI_FROM_DATABASE=Sitronics Telecom Solutions
+
+OUI:001331*
+ ID_OUI_FROM_DATABASE=CellPoint Connect
+
+OUI:001336*
+ ID_OUI_FROM_DATABASE=Tianjin 712 Communication Broadcasting co., ltd.
OUI:001324*
ID_OUI_FROM_DATABASE=Schneider Electric Ultra Terminal
@@ -39740,53 +40808,47 @@ OUI:00130D*
OUI:001308*
ID_OUI_FROM_DATABASE=Nuvera Fuel Cells
-OUI:001181*
- ID_OUI_FROM_DATABASE=InterEnergy Co.Ltd,
-
-OUI:00117B*
- ID_OUI_FROM_DATABASE=Büchi Labortechnik AG
-
-OUI:00116F*
- ID_OUI_FROM_DATABASE=Netforyou Co., LTD.
+OUI:00122F*
+ ID_OUI_FROM_DATABASE=Sanei Electric Inc.
-OUI:001168*
- ID_OUI_FROM_DATABASE=HomeLogic LLC
+OUI:001235*
+ ID_OUI_FROM_DATABASE=Andrew Corporation
-OUI:00115E*
- ID_OUI_FROM_DATABASE=ProMinent Dosiertechnik GmbH
+OUI:00122B*
+ ID_OUI_FROM_DATABASE=Virbiage Pty Ltd
-OUI:001157*
- ID_OUI_FROM_DATABASE=Oki Electric Industry Co., Ltd.
+OUI:001212*
+ ID_OUI_FROM_DATABASE=PLUS Corporation
-OUI:001158*
- ID_OUI_FROM_DATABASE=Nortel Networks
+OUI:001219*
+ ID_OUI_FROM_DATABASE=Ahead Communication Systems Inc
-OUI:001152*
- ID_OUI_FROM_DATABASE=Eidsvoll Electronics AS
+OUI:0012D8*
+ ID_OUI_FROM_DATABASE=International Games System Co., Ltd.
-OUI:0011A4*
- ID_OUI_FROM_DATABASE=JStream Technologies Inc.
+OUI:0012CB*
+ ID_OUI_FROM_DATABASE=CSS Inc.
-OUI:001198*
- ID_OUI_FROM_DATABASE=Prism Media Products Limited
+OUI:0012C5*
+ ID_OUI_FROM_DATABASE=V-Show Technology (China) Co.,Ltd
-OUI:00119D*
- ID_OUI_FROM_DATABASE=Diginfo Technology Corporation
+OUI:0012CC*
+ ID_OUI_FROM_DATABASE=Bitatek CO., LTD
-OUI:00119E*
- ID_OUI_FROM_DATABASE=Solectron Brazil
+OUI:0012B4*
+ ID_OUI_FROM_DATABASE=Work Microwave GmbH
-OUI:00118E*
- ID_OUI_FROM_DATABASE=Halytech Mace
+OUI:0012BB*
+ ID_OUI_FROM_DATABASE=Telecommunications Industry Association TR-41 Committee
-OUI:001193*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:001206*
+ ID_OUI_FROM_DATABASE=iQuest (NZ) Ltd
-OUI:001187*
- ID_OUI_FROM_DATABASE=Category Solutions, Inc
+OUI:00120B*
+ ID_OUI_FROM_DATABASE=Chinasys Technologies Limited
-OUI:001182*
- ID_OUI_FROM_DATABASE=IMI Norgren Ltd
+OUI:00120C*
+ ID_OUI_FROM_DATABASE=CE-Infosys Pte Ltd
OUI:0011FF*
ID_OUI_FROM_DATABASE=Digitro Tecnologia Ltda
@@ -39794,9 +40856,6 @@ OUI:0011FF*
OUI:0011FA*
ID_OUI_FROM_DATABASE=Rane Corporation
-OUI:0011F9*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:0011F0*
ID_OUI_FROM_DATABASE=Wideful Limited
@@ -39806,77 +40865,86 @@ OUI:0011EF*
OUI:0011E9*
ID_OUI_FROM_DATABASE=STARNEX CO., LTD.
-OUI:0011DD*
- ID_OUI_FROM_DATABASE=FROMUS TEC. Co., Ltd.
+OUI:001187*
+ ID_OUI_FROM_DATABASE=Category Solutions, Inc
-OUI:0011E2*
- ID_OUI_FROM_DATABASE=Hua Jung Components Co., Ltd.
+OUI:001182*
+ ID_OUI_FROM_DATABASE=IMI Norgren Ltd
-OUI:000FFA*
- ID_OUI_FROM_DATABASE=Optinel Systems, Inc.
+OUI:001181*
+ ID_OUI_FROM_DATABASE=InterEnergy Co.Ltd,
-OUI:000FFF*
- ID_OUI_FROM_DATABASE=Control4
+OUI:00117B*
+ ID_OUI_FROM_DATABASE=Büchi Labortechnik AG
-OUI:000FF1*
- ID_OUI_FROM_DATABASE=nex-G Systems Pte.Ltd
+OUI:00116F*
+ ID_OUI_FROM_DATABASE=Netforyou Co., LTD.
-OUI:000FE4*
- ID_OUI_FROM_DATABASE=Pantech Co.,Ltd
+OUI:001168*
+ ID_OUI_FROM_DATABASE=HomeLogic LLC
-OUI:000FEA*
- ID_OUI_FROM_DATABASE=Giga-Byte Technology Co.,LTD.
+OUI:00115E*
+ ID_OUI_FROM_DATABASE=ProMinent Dosiertechnik GmbH
-OUI:000FE3*
- ID_OUI_FROM_DATABASE=Damm Cellular Systems A/S
+OUI:001157*
+ ID_OUI_FROM_DATABASE=Oki Electric Industry Co., Ltd.
-OUI:000FD7*
- ID_OUI_FROM_DATABASE=Harman Music Group
+OUI:000FB2*
+ ID_OUI_FROM_DATABASE=Broadband Pacenet (India) Pvt. Ltd.
-OUI:001235*
- ID_OUI_FROM_DATABASE=Andrew Corporation
+OUI:000FA5*
+ ID_OUI_FROM_DATABASE=BWA Technology GmbH
-OUI:00122B*
- ID_OUI_FROM_DATABASE=Virbiage Pty Ltd
+OUI:000FB1*
+ ID_OUI_FROM_DATABASE=Cognio Inc.
-OUI:001212*
- ID_OUI_FROM_DATABASE=PLUS Corporation
+OUI:000FAC*
+ ID_OUI_FROM_DATABASE=IEEE 802.11
-OUI:001219*
- ID_OUI_FROM_DATABASE=Ahead Communication Systems Inc
+OUI:000F9C*
+ ID_OUI_FROM_DATABASE=Panduit Corp
-OUI:001206*
- ID_OUI_FROM_DATABASE=iQuest (NZ) Ltd
+OUI:000FA0*
+ ID_OUI_FROM_DATABASE=CANON KOREA BUSINESS SOLUTIONS INC.
-OUI:00120B*
- ID_OUI_FROM_DATABASE=Chinasys Technologies Limited
+OUI:000F97*
+ ID_OUI_FROM_DATABASE=Avanex Corporation
-OUI:00120C*
- ID_OUI_FROM_DATABASE=CE-Infosys Pte Ltd
+OUI:000F8A*
+ ID_OUI_FROM_DATABASE=WideView
-OUI:001130*
- ID_OUI_FROM_DATABASE=Allied Telesis (Hong Kong) Ltd.
+OUI:000F89*
+ ID_OUI_FROM_DATABASE=Winnertec System Co., Ltd.
-OUI:00111E*
- ID_OUI_FROM_DATABASE=EPSG (Ethernet Powerlink Standardization Group)
+OUI:000F90*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00111F*
- ID_OUI_FROM_DATABASE=Doremi Labs, Inc.
+OUI:000FD7*
+ ID_OUI_FROM_DATABASE=Harman Music Group
-OUI:001112*
- ID_OUI_FROM_DATABASE=Honeywell CMSS
+OUI:000FD1*
+ ID_OUI_FROM_DATABASE=Applied Wireless Identifications Group, Inc.
-OUI:001118*
- ID_OUI_FROM_DATABASE=BLX IC Design Corp., Ltd.
+OUI:000FD2*
+ ID_OUI_FROM_DATABASE=EWA Technologies, Inc.
-OUI:001105*
- ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd.
+OUI:000FC4*
+ ID_OUI_FROM_DATABASE=NST co.,LTD.
-OUI:00110C*
- ID_OUI_FROM_DATABASE=Atmark Techno, Inc.
+OUI:000FCB*
+ ID_OUI_FROM_DATABASE=3Com Ltd
-OUI:000FF9*
- ID_OUI_FROM_DATABASE=Valcretec, Inc.
+OUI:000FBF*
+ ID_OUI_FROM_DATABASE=DGT Sp. z o.o.
+
+OUI:000FB8*
+ ID_OUI_FROM_DATABASE=CallURL Inc.
+
+OUI:0011DD*
+ ID_OUI_FROM_DATABASE=FROMUS TEC. Co., Ltd.
+
+OUI:0011E2*
+ ID_OUI_FROM_DATABASE=Hua Jung Components Co., Ltd.
OUI:0011CF*
ID_OUI_FROM_DATABASE=Thrane & Thrane A/S
@@ -39902,38 +40970,59 @@ OUI:0011BE*
OUI:0011BD*
ID_OUI_FROM_DATABASE=Bombardier Transportation
+OUI:001105*
+ ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd.
+
+OUI:00110C*
+ ID_OUI_FROM_DATABASE=Atmark Techno, Inc.
+
+OUI:000FF9*
+ ID_OUI_FROM_DATABASE=Valcretec, Inc.
+
+OUI:000FFA*
+ ID_OUI_FROM_DATABASE=Optinel Systems, Inc.
+
+OUI:000FFF*
+ ID_OUI_FROM_DATABASE=Control4
+
+OUI:000FF1*
+ ID_OUI_FROM_DATABASE=nex-G Systems Pte.Ltd
+
+OUI:000FE4*
+ ID_OUI_FROM_DATABASE=Pantech Co.,Ltd
+
+OUI:000FEA*
+ ID_OUI_FROM_DATABASE=Giga-Byte Technology Co.,LTD.
+
+OUI:000FE3*
+ ID_OUI_FROM_DATABASE=Damm Cellular Systems A/S
+
OUI:0011AB*
ID_OUI_FROM_DATABASE=TRUSTABLE TECHNOLOGY CO.,LTD.
OUI:0011B0*
ID_OUI_FROM_DATABASE=Fortelink Inc.
-OUI:00125F*
- ID_OUI_FROM_DATABASE=AWIND Inc.
-
-OUI:001255*
- ID_OUI_FROM_DATABASE=NetEffect Incorporated
-
-OUI:00124E*
- ID_OUI_FROM_DATABASE=XAC AUTOMATION CORP.
+OUI:0011A4*
+ ID_OUI_FROM_DATABASE=JStream Technologies Inc.
-OUI:001247*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+OUI:001198*
+ ID_OUI_FROM_DATABASE=Prism Media Products Limited
-OUI:001248*
- ID_OUI_FROM_DATABASE=EMC Corporation (Kashya)
+OUI:00119D*
+ ID_OUI_FROM_DATABASE=Diginfo Technology Corporation
-OUI:001242*
- ID_OUI_FROM_DATABASE=Millennial Net
+OUI:00119E*
+ ID_OUI_FROM_DATABASE=Solectron Brazil
-OUI:001236*
- ID_OUI_FROM_DATABASE=ConSentry Networks
+OUI:00118E*
+ ID_OUI_FROM_DATABASE=Halytech Mace
-OUI:00123B*
- ID_OUI_FROM_DATABASE=KeRo Systems ApS
+OUI:001193*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:00122F*
- ID_OUI_FROM_DATABASE=Sanei Electric Inc.
+OUI:001152*
+ ID_OUI_FROM_DATABASE=Eidsvoll Electronics AS
OUI:00114F*
ID_OUI_FROM_DATABASE=US Digital Television, Inc
@@ -39956,23 +41045,20 @@ OUI:001136*
OUI:00112C*
ID_OUI_FROM_DATABASE=IZT GmbH
-OUI:000F77*
- ID_OUI_FROM_DATABASE=DENTUM CO.,LTD
-
-OUI:000F71*
- ID_OUI_FROM_DATABASE=Sanmei Electronics Co.,Ltd
+OUI:001130*
+ ID_OUI_FROM_DATABASE=Allied Telesis (Hong Kong) Ltd.
-OUI:000F78*
- ID_OUI_FROM_DATABASE=Datacap Systems Inc
+OUI:00111E*
+ ID_OUI_FROM_DATABASE=EPSG (Ethernet Powerlink Standardization Group)
-OUI:000F6A*
- ID_OUI_FROM_DATABASE=Nortel Networks
+OUI:00111F*
+ ID_OUI_FROM_DATABASE=Doremi Labs, Inc.
-OUI:000F65*
- ID_OUI_FROM_DATABASE=icube Corp.
+OUI:001112*
+ ID_OUI_FROM_DATABASE=Honeywell CMSS
-OUI:000F5E*
- ID_OUI_FROM_DATABASE=Veo
+OUI:001118*
+ ID_OUI_FROM_DATABASE=BLX IC Design Corp., Ltd.
OUI:000F58*
ID_OUI_FROM_DATABASE=Adder Technology Limited
@@ -40010,6 +41096,9 @@ OUI:000F32*
OUI:000F2B*
ID_OUI_FROM_DATABASE=GREENBELL SYSTEMS
+OUI:000E98*
+ ID_OUI_FROM_DATABASE=HME Clear-Com LTD.
+
OUI:000E93*
ID_OUI_FROM_DATABASE=Milénio 3 Sistemas Electrónicos, Lda.
@@ -40031,36 +41120,6 @@ OUI:000E74*
OUI:000E79*
ID_OUI_FROM_DATABASE=Ample Communications Inc.
-OUI:000E71*
- ID_OUI_FROM_DATABASE=Gemstar Technology Development Ltd.
-
-OUI:000E6C*
- ID_OUI_FROM_DATABASE=Device Drivers Limited
-
-OUI:000EB8*
- ID_OUI_FROM_DATABASE=Iiga co.,Ltd
-
-OUI:000EB7*
- ID_OUI_FROM_DATABASE=Knovative, Inc.
-
-OUI:000EBE*
- ID_OUI_FROM_DATABASE=B&B Electronics Manufacturing Co.
-
-OUI:000EB2*
- ID_OUI_FROM_DATABASE=Micro-Research Finland Oy
-
-OUI:000EAB*
- ID_OUI_FROM_DATABASE=Cray Inc
-
-OUI:000EA5*
- ID_OUI_FROM_DATABASE=BLIP Systems
-
-OUI:000E9F*
- ID_OUI_FROM_DATABASE=TEMIC SDS GmbH
-
-OUI:000E98*
- ID_OUI_FROM_DATABASE=HME Clear-Com LTD.
-
OUI:000F24*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -40085,62 +41144,32 @@ OUI:000F00*
OUI:000F05*
ID_OUI_FROM_DATABASE=3B SYSTEM INC.
-OUI:000EF9*
- ID_OUI_FROM_DATABASE=REA Elektronik GmbH
-
-OUI:000FAC*
- ID_OUI_FROM_DATABASE=IEEE 802.11
-
-OUI:000F9C*
- ID_OUI_FROM_DATABASE=Panduit Corp
-
-OUI:000FA0*
- ID_OUI_FROM_DATABASE=CANON KOREA BUSINESS SOLUTIONS INC.
-
-OUI:000F97*
- ID_OUI_FROM_DATABASE=Avanex Corporation
-
-OUI:000F8A*
- ID_OUI_FROM_DATABASE=WideView
-
-OUI:000F89*
- ID_OUI_FROM_DATABASE=Winnertec System Co., Ltd.
-
-OUI:000F90*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
OUI:000F7D*
ID_OUI_FROM_DATABASE=Xirrus
OUI:000F84*
ID_OUI_FROM_DATABASE=Astute Networks, Inc.
-OUI:000FD1*
- ID_OUI_FROM_DATABASE=Applied Wireless Identifications Group, Inc.
-
-OUI:000FD2*
- ID_OUI_FROM_DATABASE=EWA Technologies, Inc.
-
-OUI:000FC4*
- ID_OUI_FROM_DATABASE=NST co.,LTD.
+OUI:000F77*
+ ID_OUI_FROM_DATABASE=DENTUM CO.,LTD
-OUI:000FCB*
- ID_OUI_FROM_DATABASE=3Com Ltd
+OUI:000F71*
+ ID_OUI_FROM_DATABASE=Sanmei Electronics Co.,Ltd
-OUI:000FBF*
- ID_OUI_FROM_DATABASE=DGT Sp. z o.o.
+OUI:000F78*
+ ID_OUI_FROM_DATABASE=Datacap Systems Inc
-OUI:000FB8*
- ID_OUI_FROM_DATABASE=CallURL Inc.
+OUI:000F65*
+ ID_OUI_FROM_DATABASE=icube Corp.
-OUI:000FB2*
- ID_OUI_FROM_DATABASE=Broadband Pacenet (India) Pvt. Ltd.
+OUI:000F5E*
+ ID_OUI_FROM_DATABASE=Veo
-OUI:000FA5*
- ID_OUI_FROM_DATABASE=BWA Technology GmbH
+OUI:000E71*
+ ID_OUI_FROM_DATABASE=Gemstar Technology Development Ltd.
-OUI:000FB1*
- ID_OUI_FROM_DATABASE=Cognio Inc.
+OUI:000E6C*
+ ID_OUI_FROM_DATABASE=Device Drivers Limited
OUI:000E65*
ID_OUI_FROM_DATABASE=TransCore
@@ -40160,12 +41189,63 @@ OUI:000E46*
OUI:000E4D*
ID_OUI_FROM_DATABASE=Numesa Inc.
-OUI:000E40*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000E3F*
ID_OUI_FROM_DATABASE=Soronti, Inc.
+OUI:000EC5*
+ ID_OUI_FROM_DATABASE=Digital Multitools Inc
+
+OUI:000EB8*
+ ID_OUI_FROM_DATABASE=Iiga co.,Ltd
+
+OUI:000EB7*
+ ID_OUI_FROM_DATABASE=Knovative, Inc.
+
+OUI:000EBE*
+ ID_OUI_FROM_DATABASE=B&B Electronics Manufacturing Co.
+
+OUI:000EB2*
+ ID_OUI_FROM_DATABASE=Micro-Research Finland Oy
+
+OUI:000EAB*
+ ID_OUI_FROM_DATABASE=Cray Inc
+
+OUI:000EA5*
+ ID_OUI_FROM_DATABASE=BLIP Systems
+
+OUI:000E9F*
+ ID_OUI_FROM_DATABASE=TEMIC SDS GmbH
+
+OUI:000E0A*
+ ID_OUI_FROM_DATABASE=SAKUMA DESIGN OFFICE
+
+OUI:000E12*
+ ID_OUI_FROM_DATABASE=Adaptive Micro Systems Inc.
+
+OUI:000E04*
+ ID_OUI_FROM_DATABASE=CMA/Microdialysis AB
+
+OUI:000DF7*
+ ID_OUI_FROM_DATABASE=Space Dynamics Lab
+
+OUI:000DFE*
+ ID_OUI_FROM_DATABASE=Hauppauge Computer Works, Inc.
+
+OUI:000DF1*
+ ID_OUI_FROM_DATABASE=IONIX INC.
+
+OUI:000DEB*
+ ID_OUI_FROM_DATABASE=CompXs Limited
+
+OUI:000DF2*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:000DE4*
+ ID_OUI_FROM_DATABASE=DIGINICS, Inc.
+
+OUI:000EF9*
+ ID_OUI_FROM_DATABASE=REA Elektronik GmbH
+
OUI:000EF2*
ID_OUI_FROM_DATABASE=Infinico Corporation
@@ -40190,35 +41270,62 @@ OUI:000EDA*
OUI:000ED6*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000EC5*
- ID_OUI_FROM_DATABASE=Digital Multitools Inc
+OUI:000E37*
+ ID_OUI_FROM_DATABASE=Harms & Wende GmbH & Co.KG
-OUI:000DB2*
- ID_OUI_FROM_DATABASE=Ammasso, Inc.
+OUI:000E38*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000DAD*
- ID_OUI_FROM_DATABASE=Dataprobe, Inc.
+OUI:000E31*
+ ID_OUI_FROM_DATABASE=Olympus Soft Imaging Solutions GmbH
-OUI:000D9E*
- ID_OUI_FROM_DATABASE=TOKUDEN OHIZUMI SEISAKUSYO Co.,Ltd.
+OUI:000E2A*
+ ID_OUI_FROM_DATABASE=Private
-OUI:000DA5*
- ID_OUI_FROM_DATABASE=Fabric7 Systems, Inc
+OUI:000E25*
+ ID_OUI_FROM_DATABASE=Hannae Technology Co., Ltd
-OUI:000D99*
- ID_OUI_FROM_DATABASE=Orbital Sciences Corp.; Launch Systems Group
+OUI:000E18*
+ ID_OUI_FROM_DATABASE=MyA Technology
-OUI:000D8C*
- ID_OUI_FROM_DATABASE=Shanghai Wedone Digital Ltd. CO.
+OUI:000E17*
+ ID_OUI_FROM_DATABASE=Private
-OUI:000D8B*
- ID_OUI_FROM_DATABASE=T&D Corporation
+OUI:000E0E*
+ ID_OUI_FROM_DATABASE=ESA elettronica S.P.A.
-OUI:000D85*
- ID_OUI_FROM_DATABASE=Tapwave, Inc.
+OUI:000C7E*
+ ID_OUI_FROM_DATABASE=Tellium Incorporated
-OUI:000D86*
- ID_OUI_FROM_DATABASE=Huber + Suhner AG
+OUI:000C86*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:000C81*
+ ID_OUI_FROM_DATABASE=Schneider Electric (Australia)
+
+OUI:000C72*
+ ID_OUI_FROM_DATABASE=Tempearl Industrial Co., Ltd.
+
+OUI:000C79*
+ ID_OUI_FROM_DATABASE=Extel Communications P/L
+
+OUI:000C66*
+ ID_OUI_FROM_DATABASE=Pronto Networks Inc
+
+OUI:000C6B*
+ ID_OUI_FROM_DATABASE=Kurz Industrie-Elektronik GmbH
+
+OUI:000C6D*
+ ID_OUI_FROM_DATABASE=Edwards Ltd.
+
+OUI:000DDF*
+ ID_OUI_FROM_DATABASE=Japan Image & Network Inc.
+
+OUI:000DD2*
+ ID_OUI_FROM_DATABASE=Simrad Optronics ASA
+
+OUI:000DD1*
+ ID_OUI_FROM_DATABASE=Stryker Corporation
OUI:000DD8*
ID_OUI_FROM_DATABASE=BBN
@@ -40238,56 +41345,80 @@ OUI:000DC5*
OUI:000DB9*
ID_OUI_FROM_DATABASE=PC Engines GmbH
-OUI:000D4C*
- ID_OUI_FROM_DATABASE=Outline Electronics Ltd.
+OUI:000D8C*
+ ID_OUI_FROM_DATABASE=Shanghai Wedone Digital Ltd. CO.
-OUI:000D53*
- ID_OUI_FROM_DATABASE=Beijing 5w Communication Corp.
+OUI:000D8B*
+ ID_OUI_FROM_DATABASE=T&D Corporation
-OUI:000D3F*
- ID_OUI_FROM_DATABASE=VTI Instruments Corporation
+OUI:000D85*
+ ID_OUI_FROM_DATABASE=Tapwave, Inc.
-OUI:000D44*
- ID_OUI_FROM_DATABASE=Audio BU - Logitech
+OUI:000D86*
+ ID_OUI_FROM_DATABASE=Huber + Suhner AG
-OUI:000D38*
- ID_OUI_FROM_DATABASE=NISSIN INC.
+OUI:000D7E*
+ ID_OUI_FROM_DATABASE=Axiowave Networks, Inc.
-OUI:000D32*
- ID_OUI_FROM_DATABASE=DispenseSource, Inc.
+OUI:000D78*
+ ID_OUI_FROM_DATABASE=Engineering & Security
-OUI:000D31*
- ID_OUI_FROM_DATABASE=Compellent Technologies, Inc.
+OUI:000D77*
+ ID_OUI_FROM_DATABASE=FalconStor Software
-OUI:000E04*
- ID_OUI_FROM_DATABASE=CMA/Microdialysis AB
+OUI:000D6B*
+ ID_OUI_FROM_DATABASE=Mita-Teknik A/S
-OUI:000DF7*
- ID_OUI_FROM_DATABASE=Space Dynamics Lab
+OUI:000D65*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000DFE*
- ID_OUI_FROM_DATABASE=Hauppauge Computer Works, Inc.
+OUI:000D5F*
+ ID_OUI_FROM_DATABASE=Minds Inc
-OUI:000DF1*
- ID_OUI_FROM_DATABASE=IONIX INC.
+OUI:000D66*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000DEB*
- ID_OUI_FROM_DATABASE=CompXs Limited
+OUI:000CB1*
+ ID_OUI_FROM_DATABASE=Salland Engineering (Europe) BV
-OUI:000DF2*
- ID_OUI_FROM_DATABASE=Private
+OUI:000CB7*
+ ID_OUI_FROM_DATABASE=Nanjing Huazhuo Electronics Co., Ltd.
-OUI:000DE4*
- ID_OUI_FROM_DATABASE=DIGINICS, Inc.
+OUI:000CBE*
+ ID_OUI_FROM_DATABASE=Innominate Security Technologies AG
-OUI:000DDF*
- ID_OUI_FROM_DATABASE=Japan Image & Network Inc.
+OUI:000CC3*
+ ID_OUI_FROM_DATABASE=BeWAN systems
-OUI:000DD2*
- ID_OUI_FROM_DATABASE=Simrad Optronics ASA
+OUI:000CB2*
+ ID_OUI_FROM_DATABASE=UNION co., ltd.
-OUI:000DD1*
- ID_OUI_FROM_DATABASE=Stryker Corporation
+OUI:000CA5*
+ ID_OUI_FROM_DATABASE=Naman NZ LTd
+
+OUI:000CAC*
+ ID_OUI_FROM_DATABASE=Citizen Watch Co., Ltd.
+
+OUI:000C94*
+ ID_OUI_FROM_DATABASE=United Electronic Industries, Inc. (EUI)
+
+OUI:000C99*
+ ID_OUI_FROM_DATABASE=HITEL LINK Co.,Ltd
+
+OUI:000CA0*
+ ID_OUI_FROM_DATABASE=StorCase Technology, Inc.
+
+OUI:000C8D*
+ ID_OUI_FROM_DATABASE=MATRIX VISION GmbH
+
+OUI:000C92*
+ ID_OUI_FROM_DATABASE=WolfVision Gmbh
+
+OUI:000D32*
+ ID_OUI_FROM_DATABASE=DispenseSource, Inc.
+
+OUI:000D31*
+ ID_OUI_FROM_DATABASE=Compellent Technologies, Inc.
OUI:000D2C*
ID_OUI_FROM_DATABASE=Patapsco Designs Ltd
@@ -40310,11 +41441,38 @@ OUI:000D0D*
OUI:000D12*
ID_OUI_FROM_DATABASE=AXELL Corporation
-OUI:000D00*
- ID_OUI_FROM_DATABASE=Seaway Networks Inc.
+OUI:000DB2*
+ ID_OUI_FROM_DATABASE=Ammasso, Inc.
-OUI:000D06*
- ID_OUI_FROM_DATABASE=Compulogic Limited
+OUI:000DAD*
+ ID_OUI_FROM_DATABASE=Dataprobe, Inc.
+
+OUI:000D9E*
+ ID_OUI_FROM_DATABASE=TOKUDEN OHIZUMI SEISAKUSYO Co.,Ltd.
+
+OUI:000DA5*
+ ID_OUI_FROM_DATABASE=Fabric7 Systems, Inc
+
+OUI:000D99*
+ ID_OUI_FROM_DATABASE=Orbital Sciences Corp.; Launch Systems Group
+
+OUI:000D58*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:000D4C*
+ ID_OUI_FROM_DATABASE=Outline Electronics Ltd.
+
+OUI:000D53*
+ ID_OUI_FROM_DATABASE=Beijing 5w Communication Corp.
+
+OUI:000D3F*
+ ID_OUI_FROM_DATABASE=VTI Instruments Corporation
+
+OUI:000D44*
+ ID_OUI_FROM_DATABASE=Audio BU - Logitech
+
+OUI:000D38*
+ ID_OUI_FROM_DATABASE=NISSIN INC.
OUI:000CD1*
ID_OUI_FROM_DATABASE=SFOM Technology Corp.
@@ -40331,86 +41489,98 @@ OUI:000CCA*
OUI:000CC4*
ID_OUI_FROM_DATABASE=Tiptel AG
-OUI:000CB1*
- ID_OUI_FROM_DATABASE=Salland Engineering (Europe) BV
+OUI:000D00*
+ ID_OUI_FROM_DATABASE=Seaway Networks Inc.
-OUI:000E37*
- ID_OUI_FROM_DATABASE=Harms & Wende GmbH & Co.KG
+OUI:000D06*
+ ID_OUI_FROM_DATABASE=Compulogic Limited
-OUI:000E38*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:000CFA*
+ ID_OUI_FROM_DATABASE=Digital Systems Corp
-OUI:000E31*
- ID_OUI_FROM_DATABASE=Olympus Soft Imaging Solutions GmbH
+OUI:000CFF*
+ ID_OUI_FROM_DATABASE=MRO-TEK LIMITED
-OUI:000E2A*
- ID_OUI_FROM_DATABASE=Private
+OUI:000CED*
+ ID_OUI_FROM_DATABASE=Real Digital Media
-OUI:000E1E*
- ID_OUI_FROM_DATABASE=QLogic Corporation
+OUI:000CEE*
+ ID_OUI_FROM_DATABASE=jp-embedded
-OUI:000E25*
- ID_OUI_FROM_DATABASE=Hannae Technology Co., Ltd
+OUI:000CF3*
+ ID_OUI_FROM_DATABASE=CALL IMAGE SA
-OUI:000E18*
- ID_OUI_FROM_DATABASE=MyA Technology
+OUI:000CE7*
+ ID_OUI_FROM_DATABASE=MediaTek Inc.
-OUI:000E17*
- ID_OUI_FROM_DATABASE=Private
+OUI:000CE3*
+ ID_OUI_FROM_DATABASE=Option International N.V.
-OUI:000E0E*
- ID_OUI_FROM_DATABASE=ESA elettronica S.P.A.
+OUI:000B01*
+ ID_OUI_FROM_DATABASE=DAIICHI ELECTRONICS CO., LTD.
-OUI:000E0A*
- ID_OUI_FROM_DATABASE=SAKUMA DESIGN OFFICE
+OUI:000AF0*
+ ID_OUI_FROM_DATABASE=SHIN-OH ELECTRONICS CO., LTD. R&D
-OUI:000E12*
- ID_OUI_FROM_DATABASE=Adaptive Micro Systems Inc.
+OUI:000AF5*
+ ID_OUI_FROM_DATABASE=Airgo Networks, Inc.
-OUI:000D7E*
- ID_OUI_FROM_DATABASE=Axiowave Networks, Inc.
+OUI:000AEC*
+ ID_OUI_FROM_DATABASE=Koatsu Gas Kogyo Co., Ltd.
-OUI:000D78*
- ID_OUI_FROM_DATABASE=Engineering & Security
+OUI:000AE5*
+ ID_OUI_FROM_DATABASE=ScottCare Corporation
-OUI:000D77*
- ID_OUI_FROM_DATABASE=FalconStor Software
+OUI:000AE7*
+ ID_OUI_FROM_DATABASE=ELIOP S.A.
-OUI:000D6B*
- ID_OUI_FROM_DATABASE=Mita-Teknik A/S
+OUI:000AE0*
+ ID_OUI_FROM_DATABASE=Fujitsu Softek
-OUI:000D65*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:000AC8*
+ ID_OUI_FROM_DATABASE=ZPSYS CO.,LTD. (Planning&Management)
-OUI:000D5F*
- ID_OUI_FROM_DATABASE=Minds Inc
+OUI:000ACD*
+ ID_OUI_FROM_DATABASE=Sunrich Technology Limited
-OUI:000D66*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:000AD4*
+ ID_OUI_FROM_DATABASE=CoreBell Systems Inc.
-OUI:000D58*
- ID_OUI_FROM_DATABASE=Private
+OUI:000B5E*
+ ID_OUI_FROM_DATABASE=Audio Engineering Society Inc.
-OUI:000CFA*
- ID_OUI_FROM_DATABASE=Digital Systems Corp
+OUI:000B63*
+ ID_OUI_FROM_DATABASE=Kaleidescape
-OUI:000CFF*
- ID_OUI_FROM_DATABASE=MRO-TEK LIMITED
+OUI:000B55*
+ ID_OUI_FROM_DATABASE=ADInstruments
-OUI:000CED*
- ID_OUI_FROM_DATABASE=Real Digital Media
+OUI:000B5A*
+ ID_OUI_FROM_DATABASE=HyperEdge
-OUI:000CEE*
- ID_OUI_FROM_DATABASE=jp-embedded
+OUI:000B52*
+ ID_OUI_FROM_DATABASE=JOYMAX ELECTRONICS CO. LTD.
-OUI:000CF3*
- ID_OUI_FROM_DATABASE=CALL IMAGE SA
+OUI:000B4D*
+ ID_OUI_FROM_DATABASE=Emuzed
-OUI:000CE7*
- ID_OUI_FROM_DATABASE=MediaTek Inc.
+OUI:000B41*
+ ID_OUI_FROM_DATABASE=Ing. Büro Dr. Beutlhauser
-OUI:000CE3*
- ID_OUI_FROM_DATABASE=Option International N.V.
+OUI:000B46*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:000B33*
+ ID_OUI_FROM_DATABASE=Vivato Technologies
+
+OUI:000B3A*
+ ID_OUI_FROM_DATABASE=QuStream Corporation
+
+OUI:000B3F*
+ ID_OUI_FROM_DATABASE=Anthology Solutions Inc.
+
+OUI:000B95*
+ ID_OUI_FROM_DATABASE=eBet Gaming Systems Pty Ltd
OUI:000B8F*
ID_OUI_FROM_DATABASE=AKITA ELECTRONICS SYSTEMS CO.,LTD.
@@ -40436,35 +41606,35 @@ OUI:000B6F*
OUI:000B76*
ID_OUI_FROM_DATABASE=ET&T Technology Co. Ltd.
-OUI:000B5E*
- ID_OUI_FROM_DATABASE=Audio Engineering Society Inc.
+OUI:000AC1*
+ ID_OUI_FROM_DATABASE=Futuretel
-OUI:000B63*
- ID_OUI_FROM_DATABASE=Kaleidescape
+OUI:000AC6*
+ ID_OUI_FROM_DATABASE=Overture Networks.
-OUI:000C7E*
- ID_OUI_FROM_DATABASE=Tellium Incorporated
+OUI:000AAE*
+ ID_OUI_FROM_DATABASE=Rosemount Process Analytical
-OUI:000C86*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:000AB3*
+ ID_OUI_FROM_DATABASE=Fa. GIRA
-OUI:000C81*
- ID_OUI_FROM_DATABASE=Schneider Electric (Australia)
+OUI:000AB5*
+ ID_OUI_FROM_DATABASE=Digital Electronic Network
-OUI:000C72*
- ID_OUI_FROM_DATABASE=Tempearl Industrial Co., Ltd.
+OUI:000ABA*
+ ID_OUI_FROM_DATABASE=Arcon Technology Limited
-OUI:000C79*
- ID_OUI_FROM_DATABASE=Extel Communications P/L
+OUI:000AA2*
+ ID_OUI_FROM_DATABASE=SYSTEK INC.
-OUI:000C66*
- ID_OUI_FROM_DATABASE=Pronto Networks Inc
+OUI:000AA7*
+ ID_OUI_FROM_DATABASE=FEI Electron Optics
-OUI:000C6B*
- ID_OUI_FROM_DATABASE=Kurz Industrie-Elektronik GmbH
+OUI:000A8F*
+ ID_OUI_FROM_DATABASE=Aska International Inc.
-OUI:000C6D*
- ID_OUI_FROM_DATABASE=Edwards Ltd.
+OUI:000A94*
+ ID_OUI_FROM_DATABASE=ShangHai cellink CO., LTD
OUI:000C4E*
ID_OUI_FROM_DATABASE=Winbest Technology CO,LT
@@ -40496,66 +41666,6 @@ OUI:000C2D*
OUI:000C1A*
ID_OUI_FROM_DATABASE=Quest Technical Solutions Inc.
-OUI:000B2E*
- ID_OUI_FROM_DATABASE=Cal-Comp Electronics (Thailand) Public Company Limited Taipe
-
-OUI:000B1B*
- ID_OUI_FROM_DATABASE=Systronix, Inc.
-
-OUI:000B20*
- ID_OUI_FROM_DATABASE=Hirata corporation
-
-OUI:000B22*
- ID_OUI_FROM_DATABASE=Environmental Systems and Services
-
-OUI:000B14*
- ID_OUI_FROM_DATABASE=ViewSonic Corporation
-
-OUI:000B0D*
- ID_OUI_FROM_DATABASE=Air2U, Inc.
-
-OUI:000B0F*
- ID_OUI_FROM_DATABASE=Bosch Rexroth
-
-OUI:000B08*
- ID_OUI_FROM_DATABASE=Pillar Data Systems
-
-OUI:000AFC*
- ID_OUI_FROM_DATABASE=Core Tec Communications, LLC
-
-OUI:000B01*
- ID_OUI_FROM_DATABASE=DAIICHI ELECTRONICS CO., LTD.
-
-OUI:000B55*
- ID_OUI_FROM_DATABASE=ADInstruments
-
-OUI:000B5A*
- ID_OUI_FROM_DATABASE=HyperEdge
-
-OUI:000B52*
- ID_OUI_FROM_DATABASE=JOYMAX ELECTRONICS CO. LTD.
-
-OUI:000B4D*
- ID_OUI_FROM_DATABASE=Emuzed
-
-OUI:000B41*
- ID_OUI_FROM_DATABASE=Ing. Büro Dr. Beutlhauser
-
-OUI:000B46*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:000B33*
- ID_OUI_FROM_DATABASE=Vivato Technologies
-
-OUI:000B3A*
- ID_OUI_FROM_DATABASE=QuStream Corporation
-
-OUI:000B3F*
- ID_OUI_FROM_DATABASE=Anthology Solutions Inc.
-
-OUI:000B27*
- ID_OUI_FROM_DATABASE=Scion Corporation
-
OUI:000C1E*
ID_OUI_FROM_DATABASE=Global Cache
@@ -40571,14 +41681,8 @@ OUI:000C15*
OUI:000C09*
ID_OUI_FROM_DATABASE=Hitachi IE Systems Co., Ltd
-OUI:000BF6*
- ID_OUI_FROM_DATABASE=Nitgen Co., Ltd
-
-OUI:000BFB*
- ID_OUI_FROM_DATABASE=D-NET International Corporation
-
-OUI:000C02*
- ID_OUI_FROM_DATABASE=ABB Oy
+OUI:000BD3*
+ ID_OUI_FROM_DATABASE=cd3o
OUI:000BC7*
ID_OUI_FROM_DATABASE=ICET S.p.A.
@@ -40610,41 +41714,44 @@ OUI:000BAA*
OUI:000B9E*
ID_OUI_FROM_DATABASE=Yasing Technology Corp.
-OUI:000B95*
- ID_OUI_FROM_DATABASE=eBet Gaming Systems Pty Ltd
+OUI:000B27*
+ ID_OUI_FROM_DATABASE=Scion Corporation
-OUI:000CB7*
- ID_OUI_FROM_DATABASE=Nanjing Huazhuo Electronics Co., Ltd.
+OUI:000B2E*
+ ID_OUI_FROM_DATABASE=Cal-Comp Electronics (Thailand) Public Company Limited Taipe
-OUI:000CBE*
- ID_OUI_FROM_DATABASE=Innominate Security Technologies AG
+OUI:000B1B*
+ ID_OUI_FROM_DATABASE=Systronix, Inc.
-OUI:000CC3*
- ID_OUI_FROM_DATABASE=BeWAN systems
+OUI:000B20*
+ ID_OUI_FROM_DATABASE=Hirata corporation
-OUI:000CB2*
- ID_OUI_FROM_DATABASE=UNION co., ltd.
+OUI:000B22*
+ ID_OUI_FROM_DATABASE=Environmental Systems and Services
-OUI:000CA5*
- ID_OUI_FROM_DATABASE=Naman NZ LTd
+OUI:000B14*
+ ID_OUI_FROM_DATABASE=ViewSonic Corporation
-OUI:000CAC*
- ID_OUI_FROM_DATABASE=Citizen Watch Co., Ltd.
+OUI:000B0D*
+ ID_OUI_FROM_DATABASE=Air2U, Inc.
-OUI:000C94*
- ID_OUI_FROM_DATABASE=United Electronic Industries, Inc. (EUI)
+OUI:000B0F*
+ ID_OUI_FROM_DATABASE=Bosch Rexroth
-OUI:000C99*
- ID_OUI_FROM_DATABASE=HITEL LINK Co.,Ltd
+OUI:000B08*
+ ID_OUI_FROM_DATABASE=Pillar Data Systems
-OUI:000CA0*
- ID_OUI_FROM_DATABASE=StorCase Technology, Inc.
+OUI:000AFC*
+ ID_OUI_FROM_DATABASE=Core Tec Communications, LLC
-OUI:000C8D*
- ID_OUI_FROM_DATABASE=MATRIX VISION GmbH
+OUI:000BF6*
+ ID_OUI_FROM_DATABASE=Nitgen Co., Ltd
-OUI:000C92*
- ID_OUI_FROM_DATABASE=WolfVision Gmbh
+OUI:000BFB*
+ ID_OUI_FROM_DATABASE=D-NET International Corporation
+
+OUI:000C02*
+ ID_OUI_FROM_DATABASE=ABB Oy
OUI:000BEA*
ID_OUI_FROM_DATABASE=Zultys Technologies
@@ -40667,42 +41774,6 @@ OUI:000BD7*
OUI:000BDC*
ID_OUI_FROM_DATABASE=AKCP
-OUI:000BD3*
- ID_OUI_FROM_DATABASE=cd3o
-
-OUI:000AF0*
- ID_OUI_FROM_DATABASE=SHIN-OH ELECTRONICS CO., LTD. R&D
-
-OUI:000AF5*
- ID_OUI_FROM_DATABASE=Airgo Networks, Inc.
-
-OUI:000AEC*
- ID_OUI_FROM_DATABASE=Koatsu Gas Kogyo Co., Ltd.
-
-OUI:000AE5*
- ID_OUI_FROM_DATABASE=ScottCare Corporation
-
-OUI:000AE7*
- ID_OUI_FROM_DATABASE=ELIOP S.A.
-
-OUI:000AE0*
- ID_OUI_FROM_DATABASE=Fujitsu Softek
-
-OUI:000AC8*
- ID_OUI_FROM_DATABASE=ZPSYS CO.,LTD. (Planning&Management)
-
-OUI:000ACD*
- ID_OUI_FROM_DATABASE=Sunrich Technology Limited
-
-OUI:000AD4*
- ID_OUI_FROM_DATABASE=CoreBell Systems Inc.
-
-OUI:000AC1*
- ID_OUI_FROM_DATABASE=Futuretel
-
-OUI:000AC6*
- ID_OUI_FROM_DATABASE=Overture Networks.
-
OUI:000994*
ID_OUI_FROM_DATABASE=Cronyx Engineering
@@ -40733,35 +41804,11 @@ OUI:000968*
OUI:000962*
ID_OUI_FROM_DATABASE=Sonitor Technologies AS
-OUI:000967*
- ID_OUI_FROM_DATABASE=Tachyon, Inc
-
-OUI:00096E*
- ID_OUI_FROM_DATABASE=GIANT ELECTRONICS LTD.
-
-OUI:0009C3*
- ID_OUI_FROM_DATABASE=NETAS
-
-OUI:0009B9*
- ID_OUI_FROM_DATABASE=Action Imaging Solutions
-
-OUI:0009BA*
- ID_OUI_FROM_DATABASE=MAKU Informationstechik GmbH
-
-OUI:0009AC*
- ID_OUI_FROM_DATABASE=LANVOICE
-
-OUI:0009B3*
- ID_OUI_FROM_DATABASE=MCM Systems Ltd
-
-OUI:0009A7*
- ID_OUI_FROM_DATABASE=Bang & Olufsen A/S
-
-OUI:00099A*
- ID_OUI_FROM_DATABASE=ELMO COMPANY, LIMITED
+OUI:000A9B*
+ ID_OUI_FROM_DATABASE=TB Group Inc
-OUI:0009A0*
- ID_OUI_FROM_DATABASE=Microtechno Corporation
+OUI:000A9A*
+ ID_OUI_FROM_DATABASE=Aiptek International Inc
OUI:000A80*
ID_OUI_FROM_DATABASE=Telkonet Inc.
@@ -40787,11 +41834,35 @@ OUI:000A74*
OUI:000A61*
ID_OUI_FROM_DATABASE=Cellinx Systems Inc.
-OUI:000A68*
- ID_OUI_FROM_DATABASE=SolarFlare Communications, Inc.
+OUI:0009C3*
+ ID_OUI_FROM_DATABASE=NETAS
-OUI:000A5C*
- ID_OUI_FROM_DATABASE=Carel s.p.a.
+OUI:0009B9*
+ ID_OUI_FROM_DATABASE=Action Imaging Solutions
+
+OUI:0009BA*
+ ID_OUI_FROM_DATABASE=MAKU Informationstechik GmbH
+
+OUI:0009AC*
+ ID_OUI_FROM_DATABASE=LANVOICE
+
+OUI:0009B3*
+ ID_OUI_FROM_DATABASE=MCM Systems Ltd
+
+OUI:0009A7*
+ ID_OUI_FROM_DATABASE=Bang & Olufsen A/S
+
+OUI:00099A*
+ ID_OUI_FROM_DATABASE=ELMO COMPANY, LIMITED
+
+OUI:0009A0*
+ ID_OUI_FROM_DATABASE=Microtechno Corporation
+
+OUI:0009ED*
+ ID_OUI_FROM_DATABASE=CipherOptics
+
+OUI:0009F2*
+ ID_OUI_FROM_DATABASE=Cohu, Inc., Electronics Division
OUI:0009E6*
ID_OUI_FROM_DATABASE=Cyber Switching Inc.
@@ -40817,35 +41888,74 @@ OUI:0009CE*
OUI:0009D3*
ID_OUI_FROM_DATABASE=Western DataCom Co., Inc.
-OUI:000AAE*
- ID_OUI_FROM_DATABASE=Rosemount Process Analytical
+OUI:000901*
+ ID_OUI_FROM_DATABASE=Shenzhen Shixuntong Information & Technoligy Co
-OUI:000AB3*
- ID_OUI_FROM_DATABASE=Fa. GIRA
+OUI:0008FC*
+ ID_OUI_FROM_DATABASE=Gigaphoton Inc.
-OUI:000AB5*
- ID_OUI_FROM_DATABASE=Digital Electronic Network
+OUI:0008F9*
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
-OUI:000ABA*
- ID_OUI_FROM_DATABASE=Arcon Technology Limited
+OUI:0008F4*
+ ID_OUI_FROM_DATABASE=Bluetake Technology Co., Ltd.
-OUI:000AA2*
- ID_OUI_FROM_DATABASE=SYSTEK INC.
+OUI:0008EB*
+ ID_OUI_FROM_DATABASE=ROMWin Co.,Ltd.
-OUI:000AA7*
- ID_OUI_FROM_DATABASE=FEI Electron Optics
+OUI:0008E4*
+ ID_OUI_FROM_DATABASE=Envenergy Inc
-OUI:000A8F*
- ID_OUI_FROM_DATABASE=Aska International Inc.
+OUI:0008DF*
+ ID_OUI_FROM_DATABASE=Alistel Inc.
-OUI:000A94*
- ID_OUI_FROM_DATABASE=ShangHai cellink CO., LTD
+OUI:0008D8*
+ ID_OUI_FROM_DATABASE=Dowkey Microwave
-OUI:000A9B*
- ID_OUI_FROM_DATABASE=TB Group Inc
+OUI:0008D2*
+ ID_OUI_FROM_DATABASE=ZOOM Networks Inc.
-OUI:000A9A*
- ID_OUI_FROM_DATABASE=Aiptek International Inc
+OUI:0008CC*
+ ID_OUI_FROM_DATABASE=Remotec, Inc.
+
+OUI:0008D1*
+ ID_OUI_FROM_DATABASE=KAREL INC.
+
+OUI:000967*
+ ID_OUI_FROM_DATABASE=Tachyon, Inc
+
+OUI:00096E*
+ ID_OUI_FROM_DATABASE=GIANT ELECTRONICS LTD.
+
+OUI:00095E*
+ ID_OUI_FROM_DATABASE=Masstech Group Inc.
+
+OUI:000959*
+ ID_OUI_FROM_DATABASE=Sitecsoft
+
+OUI:00094D*
+ ID_OUI_FROM_DATABASE=Braintree Communications Pty Ltd
+
+OUI:000952*
+ ID_OUI_FROM_DATABASE=Auerswald GmbH & Co. KG
+
+OUI:000946*
+ ID_OUI_FROM_DATABASE=Cluster Labs GmbH
+
+OUI:000940*
+ ID_OUI_FROM_DATABASE=AGFEO GmbH & Co. KG
+
+OUI:00093F*
+ ID_OUI_FROM_DATABASE=Double-Win Enterpirse CO., LTD
+
+OUI:00093A*
+ ID_OUI_FROM_DATABASE=Molex Fiber Optics
+
+OUI:000933*
+ ID_OUI_FROM_DATABASE=Ophit Co.Ltd.
+
+OUI:000A5C*
+ ID_OUI_FROM_DATABASE=Carel s.p.a.
OUI:000A50*
ID_OUI_FROM_DATABASE=REMOTEK CORPORATION
@@ -40874,6 +41984,30 @@ OUI:000A3D*
OUI:000A2F*
ID_OUI_FROM_DATABASE=Artnix Inc.
+OUI:000927*
+ ID_OUI_FROM_DATABASE=TOYOKEIKI CO.,LTD.
+
+OUI:00092E*
+ ID_OUI_FROM_DATABASE=B&Tech System Inc.
+
+OUI:000920*
+ ID_OUI_FROM_DATABASE=EpoX COMPUTER CO.,LTD.
+
+OUI:00091B*
+ ID_OUI_FROM_DATABASE=Digital Generation Inc.
+
+OUI:000914*
+ ID_OUI_FROM_DATABASE=COMPUTROLS INC.
+
+OUI:00090E*
+ ID_OUI_FROM_DATABASE=Helix Technology Inc.
+
+OUI:000908*
+ ID_OUI_FROM_DATABASE=VTech Technology Corp.
+
+OUI:00090D*
+ ID_OUI_FROM_DATABASE=LEADER ELECTRONICS CORP.
+
OUI:000A20*
ID_OUI_FROM_DATABASE=SVA Networks, Inc.
@@ -40901,75 +42035,6 @@ OUI:0009FC*
OUI:000A03*
ID_OUI_FROM_DATABASE=ENDESA SERVICIOS, S.L.
-OUI:0009ED*
- ID_OUI_FROM_DATABASE=CipherOptics
-
-OUI:0009F2*
- ID_OUI_FROM_DATABASE=Cohu, Inc., Electronics Division
-
-OUI:00095E*
- ID_OUI_FROM_DATABASE=Masstech Group Inc.
-
-OUI:000959*
- ID_OUI_FROM_DATABASE=Sitecsoft
-
-OUI:00094D*
- ID_OUI_FROM_DATABASE=Braintree Communications Pty Ltd
-
-OUI:000952*
- ID_OUI_FROM_DATABASE=Auerswald GmbH & Co. KG
-
-OUI:000946*
- ID_OUI_FROM_DATABASE=Cluster Labs GmbH
-
-OUI:000940*
- ID_OUI_FROM_DATABASE=AGFEO GmbH & Co. KG
-
-OUI:00093F*
- ID_OUI_FROM_DATABASE=Double-Win Enterpirse CO., LTD
-
-OUI:00093A*
- ID_OUI_FROM_DATABASE=Molex Fiber Optics
-
-OUI:000933*
- ID_OUI_FROM_DATABASE=Ophit Co.Ltd.
-
-OUI:00072C*
- ID_OUI_FROM_DATABASE=Fabricom
-
-OUI:000733*
- ID_OUI_FROM_DATABASE=DANCONTROL Engineering
-
-OUI:000732*
- ID_OUI_FROM_DATABASE=AAEON Technology Inc.
-
-OUI:000716*
- ID_OUI_FROM_DATABASE=J & S Marine Ltd.
-
-OUI:00071B*
- ID_OUI_FROM_DATABASE=CDVI Americas Ltd
-
-OUI:000722*
- ID_OUI_FROM_DATABASE=The Nielsen Company
-
-OUI:00071C*
- ID_OUI_FROM_DATABASE=AT&T Fixed Wireless Services
-
-OUI:00070A*
- ID_OUI_FROM_DATABASE=Unicom Automation Co., Ltd.
-
-OUI:00070F*
- ID_OUI_FROM_DATABASE=Fujant, Inc.
-
-OUI:000709*
- ID_OUI_FROM_DATABASE=Westerstrand Urfabrik AB
-
-OUI:000702*
- ID_OUI_FROM_DATABASE=Varian Medical Systems
-
-OUI:0006F3*
- ID_OUI_FROM_DATABASE=AcceLight Networks
-
OUI:0006F4*
ID_OUI_FROM_DATABASE=Prime Electronics & Satellitics Inc.
@@ -40985,41 +42050,38 @@ OUI:0006FF*
OUI:0006FD*
ID_OUI_FROM_DATABASE=Comjet Information Systems Corp.
-OUI:00082D*
- ID_OUI_FROM_DATABASE=Indus Teqsite Private Limited
-
-OUI:000821*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:0006E7*
+ ID_OUI_FROM_DATABASE=Bit Blitz Communications Inc.
-OUI:000814*
- ID_OUI_FROM_DATABASE=TIL Technologies
+OUI:0006ED*
+ ID_OUI_FROM_DATABASE=Inara Networks
-OUI:00081A*
- ID_OUI_FROM_DATABASE=Sanrad Intelligence Storage Communications (2000) Ltd.
+OUI:0006DC*
+ ID_OUI_FROM_DATABASE=Syabas Technology (Amquest)
-OUI:00080F*
- ID_OUI_FROM_DATABASE=Proximion Fiber Optics AB
+OUI:0006E1*
+ ID_OUI_FROM_DATABASE=Techno Trade s.a
-OUI:000809*
- ID_OUI_FROM_DATABASE=Systemonic AG
+OUI:0006E6*
+ ID_OUI_FROM_DATABASE=DongYang Telecom Co., Ltd.
-OUI:000803*
- ID_OUI_FROM_DATABASE=Cos Tron
+OUI:0006CF*
+ ID_OUI_FROM_DATABASE=Thales Avionics In-Flight Systems, LLC
-OUI:0007FF*
- ID_OUI_FROM_DATABASE=Gluon Networks
+OUI:0006D6*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0007F9*
- ID_OUI_FROM_DATABASE=Sensaphone
+OUI:0006D5*
+ ID_OUI_FROM_DATABASE=Diamond Systems Corp.
-OUI:0007F3*
- ID_OUI_FROM_DATABASE=Thinkengine Networks
+OUI:0006C9*
+ ID_OUI_FROM_DATABASE=Technical Marketing Research, Inc.
-OUI:0007EC*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:0007B1*
+ ID_OUI_FROM_DATABASE=Equator Technologies
-OUI:0007F2*
- ID_OUI_FROM_DATABASE=IOA Corporation
+OUI:0007B8*
+ ID_OUI_FROM_DATABASE=Corvalent Corporation
OUI:0007B2*
ID_OUI_FROM_DATABASE=Transaccess S.A.
@@ -41057,11 +42119,41 @@ OUI:000785*
OUI:00077B*
ID_OUI_FROM_DATABASE=Millimetrix Broadband Networks
-OUI:00077E*
- ID_OUI_FROM_DATABASE=Elrest GmbH
+OUI:000856*
+ ID_OUI_FROM_DATABASE=Gamatronic Electronic Industries Ltd.
-OUI:00076F*
- ID_OUI_FROM_DATABASE=Synoptics Limited
+OUI:00082D*
+ ID_OUI_FROM_DATABASE=Indus Teqsite Private Limited
+
+OUI:000821*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:000814*
+ ID_OUI_FROM_DATABASE=TIL Technologies
+
+OUI:00081A*
+ ID_OUI_FROM_DATABASE=Sanrad Intelligence Storage Communications (2000) Ltd.
+
+OUI:00080F*
+ ID_OUI_FROM_DATABASE=Proximion Fiber Optics AB
+
+OUI:000809*
+ ID_OUI_FROM_DATABASE=Systemonic AG
+
+OUI:000803*
+ ID_OUI_FROM_DATABASE=Cos Tron
+
+OUI:0007FF*
+ ID_OUI_FROM_DATABASE=Gluon Networks
+
+OUI:0007F9*
+ ID_OUI_FROM_DATABASE=Sensaphone
+
+OUI:000894*
+ ID_OUI_FROM_DATABASE=InnoVISION Multimedia Ltd.
+
+OUI:00088F*
+ ID_OUI_FROM_DATABASE=ADVANCED DIGITAL TECHNOLOGY
OUI:000888*
ID_OUI_FROM_DATABASE=OULLIM Information Technology Inc,.
@@ -41096,35 +42188,89 @@ OUI:000862*
OUI:000850*
ID_OUI_FROM_DATABASE=Arizona Instrument Corp.
-OUI:000856*
- ID_OUI_FROM_DATABASE=Gamatronic Electronic Industries Ltd.
+OUI:000738*
+ ID_OUI_FROM_DATABASE=Young Technology Co., Ltd.
-OUI:000927*
- ID_OUI_FROM_DATABASE=TOYOKEIKI CO.,LTD.
+OUI:00073F*
+ ID_OUI_FROM_DATABASE=Woojyun Systec Co., Ltd.
-OUI:00092E*
- ID_OUI_FROM_DATABASE=B&Tech System Inc.
+OUI:00072C*
+ ID_OUI_FROM_DATABASE=Fabricom
-OUI:000920*
- ID_OUI_FROM_DATABASE=EpoX COMPUTER CO.,LTD.
+OUI:000733*
+ ID_OUI_FROM_DATABASE=DANCONTROL Engineering
-OUI:00091B*
- ID_OUI_FROM_DATABASE=Digital Generation Inc.
+OUI:000732*
+ ID_OUI_FROM_DATABASE=AAEON Technology Inc.
-OUI:000914*
- ID_OUI_FROM_DATABASE=COMPUTROLS INC.
+OUI:000716*
+ ID_OUI_FROM_DATABASE=J & S Marine Ltd.
-OUI:00090E*
- ID_OUI_FROM_DATABASE=Helix Technology Inc.
+OUI:00071B*
+ ID_OUI_FROM_DATABASE=CDVI Americas Ltd
-OUI:000908*
- ID_OUI_FROM_DATABASE=VTech Technology Corp.
+OUI:000722*
+ ID_OUI_FROM_DATABASE=The Nielsen Company
-OUI:00090D*
- ID_OUI_FROM_DATABASE=LEADER ELECTRONICS CORP.
+OUI:00071C*
+ ID_OUI_FROM_DATABASE=AT&T Fixed Wireless Services
-OUI:000901*
- ID_OUI_FROM_DATABASE=Shenzhen Shixuntong Information & Technoligy Co
+OUI:00070A*
+ ID_OUI_FROM_DATABASE=Unicom Automation Co., Ltd.
+
+OUI:00070F*
+ ID_OUI_FROM_DATABASE=Fujant, Inc.
+
+OUI:000709*
+ ID_OUI_FROM_DATABASE=Westerstrand Urfabrik AB
+
+OUI:000702*
+ ID_OUI_FROM_DATABASE=Varian Medical Systems
+
+OUI:0006F3*
+ ID_OUI_FROM_DATABASE=AcceLight Networks
+
+OUI:0006C3*
+ ID_OUI_FROM_DATABASE=Schindler Elevator Ltd.
+
+OUI:0006C8*
+ ID_OUI_FROM_DATABASE=Sumitomo Metal Micro Devices, Inc.
+
+OUI:0006BF*
+ ID_OUI_FROM_DATABASE=Accella Technologies Co., Ltd.
+
+OUI:0006B9*
+ ID_OUI_FROM_DATABASE=A5TEK Corp.
+
+OUI:0006B2*
+ ID_OUI_FROM_DATABASE=Linxtek Co.
+
+OUI:0006AC*
+ ID_OUI_FROM_DATABASE=Intersoft Co.
+
+OUI:0006A6*
+ ID_OUI_FROM_DATABASE=Artistic Licence Engineering Ltd
+
+OUI:0006A2*
+ ID_OUI_FROM_DATABASE=Microtune, Inc.
+
+OUI:000695*
+ ID_OUI_FROM_DATABASE=Ensure Technologies, Inc.
+
+OUI:00069C*
+ ID_OUI_FROM_DATABASE=Transmode Systems AB
+
+OUI:000696*
+ ID_OUI_FROM_DATABASE=Advent Networks
+
+OUI:0007F3*
+ ID_OUI_FROM_DATABASE=Thinkengine Networks
+
+OUI:0007EC*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:0007F2*
+ ID_OUI_FROM_DATABASE=IOA Corporation
OUI:0007E6*
ID_OUI_FROM_DATABASE=edgeflow Canada Inc.
@@ -41150,11 +42296,11 @@ OUI:0007C4*
OUI:0007BE*
ID_OUI_FROM_DATABASE=DataLogic SpA
-OUI:0007B1*
- ID_OUI_FROM_DATABASE=Equator Technologies
+OUI:00077E*
+ ID_OUI_FROM_DATABASE=Elrest GmbH
-OUI:0007B8*
- ID_OUI_FROM_DATABASE=Corvalent Corporation
+OUI:00076F*
+ ID_OUI_FROM_DATABASE=Synoptics Limited
OUI:00076E*
ID_OUI_FROM_DATABASE=Sinetica Corporation Limited
@@ -41186,11 +42332,8 @@ OUI:00074B*
OUI:000745*
ID_OUI_FROM_DATABASE=Radlan Computer Communications Ltd.
-OUI:000738*
- ID_OUI_FROM_DATABASE=Young Technology Co., Ltd.
-
-OUI:00073F*
- ID_OUI_FROM_DATABASE=Woojyun Systec Co., Ltd.
+OUI:0008C2*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:0008BB*
ID_OUI_FROM_DATABASE=NetExcell
@@ -41216,44 +42359,8 @@ OUI:0008A3*
OUI:00089C*
ID_OUI_FROM_DATABASE=Elecs Industry Co., Ltd.
-OUI:000894*
- ID_OUI_FROM_DATABASE=InnoVISION Multimedia Ltd.
-
-OUI:00088F*
- ID_OUI_FROM_DATABASE=ADVANCED DIGITAL TECHNOLOGY
-
-OUI:0008FC*
- ID_OUI_FROM_DATABASE=Gigaphoton Inc.
-
-OUI:0008F9*
- ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
-
-OUI:0008F4*
- ID_OUI_FROM_DATABASE=Bluetake Technology Co., Ltd.
-
-OUI:0008EB*
- ID_OUI_FROM_DATABASE=ROMWin Co.,Ltd.
-
-OUI:0008E4*
- ID_OUI_FROM_DATABASE=Envenergy Inc
-
-OUI:0008DF*
- ID_OUI_FROM_DATABASE=Alistel Inc.
-
-OUI:0008D8*
- ID_OUI_FROM_DATABASE=Dowkey Microwave
-
-OUI:0008D2*
- ID_OUI_FROM_DATABASE=ZOOM Networks Inc.
-
-OUI:0008CC*
- ID_OUI_FROM_DATABASE=Remotec, Inc.
-
-OUI:0008D1*
- ID_OUI_FROM_DATABASE=KAREL INC.
-
-OUI:0008C2*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:000690*
+ ID_OUI_FROM_DATABASE=Euracom Communication GmbH
OUI:00068F*
ID_OUI_FROM_DATABASE=Telemonitor, Inc.
@@ -41294,11 +42401,11 @@ OUI:00055A*
OUI:00065C*
ID_OUI_FROM_DATABASE=Malachite Technologies, Inc.
-OUI:000650*
- ID_OUI_FROM_DATABASE=Tiburon Networks, Inc.
+OUI:000610*
+ ID_OUI_FROM_DATABASE=Abeona Networks Inc
-OUI:000656*
- ID_OUI_FROM_DATABASE=Tactel AB
+OUI:000616*
+ ID_OUI_FROM_DATABASE=Tel Net Co., Ltd.
OUI:00060A*
ID_OUI_FROM_DATABASE=Blue2space
@@ -41345,39 +42452,6 @@ OUI:0005CF*
OUI:0005C9*
ID_OUI_FROM_DATABASE=LG Innotek Co., Ltd.
-OUI:0006E7*
- ID_OUI_FROM_DATABASE=Bit Blitz Communications Inc.
-
-OUI:0006ED*
- ID_OUI_FROM_DATABASE=Inara Networks
-
-OUI:0006DC*
- ID_OUI_FROM_DATABASE=Syabas Technology (Amquest)
-
-OUI:0006E1*
- ID_OUI_FROM_DATABASE=Techno Trade s.a
-
-OUI:0006E6*
- ID_OUI_FROM_DATABASE=DongYang Telecom Co., Ltd.
-
-OUI:0006CF*
- ID_OUI_FROM_DATABASE=Thales Avionics In-Flight Systems, LLC
-
-OUI:0006D6*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:0006D5*
- ID_OUI_FROM_DATABASE=Diamond Systems Corp.
-
-OUI:0006C9*
- ID_OUI_FROM_DATABASE=Technical Marketing Research, Inc.
-
-OUI:0006C3*
- ID_OUI_FROM_DATABASE=Schindler Elevator Ltd.
-
-OUI:0006C8*
- ID_OUI_FROM_DATABASE=Sumitomo Metal Micro Devices, Inc.
-
OUI:0005D5*
ID_OUI_FROM_DATABASE=Speedcom Wireless
@@ -41402,17 +42476,47 @@ OUI:0005A2*
OUI:0005AC*
ID_OUI_FROM_DATABASE=Northern Digital, Inc.
-OUI:000589*
- ID_OUI_FROM_DATABASE=National Datacomputer
+OUI:0004E5*
+ ID_OUI_FROM_DATABASE=Glonet Systems, Inc.
-OUI:000595*
- ID_OUI_FROM_DATABASE=Alesis Corporation
+OUI:0004D9*
+ ID_OUI_FROM_DATABASE=Titan Electronics, Inc.
-OUI:00058F*
- ID_OUI_FROM_DATABASE=CLCsoft co.
+OUI:0004D3*
+ ID_OUI_FROM_DATABASE=Toyokeiki Co., Ltd.
-OUI:000596*
- ID_OUI_FROM_DATABASE=Genotech Co., Ltd.
+OUI:0004CC*
+ ID_OUI_FROM_DATABASE=Peek Traffic B.V.
+
+OUI:0004C0*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:0004B9*
+ ID_OUI_FROM_DATABASE=S.I. Soubou, Inc.
+
+OUI:0004BA*
+ ID_OUI_FROM_DATABASE=KDD Media Will Corporation
+
+OUI:0004AF*
+ ID_OUI_FROM_DATABASE=Digital Fountain, Inc.
+
+OUI:0004B4*
+ ID_OUI_FROM_DATABASE=CIAC
+
+OUI:0004B3*
+ ID_OUI_FROM_DATABASE=Videotek, Inc.
+
+OUI:0004A6*
+ ID_OUI_FROM_DATABASE=SAF Tehnika Ltd.
+
+OUI:0004A0*
+ ID_OUI_FROM_DATABASE=Verity Instruments, Inc.
+
+OUI:00050C*
+ ID_OUI_FROM_DATABASE=Network Photonics, Inc.
+
+OUI:000512*
+ ID_OUI_FROM_DATABASE=Zebra Technologies Inc
OUI:000506*
ID_OUI_FROM_DATABASE=Reddo Networks AB
@@ -41438,47 +42542,11 @@ OUI:0004EF*
OUI:0004DF*
ID_OUI_FROM_DATABASE=Teracom Telematica Ltda.
-OUI:0004E5*
- ID_OUI_FROM_DATABASE=Glonet Systems, Inc.
-
-OUI:0004D9*
- ID_OUI_FROM_DATABASE=Titan Electronics, Inc.
-
-OUI:00062D*
- ID_OUI_FROM_DATABASE=TouchStar Technologies, L.L.C.
-
-OUI:000649*
- ID_OUI_FROM_DATABASE=3M Deutschland GmbH
-
-OUI:000643*
- ID_OUI_FROM_DATABASE=SONO Computer Co., Ltd.
-
-OUI:00064A*
- ID_OUI_FROM_DATABASE=Honeywell Co., Ltd. (KOREA)
-
-OUI:00063F*
- ID_OUI_FROM_DATABASE=Everex Communications Inc.
-
-OUI:000639*
- ID_OUI_FROM_DATABASE=Newtec
-
-OUI:000633*
- ID_OUI_FROM_DATABASE=Cross Match Technologies GmbH
-
-OUI:000626*
- ID_OUI_FROM_DATABASE=MWE GmbH
-
-OUI:00061D*
- ID_OUI_FROM_DATABASE=MIP Telecom, Inc.
-
-OUI:000623*
- ID_OUI_FROM_DATABASE=MGE UPS Systems France
-
-OUI:000610*
- ID_OUI_FROM_DATABASE=Abeona Networks Inc
+OUI:000553*
+ ID_OUI_FROM_DATABASE=DVC Company, Inc.
-OUI:000616*
- ID_OUI_FROM_DATABASE=Tel Net Co., Ltd.
+OUI:000548*
+ ID_OUI_FROM_DATABASE=Disco Corporation
OUI:00054D*
ID_OUI_FROM_DATABASE=Brans Technologies, Inc.
@@ -41513,41 +42581,53 @@ OUI:00051C*
OUI:000516*
ID_OUI_FROM_DATABASE=SMART Modular Technologies
-OUI:00050C*
- ID_OUI_FROM_DATABASE=Network Photonics, Inc.
+OUI:000650*
+ ID_OUI_FROM_DATABASE=Tiburon Networks, Inc.
-OUI:000512*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc
+OUI:000656*
+ ID_OUI_FROM_DATABASE=Tactel AB
-OUI:0006BF*
- ID_OUI_FROM_DATABASE=Accella Technologies Co., Ltd.
+OUI:00062D*
+ ID_OUI_FROM_DATABASE=TouchStar Technologies, L.L.C.
-OUI:0006B9*
- ID_OUI_FROM_DATABASE=A5TEK Corp.
+OUI:000649*
+ ID_OUI_FROM_DATABASE=3M Deutschland GmbH
-OUI:0006B2*
- ID_OUI_FROM_DATABASE=Linxtek Co.
+OUI:000643*
+ ID_OUI_FROM_DATABASE=SONO Computer Co., Ltd.
-OUI:0006AC*
- ID_OUI_FROM_DATABASE=Intersoft Co.
+OUI:00064A*
+ ID_OUI_FROM_DATABASE=Honeywell Co., Ltd. (KOREA)
-OUI:0006A6*
- ID_OUI_FROM_DATABASE=Artistic Licence Engineering Ltd
+OUI:00063F*
+ ID_OUI_FROM_DATABASE=Everex Communications Inc.
-OUI:0006A2*
- ID_OUI_FROM_DATABASE=Microtune, Inc.
+OUI:000639*
+ ID_OUI_FROM_DATABASE=Newtec
-OUI:000695*
- ID_OUI_FROM_DATABASE=Ensure Technologies, Inc.
+OUI:000633*
+ ID_OUI_FROM_DATABASE=Cross Match Technologies GmbH
-OUI:00069C*
- ID_OUI_FROM_DATABASE=Transmode Systems AB
+OUI:000626*
+ ID_OUI_FROM_DATABASE=MWE GmbH
-OUI:000696*
- ID_OUI_FROM_DATABASE=Advent Networks
+OUI:00061D*
+ ID_OUI_FROM_DATABASE=MIP Telecom, Inc.
-OUI:000690*
- ID_OUI_FROM_DATABASE=Euracom Communication GmbH
+OUI:000623*
+ ID_OUI_FROM_DATABASE=MGE UPS Systems France
+
+OUI:000589*
+ ID_OUI_FROM_DATABASE=National Datacomputer
+
+OUI:000595*
+ ID_OUI_FROM_DATABASE=Alesis Corporation
+
+OUI:00058F*
+ ID_OUI_FROM_DATABASE=CLCsoft co.
+
+OUI:000596*
+ ID_OUI_FROM_DATABASE=Genotech Co., Ltd.
OUI:00057D*
ID_OUI_FROM_DATABASE=Sun Communications, Inc.
@@ -41576,11 +42656,44 @@ OUI:000560*
OUI:000559*
ID_OUI_FROM_DATABASE=Intracom S.A.
-OUI:000553*
- ID_OUI_FROM_DATABASE=DVC Company, Inc.
+OUI:0004A5*
+ ID_OUI_FROM_DATABASE=Barco Projection Systems NV
-OUI:000548*
- ID_OUI_FROM_DATABASE=Disco Corporation
+OUI:000499*
+ ID_OUI_FROM_DATABASE=Chino Corporation
+
+OUI:00048D*
+ ID_OUI_FROM_DATABASE=Teo Technologies, Inc
+
+OUI:000493*
+ ID_OUI_FROM_DATABASE=Tsinghua Unisplendour Co., Ltd.
+
+OUI:000484*
+ ID_OUI_FROM_DATABASE=Amann GmbH
+
+OUI:00048A*
+ ID_OUI_FROM_DATABASE=Temia Vertriebs GmbH
+
+OUI:00047A*
+ ID_OUI_FROM_DATABASE=AXXESSIT ASA
+
+OUI:000474*
+ ID_OUI_FROM_DATABASE=LEGRAND
+
+OUI:00046E*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:000473*
+ ID_OUI_FROM_DATABASE=Photonex Corporation
+
+OUI:000467*
+ ID_OUI_FROM_DATABASE=Wuhan Research Institute of MII
+
+OUI:000461*
+ ID_OUI_FROM_DATABASE=EPOX Computer Co., Ltd.
+
+OUI:0003D9*
+ ID_OUI_FROM_DATABASE=Secheron SA
OUI:0003D2*
ID_OUI_FROM_DATABASE=Crossbeam Systems, Inc.
@@ -41615,48 +42728,6 @@ OUI:0003A8*
OUI:0003A1*
ID_OUI_FROM_DATABASE=HIPER Information & Communication, Inc.
-OUI:00044E*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:00044F*
- ID_OUI_FROM_DATABASE=Schubert System Elektronik Gmbh
-
-OUI:000454*
- ID_OUI_FROM_DATABASE=Quadriga UK
-
-OUI:000445*
- ID_OUI_FROM_DATABASE=LMS Skalar Instruments GmbH
-
-OUI:00044A*
- ID_OUI_FROM_DATABASE=iPolicy Networks, Inc.
-
-OUI:000444*
- ID_OUI_FROM_DATABASE=Western Multiplex Corporation
-
-OUI:00043E*
- ID_OUI_FROM_DATABASE=Telencomm
-
-OUI:000438*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
-OUI:000432*
- ID_OUI_FROM_DATABASE=Voyetra Turtle Beach, Inc.
-
-OUI:000437*
- ID_OUI_FROM_DATABASE=Powin Information Technology, Inc.
-
-OUI:00042B*
- ID_OUI_FROM_DATABASE=IT Access Co., Ltd.
-
-OUI:000425*
- ID_OUI_FROM_DATABASE=Atmel Corporation
-
-OUI:000419*
- ID_OUI_FROM_DATABASE=Fibercycle Networks, Inc.
-
-OUI:00041A*
- ID_OUI_FROM_DATABASE=Ines Test and Measurement GmbH & CoKG
-
OUI:000399*
ID_OUI_FROM_DATABASE=Dongju Informations & Communications Co., Ltd.
@@ -41687,8 +42758,8 @@ OUI:000371*
OUI:00036D*
ID_OUI_FROM_DATABASE=Runtop, Inc.
-OUI:000361*
- ID_OUI_FROM_DATABASE=Widcomm, Inc.
+OUI:0002E3*
+ ID_OUI_FROM_DATABASE=LITE-ON Communications, Inc.
OUI:0002DE*
ID_OUI_FROM_DATABASE=Astrodesign, Inc.
@@ -41729,8 +42800,41 @@ OUI:0002AF*
OUI:0002AA*
ID_OUI_FROM_DATABASE=PLcom Co., Ltd.
-OUI:0002A3*
- ID_OUI_FROM_DATABASE=ABB Switzerland Ltd, Power Systems
+OUI:00045B*
+ ID_OUI_FROM_DATABASE=Techsan Electronics Co., Ltd.
+
+OUI:00044E*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:00044F*
+ ID_OUI_FROM_DATABASE=Schubert System Elektronik Gmbh
+
+OUI:000454*
+ ID_OUI_FROM_DATABASE=Quadriga UK
+
+OUI:000445*
+ ID_OUI_FROM_DATABASE=LMS Skalar Instruments GmbH
+
+OUI:00044A*
+ ID_OUI_FROM_DATABASE=iPolicy Networks, Inc.
+
+OUI:000444*
+ ID_OUI_FROM_DATABASE=Western Multiplex Corporation
+
+OUI:00043E*
+ ID_OUI_FROM_DATABASE=Telencomm
+
+OUI:000432*
+ ID_OUI_FROM_DATABASE=Voyetra Turtle Beach, Inc.
+
+OUI:000437*
+ ID_OUI_FROM_DATABASE=Powin Information Technology, Inc.
+
+OUI:00042B*
+ ID_OUI_FROM_DATABASE=IT Access Co., Ltd.
+
+OUI:000361*
+ ID_OUI_FROM_DATABASE=Widcomm, Inc.
OUI:00035A*
ID_OUI_FROM_DATABASE=Photron Limited
@@ -41810,77 +42914,50 @@ OUI:0002F5*
OUI:0002EA*
ID_OUI_FROM_DATABASE=Focus Enhancements
-OUI:0002E3*
- ID_OUI_FROM_DATABASE=LITE-ON Communications, Inc.
-
-OUI:0004D3*
- ID_OUI_FROM_DATABASE=Toyokeiki Co., Ltd.
-
-OUI:0004CC*
- ID_OUI_FROM_DATABASE=Peek Traffic B.V.
-
-OUI:0004C0*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:0004B9*
- ID_OUI_FROM_DATABASE=S.I. Soubou, Inc.
-
-OUI:0004BA*
- ID_OUI_FROM_DATABASE=KDD Media Will Corporation
-
-OUI:0004AF*
- ID_OUI_FROM_DATABASE=Digital Fountain, Inc.
-
-OUI:0004B4*
- ID_OUI_FROM_DATABASE=CIAC
-
-OUI:0004B3*
- ID_OUI_FROM_DATABASE=Videotek, Inc.
-
-OUI:0004A6*
- ID_OUI_FROM_DATABASE=SAF Tehnika Ltd.
+OUI:000269*
+ ID_OUI_FROM_DATABASE=Nadatel Co., Ltd
-OUI:0004A0*
- ID_OUI_FROM_DATABASE=Verity Instruments, Inc.
+OUI:000265*
+ ID_OUI_FROM_DATABASE=Virditech Co. Ltd.
-OUI:0004A5*
- ID_OUI_FROM_DATABASE=Barco Projection Systems NV
+OUI:00025E*
+ ID_OUI_FROM_DATABASE=High Technology Ltd
-OUI:000499*
- ID_OUI_FROM_DATABASE=Chino Corporation
+OUI:000261*
+ ID_OUI_FROM_DATABASE=Tilgin AB
-OUI:00048D*
- ID_OUI_FROM_DATABASE=Teo Technologies, Inc
+OUI:000259*
+ ID_OUI_FROM_DATABASE=Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group
-OUI:000493*
- ID_OUI_FROM_DATABASE=Tsinghua Unisplendour Co., Ltd.
+OUI:000255*
+ ID_OUI_FROM_DATABASE=IBM Corp
-OUI:000484*
- ID_OUI_FROM_DATABASE=Amann GmbH
+OUI:000249*
+ ID_OUI_FROM_DATABASE=Aviv Infocom Co, Ltd.
-OUI:00048A*
- ID_OUI_FROM_DATABASE=Temia Vertriebs GmbH
+OUI:000250*
+ ID_OUI_FROM_DATABASE=Geyser Networks, Inc.
-OUI:00047A*
- ID_OUI_FROM_DATABASE=AXXESSIT ASA
+OUI:000242*
+ ID_OUI_FROM_DATABASE=Videoframe Systems
-OUI:000474*
- ID_OUI_FROM_DATABASE=LEGRAND
+OUI:000244*
+ ID_OUI_FROM_DATABASE=SURECOM Technology Co.
-OUI:00046E*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:00022C*
+ ID_OUI_FROM_DATABASE=ABB Bomem, Inc.
-OUI:000473*
- ID_OUI_FROM_DATABASE=Photonex Corporation
+OUI:00023A*
+ ID_OUI_FROM_DATABASE=ZSK Stickmaschinen GmbH
-OUI:000467*
- ID_OUI_FROM_DATABASE=Wuhan Research Institute of MII
+OUI:000425*
+ ID_OUI_FROM_DATABASE=Atmel Corporation
-OUI:000461*
- ID_OUI_FROM_DATABASE=EPOX Computer Co., Ltd.
+OUI:000419*
+ ID_OUI_FROM_DATABASE=Fibercycle Networks, Inc.
-OUI:00045B*
- ID_OUI_FROM_DATABASE=Techsan Electronics Co., Ltd.
+OUI:00041A*
+ ID_OUI_FROM_DATABASE=Ines Test and Measurement GmbH & CoKG
OUI:000414*
ID_OUI_FROM_DATABASE=Umezawa Musen Denki Co., Ltd.
@@ -41909,77 +42986,38 @@ OUI:0003EB*
OUI:0003E5*
ID_OUI_FROM_DATABASE=Hermstedt SG
-OUI:0003D9*
- ID_OUI_FROM_DATABASE=Secheron SA
-
-OUI:00022F*
- ID_OUI_FROM_DATABASE=P-Cube, Ltd.
-
-OUI:000227*
- ID_OUI_FROM_DATABASE=ESD Electronic System Design GmbH
-
-OUI:00021F*
- ID_OUI_FROM_DATABASE=Aculab PLC
-
-OUI:00021B*
- ID_OUI_FROM_DATABASE=Kollmorgen-Servotronix
-
-OUI:00020C*
- ID_OUI_FROM_DATABASE=Metro-Optix
-
-OUI:000218*
- ID_OUI_FROM_DATABASE=Advanced Scientific Corp
-
-OUI:000213*
- ID_OUI_FROM_DATABASE=S.D.E.L.
-
-OUI:00020F*
- ID_OUI_FROM_DATABASE=AATR
-
-OUI:0001F9*
- ID_OUI_FROM_DATABASE=TeraGlobal Communications Corp.
-
-OUI:000200*
- ID_OUI_FROM_DATABASE=Net & Sys Co., Ltd.
-
-OUI:00015E*
- ID_OUI_FROM_DATABASE=BEST TECHNOLOGY CO., LTD.
-
-OUI:000162*
- ID_OUI_FROM_DATABASE=Cygnet Technologies, Inc.
-
-OUI:000169*
- ID_OUI_FROM_DATABASE=Celestix Networks Pte Ltd.
+OUI:0002A3*
+ ID_OUI_FROM_DATABASE=ABB Switzerland Ltd, Power Systems
-OUI:000175*
- ID_OUI_FROM_DATABASE=Radiant Communications Corp.
+OUI:000298*
+ ID_OUI_FROM_DATABASE=Broadframe Corporation
-OUI:000159*
- ID_OUI_FROM_DATABASE=S1 Corporation
+OUI:000292*
+ ID_OUI_FROM_DATABASE=Logic Innovations, Inc.
-OUI:000165*
- ID_OUI_FROM_DATABASE=AirSwitch Corporation
+OUI:00028D*
+ ID_OUI_FROM_DATABASE=Movita Technologies, Inc.
-OUI:000171*
- ID_OUI_FROM_DATABASE=Allied Data Technologies
+OUI:000283*
+ ID_OUI_FROM_DATABASE=Spectrum Controls, Inc.
-OUI:000157*
- ID_OUI_FROM_DATABASE=SYSWAVE CO., LTD
+OUI:000277*
+ ID_OUI_FROM_DATABASE=Cash Systemes Industrie
-OUI:000153*
- ID_OUI_FROM_DATABASE=ARCHTEK TELECOM CORPORATION
+OUI:00027C*
+ ID_OUI_FROM_DATABASE=Trilithic, Inc.
-OUI:000144*
- ID_OUI_FROM_DATABASE=EMC Corporation
+OUI:000275*
+ ID_OUI_FROM_DATABASE=SMART Technologies, Inc.
-OUI:00014B*
- ID_OUI_FROM_DATABASE=Ennovate Networks, Inc.
+OUI:000270*
+ ID_OUI_FROM_DATABASE=Crewave Co., Ltd.
-OUI:00012C*
- ID_OUI_FROM_DATABASE=Aravox Technologies, Inc.
+OUI:000104*
+ ID_OUI_FROM_DATABASE=DVICO Co., Ltd.
-OUI:000138*
- ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
+OUI:000110*
+ ID_OUI_FROM_DATABASE=Gotham Networks
OUI:00010C*
ID_OUI_FROM_DATABASE=System Talks Inc.
@@ -42014,32 +43052,38 @@ OUI:00B091*
OUI:0030BE*
ID_OUI_FROM_DATABASE=City-Net Technology, Inc.
-OUI:00303E*
- ID_OUI_FROM_DATABASE=Radcom Ltd.
+OUI:000233*
+ ID_OUI_FROM_DATABASE=Mantra Communications, Inc.
-OUI:0030D7*
- ID_OUI_FROM_DATABASE=Innovative Systems, L.L.C.
+OUI:00022F*
+ ID_OUI_FROM_DATABASE=P-Cube, Ltd.
-OUI:0030FC*
- ID_OUI_FROM_DATABASE=Terawave Communications, Inc.
+OUI:000227*
+ ID_OUI_FROM_DATABASE=ESD Electronic System Design GmbH
-OUI:00300F*
- ID_OUI_FROM_DATABASE=IMT - Information Management T
+OUI:00021F*
+ ID_OUI_FROM_DATABASE=Aculab PLC
-OUI:003004*
- ID_OUI_FROM_DATABASE=LEADTEK RESEARCH INC.
+OUI:00021B*
+ ID_OUI_FROM_DATABASE=Kollmorgen-Servotronix
-OUI:003018*
- ID_OUI_FROM_DATABASE=Jetway Information Co., Ltd.
+OUI:00020C*
+ ID_OUI_FROM_DATABASE=Metro-Optix
-OUI:003088*
- ID_OUI_FROM_DATABASE=Ericsson
+OUI:000218*
+ ID_OUI_FROM_DATABASE=Advanced Scientific Corp
-OUI:0030CA*
- ID_OUI_FROM_DATABASE=Discovery Com
+OUI:000213*
+ ID_OUI_FROM_DATABASE=S.D.E.L.
-OUI:00304F*
- ID_OUI_FROM_DATABASE=PLANET Technology Corporation
+OUI:00020F*
+ ID_OUI_FROM_DATABASE=AATR
+
+OUI:0001F9*
+ ID_OUI_FROM_DATABASE=TeraGlobal Communications Corp.
+
+OUI:000200*
+ ID_OUI_FROM_DATABASE=Net & Sys Co., Ltd.
OUI:0001FC*
ID_OUI_FROM_DATABASE=Keyence Corporation
@@ -42074,44 +43118,80 @@ OUI:0001D1*
OUI:0001B3*
ID_OUI_FROM_DATABASE=Precision Electronic Manufacturing
-OUI:0001B1*
- ID_OUI_FROM_DATABASE=General Bandwidth
+OUI:000160*
+ ID_OUI_FROM_DATABASE=ELMEX Co., LTD.
-OUI:0001BB*
- ID_OUI_FROM_DATABASE=Frequentis
+OUI:00015E*
+ ID_OUI_FROM_DATABASE=BEST TECHNOLOGY CO., LTD.
-OUI:00025E*
- ID_OUI_FROM_DATABASE=High Technology Ltd
+OUI:000162*
+ ID_OUI_FROM_DATABASE=Cygnet Technologies, Inc.
-OUI:000261*
- ID_OUI_FROM_DATABASE=Tilgin AB
+OUI:000169*
+ ID_OUI_FROM_DATABASE=Celestix Networks Pte Ltd.
-OUI:000259*
- ID_OUI_FROM_DATABASE=Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group
+OUI:000175*
+ ID_OUI_FROM_DATABASE=Radiant Communications Corp.
-OUI:000255*
- ID_OUI_FROM_DATABASE=IBM Corp
+OUI:000159*
+ ID_OUI_FROM_DATABASE=S1 Corporation
-OUI:000249*
- ID_OUI_FROM_DATABASE=Aviv Infocom Co, Ltd.
+OUI:000165*
+ ID_OUI_FROM_DATABASE=AirSwitch Corporation
-OUI:000250*
- ID_OUI_FROM_DATABASE=Geyser Networks, Inc.
+OUI:000171*
+ ID_OUI_FROM_DATABASE=Allied Data Technologies
-OUI:000242*
- ID_OUI_FROM_DATABASE=Videoframe Systems
+OUI:000157*
+ ID_OUI_FROM_DATABASE=SYSWAVE CO., LTD
-OUI:000244*
- ID_OUI_FROM_DATABASE=SURECOM Technology Co.
+OUI:000153*
+ ID_OUI_FROM_DATABASE=ARCHTEK TELECOM CORPORATION
-OUI:00022C*
- ID_OUI_FROM_DATABASE=ABB Bomem, Inc.
+OUI:000144*
+ ID_OUI_FROM_DATABASE=EMC Corporation
-OUI:00023A*
- ID_OUI_FROM_DATABASE=ZSK Stickmaschinen GmbH
+OUI:003038*
+ ID_OUI_FROM_DATABASE=XCP, INC.
-OUI:000233*
- ID_OUI_FROM_DATABASE=Mantra Communications, Inc.
+OUI:0030DB*
+ ID_OUI_FROM_DATABASE=Mindready Solutions, Inc.
+
+OUI:00306A*
+ ID_OUI_FROM_DATABASE=PENTA MEDIA CO., LTD.
+
+OUI:003021*
+ ID_OUI_FROM_DATABASE=HSING TECH. ENTERPRISE CO.,LTD
+
+OUI:0030EA*
+ ID_OUI_FROM_DATABASE=TeraForce Technology Corporation
+
+OUI:0030F4*
+ ID_OUI_FROM_DATABASE=STARDOT TECHNOLOGIES
+
+OUI:003087*
+ ID_OUI_FROM_DATABASE=VEGA GRIESHABER KG
+
+OUI:003000*
+ ID_OUI_FROM_DATABASE=ALLWELL TECHNOLOGY CORP.
+
+OUI:003034*
+ ID_OUI_FROM_DATABASE=SET ENGINEERING
+
+OUI:00308D*
+ ID_OUI_FROM_DATABASE=Pinnacle Systems, Inc.
+
+OUI:00304B*
+ ID_OUI_FROM_DATABASE=ORBACOM SYSTEMS, INC.
+
+OUI:0030FA*
+ ID_OUI_FROM_DATABASE=TELICA, INC.
+
+OUI:0001B1*
+ ID_OUI_FROM_DATABASE=General Bandwidth
+
+OUI:0001BB*
+ ID_OUI_FROM_DATABASE=Frequentis
OUI:0001B7*
ID_OUI_FROM_DATABASE=Centos, Inc.
@@ -42155,38 +43235,38 @@ OUI:0030F5*
OUI:000184*
ID_OUI_FROM_DATABASE=SIEB & MEYER AG
-OUI:000160*
- ID_OUI_FROM_DATABASE=ELMEX Co., LTD.
+OUI:00303E*
+ ID_OUI_FROM_DATABASE=Radcom Ltd.
-OUI:000298*
- ID_OUI_FROM_DATABASE=Broadframe Corporation
+OUI:0030D7*
+ ID_OUI_FROM_DATABASE=Innovative Systems, L.L.C.
-OUI:000292*
- ID_OUI_FROM_DATABASE=Logic Innovations, Inc.
+OUI:0030FC*
+ ID_OUI_FROM_DATABASE=Terawave Communications, Inc.
-OUI:00028D*
- ID_OUI_FROM_DATABASE=Movita Technologies, Inc.
+OUI:00300F*
+ ID_OUI_FROM_DATABASE=IMT - Information Management T
-OUI:000283*
- ID_OUI_FROM_DATABASE=Spectrum Controls, Inc.
+OUI:003004*
+ ID_OUI_FROM_DATABASE=LEADTEK RESEARCH INC.
-OUI:000277*
- ID_OUI_FROM_DATABASE=Cash Systemes Industrie
+OUI:003018*
+ ID_OUI_FROM_DATABASE=Jetway Information Co., Ltd.
-OUI:00027C*
- ID_OUI_FROM_DATABASE=Trilithic, Inc.
+OUI:003088*
+ ID_OUI_FROM_DATABASE=Ericsson
-OUI:000275*
- ID_OUI_FROM_DATABASE=SMART Technologies, Inc.
+OUI:0030CA*
+ ID_OUI_FROM_DATABASE=Discovery Com
-OUI:000270*
- ID_OUI_FROM_DATABASE=Crewave Co., Ltd.
+OUI:00304F*
+ ID_OUI_FROM_DATABASE=PLANET Technology Corporation
-OUI:000269*
- ID_OUI_FROM_DATABASE=Nadatel Co., Ltd
+OUI:00014B*
+ ID_OUI_FROM_DATABASE=Ennovate Networks, Inc.
-OUI:000265*
- ID_OUI_FROM_DATABASE=Virditech Co. Ltd.
+OUI:00012C*
+ ID_OUI_FROM_DATABASE=Aravox Technologies, Inc.
OUI:000134*
ID_OUI_FROM_DATABASE=Selectron Systems AG
@@ -42209,11 +43289,26 @@ OUI:000123*
OUI:00011F*
ID_OUI_FROM_DATABASE=RC Networks, Inc.
-OUI:000104*
- ID_OUI_FROM_DATABASE=DVICO Co., Ltd.
+OUI:003045*
+ ID_OUI_FROM_DATABASE=Village Networks, Inc. (VNI)
-OUI:000110*
- ID_OUI_FROM_DATABASE=Gotham Networks
+OUI:0030BB*
+ ID_OUI_FROM_DATABASE=CacheFlow, Inc.
+
+OUI:003053*
+ ID_OUI_FROM_DATABASE=Basler AG
+
+OUI:003072*
+ ID_OUI_FROM_DATABASE=Intellibyte Inc.
+
+OUI:0030B1*
+ ID_OUI_FROM_DATABASE=TrunkNet
+
+OUI:0030A7*
+ ID_OUI_FROM_DATABASE=SCHWEITZER ENGINEERING
+
+OUI:00D086*
+ ID_OUI_FROM_DATABASE=FOVEON, INC.
OUI:00D05A*
ID_OUI_FROM_DATABASE=SYMBIONICS, LTD.
@@ -42260,47 +43355,50 @@ OUI:00D01E*
OUI:00D0A9*
ID_OUI_FROM_DATABASE=SHINANO KENSHI CO., LTD.
-OUI:00D0F2*
- ID_OUI_FROM_DATABASE=MONTEREY NETWORKS
+OUI:0030E9*
+ ID_OUI_FROM_DATABASE=GMA COMMUNICATION MANUFACT'G
-OUI:0030DB*
- ID_OUI_FROM_DATABASE=Mindready Solutions, Inc.
+OUI:003027*
+ ID_OUI_FROM_DATABASE=KERBANGO, INC.
-OUI:00306A*
- ID_OUI_FROM_DATABASE=PENTA MEDIA CO., LTD.
+OUI:0030F6*
+ ID_OUI_FROM_DATABASE=SECURELOGIX CORPORATION
-OUI:003021*
- ID_OUI_FROM_DATABASE=HSING TECH. ENTERPRISE CO.,LTD
+OUI:0030B6*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0030EA*
- ID_OUI_FROM_DATABASE=TeraForce Technology Corporation
+OUI:0030B2*
+ ID_OUI_FROM_DATABASE=L-3 Sonoma EO
-OUI:0030F4*
- ID_OUI_FROM_DATABASE=STARDOT TECHNOLOGIES
+OUI:0030D6*
+ ID_OUI_FROM_DATABASE=MSC VERTRIEBS GMBH
-OUI:003087*
- ID_OUI_FROM_DATABASE=VEGA GRIESHABER KG
+OUI:003008*
+ ID_OUI_FROM_DATABASE=AVIO DIGITAL, INC.
-OUI:003000*
- ID_OUI_FROM_DATABASE=ALLWELL TECHNOLOGY CORP.
+OUI:00306D*
+ ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES
-OUI:003034*
- ID_OUI_FROM_DATABASE=SET ENGINEERING
+OUI:0030E4*
+ ID_OUI_FROM_DATABASE=CHIYODA SYSTEM RIKEN
-OUI:00308D*
- ID_OUI_FROM_DATABASE=Pinnacle Systems, Inc.
+OUI:00301A*
+ ID_OUI_FROM_DATABASE=SMARTBRIDGES PTE. LTD.
-OUI:00304B*
- ID_OUI_FROM_DATABASE=ORBACOM SYSTEMS, INC.
+OUI:0030CD*
+ ID_OUI_FROM_DATABASE=CONEXANT SYSTEMS, INC.
-OUI:0030FA*
- ID_OUI_FROM_DATABASE=TELICA, INC.
+OUI:003001*
+ ID_OUI_FROM_DATABASE=SMP
-OUI:0030E9*
- ID_OUI_FROM_DATABASE=GMA COMMUNICATION MANUFACT'G
+OUI:0030E1*
+ ID_OUI_FROM_DATABASE=Network Equipment Technologies, Inc.
-OUI:003027*
- ID_OUI_FROM_DATABASE=KERBANGO, INC.
+OUI:0050A7*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:00D0EE*
+ ID_OUI_FROM_DATABASE=DICTAPHONE CORPORATION
OUI:00D0B8*
ID_OUI_FROM_DATABASE=Iomega Corporation
@@ -42344,56 +43442,101 @@ OUI:0050A9*
OUI:00503C*
ID_OUI_FROM_DATABASE=TSINGHUA NOVEL ELECTRONICS
-OUI:0050B6*
- ID_OUI_FROM_DATABASE=GOOD WAY IND. CO., LTD.
+OUI:005030*
+ ID_OUI_FROM_DATABASE=FUTURE PLUS SYSTEMS
-OUI:0050FF*
- ID_OUI_FROM_DATABASE=HAKKO ELECTRONICS CO., LTD.
+OUI:005037*
+ ID_OUI_FROM_DATABASE=KOGA ELECTRONICS CO.
-OUI:005032*
- ID_OUI_FROM_DATABASE=PICAZO COMMUNICATIONS, INC.
+OUI:00501F*
+ ID_OUI_FROM_DATABASE=MRG SYSTEMS, LTD.
-OUI:0030F6*
- ID_OUI_FROM_DATABASE=SECURELOGIX CORPORATION
+OUI:005092*
+ ID_OUI_FROM_DATABASE=Rigaku Corporation Osaka Plant
-OUI:0030B6*
+OUI:00501C*
+ ID_OUI_FROM_DATABASE=JATOM SYSTEMS, INC.
+
+OUI:00505C*
+ ID_OUI_FROM_DATABASE=TUNDO CORPORATION
+
+OUI:005068*
+ ID_OUI_FROM_DATABASE=ELECTRONIC INDUSTRIES ASSOCIATION
+
+OUI:00501A*
+ ID_OUI_FROM_DATABASE=IQinVision
+
+OUI:005063*
+ ID_OUI_FROM_DATABASE=OY COMSEL SYSTEM AB
+
+OUI:0050DE*
+ ID_OUI_FROM_DATABASE=SIGNUM SYSTEMS CORP.
+
+OUI:00507B*
+ ID_OUI_FROM_DATABASE=MERLOT COMMUNICATIONS
+
+OUI:005078*
+ ID_OUI_FROM_DATABASE=MEGATON HOUSE, LTD.
+
+OUI:00508F*
+ ID_OUI_FROM_DATABASE=ASITA TECHNOLOGIES INT'L LTD.
+
+OUI:005057*
+ ID_OUI_FROM_DATABASE=BROADBAND ACCESS SYSTEMS
+
+OUI:005087*
+ ID_OUI_FROM_DATABASE=TERASAKI ELECTRIC CO., LTD.
+
+OUI:00D03E*
+ ID_OUI_FROM_DATABASE=ROCKETCHIPS, INC.
+
+OUI:00D03F*
+ ID_OUI_FROM_DATABASE=AMERICAN COMMUNICATION
+
+OUI:00D033*
+ ID_OUI_FROM_DATABASE=DALIAN DAXIAN NETWORK
+
+OUI:00D0CE*
+ ID_OUI_FROM_DATABASE=ASYST ELECTRONIC
+
+OUI:00D090*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0030B2*
- ID_OUI_FROM_DATABASE=L-3 Sonoma EO
+OUI:00D0B6*
+ ID_OUI_FROM_DATABASE=CRESCENT NETWORKS, INC.
-OUI:0030D6*
- ID_OUI_FROM_DATABASE=MSC VERTRIEBS GMBH
+OUI:00D0D2*
+ ID_OUI_FROM_DATABASE=EPILOG CORPORATION
-OUI:003008*
- ID_OUI_FROM_DATABASE=AVIO DIGITAL, INC.
+OUI:0050B6*
+ ID_OUI_FROM_DATABASE=GOOD WAY IND. CO., LTD.
-OUI:00306D*
- ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES
+OUI:0050FF*
+ ID_OUI_FROM_DATABASE=HAKKO ELECTRONICS CO., LTD.
-OUI:0030E4*
- ID_OUI_FROM_DATABASE=CHIYODA SYSTEM RIKEN
+OUI:005032*
+ ID_OUI_FROM_DATABASE=PICAZO COMMUNICATIONS, INC.
-OUI:00301A*
- ID_OUI_FROM_DATABASE=SMARTBRIDGES PTE. LTD.
+OUI:0050DA*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
-OUI:0030CD*
- ID_OUI_FROM_DATABASE=CONEXANT SYSTEMS, INC.
+OUI:0050F9*
+ ID_OUI_FROM_DATABASE=Sensormatic Electronics LLC
-OUI:003001*
- ID_OUI_FROM_DATABASE=SMP
+OUI:0050F6*
+ ID_OUI_FROM_DATABASE=PAN-INTERNATIONAL INDUSTRIAL CORP.
-OUI:0030E1*
- ID_OUI_FROM_DATABASE=Network Equipment Technologies, Inc.
+OUI:00506C*
+ ID_OUI_FROM_DATABASE=Beijer Electronics Products AB
-OUI:0030D8*
- ID_OUI_FROM_DATABASE=SITEK
+OUI:0050A5*
+ ID_OUI_FROM_DATABASE=CAPITOL BUSINESS SYSTEMS, LTD.
-OUI:003062*
- ID_OUI_FROM_DATABASE=IP Video Networks Inc
+OUI:005000*
+ ID_OUI_FROM_DATABASE=NEXO COMMUNICATIONS, INC.
-OUI:003081*
- ID_OUI_FROM_DATABASE=ALTOS C&C
+OUI:00D071*
+ ID_OUI_FROM_DATABASE=ECHELON CORP.
OUI:00D066*
ID_OUI_FROM_DATABASE=WINTRISS ENGINEERING CORP.
@@ -42425,29 +43568,8 @@ OUI:00D038*
OUI:00D00C*
ID_OUI_FROM_DATABASE=SNIJDER MICRO SYSTEMS
-OUI:00D086*
- ID_OUI_FROM_DATABASE=FOVEON, INC.
-
-OUI:00D03F*
- ID_OUI_FROM_DATABASE=AMERICAN COMMUNICATION
-
-OUI:00D033*
- ID_OUI_FROM_DATABASE=DALIAN DAXIAN NETWORK
-
-OUI:00D0CE*
- ID_OUI_FROM_DATABASE=ASYST ELECTRONIC
-
-OUI:00D090*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
-OUI:00D0B6*
- ID_OUI_FROM_DATABASE=CRESCENT NETWORKS, INC.
-
-OUI:00D0D2*
- ID_OUI_FROM_DATABASE=EPILOG CORPORATION
-
-OUI:00D071*
- ID_OUI_FROM_DATABASE=ECHELON CORP.
+OUI:00D0F2*
+ ID_OUI_FROM_DATABASE=MONTEREY NETWORKS
OUI:00D07B*
ID_OUI_FROM_DATABASE=COMCAM INTERNATIONAL INC
@@ -42464,11 +43586,14 @@ OUI:00D04C*
OUI:00D0FD*
ID_OUI_FROM_DATABASE=OPTIMA TELE.COM, INC.
-OUI:0050A7*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:0030D8*
+ ID_OUI_FROM_DATABASE=SITEK
-OUI:00D0EE*
- ID_OUI_FROM_DATABASE=DICTAPHONE CORPORATION
+OUI:003062*
+ ID_OUI_FROM_DATABASE=IP Video Networks Inc
+
+OUI:003081*
+ ID_OUI_FROM_DATABASE=ALTOS C&C
OUI:00D0B0*
ID_OUI_FROM_DATABASE=BITSWITCH LTD.
@@ -42485,30 +43610,6 @@ OUI:00D045*
OUI:00D0D0*
ID_OUI_FROM_DATABASE=ZHONGXING TELECOM LTD.
-OUI:00D03E*
- ID_OUI_FROM_DATABASE=ROCKETCHIPS, INC.
-
-OUI:003045*
- ID_OUI_FROM_DATABASE=Village Networks, Inc. (VNI)
-
-OUI:0030BB*
- ID_OUI_FROM_DATABASE=CacheFlow, Inc.
-
-OUI:003053*
- ID_OUI_FROM_DATABASE=Basler AG
-
-OUI:003072*
- ID_OUI_FROM_DATABASE=Intellibyte Inc.
-
-OUI:0030B1*
- ID_OUI_FROM_DATABASE=TrunkNet
-
-OUI:0030A7*
- ID_OUI_FROM_DATABASE=SCHWEITZER ENGINEERING
-
-OUI:003038*
- ID_OUI_FROM_DATABASE=XCP, INC.
-
OUI:00902C*
ID_OUI_FROM_DATABASE=DATA & CONTROL EQUIPMENT LTD.
@@ -42527,50 +43628,86 @@ OUI:009017*
OUI:00907B*
ID_OUI_FROM_DATABASE=E-TECH, INC.
-OUI:00909D*
- ID_OUI_FROM_DATABASE=NovaTech Process Solutions, LLC
+OUI:00102A*
+ ID_OUI_FROM_DATABASE=ZF MICROSYSTEMS, INC.
-OUI:009038*
- ID_OUI_FROM_DATABASE=FOUNTAIN TECHNOLOGIES, INC.
+OUI:00107D*
+ ID_OUI_FROM_DATABASE=AURORA COMMUNICATIONS, LTD.
-OUI:00501F*
- ID_OUI_FROM_DATABASE=MRG SYSTEMS, LTD.
+OUI:00101C*
+ ID_OUI_FROM_DATABASE=OHM TECHNOLOGIES INTL, LLC
-OUI:005092*
- ID_OUI_FROM_DATABASE=Rigaku Corporation Osaka Plant
+OUI:00106C*
+ ID_OUI_FROM_DATABASE=EDNT GmbH
-OUI:00501C*
- ID_OUI_FROM_DATABASE=JATOM SYSTEMS, INC.
+OUI:0010D4*
+ ID_OUI_FROM_DATABASE=STORAGE COMPUTER CORPORATION
-OUI:00505C*
- ID_OUI_FROM_DATABASE=TUNDO CORPORATION
+OUI:0010BF*
+ ID_OUI_FROM_DATABASE=InterAir Wireless
-OUI:005068*
- ID_OUI_FROM_DATABASE=ELECTRONIC INDUSTRIES ASSOCIATION
+OUI:001036*
+ ID_OUI_FROM_DATABASE=INTER-TEL INTEGRATED SYSTEMS
-OUI:00501A*
- ID_OUI_FROM_DATABASE=IQinVision
+OUI:001026*
+ ID_OUI_FROM_DATABASE=ACCELERATED NETWORKS, INC.
-OUI:005063*
- ID_OUI_FROM_DATABASE=OY COMSEL SYSTEM AB
+OUI:00104B*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
-OUI:0050DE*
- ID_OUI_FROM_DATABASE=SIGNUM SYSTEMS CORP.
+OUI:000629*
+ ID_OUI_FROM_DATABASE=IBM Corp
-OUI:00507B*
- ID_OUI_FROM_DATABASE=MERLOT COMMUNICATIONS
+OUI:001004*
+ ID_OUI_FROM_DATABASE=THE BRANTLEY COILE COMPANY,INC
-OUI:005078*
- ID_OUI_FROM_DATABASE=MEGATON HOUSE, LTD.
+OUI:00103A*
+ ID_OUI_FROM_DATABASE=DIAMOND NETWORK TECH
-OUI:00508F*
- ID_OUI_FROM_DATABASE=ASITA TECHNOLOGIES INT'L LTD.
+OUI:0010D8*
+ ID_OUI_FROM_DATABASE=CALISTA
-OUI:005057*
- ID_OUI_FROM_DATABASE=BROADBAND ACCESS SYSTEMS
+OUI:001031*
+ ID_OUI_FROM_DATABASE=OBJECTIVE COMMUNICATIONS, INC.
-OUI:005087*
- ID_OUI_FROM_DATABASE=TERASAKI ELECTRIC CO., LTD.
+OUI:00107E*
+ ID_OUI_FROM_DATABASE=BACHMANN ELECTRONIC GmbH
+
+OUI:0010C0*
+ ID_OUI_FROM_DATABASE=ARMA, Inc.
+
+OUI:001016*
+ ID_OUI_FROM_DATABASE=T.SQWARE
+
+OUI:00103D*
+ ID_OUI_FROM_DATABASE=PHASECOM, LTD.
+
+OUI:0010C2*
+ ID_OUI_FROM_DATABASE=WILLNET, INC.
+
+OUI:00107A*
+ ID_OUI_FROM_DATABASE=AmbiCom, Inc.
+
+OUI:0010C4*
+ ID_OUI_FROM_DATABASE=MEDIA GLOBAL LINKS CO., LTD.
+
+OUI:0010EB*
+ ID_OUI_FROM_DATABASE=SELSIUS SYSTEMS, INC.
+
+OUI:0010FE*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:00102E*
+ ID_OUI_FROM_DATABASE=NETWORK SYSTEMS & TECHNOLOGIES PVT. LTD.
+
+OUI:00103E*
+ ID_OUI_FROM_DATABASE=NETSCHOOLS CORPORATION
+
+OUI:001049*
+ ID_OUI_FROM_DATABASE=ShoreTel, Inc
+
+OUI:00105E*
+ ID_OUI_FROM_DATABASE=Spirent plc, Service Assurance Broadband
OUI:005088*
ID_OUI_FROM_DATABASE=AMANO CORPORATION
@@ -42602,30 +43739,6 @@ OUI:0050EB*
OUI:0050BC*
ID_OUI_FROM_DATABASE=HAMMER STORAGE SOLUTIONS
-OUI:00900F*
- ID_OUI_FROM_DATABASE=KAWASAKI HEAVY INDUSTRIES, LTD
-
-OUI:009036*
- ID_OUI_FROM_DATABASE=ens, inc.
-
-OUI:0090E9*
- ID_OUI_FROM_DATABASE=JANZ COMPUTER AG
-
-OUI:009032*
- ID_OUI_FROM_DATABASE=PELCOMBE GROUP LTD.
-
-OUI:0090B8*
- ID_OUI_FROM_DATABASE=ROHDE & SCHWARZ GMBH & CO. KG
-
-OUI:009058*
- ID_OUI_FROM_DATABASE=Ultra Electronics Ltd., Command and Control Systems
-
-OUI:0090BE*
- ID_OUI_FROM_DATABASE=IBC/INTEGRATED BUSINESS COMPUTERS
-
-OUI:009062*
- ID_OUI_FROM_DATABASE=ICP VORTEX COMPUTERSYSTEME GmbH
-
OUI:0090C3*
ID_OUI_FROM_DATABASE=TOPIC SEMICONDUCTOR CORP.
@@ -42644,9 +43757,6 @@ OUI:0090C1*
OUI:0010D3*
ID_OUI_FROM_DATABASE=GRIPS ELECTRONIC GMBH
-OUI:001087*
- ID_OUI_FROM_DATABASE=Xstreamis PLC
-
OUI:0010ED*
ID_OUI_FROM_DATABASE=SUNDANCE TECHNOLOGY, INC.
@@ -42668,14 +43778,11 @@ OUI:0010D5*
OUI:0010E5*
ID_OUI_FROM_DATABASE=SOLECTRON TEXAS
-OUI:00102A*
- ID_OUI_FROM_DATABASE=ZF MICROSYSTEMS, INC.
-
-OUI:00107D*
- ID_OUI_FROM_DATABASE=AURORA COMMUNICATIONS, LTD.
+OUI:00909D*
+ ID_OUI_FROM_DATABASE=NovaTech Process Solutions, LLC
-OUI:00101C*
- ID_OUI_FROM_DATABASE=OHM TECHNOLOGIES INTL, LLC
+OUI:009038*
+ ID_OUI_FROM_DATABASE=FOUNTAIN TECHNOLOGIES, INC.
OUI:0090C5*
ID_OUI_FROM_DATABASE=INTERNET MAGIC, INC.
@@ -42734,131 +43841,65 @@ OUI:009098*
OUI:0090CF*
ID_OUI_FROM_DATABASE=NORTEL
-OUI:0050DA*
- ID_OUI_FROM_DATABASE=3COM CORPORATION
-
-OUI:0050F9*
- ID_OUI_FROM_DATABASE=Sensormatic Electronics LLC
-
-OUI:0050F6*
- ID_OUI_FROM_DATABASE=PAN-INTERNATIONAL INDUSTRIAL CORP.
-
-OUI:00506C*
- ID_OUI_FROM_DATABASE=Beijer Electronics Products AB
-
-OUI:0050A5*
- ID_OUI_FROM_DATABASE=CAPITOL BUSINESS SYSTEMS, LTD.
-
-OUI:005000*
- ID_OUI_FROM_DATABASE=NEXO COMMUNICATIONS, INC.
-
-OUI:005030*
- ID_OUI_FROM_DATABASE=FUTURE PLUS SYSTEMS
-
-OUI:005037*
- ID_OUI_FROM_DATABASE=KOGA ELECTRONICS CO.
-
-OUI:00106C*
- ID_OUI_FROM_DATABASE=EDNT GmbH
-
-OUI:0010D4*
- ID_OUI_FROM_DATABASE=STORAGE COMPUTER CORPORATION
-
-OUI:0010BF*
- ID_OUI_FROM_DATABASE=InterAir Wireless
-
-OUI:001036*
- ID_OUI_FROM_DATABASE=INTER-TEL INTEGRATED SYSTEMS
-
-OUI:001026*
- ID_OUI_FROM_DATABASE=ACCELERATED NETWORKS, INC.
-
-OUI:00104B*
- ID_OUI_FROM_DATABASE=3COM CORPORATION
-
-OUI:000629*
- ID_OUI_FROM_DATABASE=IBM Corp
-
-OUI:001004*
- ID_OUI_FROM_DATABASE=THE BRANTLEY COILE COMPANY,INC
-
-OUI:00103A*
- ID_OUI_FROM_DATABASE=DIAMOND NETWORK TECH
-
-OUI:0010D8*
- ID_OUI_FROM_DATABASE=CALISTA
-
-OUI:001031*
- ID_OUI_FROM_DATABASE=OBJECTIVE COMMUNICATIONS, INC.
-
-OUI:00103D*
- ID_OUI_FROM_DATABASE=PHASECOM, LTD.
-
-OUI:0010C2*
- ID_OUI_FROM_DATABASE=WILLNET, INC.
-
-OUI:00107A*
- ID_OUI_FROM_DATABASE=AmbiCom, Inc.
-
-OUI:0010C4*
- ID_OUI_FROM_DATABASE=MEDIA GLOBAL LINKS CO., LTD.
+OUI:00900F*
+ ID_OUI_FROM_DATABASE=KAWASAKI HEAVY INDUSTRIES, LTD
-OUI:0010EB*
- ID_OUI_FROM_DATABASE=SELSIUS SYSTEMS, INC.
+OUI:009036*
+ ID_OUI_FROM_DATABASE=ens, inc.
-OUI:0010FE*
- ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+OUI:0090E9*
+ ID_OUI_FROM_DATABASE=JANZ COMPUTER AG
-OUI:00102E*
- ID_OUI_FROM_DATABASE=NETWORK SYSTEMS & TECHNOLOGIES PVT. LTD.
+OUI:009032*
+ ID_OUI_FROM_DATABASE=PELCOMBE GROUP LTD.
-OUI:0010C1*
- ID_OUI_FROM_DATABASE=OI ELECTRIC CO., LTD.
+OUI:0090B8*
+ ID_OUI_FROM_DATABASE=ROHDE & SCHWARZ GMBH & CO. KG
-OUI:00103E*
- ID_OUI_FROM_DATABASE=NETSCHOOLS CORPORATION
+OUI:0090BE*
+ ID_OUI_FROM_DATABASE=IBC/INTEGRATED BUSINESS COMPUTERS
-OUI:001049*
- ID_OUI_FROM_DATABASE=ShoreTel, Inc
+OUI:009062*
+ ID_OUI_FROM_DATABASE=ICP VORTEX COMPUTERSYSTEME GmbH
-OUI:00105E*
- ID_OUI_FROM_DATABASE=Spirent plc, Service Assurance Broadband
+OUI:00108F*
+ ID_OUI_FROM_DATABASE=RAPTOR SYSTEMS
-OUI:0010B1*
- ID_OUI_FROM_DATABASE=FOR-A CO., LTD.
+OUI:001089*
+ ID_OUI_FROM_DATABASE=WebSonic
-OUI:001041*
- ID_OUI_FROM_DATABASE=BRISTOL BABCOCK, INC.
+OUI:001086*
+ ID_OUI_FROM_DATABASE=ATTO Technology, Inc.
-OUI:0010F7*
- ID_OUI_FROM_DATABASE=IRIICHI TECHNOLOGIES Inc.
+OUI:001027*
+ ID_OUI_FROM_DATABASE=L-3 COMMUNICATIONS EAST
-OUI:00E0FD*
- ID_OUI_FROM_DATABASE=A-TREND TECHNOLOGY CO., LTD.
+OUI:0010B8*
+ ID_OUI_FROM_DATABASE=ISHIGAKI COMPUTER SYSTEM CO.
-OUI:00E0FB*
- ID_OUI_FROM_DATABASE=LEIGHTRONIX, INC.
+OUI:00104C*
+ ID_OUI_FROM_DATABASE=Teledyne LeCroy, Inc
-OUI:00E0D3*
- ID_OUI_FROM_DATABASE=DATENTECHNIK GmbH
+OUI:001001*
+ ID_OUI_FROM_DATABASE=Citel
-OUI:00E05E*
- ID_OUI_FROM_DATABASE=JAPAN AVIATION ELECTRONICS INDUSTRY, LTD.
+OUI:0010CF*
+ ID_OUI_FROM_DATABASE=FIBERLANE COMMUNICATIONS
-OUI:00E0E5*
- ID_OUI_FROM_DATABASE=CINCO NETWORKS, INC.
+OUI:001068*
+ ID_OUI_FROM_DATABASE=COMOS TELECOM
-OUI:00E0A1*
- ID_OUI_FROM_DATABASE=HIMA PAUL HILDEBRANDT GmbH Co. KG
+OUI:001067*
+ ID_OUI_FROM_DATABASE=Ericsson
-OUI:00E028*
- ID_OUI_FROM_DATABASE=APTIX CORPORATION
+OUI:0010F1*
+ ID_OUI_FROM_DATABASE=I-O CORPORATION
-OUI:00E0F2*
- ID_OUI_FROM_DATABASE=ARLOTTO COMNET, INC.
+OUI:001073*
+ ID_OUI_FROM_DATABASE=TECHNOBOX, INC.
-OUI:00E020*
- ID_OUI_FROM_DATABASE=TECNOMEN OY
+OUI:00E0C0*
+ ID_OUI_FROM_DATABASE=SEIWA ELECTRIC MFG. CO., LTD.
OUI:00E046*
ID_OUI_FROM_DATABASE=BENTLY NEVADA CORP.
@@ -42893,51 +43934,6 @@ OUI:00E012*
OUI:00E0D8*
ID_OUI_FROM_DATABASE=LANBit Computer, Inc.
-OUI:00108F*
- ID_OUI_FROM_DATABASE=RAPTOR SYSTEMS
-
-OUI:001089*
- ID_OUI_FROM_DATABASE=WebSonic
-
-OUI:001086*
- ID_OUI_FROM_DATABASE=ATTO Technology, Inc.
-
-OUI:001027*
- ID_OUI_FROM_DATABASE=L-3 COMMUNICATIONS EAST
-
-OUI:0010B8*
- ID_OUI_FROM_DATABASE=ISHIGAKI COMPUTER SYSTEM CO.
-
-OUI:00104C*
- ID_OUI_FROM_DATABASE=Teledyne LeCroy, Inc
-
-OUI:001001*
- ID_OUI_FROM_DATABASE=Citel
-
-OUI:0010CF*
- ID_OUI_FROM_DATABASE=FIBERLANE COMMUNICATIONS
-
-OUI:001068*
- ID_OUI_FROM_DATABASE=COMOS TELECOM
-
-OUI:001067*
- ID_OUI_FROM_DATABASE=Ericsson
-
-OUI:0010F1*
- ID_OUI_FROM_DATABASE=I-O CORPORATION
-
-OUI:001073*
- ID_OUI_FROM_DATABASE=TECHNOBOX, INC.
-
-OUI:00107E*
- ID_OUI_FROM_DATABASE=BACHMANN ELECTRONIC GmbH
-
-OUI:0010C0*
- ID_OUI_FROM_DATABASE=ARMA, Inc.
-
-OUI:001016*
- ID_OUI_FROM_DATABASE=T.SQWARE
-
OUI:00E02D*
ID_OUI_FROM_DATABASE=InnoMediaLogic, Inc.
@@ -42959,9 +43955,6 @@ OUI:00E06C*
OUI:00E0CE*
ID_OUI_FROM_DATABASE=ARN
-OUI:00E091*
- ID_OUI_FROM_DATABASE=LG ELECTRONICS, INC.
-
OUI:00E05F*
ID_OUI_FROM_DATABASE=e-Net, Inc.
@@ -42974,17 +43967,38 @@ OUI:00E0C7*
OUI:00E0C4*
ID_OUI_FROM_DATABASE=HORNER ELECTRIC, INC.
-OUI:0010E6*
- ID_OUI_FROM_DATABASE=APPLIED INTELLIGENT SYSTEMS, INC.
+OUI:00E04D*
+ ID_OUI_FROM_DATABASE=INTERNET INITIATIVE JAPAN, INC
-OUI:00101E*
- ID_OUI_FROM_DATABASE=MATSUSHITA ELECTRONIC INSTRUMENTS CORP.
+OUI:00607F*
+ ID_OUI_FROM_DATABASE=AURORA TECHNOLOGIES, INC.
-OUI:0010F2*
- ID_OUI_FROM_DATABASE=ANTEC
+OUI:00E039*
+ ID_OUI_FROM_DATABASE=PARADYNE CORP.
-OUI:0010BE*
- ID_OUI_FROM_DATABASE=MARCH NETWORKS CORPORATION
+OUI:006091*
+ ID_OUI_FROM_DATABASE=FIRST PACIFIC NETWORKS, INC.
+
+OUI:006002*
+ ID_OUI_FROM_DATABASE=SCREEN SUBTITLING SYSTEMS, LTD
+
+OUI:006061*
+ ID_OUI_FROM_DATABASE=WHISTLE COMMUNICATIONS CORP.
+
+OUI:0060BD*
+ ID_OUI_FROM_DATABASE=HUBBELL-PULSECOM
+
+OUI:00E0A1*
+ ID_OUI_FROM_DATABASE=HIMA PAUL HILDEBRANDT GmbH Co. KG
+
+OUI:00E028*
+ ID_OUI_FROM_DATABASE=APTIX CORPORATION
+
+OUI:00E0F2*
+ ID_OUI_FROM_DATABASE=ARLOTTO COMNET, INC.
+
+OUI:00E020*
+ ID_OUI_FROM_DATABASE=TECNOMEN OY
OUI:00E0C5*
ID_OUI_FROM_DATABASE=BCOM ELECTRONICS INC.
@@ -43007,50 +44021,71 @@ OUI:00E0F0*
OUI:00E0B7*
ID_OUI_FROM_DATABASE=PI GROUP, LTD.
-OUI:00E0C0*
- ID_OUI_FROM_DATABASE=SEIWA ELECTRIC MFG. CO., LTD.
+OUI:0010B1*
+ ID_OUI_FROM_DATABASE=FOR-A CO., LTD.
-OUI:006098*
- ID_OUI_FROM_DATABASE=HT COMMUNICATIONS
+OUI:001041*
+ ID_OUI_FROM_DATABASE=BRISTOL BABCOCK, INC.
-OUI:0060F7*
- ID_OUI_FROM_DATABASE=DATAFUSION SYSTEMS
+OUI:0010F7*
+ ID_OUI_FROM_DATABASE=IRIICHI TECHNOLOGIES Inc.
-OUI:0060DE*
- ID_OUI_FROM_DATABASE=Kayser-Threde GmbH
+OUI:0010E6*
+ ID_OUI_FROM_DATABASE=APPLIED INTELLIGENT SYSTEMS, INC.
-OUI:0060D0*
- ID_OUI_FROM_DATABASE=SNMP RESEARCH INCORPORATED
+OUI:00101E*
+ ID_OUI_FROM_DATABASE=MATSUSHITA ELECTRONIC INSTRUMENTS CORP.
-OUI:006079*
- ID_OUI_FROM_DATABASE=Mainstream Data, Inc.
+OUI:0010F2*
+ ID_OUI_FROM_DATABASE=ANTEC
-OUI:006020*
- ID_OUI_FROM_DATABASE=PIVOTAL NETWORKING, INC.
+OUI:0010BE*
+ ID_OUI_FROM_DATABASE=MARCH NETWORKS CORPORATION
-OUI:0005A8*
- ID_OUI_FROM_DATABASE=WYLE ELECTRONICS
+OUI:006058*
+ ID_OUI_FROM_DATABASE=COPPER MOUNTAIN COMMUNICATIONS, INC.
-OUI:0060B7*
- ID_OUI_FROM_DATABASE=CHANNELMATIC, INC.
+OUI:00601B*
+ ID_OUI_FROM_DATABASE=MESA ELECTRONICS
-OUI:0060A3*
- ID_OUI_FROM_DATABASE=CONTINUUM TECHNOLOGY CORP.
+OUI:0060FF*
+ ID_OUI_FROM_DATABASE=QuVis, Inc.
-OUI:006050*
- ID_OUI_FROM_DATABASE=INTERNIX INC.
+OUI:006056*
+ ID_OUI_FROM_DATABASE=NETWORK TOOLS, INC.
-OUI:0060E0*
- ID_OUI_FROM_DATABASE=AXIOM TECHNOLOGY CO., LTD.
+OUI:0060D8*
+ ID_OUI_FROM_DATABASE=ELMIC SYSTEMS, INC.
-OUI:0060A8*
- ID_OUI_FROM_DATABASE=TIDOMAT AB
+OUI:00607A*
+ ID_OUI_FROM_DATABASE=DVS GMBH
-OUI:00608E*
- ID_OUI_FROM_DATABASE=HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH
+OUI:006097*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
-OUI:0060F0*
- ID_OUI_FROM_DATABASE=JOHNSON & JOHNSON MEDICAL, INC
+OUI:0060E3*
+ ID_OUI_FROM_DATABASE=ARBIN INSTRUMENTS
+
+OUI:00E0FD*
+ ID_OUI_FROM_DATABASE=A-TREND TECHNOLOGY CO., LTD.
+
+OUI:00E0FB*
+ ID_OUI_FROM_DATABASE=LEIGHTRONIX, INC.
+
+OUI:00E0D3*
+ ID_OUI_FROM_DATABASE=DATENTECHNIK GmbH
+
+OUI:00E05E*
+ ID_OUI_FROM_DATABASE=JAPAN AVIATION ELECTRONICS INDUSTRY, LTD.
+
+OUI:00E0E5*
+ ID_OUI_FROM_DATABASE=CINCO NETWORKS, INC.
+
+OUI:00A0FD*
+ ID_OUI_FROM_DATABASE=SCITEX DIGITAL PRINTING, INC.
+
+OUI:00A0F5*
+ ID_OUI_FROM_DATABASE=RADGUARD LTD.
OUI:00A022*
ID_OUI_FROM_DATABASE=CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING
@@ -43091,6 +44126,57 @@ OUI:00A065*
OUI:00A044*
ID_OUI_FROM_DATABASE=NTT IT CO., LTD.
+OUI:006008*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:0060EF*
+ ID_OUI_FROM_DATABASE=FLYTECH TECHNOLOGY CO., LTD.
+
+OUI:006098*
+ ID_OUI_FROM_DATABASE=HT COMMUNICATIONS
+
+OUI:0060F7*
+ ID_OUI_FROM_DATABASE=DATAFUSION SYSTEMS
+
+OUI:0060DE*
+ ID_OUI_FROM_DATABASE=Kayser-Threde GmbH
+
+OUI:0060D0*
+ ID_OUI_FROM_DATABASE=SNMP RESEARCH INCORPORATED
+
+OUI:006079*
+ ID_OUI_FROM_DATABASE=Mainstream Data, Inc.
+
+OUI:006020*
+ ID_OUI_FROM_DATABASE=PIVOTAL NETWORKING, INC.
+
+OUI:0005A8*
+ ID_OUI_FROM_DATABASE=WYLE ELECTRONICS
+
+OUI:0060B7*
+ ID_OUI_FROM_DATABASE=CHANNELMATIC, INC.
+
+OUI:0060A3*
+ ID_OUI_FROM_DATABASE=CONTINUUM TECHNOLOGY CORP.
+
+OUI:006050*
+ ID_OUI_FROM_DATABASE=INTERNIX INC.
+
+OUI:0060E0*
+ ID_OUI_FROM_DATABASE=AXIOM TECHNOLOGY CO., LTD.
+
+OUI:0060A8*
+ ID_OUI_FROM_DATABASE=TIDOMAT AB
+
+OUI:00A056*
+ ID_OUI_FROM_DATABASE=MICROPROSS
+
+OUI:00A051*
+ ID_OUI_FROM_DATABASE=ANGIA COMMUNICATIONS. INC.
+
+OUI:00A0A6*
+ ID_OUI_FROM_DATABASE=M.I. SYSTEMS, K.K.
+
OUI:00A05F*
ID_OUI_FROM_DATABASE=BTG Electronics Design BV
@@ -43100,9 +44186,6 @@ OUI:00A094*
OUI:00A010*
ID_OUI_FROM_DATABASE=SYSLOGIC DATENTECHNIK AG
-OUI:00A012*
- ID_OUI_FROM_DATABASE=Telco Systems, Inc.
-
OUI:00A063*
ID_OUI_FROM_DATABASE=JRL SYSTEMS, INC.
@@ -43121,8 +44204,32 @@ OUI:00A0F7*
OUI:00A09C*
ID_OUI_FROM_DATABASE=Xyplex, Inc.
-OUI:00A0A0*
- ID_OUI_FROM_DATABASE=COMPACT DATA, LTD.
+OUI:00A092*
+ ID_OUI_FROM_DATABASE=H. BOLLMANN MANUFACTURERS, LTD
+
+OUI:00A04D*
+ ID_OUI_FROM_DATABASE=EDA INSTRUMENTS, INC.
+
+OUI:00A0DB*
+ ID_OUI_FROM_DATABASE=FISHER & PAYKEL PRODUCTION
+
+OUI:00A0A5*
+ ID_OUI_FROM_DATABASE=TEKNOR MICROSYSTEME, INC.
+
+OUI:00A018*
+ ID_OUI_FROM_DATABASE=CREATIVE CONTROLLERS, INC.
+
+OUI:00A09F*
+ ID_OUI_FROM_DATABASE=COMMVISION CORP.
+
+OUI:00A06B*
+ ID_OUI_FROM_DATABASE=DMS DORSCH MIKROSYSTEM GMBH
+
+OUI:006051*
+ ID_OUI_FROM_DATABASE=QUALITY SEMICONDUCTOR
+
+OUI:00605E*
+ ID_OUI_FROM_DATABASE=LIBERTY TECHNOLOGY NETWORKING
OUI:0060C6*
ID_OUI_FROM_DATABASE=DCS AG
@@ -43148,14 +44255,11 @@ OUI:00A039*
OUI:00A06D*
ID_OUI_FROM_DATABASE=MANNESMANN TALLY CORPORATION
-OUI:00A056*
- ID_OUI_FROM_DATABASE=MICROPROSS
-
-OUI:00A051*
- ID_OUI_FROM_DATABASE=ANGIA COMMUNICATIONS. INC.
+OUI:00608E*
+ ID_OUI_FROM_DATABASE=HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH
-OUI:00A0A6*
- ID_OUI_FROM_DATABASE=M.I. SYSTEMS, K.K.
+OUI:0060F0*
+ ID_OUI_FROM_DATABASE=JOHNSON & JOHNSON MEDICAL, INC
OUI:0060D2*
ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES TAIWAN TELECOMMUNICATIONS CO., LTD.
@@ -43175,74 +44279,101 @@ OUI:00608B*
OUI:0060C3*
ID_OUI_FROM_DATABASE=NETVISION CORPORATION
-OUI:006051*
- ID_OUI_FROM_DATABASE=QUALITY SEMICONDUCTOR
+OUI:00A0A0*
+ ID_OUI_FROM_DATABASE=COMPACT DATA, LTD.
-OUI:00605E*
- ID_OUI_FROM_DATABASE=LIBERTY TECHNOLOGY NETWORKING
+OUI:00A024*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
-OUI:006058*
- ID_OUI_FROM_DATABASE=COPPER MOUNTAIN COMMUNICATIONS, INC.
+OUI:00A08B*
+ ID_OUI_FROM_DATABASE=ASTON ELECTRONIC DESIGNS LTD.
-OUI:00601B*
- ID_OUI_FROM_DATABASE=MESA ELECTRONICS
+OUI:00A0AA*
+ ID_OUI_FROM_DATABASE=SPACELABS MEDICAL
-OUI:0060FF*
- ID_OUI_FROM_DATABASE=QuVis, Inc.
+OUI:00A04F*
+ ID_OUI_FROM_DATABASE=AMERITEC CORP.
-OUI:006056*
- ID_OUI_FROM_DATABASE=NETWORK TOOLS, INC.
+OUI:00A073*
+ ID_OUI_FROM_DATABASE=COM21, INC.
-OUI:0060D8*
- ID_OUI_FROM_DATABASE=ELMIC SYSTEMS, INC.
+OUI:00A084*
+ ID_OUI_FROM_DATABASE=Dataplex Pty Ltd
-OUI:00607A*
- ID_OUI_FROM_DATABASE=DVS GMBH
+OUI:00A034*
+ ID_OUI_FROM_DATABASE=AXEL
-OUI:006097*
- ID_OUI_FROM_DATABASE=3COM CORPORATION
+OUI:00C0BC*
+ ID_OUI_FROM_DATABASE=TELECOM AUSTRALIA/CSSC
-OUI:0060E3*
- ID_OUI_FROM_DATABASE=ARBIN INSTRUMENTS
+OUI:00C0EF*
+ ID_OUI_FROM_DATABASE=ABIT CORPORATION
-OUI:006008*
- ID_OUI_FROM_DATABASE=3COM CORPORATION
+OUI:00C03C*
+ ID_OUI_FROM_DATABASE=TOWER TECH S.R.L.
-OUI:0060EF*
- ID_OUI_FROM_DATABASE=FLYTECH TECHNOLOGY CO., LTD.
+OUI:00C061*
+ ID_OUI_FROM_DATABASE=SOLECTEK CORPORATION
-OUI:00E04D*
- ID_OUI_FROM_DATABASE=INTERNET INITIATIVE JAPAN, INC
+OUI:00C074*
+ ID_OUI_FROM_DATABASE=TOYODA AUTOMATIC LOOM
-OUI:00607F*
- ID_OUI_FROM_DATABASE=AURORA TECHNOLOGIES, INC.
+OUI:00C07F*
+ ID_OUI_FROM_DATABASE=NUPON COMPUTING CORP.
-OUI:00E039*
- ID_OUI_FROM_DATABASE=PARADYNE CORP.
+OUI:00C027*
+ ID_OUI_FROM_DATABASE=CIPHER SYSTEMS, INC.
-OUI:006091*
- ID_OUI_FROM_DATABASE=FIRST PACIFIC NETWORKS, INC.
+OUI:00C025*
+ ID_OUI_FROM_DATABASE=DATAPRODUCTS CORPORATION
-OUI:006002*
- ID_OUI_FROM_DATABASE=SCREEN SUBTITLING SYSTEMS, LTD
+OUI:00C022*
+ ID_OUI_FROM_DATABASE=LASERMASTER TECHNOLOGIES, INC.
-OUI:006061*
- ID_OUI_FROM_DATABASE=WHISTLE COMMUNICATIONS CORP.
+OUI:00C0E6*
+ ID_OUI_FROM_DATABASE=Verilink Corporation
-OUI:0060BD*
- ID_OUI_FROM_DATABASE=HUBBELL-PULSECOM
+OUI:00C05C*
+ ID_OUI_FROM_DATABASE=ELONEX PLC
-OUI:006074*
- ID_OUI_FROM_DATABASE=QSC AUDIO PRODUCTS
+OUI:00C0C1*
+ ID_OUI_FROM_DATABASE=QUAD/GRAPHICS, INC.
-OUI:00A024*
- ID_OUI_FROM_DATABASE=3COM CORPORATION
+OUI:00C091*
+ ID_OUI_FROM_DATABASE=JABIL CIRCUIT, INC.
-OUI:00A0FD*
- ID_OUI_FROM_DATABASE=SCITEX DIGITAL PRINTING, INC.
+OUI:00C002*
+ ID_OUI_FROM_DATABASE=SERCOMM CORPORATION
-OUI:00A0F5*
- ID_OUI_FROM_DATABASE=RADGUARD LTD.
+OUI:00C0F5*
+ ID_OUI_FROM_DATABASE=METACOMP, INC.
+
+OUI:00C042*
+ ID_OUI_FROM_DATABASE=DATALUX CORP.
+
+OUI:00C089*
+ ID_OUI_FROM_DATABASE=TELINDUS DISTRIBUTION
+
+OUI:00C09D*
+ ID_OUI_FROM_DATABASE=DISTRIBUTED SYSTEMS INT'L, INC
+
+OUI:00C0A5*
+ ID_OUI_FROM_DATABASE=DICKENS DATA SYSTEMS
+
+OUI:00C0E3*
+ ID_OUI_FROM_DATABASE=OSITECH COMMUNICATIONS, INC.
+
+OUI:00C071*
+ ID_OUI_FROM_DATABASE=AREANEX COMMUNICATIONS, INC.
+
+OUI:00C0AF*
+ ID_OUI_FROM_DATABASE=TEKLOGIX INC.
+
+OUI:00209F*
+ ID_OUI_FROM_DATABASE=MERCURY COMPUTER SYSTEMS, INC.
+
+OUI:0020B7*
+ ID_OUI_FROM_DATABASE=NAMAQUA COMPUTERWARE
OUI:00201B*
ID_OUI_FROM_DATABASE=NORTHERN TELECOM/NETWORK
@@ -43286,39 +44417,6 @@ OUI:00206B*
OUI:0020FC*
ID_OUI_FROM_DATABASE=MATROX
-OUI:002035*
- ID_OUI_FROM_DATABASE=IBM Corp
-
-OUI:0020E2*
- ID_OUI_FROM_DATABASE=INFORMATION RESOURCE ENGINEERING
-
-OUI:002058*
- ID_OUI_FROM_DATABASE=ALLIED SIGNAL INC.
-
-OUI:00208C*
- ID_OUI_FROM_DATABASE=GALAXY NETWORKS, INC.
-
-OUI:002063*
- ID_OUI_FROM_DATABASE=WIPRO INFOTECH LTD.
-
-OUI:0020DC*
- ID_OUI_FROM_DATABASE=DENSITRON TAIWAN LTD.
-
-OUI:002078*
- ID_OUI_FROM_DATABASE=RUNTOP, INC.
-
-OUI:002042*
- ID_OUI_FROM_DATABASE=DATAMETRICS CORP.
-
-OUI:0020F8*
- ID_OUI_FROM_DATABASE=CARRERA COMPUTERS, INC.
-
-OUI:00200C*
- ID_OUI_FROM_DATABASE=ADASTRA SYSTEMS CORP.
-
-OUI:0020C4*
- ID_OUI_FROM_DATABASE=INET,INC.
-
OUI:00C003*
ID_OUI_FROM_DATABASE=GLOBALNET COMMUNICATIONS
@@ -43331,26 +44429,26 @@ OUI:00C04D*
OUI:00C055*
ID_OUI_FROM_DATABASE=MODULAR COMPUTING TECHNOLOGIES
-OUI:00A0DB*
- ID_OUI_FROM_DATABASE=FISHER & PAYKEL PRODUCTION
+OUI:00C067*
+ ID_OUI_FROM_DATABASE=UNITED BARCODE INDUSTRIES
-OUI:00A0A5*
- ID_OUI_FROM_DATABASE=TEKNOR MICROSYSTEME, INC.
+OUI:00C0B4*
+ ID_OUI_FROM_DATABASE=MYSON TECHNOLOGY, INC.
-OUI:00A018*
- ID_OUI_FROM_DATABASE=CREATIVE CONTROLLERS, INC.
+OUI:00C080*
+ ID_OUI_FROM_DATABASE=NETSTAR, INC.
-OUI:00A09F*
- ID_OUI_FROM_DATABASE=COMMVISION CORP.
+OUI:00C015*
+ ID_OUI_FROM_DATABASE=NEW MEDIA CORPORATION
-OUI:00A06B*
- ID_OUI_FROM_DATABASE=DMS DORSCH MIKROSYSTEM GMBH
+OUI:0070B3*
+ ID_OUI_FROM_DATABASE=DATA RECALL LTD.
-OUI:00209F*
- ID_OUI_FROM_DATABASE=MERCURY COMPUTER SYSTEMS, INC.
+OUI:00E6D3*
+ ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORP.
-OUI:0020B7*
- ID_OUI_FROM_DATABASE=NAMAQUA COMPUTERWARE
+OUI:00C083*
+ ID_OUI_FROM_DATABASE=TRACE MOUNTAIN PRODUCTS, INC.
OUI:00C005*
ID_OUI_FROM_DATABASE=LIVINGSTON ENTERPRISES, INC.
@@ -43385,35 +44483,44 @@ OUI:00C0C6*
OUI:00C03B*
ID_OUI_FROM_DATABASE=MULTIACCESS COMPUTING CORP.
-OUI:00C099*
- ID_OUI_FROM_DATABASE=YOSHIKI INDUSTRIAL CO.,LTD.
+OUI:0020F4*
+ ID_OUI_FROM_DATABASE=SPECTRIX CORPORATION
-OUI:00C0FC*
- ID_OUI_FROM_DATABASE=ELASTIC REALITY, INC.
+OUI:00204E*
+ ID_OUI_FROM_DATABASE=NETWORK SECURITY SYSTEMS, INC.
-OUI:00C067*
- ID_OUI_FROM_DATABASE=UNITED BARCODE INDUSTRIES
+OUI:002027*
+ ID_OUI_FROM_DATABASE=MING FORTUNE INDUSTRY CO., LTD
-OUI:00C0B4*
- ID_OUI_FROM_DATABASE=MYSON TECHNOLOGY, INC.
+OUI:0020ED*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO., LTD.
-OUI:00C080*
- ID_OUI_FROM_DATABASE=NETSTAR, INC.
+OUI:00200E*
+ ID_OUI_FROM_DATABASE=SATELLITE TECHNOLOGY MGMT, INC
-OUI:00C015*
- ID_OUI_FROM_DATABASE=NEW MEDIA CORPORATION
+OUI:002096*
+ ID_OUI_FROM_DATABASE=Invensys
-OUI:00C09F*
- ID_OUI_FROM_DATABASE=QUANTA COMPUTER, INC.
+OUI:0020BB*
+ ID_OUI_FROM_DATABASE=ZAX CORPORATION
-OUI:0070B3*
- ID_OUI_FROM_DATABASE=DATA RECALL LTD.
+OUI:00204D*
+ ID_OUI_FROM_DATABASE=INOVIS GMBH
-OUI:00E6D3*
- ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORP.
+OUI:002089*
+ ID_OUI_FROM_DATABASE=T3PLUS NETWORKING, INC.
-OUI:00C083*
- ID_OUI_FROM_DATABASE=TRACE MOUNTAIN PRODUCTS, INC.
+OUI:00205F*
+ ID_OUI_FROM_DATABASE=GAMMADATA COMPUTER GMBH
+
+OUI:002035*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:0020E2*
+ ID_OUI_FROM_DATABASE=INFORMATION RESOURCE ENGINEERING
+
+OUI:002058*
+ ID_OUI_FROM_DATABASE=ALLIED SIGNAL INC.
OUI:002081*
ID_OUI_FROM_DATABASE=TITAN ELECTRONICS
@@ -43439,65 +44546,65 @@ OUI:0020DE*
OUI:0020F7*
ID_OUI_FROM_DATABASE=CYBERDATA CORPORATION
-OUI:000267*
- ID_OUI_FROM_DATABASE=NODE RUNNER, INC.
+OUI:0020EE*
+ ID_OUI_FROM_DATABASE=GTECH CORPORATION
-OUI:002064*
- ID_OUI_FROM_DATABASE=PROTEC MICROSYSTEMS, INC.
+OUI:00208C*
+ ID_OUI_FROM_DATABASE=GALAXY NETWORKS, INC.
-OUI:002032*
- ID_OUI_FROM_DATABASE=ALCATEL TAISEL
+OUI:002063*
+ ID_OUI_FROM_DATABASE=WIPRO INFOTECH LTD.
-OUI:002027*
- ID_OUI_FROM_DATABASE=MING FORTUNE INDUSTRY CO., LTD
+OUI:0020DC*
+ ID_OUI_FROM_DATABASE=DENSITRON TAIWAN LTD.
-OUI:0020ED*
- ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO., LTD.
+OUI:002078*
+ ID_OUI_FROM_DATABASE=RUNTOP, INC.
-OUI:00200E*
- ID_OUI_FROM_DATABASE=SATELLITE TECHNOLOGY MGMT, INC
+OUI:002042*
+ ID_OUI_FROM_DATABASE=DATAMETRICS CORP.
-OUI:002096*
- ID_OUI_FROM_DATABASE=Invensys
+OUI:0020F8*
+ ID_OUI_FROM_DATABASE=CARRERA COMPUTERS, INC.
-OUI:0020BB*
- ID_OUI_FROM_DATABASE=ZAX CORPORATION
+OUI:00200C*
+ ID_OUI_FROM_DATABASE=ADASTRA SYSTEMS CORP.
-OUI:00204D*
- ID_OUI_FROM_DATABASE=INOVIS GMBH
+OUI:0020C4*
+ ID_OUI_FROM_DATABASE=INET,INC.
-OUI:002089*
- ID_OUI_FROM_DATABASE=T3PLUS NETWORKING, INC.
+OUI:00C099*
+ ID_OUI_FROM_DATABASE=YOSHIKI INDUSTRIAL CO.,LTD.
-OUI:00205F*
- ID_OUI_FROM_DATABASE=GAMMADATA COMPUTER GMBH
+OUI:00C0FC*
+ ID_OUI_FROM_DATABASE=ELASTIC REALITY, INC.
-OUI:0020EE*
- ID_OUI_FROM_DATABASE=GTECH CORPORATION
+OUI:00C0D0*
+ ID_OUI_FROM_DATABASE=RATOC SYSTEM INC.
-OUI:00A08B*
- ID_OUI_FROM_DATABASE=ASTON ELECTRONIC DESIGNS LTD.
+OUI:00C07A*
+ ID_OUI_FROM_DATABASE=PRIVA B.V.
-OUI:00A0AA*
- ID_OUI_FROM_DATABASE=SPACELABS MEDICAL
+OUI:000701*
+ ID_OUI_FROM_DATABASE=RACAL-DATACOM
-OUI:00A04F*
- ID_OUI_FROM_DATABASE=AMERITEC CORP.
+OUI:00C09C*
+ ID_OUI_FROM_DATABASE=HIOKI E.E. CORPORATION
-OUI:00A073*
- ID_OUI_FROM_DATABASE=COM21, INC.
+OUI:00C004*
+ ID_OUI_FROM_DATABASE=JAPAN BUSINESS COMPUTER CO.LTD
-OUI:00A084*
- ID_OUI_FROM_DATABASE=Dataplex Pty Ltd
+OUI:00C062*
+ ID_OUI_FROM_DATABASE=IMPULSE TECHNOLOGY
-OUI:00A034*
- ID_OUI_FROM_DATABASE=AXEL
+OUI:000267*
+ ID_OUI_FROM_DATABASE=NODE RUNNER, INC.
-OUI:00A092*
- ID_OUI_FROM_DATABASE=H. BOLLMANN MANUFACTURERS, LTD
+OUI:002064*
+ ID_OUI_FROM_DATABASE=PROTEC MICROSYSTEMS, INC.
-OUI:00A04D*
- ID_OUI_FROM_DATABASE=EDA INSTRUMENTS, INC.
+OUI:002032*
+ ID_OUI_FROM_DATABASE=ALCATEL TAISEL
OUI:00207F*
ID_OUI_FROM_DATABASE=KYOEI SANGYO CO., LTD.
@@ -43511,71 +44618,83 @@ OUI:002068*
OUI:00202A*
ID_OUI_FROM_DATABASE=N.V. DZINE
-OUI:0020F4*
- ID_OUI_FROM_DATABASE=SPECTRIX CORPORATION
+OUI:008006*
+ ID_OUI_FROM_DATABASE=COMPUADD CORPORATION
-OUI:00204E*
- ID_OUI_FROM_DATABASE=NETWORK SECURITY SYSTEMS, INC.
+OUI:0080EF*
+ ID_OUI_FROM_DATABASE=RATIONAL
-OUI:00C074*
- ID_OUI_FROM_DATABASE=TOYODA AUTOMATIC LOOM
+OUI:0080C4*
+ ID_OUI_FROM_DATABASE=DOCUMENT TECHNOLOGIES, INC.
-OUI:00C07F*
- ID_OUI_FROM_DATABASE=NUPON COMPUTING CORP.
+OUI:008095*
+ ID_OUI_FROM_DATABASE=BASIC MERTON HANDELSGES.M.B.H.
-OUI:00C027*
- ID_OUI_FROM_DATABASE=CIPHER SYSTEMS, INC.
+OUI:008053*
+ ID_OUI_FROM_DATABASE=INTELLICOM, INC.
-OUI:00C025*
- ID_OUI_FROM_DATABASE=DATAPRODUCTS CORPORATION
+OUI:008026*
+ ID_OUI_FROM_DATABASE=NETWORK PRODUCTS CORPORATION
-OUI:00C022*
- ID_OUI_FROM_DATABASE=LASERMASTER TECHNOLOGIES, INC.
+OUI:0080FE*
+ ID_OUI_FROM_DATABASE=AZURE TECHNOLOGIES, INC.
-OUI:00C0E6*
- ID_OUI_FROM_DATABASE=Verilink Corporation
+OUI:008028*
+ ID_OUI_FROM_DATABASE=TRADPOST (HK) LTD
-OUI:00C05C*
- ID_OUI_FROM_DATABASE=ELONEX PLC
+OUI:0080B6*
+ ID_OUI_FROM_DATABASE=THEMIS COMPUTER
-OUI:00C0C1*
- ID_OUI_FROM_DATABASE=QUAD/GRAPHICS, INC.
+OUI:0080C0*
+ ID_OUI_FROM_DATABASE=PENRIL DATACOMM
-OUI:00C091*
- ID_OUI_FROM_DATABASE=JABIL CIRCUIT, INC.
+OUI:0080F5*
+ ID_OUI_FROM_DATABASE=Quantel Ltd
-OUI:00C002*
- ID_OUI_FROM_DATABASE=SERCOMM CORPORATION
+OUI:00401D*
+ ID_OUI_FROM_DATABASE=INVISIBLE SOFTWARE, INC.
-OUI:00C0F5*
- ID_OUI_FROM_DATABASE=METACOMP, INC.
+OUI:0040BD*
+ ID_OUI_FROM_DATABASE=STARLIGHT NETWORKS, INC.
-OUI:00C042*
- ID_OUI_FROM_DATABASE=DATALUX CORP.
+OUI:00406D*
+ ID_OUI_FROM_DATABASE=LANCO, INC.
-OUI:00C089*
- ID_OUI_FROM_DATABASE=TELINDUS DISTRIBUTION
+OUI:00404D*
+ ID_OUI_FROM_DATABASE=TELECOMMUNICATIONS TECHNIQUES
-OUI:00C09D*
- ID_OUI_FROM_DATABASE=DISTRIBUTED SYSTEMS INT'L, INC
+OUI:0040A5*
+ ID_OUI_FROM_DATABASE=CLINICOMP INTL.
-OUI:00C0A5*
- ID_OUI_FROM_DATABASE=DICKENS DATA SYSTEMS
+OUI:004059*
+ ID_OUI_FROM_DATABASE=YOSHIDA KOGYO K. K.
-OUI:00C0E3*
- ID_OUI_FROM_DATABASE=OSITECH COMMUNICATIONS, INC.
+OUI:004021*
+ ID_OUI_FROM_DATABASE=RASTER GRAPHICS
-OUI:00C071*
- ID_OUI_FROM_DATABASE=AREANEX COMMUNICATIONS, INC.
+OUI:004081*
+ ID_OUI_FROM_DATABASE=MANNESMANN SCANGRAPHIC GMBH
-OUI:00C0AF*
- ID_OUI_FROM_DATABASE=TEKLOGIX INC.
+OUI:00806C*
+ ID_OUI_FROM_DATABASE=CEGELEC PROJECTS LTD
-OUI:00C05D*
- ID_OUI_FROM_DATABASE=L&N TECHNOLOGIES
+OUI:00404A*
+ ID_OUI_FROM_DATABASE=WEST AUSTRALIAN DEPARTMENT
-OUI:00C0E4*
- ID_OUI_FROM_DATABASE=SIEMENS BUILDING
+OUI:00400A*
+ ID_OUI_FROM_DATABASE=PIVOTAL TECHNOLOGIES, INC.
+
+OUI:004032*
+ ID_OUI_FROM_DATABASE=DIGITAL COMMUNICATIONS
+
+OUI:004042*
+ ID_OUI_FROM_DATABASE=N.A.T. GMBH
+
+OUI:0040C2*
+ ID_OUI_FROM_DATABASE=APPLIED COMPUTING DEVICES
+
+OUI:00403C*
+ ID_OUI_FROM_DATABASE=FORKS, INC.
OUI:0040C4*
ID_OUI_FROM_DATABASE=KINKEI SYSTEM CORPORATION
@@ -43601,8 +44720,38 @@ OUI:004090*
OUI:00409A*
ID_OUI_FROM_DATABASE=NETWORK EXPRESS, INC.
-OUI:004055*
- ID_OUI_FROM_DATABASE=METRONIX GMBH
+OUI:0040DE*
+ ID_OUI_FROM_DATABASE=Elsag Datamat spa
+
+OUI:004063*
+ ID_OUI_FROM_DATABASE=VIA TECHNOLOGIES, INC.
+
+OUI:00406C*
+ ID_OUI_FROM_DATABASE=COPERNIQUE
+
+OUI:0040DF*
+ ID_OUI_FROM_DATABASE=DIGALOG SYSTEMS, INC.
+
+OUI:004015*
+ ID_OUI_FROM_DATABASE=ASCOM INFRASYS AG
+
+OUI:008056*
+ ID_OUI_FROM_DATABASE=SPHINX Electronics GmbH & Co KG
+
+OUI:008060*
+ ID_OUI_FROM_DATABASE=NETWORK INTERFACE CORPORATION
+
+OUI:00805E*
+ ID_OUI_FROM_DATABASE=LSI LOGIC CORPORATION
+
+OUI:008093*
+ ID_OUI_FROM_DATABASE=XYRON CORPORATION
+
+OUI:00C05D*
+ ID_OUI_FROM_DATABASE=L&N TECHNOLOGIES
+
+OUI:00C0E4*
+ ID_OUI_FROM_DATABASE=SIEMENS BUILDING
OUI:00C01B*
ID_OUI_FROM_DATABASE=SOCKET COMMUNICATIONS, INC.
@@ -43628,47 +44777,23 @@ OUI:004037*
OUI:0040CC*
ID_OUI_FROM_DATABASE=SILCOM MANUF'G TECHNOLOGY INC.
-OUI:00404C*
- ID_OUI_FROM_DATABASE=HYPERTEC PTY LTD.
-
-OUI:00C0EE*
- ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
-
-OUI:0040A5*
- ID_OUI_FROM_DATABASE=CLINICOMP INTL.
-
-OUI:004059*
- ID_OUI_FROM_DATABASE=YOSHIDA KOGYO K. K.
-
-OUI:004021*
- ID_OUI_FROM_DATABASE=RASTER GRAPHICS
-
-OUI:004081*
- ID_OUI_FROM_DATABASE=MANNESMANN SCANGRAPHIC GMBH
-
-OUI:00806C*
- ID_OUI_FROM_DATABASE=CEGELEC PROJECTS LTD
-
-OUI:00404A*
- ID_OUI_FROM_DATABASE=WEST AUSTRALIAN DEPARTMENT
-
-OUI:00400A*
- ID_OUI_FROM_DATABASE=PIVOTAL TECHNOLOGIES, INC.
+OUI:004052*
+ ID_OUI_FROM_DATABASE=STAR TECHNOLOGIES, INC.
-OUI:004032*
- ID_OUI_FROM_DATABASE=DIGITAL COMMUNICATIONS
+OUI:00407A*
+ ID_OUI_FROM_DATABASE=SOCIETE D'EXPLOITATION DU CNIT
-OUI:004042*
- ID_OUI_FROM_DATABASE=N.A.T. GMBH
+OUI:004089*
+ ID_OUI_FROM_DATABASE=MEIDENSHA CORPORATION
-OUI:0040C2*
- ID_OUI_FROM_DATABASE=APPLIED COMPUTING DEVICES
+OUI:00405A*
+ ID_OUI_FROM_DATABASE=GOLDSTAR INFORMATION & COMM.
-OUI:00403C*
- ID_OUI_FROM_DATABASE=FORKS, INC.
+OUI:00404C*
+ ID_OUI_FROM_DATABASE=HYPERTEC PTY LTD.
-OUI:004004*
- ID_OUI_FROM_DATABASE=ICM CO. LTD.
+OUI:00C0EE*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
OUI:00C0CB*
ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY CORPORATION
@@ -43682,47 +44807,8 @@ OUI:00C01A*
OUI:00404B*
ID_OUI_FROM_DATABASE=MAPLE COMPUTER SYSTEMS
-OUI:00401D*
- ID_OUI_FROM_DATABASE=INVISIBLE SOFTWARE, INC.
-
-OUI:0040BD*
- ID_OUI_FROM_DATABASE=STARLIGHT NETWORKS, INC.
-
-OUI:00406D*
- ID_OUI_FROM_DATABASE=LANCO, INC.
-
-OUI:00404D*
- ID_OUI_FROM_DATABASE=TELECOMMUNICATIONS TECHNIQUES
-
-OUI:00C0D0*
- ID_OUI_FROM_DATABASE=RATOC SYSTEM INC.
-
-OUI:00C07A*
- ID_OUI_FROM_DATABASE=PRIVA B.V.
-
-OUI:000701*
- ID_OUI_FROM_DATABASE=RACAL-DATACOM
-
-OUI:00C09C*
- ID_OUI_FROM_DATABASE=HIOKI E.E. CORPORATION
-
-OUI:00C004*
- ID_OUI_FROM_DATABASE=JAPAN BUSINESS COMPUTER CO.LTD
-
-OUI:00C062*
- ID_OUI_FROM_DATABASE=IMPULSE TECHNOLOGY
-
-OUI:00C0BC*
- ID_OUI_FROM_DATABASE=TELECOM AUSTRALIA/CSSC
-
-OUI:00C0EF*
- ID_OUI_FROM_DATABASE=ABIT CORPORATION
-
-OUI:00C03C*
- ID_OUI_FROM_DATABASE=TOWER TECH S.R.L.
-
-OUI:00C061*
- ID_OUI_FROM_DATABASE=SOLECTEK CORPORATION
+OUI:004055*
+ ID_OUI_FROM_DATABASE=METRONIX GMBH
OUI:004045*
ID_OUI_FROM_DATABASE=TWINHEAD CORPORATION
@@ -43739,17 +44825,8 @@ OUI:0040B9*
OUI:0040C7*
ID_OUI_FROM_DATABASE=RUBY TECH CORPORATION
-OUI:004052*
- ID_OUI_FROM_DATABASE=STAR TECHNOLOGIES, INC.
-
-OUI:00407A*
- ID_OUI_FROM_DATABASE=SOCIETE D'EXPLOITATION DU CNIT
-
-OUI:004089*
- ID_OUI_FROM_DATABASE=MEIDENSHA CORPORATION
-
-OUI:00405A*
- ID_OUI_FROM_DATABASE=GOLDSTAR INFORMATION & COMM.
+OUI:004004*
+ ID_OUI_FROM_DATABASE=ICM CO. LTD.
OUI:004070*
ID_OUI_FROM_DATABASE=INTERWARE CO., LTD.
@@ -43766,41 +44843,14 @@ OUI:0080AA*
OUI:00C0E7*
ID_OUI_FROM_DATABASE=FIBERDATA AB
-OUI:008095*
- ID_OUI_FROM_DATABASE=BASIC MERTON HANDELSGES.M.B.H.
-
-OUI:008053*
- ID_OUI_FROM_DATABASE=INTELLICOM, INC.
-
-OUI:008026*
- ID_OUI_FROM_DATABASE=NETWORK PRODUCTS CORPORATION
-
-OUI:0080FE*
- ID_OUI_FROM_DATABASE=AZURE TECHNOLOGIES, INC.
-
-OUI:008028*
- ID_OUI_FROM_DATABASE=TRADPOST (HK) LTD
-
-OUI:0080B6*
- ID_OUI_FROM_DATABASE=THEMIS COMPUTER
-
-OUI:008058*
- ID_OUI_FROM_DATABASE=PRINTER SYSTEMS CORPORATION
-
-OUI:0080C0*
- ID_OUI_FROM_DATABASE=PENRIL DATACOMM
-
-OUI:0080F5*
- ID_OUI_FROM_DATABASE=Quantel Ltd
-
-OUI:00608C*
- ID_OUI_FROM_DATABASE=3COM CORPORATION
+OUI:00800A*
+ ID_OUI_FROM_DATABASE=JAPAN COMPUTER CORP.
-OUI:00804E*
- ID_OUI_FROM_DATABASE=APEX COMPUTER COMPANY
+OUI:00806E*
+ ID_OUI_FROM_DATABASE=NIPPON STEEL CORPORATION
-OUI:00800E*
- ID_OUI_FROM_DATABASE=ATLANTIX CORPORATION
+OUI:008010*
+ ID_OUI_FROM_DATABASE=COMMODORE INTERNATIONAL
OUI:0080DA*
ID_OUI_FROM_DATABASE=Bruel & Kjaer Sound & Vibration Measurement A/S
@@ -43823,74 +44873,50 @@ OUI:00807D*
OUI:008063*
ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH
-OUI:008030*
- ID_OUI_FROM_DATABASE=NEXUS ELECTRONICS
-
-OUI:008022*
- ID_OUI_FROM_DATABASE=SCAN-OPTICS
-
-OUI:000041*
- ID_OUI_FROM_DATABASE=ICE CORPORATION
-
-OUI:0040DE*
- ID_OUI_FROM_DATABASE=Elsag Datamat spa
-
-OUI:004063*
- ID_OUI_FROM_DATABASE=VIA TECHNOLOGIES, INC.
-
-OUI:00406C*
- ID_OUI_FROM_DATABASE=COPERNIQUE
-
-OUI:0040DF*
- ID_OUI_FROM_DATABASE=DIGALOG SYSTEMS, INC.
-
-OUI:004015*
- ID_OUI_FROM_DATABASE=ASCOM INFRASYS AG
-
-OUI:008056*
- ID_OUI_FROM_DATABASE=SPHINX Electronics GmbH & Co KG
+OUI:00608C*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
-OUI:008060*
- ID_OUI_FROM_DATABASE=NETWORK INTERFACE CORPORATION
+OUI:00804E*
+ ID_OUI_FROM_DATABASE=APEX COMPUTER COMPANY
-OUI:00805E*
- ID_OUI_FROM_DATABASE=LSI LOGIC CORPORATION
+OUI:00800E*
+ ID_OUI_FROM_DATABASE=ATLANTIX CORPORATION
-OUI:008093*
- ID_OUI_FROM_DATABASE=XYRON CORPORATION
+OUI:00806F*
+ ID_OUI_FROM_DATABASE=ONELAN LTD.
-OUI:008006*
- ID_OUI_FROM_DATABASE=COMPUADD CORPORATION
+OUI:008098*
+ ID_OUI_FROM_DATABASE=TDK CORPORATION
-OUI:0080EF*
- ID_OUI_FROM_DATABASE=RATIONAL
+OUI:00809C*
+ ID_OUI_FROM_DATABASE=LUXCOM, INC.
-OUI:0080C4*
- ID_OUI_FROM_DATABASE=DOCUMENT TECHNOLOGIES, INC.
+OUI:008065*
+ ID_OUI_FROM_DATABASE=CYBERGRAPHIC SYSTEMS PTY LTD.
-OUI:00801D*
- ID_OUI_FROM_DATABASE=INTEGRATED INFERENCE MACHINES
+OUI:008016*
+ ID_OUI_FROM_DATABASE=WANDEL AND GOLTERMANN
-OUI:008015*
- ID_OUI_FROM_DATABASE=SEIKO SYSTEMS, INC.
+OUI:0080E6*
+ ID_OUI_FROM_DATABASE=PEER NETWORKS, INC.
-OUI:008034*
- ID_OUI_FROM_DATABASE=SMT GOUPIL
+OUI:0080A2*
+ ID_OUI_FROM_DATABASE=CREATIVE ELECTRONIC SYSTEMS
-OUI:0080C9*
- ID_OUI_FROM_DATABASE=ALBERTA MICROELECTRONIC CENTRE
+OUI:0080E0*
+ ID_OUI_FROM_DATABASE=XTP SYSTEMS, INC.
-OUI:00800B*
- ID_OUI_FROM_DATABASE=CSK CORPORATION
+OUI:008050*
+ ID_OUI_FROM_DATABASE=ZIATECH CORPORATION
-OUI:00800A*
- ID_OUI_FROM_DATABASE=JAPAN COMPUTER CORP.
+OUI:0000E0*
+ ID_OUI_FROM_DATABASE=QUADRAM CORP.
-OUI:00806E*
- ID_OUI_FROM_DATABASE=NIPPON STEEL CORPORATION
+OUI:000057*
+ ID_OUI_FROM_DATABASE=SCITEX CORPORATION LTD.
-OUI:008010*
- ID_OUI_FROM_DATABASE=COMMODORE INTERNATIONAL
+OUI:0000D6*
+ ID_OUI_FROM_DATABASE=PUNCH LINE HOLDING
OUI:0000C8*
ID_OUI_FROM_DATABASE=ALTOS COMPUTER SYSTEMS
@@ -43919,56 +44945,56 @@ OUI:0000E7*
OUI:0000F3*
ID_OUI_FROM_DATABASE=GANDALF DATA LIMITED
-OUI:00005C*
- ID_OUI_FROM_DATABASE=TELEMATICS INTERNATIONAL INC.
+OUI:000064*
+ ID_OUI_FROM_DATABASE=Yokogawa Electric Corporation
-OUI:0000AC*
- ID_OUI_FROM_DATABASE=CONWARE COMPUTER CONSULTING
+OUI:00002C*
+ ID_OUI_FROM_DATABASE=AUTOTOTE LIMITED
-OUI:0000F2*
- ID_OUI_FROM_DATABASE=SPIDER COMMUNICATIONS
+OUI:00002A*
+ ID_OUI_FROM_DATABASE=TRW - SEDD/INP
-OUI:000030*
- ID_OUI_FROM_DATABASE=VG LABORATORY SYSTEMS LTD
+OUI:0000F1*
+ ID_OUI_FROM_DATABASE=MAGNA COMPUTER CORPORATION
-OUI:000035*
- ID_OUI_FROM_DATABASE=SPECTRAGRAPHICS CORPORATION
+OUI:000083*
+ ID_OUI_FROM_DATABASE=TADPOLE TECHNOLOGY PLC
-OUI:0000E0*
- ID_OUI_FROM_DATABASE=QUADRAM CORP.
+OUI:000020*
+ ID_OUI_FROM_DATABASE=DATAINDUSTRIER DIAB AB
-OUI:000057*
- ID_OUI_FROM_DATABASE=SCITEX CORPORATION LTD.
+OUI:00007A*
+ ID_OUI_FROM_DATABASE=DANA COMPUTER INC.
-OUI:0000D6*
- ID_OUI_FROM_DATABASE=PUNCH LINE HOLDING
+OUI:00007C*
+ ID_OUI_FROM_DATABASE=AMPERE INCORPORATED
-OUI:00806F*
- ID_OUI_FROM_DATABASE=ONELAN LTD.
+OUI:00008A*
+ ID_OUI_FROM_DATABASE=DATAHOUSE INFORMATION SYSTEMS
-OUI:008098*
- ID_OUI_FROM_DATABASE=TDK CORPORATION
+OUI:000068*
+ ID_OUI_FROM_DATABASE=ROSEMOUNT CONTROLS
-OUI:00809C*
- ID_OUI_FROM_DATABASE=LUXCOM, INC.
+OUI:0000A8*
+ ID_OUI_FROM_DATABASE=STRATUS COMPUTER INC.
-OUI:008065*
- ID_OUI_FROM_DATABASE=CYBERGRAPHIC SYSTEMS PTY LTD.
+OUI:0000DF*
+ ID_OUI_FROM_DATABASE=BELL & HOWELL PUB SYS DIV
-OUI:008016*
- ID_OUI_FROM_DATABASE=WANDEL AND GOLTERMANN
+OUI:000062*
+ ID_OUI_FROM_DATABASE=BULL HN INFORMATION SYSTEMS
-OUI:0080E6*
- ID_OUI_FROM_DATABASE=PEER NETWORKS, INC.
+OUI:0000AD*
+ ID_OUI_FROM_DATABASE=BRUKER INSTRUMENTS INC.
-OUI:0080A2*
- ID_OUI_FROM_DATABASE=CREATIVE ELECTRONIC SYSTEMS
+OUI:0000D0*
+ ID_OUI_FROM_DATABASE=DEVELCON ELECTRONICS LTD.
-OUI:0080E0*
- ID_OUI_FROM_DATABASE=XTP SYSTEMS, INC.
+OUI:000093*
+ ID_OUI_FROM_DATABASE=PROTEON INC.
-OUI:008050*
- ID_OUI_FROM_DATABASE=ZIATECH CORPORATION
+OUI:008008*
+ ID_OUI_FROM_DATABASE=DYNATECH COMPUTER SYSTEMS
OUI:0080FF*
ID_OUI_FROM_DATABASE=SOC. DE TELEINFORMATIQUE RTC
@@ -43988,8 +45014,14 @@ OUI:000024*
OUI:000048*
ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION
-OUI:000016*
- ID_OUI_FROM_DATABASE=DU PONT PIXEL SYSTEMS .
+OUI:008030*
+ ID_OUI_FROM_DATABASE=NEXUS ELECTRONICS
+
+OUI:008022*
+ ID_OUI_FROM_DATABASE=SCAN-OPTICS
+
+OUI:000041*
+ ID_OUI_FROM_DATABASE=ICE CORPORATION
OUI:00001E*
ID_OUI_FROM_DATABASE=TELSIST INDUSTRIA ELECTRONICA
@@ -44006,23 +45038,44 @@ OUI:0080F9*
OUI:008005*
ID_OUI_FROM_DATABASE=CACTUS COMPUTER INC.
-OUI:008008*
- ID_OUI_FROM_DATABASE=DYNATECH COMPUTER SYSTEMS
+OUI:00801D*
+ ID_OUI_FROM_DATABASE=INTEGRATED INFERENCE MACHINES
-OUI:08005E*
- ID_OUI_FROM_DATABASE=COUNTERPOINT COMPUTER INC.
+OUI:008015*
+ ID_OUI_FROM_DATABASE=SEIKO SYSTEMS, INC.
-OUI:08005A*
- ID_OUI_FROM_DATABASE=IBM Corp
+OUI:008034*
+ ID_OUI_FROM_DATABASE=SMT GOUPIL
-OUI:080056*
- ID_OUI_FROM_DATABASE=STANFORD LINEAR ACCEL. CENTER
+OUI:0080C9*
+ ID_OUI_FROM_DATABASE=ALBERTA MICROELECTRONIC CENTRE
-OUI:080053*
- ID_OUI_FROM_DATABASE=MIDDLE EAST TECH. UNIVERSITY
+OUI:00800B*
+ ID_OUI_FROM_DATABASE=CSK CORPORATION
-OUI:08004F*
- ID_OUI_FROM_DATABASE=CYGNET SYSTEMS
+OUI:000016*
+ ID_OUI_FROM_DATABASE=DU PONT PIXEL SYSTEMS .
+
+OUI:00005C*
+ ID_OUI_FROM_DATABASE=TELEMATICS INTERNATIONAL INC.
+
+OUI:0000AC*
+ ID_OUI_FROM_DATABASE=CONWARE COMPUTER CONSULTING
+
+OUI:0000F2*
+ ID_OUI_FROM_DATABASE=SPIDER COMMUNICATIONS
+
+OUI:000030*
+ ID_OUI_FROM_DATABASE=VG LABORATORY SYSTEMS LTD
+
+OUI:000035*
+ ID_OUI_FROM_DATABASE=SPECTRAGRAPHICS CORPORATION
+
+OUI:020701*
+ ID_OUI_FROM_DATABASE=RACAL-DATACOM
+
+OUI:080011*
+ ID_OUI_FROM_DATABASE=TEKTRONIX INC.
OUI:080040*
ID_OUI_FROM_DATABASE=FERRANTI COMPUTER SYS. LIMITED
@@ -44036,53 +45089,35 @@ OUI:08003D*
OUI:080039*
ID_OUI_FROM_DATABASE=SPIDER SYSTEMS LIMITED
-OUI:00DD0C*
- ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
-
-OUI:000005*
- ID_OUI_FROM_DATABASE=XEROX CORPORATION
-
-OUI:0000AA*
- ID_OUI_FROM_DATABASE=XEROX CORPORATION
-
-OUI:000064*
- ID_OUI_FROM_DATABASE=Yokogawa Electric Corporation
-
-OUI:00002C*
- ID_OUI_FROM_DATABASE=AUTOTOTE LIMITED
-
-OUI:00002A*
- ID_OUI_FROM_DATABASE=TRW - SEDD/INP
-
-OUI:0000F1*
- ID_OUI_FROM_DATABASE=MAGNA COMPUTER CORPORATION
+OUI:080030*
+ ID_OUI_FROM_DATABASE=NETWORK RESEARCH CORPORATION
-OUI:000083*
- ID_OUI_FROM_DATABASE=TADPOLE TECHNOLOGY PLC
+OUI:080027*
+ ID_OUI_FROM_DATABASE=Cadmus Computer Systems
-OUI:000020*
- ID_OUI_FROM_DATABASE=DATAINDUSTRIER DIAB AB
+OUI:00009B*
+ ID_OUI_FROM_DATABASE=INFORMATION INTERNATIONAL, INC
-OUI:00007A*
- ID_OUI_FROM_DATABASE=DANA COMPUTER INC.
+OUI:00DD0F*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
-OUI:00007C*
- ID_OUI_FROM_DATABASE=AMPERE INCORPORATED
+OUI:000001*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
-OUI:00008A*
- ID_OUI_FROM_DATABASE=DATAHOUSE INFORMATION SYSTEMS
+OUI:080021*
+ ID_OUI_FROM_DATABASE=3M COMPANY
-OUI:080030*
- ID_OUI_FROM_DATABASE=NETWORK RESEARCH CORPORATION
+OUI:AA0004*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
-OUI:080027*
- ID_OUI_FROM_DATABASE=Cadmus Computer Systems
+OUI:08000C*
+ ID_OUI_FROM_DATABASE=MIKLYN DEVELOPMENT CO.
-OUI:020701*
- ID_OUI_FROM_DATABASE=RACAL-DATACOM
+OUI:00DD08*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
-OUI:080011*
- ID_OUI_FROM_DATABASE=TEKTRONIX INC.
+OUI:0000A0*
+ ID_OUI_FROM_DATABASE=SANYO Electric Co., Ltd.
OUI:08007F*
ID_OUI_FROM_DATABASE=CARNEGIE-MELLON UNIVERSITY
@@ -44093,8 +45128,14 @@ OUI:080082*
OUI:08007B*
ID_OUI_FROM_DATABASE=SANYO ELECTRIC CO. LTD.
-OUI:080074*
- ID_OUI_FROM_DATABASE=CASIO COMPUTER CO. LTD.
+OUI:00DD0C*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:000005*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:0000AA*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
OUI:00406B*
ID_OUI_FROM_DATABASE=SYSGEN
@@ -44114,56 +45155,35 @@ OUI:08004B*
OUI:080003*
ID_OUI_FROM_DATABASE=ADVANCED COMPUTER COMM.
-OUI:00009B*
- ID_OUI_FROM_DATABASE=INFORMATION INTERNATIONAL, INC
-
-OUI:000068*
- ID_OUI_FROM_DATABASE=ROSEMOUNT CONTROLS
-
-OUI:0000A8*
- ID_OUI_FROM_DATABASE=STRATUS COMPUTER INC.
-
-OUI:0000DF*
- ID_OUI_FROM_DATABASE=BELL & HOWELL PUB SYS DIV
-
-OUI:000062*
- ID_OUI_FROM_DATABASE=BULL HN INFORMATION SYSTEMS
-
-OUI:0000AD*
- ID_OUI_FROM_DATABASE=BRUKER INSTRUMENTS INC.
-
-OUI:0000D0*
- ID_OUI_FROM_DATABASE=DEVELCON ELECTRONICS LTD.
-
-OUI:000093*
- ID_OUI_FROM_DATABASE=PROTEON INC.
+OUI:080074*
+ ID_OUI_FROM_DATABASE=CASIO COMPUTER CO. LTD.
-OUI:0000A0*
- ID_OUI_FROM_DATABASE=SANYO Electric Co., Ltd.
+OUI:08005E*
+ ID_OUI_FROM_DATABASE=COUNTERPOINT COMPUTER INC.
-OUI:00DD0F*
- ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+OUI:08005A*
+ ID_OUI_FROM_DATABASE=IBM Corp
-OUI:000001*
- ID_OUI_FROM_DATABASE=XEROX CORPORATION
+OUI:080056*
+ ID_OUI_FROM_DATABASE=STANFORD LINEAR ACCEL. CENTER
-OUI:080021*
- ID_OUI_FROM_DATABASE=3M COMPANY
+OUI:080053*
+ ID_OUI_FROM_DATABASE=MIDDLE EAST TECH. UNIVERSITY
-OUI:AA0004*
- ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+OUI:08004F*
+ ID_OUI_FROM_DATABASE=CYGNET SYSTEMS
-OUI:08000C*
- ID_OUI_FROM_DATABASE=MIKLYN DEVELOPMENT CO.
+OUI:F8E71E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
-OUI:00DD08*
- ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+OUI:00194B*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:0000D8*
- ID_OUI_FROM_DATABASE=NOVELL, INC.
+OUI:001F95*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:F8E71E*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
+OUI:000E59*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:A01B29*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -44177,15 +45197,6 @@ OUI:ECDF3A*
OUI:E45AA2*
ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-OUI:00194B*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-
-OUI:001F95*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-
-OUI:000E59*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-
OUI:00235A*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
@@ -44204,9 +45215,6 @@ OUI:94C150*
OUI:60FE20*
ID_OUI_FROM_DATABASE=2Wire Inc
-OUI:D4AE52*
- ID_OUI_FROM_DATABASE=Dell Inc.
-
OUI:989096*
ID_OUI_FROM_DATABASE=Dell Inc.
@@ -44219,12 +45227,6 @@ OUI:00D09E*
OUI:000D72*
ID_OUI_FROM_DATABASE=2Wire Inc
-OUI:B0E754*
- ID_OUI_FROM_DATABASE=2Wire Inc
-
-OUI:B8E625*
- ID_OUI_FROM_DATABASE=2Wire Inc
-
OUI:000F1F*
ID_OUI_FROM_DATABASE=Dell Inc.
@@ -44234,6 +45236,15 @@ OUI:14FEB5*
OUI:0015C5*
ID_OUI_FROM_DATABASE=Dell Inc.
+OUI:D4AE52*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:B0E754*
+ ID_OUI_FROM_DATABASE=2Wire Inc
+
+OUI:B8E625*
+ ID_OUI_FROM_DATABASE=2Wire Inc
+
OUI:549F35*
ID_OUI_FROM_DATABASE=Dell Inc.
@@ -44261,12 +45272,12 @@ OUI:A4A1C2*
OUI:348446*
ID_OUI_FROM_DATABASE=Ericsson AB
-OUI:F8F1B6*
- ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
-
OUI:AC2B6E*
ID_OUI_FROM_DATABASE=Intel Corporate
+OUI:F8F1B6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
OUI:00216A*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -44279,22 +45290,19 @@ OUI:0016EB*
OUI:0018DE*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:28B2BD*
- ID_OUI_FROM_DATABASE=Intel Corporate
-
-OUI:08D40C*
+OUI:681729*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:843A4B*
+OUI:5C514F*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:681729*
+OUI:B808CF*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:5C514F*
+OUI:C8F733*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:B808CF*
+OUI:4851B7*
ID_OUI_FROM_DATABASE=Intel Corporate
OUI:5CC5D4*
@@ -44306,22 +45314,25 @@ OUI:7CCCB8*
OUI:F40669*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:C8F733*
+OUI:3CA9F4*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:0CD292*
+OUI:28B2BD*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:78929C*
+OUI:08D40C*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:6805CA*
+OUI:843A4B*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:4851B7*
+OUI:0CD292*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:3CA9F4*
+OUI:78929C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:6805CA*
ID_OUI_FROM_DATABASE=Intel Corporate
OUI:ACA31E*
@@ -44342,9 +45353,6 @@ OUI:84D47E*
OUI:A85840*
ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
-OUI:002423*
- ID_OUI_FROM_DATABASE=AzureWave Technologies (Shanghai) Inc.
-
OUI:002243*
ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
@@ -44366,14 +45374,23 @@ OUI:240A64*
OUI:D0E782*
ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+OUI:0C4C39*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
+OUI:002423*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies (Shanghai) Inc.
+
OUI:A81D16*
ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
OUI:38A53C*
ID_OUI_FROM_DATABASE=COMECER Netherlands
-OUI:0C4C39*
- ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+OUI:001D8B*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:A4526F*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
OUI:581243*
ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
@@ -44387,18 +45404,15 @@ OUI:0030F1*
OUI:001974*
ID_OUI_FROM_DATABASE=16063
+OUI:ECF00E*
+ ID_OUI_FROM_DATABASE=AboCom
+
OUI:3039F2*
ID_OUI_FROM_DATABASE=ADB Broadband Italia
OUI:000827*
ID_OUI_FROM_DATABASE=ADB Broadband Italia
-OUI:001D8B*
- ID_OUI_FROM_DATABASE=ADB Broadband Italia
-
-OUI:A4526F*
- ID_OUI_FROM_DATABASE=ADB Broadband Italia
-
OUI:001CA8*
ID_OUI_FROM_DATABASE=AirTies Wireless Netowrks
@@ -44411,12 +45425,6 @@ OUI:18FE34*
OUI:54F6C5*
ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD
-OUI:A43111*
- ID_OUI_FROM_DATABASE=ZIV
-
-OUI:ECF00E*
- ID_OUI_FROM_DATABASE=AboCom
-
OUI:28EF01*
ID_OUI_FROM_DATABASE=Private
@@ -44426,6 +45434,12 @@ OUI:5C338E*
OUI:001AEB*
ID_OUI_FROM_DATABASE=Allied Telesis R&D Center K.K.
+OUI:747548*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:A43111*
+ ID_OUI_FROM_DATABASE=ZIV
+
OUI:5C93A2*
ID_OUI_FROM_DATABASE=Liteon Technology Corporation
@@ -44435,11 +45449,35 @@ OUI:E8C74F*
OUI:E8F724*
ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
-OUI:747548*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+OUI:1C1448*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:080046*
- ID_OUI_FROM_DATABASE=Sony Corporation
+OUI:707E43*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001AAD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A47AA4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:701A04*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:48D224*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:2CD05A*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:74E543*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:A4DB30*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:B8EE65*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
OUI:001DBA*
ID_OUI_FROM_DATABASE=Sony Corporation
@@ -44462,24 +45500,6 @@ OUI:001B59*
OUI:78843C*
ID_OUI_FROM_DATABASE=Sony Corporation
-OUI:701A04*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
-OUI:48D224*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
-OUI:2CD05A*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
-OUI:74E543*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
-OUI:A4DB30*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
-OUI:B8EE65*
- ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-
OUI:0023F1*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
@@ -44495,11 +45515,8 @@ OUI:04E676*
OUI:0022F4*
ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
-OUI:1C1448*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:707E43*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:080046*
+ ID_OUI_FROM_DATABASE=Sony Corporation
OUI:0003E0*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -44510,12 +45527,6 @@ OUI:00128A*
OUI:001225*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:001AAD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A47AA4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:3C754A*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -44534,39 +45545,45 @@ OUI:002395*
OUI:0023ED*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:745612*
+OUI:001B52*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:E46449*
+OUI:00230B*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:002493*
+OUI:001E8D*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:40FC89*
+OUI:0023A2*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:001B52*
+OUI:001BDD*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:00230B*
+OUI:001404*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:001E8D*
+OUI:745612*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:0023A2*
+OUI:E46449*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:001BDD*
+OUI:002493*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:001404*
+OUI:40FC89*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:00195E*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:000D92*
+ ID_OUI_FROM_DATABASE=ARIMA Communications Corp.
+
+OUI:009096*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
OUI:0011F5*
ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
@@ -44582,11 +45599,8 @@ OUI:000B6A*
OUI:40BA61*
ID_OUI_FROM_DATABASE=ARIMA Communications Corp.
-OUI:000D92*
- ID_OUI_FROM_DATABASE=ARIMA Communications Corp.
-
-OUI:009096*
- ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+OUI:841B5E*
+ ID_OUI_FROM_DATABASE=NETGEAR
OUI:204E7F*
ID_OUI_FROM_DATABASE=NETGEAR
@@ -44603,8 +45617,11 @@ OUI:C03F0E*
OUI:001F33*
ID_OUI_FROM_DATABASE=NETGEAR
-OUI:841B5E*
- ID_OUI_FROM_DATABASE=NETGEAR
+OUI:1883BF*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:9C80DF*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
OUI:001CCC*
ID_OUI_FROM_DATABASE=BlackBerry RTS
@@ -44612,17 +45629,11 @@ OUI:001CCC*
OUI:94EBCD*
ID_OUI_FROM_DATABASE=BlackBerry RTS
-OUI:A4E4B8*
- ID_OUI_FROM_DATABASE=BlackBerry RTS
-
-OUI:58671A*
- ID_OUI_FROM_DATABASE=Barnes&Noble
-
-OUI:BC0543*
- ID_OUI_FROM_DATABASE=AVM GmbH
+OUI:644FB0*
+ ID_OUI_FROM_DATABASE=Hyunjin.com
-OUI:002675*
- ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd
+OUI:001A2A*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
OUI:001D19*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
@@ -44630,17 +45641,17 @@ OUI:001D19*
OUI:88252C*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:1883BF*
- ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+OUI:A4E4B8*
+ ID_OUI_FROM_DATABASE=BlackBerry RTS
-OUI:9C80DF*
- ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+OUI:58671A*
+ ID_OUI_FROM_DATABASE=Barnes&Noble
-OUI:644FB0*
- ID_OUI_FROM_DATABASE=Hyunjin.com
+OUI:BC0543*
+ ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:001A2A*
- ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+OUI:002675*
+ ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd
OUI:001F3F*
ID_OUI_FROM_DATABASE=AVM GmbH
@@ -44654,40 +45665,49 @@ OUI:6CB0CE*
OUI:100D7F*
ID_OUI_FROM_DATABASE=NETGEAR
+OUI:0020D6*
+ ID_OUI_FROM_DATABASE=Breezecom, Ltd.
+
OUI:001018*
ID_OUI_FROM_DATABASE=Broadcom
OUI:001BE9*
ID_OUI_FROM_DATABASE=Broadcom
-OUI:0020D6*
- ID_OUI_FROM_DATABASE=Breezecom, Ltd.
-
OUI:008077*
ID_OUI_FROM_DATABASE=Brother industries, LTD.
-OUI:FC2F40*
- ID_OUI_FROM_DATABASE=Calxeda, Inc.
-
OUI:029D8E*
ID_OUI_FROM_DATABASE=CARDIAC RECORDERS, INC.
+OUI:FC2F40*
+ ID_OUI_FROM_DATABASE=Calxeda, Inc.
+
OUI:0026E4*
ID_OUI_FROM_DATABASE=Canal +
-OUI:E458E7*
+OUI:389496*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:8CBFA6*
+OUI:0CB319*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:7840E4*
+OUI:08EE8B*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:9000DB*
+OUI:84A466*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:183A2D*
+OUI:981DFA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:FCF136*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0C8910*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:54FA3E*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:A89FBA*
@@ -44705,16 +45725,13 @@ OUI:5C2E59*
OUI:646CB2*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:A48431*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:E4F8EF*
+OUI:F884F2*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:1867B0*
+OUI:14B484*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:F40E22*
+OUI:608F5C*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:4CBCA5*
@@ -44729,65 +45746,50 @@ OUI:B0D09C*
OUI:4CA56D*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:08373D*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:50F520*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:A4EBD3*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:28987B*
+OUI:A48431*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:9C3AAF*
+OUI:E4F8EF*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:1432D1*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:F884F2*
+OUI:E458E7*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:14B484*
+OUI:8CBFA6*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:608F5C*
+OUI:7840E4*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:389496*
+OUI:9000DB*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:0CB319*
+OUI:183A2D*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:08EE8B*
+OUI:08373D*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:84A466*
+OUI:50F520*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:981DFA*
+OUI:A4EBD3*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:FCF136*
+OUI:28987B*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:0C8910*
+OUI:1867B0*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:54FA3E*
+OUI:F40E22*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:702559*
- ID_OUI_FROM_DATABASE=CyberTAN Technology Inc.
-
-OUI:0090D6*
- ID_OUI_FROM_DATABASE=Crystal Group, Inc.
-
-OUI:02CF1C*
- ID_OUI_FROM_DATABASE=Communication Machinery Corporation
+OUI:9C3AAF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:BCF2AF*
ID_OUI_FROM_DATABASE=devolo AG
@@ -44798,30 +45800,36 @@ OUI:0270B3*
OUI:000FF6*
ID_OUI_FROM_DATABASE=DARFON LIGHTING CORP
+OUI:702559*
+ ID_OUI_FROM_DATABASE=CyberTAN Technology Inc.
+
+OUI:0090D6*
+ ID_OUI_FROM_DATABASE=Crystal Group, Inc.
+
OUI:001DAA*
ID_OUI_FROM_DATABASE=DrayTek Corp.
+OUI:02CF1C*
+ ID_OUI_FROM_DATABASE=Communication Machinery Corporation
+
OUI:0C75BD*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:38F0C8*
ID_OUI_FROM_DATABASE=Livestream
-OUI:0C1167*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-
OUI:74EAE8*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:A811FC*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:0C1167*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
OUI:001982*
ID_OUI_FROM_DATABASE=SmarDTV
-OUI:00904B*
- ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
-
OUI:10C6FC*
ID_OUI_FROM_DATABASE=Garmin International
@@ -44846,6 +45854,15 @@ OUI:002682*
OUI:001A73*
ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+OUI:00904B*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:D86BF7*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:A4C0E1*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
OUI:34AF2C*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
@@ -44861,6 +45878,12 @@ OUI:600194*
OUI:F44D17*
ID_OUI_FROM_DATABASE=GOLDCARD HIGH-TECH CO.,LTD.
+OUI:001E35*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001FC5*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
OUI:0021BD*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
@@ -44870,10 +45893,7 @@ OUI:002709*
OUI:E84ECE*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-OUI:D86BF7*
- ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-
-OUI:A4C0E1*
+OUI:0009BF*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
OUI:001AE9*
@@ -44882,15 +45902,6 @@ OUI:001AE9*
OUI:001CBE*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-OUI:001E35*
- ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-
-OUI:001FC5*
- ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-
-OUI:0009BF*
- ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-
OUI:002403*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
@@ -44900,20 +45911,26 @@ OUI:002265*
OUI:0019B7*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001D6E*
+OUI:002404*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001B33*
+OUI:0002EE*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:ECF35B*
- ID_OUI_FROM_DATABASE=Nokia Corporation
+OUI:001C9A*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:EC9B5B*
- ID_OUI_FROM_DATABASE=Nokia Corporation
+OUI:001F01*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:BCC6DB*
- ID_OUI_FROM_DATABASE=Nokia Corporation
+OUI:000EED*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001E3A*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001A89*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
OUI:0021AA*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
@@ -44930,26 +45947,20 @@ OUI:002109*
OUI:002108*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001F01*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:000EED*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:001E3A*
+OUI:001D6E*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001A89*
+OUI:001B33*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:002404*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:ECF35B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:0002EE*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:EC9B5B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:001C9A*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:BCC6DB*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
OUI:B83241*
ID_OUI_FROM_DATABASE=Wuhan Tianyu Information Industry Co., Ltd.
@@ -44975,35 +45986,23 @@ OUI:1C5CF2*
OUI:0821EF*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:B462AD*
- ID_OUI_FROM_DATABASE=Elysia Germany GmbH
-
-OUI:747818*
- ID_OUI_FROM_DATABASE=Jurumani Solutions
-
OUI:A0CBFD*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:34145F*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:803896*
- ID_OUI_FROM_DATABASE=SHARP Corporation
-
-OUI:00D9D1*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:F8D0AC*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+OUI:B462AD*
+ ID_OUI_FROM_DATABASE=Elysia Germany GmbH
-OUI:0CFE45*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+OUI:747818*
+ ID_OUI_FROM_DATABASE=Jurumani Solutions
-OUI:D8D43C*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+OUI:803896*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
-OUI:3C0771*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+OUI:80D160*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
OUI:686E23*
ID_OUI_FROM_DATABASE=Wi3 Inc.
@@ -45011,9 +46010,6 @@ OUI:686E23*
OUI:B8A175*
ID_OUI_FROM_DATABASE=Roku, Inc.
-OUI:80D160*
- ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
-
OUI:0080E5*
ID_OUI_FROM_DATABASE=NetApp
@@ -45032,20 +46028,11 @@ OUI:002340*
OUI:B48B19*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:4CCC6A*
- ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD.
-
OUI:00AF1F*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:245EBE*
- ID_OUI_FROM_DATABASE=QNAP Systems, Inc.
-
-OUI:A89352*
- ID_OUI_FROM_DATABASE=SHANGHAI ZHONGMI COMMUNICATION TECHNOLOGY CO.,LTD
-
-OUI:AC5F3E*
- ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+OUI:4CCC6A*
+ ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD.
OUI:985BB0*
ID_OUI_FROM_DATABASE=KMDATA INC.
@@ -45053,17 +46040,14 @@ OUI:985BB0*
OUI:6C8FB5*
ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
-OUI:D4E33F*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:143E60*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
+OUI:245EBE*
+ ID_OUI_FROM_DATABASE=QNAP Systems, Inc.
-OUI:248A07*
- ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+OUI:A89352*
+ ID_OUI_FROM_DATABASE=SHANGHAI ZHONGMI COMMUNICATION TECHNOLOGY CO.,LTD
-OUI:9C9D5D*
- ID_OUI_FROM_DATABASE=Raden Inc
+OUI:AC5F3E*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
OUI:B07FB9*
ID_OUI_FROM_DATABASE=NETGEAR
@@ -45074,8 +46058,8 @@ OUI:70661B*
OUI:1C98EC*
ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
-OUI:EC438B*
- ID_OUI_FROM_DATABASE=YAPTV
+OUI:9C9D5D*
+ ID_OUI_FROM_DATABASE=Raden Inc
OUI:E8FD72*
ID_OUI_FROM_DATABASE=SHANGHAI LINGUO TECHNOLOGY CO., LTD.
@@ -45083,17 +46067,8 @@ OUI:E8FD72*
OUI:98BB1E*
ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd.
-OUI:001D0D*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:00041F*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:20A90E*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
-OUI:CCB11A*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:EC438B*
+ ID_OUI_FROM_DATABASE=YAPTV
OUI:1866DA*
ID_OUI_FROM_DATABASE=Dell Inc.
@@ -45101,23 +46076,23 @@ OUI:1866DA*
OUI:981FB1*
ID_OUI_FROM_DATABASE=Shenzhen Lemon Network Technology Co.,Ltd
+OUI:CCB11A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
OUI:40476A*
ID_OUI_FROM_DATABASE=AG Acquisition Corp. d.b.a. ASTRO Gaming
OUI:A4BF01*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:0004C6*
- ID_OUI_FROM_DATABASE=YAMAHA MOTOR CO.,LTD
-
OUI:509EA7*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:DCCF96*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:64CC2E*
- ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+OUI:0004C6*
+ ID_OUI_FROM_DATABASE=YAMAHA MOTOR CO.,LTD
OUI:14D11F*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -45128,6 +46103,9 @@ OUI:54511B*
OUI:68536C*
ID_OUI_FROM_DATABASE=SPnS Co.,Ltd
+OUI:64CC2E*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
OUI:005BA1*
ID_OUI_FROM_DATABASE=shanghai huayuan chuangxin software CO., LTD.
@@ -45137,9 +46115,6 @@ OUI:B07E70*
OUI:405EE1*
ID_OUI_FROM_DATABASE=Shenzhen H&T Intelligent Control Co.,Ltd.
-OUI:88795B*
- ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
-
OUI:10F005*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -45173,15 +46148,15 @@ OUI:001174*
OUI:BC15AC*
ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A.
-OUI:1C740D*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:140C5B*
ID_OUI_FROM_DATABASE=PLNetworks
OUI:D0B0CD*
ID_OUI_FROM_DATABASE=Moen
+OUI:0071C2*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
OUI:DCFE07*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
@@ -45197,9 +46172,6 @@ OUI:EC93ED*
OUI:4C72B9*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
-OUI:0071C2*
- ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
-
OUI:F462D0*
ID_OUI_FROM_DATABASE=Not for Radio, LLC
@@ -45224,12 +46196,6 @@ OUI:001921*
OUI:00142A*
ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd.
-OUI:0050FC*
- ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd.
-
-OUI:200A5E*
- ID_OUI_FROM_DATABASE=Xiangshan Giant Eagle Technology Developing Co., Ltd.
-
OUI:0001F4*
ID_OUI_FROM_DATABASE=Enterasys
@@ -45239,33 +46205,36 @@ OUI:487ADA*
OUI:1C7370*
ID_OUI_FROM_DATABASE=Neotech
+OUI:0050FC*
+ ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd.
+
+OUI:200A5E*
+ ID_OUI_FROM_DATABASE=Xiangshan Giant Eagle Technology Developing Co., Ltd.
+
OUI:30E37A*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:A08CFD*
- ID_OUI_FROM_DATABASE=Hewlett Packard
-
OUI:4CA003*
ID_OUI_FROM_DATABASE=T-21 Technologies LLC
OUI:F0EE58*
ID_OUI_FROM_DATABASE=PACE Telematics GmbH
+OUI:A08CFD*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:4000E0*
+ ID_OUI_FROM_DATABASE=Derek(Shaoguan)Limited
+
OUI:001397*
ID_OUI_FROM_DATABASE=Oracle Corporation
OUI:00A0A4*
ID_OUI_FROM_DATABASE=Oracle Corporation
-OUI:4000E0*
- ID_OUI_FROM_DATABASE=Derek(Shaoguan)Limited
-
OUI:A4E597*
ID_OUI_FROM_DATABASE=Gessler GmbH
-OUI:001A34*
- ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
-
OUI:0024F4*
ID_OUI_FROM_DATABASE=Kaminario, Ltd.
@@ -45314,27 +46283,621 @@ OUI:0010DB*
OUI:307C5E*
ID_OUI_FROM_DATABASE=Juniper Networks
-OUI:002688*
- ID_OUI_FROM_DATABASE=Juniper Networks
-
OUI:841888*
ID_OUI_FROM_DATABASE=Juniper Networks
OUI:40B4F0*
ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:002688*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
OUI:0017CB*
ID_OUI_FROM_DATABASE=Juniper Networks
OUI:E0A3AC*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:E00EDA*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
OUI:044E5A*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:E00EDA*
+OUI:6C2483*
+ ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
+
+OUI:94E8C5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:848319*
+ ID_OUI_FROM_DATABASE=Hangzhou Zero Zero Technology Co., Ltd.
+
+OUI:001F20*
+ ID_OUI_FROM_DATABASE=Logitech Europe SA
+
+OUI:882012*
+ ID_OUI_FROM_DATABASE=LMI Technologies
+
+OUI:002382*
+ ID_OUI_FROM_DATABASE=Lih Rong electronic Enterprise Co., Ltd.
+
+OUI:88795B*
+ ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
+
+OUI:001A34*
+ ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
+
+OUI:20A90E*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:8C99E6*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:745C9F*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:0CBD51*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:E42D02*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:3CE5A6*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:3C8C40*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:B04519*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:A81559*
+ ID_OUI_FROM_DATABASE=Breathometer, Inc.
+
+OUI:ECADB8*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:9801A7*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:2CF0A2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C09727*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+
+OUI:2C5A8D*
+ ID_OUI_FROM_DATABASE=SYSTRONIK Elektronik u. Systemtechnik GmbH
+
+OUI:B8BBAF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:60C5AD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:8C897A*
+ ID_OUI_FROM_DATABASE=AUGTEK
+
+OUI:54EDA3*
+ ID_OUI_FROM_DATABASE=Navdy, Inc.
+
+OUI:046565*
+ ID_OUI_FROM_DATABASE=Testop
+
+OUI:042758*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+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
+
+OUI:C48F07*
+ ID_OUI_FROM_DATABASE=Shenzhen Yihao Hulian Science and Technology Co., Ltd.
+
+OUI:009E1E*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:002550*
+ ID_OUI_FROM_DATABASE=Riverbed Technology, Inc.
+
+OUI:D85B2A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:ACC33A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F45B73*
+ ID_OUI_FROM_DATABASE=Wanjiaan Interconnected Technology Co., Ltd
+
+OUI:0021E2*
+ ID_OUI_FROM_DATABASE=visago Systems & Controls GmbH & Co. KG
+
+OUI:28F10E*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:C4A366*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:0014B4*
+ ID_OUI_FROM_DATABASE=General Dynamics United Kingdom Ltd
+
+OUI:A0B437*
+ ID_OUI_FROM_DATABASE=GD Mission Systems
+
+OUI:5052D2*
+ ID_OUI_FROM_DATABASE=Hangzhou Telin Technologies Co., Limited
+
+OUI:1CD6BD*
+ ID_OUI_FROM_DATABASE=LEEDARSON LIGHTING CO., LTD.
+
+OUI:9CDD1F*
+ ID_OUI_FROM_DATABASE=Intelligent Steward Co.,Ltd
+
+OUI:00EBD5*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F8A097*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:1C7B23*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:1C740D*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:001349*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:404A03*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:CC5D4E*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:A0E4CB*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:90CF7D*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:F8F082*
+ ID_OUI_FROM_DATABASE=NAG LLC
+
+OUI:40F413*
+ ID_OUI_FROM_DATABASE=Rubezh
+
+OUI:2C094D*
+ ID_OUI_FROM_DATABASE=Raptor Engineering, LLC
+
+OUI:ACE77B*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:B0E235*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:88797E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:40C729*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:AC040B*
+ ID_OUI_FROM_DATABASE=Peloton Interactive, Inc
+
+OUI:006074*
+ ID_OUI_FROM_DATABASE=QSC LLC
+
+OUI:34ED0B*
+ ID_OUI_FROM_DATABASE=Shanghai XZ-COM.CO.,Ltd.
+
+OUI:0010C1*
+ ID_OUI_FROM_DATABASE=OI ELECTRIC CO.,LTD
+
+OUI:4432C8*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:E0885D*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:802994*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:206A8A*
+ ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
+
+OUI:F0DEF1*
+ ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
+
+OUI:F80F41*
+ ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
+
+OUI:94DF4E*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd.
+
+OUI:48A9D2*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:683E34*
+ ID_OUI_FROM_DATABASE=MEIZU Technology Co., Ltd.
+
+OUI:001EC0*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
+OUI:3C0771*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:D8D43C*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:00A012*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:94611E*
+ ID_OUI_FROM_DATABASE=Wata Electronics Co.,Ltd.
+
+OUI:0025D4*
+ ID_OUI_FROM_DATABASE=General Dynamics Mission Systems
+
+OUI:5CA86A*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C8778B*
+ ID_OUI_FROM_DATABASE=Themis Computer
+
+OUI:000A68*
+ ID_OUI_FROM_DATABASE=Solarflare Communications Inc
+
+OUI:0CD502*
+ ID_OUI_FROM_DATABASE=Westell Technologies Inc.
+
+OUI:001636*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:00C09F*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:54AB3A*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:089E01*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:00199D*
+ ID_OUI_FROM_DATABASE=Vizio, Inc
+
+OUI:6C0B84*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:24A43C*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:E4509A*
+ ID_OUI_FROM_DATABASE=HW Communications Ltd
+
+OUI:702900*
+ ID_OUI_FROM_DATABASE=Shenzhen ChipTrip Technology Co,Ltd
+
+OUI:204C03*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:90F052*
+ ID_OUI_FROM_DATABASE=MEIZU Technology Co., Ltd.
+
+OUI:000E1E*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:D8EB97*
+ ID_OUI_FROM_DATABASE=TRENDnet, Inc.
+
+OUI:146102*
+ ID_OUI_FROM_DATABASE=Alpine Electronics, Inc.
+
+OUI:9003B7*
+ ID_OUI_FROM_DATABASE=PARROT SA
+
+OUI:0CFE45*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:F8D0AC*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:00D9D1*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:00041F*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:001D0D*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:7CC709*
+ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+
+OUI:D455BE*
+ ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD
+
+OUI:8CA6DF*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:00E091*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:6CD032*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:C041F6*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:404AD4*
+ ID_OUI_FROM_DATABASE=Widex A/S
+
+OUI:0021FB*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:8C3AE3*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:30766F*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:F80CF3*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0022CF*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:A84E3F*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+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.
+
+OUI:00167A*
+ ID_OUI_FROM_DATABASE=Skyworth Overseas Development Ltd.
+
+OUI:28BE03*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:D4E33F*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:143E60*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:84DBFC*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:38521A*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:F4C613*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:D826B9*
+ ID_OUI_FROM_DATABASE=Guangdong Coagent Electronics S&amp;T Co.,Ltd.
+
+OUI:FCB0C4*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
+
+OUI:24AF4A*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:001AF0*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:AC9CE4*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:D84710*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:000E40*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001158*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0011F9*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000F6A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001283*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000438*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002347*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:002561*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:008058*
+ ID_OUI_FROM_DATABASE=PRINTER SYSTEMS CORP.
+
+OUI:00140D*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001765*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0018B0*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001B25*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001DAF*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00166D*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:0016F2*
+ ID_OUI_FROM_DATABASE=Dmobile System Co., Ltd.
+
+OUI:000138*
+ ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
+
+OUI:3C9157*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:0000D8*
+ ID_OUI_FROM_DATABASE=Novell, Inc.
+
+OUI:001087*
+ ID_OUI_FROM_DATABASE=XSTREAMIS PLC
+
+OUI:7C0623*
+ ID_OUI_FROM_DATABASE=Ultra Electronics Sonar System Division
+
+OUI:002555*
+ ID_OUI_FROM_DATABASE=Visonic Technologies 1993 Ltd.
+
+OUI:009058*
+ ID_OUI_FROM_DATABASE=Ultra Electronics Limited (AEP Networks)
+
+OUI:48FD8E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:244427*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:B4A984*
+ ID_OUI_FROM_DATABASE=Symantec Corporation
+
+OUI:34074F*
+ ID_OUI_FROM_DATABASE=AccelStor, Inc.
+
+OUI:248A07*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:00258B*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:3C2DB7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0023D4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001831*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D08CB5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B4EED4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:CC8CE3*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:102EAF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:647BD4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E6*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B0B448*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:505663*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:3C7DB1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:40984E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0012D1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:88C255*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:E0C79D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:9059AF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B4994C*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:70FF76*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:507224*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:440444*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:506583*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:BC282C*
+ ID_OUI_FROM_DATABASE=e-Smart Systems Pvt. Ltd
+
+OUI:546C0E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:F85C4D*
+ ID_OUI_FROM_DATABASE=NOKIA
+
+OUI:D013FD*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:D8E72B*
+ ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
+
+OUI:BC644B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:04FEA1*
+ ID_OUI_FROM_DATABASE=Fihonest communication co.,Ltd
+
+OUI:2CAC44*
+ ID_OUI_FROM_DATABASE=CONEXTOP
+
+OUI:A8BD27*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:981E0F*
+ ID_OUI_FROM_DATABASE=Jeelan (Shanghai Jeelan Technology Information Inc
+
OUI:D86CE9*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -45404,45 +46967,6 @@ OUI:000D88*
OUI:001346*
ID_OUI_FROM_DATABASE=D-Link Corporation
-OUI:0021BA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0022A5*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0024BA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D03761*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017E4*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:5C6B32*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:1C4593*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:84DD20*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:883314*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017EB*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:C4EDBA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:34B1F7*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:C8A030*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:205532*
ID_OUI_FROM_DATABASE=Gotech International Technology Limited
@@ -45458,18 +46982,6 @@ OUI:B8A386*
OUI:C8D3A3*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:F4FC32*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:649C8E*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D8952F*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:001833*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:4419B6*
ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
@@ -45728,33 +47240,6 @@ OUI:ACE87B*
OUI:688F84*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:001AB6*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D03972*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:7C669D*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:78A504*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:C4BE84*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D05FB8*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:74D6EA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:7CEC79*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:E0E5CF*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:ACF7F3*
ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
@@ -45923,9 +47408,6 @@ OUI:00214F*
OUI:00E036*
ID_OUI_FROM_DATABASE=PIONEER CORPORATION
-OUI:C83DFC*
- ID_OUI_FROM_DATABASE=PIONEER CORPORATION
-
OUI:E0AE5E*
ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
@@ -46445,9 +47927,6 @@ OUI:209BCD*
OUI:F0B0E7*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:A09169*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:CC20E8*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -46478,9 +47957,6 @@ OUI:CC794A*
OUI:60FD56*
ID_OUI_FROM_DATABASE=WOORISYSTEMS CO., Ltd
-OUI:7CFE90*
- ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
-
OUI:483974*
ID_OUI_FROM_DATABASE=Proware Technologies Co., Ltd.
@@ -46592,9 +48068,6 @@ OUI:D02516*
OUI:D05C7A*
ID_OUI_FROM_DATABASE=Sartura d.o.o.
-OUI:583F54*
- ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
-
OUI:9C37F4*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -46736,9 +48209,6 @@ OUI:AC9E17*
OUI:ACC73F*
ID_OUI_FROM_DATABASE=VITSMO CO., LTD.
-OUI:505527*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:18BDAD*
ID_OUI_FROM_DATABASE=L-TECH CORPORATION
@@ -46826,9 +48296,6 @@ OUI:E08E3C*
OUI:78A351*
ID_OUI_FROM_DATABASE=SHENZHEN ZHIBOTONG ELECTRONICS CO.,LTD
-OUI:34FCEF*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:94E2FD*
ID_OUI_FROM_DATABASE=Boge Kompressoren OTTO Boge GmbH & Co. KG
@@ -46904,9 +48371,6 @@ OUI:5C966A*
OUI:2C5089*
ID_OUI_FROM_DATABASE=Shenzhen Kaixuan Visual Technology Co.,Limited
-OUI:A89DD2*
- ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd
-
OUI:EC13B2*
ID_OUI_FROM_DATABASE=Netonix
@@ -46925,9 +48389,6 @@ OUI:00A2F5*
OUI:70FC8C*
ID_OUI_FROM_DATABASE=OneAccess SA
-OUI:2C600C*
- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
-
OUI:902CC7*
ID_OUI_FROM_DATABASE=C-MAX Asia Limited
@@ -46949,9 +48410,6 @@ OUI:AC3870*
OUI:80EACA*
ID_OUI_FROM_DATABASE=Dialog Semiconductor Hellas SA
-OUI:60512C*
- ID_OUI_FROM_DATABASE=TCT mobile limited
-
OUI:4CBC42*
ID_OUI_FROM_DATABASE=Shenzhen Hangsheng Electronics Co.,Ltd.
@@ -46964,9 +48422,6 @@ OUI:987E46*
OUI:8432EA*
ID_OUI_FROM_DATABASE=ANHUI WANZTEN P&T CO., LTD
-OUI:ACA213*
- ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
-
OUI:90B686*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
@@ -47015,15 +48470,9 @@ OUI:284ED7*
OUI:5C5BC2*
ID_OUI_FROM_DATABASE=YIK Corporation
-OUI:184A6F*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:EC8A4C*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:340AFF*
- ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd
-
OUI:8014A8*
ID_OUI_FROM_DATABASE=Guangzhou V-SOLUTION Electronic Technology Co., Ltd.
@@ -47039,9 +48488,6 @@ OUI:C8E42F*
OUI:FC2325*
ID_OUI_FROM_DATABASE=EosTek (Shenzhen) Co., Ltd.
-OUI:485929*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:A81374*
ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
@@ -47078,9 +48524,6 @@ OUI:08DF1F*
OUI:542AA2*
ID_OUI_FROM_DATABASE=Alpha Networks Inc.
-OUI:58238C*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
-
OUI:84948C*
ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
@@ -47090,9 +48533,6 @@ OUI:CCA0E5*
OUI:3059B7*
ID_OUI_FROM_DATABASE=Microsoft
-OUI:80414E*
- ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.,
-
OUI:0874F6*
ID_OUI_FROM_DATABASE=Winterhalter Gastronom GmbH
@@ -47117,9 +48557,6 @@ OUI:38262B*
OUI:20ED74*
ID_OUI_FROM_DATABASE=Ability enterprise co.,Ltd.
-OUI:982F3C*
- ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
-
OUI:7824AF*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
@@ -47153,9 +48590,6 @@ OUI:C8D590*
OUI:709383*
ID_OUI_FROM_DATABASE=Intelligent Optical Network High Tech CO.,LTD.
-OUI:3CCD93*
- ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
-
OUI:6047D4*
ID_OUI_FROM_DATABASE=FORICS Electronic Technology Co., Ltd.
@@ -47243,9 +48677,6 @@ OUI:441E91*
OUI:6C14F7*
ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH
-OUI:70F96D*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:CC07E4*
ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
@@ -47285,9 +48716,6 @@ OUI:68856A*
OUI:30F42F*
ID_OUI_FROM_DATABASE=ESP
-OUI:C816BD*
- ID_OUI_FROM_DATABASE=HISENSE ELECTRIC CO.,LTD.
-
OUI:746A8F*
ID_OUI_FROM_DATABASE=VS Vision Systems GmbH
@@ -47474,9 +48902,6 @@ OUI:FCD817*
OUI:909F43*
ID_OUI_FROM_DATABASE=Accutron Instruments Inc.
-OUI:C42795*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
OUI:50C006*
ID_OUI_FROM_DATABASE=Carmanah Signs
@@ -47528,9 +48953,6 @@ OUI:B8DF6B*
OUI:742B62*
ID_OUI_FROM_DATABASE=FUJITSU LIMITED
-OUI:A0143D*
- ID_OUI_FROM_DATABASE=PARROT SA
-
OUI:58BDF9*
ID_OUI_FROM_DATABASE=Sigrand
@@ -47543,9 +48965,6 @@ OUI:C0C687*
OUI:142BD2*
ID_OUI_FROM_DATABASE=Armtel Ltd.
-OUI:F845AD*
- ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
-
OUI:54A54B*
ID_OUI_FROM_DATABASE=NSC Communications Siberia Ltd
@@ -47609,9 +49028,6 @@ OUI:B4346C*
OUI:9C1465*
ID_OUI_FROM_DATABASE=Edata Elektronik San. ve Tic. A.Ş.
-OUI:C45444*
- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
-
OUI:587A4D*
ID_OUI_FROM_DATABASE=Stonesoft Corporation
@@ -47657,9 +49073,6 @@ OUI:140D4F*
OUI:B847C6*
ID_OUI_FROM_DATABASE=SanJet Technology Corp.
-OUI:CC3540*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
OUI:4CDF3D*
ID_OUI_FROM_DATABASE=TEAM ENGINEERS ADVANCE TECHNOLOGIES INDIA PVT LTD
@@ -47678,18 +49091,12 @@ OUI:704CED*
OUI:E8516E*
ID_OUI_FROM_DATABASE=TSMART Inc.
-OUI:A067BE*
- ID_OUI_FROM_DATABASE=Sicon s.r.l.
-
OUI:7C1AFC*
ID_OUI_FROM_DATABASE=Dalian Co-Edifice Video Technology Co., Ltd
OUI:C034B4*
ID_OUI_FROM_DATABASE=Gigastone Corporation
-OUI:587E61*
- ID_OUI_FROM_DATABASE=Hisense Electric Co., Ltd
-
OUI:74ADB7*
ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
@@ -47813,9 +49220,6 @@ OUI:DC825B*
OUI:B08807*
ID_OUI_FROM_DATABASE=Strata Worldwide
-OUI:9893CC*
- ID_OUI_FROM_DATABASE=LG Electronics Inc.
-
OUI:74D02B*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
@@ -47861,9 +49265,6 @@ OUI:E0C6B3*
OUI:FCDB96*
ID_OUI_FROM_DATABASE=ENERVALLEY CO., LTD
-OUI:74258A*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:F06BCA*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -47879,15 +49280,9 @@ OUI:D429EA*
OUI:C80E95*
ID_OUI_FROM_DATABASE=OmniLync Inc.
-OUI:18DC56*
- ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt
-
OUI:50ABBF*
ID_OUI_FROM_DATABASE=Hoseo Telecom
-OUI:8C7716*
- ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
-
OUI:C8EEA6*
ID_OUI_FROM_DATABASE=Shenzhen SHX Technology Co., Ltd
@@ -47897,9 +49292,6 @@ OUI:28CBEB*
OUI:18E8DD*
ID_OUI_FROM_DATABASE=MODULETEK
-OUI:2C282D*
- ID_OUI_FROM_DATABASE=BBK COMMUNICATIAO TECHNOLOGY CO.,LTD.
-
OUI:4CCC34*
ID_OUI_FROM_DATABASE=Motorola Solutions Inc.
@@ -47918,9 +49310,6 @@ OUI:94ACCA*
OUI:7CD844*
ID_OUI_FROM_DATABASE=Enmotus Inc
-OUI:40B0FA*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:F4C6D7*
ID_OUI_FROM_DATABASE=blackned GmbH
@@ -47936,18 +49325,12 @@ OUI:081DFB*
OUI:D0CDE1*
ID_OUI_FROM_DATABASE=Scientech Electronics
-OUI:98D6F7*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:94756E*
ID_OUI_FROM_DATABASE=QinetiQ North America
OUI:543D37*
ID_OUI_FROM_DATABASE=Ruckus Wireless
-OUI:905F2E*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
OUI:0C5521*
ID_OUI_FROM_DATABASE=Axiros GmbH
@@ -48029,9 +49412,6 @@ OUI:E4EEFD*
OUI:105CBF*
ID_OUI_FROM_DATABASE=DuroByte Inc
-OUI:30C82A*
- ID_OUI_FROM_DATABASE=Wi-Next s.r.l.
-
OUI:88A3CC*
ID_OUI_FROM_DATABASE=Amatis Controls
@@ -48089,9 +49469,6 @@ OUI:9C2A70*
OUI:A0A130*
ID_OUI_FROM_DATABASE=DLI Taiwan Branch office
-OUI:38BC1A*
- ID_OUI_FROM_DATABASE=Meizu technology co.,ltd
-
OUI:ECE915*
ID_OUI_FROM_DATABASE=STI Ltd
@@ -48194,9 +49571,6 @@ OUI:A0E534*
OUI:2891D0*
ID_OUI_FROM_DATABASE=Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH
-OUI:A854B2*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:98291D*
ID_OUI_FROM_DATABASE=Jaguar de Mexico, SA de CV
@@ -48248,9 +49622,6 @@ OUI:0CC66A*
OUI:3078C2*
ID_OUI_FROM_DATABASE=Innowireless, Co. Ltd.
-OUI:58986F*
- ID_OUI_FROM_DATABASE=Revolution Display
-
OUI:7CFE28*
ID_OUI_FROM_DATABASE=Salutron Inc.
@@ -48266,9 +49637,6 @@ OUI:98A7B0*
OUI:88DC96*
ID_OUI_FROM_DATABASE=SENAO Networks, Inc.
-OUI:4C0B3A*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
OUI:C455C2*
ID_OUI_FROM_DATABASE=Bach-Simpson
@@ -48356,9 +49724,6 @@ OUI:E49069*
OUI:B48910*
ID_OUI_FROM_DATABASE=Coster T.E. S.P.A.
-OUI:183919*
- ID_OUI_FROM_DATABASE=Unicoi Systems
-
OUI:A4B1E9*
ID_OUI_FROM_DATABASE=Technicolor
@@ -48446,9 +49811,6 @@ OUI:6089B1*
OUI:080CC9*
ID_OUI_FROM_DATABASE=Mission Technology Group, dba Magma
-OUI:3C970E*
- ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd.
-
OUI:A0F450*
ID_OUI_FROM_DATABASE=HTC Corporation
@@ -48479,9 +49841,6 @@ OUI:04F17D*
OUI:A0DC04*
ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH
-OUI:B85510*
- ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
-
OUI:8CC121*
ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
@@ -48671,9 +50030,6 @@ OUI:78A5DD*
OUI:28B0CC*
ID_OUI_FROM_DATABASE=Xenya d.o.o.
-OUI:94D723*
- ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd
-
OUI:ECE744*
ID_OUI_FROM_DATABASE=Omntec mfg. inc
@@ -48704,9 +50060,6 @@ OUI:EC6264*
OUI:00F051*
ID_OUI_FROM_DATABASE=KWB Gmbh
-OUI:44DC91*
- ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
-
OUI:F0DEB9*
ID_OUI_FROM_DATABASE=ShangHai Y&Y Electronics Co., Ltd
@@ -48785,9 +50138,6 @@ OUI:D4CA6D*
OUI:D8E743*
ID_OUI_FROM_DATABASE=Wush, Inc
-OUI:A0F3E4*
- ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
-
OUI:908FCF*
ID_OUI_FROM_DATABASE=UNO System Co., Ltd
@@ -48803,9 +50153,6 @@ OUI:F0620D*
OUI:843611*
ID_OUI_FROM_DATABASE=hyungseul publishing networks
-OUI:DC9FDB*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc.
-
OUI:B8FD32*
ID_OUI_FROM_DATABASE=Zhejiang ROICX Microelectronics
@@ -48830,9 +50177,6 @@ OUI:8CDE52*
OUI:A8776F*
ID_OUI_FROM_DATABASE=Zonoff
-OUI:FC4DD4*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:902B34*
ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
@@ -48881,9 +50225,6 @@ OUI:A849A5*
OUI:94DB49*
ID_OUI_FROM_DATABASE=SITCORP
-OUI:30144A*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:8CD17B*
ID_OUI_FROM_DATABASE=CG Mobile
@@ -48977,15 +50318,9 @@ OUI:B8CDA7*
OUI:F49461*
ID_OUI_FROM_DATABASE=NexGen Storage
-OUI:402CF4*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:804731*
ID_OUI_FROM_DATABASE=Packet Design, Inc.
-OUI:C4CAD9*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
OUI:ACCB09*
ID_OUI_FROM_DATABASE=Hefcom Metering (Pty) Ltd
@@ -49115,9 +50450,6 @@ OUI:FCF1CD*
OUI:B03829*
ID_OUI_FROM_DATABASE=Siliconware Precision Industries Co., Ltd.
-OUI:C86C87*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:BC0F2B*
ID_OUI_FROM_DATABASE=FORTUNE TECHGROUP CO.,LTD
@@ -49262,9 +50594,6 @@ OUI:38D135*
OUI:184E94*
ID_OUI_FROM_DATABASE=MESSOA TECHNOLOGIES INC.
-OUI:A8922C*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:94D93C*
ID_OUI_FROM_DATABASE=ENELPS
@@ -49334,9 +50663,6 @@ OUI:F0A764*
OUI:A0F217*
ID_OUI_FROM_DATABASE=GE Medical System(China) Co., Ltd.
-OUI:5067F0*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:643409*
ID_OUI_FROM_DATABASE=BITwave Pte Ltd
@@ -49412,9 +50738,6 @@ OUI:04209A*
OUI:64DC01*
ID_OUI_FROM_DATABASE=Static Systems Group PLC
-OUI:90A4DE*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:1CF5E7*
ID_OUI_FROM_DATABASE=Turtle Industry Co., Ltd.
@@ -49424,9 +50747,6 @@ OUI:9C4A7B*
OUI:2C8065*
ID_OUI_FROM_DATABASE=HARTING Inc. of North America
-OUI:80C6AB*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
OUI:F8F014*
ID_OUI_FROM_DATABASE=RackWare Inc.
@@ -49706,9 +51026,6 @@ OUI:D0E347*
OUI:84A991*
ID_OUI_FROM_DATABASE=Cyber Trans Japan Co.,Ltd.
-OUI:380DD4*
- ID_OUI_FROM_DATABASE=Primax Electronics LTD.
-
OUI:D81C14*
ID_OUI_FROM_DATABASE=Compacta International, Ltd.
@@ -49811,9 +51128,6 @@ OUI:00D11C*
OUI:1056CA*
ID_OUI_FROM_DATABASE=Peplink International Ltd.
-OUI:E83A97*
- ID_OUI_FROM_DATABASE=OCZ Technology Group
-
OUI:44A689*
ID_OUI_FROM_DATABASE=PROMAX ELECTRONICA SA
@@ -50258,9 +51572,6 @@ OUI:0026AA*
OUI:0026A4*
ID_OUI_FROM_DATABASE=Novus Produtos Eletronicos Ltda
-OUI:00269E*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc
-
OUI:002698*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -50273,9 +51584,6 @@ OUI:00268B*
OUI:002685*
ID_OUI_FROM_DATABASE=Digital Innovation
-OUI:00267E*
- ID_OUI_FROM_DATABASE=Parrot SA
-
OUI:002678*
ID_OUI_FROM_DATABASE=Logic Instrument SA
@@ -50333,9 +51641,6 @@ OUI:002614*
OUI:00260E*
ID_OUI_FROM_DATABASE=Ablaze Systems, LLC
-OUI:00260F*
- ID_OUI_FROM_DATABASE=Linn Products Ltd
-
OUI:002602*
ID_OUI_FROM_DATABASE=SMART Temps LLC
@@ -50534,12 +51839,6 @@ OUI:002491*
OUI:002496*
ID_OUI_FROM_DATABASE=Ginzinger electronic systems
-OUI:00247E*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd
-
-OUI:002483*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:002477*
ID_OUI_FROM_DATABASE=Tibbo Technology
@@ -50870,9 +52169,6 @@ OUI:00210B*
OUI:00210C*
ID_OUI_FROM_DATABASE=Cymtec Systems, Inc.
-OUI:002105*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:001FFC*
ID_OUI_FROM_DATABASE=Riccius+Sohn GmbH
@@ -50888,9 +52184,6 @@ OUI:002168*
OUI:002161*
ID_OUI_FROM_DATABASE=Yournet Inc.
-OUI:00215B*
- ID_OUI_FROM_DATABASE=Inotive
-
OUI:002155*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -51029,9 +52322,6 @@ OUI:002202*
OUI:0021F9*
ID_OUI_FROM_DATABASE=WIRECOM Technologies
-OUI:001F46*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001F40*
ID_OUI_FROM_DATABASE=Speakercraft Inc.
@@ -51104,9 +52394,6 @@ OUI:001E20*
OUI:001E19*
ID_OUI_FROM_DATABASE=GTRI
-OUI:001E1F*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001E0F*
ID_OUI_FROM_DATABASE=Briot International
@@ -51164,9 +52451,6 @@ OUI:001E8A*
OUI:001E85*
ID_OUI_FROM_DATABASE=Lagotek Corporation
-OUI:001E7E*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001E78*
ID_OUI_FROM_DATABASE=Owitek Technology Ltd.,
@@ -51176,9 +52460,6 @@ OUI:001E6D*
OUI:001E6E*
ID_OUI_FROM_DATABASE=Shenzhen First Mile Communications Ltd
-OUI:001E68*
- ID_OUI_FROM_DATABASE=Quanta Computer
-
OUI:001F71*
ID_OUI_FROM_DATABASE=xG Technology, Inc.
@@ -51209,9 +52490,6 @@ OUI:001F4D*
OUI:001F52*
ID_OUI_FROM_DATABASE=UVT Unternehmensberatung fur Verkehr und Technik GmbH
-OUI:001F0A*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001F03*
ID_OUI_FROM_DATABASE=NUM AG
@@ -51326,9 +52604,6 @@ OUI:001CAC*
OUI:001CA1*
ID_OUI_FROM_DATABASE=AKAMAI TECHNOLOGIES, INC.
-OUI:001C9C*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001C95*
ID_OUI_FROM_DATABASE=Opticomm Corporation
@@ -51353,9 +52628,6 @@ OUI:001C6E*
OUI:001C69*
ID_OUI_FROM_DATABASE=Packet Vision Ltd
-OUI:001C62*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
-
OUI:001DA5*
ID_OUI_FROM_DATABASE=WB Electronics
@@ -51674,9 +52946,6 @@ OUI:001BD9*
OUI:001BDB*
ID_OUI_FROM_DATABASE=Valeo VECS
-OUI:001BDA*
- ID_OUI_FROM_DATABASE=UTStarcom Inc
-
OUI:001BD4*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -51695,9 +52964,6 @@ OUI:001C21*
OUI:001C20*
ID_OUI_FROM_DATABASE=CLB Benelux
-OUI:001C17*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001C15*
ID_OUI_FROM_DATABASE=iPhotonix LLC
@@ -51869,9 +53135,6 @@ OUI:001A28*
OUI:001A1C*
ID_OUI_FROM_DATABASE=GT&T Engineering Pte Ltd
-OUI:001A21*
- ID_OUI_FROM_DATABASE=Indac B.V.
-
OUI:001A23*
ID_OUI_FROM_DATABASE=Ice Qube, Inc
@@ -51980,9 +53243,6 @@ OUI:001827*
OUI:00182C*
ID_OUI_FROM_DATABASE=Ascend Networks, Inc.
-OUI:00182E*
- ID_OUI_FROM_DATABASE=XStreamHD, LLC
-
OUI:00181B*
ID_OUI_FROM_DATABASE=TaiJin Metal Co., Ltd.
@@ -52181,9 +53441,6 @@ OUI:00163B*
OUI:001640*
ID_OUI_FROM_DATABASE=Asmobile Communication Inc.
-OUI:001639*
- ID_OUI_FROM_DATABASE=UBIQUAM Co.,Ltd
-
OUI:00163A*
ID_OUI_FROM_DATABASE=YVES TECHNOLOGY CO., LTD.
@@ -52247,9 +53504,6 @@ OUI:00170C*
OUI:001707*
ID_OUI_FROM_DATABASE=InGrid, Inc
-OUI:0016FB*
- ID_OUI_FROM_DATABASE=SHENZHEN MTC CO.,LTD.
-
OUI:001702*
ID_OUI_FROM_DATABASE=Osung Midicom Co., Ltd
@@ -52358,9 +53612,6 @@ OUI:0015C2*
OUI:0015BE*
ID_OUI_FROM_DATABASE=Iqua Ltd.
-OUI:0015B7*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:0015B9*
ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
@@ -52466,9 +53717,6 @@ OUI:00144B*
OUI:001589*
ID_OUI_FROM_DATABASE=D-MAX Technology Co.,Ltd
-OUI:00157D*
- ID_OUI_FROM_DATABASE=POSDATA CO., LTD.
-
OUI:001582*
ID_OUI_FROM_DATABASE=Pulse Eight Limited
@@ -52652,9 +53900,6 @@ OUI:001322*
OUI:001316*
ID_OUI_FROM_DATABASE=L-S-B Broadcast Technologies GmbH
-OUI:00130A*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:00130F*
ID_OUI_FROM_DATABASE=EGEMEN Bilgisayar Muh San ve Tic LTD STI
@@ -52949,9 +54194,6 @@ OUI:001122*
OUI:001171*
ID_OUI_FROM_DATABASE=DEXTER Communications, Inc.
-OUI:001165*
- ID_OUI_FROM_DATABASE=Znyx Networks
-
OUI:00116A*
ID_OUI_FROM_DATABASE=Domo Ltd
@@ -53006,9 +54248,6 @@ OUI:001223*
OUI:001228*
ID_OUI_FROM_DATABASE=Data Ltd.
-OUI:00121C*
- ID_OUI_FROM_DATABASE=PARROT S.A.
-
OUI:001210*
ID_OUI_FROM_DATABASE=WideRay Corp
@@ -53207,9 +54446,6 @@ OUI:000F28*
OUI:000F21*
ID_OUI_FROM_DATABASE=Scientific Atlanta, Inc
-OUI:000EE8*
- ID_OUI_FROM_DATABASE=zioncom
-
OUI:000EEF*
ID_OUI_FROM_DATABASE=Private
@@ -53279,9 +54515,6 @@ OUI:000FE8*
OUI:000FED*
ID_OUI_FROM_DATABASE=Anam Electronics Co., Ltd
-OUI:000FDB*
- ID_OUI_FROM_DATABASE=Westell Technologies
-
OUI:000FDC*
ID_OUI_FROM_DATABASE=Ueda Japan Radio Co., Ltd.
@@ -53417,12 +54650,6 @@ OUI:000D10*
OUI:000D04*
ID_OUI_FROM_DATABASE=Foxboro Eckardt Development GmbH
-OUI:000CF7*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
-OUI:000CF8*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000CFD*
ID_OUI_FROM_DATABASE=Hyundai ImageQuest Co.,Ltd.
@@ -53996,9 +55223,6 @@ OUI:000AF2*
OUI:000A05*
ID_OUI_FROM_DATABASE=Widax Corp.
-OUI:000A08*
- ID_OUI_FROM_DATABASE=ALPINE ELECTRONICS, INC.
-
OUI:000A0A*
ID_OUI_FROM_DATABASE=SUNIX Co., Ltd.
@@ -54131,9 +55355,6 @@ OUI:000906*
OUI:0008FB*
ID_OUI_FROM_DATABASE=SonoSite, Inc.
-OUI:0008F1*
- ID_OUI_FROM_DATABASE=Voltaire
-
OUI:0008F2*
ID_OUI_FROM_DATABASE=C&S Technology
@@ -54287,18 +55508,12 @@ OUI:000779*
OUI:000778*
ID_OUI_FROM_DATABASE=GERSTEL GmbH & Co. KG
-OUI:000772*
- ID_OUI_FROM_DATABASE=Alcatel Shanghai Bell Co., Ltd.
-
OUI:00076C*
ID_OUI_FROM_DATABASE=Daehanet, Inc.
OUI:00075C*
ID_OUI_FROM_DATABASE=Eastman Kodak Company
-OUI:000761*
- ID_OUI_FROM_DATABASE=Logitech Europe SA
-
OUI:000768*
ID_OUI_FROM_DATABASE=Danfoss A/S
@@ -54335,9 +55550,6 @@ OUI:000728*
OUI:000718*
ID_OUI_FROM_DATABASE=iCanTek Co., Ltd.
-OUI:00080D*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:000806*
ID_OUI_FROM_DATABASE=Raonet Systems, Inc.
@@ -54494,9 +55706,6 @@ OUI:000575*
OUI:00056F*
ID_OUI_FROM_DATABASE=Innomedia Technologies Pvt. Ltd.
-OUI:000569*
- ID_OUI_FROM_DATABASE=VMware, Inc.
-
OUI:000568*
ID_OUI_FROM_DATABASE=Piltofish Networks AB
@@ -54713,9 +55922,6 @@ OUI:00035F*
OUI:00035C*
ID_OUI_FROM_DATABASE=Saint Song Corp.
-OUI:000358*
- ID_OUI_FROM_DATABASE=Hanyang Digitech Co., Ltd.
-
OUI:00034D*
ID_OUI_FROM_DATABASE=Chiaro Networks, Ltd.
@@ -54803,9 +56009,6 @@ OUI:0004AD*
OUI:0004AA*
ID_OUI_FROM_DATABASE=Jetstream Communications
-OUI:0004A3*
- ID_OUI_FROM_DATABASE=Microchip Technology, Inc.
-
OUI:00049D*
ID_OUI_FROM_DATABASE=Ipanema Technologies
@@ -54923,9 +56126,6 @@ OUI:000464*
OUI:00045D*
ID_OUI_FROM_DATABASE=BEKA Elektronik
-OUI:0003B2*
- ID_OUI_FROM_DATABASE=Radware
-
OUI:000457*
ID_OUI_FROM_DATABASE=Universal Access Technology, Inc.
@@ -55001,9 +56201,6 @@ OUI:0002E1*
OUI:0002D5*
ID_OUI_FROM_DATABASE=ACR
-OUI:0002C9*
- ID_OUI_FROM_DATABASE=Mellanox Technologies
-
OUI:0002CE*
ID_OUI_FROM_DATABASE=FoxJet, Inc.
@@ -55877,9 +57074,6 @@ OUI:001097*
OUI:00106F*
ID_OUI_FROM_DATABASE=TRENTON TECHNOLOGY INC.
-OUI:0010C6*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:0010DA*
ID_OUI_FROM_DATABASE=Kollmorgen Corp
@@ -56033,9 +57227,6 @@ OUI:0010EA*
OUI:0010BD*
ID_OUI_FROM_DATABASE=THE TELECOMMUNICATION TECHNOLOGY COMMITTEE (TTC)
-OUI:0060D5*
- ID_OUI_FROM_DATABASE=MIYACHI TECHNOS CORP.
-
OUI:006099*
ID_OUI_FROM_DATABASE=SBE, Inc.
@@ -56246,9 +57437,6 @@ OUI:00A043*
OUI:00A047*
ID_OUI_FROM_DATABASE=INTEGRATED FITNESS CORP.
-OUI:00A00E*
- ID_OUI_FROM_DATABASE=VISUAL NETWORKS, INC.
-
OUI:00A07C*
ID_OUI_FROM_DATABASE=TONYANG NYLON CO., LTD.
@@ -56288,9 +57476,6 @@ OUI:00E017*
OUI:00603B*
ID_OUI_FROM_DATABASE=AMTEC spa
-OUI:00E08B*
- ID_OUI_FROM_DATABASE=QLogic Corp.
-
OUI:0020E5*
ID_OUI_FROM_DATABASE=APEX DATA, INC.
@@ -56351,9 +57536,6 @@ OUI:002006*
OUI:00A0A2*
ID_OUI_FROM_DATABASE=DIGICOM S.P.A.
-OUI:00A09B*
- ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS, LTD.
-
OUI:00A054*
ID_OUI_FROM_DATABASE=Private
@@ -57269,18 +58451,12 @@ OUI:0080C2*
OUI:C46699*
ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-OUI:002067*
- ID_OUI_FROM_DATABASE=Private
-
OUI:383BC8*
ID_OUI_FROM_DATABASE=2Wire Inc
OUI:DC7FA4*
ID_OUI_FROM_DATABASE=2Wire Inc
-OUI:1100AA*
- ID_OUI_FROM_DATABASE=Private
-
OUI:001288*
ID_OUI_FROM_DATABASE=2Wire Inc
@@ -57458,9 +58634,6 @@ OUI:4C14A3*
OUI:F48E38*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:74DAEA*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:D887D5*
ID_OUI_FROM_DATABASE=Leadcore Technology CO.,LTD
@@ -57944,6 +59117,9 @@ OUI:14C126*
OUI:4C2578*
ID_OUI_FROM_DATABASE=Nokia Corporation
+OUI:001EA4*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
OUI:001262*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
@@ -57953,21 +59129,18 @@ OUI:00174B*
OUI:002547*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001D3B*
+OUI:001DE9*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:0014A7*
+OUI:001D3B*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001EA4*
+OUI:0014A7*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
OUI:001CD6*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001DE9*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
OUI:D099D5*
ID_OUI_FROM_DATABASE=Alcatel-Lucent
@@ -58001,12 +59174,12 @@ OUI:78C3E9*
OUI:9C5C8E*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:102AB3*
- ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
-
OUI:70884D*
ID_OUI_FROM_DATABASE=JAPAN RADIO CO., LTD.
+OUI:102AB3*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
OUI:4C55CC*
ID_OUI_FROM_DATABASE=Zentri Pty Ltd
@@ -58019,9 +59192,6 @@ OUI:DC415F*
OUI:30636B*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:280DFC*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:84683E*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -58034,24 +59204,15 @@ OUI:FC1A11*
OUI:30A9DE*
ID_OUI_FROM_DATABASE=LG Innotek
-OUI:702526*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:903AA0*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:E0CDFD*
ID_OUI_FROM_DATABASE=Beijing E3Control Technology Co, LTD
-OUI:BC52B4*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
+OUI:208B37*
+ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd
OUI:08BE77*
ID_OUI_FROM_DATABASE=Green Electronics
-OUI:208B37*
- ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd
-
OUI:280C28*
ID_OUI_FROM_DATABASE=Unigen DataStorage Corporation
@@ -58076,12 +59237,6 @@ OUI:9046A2*
OUI:6479A7*
ID_OUI_FROM_DATABASE=Phison Electronics Corp.
-OUI:0019C5*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
-OUI:0015C1*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:C83870*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -58094,8 +59249,8 @@ OUI:44783E*
OUI:202D07*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:FC2FAA*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
+OUI:0452C7*
+ ID_OUI_FROM_DATABASE=Bose Corporation
OUI:D4612E*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -58103,9 +59258,6 @@ OUI:D4612E*
OUI:1C6758*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0452C7*
- ID_OUI_FROM_DATABASE=Bose Corporation
-
OUI:E85659*
ID_OUI_FROM_DATABASE=Advanced-Connectek Inc.
@@ -58118,6 +59270,12 @@ 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.
@@ -58136,24 +59294,9 @@ OUI:04C1B9*
OUI:689361*
ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
-OUI:D4AD2D*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:48555F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:04A316*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:98072D*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:A082AC*
ID_OUI_FROM_DATABASE=Linear DMS Solutions Sdn. Bhd.
-OUI:705A9E*
- ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
-
OUI:002697*
ID_OUI_FROM_DATABASE=Alpha Technologies Inc.
@@ -58166,16 +59309,16 @@ OUI:1CABC0*
OUI:84E323*
ID_OUI_FROM_DATABASE=Green Wave Telecommunication SDN BHD
-OUI:7071BC*
- ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
-
OUI:44650D*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-OUI:E06995*
+OUI:D897BA*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
-OUI:D897BA*
+OUI:7071BC*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:E06995*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
OUI:54D9E4*
@@ -58184,6 +59327,9 @@ OUI:54D9E4*
OUI:E4F3F5*
ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+OUI:00089F*
+ ID_OUI_FROM_DATABASE=EFM Networks
+
OUI:00185C*
ID_OUI_FROM_DATABASE=EDSLAB Technologies
@@ -58193,9 +59339,6 @@ OUI:000E2E*
OUI:00020E*
ID_OUI_FROM_DATABASE=ECI Telecom Ltd.
-OUI:0000C9*
- ID_OUI_FROM_DATABASE=Emulex Corporation
-
OUI:00115B*
ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd.
@@ -58211,11 +59354,8 @@ OUI:C03FD5*
OUI:7427EA*
ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd.
-OUI:00089F*
- ID_OUI_FROM_DATABASE=EFM Networks
-
-OUI:042AE2*
- ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:0000C9*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
OUI:001A45*
ID_OUI_FROM_DATABASE=GN Netcom A/S
@@ -58223,21 +59363,24 @@ OUI:001A45*
OUI:00168F*
ID_OUI_FROM_DATABASE=GN Netcom A/S
-OUI:00104F*
- ID_OUI_FROM_DATABASE=Oracle Corporation
-
-OUI:000782*
- ID_OUI_FROM_DATABASE=Oracle Corporation
-
OUI:083FBC*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:903809*
- ID_OUI_FROM_DATABASE=Ericsson AB
+OUI:042AE2*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:1C1B0D*
ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+OUI:903809*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:00104F*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:000782*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
OUI:E42F56*
ID_OUI_FROM_DATABASE=OptoMET GmbH
@@ -58286,6 +59429,12 @@ OUI:54E032*
OUI:3C6104*
ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:BC7574*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:20A680*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
OUI:0019E2*
ID_OUI_FROM_DATABASE=Juniper Networks
@@ -58307,21 +59456,660 @@ OUI:003146*
OUI:80ACAC*
ID_OUI_FROM_DATABASE=Juniper Networks
-OUI:BC7574*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
-OUI:20A680*
- ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-
OUI:50DD4F*
ID_OUI_FROM_DATABASE=Automation Components, Inc
OUI:904D4A*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+OUI:38700C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
OUI:7C79E8*
ID_OUI_FROM_DATABASE=PayRange Inc.
+OUI:540593*
+ ID_OUI_FROM_DATABASE=WOORI ELEC Co.,Ltd
+
+OUI:A067BE*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:C4CAD9*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:74258A*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:70F96D*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:00260F*
+ ID_OUI_FROM_DATABASE=Linn Products Ltd
+
+OUI:F845AD*
+ ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
+
+OUI:000358*
+ ID_OUI_FROM_DATABASE=Hanyang Digitech Co.Ltd
+
+OUI:000761*
+ ID_OUI_FROM_DATABASE=29530
+
+OUI:60512C*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:905F2E*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:4C0B3A*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:C02FF1*
+ ID_OUI_FROM_DATABASE=Volta Networks
+
+OUI:4882F2*
+ ID_OUI_FROM_DATABASE=Appel Elektronik GmbH
+
+OUI:0C5101*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:086D41*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:04D3CF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:30C82A*
+ ID_OUI_FROM_DATABASE=WI-BIZ srl
+
+OUI:0062EC*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:0C8A87*
+ ID_OUI_FROM_DATABASE=AgLogica Holdings, Inc
+
+OUI:34A2A2*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:20F17C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:34B354*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:749D8F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:346AC2*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:50F5DA*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:8CD2E9*
+ ID_OUI_FROM_DATABASE=NIPPON SMT Co.Ltd
+
+OUI:C83DFC*
+ ID_OUI_FROM_DATABASE=Pioneer DJ Corporation
+
+OUI:0016FB*
+ ID_OUI_FROM_DATABASE=SHENZHEN MTC CO LTD
+
+OUI:08010F*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:381DD9*
+ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED
+
+OUI:6C9522*
+ ID_OUI_FROM_DATABASE=Scalys
+
+OUI:8C59C3*
+ ID_OUI_FROM_DATABASE=ADB Italia
+
+OUI:60C0BF*
+ ID_OUI_FROM_DATABASE=ON Semiconductor
+
+OUI:98398E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:348A7B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:BC765E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E0A8B8*
+ ID_OUI_FROM_DATABASE=Le Shi Zhi Xin Electronic Technology (Tianjin) Limited
+
+OUI:B88198*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:CCA260*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
+
+OUI:E4FB8F*
+ ID_OUI_FROM_DATABASE=MOBIWIRE MOBILES (NINGBO) CO.,LTD
+
+OUI:78009E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C8AFE3*
+ ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
+
+OUI:7C3548*
+ ID_OUI_FROM_DATABASE=Transcend Information
+
+OUI:E83A97*
+ ID_OUI_FROM_DATABASE=Toshiba Corporation
+
+OUI:9C8ECD*
+ ID_OUI_FROM_DATABASE=Amcrest Technologies
+
+OUI:282536*
+ ID_OUI_FROM_DATABASE=SHENZHEN HOLATEK CO.,LTD
+
+OUI:FCA89A*
+ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd
+
+OUI:B8F8BE*
+ ID_OUI_FROM_DATABASE=BLUECOM
+
+OUI:6073BC*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:90EED9*
+ ID_OUI_FROM_DATABASE=UNIVERSAL DE DESARROLLOS ELECTRÓNICOS, SA
+
+OUI:043110*
+ ID_OUI_FROM_DATABASE=Inspur Group Co., Ltd.
+
+OUI:00215B*
+ ID_OUI_FROM_DATABASE=SenseAnywhere
+
+OUI:C816BD*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:587E61*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:340AFF*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:FC51A4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F85A00*
+ ID_OUI_FROM_DATABASE=Sanford LP
+
+OUI:5067F0*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:C86C87*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:D8E0B8*
+ ID_OUI_FROM_DATABASE=BULAT LLC
+
+OUI:68C44D*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:48FCB6*
+ ID_OUI_FROM_DATABASE=LAVA INTERNATIONAL(H.K) LIMITED
+
+OUI:CC3540*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:C42795*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:58238C*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:705A9E*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:80C6AB*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:90A4DE*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:3C970E*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd.
+
+OUI:30144A*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:A854B2*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:38BC1A*
+ ID_OUI_FROM_DATABASE=MEIZU Technology Co., Ltd.
+
+OUI:0004A3*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
+OUI:98CF53*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:F4CB52*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:446EE5*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:2C282D*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:80414E*
+ ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
+
+OUI:8C7716*
+ ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
+
+OUI:000A08*
+ ID_OUI_FROM_DATABASE=Alpine Electronics, Inc.
+
+OUI:A0143D*
+ ID_OUI_FROM_DATABASE=PARROT SA
+
+OUI:00267E*
+ ID_OUI_FROM_DATABASE=PARROT SA
+
+OUI:00121C*
+ ID_OUI_FROM_DATABASE=PARROT SA
+
+OUI:B85510*
+ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
+
+OUI:000EE8*
+ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
+
+OUI:001165*
+ ID_OUI_FROM_DATABASE=ZNYX Networks, Inc.
+
+OUI:0060D5*
+ ID_OUI_FROM_DATABASE=AMADA MIYACHI Co., Ltd
+
+OUI:000FDB*
+ ID_OUI_FROM_DATABASE=Westell Technologies Inc.
+
+OUI:D404FF*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:C45444*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:00269E*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:683563*
+ ID_OUI_FROM_DATABASE=SHENZHEN LIOWN ELECTRONICS CO.,LTD.
+
+OUI:0003B2*
+ ID_OUI_FROM_DATABASE=Radware
+
+OUI:2C600C*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:001E68*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:00A09B*
+ ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS, LTD.
+
+OUI:00E08B*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:00080D*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:0015B7*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:000569*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:0008F1*
+ ID_OUI_FROM_DATABASE=Voltaire
+
+OUI:001BDA*
+ ID_OUI_FROM_DATABASE=UTStarcom Inc
+
+OUI:FC4DD4*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:402CF4*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:0010C6*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:00247E*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:DC9FDB*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:001639*
+ ID_OUI_FROM_DATABASE=Ubiquam Co., Ltd.
+
+OUI:183919*
+ ID_OUI_FROM_DATABASE=Unicoi Systems
+
+OUI:90A46A*
+ ID_OUI_FROM_DATABASE=SISNET CO., LTD
+
+OUI:14E7C8*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:280DFC*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:0015C1*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:0019C5*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:ACA213*
+ ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+
+OUI:38F8CA*
+ ID_OUI_FROM_DATABASE=OWIN Inc.
+
+OUI:54D272*
+ ID_OUI_FROM_DATABASE=Nuki Home Solutions GmbH
+
+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
+
+OUI:3CCD93*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:583F54*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:001C62*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:002483*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:E417D8*
+ ID_OUI_FROM_DATABASE=8BITDO TECHNOLOGY HK LIMITED
+
+OUI:40B0FA*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:A09169*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:286C07*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
+OUI:84D931*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:34FCEF*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:485929*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:505527*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:98D6F7*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:A8922C*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:44DC91*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:9CD332*
+ ID_OUI_FROM_DATABASE=PLC Technology Ltd
+
+OUI:94D723*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
+
+OUI:A89DD2*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
+
+OUI:903AA0*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:184A6F*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:FC2FAA*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:BC52B4*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:A0F3E4*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:002105*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:000772*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:E0DDC0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:702526*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:982F3C*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:380DD4*
+ ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
+
+OUI:98FDB4*
+ ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
+
+OUI:00157D*
+ ID_OUI_FROM_DATABASE=POSDATA
+
+OUI:F8E61A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:888322*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:84B541*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:18DC56*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:001F46*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001F0A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00130A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001E7E*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001C9C*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000CF8*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000CF7*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001E1F*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001C17*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00182E*
+ ID_OUI_FROM_DATABASE=XStreamHD
+
+OUI:50016B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:58986F*
+ ID_OUI_FROM_DATABASE=Revolution Display
+
+OUI:28AC67*
+ ID_OUI_FROM_DATABASE=Mach Power, Rappresentanze Internazionali s.r.l.
+
+OUI:B0B28F*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:DC1A01*
+ ID_OUI_FROM_DATABASE=Ecoliv Technology ( Shenzhen ) Ltd.
+
+OUI:7CFE90*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:0002C9*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:D05FB8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C4BE84*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:78A504*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7C669D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D03972*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:E0E5CF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7CEC79*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:74D6EA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017EB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:883314*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:84DD20*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:1C4593*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:5C6B32*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D03761*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0024BA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0022A5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0021BA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001833*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D8952F*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:649C8E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:F4FC32*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:74DAEA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:04A316*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:98072D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001AB6*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C8A030*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:34B1F7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C4EDBA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:641269*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:287AEE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A40DBC*
+ ID_OUI_FROM_DATABASE=Xiamen Intretech Inc.
+
+OUI:EC8EAE*
+ ID_OUI_FROM_DATABASE=Nagravision SA
+
+OUI:606405*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:708BCD*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001A21*
+ ID_OUI_FROM_DATABASE=Brookhuis Applied Technologies BV
+
+OUI:00A00E*
+ ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
+
+OUI:1C330E*
+ ID_OUI_FROM_DATABASE=PernixData
+
+OUI:345760*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
+OUI:343DC4*
+ ID_OUI_FROM_DATABASE=BUFFALO.INC
+
OUI:2C3996*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -58343,9 +60131,6 @@ OUI:A0F895*
OUI:0078CD*
ID_OUI_FROM_DATABASE=Ignition Design Labs
-OUI:40D855*
- ID_OUI_FROM_DATABASE=IEEE Registration Authority
-
OUI:28ED6A*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -58367,21 +60152,6 @@ OUI:086698*
OUI:002926*
ID_OUI_FROM_DATABASE=Applied Optoelectronics, Inc Taiwan Branch
-OUI:44C15C*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:1CE2CC*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:985945*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:1CBA8C*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:BC6A29*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:2CFD37*
ID_OUI_FROM_DATABASE=Blue Calypso, Inc.
@@ -58412,24 +60182,6 @@ OUI:3CDD89*
OUI:2C56DC*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:001830*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:C0E422*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:04E451*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D00790*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017E7*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:0017E9*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:001E4C*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
@@ -58448,9 +60200,6 @@ OUI:B0C090*
OUI:001DD2*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:B0C287*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
-
OUI:1CA770*
ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
@@ -58460,9 +60209,6 @@ OUI:C42F90*
OUI:9C5D12*
ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
-OUI:1CCB99*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:A42BB0*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
@@ -58511,12 +60257,6 @@ OUI:84ACFB*
OUI:34BA75*
ID_OUI_FROM_DATABASE=Tembo Systems, Inc.
-OUI:FCFFAA*
- ID_OUI_FROM_DATABASE=IEEE Registration Authority
-
-OUI:00CB00*
- ID_OUI_FROM_DATABASE=Private
-
OUI:9486CD*
ID_OUI_FROM_DATABASE=SEOUL ELECTRONICS&TELECOM
@@ -58697,9 +60437,6 @@ OUI:001FE1*
OUI:002268*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
-OUI:9471AC*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:A09347*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
@@ -58964,39 +60701,6 @@ OUI:9017AC*
OUI:94049C*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:001237*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:948854*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:A863F2*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:D0FF50*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:20C38F*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:A0E6F8*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:5C313E*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:F4B85E*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:68C90B*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:EC24B8*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:689E19*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:C46AB7*
ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
@@ -59582,9 +61286,6 @@ OUI:38B725*
OUI:ACEC80*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:80EA23*
- ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
-
OUI:4CC681*
ID_OUI_FROM_DATABASE=Shenzhen Aisat Electronic Co., Ltd.
@@ -59597,9 +61298,6 @@ OUI:E0553D*
OUI:0894EF*
ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
-OUI:304487*
- ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
-
OUI:E0319E*
ID_OUI_FROM_DATABASE=Valve Corporation
@@ -59621,9 +61319,6 @@ OUI:949F3E*
OUI:788E33*
ID_OUI_FROM_DATABASE=Jiangsu SEUIC Technology Co.,Ltd
-OUI:94D859*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:E01AEA*
ID_OUI_FROM_DATABASE=Allied Telesis, Inc.
@@ -59663,9 +61358,6 @@ OUI:00FC8D*
OUI:1CC586*
ID_OUI_FROM_DATABASE=Absolute Acoustics
-OUI:C49A02*
- ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communicaitons)
-
OUI:E076D0*
ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
@@ -59678,9 +61370,6 @@ OUI:64167F*
OUI:54E2C8*
ID_OUI_FROM_DATABASE=Dongguan Aoyuan Electronics Technology Co., Ltd
-OUI:08D0B7*
- ID_OUI_FROM_DATABASE=HISENSE ELECTRIC CO.,LTD.
-
OUI:20D75A*
ID_OUI_FROM_DATABASE=Posh Mobile Limited
@@ -59750,9 +61439,6 @@ OUI:408D5C*
OUI:6CE01E*
ID_OUI_FROM_DATABASE=Modcam AB
-OUI:D09DAB*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:E8F2E3*
ID_OUI_FROM_DATABASE=Starcor Beijing Co.,Limited
@@ -59789,9 +61475,6 @@ OUI:0CE725*
OUI:6C2E72*
ID_OUI_FROM_DATABASE=B&B EXPORTING LIMITED
-OUI:98EECB*
- ID_OUI_FROM_DATABASE=Wistron InfoComm(ZhongShan)Corporation
-
OUI:FC3288*
ID_OUI_FROM_DATABASE=CELOT Wireless Co., Ltd
@@ -59816,9 +61499,6 @@ OUI:ACCAAB*
OUI:241B44*
ID_OUI_FROM_DATABASE=Hangzhou Tuners Electronics Co., Ltd
-OUI:B0E03C*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:90C35F*
ID_OUI_FROM_DATABASE=Nanjing Jiahao Technology Co., Ltd.
@@ -59840,9 +61520,6 @@ OUI:34873D*
OUI:186882*
ID_OUI_FROM_DATABASE=Beward R&D Co., Ltd.
-OUI:FC3D93*
- ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
-
OUI:344CA4*
ID_OUI_FROM_DATABASE=amazipoint technology Ltd.
@@ -60002,9 +61679,6 @@ OUI:0499E6*
OUI:94BF95*
ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd
-OUI:344DF7*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:FC9FE1*
ID_OUI_FROM_DATABASE=CONWIN.Tech. Ltd
@@ -60056,9 +61730,6 @@ OUI:CCBDD3*
OUI:50294D*
ID_OUI_FROM_DATABASE=NANJING IOT SENSOR TECHNOLOGY CO,LTD
-OUI:90EF68*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:0CCFD1*
ID_OUI_FROM_DATABASE=SPRINGWAVE Co., Ltd
@@ -60083,9 +61754,6 @@ OUI:4C0BBE*
OUI:08EB29*
ID_OUI_FROM_DATABASE=Jiangsu Huitong Group Co.,Ltd.
-OUI:D88039*
- ID_OUI_FROM_DATABASE=Microchip Technology Inc.
-
OUI:E48C0F*
ID_OUI_FROM_DATABASE=Discovery Insure
@@ -60104,12 +61772,6 @@ OUI:C4BD6A*
OUI:14488B*
ID_OUI_FROM_DATABASE=Shenzhen Doov Technology Co.,Ltd
-OUI:70BAEF*
- ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-
-OUI:CC03FA*
- ID_OUI_FROM_DATABASE=Technicolor CH USA
-
OUI:603696*
ID_OUI_FROM_DATABASE=The Sapling Company
@@ -60167,12 +61829,6 @@ OUI:480C49*
OUI:5CB8CB*
ID_OUI_FROM_DATABASE=Allis Communications
-OUI:4C9EFF*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
-OUI:C44BD1*
- ID_OUI_FROM_DATABASE=Wallys Communications Teachnologies Co.,Ltd.
-
OUI:E85D6B*
ID_OUI_FROM_DATABASE=Luminate Wireless
@@ -60221,9 +61877,6 @@ OUI:A0FC6E*
OUI:44D4E0*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
-OUI:5CF4AB*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:D0FA1D*
ID_OUI_FROM_DATABASE=Qihoo 360 Technology Co.,Ltd
@@ -60311,12 +61964,6 @@ OUI:A46CC1*
OUI:90DB46*
ID_OUI_FROM_DATABASE=E-LEAD ELECTRONIC CO., LTD
-OUI:F8A9D0*
- ID_OUI_FROM_DATABASE=LG Electronics
-
-OUI:289AFA*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
OUI:D42F23*
ID_OUI_FROM_DATABASE=Akenori PTE Ltd
@@ -60434,9 +62081,6 @@ OUI:18CC23*
OUI:648D9E*
ID_OUI_FROM_DATABASE=IVT Electronic Co.,Ltd
-OUI:CCFA00*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:CC95D7*
ID_OUI_FROM_DATABASE=Vizio, Inc
@@ -60575,9 +62219,6 @@ OUI:68FCB3*
OUI:70305E*
ID_OUI_FROM_DATABASE=Nanjing Zhongke Menglian Information Technology Co.,LTD
-OUI:6C98EB*
- ID_OUI_FROM_DATABASE=Ocedo GmbH
-
OUI:9C8888*
ID_OUI_FROM_DATABASE=Simac Techniek NV
@@ -60659,9 +62300,6 @@ OUI:084027*
OUI:7C2048*
ID_OUI_FROM_DATABASE=KoamTac
-OUI:BCF5AC*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:705986*
ID_OUI_FROM_DATABASE=OOO TTV
@@ -60737,9 +62375,6 @@ OUI:A0CEC8*
OUI:907A28*
ID_OUI_FROM_DATABASE=Beijing Morncloud Information And Technology Co. Ltd.
-OUI:28285D*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:CCD29B*
ID_OUI_FROM_DATABASE=Shenzhen Bopengfa Elec&Technology CO.,Ltd
@@ -60815,9 +62450,6 @@ OUI:103B59*
OUI:746630*
ID_OUI_FROM_DATABASE=T:mi Ytti
-OUI:70E284*
- ID_OUI_FROM_DATABASE=Wistron InfoComm(Zhongshan) Corporation
-
OUI:B0FEBD*
ID_OUI_FROM_DATABASE=Private
@@ -61112,9 +62744,6 @@ OUI:58D6D3*
OUI:68FB95*
ID_OUI_FROM_DATABASE=Generalplus Technology Inc.
-OUI:6002B4*
- ID_OUI_FROM_DATABASE=Wistron NeWeb Corp.
-
OUI:E4C146*
ID_OUI_FROM_DATABASE=Objetivos y Servicios de Valor A
@@ -61127,9 +62756,6 @@ OUI:C45DD8*
OUI:C44EAC*
ID_OUI_FROM_DATABASE=Shenzhen Shiningworth Technology Co., Ltd.
-OUI:44334C*
- ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
-
OUI:C458C2*
ID_OUI_FROM_DATABASE=Shenzhen TATFOOK Technology Co., Ltd.
@@ -61184,9 +62810,6 @@ OUI:C0AA68*
OUI:B829F7*
ID_OUI_FROM_DATABASE=Blaster Tech
-OUI:CC2D8C*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
-
OUI:00C14F*
ID_OUI_FROM_DATABASE=DDL Co,.ltd.
@@ -61292,9 +62915,6 @@ OUI:34BDFA*
OUI:70F927*
ID_OUI_FROM_DATABASE=Samsung Electronics
-OUI:A8AD3D*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:8CEEC6*
ID_OUI_FROM_DATABASE=Precepscion Pty. Ltd.
@@ -61415,9 +63035,6 @@ OUI:D88A3B*
OUI:BCD940*
ID_OUI_FROM_DATABASE=ASR Co,.Ltd.
-OUI:F45214*
- ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
-
OUI:EC4993*
ID_OUI_FROM_DATABASE=Qihan Technology Co., Ltd
@@ -61457,9 +63074,6 @@ OUI:9C0111*
OUI:0CA138*
ID_OUI_FROM_DATABASE=Blinq Wireless Inc.
-OUI:B0B2DC*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:348137*
ID_OUI_FROM_DATABASE=UNICARD SA
@@ -61517,9 +63131,6 @@ OUI:3CC1F6*
OUI:54E63F*
ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd.
-OUI:006B9E*
- ID_OUI_FROM_DATABASE=VIZIO Inc
-
OUI:F88C1C*
ID_OUI_FROM_DATABASE=KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING
@@ -61628,15 +63239,9 @@ OUI:6044F5*
OUI:AC51EE*
ID_OUI_FROM_DATABASE=Cambridge Communication Systems Ltd
-OUI:00AA70*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:10E4AF*
ID_OUI_FROM_DATABASE=APR, LLC
-OUI:E03005*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:B0BD6D*
ID_OUI_FROM_DATABASE=Echostreams Innovative Solutions
@@ -61787,9 +63392,6 @@ OUI:C8F9F9*
OUI:F0F755*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:10F96F*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:B01C91*
ID_OUI_FROM_DATABASE=Elim Co
@@ -62039,12 +63641,6 @@ OUI:C0E54E*
OUI:E435FB*
ID_OUI_FROM_DATABASE=Sabre Technology (Hull) Ltd
-OUI:28BE9B*
- ID_OUI_FROM_DATABASE=Technicolor USA Inc.
-
-OUI:F01C13*
- ID_OUI_FROM_DATABASE=LG Electronics
-
OUI:00CD90*
ID_OUI_FROM_DATABASE=MAS Elektronik AG
@@ -62180,9 +63776,6 @@ OUI:A88CEE*
OUI:204005*
ID_OUI_FROM_DATABASE=feno GmbH
-OUI:CC52AF*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:6C81FE*
ID_OUI_FROM_DATABASE=Mitsuba Corporation
@@ -62321,9 +63914,6 @@ OUI:B44CC2*
OUI:084EBF*
ID_OUI_FROM_DATABASE=Broad Net Mux Corporation
-OUI:18ABF5*
- ID_OUI_FROM_DATABASE=Ultra Electronics - Electrics
-
OUI:48CB6E*
ID_OUI_FROM_DATABASE=Cello Electronics (UK) Ltd
@@ -62336,9 +63926,6 @@ OUI:A86A6F*
OUI:4022ED*
ID_OUI_FROM_DATABASE=Digital Projection Ltd
-OUI:0CA402*
- ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
-
OUI:0817F4*
ID_OUI_FROM_DATABASE=IBM Corp
@@ -62405,9 +63992,6 @@ OUI:20FECD*
OUI:94D019*
ID_OUI_FROM_DATABASE=Cydle Corp.
-OUI:9C220E*
- ID_OUI_FROM_DATABASE=TASCAN Service GmbH
-
OUI:2CA157*
ID_OUI_FROM_DATABASE=acromate, Inc.
@@ -62546,9 +64130,6 @@ OUI:5CBD9E*
OUI:743889*
ID_OUI_FROM_DATABASE=ANNAX Anzeigesysteme GmbH
-OUI:E89A8F*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc.
-
OUI:647FDA*
ID_OUI_FROM_DATABASE=TEKTELIC Communications Inc.
@@ -62618,9 +64199,6 @@ OUI:34A183*
OUI:740ABC*
ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited
-OUI:E8E0B7*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:588D09*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -62630,9 +64208,6 @@ OUI:342109*
OUI:08FAE0*
ID_OUI_FROM_DATABASE=Fohhn Audio AG
-OUI:B439D6*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
-
OUI:506F9A*
ID_OUI_FROM_DATABASE=Wi-Fi Alliance
@@ -62681,9 +64256,6 @@ OUI:FC75E6*
OUI:20B0F7*
ID_OUI_FROM_DATABASE=Enclustra GmbH
-OUI:8C90D3*
- ID_OUI_FROM_DATABASE=Alcatel Lucent
-
OUI:4013D9*
ID_OUI_FROM_DATABASE=Global ES
@@ -62864,9 +64436,6 @@ OUI:F04335*
OUI:A479E4*
ID_OUI_FROM_DATABASE=KLINFO Corp
-OUI:FCFAF7*
- ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd.
-
OUI:003CC5*
ID_OUI_FROM_DATABASE=WONWOO Engineering Co., Ltd
@@ -62930,9 +64499,6 @@ OUI:E0CA4D*
OUI:E497F0*
ID_OUI_FROM_DATABASE=Shanghai VLC Technologies Ltd. Co.
-OUI:44A42D*
- ID_OUI_FROM_DATABASE=TCT Mobile Limited
-
OUI:204E6B*
ID_OUI_FROM_DATABASE=Axxana(israel) ltd
@@ -63083,15 +64649,9 @@ OUI:7CCB0D*
OUI:ECE9F8*
ID_OUI_FROM_DATABASE=Guang Zhou TRI-SUN Electronics Technology Co., Ltd
-OUI:E89D87*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:9CAFCA*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:784476*
- ID_OUI_FROM_DATABASE=Zioncom technology co.,ltd
-
OUI:34CE94*
ID_OUI_FROM_DATABASE=Parsec (Pty) Ltd
@@ -63245,9 +64805,6 @@ OUI:DC3350*
OUI:00271E*
ID_OUI_FROM_DATABASE=Xagyl Communications
-OUI:002722*
- ID_OUI_FROM_DATABASE=Ubiquiti Networks
-
OUI:002716*
ID_OUI_FROM_DATABASE=Adachi-Syokai Co., Ltd.
@@ -63278,9 +64835,6 @@ OUI:00264E*
OUI:0025E6*
ID_OUI_FROM_DATABASE=Belgian Monitoring Systems bvba
-OUI:0025E5*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
-
OUI:0025E1*
ID_OUI_FROM_DATABASE=SHANGHAI SEEYOO ELECTRONIC & TECHNOLOGY CO., LTD
@@ -63347,9 +64901,6 @@ OUI:0025A3*
OUI:00259C*
ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
-OUI:002597*
- ID_OUI_FROM_DATABASE=Kalki Communication Technologies
-
OUI:002590*
ID_OUI_FROM_DATABASE=Super Micro Computer, Inc.
@@ -63380,9 +64931,6 @@ OUI:0026FE*
OUI:0026F8*
ID_OUI_FROM_DATABASE=Golden Highway Industry Development Co., Ltd.
-OUI:0026F1*
- ID_OUI_FROM_DATABASE=ProCurve Networking by HP
-
OUI:0026EB*
ID_OUI_FROM_DATABASE=Advanced Spectrum Technology Co., Ltd.
@@ -63527,9 +65075,6 @@ OUI:00250B*
OUI:002504*
ID_OUI_FROM_DATABASE=Valiant Communications Limited
-OUI:0024FF*
- ID_OUI_FROM_DATABASE=QLogic Corporation
-
OUI:0024FD*
ID_OUI_FROM_DATABASE=Accedian Networks Inc
@@ -63713,9 +65258,6 @@ OUI:0022BC*
OUI:0022B5*
ID_OUI_FROM_DATABASE=NOVITA
-OUI:0022A9*
- ID_OUI_FROM_DATABASE=LG Electronics Inc
-
OUI:0022AF*
ID_OUI_FROM_DATABASE=Safety Vision
@@ -63734,9 +65276,6 @@ OUI:002323*
OUI:00231A*
ID_OUI_FROM_DATABASE=ITF Co., Ltd.
-OUI:002318*
- ID_OUI_FROM_DATABASE=Toshiba
-
OUI:002311*
ID_OUI_FROM_DATABASE=Gloscom Co., Ltd.
@@ -63791,9 +65330,6 @@ OUI:002405*
OUI:0023F5*
ID_OUI_FROM_DATABASE=WILO SE
-OUI:0023F8*
- ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
-
OUI:0023FE*
ID_OUI_FROM_DATABASE=Biodevices, SA
@@ -64142,9 +65678,6 @@ OUI:001FA4*
OUI:001FA0*
ID_OUI_FROM_DATABASE=A10 Networks
-OUI:001F9A*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:001F99*
ID_OUI_FROM_DATABASE=SERONICS co.ltd
@@ -64304,9 +65837,6 @@ OUI:001D02*
OUI:001CF6*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001CEF*
- ID_OUI_FROM_DATABASE=Primax Electronics LTD
-
OUI:001CEA*
ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc
@@ -64493,9 +66023,6 @@ OUI:001D7F*
OUI:001D83*
ID_OUI_FROM_DATABASE=Emitech Corporation
-OUI:001D72*
- ID_OUI_FROM_DATABASE=Wistron Corporation
-
OUI:001D79*
ID_OUI_FROM_DATABASE=SIGNAMAX LLC
@@ -64664,9 +66191,6 @@ OUI:001B28*
OUI:001B2D*
ID_OUI_FROM_DATABASE=Med-Eng Systems Inc.
-OUI:001B24*
- ID_OUI_FROM_DATABASE=Quanta Computer Inc.
-
OUI:001B1F*
ID_OUI_FROM_DATABASE=DELTA - Danish Electronics, Light & Acoustics
@@ -64730,9 +66254,6 @@ OUI:001BCB*
OUI:001BC4*
ID_OUI_FROM_DATABASE=Ultratec, Inc.
-OUI:001BBA*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:001BB5*
ID_OUI_FROM_DATABASE=ZF Electronics GmbH
@@ -64748,9 +66269,6 @@ OUI:001B05*
OUI:001B00*
ID_OUI_FROM_DATABASE=Neopost Technologies
-OUI:001AF4*
- ID_OUI_FROM_DATABASE=Handreamnet
-
OUI:001AF9*
ID_OUI_FROM_DATABASE=AeroVIronment (AV Inc)
@@ -64760,9 +66278,6 @@ OUI:001AEF*
OUI:001AE3*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001AE8*
- ID_OUI_FROM_DATABASE=Unify GmbH and Co KG
-
OUI:001AEA*
ID_OUI_FROM_DATABASE=Radio Terminal Systems Pty Ltd
@@ -64826,9 +66341,6 @@ OUI:001A70*
OUI:001A72*
ID_OUI_FROM_DATABASE=Mosart Semiconductor Corp.
-OUI:001A6B*
- ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
-
OUI:001A64*
ID_OUI_FROM_DATABASE=IBM Corp
@@ -65027,9 +66539,6 @@ OUI:0018ED*
OUI:0018E6*
ID_OUI_FROM_DATABASE=Computer Hardware Design SIA
-OUI:0018DA*
- ID_OUI_FROM_DATABASE=AMBER wireless GmbH
-
OUI:0018DF*
ID_OUI_FROM_DATABASE=The Morey Corporation
@@ -65075,9 +66584,6 @@ OUI:0017DB*
OUI:0017CC*
ID_OUI_FROM_DATABASE=Alcatel-Lucent
-OUI:0017D1*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:0017C5*
ID_OUI_FROM_DATABASE=SonicWALL
@@ -65102,9 +66608,6 @@ OUI:00184B*
OUI:001846*
ID_OUI_FROM_DATABASE=Crypto S.A.
-OUI:00183A*
- ID_OUI_FROM_DATABASE=Westell Technologies
-
OUI:001829*
ID_OUI_FROM_DATABASE=Gatsometer
@@ -65234,9 +66737,6 @@ OUI:0016BA*
OUI:00164F*
ID_OUI_FROM_DATABASE=World Ethnic Broadcastin Inc.
-OUI:00164D*
- ID_OUI_FROM_DATABASE=Alcatel North America IP Division
-
OUI:001648*
ID_OUI_FROM_DATABASE=SSD Company Limited
@@ -65378,9 +66878,6 @@ OUI:00166E*
OUI:001667*
ID_OUI_FROM_DATABASE=A-TEC Subsystem INC.
-OUI:001660*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:00165B*
ID_OUI_FROM_DATABASE=Grip Audio
@@ -65435,9 +66932,6 @@ OUI:001685*
OUI:0015EF*
ID_OUI_FROM_DATABASE=NEC TOKIN Corporation
-OUI:0015E8*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:0015E3*
ID_OUI_FROM_DATABASE=Dream Technologies Corporation
@@ -65474,9 +66968,6 @@ OUI:0014CE*
OUI:0014C8*
ID_OUI_FROM_DATABASE=Contemporary Research Corp
-OUI:0014C7*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:0014BB*
ID_OUI_FROM_DATABASE=Open Interface North America
@@ -65582,9 +67073,6 @@ OUI:00154F*
OUI:001546*
ID_OUI_FROM_DATABASE=ITG Worldwide Sdn Bhd
-OUI:001540*
- ID_OUI_FROM_DATABASE=Nortel
-
OUI:00153F*
ID_OUI_FROM_DATABASE=Alcatel Alenia Space Italia
@@ -65627,9 +67115,6 @@ OUI:00148B*
OUI:00148D*
ID_OUI_FROM_DATABASE=Cubic Defense Simulation Systems
-OUI:00148C*
- ID_OUI_FROM_DATABASE=Fortress Technologies
-
OUI:001486*
ID_OUI_FROM_DATABASE=Echo Digital Audio Corporation
@@ -65750,9 +67235,6 @@ OUI:00142E*
OUI:001429*
ID_OUI_FROM_DATABASE=V Center Technologies Co., Ltd.
-OUI:001428*
- ID_OUI_FROM_DATABASE=Vocollect, Inc
-
OUI:001427*
ID_OUI_FROM_DATABASE=JazzMutant
@@ -65903,9 +67385,6 @@ OUI:00127F*
OUI:001278*
ID_OUI_FROM_DATABASE=International Bar Code
-OUI:00126C*
- ID_OUI_FROM_DATABASE=Visonic Ltd.
-
OUI:001273*
ID_OUI_FROM_DATABASE=Stoke Inc
@@ -65999,9 +67478,6 @@ OUI:00120E*
OUI:00117A*
ID_OUI_FROM_DATABASE=Singim International Corp.
-OUI:00116E*
- ID_OUI_FROM_DATABASE=PePLink Ltd.
-
OUI:001173*
ID_OUI_FROM_DATABASE=SMART Storage Systems
@@ -66977,9 +68453,6 @@ OUI:000A5D*
OUI:000AF4*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000AED*
- ID_OUI_FROM_DATABASE=HARTING Systems GmbH & Co KG
-
OUI:000AE8*
ID_OUI_FROM_DATABASE=Cathay Roxus Information Technology Co. LTD
@@ -67043,9 +68516,6 @@ OUI:000B1F*
OUI:000B13*
ID_OUI_FROM_DATABASE=ZETRON INC
-OUI:000B0E*
- ID_OUI_FROM_DATABASE=Trapeze Networks
-
OUI:000B0C*
ID_OUI_FROM_DATABASE=Agile Systems Inc.
@@ -67820,9 +69290,6 @@ OUI:00035B*
OUI:000356*
ID_OUI_FROM_DATABASE=Wincor Nixdorf International GmbH
-OUI:00034B*
- ID_OUI_FROM_DATABASE=Nortel Networks
-
OUI:000350*
ID_OUI_FROM_DATABASE=BTICINO SPA
@@ -67925,9 +69392,6 @@ OUI:0003AD*
OUI:000396*
ID_OUI_FROM_DATABASE=EZ Cast Co., Ltd.
-OUI:00039D*
- ID_OUI_FROM_DATABASE=Qisda Corporation
-
OUI:00050D*
ID_OUI_FROM_DATABASE=Midstream Technologies, Inc.
@@ -68123,9 +69587,6 @@ OUI:00024F*
OUI:000274*
ID_OUI_FROM_DATABASE=Tommy Technologies Corp.
-OUI:000276*
- ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
-
OUI:00026F*
ID_OUI_FROM_DATABASE=Senao International Co., Ltd.
@@ -68744,9 +70205,6 @@ OUI:009061*
OUI:0090A9*
ID_OUI_FROM_DATABASE=WESTERN DIGITAL
-OUI:009006*
- ID_OUI_FROM_DATABASE=HAMAMATSU PHOTONICS K.K.
-
OUI:009072*
ID_OUI_FROM_DATABASE=SIMRAD AS
@@ -69206,9 +70664,6 @@ OUI:00E0B5*
OUI:00E073*
ID_OUI_FROM_DATABASE=NATIONAL AMUSEMENT NETWORK, INC.
-OUI:00E09E*
- ID_OUI_FROM_DATABASE=QUANTUM CORPORATION
-
OUI:00E0E8*
ID_OUI_FROM_DATABASE=GRETACODER Data Systems AG
@@ -69329,9 +70784,6 @@ OUI:006028*
OUI:00606A*
ID_OUI_FROM_DATABASE=MITSUBISHI WIRELESS COMMUNICATIONS. INC.
-OUI:00E011*
- ID_OUI_FROM_DATABASE=Uniden Corporation
-
OUI:00E021*
ID_OUI_FROM_DATABASE=FREEGATE CORP.
@@ -69407,9 +70859,6 @@ OUI:00A0C1*
OUI:00A07D*
ID_OUI_FROM_DATABASE=SEEQ TECHNOLOGY, INC.
-OUI:00A0C6*
- ID_OUI_FROM_DATABASE=QUALCOMM INCORPORATED
-
OUI:00A0CF*
ID_OUI_FROM_DATABASE=SOTAS, INC.
@@ -69707,9 +71156,6 @@ OUI:00C0DD*
OUI:00C08A*
ID_OUI_FROM_DATABASE=Lauterbach GmbH
-OUI:00409F*
- ID_OUI_FROM_DATABASE=Telco Systems, Inc.
-
OUI:0040FF*
ID_OUI_FROM_DATABASE=TELEBIT CORPORATION
@@ -70121,9 +71567,6 @@ OUI:00804C*
OUI:008020*
ID_OUI_FROM_DATABASE=NETWORK PRODUCTS
-OUI:00809F*
- ID_OUI_FROM_DATABASE=ALE International
-
OUI:004044*
ID_OUI_FROM_DATABASE=QNIX COMPUTER CO., LTD.
@@ -70280,9 +71723,6 @@ OUI:08006F*
OUI:0000B0*
ID_OUI_FROM_DATABASE=RND-RAD NETWORK DEVICES
-OUI:00001B*
- ID_OUI_FROM_DATABASE=NOVELL INC.
-
OUI:000071*
ID_OUI_FROM_DATABASE=ADRA SYSTEMS INC.
@@ -70307,9 +71747,6 @@ OUI:026086*
OUI:00DD05*
ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
-OUI:00DD0A*
- ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
-
OUI:00BBF0*
ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
@@ -70382,18 +71819,6 @@ OUI:C8F230*
OUI:1C4419*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:005079*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:9C93E4*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:B0D5CC*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:5CF821*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:749DDC*
ID_OUI_FROM_DATABASE=2Wire Inc
@@ -70589,9 +72014,6 @@ OUI:24DEC6*
OUI:D8C7C8*
ID_OUI_FROM_DATABASE=Aruba Networks
-OUI:18E3BC*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:900BC1*
ID_OUI_FROM_DATABASE=Sprocomm Technologies CO.,Ltd
@@ -71039,12 +72461,21 @@ OUI:0017AB*
OUI:001BEA*
ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
-OUI:48F7C0*
- ID_OUI_FROM_DATABASE=Cisco SPVTG
-
OUI:0015DE*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:001370*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00247C*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0023B4*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0021AB*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
OUI:001FDF*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
@@ -71066,22 +72497,7 @@ OUI:2CCC15*
OUI:00BD3A*
ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:A04E04*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
-OUI:001370*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:00247C*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:0023B4*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:001F5C*
- ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-
-OUI:001F00*
+OUI:0026CC*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
OUI:00164E*
@@ -71096,15 +72512,18 @@ OUI:001ADC*
OUI:002668*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:0021AB*
+OUI:001F5C*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:001E3B*
+OUI:001F00*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
-OUI:0026CC*
+OUI:001E3B*
ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+OUI:A04E04*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
OUI:240B0A*
ID_OUI_FROM_DATABASE=Palo Alto Networks
@@ -71168,9 +72587,6 @@ OUI:80ED2C*
OUI:E8B2AC*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:FCF152*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:0080B8*
ID_OUI_FROM_DATABASE=DMG MORI B.U.G. CO., LTD.
@@ -71186,15 +72602,6 @@ OUI:A09D91*
OUI:30785C*
ID_OUI_FROM_DATABASE=Partow Tamas Novin (Parman)
-OUI:0C54B9*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:C4084A*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
-OUI:34AA99*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:441102*
ID_OUI_FROM_DATABASE=EDMI Europe Ltd
@@ -71213,18 +72620,12 @@ OUI:DC4D23*
OUI:085BDA*
ID_OUI_FROM_DATABASE=CliniCare LTD
-OUI:00248D*
- ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
-
OUI:0C5A9E*
ID_OUI_FROM_DATABASE=Wi-SUN Alliance
OUI:00C164*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:10D0AB*
- ID_OUI_FROM_DATABASE=zte corporation
-
OUI:C4BED4*
ID_OUI_FROM_DATABASE=Avaya Inc
@@ -71234,12 +72635,15 @@ OUI:98E7F5*
OUI:24BCF8*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:042DB4*
- ID_OUI_FROM_DATABASE=First Property (Beijing) Co., Ltd Modern MOMA Branch
+OUI:10D0AB*
+ ID_OUI_FROM_DATABASE=zte corporation
OUI:202DF8*
ID_OUI_FROM_DATABASE=Digital Media Cartridge Ltd.
+OUI:042DB4*
+ ID_OUI_FROM_DATABASE=First Property (Beijing) Co., Ltd Modern MOMA Branch
+
OUI:008A96*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -71264,17 +72668,20 @@ OUI:000AC2*
OUI:F08CFB*
ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-OUI:FCF8B7*
- ID_OUI_FROM_DATABASE=TRONTEQ Electronic
-
OUI:D4F207*
ID_OUI_FROM_DATABASE=DIAODIAO(Beijing)Technology CO.,Ltd
+OUI:FCF8B7*
+ ID_OUI_FROM_DATABASE=TRONTEQ Electronic
+
OUI:D4883F*
ID_OUI_FROM_DATABASE=HDPRO CO., LTD.
-OUI:FC0F4B*
- ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:001BF3*
+ ID_OUI_FROM_DATABASE=TRANSRADIO SenderSysteme Berlin AG
+
+OUI:E0071B*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
OUI:A86AC1*
ID_OUI_FROM_DATABASE=HanbitEDS Co., Ltd.
@@ -71282,12 +72689,6 @@ OUI:A86AC1*
OUI:40163B*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:001BF3*
- ID_OUI_FROM_DATABASE=TRANSRADIO SenderSysteme Berlin AG
-
-OUI:E0071B*
- ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
-
OUI:88B1E1*
ID_OUI_FROM_DATABASE=Mojo Networks, Inc.
@@ -71309,10 +72710,10 @@ OUI:746FF7*
OUI:B01BD2*
ID_OUI_FROM_DATABASE=Le Shi Zhi Xin Electronic Technology (Tianjin) Limited
-OUI:386077*
+OUI:74852A*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
-OUI:74852A*
+OUI:386077*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
OUI:60B4F7*
@@ -71321,6 +72722,15 @@ OUI:60B4F7*
OUI:A4D8CA*
ID_OUI_FROM_DATABASE=HONG KONG WATER WORLD TECHNOLOGY CO. LIMITED
+OUI:00109B*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
+
+OUI:00E0D5*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
+
+OUI:001035*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd.
+
OUI:ECA86B*
ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd.
@@ -71333,21 +72743,12 @@ OUI:002197*
OUI:649968*
ID_OUI_FROM_DATABASE=Elentec
-OUI:00109B*
- ID_OUI_FROM_DATABASE=Emulex Corporation
-
-OUI:00E0D5*
- ID_OUI_FROM_DATABASE=Emulex Corporation
-
-OUI:001035*
- ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd.
+OUI:00208F*
+ ID_OUI_FROM_DATABASE=ECI Telecom Ltd.
OUI:9CDF03*
ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
-OUI:00208F*
- ID_OUI_FROM_DATABASE=ECI Telecom Ltd.
-
OUI:F0407B*
ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
@@ -71360,14 +72761,11 @@ OUI:002378*
OUI:002088*
ID_OUI_FROM_DATABASE=GLOBAL VILLAGE COMMUNICATION
-OUI:BC6A44*
- ID_OUI_FROM_DATABASE=Commend International GmbH
-
OUI:90C7D8*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:F8DA0C*
- ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+OUI:BC6A44*
+ ID_OUI_FROM_DATABASE=Commend International GmbH
OUI:0020F2*
ID_OUI_FROM_DATABASE=Oracle Corporation
@@ -71375,6 +72773,9 @@ OUI:0020F2*
OUI:00015D*
ID_OUI_FROM_DATABASE=Oracle Corporation
+OUI:F8DA0C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
OUI:943BB1*
ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD.
@@ -71393,15 +72794,6 @@ OUI:0060B1*
OUI:00177D*
ID_OUI_FROM_DATABASE=IDT Technology Limited
-OUI:AC4BC8*
- ID_OUI_FROM_DATABASE=Juniper Networks
-
-OUI:B0A86E*
- ID_OUI_FROM_DATABASE=Juniper Networks
-
-OUI:3C94D5*
- ID_OUI_FROM_DATABASE=Juniper Networks
-
OUI:288A1C*
ID_OUI_FROM_DATABASE=Juniper Networks
@@ -71426,10 +72818,19 @@ OUI:2C6BF5*
OUI:002283*
ID_OUI_FROM_DATABASE=Juniper Networks
-OUI:F4CC55*
+OUI:EC13DB*
ID_OUI_FROM_DATABASE=Juniper Networks
-OUI:EC13DB*
+OUI:AC4BC8*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:B0A86E*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:3C94D5*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:F4CC55*
ID_OUI_FROM_DATABASE=Juniper Networks
OUI:002159*
@@ -71443,3 +72844,609 @@ OUI:3497F6*
OUI:50680A*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:D89403*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:9C8D7C*
+ ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
+
+OUI:E04F43*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:B0E03C*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:D09DAB*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:94D859*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:9471AC*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:70BAEF*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:009006*
+ ID_OUI_FROM_DATABASE=Hamamatsu Photonics K.K.
+
+OUI:001AF4*
+ ID_OUI_FROM_DATABASE=Handreamnet
+
+OUI:000AED*
+ ID_OUI_FROM_DATABASE=HARTING Electronics GmbH
+
+OUI:1CCB99*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:18E3BC*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:289AFA*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:44A42D*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:8C8EF2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:F40F24*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:A0D385*
+ ID_OUI_FROM_DATABASE=AUMA Riester GmbH & Co. KG
+
+OUI:1414E6*
+ ID_OUI_FROM_DATABASE=Ningbo Sanhe Digital Co.,Ltd
+
+OUI:84A134*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:1C9148*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:CC167E*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:600810*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C85B76*
+ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd
+
+OUI:001AE8*
+ ID_OUI_FROM_DATABASE=Unify Software and Solutions GmbH & Co. KG
+
+OUI:945907*
+ ID_OUI_FROM_DATABASE=Shanghai HITE-BELDEN Network Technology Co., Ltd.
+
+OUI:48C663*
+ ID_OUI_FROM_DATABASE=GTO Access Systems LLC
+
+OUI:606453*
+ ID_OUI_FROM_DATABASE=AOD Co.,Ltd.
+
+OUI:6C98EB*
+ ID_OUI_FROM_DATABASE=Riverbed Technology, Inc.
+
+OUI:DC293A*
+ ID_OUI_FROM_DATABASE=Shenzhen Nuoshi Technology Co., LTD.
+
+OUI:40562D*
+ ID_OUI_FROM_DATABASE=Smartron India Pvt ltd
+
+OUI:70288B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:00809F*
+ ID_OUI_FROM_DATABASE=ALE International
+
+OUI:B0D7CC*
+ ID_OUI_FROM_DATABASE=Tridonic GmbH & Co KG
+
+OUI:7C574E*
+ ID_OUI_FROM_DATABASE=COBI GmbH
+
+OUI:34C0F9*
+ ID_OUI_FROM_DATABASE=Rockwell Automation
+
+OUI:20C047*
+ ID_OUI_FROM_DATABASE=Verizon
+
+OUI:AC0481*
+ ID_OUI_FROM_DATABASE=Jiangsu Huaxing Electronics Co., Ltd.
+
+OUI:FC2D5E*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:E811CA*
+ ID_OUI_FROM_DATABASE=SHANDONG KAER ELECTRIC.CO.,LTD
+
+OUI:ECD68A*
+ ID_OUI_FROM_DATABASE=Shenzhen JMicron Intelligent Technology Developmen
+
+OUI:1C77F6*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:08D0B7*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:28285D*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:5CF4AB*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:4C9EFF*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:0023F8*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:B0B2DC*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:90EF68*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:00248D*
+ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
+
+OUI:54276C*
+ ID_OUI_FROM_DATABASE=Jiangsu Houge Technology Corp.
+
+OUI:00CB00*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:FCFFAA*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
+OUI:40D855*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
+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
+
+OUI:8416F9*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:C44BD1*
+ ID_OUI_FROM_DATABASE=Wallys Communications Teachnologies Co.,Ltd.
+
+OUI:2057AF*
+ ID_OUI_FROM_DATABASE=Shenzhen FH-NET OPTOELECTRONICS CO.,LTD
+
+OUI:34EA34*
+ ID_OUI_FROM_DATABASE=HangZhou Gubei Electronics Technology Co.,Ltd
+
+OUI:F8A9D0*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:CCFA00*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:BCF5AC*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:00AA70*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:F01C13*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:CC2D8C*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:344DF7*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:C49A02*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0022A9*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0025E5*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:10F96F*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:00116E*
+ ID_OUI_FROM_DATABASE=Peplink International Ltd.
+
+OUI:A091C8*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:002597*
+ ID_OUI_FROM_DATABASE=Kalki Communication Technologies
+
+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.
+
+OUI:3044A1*
+ ID_OUI_FROM_DATABASE=Shanghai Nanchao Information Technology
+
+OUI:C4F1D1*
+ ID_OUI_FROM_DATABASE=BEIJING SOGOU TECHNOLOGY DEVELOPMENT CO., LTD.
+
+OUI:38A28C*
+ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+
+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.
+
+OUI:CC03FA*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:28BE9B*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:509F3B*
+ ID_OUI_FROM_DATABASE=OI ELECTRIC CO.,LTD
+
+OUI:E4029B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:6002B4*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:98EECB*
+ ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
+
+OUI:70E284*
+ ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
+
+OUI:80EA23*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:D88039*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
+OUI:001D72*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:FC3D93*
+ ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
+
+OUI:48F7C0*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:00409F*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:00E09E*
+ ID_OUI_FROM_DATABASE=Quantum Corporation
+
+OUI:00148C*
+ ID_OUI_FROM_DATABASE=General Dynamics Mission Systems
+
+OUI:A47174*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:D4A148*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:D065CA*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:8CEBC6*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:B808D7*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:FCF152*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:784476*
+ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
+
+OUI:00183A*
+ ID_OUI_FROM_DATABASE=Westell Technologies Inc.
+
+OUI:E89A8F*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:001B24*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:CC52AF*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:001A6B*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:002722*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:00DD0A*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00039D*
+ ID_OUI_FROM_DATABASE=Qisda Corporation
+
+OUI:000B0E*
+ ID_OUI_FROM_DATABASE=Trapeze Networks
+
+OUI:002318*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:E89D87*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:E8E0B7*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:001428*
+ ID_OUI_FROM_DATABASE=Vocollect Inc
+
+OUI:006B9E*
+ ID_OUI_FROM_DATABASE=Vizio, Inc
+
+OUI:0024FF*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:00A0C6*
+ ID_OUI_FROM_DATABASE=Qualcomm Inc.
+
+OUI:ECAAA0*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:E8886C*
+ ID_OUI_FROM_DATABASE=Shenzhen SC Technologies Co.,LTD
+
+OUI:DC35F1*
+ ID_OUI_FROM_DATABASE=Positivo Informática SA.
+
+OUI:EC6881*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:44334C*
+ ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+
+OUI:D84FB8*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS
+
+OUI:9C220E*
+ ID_OUI_FROM_DATABASE=TASCAN Systems GmbH
+
+OUI:0CA402*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:00164D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:FCFAF7*
+ ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd.
+
+OUI:0C54B9*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:C4084A*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:34AA99*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:8C90D3*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Canada
+
+OUI:A8AD3D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:E03005*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:2824FF*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:14C1FF*
+ ID_OUI_FROM_DATABASE=ShenZhen QianHai Comlan communication Co.,LTD
+
+OUI:EC8EB5*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:70AF6A*
+ ID_OUI_FROM_DATABASE=SHENZHEN FENGLIAN TECHNOLOGY CO., LTD.
+
+OUI:0026F1*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:B439D6*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:001CEF*
+ ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
+
+OUI:000276*
+ ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
+
+OUI:4849C7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001F9A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0014C7*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001540*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0017D1*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0015E8*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001660*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001BBA*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:205EF7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:00034B*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00001B*
+ ID_OUI_FROM_DATABASE=Novell, Inc.
+
+OUI:00E011*
+ ID_OUI_FROM_DATABASE=UNIDEN CORPORATION
+
+OUI:B03EB0*
+ ID_OUI_FROM_DATABASE=MICRODIA Ltd.
+
+OUI:00126C*
+ ID_OUI_FROM_DATABASE=Visonic Technologies 1993 Ltd.
+
+OUI:18ABF5*
+ ID_OUI_FROM_DATABASE=Ultra Electronics Electrics
+
+OUI:304487*
+ ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
+
+OUI:AC6175*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:AC482D*
+ ID_OUI_FROM_DATABASE=Ralinwi Nanjing Electronic Technology Co., Ltd.
+
+OUI:A48269*
+ ID_OUI_FROM_DATABASE=Datrium, Inc.
+
+OUI:441441*
+ ID_OUI_FROM_DATABASE=AudioControl Inc.
+
+OUI:0018DA*
+ ID_OUI_FROM_DATABASE=AMBER wireless GmbH
+
+OUI:EC24B8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:68C90B*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:F4B85E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:5C313E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:A0E6F8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:20C38F*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D0FF50*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7472B0*
+ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronics Co., Ltd.
+
+OUI:44BFE3*
+ ID_OUI_FROM_DATABASE=Shenzhen Longtech Electronics Co.,Ltd
+
+OUI:F45214*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:689E19*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:985945*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:1CE2CC*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:44C15C*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E9*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D00790*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:04E451*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B0D5CC*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:5CF821*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:FC0F4B*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:3C6FEA*
+ ID_OUI_FROM_DATABASE=Panasonic India Pvt. Ltd.
+
+OUI:A863F2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:948854*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001237*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:BC6A29*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C0E422*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001830*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:1CBA8C*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7CA97D*
+ ID_OUI_FROM_DATABASE=Objenious
+
+OUI:58FB84*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E0E7BB*
+ ID_OUI_FROM_DATABASE=Nureva, Inc.
+
+OUI:5CB066*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:BC8AA3*
+ ID_OUI_FROM_DATABASE=NHN Entertainment
diff --git a/hwdb/20-bluetooth-vendor-product.hwdb b/hwdb/20-bluetooth-vendor-product.hwdb
index 516abad246..60b62b0b38 100644
--- a/hwdb/20-bluetooth-vendor-product.hwdb
+++ b/hwdb/20-bluetooth-vendor-product.hwdb
@@ -436,7 +436,7 @@ bluetooth:v008E*
ID_VENDOR_FROM_DATABASE=Quintic Corp.
bluetooth:v008F*
- ID_VENDOR_FROM_DATABASE=Stollman E+V GmbH
+ ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions GmbH (Formerly Stollman E+V GmbH)
bluetooth:v0090*
ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd.
@@ -1111,7 +1111,7 @@ bluetooth:v016F*
ID_VENDOR_FROM_DATABASE=Podo Labs, Inc
bluetooth:v0170*
- ID_VENDOR_FROM_DATABASE=Roche Diabetes Care AG
+ ID_VENDOR_FROM_DATABASE=F. Hoffmann-La Roche AG
bluetooth:v0171*
ID_VENDOR_FROM_DATABASE=Amazon Fulfillment Service
@@ -2231,3 +2231,420 @@ bluetooth:v02E4*
bluetooth:v02E5*
ID_VENDOR_FROM_DATABASE=Espressif Incorporated ( 乐鑫信息科技(上海)有限公司 )
+
+bluetooth:v02E6*
+ ID_VENDOR_FROM_DATABASE=Unwire
+
+bluetooth:v02E7*
+ ID_VENDOR_FROM_DATABASE=Connected Yard, Inc.
+
+bluetooth:v02E8*
+ ID_VENDOR_FROM_DATABASE=American Music Environments
+
+bluetooth:v02E9*
+ ID_VENDOR_FROM_DATABASE=Sensogram Technologies, Inc.
+
+bluetooth:v02EA*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Limited
+
+bluetooth:v02EB*
+ ID_VENDOR_FROM_DATABASE=Ardic Technology
+
+bluetooth:v02EC*
+ ID_VENDOR_FROM_DATABASE=Delta Systems, Inc
+
+bluetooth:v02ED*
+ ID_VENDOR_FROM_DATABASE=HTC Corporation
+
+bluetooth:v02EE*
+ ID_VENDOR_FROM_DATABASE=Citizen Holdings Co., Ltd.
+
+bluetooth:v02EF*
+ ID_VENDOR_FROM_DATABASE=SMART-INNOVATION.inc
+
+bluetooth:v02F0*
+ ID_VENDOR_FROM_DATABASE=Blackrat Software
+
+bluetooth:v02F1*
+ ID_VENDOR_FROM_DATABASE=The Idea Cave, LLC
+
+bluetooth:v02F2*
+ ID_VENDOR_FROM_DATABASE=GoPro, Inc.
+
+bluetooth:v02F3*
+ ID_VENDOR_FROM_DATABASE=AuthAir, Inc
+
+bluetooth:v02F4*
+ ID_VENDOR_FROM_DATABASE=Vensi, Inc.
+
+bluetooth:v02F5*
+ ID_VENDOR_FROM_DATABASE=Indagem Tech LLC
+
+bluetooth:v02F6*
+ ID_VENDOR_FROM_DATABASE=Intemo Technologies
+
+bluetooth:v02F7*
+ ID_VENDOR_FROM_DATABASE=DreamVisions co., Ltd.
+
+bluetooth:v02F8*
+ ID_VENDOR_FROM_DATABASE=Runteq Oy Ltd
+
+bluetooth:v02F9*
+ ID_VENDOR_FROM_DATABASE=IMAGINATION TECHNOLOGIES LTD
+
+bluetooth:v02FA*
+ ID_VENDOR_FROM_DATABASE=CoSTAR Technologies
+
+bluetooth:v02FB*
+ ID_VENDOR_FROM_DATABASE=Clarius Mobile Health Corp.
+
+bluetooth:v02FC*
+ ID_VENDOR_FROM_DATABASE=Shanghai Frequen Microelectronics Co., Ltd.
+
+bluetooth:v02FD*
+ ID_VENDOR_FROM_DATABASE=Uwanna, Inc.
+
+bluetooth:v02FE*
+ ID_VENDOR_FROM_DATABASE=Lierda Science & Technology Group Co., Ltd.
+
+bluetooth:v02FF*
+ ID_VENDOR_FROM_DATABASE=Silicon Laboratories
+
+bluetooth:v0300*
+ ID_VENDOR_FROM_DATABASE=World Moto Inc.
+
+bluetooth:v0301*
+ ID_VENDOR_FROM_DATABASE=Giatec Scientific Inc.
+
+bluetooth:v0302*
+ ID_VENDOR_FROM_DATABASE=Loop Devices, Inc
+
+bluetooth:v0303*
+ ID_VENDOR_FROM_DATABASE=IACA electronique
+
+bluetooth:v0304*
+ ID_VENDOR_FROM_DATABASE=Martians Inc
+
+bluetooth:v0305*
+ ID_VENDOR_FROM_DATABASE=Swipp ApS
+
+bluetooth:v0306*
+ ID_VENDOR_FROM_DATABASE=Life Laboratory Inc.
+
+bluetooth:v0307*
+ ID_VENDOR_FROM_DATABASE=FUJI INDUSTRIAL CO.,LTD.
+
+bluetooth:v0308*
+ ID_VENDOR_FROM_DATABASE=Surefire, LLC
+
+bluetooth:v0309*
+ ID_VENDOR_FROM_DATABASE=Dolby Labs
+
+bluetooth:v030A*
+ ID_VENDOR_FROM_DATABASE=Ellisys
+
+bluetooth:v030B*
+ ID_VENDOR_FROM_DATABASE=Magnitude Lighting Converters
+
+bluetooth:v030C*
+ ID_VENDOR_FROM_DATABASE=Hilti AG
+
+bluetooth:v030D*
+ ID_VENDOR_FROM_DATABASE=Devdata S.r.l.
+
+bluetooth:v030E*
+ ID_VENDOR_FROM_DATABASE=Deviceworx
+
+bluetooth:v030F*
+ ID_VENDOR_FROM_DATABASE=Shortcut Labs
+
+bluetooth:v0310*
+ ID_VENDOR_FROM_DATABASE=SGL Italia S.r.l.
+
+bluetooth:v0311*
+ ID_VENDOR_FROM_DATABASE=PEEQ DATA
+
+bluetooth:v0312*
+ ID_VENDOR_FROM_DATABASE=Ducere Technologies Pvt Ltd
+
+bluetooth:v0313*
+ ID_VENDOR_FROM_DATABASE=DiveNav, Inc.
+
+bluetooth:v0314*
+ ID_VENDOR_FROM_DATABASE=RIIG AI Sp. z o.o.
+
+bluetooth:v0315*
+ ID_VENDOR_FROM_DATABASE=Thermo Fisher Scientific
+
+bluetooth:v0316*
+ ID_VENDOR_FROM_DATABASE=AG Measurematics Pvt. Ltd.
+
+bluetooth:v0317*
+ ID_VENDOR_FROM_DATABASE=CHUO Electronics CO., LTD.
+
+bluetooth:v0318*
+ ID_VENDOR_FROM_DATABASE=Aspenta International
+
+bluetooth:v0319*
+ ID_VENDOR_FROM_DATABASE=Eugster Frismag AG
+
+bluetooth:v031A*
+ ID_VENDOR_FROM_DATABASE=Amber wireless GmbH
+
+bluetooth:v031B*
+ ID_VENDOR_FROM_DATABASE=HQ Inc
+
+bluetooth:v031C*
+ ID_VENDOR_FROM_DATABASE=Lab Sensor Solutions
+
+bluetooth:v031D*
+ ID_VENDOR_FROM_DATABASE=Enterlab ApS
+
+bluetooth:v031E*
+ ID_VENDOR_FROM_DATABASE=Eyefi, Inc.
+
+bluetooth:v031F*
+ ID_VENDOR_FROM_DATABASE=MetaSystem S.p.A
+
+bluetooth:v0320*
+ ID_VENDOR_FROM_DATABASE=SONO ELECTRONICS. CO., LTD
+
+bluetooth:v0321*
+ ID_VENDOR_FROM_DATABASE=Jewelbots
+
+bluetooth:v0322*
+ ID_VENDOR_FROM_DATABASE=Compumedics Limited
+
+bluetooth:v0323*
+ ID_VENDOR_FROM_DATABASE=Rotor Bike Components
+
+bluetooth:v0324*
+ ID_VENDOR_FROM_DATABASE=Astro, Inc.
+
+bluetooth:v0325*
+ ID_VENDOR_FROM_DATABASE=Amotus Solutions
+
+bluetooth:v0326*
+ ID_VENDOR_FROM_DATABASE=Healthwear Technologies (Changzhou)Ltd
+
+bluetooth:v0327*
+ ID_VENDOR_FROM_DATABASE=Essex Electronics
+
+bluetooth:v0328*
+ ID_VENDOR_FROM_DATABASE=Grundfos A/S
+
+bluetooth:v0329*
+ ID_VENDOR_FROM_DATABASE=Eargo, Inc.
+
+bluetooth:v032A*
+ ID_VENDOR_FROM_DATABASE=Electronic Design Lab
+
+bluetooth:v032B*
+ ID_VENDOR_FROM_DATABASE=ESYLUX
+
+bluetooth:v032C*
+ ID_VENDOR_FROM_DATABASE=NIPPON SMT.CO.,Ltd
+
+bluetooth:v032D*
+ ID_VENDOR_FROM_DATABASE=BM innovations GmbH
+
+bluetooth:v032E*
+ ID_VENDOR_FROM_DATABASE=indoormap
+
+bluetooth:v032F*
+ ID_VENDOR_FROM_DATABASE=OttoQ Inc
+
+bluetooth:v0330*
+ ID_VENDOR_FROM_DATABASE=North Pole Engineering
+
+bluetooth:v0331*
+ ID_VENDOR_FROM_DATABASE=3flares Technologies Inc.
+
+bluetooth:v0332*
+ ID_VENDOR_FROM_DATABASE=Electrocompaniet A.S.
+
+bluetooth:v0333*
+ ID_VENDOR_FROM_DATABASE=Mul-T-Lock
+
+bluetooth:v0334*
+ ID_VENDOR_FROM_DATABASE=Corentium AS
+
+bluetooth:v0335*
+ ID_VENDOR_FROM_DATABASE=Enlighted Inc
+
+bluetooth:v0336*
+ ID_VENDOR_FROM_DATABASE=GISTIC
+
+bluetooth:v0337*
+ ID_VENDOR_FROM_DATABASE=AJP2 Holdings, LLC
+
+bluetooth:v0338*
+ ID_VENDOR_FROM_DATABASE=COBI GmbH
+
+bluetooth:v0339*
+ ID_VENDOR_FROM_DATABASE=Blue Sky Scientific, LLC
+
+bluetooth:v033A*
+ ID_VENDOR_FROM_DATABASE=Appception, Inc.
+
+bluetooth:v033B*
+ ID_VENDOR_FROM_DATABASE=Courtney Thorne Limited
+
+bluetooth:v033C*
+ ID_VENDOR_FROM_DATABASE=Virtuosys
+
+bluetooth:v033D*
+ ID_VENDOR_FROM_DATABASE=TPV Technology Limited
+
+bluetooth:v033E*
+ ID_VENDOR_FROM_DATABASE=Monitra SA
+
+bluetooth:v033F*
+ ID_VENDOR_FROM_DATABASE=Automation Components, Inc.
+
+bluetooth:v0340*
+ ID_VENDOR_FROM_DATABASE=Letsense s.r.l.
+
+bluetooth:v0341*
+ ID_VENDOR_FROM_DATABASE=Etesian Technologies LLC
+
+bluetooth:v0342*
+ ID_VENDOR_FROM_DATABASE=GERTEC BRASIL LTDA.
+
+bluetooth:v0343*
+ ID_VENDOR_FROM_DATABASE=Drekker Development Pty. Ltd.
+
+bluetooth:v0344*
+ ID_VENDOR_FROM_DATABASE=Whirl Inc
+
+bluetooth:v0345*
+ ID_VENDOR_FROM_DATABASE=Locus Positioning
+
+bluetooth:v0346*
+ ID_VENDOR_FROM_DATABASE=Acuity Brands Lighting, Inc
+
+bluetooth:v0347*
+ ID_VENDOR_FROM_DATABASE=Prevent Biometrics
+
+bluetooth:v0348*
+ ID_VENDOR_FROM_DATABASE=Arioneo
+
+bluetooth:v0349*
+ ID_VENDOR_FROM_DATABASE=VersaMe
+
+bluetooth:v034A*
+ ID_VENDOR_FROM_DATABASE=Vaddio
+
+bluetooth:v034B*
+ ID_VENDOR_FROM_DATABASE=Libratone A/S
+
+bluetooth:v034C*
+ ID_VENDOR_FROM_DATABASE=HM Electronics, Inc.
+
+bluetooth:v034D*
+ ID_VENDOR_FROM_DATABASE=TASER International, Inc.
+
+bluetooth:v034E*
+ ID_VENDOR_FROM_DATABASE=Safe Trust Inc.
+
+bluetooth:v034F*
+ ID_VENDOR_FROM_DATABASE=Heartland Payment Systems
+
+bluetooth:v0350*
+ ID_VENDOR_FROM_DATABASE=Bitstrata Systems Inc.
+
+bluetooth:v0351*
+ ID_VENDOR_FROM_DATABASE=Pieps GmbH
+
+bluetooth:v0352*
+ ID_VENDOR_FROM_DATABASE=iRiding(Xiamen)Technology Co.,Ltd.
+
+bluetooth:v0353*
+ ID_VENDOR_FROM_DATABASE=Alpha Audiotronics, Inc.
+
+bluetooth:v0354*
+ ID_VENDOR_FROM_DATABASE=TOPPAN FORMS CO.,LTD.
+
+bluetooth:v0355*
+ ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc.
+
+bluetooth:v0356*
+ ID_VENDOR_FROM_DATABASE=Spectrum Brands, Inc.
+
+bluetooth:v0357*
+ ID_VENDOR_FROM_DATABASE=Polymap Wireless
+
+bluetooth:v0358*
+ ID_VENDOR_FROM_DATABASE=MagniWare Ltd.
+
+bluetooth:v0359*
+ ID_VENDOR_FROM_DATABASE=Novotec Medical GmbH
+
+bluetooth:v035A*
+ ID_VENDOR_FROM_DATABASE=Medicom Innovation Partner a/s
+
+bluetooth:v035B*
+ ID_VENDOR_FROM_DATABASE=Matrix Inc.
+
+bluetooth:v035C*
+ ID_VENDOR_FROM_DATABASE=Eaton Corporation
+
+bluetooth:v035D*
+ ID_VENDOR_FROM_DATABASE=KYS
+
+bluetooth:v035E*
+ ID_VENDOR_FROM_DATABASE=Naya Health, Inc.
+
+bluetooth:v035F*
+ ID_VENDOR_FROM_DATABASE=Acromag
+
+bluetooth:v0360*
+ ID_VENDOR_FROM_DATABASE=Insulet Corporation
+
+bluetooth:v0361*
+ ID_VENDOR_FROM_DATABASE=Wellinks Inc.
+
+bluetooth:v0362*
+ ID_VENDOR_FROM_DATABASE=ON Semiconductor
+
+bluetooth:v0363*
+ ID_VENDOR_FROM_DATABASE=FREELAP SA
+
+bluetooth:v0364*
+ ID_VENDOR_FROM_DATABASE=Favero Electronics Srl
+
+bluetooth:v0365*
+ ID_VENDOR_FROM_DATABASE=BioMech Sensor LLC
+
+bluetooth:v0366*
+ ID_VENDOR_FROM_DATABASE=BOLTT Sports technologies Private limited
+
+bluetooth:v0367*
+ ID_VENDOR_FROM_DATABASE=Saphe International
+
+bluetooth:v0368*
+ ID_VENDOR_FROM_DATABASE=Metormote AB
+
+bluetooth:v0369*
+ ID_VENDOR_FROM_DATABASE=littleBits
+
+bluetooth:v036A*
+ ID_VENDOR_FROM_DATABASE=SetPoint Medical
+
+bluetooth:v036B*
+ ID_VENDOR_FROM_DATABASE=BRControls Products BV
+
+bluetooth:v036C*
+ ID_VENDOR_FROM_DATABASE=Zipcar
+
+bluetooth:v036D*
+ ID_VENDOR_FROM_DATABASE=AirBolt Pty Ltd
+
+bluetooth:v036E*
+ ID_VENDOR_FROM_DATABASE=KeepTruckin Inc
+
+bluetooth:v036F*
+ ID_VENDOR_FROM_DATABASE=Motiv, Inc.
+
+bluetooth:v0370*
+ ID_VENDOR_FROM_DATABASE=Wazombi Labs OÜ
diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb
index 91c784b891..f068e53fbc 100644
--- a/hwdb/20-pci-vendor-model.hwdb
+++ b/hwdb/20-pci-vendor-model.hwdb
@@ -731,6 +731,9 @@ pci:v00001000d00000030sv0000103Csd00001323*
pci:v00001000d00000030sv0000103Csd00003108*
ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (Single Channel Ultra320 SCSI HBA G2)
+pci:v00001000d00000030sv0000103Csd0000322A*
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (SC11Xe Ultra320 Single Channel PCIe x4 SCSI Host Bus Adapter (412911-B21))
+
pci:v00001000d00000030sv0000124Bsd00001170*
ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (PMC-USCSI320)
@@ -1349,6 +1352,51 @@ pci:v00001000d0000007Csv00001014sd00000395*
pci:v00001000d0000007E*
ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD
+pci:v00001000d0000007Esv00001000sd00000504*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro NWD-BLP4-800)
+
+pci:v00001000d0000007Esv00001000sd00000507*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro NWD-BLP4-1600)
+
+pci:v00001000d0000007Esv00001000sd00000581*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro NWD-BLP4-400)
+
+pci:v00001000d0000007Esv00001000sd0000100D*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro NWD-BFH6-1200)
+
+pci:v00001000d0000007Esv00001000sd0000100E*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro NWD-BFH8-1600)
+
+pci:v00001000d0000007Esv00001000sd0000107E*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro NWD-BFH8-3200)
+
+pci:v00001000d0000007Esv00001000sd00001310*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6302-8B1536)
+
+pci:v00001000d0000007Esv00001000sd00001311*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6302-8B2048)
+
+pci:v00001000d0000007Esv00001000sd00001314*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6302-8B4096)
+
+pci:v00001000d0000007Esv00001000sd0000150C*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6210-4A2048)
+
+pci:v00001000d0000007Esv00001000sd0000150F*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6210-4B2048)
+
+pci:v00001000d0000007Esv00001000sd0000160B*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6209-4A1024)
+
+pci:v00001000d0000007Esv00001000sd00001613*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro XP6209-4B2048)
+
+pci:v00001000d0000007Esv0000108Esd0000050A*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro ELP4x200_4d_n)
+
+pci:v00001000d0000007Esv0000108Esd00000581*
+ ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD (Nytro ELP4x100_4d_n)
+
pci:v00001000d00000080*
ID_MODEL_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
@@ -1373,6 +1421,12 @@ pci:v00001000d00000086*
pci:v00001000d00000087*
ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2
+pci:v00001000d00000087sv00001000sd00003020*
+ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (9207-8i SAS2.1 HBA)
+
+pci:v00001000d00000087sv00001000sd00003040*
+ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (9207-8e SAS2.1 HBA)
+
pci:v00001000d00000087sv00001590sd00000044*
ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (H220i)
@@ -4421,6 +4475,12 @@ pci:v00001002d00006647*
pci:v00001002d00006649*
ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100]
+pci:v00001002d00006649sv00001002sd00000B0C*
+ ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100] (FirePro W4300)
+
+pci:v00001002d00006649sv0000103Csd00000B0C*
+ ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100] (Bonaire [FirePro W4300])
+
pci:v00001002d00006650*
ID_MODEL_FROM_DATABASE=Bonaire
@@ -6128,6 +6188,9 @@ pci:v00001002d000067A0*
pci:v00001002d000067A0sv00001002sd00000335*
ID_MODEL_FROM_DATABASE=Hawaii XT GL [FirePro W9100] (FirePro S9150)
+pci:v00001002d000067A0sv00001002sd00000735*
+ ID_MODEL_FROM_DATABASE=Hawaii XT GL [FirePro W9100] (FirePro S9170)
+
pci:v00001002d000067A0sv00001028sd0000031F*
ID_MODEL_FROM_DATABASE=Hawaii XT GL [FirePro W9100] (FirePro W9100)
@@ -6156,70 +6219,115 @@ pci:v00001002d000067AA*
ID_MODEL_FROM_DATABASE=Hawaii
pci:v00001002d000067B0*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X]
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X]
+
+pci:v00001002d000067B0sv00001028sd00000B00*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Grenada XT [Radeon R9 390X])
+
+pci:v00001002d000067B0sv0000103Csd00006566*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
pci:v00001002d000067B0sv00001043sd0000046A*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X DirectCU II)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X DirectCU II)
pci:v00001002d000067B0sv00001043sd0000046C*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X DirectCU II OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X DirectCU II OC)
pci:v00001002d000067B0sv00001043sd00000474*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (Matrix R9 290X Platinum)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Matrix R9 290X Platinum)
pci:v00001002d000067B0sv00001043sd00000476*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (ARES III)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (ARES III)
+
+pci:v00001002d000067B0sv00001043sd000004D7*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
+
+pci:v00001002d000067B0sv00001043sd000004DB*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
+
+pci:v00001002d000067B0sv00001043sd000004DF*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
+
+pci:v00001002d000067B0sv00001043sd000004E9*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
pci:v00001002d000067B0sv00001458sd0000227C*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X WindForce 3X OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X WindForce 3X OC)
pci:v00001002d000067B0sv00001458sd00002281*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X WindForce 3X OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X WindForce 3X OC)
pci:v00001002d000067B0sv00001458sd0000228C*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X WindForce 3X)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X WindForce 3X)
pci:v00001002d000067B0sv00001458sd0000228D*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X WindForce 3X OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X WindForce 3X OC)
pci:v00001002d000067B0sv00001458sd00002290*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X WindForce 3X)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X WindForce 3X)
+
+pci:v00001002d000067B0sv00001458sd000022BC*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
pci:v00001002d000067B0sv00001458sd000022C1*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (Grenada PRO [Radeon R9 390])
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Grenada PRO [Radeon R9 390])
+
+pci:v00001002d000067B0sv00001462sd00002015*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
pci:v00001002d000067B0sv00001462sd00003070*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X Lightning)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X Lightning)
pci:v00001002d000067B0sv00001462sd00003071*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X Lightning)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X Lightning)
pci:v00001002d000067B0sv00001462sd00003072*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X Lightning LE)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X Lightning LE)
pci:v00001002d000067B0sv00001462sd00003080*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X Gaming)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X Gaming)
pci:v00001002d000067B0sv00001462sd00003082*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X Gaming OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X Gaming OC)
pci:v00001002d000067B0sv0000148Csd00002347*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (Devil 13 Dual Core R9 290X)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Devil 13 Dual Core R9 290X)
+
+pci:v00001002d000067B0sv0000148Csd00002357*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Grenada XT [Radeon R9 390X])
pci:v00001002d000067B0sv00001682sd00009290*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (Double Dissipation R9 290X)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Double Dissipation R9 290X)
+
+pci:v00001002d000067B0sv00001682sd00009395*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Grenada XT [Radeon R9 390X])
+
+pci:v00001002d000067B0sv0000174Bsd00000E34*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Radeon R9 390X)
pci:v00001002d000067B0sv0000174Bsd0000E282*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (Vapor-X R9 290X Tri-X OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Vapor-X R9 290X Tri-X OC)
pci:v00001002d000067B0sv0000174Bsd0000E285*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X Tri-X OC)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X Tri-X OC)
+
+pci:v00001002d000067B0sv0000174Bsd0000E324*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Grenada XT2 [Radeon R9 390X])
pci:v00001002d000067B0sv00001787sd00002020*
- ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] (R9 290X IceQ X² Turbo)
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (R9 290X IceQ X² Turbo)
+
+pci:v00001002d000067B0sv00001787sd00002357*
+ ID_MODEL_FROM_DATABASE=Hawaii XT / Grenada XT [Radeon R9 290X/390X] (Grenada XT [Radeon R9 390X])
pci:v00001002d000067B1*
- ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290]
+ ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290/390]
+
+pci:v00001002d000067B1sv00001043sd000004DD*
+ ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290/390] (STRIX R9 390)
+
+pci:v00001002d000067B1sv0000148Csd00002358*
+ ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290/390] (Radeon R9 390)
pci:v00001002d000067B9*
ID_MODEL_FROM_DATABASE=Vesuvius [Radeon R9 295X2]
@@ -6227,6 +6335,30 @@ pci:v00001002d000067B9*
pci:v00001002d000067BE*
ID_MODEL_FROM_DATABASE=Hawaii LE
+pci:v00001002d000067C0*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+
+pci:v00001002d000067DF*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+
+pci:v00001002d000067E0*
+ ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+
+pci:v00001002d000067E1*
+ ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+
+pci:v00001002d000067E8*
+ ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+
+pci:v00001002d000067E9*
+ ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+
+pci:v00001002d000067EB*
+ ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+
+pci:v00001002d000067FF*
+ ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+
pci:v00001002d00006800*
ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M]
@@ -6273,13 +6405,13 @@ pci:v00001002d00006809*
ID_MODEL_FROM_DATABASE=Pitcairn LE GL [FirePro W5000]
pci:v00001002d00006810*
- ID_MODEL_FROM_DATABASE=Curacao XT [Radeon R7 370 / R9 270X/370 OEM]
+ ID_MODEL_FROM_DATABASE=Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X]
pci:v00001002d00006810sv0000148Csd00000908*
- ID_MODEL_FROM_DATABASE=Curacao XT [Radeon R7 370 / R9 270X/370 OEM] (Radeon R9 370 OEM)
+ ID_MODEL_FROM_DATABASE=Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] (Radeon R9 370 OEM)
pci:v00001002d00006810sv00001682sd00007370*
- ID_MODEL_FROM_DATABASE=Curacao XT [Radeon R7 370 / R9 270X/370 OEM] (Radeon R7 370)
+ ID_MODEL_FROM_DATABASE=Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] (Radeon R7 370)
pci:v00001002d00006811*
ID_MODEL_FROM_DATABASE=Curacao PRO [Radeon R7 370 / R9 270/370 OEM]
@@ -8187,26 +8319,83 @@ pci:v00001002d000068FE*
ID_MODEL_FROM_DATABASE=Cedar LE
pci:v00001002d00006900*
- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265]
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360]
+
+pci:v00001002d00006900sv00001025sd00001056*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360 / R8 M365DX)
pci:v00001002d00006900sv00001028sd00000640*
- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M265)
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260/M265)
+
+pci:v00001002d00006900sv00001028sd00000643*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260/M265)
+
+pci:v00001002d00006900sv00001028sd0000067F*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv00001028sd0000130A*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv0000103Csd00002263*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
pci:v00001002d00006900sv0000103Csd00002269*
- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M260)
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv0000103Csd000022C6*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
pci:v00001002d00006900sv0000103Csd000022C8*
- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M260)
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv0000103Csd0000808C*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv0000103Csd00008099*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360)
+
+pci:v00001002d00006900sv0000103Csd000080B5*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360)
+
+pci:v00001002d00006900sv0000103Csd000080B9*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360)
+
+pci:v00001002d00006900sv0000103Csd0000811C*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M340)
+
+pci:v00001002d00006900sv000010CFsd00001906*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv00001170sd00009979*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360)
pci:v00001002d00006900sv00001179sd0000F903*
- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M260)
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv00001179sd0000F922*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv00001179sd0000F923*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
pci:v00001002d00006900sv00001179sd0000F934*
- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M260)
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
+
+pci:v00001002d00006900sv000017AAsd00003822*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360)
+
+pci:v00001002d00006900sv000017AAsd00003824*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M360)
+
+pci:v00001002d00006900sv000017AAsd00005021*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360] (Radeon R7 M260)
pci:v00001002d00006901*
ID_MODEL_FROM_DATABASE=Topaz PRO [Radeon R5 M255]
+pci:v00001002d00006901sv0000103Csd00001318*
+ ID_MODEL_FROM_DATABASE=Topaz PRO [Radeon R5 M255] (Radeon R6 M255DX)
+
pci:v00001002d00006921*
ID_MODEL_FROM_DATABASE=Amethyst XT [Radeon R9 M295X]
@@ -8220,10 +8409,31 @@ pci:v00001002d0000692F*
ID_MODEL_FROM_DATABASE=Tonga XTV GL [FirePro S7150V]
pci:v00001002d00006938*
- ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X Mac Edition]
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X]
+
+pci:v00001002d00006938sv00001043sd000004F5*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X)
+
+pci:v00001002d00006938sv00001043sd000004F7*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X)
+
+pci:v00001002d00006938sv0000106Bsd0000013A*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 M295X Mac Edition)
+
+pci:v00001002d00006938sv00001458sd000022C8*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X)
+
+pci:v00001002d00006938sv0000148Csd00002350*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X)
+
+pci:v00001002d00006938sv00001682sd00009385*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X)
pci:v00001002d00006938sv0000174Bsd0000E308*
- ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X Mac Edition] (Radeon R9 380X Nitro 4G D5)
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X Nitro 4G D5)
+
+pci:v00001002d00006938sv000017AFsd00002006*
+ ID_MODEL_FROM_DATABASE=Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] (Radeon R9 380X)
pci:v00001002d00006939*
ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380]
@@ -9614,6 +9824,9 @@ pci:v00001002d0000AAD8*
pci:v00001002d0000AAD8sv0000174Bsd0000AAD8*
ID_MODEL_FROM_DATABASE=Tonga HDMI Audio [Radeon R9 285/380] (Radeon R9 285/380 HDMI Audio)
+pci:v00001002d0000AAE8*
+ ID_MODEL_FROM_DATABASE=Fiji HDMI/DP Audio Controller
+
pci:v00001002d0000AC00*
ID_MODEL_FROM_DATABASE=Theater 600 Pro
@@ -17306,6 +17519,9 @@ pci:v00001077d00001644sv00001077sd0000E4F8*
pci:v00001077d00001656*
ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller
+pci:v00001077d00001656sv00001077sd000002A7*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (QL45212-DE 25GbE Adapter)
+
pci:v00001077d00001656sv00001077sd0000E4F6*
ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (FastLinQ QL45211H 25GbE Adapter)
@@ -17375,6 +17591,18 @@ pci:v00001077d00002031sv0000103Csd00008002*
pci:v00001077d00002071*
ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter
+pci:v00001077d00002071sv00001077sd00000283*
+ ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2764 Quad Port 32Gb Fibre Channel to PCIe Adapter)
+
+pci:v00001077d00002071sv00001077sd0000029E*
+ ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2694 Quad Port 16Gb Fibre Channel to PCIe Adapter)
+
+pci:v00001077d00002071sv00001077sd000002A2*
+ ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2694L Quad Port 16Gb Fibre Channel to PCIe Adapter)
+
+pci:v00001077d00002071sv00001077sd000002AD*
+ ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2694U Quad Port 16/32Gb Fibre Channel to PCIe Adapter)
+
pci:v00001077d00002100*
ID_MODEL_FROM_DATABASE=QLA2100 64-bit Fibre Channel Adapter
@@ -17390,6 +17618,18 @@ pci:v00001077d00002200sv00001077sd00000002*
pci:v00001077d00002261*
ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter
+pci:v00001077d00002261sv00001077sd00000299*
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2740 Single Port 32Gb Fibre Channel to PCIe Adapter)
+
+pci:v00001077d00002261sv00001077sd0000029A*
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2742 Dual Port 32Gb Fibre Channel to PCIe Adapter)
+
+pci:v00001077d00002261sv00001077sd0000029B*
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2690 Single Port 16Gb Fibre Channel to PCIe Adapter)
+
+pci:v00001077d00002261sv00001077sd0000029C*
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2692 Dual Port 16Gb Fibre Channel to PCIe 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)
@@ -17432,6 +17672,9 @@ pci:v00001077d00002532*
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:v00001077d00002532sv00001077sd00000167*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QME2572 Dual Port FC8 HBA Mezzanine)
@@ -21786,7 +22029,7 @@ pci:v000010B5d00009080sv000012D9sd00000002*
ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (PCI Prosody Card)
pci:v000010B5d00009080sv000012DFsd00004422*
- ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (4422PCI ["Do-All" Telemetry Data Aquisition System])
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (4422PCI ["Do-All" Telemetry Data Acquisition System])
pci:v000010B5d00009080sv00001369sd00009601*
ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (PCX822np)
@@ -23856,7 +24099,7 @@ pci:v000010DEd0000006A*
ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP)
pci:v000010DEd0000006Asv00001043sd00008095*
- ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP)
+ ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP) (nForce2 AC97 Audio Controller (MCP))
pci:v000010DEd0000006Asv0000A0A0sd00000304*
ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP) (UK79G-1394 motherboard)
@@ -28898,6 +29141,9 @@ pci:v000010DEd00000F02*
pci:v000010DEd00000F06*
ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 730]
+pci:v000010DEd00000FB0*
+ ID_MODEL_FROM_DATABASE=GM200 High Definition Audio
+
pci:v000010DEd00000FBB*
ID_MODEL_FROM_DATABASE=GM204 High Definition Audio Controller
@@ -29294,6 +29540,9 @@ pci:v000010DEd0000105Bsv000017AAsd0000309D*
pci:v000010DEd0000105Bsv000017AAsd000030B1*
ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 800A)
+pci:v000010DEd0000105Bsv000017AAsd000030F3*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 705A)
+
pci:v000010DEd0000105Bsv000017AAsd000036A1*
ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 800A)
@@ -30722,6 +30971,9 @@ pci:v000010DEd00001288*
pci:v000010DEd00001289*
ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 710]
+pci:v000010DEd0000128B*
+ ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 710B]
+
pci:v000010DEd00001290*
ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M]
@@ -30794,6 +31046,15 @@ pci:v000010DEd00001298*
pci:v000010DEd00001299*
ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M]
+pci:v000010DEd00001299sv000017AAsd000030BB*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M] (GeForce 920A)
+
+pci:v000010DEd00001299sv000017AAsd000036A7*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M] (GeForce 920A)
+
+pci:v000010DEd00001299sv000017AAsd000036AF*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M] (GeForce 920M)
+
pci:v000010DEd0000129A*
ID_MODEL_FROM_DATABASE=GK208M [GeForce 910M]
@@ -30833,11 +31094,26 @@ pci:v000010DEd00001346*
pci:v000010DEd00001347*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 940M]
+pci:v000010DEd00001348*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 945M / 945A]
+
+pci:v000010DEd00001349*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 930M]
+
pci:v000010DEd0000134D*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 940MX]
+pci:v000010DEd0000134E*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 930MX]
+
+pci:v000010DEd0000134F*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 920MX]
+
pci:v000010DEd0000137A*
- ID_MODEL_FROM_DATABASE=GM108GLM [Quadro K620M]
+ ID_MODEL_FROM_DATABASE=GM108GLM [Quadro K620M / Quadro M500M]
+
+pci:v000010DEd0000137Asv000017AAsd0000505A*
+ ID_MODEL_FROM_DATABASE=GM108GLM [Quadro K620M / Quadro M500M] (Quadro M500M)
pci:v000010DEd0000137D*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 940A]
@@ -30890,6 +31166,9 @@ pci:v000010DEd0000139Asv000017AAsd0000363F*
pci:v000010DEd0000139Asv000017AAsd00003640*
ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 950M] (GeForce GTX 950A)
+pci:v000010DEd0000139Asv000017AAsd00003647*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 950M] (GeForce GTX 950A)
+
pci:v000010DEd0000139Asv000017AAsd000036B9*
ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 950M] (GeForce GTX 950A)
@@ -30902,6 +31181,9 @@ pci:v000010DEd0000139Bsv0000103Csd00002B4C*
pci:v000010DEd0000139C*
ID_MODEL_FROM_DATABASE=GM107M [GeForce 940M]
+pci:v000010DEd0000139D*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 750 Ti]
+
pci:v000010DEd000013B0*
ID_MODEL_FROM_DATABASE=GM107GLM [Quadro M2000M]
@@ -30965,6 +31247,9 @@ pci:v000010DEd000013F1*
pci:v000010DEd000013F2*
ID_MODEL_FROM_DATABASE=GM204GL [Tesla M60]
+pci:v000010DEd000013F3*
+ ID_MODEL_FROM_DATABASE=GM204GL [Tesla M6]
+
pci:v000010DEd000013F8*
ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M5000M]
@@ -30974,18 +31259,30 @@ pci:v000010DEd000013F9*
pci:v000010DEd000013FA*
ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M3000M]
+pci:v000010DEd000013FB*
+ ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M5500]
+
pci:v000010DEd00001401*
ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 960]
pci:v000010DEd00001402*
ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 950]
+pci:v000010DEd00001406*
+ ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 960]
+
pci:v000010DEd00001407*
ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 750 v2]
pci:v000010DEd00001427*
ID_MODEL_FROM_DATABASE=GM206M [GeForce GTX 965M]
+pci:v000010DEd00001430*
+ ID_MODEL_FROM_DATABASE=GM206GL [Quadro M2000]
+
+pci:v000010DEd00001431*
+ ID_MODEL_FROM_DATABASE=GM206GL [Tesla M4]
+
pci:v000010DEd00001617*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980M]
@@ -30998,6 +31295,9 @@ pci:v000010DEd00001619*
pci:v000010DEd0000161A*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980]
+pci:v000010DEd00001667*
+ ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 965M]
+
pci:v000010DEd000017C2*
ID_MODEL_FROM_DATABASE=GM200 [GeForce GTX TITAN X]
@@ -31007,9 +31307,15 @@ pci:v000010DEd000017C8*
pci:v000010DEd000017F0*
ID_MODEL_FROM_DATABASE=GM200GL [Quadro M6000]
+pci:v000010DEd000017F1*
+ ID_MODEL_FROM_DATABASE=GM200GL [Quadro M6000 24GB]
+
pci:v000010DEd000017FD*
ID_MODEL_FROM_DATABASE=GM200GL [Tesla M40]
+pci:v000010DEd00001B80*
+ ID_MODEL_FROM_DATABASE=GP104 [GeForce GTX 1080]
+
pci:v000010DF*
ID_VENDOR_FROM_DATABASE=Emulex Corporation
@@ -31100,6 +31406,9 @@ pci:v000010DFd0000E260*
pci:v000010DFd0000E268*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Converged Network Adapter (Lancer-VF)
+pci:v000010DFd0000E300*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter
+
pci:v000010DFd0000F011*
ID_MODEL_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter
@@ -31142,6 +31451,9 @@ pci:v000010DFd0000F0F5*
pci:v000010DFd0000F100*
ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter
+pci:v000010DFd0000F100sv0000103Csd00003282*
+ ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb Dual-port PCI-e FC HBA)
+
pci:v000010DFd0000F111*
ID_MODEL_FROM_DATABASE=Saturn-X LightPulse Fibre Channel Host Adapter
@@ -31760,9 +32072,6 @@ pci:v000010ECd00008168sv0000103Csd00001950*
pci:v000010ECd00008168sv0000103Csd00002A6F*
ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Asus IPIBL-LB Motherboard)
-pci:v000010ECd00008168sv00001043sd000011F5*
- ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (A6J-Q008)
-
pci:v000010ECd00008168sv00001043sd000016D5*
ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (U6V/U31J laptop)
@@ -33236,6 +33545,9 @@ pci:v00001106d00003059sv00001043sd000080A1*
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)
+
pci:v00001106d00003059sv00001043sd0000810D*
ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (Asus P5VD1-X (AD1888 codec [SoundMax]))
@@ -37583,6 +37895,9 @@ pci:v00001180d00000476*
pci:v00001180d00000476sv00001014sd00000185*
ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad A/T/X Series)
+pci:v00001180d00000476sv00001014sd00000555*
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad X41)
+
pci:v00001180d00000476sv00001014sd0000056C*
ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad Z60t)
@@ -37743,7 +38058,7 @@ pci:v00001180d00000822*
ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter
pci:v00001180d00000822sv00001014sd00000556*
- ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad X60s / Z60t)
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad X40 / X41 / X60s / Z60t)
pci:v00001180d00000822sv00001014sd00000598*
ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad Z60m)
@@ -38402,6 +38717,9 @@ pci:v000011ABd00002B36*
pci:v000011ABd00002B38*
ID_MODEL_FROM_DATABASE=88W8897 [AVASTAR] 802.11ac Wireless
+pci:v000011ABd00002B40*
+ ID_MODEL_FROM_DATABASE=88W8964 [Avastar] 802.11ac Wireless
+
pci:v000011ABd00004101*
ID_MODEL_FROM_DATABASE=OLPC Cafe Controller Secure Digital Controller
@@ -46499,6 +46817,9 @@ pci:v00001425d0000509A*
pci:v00001425d0000509B*
ID_MODEL_FROM_DATABASE=T540-509B Unified Wire Ethernet Controller
+pci:v00001425d0000509C*
+ ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Ethernet Controller
+
pci:v00001425d00005401*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -46634,6 +46955,9 @@ pci:v00001425d0000549A*
pci:v00001425d0000549B*
ID_MODEL_FROM_DATABASE=T540-509B Unified Wire Ethernet Controller
+pci:v00001425d0000549C*
+ ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Ethernet Controller
+
pci:v00001425d00005501*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
@@ -46769,6 +47093,9 @@ pci:v00001425d0000559A*
pci:v00001425d0000559B*
ID_MODEL_FROM_DATABASE=T540-509B Unified Wire Storage Controller
+pci:v00001425d0000559C*
+ ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Storage Controller
+
pci:v00001425d00005601*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
@@ -46904,6 +47231,9 @@ pci:v00001425d0000569A*
pci:v00001425d0000569B*
ID_MODEL_FROM_DATABASE=T540-509B Unified Wire Storage Controller
+pci:v00001425d0000569C*
+ ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Storage Controller
+
pci:v00001425d00005701*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -47156,6 +47486,9 @@ pci:v00001425d0000589A*
pci:v00001425d0000589B*
ID_MODEL_FROM_DATABASE=T540-509B Unified Wire Ethernet Controller [VF]
+pci:v00001425d0000589C*
+ ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Ethernet Controller [VF]
+
pci:v00001425d0000A000*
ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
@@ -47342,6 +47675,9 @@ pci:v0000144Ad00009113*
pci:v0000144Ad00009114*
ID_MODEL_FROM_DATABASE=PCI-9114
+pci:v0000144Ad0000A001*
+ ID_MODEL_FROM_DATABASE=ADi-BSEC
+
pci:v0000144B*
ID_VENDOR_FROM_DATABASE=Verint Systems Inc.
@@ -47690,6 +48026,9 @@ pci:v00001498d000030C8*
pci:v00001498d000070C8*
ID_MODEL_FROM_DATABASE=TPCE200 4 Slot IndustryPack PCIe Carrier
+pci:v00001498d00009177*
+ ID_MODEL_FROM_DATABASE=TXMC375 8 channel RS232/RS422/RS485 programmable serial interface
+
pci:v00001499*
ID_VENDOR_FROM_DATABASE=EMTEC CO., Ltd
@@ -48207,7 +48546,7 @@ pci:v000014E4d00001639sv0000103Csd00007055*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (NC382i Integrated Multi-port PCI Express Gigabit Server Adapter)
pci:v000014E4d00001639sv0000103Csd00007059*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter)
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (NC382T PCIe Dual Port Multifunction Gigabit Server Adapter)
pci:v000014E4d00001639sv000010A9sd00008027*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (Quad port Gigabit Ethernet Controller)
@@ -48420,7 +48759,7 @@ pci:v000014E4d00001647sv00000E11sd0000009A*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NC7770 1000BaseTX)
pci:v000014E4d00001647sv000010A9sd00008010*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (SGI IO9 Gigabit Ethernet (Copper))
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (IO9 Gigabit Ethernet (Copper))
pci:v000014E4d00001647sv000014E4sd00000009*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (BCM5703 1000BaseTX)
@@ -48590,6 +48929,9 @@ pci:v000014E4d00001657sv0000103Csd0000169D*
pci:v000014E4d00001657sv0000103Csd000022BE*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5719 Gigabit Ethernet PCIe (Ethernet 1Gb 4-port 331i Adapter)
+pci:v000014E4d00001657sv0000103Csd00003383*
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5719 Gigabit Ethernet PCIe (Ethernet 1Gb 4-port 331T Adapter)
+
pci:v000014E4d00001659*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express
@@ -48792,7 +49134,7 @@ pci:v000014E4d0000167D*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express
pci:v000014E4d0000167Dsv00001014sd00000577*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (ThinkPad Z60t)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (ThinkPad X41 / Z60t)
pci:v000014E4d0000167Dsv0000103Csd00000934*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (nx8220)
@@ -49901,6 +50243,9 @@ pci:v000014E4d000043A9*
pci:v000014E4d000043AA*
ID_MODEL_FROM_DATABASE=BCM43131 802.11b/g/n
+pci:v000014E4d000043AE*
+ ID_MODEL_FROM_DATABASE=BCM43162 802.11ac Wireless Network Adapter
+
pci:v000014E4d000043B1*
ID_MODEL_FROM_DATABASE=BCM4352 802.11ac Wireless Network Adapter
@@ -50963,6 +51308,9 @@ pci:v000014F1d00008880*
pci:v000014F1d00008880sv00000070sd00002259*
ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (WinTV HVR-1250)
+pci:v000014F1d00008880sv00000070sd00006A18*
+ ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (WinTV-quadHD)
+
pci:v000014F1d00008880sv00000070sd0000C108*
ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (WinTV-HVR-4400-HD model 1278)
@@ -51950,6 +52298,9 @@ pci:v000015AB*
pci:v000015AC*
ID_VENDOR_FROM_DATABASE=North Atlantic Instruments
+pci:v000015ACd00006893*
+ ID_MODEL_FROM_DATABASE=3U OpenVPX Multi-function I/O Board [Model 68C3]
+
pci:v000015AD*
ID_VENDOR_FROM_DATABASE=VMware
@@ -51998,6 +52349,9 @@ pci:v000015ADd00000801*
pci:v000015ADd00000801sv000015ADsd00000800*
ID_MODEL_FROM_DATABASE=Virtual Machine Interface (Hypervisor ROM Interface)
+pci:v000015ADd00000820*
+ ID_MODEL_FROM_DATABASE=Paravirtual RDMA controller
+
pci:v000015ADd00001977*
ID_MODEL_FROM_DATABASE=HD Audio Controller
@@ -52137,11 +52491,38 @@ pci:v000015B3d00001016*
ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx Virtual Function]
pci:v000015B3d00001017*
- ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5]
+ ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5, PCIe 3.0]
pci:v000015B3d00001018*
ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Virtual Function]
+pci:v000015B3d00001019*
+ ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5, PCIe 4.0]
+
+pci:v000015B3d0000101A*
+ ID_MODEL_FROM_DATABASE=MT28830
+
+pci:v000015B3d0000101B*
+ ID_MODEL_FROM_DATABASE=MT28831
+
+pci:v000015B3d0000101C*
+ ID_MODEL_FROM_DATABASE=MT28840
+
+pci:v000015B3d0000101D*
+ ID_MODEL_FROM_DATABASE=MT28841
+
+pci:v000015B3d0000101E*
+ ID_MODEL_FROM_DATABASE=MT28850
+
+pci:v000015B3d0000101F*
+ ID_MODEL_FROM_DATABASE=MT28851
+
+pci:v000015B3d00001020*
+ ID_MODEL_FROM_DATABASE=MT28860
+
+pci:v000015B3d00001021*
+ ID_MODEL_FROM_DATABASE=MT28861
+
pci:v000015B3d00005274*
ID_MODEL_FROM_DATABASE=MT21108 InfiniBridge
@@ -52226,9 +52607,36 @@ pci:v000015B3d0000676E*
pci:v000015B3d00006778*
ID_MODEL_FROM_DATABASE=MT26488 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE Virtualization+]
+pci:v000015B3d00007101*
+ ID_MODEL_FROM_DATABASE=NPS-400 configuration and management interface
+
+pci:v000015B3d00007102*
+ ID_MODEL_FROM_DATABASE=NPS-400 network interface PF
+
+pci:v000015B3d00007103*
+ ID_MODEL_FROM_DATABASE=NPS-400 network interface VF
+
+pci:v000015B3d00007121*
+ ID_MODEL_FROM_DATABASE=NPS-600 configuration and management interface
+
+pci:v000015B3d00007122*
+ ID_MODEL_FROM_DATABASE=NPS-600 network interface PF
+
+pci:v000015B3d00007123*
+ ID_MODEL_FROM_DATABASE=NPS-600 network interface VF
+
pci:v000015B3d0000C738*
ID_MODEL_FROM_DATABASE=MT51136
+pci:v000015B3d0000C739*
+ ID_MODEL_FROM_DATABASE=MT51136 GW
+
+pci:v000015B3d0000C838*
+ ID_MODEL_FROM_DATABASE=MT52236
+
+pci:v000015B3d0000C839*
+ ID_MODEL_FROM_DATABASE=MT52236 router
+
pci:v000015B3d0000CAF1*
ID_MODEL_FROM_DATABASE=ConnectX-4 CAPI Function
@@ -53630,6 +54038,9 @@ pci:v0000168Cd00000029sv00001186sd00003A7A*
pci:v0000168Cd00000029sv00001186sd00003A7D*
ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (DWA-552 802.11n Xtreme N Desktop Adapter (rev A3))
+pci:v0000168Cd00000029sv0000168Csd00002096*
+ ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (Compex WLM200NX / Wistron DNMA-92)
+
pci:v0000168Cd0000002A*
ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express)
@@ -53795,6 +54206,9 @@ pci:v0000168Cd00000040*
pci:v0000168Cd00000041*
ID_MODEL_FROM_DATABASE=QCA6164 802.11ac Wireless Network Adapter
+pci:v0000168Cd00000042*
+ ID_MODEL_FROM_DATABASE=QCA9377 802.11ac Wireless Network Adapter
+
pci:v0000168Cd00000050*
ID_MODEL_FROM_DATABASE=QCA9887 802.11ac Wireless Network Adapter
@@ -54407,6 +54821,24 @@ pci:v0000177Dd00000096*
pci:v0000177Dd00009700*
ID_MODEL_FROM_DATABASE=Octeon III CN73XX Network Processor
+pci:v0000177Dd00009702*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter
+
+pci:v0000177Dd00009702sv0000177Dsd00000003*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2350 [LiquidIO II] 2-port 10GbE Intelligent adapter)
+
+pci:v0000177Dd00009702sv0000177Dsd00000004*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2350 [LiquidIO II] 2-port 25GbE Intelligent adapter)
+
+pci:v0000177Dd00009703*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] NVMe Controller
+
+pci:v0000177Dd00009712*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] SRIOV Virtual Function
+
+pci:v0000177Dd00009713*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] NVMe SRIOV Virtual Function
+
pci:v0000177Dd00009800*
ID_MODEL_FROM_DATABASE=Octeon Fusion CNF75XX Processor
@@ -55193,6 +55625,9 @@ pci:v00001814d00000301sv00001458sd0000E933*
pci:v00001814d00000301sv00001458sd0000E934*
ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (GN-WP01GS)
+pci:v00001814d00000301sv00001462sd0000B833*
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (MP54G5 (MS-6833B))
+
pci:v00001814d00000301sv00001737sd00000055*
ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (WMP54G v4.1)
@@ -55883,6 +56318,9 @@ pci:v000018F4d00000145*
pci:v000018F4d00000155*
ID_MODEL_FROM_DATABASE=NT100E3-1-PTP Network Adapter 1x100Gb
+pci:v000018F4d00000165*
+ ID_MODEL_FROM_DATABASE=NT80E3-2-PTP Network Adapter 2x40Gb
+
pci:v000018F4d00000175*
ID_MODEL_FROM_DATABASE=NT20E3-2-PTP Network Adapter 2x10Gb
@@ -56394,7 +56832,7 @@ pci:v0000193C*
ID_VENDOR_FROM_DATABASE=MAXIM Integrated Products
pci:v0000193F*
- ID_VENDOR_FROM_DATABASE=Comtech AHA Corp.
+ ID_VENDOR_FROM_DATABASE=AHA Products Group
pci:v0000193Fd00000001*
ID_MODEL_FROM_DATABASE=AHA36x-PCIX
@@ -56414,12 +56852,24 @@ pci:v0000193Fd00000367*
pci:v0000193Fd00000370*
ID_MODEL_FROM_DATABASE=AHA370-PCIe
+pci:v0000193Fd00000604*
+ ID_MODEL_FROM_DATABASE=AHA604
+
+pci:v0000193Fd00000605*
+ ID_MODEL_FROM_DATABASE=AHA605
+
pci:v0000193Fd00003641*
ID_MODEL_FROM_DATABASE=AHA3641
pci:v0000193Fd00003642*
ID_MODEL_FROM_DATABASE=AHA3642
+pci:v0000193Fd00006101*
+ ID_MODEL_FROM_DATABASE=AHA6101
+
+pci:v0000193Fd00006102*
+ ID_MODEL_FROM_DATABASE=AHA6102
+
pci:v00001942*
ID_VENDOR_FROM_DATABASE=ClearSpeed Technology plc
@@ -56666,6 +57116,9 @@ pci:v00001957d00000408*
pci:v00001957d00000409*
ID_MODEL_FROM_DATABASE=P4040
+pci:v00001957d0000041F*
+ ID_MODEL_FROM_DATABASE=P3041
+
pci:v00001957d00000440*
ID_MODEL_FROM_DATABASE=T4240 with security
@@ -57521,6 +57974,15 @@ pci:v00001ADE*
pci:v00001ADEd00001501*
ID_MODEL_FROM_DATABASE=Swipetech barcode scanner
+pci:v00001ADEd00003038*
+ ID_MODEL_FROM_DATABASE=PCIe Video Bridge
+
+pci:v00001ADEd00003038sv000013C2sd00003016*
+ ID_MODEL_FROM_DATABASE=PCIe Video Bridge (TT-budget S2-4200 Twin)
+
+pci:v00001ADEd00003038sv00004254sd00000552*
+ ID_MODEL_FROM_DATABASE=PCIe Video Bridge (S952 v3)
+
pci:v00001AE0*
ID_VENDOR_FROM_DATABASE=Google, Inc.
@@ -57653,11 +58115,32 @@ pci:v00001AF4d00001005*
pci:v00001AF4d00001009*
ID_MODEL_FROM_DATABASE=Virtio filesystem
-pci:v00001AF4d00001010*
+pci:v00001AF4d00001041*
+ ID_MODEL_FROM_DATABASE=Virtio network device
+
+pci:v00001AF4d00001042*
+ ID_MODEL_FROM_DATABASE=Virtio block device
+
+pci:v00001AF4d00001043*
+ ID_MODEL_FROM_DATABASE=Virtio console
+
+pci:v00001AF4d00001044*
+ ID_MODEL_FROM_DATABASE=Virtio RNG
+
+pci:v00001AF4d00001045*
+ ID_MODEL_FROM_DATABASE=Virtio memory balloon
+
+pci:v00001AF4d00001048*
+ ID_MODEL_FROM_DATABASE=Virtio SCSI
+
+pci:v00001AF4d00001049*
+ ID_MODEL_FROM_DATABASE=Virtio filesystem
+
+pci:v00001AF4d00001050*
ID_MODEL_FROM_DATABASE=Virtio GPU
-pci:v00001AF4d00001012*
- ID_MODEL_FROM_DATABASE=Virtio input device
+pci:v00001AF4d00001052*
+ ID_MODEL_FROM_DATABASE=Virtio input
pci:v00001AF4d00001110*
ID_MODEL_FROM_DATABASE=Inter-VM shared memory
@@ -57983,6 +58466,9 @@ pci:v00001B74d0000D410*
pci:v00001B74d0000D430*
ID_MODEL_FROM_DATABASE=D410/430 Quad-port E1/T1 card
+pci:v00001B79*
+ ID_VENDOR_FROM_DATABASE=Absolute Analysis
+
pci:v00001B85*
ID_VENDOR_FROM_DATABASE=OCZ Technology Group, Inc.
@@ -58142,6 +58628,9 @@ pci:v00001C09d00004255*
pci:v00001C09d00004256*
ID_MODEL_FROM_DATABASE=10G-PCIE3-8D-2S
+pci:v00001C09d00004258*
+ ID_MODEL_FROM_DATABASE=10G-PCIE3-8E-2S
+
pci:v00001C1C*
ID_VENDOR_FROM_DATABASE=Symphony
@@ -58218,10 +58707,16 @@ pci:v00001C58d00000003*
ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD
pci:v00001C58d00000003sv00001014sd000004F5*
- ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (PCIe3 1.6TB NVMe Adapter)
+ ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (PCIe3 1.6TB NVMe Flash Adapter)
pci:v00001C58d00000003sv00001014sd000004F6*
- ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (PCIe3 3.2TB NVMe Adapter)
+ ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (PCIe3 3.2TB NVMe Flash Adapter)
+
+pci:v00001C63*
+ ID_VENDOR_FROM_DATABASE=Science and Research Centre of Computer Technology (JSC "NICEVT")
+
+pci:v00001C63d00000008*
+ ID_MODEL_FROM_DATABASE=K1927BB1Ya [EC8430] Angara Interconnection Network Adapter
pci:v00001C7E*
ID_VENDOR_FROM_DATABASE=TTTech Computertechnik AG
@@ -58331,6 +58826,9 @@ pci:v00001D5C*
pci:v00001D61*
ID_VENDOR_FROM_DATABASE=Technobox, Inc.
+pci:v00001D62*
+ ID_VENDOR_FROM_DATABASE=Nebbiolo Technologies
+
pci:v00001D65*
ID_VENDOR_FROM_DATABASE=Imagine Communications Corp.
@@ -58361,6 +58859,21 @@ pci:v00001D6Cd00001006*
pci:v00001D6Cd00001007*
ID_MODEL_FROM_DATABASE=XUSP3S-VU095 [Jasper]
+pci:v00001D6Cd00001008*
+ ID_MODEL_FROM_DATABASE=XUSPL4-VU065 [Mustang UltraScale]
+
+pci:v00001D6Cd00001009*
+ ID_MODEL_FROM_DATABASE=XUSPL4-VU3P [Mustang UltraScale+]
+
+pci:v00001D6Cd0000100A*
+ ID_MODEL_FROM_DATABASE=A10PL4-A10GX115
+
+pci:v00001D6Cd0000100B*
+ ID_MODEL_FROM_DATABASE=K35-2SFP
+
+pci:v00001D6Cd0000100C*
+ ID_MODEL_FROM_DATABASE=K35-4SFP
+
pci:v00001D6Cd00004200*
ID_MODEL_FROM_DATABASE=A5PL-E1-10GETI [10 GbE Ethernet Traffic Instrument]
@@ -58478,9 +58991,15 @@ pci:v00001FC9d00004020*
pci:v00001FC9d00004022*
ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter
+pci:v00001FC9d00004022sv00001043sd00008709*
+ ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (XG-C100F 10GbE SFP+ Ethernet Adapter)
+
pci:v00001FC9d00004022sv00001186sd00004D00*
ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (DXE-810S 10GbE SFP+ Ethernet Adapter)
+pci:v00001FC9d00004022sv00001432sd00008103*
+ ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (EN-8102PF 10GbE SPF+ Ethernet Adapter)
+
pci:v00001FC9d00004022sv00001FC9sd00003015*
ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (Ethernet Adapter)
@@ -58490,9 +59009,15 @@ pci:v00001FC9d00004024*
pci:v00001FC9d00004025*
ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter
+pci:v00001FC9d00004025sv0000105Asd00007203*
+ ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (SANLink3 NBase-T1)
+
pci:v00001FC9d00004025sv00001186sd00002900*
ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (DXE-810T 10GBase-T Ethernet Adapter)
+pci:v00001FC9d00004025sv00001432sd00008102*
+ ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (EN-8102P 10GbE Ethernet Adapter)
+
pci:v00001FC9d00004025sv00001FC9sd00003015*
ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (Ethernet Adapter)
@@ -59276,137 +59801,347 @@ pci:v00004943*
pci:v0000494F*
ID_VENDOR_FROM_DATABASE=ACCES I/O Products, Inc.
+pci:v0000494Fd00000508*
+ ID_MODEL_FROM_DATABASE=PCI-IDO-16A FET Output Card
+
+pci:v0000494Fd00000518*
+ ID_MODEL_FROM_DATABASE=PCI-IDO-32A FET Output Card
+
pci:v0000494Fd00000520*
- ID_MODEL_FROM_DATABASE=PCI-IDO-48
+ ID_MODEL_FROM_DATABASE=PCI-IDO-48 FET Output Card
+
+pci:v0000494Fd00000521*
+ ID_MODEL_FROM_DATABASE=PCI-IDO-48A FET Output Card
+
+pci:v0000494Fd00000703*
+ ID_MODEL_FROM_DATABASE=PCIe-RO-4 Electromechanical Relay Output Card
+
+pci:v0000494Fd000007D0*
+ ID_MODEL_FROM_DATABASE=PCIe-IDO-24 FET Output Card
pci:v0000494Fd00000920*
- ID_MODEL_FROM_DATABASE=PCI-IDI-48
+ ID_MODEL_FROM_DATABASE=PCI-IDI-48 Isolated Digital Input Card
+
+pci:v0000494Fd00000BD0*
+ ID_MODEL_FROM_DATABASE=PCIe-IDI-24 Isolated Digital Input Card
pci:v0000494Fd00000C50*
- ID_MODEL_FROM_DATABASE=PCI-DIO-24H
+ ID_MODEL_FROM_DATABASE=PCI-DIO-24H 1x 8255 Digital Input / Output Card
pci:v0000494Fd00000C51*
- ID_MODEL_FROM_DATABASE=PCI-DIO-24D
+ ID_MODEL_FROM_DATABASE=PCI-DIO-24D 1x 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000C52*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-24 1x 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000C53*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-24H 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000C57*
+ ID_MODEL_FROM_DATABASE=mPCIe-DIO-24 8255 Digital Input / Output Card
pci:v0000494Fd00000C60*
- ID_MODEL_FROM_DATABASE=PCI-DIO-48(H)
+ ID_MODEL_FROM_DATABASE=PCI-DIO-48H 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000C61*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-48 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000C62*
+ ID_MODEL_FROM_DATABASE=P104-DIO-48 8255 Digital Input / Output Card
pci:v0000494Fd00000C68*
- ID_MODEL_FROM_DATABASE=PCI-DIO-72
+ ID_MODEL_FROM_DATABASE=PCI-DIO-72 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000C69*
+ ID_MODEL_FROM_DATABASE=P104-DIO-96 8255 Digital Input / Output Card
pci:v0000494Fd00000C70*
- ID_MODEL_FROM_DATABASE=PCI-DIO-96
+ ID_MODEL_FROM_DATABASE=PCI-DIO-96 8255 Digital Input / Output Card
pci:v0000494Fd00000C78*
- ID_MODEL_FROM_DATABASE=PCI-DIO-120
+ ID_MODEL_FROM_DATABASE=PCI-DIO-120 8255 Digital Input / Output Card
pci:v0000494Fd00000DC8*
- ID_MODEL_FROM_DATABASE=PCI-IDIO-16
+ ID_MODEL_FROM_DATABASE=PCI-IDIO-16 Isolated Digital Input / FET Output Card
pci:v0000494Fd00000E50*
- ID_MODEL_FROM_DATABASE=PCI-DIO-24S
+ ID_MODEL_FROM_DATABASE=PCI-DIO-24S 8255 Digital Input / Output Card
pci:v0000494Fd00000E51*
- ID_MODEL_FROM_DATABASE=PCI-DIO-24H(C)
+ ID_MODEL_FROM_DATABASE=PCI-DIO-24H(C) 8255 Digital Input / Output Card
pci:v0000494Fd00000E52*
- ID_MODEL_FROM_DATABASE=PCI-DIO-24D(C)
+ ID_MODEL_FROM_DATABASE=PCI-DIO-24D(C) 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000E53*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-24S 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000E54*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-24HS 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000E55*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-24DC 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000E56*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-24DCS 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000E57*
+ ID_MODEL_FROM_DATABASE=mPCIe-DIO-24S 8255 Digital Input / Output Card
pci:v0000494Fd00000E60*
- ID_MODEL_FROM_DATABASE=PCI-DIO-48S(H)
+ ID_MODEL_FROM_DATABASE=PCI-DIO-48S 2x 8255 Digital Input / Output Card
pci:v0000494Fd00000E61*
- ID_MODEL_FROM_DATABASE=P104-DIO-24S
+ ID_MODEL_FROM_DATABASE=PCIe-DIO-48S 2x 8255 Digital Input / Output Card
+
+pci:v0000494Fd00000E62*
+ ID_MODEL_FROM_DATABASE=P104-DIO-48S 2x 8255 Digital Input / Output Card
pci:v0000494Fd00000F00*
- ID_MODEL_FROM_DATABASE=PCI-IIRO-8
+ ID_MODEL_FROM_DATABASE=PCI-IIRO-8 Isolated Digital / Relay Output Card
pci:v0000494Fd00000F01*
- ID_MODEL_FROM_DATABASE=LPCI-IIRO-8
+ ID_MODEL_FROM_DATABASE=LPCI-IIRO-8 Isolated Digital / Relay Output Card
+
+pci:v0000494Fd00000F02*
+ ID_MODEL_FROM_DATABASE=PCIe-IIRO-8 Isolated Digital / Relay Output Card
pci:v0000494Fd00000F08*
- ID_MODEL_FROM_DATABASE=PCI-IIRO-16
+ ID_MODEL_FROM_DATABASE=PCI-IIRO-16 Isolated Digital / Relay Output Card
+
+pci:v0000494Fd00000F09*
+ ID_MODEL_FROM_DATABASE=PCIe-IIRO-16 Isolated Digital / Relay Output Card
+
+pci:v0000494Fd00000FC0*
+ ID_MODEL_FROM_DATABASE=PCIe-IDIO-12 Isolated Digital Input / FET Output Card
+
+pci:v0000494Fd00000FC1*
+ ID_MODEL_FROM_DATABASE=PCIe-IDI-12 Isolated Digital Input Card
+
+pci:v0000494Fd00000FC2*
+ ID_MODEL_FROM_DATABASE=PCIe-IDO-12 FET Output Card
+
+pci:v0000494Fd00000FD0*
+ ID_MODEL_FROM_DATABASE=PCIe-IDIO-24 Isolated Digital Input / FET Output Card
pci:v0000494Fd00001050*
- ID_MODEL_FROM_DATABASE=PCI-422/485-2
+ ID_MODEL_FROM_DATABASE=PCI-422/485-2 2x RS422/RS484 Card
+
+pci:v0000494Fd00001051*
+ ID_MODEL_FROM_DATABASE=PCIe-COM-2SRJ 2x RS422/RS484 Card w/RJ45 Connectors
+
+pci:v0000494Fd00001052*
+ ID_MODEL_FROM_DATABASE=104I-COM-2S 2x RS422/RS484 PCI/104 Board
+
+pci:v0000494Fd00001053*
+ ID_MODEL_FROM_DATABASE=mPCIe-COM-2S 2x RS422/RS484 PCI Express Mini Card
pci:v0000494Fd00001058*
- ID_MODEL_FROM_DATABASE=PCI-COM422/4
+ ID_MODEL_FROM_DATABASE=PCI-COM422/4 4x RS422 Card
pci:v0000494Fd00001059*
- ID_MODEL_FROM_DATABASE=PCI-COM485/4
+ ID_MODEL_FROM_DATABASE=PCI-COM485/4 4x RS485 Card
+
+pci:v0000494Fd0000105A*
+ ID_MODEL_FROM_DATABASE=PCIe-COM422-4 4x RS422 Card
+
+pci:v0000494Fd0000105B*
+ ID_MODEL_FROM_DATABASE=PCIe-COM485-4 4x RS485 Card
+
+pci:v0000494Fd0000105C*
+ ID_MODEL_FROM_DATABASE=PCIe-COM-4SRJ 4x RS422/RS485 Card w/RJ45 Connectors
+
+pci:v0000494Fd0000105D*
+ ID_MODEL_FROM_DATABASE=104I-COM-4S 4x RS422/RS484 PCI/104 Board
+
+pci:v0000494Fd0000105E*
+ ID_MODEL_FROM_DATABASE=mPCIe-COM-4S 4x RS422/RS484 PCI Express Mini Card
pci:v0000494Fd00001068*
- ID_MODEL_FROM_DATABASE=PCI-COM422/8
+ ID_MODEL_FROM_DATABASE=PCI-COM422/8 8x RS422 Card
pci:v0000494Fd00001069*
- ID_MODEL_FROM_DATABASE=PCI-COM485/8
+ ID_MODEL_FROM_DATABASE=PCI-COM485/8 8x RS485 Card
+
+pci:v0000494Fd0000106A*
+ ID_MODEL_FROM_DATABASE=PCIe-COM422-8 8x RS422 Card
+
+pci:v0000494Fd0000106B*
+ ID_MODEL_FROM_DATABASE=PCIe-COM485-8 8x RS485 Card
+
+pci:v0000494Fd0000106C*
+ ID_MODEL_FROM_DATABASE=104I-COM-8S 8x RS422/RS485 PCI/104 Board
pci:v0000494Fd00001088*
- ID_MODEL_FROM_DATABASE=PCI-COM232/1
+ ID_MODEL_FROM_DATABASE=PCI-COM232/1 1x RS232 Card
pci:v0000494Fd00001090*
- ID_MODEL_FROM_DATABASE=PCI-COM232/2
+ ID_MODEL_FROM_DATABASE=PCI-COM232/2 2x RS232 Card
+
+pci:v0000494Fd00001091*
+ ID_MODEL_FROM_DATABASE=PCIe-COM232-2RJ 2x RS232 Card w/RJ45 Connectors
+
+pci:v0000494Fd00001093*
+ ID_MODEL_FROM_DATABASE=mPCIe-COM232-2 2x RS232 PCI Express Mini Card
+
+pci:v0000494Fd00001098*
+ ID_MODEL_FROM_DATABASE=PCIe-COM232-4 4x RS232 Card
+
+pci:v0000494Fd00001099*
+ ID_MODEL_FROM_DATABASE=PCIe-COM232-4RJ 4x RS232 Card w/RJ45 Connectors
+
+pci:v0000494Fd0000109B*
+ ID_MODEL_FROM_DATABASE=mPCIe-COM232-4 4x RS232 PCI Express Mini Card
pci:v0000494Fd000010A8*
- ID_MODEL_FROM_DATABASE=P104-COM232-8
+ ID_MODEL_FROM_DATABASE=P104-COM232-8 8x RS232 PC-104+ Board
+
+pci:v0000494Fd000010A9*
+ ID_MODEL_FROM_DATABASE=PCIe-COM232-8 8x RS232 Card
pci:v0000494Fd000010C9*
- ID_MODEL_FROM_DATABASE=PCI-COM-1S
+ ID_MODEL_FROM_DATABASE=PCI-COM-1S 1x RS422/RS485 Card
pci:v0000494Fd000010D0*
- ID_MODEL_FROM_DATABASE=PCI-COM2S
+ ID_MODEL_FROM_DATABASE=PCI-COM2S 2x RS422/RS485 Card
+
+pci:v0000494Fd000010D1*
+ ID_MODEL_FROM_DATABASE=PCIe-COM-2SMRJ 2x RS232/RS422/RS485 Card w/RJ45 Connectors
+
+pci:v0000494Fd000010D2*
+ ID_MODEL_FROM_DATABASE=104I-COM-2SM 2x RS232/RS422/RS485 PCI/104 Board
+
+pci:v0000494Fd000010D3*
+ ID_MODEL_FROM_DATABASE=mPCIe-COM-2SM 2x RS232/RS422/RS485 PCI Express Mini Card
+
+pci:v0000494Fd000010D8*
+ ID_MODEL_FROM_DATABASE=PCI-COM-4SM 4x RS232/RS422/RS485 Card
+
+pci:v0000494Fd000010D9*
+ ID_MODEL_FROM_DATABASE=PCIe-COM-4SM 4x RS232/RS422/RS485 Card
+
+pci:v0000494Fd000010DA*
+ ID_MODEL_FROM_DATABASE=PCIe-COM-4SMRJ 4x RS232/RS422/RS485 Card w/RJ45 Connectors
+
+pci:v0000494Fd000010DB*
+ ID_MODEL_FROM_DATABASE=104I-COM-4SM 4x RS232/RS422/RS485 PCI/104 Board
+
+pci:v0000494Fd000010DC*
+ ID_MODEL_FROM_DATABASE=mPCIe-COM-4SM 4x RS232/RS422/RS485 PCI Express Mini Card
pci:v0000494Fd000010E8*
- ID_MODEL_FROM_DATABASE=PCI-COM-8SM
+ ID_MODEL_FROM_DATABASE=PCI-COM-8SM 8x RS232/RS422/RS485 Card
+
+pci:v0000494Fd000010E9*
+ ID_MODEL_FROM_DATABASE=PCIe-COM-8SM 8x RS232/RS422/RS485 Card
+
+pci:v0000494Fd000010EA*
+ ID_MODEL_FROM_DATABASE=104I-COM-8SM 8x RS232/RS422/RS485 PCI-104 Board
+
+pci:v0000494Fd00001108*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM485-1 1x Isolated RS485 PCI Express Mini Card
+
+pci:v0000494Fd00001110*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM422-2 2x Isolated RS422 PCI Express Mini Card
+
+pci:v0000494Fd00001111*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM485-2 2x Isolated RS485 PCI Express Mini Card
+
+pci:v0000494Fd00001118*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM422-4 4x Isolated RS422 PCI Express Mini Card
+
+pci:v0000494Fd00001119*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM485-4 4x Isolated RS485 PCI Express Mini Card
pci:v0000494Fd00001148*
- ID_MODEL_FROM_DATABASE=PCI-ICM-1S
+ ID_MODEL_FROM_DATABASE=PCI-ICM-1S 1x Isolated RS422/RS485 Card
pci:v0000494Fd00001150*
- ID_MODEL_FROM_DATABASE=PCI-ICM-2S
+ ID_MODEL_FROM_DATABASE=PCI-ICM-2S 2x Isolated RS422/RS485 Card
+
+pci:v0000494Fd00001152*
+ ID_MODEL_FROM_DATABASE=PCIe-ICM-2S 2x Isolated RS422/RS485 Card
pci:v0000494Fd00001158*
- ID_MODEL_FROM_DATABASE=PCI-ICM422/4
+ ID_MODEL_FROM_DATABASE=PCI-ICM422/4 4x Isolated RS422 Card
pci:v0000494Fd00001159*
- ID_MODEL_FROM_DATABASE=PCI-ICM485/4
+ ID_MODEL_FROM_DATABASE=PCI-ICM485/4 4x Isolated RS485 Card
+
+pci:v0000494Fd0000115A*
+ ID_MODEL_FROM_DATABASE=PCIe-ICM-4S 4x Isolated RS422/RS485 Card
+
+pci:v0000494Fd00001190*
+ ID_MODEL_FROM_DATABASE=PCIe-ICM232-2 2x Isolated RS232 Card
+
+pci:v0000494Fd00001191*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM232-2 2x Isolated RS232 PCI Express Mini Card
+
+pci:v0000494Fd00001198*
+ ID_MODEL_FROM_DATABASE=PCIe-ICM232-4 4x Isolated RS232 Card
+
+pci:v0000494Fd00001199*
+ ID_MODEL_FROM_DATABASE=mPCIe-ICM232-4 4x Isolated RS422 PCI Express Mini Card
+
+pci:v0000494Fd000011D0*
+ ID_MODEL_FROM_DATABASE=PCIe-ICM-2SM 2x Isolated RS232/RS422/RS485 Card
+
+pci:v0000494Fd000011D8*
+ ID_MODEL_FROM_DATABASE=PCIe-ICM-4SM 4x Isolated RS232/RS422/RS485 Card
pci:v0000494Fd00001250*
- ID_MODEL_FROM_DATABASE=PCI-WDG-2S
+ ID_MODEL_FROM_DATABASE=PCI-WDG-2S Watchdog and 2x Serial Card
pci:v0000494Fd000012D0*
ID_MODEL_FROM_DATABASE=PCI-WDG-IMPAC
+pci:v0000494Fd00002230*
+ ID_MODEL_FROM_DATABASE=PCI-QUAD-8 8x Quadrature Input Card
+
+pci:v0000494Fd00002231*
+ ID_MODEL_FROM_DATABASE=PCI-QUAD-4 4x Quadrature Input Card
+
pci:v0000494Fd000022C0*
- ID_MODEL_FROM_DATABASE=PCI-WDG-CSM
+ ID_MODEL_FROM_DATABASE=PCI-WDG-CSM Watchdog Card
+
+pci:v0000494Fd000025C0*
+ ID_MODEL_FROM_DATABASE=P104-WDG-E Watchdog PC/104+ Board
pci:v0000494Fd00002C50*
- ID_MODEL_FROM_DATABASE=PCI-DIO-96CT
+ ID_MODEL_FROM_DATABASE=PCI-DIO-96CT 96x Digital Input / Output Card
pci:v0000494Fd00002C58*
- ID_MODEL_FROM_DATABASE=PCI-DIO-96C3
+ ID_MODEL_FROM_DATABASE=PCI-DIO-96C3 96x Digital Input / Output Card w/3x 8254 Counter Card
+
+pci:v0000494Fd00002EE0*
+ ID_MODEL_FROM_DATABASE=PCIe-DIO24S-CTR12 24x Digital Input / Output Card w/4x 8254 Counter Card
+
+pci:v0000494Fd00002FC0*
+ ID_MODEL_FROM_DATABASE=P104-WDG-CSM Watchdog PC/104+ Board
+
+pci:v0000494Fd00002FC1*
+ ID_MODEL_FROM_DATABASE=P104-WDG-CSMA Advanced Watchdog PC/104+ Board
pci:v0000494Fd00005ED0*
ID_MODEL_FROM_DATABASE=PCI-DAC
pci:v0000494Fd00006C90*
- ID_MODEL_FROM_DATABASE=PCI-DA12-2
+ ID_MODEL_FROM_DATABASE=PCI-DA12-2 2x 12-bit Analog Output Card
pci:v0000494Fd00006C98*
- ID_MODEL_FROM_DATABASE=PCI-DA12-4
+ ID_MODEL_FROM_DATABASE=PCI-DA12-4 4x 12-bit Analog Output Card
pci:v0000494Fd00006CA0*
- ID_MODEL_FROM_DATABASE=PCI-DA12-6
+ ID_MODEL_FROM_DATABASE=PCI-DA12-6 6x 12-bit Analog Output Card
pci:v0000494Fd00006CA8*
- ID_MODEL_FROM_DATABASE=PCI-DA12-8
+ ID_MODEL_FROM_DATABASE=PCI-DA12-8 8x 12-bit Analog Output Card
pci:v0000494Fd00006CA9*
ID_MODEL_FROM_DATABASE=PCI-DA12-8V
pci:v0000494Fd00006CB0*
- ID_MODEL_FROM_DATABASE=PCI-DA12-16
+ ID_MODEL_FROM_DATABASE=PCI-DA12-16 16x 12-bit Analog Output Card
pci:v0000494Fd00006CB1*
ID_MODEL_FROM_DATABASE=PCI-DA12-16V
@@ -59415,22 +60150,22 @@ pci:v0000494Fd00008EF0*
ID_MODEL_FROM_DATABASE=P104-FAS16-16
pci:v0000494Fd0000ACA8*
- ID_MODEL_FROM_DATABASE=PCI-AI12-16
+ ID_MODEL_FROM_DATABASE=PCI-AI12-16 12-bit 100kHz Analog Input Card
pci:v0000494Fd0000ACA9*
- ID_MODEL_FROM_DATABASE=PCI-AI12-16A
+ ID_MODEL_FROM_DATABASE=PCI-AI12-16A 12-bit 100kHz Analog Input w/FIFO Card
pci:v0000494Fd0000ECA8*
- ID_MODEL_FROM_DATABASE=PCI-AIO12-16
-
-pci:v0000494Fd0000ECA9*
- ID_MODEL_FROM_DATABASE=PCI-A12-16
+ ID_MODEL_FROM_DATABASE=PCI-AIO12-16 12-bit 100kHz Analog Input w/2x Analog Output and FIFO Card
pci:v0000494Fd0000ECAA*
- ID_MODEL_FROM_DATABASE=PCI-A12-16A
+ ID_MODEL_FROM_DATABASE=PCI-A12-16A 12-bit 100kHz Analog Input w/2x Analog Output and FIFO Card
pci:v0000494Fd0000ECE8*
- ID_MODEL_FROM_DATABASE=PCI-A16-16
+ ID_MODEL_FROM_DATABASE=LPCI-A16-16A 16-bit 500kHz Analog Input low-profile Card
+
+pci:v0000494Fd0000ECE9*
+ ID_MODEL_FROM_DATABASE=LPCI-AIO16A 16-bit 500kHz Analog Input low-profile Card
pci:v00004978*
ID_VENDOR_FROM_DATABASE=Axil Computer Inc
@@ -64595,6 +65330,9 @@ pci:v00008086d00001510*
pci:v00008086d00001511*
ID_MODEL_FROM_DATABASE=82580 Gigabit SFP Connection
+pci:v00008086d00001513*
+ ID_MODEL_FROM_DATABASE=CV82524 Thunderbolt Controller [Light Ridge 4C 2010]
+
pci:v00008086d00001514*
ID_MODEL_FROM_DATABASE=Ethernet X520 10GbE Dual Port KX4 Mezz
@@ -64622,6 +65360,12 @@ pci:v00008086d00001517sv00001137sd0000006A*
pci:v00008086d00001518*
ID_MODEL_FROM_DATABASE=82576NS SerDes Gigabit Network Connection
+pci:v00008086d0000151A*
+ ID_MODEL_FROM_DATABASE=DSL2310 Thunderbolt Controller [Eagle Ridge 2C 2011]
+
+pci:v00008086d0000151B*
+ ID_MODEL_FROM_DATABASE=CVL2510 Thunderbolt Controller [Light Peak 2C 2010]
+
pci:v00008086d0000151C*
ID_MODEL_FROM_DATABASE=82599 10 Gigabit TN Network Connection
@@ -64688,6 +65432,9 @@ pci:v00008086d00001521sv00001093sd0000775B*
pci:v00008086d00001521sv000010A9sd0000802A*
ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (UV2-BaseIO dual-port GbE)
+pci:v00008086d00001521sv000015D9sd00000652*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Dual Port i350 GbE MicroLP [AOC-CGP-i2])
+
pci:v00008086d00001521sv000017AAsd00001074*
ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (ThinkServer I350-T4 AnyFabric)
@@ -64908,10 +65655,13 @@ pci:v00008086d0000153B*
ID_MODEL_FROM_DATABASE=Ethernet Connection I217-V
pci:v00008086d00001547*
- ID_MODEL_FROM_DATABASE=DSL3510 Thunderbolt Port [Cactus Ridge]
+ ID_MODEL_FROM_DATABASE=DSL3510 Thunderbolt Controller [Cactus Ridge 4C 2012]
+
+pci:v00008086d00001548*
+ ID_MODEL_FROM_DATABASE=DSL3310 Thunderbolt Controller [Cactus Ridge 2C 2012]
pci:v00008086d00001549*
- ID_MODEL_FROM_DATABASE=DSL3510 Thunderbolt Controller [Cactus Ridge]
+ ID_MODEL_FROM_DATABASE=DSL2210 Thunderbolt Controller [Port Ridge 1C 2011]
pci:v00008086d0000154A*
ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-4
@@ -64988,11 +65738,32 @@ pci:v00008086d00001563sv00008086sd00000001*
pci:v00008086d00001563sv00008086sd0000001A*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
+pci:v00008086d00001563sv00008086sd00000022*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
+
+pci:v00008086d00001566*
+ ID_MODEL_FROM_DATABASE=DSL4410 Thunderbolt NHI [Redwood Ridge 2C 2013]
+
+pci:v00008086d00001567*
+ ID_MODEL_FROM_DATABASE=DSL4410 Thunderbolt Bridge [Redwood Ridge 2C 2013]
+
+pci:v00008086d00001568*
+ ID_MODEL_FROM_DATABASE=DSL4510 Thunderbolt NHI [Redwood Ridge 4C 2013]
+
+pci:v00008086d00001569*
+ ID_MODEL_FROM_DATABASE=DSL4510 Thunderbolt Bridge [Redwood Ridge 4C 2013]
+
+pci:v00008086d0000156A*
+ ID_MODEL_FROM_DATABASE=DSL5320 Thunderbolt 2 NHI [Falcon Ridge 2C 2013]
+
+pci:v00008086d0000156B*
+ ID_MODEL_FROM_DATABASE=DSL5320 Thunderbolt 2 Bridge [Falcon Ridge 2C 2013]
+
pci:v00008086d0000156C*
- ID_MODEL_FROM_DATABASE=DSL5520 Thunderbolt [Falcon Ridge]
+ ID_MODEL_FROM_DATABASE=DSL5520 Thunderbolt 2 NHI [Falcon Ridge 4C 2013]
pci:v00008086d0000156D*
- ID_MODEL_FROM_DATABASE=DSL5520 Thunderbolt [Falcon Ridge]
+ ID_MODEL_FROM_DATABASE=DSL5520 Thunderbolt 2 Bridge [Falcon Ridge 4C 2013]
pci:v00008086d0000156F*
ID_MODEL_FROM_DATABASE=Ethernet Connection I219-LM
@@ -65078,8 +65849,17 @@ pci:v00008086d00001572sv00008086sd00004005*
pci:v00008086d00001572sv00008086sd00004006*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+pci:v00008086d00001575*
+ ID_MODEL_FROM_DATABASE=DSL5110 Thunderbolt NHI [Falcon Ridge LP 2014]
+
+pci:v00008086d00001576*
+ ID_MODEL_FROM_DATABASE=DSL5110 Thunderbolt Bridge [Falcon Ridge LP 2014]
+
+pci:v00008086d00001577*
+ ID_MODEL_FROM_DATABASE=DSL6540 Thunderbolt 3 NHI [Alpine Ridge 4C 2015]
+
pci:v00008086d00001578*
- ID_MODEL_FROM_DATABASE=DSL6540 Thunderbolt [Alpine Ridge]
+ ID_MODEL_FROM_DATABASE=DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
pci:v00008086d0000157B*
ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
@@ -65087,6 +65867,12 @@ pci:v00008086d0000157B*
pci:v00008086d0000157C*
ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection
+pci:v00008086d0000157D*
+ ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 NHI [Alpine Ridge 2C 2015]
+
+pci:v00008086d0000157E*
+ ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 Bridge [Alpine Ridge 2C 2015]
+
pci:v00008086d00001580*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE backplane
@@ -65102,6 +65888,12 @@ pci:v00008086d00001581sv00001028sd00001F98*
pci:v00008086d00001581sv00001028sd00001F9E*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 10G 2P X710-k bNDC)
+pci:v00008086d00001581sv00001590sd00000000*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 2-port 563i Adapter)
+
+pci:v00008086d00001581sv00001590sd000000F8*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 2-port 563i Adapter)
+
pci:v00008086d00001581sv00008086sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet Converged Network Adapter XL710-Q2)
@@ -65121,10 +65913,10 @@ pci:v00008086d00001583sv0000108Esd00007B1B*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (10 Gb/40 Gb Ethernet Adapter)
pci:v00008086d00001583sv00001137sd00000000*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged NIC XL710-Q2)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged NIC XL710-QDA2)
pci:v00008086d00001583sv00001137sd0000013C*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged NIC XL710-Q2)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged NIC XL710-QDA2)
pci:v00008086d00001583sv00008086sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q2)
@@ -65195,6 +65987,12 @@ pci:v00008086d00001588sv0000103Csd000022FF*
pci:v00008086d00001589*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T
+pci:v00008086d00001589sv0000108Esd00000000*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Quad Port 10GBase-T Adapter)
+
+pci:v00008086d00001589sv0000108Esd00007B1C*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Quad Port 10GBase-T Adapter)
+
pci:v00008086d00001589sv00008086sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T)
@@ -65255,15 +66053,24 @@ pci:v00008086d000015B8*
pci:v00008086d000015B9*
ID_MODEL_FROM_DATABASE=Ethernet Connection (3) I219-LM
+pci:v00008086d000015D0*
+ ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2
+
pci:v00008086d000015D1*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T
pci:v00008086d000015D1sv00008086sd00000002*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
+pci:v00008086d000015D1sv00008086sd00000021*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
+
pci:v00008086d000015D1sv00008086sd000000A2*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
+pci:v00008086d000015D5*
+ ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-25GbE-DA2
+
pci:v00008086d000015D6*
ID_MODEL_FROM_DATABASE=Ethernet Connection (5) I219-V
@@ -65295,7 +66102,7 @@ pci:v00008086d00001605*
ID_MODEL_FROM_DATABASE=Broadwell-U PCI Express x8 Controller
pci:v00008086d00001606*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics
pci:v00008086d00001607*
ID_MODEL_FROM_DATABASE=Broadwell-U CHAPS Device
@@ -65328,16 +66135,16 @@ pci:v00008086d00001610*
ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge - DMI
pci:v00008086d00001612*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 5600
pci:v00008086d00001614*
ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge - DMI
pci:v00008086d00001616*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 5500
pci:v00008086d00001616sv0000103Csd00002216*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics (ZBook 15u G2 Mobile Workstation)
+ ID_MODEL_FROM_DATABASE=HD Graphics 5500 (ZBook 15u G2 Mobile Workstation)
pci:v00008086d00001618*
ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge - DMI
@@ -65352,19 +66159,19 @@ pci:v00008086d0000161D*
ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
pci:v00008086d0000161E*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 5300
pci:v00008086d00001622*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Iris Pro Graphics 6200
pci:v00008086d00001626*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 6000
pci:v00008086d0000162A*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Iris Pro Graphics P6300
pci:v00008086d0000162B*
- ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Iris Graphics 6100
pci:v00008086d0000162D*
ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
@@ -65396,6 +66203,9 @@ pci:v00008086d00001900*
pci:v00008086d00001901*
ID_MODEL_FROM_DATABASE=Skylake PCIe Controller (x16)
+pci:v00008086d00001902*
+ ID_MODEL_FROM_DATABASE=HD Graphics 510
+
pci:v00008086d00001903*
ID_MODEL_FROM_DATABASE=Skylake Processor Thermal Subsystem
@@ -65405,6 +66215,9 @@ pci:v00008086d00001904*
pci:v00008086d00001905*
ID_MODEL_FROM_DATABASE=Skylake PCIe Controller (x8)
+pci:v00008086d00001906*
+ ID_MODEL_FROM_DATABASE=HD Graphics 510
+
pci:v00008086d00001908*
ID_MODEL_FROM_DATABASE=Skylake Host Bridge/DRAM Registers
@@ -65424,10 +66237,10 @@ pci:v00008086d00001911*
ID_MODEL_FROM_DATABASE=Skylake Gaussian Mixture Model
pci:v00008086d00001912*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 530
pci:v00008086d00001916*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 520
pci:v00008086d00001918*
ID_MODEL_FROM_DATABASE=Skylake Host Bridge/DRAM Registers
@@ -65436,22 +66249,43 @@ pci:v00008086d00001919*
ID_MODEL_FROM_DATABASE=Skylake Imaging Unit
pci:v00008086d0000191B*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 530
+
+pci:v00008086d0000191D*
+ ID_MODEL_FROM_DATABASE=HD Graphics P530
pci:v00008086d0000191E*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=HD Graphics 515
pci:v00008086d0000191F*
ID_MODEL_FROM_DATABASE=Skylake Host Bridge/DRAM Registers
+pci:v00008086d00001921*
+ ID_MODEL_FROM_DATABASE=HD Graphics 520
+
pci:v00008086d00001926*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Iris Graphics 540
+
+pci:v00008086d00001927*
+ ID_MODEL_FROM_DATABASE=Iris Graphics 550
+
+pci:v00008086d0000192B*
+ ID_MODEL_FROM_DATABASE=Iris Graphics 555
+
+pci:v00008086d0000192D*
+ ID_MODEL_FROM_DATABASE=Iris Graphics P555
pci:v00008086d00001932*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Iris Pro Graphics 580
+
+pci:v00008086d0000193A*
+ ID_MODEL_FROM_DATABASE=Iris Pro Graphics P580
pci:v00008086d0000193B*
- ID_MODEL_FROM_DATABASE=Skylake Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Iris Pro Graphics 580
+
+pci:v00008086d0000193D*
+ ID_MODEL_FROM_DATABASE=Iris Pro Graphics P580
pci:v00008086d00001960*
ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor
@@ -66284,6 +67118,9 @@ pci:v00008086d00001E1Esv00001849sd00001E1E*
pci:v00008086d00001E20*
ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller
+pci:v00008086d00001E20sv00001028sd0000054B*
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (Dell XPS One 2710)
+
pci:v00008086d00001E20sv00001043sd0000108D*
ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (VivoBook X202EV)
@@ -66818,6 +67655,99 @@ pci:v00008086d0000225D*
pci:v00008086d0000225E*
ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 31S1
+pci:v00008086d00002280*
+ ID_MODEL_FROM_DATABASE=Braswell SoC Transaction Router
+
+pci:v00008086d00002284*
+ ID_MODEL_FROM_DATABASE=Braswell HD Audio Controller
+
+pci:v00008086d00002286*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O DMA
+
+pci:v00008086d0000228A*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O HSUART Port 1
+
+pci:v00008086d0000228C*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O HSUART Port 2
+
+pci:v00008086d00002292*
+ ID_MODEL_FROM_DATABASE=Braswell Platform Controller Unit SMBus
+
+pci:v00008086d00002294*
+ ID_MODEL_FROM_DATABASE=Braswell Storage Cluster Control MMC Port
+
+pci:v00008086d00002295*
+ ID_MODEL_FROM_DATABASE=Braswell Storage Cluster Control SDIO Port
+
+pci:v00008086d00002296*
+ ID_MODEL_FROM_DATABASE=Braswell Storage Cluster Control SD Port
+
+pci:v00008086d00002298*
+ ID_MODEL_FROM_DATABASE=Braswell Trusted Execution Engine Interface
+
+pci:v00008086d0000229C*
+ ID_MODEL_FROM_DATABASE=Braswell Platform Controller Unit LPC
+
+pci:v00008086d000022A3*
+ ID_MODEL_FROM_DATABASE=Braswell SATA Controller
+
+pci:v00008086d000022A4*
+ ID_MODEL_FROM_DATABASE=Braswell SATA AHCI Controller
+
+pci:v00008086d000022A8*
+ ID_MODEL_FROM_DATABASE=Braswell Low Power Engine Audio
+
+pci:v00008086d000022B0*
+ ID_MODEL_FROM_DATABASE=Braswell PCI Configuration Registers
+
+pci:v00008086d000022B1*
+ ID_MODEL_FROM_DATABASE=Braswell Integrated Graphics Controller
+
+pci:v00008086d000022B5*
+ ID_MODEL_FROM_DATABASE=Braswell USB xHCI Host Controller
+
+pci:v00008086d000022B8*
+ ID_MODEL_FROM_DATABASE=Braswell ISP Camera
+
+pci:v00008086d000022C0*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O DMA
+
+pci:v00008086d000022C1*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 1
+
+pci:v00008086d000022C2*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 2
+
+pci:v00008086d000022C3*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 3
+
+pci:v00008086d000022C4*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 4
+
+pci:v00008086d000022C5*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 5
+
+pci:v00008086d000022C6*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 6
+
+pci:v00008086d000022C7*
+ ID_MODEL_FROM_DATABASE=Braswell Serial I/O I2C Port 7
+
+pci:v00008086d000022C8*
+ ID_MODEL_FROM_DATABASE=Braswell PCIe Port 1
+
+pci:v00008086d000022CA*
+ ID_MODEL_FROM_DATABASE=Braswell PCIe Port 2
+
+pci:v00008086d000022CC*
+ ID_MODEL_FROM_DATABASE=Braswell PCIe Port 3
+
+pci:v00008086d000022CE*
+ ID_MODEL_FROM_DATABASE=Braswell PCIe Port 4
+
+pci:v00008086d000022DC*
+ ID_MODEL_FROM_DATABASE=Braswell P-Unit Power Management
+
pci:v00008086d00002310*
ID_MODEL_FROM_DATABASE=DH89xxCC LPC Controller
@@ -68814,10 +69744,19 @@ pci:v00008086d000024F0*
ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete]
pci:v00008086d000024F0sv000010A9sd0000802E*
- ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-path HFI 100 Series, 1-port)
+ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-path HFI 100 Series, 1-port A-board)
pci:v00008086d000024F0sv000010A9sd0000802F*
- ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-path HFI 100 Series, 2-port)
+ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-path HFI 100 Series, 2-port A-board)
+
+pci:v00008086d000024F0sv000010A9sd00008030*
+ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-path HFI 100 Series, 1-port B-board)
+
+pci:v00008086d000024F0sv000010A9sd00008031*
+ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-path HFI 100 Series, 2-port B-board)
+
+pci:v00008086d000024F0sv000015D9sd00000934*
+ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16, SIOM Module)
pci:v00008086d000024F0sv00008086sd00002628*
ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16)
@@ -69123,7 +70062,7 @@ pci:v00008086d00002590*
ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
pci:v00008086d00002590sv00001014sd00000575*
- ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (ThinkPad Z60t)
+ 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)
@@ -69158,6 +70097,9 @@ pci:v00008086d00002591sv0000103Csd00000934*
pci:v00008086d00002592*
ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller
+pci:v00008086d00002592sv00001014sd00000582*
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (ThinkPad X41)
+
pci:v00008086d00002592sv0000103Csd0000099C*
ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (NX6110/NC6120)
@@ -69674,6 +70616,9 @@ pci:v00008086d00002640sv0000E4BFsd000058B1*
pci:v00008086d00002641*
ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge
+pci:v00008086d00002641sv00001014sd00000568*
+ ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (ThinkPad X41)
+
pci:v00008086d00002641sv0000103Csd00000934*
ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (Compaq nw8240/nx8220)
@@ -69719,9 +70664,15 @@ pci:v00008086d00002652sv00001462sd00007028*
pci:v00008086d00002653*
ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) SATA Controller
+pci:v00008086d00002653sv00001014sd0000056A*
+ ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) SATA Controller (ThinkPad X41)
+
pci:v00008086d00002658*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
+pci:v00008086d00002658sv00001014sd00000565*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (ThinkPad X41)
+
pci:v00008086d00002658sv00001028sd00000177*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Dimension 8400)
@@ -69758,6 +70709,9 @@ pci:v00008086d00002658sv0000E4BFsd000058B1*
pci:v00008086d00002659*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
+pci:v00008086d00002659sv00001014sd00000565*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (ThinkPad X41)
+
pci:v00008086d00002659sv00001028sd00000177*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Dimension 8400)
@@ -69794,6 +70748,9 @@ pci:v00008086d00002659sv0000E4BFsd000058B1*
pci:v00008086d0000265A*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
+pci:v00008086d0000265Asv00001014sd00000565*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (ThinkPad X41)
+
pci:v00008086d0000265Asv00001028sd00000177*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Dimension 8400)
@@ -69830,6 +70787,9 @@ pci:v00008086d0000265Asv0000E4BFsd000058B1*
pci:v00008086d0000265B*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
+pci:v00008086d0000265Bsv00001014sd00000565*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (ThinkPad X41)
+
pci:v00008086d0000265Bsv00001028sd00000177*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (Dimension 8400)
@@ -69863,6 +70823,9 @@ pci:v00008086d0000265Bsv0000E4BFsd000058B1*
pci:v00008086d0000265C*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
+pci:v00008086d0000265Csv00001014sd00000566*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (ThinkPad X41)
+
pci:v00008086d0000265Csv00001028sd00000177*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Dimension 8400)
@@ -69980,6 +70943,9 @@ pci:v00008086d00002668sv00001AF4sd00001100*
pci:v00008086d0000266A*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
+pci:v00008086d0000266Asv00001014sd0000056B*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (ThinkPad X41)
+
pci:v00008086d0000266Asv00001028sd00000177*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (Dimension 8400)
@@ -70025,6 +70991,9 @@ pci:v00008086d0000266Dsv0000103Csd0000099C*
pci:v00008086d0000266E*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
+pci:v00008086d0000266Esv00001014sd00000581*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (ThinkPad X41 (Analog Devices AD1981B codec))
+
pci:v00008086d0000266Esv00001025sd0000006A*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Realtek ALC 655 codec (in Acer TravelMate 2410 serie laptop))
@@ -70373,6 +71342,9 @@ pci:v00008086d00002782sv00001734sd0000105B*
pci:v00008086d00002792*
ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller
+pci:v00008086d00002792sv00001014sd00000582*
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (ThinkPad X41)
+
pci:v00008086d00002792sv0000103Csd0000099C*
ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (NX6110/NC6120)
@@ -75086,6 +76058,30 @@ pci:v00008086d0000372C*
pci:v00008086d0000373F*
ID_MODEL_FROM_DATABASE=Xeon C5500/C3500 IOxAPIC
+pci:v00008086d000037CD*
+ ID_MODEL_FROM_DATABASE=X722 Virtual Function
+
+pci:v00008086d000037CE*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE backplane
+
+pci:v00008086d000037CF*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+
+
+pci:v00008086d000037D0*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
+pci:v00008086d000037D1*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE
+
+pci:v00008086d000037D2*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
+
+pci:v00008086d000037D3*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
+pci:v00008086d000037D4*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+
+
pci:v00008086d00003A00*
ID_MODEL_FROM_DATABASE=82801JD/DO (ICH10 Family) 4-port SATA IDE Controller
@@ -75890,6 +76886,9 @@ pci:v00008086d00003B56sv00001028sd0000040A*
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)
+
pci:v00008086d00003B56sv0000144Dsd0000C06A*
ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (R730 Laptop)
@@ -78407,6 +79406,9 @@ pci:v00008086d00009C24*
pci:v00008086d00009C26*
ID_MODEL_FROM_DATABASE=8 Series USB EHCI #1
+pci:v00008086d00009C26sv000017AAsd0000220C*
+ ID_MODEL_FROM_DATABASE=8 Series USB EHCI #1 (T440s)
+
pci:v00008086d00009C26sv000017AAsd00002214*
ID_MODEL_FROM_DATABASE=8 Series USB EHCI #1 (ThinkPad X240)
@@ -79233,7 +80235,10 @@ pci:v00008686*
ID_VENDOR_FROM_DATABASE=ScaleMP
pci:v00008686d00001010*
- ID_MODEL_FROM_DATABASE=vSMPowered system controller [vSMP CTL]
+ ID_MODEL_FROM_DATABASE=vSMP Foundation controller [vSMP CTL]
+
+pci:v00008686d00001011*
+ ID_MODEL_FROM_DATABASE=vSMP Foundation MEX/FLX controller [vSMP CTL]
pci:v00008800*
ID_VENDOR_FROM_DATABASE=Trigem Computer Inc.
@@ -80708,6 +81713,21 @@ pci:v0000BDBDd0000A138*
pci:v0000BDBDd0000A139*
ID_MODEL_FROM_DATABASE=Intensity Pro 4K
+pci:v0000BDBDd0000A13B*
+ ID_MODEL_FROM_DATABASE=DeckLink Micro Recorder
+
+pci:v0000BDBDd0000A13D*
+ ID_MODEL_FROM_DATABASE=DeckLink 4K Pro
+
+pci:v0000BDBDd0000A13E*
+ ID_MODEL_FROM_DATABASE=UltraStudio 4K Extreme
+
+pci:v0000BDBDd0000A13F*
+ ID_MODEL_FROM_DATABASE=DeckLink Quad 2
+
+pci:v0000BDBDd0000A140*
+ ID_MODEL_FROM_DATABASE=DeckLink Duo 2
+
pci:v0000C001*
ID_VENDOR_FROM_DATABASE=TSI Telsys
diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb
index 46b7ed9ab4..cef2ade2e9 100644
--- a/hwdb/20-usb-vendor-model.hwdb
+++ b/hwdb/20-usb-vendor-model.hwdb
@@ -41937,7 +41937,7 @@ usb:v1050*
ID_VENDOR_FROM_DATABASE=Yubico.com
usb:v1050p0010*
- ID_MODEL_FROM_DATABASE=Yubikey
+ ID_MODEL_FROM_DATABASE=Yubikey (v1 or v2)
usb:v1050p0110*
ID_MODEL_FROM_DATABASE=Yubikey NEO(-N) OTP
@@ -41964,11 +41964,35 @@ usb:v1050p0120*
ID_MODEL_FROM_DATABASE=Yubikey Touch U2F Security Key
usb:v1050p0200*
- ID_MODEL_FROM_DATABASE=U2F Gnubby
+ ID_MODEL_FROM_DATABASE=Gnubby U2F
usb:v1050p0211*
ID_MODEL_FROM_DATABASE=Gnubby
+usb:v1050p0401*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 OTP
+
+usb:v1050p0402*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 U2F
+
+usb:v1050p0403*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 OTP+U2F
+
+usb:v1050p0404*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 CCID
+
+usb:v1050p0405*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 OTP+CCID
+
+usb:v1050p0406*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 U2F+CCID
+
+usb:v1050p0407*
+ ID_MODEL_FROM_DATABASE=Yubikey 4 OTP+U2F+CCID
+
+usb:v1050p0410*
+ ID_MODEL_FROM_DATABASE=Yubikey plus OTP+U2F
+
usb:v1053*
ID_VENDOR_FROM_DATABASE=Immanuel Electronics Co., Ltd
diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb
index d060d81f61..90acb44a1c 100644
--- a/hwdb/60-evdev.hwdb
+++ b/hwdb/60-evdev.hwdb
@@ -98,6 +98,12 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:bvn*:bvr*:bd*:svnASUSTeKComputerInc.:pnK
EVDEV_ABS_35=::18
EVDEV_ABS_36=::16
+evdev:name:ETPS/2 Elantech Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnX550CC:*
+ EVDEV_ABS_00=::31
+ EVDEV_ABS_01=::30
+ EVDEV_ABS_35=::31
+ EVDEV_ABS_36=::30
+
#########################################
# Dell
#########################################
@@ -121,6 +127,13 @@ evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLati
EVDEV_ABS_35=76:1815:22
EVDEV_ABS_36=131:1330:30
+# Dell XPS15 9550
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPS159550*
+ EVDEV_ABS_00=::41
+ EVDEV_ABS_01=::43
+ EVDEV_ABS_35=::41
+ EVDEV_ABS_36=::43
+
#########################################
# Google
#########################################
@@ -147,10 +160,26 @@ evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondm4*
# Lenovo
#########################################
-# Lenovo X230 series
-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*X230*
- EVDEV_ABS_01=::100
- EVDEV_ABS_36=::100
+# Lenovo E530
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:pn*ThinkPadEdgeE530*
+ EVDEV_ABS_00=1241:5703:49
+ EVDEV_ABS_01=1105:4820:68
+ EVDEV_ABS_35=1241:5703:49
+ EVDEV_ABS_36=1105:4820:68
+
+# Lenovo P50
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*P50*
+ EVDEV_ABS_00=::44
+ EVDEV_ABS_01=::67
+ EVDEV_ABS_35=::44
+ EVDEV_ABS_36=::67
+
+# Lenovo T460
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460*
+ EVDEV_ABS_00=1266:5677:44
+ EVDEV_ABS_01=1093:4832:65
+ EVDEV_ABS_35=1266:5677:44
+ EVDEV_ABS_36=1093:4832:65
# Lenovo T510
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T510*
@@ -159,6 +188,11 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T510*
EVDEV_ABS_35=778:6239:72
EVDEV_ABS_36=841:5330:100
+# Lenovo X230 series
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*X230*
+ EVDEV_ABS_01=::100
+ EVDEV_ABS_36=::100
+
#########################################
# Samsung
#########################################
diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb
index 01213b6069..fd49b03493 100644
--- a/hwdb/60-keyboard.hwdb
+++ b/hwdb/60-keyboard.hwdb
@@ -378,6 +378,7 @@ evdev:input:b0003v0458p0708*
###########################################################
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*:pvr*
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*:pvr*
KEYBOARD_KEY_81=fn_esc
KEYBOARD_KEY_89=battery # Fn+F8
KEYBOARD_KEY_8a=screenlock # Fn+F6
@@ -488,22 +489,29 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnFalco:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:pvr*
# HP ProBook 440 G2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP440G2:pvr*
-# HP ProBook 445 G1
-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPProBook445G1NotebookPC:pvr*
-# HP ProBook 450 G0
-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPProBook450G0:pvr*
+# several HP ProBooks 4xx
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook4*:pvr*
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHP*ProBook*4*:pvr*
+# HP ZBook
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:pvr*
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute
+# HP Folio 1040g2
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:pvr*
+ KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute
+ KEYBOARD_KEY_d8=!f23 # touchpad off
+ KEYBOARD_KEY_d9=!f22 # touchpad on
+
# HP ProBook 6555b
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard:pnHPProBook6555b:*
KEYBOARD_KEY_b2=www # Earth
# HP ProBook 440 G3
evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*440*G3*
- KEYBOARD_KEY_92=brightnessdown
- KEYBOARD_KEY_97=brightnessup
- KEYBOARD_KEY_ee=switchvideomode
- KEYBOARD_KEY_81=f20 # micmute
+# HP ProBook 640 G2
+evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*640*G2*
+ KEYBOARD_KEY_85=unknown # lid close; also reported via special evdev
+ KEYBOARD_KEY_f8=unknown # rf kill; also reported via special evdev
###########################################################
# IBM
diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb
index 54ace7cbc1..a5b39dc41e 100644
--- a/hwdb/70-mouse.hwdb
+++ b/hwdb/70-mouse.hwdb
@@ -132,6 +132,14 @@ mouse:usb:v046dpc063:name:DELL DELL USB Laser Mouse:
MOUSE_DPI=1000@125
##########################################
+# Dynex
+#########################################
+
+# Dynex Wired Optical Mouse (DX-WMSE2)
+mouse:usb:v0461p4d46:name:USB Optical Mouse:
+ MOUSE_DPI=1000@125
+
+##########################################
# Fujitsu Siemens
##########################################
@@ -420,6 +428,14 @@ mouse:usb:v22d4p1308:name:Laview Technology Mionix Avior 7000:
MOUSE_WHEEL_CLICK_ANGLE=15
##########################################
+# MODECOM
+##########################################
+
+# MODECOM MC-WM4 Wireless Optical Mouse
+mouse:usb:v0e8fp00a7:name:DaKai 2.4G RX:
+ MOUSE_DPI=*800@126 1600@126
+
+##########################################
# Oklick
##########################################
@@ -443,3 +459,27 @@ mouse:usb:v1532p0042:name:Razer Razer Abyssus:
mouse:usb:v1e7dp2c2e:name:ROCCAT ROCCAT Lua:
MOUSE_DPI=250@125 500@125 1000@125 1250@125 1500@125 1750@125 2000@125 250@250 500@250 1000@250 1250@250 1500@250 1750@250 2000@250 250@500 500@500 1000@500 1250@500 1500@500 1750@500 2000@500 250@1000 500@1000 *1000@1000 1250@1000 1500@1000 1750@1000 2000@1000
MOUSE_WHEEL_CLICK_ANGLE=15
+
+##########################################
+# Sharkoon
+##########################################
+
+# Sharkoon Shark Force Gaming Mouse
+mouse:usb:v093ap2521:name:USB OPTICAL MOUSE:
+ MOUSE_DPI=*1000@125 1600@125 600@125
+
+##########################################
+# SteelSeries
+##########################################
+
+# SteelSeries Sensei Raw
+mouse:usb:v1038p1369:name:SteelSeries Sensei Raw Gaming Mouse:
+ MOUSE_DPI=1000@1022
+
+##########################################
+# Trust
+##########################################
+
+# Trust illuminated mouse gxt 152
+mouse:usb:v145fp01ac:name:HID-compliant Mouse Trust Gaming Mouse:
+ MOUSE_DPI=*800@528 1200@537 1600@536 2400@521
diff --git a/man/bootchart.conf.xml b/man/bootchart.conf.xml
deleted file mode 100644
index f6ac7e6ae2..0000000000
--- a/man/bootchart.conf.xml
+++ /dev/null
@@ -1,172 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- This file is part of systemd.
-
- Copyright 2012 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.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/>.
--->
-
-<refentry id="bootchart.conf" conditional='ENABLE_BOOTCHART'
- xmlns:xi="http://www.w3.org/2001/XInclude">
- <refentryinfo>
- <title>bootchart.conf</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Auke</firstname>
- <surname>Kok</surname>
- <email>auke-jan.h.kok@intel.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>bootchart.conf</refentrytitle>
- <manvolnum>5</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>bootchart.conf</refname>
- <refname>bootchart.conf.d</refname>
- <refpurpose>Boot performance analysis graphing tool configuration files</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <para><filename>/etc/systemd/bootchart.conf</filename></para>
- <para><filename>/etc/systemd/bootchart.conf.d/*.conf</filename></para>
- <para><filename>/run/systemd/bootchart.conf.d/*.conf</filename></para>
- <para><filename>/usr/lib/systemd/bootchart.conf.d/*.conf</filename></para>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para>When starting, systemd-bootchart will read the configuration
- file <filename>/etc/systemd/bootchart.conf</filename>, followed by
- the files in the <filename>bootchart.conf.d</filename>
- directories. These configuration files determine logging
- parameters and graph output.</para>
- </refsect1>
-
- <xi:include href="standard-conf.xml" xpointer="main-conf" />
-
- <refsect1>
- <title>Options</title>
-
- <variablelist class='bootchart-directives'>
-
- <varlistentry>
- <term><varname>Samples=500</varname></term>
- <listitem><para>Configure the amount of samples to record in
- total before bootchart exits. Each sample will record at
- intervals defined by Frequency=.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>Frequency=25</varname></term>
- <listitem><para>Configure the sample log frequency. This can
- be a fractional number, but must be larger than 0.0. Most
- systems can cope with values under 25–50 without impacting
- boot time severely.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>Relative=no</varname></term>
- <listitem><para>Configures whether the left axis of the output
- graph equals time=0.0 (<constant>CLOCK_MONOTONIC</constant>
- start). This is useful for using bootchart at post-boot time
- to profile an already booted system, otherwise the graph would
- become extremely large. If set to yes, the horizontal axis
- starts at the first recorded sample instead of time=0.0.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>Filter=no</varname></term>
- <listitem><para>Configures whether the resulting graph should
- omit tasks that did not contribute significantly to the boot.
- Processes that are too short-lived (only seen in one sample)
- or that do not consume any significant CPU time (less than
- 0.001sec) will not be displayed in the output
- graph.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>Output=[path]</varname></term>
- <listitem><para>Configures the output directory for writing
- the graphs. By default, bootchart writes the graphs to
- <filename>/run/log</filename>.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>Init=[path]</varname></term>
- <listitem><para>Configures bootchart to run a non-standard
- binary instead of
- <filename>/usr/lib/systemd/systemd</filename>. This option is
- only relevant if bootchart was invoked from the kernel command
- line with
- init=/usr/lib/systemd/systemd-bootchart.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>PlotMemoryUsage=no</varname></term>
- <listitem><para>If set to yes, enables logging and graphing of
- processes' PSS memory consumption.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>PlotEntropyGraph=no</varname></term>
- <listitem><para>If set to yes, enables logging and graphing of
- the kernel random entropy pool size.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>ScaleX=100</varname></term>
- <listitem><para>Horizontal scaling factor for all variable
- graph components.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>ScaleY=20</varname></term>
- <listitem><para>Vertical scaling factor for all variable graph
- components.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>ControlGroup=no</varname></term>
- <listitem><para>Display process control group.
- </para></listitem>
- </varlistentry>
-
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>systemd-bootchart</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- </para>
- </refsect1>
-
-</refentry>
diff --git a/man/bootup.xml b/man/bootup.xml
index b92057af29..986996398c 100644
--- a/man/bootup.xml
+++ b/man/bootup.xml
@@ -179,6 +179,8 @@
identical to the system manager bootup (see above) until it
reaches <filename>basic.target</filename>. From there, systemd
approaches the special target <filename>initrd.target</filename>.
+ When the root device becomes available,
+ <filename>initd-root-device.target</filename> is reached.
If the root device can be mounted at
<filename>/sysroot</filename>, the
<filename>sysroot.mount</filename> unit becomes active and
@@ -204,7 +206,10 @@
| emergency.service
______________________/| |
/ | v
- | sysroot.mount <emphasis>emergency.target</emphasis>
+ | initrd-root-device.target <emphasis>emergency.target</emphasis>
+ | |
+ | v
+ | sysroot.mount
| |
| v
| initrd-root-fs.target
diff --git a/man/busctl.xml b/man/busctl.xml
index 26d778d4dd..b71a174634 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -473,7 +473,6 @@ o "/org/freedesktop/systemd1/job/42684"</programlisting>
<ulink url="http://freedesktop.org/wiki/Software/dbus">D-Bus</ulink>,
<citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-bus-proxyd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>wireshark</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml
index a0a497b467..4f95680a3a 100644
--- a/man/coredump.conf.xml
+++ b/man/coredump.conf.xml
@@ -45,7 +45,7 @@
<refnamediv>
<refname>coredump.conf</refname>
<refname>coredump.conf.d</refname>
- <refpurpose>Coredump storage configuration files</refpurpose>
+ <refpurpose>Core dump storage configuration files</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -60,7 +60,14 @@
<para>These files configure the behavior of
<citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- a handler for core dumps invoked by the kernel.</para>
+ a handler for core dumps invoked by the kernel. Whether <command>systemd-coredump</command> is used
+ is determined by the kernel's
+ <varname>kernel.core_pattern</varname> <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ setting. See
+ <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ and
+ <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ pages for the details.</para>
</refsect1>
<xi:include href="standard-conf.xml" xpointer="main-conf" />
@@ -79,7 +86,7 @@
<listitem><para>Controls where to store cores. One of
<literal>none</literal>, <literal>external</literal>,
<literal>journal</literal>, and <literal>both</literal>. When
- <literal>none</literal>, the coredumps will be logged but not
+ <literal>none</literal>, the core dumps will be logged but not
stored permanently. When <literal>external</literal> (the
default), cores will be stored in <filename>/var/lib/systemd/coredump</filename>.
When <literal>journal</literal>, cores will be stored in
@@ -107,7 +114,7 @@
<term><varname>ProcessSizeMax=</varname></term>
<listitem><para>The maximum size in bytes of a core
- which will be processed. Coredumps exceeding this size
+ which will be processed. Core dumps exceeding this size
will be logged, but the backtrace will not be generated
and the core will not be stored.</para></listitem>
</varlistentry>
@@ -125,14 +132,14 @@
<term><varname>KeepFree=</varname></term>
<listitem><para>Enforce limits on the disk space taken up by
- externally stored coredumps. <option>MaxUse=</option> makes
- sure that old coredumps are removed as soon as the total disk
- space taken up by coredumps grows beyond this limit (defaults
+ externally stored core dumps. <option>MaxUse=</option> makes
+ sure that old core dumps are removed as soon as the total disk
+ space taken up by core dumps grows beyond this limit (defaults
to 10% of the total disk size). <option>KeepFree=</option>
controls how much disk space to keep free at least (defaults
to 15% of the total disk size). Note that the disk space used
- by coredumps might temporarily exceed these limits while
- coredumps are processed. Note that old coredumps are also
+ by core dumps might temporarily exceed these limits while
+ core dumps are processed. Note that old core dumps are also
removed based on time via
<citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Set
either value to 0 to turn off size-based
diff --git a/man/coredumpctl.xml b/man/coredumpctl.xml
index 0f1afe77c3..abc245be5e 100644
--- a/man/coredumpctl.xml
+++ b/man/coredumpctl.xml
@@ -45,7 +45,7 @@
<refnamediv>
<refname>coredumpctl</refname>
- <refpurpose>Retrieve coredumps from the journal</refpurpose>
+ <refpurpose>Retrieve and process saved core dumps and metadata</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -60,9 +60,10 @@
<refsect1>
<title>Description</title>
- <para><command>coredumpctl</command> may be used to
- retrieve coredumps from
- <citerefentry><refentrytitle>systemd-journald</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ <para><command>coredumpctl</command> is a tool that can be used to retrieve and process core
+ dumps and metadata which were saved by
+ <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ </para>
</refsect1>
<refsect1>
@@ -71,18 +72,23 @@
<para>The following options are understood:</para>
<variablelist>
+
+ <xi:include href="standard-options.xml" xpointer="help" />
+ <xi:include href="standard-options.xml" xpointer="version" />
+
<varlistentry>
<term><option>--no-legend</option></term>
- <listitem><para>Do not print column headers.
- </para></listitem>
+ <listitem><para>Do not print column headers.</para></listitem>
</varlistentry>
+ <xi:include href="standard-options.xml" xpointer="no-pager" />
+
<varlistentry>
<term><option>-1</option></term>
- <listitem><para>Show information of a single coredump only,
- instead of listing all known coredumps. </para></listitem>
+ <listitem><para>Show information of a single core dump only, instead of listing
+ all known core dumps.</para></listitem>
</varlistentry>
<varlistentry>
@@ -90,7 +96,7 @@
<term><option>--field=</option><replaceable>FIELD</replaceable></term>
<listitem><para>Print all possible data values the specified
- field takes in matching coredump entries of the
+ field takes in matching core dump entries of the
journal.</para></listitem>
</varlistentry>
@@ -110,11 +116,11 @@
</para></listitem>
</varlistentry>
- <xi:include href="standard-options.xml" xpointer="help" />
- <xi:include href="standard-options.xml" xpointer="version" />
- <xi:include href="standard-options.xml" xpointer="no-pager" />
-
</variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Commands</title>
<para>The following commands are understood:</para>
@@ -122,23 +128,31 @@
<varlistentry>
<term><command>list</command></term>
- <listitem><para>List coredumps captured in the journal
+ <listitem><para>List core dumps captured in the journal
matching specified characteristics. If no command is
- specified, this is the implied default.</para></listitem>
+ specified, this is the implied default.</para>
+
+ <para>It's worth noting that different restrictions apply to
+ data saved in the journal and core dump files saved in
+ <filename>/var/lib/systemd/coredump</filename>, see overview in
+ <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ Thus it may very well happen that a particular core dump is still listed
+ in the journal while its corresponding core dump file has already been
+ removed.</para></listitem>
</varlistentry>
<varlistentry>
<term><command>info</command></term>
- <listitem><para>Show detailed information about coredumps
+ <listitem><para>Show detailed information about core dumps
captured in the journal.</para></listitem>
</varlistentry>
<varlistentry>
<term><command>dump</command></term>
- <listitem><para>Extract the last coredump matching specified
- characteristics. The coredump will be written on standard
+ <listitem><para>Extract the last core dump matching specified
+ characteristics. The core dump will be written on standard
output, unless an output file is specified with
<option>--output=</option>. </para></listitem>
</varlistentry>
@@ -146,7 +160,7 @@
<varlistentry>
<term><command>gdb</command></term>
- <listitem><para>Invoke the GNU debugger on the last coredump
+ <listitem><para>Invoke the GNU debugger on the last core dump
matching specified characteristics. </para></listitem>
</varlistentry>
@@ -197,7 +211,7 @@
<refsect1>
<title>Exit status</title>
<para>On success, 0 is returned; otherwise, a non-zero failure
- code is returned. Not finding any matching coredumps is treated as
+ code is returned. Not finding any matching core dumps is treated as
failure.
</para>
</refsect1>
@@ -206,13 +220,13 @@
<title>Examples</title>
<example>
- <title>List all the coredumps of a program named foo</title>
+ <title>List all the core dumps of a program named foo</title>
<programlisting># coredumpctl list foo</programlisting>
</example>
<example>
- <title>Invoke gdb on the last coredump</title>
+ <title>Invoke gdb on the last core dump</title>
<programlisting># coredumpctl gdb</programlisting>
</example>
@@ -225,7 +239,7 @@
</example>
<example>
- <title>Extract the last coredump of /usr/bin/bar to a file named
+ <title>Extract the last core dump of /usr/bin/bar to a file named
<filename noindex="true">bar.coredump</filename></title>
<programlisting># coredumpctl -o bar.coredump dump /usr/bin/bar</programlisting>
diff --git a/man/daemon.xml b/man/daemon.xml
index f74fd35fc5..a649749683 100644
--- a/man/daemon.xml
+++ b/man/daemon.xml
@@ -180,14 +180,12 @@
functionality of the init system, it is recommended not to
execute them when run as new-style service.</para>
- <para>Note that new-style init systems guarantee execution of
- daemon processes in a clean process context: it is guaranteed
- that the environment block is sanitized, that the signal
- handlers and mask is reset and that no left-over file
- descriptors are passed. Daemons will be executed in their own
- session, with standard input/output/error connected to
- <filename>/dev/null</filename> unless otherwise configured. The
- umask is reset.
+ <para>Note that new-style init systems guarantee execution of daemon processes in a clean process context: it is
+ guaranteed that the environment block is sanitized, that the signal handlers and mask is reset and that no
+ left-over file descriptors are passed. Daemons will be executed in their own session, with standard input
+ connected to <filename>/dev/null</filename> and standard output/error connected to the
+ <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ logging service, unless otherwise configured. The umask is reset.
</para>
<para>It is recommended for new-style daemons to implement the
@@ -234,7 +232,7 @@
bus-activatable by supplying a D-Bus service activation
configuration file. This has multiple advantages: your daemon
may be started lazily on-demand; it may be started in parallel
- to other daemons requiring it -- which maximizes
+ to other daemons requiring it — which maximizes
parallelization and boot-up speed; your daemon can be
restarted on failure without losing any bus requests, as the
bus queues requests for activatable services. See below for
diff --git a/man/halt.xml b/man/halt.xml
index a06dbd0097..e3fa60a915 100644
--- a/man/halt.xml
+++ b/man/halt.xml
@@ -133,6 +133,14 @@
</varlistentry>
<varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-sync</option></term>
+
+ <listitem><para>Don't sync hard disks/storage media before
+ halt, power-off, reboot.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--no-wall</option></term>
<listitem><para>Do not send wall message before halt,
diff --git a/man/journalctl.xml b/man/journalctl.xml
index b281f26b45..3efe6ef62a 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -272,6 +272,16 @@
<varlistentry>
<term>
+ <option>short-unix</option>
+ </term>
+ <listitem>
+ <para>is very similar, but shows seconds passed since January 1st 1970 UTC instead of wallclock
+ timestamps ("UNIX time"). The time is shown with microsecond accuracy.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>verbose</option>
</term>
<listitem>
@@ -350,6 +360,13 @@
</varlistentry>
<varlistentry>
+ <term><option>--no-hostname</option></term>
+
+ <listitem><para>Don't show the hostname field of log messages originating from the local host. This switch only
+ has an effect on the <option>short</option> family of output modes (see above).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-x</option></term>
<term><option>--catalog</option></term>
@@ -673,9 +690,9 @@
space they use falls below the specified size (specified with
the usual <literal>K</literal>, <literal>M</literal>,
<literal>G</literal> and <literal>T</literal> suffixes), or all
- journal files contain no data older than the specified
+ archived journal files contain no data older than the specified
timespan (specified with the usual <literal>s</literal>,
- <literal>min</literal>, <literal>h</literal>,
+ <literal>m</literal>, <literal>h</literal>,
<literal>days</literal>, <literal>months</literal>,
<literal>weeks</literal> and <literal>years</literal> suffixes),
or no more than the specified number of separate journal files
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index a9690e8138..3964cd6bc5 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -148,12 +148,12 @@
</varlistentry>
<varlistentry>
- <term><varname>RateLimitInterval=</varname></term>
+ <term><varname>RateLimitIntervalSec=</varname></term>
<term><varname>RateLimitBurst=</varname></term>
<listitem><para>Configures the rate limiting that is applied
to all messages generated on the system. If, in the time
- interval defined by <varname>RateLimitInterval=</varname>,
+ interval defined by <varname>RateLimitIntervalSec=</varname>,
more messages than specified in
<varname>RateLimitBurst=</varname> are logged by a service,
all further messages within the interval are dropped until the
@@ -162,7 +162,7 @@
per-service, so that two services which log do not interfere
with each other's limits. Defaults to 1000 messages in 30s.
The time specification for
- <varname>RateLimitInterval=</varname> may be specified in the
+ <varname>RateLimitIntervalSec=</varname> may be specified in the
following units: <literal>s</literal>, <literal>min</literal>,
<literal>h</literal>, <literal>ms</literal>,
<literal>us</literal>. To turn off any kind of rate limiting,
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index 42d5e006bb..9c04849f66 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -322,6 +322,15 @@
</varlistentry>
<varlistentry>
+ <term><varname>systemd.default_timeout_start_sec=</varname></term>
+
+ <listitem>
+ <para>Overwrites the default start job timeout <varname>DefaultTimeoutStartSec=</varname> at boot. For details,
+ see <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>modules-load=</varname></term>
<term><varname>rd.modules-load=</varname></term>
diff --git a/man/loginctl.xml b/man/loginctl.xml
index f41acc6a1b..fb51740503 100644
--- a/man/loginctl.xml
+++ b/man/loginctl.xml
@@ -94,6 +94,16 @@
</varlistentry>
<varlistentry>
+ <term><option>--value</option></term>
+
+ <listitem>
+ <para>When printing properties with <command>show</command>,
+ only print the value, and skip the property name and
+ <literal>=</literal>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-a</option></term>
<term><option>--all</option></term>
@@ -302,7 +312,10 @@
This allows users who are not logged in to run long-running
services. Takes one or more user names or numeric UIDs as
argument. If no argument is specified, enables/disables
- lingering for the user of the session of the caller.
+ lingering for the user of the session of the caller.</para>
+
+ <para>See also <varname>KillUserProcesses=</varname> setting in
+ <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para></listitem>
</varlistentry>
@@ -400,6 +413,37 @@
otherwise.</para>
</refsect1>
+ <refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Querying user status</title>
+
+ <programlisting>$ loginctl user-status
+fatima (1005)
+ Since: Sat 2016-04-09 14:23:31 EDT; 54min ago
+ State: active
+ Sessions: 5 *3
+ Unit: user-1005.slice
+ ├─user@1005.service
+ ...
+ ├─session-3.scope
+ ...
+ └─session-5.scope
+ ├─3473 login -- fatima
+ └─3515 -zsh
+
+Apr 09 14:40:30 laptop login[2325]: pam_unix(login:session):
+ session opened for user fatima by LOGIN(uid=0)
+Apr 09 14:40:30 laptop login[2325]: LOGIN ON tty3 BY fatima
+</programlisting>
+
+ <para>There are two sessions, 3 and 5. Session 3 is a graphical session,
+ marked with a star. The tree of processing including the two corresponding
+ scope units and the user manager unit are shown.</para>
+ </example>
+ </refsect1>
+
<xi:include href="less-variables.xml" />
<refsect1>
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 597759e33a..fe92277a1f 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -119,30 +119,46 @@
<varlistentry>
<term><varname>KillUserProcesses=</varname></term>
- <listitem><para>Takes a boolean argument. Configures whether
- the processes of a user should be killed when the user
- completely logs out (i.e. after the user's last session
- ended). Defaults to <literal>no</literal>.</para>
-
- <para>Note that setting <varname>KillUserProcesses=1</varname>
+ <listitem><para>Takes a boolean argument. Configures whether the processes of a
+ user should be killed when the user logs out. If true, the scope unit
+ corresponding to the session and all processes inside that scope will be
+ terminated. If false, the scope is "abandoned", see
+ <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ and processes are not killed. Defaults to <literal>yes</literal>,
+ but see the options <varname>KillOnlyUsers=</varname> and
+ <varname>KillExcludeUsers=</varname> below.</para>
+
+ <para>In addition to session processes, user process may run under the user
+ manager unit <filename>user@.service</filename>. Depending on the linger
+ settings, this may allow users to run processes independent of their login
+ sessions. See the description of <command>enable-linger</command> in
+ <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
+
+ <para>Note that setting <varname>KillUserProcesses=yes</varname>
will break tools like
- <citerefentry project='die-net'><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem>
+ <citerefentry project='die-net'><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ and
+ <citerefentry project='die-net'><refentrytitle>tmux</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ unless they are moved out of the session scope. See example in
+ <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><varname>KillOnlyUsers=</varname></term>
<term><varname>KillExcludeUsers=</varname></term>
- <listitem><para>These settings take space-separated lists of
- usernames that influence the effect of
- <varname>KillUserProcesses=</varname>. If not empty, only
- processes of users listed in <varname>KillOnlyUsers=</varname>
- will be killed when they log out entirely. Processes of users
- listed in <varname>KillExcludeUsers=</varname> are excluded
- from being killed. <varname>KillExcludeUsers=</varname>
- defaults to <literal>root</literal> and takes precedence over
- <varname>KillOnlyUsers=</varname>, which defaults to the empty
- list.</para></listitem>
+ <listitem><para>These settings take space-separated lists of usernames that override
+ the <varname>KillUserProcesses=</varname> setting. A user name may be added to
+ <varname>KillExcludeUsers=</varname> to exclude the processes in the session scopes of
+ that user from being killed even if <varname>KillUserProcesses=yes</varname> is set. If
+ <varname>KillExcludeUsers=</varname> is not set, the <literal>root</literal> user is
+ excluded by default. <varname>KillExcludeUsers=</varname> may be set to an empty value
+ to override this default. If a user is not excluded, <varname>KillOnlyUsers=</varname>
+ is checked next. If this setting is specified, only the session scopes of those users
+ will be killed. Otherwise, users are subject to the
+ <varname>KillUserProcesses=yes</varname> setting.</para></listitem>
</varlistentry>
<varlistentry>
@@ -281,6 +297,22 @@
</varlistentry>
<varlistentry>
+ <term><varname>InhibitorsMax=</varname></term>
+
+ <listitem><para>Controls the maximum number of concurrent inhibitors to permit. Defaults to 8192
+ (8K).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SessionsMax=</varname></term>
+
+ <listitem><para>Controls the maximum number of concurrent user sessions to manage. Defaults to 8192
+ (8K). Depending on how the <filename>pam_systemd.so</filename> module is included in the PAM stack
+ configuration, further login sessions will either be refused, or permitted but not tracked by
+ <filename>systemd-logind</filename>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>UserTasksMax=</varname></term>
<listitem><para>Sets the maximum number of OS tasks each user
diff --git a/man/machinectl.xml b/man/machinectl.xml
index 0e07c201bd..4b7f9a0391 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -133,7 +133,16 @@
<para>When listing VM or container images, do not suppress
images beginning in a dot character
- (<literal>.</literal>).</para></listitem>
+ (<literal>.</literal>).</para>
+
+ <para>When cleaning VM or container images, remove all images, not just hidden ones.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--value</option></term>
+
+ <listitem><para>When printing properties with <command>show</command>, only print the value,
+ and skip the property name and <literal>=</literal>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -186,16 +195,14 @@
</varlistentry>
<varlistentry>
- <term><option>--setenv=</option></term>
+ <term><option>-E <replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+ <term><option>--setenv=<replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
- <listitem><para>When used with the <command>shell</command>
- command, sets an environment variable to pass to the executed
- shell. Takes a pair of environment variable name and value,
- separated by <literal>=</literal> as argument. This switch
- may be used multiple times to set multiple environment
- variables. Note that this switch is not supported for the
- <command>login</command> command (see
- below).</para></listitem>
+ <listitem><para>When used with the <command>shell</command> command, sets an environment
+ variable to pass to the executed shell. Takes an environment variable name and value,
+ separated by <literal>=</literal>. This switch may be used multiple times to set multiple
+ environment variables. Note that this switch is not supported for the
+ <command>login</command> command (see below).</para></listitem>
</varlistentry>
<varlistentry>
@@ -210,9 +217,11 @@
<term><option>--read-only</option></term>
<listitem><para>When used with <command>bind</command>, applies
- a read-only bind mount.</para></listitem>
- </varlistentry>
+ a read-only bind mount.</para>
+ <para>When used with <command>clone</command>, <command>import-raw</command> or <command>import-tar</command> a
+ read-only container or VM image is created.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>-n</option></term>
@@ -580,19 +589,20 @@
<varlistentry>
<term><command>clone</command> <replaceable>NAME</replaceable> <replaceable>NAME</replaceable></term>
- <listitem><para>Clones a container or VM image. The
- arguments specify the name of the image to clone and the name
- of the newly cloned image. Note that plain directory container
- images are cloned into subvolume images with this command.
- Note that cloning a container or VM image is optimized for
- btrfs file systems, and might not be efficient on others, due
- to file system limitations.</para>
+ <listitem><para>Clones a container or VM image. The arguments specify the name of the image to clone and the
+ name of the newly cloned image. Note that plain directory container images are cloned into btrfs subvolume
+ images with this command, if the underlying file system supports this. Note that cloning a container or VM
+ image is optimized for btrfs file systems, and might not be efficient on others, due to file system
+ limitations.</para>
<para>Note that this command leaves host name, machine ID and
all other settings that could identify the instance
unmodified. The original image and the cloned copy will hence
share these credentials, and it might be necessary to manually
- change them in the copy.</para></listitem>
+ change them in the copy.</para>
+
+ <para>If combined with the <option>--read-only</option> switch a read-only cloned image is
+ created.</para></listitem>
</varlistentry>
<varlistentry>
@@ -653,6 +663,23 @@
itself.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>clean</command></term>
+
+ <listitem><para>Remove hidden VM or container images (or all). This command removes all hidden machine images
+ from <filename>/var/lib/machines</filename>, i.e. those whose name begins with a dot. Use <command>machinectl
+ list-images --all</command> to see a list of all machine images, including the hidden ones.</para>
+
+ <para>When combined with the <option>--all</option> switch removes all images, not just hidden ones. This
+ command effectively empties <filename>/var/lib/machines</filename>.</para>
+
+ <para>Note that commands such as <command>machinectl pull-tar</command> or <command>machinectl
+ pull-raw</command> usually create hidden, read-only, unmodified machine images from the downloaded image first,
+ before cloning a writable working copy of it, in order to avoid duplicate downloads in case of images that are
+ reused multiple times. Use <command>machinectl clean</command> to remove old, hidden images created this
+ way.</para></listitem>
+ </varlistentry>
+
</variablelist></refsect2>
<refsect2><title>Image Transfer Commands</title><variablelist>
@@ -933,12 +960,12 @@
<title>Download a Fedora image, set a root password in it, start
it as service</title>
- <programlisting># machinectl pull-raw --verify=no http://ftp.halifax.rwth-aachen.de/fedora/linux/releases/21/Cloud/Images/x86_64/Fedora-Cloud-Base-20141203-21.x86_64.raw.xz
-# systemd-nspawn -M Fedora-Cloud-Base-20141203-21
+ <programlisting># machinectl pull-raw --verify=no https://dl.fedoraproject.org/pub/fedora/linux/releases/23/Cloud/x86_64/Images/Fedora-Cloud-Base-23-20151030.x86_64.raw.xz
+# systemd-nspawn -M Fedora-Cloud-Base-23-20151030
# passwd
# exit
-# machinectl start Fedora-Cloud-Base-20141203-21
-# machinectl login Fedora-Cloud-Base-20141203-21</programlisting>
+# machinectl start Fedora-Cloud-Base-23-20151030
+# machinectl login Fedora-Cloud-Base-23-20151030</programlisting>
<para>This downloads the specified <filename>.raw</filename>
image with verification disabled. Then, a shell is opened in it
diff --git a/man/networkctl.xml b/man/networkctl.xml
index c688714b30..24e1de6986 100644
--- a/man/networkctl.xml
+++ b/man/networkctl.xml
@@ -102,12 +102,14 @@
<varlistentry>
<term>
<command>list</command>
+ <optional><replaceable>LINK...</replaceable></optional>
</term>
<listitem>
- <para>Show a list of existing links and their
- status. Produces output similar to <programlisting>
-IDX LINK TYPE OPERATIONAL SETUP
+ <para>Show a list of existing links and their status. If no further arguments are specified shows all links,
+ otherwise just the specified links. Produces output similar to:
+
+ <programlisting>IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback carrier unmanaged
2 eth0 ether routable configured
3 virbr0 ether no-carrier unmanaged
@@ -128,10 +130,10 @@ IDX LINK TYPE OPERATIONAL SETUP
state, kernel module driver, hardware and IP address,
configured DNS servers, etc.</para>
- <para>When no links are specified, routable links are
- shown. Also see the option <option>--all</option>.</para>
+ <para>When no links are specified, an overall network status is shown. Also see the option
+ <option>--all</option>.</para>
- <para>Produces output similar to
+ <para>Produces output similar to:
<programlisting>
● State: routable
Address: 10.193.76.5 on eth0
@@ -148,11 +150,26 @@ IDX LINK TYPE OPERATIONAL SETUP
<varlistentry>
<term>
<command>lldp</command>
+ <optional><replaceable>LINK...</replaceable></optional>
</term>
<listitem>
- <para>Show LLDP (Link Layer Discovery Protocol)
- status.</para>
+ <para>Show discovered LLDP (Link Layer Discovery Protocol) neighbors. If one or more link names are specified
+ only neighbors on those interfaces are shown. Otherwise shows discovered neighbors on all interfaces. Note
+ that for this feature to work, <varname>LLDP=</varname> must be turned on on the specific interface, see
+ <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+ details.</para>
+
+ <para>Produces output similar to:
+ <programlisting>LINK CHASSIS ID SYSTEM NAME CAPS PORT ID PORT DESCRIPTION
+enp0s25 00:e0:4c:00:00:00 GS1900 ..b........ 2 Port #2
+
+Capability Flags:
+o - Other; p - Repeater; b - Bridge; w - WLAN Access Point; r - Router;
+t - Telephone; d - DOCSIS cable device; a - Station; c - Customer VLAN;
+s - Service VLAN, m - Two-port MAC Relay (TPMR)
+
+1 neighbors listed.</programlisting></para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml
new file mode 100644
index 0000000000..4bfc4f773a
--- /dev/null
+++ b/man/networkd.conf.xml
@@ -0,0 +1,154 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2014 Vinay Kulkarni
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="networkd.conf" conditional='ENABLE_NETWORKD'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <refentryinfo>
+ <title>networkd.conf</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Vinay</firstname>
+ <surname>Kulkarni</surname>
+ <email>kulkarniv@vmware.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>networkd.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>networkd.conf</refname>
+ <refname>networkd.conf.d</refname>
+ <refpurpose>Global Network configuration files</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>/etc/systemd/networkd.conf</filename></para>
+ <para><filename>/etc/systemd/networkd.conf.d/*.conf</filename></para>
+ <para><filename>/usr/lib/systemd/networkd.conf.d/*.conf</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>These configuration files control global network parameters.
+ Currently the DHCP Unique Identifier (DUID).</para>
+
+ </refsect1>
+
+ <xi:include href="standard-conf.xml" xpointer="main-conf" />
+
+ <refsect1>
+ <title>[DHCP] Section Options</title>
+
+ <para>This section configures the DHCP Unique Identifier (DUID) value used by DHCP
+ protocol. DHCPv6 client protocol sends the DHCP Unique Identifier and the interface
+ Identity Association Identifier (IAID) to a DHCP server when acquiring a dynamic IPv6
+ address. DHCPv4 client protocol sends IAID and DUID to the DHCP server when acquiring
+ a dynamic IPv4 address if <option>ClientIdentifier=duid</option>. IAID and DUID allows
+ a DHCP server to uniquely identify the machine and the interface requesting a DHCP IP.
+ To configure IAID and ClientIdentifier, see
+ <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ </para>
+
+ <para>The following options are understood:</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>DUIDType=</varname></term>
+ <listitem><para>Specifies how the DUID should be generated. See
+ <ulink url="https://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>
+ for a description of all the options.</para>
+
+ <para>The following values are understood:
+ <variablelist>
+ <varlistentry>
+ <term><option>vendor</option> </term>
+ <listitem><para>If <literal>DUIDType=vendor</literal>, then the DUID value will be generated using
+ <literal>43793</literal> as the vendor identifier (systemd) and hashed contents of
+ <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This is the default if <varname>DUIDType=</varname> is not specified.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>link-layer-time</option> </term>
+ <term><option>link-layer</option> </term>
+ <term><option>uuid</option> </term>
+ <listitem><para>Those values are parsed and can be used to set the DUID type
+ field, but DUID contents must be provided using <varname>DUIDRawData=</varname>.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>In all cases, <varname>DUIDRawData=</varname> can be used to override the
+ actual DUID value that is used.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DUIDRawData=</varname></term>
+ <listitem><para>Specifies the DHCP DUID value as a single newline-terminated, hexadecimal string, with each
+ byte separated by <literal>:</literal>. The DUID that is sent is composed of the DUID type specified by
+ <varname>DUIDType=</varname> and the value configured here.</para>
+
+ <para>The DUID value specified here overrides the DUID that systemd-networkd generates using the machine-id
+ from the <filename>/etc/machine-id</filename> file. To configure DUID per-network, see
+ <citerefentry><refentrytitle>systemd.network </refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ The configured DHCP DUID should conform to the specification in
+ <ulink url="http://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>,
+ <ulink url="http://tools.ietf.org/html/rfc6355">RFC 6355</ulink>. To configure IAID, see
+ <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>.</para>
+
+ <example>
+ <title>A <option>DUIDType=vendor</option> with a custom value</title>
+
+ <programlisting>DUIDType=vendor
+DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
+
+ <para>This specifies a 14 byte DUID, with the type DUID-EN (<literal>00:02</literal>), enterprise number
+ 43793 (<literal>00:00:ab:11</literal>), and identifier value <literal>f9:2a:c2:77:29:f9:5c:00</literal>.
+ </para>
+ </example>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/nss-myhostname.xml b/man/nss-myhostname.xml
index 251bdecbad..a920ec334f 100644
--- a/man/nss-myhostname.xml
+++ b/man/nss-myhostname.xml
@@ -57,12 +57,11 @@
<refsect1>
<title>Description</title>
- <para><command>nss-myhostname</command> is a plugin for the GNU
- Name Service Switch (NSS) functionality of the GNU C Library
- (<command>glibc</command>), primarily providing hostname resolution
- for the locally configured system hostname as returned by
- <citerefentry><refentrytitle>gethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
- The precise hostnames resolved by this module are:</para>
+ <para><command>nss-myhostname</command> is a plug-in module for the GNU Name Service Switch (NSS) functionality of
+ the GNU C Library (<command>glibc</command>), primarily providing hostname resolution for the locally configured
+ system hostname as returned by
+ <citerefentry><refentrytitle>gethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>. The precise
+ hostnames resolved by this module are:</para>
<itemizedlist>
<listitem><para>The local, configured hostname is resolved to
@@ -71,16 +70,16 @@
is on the local loopback) and the IPv6 address ::1 (which is the
local host).</para></listitem>
- <listitem><para>The hostname <literal>localhost</literal> (as well as any hostname ending in
- <literal>.localhost</literal>, <literal>.localdomain</literal> or equal to <literal>localdomain</literal>) is
- resolved to the IP addresses 127.0.0.1 and ::1.</para></listitem>
+ <listitem><para>The hostnames <literal>localhost</literal> and
+ <literal>localhost.localdomain</literal> (as well as any hostname
+ ending in <literal>.localhost</literal> or <literal>.localhost.localdomain</literal>)
+ are resolved to the IP addresses 127.0.0.1 and ::1.</para></listitem>
<listitem><para>The hostname <literal>gateway</literal> is
resolved to all current default routing gateway addresses,
ordered by their metric. This assigns a stable hostname to the
current gateway, useful for referencing it independently of the
current network configuration state.</para></listitem>
-
</itemizedlist>
<para>Various software relies on an always-resolvable local
@@ -93,29 +92,25 @@
changing <filename>/etc/hosts</filename> is unnecessary, and on
many systems, the file becomes entirely optional.</para>
- <para>To activate the NSS modules, <literal>myhostname</literal>
- has to be added to the line starting with
- <literal>hosts:</literal> in
- <filename>/etc/nsswitch.conf</filename>.</para>
+ <para>To activate the NSS modules, add <literal>myhostname</literal> to the line starting with
+ <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
- <para>It is recommended to place <literal>myhostname</literal>
- last in the <filename>nsswitch.conf</filename> line to make sure
- that this mapping is only used as fallback, and that any DNS or
- <filename>/etc/hosts</filename> based mapping takes
- precedence.</para>
+ <para>It is recommended to place <literal>myhostname</literal> last in the <filename>nsswitch.conf</filename>'
+ <literal>hosts:</literal> line to make sure that this mapping is only used as fallback, and that any DNS or
+ <filename>/etc/hosts</filename> based mapping takes precedence.</para>
</refsect1>
<refsect1>
<title>Example</title>
- <para>Here is an example <filename>/etc/nsswitch.conf</filename>
- file that enables <command>myhostname</command> correctly:</para>
+ <para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables
+ <command>nss-myhostname</command> correctly:</para>
<programlisting>passwd: compat mymachines
group: compat mymachines
shadow: compat
-hosts: files resolve mymachines <command>myhostname</command>
+hosts: files mymachines resolve <command>myhostname</command>
networks: files
protocols: db files
diff --git a/man/nss-mymachines.xml b/man/nss-mymachines.xml
index d2bec763bb..ec047449bf 100644
--- a/man/nss-mymachines.xml
+++ b/man/nss-mymachines.xml
@@ -56,42 +56,37 @@
<refsect1>
<title>Description</title>
- <para><command>nss-mymachines</command> is a plugin for the GNU
- Name Service Switch (NSS) functionality of the GNU C Library
- (<command>glibc</command>), providing hostname resolution for
- container names of containers running locally that are registered
- with
- <citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
- The container names are resolved to the IP addresses of the
- specific container, ordered by their scope.</para>
-
- <para>The module also resolves user IDs used by containers to user
- names indicating the container name, and back.</para>
-
- <para>To activate the NSS modules, <literal>mymachines</literal>
- has to be added to the lines starting with
- <literal>hosts:</literal>, <literal>passwd:</literal> and
- <literal>group:</literal> in
+ <para><command>nss-mymachines</command> is a plug-in module for the GNU Name Service Switch (NSS) functionality of
+ the GNU C Library (<command>glibc</command>), providing hostname resolution for the names of containers running
+ locally that are registered with
+ <citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. The
+ container names are resolved to the IP addresses of the specific container, ordered by their scope. This
+ functionality only applies to containers using network namespacing.</para>
+
+ <para>The module also resolves user and group IDs used by containers to user and group names indicating the
+ container name, and back. This functionality only applies to containers using user namespacing.</para>
+
+ <para>To activate the NSS module, add <literal>mymachines</literal> to the lines starting with
+ <literal>hosts:</literal>, <literal>passwd:</literal> and <literal>group:</literal> in
<filename>/etc/nsswitch.conf</filename>.</para>
- <para>It is recommended to place <literal>mymachines</literal>
- near the end of the <filename>nsswitch.conf</filename> lines to
- make sure that its mappings are only used as fallback, and that any
- other mappings, such as DNS or <filename>/etc/hosts</filename>
- based mappings, take precedence.</para>
+ <para>It is recommended to place <literal>mymachines</literal> after the <literal>files</literal> or
+ <literal>compat</literal> entry of the <filename>/etc/nsswitch.conf</filename> lines to make sure that its mappings
+ are preferred over other resolvers such as DNS, but so that <filename>/etc/hosts</filename>,
+ <filename>/etc/passwd</filename> and <filename>/etc/group</filename> based mappings take precedence.</para>
</refsect1>
<refsect1>
<title>Example</title>
- <para>Here is an example <filename>/etc/nsswitch.conf</filename>
- file that enables <command>mymachines</command> correctly:</para>
+ <para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables
+ <command>nss-mymachines</command> correctly:</para>
<programlisting>passwd: compat <command>mymachines</command>
group: compat <command>mymachines</command>
shadow: compat
-hosts: files resolve <command>mymachines</command> myhostname
+hosts: files <command>mymachines</command> resolve myhostname
networks: files
protocols: db files
diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index 8b0928145f..d9e56453e8 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -56,37 +56,36 @@
<refsect1>
<title>Description</title>
- <para><command>nss-resolve</command> is a plugin module for the
- GNU Name Service Switch (NSS) functionality of the GNU C Library
- (<command>glibc</command>) enabling it to resolve host names via
- the
- <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- local network name resolution service.</para>
-
- <para>To activate the NSS module, <literal>resolve</literal>
- has to be added to the line starting with
- <literal>hosts:</literal> in
- <filename>/etc/nsswitch.conf</filename>.</para>
-
- <para>It is recommended to place <literal>resolve</literal> early
- in the <filename>nsswitch.conf</filename> line (but after the
- <literal>files</literal> entry), replacing the
- <literal>dns</literal> entry if it exists, to ensure DNS queries
- are always routed via
+ <para><command>nss-resolve</command> is a plug-in module for the GNU Name Service Switch (NSS) functionality of the
+ GNU C Library (<command>glibc</command>) enabling it to resolve host names via the
+ <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry> local network
+ name resolution service. It replaces the <command>nss-dns</command> plug-in module that traditionally resolves
+ 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>.</para>
+
+ <para>It is recommended to place <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>'
+ <literal>hosts:</literal> line (but after the <literal>files</literal> or <literal>mymachines</literal> entries),
+ replacing the <literal>dns</literal> entry if it exists, to ensure DNS queries are always routed via
<citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+ <para>Note that <command>nss-resolve</command> will chain-load <command>nss-dns</command> if
+ <filename>systemd-resolved.service</filename> is not running, ensuring that basic DNS resolution continues to work
+ if the service is down.</para>
</refsect1>
<refsect1>
<title>Example</title>
- <para>Here is an example <filename>/etc/nsswitch.conf</filename>
- file that enables <command>resolve</command> correctly:</para>
+ <para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables <command>nss-resolve</command>
+ correctly:</para>
<programlisting>passwd: compat mymachines
group: compat mymachines
shadow: compat
-hosts: files <command>resolve</command> mymachines myhostname
+hosts: files mymachines <command>resolve</command> myhostname
networks: files
protocols: db files
@@ -96,12 +95,6 @@ rpc: db files
netgroup: nis</programlisting>
- <para>Note that <command>nss-resolve</command> will chain-load
- <command>nss-dns</command> if
- <filename>systemd-resolved.service</filename> is not running,
- ensuring that basic DNS resolution continues to work if the
- service is down.</para>
-
</refsect1>
<refsect1>
diff --git a/man/sd_bus_creds_get_pid.xml b/man/sd_bus_creds_get_pid.xml
index 3bcda46656..4c05835568 100644
--- a/man/sd_bus_creds_get_pid.xml
+++ b/man/sd_bus_creds_get_pid.xml
@@ -406,15 +406,11 @@
For processes that are not part of a session, returns -ENXIO.
</para>
- <para><function>sd_bus_creds_has_effective_cap()</function> will
- check whether the capability specified by
- <parameter>capability</parameter> was set in the effective
- capabilities mask. A positive return value means that is was
- set, zero means that it was not set, and a negative return
- value indicates an error. See
- <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- and <varname>Capabilities=</varname> and
- <varname>CapabilityBoundingSet=</varname> settings in
+ <para><function>sd_bus_creds_has_effective_cap()</function> will check whether the capability specified by
+ <parameter>capability</parameter> was set in the effective capabilities mask. A positive return value means that it
+ was set, zero means that it was not set, and a negative return value indicates an error. See <citerefentry
+ project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> and the
+ <varname>AmbientCapabilities=</varname> and <varname>CapabilityBoundingSet=</varname> settings in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
diff --git a/man/sd_event_source_set_priority.xml b/man/sd_event_source_set_priority.xml
index 9234f4233e..8c9b39fe5e 100644
--- a/man/sd_event_source_set_priority.xml
+++ b/man/sd_event_source_set_priority.xml
@@ -97,7 +97,7 @@
<constant>SD_EVENT_PRIORITY_IDLE</constant> (100) may be used to
indicate event sources that shall be dispatched early, normally or
late. It is recommended to specify priorities based on these
- definitions, and relative to them -- however, the full 64bit
+ definitions, and relative to them — however, the full 64bit
signed integer range is available for ordering event
sources.</para>
diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml
index 3b27444f8d..98415d53fd 100644
--- a/man/sd_journal_add_match.xml
+++ b/man/sd_journal_add_match.xml
@@ -88,11 +88,19 @@
<citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- Matches are of the form <literal>FIELD=value</literal>, where the
- field part is a short uppercase string consisting only of 0–9, A–Z
- and the underscore. It may not begin with two underscores or be
- the empty string. The value part may be any value, including
- binary. If a match is applied, only entries with this field set
+ Parameter <parameter>data</parameter> must be of the form
+ <literal><replaceable>FIELD</replaceable>=<replaceable>value</replaceable></literal>,
+ where the <replaceable>FIELD</replaceable> part is a short uppercase string consisting only
+ of 0–9, A–Z and the underscore; it may not begin with two underscores or be the empty
+ string. The <replaceable>value</replaceable> part may be anything, including binary. Parameter
+ <parameter>size</parameter> specifies the number of bytes in <parameter>data</parameter>
+ (i.e. the length of <replaceable>FIELD</replaceable>, plus one, plus the length of
+ <replaceable>value</replaceable>). Parameter <parameter>size</parameter> may also be
+ specified as <constant>0</constant>, in which case <parameter>data</parameter>
+ must be a <constant>NUL</constant>-terminated string, and the bytes before the terminating
+ zero are used as the match.</para>
+
+ <para>If a match is applied, only entries with this field set
will be iterated. Multiple matches may be active at the same time:
If they apply to different fields, only entries with both fields
set like this will be iterated. If they apply to the same fields,
diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml
index 1f25d068d7..908ee7db16 100644
--- a/man/sd_journal_get_data.xml
+++ b/man/sd_journal_get_data.xml
@@ -148,7 +148,7 @@
<function>sd_journal_enumerate_unique()</function>. This threshold
is a hint only: it indicates that the client program is interested
only in the initial parts of the data fields, up to the threshold
- in size -- but the library might still return larger data objects.
+ in size — but the library might still return larger data objects.
That means applications should not rely exclusively on this
setting to limit the size of the data fields returned, but need to
apply a explicit size limit on the returned data as well. This
diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml
index fef453f8dc..153af2387f 100644
--- a/man/sd_journal_open.xml
+++ b/man/sd_journal_open.xml
@@ -45,14 +45,16 @@
<refnamediv>
<refname>sd_journal_open</refname>
<refname>sd_journal_open_directory</refname>
+ <refname>sd_journal_open_directory_fd</refname>
<refname>sd_journal_open_files</refname>
- <refname>sd_journal_open_container</refname>
+ <refname>sd_journal_open_files_fd</refname>
<refname>sd_journal_close</refname>
<refname>sd_journal</refname>
<refname>SD_JOURNAL_LOCAL_ONLY</refname>
<refname>SD_JOURNAL_RUNTIME_ONLY</refname>
<refname>SD_JOURNAL_SYSTEM</refname>
<refname>SD_JOURNAL_CURRENT_USER</refname>
+ <refname>SD_JOURNAL_OS_ROOT</refname>
<refpurpose>Open the system journal for reading</refpurpose>
</refnamediv>
@@ -74,6 +76,13 @@
</funcprototype>
<funcprototype>
+ <funcdef>int <function>sd_journal_open_directory_fd</function></funcdef>
+ <paramdef>sd_journal **<parameter>ret</parameter></paramdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>flags</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
<funcdef>int <function>sd_journal_open_files</function></funcdef>
<paramdef>sd_journal **<parameter>ret</parameter></paramdef>
<paramdef>const char **<parameter>paths</parameter></paramdef>
@@ -81,9 +90,10 @@
</funcprototype>
<funcprototype>
- <funcdef>int <function>sd_journal_open_container</function></funcdef>
+ <funcdef>int <function>sd_journal_open_files_fd</function></funcdef>
<paramdef>sd_journal **<parameter>ret</parameter></paramdef>
- <paramdef>const char *<parameter>machine</parameter></paramdef>
+ <paramdef>int <parameter>fds[]</parameter></paramdef>
+ <paramdef>unsigned <parameter>n_fds</parameter></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
</funcprototype>
@@ -117,29 +127,28 @@
<constant>SD_JOURNAL_CURRENT_USER</constant> are specified, all
journal file types will be opened.</para>
- <para><function>sd_journal_open_directory()</function> is similar
- to <function>sd_journal_open()</function> but takes an absolute
- directory path as argument. All journal files in this directory
- will be opened and interleaved automatically. This call also takes
- a flags argument, but it must be passed as 0 as no flags are
- currently understood for this call.</para>
-
- <para><function>sd_journal_open_files()</function> is similar to
- <function>sd_journal_open()</function> but takes a
- <constant>NULL</constant>-terminated list of file paths to open.
- All files will be opened and interleaved automatically. This call
- also takes a flags argument, but it must be passed as 0 as no
- flags are currently understood for this call. Please note that in
- the case of a live journal, this function is only useful for
- debugging, because individual journal files can be rotated at any
- moment, and the opening of specific files is inherently
- racy.</para>
-
- <para><function>sd_journal_open_container()</function> is similar
- to <function>sd_journal_open()</function> but opens the journal
- files of a running OS container. The specified machine name refers
- to a container that is registered with
- <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ <para><function>sd_journal_open_directory()</function> is similar to <function>sd_journal_open()</function> but
+ takes an absolute directory path as argument. All journal files in this directory will be opened and interleaved
+ automatically. This call also takes a flags argument. The only flags parameter accepted by this call is
+ <constant>SD_JOURNAL_OS_ROOT</constant>. If specified, the journal files are searched below the usual
+ <filename>/var/log/journal</filename> and <filename>/run/log/journal</filename> relative to the specified path,
+ instead of directly beneath it.</para>
+
+ <para><function>sd_journal_open_directory_fd()</function> is similar to
+ <function>sd_journal_open_directory()</function>, but takes a file descriptor referencing a directory in the file
+ system instead of an absolute file system path.</para>
+
+ <para><function>sd_journal_open_files()</function> is similar to <function>sd_journal_open()</function> but takes a
+ <constant>NULL</constant>-terminated list of file paths to open. All files will be opened and interleaved
+ automatically. This call also takes a flags argument, but it must be passed as 0 as no flags are currently
+ understood for this call. Please note that in the case of a live journal, this function is only useful for
+ debugging, because individual journal files can be rotated at any moment, and the opening of specific files is
+ inherently racy.</para>
+
+ <para><function>sd_journal_open_files_fd()</function> is similar to <function>sd_journal_open_files()</function>
+ but takes an array of open file descriptors that must reference journal files, instead of an array of file system
+ paths. Pass the array of file descriptors as second argument, and the number of array entries in the third. The
+ flags parameter must be passed as 0.</para>
<para><varname>sd_journal</varname> objects cannot be used in the
child after a fork. Functions which take a journal object as an
@@ -205,26 +214,6 @@
</refsect1>
<refsect1>
- <title>History</title>
-
- <para><function>sd_journal_open()</function>,
- <function>sd_journal_close()</function>,
- <constant>SD_JOURNAL_LOCAL_ONLY</constant>,
- <constant>SD_JOURNAL_RUNTIME_ONLY</constant>,
- <constant>SD_JOURNAL_SYSTEM_ONLY</constant> were added in
- systemd-38.</para>
-
- <para><function>sd_journal_open_directory()</function> was added
- in systemd-187.</para>
-
- <para><constant>SD_JOURNAL_SYSTEM</constant>,
- <constant>SD_JOURNAL_CURRENT_USER</constant>, and
- <function>sd_journal_open_files()</function> were added in
- systemd-205. <constant>SD_JOURNAL_SYSTEM_ONLY</constant> was
- deprecated.</para>
- </refsect1>
-
- <refsect1>
<title>See Also</title>
<para>
diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
index 4cc7405dd6..130af761da 100644
--- a/man/sd_uid_get_state.xml
+++ b/man/sd_uid_get_state.xml
@@ -218,19 +218,6 @@
</refsect1>
<refsect1>
- <title>History</title>
-
- <para><function>sd_uid_get_state()</function>,
- <function>sd_uid_is_on_seat()</function>,
- <function>sd_uid_get_sessions()</function>, and
- <function>sd_uid_get_seats()</function> functions were added in
- systemd-31.</para>
-
- <para><function>sd_uid_get_display()</function> was added in
- systemd-213.</para>
- </refsect1>
-
- <refsect1>
<title>See Also</title>
<para>
diff --git a/man/sd_watchdog_enabled.xml b/man/sd_watchdog_enabled.xml
index 6e27528a71..3de9899453 100644
--- a/man/sd_watchdog_enabled.xml
+++ b/man/sd_watchdog_enabled.xml
@@ -155,18 +155,6 @@
</refsect1>
<refsect1>
- <title>History</title>
-
- <para>The watchdog functionality and the
- <varname>$WATCHDOG_USEC</varname> variable were added in
- systemd-41.</para>
-
- <para><function>sd_watchdog_enabled()</function> function was
- added in systemd-209. Since that version, the
- <varname>$WATCHDOG_PID</varname> variable is also set.</para>
- </refsect1>
-
- <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 1480bf8380..991e9bafaf 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -233,6 +233,16 @@
</varlistentry>
<varlistentry>
+ <term><option>--value</option></term>
+
+ <listitem>
+ <para>When printing properties with <command>show</command>,
+ only print the value, and skip the property name and
+ <literal>=</literal>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--show-types</option></term>
<listitem>
@@ -1074,22 +1084,22 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<term><command>preset <replaceable>NAME</replaceable>...</command></term>
<listitem>
- <para>Reset one or more unit files, as specified on the
- command line, to the defaults configured in the preset
- policy files. This has the same effect as
- <command>disable</command> or <command>enable</command>,
- depending how the unit is listed in the preset files.</para>
+ <para>Reset the enable/disable status one or more unit files, as specified on
+ the command line, to the defaults configured in the preset policy files. This
+ has the same effect as <command>disable</command> or
+ <command>enable</command>, depending how the unit is listed in the preset
+ files.</para>
- <para>Use <option>--preset-mode=</option> to control
- whether units shall be enabled and disabled, or only
- enabled, or only disabled.</para>
+ <para>Use <option>--preset-mode=</option> to control whether units shall be
+ enabled and disabled, or only enabled, or only disabled.</para>
- <para>For more information on the preset policy format,
- see
+ <para>If the unit carries no install information, it will be silently ignored
+ by this command.</para>
+
+ <para>For more information on the preset policy format, see
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- For more information on the concept of presets, please
- consult the <ulink
- url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
+ For more information on the concept of presets, please consult the
+ <ulink url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
document.</para>
</listitem>
</varlistentry>
@@ -1158,22 +1168,32 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</row>
<row>
<entry><literal>static</literal></entry>
- <entry>The unit file is not enabled, and has no provisions for enabling in the <literal>[Install]</literal> section.</entry>
+ <entry>The unit file is not enabled, and has no provisions for enabling in the <literal>[Install]</literal> unit file section.</entry>
<entry>0</entry>
</row>
<row>
<entry><literal>indirect</literal></entry>
- <entry>The unit file itself is not enabled, but it has a non-empty <varname>Also=</varname> setting in the <literal>[Install]</literal> section, listing other unit files that might be enabled.</entry>
+ <entry>The unit file itself is not enabled, but it has a non-empty <varname>Also=</varname> setting in the <literal>[Install]</literal> unit file section, listing other unit files that might be enabled.</entry>
<entry>0</entry>
</row>
<row>
<entry><literal>disabled</literal></entry>
- <entry>Unit file is not enabled, but contains an <literal>[Install]</literal> section with installation instructions.</entry>
+ <entry>The unit file is not enabled, but contains an <literal>[Install]</literal> section with installation instructions.</entry>
<entry>&gt; 0</entry>
</row>
<row>
+ <entry><literal>generated</literal></entry>
+ <entry>The unit file was generated dynamically via a generator tool. See <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Generated unit files may not be enabled, they are enabled implicitly by their generator.</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry><literal>transient</literal></entry>
+ <entry>The unit file has been created dynamically with the runtime API. Transient units may not be enabled.</entry>
+ <entry>0</entry>
+ </row>
+ <row>
<entry><literal>bad</literal></entry>
- <entry>Unit file is invalid or another error occurred. Note that <command>is-enabled</command> will not actually return this state, but print an error message instead. However the unit file listing printed by <command>list-unit-files</command> might show it.</entry>
+ <entry>The unit file is invalid or another error occurred. Note that <command>is-enabled</command> will not actually return this state, but print an error message instead. However the unit file listing printed by <command>list-unit-files</command> might show it.</entry>
<entry>&gt; 0</entry>
</row>
</tbody>
@@ -1225,6 +1245,28 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
+ <term><command>revert <replaceable>NAME</replaceable>...</command></term>
+
+ <listitem>
+ <para>Revert one or more unit files to their vendor versions. This command removes drop-in configuration
+ files that modify the specified units, as well as any user-configured unit file that overrides a matching
+ vendor supplied unit file. Specifically, for a unit <literal>foo.service</literal> the matching directories
+ <literal>foo.service.d/</literal> with all their contained files are removed, both below the persistent and
+ runtime configuration directories (i.e. below <filename>/etc/systemd/system</filename> and
+ <filename>/run/systemd/system</filename>); if the unit file has a vendor-supplied version (i.e. a unit file
+ located below <filename>/usr</filename>) any matching peristent or runtime unit file that overrides it is
+ removed, too. Note that if a unit file has no vendor-supplied version (i.e. is only defined below
+ <filename>/etc/systemd/system</filename> or <filename>/run/systemd/system</filename>, but not in a unit
+ file stored below <filename>/usr</filename>), then it is not removed. Also, if a unit is masked, it is
+ unmasked.</para>
+
+ <para>Effectively, this command may be used to undo all changes made with <command>systemctl
+ edit</command>, <command>systemctl set-property</command> and <command>systemctl mask</command> and puts
+ the original unit file with its settings back in effect.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>add-wants <replaceable>TARGET</replaceable>
<replaceable>NAME</replaceable>...</command></term>
<term><command>add-requires <replaceable>TARGET</replaceable>
diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml
index 2a4d24349b..2b6fb5a82f 100644
--- a/man/systemd-ask-password.xml
+++ b/man/systemd-ask-password.xml
@@ -67,7 +67,7 @@
processes.</para>
<para>The purpose of this tool is to query system-wide passwords
- -- that is passwords not attached to a specific user account.
+ — that is passwords not attached to a specific user account.
Examples include: unlocking encrypted hard disks when they are
plugged in or at boot, entering an SSL certificate passphrase for
web and VPN servers.</para>
@@ -192,6 +192,15 @@
This will output one password per line.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--no-output</option></term>
+
+ <listitem><para>Do not print passwords to standard output.
+ This is useful if you want to store a password in kernel
+ keyring with <option>--keyname</option> but do not want it
+ to show up on screen or in logs.</para></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="help" />
</variablelist>
diff --git a/man/systemd-bootchart.xml b/man/systemd-bootchart.xml
deleted file mode 100644
index bcee11fd0b..0000000000
--- a/man/systemd-bootchart.xml
+++ /dev/null
@@ -1,323 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- This file is part of systemd.
-
- Copyright 2012 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.com>
- William Giokas <1007380@gmail.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/>.
--->
-
-<refentry id="systemd-bootchart" conditional='ENABLE_BOOTCHART'
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
- <refentryinfo>
- <title>systemd-bootchart</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Auke</firstname>
- <surname>Kok</surname>
- <email>auke-jan.h.kok@intel.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>systemd-bootchart</refentrytitle>
- <manvolnum>1</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>systemd-bootchart</refname>
- <refpurpose>Boot performance graphing tool</refpurpose>
- </refnamediv>
-
- <refsect1>
- <title>Description</title>
- <para>
- <command>systemd-bootchart</command> is a tool, usually run at
- system startup, that collects the CPU load, disk load, memory
- usage, as well as per-process information from a running system.
- Collected results are output as an SVG graph. Normally,
- systemd-bootchart is invoked by the kernel by passing
- <option>init=<filename>/usr/lib/systemd/systemd-bootchart</filename></option>
- on the kernel command line. systemd-bootchart will then fork the
- real init off to resume normal system startup, while monitoring
- and logging startup information in the background.
- </para>
- <para>
- After collecting a certain amount of data (usually 15–30
- seconds, default 20 s) the logging stops and a graph is
- generated from the logged information. This graph contains vital
- clues as to which resources are being used, in which order, and
- where possible problems exist in the startup sequence of the
- system. It is essentially a more detailed version of the
- <command>systemd-analyze plot</command> function.
- </para>
- <para>
- Of course, bootchart can also be used at any moment in time to
- collect and graph some data for an amount of time. It is
- recommended to use the <option>--rel</option> switch in this
- case.
- </para>
- <para>
- Bootchart does not require root privileges, and will happily run
- as a normal user.
- </para>
- <para>
- Bootchart graphs are by default written time-stamped in
- <filename>/run/log</filename> and saved to the journal with
- <varname>MESSAGE_ID=9f26aa562cf440c2b16c773d0479b518</varname>.
- Journal field <varname>BOOTCHART=</varname> contains the
- bootchart in SVG format.
- </para>
-
- </refsect1>
-
- <refsect1>
- <title>Invocation</title>
-
- <para><command>systemd-bootchart</command> can be invoked in several different ways:</para>
-
- <variablelist>
-
- <varlistentry>
- <term><emphasis>Kernel invocation</emphasis></term>
- <listitem><para>The kernel can invoke
- <command>systemd-bootchart</command> instead of the init
- process. In turn, <command>systemd-bootchart</command> will
- invoke <command>/usr/lib/systemd/systemd</command>.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><emphasis>Started as a standalone program</emphasis></term>
- <listitem><para>One can execute
- <command>systemd-bootchart</command> as normal application
- from the command line. In this mode, it is highly recommended
- to pass the <option>-r</option> flag in order to not graph the
- time elapsed since boot and before systemd-bootchart was
- started, as it may result in extremely large graphs. The time
- elapsed since boot might also include any time that the system
- was suspended.</para></listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Options</title>
-
- <para>These options can also be set in the
- <filename>/etc/systemd/bootchart.conf</filename> file. See
- <citerefentry project='man-pages'><refentrytitle>bootchart.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- </para>
-
- <variablelist>
- <xi:include href="standard-options.xml" xpointer="help" />
-
- <varlistentry>
- <term><option>-n</option></term>
- <term><option>--sample <replaceable>N</replaceable></option></term>
- <listitem><para>Specify the number of samples,
- <replaceable>N</replaceable>, to record. Samples will be
- recorded at intervals defined with <option>--freq</option>.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-f</option></term>
- <term><option>--freq <replaceable>f</replaceable></option></term>
- <listitem><para>Specify the sample log frequency, a positive
- real <replaceable>f</replaceable>, in Hz. Most systems can
- cope with values up to 25–50 without creating too much
- overhead.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-r</option></term>
- <term><option>--rel</option></term>
- <listitem><para>Use relative times instead of absolute times.
- This is useful for using bootchart at post-boot time to
- profile an already booted system. Without this option the
- graph would become extremely large. If set, the horizontal
- axis starts at the first recorded sample instead of time
- 0.0.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-F</option></term>
- <term><option>--no-filter</option></term>
- <listitem><para>Disable filtering of tasks that did not
- contribute significantly to the boot. Processes that are too
- short-lived (only seen in one sample) or that do not consume
- any significant CPU time (less than 0.001 s) will not be
- displayed in the output graph. </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-C</option></term>
- <term><option>--cmdline</option></term>
- <listitem><para>Display the full command line with arguments
- of processes, instead of only the process name.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-g</option></term>
- <term><option>--control-group</option></term>
- <listitem><para>Display process control group
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-o</option></term>
- <term><option>--output <replaceable>path</replaceable></option></term>
- <listitem><para>Specify the output directory for the graphs.
- By default, bootchart writes the graphs to
- <filename>/run/log</filename>.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-i</option></term>
- <term><option>--init <replaceable>path</replaceable></option></term>
- <listitem><para>Use this init binary. Defaults to
- <command>/usr/lib/systemd/systemd</command>.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-p</option></term>
- <term><option>--pss</option></term>
- <listitem><para>Enable logging and graphing of processes' PSS
- (Proportional Set Size) memory consumption. See
- <filename>filesystems/proc.txt</filename> in the kernel
- documentation for an explanation of this field.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-e</option></term>
- <term><option>--entropy</option></term>
- <listitem><para>Enable logging and graphing of the kernel
- random entropy pool size.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-x</option></term>
- <term><option>--scale-x <replaceable>N</replaceable></option></term>
- <listitem><para>Horizontal scaling factor for all variable
- graph components.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-y</option></term>
- <term><option>--scale-y <replaceable>N</replaceable></option></term>
- <listitem><para>Vertical scaling factor for all variable graph
- components.</para></listitem>
- </varlistentry>
-
- </variablelist>
-
-
- </refsect1>
-
- <refsect1>
- <title>Output</title>
-
- <para><command>systemd-bootchart</command> generates SVG graphs.
- In order to render those on a graphical display any SVG capable
- viewer can be used. It should be noted that the SVG render engines
- in most browsers (including Chrome and Firefox) are many times
- faster than dedicated graphical applications like Gimp and
- Inkscape. Just point your browser at
- <ulink url="file:///run/log/" />!
- </para>
- </refsect1>
-
- <refsect1>
- <title>History</title>
-
- <para>This version of bootchart was implemented from scratch, but
- is inspired by former bootchart incantations:</para>
-
- <variablelist>
- <varlistentry>
- <term><emphasis>Original bash</emphasis></term>
- <listitem><para>The original bash/shell code implemented
- bootchart. This version created a compressed tarball for
- processing with external applications. This version did not
- graph anything, only generated data.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><emphasis>Ubuntu C Implementation</emphasis></term>
- <listitem><para>This version replaced the shell version with a
- fast and efficient data logger, but also did not graph the
- data.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><emphasis>Java bootchart</emphasis></term>
- <listitem><para>This was the original graphing application for
- charting the data, written in java.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><emphasis>pybootchartgui.py</emphasis></term>
- <listitem><para>pybootchart created a graph from the data
- collected by either the bash or C version.</para></listitem>
- </varlistentry>
- </variablelist>
-
- <para>The version of bootchart you are using now combines both the
- data collection and the charting into a single application, making
- it more efficient and simpler. There are no longer any timing
- issues with the data collector and the grapher, as the graphing
- cannot be run until the data has been collected. Also, the data
- kept in memory is reduced to the absolute minimum needed.</para>
-
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
-
- <para>
- <citerefentry project='man-pages'><refentrytitle>bootchart.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- </para>
- </refsect1>
-
- <refsect1>
- <title>Bugs</title>
-
- <para>systemd-bootchart does not get the model information for the
- hard drive unless the root device is specified with
- <code>root=/dev/sdxY</code>. Using UUIDs or PARTUUIDs will boot
- fine, but the hard drive model will not be added to the
- chart.</para>
- <para>For bugs, please contact the author and current maintainer:</para>
- <simplelist>
- <member>Auke Kok <email>auke-jan.h.kok@intel.com</email></member>
- </simplelist>
- </refsect1>
-
-</refentry>
diff --git a/man/systemd-bus-proxyd.service.xml b/man/systemd-bus-proxyd.service.xml
deleted file mode 100644
index 02189eea7c..0000000000
--- a/man/systemd-bus-proxyd.service.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
--->
-
-<refentry id="systemd-bus-proxyd.service">
-
- <refentryinfo>
- <title>systemd-bus-proxyd.service</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Lennart</firstname>
- <surname>Poettering</surname>
- <email>lennart@poettering.net</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>systemd-bus-proxyd.service</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>systemd-bus-proxyd.service</refname>
- <refname>systemd-bus-proxyd.socket</refname>
- <refpurpose>Proxy classic D-Bus clients to kdbus</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <para><filename>systemd-bus-proxyd.service</filename></para>
- <para><filename>systemd-bus-proxyd.socket</filename></para>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para><filename>systemd-bus-proxyd.socket</filename> will launch
- <filename>systemd-bus-proxyd.service</filename> for connections
- to the classic D-Bus socket in
- <filename>/var/run/dbus/system_bus_socket</filename>.</para>
-
- <para><filename>systemd-bus-proxyd.service</filename> is launched
- for an existing D-Bus connection and will use
- <command>systemd-bus-proxyd</command> to proxy messages from this
- connection to the system bus (either kdbus or classic D-Bus).
- </para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
-
- <para>
- <citerefentry><refentrytitle>systemd-bus-proxyd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry project='dbus'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <ulink url="http://freedesktop.org/wiki/Software/dbus">D-Bus</ulink>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/systemd-bus-proxyd.xml b/man/systemd-bus-proxyd.xml
deleted file mode 100644
index 0923396151..0000000000
--- a/man/systemd-bus-proxyd.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
--->
-
-<refentry id="systemd-bus-proxyd"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
- <refentryinfo>
- <title>systemd-bus-proxyd</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Lennart</firstname>
- <surname>Poettering</surname>
- <email>lennart@poettering.net</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>systemd-bus-proxyd</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>systemd-bus-proxyd</refname>
- <refpurpose>Connect STDIO or a socket to a given bus address</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>/usr/lib/systemd/systemd-bus-proxyd</command>
- <arg choice="opt" rep="repeat">OPTIONS</arg>
- <arg choice="opt"><replaceable>PLACEHOLDER</replaceable></arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para><command>systemd-bus-proxyd</command> will proxy D-Bus
- messages to and from a bus. The will be either the system bus or
- the bus specified with <option>--address</option> when that option
- is given. Messages will be proxied to/from standard input and
- output, or the socket received through socket activation.</para>
-
- <para>This program can be used to connect a program using classic
- D-Bus to kdbus.</para>
- </refsect1>
-
- <refsect1>
- <title>Options and Arguments</title>
-
- <para>The following options are understood:</para>
-
- <variablelist>
- <varlistentry>
- <term><option>--address=<replaceable>ADDRESS</replaceable><optional>:<replaceable>ADDRESS...</replaceable></optional></option></term>
-
- <listitem>
- <para>Connect to the bus specified by
- <replaceable>ADDRESS</replaceable>. Multiple colon-separated
- addresses can be specified, in which case
- <command>systemd-bus-proxyd</command> will attempt to
- connect to them in turn.</para>
- </listitem>
- </varlistentry>
-
- <xi:include href="standard-options.xml" xpointer="help" />
- <xi:include href="standard-options.xml" xpointer="version" />
- </variablelist>
-
- <para><replaceable>PLACEHOLDER</replaceable>, if given, must be a string
- of <literal>x</literal> and will be used to display information about
- the process that <command>systemd-bus-proxyd</command> is forwarding
- messages for.</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
-
- <para>
- <citerefentry project='dbus'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <ulink url="http://freedesktop.org/wiki/Software/dbus">D-Bus</ulink>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml
index f1598461ef..a28dc62e5a 100644
--- a/man/systemd-coredump.xml
+++ b/man/systemd-coredump.xml
@@ -45,50 +45,89 @@
<refnamediv>
<refname>systemd-coredump</refname>
- <refpurpose>Log and store core dumps</refpurpose>
+ <refname>systemd-coredump.socket</refname>
+ <refname>systemd-coredump@.service</refname>
+ <refpurpose>Acquire, save and process core dumps</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>/usr/lib/systemd/systemd-coredump</filename></para>
+ <para><filename>systemd-coredump@.service</filename></para>
+ <para><filename>systemd-coredump.socket</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
+ <para><command>systemd-coredump</command> is a system service that can acquire core dumps
+ from the kernel and handle them in various ways.</para>
- <para><command>systemd-coredump</command> can be used as a helper
- binary by the kernel when a user space program receives a fatal
- signal and dumps core. For it to be used in this capacity, it must
- be specified by the
- <varname>kernel.core_pattern</varname> <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- setting. Systemd installs
- <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> which
- configures <varname>kernel.core_pattern</varname> to invoke
- <command>systemd-coredump</command>. This file may be masked or
- overridden to use a different setting following normal
- <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> rules.</para>
-
- <para>The behavior of a specific program upon reception of a
- signal is governed by a few factors which are described in detail
- in <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- In particular, the coredump will only be processed when the
- related resource limits are high enough. For programs started by
- <command>systemd</command>, those may be set using
- <varname>LimitCore=</varname> (see
- <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+ <para>Core dumps can be written to the journal or saved as a file. Once saved they can be retrieved
+ for further processing, for example in
+ <citerefentry project='man-pages'><refentrytitle>gdb</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
</para>
- <para><command>systemd-coredump</command> will log the coredump
- including a backtrace if possible, and store the core (contents of
- process' memory contents) in an external file on disk in
- <filename>/var/lib/systemd/coredump</filename>, or directly in
- the journal. This behavior may be modified using
- <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+ <para>By default, <command>systemd-coredump</command> will log the core dump including a backtrace
+ if possible to the journal and store the core dump itself in an external file in
+ <filename>/var/lib/systemd/coredump</filename>.</para>
+
+ <para>When the kernel invokes <command>systemd-coredump</command> to handle a core dump,
+ it will connect to the socket created by the <filename>systemd-coredump.socket</filename>
+ unit, which in turn will spawn a <filename>systemd-coredump@.service</filename> instance
+ to process the core dump. Hence <filename>systemd-coredump.socket</filename>
+ and <filename>systemd-coredump@.service</filename> are helper units which do the actual
+ processing of core dumps and are subject to normal service management.</para>
+
+ <para>The behavior of a specific program upon reception of a signal is governed by a few
+ factors which are described in detail in
+ <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ In particular, the core dump will only be processed when the related resource limits are sufficient.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Configuration</title>
+ <para>For programs started by <command>systemd</command> process resource limits can be set by directive
+ <varname>LimitCore=</varname>, see
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ </para>
- <para>Apart from the
+ <para>In order to be used <command>systemd-coredump</command> must be configured in
+ <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ parameter <varname>kernel.core_pattern</varname>. The syntax of this parameter is explained in
+ <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ Systemd installs the file <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> which configures
+ <varname>kernel.core_pattern</varname> accordingly. This file may be masked or overridden to use a different
+ setting following normal
+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ rules.
+ If the sysctl configuration is modified, it must be updated in the kernel before
+ it takes effect, see
+ <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ and
+ <citerefentry><refentrytitle>systemd-sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ </para>
+
+ <para>The behaviour of <command>systemd-coredump</command> itself is configured through the configuration file
+ <filename>/etc/systemd/coredump.conf</filename> and corresponding snippets
+ <filename>/etc/systemd/coredump.conf.d/*.conf</filename>, see
+ <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. A new
+ instance of <command>systemd-coredump</command> is invoked upon receiving every core dump. Therefore, changes
+ in these files will take effect the next time a core dump is received.</para>
+
+ <para>Resources used by core dump files are restricted in two ways. Parameters like maximum size of acquired
+ core dumps and files can be set in files <filename>/etc/systemd/coredump.conf</filename> and snippets mentioned
+ above. In addition the storage time of core dump files is restricted by <command>systemd-tmpfiles</command>,
+ corresponding settings are by default in <filename>/usr/lib/tmpfiles.d/systemd.conf</filename>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Usage</title>
+ <para>Data stored in the journal can be viewed with
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- log viewer,
+ as usual.
<citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- may be used to list and extract coredumps.</para>
+ can be used to retrieve saved core dumps independent of their location, to display information and to process
+ them e.g. by passing to the GNU debugger (gdb).</para>
</refsect1>
<refsect1>
@@ -97,6 +136,7 @@
<citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-sysctl.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
diff --git a/man/systemd-importd.service.xml b/man/systemd-importd.service.xml
new file mode 100644
index 0000000000..8fdced475c
--- /dev/null
+++ b/man/systemd-importd.service.xml
@@ -0,0 +1,82 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-importd.service" conditional='ENABLE_IMPORTD'>
+
+ <refentryinfo>
+ <title>systemd-importd.service</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-importd.service</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-importd.service</refname>
+ <refname>systemd-importd</refname>
+ <refpurpose>VM and container image import and export service</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>systemd-importd.service</filename></para>
+ <para><filename>/usr/lib/systemd/systemd-importd</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><command>systemd-importd</command> is a system service that allows importing, exporting and downloading of
+ system images suitable for running as VM or containers. It is a companion service for
+ <citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, and provides the implementation for
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+ <command>pull-raw</command>, <command>pull-tar</command>, <command>import-raw</command>,
+ <command>import-tar</command>, <command>export-raw</command>, and <command>export-tar</command> commands.</para>
+
+ <para>See the
+ <ulink url="http://www.freedesktop.org/wiki/Software/systemd/importd">
+ importd D-Bus API Documentation</ulink> for information about the
+ APIs <filename>systemd-importd</filename> provides.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
index e32ac26850..9ed85c3950 100644
--- a/man/systemd-journal-gatewayd.service.xml
+++ b/man/systemd-journal-gatewayd.service.xml
@@ -262,7 +262,7 @@
<term><uri>boot</uri></term>
<listitem><para>Limit events to the current boot of the system
- (like <command>journalctl --this--boot</command>).</para></listitem>
+ (like <command>journalctl --this-boot</command>).</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index bd7392c2a2..476cc2932f 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -58,7 +58,7 @@
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-nspawn</command>
- <arg choice="plain">-b</arg>
+ <arg choice="plain">--boot</arg>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="opt" rep="repeat">ARGS</arg>
</cmdsynopsis>
@@ -263,7 +263,7 @@
signals. It is recommended to use this mode to invoke arbitrary commands in containers, unless they have been
modified to run correctly as PID 1. Or in other words: this switch should be used for pretty much all commands,
except when the command refers to an init or shell implementation, as these are generally capable of running
- correctly as PID 1). This option may not be combined with <option>--boot</option> or
+ correctly as PID 1. This option may not be combined with <option>--boot</option> or
<option>--share-system</option>.</para>
</listitem>
</varlistentry>
@@ -294,12 +294,12 @@
<tbody>
<row>
<entry>Neither <option>--as-pid2</option> nor <option>--boot</option> specified</entry>
- <entry>The passed parameters are interpreted as command line, which is executed as PID 1 in the container.</entry>
+ <entry>The passed parameters are interpreted as the command line, which is executed as PID 1 in the container.</entry>
</row>
<row>
<entry><option>--as-pid2</option> specified</entry>
- <entry>The passed parameters are interpreted as command line, which are executed as PID 2 in the container. A stub init process is run as PID 1.</entry>
+ <entry>The passed parameters are interpreted as the command line, which is executed as PID 2 in the container. A stub init process is run as PID 1.</entry>
</row>
<row>
@@ -355,7 +355,9 @@
<listitem><para>Set the specified UUID for the container. The
init system will initialize
<filename>/etc/machine-id</filename> from this if this file is
- not set yet. </para></listitem>
+ not set yet. Note that this option takes effect only if
+ <filename>/etc/machine-id</filename> in the container is
+ unpopulated.</para></listitem>
</varlistentry>
<varlistentry>
@@ -385,38 +387,79 @@
<varlistentry>
<term><option>--private-users=</option></term>
- <listitem><para>Enables user namespacing. If enabled, the
- container will run with its own private set of Unix user and
- group ids (UIDs and GIDs). Takes none, one or two
- colon-separated parameters: the first parameter specifies the
- first host UID to assign to the container, the second
- parameter specifies the number of host UIDs to assign to the
- container. If the second parameter is omitted, 65536 UIDs are
- assigned. If the first parameter is also omitted (and hence
- no parameter passed at all), the first UID assigned to the
- container is read from the owner of the root directory of the
- container's directory tree. By default, no user namespacing is
- applied.</para>
-
- <para>Note that user namespacing currently requires OS trees
- that are prepared for the UID shift that is being applied:
- UIDs and GIDs used for file ownership or in file ACL entries
- must be shifted to the container UID base that is
- used during container runtime.</para>
+ <listitem><para>Controls user namespacing. If enabled, the container will run with its own private set of UNIX
+ user and group ids (UIDs and GIDs). This involves mapping the private UIDs/GIDs used in the container (starting
+ with the container's root user 0 and up) to a range of UIDs/GIDs on the host that are not used for other
+ purposes (usually in the range beyond the host's UID/GID 65536). The parameter may be specified as follows:</para>
+
+ <orderedlist>
+ <listitem><para>The value <literal>no</literal> turns off user namespacing. This is the default.</para></listitem>
+
+ <listitem><para>The value <literal>yes</literal> (or the omission of a parameter) turns on user
+ namespacing. The UID/GID range to use is determined automatically from the file ownership of the root
+ directory of the container's directory tree. To use this option, make sure to prepare the directory tree in
+ advance, and ensure that all files and directories in it are owned by UIDs/GIDs in the range you'd like to
+ use. Also, make sure that used file ACLs exclusively reference UIDs/GIDs in the appropriate range. If this
+ mode is used the number of UIDs/GIDs assigned to the container for use is 65536, and the UID/GID of the
+ root directory must be a multiple of 65536.</para></listitem>
+
+ <listitem><para>The value "pick" turns on user namespacing. In this case the UID/GID range is automatically
+ chosen. As first step, the file owner of the root directory of the container's directory tree is read, and it
+ is checked that it is currently not used by the system otherwise (in particular, that no other container is
+ using it). If this check is successful, the UID/GID range determined this way is used, similar to the
+ behaviour if "yes" is specified. If the check is not successful (and thus the UID/GID range indicated in the
+ root directory's file owner is already used elsewhere) a new – currently unused – UID/GID range of 65536
+ UIDs/GIDs is randomly chosen between the host UID/GIDs of 524288 and 1878982656, always starting at a
+ multiple of 65536. This setting implies <option>--private-users-chown</option> (see below), which has the
+ effect that the files and directories in the container's directory tree will be owned by the appropriate
+ users of the range picked. Using this option makes user namespace behaviour fully automatic. Note that the
+ first invocation of a previously unused container image might result in picking a new UID/GID range for it,
+ and thus in the (possibly expensive) file ownership adjustment operation. However, subsequent invocations of
+ the container will be cheap (unless of course the picked UID/GID range is assigned to a different use by
+ then).</para></listitem>
+
+ <listitem><para>Finally if one or two colon-separated numeric parameters are specified, user namespacing is
+ turned on, too. The first parameter specifies the first host UID/GID to assign to the container, the second
+ parameter specifies the number of host UIDs/GIDs to assign to the container. If the second parameter is
+ omitted, 65536 UIDs/GIDs are assigned.</para></listitem>
+ </orderedlist>
+
+ <para>It is recommended to assign at least 65536 UIDs/GIDs to each container, so that the usable UID/GID range in the
+ container covers 16 bit. For best security, do not assign overlapping UID/GID ranges to multiple containers. It is
+ hence a good idea to use the upper 16 bit of the host 32-bit UIDs/GIDs as container identifier, while the lower 16
+ bit encode the container UID/GID used. This is in fact the behaviour enforced by the
+ <option>--private-users=pick</option> option.</para>
+
+ <para>When user namespaces are used, the GID range assigned to each container is always chosen identical to the
+ UID range.</para>
+
+ <para>In most cases, using <option>--private-users=pick</option> is the recommended option as it enhances
+ container security massively and operates fully automatically in most cases.</para>
+
+ <para>Note that the picked UID/GID range is not written to <filename>/etc/passwd</filename> or
+ <filename>/etc/group</filename>. In fact, the allocation of the range is not stored persistently anywhere,
+ except in the file ownership of the files and directories of the container.</para></listitem>
+ </varlistentry>
- <para>It is recommended to assign at least 65536 UIDs to each
- container, so that the usable UID range in the container
- covers 16 bit. For best security, do not assign overlapping UID
- ranges to multiple containers. It is hence a good idea to use
- the upper 16 bit of the host 32-bit UIDs as container
- identifier, while the lower 16 bit encode the container UID
- used.</para>
+ <varlistentry>
+ <term><option>-U</option></term>
- <para>When user namespaces are used, the GID range assigned to
- each container is always chosen identical to the UID
- range.</para></listitem>
+ <listitem><para>If the kernel supports the user namespaces feature, equivalent to
+ <option>--private-users=pick</option>, otherwise equivalent to
+ <option>--private-users=no</option>.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--private-users-chown</option></term>
+
+ <listitem><para>If specified, all files and directories in the container's directory tree will adjusted so that
+ they are owned to the appropriate UIDs/GIDs selected for the container (see above). This operation is
+ potentially expensive, as it involves descending and iterating through the full directory tree of the
+ container. Besides actual file ownership, file ACLs are adjusted as well.</para>
+
+ <para>This option is implied if <option>--private-users=pick</option> is used. This option has no effect if
+ user namespacing is not used.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>--private-network</option></term>
@@ -481,15 +524,23 @@
<term><option>-n</option></term>
<term><option>--network-veth</option></term>
- <listitem><para>Create a virtual Ethernet link
- (<literal>veth</literal>) between host and container. The host
- side of the Ethernet link will be available as a network
- interface named after the container's name (as specified with
- <option>--machine=</option>), prefixed with
- <literal>ve-</literal>. The container side of the Ethernet
- link will be named <literal>host0</literal>. Note that
- <option>--network-veth</option> implies
- <option>--private-network</option>.</para></listitem>
+ <listitem><para>Create a virtual Ethernet link (<literal>veth</literal>) between host and container. The host
+ side of the Ethernet link will be available as a network interface named after the container's name (as
+ specified with <option>--machine=</option>), prefixed with <literal>ve-</literal>. The container side of the
+ Ethernet link will be named <literal>host0</literal>. The <option>--network-veth</option> option implies
+ <option>--private-network</option>.</para>
+
+ <para>Note that
+ <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ includes by default a network file <filename>/usr/lib/systemd/network/80-container-ve.network</filename>
+ matching the host-side interfaces created this way, which contains settings to enable automatic address
+ provisioning on the created virtual link via DHCP, as well as automatic IP routing onto the host's external
+ network interfaces. It also contains <filename>/usr/lib/systemd/network/80-container-host0.network</filename>
+ matching the container-side interface created this way, containing settings to enable client side address
+ assignment via DHCP. In case <filename>systemd-networkd</filename> is running on both the host and inside the
+ container, automatic IP communication from the container to the host is thus available, with further
+ connectivity to the external network.</para>
+ </listitem>
</varlistentry>
<varlistentry>
@@ -500,7 +551,7 @@
host interface name and container interface name. The latter
may be omitted in which case the container and host sides will
be assigned the same name. This switch is independent of
- <option>--network-veth</option>, and -- in contrast -- may be
+ <option>--network-veth</option>, and — in contrast — may be
used multiple times, and allows configuration of the network
interface names. Note that <option>--network-bridge=</option>
has no effect on interfaces created with
@@ -510,16 +561,43 @@
<varlistentry>
<term><option>--network-bridge=</option></term>
- <listitem><para>Adds the host side of the Ethernet link
- created with <option>--network-veth</option> to the specified
- bridge. Note that <option>--network-bridge=</option> implies
- <option>--network-veth</option>. If this option is used, the
- host side of the Ethernet link will use the
- <literal>vb-</literal> prefix instead of
+ <listitem><para>Adds the host side of the Ethernet link created with <option>--network-veth</option> to the
+ specified Ethernet bridge interface. Expects a valid network interface name of a bridge device as
+ argument. Note that <option>--network-bridge=</option> implies <option>--network-veth</option>. If this option
+ is used, the host side of the Ethernet link will use the <literal>vb-</literal> prefix instead of
<literal>ve-</literal>.</para></listitem>
</varlistentry>
<varlistentry>
+ <term><option>--network-zone=</option></term>
+
+ <listitem><para>Creates a virtual Ethernet link (<literal>veth</literal>) to the container and adds it to an
+ automatically managed Ethernet bridge interface. The bridge interface is named after the passed argument,
+ prefixed with <literal>vz-</literal>. The bridge interface is automatically created when the first container
+ configured for its name is started, and is automatically removed when the last container configured for its
+ name exits. Hence, each bridge interface configured this way exists only as long as there's at least one
+ container referencing it running. This option is very similar to <option>--network-bridge=</option>, besides
+ this automatic creation/removal of the bridge device.</para>
+
+ <para>This setting makes it easy to place multiple related containers on a common, virtual Ethernet-based
+ broadcast domain, here called a "zone". Each container may only be part of one zone, but each zone may contain
+ any number of containers. Each zone is referenced by its name. Names may be chosen freely (as long as they form
+ valid network interface names when prefixed with <literal>vz-</literal>), and it is sufficient to pass the same
+ name to the <option>--network-zones=</option> switch of the various concurrently running containers to join
+ them in one zone.</para>
+
+ <para>Note that
+ <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ includes by default a network file <filename>/usr/lib/systemd/network/80-container-vz.network</filename>
+ matching the bridge interfaces created this way, which contains settings to enable automatic address
+ provisioning on the created virtual network via DHCP, as well as automatic IP routing onto the host's external
+ network interfaces. Using <option>--network-zone=</option> is hence in most cases fully automatic and
+ sufficient to connect multiple local containers in a joined broadcast domain to the host, with further
+ connectivity to the external network.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-p</option></term>
<term><option>--port=</option></term>
@@ -534,7 +612,7 @@
port number and its colon may be omitted, in which case the
same port as the host port is implied. This option is only
supported if private networking is used, such as with
- <option>--network-veth</option> or
+ <option>--network-veth</option>, <option>--network-zone=</option>
<option>--network-bridge=</option>.</para></listitem>
</varlistentry>
@@ -595,9 +673,8 @@
order to trigger an orderly shutdown of the
container. Defaults to SIGRTMIN+3 if <option>--boot</option>
is used (on systemd-compatible init systems SIGRTMIN+3
- triggers an orderly shutdown). Takes a signal name like
- <literal>SIGHUP</literal>, <literal>SIGTERM</literal> or
- similar as argument.</para></listitem>
+ triggers an orderly shutdown). For a list of valid signals, see
+ <citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -736,7 +813,8 @@
</varlistentry>
<varlistentry>
- <term><option>--setenv=</option></term>
+ <term><option>-E <replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+ <term><option>--setenv=<replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
<listitem><para>Specifies an environment variable assignment
to pass to the init process in the container, in the format
diff --git a/man/systemd-resolve.xml b/man/systemd-resolve.xml
index f1e663c5bb..4b66f836a2 100644
--- a/man/systemd-resolve.xml
+++ b/man/systemd-resolve.xml
@@ -65,7 +65,7 @@
<command>systemd-resolve</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<command> --type=<replaceable>TYPE</replaceable></command>
- <arg choice="plain" rep="repeat"><replaceable>RRDOMAIN</replaceable></arg>
+ <arg choice="plain" rep="repeat"><replaceable>DOMAIN</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
@@ -79,6 +79,20 @@
<cmdsynopsis>
<command>systemd-resolve</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
+ <command> --openpgp</command>
+ <arg choice="plain"><replaceable>USER@DOMAIN</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>systemd-resolve</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <command> --tlsa</command>
+ <arg choice="plain"><replaceable>DOMAIN<optional>:PORT</optional></replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>systemd-resolve</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
<command> --statistics</command>
</cmdsynopsis>
@@ -114,8 +128,17 @@
is assumed to be a domain name, that is already prefixed with an SRV type, and an SRV lookup is done (no
TXT).</para>
+ <para>The <option>--openpgp</option> switch may be used to query PGP keys stored as
+ <ulink url="https://tools.ietf.org/html/draft-wouters-dane-openpgp-02">OPENPGPKEY</ulink> resource records.
+ When this option is specified one or more e-mail address must be specified.</para>
+
+ <para>The <option>--tlsa</option> switch maybe be used to query TLS public
+ keys stored as
+ <ulink url="https://tools.ietf.org/html/rfc6698">TLSA</ulink> resource records.
+ When this option is specified one or more domain names must be specified.</para>
+
<para>The <option>--statistics</option> switch may be used to show resolver statistics, including information about
- the number of succesful and failed DNSSEC validations.</para>
+ the number of successful and failed DNSSEC validations.</para>
<para>The <option>--reset-statistics</option> may be used to reset various statistics counters maintained the
resolver, including those shown in the <option>--statistics</option> output. This operation requires root
@@ -152,7 +175,7 @@
<listitem><para>Specifies the network protocol for the query. May be one of <literal>dns</literal>
(i.e. classic unicast DNS), <literal>llmnr</literal> (<ulink
url="https://tools.ietf.org/html/rfc4795">Link-Local Multicast Name Resolution</ulink>),
- <literal>llmr-ipv4</literal>, <literal>llmnr-ipv6</literal> (LLMNR via the indicated underlying IP
+ <literal>llmnr-ipv4</literal>, <literal>llmnr-ipv6</literal> (LLMNR via the indicated underlying IP
protocols). By default the lookup is done via all protocols suitable for the lookup. If used, limits the set of
protocols that may be used. Use this option multiple times to enable resolving via multiple protocols at the
same time. The setting <literal>llmnr</literal> is identical to specifying this switch once with
@@ -198,6 +221,28 @@
</varlistentry>
<varlistentry>
+ <term><option>--openpgp</option></term>
+
+ <listitem><para>Enables OPENPGPKEY resource record resolution (see above). Specified e-mail
+ addresses are converted to the corresponding DNS domain name, and any OPENPGPKEY keys are
+ printed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--tlsa</option></term>
+
+ <listitem><para>Enables TLSA resource record resolution (see above).
+ A query will be performed for each of the specified names prefixed with
+ the port and family
+ (<literal>_<replaceable>port</replaceable>._<replaceable>family</replaceable>.<replaceable>domain</replaceable></literal>).
+ The port number may be specified after a colon
+ (<literal>:</literal>), otherwise <constant>443</constant> will be used
+ by default. The family may be specified as an argument after
+ <option>--tlsa</option>, otherwise <constant>tcp</constant> will be
+ used.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--cname=</option><replaceable>BOOL</replaceable></term>
<listitem><para>Takes a boolean parameter. If true (the default), DNS CNAME or DNAME redirections are
@@ -214,6 +259,16 @@
</varlistentry>
<varlistentry>
+ <term><option>--raw</option><optional>=payload|packet</optional></term>
+
+ <listitem><para>Dump the answer as binary data. If there is no argument or if the argument is
+ <literal>payload</literal>, the payload of the packet is exported. If the argument is
+ <literal>packet</literal>, the whole packet is dumped in wire format, prefixed by
+ length specified as a little-endian 64-bit number. This format allows multiple packets
+ to be dumped and unambigously parsed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--legend=</option><replaceable>BOOL</replaceable></term>
<listitem><para>Takes a boolean parameter. If true (the default), column headers and meta information about the
@@ -244,27 +299,70 @@
<example>
<title>Retrieve the addresses of the <literal>www.0pointer.net</literal> domain</title>
- <programlisting>$ systemd-resolve www.0pointer.net</programlisting>
+ <programlisting>$ systemd-resolve www.0pointer.net
+www.0pointer.net: 2a01:238:43ed:c300:10c3:bcf3:3266:da74
+ 85.214.157.71
+
+-- Information acquired via protocol DNS in 611.6ms.
+-- Data is authenticated: no
+</programlisting>
</example>
<example>
<title>Retrieve the domain of the <literal>85.214.157.71</literal> IP address</title>
- <programlisting>$ systemd-resolve 85.214.157.71</programlisting>
+ <programlisting>$ systemd-resolve 85.214.157.71
+85.214.157.71: gardel.0pointer.net
+
+-- Information acquired via protocol DNS in 1.2997s.
+-- Data is authenticated: no
+</programlisting>
</example>
<example>
<title>Retrieve the MX record of the <literal>0pointer.net</literal> domain</title>
- <programlisting>$ systemd-resolve -t MX 0pointer.net</programlisting>
+ <programlisting>$ systemd-resolve -t MX yahoo.com --legend=no
+yahoo.com. IN MX 1 mta7.am0.yahoodns.net
+yahoo.com. IN MX 1 mta6.am0.yahoodns.net
+yahoo.com. IN MX 1 mta5.am0.yahoodns.net
+</programlisting>
</example>
<example>
<title>Resolve an SRV service</title>
- <programlisting>$ systemd-resolve --service _xmpp-server._tcp gmail.com</programlisting>
+ <programlisting>$ systemd-resolve --service _xmpp-server._tcp gmail.com
+_xmpp-server._tcp/gmail.com: alt1.xmpp-server.l.google.com:5269 [priority=20, weight=0]
+ 173.194.210.125
+ alt4.xmpp-server.l.google.com:5269 [priority=20, weight=0]
+ 173.194.65.125
+ ...
+</programlisting>
</example>
+ <example>
+ <title>Retrieve a PGP key</title>
+
+ <programlisting>$ systemd-resolve --openpgp zbyszek@fedoraproject.org
+d08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org. IN OPENPGPKEY
+ mQINBFBHPMsBEACeInGYJCb+7TurKfb6wGyTottCDtiSJB310i37/6ZYoeIay/5soJjlMyf
+ MFQ9T2XNT/0LM6gTa0MpC1st9LnzYTMsT6tzRly1D1UbVI6xw0g0vE5y2Cjk3xUwAynCsSs
+ ...
+</programlisting>
+ </example>
+
+ <example>
+ <title>Retrieve a TLS key (<literal>=tcp</literal> and
+ <literal>:443</literal> could be skipped)</title>
+
+ <programlisting>$ systemd-resolve --tlsa=tcp fedoraproject.org:443
+_443._tcp.fedoraproject.org IN TLSA 0 0 1 19400be5b7a31fb733917700789d2f0a2471c0c9d506c0e504c06c16d7cb17c0
+ -- Cert. usage: CA constraint
+ -- Selector: Full Certificate
+ -- Matching type: SHA-256
+</programlisting>
+ </example>
</refsect1>
<refsect1>
diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml
index 7a9e23a2c6..829729ca09 100644
--- a/man/systemd-resolved.service.xml
+++ b/man/systemd-resolved.service.xml
@@ -87,9 +87,10 @@
is on the local loopback) and the IPv6 address ::1 (which is the
local host).</para></listitem>
- <listitem><para>The hostname <literal>localhost</literal> (as well as any hostname ending in
- <literal>.localhost</literal>, <literal>.localdomain</literal> or equal to <literal>localdomain</literal>) is
- resolved to the IP addresses 127.0.0.1 and ::1.</para></listitem>
+ <listitem><para>The hostnames <literal>localhost</literal> and
+ <literal>localhost.localdomain</literal> (as well as any hostname
+ ending in <literal>.localhost</literal> or <literal>.localhost.localdomain</literal>)
+ are resolved to the IP addresses 127.0.0.1 and ::1.</para></listitem>
<listitem><para>The hostname <literal>gateway</literal> is
resolved to all current default routing gateway addresses,
diff --git a/man/systemd-run.xml b/man/systemd-run.xml
index 414e1c8335..9c1a29218e 100644
--- a/man/systemd-run.xml
+++ b/man/systemd-run.xml
@@ -226,11 +226,11 @@
</varlistentry>
<varlistentry>
- <term><option>--setenv=</option></term>
+ <term><option>-E <replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+ <term><option>--setenv=<replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
- <listitem><para>Runs the service process with the specified
- environment variables set. Also see
- <varname>Environment=</varname> in
+ <listitem><para>Runs the service process with the specified environment variable set.
+ Also see <varname>Environment=</varname> in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
@@ -341,33 +341,41 @@
<refsect1>
<title>Examples</title>
- <para>The following command will log the environment variables
- provided by systemd to services:</para>
+ <example>
+ <title>Logging environment variables provided by systemd to services</title>
- <programlisting># systemd-run env
-Running as unit run-19945.service.
+ <programlisting># systemd-run env
+Running as unit: run-19945.service
# journalctl -u run-19945.service
Sep 08 07:37:21 bupkis systemd[1]: Starting /usr/bin/env...
Sep 08 07:37:21 bupkis systemd[1]: Started /usr/bin/env.
Sep 08 07:37:21 bupkis env[19948]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Sep 08 07:37:21 bupkis env[19948]: LANG=en_US.UTF-8
Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20.x86_64</programlisting>
+ </example>
+
+ <example>
+ <title>Limiting resources available to a command</title>
+
+ <programlisting># systemd-run -p BlockIOWeight=10 updatedb</programlisting>
- <para>The following command invokes the
- <citerefentry project='man-pages'><refentrytitle>updatedb</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- tool, but lowers the block I/O weight for it to 10. See
- <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for more information on the <varname>BlockIOWeight=</varname>
- property.</para>
+ <para>This command invokes the
+ <citerefentry project='man-pages'><refentrytitle>updatedb</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ tool, but lowers the block I/O weight for it to 10. See
+ <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more information on the <varname>BlockIOWeight=</varname>
+ property.</para>
+ </example>
- <programlisting># systemd-run -p BlockIOWeight=10 updatedb</programlisting>
+ <example>
+ <title>Running commands at a specified time</title>
- <para>The following command will touch a file after 30 seconds.</para>
+ <para>The following command will touch a file after 30 seconds.</para>
- <programlisting># date; systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo
+ <programlisting># date; systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo
Mon Dec 8 20:44:24 KST 2014
-Running as unit run-71.timer.
-Will run as unit run-71.service.
+Running as unit: run-71.timer
+Will run service as unit: run-71.service
# journalctl -b -u run-71.timer
-- Logs begin at Fri 2014-12-05 19:09:21 KST, end at Mon 2014-12-08 20:44:54 KST. --
Dec 08 20:44:38 container systemd[1]: Starting /bin/touch /tmp/foo.
@@ -376,13 +384,60 @@ Dec 08 20:44:38 container systemd[1]: Started /bin/touch /tmp/foo.
-- Logs begin at Fri 2014-12-05 19:09:21 KST, end at Mon 2014-12-08 20:44:54 KST. --
Dec 08 20:44:48 container systemd[1]: Starting /bin/touch /tmp/foo...
Dec 08 20:44:48 container systemd[1]: Started /bin/touch /tmp/foo.</programlisting>
-
- <para>The following command invokes <filename>/bin/bash</filename>
- as a service passing its standard input, output and error to
- the calling TTY.</para>
-
- <programlisting># systemd-run -t --send-sighup /bin/bash</programlisting>
-
+ </example>
+
+ <example>
+ <title>Allowing access to the tty</title>
+
+ <para>The following command invokes <filename>/bin/bash</filename> as a service
+ passing its standard input, output and error to the calling TTY.</para>
+
+ <programlisting># systemd-run -t --send-sighup /bin/bash</programlisting>
+ </example>
+
+ <example>
+ <title>Start <command>screen</command> as a user service</title>
+
+ <programlisting>$ systemd-run --scope --user screen
+Running scope as unit run-r14b0047ab6df45bfb45e7786cc839e76.scope.
+
+$ screen -ls
+There is a screen on:
+ 492..laptop (Detached)
+1 Socket in /var/run/screen/S-fatima.
+</programlisting>
+
+ <para>This starts the <command>screen</command> process as a child of the
+ <command>systemd --user</command> process that was started by
+ <filename>user@.service</filename>, in a scope unit. A
+ <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ unit is used instead of a
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ unit, because <command>screen</command> will exit when detaching from the terminal,
+ and a service unit would be terminated. Running <command>screen</command>
+ as a user unit has the advantage that it is not part of the session scope.
+ If <varname>KillUserProcesses=yes</varname> is configured in
+ <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ the default, the session scope will be terminated when the user logs
+ out of that session.</para>
+
+ <para>The <filename>user@.service</filename> is started automatically
+ when the user first logs in, and stays around as long as at least one
+ login session is open. After the user logs out of the last session,
+ <filename>user@.service</filename> and all services underneath it
+ are terminated. This behaviour is the default, when "lingering" is
+ not enabled for that user. Enabling lingering means that
+ <filename>user@.service</filename> is started automatically during
+ boot, even if the user is not logged in, and that the service is
+ not terminated when the user logs out.</para>
+
+ <para>Enabling lingering allows the user to run processes without being logged in,
+ for example to allow <command>screen</command> to persist after the user logs out,
+ even if the session scope is terminated. In the default configuration, users can
+ enable lingering for themselves:</para>
+
+ <programlisting>$ loginctl enable-linger</programlisting>
+ </example>
</refsect1>
<refsect1>
diff --git a/src/systemd-activate/systemd-activate.xml b/man/systemd-socket-activate.xml
index 995e6eecce..5d7f157c72 100644
--- a/src/systemd-activate/systemd-activate.xml
+++ b/man/systemd-socket-activate.xml
@@ -21,11 +21,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd-activate"
+<refentry id="systemd-socket-activate"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
- <title>systemd-activate</title>
+ <title>systemd-socket-activate</title>
<productname>systemd</productname>
<authorgroup>
@@ -39,18 +39,18 @@
</refentryinfo>
<refmeta>
- <refentrytitle>systemd-activate</refentrytitle>
- <manvolnum>8</manvolnum>
+ <refentrytitle>systemd-socket-activate</refentrytitle>
+ <manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
- <refname>systemd-activate</refname>
+ <refname>systemd-socket-activate</refname>
<refpurpose>Test socket activation of daemons</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
- <command>/usr/lib/systemd/systemd-activate</command>
+ <command>systemd-socket-activate</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain"><replaceable>daemon</replaceable></arg>
<arg choice="opt" rep="repeat">OPTIONS</arg>
@@ -60,20 +60,20 @@
<refsect1>
<title>Description</title>
- <para><command>systemd-activate</command> may be used to launch a socket-activated service binary from the command
+ <para><command>systemd-socket-activate</command> may be used to launch a socket-activated service binary from the command
line for testing purposes. It may also be used to launch individual instances of the service binary per connection.
</para>
<para>The daemon to launch and its options should be specified
- after options intended for <command>systemd-activate</command>.
+ after options intended for <command>systemd-socket-activate</command>.
</para>
<para>If the <option>--inetd</option> option is given, the socket file descriptor will be used as the standard
input and output of the launched process. Otherwise, standard input and output will be inherited, and sockets will
be passed through file descriptors 3 and higher. Sockets passed through <varname>$LISTEN_FDS</varname> to
- <command>systemd-activate</command> will be passed through to the daemon, in the original positions. Other sockets
+ <command>systemd-socket-activate</command> will be passed through to the daemon, in the original positions. Other sockets
specified with <option>--listen=</option> will use consecutive descriptors. By default,
- <command>systemd-activate</command> listens on a stream socket, use <option>--datagram</option> and
+ <command>systemd-socket-activate</command> listens on a stream socket, use <option>--datagram</option> and
<option>--seqpacket</option> to listen on datagram or sequential packet sockets instead (see below).
</para>
</refsect1>
@@ -131,18 +131,20 @@
launched process. If <replaceable>VAR</replaceable> is
followed by <literal>=</literal>, assume that it is a
variable–value pair. Otherwise, obtain the value from the
- environment of <command>systemd-activate</command> itself.
+ environment of <command>systemd-socket-activate</command> itself.
</para></listitem>
</varlistentry>
<varlistentry>
- <term><option>--fdname=</option><replaceable>NAME</replaceable></term>
-
- <listitem><para>Specify a name for the activation file
- descriptors. This is equivalent to setting
- <varname>FileDescriptorName=</varname> in socket unit files, and
- enables use of
- <citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+ <term><option>--fdname=</option><replaceable>NAME</replaceable><optional>:<replaceable>NAME</replaceable>...</optional></term>
+
+ <listitem><para>Specify names for the file descriptors passed. This is equivalent to setting
+ <varname>FileDescriptorName=</varname> in socket unit files, and enables use of
+ <citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ Multiple entries may be specifies using separate options or by separating names with colons
+ (<literal>:</literal>) in one option. In case more names are given than descriptors, superflous ones willl be
+ ignored. In case less names are given than descriptors, the remaining file descriptors will be unnamed.
+ </para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
@@ -180,13 +182,13 @@
<example>
<title>Run an echo server on port 2000</title>
- <programlisting>$ /usr/lib/systemd/systemd-activate -l 2000 --inetd -a cat</programlisting>
+ <programlisting>$ systemd-socket-activate -l 2000 --inetd -a cat</programlisting>
</example>
<example>
<title>Run a socket-activated instance of <citerefentry><refentrytitle>systemd-journal-gatewayd</refentrytitle><manvolnum>8</manvolnum></citerefentry></title>
- <programlisting>$ /usr/lib/systemd/systemd-activate -l 19531 /usr/lib/systemd/systemd-journal-gatewayd</programlisting>
+ <programlisting>$ systemd-socket-activate -l 19531 /usr/lib/systemd/systemd-journal-gatewayd</programlisting>
</example>
</refsect1>
diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml
index 9027ff0f3f..686b2cdef4 100644
--- a/man/systemd-sysctl.service.xml
+++ b/man/systemd-sysctl.service.xml
@@ -62,24 +62,29 @@
<para><filename>systemd-sysctl.service</filename> is an early boot
service that configures
<citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- kernel parameters.</para>
+ kernel parameters by invoking <command>/usr/lib/systemd/systemd-sysctl</command>.</para>
- <para>If invoked with no arguments, it applies all directives from
- all configuration files in
- <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- are searched for a matching file. If one or more filenames are passed on
- the command line, only the directives in these files are applied.
- </para>
+ <para>When invoked with no arguments, <command>/usr/lib/systemd/systemd-sysctl</command> applies
+ all directives from configuration files listed in
+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ If one or more filenames are passed on the command line, only the directives in these files are
+ applied.</para>
+
+ <para>In addition, <option>--prefix=</option> option may be used to limit which sysctl
+ settings are applied.</para>
<para>See
<citerefentry project='man-pages'><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for information about the configuration of this service.</para>
+ for information about the configuration of sysctl settings. After sysctl configuration is
+ changed on disk, it must be written to the files in <filename>/proc/sys</filename> before it
+ takes effect. It is possible to update specific settings, or simply to reload all configuration,
+ see Examples below.</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
- <varlistentry id='path'>
- <term><option>--path=</option></term>
+ <varlistentry id='prefix'>
+ <term><option>--prefix=</option></term>
<listitem>
<para>Only apply rules with the specified prefix.</para>
</listitem>
@@ -92,6 +97,50 @@
</refsect1>
<refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Reset all sysctl settings</title>
+
+ <programlisting>systemctl restart systemd-sysctl</programlisting>
+ </example>
+
+ <example>
+ <title>View coredump handler configuration</title>
+
+ <programlisting># sysctl kernel.core_pattern
+kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t %P %I
+</programlisting>
+ </example>
+
+ <example>
+ <title>Update coredump handler configuration</title>
+
+ <programlisting># /usr/lib/systemd/systemd-sysctl --prefix kernel.core_pattern</programlisting>
+
+ <para>This searches all the directories listed in
+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for configuration files and writes <filename>/proc/sys/kernel/core_pattern</filename>.</para>
+ </example>
+
+ <example>
+ <title>Update coredump handler configuration according to a specific file</title>
+
+ <programlisting># /usr/lib/systemd/systemd-sysctl 50-coredump.conf</programlisting>
+
+ <para>This applies all the settings found in <filename>50-coredump.conf</filename>.
+ Either <filename>/etc/sysctl.d/50-coredump.conf</filename>, or
+ <filename>/run/sysctl.d/50-coredump.conf</filename>, or
+ <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> will be used, in the order
+ of preference.</para>
+ </example>
+
+ <para>See
+ <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for various ways to directly apply sysctl settings.</para>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index edc6df914a..8833e73c72 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -271,16 +271,16 @@
</varlistentry>
<varlistentry>
- <term><varname>DefaultStartLimitInterval=</varname></term>
+ <term><varname>DefaultStartLimitIntervalSec=</varname></term>
<term><varname>DefaultStartLimitBurst=</varname></term>
<listitem><para>Configure the default unit start rate
limiting, as configured per-service by
- <varname>StartLimitInterval=</varname> and
+ <varname>StartLimitIntervalSec=</varname> and
<varname>StartLimitBurst=</varname>. See
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details on the per-service settings.
- <varname>DefaultStartLimitInterval=</varname> defaults to
+ <varname>DefaultStartLimitIntervalSec=</varname> defaults to
10s. <varname>DefaultStartLimitBurst=</varname> defaults to
5.</para></listitem>
</varlistentry>
diff --git a/man/systemd-sysv-generator.xml b/man/systemd-sysv-generator.xml
index bb5cc55e9f..2353eb3efe 100644
--- a/man/systemd-sysv-generator.xml
+++ b/man/systemd-sysv-generator.xml
@@ -77,7 +77,7 @@
which correspond to runlevels for which the script is
enabled.</para>
- <para><command>systemd</command> does not supports SysV scripts as
+ <para><command>systemd</command> does not support SysV scripts as
part of early boot, so all wrapper units are ordered after
<filename>basic.target</filename>.</para>
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 447a7eaa17..c1aab51551 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -75,11 +75,11 @@
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
- <para>If invoked with no arguments, it applies all directives from
- all configuration files. If one or more absolute filenames are passed on
- the command line, only the directives in these files are applied.
- If only the basename of a configuration file is specified, all
- configuration directories as specified in
+ <para>If invoked with no arguments, it applies all directives from all configuration
+ files. If one or more absolute filenames are passed on the command line, only the
+ directives in these files are applied. If <literal>-</literal> is specified instead
+ of a filename, directives are read from standard input. If only the basename of a
+ configuration file is specified, all configuration directories as specified in
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
are searched for a matching file.</para>
</refsect1>
diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml
index 1b0ae832da..a43dc981bd 100644
--- a/man/systemd.automount.xml
+++ b/man/systemd.automount.xml
@@ -66,14 +66,13 @@
[Install] sections. The automount specific configuration options
are configured in the [Automount] section.</para>
- <para>Automount units must be named after the automount
- directories they control. Example: the automount point
- <filename noindex='true'>/home/lennart</filename> must be
- configured in a unit file
- <filename>home-lennart.automount</filename>. For details about the
- escaping logic used to convert a file system path to a unit name
- see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+ <para>Automount units must be named after the automount directories they control. Example: the automount point
+ <filename noindex='true'>/home/lennart</filename> must be configured in a unit file
+ <filename>home-lennart.automount</filename>. For details about the escaping logic used to convert a file system
+ path to a unit name see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Note that
+ automount units cannot be templated, nor is it possible to add multiple names to an automount unit by creating
+ additional symlinks to its unit file.</para>
<para>For each automount unit file a matching mount unit file (see
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
@@ -97,11 +96,9 @@
<para>An implicit <varname>Before=</varname> dependency is created
between an automount unit and the mount unit it activates.</para>
- <para>Automount units acquire automatic <varname>Before=</varname>
- and <varname>Conflicts=</varname> on
- <filename>umount.target</filename> in order to be stopped during
- shutdown, unless <varname>DefaultDependencies=no</varname> is
- set.</para>
+ <para>Automount units acquire automatic <varname>Before=</varname> and <varname>Conflicts=</varname> on
+ <filename>umount.target</filename> in order to be stopped during shutdown, unless
+ <varname>DefaultDependencies=no</varname> is set in the <literal>[Unit]</literal> section.</para>
</refsect1>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index f0f77c5091..3cf6de8256 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -94,11 +94,9 @@
required to access <filename>/tmp</filename> and
<filename>/var/tmp</filename>.</para>
- <para>Units whose output standard output or error output is
- connected to any other sink but <option>null</option>,
- <option>tty</option> and <option>socket</option> automatically
- acquire dependencies of type <varname>After=</varname> on
- <filename>journald.socket</filename>.</para>
+ <para>Units whose standard output or error output is connected to <option>journal</option>, <option>syslog</option>
+ or <option>kmsg</option> (or their combinations with console output, see below) automatically acquire dependencies
+ of type <varname>After=</varname> on <filename>systemd-journald.socket</filename>.</para>
</refsect1>
<refsect1>
@@ -470,6 +468,10 @@
similar to the same option of
<varname>StandardInput=</varname>.</para>
+ <para>If the standard output (or error output, see below) of a unit is connected to the journal, syslog or the
+ kernel log buffer, the unit will implicitly gain a dependency of type <varname>After=</varname> on
+ <filename>systemd-journald.socket</filename> (also see the automatic dependencies section above).</para>
+
<para>This setting defaults to the value set with
<option>DefaultStandardOutput=</option> in
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
@@ -627,27 +629,23 @@
<term><varname>LimitNICE=</varname></term>
<term><varname>LimitRTPRIO=</varname></term>
<term><varname>LimitRTTIME=</varname></term>
- <listitem><para>These settings set both soft and hard limits
- of various resources for executed processes. See
- <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- for details. The resource limit is possible to specify in two formats,
- <option>value</option> to set soft and hard limits to the same value,
- or <option>soft:hard</option> to set both limits individually (e.g. LimitAS=4G:16G).
- Use the string <varname>infinity</varname> to
- configure no limit on a specific resource. The multiplicative
- suffixes K (=1024), M (=1024*1024) and so on for G, T, P and E
- may be used for resource limits measured in bytes
- (e.g. LimitAS=16G). For the limits referring to time values,
- the usual time units ms, s, min, h and so on may be used (see
- <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for details). Note that if no time unit is specified for
- <varname>LimitCPU=</varname> the default unit of seconds is
- implied, while for <varname>LimitRTTIME=</varname> the default
- unit of microseconds is implied. Also, note that the effective
- granularity of the limits might influence their
- enforcement. For example, time limits specified for
- <varname>LimitCPU=</varname> will be rounded up implicitly to
- multiples of 1s.</para>
+ <listitem><para>Set soft and hard limits on various resources for executed processes. See
+ <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry> for details on
+ the resource limit concept. Resource limits may be specified in two formats: either as single value to set a
+ specific soft and hard limit to the same value, or as colon-separated pair <option>soft:hard</option> to set
+ both limits individually (e.g. <literal>LimitAS=4G:16G</literal>). Use the string <varname>infinity</varname>
+ to configure no limit on a specific resource. The multiplicative suffixes K, M, G, T, P and E (to the base
+ 1024) may be used for resource limits measured in bytes (e.g. LimitAS=16G). For the limits referring to time
+ values, the usual time units ms, s, min, h and so on may be used (see
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details). Note that if no time unit is specified for <varname>LimitCPU=</varname> the default unit of seconds
+ is implied, while for <varname>LimitRTTIME=</varname> the default unit of microseconds is implied. Also, note
+ that the effective granularity of the limits might influence their enforcement. For example, time limits
+ specified for <varname>LimitCPU=</varname> will be rounded up implicitly to multiples of 1s. For
+ <varname>LimitNICE=</varname> the value may be specified in two syntaxes: if prefixed with <literal>+</literal>
+ or <literal>-</literal>, the value is understood as regular Linux nice value in the range -20..19. If not
+ prefixed like this the value is understood as raw resource limit parameter in the range 0..40 (with 0 being
+ equivalent to 1).</para>
<para>Note that most process resource limits configured with
these options are per-process, and processes may fork in order
@@ -778,32 +776,21 @@
<varlistentry>
<term><varname>CapabilityBoundingSet=</varname></term>
- <listitem><para>Controls which capabilities to include in the
- capability bounding set for the executed process. See
- <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for details. Takes a whitespace-separated list of capability
- names as read by
- <citerefentry project='mankier'><refentrytitle>cap_from_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- e.g. <constant>CAP_SYS_ADMIN</constant>,
- <constant>CAP_DAC_OVERRIDE</constant>,
- <constant>CAP_SYS_PTRACE</constant>. Capabilities listed will
- be included in the bounding set, all others are removed. If
- the list of capabilities is prefixed with
- <literal>~</literal>, all but the listed capabilities will be
- included, the effect of the assignment inverted. Note that
- this option also affects the respective capabilities in the
- effective, permitted and inheritable capability sets, on top
- of what <varname>Capabilities=</varname> does. If this option
- is not used, the capability bounding set is not modified on
- process execution, hence no limits on the capabilities of the
- process are enforced. This option may appear more than once, in
- which case the bounding sets are merged. If the empty string
- is assigned to this option, the bounding set is reset to the
- empty capability set, and all prior settings have no effect.
- If set to <literal>~</literal> (without any further argument),
- the bounding set is reset to the full set of available
- capabilities, also undoing any previous
- settings.</para></listitem>
+ <listitem><para>Controls which capabilities to include in the capability bounding set for the executed
+ process. See <citerefentry
+ project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details. Takes a whitespace-separated list of capability names as read by <citerefentry
+ project='mankier'><refentrytitle>cap_from_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ e.g. <constant>CAP_SYS_ADMIN</constant>, <constant>CAP_DAC_OVERRIDE</constant>,
+ <constant>CAP_SYS_PTRACE</constant>. Capabilities listed will be included in the bounding set, all others are
+ removed. If the list of capabilities is prefixed with <literal>~</literal>, all but the listed capabilities
+ will be included, the effect of the assignment inverted. Note that this option also affects the respective
+ capabilities in the effective, permitted and inheritable capability sets. If this option is not used, the
+ capability bounding set is not modified on process execution, hence no limits on the capabilities of the
+ process are enforced. This option may appear more than once, in which case the bounding sets are merged. If the
+ empty string is assigned to this option, the bounding set is reset to the empty capability set, and all prior
+ settings have no effect. If set to <literal>~</literal> (without any further argument), the bounding set is
+ reset to the full set of available capabilities, also undoing any previous settings.</para></listitem>
</varlistentry>
<varlistentry>
@@ -854,20 +841,6 @@
</varlistentry>
<varlistentry>
- <term><varname>Capabilities=</varname></term>
- <listitem><para>Controls the
- <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- set for the executed process. Take a capability string
- describing the effective, permitted and inherited capability
- sets as documented in
- <citerefentry project='mankier'><refentrytitle>cap_from_text</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- Note that these capability sets are usually influenced (and
- filtered) by the capabilities attached to the executed file.
- Due to that <varname>CapabilityBoundingSet=</varname> is
- probably a much more useful setting.</para></listitem>
- </varlistentry>
-
- <varlistentry>
<term><varname>ReadWriteDirectories=</varname></term>
<term><varname>ReadOnlyDirectories=</varname></term>
<term><varname>InaccessibleDirectories=</varname></term>
@@ -884,9 +857,12 @@
reading only, writing will be refused even if the usual file
access controls would permit this. Directories listed in
<varname>InaccessibleDirectories=</varname> will be made
- inaccessible for processes inside the namespace. Note that
- restricting access with these options does not extend to
- submounts of a directory that are created later on. These
+ inaccessible for processes inside the namespace, and may not
+ countain any other mountpoints, including those specified by
+ <varname>ReadWriteDirectories=</varname> or
+ <varname>ReadOnlyDirectories=</varname>.
+ Note that restricting access with these options does not extend
+ to submounts of a directory that are created later on. These
options may be specified more than once, in which case all
directories listed will have limited access from within the
namespace. If the empty string is assigned to this option, the
@@ -957,7 +933,10 @@
(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.</para></listitem>
+ 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 using <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ of <filename>/dev/zero</filename> instead of using <constant>MAP_ANON</constant>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1180,7 +1159,9 @@
first character of the list is <literal>~</literal>, the
effect is inverted: only the listed system calls will result
in immediate process termination (blacklisting). If running in
- user mode and this option is used,
+ user mode, or in system mode, but without the
+ <constant>CAP_SYS_ADMIN</constant> capabiblity (e.g. setting
+ <varname>User=nobody</varname>),
<varname>NoNewPrivileges=yes</varname> is implied. This
feature makes use of the Secure Computing Mode 2 interfaces of
the kernel ('seccomp filtering') and is useful for enforcing a
@@ -1239,8 +1220,10 @@
systems. The special <constant>native</constant> identifier
implicitly maps to the native architecture of the system (or
more strictly: to the architecture the system manager is
- compiled for). If running in user mode and this option is
- used, <varname>NoNewPrivileges=yes</varname> is implied. Note
+ compiled for). If running in user mode, or in system mode,
+ but without the <constant>CAP_SYS_ADMIN</constant>
+ capabiblity (e.g. setting <varname>User=nobody</varname>),
+ <varname>NoNewPrivileges=yes</varname> is implied. Note
that setting this option to a non-empty list implies that
<constant>native</constant> is included too. By default, this
option is set to the empty list, i.e. no architecture system
@@ -1269,8 +1252,10 @@
<function>socketpair()</function> (which creates connected
AF_UNIX sockets only) are unaffected. Note that this option
has no effect on 32-bit x86 and is ignored (but works
- correctly on x86-64). If running in user mode and this option
- is used, <varname>NoNewPrivileges=yes</varname> is implied. By
+ correctly on x86-64). If running in user mode, or in system
+ mode, but without the <constant>CAP_SYS_ADMIN</constant>
+ capabiblity (e.g. setting <varname>User=nobody</varname>),
+ <varname>NoNewPrivileges=yes</varname> is implied. By
default, no restriction applies, all address families are
accessible to processes. If assigned the empty string, any
previous list changes are undone.</para>
@@ -1287,14 +1272,17 @@
<varlistentry>
<term><varname>Personality=</varname></term>
- <listitem><para>Controls which kernel architecture
- <citerefentry project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- shall report, when invoked by unit processes. Takes one of
- <constant>x86</constant> and <constant>x86-64</constant>. This
- is useful when running 32-bit services on a 64-bit host
- system. If not specified, the personality is left unmodified
- and thus reflects the personality of the host system's
- kernel.</para></listitem>
+ <listitem><para>Controls which kernel architecture <citerefentry
+ project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry> shall report,
+ when invoked by unit processes. Takes one of the architecture identifiers <constant>x86</constant>,
+ <constant>x86-64</constant>, <constant>ppc</constant>, <constant>ppc-le</constant>, <constant>ppc64</constant>,
+ <constant>ppc64-le</constant>, <constant>s390</constant> or <constant>s390x</constant>. Which personality
+ architectures are supported depends on the system architecture. Usually the 64bit versions of the various
+ system architectures support their immediate 32bit personality architecture counterpart, but no others. For
+ example, <constant>x86-64</constant> systems support the <constant>x86-64</constant> and
+ <constant>x86</constant> personalities but no others. The personality feature is useful when running 32-bit
+ services on a 64-bit host system. If not specified, the personality is left unmodified and thus reflects the
+ personality of the host system's kernel.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index a9f8a654c8..d5b4d1038d 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -82,6 +82,10 @@
shipped by the system, any user-supplied
<filename>.link</filename> should hence have a lexically earlier
name to be considered at all.</para>
+
+ <para>See
+ <citerefentry><refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for diagnosing problems with <filename>.link</filename> files.</para>
</refsect1>
<refsect1>
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index 4a8d265fed..66cddd72e0 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -82,14 +82,12 @@
will refuse options that are not listed in
<filename>/etc/fstab</filename> if it is not run as UID 0.</para>
- <para>Mount units must be named after the mount point directories
- they control. Example: the mount point
- <filename noindex='true'>/home/lennart</filename> must be
- configured in a unit file <filename>home-lennart.mount</filename>.
- For details about the escaping logic used to convert a file system
- path to a unit name, see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- Note that mount units cannot be templated.</para>
+ <para>Mount units must be named after the mount point directories they control. Example: the mount point <filename
+ noindex='true'>/home/lennart</filename> must be configured in a unit file <filename>home-lennart.mount</filename>.
+ For details about the escaping logic used to convert a file system path to a unit name, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Note that mount
+ units cannot be templated, nor is possible to add multiple names to a mount unit by creating additional symlinks to
+ it.</para>
<para>Optionally, a mount unit may be accompanied by an automount
unit, to allow on-demand or parallelized mounting. See
@@ -128,26 +126,17 @@
<filename>systemd-quotacheck.service</filename> and
<filename>quotaon.service</filename> are added.</para>
- <para>For mount units with
- <varname>DefaultDependencies=yes</varname> (the default) a couple
- additional dependencies are added. Mount units referring to local
- file systems automatically gain an <varname>After=</varname>
- dependency on <filename>local-fs-pre.target</filename>. Network
- mount units automatically acquire <varname>After=</varname>
- dependencies on <filename>remote-fs-pre.target</filename>,
- <filename>network.target</filename> and
- <filename>network-online.target</filename>. Towards the latter a
- <varname>Wants=</varname> unit is added as well. Mount units
- referring to local and network file systems are distinguished by
- their file system type specification. In some cases this is not
- sufficient (for example network block device based mounts, such as
- iSCSI), in which case <option>_netdev</option> may be added to the
- mount option string of the unit, which forces systemd to consider the
- mount unit a network mount. Mount units (regardless if local or
- network) also acquire automatic <varname>Before=</varname> and
- <varname>Conflicts=</varname> on
- <filename>umount.target</filename> in order to be stopped
- during shutdown.</para>
+ <para>For mount units with <varname>DefaultDependencies=yes</varname> in the <literal>[Unit]</literal> section (the
+ default) a couple additional dependencies are added. Mount units referring to local file systems automatically gain
+ an <varname>After=</varname> dependency on <filename>local-fs-pre.target</filename>. Network mount units
+ automatically acquire <varname>After=</varname> dependencies on <filename>remote-fs-pre.target</filename>,
+ <filename>network.target</filename> and <filename>network-online.target</filename>. Towards the latter a
+ <varname>Wants=</varname> unit is added as well. Mount units referring to local and network file systems are
+ distinguished by their file system type specification. In some cases this is not sufficient (for example network
+ block device based mounts, such as iSCSI), in which case <option>_netdev</option> may be added to the mount option
+ string of the unit, which forces systemd to consider the mount unit a network mount. Mount units (regardless if
+ local or network) also acquire automatic <varname>Before=</varname> and <varname>Conflicts=</varname> on
+ <filename>umount.target</filename> in order to be stopped during shutdown.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
@@ -170,6 +159,11 @@
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for details about the conversion.</para>
+ <para>The NFS mount option <option>bg</option> for NFS background mounts
+ as documented in <citerefentry><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>
+
<para>When reading <filename>/etc/fstab</filename> a few special
mount options are understood by systemd which influence how
dependencies are created for mount points. systemd will create a
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index b697d0c9a6..8d12c305d2 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -310,6 +310,26 @@
of the Listening and Learning states before the Forwarding state is entered.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>MulticastQuerier=</varname></term>
+ <listitem>
+ <para>A boolean. This setting controls the IFLA_BR_MCAST_QUERIER option in the kernel.
+ If enabled, the kernel will send general ICMP queries from a zero source address.
+ This feature should allow faster convergence on startup, but it causes some
+ multicast-aware switches to misbehave and disrupt forwarding of multicast packets.
+ When unset, the kernel's default setting applies.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>MulticastSnooping=</varname></term>
+ <listitem>
+ <para>A boolean. This setting controls the IFLA_BR_MCAST_SNOOPING option in the kernel.
+ If enabled, IGMP snooping monitors the Internet Group Management Protocol (IGMP) traffic
+ between hosts and multicast routers. When unset, the kernel's default setting applies.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -361,7 +381,7 @@
<para>The <literal>[MACVTAP]</literal> section applies for
netdevs of kind <literal>macvtap</literal> and accepts the
- same key as <literal>[MACVLAN].</literal> </para>
+ same key as <literal>[MACVLAN]</literal>.</para>
</refsect1>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index f88751b672..821e22aff8 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -79,6 +79,11 @@
needed. As a special case, an empty file (file size 0) or symlink
with the same name pointing to <filename>/dev/null</filename>
disables the configuration file entirely (it is "masked").</para>
+
+ <para>Note that an interface without any static IPv6 addresses configured, and neither DHCPv6 nor IPv6LL enabled,
+ shall be considered to have no IPv6 support. IPv6 will be automatically disabled for that interface by writing "1"
+ to <filename>/proc/sys/net/ipv6/conf/<replaceable>ifname</replaceable>/disable_ipv6</filename>.
+ </para>
</refsect1>
<refsect1>
@@ -100,7 +105,8 @@
<varlistentry>
<term><varname>MACAddress=</varname></term>
<listitem>
- <para>The hardware address.</para>
+ <para>The hardware address of the interface (use full colon-delimited hexadecimal, e.g.,
+ 01:23:45:67:89:ab).</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -193,7 +199,7 @@
<varlistentry>
<term><varname>MACAddress=</varname></term>
<listitem>
- <para>The hardware address.</para>
+ <para>The hardware address to set for the device.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -202,6 +208,8 @@
<para>The maximum transmission unit in bytes to set for the
device. The usual suffixes K, M, G, are supported and are
understood to the base of 1024.</para>
+ <para>Note that if IPv6 is enabled on the interface, and the MTU is chosen
+ below 1280 (the minimum MTU for IPv6) it will automatically be increased to this value.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -237,6 +245,9 @@
<para>Furthermore, note that by default the domain name
specified through DHCP is not used for name resolution.
See option <option>UseDomains=</option> below.</para>
+
+ <para>See the <literal>[DHCP]</literal> section below for further configuration options for the DHCP client
+ support.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -270,8 +281,10 @@
<term><varname>IPv6Token=</varname></term>
<listitem>
<para>An IPv6 address with the top 64 bits unset. When set, indicates the
- 64-bit interface part of SLAAC IPv6 addresses for this link. By default,
- it is autogenerated.</para>
+ 64-bit interface part of SLAAC IPv6 addresses for this link. Note that
+ the token is only ever used for SLAAC, and not for DHCPv6 addresses, even
+ in the case DHCP is requested by router advertisement. By default, the
+ token is autogenerated.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -335,18 +348,50 @@
<varlistentry>
<term><varname>LLDP=</varname></term>
<listitem>
- <para>A boolean. When true, enables LLDP link receive support.
+ <para>Controls support for Ethernet LLDP packet reception. LLDP is a link-layer protocol commonly
+ implemented on professional routers and bridges which announces which physical port a system is connected
+ to, as well as other related data. Accepts a boolean or the special value
+ <literal>routers-only</literal>. When true, incoming LLDP packets are accepted and a database of all LLDP
+ neighbors maintained. If <literal>routers-only</literal> is set only LLDP data of various types of routers
+ is collected and LLDP data about other types of devices ignored (such as stations, telephones and
+ others). If false, LLDP reception is disabled. Defaults to <literal>routers-only</literal>. Use
+ <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> to query the
+ collected neighbor data. LLDP is only available on Ethernet links. See <varname>EmitLLDP=</varname> below
+ for enabling LLDP packet emission from the local system.
</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>EmitLLDP=</varname></term>
+ <listitem>
+ <para>Controls support for Ethernet LLDP packet emission. Accepts a boolean parameter or the special values
+ <literal>nearest-bridge</literal>, <literal>non-tpmr-bridge</literal> and
+ <literal>customer-bridge</literal>. Defaults to false, which turns off LLDP packet emission. If not false,
+ a short LLDP packet with information about the local system is sent out in regular intervals on the
+ link. The LLDP packet will contain information about the local host name, the local machine ID (as stored
+ in <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>) and the
+ local interface name, as well as the pretty hostname of the system (as set in
+ <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>). LLDP
+ emission is only available on Ethernet links. Note that this setting passes data suitable for
+ identification of host to the network and should thus not be enabled on untrusted networks, where such
+ identification data should not be made available. Use this option to permit other systems to identify on
+ which interfaces they are connected to this system. The three special values control propagation of the
+ LLDP packets. The <literal>nearest-bridge</literal> setting permits propagation only to the nearest
+ connected bridge, <literal>non-tpmr-bridge</literal> permits propagation across Two-Port MAC Relays, but
+ not any other bridges, and <literal>customer-bridge</literal> permits propagation until a customer bridge
+ is reached. For details about these concepts, see <ulink
+ url="http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf">IEEE 802.1AB-2009</ulink>. Note that
+ configuring this setting to true is equivalent to <literal>nearest-bridge</literal>, the recommended and
+ most restricted level of propagation. See <varname>LLDP=</varname> above for an option to enable LLDP
+ reception.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>BindCarrier=</varname></term>
<listitem>
- <para>A port or a list of ports. When set, controls the
- behavior of the current interface. When all ports in the list
- are in an operational down state, the current interface is brought
- down. When at least one port has carrier, the current interface
- is brought up.
+ <para>A link name or a list of link names. When set, controls the behavior of the current
+ link. When all links in the list are in an operational down state, the current link is brought
+ down. When at least one link has carrier, the current interface is brought up.
</para>
</listitem>
</varlistentry>
@@ -412,7 +457,7 @@
domains specified here are preferably routed to the DNS servers configured for this interface. If a domain
name is prefixed with <literal>~</literal>, the domain name becomes a pure "routing" domain, is used for
DNS query routing purposes only and is not used in the described domain search logic. By specifying a
- routing domain of <literal>~.</literal> (the tilda indicating definition of a routing domain, the dot
+ routing domain of <literal>~.</literal> (the tilde indicating definition of a routing domain, the dot
referring to the DNS root domain which is the implied suffix of all valid DNS names) it is possible to
route all DNS traffic preferably to the DNS server specified for this interface. The route domain logic is
particularly useful on multi-homed hosts with DNS servers serving particular private DNS zones on each
@@ -517,6 +562,15 @@
</para></listitem>
</varlistentry>
<varlistentry>
+ <term><varname>ProxyARP=</varname></term>
+ <listitem><para>A boolean. Configures proxy ARP. Proxy ARP is the technique in which one host,
+ usually a router, answers ARP requests intended for another machine. By "faking" its identity,
+ the router accepts responsibility for routing packets to the "real" destination. (see <ulink
+ url="https://tools.ietf.org/html/rfc1027">RFC 1027</ulink>.
+ Defaults to unset.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Bridge=</varname></term>
<listitem>
<para>The name of the bridge to add the link to.</para>
@@ -600,6 +654,18 @@
<para>An address label.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>PreferredLifetime=</varname></term>
+ <listitem>
+ <para>Allows the default "preferred lifetime" of the address to be overridden.
+ Only three settings are accepted: <literal>forever</literal> or <literal>infinity</literal>
+ which is the default and means that the address never expires, and <literal>0</literal> which means
+ that the address is considered immediately "expired" and will not be used,
+ unless explicitly requested. A setting of PreferredLifetime=0 is useful for
+ addresses which are added to be used only by a specific application,
+ which is then configured to use them explicitly.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -654,6 +720,14 @@
<citerefentry project='man-pages'><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>Table=<replaceable>num</replaceable></varname></term>
+ <listitem>
+ <para>The table identifier for the route (a number between 1 and 4294967295, or 0 to unset).
+ The table can be retrieved using <command>ip route show table <replaceable>num</replaceable></command>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -717,7 +791,7 @@
<varlistentry>
<term><varname>UseDomains=</varname></term>
<listitem>
- <para>Takes a boolean argument, or a the special value <literal>route</literal>. When true, the domain name
+ <para>Takes a boolean argument, or the special value <literal>route</literal>. When true, the domain name
received from the DHCP server will be used as DNS search domain over this link, similar to the effect of
the <option>Domains=</option> setting. If set to <literal>route</literal>, the domain name received from
the DHCP server will be used for routing DNS queries only, but not for searching, similar to the effect of
@@ -760,14 +834,15 @@
false.</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term><varname>ClientIdentifier=</varname></term>
<listitem>
- <para>DHCP client identifier to use. Either <literal>mac</literal>
- to use the MAC address of the link or <literal>duid</literal>
- (the default) to use a RFC4361-compliant Client ID.</para>
+ <para>The DHCPv4 client identifier to use. Either <literal>mac</literal> to use the MAC address of the link
+ or <literal>duid</literal> (the default, see below) to use a RFC4361-compliant Client ID.</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term><varname>VendorClassIdentifier=</varname></term>
<listitem>
@@ -775,6 +850,32 @@
type and configuration.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>DUIDType=</varname></term>
+ <listitem>
+ <para>Override the global <varname>DUIDType</varname> setting for this network. See
+ <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for a description of possible values.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DUIDRawData=</varname></term>
+ <listitem>
+ <para>Override the global <varname>DUIDRawData</varname> setting for this network. See
+ <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for a description of possible values.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>IAID=</varname></term>
+ <listitem>
+ <para>The DHCP Identity Association Identifier (IAID) for the interface, a 32-bit unsigned integer.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>RequestBroadcast=</varname></term>
<listitem>
@@ -786,6 +887,7 @@
networks where broadcasts are filtered out.</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
@@ -794,8 +896,7 @@
</listitem>
</varlistentry>
</variablelist>
-
- </refsect1>
+ </refsect1>
<refsect1>
<title>[DHCPServer] Section Options</title>
@@ -882,6 +983,16 @@
</varlistentry>
<varlistentry>
+ <term><varname>EmitRouter=</varname></term>
+
+ <listitem><para>Similar to the <varname>EmitDNS=</varname>
+ setting described above, this setting configures whether the
+ DHCP lease should contain the router option. The same syntax,
+ propagation semantics and defaults apply as for
+ <varname>EmitDNS=</varname>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>EmitTimezone=</varname></term>
<term><varname>Timezone=</varname></term>
diff --git a/man/systemd.nspawn.xml b/man/systemd.nspawn.xml
index c07a4b0243..3683412c14 100644
--- a/man/systemd.nspawn.xml
+++ b/man/systemd.nspawn.xml
@@ -224,6 +224,18 @@
</varlistentry>
<varlistentry>
+ <term><varname>KillSignal=</varname></term>
+
+ <listitem><para>Specify the process signal to send to the
+ container's PID 1 when nspawn itself receives SIGTERM, in
+ order to trigger an orderly shutdown of the container.
+ Defaults to SIGRTMIN+3 if <option>Boot=</option> is used
+ (on systemd-compatible init systems SIGRTMIN+3 triggers an
+ orderly shutdown). For a list of valid signals, see
+ <citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>Personality=</varname></term>
<listitem><para>Configures the kernel personality for the
@@ -239,6 +251,14 @@
<option>--uuid=</option> command line switch. This option is
privileged (see above). </para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>PrivateUsers=</varname></term>
+
+ <listitem><para>Configures support for usernamespacing. This is equivalent to the
+ <option>--private-users=</option> command line switch, and takes the same options. This option is privileged
+ (see above). </para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -302,6 +322,16 @@
for details about the specific options supported. This setting
is privileged (see above).</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>PrivateUsersChown=</varname></term>
+
+ <listitem><para>Configures whether the ownership of the files and directories in the container tree shall be
+ adjusted to the UID/GID range used, if necessary and user namespacing is enabled. This is equivalent to the
+ <option>--private-users-chown</option> command line switch. This option is privileged (see
+ above). </para></listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
@@ -390,6 +420,16 @@
</varlistentry>
<varlistentry>
+ <term><varname>Zone=</varname></term>
+
+ <listitem><para>Takes a network zone name. This setting implies <varname>VirtualEthernet=yes</varname> and
+ <varname>Private=yes</varname> and has the effect that the host side of the created virtual Ethernet link is
+ connected to an automatically managed bridge interface named after the passed argument, prefixed with
+ <literal>vz-</literal>. This option corresponds to the <option>--network-zone=</option> command line
+ switch. This option is privileged (see above).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>Port=</varname></term>
<listitem><para>Exposes a TCP or UDP port of the container on
diff --git a/man/systemd.offline-updates.xml b/man/systemd.offline-updates.xml
new file mode 100644
index 0000000000..946234ad90
--- /dev/null
+++ b/man/systemd.offline-updates.xml
@@ -0,0 +1,169 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2013 Lennart Poettering
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.offline-updates">
+ <refentryinfo>
+ <title>systemd.offline-updates</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd.offline-updates</refentrytitle>
+ <manvolnum>7</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd.offline-updates</refname>
+ <refpurpose>Implementation of offline updates in systemd</refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>Implementing Offline System Updates</title>
+
+ <para>This man page describes how to implement "offline" system updates with systemd. By "offline"
+ OS updates we mean package installations and updates that are run with the system booted into a
+ special system update mode, in order to avoid problems related to conflicts of libraries and
+ services that are currently running with those on disk. This document is inspired by this
+ <ulink url="https://wiki.gnome.org/Design/OS/SoftwareUpdates">GNOME design whiteboard</ulink>.
+ </para>
+
+ <para>The logic:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The package manager prepares system updates by downloading all (RPM or DEB or
+ whatever) packages to update off-line in a special directory
+ <filename noindex="true">/var/lib/system-update</filename> (or
+ another directory of the package/upgrade manager's choice).</para>
+ </listitem>
+
+ <listitem>
+ <para>When the user OK'ed the update, the symlink <filename>/system-update</filename> is
+ created that points to <filename noindex="true">/var/lib/system-update</filename> (or
+ wherever the directory with the upgrade files is located) and the system is rebooted. This
+ symlink is in the root directory, since we need to check for it very early at boot, at a
+ time where <filename>/var</filename> is not available yet.</para>
+ </listitem>
+
+ <listitem>
+ <para>Very early in the new boot
+ <citerefentry><refentrytitle>systemd-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ checks whether <filename>/system-update</filename> exists. If so, it (temporarily and for
+ this boot only) redirects (i.e. symlinks) <filename>default.target</filename> to
+ <filename>system-update.target</filename>, a special target that is pulls in the base system
+ (i.e. <filename>sysinit.target</filename>, so that all file systems are mounted but little
+ else) and the system update units.</para>
+ </listitem>
+
+ <listitem>
+ <para>The system now continues to boot into <filename>default.target</filename>, and thus
+ into <filename>system-update.target</filename>. This target pulls in the system update unit,
+ which starts the system update script after all file systems have been mounted.</para>
+ </listitem>
+
+ <listitem>
+ <para>As the first step, the update script should check if the
+ <filename>/system-update</filename> symlink points to the the location used by that update
+ script. In case it does not exists or points to a different location, the script must exit
+ without error. It is possible for multiple update services to be installed, and for multiple
+ update scripts to be launched in parallel, and only the one that corresponds to the tool
+ that <emphasis>created</emphasis> the symlink before reboot should perform any actions. It
+ is unsafe to run multiple updates in parallel.</para>
+ </listitem>
+
+ <listitem>
+ <para>The update script should now do its job. If applicable and possible, it should
+ create a file system snapshot, then install all packages.
+ After completion (regardless whether the update succeeded or failed) the machine
+ must be rebooted, for example by calling <command>systemctl reboot</command>.
+ In addition, on failure the script should revert to the old file system snapshot
+ (without the symlink).</para>
+ </listitem>
+
+ <listitem>
+ <para>The system is rebooted. Since the <filename>/system-update</filename> symlink is gone,
+ the generator won't redirect <filename>default.target</filename> after reboot and the
+ system now boots into the default target again.</para>
+ </listitem>
+ </orderedlist>
+ </refsect1>
+
+ <refsect1>
+ <title>Recommendations</title>
+
+ <orderedlist>
+ <listitem>
+ <para>To make things a bit more robust we recommend hooking the update script into
+ <filename>system-update.target</filename> via a <filename noindex='true'>.wants/</filename>
+ symlink in the distribution package, rather than depending on <command>systemctl
+ enable</command> in the postinst scriptlets of your package. More specifically, for your
+ update script create a .service file, without [Install] section, and then add a symlink like
+ <filename noindex='true'>/usr/lib/systemd/system-update.target.wants/foobar.service</filename>
+ → <filename noindex='true'>../foobar.service</filename> to your package.</para>
+ </listitem>
+
+ <listitem>
+ <para>Make sure to remove the <filename>/system-update</filename> symlink as early as
+ possible in the update script to avoid reboot loops in case the update fails.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use <varname>FailureAction=reboot</varname> in the service file for your update script
+ to ensure that a reboot is automatically triggered if the update fails.
+ <varname>FailureAction=</varname> makes sure that the specified unit is activated if your
+ script exits uncleanly (by non-zero error code, or signal/coredump). If your script succeeds
+ you should trigger the reboot in your own code, for example by invoking logind's
+ <command>Reboot()</command> call or calling <command>systemct reboot</command>. See
+ <ulink url="http://www.freedesktop.org/wiki/Software/systemd/logind">logind dbus API</ulink>
+ for details.</para>
+ </listitem>
+
+ <listitem>
+ <para>The update service should declare <varname>DefaultDependencies=false</varname>,
+ and pull in any services it requires explicitly.</para>
+ </listitem>
+ </orderedlist>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para>
+ <ulink url="http://www.freedesktop.org/wiki/Software/systemd/SystemUpdates/">Implementing Offline System Updates</ulink>,
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>dnf.plugin.system-upgrade</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index 1bd65ce86d..7200c8fe27 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -91,16 +91,12 @@
<para>An implicit <varname>Before=</varname> dependency is added
between a path unit and the unit it is supposed to activate.</para>
- <para>Unless <varname>DefaultDependencies=false</varname> is used,
- path units will implicitly have dependencies of type
- <varname>Before=</varname> on <filename>paths.target</filename>,
- dependencies of type <varname>After=</varname> and
- <varname>Requires=</varname> on
- <filename>sysinit.target</filename>, and have dependencies of type
- <varname>Conflicts=</varname> and <varname>Before=</varname> on
- <filename>shutdown.target</filename>. These ensure that path units
- are terminated cleanly prior to system shutdown. Only path units
- involved with early boot or late system shutdown should disable
+ <para>Unless <varname>DefaultDependencies=false</varname> in the <literal>[Unit]</literal> section is used, path
+ units will implicitly have dependencies of type <varname>Before=</varname> on <filename>paths.target</filename>,
+ dependencies of type <varname>After=</varname> and <varname>Requires=</varname> on
+ <filename>sysinit.target</filename>, and have dependencies of type <varname>Conflicts=</varname> and
+ <varname>Before=</varname> on <filename>shutdown.target</filename>. These ensure that path units are terminated
+ cleanly prior to system shutdown. Only path units involved with early boot or late system shutdown should disable
this option.
</para>
</refsect1>
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
index 08cdf06e23..066f2cc19b 100644
--- a/man/systemd.resource-control.xml
+++ b/man/systemd.resource-control.xml
@@ -99,6 +99,31 @@
</refsect1>
<refsect1>
+ <title>Unified and Legacy Control Group Hierarchies</title>
+
+ <para>Unified control group hierarchy is the new version of kernel control group interface. Depending on the
+ resource type, there are differences in resource control capabilities. Also, because of interface changes, some
+ resource types have a separate set of options on the unified hierarchy.</para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><option>IO</option></term>
+ <listitem>
+ <para><varname>IO</varname> prefixed settings are superset of and replace <varname>BlockIO</varname>
+ prefixed ones. On unified hierarchy, IO resource control also applies to buffered writes.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>To ease the transition, there is best-effort translation between the two versions of settings. If all
+ settings of a unit for a given resource type are for the other hierarchy type, the settings are translated and
+ applied. If there are any valid settings for the hierarchy in use, all translations are disabled for the resource
+ type. Mixing the two types of settings on a unit can lead to confusing results.</para>
+ </refsect1>
+
+ <refsect1>
<title>Options</title>
<para>Units of the types listed above can have settings
@@ -202,7 +227,7 @@
controls the <literal>memory.limit_in_bytes</literal>
control group attribute. For details about this control
group attribute, see <ulink
- url="https://www.kernel.org/doc/Documentation/cgroups/memory.txt">memory.txt</ulink>.</para>
+ url="https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt">memory.txt</ulink>.</para>
<para>Implies <literal>MemoryAccounting=true</literal>.</para>
</listitem>
@@ -239,7 +264,7 @@
controls the <literal>pids.max</literal> control group
attribute. For details about this control group attribute,
see <ulink
- url="https://www.kernel.org/doc/Documentation/cgroups/pids.txt">pids.txt</ulink>.</para>
+ url="https://www.kernel.org/doc/Documentation/cgroup-v1/pids.txt">pids.txt</ulink>.</para>
<para>Implies <literal>TasksAccounting=true</literal>. The
system default for this setting may be controlled with
@@ -249,17 +274,130 @@
</varlistentry>
<varlistentry>
+ <term><varname>IOAccounting=</varname></term>
+
+ <listitem>
+ <para>Turn on Block I/O accounting for this unit, if the unified control group hierarchy is used on the
+ system. Takes a boolean argument. Note that turning on block I/O accounting for one unit will also implicitly
+ turn it on for all units contained in the same slice and all for its parent slices and the units contained
+ therein. The system default for this setting may be controlled with <varname>DefaultIOAccounting=</varname>
+ in
+ <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+ <para>This setting is supported only if the unified control group hierarchy is used. Use
+ <varname>BlockIOAccounting=</varname> on systems using the legacy control group hierarchy.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>IOWeight=<replaceable>weight</replaceable></varname></term>
+ <term><varname>StartupIOWeight=<replaceable>weight</replaceable></varname></term>
+
+ <listitem>
+ <para>Set the default overall block I/O weight for the executed processes, if the unified control group
+ hierarchy is used on the system. Takes a single weight value (between 1 and 10000) to set the default block
+ I/O weight. This controls the <literal>io.weight</literal> control group attribute, which defaults to
+ 100. For details about this control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>. The available I/O
+ bandwidth is split up among all units within one slice relative to their block I/O weight.</para>
+
+ <para>While <varname>StartupIOWeight=</varname> only applies
+ to the startup phase of the system,
+ <varname>IOWeight=</varname> applies to the later runtime of
+ the system, and if the former is not set also to the startup
+ phase. This allows prioritizing specific services at boot-up
+ differently than during runtime.</para>
+
+ <para>Implies <literal>IOAccounting=true</literal>.</para>
+
+ <para>This setting is supported only if the unified control group hierarchy is used. Use
+ <varname>BlockIOWeight=</varname> and <varname>StartupBlockIOWeight=</varname> on systems using the legacy
+ control group hierarchy.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>IODeviceWeight=<replaceable>device</replaceable> <replaceable>weight</replaceable></varname></term>
+
+ <listitem>
+ <para>Set the per-device overall block I/O weight for the executed processes, if the unified control group
+ hierarchy is used on the system. Takes a space-separated pair of a file path and a weight value to specify
+ the device specific weight value, between 1 and 10000. (Example: "/dev/sda 1000"). The file path may be
+ specified as path to a block device node or as any other file, in which case the backing block device of the
+ file system of the file is determined. This controls the <literal>io.weight</literal> control group
+ attribute, which defaults to 100. Use this option multiple times to set weights for multiple devices. For
+ details about this control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
+
+ <para>Implies <literal>IOAccounting=true</literal>.</para>
+
+ <para>This setting is supported only if the unified control group hierarchy is used. Use
+ <varname>BlockIODeviceWeight=</varname> on systems using the legacy control group hierarchy.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>IOReadBandwidthMax=<replaceable>device</replaceable> <replaceable>bytes</replaceable></varname></term>
+ <term><varname>IOWriteBandwidthMax=<replaceable>device</replaceable> <replaceable>bytes</replaceable></varname></term>
+
+ <listitem>
+ <para>Set the per-device overall block I/O bandwidth maximum limit for the executed processes, if the unified
+ control group hierarchy is used on the system. This limit is not work-conserving and the executed processes
+ are not allowed to use more even if the device has idle capacity. Takes a space-separated pair of a file
+ path and a bandwidth value (in bytes per second) to specify the device specific bandwidth. The file path may
+ be a path to a block device node, or as any other file in which case the backing block device of the file
+ system of the file is used. If the bandwidth is suffixed with K, M, G, or T, the specified bandwidth is
+ parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes, respectively, to the base of 1000. (Example:
+ "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This controls the <literal>io.max</literal> control
+ group attributes. Use this option multiple times to set bandwidth limits for multiple devices. For details
+ about this control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.
+ </para>
+
+ <para>Implies <literal>IOAccounting=true</literal>.</para>
+
+ <para>This setting is supported only if the unified control group hierarchy is used. Use
+ <varname>BlockIOAccounting=</varname> on systems using the legacy control group hierarchy.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>IOReadIOPSMax=<replaceable>device</replaceable> <replaceable>IOPS</replaceable></varname></term>
+ <term><varname>IOWriteIOPSMax=<replaceable>device</replaceable> <replaceable>IOPS</replaceable></varname></term>
+
+ <listitem>
+ <para>Set the per-device overall block I/O IOs-Per-Second maximum limit for the executed processes, if the
+ unified control group hierarchy is used on the system. This limit is not work-conserving and the executed
+ processes are not allowed to use more even if the device has idle capacity. Takes a space-separated pair of
+ a file path and an IOPS value to specify the device specific IOPS. The file path may be a path to a block
+ device node, or as any other file in which case the backing block device of the file system of the file is
+ used. If the IOPS is suffixed with K, M, G, or T, the specified IOPS is parsed as KiloIOPS, MegaIOPS,
+ GigaIOPS, or TeraIOPS, respectively, to the base of 1000. (Example:
+ "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 1K"). This controls the <literal>io.max</literal> control
+ group attributes. Use this option multiple times to set IOPS limits for multiple devices. For details about
+ this control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.
+ </para>
+
+ <para>Implies <literal>IOAccounting=true</literal>.</para>
+
+ <para>This setting is supported only if the unified control group hierarchy is used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>BlockIOAccounting=</varname></term>
<listitem>
- <para>Turn on Block I/O accounting for this unit. Takes a
- boolean argument. Note that turning on block I/O accounting
- for one unit will also implicitly turn it on for all units
- contained in the same slice and all for its parent slices
- and the units contained therein. The system default for this
- setting may be controlled with
+ <para>Turn on Block I/O accounting for this unit, if the legacy control group hierarchy is used on the
+ system. Takes a boolean argument. Note that turning on block I/O accounting for one unit will also implicitly
+ turn it on for all units contained in the same slice and all for its parent slices and the units contained
+ therein. The system default for this setting may be controlled with
<varname>DefaultBlockIOAccounting=</varname> in
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+ <para>This setting is supported only if the legacy control group hierarchy is used. Use
+ <varname>IOAccounting=</varname> on systems using the unified control group hierarchy.</para>
</listitem>
</varlistentry>
@@ -267,15 +405,13 @@
<term><varname>BlockIOWeight=<replaceable>weight</replaceable></varname></term>
<term><varname>StartupBlockIOWeight=<replaceable>weight</replaceable></varname></term>
- <listitem><para>Set the default overall block I/O weight for
- the executed processes. Takes a single weight value (between
- 10 and 1000) to set the default block I/O weight. This controls
- the <literal>blkio.weight</literal> control group attribute,
- which defaults to 500. For details about this control group
- attribute, see <ulink
- url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.
- The available I/O bandwidth is split up among all units within
- one slice relative to their block I/O weight.</para>
+ <listitem><para>Set the default overall block I/O weight for the executed processes, if the legacy control
+ group hierarchy is used on the system. Takes a single weight value (between 10 and 1000) to set the default
+ block I/O weight. This controls the <literal>blkio.weight</literal> control group attribute, which defaults to
+ 500. For details about this control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt">blkio-controller.txt</ulink>.
+ The available I/O bandwidth is split up among all units within one slice relative to their block I/O
+ weight.</para>
<para>While <varname>StartupBlockIOWeight=</varname> only
applies to the startup phase of the system,
@@ -286,29 +422,32 @@
<para>Implies
<literal>BlockIOAccounting=true</literal>.</para>
- </listitem>
+
+ <para>This setting is supported only if the legacy control group hierarchy is used. Use
+ <varname>IOWeight=</varname> and <varname>StartupIOWeight=</varname> on systems using the unified control group
+ hierarchy.</para>
+
+ </listitem>
</varlistentry>
<varlistentry>
<term><varname>BlockIODeviceWeight=<replaceable>device</replaceable> <replaceable>weight</replaceable></varname></term>
<listitem>
- <para>Set the per-device overall block I/O weight for the
- executed processes. Takes a space-separated pair of a file
- path and a weight value to specify the device specific
- weight value, between 10 and 1000. (Example: "/dev/sda
- 500"). The file path may be specified as path to a block
- device node or as any other file, in which case the backing
- block device of the file system of the file is
- determined. This controls the
- <literal>blkio.weight_device</literal> control group
- attribute, which defaults to 1000. Use this option multiple
- times to set weights for multiple devices. For details about
- this control group attribute, see <ulink
- url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.</para>
+ <para>Set the per-device overall block I/O weight for the executed processes, if the legacy control group
+ hierarchy is used on the system. Takes a space-separated pair of a file path and a weight value to specify
+ the device specific weight value, between 10 and 1000. (Example: "/dev/sda 500"). The file path may be
+ specified as path to a block device node or as any other file, in which case the backing block device of the
+ file system of the file is determined. This controls the <literal>blkio.weight_device</literal> control group
+ attribute, which defaults to 1000. Use this option multiple times to set weights for multiple devices. For
+ details about this control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt">blkio-controller.txt</ulink>.</para>
<para>Implies
<literal>BlockIOAccounting=true</literal>.</para>
+
+ <para>This setting is supported only if the legacy control group hierarchy is used. Use
+ <varname>IODeviceWeight=</varname> on systems using the unified control group hierarchy.</para>
</listitem>
</varlistentry>
@@ -317,27 +456,25 @@
<term><varname>BlockIOWriteBandwidth=<replaceable>device</replaceable> <replaceable>bytes</replaceable></varname></term>
<listitem>
- <para>Set the per-device overall block I/O bandwidth limit
- for the executed processes. Takes a space-separated pair of
- a file path and a bandwidth value (in bytes per second) to
- specify the device specific bandwidth. The file path may be
- a path to a block device node, or as any other file in which
- case the backing block device of the file system of the file
- is used. If the bandwidth is suffixed with K, M, G, or T,
- the specified bandwidth is parsed as Kilobytes, Megabytes,
- Gigabytes, or Terabytes, respectively, to the base of
- 1000. (Example:
- "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This
- controls the <literal>blkio.read_bps_device</literal> and
- <literal>blkio.write_bps_device</literal> control group
- attributes. Use this option multiple times to set bandwidth
- limits for multiple devices. For details about these control
- group attributes, see <ulink
- url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.
+ <para>Set the per-device overall block I/O bandwidth limit for the executed processes, if the legacy control
+ group hierarchy is used on the system. Takes a space-separated pair of a file path and a bandwidth value (in
+ bytes per second) to specify the device specific bandwidth. The file path may be a path to a block device
+ node, or as any other file in which case the backing block device of the file system of the file is used. If
+ the bandwidth is suffixed with K, M, G, or T, the specified bandwidth is parsed as Kilobytes, Megabytes,
+ Gigabytes, or Terabytes, respectively, to the base of 1000. (Example:
+ "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This controls the
+ <literal>blkio.throttle.read_bps_device</literal> and <literal>blkio.throttle.write_bps_device</literal>
+ control group attributes. Use this option multiple times to set bandwidth limits for multiple devices. For
+ details about these control group attributes, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt">blkio-controller.txt</ulink>.
</para>
<para>Implies
<literal>BlockIOAccounting=true</literal>.</para>
+
+ <para>This setting is supported only if the legacy control group hierarchy is used. Use
+ <varname>IOReadBandwidthMax=</varname> and <varname>IOWriteBandwidthMax=</varname> on systems using the
+ unified control group hierarchy.</para>
</listitem>
</varlistentry>
@@ -357,7 +494,7 @@
<literal>devices.deny</literal> control group
attributes. For details about these control group
attributes, see <ulink
- url="https://www.kernel.org/doc/Documentation/cgroups/devices.txt">devices.txt</ulink>.</para>
+ url="https://www.kernel.org/doc/Documentation/cgroup-v1/devices.txt">devices.txt</ulink>.</para>
<para>The device node specifier is either a path to a device
node in the file system, starting with
@@ -482,10 +619,10 @@
<citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
The documentation for control groups and specific controllers in the Linux kernel:
- <ulink url="https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt</ulink>,
- <ulink url="https://www.kernel.org/doc/Documentation/cgroups/cpuacct.txt">cpuacct.txt</ulink>,
- <ulink url="https://www.kernel.org/doc/Documentation/cgroups/memory.txt">memory.txt</ulink>,
- <ulink url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.
+ <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt">cgroups.txt</ulink>,
+ <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v1/cpuacct.txt">cpuacct.txt</ulink>,
+ <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt">memory.txt</ulink>,
+ <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt">blkio-controller.txt</ulink>.
</para>
</refsect1>
</refentry>
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index d7760d4f2c..6641dfed4f 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -100,18 +100,13 @@
their activated <filename>.socket</filename> units via an
automatic <varname>After=</varname> dependency.</para>
- <para>Unless <varname>DefaultDependencies=</varname> is set to
- <option>false</option>, service units will implicitly have
- dependencies of type <varname>Requires=</varname> and
- <varname>After=</varname> on <filename>sysinit.target</filename>,
- a dependency of type <varname>After=</varname> on
- <filename>basic.target</filename> as well as dependencies of
- type <varname>Conflicts=</varname> and <varname>Before=</varname>
- on <filename>shutdown.target</filename>. These ensure that normal
- service units pull in basic system initialization, and are
- terminated cleanly prior to system shutdown. Only services
- involved with early boot or late system shutdown should disable
- this option.</para>
+ <para>Unless <varname>DefaultDependencies=</varname> in the <literal>[Unit]</literal> is set to
+ <option>false</option>, service units will implicitly have dependencies of type <varname>Requires=</varname> and
+ <varname>After=</varname> on <filename>sysinit.target</filename>, a dependency of type <varname>After=</varname> on
+ <filename>basic.target</filename> as well as dependencies of type <varname>Conflicts=</varname> and
+ <varname>Before=</varname> on <filename>shutdown.target</filename>. These ensure that normal service units pull in
+ basic system initialization, and are terminated cleanly prior to system shutdown. Only services involved with early
+ boot or late system shutdown should disable this option.</para>
<para>Instanced service units (i.e. service units with an <literal>@</literal> in their name) are assigned by
default a per-template slice unit (see
@@ -273,42 +268,6 @@
</varlistentry>
<varlistentry>
- <term><varname>BusPolicy=</varname></term>
-
- <listitem><para>If specified, a custom kdbus
- endpoint will be created and installed as the default bus node
- for the service. Such a custom endpoint can hold an own set of
- policy rules that are enforced on top of the bus-wide ones.
- The custom endpoint is named after the service it was created
- for, and its node will be bind-mounted over the default bus
- node location, so the service can only access the bus through
- its own endpoint. Note that custom bus endpoints default to a
- "deny all" policy. Hence, if at least one
- <varname>BusPolicy=</varname> directive is given, you have to
- make sure to add explicit rules for everything the service
- should be able to do.</para>
- <para>The value of this directive is comprised
- of two parts; the bus name, and a verb to
- specify to granted access, which is one of
- <option>see</option>,
- <option>talk</option>, or
- <option>own</option>.
- <option>talk</option> implies
- <option>see</option>, and <option>own</option>
- implies both <option>talk</option> and
- <option>see</option>.
- If multiple access levels are specified for the
- same bus name, the most powerful one takes
- effect.
- </para>
- <para>Examples:</para>
- <programlisting>BusPolicy=org.freedesktop.systemd1 talk</programlisting>
- <programlisting>BusPolicy=org.foo.bar see</programlisting>
- <para>This option is only available on kdbus enabled systems.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
<term><varname>ExecStart=</varname></term>
<listitem><para>Commands with their arguments that are
executed when this service is started. The value is split into
@@ -446,7 +405,7 @@
asynchronous one.</para>
<para>Note that the commands specified in <varname>ExecStop=</varname> are only executed when the service
- started successfuly first. They are not invoked if the service was never started at all, or in case its
+ started successfully first. They are not invoked if the service was never started at all, or in case its
start-up failed, for example because any of the commands specified in <varname>ExecStart=</varname>,
<varname>ExecStartPre=</varname> or <varname>ExecStartPost=</varname> failed (and weren't prefixed with
<literal>-</literal>, see above) or timed out. Use <varname>ExecStopPost=</varname> to invoke commands when a
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index 5c87bf0260..eee98d99ee 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -71,6 +71,9 @@
the root slice <filename>-.slice</filename>.
</para>
+ <para>Note that slice units cannot be templated, nor is possible to add multiple names to a slice unit by creating
+ additional symlinks to it.</para>
+
<para>By default, service and scope units are placed in
<filename>system.slice</filename>, virtual machines and containers
registered with
@@ -106,14 +109,10 @@
<varname>After=</varname> and <varname>Requires=</varname> on
their immediate parent slice unit.</para>
- <para>Unless <varname>DefaultDependencies=false</varname>
- is used, slice units will implicitly have dependencies of
- type <varname>Conflicts=</varname> and
- <varname>Before=</varname> on
- <filename>shutdown.target</filename>. These ensure
- that slice units are removed prior to system
- shutdown. Only slice units involved with early boot or
- late system shutdown should disable this option.
+ <para>Unless <varname>DefaultDependencies=false</varname> is used in the <literal>[Unit]</literal> section, slice
+ units will implicitly have dependencies of type <varname>Conflicts=</varname> and <varname>Before=</varname> on
+ <filename>shutdown.target</filename>. These ensure that slice units are removed prior to system shutdown. Only
+ slice units involved with early boot or late system shutdown should disable this option.
</para>
</refsect1>
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 43841c2399..5bf54d8ef3 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -97,16 +97,12 @@
<filename>foo@.service</filename> must exist from which services
are instantiated for each incoming connection.</para>
- <para>Unless <varname>DefaultDependencies=</varname> is set to
- <option>false</option>, socket units will implicitly have
- dependencies of type <varname>Requires=</varname> and
- <varname>After=</varname> on <filename>sysinit.target</filename>
- as well as dependencies of type <varname>Conflicts=</varname> and
- <varname>Before=</varname> on
- <filename>shutdown.target</filename>. These ensure that socket
- units pull in basic system initialization, and are terminated
- cleanly prior to system shutdown. Only sockets involved with early
- boot or late system shutdown should disable this option.</para>
+ <para>Unless <varname>DefaultDependencies=</varname> in the <literal>[Unit]</literal> section is set to
+ <option>false</option>, socket units will implicitly have dependencies of type <varname>Requires=</varname> and
+ <varname>After=</varname> on <filename>sysinit.target</filename> as well as dependencies of type
+ <varname>Conflicts=</varname> and <varname>Before=</varname> on <filename>shutdown.target</filename>. These ensure
+ that socket units pull in basic system initialization, and are terminated cleanly prior to system shutdown. Only
+ sockets involved with early boot or late system shutdown should disable this option.</para>
<para>Socket units will have a <varname>Before=</varname>
dependency on the service which they trigger added implicitly. No
@@ -811,6 +807,23 @@
suffix.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>TriggerLimitIntervalSec=</varname></term>
+ <term><varname>TriggerLimitBurst=</varname></term>
+
+ <listitem><para>Configures a limit on how often this socket unit my be activated within a specific time
+ interval. The <varname>TriggerLimitIntervalSec=</varname> may be used to configure the length of the time
+ interval in the usual time units <literal>us</literal>, <literal>ms</literal>, <literal>s</literal>,
+ <literal>min</literal>, <literal>h</literal>, … and defaults to 2s (See
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details on
+ the various time units understood). The <varname>TriggerLimitBurst=</varname> setting takes a positive integer
+ value and specifies the number of permitted activations per time interval, and defaults to 200 for
+ <varname>Accept=yes</varname> sockets (thus by default permitting 200 activations per 2s), and 20 otherwise (20
+ activations per 2s). Set either to 0 to disable any form of trigger rate limiting. If the limit is hit, the
+ socket unit is placed into a failure mode, and will not be connectible anymore until restarted. Note that this
+ limit is enforced before the service activation is enqueued.</para></listitem>
+ </varlistentry>
+
</variablelist>
<para>Check
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index 055d854555..26974ed73f 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -83,6 +83,7 @@
<filename>remote-fs.target</filename>,
<filename>remote-fs-pre.target</filename>,
<filename>rescue.target</filename>,
+ <filename>initrd-root-device.target</filename>,
<filename>initrd-root-fs.target</filename>,
<filename>rpcbind.target</filename>,
<filename>runlevel2.target</filename>,
@@ -205,7 +206,7 @@
<term><filename>emergency.target</filename></term>
<listitem>
<para>A special target unit that starts an emergency shell on the main console. This target does not pull in
- any serices or mounts. It is the most minimal version of starting the system in order to acquire an
+ any services or mounts. It is the most minimal version of starting the system in order to acquire an
interactive shell; the only processes running are usually just the system manager (PID 1) and the shell
process. This unit is supposed to be used with the kernel command line option
<varname>systemd.unit=</varname>; it is also used when a file system check on a required file system fails,
@@ -465,6 +466,18 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><filename>initrd-root-device.target</filename></term>
+ <listitem>
+ <para>A special initrd target unit that is reached when the root filesystem device is available, but before
+ it has been mounted.
+ <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ and
+ <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ automatically setup the appropiate dependencies to make this happen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><filename>initrd-root-fs.target</filename></term>
<listitem>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
@@ -526,7 +539,7 @@
<para>A special target unit that sets up all slice units (see
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details) that shall be active after boot. By default the generic <filename>user.slice</filename>,
- <filename>system.slice</filename>, <filename>machines.slice</filename> slice units, as well as the the root
+ <filename>system.slice</filename>, <filename>machines.slice</filename> slice units, as well as the root
slice unit <filename>-.slice</filename> are pulled in and ordered before this unit (see below).</para>
<para>It's a good idea to add <varname>WantedBy=slices.target</varname> lines to the <literal>[Install]</literal>
@@ -742,7 +755,7 @@
defined what that is supposed to mean, with one exception:
at shutdown, a unit that is ordered after
<filename>network.target</filename> will be stopped before
- the network -- to whatever level it might be set up then --
+ the network — to whatever level it might be set up then —
is shut down. It is hence useful when writing service files
that require network access on shutdown, which should order
themselves after this target, but not pull it in. Also see
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index c600405c87..cf4e1ba839 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -72,19 +72,18 @@
project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
binary is executed in, in
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- which define the way the these processes are
+ which define the way these processes are
terminated, and in
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which configure resource control settings for these processes of the
unit.</para>
- <para>Swap units must be named after the devices
- or files they control. Example: the swap device
- <filename noindex='true'>/dev/sda5</filename> must be configured in a
- unit file <filename>dev-sda5.swap</filename>. For details about
- the escaping logic used to convert a file system path to a unit
- name, see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+ <para>Swap units must be named after the devices or files they control. Example: the swap device <filename
+ noindex='true'>/dev/sda5</filename> must be configured in a unit file <filename>dev-sda5.swap</filename>. For
+ details about the escaping logic used to convert a file system path to a unit name, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Note that swap
+ units cannot be templated, nor is possible to add multiple names to a swap unit by creating additional symlinks to
+ it.</para>
</refsect1>
<refsect1>
@@ -95,12 +94,10 @@
dependencies on the device units or the mount units of the files
they are activated from.</para>
- <para>Swap units with <varname>DefaultDependencies=</varname>
- enabled implicitly acquire a <varname>Conflicts=</varname> and an
- <varname>After=</varname> dependency on
- <filename>umount.target</filename> so that they are deactivated at
- shutdown, unless <varname>DefaultDependencies=no</varname> is
- specified.</para>
+ <para>Swap units with <varname>DefaultDependencies=</varname> in the <literal>[Unit]</literal> section enabled
+ implicitly acquire a <varname>Conflicts=</varname> and an <varname>After=</varname> dependency on
+ <filename>umount.target</filename> so that they are deactivated at shutdown, unless
+ <varname>DefaultDependencies=no</varname> is specified.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
index bd4ab3903e..ab910d75dd 100644
--- a/man/systemd.target.xml
+++ b/man/systemd.target.xml
@@ -82,14 +82,11 @@
<refsect1>
<title>Automatic Dependencies</title>
- <para>Unless <varname>DefaultDependencies=</varname> is set to
- <option>no</option>, target units will implicitly complement all
- configured dependencies of type <varname>Wants=</varname>,
- <varname>Requires=</varname> with dependencies of type
- <varname>After=</varname>, unless an ordering dependency of any
- kind between the target and the respective other unit is already
- in place. Note that this behaviour is disabled if either unit has
- <varname>DefaultDependencies=no</varname>.</para>
+ <para>Unless <varname>DefaultDependencies=</varname> in the <literal>[Unit]</literal> section is set to
+ <option>no</option>, target units will implicitly complement all configured dependencies of type
+ <varname>Wants=</varname>, <varname>Requires=</varname> with dependencies of type <varname>After=</varname>, unless
+ an ordering dependency of any kind between the target and the respective other unit is already in place. Note that
+ this behaviour is disabled if either unit has <varname>DefaultDependencies=no</varname>.</para>
</refsect1>
<refsect1>
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index 29e235e2dc..0fa95e97a8 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -73,6 +73,12 @@
<filename>foo.timer</filename> activates a matching service
<filename>foo.service</filename>. The unit to activate may be
controlled by <varname>Unit=</varname> (see below).</para>
+
+ <para>Note that in case the unit to activate is already active at the time the timer elapses it is not restarted,
+ but simply left running. There is no concept of spawning new service instances in this case. Due to this, services
+ with <varname>RemainAfterExit=</varname> set (which stay around continously even after the service's main process
+ exited) are usually not suitable for activation via repetitive timers, as they will only be activated once, and
+ then stay around forever.</para>
</refsect1>
<refsect1>
@@ -81,21 +87,15 @@
<para>Timer units automatically gain a <varname>Before=</varname>
dependency on the service they are supposed to activate.</para>
- <para>Unless <varname>DefaultDependencies=</varname> is set to
- <option>false</option>, all timer units will implicitly have
- dependencies of type <varname>Requires=</varname> and
- <varname>After=</varname> on <filename>sysinit.target</filename>,
- a dependency of type <varname>Before=</varname> on
- <filename>timers.target</filename>, as well as
- <varname>Conflicts=</varname> and <varname>Before=</varname> on
- <filename>shutdown.target</filename> to ensure that they are
- stopped cleanly prior to system shutdown. Timer units with at
- least one <varname>OnCalendar=</varname> directive will have an
- additional <varname>After=</varname> dependency on
- <filename>timer-sync.target</filename> to avoid being started
- before the system clock has been correctly set. Only timer units
- involved with early boot or late system shutdown should disable
- the <varname>DefaultDependencies=</varname> option.</para>
+ <para>Unless <varname>DefaultDependencies=</varname> in the <literal>[Unit]</literal> section is set to
+ <option>false</option>, all timer units will implicitly have dependencies of type <varname>Requires=</varname> and
+ <varname>After=</varname> on <filename>sysinit.target</filename>, a dependency of type <varname>Before=</varname>
+ on <filename>timers.target</filename>, as well as <varname>Conflicts=</varname> and <varname>Before=</varname> on
+ <filename>shutdown.target</filename> to ensure that they are stopped cleanly prior to system shutdown. Timer units
+ with at least one <varname>OnCalendar=</varname> directive will have an additional <varname>After=</varname>
+ dependency on <filename>timer-sync.target</filename> to avoid being started before the system clock has been
+ correctly set. Only timer units involved with early boot or late system shutdown should disable the
+ <varname>DefaultDependencies=</varname> option.</para>
</refsect1>
<refsect1>
@@ -259,7 +259,8 @@
during the time when the timer was inactive. This is useful to
catch up on missed runs of the service when the machine was
off. Note that this setting only has an effect on timers
- configured with <varname>OnCalendar=</varname>.
+ configured with <varname>OnCalendar=</varname>. Defaults
+ to <varname>false</varname>.
</para></listitem>
</varlistentry>
@@ -287,7 +288,7 @@
starting a timer unit that only elapses once: if
<varname>RemainAfterElapse=</varname> is on, it will not be
started again, and is guaranteed to elapse only once. However,
- if <varname>RemainAfterLeapse=</varname> is off, it might be
+ if <varname>RemainAfterElapse=</varname> is off, it might be
started again if it is already elapsed, and thus be triggered
multiple times. Defaults to
<varname>yes</varname>.</para></listitem>
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 5794681963..341789cd47 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -66,18 +66,16 @@
<para><literallayout><filename>/etc/systemd/system/*</filename>
<filename>/run/systemd/system/*</filename>
<filename>/usr/lib/systemd/system/*</filename>
-<filename>...</filename>
+<filename>…</filename>
</literallayout></para>
- <para><literallayout><filename>$XDG_CONFIG_HOME/systemd/user/*</filename>
-<filename>$HOME/.config/systemd/user/*</filename>
+ <para><literallayout><filename>~/.config/systemd/user/*</filename>
<filename>/etc/systemd/user/*</filename>
<filename>$XDG_RUNTIME_DIR/systemd/user/*</filename>
<filename>/run/systemd/user/*</filename>
-<filename>$XDG_DATA_HOME/systemd/user/*</filename>
-<filename>$HOME/.local/share/systemd/user/*</filename>
+<filename>~/.local/share/systemd/user/*</filename>
<filename>/usr/lib/systemd/user/*</filename>
-<filename>...</filename>
+<filename>…</filename>
</literallayout></para>
</refsynopsisdiv>
@@ -558,14 +556,17 @@
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. If one unit
- with an ordering dependency on another unit is shut down while
- the latter is started up, the shut down is ordered before the
- start-up regardless of whether the ordering dependency is
- actually of type <varname>After=</varname> or
- <varname>Before=</varname>. If two units have no ordering
- dependencies between them, they are shut down or started up
- simultaneously, and no ordering takes place.
+ 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>. 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>
</varlistentry>
@@ -602,7 +603,7 @@
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details). If a unit that has this setting set is started,
its processes will see the same <filename>/tmp</filename>,
- <filename>/tmp/var</filename> and network namespace as one
+ <filename>/var/tmp</filename> and network namespace as one
listed unit that is started. If multiple listed units are
already started, it is not defined which namespace is joined.
Note that this setting only has an effect if
@@ -750,14 +751,14 @@
</varlistentry>
<varlistentry>
- <term><varname>StartLimitInterval=</varname></term>
+ <term><varname>StartLimitIntervalSec=</varname></term>
<term><varname>StartLimitBurst=</varname></term>
<listitem><para>Configure unit start rate limiting. By default, units which are started more than 5 times
within 10 seconds are not permitted to start any more times until the 10 second interval ends. With these two
- options, this rate limiting may be modified. Use <varname>StartLimitInterval=</varname> to configure the
- checking interval (defaults to <varname>DefaultStartLimitInterval=</varname> in manager configuration file, set
- to 0 to disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many
+ options, this rate limiting may be modified. Use <varname>StartLimitIntervalSec=</varname> to configure the
+ checking interval (defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file,
+ set to 0 to disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many
starts per interval are allowed (defaults to <varname>DefaultStartLimitBurst=</varname> in manager
configuration file). These configuration options are particularly useful in conjunction with the service
setting <varname>Restart=</varname> (see
@@ -768,14 +769,17 @@
manually at a later point, from which point on, the restart logic is again activated. Note that
<command>systemctl reset-failed</command> will cause the restart rate counter for a service to be flushed,
which is useful if the administrator wants to manually start a unit and the start limit interferes with
- that.</para></listitem>
+ that. Note that this rate-limiting is enforced after any unit condition checks are executed, and hence unit
+ activations with failing conditions are not counted by this rate limiting. Slice, target, device and scope
+ units do not enforce this setting, as they are unit types whose activation may either never fail, or may
+ succeed only a single time.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>StartLimitAction=</varname></term>
<listitem><para>Configure the action to take if the rate limit configured with
- <varname>StartLimitInterval=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes one of
+ <varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes one of
<option>none</option>, <option>reboot</option>, <option>reboot-force</option>,
<option>reboot-immediate</option>, <option>poweroff</option>, <option>poweroff-force</option> or
<option>poweroff-immediate</option>. If <option>none</option> is set, hitting the rate limit will trigger no
@@ -1101,13 +1105,12 @@
<varlistentry>
<term><varname>Alias=</varname></term>
- <listitem><para>A space-separated list of additional names
- this unit shall be installed under. The names listed here must
- have the same suffix (i.e. type) as the unit file name. This
- option may be specified more than once, in which case all
- listed names are used. At installation time,
- <command>systemctl enable</command> will create symlinks from
- these names to the unit filename.</para></listitem>
+ <listitem><para>A space-separated list of additional names this unit shall be installed under. The names listed
+ here must have the same suffix (i.e. type) as the unit file name. This option may be specified more than once,
+ in which case all listed names are used. At installation time, <command>systemctl enable</command> will create
+ symlinks from these names to the unit filename. Note that not all unit types support such alias names, and this
+ setting is not supported for them. Specifically, mount, slice, swap, and automount units do not support
+ aliasing.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 3b6b1e3f11..957475d2bd 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -157,13 +157,23 @@
<varlistentry>
<term><varname>d</varname></term>
- <listitem><para>Create a directory if it does not exist yet.
- </para></listitem>
+ <listitem><para>Create a directory. The mode and ownership will be adjusted if
+ specified and the directory already exists. Contents of this directory are subject
+ to time based cleanup if the time argument is specified.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>D</varname></term>
- <listitem><para>Create or empty a directory.</para></listitem>
+ <listitem><para>Similar to <varname>d</varname>, but in addition the contents
+ of the directory will be removed when <option>--remove</option> is used.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>e</varname></term>
+ <listitem><para>Similar to <varname>d</varname>, but the directory will not be
+ created if it does not exist. Lines of this type accept shell-style globs in
+ place of normal path names.</para></listitem>
</varlistentry>
<varlistentry>
@@ -577,7 +587,7 @@
unconditionally.</para>
<para>The age field only applies to lines starting with
- <varname>d</varname>, <varname>D</varname>,
+ <varname>d</varname>, <varname>D</varname>, <varname>e</varname>,
<varname>v</varname>, <varname>q</varname>,
<varname>Q</varname>, <varname>C</varname>, <varname>x</varname>
and <varname>X</varname>. If omitted or set to
@@ -612,22 +622,63 @@
</refsect1>
<refsect1>
- <title>Example</title>
+ <title>Examples</title>
<example>
- <title>/etc/tmpfiles.d/screen.conf example</title>
- <para><command>screen</command> needs two directories created at
- boot with specific modes and ownership.</para>
+ <title>Create directories with specific mode and ownership</title>
+ <para>
+ <citerefentry><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ needs two directories created at boot with specific modes and ownership:</para>
+
+ <programlisting># /usr/lib/tmpfiles.d/screen.conf
+d /run/screens 1777 root screen 10d
+d /run/uscreens 0755 root screen 10d12h
+</programlisting>
+
+ <para>Contents of <filename>/run/screens</filename> and /run/uscreens will
+ cleaned up after 10 and 10½ days, respectively.</para>
+ </example>
- <programlisting>d /run/screens 1777 root root 10d
-d /run/uscreens 0755 root root 10d12h
-t /run/screen - - - - user.name="John Smith" security.SMACK64=screen</programlisting>
+ <example>
+ <title>Create a directory with a SMACK attribute</title>
+ <programlisting>D /run/cups - - - -
+t /run/cups - - - - security.SMACK64=printing user.attr-with-spaces="foo bar"
+ </programlisting>
+
+ <para>The direcory will be owned by root and have default mode. It's contents are
+ not subject to time based cleanup, but will be obliterated when
+ <command>systemd-tmpfiles --remove</command> runs.</para>
</example>
+
<example>
- <title>/etc/tmpfiles.d/abrt.conf example</title>
- <para><command>abrt</command> needs a directory created at boot with specific mode and ownership and its content should be preserved.</para>
+ <title>Create a directory and prevent its contents from cleanup</title>
+ <para>
+ <citerefentry><refentrytitle>abrt</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ needs a directory created at boot with specific mode and ownership and its content
+ should be preserved from the automatic cleanup applied to the contents of
+ <filename>/var/tmp</filename>:</para>
+
+ <programlisting># /usr/lib/tmpfiles.d/tmp.conf
+d /var/tmp 1777 root root 30d
+</programlisting>
+
+ <programlisting># /usr/lib/tmpfiles.d/abrt.conf
+d /var/tmp/abrt 0755 abrt abrt -
+</programlisting>
+ </example>
- <programlisting>d /var/tmp/abrt 0755 abrt abrt
-x /var/tmp/abrt/*</programlisting>
+ <example>
+ <title>Apply clean up during boot and based on time</title>
+
+ <programlisting># /usr/lib/tmpfiles.d/dnf.conf
+r! /var/cache/dnf/*/*/download_lock.pid
+r! /var/cache/dnf/*/*/metadata_lock.pid
+r! /var/lib/dnf/rpmdb_lock.pid
+e /var/chache/dnf/ - - - 30d
+</programlisting>
+
+ <para>The lock files will be removed during boot. Any files and directories in
+ <filename>/var/chache/dnf/</filename> will be removed after they have not been
+ accessed in 30 days.</para>
</example>
</refsect1>
diff --git a/man/udev_device_get_syspath.xml b/man/udev_device_get_syspath.xml
index ca9763fedf..b54749ed56 100644
--- a/man/udev_device_get_syspath.xml
+++ b/man/udev_device_get_syspath.xml
@@ -127,6 +127,8 @@
<funcprototype>
<funcdef>struct udev_device *<function>udev_device_get_parent_with_subsystem_devtype</function></funcdef>
<paramdef>struct udev_device *<parameter>udev_device</parameter></paramdef>
+ <paramdef>const char *<parameter>subsystem</parameter></paramdef>
+ <paramdef>const char *<parameter>devtype</parameter></paramdef>
</funcprototype>
<funcprototype>
@@ -137,8 +139,6 @@
<funcprototype>
<funcdef>const char *<function>udev_device_get_action</function></funcdef>
<paramdef>struct udev_device *<parameter>udev_device</parameter></paramdef>
- <paramdef>const char *<parameter>subsystem</parameter></paramdef>
- <paramdef>const char *<parameter>devtype</parameter></paramdef>
</funcprototype>
</funcsynopsis>
diff --git a/move.sh b/move.sh
index 22caeb8a6f..3c9d359fbf 100755
--- a/move.sh
+++ b/move.sh
@@ -36,7 +36,6 @@ move_files() (
ask-password
backlight
binfmt
- bootchart
cgls
cgroups-agent
cgtop
@@ -58,6 +57,7 @@ move_files() (
reply-password
rfkill
run
+ stdio-bridge
timesync
tmpfiles
tty-ask-password-agent
@@ -70,16 +70,12 @@ move_files() (
mv -T src/{,systemd-}$d
done
-
- mv -T {,src/journal/}catalog
-
mv -T {shell-completion/bash/,src/kernel-install/bash-completion_}kernel-install
mv -T {shell-completion/zsh/_,src/kernel-install/zsh-completion_}kernel-install
mv -T {man,src/kernel-install}/kernel-install.xml
mv -T src/lib{shared,core}/linux
- mv -T src/{,libsystemd/}/compat-libs
mkdir src/libsystemd/include
mv -T src/{,libsystemd/include}/systemd
@@ -116,8 +112,6 @@ move_files() (
mkdir src/libudev/include
mv -T src/libudev/{src,include}/libudev.h
- mv -T {man,src/systemd-activate}/systemd-activate.xml
-
mv -T src/libsystemd/{src,}/libsystemd.pc.in
mv -T src/libsystemd/{src,}/libsystemd.sym
mv -T src/libsystemd/{src,}/.gitignore
@@ -176,12 +170,6 @@ move_files() (
mv -T src/{udev,libudev/src}/udev.h
- mv -T src/{bus-proxyd,libbus-proxy-core}
- mkdir src/systemd-bus-proxyd
- mv src/{libbus-proxy-core,systemd-bus-proxyd}/bus-proxyd.c
- mkdir src/systemd-stdio-bridge
- mv src/{libbus-proxy-core,systemd-stdio-bridge}/stdio-bridge.c
-
mkdir src/grp-timedate
mv -T src/timedate src/grp-timedate/systemd-timedated
mkdir src/grp-timedate/timedatectl
@@ -190,6 +178,20 @@ move_files() (
mv -T src/{libsystemd/libsystemd-internal/sd-netlink,libshared}/local-addresses.c
mv -T src/{libsystemd/libsystemd-internal/sd-netlink,libshared}/local-addresses.h
mv -T src/{libsystemd/libsystemd-internal/sd-netlink,libshared}/test-local-addresses.c
+
+ mv -T src/{journal,grp-journal}
+ mv -T {,src/grp-journal/}catalog
+ mkdir src/grp-journal/{systemd-journald,journalctl,libjournal-core}
+ mv -T src/grp-journal/{,systemd-journald}/journald.c
+ mv -T src/grp-journal/{,journalctl}/journalctl.c
+ mv src/grp-journal/*.* src/grp-journal/libjournal-core/
+
+ mv -T src/{,grp-}journal-remote
+ local suffix
+ for suffix in gatewayd remote upload; do
+ mkdir src/grp-journal-remote/systemd-journal-$suffix
+ mv src/grp-journal-remote/journal-$suffix* src/grp-journal-remote/systemd-journal-$suffix/
+ done
)
breakup_makefile() (
diff --git a/network/80-container-host0.network b/network/80-container-host0.network
index b65cc6acbe..b012cf98cb 100644
--- a/network/80-container-host0.network
+++ b/network/80-container-host0.network
@@ -5,6 +5,10 @@
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
+# This network file matches the container-side of the virtual Ethernet link
+# created by systemd-nspawn's --network-veth switch. See systemd-nspawn(1) for
+# details.
+
[Match]
Virtualization=container
Name=host0
@@ -12,6 +16,8 @@ Name=host0
[Network]
DHCP=yes
LinkLocalAddressing=yes
+LLDP=yes
+EmitLLDP=customer-bridge
[DHCP]
UseTimezone=yes
diff --git a/network/80-container-ve.network b/network/80-container-ve.network
index 72c20eba55..ac796bfb07 100644
--- a/network/80-container-ve.network
+++ b/network/80-container-ve.network
@@ -5,6 +5,10 @@
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
+# This network file matches the host-side of the virtual Ethernet link
+# created by systemd-nspawn's --network-veth switch. See systemd-nspawn(1) for
+# details.
+
[Match]
Name=ve-*
Driver=veth
@@ -15,3 +19,5 @@ Address=0.0.0.0/28
LinkLocalAddressing=yes
DHCPServer=yes
IPMasquerade=yes
+LLDP=yes
+EmitLLDP=customer-bridge
diff --git a/network/80-container-vz.network b/network/80-container-vz.network
new file mode 100644
index 0000000000..3d532d6f60
--- /dev/null
+++ b/network/80-container-vz.network
@@ -0,0 +1,22 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# This network file matches the bridge interface created by systemd-nspawn's
+# --network-zone= switch. See systemd-nspawn(1) for details.
+
+[Match]
+Name=vz-*
+Driver=bridge
+
+[Network]
+# Default to using a /24 prefix, giving up to 253 addresses per virtual network.
+Address=0.0.0.0/24
+LinkLocalAddressing=yes
+DHCPServer=yes
+IPMasquerade=yes
+LLDP=yes
+EmitLLDP=customer-bridge
diff --git a/po/LINGUAS b/po/LINGUAS
index 2774a3228f..8fee627265 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1,20 +1,22 @@
+be
+be@latin
+bg
+da
de
el
+es
fr
gl
+hr
hu
it
ko
pl
pt_BR
ru
-uk
-sv
sr
-es
+sv
+tr
+uk
zh_CN
zh_TW
-be
-be@latin
-tr
-da
diff --git a/po/bg.po b/po/bg.po
new file mode 100644
index 0000000000..5f92f8e2e7
--- /dev/null
+++ b/po/bg.po
@@ -0,0 +1,617 @@
+# Bulgarian translation of systemd po-file.
+# Copyright (C) 2016 Alexander Shopov <ash@kambanaria.org>
+# This file is distributed under the same license as the systemd package.
+# Alexander Shopov <ash@kambanaria.org>, 2016.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-05-14 13:28+0300\n"
+"PO-Revision-Date: 2016-05-14 13:28+0300\n"
+"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
+"Language-Team: Bulgarian <dict@ludost.net>\n"
+"Language: bg\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"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Изпращане на паролата към системата"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr "За изпращане на паролата към системата е необходима идентификация."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Manage system services or other units"
+msgstr "Управление на услугите или другите модули"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to manage system services or other units."
+msgstr ""
+"За управление на услугите или другите модули е необходима идентификация."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
+msgid "Manage system service or unit files"
+msgstr "Управление на файловете за услугите или другите модули"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
+msgid "Authentication is required to manage system service or unit files."
+msgstr ""
+"За управление на файловете за услугите или другите модули е необходима "
+"идентификация."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
+msgid "Set or unset system and service manager environment variables"
+msgstr ""
+"Задаване или изтриване на променливи на средата за системата и управлението "
+"на услугите"
+
+#: ../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 ""
+"За задаване или изтриване на променливи на средата за системата и "
+"управлението на услугите е необходима идентификация."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
+msgid "Reload the systemd state"
+msgstr "Презареждане на състоянието на systemd"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
+msgid "Authentication is required to reload the systemd state."
+msgstr "За презареждане на състоянието на systemd е необходима идентификация."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Задаване на име на машината"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "За задаване на име на локалната машина е необходима идентификация."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Задаване на статично име на машината"
+
+#: ../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 ""
+"За задаване на статично име на локалната машина е необходима идентификация."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Задаване на информация за машината"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr ""
+"За задаване на информация за локалната машина е необходима идентификация."
+
+#: ../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 "Задаване на локала на системата"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "За задаване на локала на системата е необходима идентификация."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Задаване на настройките на клавиатурата"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr "За задаване на настройките на клавиатурата е необходима идентификация."
+
+#: ../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 "Позволяване на програмите да забавят приспиването на системата"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid "Authentication is required for an application to delay system sleep."
+msgstr ""
+"За позволяване на програмите да забавят приспиването на системата е "
+"необходима идентификация."
+
+#: ../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 ""
+"Позволяване на потребители, които не са се идентифицирали, да изпълняват "
+"програми"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"За позволяване на потребители, които не са се идентифицирали, да изпълняват "
+"програми е необходима изрична заявка."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow non-logged-in users to run programs"
+msgstr ""
+"Позволяване на потребители, които не са се идентифицирали, да изпълняват "
+"програми"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required to run programs as a non-logged-in user."
+msgstr ""
+"За позволяване на потребители, които не са се идентифицирали, да изпълняват "
+"програми е необходима идентификация."
+
+#: ../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 "Изключване на системата"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid "Authentication is required for powering off the system."
+msgstr "За изключване на системата е необходима идентификация."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while other users are logged in"
+msgstr "Изключване на системата, дори когато има други вписани потребители"
+
+#: ../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 ""
+"За изключване на системата, дори когато има други вписани потребители, е "
+"необходима идентификация."
+
+#: ../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 "Рестартиране на системата"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid "Authentication is required for rebooting the system."
+msgstr "За рестартиране на системата е необходима идентификация."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while other users are logged in"
+msgstr "Рестартиране на системата, дори когато има други вписани потребители"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"За рестартиране на системата, дори когато има други вписани потребители, е "
+"необходима идентификация."
+
+#: ../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 "Приспиване на системата"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for suspending the system."
+msgstr "За приспиване на системата е необходима идентификация."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while other users are logged in"
+msgstr "Приспиване на системата, дори когато има други вписани потребители"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"За приспиване на системата, дори когато има други вписани потребители, е "
+"необходима идентификация."
+
+#: ../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 "Заключване или отключване на работещите сесии"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
+msgid "Authentication is required to lock or unlock active sessions."
+msgstr ""
+"За заключване или отключване на работещите сесии е необходима идентификация."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
+msgid "Allow indication to the firmware to boot to setup interface"
+msgstr ""
+"Позволяване на заявки към фърмуера да стартира с интерфейса за управление"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
+msgid ""
+"Authentication is required to indicate to the firmware to boot to setup "
+"interface."
+msgstr ""
+"За позволяване на заявки към фърмуера да стартира с интерфейса за управление "
+"е необходима идентификация."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
+msgid "Set a wall message"
+msgstr "Задаване на системно съобщение „wall“"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
+msgid "Authentication is required to set a wall message"
+msgstr "За задаване на системно съобщение „wall“ е необходима идентификация."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
+msgid "Log into a local container"
+msgstr "Вписване в локален контейнер"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
+msgid "Authentication is required to log into a local container."
+msgstr "За вписване в локален контейнер е необходима идентификация."
+
+#: ../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 "Превключване на системния часовник между местния часови пояс и UTC"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+"За превключване на системния часовник между местния часови пояс и UTC е "
+"необходима идентификация."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Превключване на синхронизацията на времето по мрежата"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"За превключване на синхронизацията на времето по мрежата е необходима "
+"идентификация."
+
+#: ../src/core/dbus-unit.c:450
+msgid "Authentication is required to start '$(unit)'."
+msgstr "За стартиране на „$(unit)“ е необходима идентификация."
+
+#: ../src/core/dbus-unit.c:451
+msgid "Authentication is required to stop '$(unit)'."
+msgstr "За спиране на „$(unit)“ е необходима идентификация."
+
+#: ../src/core/dbus-unit.c:452
+msgid "Authentication is required to reload '$(unit)'."
+msgstr "За презареждане на „$(unit)“ е необходима идентификация."
+
+#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
+msgid "Authentication is required to restart '$(unit)'."
+msgstr "За рестартиране на „$(unit)“ е необходима идентификация."
+
+#: ../src/core/dbus-unit.c:560
+msgid "Authentication is required to kill '$(unit)'."
+msgstr "За убиване на „$(unit)“ е необходима идентификация."
+
+#: ../src/core/dbus-unit.c:590
+msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
+msgstr ""
+"За премахване на състоянието за неуспех на „$(unit)“ е необходима "
+"идентификация."
+
+#: ../src/core/dbus-unit.c:622
+msgid "Authentication is required to set properties on '$(unit)'."
+msgstr "За задаване на свойствата на „$(unit)“ е необходима идентификация."
diff --git a/po/fr.po b/po/fr.po
index 96cdc7e774..17550c755e 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,13 +1,13 @@
# French translations for systemd package
# Traductions françaises du paquet systemd.
# This file is distributed under the same license as the systemd package.
-# Sylvain Plantefève <sylvain.plantefeve@gmail.com>, 2013-2015
+# Sylvain Plantefève <sylvain.plantefeve@gmail.com>, 2013-2016
#
msgid ""
msgstr ""
"Project-Id-Version: systemd\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-21 20:11+0200\n"
+"POT-Creation-Date: 2016-04-24 21:13+0200\n"
"PO-Revision-Date: 2014-12-28 13:04+0100\n"
"Last-Translator: Sylvain Plantefève <sylvain.plantefeve@gmail.com>\n"
"Language-Team: French\n"
@@ -254,48 +254,58 @@ msgstr ""
"gestion par le système du rabat de l'écran."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr "Permet à un utilisateur non connecté d'exécuter des programmes"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Requête explicite requise pour exécuter des programmes en tant "
+"qu'utilisateur non connecté."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
msgstr "Permet aux utilisateurs non connectés d'exécuter des programmes"
-#: ../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 ""
-"Authentification requise pour permettre aux utilisateurs non connectés "
-"d'exécuter des programmes."
+"Authentification requise pour exécuter des programmes en tant qu'utilisateur "
+"non connecté."
-#: ../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 "Permet d'associer des périphériques à des postes (seats)"
-#: ../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 ""
"Authentification requise pour associer un périphérique à un poste (seat)."
-#: ../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 "Révoquer les associations de périphériques aux postes (seats)"
-#: ../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 ""
"Authentification requise pour révoquer les associations de périphériques aux "
"postes (seats)."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
msgstr "Éteindre le système"
-#: ../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 "Authentification requise pour éteindre le système."
-#: ../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 "Éteindre le système alors que d'autres utilisateurs sont connectés"
-#: ../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 +313,11 @@ msgstr ""
"Authentification requise pour éteindre le système alors que d'autres "
"utilisateurs sont connectés."
-#: ../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 "Éteindre le système alors qu'une application a demandé de l'empêcher"
-#: ../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 +325,19 @@ msgstr ""
"Authentification requise pour éteindre le système alors qu'une application a "
"demandé de l'empêcher."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
msgstr "Redémarrer le système"
-#: ../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 "Authentification requise pour redémarrer le système."
-#: ../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 "Redémarrer le système alors que d'autres utilisateurs sont connectés"
-#: ../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 +345,11 @@ msgstr ""
"Authentification requise pour redémarrer le système alors que d'autres "
"utilisateurs sont connectés."
-#: ../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 "Redémarrer le système alors qu'une application a demandé de l'empêcher"
-#: ../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,20 +357,20 @@ msgstr ""
"Authentification requise pour redémarrer le système alors qu'une application "
"a demandé de l'empêcher."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
msgstr "Mettre le système en veille"
-#: ../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 "Authentification requise pour mettre le système en veille."
-#: ../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 ""
"Mettre le système en veille alors que d'autres utilisateurs sont connectés"
-#: ../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."
@@ -368,12 +378,12 @@ msgstr ""
"Authentification requise pour mettre le système en veille alors que d'autres "
"utilisateurs sont connectés."
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
msgstr ""
"Mettre le système en veille alors qu'une application a demandé de l'empêcher"
-#: ../src/login/org.freedesktop.login1.policy.in.h: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."
@@ -381,21 +391,21 @@ msgstr ""
"Authentification requise pour mettre le système en veille alors qu'une "
"application a demandé de l'empêcher."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
msgstr "Mettre le système en hibernation"
-#: ../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 "Authentification requise pour mettre le système en hibernation."
-#: ../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 ""
"Mettre le système en hibernation alors que d'autres utilisateurs sont "
"connectés"
-#: ../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."
@@ -403,13 +413,13 @@ msgstr ""
"Authentification requise pour mettre le système en hibernation alors que "
"d'autres utilisateurs sont connectés."
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
msgstr ""
"Mettre le système en hibernation alors qu'une application a demandé de "
"l'empêcher"
-#: ../src/login/org.freedesktop.login1.policy.in.h: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."
@@ -417,34 +427,34 @@ msgstr ""
"Authentification requise pour mettre le système en hibernation alors qu'une "
"application a demandé de l'empêcher."
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
msgstr "Gérer les sessions actives, les utilisateurs et les postes (seats)"
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid ""
"Authentication is required for managing active sessions, users and seats."
msgstr ""
"Authentification requise pour gérer les sessions actives, les utilisateurs "
"et les postes (seats)."
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
msgstr "Verrouiller ou déverrouiller des sessions actives"
-#: ../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 ""
"Authentification requise pour verrouiller ou déverrouiller des sessions "
"actives."
-#: ../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 ""
"Permet d'indiquer au micrologiciel de démarrer sur l'interface de "
"configuration"
-#: ../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."
@@ -452,11 +462,11 @@ msgstr ""
"Authentification requise pour indiquer au micrologiciel de démarrer sur "
"l'interface de configuration."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
msgstr "Définir un message wall"
-#: ../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 "Authentification requise pour définir un message wall."
@@ -581,33 +591,33 @@ msgstr ""
"Authentification requise pour activer ou désactiver la synchronisation de "
"l'heure avec le réseau."
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:450
msgid "Authentication is required to start '$(unit)'."
msgstr "Authentification requise pour démarrer « $(unit) »."
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:451
msgid "Authentication is required to stop '$(unit)'."
msgstr "Authentification requise pour arrêter « $(unit) »."
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:452
msgid "Authentication is required to reload '$(unit)'."
msgstr "Authentification requise pour recharger « $(unit) »."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
msgid "Authentication is required to restart '$(unit)'."
msgstr "Authentification requise pour redémarrer « $(unit) »."
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:560
msgid "Authentication is required to kill '$(unit)'."
msgstr "Authentification requise pour tuer « $(unit) »."
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:590
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr ""
"Authentification requise pour réinitialiser l'état d'« échec » de "
"« $(unit) »."
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:622
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Authentification requise pour définir des propriétés de « $(unit) »."
diff --git a/po/hr.po b/po/hr.po
new file mode 100644
index 0000000000..a0aff4331f
--- /dev/null
+++ b/po/hr.po
@@ -0,0 +1,570 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# gogo <trebelnik2@gmail.com>, 2016.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2016-27-04 11:57+0100\n"
+"PO-Revision-Date: 2016-04-27 12:11+0200\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.7.1\n"
+"Last-Translator: gogo <trebelnik2@gmail.com>com>\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"Language: hr\n"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Pošalji lozinku natrag u sustav"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr "Potrebna je ovjera za slanje upisane lozinke natrag u sustav."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Manage system services or other units"
+msgstr "Upravljajte uslugama sustava ili drugim jedinicama"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to manage system services or other units."
+msgstr "Potrebna je ovjera za upravljanje uslugama sustava ili jedinicama."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
+msgid "Manage system service or unit files"
+msgstr "Upravljajte uslugama sustava ili datotekama jedinica"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
+msgid "Authentication is required to manage system service or unit files."
+msgstr ""
+"Potrebna je ovjera za upravljanje uslugama sustava ili datotekama jedinica."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
+msgid "Set or unset system and service manager environment variables"
+msgstr "Postavite ili uklonite varijable okruženja sustava i usluga"
+
+#: ../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 ""
+"Potrebna je ovjera za postavljanje ili uklanjanje varijabla okruženja "
+"sustava i usluga."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
+msgid "Reload the systemd state"
+msgstr "Ponovno učitaj systemd stanje"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
+msgid "Authentication is required to reload the systemd state."
+msgstr "Potrebna je ovjera za ponovno učitavanje systemd stanja."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Postavi naziv računala"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Potrebna je ovjera za postavljanje naziva lokalnog računala."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Postavi nepromjenjivi naziv račumala"
+
+#: ../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 ""
+"Potrebna je ovjera za postavljenje nepromjenjivog naziva lokalnog računala, "
+"kao i prijatnog naziva računala."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Postavi informacije računala"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr "Potrebna je ovjera za postavljanje informacije lokalnog računala."
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:1
+msgid "Import a VM or container image"
+msgstr "Uvezi VM ili spremnik slike"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:2
+msgid "Authentication is required to import a VM or container image"
+msgstr "Potrebna je ovjera za uvoz WM ili spremnika slike"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:3
+msgid "Export a VM or container image"
+msgstr "Izvezi VM ili spremnik slike"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:4
+msgid "Authentication is required to export a VM or container image"
+msgstr "Potrebna je ovjera za izvoz WM ili spremnika slike"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:5
+msgid "Download a VM or container image"
+msgstr "Preuzmi VM ili spremnik slike"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:6
+msgid "Authentication is required to download a VM or container image"
+msgstr "Potrebna je ovjera za preuzimanje VM ili spremnika slike."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Postavi sustav lokalizacije"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "Potrebna je ovjera za postavljanje sustava lokalizacije."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Postavi postavke tipkovnice sustava"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr "Potrebna je ovjera za postavljanje postavki tipkovnice sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr "Dopusti aplikacijama zaustavljanje isključivanja sustava"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required for an application to inhibit system shutdown."
+msgstr ""
+"Potrebna je ovjera za dopuštanje aplikacijama zaustavljanje isključivanja "
+"sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr "Dopusti aplikacijama odgodu isključivanja sustava"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid "Authentication is required for an application to delay system shutdown."
+msgstr ""
+"Potrebna je ovjera za dopuštanje aplikacijama odgode isključivanja sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr "Dopusti aplikacijama zaustavljanje spavanja sustava"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid "Authentication is required for an application to inhibit system sleep."
+msgstr ""
+"Potrebna je ovjera za dopuštanje aplikacijama zaustavljanja spavanja sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Dopusti aplikacijama odgodu spavanja sustava"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid "Authentication is required for an application to delay system sleep."
+msgstr "Potrebna je ovjera za odgodu spavanja sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr "Dopusti aplikacijama zaustavljanje automatskog suspendiranja sustava"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required for an application to inhibit automatic system "
+"suspend."
+msgstr ""
+"Potrebna je ovjera za dopuštanje aplikacijama zaustavljanje automatskog "
+"suspendiranja sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr ""
+"Dopusti aplikacijama sprječavanje rukovanja sustava tipkom isključivanja"
+
+#: ../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 ""
+"Potrebna je ovjera za dopuštanje aplikacijama sprječavanje rukovanja sustava "
+"tipkom isključivanja."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr "Dopusti aplikacijama sprječavanje rukovanja sustava tipkom suspenzije"
+
+#: ../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 ""
+"Potrebna je ovjera za dopuštanje aplikacijama sprječavanje rukovanja sustava "
+"tipkom suspenzije."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr "Dopusti aplikacijama sprječavanje rukovanja sustava tipkom hibernacije"
+
+#: ../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 ""
+"Potrebna je ovjera za dopuštanje aplikacijama sprječavanje rukovanja sustava "
+"tipkom hibernacije."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr "Dopusti aplikacijama sprječavanje rukovanja sustava preklopnicama"
+
+#: ../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 ""
+"Potrebna je ovjera za dopuštenje sprječavanja rukovanja sustava "
+"preklopnicama."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in users to run programs"
+msgstr "Dopusti neprijavljenim korisnicima pokretanje programa"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Authentication is required to run programs as a non-logged-in user."
+msgstr ""
+"Potrebna je ovjera za dopuštenje neprijavljenim korisnicima pokretanje "
+"programa."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow attaching devices to seats"
+msgstr "Dopusti povezivanje uređaja skupu sesija i hardvera"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required for attaching a device to a seat."
+msgstr "Potrebna je ovjera za povezivanje uređaja sa skupom sesija i hardvera."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Flush device to seat attachments"
+msgstr "Ukloni povezani uređaj sa skupa sesija i hardvera"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
+msgid ""
+"Authentication is required for resetting how devices are attached to seats."
+msgstr ""
+"Potrebna je ovjera za obnovu povezivanja uređaja sa skupom sesija i hardvera."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
+msgid "Power off the system"
+msgstr "Isključi sustav"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
+msgid "Authentication is required for powering off the system."
+msgstr "Potrebna je ovjera za isključivanje sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
+msgid "Power off the system while other users are logged in"
+msgstr "Isključi sustav kada su ostali korisnici prijavljeni"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid ""
+"Authentication is required for powering off the system while other users are "
+"logged in."
+msgstr ""
+"Potrebna je ovjera za isključivanje sustava kada su ostali korisnici "
+"prijavljeni."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while an application asked to inhibit it"
+msgstr ""
+"Isključi sustav kada je aplikacija zatražila zaustavljanje isključivanja"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Potrebna je ovjera za isključivanje sustava kada je aplikacija zatražila "
+"zaustavljanje isključivanja."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
+msgid "Reboot the system"
+msgstr "Ponovno pokreni sustav"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
+msgid "Authentication is required for rebooting the system."
+msgstr "Potrebna je ovjera za ponovno pokretanje sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system while other users are logged in"
+msgstr "Ponovno pokreni sustav kada su ostali korisnici prijavljeni"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"Potrebna je ovjera za ponovno pokretanje sustava kada su ostali korisnici "
+"prijavljeni."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while an application asked to inhibit it"
+msgstr ""
+"Ponovno pokreni sustav kada je aplikacija zatražila zaustavljanje ponovnog "
+"pokretanja"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Potrebna je ovjera za ponovno pokretanje sustava kada je aplikacija "
+"zatražila zaustavljanje ponovnog pokretanja."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
+msgid "Suspend the system"
+msgstr "Suspendiraj sustav"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
+msgid "Authentication is required for suspending the system."
+msgstr "Potrebna je ovjera za suspendiranje sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system while other users are logged in"
+msgstr "Suspendiraj sustav kada su drugi korisnici prijavljeni"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"Potrebna je ovjera za suspendiranje sustava kada su drugi korisnici "
+"prijavljeni."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr ""
+"Suspendiraj sustav kada je aplikacija zatražila zaustavljanje suspendiranja"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Potrebna je ovjera za suspendiranje sustava kada je aplikacija zatražila "
+"zaustavljanje suspendiranja."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Hibernate the system"
+msgstr "Hiberniraj sustav"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid "Authentication is required for hibernating the system."
+msgstr "Potrebna je ovjera za hibernaciju sustava."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system while other users are logged in"
+msgstr "Hiberniraj sustav kada su ostali korisnici prijavljeni."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr ""
+"Potrebna je ovjera za hibernaciju sustava kada su drugi korisnici "
+"prijavljeni."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr ""
+"Hiberniraj sustav kada je aplikacija zatražila zaustavljanje hibernacije"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Potrebna je ovjera za hibernaciju sustava kada je aplikacija zatražila "
+"zaustavljanje hibernacije."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
+msgid "Manage active sessions, users and seats"
+msgstr ""
+"Upravljanje aktivnim sesijama, korisnicima i skupovima sesija i hardvera"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
+msgid ""
+"Authentication is required for managing active sessions, users and seats."
+msgstr ""
+"Potrebna je ovjera za upravljanje aktivnim sesijama, korisnicima i skupovima "
+"sesija i hardvera."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
+msgid "Lock or unlock active sessions"
+msgstr "Zaključavanje ili otključavanje aktivne sesije"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
+msgid "Authentication is required to lock or unlock active sessions."
+msgstr "Potrebna je ovjera za zaključavanje ili otključavanje aktivne sesije."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
+msgid "Allow indication to the firmware to boot to setup interface"
+msgstr "Dopusti najavu frimveru za pokretanje sučelja postavljanja"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
+msgid ""
+"Authentication is required to indicate to the firmware to boot to setup "
+"interface."
+msgstr "Potrebna je ovjera najave frimvera za pokretanje sučelja postavljanja."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
+msgid "Set a wall message"
+msgstr "Postavljanje zaslonske pruke"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
+msgid "Authentication is required to set a wall message"
+msgstr "Potrebna je ovjera za postavljanje zaslonske pruke."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
+msgid "Log into a local container"
+msgstr "Prijavi se u lokalni spremnik"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
+msgid "Authentication is required to log into a local container."
+msgstr "Potrebna je ovjera za prijavu u lokalni spremnik."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
+msgid "Log into the local host"
+msgstr "Prijava na lokalno računalo"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
+msgid "Authentication is required to log into the local host."
+msgstr "Potrebna je ovjera za prijavu na lokalno račuanlo."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
+msgid "Acquire a shell in a local container"
+msgstr "Pokretanje ljuske u lokalnom spremniku"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
+msgid "Authentication is required to acquire a shell in a local container."
+msgstr "Potrebna je ovjera za pokretanje ljuske u lokalnom spremniku."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
+msgid "Acquire a shell on the local host"
+msgstr "Pokretanje ljuske na lokalnom računalu"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
+msgid "Authentication is required to acquire a shell on the local host."
+msgstr "Potrebna je ovjera za pokretanje ljuske na lokalnom računalu."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
+msgid "Acquire a pseudo TTY in a local container"
+msgstr "Pokretanje pseudo TTY na lokalnom spremniku"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
+msgid ""
+"Authentication is required to acquire a pseudo TTY in a local container."
+msgstr "Potrebna je ovjera za pokretanje pseudo TTY na lokalnom spremniku."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
+msgid "Acquire a pseudo TTY on the local host"
+msgstr "Pokretanje pseudo TTY na lokalnom računalu"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
+msgid "Authentication is required to acquire a pseudo TTY on the local host."
+msgstr "Potrebna je ovjera za pokretanje pseudo TTY na lokalnom računalu."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
+msgid "Manage local virtual machines and containers"
+msgstr "Upravljanje lokalnim vurtualnim strojevima i spremnicima"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
+msgid ""
+"Authentication is required to manage local virtual machines and containers."
+msgstr ""
+"Potrebna je ovjera za upravljanje lokalnim vurtualnim strojevima i "
+"spremnicima."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
+msgid "Manage local virtual machine and container images"
+msgstr "Upravljanje lokalnim vurtualnim strojevima i spremnicima slika"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
+msgid ""
+"Authentication is required to manage local virtual machine and container "
+"images."
+msgstr ""
+"Potrebna je ovjera za upravljanje lokalnim vurtualnim strojevima i "
+"spremnicima slika."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr "Postavi vrijeme sustava"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr "Potrebna je ovjera za postavljanje vremena sustava."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr "Postavi vremensku zonu sustava"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr "Potrebna je ovjera za postavljanje vremenske zone sustava."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr "Postavi RTC u lokalnu vremensku zonu ili UTC"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+"Potrebna je ovjera za postavljanje RTC-a u lokalnu vremensku zonu ili UTC."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Uključi ili isključi mrežno uklađivanje vremena"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Potrebna je ovjera za uključivanje ili isključivanje mrežnog usklađivanja "
+"vremena."
+
+#: ../src/core/dbus-unit.c:428
+msgid "Authentication is required to start '$(unit)'."
+msgstr "Potrebna je ovjera za pokretanje '$(unit)'."
+
+#: ../src/core/dbus-unit.c:429
+msgid "Authentication is required to stop '$(unit)'."
+msgstr "Potrebna je ovjera za zaustavljanje '$(unit)'."
+
+#: ../src/core/dbus-unit.c:430
+msgid "Authentication is required to reload '$(unit)'."
+msgstr "Potrebna je ovjera za ponovno učitavnje '$(unit)'."
+
+#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+msgid "Authentication is required to restart '$(unit)'."
+msgstr "Potrebna je ovjera za ponovno pokretanje'$(unit)'."
+
+#: ../src/core/dbus-unit.c:535
+msgid "Authentication is required to kill '$(unit)'."
+msgstr "Potrebna je ovjera za ubijanje '$(unit)'."
+
+#: ../src/core/dbus-unit.c:565
+msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
+msgstr "Potrebna je ovjera za vraćanje \"neuspjelog\" stanja '$(unit)'."
+
+#: ../src/core/dbus-unit.c:597
+msgid "Authentication is required to set properties on '$(unit)'."
+msgstr "Potrebna je ovjera za postavljanje svojstava na '$(unit)'."
diff --git a/po/it.po b/po/it.po
index a8547b9395..24504da42b 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: systemd\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2015-11-22 16:54+0100\n"
+"POT-Creation-Date: 2016-05-07 04:45+0200\n"
+"PO-Revision-Date: 2016-05-07 04:55+0200\n"
"Last-Translator: Daniele Medri <dmedri@gmail.com>\n"
"Language-Team: Italian\n"
"Language: it\n"
@@ -16,11 +16,11 @@ msgstr ""
"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.8.5\n"
+"X-Generator: Poedit 1.8.7.1\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
-msgstr "Inviare la frase segreta (passphrase) al sistema"
+msgstr "Invia la frase segreta (passphrase) al sistema"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
msgid ""
@@ -63,7 +63,7 @@ msgstr ""
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
-msgstr "Riavviare lo stato di systemd"
+msgstr "Riavvia lo stato di systemd"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
msgid "Authentication is required to reload the systemd state."
@@ -251,48 +251,58 @@ msgstr ""
"gestione di sistema alla apertura/chiusura del portatile."
#: ../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 "Consenti agli utenti non connessi di eseguire programmi"
#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"E' necessaria un'esplicita richiesta per eseguire programmi come utenti non "
+"connessi."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow non-logged-in users to run programs"
+msgstr "Consenti agli utenti non connessi di eseguire programmi"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
msgstr ""
"Autenticazione richiesta per consentire agli utenti non connessi di eseguire "
"programmi."
-#: ../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 "Consenti di collegare dispositivi alle postazioni"
-#: ../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 ""
"Autenticazione richiesta per collegare un dispositivo ad una postazione."
-#: ../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 "Scollega i dispositivi dalla postazione"
-#: ../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 ""
"Autenticazione richiesta per ripristinare come i dispositivi sono collegati "
"alle postazioni."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
-msgstr "Spegnere il sistema"
+msgstr "Spegni il sistema (power off)"
-#: ../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 "Autenticazione richiesta per spegnere il 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 "Spegnere il sistema mentre altri utenti sono connessi"
+msgstr "Spegni il sistema (power off) mentre altri utenti sono connessi"
-#: ../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."
@@ -300,11 +310,13 @@ msgstr ""
"Autenticazione richiesta per spegnere il sistema mentre altri utenti sono "
"connessi."
-#: ../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 "Spegnere il sistema mentre un'applicazione chiede di inibirne l'azione"
+msgstr ""
+"Spegni il sistema (power off) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../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."
@@ -312,19 +324,19 @@ msgstr ""
"Autenticazione richiesta per spegnere il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
-msgstr "Riavviare il sistema"
+msgstr "Riavvia il sistema (reboot)"
-#: ../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 "Autenticazione richiesta per riavviare il 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 "Riavviare il sistema mentre altri utenti sono connessi"
+msgstr "Riavvia il sistema (reboot) mentre altri utenti sono connessi"
-#: ../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."
@@ -332,12 +344,13 @@ msgstr ""
"Autenticazione richiesta per riavviare il sistema mentre altri utenti sono "
"connessi."
-#: ../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 ""
-"Riavviare il sistema mentre un'applicazione chiede di inibirne l'azione"
+"Riavvia il sistema (reboot) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../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."
@@ -345,19 +358,19 @@ msgstr ""
"Autenticazione richiesta per riavviare il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
-msgstr "Sospendere il sistema"
+msgstr "Sospendi il sistema (suspend)"
-#: ../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 "Autenticazione richiesta per sospendere il 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 "Sospendere il sistema mentre altri utenti sono connessi"
+msgstr "Sospendi il sistema (suspend) mentre altri utenti sono connessi"
-#: ../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."
@@ -365,12 +378,13 @@ msgstr ""
"Autenticazione richiesta per sospendere il sistema mentre altri utenti sono "
"connessi."
-#: ../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 ""
-"Sospendere il sistema mentre un'applicazione chiede di inibirne l'azione"
+"Sospendi il sistema (suspend) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../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."
@@ -378,19 +392,19 @@ msgstr ""
"Autenticazione richiesta per sospendere il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
-msgstr "Ibernare il sistema"
+msgstr "Iberna il sistema (hibernate)"
-#: ../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 "Autenticazione richiesta per ibernare il 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 "Ibernare il sistema mentre altri utenti sono connessi"
+msgstr "Iberna il sistema (hibernate) mentre altri utenti sono connessi"
-#: ../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."
@@ -398,11 +412,13 @@ msgstr ""
"Autenticazione richiesta per ibernare il sistema mentre altri utenti sono "
"connessi."
-#: ../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 "Ibernare il sistema mentre un'applicazione chiede di inibirne l'azione"
+msgstr ""
+"Iberna il sistema (hibernate) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../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."
@@ -410,32 +426,32 @@ msgstr ""
"Autenticazione richiesta per ibernare il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../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 "Gestione delle sessioni attive, utenti e postazioni"
-#: ../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 ""
"Autenticazione richiesta per gestire le sessioni attive, gli utenti e le "
"postazioni."
-#: ../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 "Blocca/sblocca sessioni attive"
-#: ../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 "Autenticazione richiesta per bloccare o sbloccare le sessioni attive."
-#: ../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 ""
"Permette indicazioni per il firmware per avviare l'interfaccia di "
"configurazione"
-#: ../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."
@@ -443,11 +459,11 @@ msgstr ""
"Autenticazione richiesta per indicare al firmware di avviare l'interfaccia "
"di configurazione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
msgstr "Configura un messaggio per gli utenti"
-#: ../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 "Autenticazione richiesta per configurare un messaggio per gli utenti"
@@ -565,31 +581,31 @@ msgstr ""
"Autenticazione richiesta per verificare se la sincronizzazione dell'orario "
"in rete possa essere attivata."
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:450
msgid "Authentication is required to start '$(unit)'."
msgstr "Autenticazione richiesta per avviare '$(unit)'."
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:451
msgid "Authentication is required to stop '$(unit)'."
msgstr "Autenticazione richiesta per fermare '$(unit)'."
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:452
msgid "Authentication is required to reload '$(unit)'."
msgstr "Autenticazione richiesta per ricaricare '$(unit)'."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
msgid "Authentication is required to restart '$(unit)'."
msgstr "Autenticazione richiesta per riavviare '$(unit)'."
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:560
msgid "Authentication is required to kill '$(unit)'."
msgstr "Autenticazione richiesta per terminare '$(unit)'."
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:590
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr ""
"Autenticazione richiesta per riconfigurare lo stato \"fallito\" di '$(unit)'."
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:622
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Autenticazione richiesta per configurare le proprietà di '$(unit)'."
diff --git a/po/pl.po b/po/pl.po
index d3e2ae8418..92e9a209cc 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,13 +1,13 @@
# translation of pl.po to Polish
-# Piotr Drąg <piotrdrag@gmail.com>, 2011, 2013, 2014, 2015.
+# Piotr Drąg <piotrdrag@gmail.com>, 2011, 2013, 2014, 2015, 2016.
# Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: systemd\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-06 20:39+0200\n"
-"PO-Revision-Date: 2015-09-06 20:40+0200\n"
+"POT-Creation-Date: 2016-04-23 14:24+0200\n"
+"PO-Revision-Date: 2016-04-23 14:25+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
"Language: pl\n"
@@ -241,48 +241,58 @@ msgstr ""
"przez system."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr "Zezwolenie niezalogowanemu użytkownikowi na uruchamianie programów"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Wymagane jest bezpośrednie żądanie, aby uruchamiać programy jako "
+"niezalogowany użytkownik."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
msgstr "Zezwolenie niezalogowanym użytkownikom na uruchamianie programów"
-#: ../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 ""
"Wymagane jest uwierzytelnienie, aby uruchamiać programy jako niezalogowany "
"użytkownik."
-#: ../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 "Zezwolenie na podłączanie urządzeń do stanowisk"
-#: ../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 ""
"Wymagane jest uwierzytelnienie, aby podłączyć urządzenie do stanowiska."
-#: ../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 "Usunięcie podłączenia urządzeń do stanowisk"
-#: ../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 ""
"Wymagane jest uwierzytelnienie, aby ponownie ustawić sposób podłączenia "
"urządzeń do stanowisk."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
msgstr "Wyłączenie systemu"
-#: ../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 "Wymagane jest uwierzytelnienie, aby wyłączyć system."
-#: ../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 "Wyłączenie systemu, kiedy są zalogowani inni użytkownicy"
-#: ../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."
@@ -290,11 +300,11 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby wyłączyć system, kiedy są zalogowani "
"inni użytkownicy."
-#: ../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 "Wyłączenie systemu, kiedy program zażądał jego wstrzymania"
-#: ../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."
@@ -302,19 +312,19 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby wyłączyć system, kiedy program zażądał "
"jego wstrzymania."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
msgstr "Ponowne uruchomienie systemu"
-#: ../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 "Wymagane jest uwierzytelnienie, aby ponownie uruchomić system."
-#: ../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 "Ponowne uruchomienie systemu, kiedy są zalogowani inni użytkownicy"
-#: ../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."
@@ -322,11 +332,11 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby ponownie uruchomić system, kiedy są "
"zalogowani inni użytkownicy."
-#: ../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 "Ponowne uruchomienie systemu, kiedy program zażądał jego wstrzymania"
-#: ../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."
@@ -334,19 +344,19 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby ponownie uruchomić system, kiedy program "
"zażądał jego wstrzymania."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
msgstr "Uśpienie systemu"
-#: ../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 "Wymagane jest uwierzytelnienie, aby uśpić system."
-#: ../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 "Uśpienie systemu, kiedy są zalogowani inni użytkownicy"
-#: ../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."
@@ -354,11 +364,11 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby uśpić system, kiedy są zalogowani inni "
"użytkownicy."
-#: ../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 "Uśpienie systemu, kiedy program zażądał jego wstrzymania"
-#: ../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."
@@ -366,19 +376,19 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby uśpić system, kiedy program zażądał jego "
"wstrzymania."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
msgstr "Hibernacja systemu"
-#: ../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 "Wymagane jest uwierzytelnienie, aby zahibernować system."
-#: ../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 "Hibernacja systemu, kiedy są zalogowani inni użytkownicy"
-#: ../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."
@@ -386,11 +396,11 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby zahibernować system, kiedy są zalogowani "
"inni użytkownicy."
-#: ../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 "Hibernacja systemu, kiedy program zażądał jej wstrzymania"
-#: ../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."
@@ -398,31 +408,31 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby zahibernować system, kiedy program "
"zażądał jej wstrzymania."
-#: ../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 "Zarządzanie aktywnymi sesjami, użytkownikami i stanowiskami"
-#: ../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 ""
"Wymagane jest uwierzytelnienie, aby zarządzać aktywnymi sesjami, "
"użytkownikami i stanowiskami."
-#: ../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 "Zablokowanie lub odblokowanie aktywnych sesji"
-#: ../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 ""
"Wymagane jest uwierzytelnienie, aby zablokować lub odblokować aktywne sesje."
-#: ../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 "Wskazanie oprogramowaniu sprzętowemu, aby uruchomić interfejs ustawień"
-#: ../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."
@@ -430,11 +440,11 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby wskazać oprogramowaniu sprzętowemu, że "
"należy uruchomić interfejs ustawień."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
msgstr "Ustawienie komunikatu wall"
-#: ../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 "Wymagane jest uwierzytelnienie, aby ustawić komunikat wall"
@@ -557,36 +567,36 @@ msgstr ""
"Wymagane jest uwierzytelnienie, aby kontrolować, czy włączyć synchronizację "
"czasu przez sieć."
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:450
msgid "Authentication is required to start '$(unit)'."
msgstr "Wymagane jest uwierzytelnienie, aby uruchomić jednostkę „$(unit)”."
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:451
msgid "Authentication is required to stop '$(unit)'."
msgstr "Wymagane jest uwierzytelnienie, aby zatrzymać jednostkę „$(unit)”."
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:452
msgid "Authentication is required to reload '$(unit)'."
msgstr ""
"Wymagane jest uwierzytelnienie, aby ponownie wczytać jednostkę „$(unit)”."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
msgid "Authentication is required to restart '$(unit)'."
msgstr ""
"Wymagane jest uwierzytelnienie, aby ponownie uruchomić jednostkę „$(unit)”."
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:560
msgid "Authentication is required to kill '$(unit)'."
msgstr ""
"Wymagane jest uwierzytelnienie, aby wymusić wyłączenie jednostki „$(unit)”."
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:590
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr ""
"Wymagane jest uwierzytelnienie, aby przywrócić stan „failed” (niepowodzenia) "
"jednostki „$(unit)”."
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:622
msgid "Authentication is required to set properties on '$(unit)'."
msgstr ""
"Wymagane jest uwierzytelnienie, aby ustawić właściwości jednostki „$(unit)”."
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 67639620fb..10c53d4538 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -4,19 +4,20 @@
#
# Frank Hill <hxf.prc@gmail.com>, 2014.
# Boyuan Yang <073plan@gmail.com>, 2015.
+# Jeff Bai <jeffbai@aosc.xyz>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: systemd\n"
"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
"POT-Creation-Date: 2015-10-27 02:24+0000\n"
-"PO-Revision-Date: 2015-10-28 15:00+0800\n"
-"Last-Translator: Boyuan Yang <073plan@gmail.com>\n"
+"PO-Revision-Date: 2016-03-01 20:38-0700\n"
+"Last-Translator: Jeff Bai <jeffbai@aosc.xyz>\n"
"Language-Team: Chinese <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Lokalize 2.0\n"
+"X-Generator: Poedit 1.8.7.1\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
@@ -26,7 +27,7 @@ msgstr "将密码发回系统"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
msgid ""
"Authentication is required to send the entered passphrase back to the system."
-msgstr "将输入的密码发回系统需要验证。"
+msgstr "将输入的密码发回系统需要认证。"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
msgid "Manage system services or other units"
@@ -34,7 +35,7 @@ msgstr "管理系统服务或其它单元"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
msgid "Authentication is required to manage system services or other units."
-msgstr "管理系统服务或其它单元需要验证。"
+msgstr "管理系统服务或其它单元需要认证。"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
msgid "Manage system service or unit files"
@@ -42,7 +43,7 @@ msgstr "管理系统服务或单元文件"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
msgid "Authentication is required to manage system service or unit files."
-msgstr "管理系统服务或单元文件需要验证。"
+msgstr "管理系统服务或单元文件需要认证。"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
msgid "Set or unset system and service manager environment variables"
@@ -52,7 +53,7 @@ msgstr "设置或清除系统及服务管理器的环境变量"
msgid ""
"Authentication is required to set or unset system and service manager "
"environment variables."
-msgstr "设置或清除系统及服务管理器的环境变量需要验证。"
+msgstr "设置或清除系统及服务管理器的环境变量需要认证。"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
@@ -60,7 +61,7 @@ msgstr "重新载入 systemd 状态"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
msgid "Authentication is required to reload the systemd state."
-msgstr "重新载入 systemd 状态需要验证。"
+msgstr "重新载入 systemd 状态需要认证。"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
msgid "Set host name"
@@ -68,7 +69,7 @@ msgstr "设置主机名"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
msgid "Authentication is required to set the local host name."
-msgstr "设置本地主机名需要验证。"
+msgstr "设置本地主机名需要认证。"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
msgid "Set static host name"
@@ -82,7 +83,7 @@ msgstr "设置静态主机名"
msgid ""
"Authentication is required to set the statically configured local host name, "
"as well as the pretty host name."
-msgstr "设置静态本地主机名或漂亮的主机名需要验证。"
+msgstr "设置静态本地主机名或美观主机名需要认证。"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
msgid "Set machine information"
@@ -90,7 +91,7 @@ msgstr "设置机器信息"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
msgid "Authentication is required to set local machine information."
-msgstr "设置本地机器信息需要验证。"
+msgstr "设置本地机器信息需要认证。"
#: ../src/import/org.freedesktop.import1.policy.in.h:1
msgid "Import a VM or container image"
@@ -98,7 +99,7 @@ msgstr "导入虚拟机或容器镜像"
#: ../src/import/org.freedesktop.import1.policy.in.h:2
msgid "Authentication is required to import a VM or container image"
-msgstr "导入虚拟机或容器镜像需要验证"
+msgstr "导入虚拟机或容器镜像需要认证"
#: ../src/import/org.freedesktop.import1.policy.in.h:3
msgid "Export a VM or container image"
@@ -106,7 +107,7 @@ msgstr "导出虚拟机或容器镜像"
#: ../src/import/org.freedesktop.import1.policy.in.h:4
msgid "Authentication is required to export a VM or container image"
-msgstr "导出虚拟机或容器镜像需要验证"
+msgstr "导出虚拟机或容器镜像需要认证"
#: ../src/import/org.freedesktop.import1.policy.in.h:5
msgid "Download a VM or container image"
@@ -114,7 +115,7 @@ msgstr "下载虚拟机或容器镜像"
#: ../src/import/org.freedesktop.import1.policy.in.h:6
msgid "Authentication is required to download a VM or container image"
-msgstr "下载虚拟机或容器镜像需要验证。"
+msgstr "下载虚拟机或容器镜像需要认证。"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
msgid "Set system locale"
@@ -122,7 +123,7 @@ msgstr "设置系统区域和语言"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
msgid "Authentication is required to set the system locale."
-msgstr "设置系统区域和语言需要验证。"
+msgstr "设置系统区域和语言需要认证。"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
msgid "Set system keyboard settings"
@@ -130,7 +131,7 @@ msgstr "设置系统键盘"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
msgid "Authentication is required to set the system keyboard settings."
-msgstr "设置系统键盘需要验证。"
+msgstr "设置系统键盘需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:1
msgid "Allow applications to inhibit system shutdown"
@@ -139,7 +140,7 @@ msgstr "允许应用程序阻止系统关机"
#: ../src/login/org.freedesktop.login1.policy.in.h:2
msgid ""
"Authentication is required for an application to inhibit system shutdown."
-msgstr "要允许应用程序阻止系统关机需要验证。"
+msgstr "允许应用程序阻止系统关机需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:3
msgid "Allow applications to delay system shutdown"
@@ -147,7 +148,7 @@ msgstr "允许应用程序延迟系统关机"
#: ../src/login/org.freedesktop.login1.policy.in.h:4
msgid "Authentication is required for an application to delay system shutdown."
-msgstr "要允许应用程序延迟系统关机需要验证。"
+msgstr "允许应用程序延迟系统关机需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:5
msgid "Allow applications to inhibit system sleep"
@@ -155,7 +156,7 @@ msgstr "允许应用程序阻止系统睡眠"
#: ../src/login/org.freedesktop.login1.policy.in.h:6
msgid "Authentication is required for an application to inhibit system sleep."
-msgstr "要允许应用程序阻止系统睡眠需要验证。"
+msgstr "允许应用程序阻止系统睡眠需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:7
msgid "Allow applications to delay system sleep"
@@ -163,7 +164,7 @@ msgstr "允许应用程序延迟系统睡眠"
#: ../src/login/org.freedesktop.login1.policy.in.h:8
msgid "Authentication is required for an application to delay system sleep."
-msgstr "要允许应用程序延迟系统睡眠需要验证。"
+msgstr "允许应用程序延迟系统睡眠需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:9
msgid "Allow applications to inhibit automatic system suspend"
@@ -173,7 +174,7 @@ msgstr "允许应用程序阻止系统自动挂起"
msgid ""
"Authentication is required for an application to inhibit automatic system "
"suspend."
-msgstr "要允许应用程序阻止系统自动挂起需要验证。"
+msgstr "允许应用程序阻止系统自动挂起需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:11
msgid "Allow applications to inhibit system handling of the power key"
@@ -183,7 +184,7 @@ msgstr "允许应用程序阻止系统响应电源键"
msgid ""
"Authentication is required for an application to inhibit system handling of "
"the power key."
-msgstr "要允许应用程序阻止系统响应电源键需要验证。"
+msgstr "允许应用程序阻止系统响应电源键需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:13
msgid "Allow applications to inhibit system handling of the suspend key"
@@ -193,7 +194,7 @@ msgstr "允许应用程序阻止系统响应挂起键"
msgid ""
"Authentication is required for an application to inhibit system handling of "
"the suspend key."
-msgstr "要允许应用程序阻止系统响应挂起键需要验证。"
+msgstr "允许应用程序阻止系统响应挂起键需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:15
msgid "Allow applications to inhibit system handling of the hibernate key"
@@ -203,19 +204,17 @@ msgstr "允许应用程序阻止系统响应挂起键"
msgid ""
"Authentication is required for an application to inhibit system handling of "
"the hibernate key."
-msgstr "要允许应用程序阻止系统响应挂起键需要验证。"
+msgstr "允许应用程序阻止系统响应挂起键需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:17
-#, fuzzy
msgid "Allow applications to inhibit system handling of the lid switch"
msgstr "允许应用程序阻止系统响应笔记本上盖开关事件"
#: ../src/login/org.freedesktop.login1.policy.in.h:18
-#, fuzzy
msgid ""
"Authentication is required for an application to inhibit system handling of "
"the lid switch."
-msgstr "要允许应用程序阻止系统响应笔记本上盖开关事件需要验证。"
+msgstr "允许应用程序阻止系统响应笔记本上盖开关事件需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:19
msgid "Allow non-logged-in users to run programs"
@@ -223,7 +222,7 @@ msgstr "允许未登录用户运行程序"
#: ../src/login/org.freedesktop.login1.policy.in.h:20
msgid "Authentication is required to run programs as a non-logged-in user."
-msgstr "要允许未登录用户运行程序需要验证。"
+msgstr "允许未登录用户运行程序需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow attaching devices to seats"
@@ -234,7 +233,7 @@ msgstr "允许将设备附加至会话座位"
# To fully understand the meaning, please refer to session management in old ConsoleKit and new systemd-logind.
#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required for attaching a device to a seat."
-msgstr "要允许将设备附加至某个会话座位需要验证。"
+msgstr "允许将设备附加至某个会话座位需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Flush device to seat attachments"
@@ -243,7 +242,7 @@ msgstr "刷新设备至会话座位间的连接"
#: ../src/login/org.freedesktop.login1.policy.in.h:24
msgid ""
"Authentication is required for resetting how devices are attached to seats."
-msgstr "重新设定设备的会话座位接入方式时需要验证。"
+msgstr "重新设定设备的会话座位接入方式时需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:25
msgid "Power off the system"
@@ -251,7 +250,7 @@ msgstr "关闭系统"
#: ../src/login/org.freedesktop.login1.policy.in.h:26
msgid "Authentication is required for powering off the system."
-msgstr "关闭系统需要验证。"
+msgstr "关闭系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system while other users are logged in"
@@ -261,7 +260,7 @@ msgstr "存在其他已登录用户时仍然关机"
msgid ""
"Authentication is required for powering off the system while other users are "
"logged in."
-msgstr "存在其他已登录用户时关闭系统需要验证。"
+msgstr "存在其他已登录用户时关闭系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:29
msgid "Power off the system while an application asked to inhibit it"
@@ -271,7 +270,7 @@ msgstr "有其它应用程序阻止时仍然关机"
msgid ""
"Authentication is required for powering off the system while an application "
"asked to inhibit it."
-msgstr "要在其它应用程序阻止关机时关闭系统需要验证。"
+msgstr "在其它应用程序阻止关机时关闭系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:31
msgid "Reboot the system"
@@ -279,7 +278,7 @@ msgstr "重启系统"
#: ../src/login/org.freedesktop.login1.policy.in.h:32
msgid "Authentication is required for rebooting the system."
-msgstr "重启系统需要验证。"
+msgstr "重启系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system while other users are logged in"
@@ -289,7 +288,7 @@ msgstr "存在其他已登录用户时仍然重启"
msgid ""
"Authentication is required for rebooting the system while other users are "
"logged in."
-msgstr "存在其他已登录用户时重启系统需要验证。"
+msgstr "存在其他已登录用户时重启系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:35
msgid "Reboot the system while an application asked to inhibit it"
@@ -299,7 +298,7 @@ msgstr "有其它应用程序阻止时仍然重启"
msgid ""
"Authentication is required for rebooting the system while an application "
"asked to inhibit it."
-msgstr "要在其它应用程序阻止重启时重启系统需要验证。"
+msgstr "在其它应用程序阻止重启时重启系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:37
msgid "Suspend the system"
@@ -307,7 +306,7 @@ msgstr "挂起系统"
#: ../src/login/org.freedesktop.login1.policy.in.h:38
msgid "Authentication is required for suspending the system."
-msgstr "挂起系统需要验证。"
+msgstr "挂起系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system while other users are logged in"
@@ -317,7 +316,7 @@ msgstr "存在其他已登录用户时仍然挂起系统"
msgid ""
"Authentication is required for suspending the system while other users are "
"logged in."
-msgstr "存在其他已登录用户时挂起系统需要验证。"
+msgstr "存在其他已登录用户时挂起系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while an application asked to inhibit it"
@@ -327,15 +326,15 @@ msgstr "有其它应用程序阻止时仍然挂起系统"
msgid ""
"Authentication is required for suspending the system while an application "
"asked to inhibit it."
-msgstr "要在其它应用程序阻止挂起时挂起系统需要验证。"
+msgstr "在其它应用程序阻止挂起时挂起系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Hibernate the system"
-msgstr "休眠"
+msgstr "休眠系统"
#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid "Authentication is required for hibernating the system."
-msgstr "休眠需要验证。"
+msgstr "休眠系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system while other users are logged in"
@@ -345,7 +344,7 @@ msgstr "存在其他已登录用户时仍然休眠"
msgid ""
"Authentication is required for hibernating the system while other users are "
"logged in."
-msgstr "存在其他已登录用户时进行休眠需要验证。"
+msgstr "存在其他已登录用户时进行休眠系统需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while an application asked to inhibit it"
@@ -355,7 +354,7 @@ msgstr "有其它应用程序阻止时仍然休眠"
msgid ""
"Authentication is required for hibernating the system while an application "
"asked to inhibit it."
-msgstr "要在其它应用程序阻止休眠时进行休眠需要验证。"
+msgstr "在其它应用程序阻止休眠时进行休眠需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Manage active sessions, users and seats"
@@ -364,42 +363,41 @@ msgstr "管理活动会话、用户与会话座位"
#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for managing active sessions, users and seats."
-msgstr "要管理活动会话、用户与会话座位需要验证。"
+msgstr "管理活动会话、用户与会话座位需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Lock or unlock active sessions"
-msgstr "活动会话锁定与解锁"
+msgstr "锁定或解锁活动会话"
#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid "Authentication is required to lock or unlock active sessions."
-msgstr "要对活动会话进行锁定或解锁需要验证。"
+msgstr "对活动会话进行锁定或解锁需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Allow indication to the firmware to boot to setup interface"
-msgstr "允许向固件发出指示以启动至固件设置界面"
+msgstr "允许向固件发出指示以启动至设置界面"
#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid ""
"Authentication is required to indicate to the firmware to boot to setup "
"interface."
-msgstr "要允许向固件发出启动时进入设置界面的指令需要验证。"
+msgstr "向固件发出启动时进入设置界面的指令需要认证。"
#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Set a wall message"
-msgstr ""
+msgstr "设置 wall 消息"
#: ../src/login/org.freedesktop.login1.policy.in.h:56
-#, fuzzy
msgid "Authentication is required to set a wall message"
-msgstr ""
+msgstr "设置 wall 消息需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
msgid "Log into a local container"
-msgstr "登入一个本地容器"
+msgstr "登入本地容器"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
msgid "Authentication is required to log into a local container."
-msgstr "要登入一个本地容器需要验证。"
+msgstr "登录一个本地容器需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
msgid "Log into the local host"
@@ -407,7 +405,7 @@ msgstr "登入本地主机"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
msgid "Authentication is required to log into the local host."
-msgstr "要登入本地主机需要验证。"
+msgstr "登入本地主机需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
msgid "Acquire a shell in a local container"
@@ -415,7 +413,7 @@ msgstr "在本地容器中获取一个 shell"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
msgid "Authentication is required to acquire a shell in a local container."
-msgstr "要在本地容器中获取 shell 需要验证。"
+msgstr "在本地容器中获取 shell 需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
msgid "Acquire a shell on the local host"
@@ -423,7 +421,7 @@ msgstr "在本地主机中获取一个 shell"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
msgid "Authentication is required to acquire a shell on the local host."
-msgstr "要在本地主机中获取 shell 需要验证。"
+msgstr "在本地主机中获取 shell 需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
msgid "Acquire a pseudo TTY in a local container"
@@ -432,7 +430,7 @@ msgstr "在本地容器中获取一个假 TTY"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
msgid ""
"Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "要在本地容器中获取假 TTY 需要验证。"
+msgstr "在本地容器中获取假 TTY 需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
msgid "Acquire a pseudo TTY on the local host"
@@ -440,7 +438,7 @@ msgstr "在本地主机中获取一个假 TTY"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "要在本地主机中获取假 TTY 需要验证。"
+msgstr "在本地主机中获取假 TTY 需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
msgid "Manage local virtual machines and containers"
@@ -449,7 +447,7 @@ msgstr "管理本地虚拟机和容器"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
msgid ""
"Authentication is required to manage local virtual machines and containers."
-msgstr "要管理本地虚拟机和容器需要验证。"
+msgstr "管理本地虚拟机和容器需要认证。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
msgid "Manage local virtual machine and container images"
@@ -459,7 +457,7 @@ msgstr "管理本地虚拟机和容器的镜像"
msgid ""
"Authentication is required to manage local virtual machine and container "
"images."
-msgstr "要管理本地的虚拟机和容器镜像需要验证。"
+msgstr "管理本地的虚拟机和容器镜像需要认证。"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
msgid "Set system time"
@@ -467,7 +465,7 @@ msgstr "设置系统时间"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
msgid "Authentication is required to set the system time."
-msgstr "设置系统时间需要验证。"
+msgstr "设置系统时间需要认证。"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
msgid "Set system timezone"
@@ -475,7 +473,7 @@ msgstr "设置系统时区"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
msgid "Authentication is required to set the system timezone."
-msgstr "设置系统时区需要验证。"
+msgstr "设置系统时区需要认证。"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
msgid "Set RTC to local timezone or UTC"
@@ -485,7 +483,7 @@ msgstr "设置硬件时钟使用本地时间或 UTC"
msgid ""
"Authentication is required to control whether the RTC stores the local or "
"UTC time."
-msgstr "设置硬件时钟使用本地时间或 UTC 需要验证。"
+msgstr "设置硬件时钟使用本地时间或 UTC 需要认证。"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
msgid "Turn network time synchronization on or off"
@@ -495,33 +493,32 @@ msgstr "打开或关闭网络时间同步"
msgid ""
"Authentication is required to control whether network time synchronization "
"shall be enabled."
-msgstr "设置是否启用网络时间同步需要验证。"
+msgstr "打开或关闭网络时间同步需要认证。"
#: ../src/core/dbus-unit.c:430
msgid "Authentication is required to start '$(unit)'."
-msgstr "启动“$(unit)”需要验证。"
+msgstr "启动“$(unit)”需要认证。"
#: ../src/core/dbus-unit.c:431
msgid "Authentication is required to stop '$(unit)'."
-msgstr "停止“$(unit)”需要验证。"
+msgstr "停止“$(unit)”需要认证。"
#: ../src/core/dbus-unit.c:432
msgid "Authentication is required to reload '$(unit)'."
-msgstr "重新载入“$(unit)”需要验证。"
+msgstr "重新载入“$(unit)”需要认证。"
#: ../src/core/dbus-unit.c:433 ../src/core/dbus-unit.c:434
msgid "Authentication is required to restart '$(unit)'."
-msgstr "重新启动“$(unit)”需要验证。"
+msgstr "重新启动“$(unit)”需要认证。"
#: ../src/core/dbus-unit.c:537
msgid "Authentication is required to kill '$(unit)'."
-msgstr "杀死“$(unit)”需要验证。"
+msgstr "杀死“$(unit)”需要认证。"
#: ../src/core/dbus-unit.c:567
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "重置“$(unit)”的失败(\"failed\")状态需要验证。"
+msgstr "重置“$(unit)”的失败(\"failed\")状态需要认证。"
#: ../src/core/dbus-unit.c:599
msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "设置“$(unit)”的属性需要验证。"
-
+msgstr "设置“$(unit)”的属性需要认证。"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 5a214a3c48..affea9126e 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -1,21 +1,21 @@
# Traditional Chinese translation for systemd.
# Copyright (C) 2015 systemd's COPYRIGHT HOLDER
# This file is distributed under the same license as the systemd package.
-# Jeff Huang <s8321414@gmail.com>, 2015.
+# Jeff Huang <s8321414@gmail.com>, 2015, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2015-06-11 12:44+0800\n"
-"Last-Translator: Jeff Huang <s8321414@gmail.com>\n"
+"PO-Revision-Date: 2016-02-12 11:46+0800\n"
+"Last-Translator: Jeff Huang <s8321414@chakraos.org>\n"
"Language-Team: chinese-l10n <chinese-l10n@googlegroups.com>\n"
"Language: zh_TW\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: Lokalize 1.5\n"
+"X-Generator: Lokalize 2.0\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
@@ -375,12 +375,11 @@ msgstr "對韌體的指示以開始設定介面需要驗證。"
#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Set a wall message"
-msgstr ""
+msgstr "設定 wall 訊息"
#: ../src/login/org.freedesktop.login1.policy.in.h:56
-#, fuzzy
msgid "Authentication is required to set a wall message"
-msgstr "設定主機名稱需要驗證。"
+msgstr "設定 wall 訊息需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
msgid "Log into a local container"
@@ -391,53 +390,45 @@ msgid "Authentication is required to log into a local container."
msgstr "登入到本機容器需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
-#, fuzzy
msgid "Log into the local host"
-msgstr "登入到本機容器"
+msgstr "登入到本機主機"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
-#, fuzzy
msgid "Authentication is required to log into the local host."
-msgstr "登入到本機容器需要驗證。"
+msgstr "登入到本機主機需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
-#, fuzzy
msgid "Acquire a shell in a local container"
-msgstr "登入到本機容器"
+msgstr "在本機容器中取得一個 shell"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
-#, fuzzy
msgid "Authentication is required to acquire a shell in a local container."
-msgstr "登入到本機容器需要驗證。"
+msgstr "在本機容器中取得一個 shell 需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
msgid "Acquire a shell on the local host"
-msgstr ""
+msgstr "在本機主機中取得一個 shell"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
-#, fuzzy
msgid "Authentication is required to acquire a shell on the local host."
-msgstr "設定主機名稱需要驗證。"
+msgstr "在本機主機中取得一個 shell 需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
-#, fuzzy
msgid "Acquire a pseudo TTY in a local container"
-msgstr "登入到本機容器"
+msgstr "取得在本機容器中的偽 TTY"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
-#, fuzzy
msgid ""
"Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "登入到本機容器需要驗證。"
+msgstr "取得在本機容器中的偽 TTY 需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
msgid "Acquire a pseudo TTY on the local host"
-msgstr ""
+msgstr "取得在本機主機中的偽 TTY"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
-#, fuzzy
msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "設定主機名稱需要驗證。"
+msgstr "取得在本機主機中的偽 TTY 需要驗證。"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
msgid "Manage local virtual machines and containers"
@@ -495,36 +486,30 @@ msgid ""
msgstr "控制網路時間同步是否啟用需要驗證。"
#: ../src/core/dbus-unit.c:428
-#, fuzzy
msgid "Authentication is required to start '$(unit)'."
-msgstr "設定系統時間需要驗證。"
+msgstr "啟動 '$(unit)' 需要驗證。"
#: ../src/core/dbus-unit.c:429
-#, fuzzy
msgid "Authentication is required to stop '$(unit)'."
-msgstr "設定系統時間需要驗證。"
+msgstr "停止 '$(unit)' 需要驗證。"
#: ../src/core/dbus-unit.c:430
-#, fuzzy
msgid "Authentication is required to reload '$(unit)'."
-msgstr "重新載入 systemd 狀態需要驗證。"
+msgstr "重新載入 '$(unit)' 需要驗證。"
#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
-#, fuzzy
msgid "Authentication is required to restart '$(unit)'."
-msgstr "設定系統時間需要驗證。"
+msgstr "重新啟動 '$(unit)' 需要驗證。"
#: ../src/core/dbus-unit.c:535
-#, fuzzy
msgid "Authentication is required to kill '$(unit)'."
-msgstr "登入到本機容器需要驗證。"
+msgstr "砍除 '$(unit)' 需要驗證。"
#: ../src/core/dbus-unit.c:565
-#, fuzzy
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "設定主機名稱需要驗證。"
+msgstr "重置 '$(unit)' 的「失敗」狀態需要驗證。"
#: ../src/core/dbus-unit.c:597
-#, fuzzy
msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "設定系統時間需要驗證。"
+msgstr "在 '$(unit)' 上設定屬性需要驗證。"
+
diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
index 0b14bb4a11..408733915c 100644
--- a/rules/60-persistent-storage.rules
+++ b/rules/60-persistent-storage.rules
@@ -14,6 +14,10 @@ TEST=="whole_disk", GOTO="persistent_storage_end"
# for partitions import parent information
ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*"
+# NVMe
+KERNEL=="nvme*[0-9]n*[0-9]", ATTR{wwid}=="?*", SYMLINK+="disk/by-id/nvme-$attr{wwid}"
+KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{wwid}=="?*", SYMLINK+="disk/by-id/nvme-$attr{wwid}-part%n"
+
# virtio-blk
KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"
KERNEL=="vd*[0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}-part%n"
@@ -74,7 +78,7 @@ ENV{DEVTYPE}=="disk", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn
ENV{DEVTYPE}=="partition", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}-part%n"
# by-partlabel/by-partuuid links (partition metadata)
-ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
+ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}"
# add symlink to GPT root disk
diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
index 5c2cda51ec..fb4517606d 100644
--- a/rules/99-systemd.rules.in
+++ b/rules/99-systemd.rules.in
@@ -11,7 +11,7 @@ SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270
KERNEL=="vport*", TAG+="systemd"
SUBSYSTEM=="block", TAG+="systemd"
-SUBSYSTEM=="block", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0"
+SUBSYSTEM=="block", ACTION=="add", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0"
# Ignore encrypted devices with no identified superblock on it, since
# we are probably still calling mke2fs or mkswap on it.
@@ -24,8 +24,8 @@ SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="
# Ignore loop devices that don't have any file attached
SUBSYSTEM=="block", KERNEL=="loop[0-9]*", ENV{DEVTYPE}=="disk", TEST!="loop/backing_file", ENV{SYSTEMD_READY}="0"
-# Ignore nbd devices in the "add" event, with "change" the nbd is ready
-ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0"
+# Ignore nbd devices until the PID file exists (which signals a connected device)
+SUBSYSTEM=="block", KERNEL=="nbd*", ENV{DEVTYPE}=="disk", TEST!="pid", ENV{SYSTEMD_READY}="0"
# We need a hardware independent way to identify network devices. We
# use the /sys/subsystem/ path for this. Kernel "bus" and "class" names
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index ef7dc6285a..6f2b3f122c 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -96,7 +96,7 @@ _systemctl () {
local i verb comps mode
local -A OPTS=(
- [STANDALONE]='--all -a --reverse --after --before --defaults --failed --force -f --full -l --global
+ [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
--help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
--quiet -q --privileged -P --system --user --version --runtime --recursive -r --firmware-setup
--show-types -i --ignore-inhibitors --plain'
diff --git a/shell-completion/bash/systemd-nspawn b/shell-completion/bash/systemd-nspawn
index 429e712eb3..0cf249d8ce 100644
--- a/shell-completion/bash/systemd-nspawn
+++ b/shell-completion/bash/systemd-nspawn
@@ -45,7 +45,10 @@ __get_env() {
}
__get_interfaces(){
- cut -f 1 -d ' ' /proc/net/dev | tail -n +3 | tr -s '\n' | tr -d ':' | xargs
+ { cd /sys/class/net && echo *; } | \
+ while read -d' ' -r name; do
+ [[ "$name" != "lo" ]] && echo "$name"
+ done
}
_systemd_nspawn() {
@@ -57,14 +60,14 @@ _systemd_nspawn() {
[ARG]='-D --directory -u --user --uuid --capability --drop-capability --link-journal --bind --bind-ro -M --machine
-S --slice --setenv -Z --selinux-context -L --selinux-apifs-context --register --network-interface --network-bridge
--personality -i --image --tmpfs --volatile
- --network-macvlan --kill-signal'
+ --network-macvlan --kill-signal --template'
)
_init_completion || return
if __contains_word "$prev" ${OPTS[ARG]}; then
case $prev in
- --directory|-D)
+ --directory|-D|--template)
compopt -o nospace
comps=$(compgen -S/ -A directory -- "$cur" )
;;
diff --git a/shell-completion/bash/systemd-resolve b/shell-completion/bash/systemd-resolve
new file mode 100644
index 0000000000..0c501c9405
--- /dev/null
+++ b/shell-completion/bash/systemd-resolve
@@ -0,0 +1,64 @@
+# systemd-resolve(1) completion -*- shell-script -*-
+#
+# 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
+# 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/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_interfaces(){
+ { cd /sys/class/net && echo *; } | \
+ while read -d' ' -r name; do
+ [[ "$name" != "lo" ]] && echo "$name"
+ done
+}
+
+_systemd-resolve() {
+ local i comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version -4 -6
+ --service --openpgp --tlsa --statistics --reset-statistics
+ --service-address=no --service-txt=no
+ --cname=no --search=no --legend=no'
+ [ARG]='-i --interface -p --protocol -t --type -c --class'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --interface|-i)
+ comps=$( __get_interfaces )
+ ;;
+ --protocol|-p|--type|-t|--class|-c)
+ comps=$( systemd-resolve --legend=no "$prev" help; echo help )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+}
+
+complete -F _systemd-resolve systemd-resolve
diff --git a/shell-completion/zsh/_coredumpctl b/shell-completion/zsh/_coredumpctl
index 833c7e2bb1..e4c04a697f 100644
--- a/shell-completion/zsh/_coredumpctl
+++ b/shell-completion/zsh/_coredumpctl
@@ -16,7 +16,7 @@ _coredumpctl_command(){
cmd="${${_coredumpctl_cmds[(r)$words[1]:*]%%:*}}"
if (( $#cmd )); then
# user can set zstyle ':completion:*:*:coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid
- _dumps=( "${(foa)$(coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" )
+ _dumps=( "${(foa)$(coredumpctl list --no-legend | awk 'BEGIN{OFS=":"} {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" )
if [[ -n "$_dumps" ]]; then
_describe -t pids 'coredumps' _dumps
else
diff --git a/shell-completion/zsh/_networkctl b/shell-completion/zsh/_networkctl
new file mode 100644
index 0000000000..61f173b78e
--- /dev/null
+++ b/shell-completion/zsh/_networkctl
@@ -0,0 +1,35 @@
+#compdef networkctl
+
+_networkctl_command(){
+ local -a _networkctl_cmds
+ _networkctl_cmds=(
+ 'list:List existing links'
+ 'status:Show information about the specified links'
+ 'lldp:Show Link Layer Discovery Protocol status'
+ )
+ if (( CURRENT == 1 )); then
+ _describe -t commands 'networkctl command' _networkctl_cmds
+ else
+ local curcontext="$curcontext"
+ local -a _links
+ cmd="${${_networkctl_cmds[(r)$words[1]:*]%%:*}}"
+ if [ $cmd = "status" ]; then
+ _links=( "${(foa)$(networkctl list --no-legend | awk 'BEGIN{OFS=":"} {sub(/[[ \t]+/, ""); print $2,$0}' 2>/dev/null)}" )
+ if [[ -n "$_links" ]]; then
+ _describe -t links 'links' _links
+ else
+ _message "no links"
+ fi
+ else
+ _message "no more options"
+ fi
+ fi
+}
+
+_arguments \
+ {-a,--all}'[Show all links with status]' \
+ '--no-pager[Do not pipe output into a pager]' \
+ '--no-legend[Do not print the column headers]' \
+ {-h,--help}'[Show this help]' \
+ '--version[Show package version]' \
+ '*::networkctl commands:_networkctl_command'
diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in
index 667243eb53..44c31b7833 100644
--- a/shell-completion/zsh/_systemctl.in
+++ b/shell-completion/zsh/_systemctl.in
@@ -156,7 +156,7 @@ _systemctl_restartable_units(){
{ while read -r a b; do echo -E - " $a"; done; } )) )
}
-_systemctl_failed_units() {_sys_failed_units=( ${${(f)"$(__systemctl list-units --failed)"}%% *} ) }
+_systemctl_failed_units() {_sys_failed_units=( ${${(f)"$(__systemctl list-units --state=failed)"}%% *} ) }
_systemctl_unit_state() { typeset -gA _sys_unit_state; _sys_unit_state=( $(__systemctl list-unit-files) ) }
local fun
@@ -364,7 +364,6 @@ _arguments -s \
'--reverse[Show reverse dependencies]' \
'--after[Show units ordered after]' \
'--before[Show units ordered before]' \
- '--failed[Show only failed units]' \
{-l,--full}"[Don't ellipsize unit names on output]" \
'--show-types[When showing sockets, show socket type]' \
{-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \
diff --git a/shell-completion/zsh/_systemd-resolve b/shell-completion/zsh/_systemd-resolve
new file mode 100644
index 0000000000..c318ab50f1
--- /dev/null
+++ b/shell-completion/zsh/_systemd-resolve
@@ -0,0 +1,64 @@
+#compdef systemd-resolve
+
+#
+# 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
+# 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/>.
+
+_dns_protocol() {
+ local -a _protocol
+ _protocol=( $(_call_program protocol ${service} --legend=no --protocol help; echo help) )
+ _values 'protocol' "$_protocol[@]"
+}
+
+_dns_type() {
+ local -a _type
+ _type=( $(_call_program type ${service} --legend=no --type help; echo help) )
+ _values 'type' "$_type[@]"
+}
+
+_dns_class() {
+ local -a _class
+ _class=( $(_call_program class ${service} --legend=no --class help; echo help) )
+ _values 'class' "$_class[@]"
+}
+
+_systemd-resolve_none() {
+ _alternative : \
+ 'domain:DNS address:' \
+ 'address:email address:'
+}
+
+_arguments \
+ {-h,--help}'[Print a short help text and exit]' \
+ '--version[Print a short version string and exit]' \
+ '--legend=no[Do not show headers and footers]' \
+ '-4[Resolve IPv4 addresses]' \
+ '-6[Resolve IPv6 addresses]' \
+ {-i+,--interface=}'[Look on interface]:interface:_net_interfaces' \
+ {-p+,--protocol=}'[Look via protocol]:protocol:_dns_protocol' \
+ {-t+,--type=}'[Query RR with DNS type]:type:_dns_type' \
+ {-c+,--class=}'[Query RR with DNS class]:class:_dns_class' \
+ '--service[Resolve services]' \
+ '--service-address=no[Do not resolve address for services]' \
+ '--service-txt=no[Do not resolve TXT records for services]' \
+ '--openpgp[Query OpenPGP public key]' \
+ '--tlsa[Query TLS public key]' \
+ '--cname=no[Do not follow CNAME redirects]' \
+ '--search=no[Do not use search domains]' \
+ '--statistics[Show resolver statistics]' \
+ '--reset-statistics[Reset resolver statistics]' \
+ '*::default: _systemd-resolve_none'
diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c
index fd3b241aad..0281409edf 100644
--- a/src/busctl/busctl.c
+++ b/src/busctl/busctl.c
@@ -62,15 +62,6 @@ static bool arg_allow_interactive_authorization = true;
static bool arg_augment_creds = true;
static usec_t arg_timeout = 0;
-static void pager_open_if_enabled(void) {
-
- /* Cache result before we open the pager */
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
#define NAME_IS_ACQUIRED INT_TO_PTR(1)
#define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
@@ -95,7 +86,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
if (r < 0)
return log_error_errno(r, "Failed to list names: %m");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
names = hashmap_new(&string_hash_ops);
if (!names)
@@ -258,8 +249,8 @@ static void print_subtree(const char *prefix, const char *path, char **l) {
l++;
}
- vertical = strjoina(prefix, draw_special_char(DRAW_TREE_VERTICAL));
- space = strjoina(prefix, draw_special_char(DRAW_TREE_SPACE));
+ vertical = strjoina(prefix, special_glyph(TREE_VERTICAL));
+ space = strjoina(prefix, special_glyph(TREE_SPACE));
for (;;) {
bool has_more = false;
@@ -280,7 +271,7 @@ static void print_subtree(const char *prefix, const char *path, char **l) {
n++;
}
- printf("%s%s%s\n", prefix, draw_special_char(has_more ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), *l);
+ printf("%s%s%s\n", prefix, special_glyph(has_more ? TREE_BRANCH : TREE_RIGHT), *l);
print_subtree(has_more ? vertical : space, *l, l);
l = n;
@@ -289,7 +280,7 @@ static void print_subtree(const char *prefix, const char *path, char **l) {
static void print_tree(const char *prefix, char **l) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
prefix = strempty(prefix);
@@ -409,7 +400,7 @@ static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool m
p = NULL;
}
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
l = set_get_strv(done);
if (!l)
@@ -438,7 +429,7 @@ static int tree(sd_bus *bus, char **argv) {
if (r < 0)
return log_error_errno(r, "Failed to get name list: %m");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
STRV_FOREACH(i, names) {
int q;
@@ -468,7 +459,7 @@ static int tree(sd_bus *bus, char **argv) {
printf("\n");
if (argv[2]) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
}
@@ -501,8 +492,10 @@ static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) {
} basic;
r = sd_bus_message_peek_type(m, &type, &contents);
- if (r <= 0)
+ if (r < 0)
return r;
+ if (r == 0)
+ return needs_space;
if (bus_type_is_container(type) > 0) {
@@ -533,18 +526,23 @@ static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) {
fputc(' ', f);
fprintf(f, "%u", n);
+ needs_space = true;
+
} else if (type == SD_BUS_TYPE_VARIANT) {
if (needs_space)
fputc(' ', f);
fprintf(f, "%s", contents);
+ needs_space = true;
}
- r = format_cmdline(m, f, needs_space || IN_SET(type, SD_BUS_TYPE_ARRAY, SD_BUS_TYPE_VARIANT));
+ r = format_cmdline(m, f, needs_space);
if (r < 0)
return r;
+ needs_space = r > 0;
+
r = sd_bus_message_exit_container(m);
if (r < 0)
return r;
@@ -985,7 +983,7 @@ static int introspect(sd_bus *bus, char **argv) {
return bus_log_parse_error(r);
}
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
name_width = strlen("NAME");
type_width = strlen("TYPE");
@@ -1081,10 +1079,21 @@ static int message_pcap(sd_bus_message *m, FILE *f) {
}
static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
- bool added_something = false;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char **i;
+ uint32_t flags = 0;
int r;
+ /* upgrade connection; it's not used for anything else after this call */
+ r = sd_bus_message_new_method_call(bus, &message, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus.Monitoring", "BecomeMonitor");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(message, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
STRV_FOREACH(i, argv+1) {
_cleanup_free_ char *m = NULL;
@@ -1097,34 +1106,38 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
if (!m)
return log_oom();
- r = sd_bus_add_match(bus, NULL, m, NULL, NULL);
+ r = sd_bus_message_append_basic(message, 's', m);
if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
+ return bus_log_create_error(r);
free(m);
m = strjoin("destination='", *i, "'", NULL);
if (!m)
return log_oom();
- r = sd_bus_add_match(bus, NULL, m, NULL, NULL);
+ r = sd_bus_message_append_basic(message, 's', m);
if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
-
- added_something = true;
+ return bus_log_create_error(r);
}
STRV_FOREACH(i, arg_matches) {
- r = sd_bus_add_match(bus, NULL, *i, NULL, NULL);
+ r = sd_bus_message_append_basic(message, 's', *i);
if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
-
- added_something = true;
+ return bus_log_create_error(r);
}
- if (!added_something) {
- r = sd_bus_add_match(bus, NULL, "", NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
+ r = sd_bus_message_close_container(message);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_basic(message, 'u', &flags);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, message, arg_timeout, &error, NULL);
+ if (r < 0) {
+ log_error("%s", bus_error_message(&error, r));
+ return r;
}
log_info("Monitoring bus message stream.");
@@ -1552,7 +1565,7 @@ static int call(sd_bus *bus, char *argv[]) {
if (r == 0 && !arg_quiet) {
if (arg_verbose) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = bus_message_dump(reply, stdout, 0);
if (r < 0)
@@ -1607,7 +1620,7 @@ static int get_property(sd_bus *bus, char *argv[]) {
return bus_log_parse_error(r);
if (arg_verbose) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_SUBTREE_ONLY);
if (r < 0)
diff --git a/src/grp-boot/bootctl/bootctl.c b/src/grp-boot/bootctl/bootctl.c
index e9baf69f6a..4a356d25d1 100644
--- a/src/grp-boot/bootctl/bootctl.c
+++ b/src/grp-boot/bootctl/bootctl.c
@@ -266,9 +266,9 @@ static int enumerate_binaries(const char *esp_path, const char *path, const char
if (r < 0)
return r;
if (r > 0)
- printf(" File: %s/%s/%s (%s)\n", draw_special_char(DRAW_TREE_RIGHT), path, de->d_name, v);
+ printf(" File: %s/%s/%s (%s)\n", special_glyph(TREE_RIGHT), path, de->d_name, v);
else
- printf(" File: %s/%s/%s\n", draw_special_char(DRAW_TREE_RIGHT), path, de->d_name);
+ printf(" File: %s/%s/%s\n", special_glyph(TREE_RIGHT), path, de->d_name);
c++;
}
@@ -320,7 +320,7 @@ static int print_efi_option(uint16_t id, bool in_order) {
printf(" ID: 0x%04X\n", id);
printf(" Status: %sactive%s\n", active ? "" : "in", in_order ? ", boot-order" : "");
printf(" Partition: /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));
- printf(" File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), path);
+ printf(" File: %s%s\n", special_glyph(TREE_RIGHT), path);
printf("\n");
return 0;
@@ -763,13 +763,13 @@ static int install_variables(const char *esp_path,
"Failed to determine current boot order: %m");
if (first || r == false) {
- r = efi_add_boot_option(slot, "Linux Boot Manager",
+ r = efi_add_boot_option(slot, "Systemd Boot Manager",
part, pstart, psize,
uuid, path);
if (r < 0)
return log_error_errno(r, "Failed to create EFI Boot variable entry: %m");
- log_info("Created EFI boot entry \"Linux Boot Manager\".");
+ log_info("Created EFI boot entry \"Systemd Boot Manager\".");
}
return insert_into_order(slot, first);
@@ -1077,7 +1077,7 @@ static int bootctl_main(int argc, char*argv[]) {
SD_ID128_FORMAT_VAL(loader_part_uuid));
else
printf(" Partition: n/a\n");
- printf(" File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), strna(loader_path));
+ printf(" File: %s%s\n", special_glyph(TREE_RIGHT), strna(loader_path));
printf("\n");
} else
printf("System:\n Not booted with EFI\n");
diff --git a/src/grp-boot/systemd-boot/Makefile b/src/grp-boot/systemd-boot/Makefile
index a1e4b6088a..f2a0ed47cb 100644
--- a/src/grp-boot/systemd-boot/Makefile
+++ b/src/grp-boot/systemd-boot/Makefile
@@ -95,12 +95,21 @@ $(outdir)/%.so:
$(outdir)/%$(EFI_MACHINE_TYPE_NAME).efi : $(outdir)/%.so; $(AM_V_GEN)$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc $(EFI_FORMAT) $< $@
$(outdir)/%$(EFI_MACHINE_TYPE_NAME).efi.stub: $(outdir)/%.so; $(AM_V_GEN)$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc $(EFI_FORMAT) $< $@
# ------------------------------------------------------------------------------
+systemd_boot_headers = \
+ src/boot/efi/util.h \
+ src/boot/efi/console.h \
+ src/boot/efi/graphics.h \
+ src/boot/efi/pefile.h \
+ src/boot/efi/measure.h \
+ src/boot/efi/disk.h
+
systemd_boot_sources = \
src/boot/efi/util.c \
src/boot/efi/console.c \
src/boot/efi/graphics.c \
src/boot/efi/pefile.c \
src/boot/efi/disk.c \
+ src/boot/efi/measure.c \
src/boot/efi/boot.c
systemd_boot = systemd-boot$(EFI_MACHINE_TYPE_NAME).efi
@@ -108,6 +117,15 @@ std.out_files += $(systemd_boot)
std.sys_files += $(bootlibdir)/$(systemd_boot)
$(outdir)/systemd-boot.so: $(addprefix $(outdir)/,$(notdir $(systemd_boot_sources:.c=.o)))
# ------------------------------------------------------------------------------
+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 \
@@ -115,6 +133,7 @@ stub_sources = \
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
stub = linux$(EFI_MACHINE_TYPE_NAME).efi.stub
diff --git a/src/grp-boot/systemd-boot/boot.c b/src/grp-boot/systemd-boot/boot.c
index 893980071f..30c1ead1aa 100644
--- a/src/grp-boot/systemd-boot/boot.c
+++ b/src/grp-boot/systemd-boot/boot.c
@@ -22,6 +22,7 @@
#include "linux.h"
#include "pefile.h"
#include "util.h"
+#include "measure.h"
#ifndef EFI_OS_INDICATIONS_BOOT_TO_FW_UI
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
@@ -1644,6 +1645,18 @@ static EFI_STATUS image_start(EFI_HANDLE parent_image, const Config *config, con
}
loaded_image->LoadOptions = options;
loaded_image->LoadOptionsSize = (StrLen(loaded_image->LoadOptions)+1) * sizeof(CHAR16);
+
+#ifdef SD_BOOT_LOG_TPM
+ /* Try to log any options to the TPM, escpecially to catch manually edited options */
+ err = tpm_log_event(SD_TPM_PCR,
+ (EFI_PHYSICAL_ADDRESS) loaded_image->LoadOptions,
+ loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
+ if (EFI_ERROR(err)) {
+ Print(L"Unable to add image options measurement: %r", err);
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ return err;
+ }
+#endif
}
efivar_set_time_usec(L"LoaderTimeExecUSec", 0);
diff --git a/src/grp-boot/systemd-boot/measure.c b/src/grp-boot/systemd-boot/measure.c
new file mode 100644
index 0000000000..7c016387c1
--- /dev/null
+++ b/src/grp-boot/systemd-boot/measure.c
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ *
+ */
+
+#ifdef SD_BOOT_LOG_TPM
+
+#include <efi.h>
+#include <efilib.h>
+#include "measure.h"
+
+#define EFI_TCG_PROTOCOL_GUID { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd} }
+
+typedef struct _TCG_VERSION {
+ UINT8 Major;
+ UINT8 Minor;
+ UINT8 RevMajor;
+ UINT8 RevMinor;
+} TCG_VERSION;
+
+typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
+ UINT8 Size;
+ struct _TCG_VERSION StructureVersion;
+ struct _TCG_VERSION ProtocolSpecVersion;
+ UINT8 HashAlgorithmBitmap;
+ BOOLEAN TPMPresentFlag;
+ BOOLEAN TPMDeactivatedFlag;
+} TCG_BOOT_SERVICE_CAPABILITY;
+
+typedef UINT32 TCG_ALGORITHM_ID;
+#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
+
+#define SHA1_DIGEST_SIZE 20
+
+typedef struct _TCG_DIGEST {
+ UINT8 Digest[SHA1_DIGEST_SIZE];
+} TCG_DIGEST;
+
+#define EV_IPL 13
+
+typedef struct _TCG_PCR_EVENT {
+ UINT32 PCRIndex;
+ UINT32 EventType;
+ struct _TCG_DIGEST digest;
+ UINT32 EventSize;
+ UINT8 Event[1];
+} TCG_PCR_EVENT;
+
+INTERFACE_DECL(_EFI_TCG);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
+ OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
+ OUT UINT32 * TCGFeatureFlags,
+ OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
+ IN UINT8 * HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
+ IN struct _TCG_PCR_EVENT * TCGLogData,
+ IN OUT UINT32 * EventNumber, IN UINT32 Flags);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 * TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 * TpmOutputParameterBlock);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN struct _TCG_PCR_EVENT * TCGLogData,
+ IN OUT UINT32 * EventNumber,
+ OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
+
+typedef struct _EFI_TCG {
+ EFI_TCG_STATUS_CHECK StatusCheck;
+ EFI_TCG_HASH_ALL HashAll;
+ EFI_TCG_LOG_EVENT LogEvent;
+ EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
+ EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
+} EFI_TCG;
+
+#define EFI_TCG2_PROTOCOL_GUID {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }}
+
+typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
+
+typedef struct tdEFI_TCG2_VERSION {
+ UINT8 Major;
+ UINT8 Minor;
+} EFI_TCG2_VERSION;
+
+typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
+typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
+typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
+
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002
+
+typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
+ UINT8 Size;
+ EFI_TCG2_VERSION StructureVersion;
+ EFI_TCG2_VERSION ProtocolVersion;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
+ EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
+ BOOLEAN TPMPresentFlag;
+ UINT16 MaxCommandSize;
+ UINT16 MaxResponseSize;
+ UINT32 ManufacturerID;
+ UINT32 NumberOfPCRBanks;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
+} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
+
+#define EFI_TCG2_EVENT_HEADER_VERSION 1
+
+typedef struct {
+ UINT32 HeaderSize;
+ UINT16 HeaderVersion;
+ UINT32 PCRIndex;
+ UINT32 EventType;
+} EFI_TCG2_EVENT_HEADER;
+
+typedef struct tdEFI_TCG2_EVENT {
+ UINT32 Size;
+ EFI_TCG2_EVENT_HEADER Header;
+ UINT8 Event[1];
+} EFI_TCG2_EVENT;
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
+ IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
+ IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
+ OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
+ OUT BOOLEAN * EventLogTruncated);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
+ IN UINT64 Flags,
+ IN EFI_PHYSICAL_ADDRESS DataToHash,
+ IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 * InputParameterBlock,
+ IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
+
+typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
+ OUT UINT32 * OperationPresent, OUT UINT32 * Response);
+
+typedef struct tdEFI_TCG2_PROTOCOL {
+ EFI_TCG2_GET_CAPABILITY GetCapability;
+ EFI_TCG2_GET_EVENT_LOG GetEventLog;
+ EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
+ EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
+ EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
+ EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
+ EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
+} EFI_TCG2;
+
+
+static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
+ UINTN buffer_size, const CHAR16 *description) {
+ EFI_STATUS status;
+ TCG_PCR_EVENT *tcg_event;
+ UINT32 event_number;
+ EFI_PHYSICAL_ADDRESS event_log_last;
+ UINTN desc_len;
+
+ desc_len = (StrLen(description) + 1) * sizeof(CHAR16);
+
+ tcg_event = AllocateZeroPool(desc_len + sizeof(TCG_PCR_EVENT));
+
+ if (tcg_event == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ tcg_event->EventSize = desc_len;
+ CopyMem((VOID *) & tcg_event->Event[0], (VOID *) description, desc_len);
+
+ tcg_event->PCRIndex = pcrindex;
+ tcg_event->EventType = EV_IPL;
+
+ event_number = 1;
+ status = uefi_call_wrapper(tcg->HashLogExtendEvent, 7,
+ tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
+
+ if (EFI_ERROR(status))
+ return status;
+
+ uefi_call_wrapper(BS->FreePool, 1, tcg_event);
+
+ return EFI_SUCCESS;
+}
+
+
+static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
+ UINT64 buffer_size, const CHAR16 *description) {
+ EFI_STATUS status;
+ EFI_TCG2_EVENT *tcg_event;
+ UINTN desc_len;
+
+ desc_len = StrLen(description) * sizeof(CHAR16);
+
+ tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1);
+
+ if (tcg_event == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ tcg_event->Size = sizeof(EFI_TCG2_EVENT) - sizeof(tcg_event->Event) + desc_len + 1;
+ tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
+ tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
+ tcg_event->Header.PCRIndex = pcrindex;
+ tcg_event->Header.EventType = EV_IPL;
+
+ CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len);
+
+ status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, tcg, 0, buffer, buffer_size, tcg_event);
+
+ uefi_call_wrapper(BS->FreePool, 1, tcg_event);
+
+ if (EFI_ERROR(status))
+ return status;
+
+ return EFI_SUCCESS;
+}
+
+static EFI_TCG * tcg1_interface_check(void) {
+ EFI_GUID tpm_guid = EFI_TCG_PROTOCOL_GUID;
+ EFI_STATUS status;
+ EFI_TCG *tcg;
+ TCG_BOOT_SERVICE_CAPABILITY capability;
+ UINT32 features;
+ EFI_PHYSICAL_ADDRESS event_log_location;
+ EFI_PHYSICAL_ADDRESS event_log_last_entry;
+
+ status = LibLocateProtocol(&tpm_guid, (void **) &tcg);
+
+ if (EFI_ERROR(status))
+ return NULL;
+
+ capability.Size = (UINT8) sizeof(capability);
+ status = uefi_call_wrapper(tcg->StatusCheck, 5, tcg, &capability, &features, &event_log_location, &event_log_last_entry);
+
+ if (EFI_ERROR(status))
+ return NULL;
+
+ if (capability.TPMDeactivatedFlag)
+ return NULL;
+
+ if (!capability.TPMPresentFlag)
+ return NULL;
+
+ return tcg;
+}
+
+static EFI_TCG2 * tcg2_interface_check(void) {
+ EFI_GUID tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
+ EFI_STATUS status;
+ EFI_TCG2 *tcg;
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
+
+ status = LibLocateProtocol(&tpm2_guid, (void **) &tcg);
+
+ if (EFI_ERROR(status))
+ return NULL;
+
+ capability.Size = (UINT8) sizeof(capability);
+ status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability);
+
+ if (EFI_ERROR(status))
+ return NULL;
+
+ if (!capability.TPMPresentFlag)
+ return NULL;
+
+ return tcg;
+}
+
+EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description) {
+ EFI_TCG *tpm1;
+ EFI_TCG2 *tpm2;
+
+ tpm2 = tcg2_interface_check();
+ if (tpm2)
+ return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description);
+
+ tpm1 = tcg1_interface_check();
+ if (tpm1)
+ return tpm1_measure_to_pcr_and_event_log(tpm1, pcrindex, buffer, buffer_size, description);
+
+ /* No active TPM found, so don't return an error */
+ return EFI_SUCCESS;
+}
+
+#endif
diff --git a/src/grp-boot/systemd-boot/measure.h b/src/grp-boot/systemd-boot/measure.h
new file mode 100644
index 0000000000..a2cfe817d0
--- /dev/null
+++ b/src/grp-boot/systemd-boot/measure.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+#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/grp-boot/systemd-boot/splash.c b/src/grp-boot/systemd-boot/splash.c
index b1cc2c0b72..c0ef7f64fe 100644
--- a/src/grp-boot/systemd-boot/splash.c
+++ b/src/grp-boot/systemd-boot/splash.c
@@ -281,9 +281,9 @@ EFI_STATUS graphics_splash(UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_
if (EFI_ERROR(err))
goto err;
- if(dib->x < GraphicsOutput->Mode->Info->HorizontalResolution)
+ if (dib->x < GraphicsOutput->Mode->Info->HorizontalResolution)
x_pos = (GraphicsOutput->Mode->Info->HorizontalResolution - dib->x) / 2;
- if(dib->y < GraphicsOutput->Mode->Info->VerticalResolution)
+ if (dib->y < GraphicsOutput->Mode->Info->VerticalResolution)
y_pos = (GraphicsOutput->Mode->Info->VerticalResolution - dib->y) / 2;
uefi_call_wrapper(GraphicsOutput->Blt, 10, GraphicsOutput,
diff --git a/src/grp-boot/systemd-boot/stub.c b/src/grp-boot/systemd-boot/stub.c
index 9633bc1792..1e250f34f4 100644
--- a/src/grp-boot/systemd-boot/stub.c
+++ b/src/grp-boot/systemd-boot/stub.c
@@ -20,6 +20,7 @@
#include "pefile.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 " ####";
@@ -97,6 +98,18 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
for (i = 0; i < cmdline_len; i++)
line[i] = options[i];
cmdline = line;
+
+#ifdef SD_BOOT_LOG_TPM
+ /* Try to log any options to the TPM, escpecially manually edited options */
+ err = tpm_log_event(SD_TPM_PCR,
+ (EFI_PHYSICAL_ADDRESS) loaded_image->LoadOptions,
+ loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
+ if (EFI_ERROR(err)) {
+ Print(L"Unable to add image options measurement: %r", err);
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ return err;
+ }
+#endif
}
/* export the device path this image is started from */
diff --git a/src/grp-coredump/coredumpctl/coredumpctl.c b/src/grp-coredump/coredumpctl/coredumpctl.c
index 5f4f710a0c..dc95da3613 100644
--- a/src/grp-coredump/coredumpctl/coredumpctl.c
+++ b/src/grp-coredump/coredumpctl/coredumpctl.c
@@ -54,7 +54,7 @@ static enum {
} arg_action = ACTION_LIST;
static const char* arg_field = NULL;
static const char *arg_directory = NULL;
-static int arg_no_pager = false;
+static bool arg_no_pager = false;
static int arg_no_legend = false;
static int arg_one = false;
static FILE* arg_output = NULL;
@@ -664,7 +664,7 @@ static int save_core(sd_journal *j, int fd, char **path, bool *unlink_temp) {
#endif
} else {
if (r == -ENOENT)
- log_error("Cannot retrieve coredump from journal nor disk.");
+ log_error("Cannot retrieve coredump from journal or disk.");
else
log_error_errno(r, "Failed to retrieve COREDUMP field: %m");
goto error;
@@ -852,9 +852,7 @@ int main(int argc, char *argv[]) {
case ACTION_LIST:
case ACTION_INFO:
- if (!arg_no_pager)
- pager_open(false);
-
+ pager_open(arg_no_pager, false);
r = dump_list(j);
break;
diff --git a/src/grp-coredump/systemd-coredump/coredump.c b/src/grp-coredump/systemd-coredump/coredump.c
index 64ce54d97f..bf0e0a038b 100644
--- a/src/grp-coredump/systemd-coredump/coredump.c
+++ b/src/grp-coredump/systemd-coredump/coredump.c
@@ -49,6 +49,7 @@
#include "journald-native.h"
#include "log.h"
#include "macro.h"
+#include "missing.h"
#include "mkdir.h"
#include "parse-util.h"
#include "process-util.h"
@@ -212,6 +213,10 @@ static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) {
#define filename_escape(s) xescape((s), "./ ")
+static inline const char *coredump_tmpfile_name(const char *s) {
+ return s ? s : "(unnamed temporary file)";
+}
+
static int fix_permissions(
int fd,
const char *filename,
@@ -219,8 +224,9 @@ static int fix_permissions(
const char *context[_CONTEXT_MAX],
uid_t uid) {
+ int r;
+
assert(fd >= 0);
- assert(filename);
assert(target);
assert(context);
@@ -230,10 +236,11 @@ static int fix_permissions(
(void) fix_xattr(fd, context);
if (fsync(fd) < 0)
- return log_error_errno(errno, "Failed to sync coredump %s: %m", filename);
+ return log_error_errno(errno, "Failed to sync coredump %s: %m", coredump_tmpfile_name(filename));
- if (rename(filename, target) < 0)
- return log_error_errno(errno, "Failed to rename coredump %s -> %s: %m", filename, target);
+ r = link_tmpfile(fd, filename, target);
+ if (r < 0)
+ return log_error_errno(r, "Failed to move coredump %s into place: %m", target);
return 0;
}
@@ -335,15 +342,11 @@ static int save_external_coredump(
if (r < 0)
return log_error_errno(r, "Failed to determine coredump file name: %m");
- r = tempfn_random(fn, NULL, &tmp);
- if (r < 0)
- return log_error_errno(r, "Failed to determine temporary file name: %m");
-
mkdir_p_label("/var/lib/systemd/coredump", 0755);
- fd = open(tmp, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0640);
+ fd = open_tmpfile_linkable(fn, O_RDWR|O_CLOEXEC, &tmp);
if (fd < 0)
- return log_error_errno(errno, "Failed to create coredump file %s: %m", tmp);
+ return log_error_errno(fd, "Failed to create temporary file for coredump %s: %m", fn);
r = copy_bytes(input_fd, fd, max_size, false);
if (r == -EFBIG) {
@@ -358,12 +361,12 @@ static int save_external_coredump(
}
if (fstat(fd, &st) < 0) {
- log_error_errno(errno, "Failed to fstat coredump %s: %m", tmp);
+ log_error_errno(errno, "Failed to fstat coredump %s: %m", coredump_tmpfile_name(tmp));
goto fail;
}
if (lseek(fd, 0, SEEK_SET) == (off_t) -1) {
- log_error_errno(errno, "Failed to seek on %s: %m", tmp);
+ log_error_errno(errno, "Failed to seek on %s: %m", coredump_tmpfile_name(tmp));
goto fail;
}
@@ -381,21 +384,15 @@ static int save_external_coredump(
goto uncompressed;
}
- r = tempfn_random(fn_compressed, NULL, &tmp_compressed);
- if (r < 0) {
- log_error_errno(r, "Failed to determine temporary file name for %s: %m", fn_compressed);
- goto uncompressed;
- }
-
- fd_compressed = open(tmp_compressed, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0640);
+ fd_compressed = open_tmpfile_linkable(fn_compressed, O_RDWR|O_CLOEXEC, &tmp_compressed);
if (fd_compressed < 0) {
- log_error_errno(errno, "Failed to create file %s: %m", tmp_compressed);
+ log_error_errno(fd_compressed, "Failed to create temporary file for coredump %s: %m", fn_compressed);
goto uncompressed;
}
r = compress_stream(fd, fd_compressed, -1);
if (r < 0) {
- log_error_errno(r, "Failed to compress %s: %m", tmp_compressed);
+ log_error_errno(r, "Failed to compress %s: %m", coredump_tmpfile_name(tmp_compressed));
goto fail_compressed;
}
@@ -404,7 +401,8 @@ static int save_external_coredump(
goto fail_compressed;
/* OK, this worked, we can get rid of the uncompressed version now */
- unlink_noerrno(tmp);
+ if (tmp)
+ unlink_noerrno(tmp);
*ret_filename = fn_compressed; /* compressed */
*ret_node_fd = fd_compressed; /* compressed */
@@ -417,7 +415,8 @@ static int save_external_coredump(
return 0;
fail_compressed:
- (void) unlink(tmp_compressed);
+ if (tmp_compressed)
+ (void) unlink(tmp_compressed);
}
uncompressed:
@@ -438,7 +437,8 @@ uncompressed:
return 0;
fail:
- (void) unlink(tmp);
+ if (tmp)
+ (void) unlink(tmp);
return r;
}
@@ -739,15 +739,16 @@ static int process_socket(int fd) {
.msg_iovlen = 1,
};
ssize_t n;
- int l;
+ ssize_t l;
if (!GREEDY_REALLOC(iovec, n_iovec_allocated, n_iovec + 3)) {
r = log_oom();
goto finish;
}
- if (ioctl(fd, FIONREAD, &l) < 0) {
- r = log_error_errno(errno, "FIONREAD failed: %m");
+ l = next_datagram_size_fd(fd);
+ if (l < 0) {
+ r = log_error_errno(l, "Failed to determine datagram size to read: %m");
goto finish;
}
@@ -847,7 +848,7 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
if (fd < 0)
return log_error_errno(errno, "Failed to create coredump socket: %m");
- if (connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return log_error_errno(errno, "Failed to connect to coredump service: %m");
for (i = 0; i < n_iovec; i++) {
@@ -1095,7 +1096,7 @@ static int process_kernel(int argc, char* argv[]) {
IOVEC_SET_STRING(iovec[n_iovec++], core_environ);
}
- core_timestamp = strjoina("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000", NULL);
+ core_timestamp = strjoina("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000");
IOVEC_SET_STRING(iovec[n_iovec++], core_timestamp);
IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
diff --git a/src/grp-coredump/systemd-coredump/stacktrace.c b/src/grp-coredump/systemd-coredump/stacktrace.c
index 68806992fc..cc4dad9465 100644
--- a/src/grp-coredump/systemd-coredump/stacktrace.c
+++ b/src/grp-coredump/systemd-coredump/stacktrace.c
@@ -91,7 +91,7 @@ static int frame_callback(Dwfl_Frame *frame, void *userdata) {
}
fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s)\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname));
- c->n_frame ++;
+ c->n_frame++;
return DWARF_CB_OK;
}
@@ -117,7 +117,7 @@ static int thread_callback(Dwfl_Thread *thread, void *userdata) {
if (dwfl_thread_getframes(thread, frame_callback, c) < 0)
return DWARF_CB_ABORT;
- c->n_thread ++;
+ c->n_thread++;
return DWARF_CB_OK;
}
diff --git a/src/journal-remote/.gitignore b/src/grp-journal-remote/.gitignore
index 06847b65d4..06847b65d4 100644
--- a/src/journal-remote/.gitignore
+++ b/src/grp-journal-remote/.gitignore
diff --git a/src/journal-remote/browse.html b/src/grp-journal-remote/browse.html
index 3594f70c87..32848c7673 100644
--- a/src/journal-remote/browse.html
+++ b/src/grp-journal-remote/browse.html
@@ -391,7 +391,7 @@
entry = document.getElementById("tableentry");
var buf = "";
- for (var key in d){
+ for (var key in d) {
var data = d[key];
if (data == null)
diff --git a/src/journal-remote/log-generator.py b/src/grp-journal-remote/log-generator.py
index fd6964e758..fd6964e758 100755
--- a/src/journal-remote/log-generator.py
+++ b/src/grp-journal-remote/log-generator.py
diff --git a/src/journal-remote/microhttpd-util.c b/src/grp-journal-remote/microhttpd-util.c
index c65c43186f..c65c43186f 100644
--- a/src/journal-remote/microhttpd-util.c
+++ b/src/grp-journal-remote/microhttpd-util.c
diff --git a/src/journal-remote/microhttpd-util.h b/src/grp-journal-remote/microhttpd-util.h
index 70c4d29c0f..ea160f212b 100644
--- a/src/journal-remote/microhttpd-util.h
+++ b/src/grp-journal-remote/microhttpd-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <microhttpd.h>
#include <stdarg.h>
diff --git a/src/systemd-bus-proxyd/Makefile b/src/grp-journal-remote/systemd-journal-gatewayd/Makefile
index 75e98b1633..ed1dfbf301 100644
--- a/src/systemd-bus-proxyd/Makefile
+++ b/src/grp-journal-remote/systemd-journal-gatewayd/Makefile
@@ -20,37 +20,49 @@
#
# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
-systemd_bus_proxyd_SOURCES = \
- src/bus-proxyd/bus-proxyd.c
+ifneq ($(HAVE_MICROHTTPD),)
+gatewayddocumentrootdir=$(pkgdatadir)/gatewayd
-systemd_bus_proxyd_LDADD = \
- libbus-proxy-core.la \
- libshared.la
+libexec_PROGRAMS += \
+ systemd-journal-gatewayd
-nodist_systemunit_DATA += \
- units/systemd-bus-proxyd.service
+systemd_journal_gatewayd_SOURCES = \
+ src/journal-remote/journal-gatewayd.c \
+ src/journal-remote/microhttpd-util.h \
+ src/journal-remote/microhttpd-util.c
-dist_systemunit_DATA += \
- units/systemd-bus-proxyd.socket
+systemd_journal_gatewayd_LDADD = \
+ libshared.la \
+ $(MICROHTTPD_LIBS)
-nodist_userunit_DATA += \
- units/user/systemd-bus-proxyd.service
+ifneq ($(HAVE_GNUTLS),)
+systemd_journal_gatewayd_LDADD += \
+ $(GNUTLS_LIBS)
+endif # HAVE_GNUTLS
-dist_userunit_DATA += \
- units/user/systemd-bus-proxyd.socket
+systemd_journal_gatewayd_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(MICROHTTPD_CFLAGS)
-EXTRA_DIST += \
- units/systemd-bus-proxyd.service.m4.in \
- units/user/systemd-bus-proxyd.service.in
+systemd_journal_gatewayd_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DDOCUMENT_ROOT=\"$(gatewayddocumentrootdir)\"
-ifneq ($(HAVE_SMACK),)
-bus-proxyd-set-cap-hook:
- -$(SETCAP) cap_mac_admin+ei $(DESTDIR)$(libexecdir)/systemd-bus-proxyd
+dist_systemunit_DATA += \
+ units/systemd-journal-gatewayd.socket
-INSTALL_EXEC_HOOKS += bus-proxyd-set-cap-hook
-endif # HAVE_SMACK
+nodist_systemunit_DATA += \
+ units/systemd-journal-gatewayd.service
+
+dist_gatewayddocumentroot_DATA = \
+ src/journal-remote/browse.html
+
+endif # HAVE_MICROHTTPD
+
+EXTRA_DIST += \
+ units/systemd-journal-gatewayd.service.in
include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal-remote/journal-gatewayd.c b/src/grp-journal-remote/systemd-journal-gatewayd/journal-gatewayd.c
index 0e27a80cf2..1cfb5e2c9c 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/grp-journal-remote/systemd-journal-gatewayd/journal-gatewayd.c
@@ -122,12 +122,14 @@ static int open_journal(RequestMeta *m) {
}
static int request_meta_ensure_tmp(RequestMeta *m) {
+ assert(m);
+
if (m->tmp)
rewind(m->tmp);
else {
int fd;
- fd = open_tmpfile("/tmp", O_RDWR|O_CLOEXEC);
+ fd = open_tmpfile_unlinkable("/tmp", O_RDWR|O_CLOEXEC);
if (fd < 0)
return fd;
diff --git a/src/journal-remote/Makefile b/src/grp-journal-remote/systemd-journal-remote/Makefile
index a95f6ab31a..5e730f9fa6 100644
--- a/src/journal-remote/Makefile
+++ b/src/grp-journal-remote/systemd-journal-remote/Makefile
@@ -20,7 +20,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/>.
-include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
ifneq ($(HAVE_MICROHTTPD),)
@@ -82,32 +82,4 @@ EXTRA_DIST += \
src/journal-remote/log-generator.py
endif # HAVE_MICROHTTPD
-ifneq ($(HAVE_LIBCURL),)
-libexec_PROGRAMS += \
- systemd-journal-upload
-
-systemd_journal_upload_SOURCES = \
- src/journal-remote/journal-upload.h \
- src/journal-remote/journal-upload.c \
- src/journal-remote/journal-upload-journal.c
-
-systemd_journal_upload_CFLAGS = \
- $(AM_CFLAGS) \
- $(LIBCURL_CFLAGS)
-
-systemd_journal_upload_LDADD = \
- libshared.la \
- $(LIBCURL_LIBS)
-
-nodist_systemunit_DATA += \
- units/systemd-journal-upload.service
-
-nodist_pkgsysconf_DATA += \
- src/journal-remote/journal-upload.conf
-endif # HAVE_LIBCURL
-
-EXTRA_DIST += \
- units/systemd-journal-upload.service.in \
- src/journal-remote/journal-upload.conf.in
-
include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal-remote/journal-remote-parse.c b/src/grp-journal-remote/systemd-journal-remote/journal-remote-parse.c
index 3864647eb7..9ba9ee3fc0 100644
--- a/src/journal-remote/journal-remote-parse.c
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote-parse.c
@@ -485,7 +485,7 @@ int process_source(RemoteSource *source, bool compress, bool seal) {
}
target = source->size;
- while (target > 16 * LINE_CHUNK && remain < target / 2)
+ while (target > 16 * LINE_CHUNK && source->filled < target / 2)
target /= 2;
if (target < source->size) {
char *tmp;
diff --git a/src/journal-remote/journal-remote-parse.h b/src/grp-journal-remote/systemd-journal-remote/journal-remote-parse.h
index 91c5650798..4f47ea89d6 100644
--- a/src/journal-remote/journal-remote-parse.h
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote-parse.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <systemd/sd-event.h>
#include "journal-remote-write.h"
diff --git a/src/journal-remote/journal-remote-write.c b/src/grp-journal-remote/systemd-journal-remote/journal-remote-write.c
index 5fab74e5cc..7bba52566e 100644
--- a/src/journal-remote/journal-remote-write.c
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote-write.c
@@ -54,7 +54,7 @@ void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) {
**********************************************************************/
static int do_rotate(JournalFile **f, bool compress, bool seal) {
- int r = journal_file_rotate(f, compress, seal);
+ int r = journal_file_rotate(f, compress, seal, NULL);
if (r < 0) {
if (*f)
log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
diff --git a/src/journal-remote/journal-remote-write.h b/src/grp-journal-remote/systemd-journal-remote/journal-remote-write.h
index 6b645a353c..53ba45fc04 100644
--- a/src/journal-remote/journal-remote-write.h
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote-write.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,9 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-
#include "journal-file.h"
typedef struct RemoteServer RemoteServer;
diff --git a/src/journal-remote/journal-remote.c b/src/grp-journal-remote/systemd-journal-remote/journal-remote.c
index db8772d3e6..9b4d12d336 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote.c
@@ -203,7 +203,7 @@ static int open_output(Writer *w, const char* host) {
O_RDWR|O_CREAT, 0640,
arg_compress, arg_seal,
&w->metrics,
- w->mmap,
+ w->mmap, NULL,
NULL, &w->journal);
if (r < 0)
log_error_errno(r, "Failed to open output journal %s: %m",
@@ -434,7 +434,7 @@ static int add_raw_socket(RemoteServer *s, int fd) {
return r;
fd_ = -1;
- s->active ++;
+ s->active++;
return 0;
}
@@ -742,7 +742,7 @@ static int setup_microhttpd_server(RemoteServer *s,
goto error;
}
- s->active ++;
+ s->active++;
return 0;
error:
diff --git a/src/journal-remote/journal-remote.conf.in b/src/grp-journal-remote/systemd-journal-remote/journal-remote.conf.in
index 7122d63362..7122d63362 100644
--- a/src/journal-remote/journal-remote.conf.in
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote.conf.in
diff --git a/src/journal-remote/journal-remote.h b/src/grp-journal-remote/systemd-journal-remote/journal-remote.h
index de83388eef..58487e498a 100644
--- a/src/journal-remote/journal-remote.h
+++ b/src/grp-journal-remote/systemd-journal-remote/journal-remote.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,9 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-
#include <systemd/sd-event.h>
#include "hashmap.h"
diff --git a/src/systemd-bootchart/Makefile b/src/grp-journal-remote/systemd-journal-upload/Makefile
index 26be9339a9..4d8fba8fd0 100644
--- a/src/systemd-bootchart/Makefile
+++ b/src/grp-journal-remote/systemd-journal-upload/Makefile
@@ -20,32 +20,35 @@
#
# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
-ifneq ($(ENABLE_BOOTCHART),)
-systemd_bootchart_SOURCES = \
- src/bootchart/bootchart.c \
- src/bootchart/bootchart.h \
- src/bootchart/store.c \
- src/bootchart/store.h \
- src/bootchart/svg.c \
- src/bootchart/svg.h
+ifneq ($(HAVE_LIBCURL),)
+libexec_PROGRAMS += \
+ systemd-journal-upload
-systemd_bootchart_LDADD = \
- libshared.la
+systemd_journal_upload_SOURCES = \
+ src/journal-remote/journal-upload.h \
+ src/journal-remote/journal-upload.c \
+ src/journal-remote/journal-upload-journal.c
-libexec_PROGRAMS += \
- systemd-bootchart
+systemd_journal_upload_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(LIBCURL_CFLAGS)
-dist_pkgsysconf_DATA += \
- src/bootchart/bootchart.conf
+systemd_journal_upload_LDADD = \
+ libshared.la \
+ $(LIBCURL_LIBS)
nodist_systemunit_DATA += \
- units/systemd-bootchart.service
-endif # ENABLE_BOOTCHART
+ units/systemd-journal-upload.service
+
+nodist_pkgsysconf_DATA += \
+ src/journal-remote/journal-upload.conf
+endif
EXTRA_DIST += \
- units/systemd-bootchart.service.in
+ units/systemd-journal-upload.service.in \
+ src/journal-remote/journal-upload.conf.in
include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal-remote/journal-upload-journal.c b/src/grp-journal-remote/systemd-journal-upload/journal-upload-journal.c
index fc8f63c9e3..aef095c8c9 100644
--- a/src/journal-remote/journal-upload-journal.c
+++ b/src/grp-journal-remote/systemd-journal-upload/journal-upload-journal.c
@@ -25,6 +25,7 @@
#include "log.h"
#include "utf8.h"
#include "util.h"
+#include <systemd/sd-daemon.h>
/**
* Write up to size bytes to buf. Return negative on error, and number of
@@ -52,7 +53,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
/* not enough space */
return pos;
- u->entry_state ++;
+ u->entry_state++;
if (pos + r == size) {
/* exactly one character short, but we don't need it */
@@ -76,7 +77,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
/* not enough space */
return pos;
- u->entry_state ++;
+ u->entry_state++;
if (r + pos == size) {
/* exactly one character short, but we don't need it */
@@ -101,7 +102,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
/* not enough space */
return pos;
- u->entry_state ++;
+ u->entry_state++;
if (r + pos == size) {
/* exactly one character short, but we don't need it */
@@ -126,7 +127,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
/* not enough space */
return pos;
- u->entry_state ++;
+ u->entry_state++;
if (r + pos == size) {
/* exactly one character short, but we don't need it */
@@ -156,7 +157,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
continue;
}
- u->entry_state ++;
+ u->entry_state++;
} /* fall through */
case ENTRY_TEXT_FIELD:
@@ -206,7 +207,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
pos += len + 1;
u->field_pos = len + 1;
- u->entry_state ++;
+ u->entry_state++;
} /* fall through */
case ENTRY_BINARY_FIELD_SIZE: {
@@ -220,7 +221,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
memcpy(buf + pos, &le64, 8);
pos += 8;
- u->entry_state ++;
+ u->entry_state++;
continue;
}
@@ -230,8 +231,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
return pos;
buf[pos++] = '\n';
- u->entry_state ++;
- u->entries_sent ++;
+ u->entry_state++;
+ u->entries_sent++;
return pos;
@@ -242,6 +243,22 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
assert_not_reached("WTF?");
}
+static inline void check_update_watchdog(Uploader *u) {
+ usec_t after;
+ usec_t elapsed_time;
+
+ if (u->watchdog_usec <= 0)
+ return;
+
+ after = now(CLOCK_MONOTONIC);
+ elapsed_time = usec_sub(after, u->watchdog_timestamp);
+ if (elapsed_time > u->watchdog_usec / 2) {
+ log_debug("Update watchdog timer");
+ sd_notify(false, "WATCHDOG=1");
+ u->watchdog_timestamp = after;
+ }
+}
+
static size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
Uploader *u = userp;
int r;
@@ -252,6 +269,8 @@ static size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void
assert(u);
assert(nmemb <= SSIZE_MAX / size);
+ check_update_watchdog(u);
+
j = u->journal;
while (j && filled < size * nmemb) {
diff --git a/src/journal-remote/journal-upload.c b/src/grp-journal-remote/systemd-journal-upload/journal-upload.c
index be3012209c..e622f6c1e1 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/grp-journal-remote/systemd-journal-upload/journal-upload.c
@@ -75,7 +75,7 @@ static void close_fd_input(Uploader *u);
curl_easy_strerror(code)); \
cmd; \
} \
- } while(0)
+ } while (0)
static size_t output_callback(char *buf,
size_t size,
@@ -463,6 +463,8 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
if (r < 0)
return log_error_errno(r, "Failed to set up signals: %m");
+ (void) sd_watchdog_enabled(false, &u->watchdog_usec);
+
return load_cursor_state(u);
}
@@ -494,6 +496,7 @@ static int perform_upload(Uploader *u) {
assert(u);
+ u->watchdog_timestamp = now(CLOCK_MONOTONIC);
code = curl_easy_perform(u->easy);
if (code) {
if (u->error[0])
diff --git a/src/journal-remote/journal-upload.conf.in b/src/grp-journal-remote/systemd-journal-upload/journal-upload.conf.in
index c5670682e8..c5670682e8 100644
--- a/src/journal-remote/journal-upload.conf.in
+++ b/src/grp-journal-remote/systemd-journal-upload/journal-upload.conf.in
diff --git a/src/journal-remote/journal-upload.h b/src/grp-journal-remote/systemd-journal-upload/journal-upload.h
index 40f64dfc60..4a521bf78f 100644
--- a/src/journal-remote/journal-upload.h
+++ b/src/grp-journal-remote/systemd-journal-upload/journal-upload.h
@@ -4,6 +4,7 @@
#include <systemd/sd-event.h>
#include <systemd/sd-journal.h>
+#include "time-util.h"
typedef enum {
ENTRY_CURSOR = 0, /* Nothing actually written yet. */
@@ -48,6 +49,8 @@ typedef struct Uploader {
size_t entries_sent;
char *last_cursor, *current_cursor;
+ usec_t watchdog_timestamp;
+ usec_t watchdog_usec;
} Uploader;
#define JOURNAL_UPLOAD_POLL_TIMEOUT (10 * USEC_PER_SEC)
diff --git a/src/journal/.gitignore b/src/grp-journal/.gitignore
index 04d5852547..04d5852547 100644
--- a/src/journal/.gitignore
+++ b/src/grp-journal/.gitignore
diff --git a/src/grp-journal/Makefile b/src/grp-journal/Makefile
new file mode 100644
index 0000000000..188a3487e4
--- /dev/null
+++ b/src/grp-journal/Makefile
@@ -0,0 +1,170 @@
+# -*- Mode: makefile; indent-tabs-mode: t -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010-2012 Lennart Poettering
+# Copyright 2010-2012 Kay Sievers
+# Copyright 2013 Zbigniew Jędrzejewski-Szmek
+# Copyright 2013 David Strauss
+# Copyright 2016 Luke Shumaker
+#
+# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(topsrcdir)/build-aux/Makefile.head.mk
+
+test_journal_SOURCES = \
+ src/journal/test-journal.c
+
+test_journal_LDADD = \
+ libjournal-core.la
+
+test_journal_send_SOURCES = \
+ src/journal/test-journal-send.c
+
+test_journal_send_LDADD = \
+ libjournal-core.la
+
+test_journal_syslog_SOURCES = \
+ src/journal/test-journal-syslog.c
+
+test_journal_syslog_LDADD = \
+ libjournal-core.la
+
+test_journal_match_SOURCES = \
+ src/journal/test-journal-match.c
+
+test_journal_match_LDADD = \
+ libjournal-core.la
+
+test_journal_enum_SOURCES = \
+ src/journal/test-journal-enum.c
+
+test_journal_enum_LDADD = \
+ libjournal-core.la
+
+test_journal_stream_SOURCES = \
+ src/journal/test-journal-stream.c
+
+test_journal_stream_LDADD = \
+ libjournal-core.la
+
+test_journal_flush_SOURCES = \
+ src/journal/test-journal-flush.c
+
+test_journal_flush_LDADD = \
+ libjournal-core.la
+
+test_journal_init_SOURCES = \
+ src/journal/test-journal-init.c
+
+test_journal_init_LDADD = \
+ libjournal-core.la
+
+test_journal_verify_SOURCES = \
+ src/journal/test-journal-verify.c
+
+test_journal_verify_LDADD = \
+ libjournal-core.la
+
+test_journal_interleaving_SOURCES = \
+ src/journal/test-journal-interleaving.c
+
+test_journal_interleaving_LDADD = \
+ libjournal-core.la
+
+test_mmap_cache_SOURCES = \
+ src/journal/test-mmap-cache.c
+
+test_mmap_cache_LDADD = \
+ libjournal-core.la
+
+test_catalog_SOURCES = \
+ src/journal/test-catalog.c
+
+test_catalog_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DCATALOG_DIR=\"$(abs_top_srcdir)/catalog\"
+
+test_catalog_LDADD = \
+ libjournal-core.la
+
+test_compress_SOURCES = \
+ src/journal/test-compress.c
+
+test_compress_LDADD = \
+ libshared.la
+
+test_compress_benchmark_SOURCES = \
+ src/journal/test-compress-benchmark.c
+
+test_compress_benchmark_LDADD = \
+ libshared.la
+
+test_audit_type_SOURCES = \
+ src/journal/test-audit-type.c
+
+test_audit_type_LDADD = \
+ libjournal-core.la
+
+journal-install-hook:
+ -$(MKDIR_P) $(DESTDIR)/var/log/journal
+ -chown 0:0 $(DESTDIR)/var/log/journal
+ -chmod 755 $(DESTDIR)/var/log/journal
+ -setfacl -nm g:adm:rx,d:g:adm:rx $(DESTDIR)/var/log/journal/
+ -setfacl -nm g:wheel:rx,d:g:wheel:rx $(DESTDIR)/var/log/journal/
+
+journal-uninstall-hook:
+ -rmdir $(DESTDIR)/var/log/journal/remote
+ -rmdir $(DESTDIR)/var/log/journal/
+
+INSTALL_EXEC_HOOKS += journal-install-hook
+UNINSTALL_EXEC_HOOKS += journal-uninstall-hook
+
+# ------------------------------------------------------------------------------
+# Update catalog on installation. Do not bother if installing
+# in DESTDIR, since this is likely for packaging purposes.
+catalog-update-hook:
+ -test -n "$(DESTDIR)" || $(bindir)/journalctl --update-catalog
+
+INSTALL_DATA_HOOKS += \
+ catalog-update-hook
+
+catalog-remove-hook:
+ -test -n "$(DESTDIR)" || rm -f $(catalogstatedir)/database
+
+UNINSTALL_DATA_HOOKS += \
+ catalog-remove-hook
+
+tests += \
+ test-journal \
+ test-journal-enum \
+ test-journal-send \
+ test-journal-syslog \
+ test-journal-match \
+ test-journal-stream \
+ test-journal-init \
+ test-journal-verify \
+ test-journal-interleaving \
+ test-journal-flush \
+ test-mmap-cache \
+ test-catalog \
+ test-audit-type
+
+ifneq ($(HAVE_COMPRESSION),)
+tests += \
+ test-compress \
+ test-compress-benchmark
+endif # HAVE_COMPRESSION
+
+include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal/catalog/systemd.be.catalog b/src/grp-journal/catalog/systemd.be.catalog
index be081d6efc..051f49492f 100644
--- a/src/journal/catalog/systemd.be.catalog
+++ b/src/grp-journal/catalog/systemd.be.catalog
@@ -53,7 +53,7 @@ Documentation: man:journald.conf(5)
Паведамленні іншых сэрвісаў засталіся.
Мяжа, пасля якой паведамленні будуць адкінуты, наладжваецца з
-дапамогай RateLimitInterval= і RateLimitBurst= у файле
+дапамогай RateLimitIntervalSec= і RateLimitBurst= у файле
/etc/systemd/journald.conf. Глядзіце journald.conf(5) для дэталей.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.be@latin.catalog b/src/grp-journal/catalog/systemd.be@latin.catalog
index 382fdb8b04..6ab361aafb 100644
--- a/src/journal/catalog/systemd.be@latin.catalog
+++ b/src/grp-journal/catalog/systemd.be@latin.catalog
@@ -53,7 +53,7 @@ Majcie na ŭvazie, što byli adkinuty paviedamliennia toĺki hetaha servisu.
Paviedamlienni inšych servisaŭ zastalisia.
Miaža, paslia jakoj paviedamlienni buduć adkinuty, naladžvajecca z
-dapamohaj RateLimitInterval= i RateLimitBurst= u fajlie
+dapamohaj RateLimitIntervalSec= i RateLimitBurst= u fajlie
/etc/systemd/journald.conf. Hliadzicie journald.conf(5) dlia detaliej.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/grp-journal/catalog/systemd.bg.catalog b/src/grp-journal/catalog/systemd.bg.catalog
new file mode 100644
index 0000000000..30246c0bbe
--- /dev/null
+++ b/src/grp-journal/catalog/systemd.bg.catalog
@@ -0,0 +1,324 @@
+# This file is part of systemd.
+#
+# Copyright 2012 Lennart Poettering
+# Copyright 2016 Alexander Shopov <ash@kambanaria.org>
+#
+# 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/>.
+
+# Message catalog for systemd's own messages
+
+# The catalog format is documented on
+# http://www.freedesktop.org/wiki/Software/systemd/catalog
+
+# For an explanation why we do all this, see https://xkcd.com/1024/
+
+-- f77379a8490b408bbe5f6940505a777b
+Subject: Журналният процес е пуснат
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Журналният процес на системата е стартирал, отворил е журналните файлове
+за запис и може да приема заявки.
+
+-- d93fb3c9c24d451a97cea615ce59c00b
+Subject: Журналният процес е спрян
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Журналният процес на системата е спрян, затворени са всички отворени
+журнални файлове.
+
+-- ec387f577b844b8fa948f33cad9a75e6
+Subject: Пространството върху диска заето от журналните файлове
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+@JOURNAL_NAME@ (@JOURNAL_PATH@) в момента заема @CURRENT_USE_PRETTY@.
+Максималният зададен размер е @MAX_USE_PRETTY@.
+Свободни се оставят поне @DISK_KEEP_FREE_PRETTY@ (от текущо наличните @DISK_AVAILABLE_PRETTY@).
+Максималният наложен размер е @LIMIT_PRETTY@, от който @AVAILABLE_PRETTY@ са свободни.
+
+Настройките за максималния размер на журнала върху диска се
+управляват чрез директивите „SystemMaxUse=“, „SystemKeepFree=“,
+„SystemMaxFileSize=“, „RuntimeMaxUse=“, „RuntimeKeepFree=“ и
+„RuntimeMaxFileSize=“ във файла „/etc/systemd/journald.conf“.
+За повече информация прегледайте „journald.conf(5)“ от ръководството.
+
+-- a596d6fe7bfa4994828e72309e95d61e
+Subject: Съобщенията от някоя услуга не са допуснати
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:journald.conf(5)
+
+Някоя услуга генерира прекалено много съобщения за кратък период.
+Част само от нейните съобщения са отхвърляни.
+
+Съобщенията от другите услуги не са засегнати.
+
+Настройките за максималния брой съобщения, които ще се обработят, се
+управляват чрез директивите „RateLimitInterval=“ и „RateLimitBurst=“ във
+файла „/etc/systemd/journald.conf“. За повече информация прегледайте
+„journald.conf(5)“ от ръководството.
+
+-- e9bf28e6e834481bb6f48f548ad13606
+Subject: Пропуснати журнални съобщения
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Някои от съобщенията на ядрото може и да са пропуснати, защото системата не
+смогваше да ги обработи достатъчно бързо.
+
+-- fc2e22bc6ee647b6b90729ab34a250b1
+Subject: Процес № @COREDUMP_PID@ (@COREDUMP_COMM@) запази освободената памет
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:core(5)
+
+Процес № @COREDUMP_PID@ (@COREDUMP_COMM@) заби, представянето му в паметта
+бе запазено.
+
+Най-често това се дължи на грешка в забилата програма и следва да я
+докладвате на създателите на програмата.
+
+-- 8d45620c1a4348dbb17410da57c60c66
+Subject: Създадена е нова сесия № @SESSION_ID@ за потребителя „@USER_ID@“
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+За потребителя „@USER_ID@“ е създадена нова сесия № @SESSION_ID@.
+
+Водещият процес на сесията е: @LEADER@
+
+-- 3354939424b4456d9802ca8333ed424a
+Subject: Сесия № @SESSION_ID@ приключи
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Сесия № @SESSION_ID@ приключи работа.
+
+-- fcbefc5da23d428093f97c82a9290f7b
+Subject: Налично е ново работно място № @SEAT_ID@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Новото работно място № @SEAT_ID@ е настроено и готово за работа.
+
+-- e7852bfe46784ed0accde04bc864c2d5
+Subject: Работното място № @SEAT_ID@ е премахнато
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Работното място № @SEAT_ID@ вече не е налично.
+
+-- c7a787079b354eaaa9e77b371893cd27
+Subject: Смяна на системното време
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Часовникът на системата е сверен да сочи @REALTIME@ микросекунди след
+1 януари 1970.
+
+-- 45f82f4aef7a4bbf942ce861d1f20990
+Subject: Смяна на часовия пояс да е „@TIMEZONE@“
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Часовият пояс на системата е сменен на „@TIMEZONE@“.
+
+-- b07a249cd024414a82dd00cd181378ff
+Subject: Стартирането на системата завърши
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Успешно са стартирали всички услуги, които са посочени за задействане при
+стартиране на системата. Това не означава, че системата бездейства, защото
+някои от услугите може да извършват специфични действия при стартиране.
+
+Стартирането на ядрото отне @KERNEL_USEC@ микросекунди.
+
+Стартирането на RAM диска за първоначално зареждане отне @INITRD_USEC@
+микросекунди.
+
+Стартирането на потребителските програми отне @USERSPACE_USEC@ микросекунди.
+
+-- 6bbd95ee977941e497c48be27c254128
+Subject: Системата е приспана на ниво „@SLEEP@“
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Системата премина в състояние на приспиване „@SLEEP@“.
+
+-- 8811e6df2a8e40f58a94cea26f8ebf14
+Subject: Системата се събуди след приспиване на ниво„@SLEEP@“
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Системата се събуди от състояние на приспиване „@SLEEP@“.
+
+-- 98268866d1d54a499c4e98921d93bc40
+Subject: Започна процедура на спиране на системата
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Започна процедурата на Systemd за спиране на системата. Всички процеси и
+услуги се спират, всички файлови системи се демонтират.
+
+-- 7d4958e842da4a758f6c1cdc7b36dcc5
+Subject: Модул „@UNIT@“ се стартира
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Модулът „@UNIT@“ се стартира в момента
+
+-- 39f53479d3a045ac8e11786248231fbf
+Subject: Модул „@UNIT@“ вече е стартиран
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Стартирането на модул „@UNIT@“ завърши.
+
+Резултатът е: @RESULT@
+
+-- de5b426a63be47a7b6ac3eaac82e2f6f
+Subject: Модул „@UNIT@“ се спира
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Модулът „@UNIT@“ се спира в момента.
+
+-- 9d1aaa27d60140bd96365438aad20286
+Subject: Модул „@UNIT@“ вече е спрян
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Спирането на модул „@UNIT@“ завърши.
+
+-- be02cf6855d2428ba40df7e9d022f03d
+Subject: Модулът „@UNIT@“ не успя да стартира
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Модулът „@UNIT@“ не успя да стартира.
+
+Резултатът е: @RESULT@
+
+-- d34d037fff1847e6ae669a370e694725
+Subject: Модулът „@UNIT@“ започна презареждане на настройките си
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Модулът „@UNIT@“ започна презареждане на настройките си.
+
+-- 7b05ebc668384222baa8881179cfda54
+Subject: Модулът „@UNIT@“ завърши презареждането на настройките си
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Модулът „@UNIT@“ завърши презареждането на настройките си.
+
+Резултатът e: @RESULT@
+
+-- 641257651c1b4ec9a8624d7a40a9e1e7
+Subject: Програмата „@EXECUTABLE@“ не успя да се стартира
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Програмата „@EXECUTABLE@“ не успя да се стартира.
+
+Върнатият номер на грешка е: @ERRNO@
+
+-- 0027229ca0644181a76c4e92458afa2e
+Subject: Поне едно съобщение не бе препратено към syslog
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Поне едно съобщение не бе препратено към журналната услуга syslog, която
+работи успоредно с journald.
+
+Най-често това указва, че тази реализация на syslog не може да поеме текущия
+обем съобщения.
+
+-- 1dee0369c7fc4736b7099b38ecb46ee7
+Subject: Точката за монтиране не е празна
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Директорията „@WHERE@“ не е празна.
+
+Тя е указана като точка за монтиране — или като второ поле във файла
+„/etc/fstab“, или чрез директивата „Where=“ в някой от файловете за
+модул на Systemd.
+
+Това не пречи на самото монтиране, но вече съществуващите там файлове и
+директории няма да се виждат повече, освен ако ръчно не монтирате тази
+непразна директория някъде другаде.
+
+-- 24d8d4452573402496068381a6312df2
+Subject: Стартирана е виртуална машина или контейнер
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Виртуалната машина „@NAME@“ с идентификатор на водещия процес @LEADER@
+е стартирана и готова за работа.
+
+-- 58432bd3bace477cb514b56381b8a758
+Subject: Спряна е виртуална машина или контейнер
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Виртуалната машина „@NAME@“ с идентификатор на водещия процес @LEADER@
+е спряна.
+
+-- 36db2dfa5a9045e1bd4af5f93e1cf057
+Subject: Режимът DNSSEC е изключен, защото сървърът не го поддържа
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8) resolved.conf(5)
+
+Локалната услуга за имена (systemd-resolved.service) установи, че
+настроения сървър за DNS не поддържа DNSSEC, затова този режим е изключен.
+
+Това се случва, когато директивата „DNSSEC=allow-downgrade“ е включена във
+файла „resolved.conf“ и зададеният сървър за DNS не е съвместим с DNSSEC.
+
+Внимавайте, защото това може да позволи атака, при която трета страна ви
+връща отговори, които да предизвикат понижаването на сигурността от DNSSEC
+до DNS.
+
+Такова събитие означава, че или сървърът за DNS не е съвместим с DNSSEC,
+или някой успешно ви е атакувал за понижаване на сигурността на имената.
+
+-- 1675d7f172174098b1108bf8c7dc8f5d
+Subject: Неуспешна проверка на DNSSEC
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+Заявка или запис в DNS не издържа проверка с DNSSEC.
+
+Това обикновено показва вмешателство на трета страна в канала ви за връзка.
+
+-- 4d4408cfd0d144859184d1e65d7c8a65
+Subject: Анулирана доверена котва в DNSSEC
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+Анулирана е доверена котва за DNSSEC и трябва да настроите нова.
+
+Понякога новата идва с обновяване на системата.
diff --git a/src/journal/catalog/systemd.catalog b/src/grp-journal/catalog/systemd.catalog
index 077f182a5a..90929bca6d 100644
--- a/src/journal/catalog/systemd.catalog
+++ b/src/grp-journal/catalog/systemd.catalog
@@ -66,7 +66,7 @@ Note that only messages from the service in question have been
dropped, other services' messages are unaffected.
The limits controlling when messages are dropped may be configured
-with RateLimitInterval= and RateLimitBurst= in
+with RateLimitIntervalSec= and RateLimitBurst= in
/etc/systemd/journald.conf. See journald.conf(5) for details.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.da.catalog b/src/grp-journal/catalog/systemd.da.catalog
index bd4d742d8a..093e8139da 100644
--- a/src/journal/catalog/systemd.da.catalog
+++ b/src/grp-journal/catalog/systemd.da.catalog
@@ -52,7 +52,7 @@ Kun beskeder fra omtalte service er smidt væk. Beskeder fra andre
services er ikke påvirket.
Grænsen for hvornår beskeder bliver smidt væk kan konfigureres
-med RateLimitInterval= og RateLimitBurst= i
+med RateLimitIntervalSec= og RateLimitBurst= i
/etc/systemd/journald.conf. Se journald.conf(5) for detaljer herom.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.fr.catalog b/src/grp-journal/catalog/systemd.fr.catalog
index 03a457786f..0cea629c31 100644
--- a/src/journal/catalog/systemd.fr.catalog
+++ b/src/grp-journal/catalog/systemd.fr.catalog
@@ -38,6 +38,25 @@ Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Le processus du journal système a été arrêté et tous ses fichiers actifs
ont été fermés.
+-- ec387f577b844b8fa948f33cad9a75e6
+Subject: Espace disque utilisé par le journal
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:journald.conf(5)
+
+@JOURNAL_NAME@ (@JOURNAL_PATH@) utilise actuellement @CURRENT_USE_PRETTY@.
+Le maximum autorisé est défini à @MAX_USE_PRETTY@.
+Au moins @DISK_KEEP_FREE_PRETTY@ doivent être laissés libres
+(sur @DISK_AVAILABLE_PRETTY@ d'espace disque actuellement libre).
+La limite appliquée est donc @LIMIT_PRETTY@, dont @AVAILABLE_PRETTY@
+sont toujours disponibles.
+
+Les limites définissant la quantité d'espace disque que peut utiliser le
+journal peuvent être configurées avec les paramètres SystemMaxUse=,
+SystemKeepFree=, SystemMaxFileSize=, RuntimeMaxUse=, RuntimeKeepFree=,
+RuntimeMaxFileSize= dans le fichier /etc/systemd/journald.conf.
+Voir journald.conf(5) pour plus de détails.
+
-- a596d6fe7bfa4994828e72309e95d61e
Subject: Des messages d'un service ont été supprimés
Defined-By: systemd
@@ -51,7 +70,7 @@ Notez que seuls des messages de ce service ont été évincés, les messages des
autres services ne sont pas affectés.
Les limites définissant ce comportement peuvent être configurées avec les
-paramètres RateLimitInterval= et RateLimitBurst= dans le fichier
+paramètres RateLimitIntervalSec= et RateLimitBurst= dans le fichier
/etc/systemd/journald.conf. Voir journald.conf(5) pour plus de détails.
-- e9bf28e6e834481bb6f48f548ad13606
@@ -98,7 +117,8 @@ Defined-By: systemd
Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
-Un nouveau poste (seat) @SEAT_ID@ a été configuré et est maintenant disponible.
+Un nouveau poste (seat) @SEAT_ID@ a été configuré et est maintenant
+disponible.
-- e7852bfe46784ed0accde04bc864c2d5
Subject: Le poste (seat) @SEAT_ID@ a été retiré
@@ -228,8 +248,8 @@ Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Un ou plusieurs messages n'ont pas pu être transmis au service syslog
s'exécutant conjointement avec journald. Cela indique généralement que
-l'implémentation de syslog utilisée n'a pas été capable de suivre la cadence
-du flux de messages.
+l'implémentation de syslog utilisée n'a pas été capable de suivre
+la cadence du flux de messages.
-- 1dee0369c7fc4736b7099b38ecb46ee7
Subject: Le point de montage n'est pas vide
@@ -237,8 +257,8 @@ Defined-By: systemd
Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Le répertoire @WHERE@ est spécifié comme point de montage (second champ du
-fichier /etc/fstab, ou champ Where= dans une unité (unit) systemd) et n'est pas
-vide.
+fichier /etc/fstab, ou champ Where= dans une unité (unit) systemd) et n'est
+pas vide.
Cela ne perturbe pas le montage du système de fichiers, mais les fichiers
préalablement présents dans ce répertoire sont devenus inaccessibles.
Pour atteindre ces fichiers, veuillez monter manuellement le système de
@@ -258,3 +278,43 @@ Defined-By: systemd
Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
La machine virtuelle @NAME@ avec le PID maître @LEADER@ a été arrêtée.
+
+-- 36db2dfa5a9045e1bd4af5f93e1cf057
+Subject: Le mode DNSSEC a été désactivé, car il n'est pas supporté par le serveur
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8) resolved.conf(5)
+
+Le service de résolution (systemd-resolved.service) a détecté que le serveur
+DNS configuré ne supporte pas DNSSEC, et la validation DNSSEC a donc été
+désactivée.
+
+Cet évènement se produit si DNSSEC=allow-downgrade est configuré dans
+resolved.conf et que le serveur DNS configuré n'est pas compatible avec
+DNSSEC.
+Veuillez noter que ce mode permet des attaques de rétrogradation DNSSEC,
+car un attaquant peut être capable de désactiver la validation DNSSEC sur
+le système en injectant des réponses DNS dans le canal de communication.
+
+Cet évènement indique que le serveur DNS est effectivement incompatible avec
+DNSSEC, ou qu'un attaquant a peut-être conduit une telle attaque avec succès.
+
+-- 1675d7f172174098b1108bf8c7dc8f5d
+Subject: La validation DNSSEC a échoué
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+Une requête ou une ressource DNS n'a pas passé la validation DNSSEC.
+Ceci est généralement une indication que le canal de communication a été
+altéré.
+
+-- 4d4408cfd0d144859184d1e65d7c8a65
+Subject: Une ancre de confiance DNSSEC a été révoquée
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+Une ancre de confiance DNSSEC a été révoquée. Une nouvelle ancre de
+confiance doit être configurée, ou le système d'exploitation a besoin
+d'être mis à jour, pour fournir une version à jour de l'ancre de confiance.
diff --git a/src/grp-journal/catalog/systemd.hr.catalog b/src/grp-journal/catalog/systemd.hr.catalog
new file mode 100644
index 0000000000..350988dd87
--- /dev/null
+++ b/src/grp-journal/catalog/systemd.hr.catalog
@@ -0,0 +1,314 @@
+# This file is part of systemd.
+#
+# Copyright 2012 Lennart Poettering
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+# Message catalog for systemd's own messages
+# Croatian translation
+
+# Format kataloga je dokumentiran na
+# http://www.freedesktop.org/wiki/Software/systemd/catalog
+
+# Za pojašnjenje zašto ovo radimo, posjetite https://xkcd.com/1024/
+
+-- f77379a8490b408bbe5f6940505a777b
+Subject: journal je pokrenut
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Journal proces sustava se pokrenuo, otvorio je journal
+ datoteke za upis i spreman je za obradu zahtjeva.
+
+-- d93fb3c9c24d451a97cea615ce59c00b
+Subject: journal je zaustavljen
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Journal proces sustava je isključio i zatvorio sve trenutno
+aktivne journal datoteke.
+
+-- ec387f577b844b8fa948f33cad9a75e6
+Subject: Diskovni prostor koji koristi journal
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+@JOURNAL_NAME@ (@JOURNAL_PATH@) trenutno koristi @CURRENT_USE_PRETTY@.
+Najveća dopuštena upotreba je postavljena na @MAX_USE_PRETTY@.
+Ostavljam najmanje @DISK_KEEP_FREE_PRETTY@ slobodno (trenutno dostupno @DISK_AVAILABLE_PRETTY@ diskovnog prostora).
+Prisilno ograničenje upotrebe je @LIMIT_PRETTY@, od kojeg je @AVAILABLE_PRETTY@ još dostupno.
+
+Ograničenja kontroliraju koliko diskovnog prostora koristi journal mogu
+se podesiti sa SystemMaxUse=, SystemKeepFree=, SystemMaxFileSize=,
+RuntimeMaxUse=, RuntimeKeepFree=, RuntimeMaxFileSize= settings u
+/etc/systemd/journald.conf. Pogledajte journald.conf(5) za više pojedinosti.
+
+-- a596d6fe7bfa4994828e72309e95d61e
+Subject: Poruka iz usluge je potisnuta
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:journald.conf(5)
+
+Usluga je prijavila previše poruka u određenom vremenskom razdoblju. Poruke
+iz usluge su odbačene.
+
+Zapamtite da samo poruke iz usluge u upitu su
+odbačene, ostale poruke usluga nisu zahvaćene.
+
+Ograničenja koja kontroliraju kada je poruka odbačena mogu se podesiti
+sa RateLimitIntervalSec= i RateLimitBurst= u
+/etc/systemd/journald.conf. Pogledajte journald.conf(5) za više pojedinosti.
+
+-- e9bf28e6e834481bb6f48f548ad13606
+Subject: Journal poruka je propuštena
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Kernel poruka je izgubljena zato jer ih journal sustav nije mogao
+dovoljno brzo obraditi.
+
+-- fc2e22bc6ee647b6b90729ab34a250b1
+Subject: Proces @COREDUMP_PID@ (@COREDUMP_COMM@) je izbacio jezgru
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:core(5)
+
+Proces @COREDUMP_PID@ (@COREDUMP_COMM@) se srušio i izbacio jezgru.
+
+Rušenje programa je uobičajeno uzrokovano greškom u programiranju i
+trebalo bi se prijaviti razvijatelju kao greška.
+
+-- 8d45620c1a4348dbb17410da57c60c66
+Subject: Nova sesija @SESSION_ID@ je stvorena za korisnika @USER_ID@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Nova sesija sa ID @SESSION_ID@ je stvorena za korisnika @USER_ID@.
+
+Glavni proces sesije je @LEADER@.
+
+-- 3354939424b4456d9802ca8333ed424a
+Subject: Sesija @SESSION_ID@ je prekinuta
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Sesija sa ID @SESSION_ID@ je prekinuta.
+
+-- fcbefc5da23d428093f97c82a9290f7b
+Subject: Novo sjedište @SEAT_ID@ je sada dostupno
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Novo sjedište @SEAT_ID@ je podešeno i sada je dostupno.
+
+-- e7852bfe46784ed0accde04bc864c2d5
+Subject: Sjedište @SEAT_ID@ je sada uklonjeno
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+
+Sjedište @SEAT_ID@ je uklonjeno i više nije dostupno.
+
+-- c7a787079b354eaaa9e77b371893cd27
+Subject: Vrijeme promjene
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Sat sustava je promijenjen na @REALTIME@ microsekundi nakon 1. Siječnja, 1970 godine.
+
+-- 45f82f4aef7a4bbf942ce861d1f20990
+Subject: Vremenska zona je promijenjena u @TIMEZONE@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Vremenska zona je promijenjena u @TIMEZONE@.
+
+-- b07a249cd024414a82dd00cd181378ff
+Subject: Pokretanje sustava je sada završeno
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Sve usluge sustava koje su zadane za pokretanje pri pokretanju sustava
+su uspješno pokrenute. Zapamtite da ovo ne znači da sada računalo
+miruje zato jer se neke usluge još uvijek mogu pokretati.
+
+Pokretanje kernela zahtijeva @KERNEL_USEC@ mikrosekundi.
+
+Pokretanje početnog RAM diska zahtijeva @INITRD_USEC@ mikrosekundi.
+
+Pokretanje prostora korisnika zahtijeva @USERSPACE_USEC@ mikrosekundi.
+
+-- 6bbd95ee977941e497c48be27c254128
+Subject: Pokrenuto je stanje spavanja @SLEEP@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Sustav je sada pokrenuo stanje spavanja @SLEEP@
+
+-- 8811e6df2a8e40f58a94cea26f8ebf14
+Subject: Završeno je stanje spavanja @SLEEP@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Sustav je sada završio stanje spavanja @SLEEP@
+
+-- 98268866d1d54a499c4e98921d93bc40
+Subject: Pokrenuto je isključivanje sustava
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Pokrenuto je isključivanje sustava. Isključivanje je sada pokrenuto,
+sve usluge sustava su prekinute i svi datotečni sustavi su odmontirani.
+
+-- 7d4958e842da4a758f6c1cdc7b36dcc5
+Subject: Jedinica @UNIT@ je započela pokretanje
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ je započela pokretanje.
+
+-- 39f53479d3a045ac8e11786248231fbf
+Subject: Jedinica @UNIT@ je završila pokretanje
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ je završila pokretanje.
+
+Rezultat pokretanja je @RESULT@.
+
+-- de5b426a63be47a7b6ac3eaac82e2f6f
+Subject: Jedinica @UNIT@ je započela isključivanje
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ je započela isključivanje.
+
+-- 9d1aaa27d60140bd96365438aad20286
+Subject: Jedinica @UNIT@ je završila isključivanje
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ je završila isključivanje.
+
+-- be02cf6855d2428ba40df7e9d022f03d
+Subject: Jedinica @UNIT@ nije uspjela
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ nije uspjela.
+
+Rezultat je @RESULT@.
+
+-- d34d037fff1847e6ae669a370e694725
+Subject: Jedinica @UNIT@ je započela ponovno učitavati podešavanja
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ je započela ponovno učitavati podešavanja
+
+-- 7b05ebc668384222baa8881179cfda54
+Subject: Jedinica @UNIT@ je završila ponovno učitavati podešavanja
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedinica @UNIT@ je završila ponovno učitavati podešavanja
+
+Rezultat je @RESULT@.
+
+-- 641257651c1b4ec9a8624d7a40a9e1e7
+Subject: Proces @EXECUTABLE@ se ne može pokrenuti
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Proces @EXECUTABLE@ se ne može pokrenuti i nije uspio.
+
+Broj greške vraćen ovim procesom je @ERRNO@.
+
+-- 0027229ca0644181a76c4e92458afa2e
+Subject: Jedna ili više poruka se ne mogu proslijediti u dnevnik sustava
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Jedna ili više poruka se ne mogu proslijediti u dnevnik sustava, usluge
+su pokrenute istovremeno s journalom. Ovo uobičajeno označava da
+implementacija dnevnika sustava ne može slijediti brzinu
+zahtjeva poruka.
+
+-- 1dee0369c7fc4736b7099b38ecb46ee7
+Subject: Točka montiranja nije prazna
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Direktorij @WHERE@ je određen za točku montiranja (drugi redak u
+/etc/fstab ili Where= redak u datoteci systemd jedinice) i nije prazan.
+To ne utječe na montiranje, ali postojeće datoteke u ovom direktoriju
+postaju nedostupne. Kako bi vidjeli datoteke preko kojih je montirano,
+ručno montirajte osnovni datotečni sustav na drugu lokaciju.
+
+-- 24d8d4452573402496068381a6312df2
+Subject: Virtualni stroj ili spremnik su pokrenuti
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Virtualni stroj @NAME@ sa vodećim @LEADER@ PID-om je
+pokrenut i spreman je za korištenje.
+
+-- 58432bd3bace477cb514b56381b8a758
+Subject: Virtualni stroj ili spremnik su isključeni
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+Virtualni stroj @NAME@ sa vodećim PID-om @LEADER@ je
+isključen.
+
+-- 36db2dfa5a9045e1bd4af5f93e1cf057
+Subject: DNSSEC način je isključen, jer ga poslužitelj ne podržava
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8) resolved.conf(5)
+
+Usluga razrješavanja (systemd-resolved.service) je otkrila da
+podešeni DNS poslužitelj ne podržava DNSSEC, i DNSSEC, kao rezultat
+provjera je isključena.
+
+Ovaj događaj će zauzeti mjesto ako je DNSSEC=allow-downgrade podešen u
+resolved.conf i podešeni DNS poslužitelj je nekompatibilan s DNSSEC. Zapamtite
+da korištenje ovog načina dopušta povećanje DNSSEC napada, napadač bi mogao
+isključiti DNSSEC provjeru na sustavu umetanjem DNS odgovora u
+komunikacijski kanal što rezultira povećanjem napada poput ovog.
+
+Ovaj događaj bi mogao označavati da je DNS poslužitelj uistinu nekompatibilan s
+DNSSEC ili da je napadač uspješno izvršio takav napad.
+
+-- 1675d7f172174098b1108bf8c7dc8f5d
+Subject: DNSSEC provjera neuspješna
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+DNS zahtjev ili snimak resursa nije prošao DNSSEC provjeru. To uobičajeno
+označava da je komunikacijski kanal mijenjan.
+
+-- 4d4408cfd0d144859184d1e65d7c8a65
+Subject: DNSSEC pouzdano sidro je opozvano
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+A DNSSEC trust anchor has been revoked. A new trust anchor has to be
+configured, or the operating system needs to be updated, to provide an updated
+DNSSEC trust anchor.
diff --git a/src/journal/catalog/systemd.hu.catalog b/src/grp-journal/catalog/systemd.hu.catalog
index 30d76916cc..68e8c2572e 100644
--- a/src/journal/catalog/systemd.hu.catalog
+++ b/src/grp-journal/catalog/systemd.hu.catalog
@@ -51,7 +51,7 @@ Ne feledje, hogy csak a kérdéses szolgáltatás üzenetei kerültek eldobásra
más szolgáltatások üzeneteit ez nem befolyásolja.
Az üzenetek eldobását vezérlő korlátok az /etc/systemd/journald.conf
-RateLimitInterval= és RateLimitBurst= beállításaival adhatók meg.
+RateLimitIntervalSec= és RateLimitBurst= beállításaival adhatók meg.
Részletekért lásd a journald.conf(5) man oldalt.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.it.catalog b/src/grp-journal/catalog/systemd.it.catalog
index 861b92b74a..b6fca48221 100644
--- a/src/journal/catalog/systemd.it.catalog
+++ b/src/grp-journal/catalog/systemd.it.catalog
@@ -46,7 +46,7 @@ Solo i messaggi del servizio indicato sono stati
eliminati, i messaggi degli altri servizi rimangono invariati.
I limiti oltre i quali i messaggi si eliminano si configurano
-con RateLimitInterval= e RateLimitBurst= in
+con RateLimitIntervalSec= e RateLimitBurst= in
/etc/systemd/journald.conf. Vedi journald.conf(5) per maggiori informazioni.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.ko.catalog b/src/grp-journal/catalog/systemd.ko.catalog
index 3c3535a94c..2fc6b60b1b 100644
--- a/src/journal/catalog/systemd.ko.catalog
+++ b/src/grp-journal/catalog/systemd.ko.catalog
@@ -55,7 +55,7 @@ Documentation: man:journald.conf(5)
다른 서비스의 메시지에는 영향을 주지 않습니다.
메시지 거절 제어 제한 값은 /etc/systemd/journald.conf 의
-RateLimitInterval= 변수와 RateLimitBurst= 변수로 설정합니다.
+RateLimitIntervalSec= 변수와 RateLimitBurst= 변수로 설정합니다.
자세한 내용은 ournald.conf(5)를 살펴보십시오.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.pl.catalog b/src/grp-journal/catalog/systemd.pl.catalog
index 6b8a31d8c4..d8059e93cd 100644
--- a/src/journal/catalog/systemd.pl.catalog
+++ b/src/grp-journal/catalog/systemd.pl.catalog
@@ -1,7 +1,7 @@
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
-# Copyright 2014, 2015 Piotr Drąg
+# Copyright 2014, 2015, 2016 Piotr Drąg
#
# 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
@@ -40,6 +40,22 @@ Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Systemowy proces dziennika został wyłączony i zamknął wszystkie obecnie
aktywne pliki dziennika.
+-- ec387f577b844b8fa948f33cad9a75e6
+Subject: Miejsce na dysku używane przez dziennik
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+
+@JOURNAL_NAME@ (@JOURNAL_PATH@) obecnie używa @CURRENT_USE_PRETTY@.
+Maksymalnie może używać @MAX_USE_PRETTY@.
+Zostawianie co najmniej @DISK_KEEP_FREE_PRETTY@ wolnego (z obecnie dostępnego @DISK_AVAILABLE_PRETTY@ miejsca na dysku).
+Wymuszone ograniczenie użycia wynosi więc @LIMIT_PRETTY@, z czego @AVAILABLE_PRETTY@ jest nadal dostępne.
+
+Ograniczenia kontrolujące ilość miejsca na dysku używanego przez dziennik
+można konfigurować za pomocą ustawień SystemMaxUse=, SystemKeepFree=,
+SystemMaxFileSize=, RuntimeMaxUse=, RuntimeKeepFree=, RuntimeMaxFileSize=
+w pliku /etc/systemd/journald.conf. Strona journald.conf(5) zawiera więcej
+informacji.
+
-- a596d6fe7bfa4994828e72309e95d61e
Subject: Ograniczono komunikaty z usługi
Defined-By: systemd
@@ -53,7 +69,7 @@ Proszę zauważyć, że tylko komunikaty z danej usługi zostały pominięte. Ni
to wpływu na komunikaty innych usług.
Ograniczenia kontrolujące pomijanie komunikatów mogą być konfigurowane
-za pomocą opcji RateLimitInterval= i RateLimitBurst= w pliku
+za pomocą opcji RateLimitIntervalSec= i RateLimitBurst= w pliku
/etc/systemd/journald.conf. Strona journald.conf(5) zawiera więcej informacji.
-- e9bf28e6e834481bb6f48f548ad13606
@@ -72,7 +88,8 @@ Documentation: man:core(5)
Proces @COREDUMP_PID@ (@COREDUMP_COMM@) uległ awarii i zrzucił plik core.
-Zwykle wskazuje to na błąd programistyczny w danym programie i powinno zostać zgłoszone jego producentowi jako błąd.
+Zwykle wskazuje to na błąd programistyczny w danym programie i powinno zostać
+zgłoszone jego producentowi jako błąd.
-- 8d45620c1a4348dbb17410da57c60c66
Subject: Utworzono nową sesję @SESSION_ID@ dla użytkownika @USER_ID@
@@ -259,3 +276,40 @@ Defined-By: systemd
Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Maszyna wirtualna @NAME@ (PID prowadzący @LEADER@) została wyłączona.
+
+-- 36db2dfa5a9045e1bd4af5f93e1cf057
+Subject: Wyłączono tryb DNSSEC, ponieważ serwer go nie obsługuje
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8) resolved.conf(5)
+
+Usługa resolver (systemd-resolved.service) wykryła, że skonfigurowany serwer
+DNS nie obsługuje DNSSEC, w wyniku czego walidacja DNSSEC została wyłączona.
+
+To zdarzenie będzie miało miejsce, jeśli skonfigurowano DNSSEC=allow-downgrade
+w pliku resolved.conf, a skonfigurowany serwer DNS jest niezgodny z DNSSEC.
+Proszę zauważyć, że używanie tego trybu umożliwia ataki wyłączające DNSSEC,
+ponieważ atakujący będzie mógł wyłączyć walidację DNSSEC na komputerze przez
+umieszczenie odpowiednich odpowiedzi DNS w kanale komunikacji.
+
+To zdarzenie może wskazywać, że serwer DNS jest faktycznie niezgodny z DNSSEC,
+albo że atakującemu udało się upozorować atak tego typu.
+
+-- 1675d7f172174098b1108bf8c7dc8f5d
+Subject: Walidacja DNSSEC się nie powiodła
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+Zapytanie DNS lub ustawiony wpis zasobu nie przeszedł walidacji DNSSEC.
+Zwykle wskazuje to, że ktoś manipulował używanym kanałem komunikacji.
+
+-- 4d4408cfd0d144859184d1e65d7c8a65
+Subject: Unieważniono kotwicę zaufania DNSSEC
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:systemd-resolved.service(8)
+
+Kotwica zaufania DNSSEC została unieważniona. Należy skonfigurować nową, albo
+system operacyjny musi zostać zaktualizowany, aby dostarczyć zaktualizowaną
+kotwicę zaufania DNSSEC.
diff --git a/src/journal/catalog/systemd.pt_BR.catalog b/src/grp-journal/catalog/systemd.pt_BR.catalog
index d9716e30f7..8b856e8355 100644
--- a/src/journal/catalog/systemd.pt_BR.catalog
+++ b/src/grp-journal/catalog/systemd.pt_BR.catalog
@@ -53,7 +53,7 @@ Note que apenas mensagens de um serviço em questão foram descartadas; outras
mensagens dos serviços não foram afetadas.
Os controles de limites de quando as mensagens são descartadas pode ser
-configurado com RateLimitInterval= e RateLimitBurst= no
+configurado com RateLimitIntervalSec= e RateLimitBurst= no
/etc/systemd/journald.conf. Veja journald.conf(5) para detalhes.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.ru.catalog b/src/grp-journal/catalog/systemd.ru.catalog
index eedbb8aa9c..e56dbe3acc 100644
--- a/src/journal/catalog/systemd.ru.catalog
+++ b/src/grp-journal/catalog/systemd.ru.catalog
@@ -76,7 +76,7 @@ Documentation: man:journald.conf(5)
сообщения других служб не затронуты.
Предел, после которого служба журнала начинает игнорировать сообщения,
-настраивается параметрами RateLimitInterval= и RateLimitBurst= в файле
+настраивается параметрами RateLimitIntervalSec= и RateLimitBurst= в файле
/etc/systemd/journald.conf. Подробности смотрите на странице руководства
journald.conf(5).
diff --git a/src/journal/catalog/systemd.sr.catalog b/src/grp-journal/catalog/systemd.sr.catalog
index cf700c477b..cc689b7956 100644
--- a/src/journal/catalog/systemd.sr.catalog
+++ b/src/grp-journal/catalog/systemd.sr.catalog
@@ -52,7 +52,7 @@ Documentation: man:journald.conf(5)
услуге нису захваћене овим.
Ограничења која подешавају начин на који се поруке одбацују се могу подесити
-помоћу „RateLimitInterval=“ и „RateLimitBurst=“ параметара унутар датотеке
+помоћу „RateLimitIntervalSec=“ и „RateLimitBurst=“ параметара унутар датотеке
/etc/systemd/journald.conf. Погледајте journald.conf(5) за појединости.
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/journal/catalog/systemd.zh_CN.catalog b/src/grp-journal/catalog/systemd.zh_CN.catalog
index 38639109e4..ed59fc9250 100644
--- a/src/journal/catalog/systemd.zh_CN.catalog
+++ b/src/grp-journal/catalog/systemd.zh_CN.catalog
@@ -50,7 +50,7 @@ Documentation: man:journald.conf(5)
请注意只有由有问题的服务传来的消息被丢弃,
其它服务的消息不受影响。
-可以在 /etc/systemd/journald.conf 中设定 RateLimitInterval=
+可以在 /etc/systemd/journald.conf 中设定 RateLimitIntervalSec=
以及 RateLimitBurst = 的值以控制丢弃信息的限制。
请参见 journald.conf(5) 以了解详情。
diff --git a/src/journal/catalog/systemd.zh_TW.catalog b/src/grp-journal/catalog/systemd.zh_TW.catalog
index 027ffe44e5..aa5004db08 100644
--- a/src/journal/catalog/systemd.zh_TW.catalog
+++ b/src/grp-journal/catalog/systemd.zh_TW.catalog
@@ -53,7 +53,7 @@ Documentation: man:journald.conf(5)
其他服務的訊息則不受影響。
可以在 /etc/systemd/journald.conf 中設定
-RateLimitInterval= 以及 RateLimitBurst=
+RateLimitIntervalSec= 以及 RateLimitBurst=
來控制當訊息要開始被丟棄時的限制。參見 journald.conf(5) 以獲得更多資訊。
-- e9bf28e6e834481bb6f48f548ad13606
diff --git a/src/libbus-proxy-core/Makefile b/src/grp-journal/journalctl/Makefile
index f3cf4a055f..c3cdb6b27a 100644
--- a/src/libbus-proxy-core/Makefile
+++ b/src/grp-journal/journalctl/Makefile
@@ -20,23 +20,30 @@
#
# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
-noinst_LTLIBRARIES += \
- libbus-proxy-core.la
+# using _CFLAGS = in the conditional below would suppress AM_CFLAGS
+journalctl_CFLAGS = \
+ $(AM_CFLAGS)
-libbus_proxy_core_la_SOURCES = \
- src/bus-proxyd/bus-xml-policy.c \
- src/bus-proxyd/bus-xml-policy.h \
- src/bus-proxyd/driver.c \
- src/bus-proxyd/driver.h \
- src/bus-proxyd/proxy.c \
- src/bus-proxyd/proxy.h \
- src/bus-proxyd/synthesize.c \
- src/bus-proxyd/synthesize.h
+journalctl_SOURCES = \
+ src/journal/journalctl.c
-libbus_proxy_core_la_LIBADD = \
- libshared.la
+journalctl_LDADD = \
+ libshared.la \
+ libudev-core.la
+
+ifneq ($(HAVE_QRENCODE),)
+journalctl_SOURCES += \
+ src/journal/journal-qrcode.c \
+ src/journal/journal-qrcode.h
+
+journalctl_CFLAGS += \
+ $(QRENCODE_CFLAGS)
+
+journalctl_LDADD += \
+ $(QRENCODE_LIBS)
+endif # HAVE_QRENCODE
include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal/journalctl.c b/src/grp-journal/journalctl/journalctl.c
index 1670978466..3602bd0556 100644
--- a/src/journal/journalctl.c
+++ b/src/grp-journal/journalctl/journalctl.c
@@ -95,11 +95,13 @@ static bool arg_boot = false;
static sd_id128_t arg_boot_id = {};
static int arg_boot_offset = 0;
static bool arg_dmesg = false;
+static bool arg_no_hostname = false;
static const char *arg_cursor = NULL;
static const char *arg_after_cursor = NULL;
static bool arg_show_cursor = false;
static const char *arg_directory = NULL;
static char **arg_file = NULL;
+static bool arg_file_stdin = false;
static int arg_priorities = 0xFF;
static const char *arg_verify_key = NULL;
#ifdef HAVE_GCRYPT
@@ -225,14 +227,6 @@ static int add_matches_for_device(sd_journal *j, const char *devpath) {
return 0;
}
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(arg_pager_end);
-}
-
static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
if (arg_utc)
@@ -278,7 +272,7 @@ static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset
static void help(void) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, arg_pager_end);
printf("%s [OPTIONS...] [MATCHES...]\n\n"
"Query the journal.\n\n"
@@ -312,6 +306,7 @@ static void help(void) {
" -a --all Show all fields, including long and unprintable\n"
" -q --quiet Do not show info messages and privilege warning\n"
" --no-pager Do not pipe output into a pager\n"
+ " --no-hostname Suppress output of hostname field\n"
" -m --merge Show entries from all available journals\n"
" -D --directory=PATH Show journal files from directory\n"
" --file=PATH Show journal file\n"
@@ -378,6 +373,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VACUUM_SIZE,
ARG_VACUUM_FILES,
ARG_VACUUM_TIME,
+ ARG_NO_HOSTNAME,
};
static const struct option options[] = {
@@ -435,6 +431,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
{ "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES },
{ "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
+ { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME },
{}
};
@@ -596,9 +593,17 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_FILE:
- r = glob_extend(&arg_file, optarg);
- if (r < 0)
- return log_error_errno(r, "Failed to add paths: %m");
+ if (streq(optarg, "-"))
+ /* An undocumented feature: we can read journal files from STDIN. We don't document
+ * this though, since after all we only support this for mmap-able, seekable files, and
+ * not for example pipes which are probably the primary usecase for reading things from
+ * STDIN. To avoid confusion we hence don't document this feature. */
+ arg_file_stdin = true;
+ else {
+ r = glob_extend(&arg_file, optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add paths: %m");
+ }
break;
case ARG_ROOT:
@@ -788,6 +793,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_LIST_FIELD_NAMES;
break;
+ case ARG_NO_HOSTNAME:
+ arg_no_hostname = true;
+ break;
+
case 'x':
arg_catalog = true;
break;
@@ -864,6 +873,18 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
+ if (!strv_isempty(arg_system_units) && (arg_journal_type == SD_JOURNAL_CURRENT_USER)) {
+
+ /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
+ * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
+ * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
+ r = strv_extend_strv(&arg_user_units, arg_system_units, true);
+ if (r < 0)
+ return -ENOMEM;
+
+ arg_system_units = strv_free(arg_system_units);
+ }
+
return 1;
}
@@ -988,18 +1009,18 @@ static void boot_id_free_all(BootId *l) {
}
}
-static int discover_next_boot(
- sd_journal *j,
- BootId **boot,
+static int discover_next_boot(sd_journal *j,
+ sd_id128_t previous_boot_id,
bool advance_older,
- bool read_realtime) {
+ BootId **ret) {
- int r;
- char match[9+32+1] = "_BOOT_ID=";
_cleanup_free_ BootId *next_boot = NULL;
+ char match[9+32+1] = "_BOOT_ID=";
+ sd_id128_t boot_id;
+ int r;
assert(j);
- assert(boot);
+ assert(ret);
/* We expect the journal to be on the last position of a boot
* (in relation to the direction we are going), so that the next
@@ -1012,29 +1033,40 @@ static int discover_next_boot(
* we can actually advance to a *different* boot. */
sd_journal_flush_matches(j);
- if (advance_older)
- r = sd_journal_previous(j);
- else
- r = sd_journal_next(j);
- if (r < 0)
- return r;
- else if (r == 0)
- return 0; /* End of journal, yay. */
+ do {
+ if (advance_older)
+ r = sd_journal_previous(j);
+ else
+ r = sd_journal_next(j);
+ if (r < 0)
+ return r;
+ else if (r == 0)
+ return 0; /* End of journal, yay. */
+
+ r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
+ if (r < 0)
+ return r;
+
+ /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
+ * normally, this will only require a single iteration, as we seeked to the last entry of the previous
+ * boot entry already. However, it might happen that the per-journal-field entry arrays are less
+ * complete than the main entry array, and hence might reference an entry that's not actually the last
+ * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
+ * speed things up, but let's not trust that it is complete, and hence, manually advance as
+ * necessary. */
+
+ } while (sd_id128_equal(boot_id, previous_boot_id));
next_boot = new0(BootId, 1);
if (!next_boot)
return -ENOMEM;
- r = sd_journal_get_monotonic_usec(j, NULL, &next_boot->id);
+ next_boot->id = boot_id;
+
+ r = sd_journal_get_realtime_usec(j, &next_boot->first);
if (r < 0)
return r;
- if (read_realtime) {
- r = sd_journal_get_realtime_usec(j, &next_boot->first);
- if (r < 0)
- return r;
- }
-
/* Now seek to the last occurrence of this boot ID. */
sd_id128_to_string(next_boot->id, match + 9);
r = sd_journal_add_match(j, match, sizeof(match) - 1);
@@ -1057,13 +1089,11 @@ static int discover_next_boot(
else if (r == 0)
return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */
- if (read_realtime) {
- r = sd_journal_get_realtime_usec(j, &next_boot->last);
- if (r < 0)
- return r;
- }
+ r = sd_journal_get_realtime_usec(j, &next_boot->last);
+ if (r < 0)
+ return r;
- *boot = next_boot;
+ *ret = next_boot;
next_boot = NULL;
return 0;
@@ -1072,47 +1102,48 @@ static int discover_next_boot(
static int get_boots(
sd_journal *j,
BootId **boots,
- BootId *query_ref_boot,
+ sd_id128_t *query_ref_boot,
int ref_boot_offset) {
bool skip_once;
int r, count = 0;
BootId *head = NULL, *tail = NULL;
const bool advance_older = query_ref_boot && ref_boot_offset <= 0;
+ sd_id128_t previous_boot_id;
assert(j);
/* Adjust for the asymmetry that offset 0 is
* the last (and current) boot, while 1 is considered the
* (chronological) first boot in the journal. */
- skip_once = query_ref_boot && sd_id128_is_null(query_ref_boot->id) && ref_boot_offset < 0;
+ skip_once = query_ref_boot && sd_id128_is_null(*query_ref_boot) && ref_boot_offset < 0;
/* Advance to the earliest/latest occurrence of our reference
* boot ID (taking our lookup direction into account), so that
* discover_next_boot() can do its job.
* If no reference is given, the journal head/tail will do,
* they're "virtual" boots after all. */
- if (query_ref_boot && !sd_id128_is_null(query_ref_boot->id)) {
+ if (query_ref_boot && !sd_id128_is_null(*query_ref_boot)) {
char match[9+32+1] = "_BOOT_ID=";
sd_journal_flush_matches(j);
- sd_id128_to_string(query_ref_boot->id, match + 9);
+ sd_id128_to_string(*query_ref_boot, match + 9);
r = sd_journal_add_match(j, match, sizeof(match) - 1);
if (r < 0)
return r;
if (advance_older)
- r = sd_journal_seek_head(j);
+ r = sd_journal_seek_head(j); /* seek to oldest */
else
- r = sd_journal_seek_tail(j);
+ r = sd_journal_seek_tail(j); /* seek to newest */
if (r < 0)
return r;
if (advance_older)
- r = sd_journal_next(j);
+ r = sd_journal_next(j); /* read the oldest entry */
else
- r = sd_journal_previous(j);
+ r = sd_journal_previous(j); /* read the most recently added entry */
if (r < 0)
return r;
else if (r == 0)
@@ -1121,21 +1152,31 @@ static int get_boots(
count = 1;
goto finish;
}
+
+ /* At this point the read pointer is positioned at the oldest/newest occurence of the reference boot
+ * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
+ * the following entry, which must then have an older/newer boot ID */
} else {
+
if (advance_older)
- r = sd_journal_seek_tail(j);
+ r = sd_journal_seek_tail(j); /* seek to newest */
else
- r = sd_journal_seek_head(j);
+ r = sd_journal_seek_head(j); /* seek to oldest */
if (r < 0)
return r;
- /* No sd_journal_next/previous here. */
+ /* No sd_journal_next()/_previous() here.
+ *
+ * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
+ * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
+ * entry we have. */
}
+ previous_boot_id = SD_ID128_NULL;
for (;;) {
_cleanup_free_ BootId *current = NULL;
- r = discover_next_boot(j, &current, advance_older, !query_ref_boot);
+ r = discover_next_boot(j, previous_boot_id, advance_older, &current);
if (r < 0) {
boot_id_free_all(head);
return r;
@@ -1144,6 +1185,8 @@ static int get_boots(
if (!current)
break;
+ previous_boot_id = current->id;
+
if (query_ref_boot) {
if (!skip_once)
ref_boot_offset += advance_older ? 1 : -1;
@@ -1151,7 +1194,7 @@ static int get_boots(
if (ref_boot_offset == 0) {
count = 1;
- query_ref_boot->id = current->id;
+ *query_ref_boot = current->id;
break;
}
} else {
@@ -1183,7 +1226,7 @@ static int list_boots(sd_journal *j) {
if (count == 0)
return count;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, arg_pager_end);
/* numbers are one less, but we need an extra char for the sign */
w = DECIMAL_STR_WIDTH(count - 1) + 1;
@@ -1207,8 +1250,8 @@ static int list_boots(sd_journal *j) {
static int add_boot(sd_journal *j) {
char match[9+32+1] = "_BOOT_ID=";
+ sd_id128_t ref_boot_id;
int r;
- BootId ref_boot_id = {};
assert(j);
@@ -1218,7 +1261,7 @@ static int add_boot(sd_journal *j) {
if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
return add_match_this_boot(j, arg_machine);
- ref_boot_id.id = arg_boot_id;
+ ref_boot_id = arg_boot_id;
r = get_boots(j, NULL, &ref_boot_id, arg_boot_offset);
assert(r <= 1);
if (r <= 0) {
@@ -1234,7 +1277,7 @@ static int add_boot(sd_journal *j) {
return r == 0 ? -ENODATA : r;
}
- sd_id128_to_string(ref_boot_id.id, match + 9);
+ sd_id128_to_string(ref_boot_id, match + 9);
r = sd_journal_add_match(j, match, sizeof(match) - 1);
if (r < 0)
@@ -1363,7 +1406,7 @@ static int add_units(sd_journal *j) {
r = sd_journal_add_disjunction(j);
if (r < 0)
return r;
- count ++;
+ count++;
}
}
@@ -1383,7 +1426,7 @@ static int add_units(sd_journal *j) {
r = sd_journal_add_disjunction(j);
if (r < 0)
return r;
- count ++;
+ count++;
}
}
@@ -1408,7 +1451,7 @@ static int add_units(sd_journal *j) {
r = sd_journal_add_disjunction(j);
if (r < 0)
return r;
- count ++;
+ count++;
}
}
@@ -1428,7 +1471,7 @@ static int add_units(sd_journal *j) {
r = sd_journal_add_disjunction(j);
if (r < 0)
return r;
- count ++;
+ count++;
}
}
@@ -1847,7 +1890,7 @@ static int access_check(sd_journal *j) {
break;
default:
- log_warning_errno(err, "An error was encountered while opening journal file %s, ignoring file.", path);
+ log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
break;
}
}
@@ -2061,7 +2104,7 @@ int main(int argc, char *argv[]) {
} else {
bool oneline = arg_action == ACTION_LIST_CATALOG;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, arg_pager_end);
if (optind < argc)
r = catalog_list_items(stdout, database, oneline, argv + optind);
@@ -2103,11 +2146,61 @@ int main(int argc, char *argv[]) {
if (arg_directory)
r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
- else if (arg_file)
+ else if (arg_file_stdin) {
+ int ifd = STDIN_FILENO;
+ r = sd_journal_open_files_fd(&j, &ifd, 1, 0);
+ } else if (arg_file)
r = sd_journal_open_files(&j, (const char**) arg_file, 0);
- else if (arg_machine)
- r = sd_journal_open_container(&j, arg_machine, 0);
- else
+ else if (arg_machine) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ int fd;
+
+ if (geteuid() != 0) {
+ /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
+ * the container, thus we need root privileges to override them. */
+ log_error("Using the --machine= switch requires root privileges.");
+ r = -EPERM;
+ goto finish;
+ }
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to open system bus: %m");
+ goto finish;
+ }
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "OpenMachineRootDirectory",
+ &error,
+ &reply,
+ "s", arg_machine);
+ if (r < 0) {
+ log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r));
+ goto finish;
+ }
+
+ r = sd_bus_message_read(reply, "h", &fd);
+ if (r < 0) {
+ bus_log_parse_error(r);
+ goto finish;
+ }
+
+ fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (fd < 0) {
+ r = log_error_errno(errno, "Failed to duplicate file descriptor: %m");
+ goto finish;
+ }
+
+ r = sd_journal_open_directory_fd(&j, fd, SD_JOURNAL_OS_ROOT);
+ if (r < 0)
+ safe_close(fd);
+ } else
r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
if (r < 0) {
log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
@@ -2181,7 +2274,7 @@ int main(int argc, char *argv[]) {
SD_JOURNAL_FOREACH_FIELD(j, field) {
printf("%s\n", field);
- n_shown ++;
+ n_shown++;
}
r = 0;
@@ -2273,7 +2366,7 @@ int main(int argc, char *argv[]) {
else
printf("%.*s\n", (int) size, (const char*) data);
- n_shown ++;
+ n_shown++;
}
r = 0;
@@ -2283,6 +2376,10 @@ int main(int argc, char *argv[]) {
/* Opening the fd now means the first sd_journal_wait() will actually wait */
if (arg_follow) {
r = sd_journal_get_fd(j);
+ if (r == -EMEDIUMTYPE) {
+ log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN.");
+ goto finish;
+ }
if (r < 0) {
log_error_errno(r, "Failed to get journal fd: %m");
goto finish;
@@ -2368,7 +2465,7 @@ int main(int argc, char *argv[]) {
}
if (!arg_follow)
- pager_open_if_enabled();
+ pager_open(arg_no_pager, arg_pager_end);
if (!arg_quiet) {
usec_t start, end;
@@ -2452,7 +2549,8 @@ int main(int argc, char *argv[]) {
arg_full * OUTPUT_FULL_WIDTH |
colors_enabled() * OUTPUT_COLOR |
arg_catalog * OUTPUT_CATALOG |
- arg_utc * OUTPUT_UTC;
+ arg_utc * OUTPUT_UTC |
+ arg_no_hostname * OUTPUT_NO_HOSTNAME;
r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
need_seek = true;
diff --git a/src/grp-journal/libjournal-core/Makefile b/src/grp-journal/libjournal-core/Makefile
new file mode 100644
index 0000000000..d55aebfb49
--- /dev/null
+++ b/src/grp-journal/libjournal-core/Makefile
@@ -0,0 +1,56 @@
+# -*- Mode: makefile; indent-tabs-mode: t -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010-2012 Lennart Poettering
+# Copyright 2010-2012 Kay Sievers
+# Copyright 2013 Zbigniew Jędrzejewski-Szmek
+# Copyright 2013 David Strauss
+# Copyright 2016 Luke Shumaker
+#
+# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
+include $(topsrcdir)/build-aux/Makefile.head.mk
+
+libjournal_core_la_SOURCES = \
+ src/journal/journald-kmsg.c \
+ src/journal/journald-kmsg.h \
+ src/journal/journald-syslog.c \
+ src/journal/journald-syslog.h \
+ src/journal/journald-stream.c \
+ src/journal/journald-stream.h \
+ src/journal/journald-server.c \
+ src/journal/journald-server.h \
+ src/journal/journald-console.c \
+ src/journal/journald-console.h \
+ src/journal/journald-wall.c \
+ src/journal/journald-wall.h \
+ src/journal/journald-native.c \
+ src/journal/journald-native.h \
+ src/journal/journald-audit.c \
+ src/journal/journald-audit.h \
+ src/journal/journald-rate-limit.c \
+ src/journal/journald-rate-limit.h \
+ src/journal/journal-internal.h
+
+nodist_libjournal_core_la_SOURCES = \
+ src/journal/journald-gperf.c
+
+libjournal_core_la_LIBADD = \
+ libshared.la
+
+noinst_LTLIBRARIES += \
+ libjournal-core.la
+
+include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal/cat.c b/src/grp-journal/libjournal-core/cat.c
index 93ab6e7f96..93ab6e7f96 100644
--- a/src/journal/cat.c
+++ b/src/grp-journal/libjournal-core/cat.c
diff --git a/src/journal/journal-qrcode.c b/src/grp-journal/libjournal-core/journal-qrcode.c
index e38730d65c..e38730d65c 100644
--- a/src/journal/journal-qrcode.c
+++ b/src/grp-journal/libjournal-core/journal-qrcode.c
diff --git a/src/journal/journal-qrcode.h b/src/grp-journal/libjournal-core/journal-qrcode.h
index 34a779d5be..34a779d5be 100644
--- a/src/journal/journal-qrcode.h
+++ b/src/grp-journal/libjournal-core/journal-qrcode.h
diff --git a/src/journal/journald-audit.c b/src/grp-journal/libjournal-core/journald-audit.c
index b2eb8a33ef..a433c91c54 100644
--- a/src/journal/journald-audit.c
+++ b/src/grp-journal/libjournal-core/journald-audit.c
@@ -63,7 +63,7 @@ static int map_simple_field(const char *field, const char **p, struct iovec **io
(*iov)[*n_iov].iov_base = c;
(*iov)[*n_iov].iov_len = l;
- (*n_iov) ++;
+ (*n_iov)++;
*p = e;
c = NULL;
@@ -142,7 +142,7 @@ static int map_string_field_internal(const char *field, const char **p, struct i
(*iov)[*n_iov].iov_base = c;
(*iov)[*n_iov].iov_len = l;
- (*n_iov) ++;
+ (*n_iov)++;
*p = e;
c = NULL;
@@ -200,7 +200,7 @@ static int map_generic_field(const char *prefix, const char **p, struct iovec **
}
strcpy(t, "=");
- e ++;
+ e++;
r = map_simple_field(c, &e, iov, n_iov_allocated, n_iov);
if (r < 0)
diff --git a/src/journal/journald-audit.h b/src/grp-journal/libjournal-core/journald-audit.h
index 8c7457778c..8c7457778c 100644
--- a/src/journal/journald-audit.h
+++ b/src/grp-journal/libjournal-core/journald-audit.h
diff --git a/src/journal/journald-console.c b/src/grp-journal/libjournal-core/journald-console.c
index fcc9f25814..fcc9f25814 100644
--- a/src/journal/journald-console.c
+++ b/src/grp-journal/libjournal-core/journald-console.c
diff --git a/src/journal/journald-console.h b/src/grp-journal/libjournal-core/journald-console.h
index dda07e2c28..dda07e2c28 100644
--- a/src/journal/journald-console.h
+++ b/src/grp-journal/libjournal-core/journald-console.h
diff --git a/src/journal/journald-gperf.gperf b/src/grp-journal/libjournal-core/journald-gperf.gperf
index c154610c54..7fecd7a964 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/grp-journal/libjournal-core/journald-gperf.gperf
@@ -19,7 +19,9 @@ Journal.Storage, config_parse_storage, 0, offsetof(Server, storage
Journal.Compress, config_parse_bool, 0, offsetof(Server, compress)
Journal.Seal, config_parse_bool, 0, offsetof(Server, seal)
Journal.SyncIntervalSec, config_parse_sec, 0, offsetof(Server, sync_interval_usec)
+# The following is a legacy name for compatibility
Journal.RateLimitInterval, config_parse_sec, 0, offsetof(Server, rate_limit_interval)
+Journal.RateLimitIntervalSec,config_parse_sec, 0, offsetof(Server, rate_limit_interval)
Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst)
Journal.SystemMaxUse, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_use)
Journal.SystemMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_size)
diff --git a/src/journal/journald-kmsg.c b/src/grp-journal/libjournal-core/journald-kmsg.c
index 1ac57bb361..3712636de2 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/grp-journal/libjournal-core/journald-kmsg.c
@@ -201,7 +201,7 @@ static void dev_kmsg_record(Server *s, const char *p, size_t l) {
if (*k != ' ')
break;
- k ++, l --;
+ k++, l--;
e = memchr(k, '\n', l);
if (!e)
diff --git a/src/journal/journald-kmsg.h b/src/grp-journal/libjournal-core/journald-kmsg.h
index dab49f1e8c..dab49f1e8c 100644
--- a/src/journal/journald-kmsg.h
+++ b/src/grp-journal/libjournal-core/journald-kmsg.h
diff --git a/src/journal/journald-native.c b/src/grp-journal/libjournal-core/journald-native.c
index 3d8f05996b..0a1ce205c2 100644
--- a/src/journal/journald-native.c
+++ b/src/grp-journal/libjournal-core/journald-native.c
@@ -206,7 +206,7 @@ void server_process_native_message(
allow_object_pid(ucred)) {
char buf[DECIMAL_STR_MAX(pid_t)];
memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
- char_array_0(buf);
+ buf[l-strlen("OBJECT_PID=")] = '\0';
/* ignore error */
parse_pid(buf, &object_pid);
@@ -448,24 +448,24 @@ void server_process_native_file(
}
int server_open_native_socket(Server*s) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/socket",
+ };
static const int one = 1;
int r;
assert(s);
if (s->native_fd < 0) {
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/socket",
- };
-
s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->native_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
- unlink(sa.un.sun_path);
+ (void) unlink(sa.un.sun_path);
- r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = bind(s->native_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
diff --git a/src/journal/journald-native.h b/src/grp-journal/libjournal-core/journald-native.h
index c13b80aa4f..c13b80aa4f 100644
--- a/src/journal/journald-native.h
+++ b/src/grp-journal/libjournal-core/journald-native.h
diff --git a/src/journal/journald-rate-limit.c b/src/grp-journal/libjournal-core/journald-rate-limit.c
index 6f6a90fe4e..fce799a6ce 100644
--- a/src/journal/journald-rate-limit.c
+++ b/src/grp-journal/libjournal-core/journald-rate-limit.c
@@ -104,7 +104,7 @@ static void journal_rate_limit_group_free(JournalRateLimitGroup *g) {
LIST_REMOVE(lru, g->parent->lru, g);
LIST_REMOVE(bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
- g->parent->n_groups --;
+ g->parent->n_groups--;
}
free(g->id);
@@ -168,7 +168,7 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
LIST_PREPEND(lru, r->lru, g);
if (!g->lru_next)
r->lru_tail = g;
- r->n_groups ++;
+ r->n_groups++;
g->parent = r;
return g;
diff --git a/src/journal/journald-rate-limit.h b/src/grp-journal/libjournal-core/journald-rate-limit.h
index bb0abb7ee9..bb0abb7ee9 100644
--- a/src/journal/journald-rate-limit.h
+++ b/src/grp-journal/libjournal-core/journald-rate-limit.h
diff --git a/src/journal/journald-server.c b/src/grp-journal/libjournal-core/journald-server.c
index 4f53bf01c3..cc29443e66 100644
--- a/src/journal/journald-server.c
+++ b/src/grp-journal/libjournal-core/journald-server.c
@@ -251,15 +251,15 @@ static int open_journal(
assert(ret);
if (reliably)
- r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
+ r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, s->deferred_closes, NULL, &f);
else
- r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
+ r = journal_file_open(-1, fname, flags, 0640, s->compress, seal, metrics, s->mmap, s->deferred_closes, NULL, &f);
if (r < 0)
return r;
r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
if (r < 0) {
- journal_file_close(f);
+ (void) journal_file_close(f);
return r;
}
@@ -302,7 +302,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
/* Too many open? Then let's close one */
f = ordered_hashmap_steal_first(s->user_journals);
assert(f);
- journal_file_close(f);
+ (void) journal_file_close(f);
}
r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
@@ -313,7 +313,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f);
if (r < 0) {
- journal_file_close(f);
+ (void) journal_file_close(f);
return s->system_journal;
}
@@ -333,7 +333,7 @@ static int do_rotate(
if (!*f)
return -EINVAL;
- r = journal_file_rotate(f, s->compress, seal);
+ r = journal_file_rotate(f, s->compress, seal, s->deferred_closes);
if (r < 0)
if (*f)
log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
@@ -364,6 +364,13 @@ void server_rotate(Server *s) {
/* Old file has been closed and deallocated */
ordered_hashmap_remove(s->user_journals, k);
}
+
+ /* Perform any deferred closes which aren't still offlining. */
+ SET_FOREACH(f, s->deferred_closes, i)
+ if (!journal_file_is_offlining(f)) {
+ (void) set_remove(s->deferred_closes, f);
+ (void) journal_file_close(f);
+ }
}
void server_sync(Server *s) {
@@ -372,13 +379,13 @@ void server_sync(Server *s) {
int r;
if (s->system_journal) {
- r = journal_file_set_offline(s->system_journal);
+ r = journal_file_set_offline(s->system_journal, false);
if (r < 0)
log_warning_errno(r, "Failed to sync system journal, ignoring: %m");
}
ORDERED_HASHMAP_FOREACH(f, s->user_journals, i) {
- r = journal_file_set_offline(f);
+ r = journal_file_set_offline(f, false);
if (r < 0)
log_warning_errno(r, "Failed to sync user journal, ignoring: %m");
}
@@ -485,38 +492,36 @@ static void server_cache_hostname(Server *s) {
}
static bool shall_try_append_again(JournalFile *f, int r) {
-
- /* -E2BIG Hit configured limit
- -EFBIG Hit fs limit
- -EDQUOT Quota limit hit
- -ENOSPC Disk full
- -EIO I/O error of some kind (mmap)
- -EHOSTDOWN Other machine
- -EBUSY Unclean shutdown
- -EPROTONOSUPPORT Unsupported feature
- -EBADMSG Corrupted
- -ENODATA Truncated
- -ESHUTDOWN Already archived
- -EIDRM Journal file has been deleted */
-
- if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
+ switch(r) {
+ case -E2BIG: /* Hit configured limit */
+ case -EFBIG: /* Hit fs limit */
+ case -EDQUOT: /* Quota limit hit */
+ case -ENOSPC: /* Disk full */
log_debug("%s: Allocation limit reached, rotating.", f->path);
- else if (r == -EHOSTDOWN)
+ return true;
+ case -EIO: /* I/O error of some kind (mmap) */
+ log_warning("%s: IO error, rotating.", f->path);
+ return true;
+ case -EHOSTDOWN: /* Other machine */
log_info("%s: Journal file from other machine, rotating.", f->path);
- else if (r == -EBUSY)
+ return true;
+ case -EBUSY: /* Unclean shutdown */
log_info("%s: Unclean shutdown, rotating.", f->path);
- else if (r == -EPROTONOSUPPORT)
+ return true;
+ case -EPROTONOSUPPORT: /* Unsupported feature */
log_info("%s: Unsupported feature, rotating.", f->path);
- else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
+ return true;
+ case -EBADMSG: /* Corrupted */
+ case -ENODATA: /* Truncated */
+ case -ESHUTDOWN: /* Already archived */
log_warning("%s: Journal file corrupted, rotating.", f->path);
- else if (r == -EIO)
- log_warning("%s: IO error, rotating.", f->path);
- else if (r == -EIDRM)
+ return true;
+ case -EIDRM: /* Journal file has been deleted */
log_warning("%s: Journal file has been deleted, rotating.", f->path);
- else
+ return true;
+ default:
return false;
-
- return true;
+ }
}
static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n, int priority) {
@@ -1400,7 +1405,7 @@ static int server_parse_proc_cmdline(Server *s) {
}
p = line;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, NULL, 0);
@@ -1655,7 +1660,7 @@ static int server_connect_notify(Server *s) {
it. Specifically: given that PID 1 might block on
dbus-daemon during IPC, and dbus-daemon is logging to us,
and might hence block on us, we might end up in a deadlock
- if we block on sending PID 1 notification messages -- by
+ if we block on sending PID 1 notification messages — by
generating a full blocking circle. To avoid this, let's
create a non-blocking socket, and connect it to the
notification socket, and then wait for POLLOUT before we
@@ -1691,7 +1696,7 @@ static int server_connect_notify(Server *s) {
if (sa.un.sun_path[0] == '@')
sa.un.sun_path[0] = 0;
- r = connect(s->notify_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(e));
+ r = connect(s->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "Failed to connect to notify socket: %m");
@@ -1765,6 +1770,10 @@ int server_init(Server *s) {
if (!s->mmap)
return log_oom();
+ s->deferred_closes = set_new(NULL);
+ if (!s->deferred_closes)
+ return log_oom();
+
r = sd_event_default(&s->event);
if (r < 0)
return log_error_errno(r, "Failed to create event loop: %m");
@@ -1918,17 +1927,22 @@ void server_done(Server *s) {
JournalFile *f;
assert(s);
+ if (s->deferred_closes) {
+ journal_file_close_set(s->deferred_closes);
+ set_free(s->deferred_closes);
+ }
+
while (s->stdout_streams)
stdout_stream_free(s->stdout_streams);
if (s->system_journal)
- journal_file_close(s->system_journal);
+ (void) journal_file_close(s->system_journal);
if (s->runtime_journal)
- journal_file_close(s->runtime_journal);
+ (void) journal_file_close(s->runtime_journal);
while ((f = ordered_hashmap_steal_first(s->user_journals)))
- journal_file_close(f);
+ (void) journal_file_close(f);
ordered_hashmap_free(s->user_journals);
diff --git a/src/journal/journald-server.h b/src/grp-journal/libjournal-core/journald-server.h
index cb8a5bbe9b..bebb056aa7 100644
--- a/src/journal/journald-server.h
+++ b/src/grp-journal/libjournal-core/journald-server.h
@@ -130,6 +130,8 @@ struct Server {
MMapCache *mmap;
+ Set *deferred_closes;
+
struct udev *udev;
uint64_t *kernel_seqnum;
diff --git a/src/journal/journald-stream.c b/src/grp-journal/libjournal-core/journald-stream.c
index 583b1305ae..99d856301c 100644
--- a/src/journal/journald-stream.c
+++ b/src/grp-journal/libjournal-core/journald-stream.c
@@ -96,7 +96,7 @@ void stdout_stream_free(StdoutStream *s) {
if (s->server) {
assert(s->server->n_stdout_streams > 0);
- s->server->n_stdout_streams --;
+ s->server->n_stdout_streams--;
LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
if (s->in_notify_queue)
@@ -511,7 +511,7 @@ static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
stream->server = s;
LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
- s->n_stdout_streams ++;
+ s->n_stdout_streams++;
if (ret)
*ret = stream;
@@ -700,23 +700,22 @@ fail:
}
int server_open_stdout_socket(Server *s) {
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/stdout",
+ };
int r;
assert(s);
if (s->stdout_fd < 0) {
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/stdout",
- };
-
s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->stdout_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
- unlink(sa.un.sun_path);
+ (void) unlink(sa.un.sun_path);
- r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
diff --git a/src/journal/journald-stream.h b/src/grp-journal/libjournal-core/journald-stream.h
index db4c67fae3..db4c67fae3 100644
--- a/src/journal/journald-stream.h
+++ b/src/grp-journal/libjournal-core/journald-stream.h
diff --git a/src/journal/journald-syslog.c b/src/grp-journal/libjournal-core/journald-syslog.c
index 480a1cc405..86fe81d179 100644
--- a/src/journal/journald-syslog.c
+++ b/src/grp-journal/libjournal-core/journald-syslog.c
@@ -52,8 +52,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
.msg_iov = (struct iovec *) iovec,
.msg_iovlen = n_iovec,
.msg_name = (struct sockaddr*) &sa.sa,
- .msg_namelen = offsetof(union sockaddr_union, un.sun_path)
- + strlen("/run/systemd/journal/syslog"),
+ .msg_namelen = SOCKADDR_UN_LEN(sa.un),
};
struct cmsghdr *cmsg;
union {
@@ -316,12 +315,12 @@ static void syslog_skip_date(char **buf) {
}
void server_process_syslog_message(
- Server *s,
- const char *buf,
- const struct ucred *ucred,
- const struct timeval *tv,
- const char *label,
- size_t label_len) {
+ Server *s,
+ const char *buf,
+ const struct ucred *ucred,
+ const struct timeval *tv,
+ const char *label,
+ size_t label_len) {
char syslog_priority[sizeof("PRIORITY=") + DECIMAL_STR_MAX(int)],
syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
@@ -365,14 +364,12 @@ void server_process_syslog_message(
if (identifier) {
syslog_identifier = strjoina("SYSLOG_IDENTIFIER=", identifier);
- if (syslog_identifier)
- IOVEC_SET_STRING(iovec[n++], syslog_identifier);
+ IOVEC_SET_STRING(iovec[n++], syslog_identifier);
}
if (pid) {
syslog_pid = strjoina("SYSLOG_PID=", pid);
- if (syslog_pid)
- IOVEC_SET_STRING(iovec[n++], syslog_pid);
+ IOVEC_SET_STRING(iovec[n++], syslog_pid);
}
message = strjoina("MESSAGE=", buf);
@@ -383,24 +380,24 @@ void server_process_syslog_message(
}
int server_open_syslog_socket(Server *s) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/dev-log",
+ };
static const int one = 1;
int r;
assert(s);
if (s->syslog_fd < 0) {
- static const union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/dev-log",
- };
-
s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->syslog_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
- unlink(sa.un.sun_path);
+ (void) unlink(sa.un.sun_path);
- r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = bind(s->syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
@@ -437,6 +434,7 @@ int server_open_syslog_socket(Server *s) {
void server_maybe_warn_forward_syslog_missed(Server *s) {
usec_t n;
+
assert(s);
if (s->n_forward_syslog_missed <= 0)
diff --git a/src/journal/journald-syslog.h b/src/grp-journal/libjournal-core/journald-syslog.h
index 46ad715314..46ad715314 100644
--- a/src/journal/journald-syslog.h
+++ b/src/grp-journal/libjournal-core/journald-syslog.h
diff --git a/src/journal/journald-wall.c b/src/grp-journal/libjournal-core/journald-wall.c
index 4d91fafffe..4d91fafffe 100644
--- a/src/journal/journald-wall.c
+++ b/src/grp-journal/libjournal-core/journald-wall.c
diff --git a/src/journal/journald-wall.h b/src/grp-journal/libjournal-core/journald-wall.h
index ebc2b89fa8..ebc2b89fa8 100644
--- a/src/journal/journald-wall.h
+++ b/src/grp-journal/libjournal-core/journald-wall.h
diff --git a/src/journal/journald.conf b/src/grp-journal/libjournal-core/journald.conf
index 7beb96c671..2541b949be 100644
--- a/src/journal/journald.conf
+++ b/src/grp-journal/libjournal-core/journald.conf
@@ -17,7 +17,7 @@
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
-#RateLimitInterval=30s
+#RateLimitIntervalSec=30s
#RateLimitBurst=1000
#SystemMaxUse=
#SystemKeepFree=
diff --git a/src/journal/test-audit-type.c b/src/grp-journal/libjournal-core/test-audit-type.c
index 88a2e6d9d9..88a2e6d9d9 100644
--- a/src/journal/test-audit-type.c
+++ b/src/grp-journal/libjournal-core/test-audit-type.c
diff --git a/src/journal/test-catalog.c b/src/grp-journal/libjournal-core/test-catalog.c
index 6f2f9f5561..f939fcdc2a 100644
--- a/src/journal/test-catalog.c
+++ b/src/grp-journal/libjournal-core/test-catalog.c
@@ -103,6 +103,8 @@ static void test_catalog_import_one(void) {
assert_se(hashmap_size(h) == 1);
HASHMAP_FOREACH(payload, h, j) {
+ printf("expect: %s\n", expect);
+ printf("actual: %s\n", payload);
assert_se(streq(expect, payload));
}
}
diff --git a/src/journal/test-compress-benchmark.c b/src/grp-journal/libjournal-core/test-compress-benchmark.c
index 5b2d130cd6..6f6d71435d 100644
--- a/src/journal/test-compress-benchmark.c
+++ b/src/grp-journal/libjournal-core/test-compress-benchmark.c
@@ -105,6 +105,8 @@ static void test_compress_decompress(const char* label, const char* type,
int r;
size = permute(i);
+ if (size == 0)
+ continue;
log_debug("%s %zu %zu", type, i, size);
@@ -162,7 +164,7 @@ int main(int argc, char *argv[]) {
arg_duration = x * USEC_PER_SEC;
}
if (argc == 3)
- (void) safe_atolu(argv[2], &arg_start);
+ (void) safe_atozu(argv[2], &arg_start);
else
arg_start = getpid();
diff --git a/src/journal/test-compress.c b/src/grp-journal/libjournal-core/test-compress.c
index 68c9a4d76c..68c9a4d76c 100644
--- a/src/journal/test-compress.c
+++ b/src/grp-journal/libjournal-core/test-compress.c
diff --git a/src/journal/test-journal-enum.c b/src/grp-journal/libjournal-core/test-journal-enum.c
index ffdc317e1d..54df59f477 100644
--- a/src/journal/test-journal-enum.c
+++ b/src/grp-journal/libjournal-core/test-journal-enum.c
@@ -44,7 +44,7 @@ int main(int argc, char *argv[]) {
printf("%.*s\n", (int) l, (char*) d);
- n ++;
+ n++;
if (n >= 10)
break;
}
diff --git a/src/journal/test-journal-flush.c b/src/grp-journal/libjournal-core/test-journal-flush.c
index 3dee462e74..7e9814f8fa 100644
--- a/src/journal/test-journal-flush.c
+++ b/src/grp-journal/libjournal-core/test-journal-flush.c
@@ -38,7 +38,7 @@ int main(int argc, char *argv[]) {
assert_se(mkdtemp(dn));
fn = strappend(dn, "/test.journal");
- r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, &new_journal);
+ r = journal_file_open(-1, fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, NULL, &new_journal);
assert_se(r >= 0);
r = sd_journal_open(&j, 0);
@@ -66,7 +66,7 @@ int main(int argc, char *argv[]) {
sd_journal_close(j);
- journal_file_close(new_journal);
+ (void) journal_file_close(new_journal);
unlink(fn);
assert_se(rmdir(dn) == 0);
diff --git a/src/journal/test-journal-init.c b/src/grp-journal/libjournal-core/test-journal-init.c
index e6713034dd..e6713034dd 100644
--- a/src/journal/test-journal-init.c
+++ b/src/grp-journal/libjournal-core/test-journal-init.c
diff --git a/src/journal/test-journal-interleaving.c b/src/grp-journal/libjournal-core/test-journal-interleaving.c
index b47182dbfd..d09ef011a6 100644
--- a/src/journal/test-journal-interleaving.c
+++ b/src/grp-journal/libjournal-core/test-journal-interleaving.c
@@ -52,12 +52,12 @@ noreturn static void log_assert_errno(const char *text, int eno, const char *fil
static JournalFile *test_open(const char *name) {
JournalFile *f;
- assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0644, true, false, NULL, NULL, NULL, &f));
+ assert_ret(journal_file_open(-1, name, O_RDWR|O_CREAT, 0644, true, false, NULL, NULL, NULL, NULL, &f));
return f;
}
static void test_close(JournalFile *f) {
- journal_file_close (f);
+ (void) journal_file_close (f);
}
static void append_number(JournalFile *f, int n, uint64_t *seqnum) {
@@ -216,8 +216,8 @@ static void test_sequence_numbers(void) {
assert_se(mkdtemp(t));
assert_se(chdir(t) >= 0);
- assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0644,
- true, false, NULL, NULL, NULL, &one) == 0);
+ assert_se(journal_file_open(-1, "one.journal", O_RDWR|O_CREAT, 0644,
+ true, false, NULL, NULL, NULL, NULL, &one) == 0);
append_number(one, 1, &seqnum);
printf("seqnum=%"PRIu64"\n", seqnum);
@@ -233,8 +233,8 @@ static void test_sequence_numbers(void) {
memcpy(&seqnum_id, &one->header->seqnum_id, sizeof(sd_id128_t));
- assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0644,
- true, false, NULL, NULL, one, &two) == 0);
+ assert_se(journal_file_open(-1, "two.journal", O_RDWR|O_CREAT, 0644,
+ true, false, NULL, NULL, NULL, one, &two) == 0);
assert_se(two->header->state == STATE_ONLINE);
assert_se(!sd_id128_equal(two->header->file_id, one->header->file_id));
@@ -264,8 +264,8 @@ static void test_sequence_numbers(void) {
/* restart server */
seqnum = 0;
- assert_se(journal_file_open("two.journal", O_RDWR, 0,
- true, false, NULL, NULL, NULL, &two) == 0);
+ assert_se(journal_file_open(-1, "two.journal", O_RDWR, 0,
+ true, false, NULL, NULL, NULL, NULL, &two) == 0);
assert_se(sd_id128_equal(two->header->seqnum_id, seqnum_id));
diff --git a/src/journal/test-journal-match.c b/src/grp-journal/libjournal-core/test-journal-match.c
index 5ee2adb827..5ee2adb827 100644
--- a/src/journal/test-journal-match.c
+++ b/src/grp-journal/libjournal-core/test-journal-match.c
diff --git a/src/journal/test-journal-send.c b/src/grp-journal/libjournal-core/test-journal-send.c
index 169082f9a4..169082f9a4 100644
--- a/src/journal/test-journal-send.c
+++ b/src/grp-journal/libjournal-core/test-journal-send.c
diff --git a/src/journal/test-journal-stream.c b/src/grp-journal/libjournal-core/test-journal-stream.c
index 57c6c0872d..0a1da47861 100644
--- a/src/journal/test-journal-stream.c
+++ b/src/grp-journal/libjournal-core/test-journal-stream.c
@@ -92,9 +92,9 @@ int main(int argc, char *argv[]) {
assert_se(mkdtemp(t));
assert_se(chdir(t) >= 0);
- assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &one) == 0);
- assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &two) == 0);
- assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &three) == 0);
+ assert_se(journal_file_open(-1, "one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &one) == 0);
+ assert_se(journal_file_open(-1, "two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &two) == 0);
+ assert_se(journal_file_open(-1, "three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &three) == 0);
for (i = 0; i < N_ENTRIES; i++) {
char *p, *q;
@@ -133,9 +133,9 @@ int main(int argc, char *argv[]) {
free(q);
}
- journal_file_close(one);
- journal_file_close(two);
- journal_file_close(three);
+ (void) journal_file_close(one);
+ (void) journal_file_close(two);
+ (void) journal_file_close(three);
assert_se(sd_journal_open_directory(&j, t, 0) >= 0);
diff --git a/src/journal/test-journal-syslog.c b/src/grp-journal/libjournal-core/test-journal-syslog.c
index 4ff7f3ec2e..4ff7f3ec2e 100644
--- a/src/journal/test-journal-syslog.c
+++ b/src/grp-journal/libjournal-core/test-journal-syslog.c
diff --git a/src/journal/test-journal-verify.c b/src/grp-journal/libjournal-core/test-journal-verify.c
index a26c624f41..3d2312fc55 100644
--- a/src/journal/test-journal-verify.c
+++ b/src/grp-journal/libjournal-core/test-journal-verify.c
@@ -55,12 +55,12 @@ static int raw_verify(const char *fn, const char *verification_key) {
JournalFile *f;
int r;
- r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
+ r = journal_file_open(-1, fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f);
if (r < 0)
return r;
r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
- journal_file_close(f);
+ (void) journal_file_close(f);
return r;
}
@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
log_info("Generating...");
- assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
+ assert_se(journal_file_open(-1, "test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
for (n = 0; n < N_ENTRIES; n++) {
struct iovec iovec;
@@ -107,11 +107,11 @@ int main(int argc, char *argv[]) {
free(test);
}
- journal_file_close(f);
+ (void) journal_file_close(f);
log_info("Verifying...");
- assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
+ assert_se(journal_file_open(-1, "test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
/* journal_file_print_header(f); */
journal_file_dump(f);
@@ -123,7 +123,7 @@ int main(int argc, char *argv[]) {
format_timestamp(b, sizeof(b), to),
format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
- journal_file_close(f);
+ (void) journal_file_close(f);
if (verification_key) {
log_info("Toggling bits...");
diff --git a/src/journal/test-journal.c b/src/grp-journal/libjournal-core/test-journal.c
index 0334b1cd1a..2543d64b5b 100644
--- a/src/journal/test-journal.c
+++ b/src/grp-journal/libjournal-core/test-journal.c
@@ -42,7 +42,7 @@ static void test_non_empty(void) {
assert_se(mkdtemp(t));
assert_se(chdir(t) >= 0);
- assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f) == 0);
+ assert_se(journal_file_open(-1, "test.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, NULL, &f) == 0);
dual_timestamp_get(&ts);
@@ -104,10 +104,10 @@ static void test_non_empty(void) {
assert_se(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);
- journal_file_rotate(&f, true, true);
- journal_file_rotate(&f, true, true);
+ journal_file_rotate(&f, true, true, NULL);
+ journal_file_rotate(&f, true, true, NULL);
- journal_file_close(f);
+ (void) journal_file_close(f);
log_info("Done...");
@@ -131,13 +131,13 @@ static void test_empty(void) {
assert_se(mkdtemp(t));
assert_se(chdir(t) >= 0);
- assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, false, false, NULL, NULL, NULL, &f1) == 0);
+ assert_se(journal_file_open(-1, "test.journal", O_RDWR|O_CREAT, 0666, false, false, NULL, NULL, NULL, NULL, &f1) == 0);
- assert_se(journal_file_open("test-compress.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &f2) == 0);
+ assert_se(journal_file_open(-1, "test-compress.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &f2) == 0);
- assert_se(journal_file_open("test-seal.journal", O_RDWR|O_CREAT, 0666, false, true, NULL, NULL, NULL, &f3) == 0);
+ assert_se(journal_file_open(-1, "test-seal.journal", O_RDWR|O_CREAT, 0666, false, true, NULL, NULL, NULL, NULL, &f3) == 0);
- assert_se(journal_file_open("test-seal-compress.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f4) == 0);
+ assert_se(journal_file_open(-1, "test-seal-compress.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, NULL, &f4) == 0);
journal_file_print_header(f1);
puts("");
@@ -158,10 +158,10 @@ static void test_empty(void) {
assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}
- journal_file_close(f1);
- journal_file_close(f2);
- journal_file_close(f3);
- journal_file_close(f4);
+ (void) journal_file_close(f1);
+ (void) journal_file_close(f2);
+ (void) journal_file_close(f3);
+ (void) journal_file_close(f4);
}
int main(int argc, char *argv[]) {
diff --git a/src/journal/test-mmap-cache.c b/src/grp-journal/libjournal-core/test-mmap-cache.c
index 009aabf55e..009aabf55e 100644
--- a/src/journal/test-mmap-cache.c
+++ b/src/grp-journal/libjournal-core/test-mmap-cache.c
diff --git a/src/grp-journal/systemd-journald/Makefile b/src/grp-journal/systemd-journald/Makefile
new file mode 100644
index 0000000000..53046d1ce3
--- /dev/null
+++ b/src/grp-journal/systemd-journald/Makefile
@@ -0,0 +1,94 @@
+# -*- Mode: makefile; indent-tabs-mode: t -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010-2012 Lennart Poettering
+# Copyright 2010-2012 Kay Sievers
+# Copyright 2013 Zbigniew Jędrzejewski-Szmek
+# Copyright 2013 David Strauss
+# Copyright 2016 Luke Shumaker
+#
+# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
+include $(topsrcdir)/build-aux/Makefile.head.mk
+
+systemd_journald_SOURCES = \
+ src/journal/journald.c \
+ src/journal/journald-server.h
+
+systemd_journald_LDADD = \
+ libjournal-core.la \
+ libshared.la
+
+systemd_cat_SOURCES = \
+ src/journal/cat.c
+
+systemd_cat_LDADD = \
+ libjournal-core.la
+
+
+libexec_PROGRAMS += \
+ systemd-journald
+
+bin_PROGRAMS += \
+ journalctl
+
+bin_PROGRAMS += \
+ systemd-cat
+
+dist_systemunit_DATA += \
+ units/systemd-journald.socket \
+ units/systemd-journald-dev-log.socket \
+ units/systemd-journald-audit.socket
+
+nodist_systemunit_DATA += \
+ units/systemd-journald.service \
+ units/systemd-journal-flush.service \
+ units/systemd-journal-catalog-update.service
+
+dist_pkgsysconf_DATA += \
+ src/journal/journald.conf
+
+dist_catalog_DATA = \
+ catalog/systemd.bg.catalog \
+ catalog/systemd.be.catalog \
+ catalog/systemd.be@latin.catalog \
+ catalog/systemd.fr.catalog \
+ catalog/systemd.it.catalog \
+ catalog/systemd.pl.catalog \
+ catalog/systemd.pt_BR.catalog \
+ catalog/systemd.ru.catalog \
+ catalog/systemd.zh_CN.catalog \
+ catalog/systemd.zh_TW.catalog \
+ catalog/systemd.catalog
+
+SOCKETS_TARGET_WANTS += \
+ systemd-journald.socket \
+ systemd-journald-dev-log.socket \
+ systemd-journald-audit.socket
+
+SYSINIT_TARGET_WANTS += \
+ systemd-journald.service \
+ systemd-journal-flush.service \
+ systemd-journal-catalog-update.service
+
+EXTRA_DIST += \
+ units/systemd-journald.service.in \
+ units/systemd-journal-flush.service.in \
+ units/systemd-journal-catalog-update.service.in
+
+gperf_gperf_sources += \
+ src/journal/journald-gperf.gperf
+
+include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/journal/journald.c b/src/grp-journal/systemd-journald/journald.c
index 1afe44fa8e..1afe44fa8e 100644
--- a/src/journal/journald.c
+++ b/src/grp-journal/systemd-journald/journald.c
diff --git a/src/grp-machine/libmachine-core/Makefile b/src/grp-machine/libmachine-core/Makefile
index de95c44f8e..884d4e74df 100644
--- a/src/grp-machine/libmachine-core/Makefile
+++ b/src/grp-machine/libmachine-core/Makefile
@@ -30,7 +30,9 @@ libmachine_core_la_SOURCES = \
src/machine/machine-dbus.c \
src/machine/machine-dbus.h \
src/machine/image-dbus.c \
- src/machine/image-dbus.h
+ src/machine/image-dbus.h \
+ src/machine/operation.c \
+ src/machine/operation.h
libmachine_core_la_LIBADD = \
libshared.la
diff --git a/src/grp-machine/libmachine-core/image-dbus.c b/src/grp-machine/libmachine-core/image-dbus.c
index 73f5112c4d..0eed9b81bb 100644
--- a/src/grp-machine/libmachine-core/image-dbus.c
+++ b/src/grp-machine/libmachine-core/image-dbus.c
@@ -20,9 +20,11 @@
#include "alloc-util.h"
#include "bus-label.h"
#include "bus-util.h"
+#include "fd-util.h"
#include "image-dbus.h"
#include "io-util.h"
#include "machine-image.h"
+#include "process-util.h"
#include "strv.h"
#include "user-util.h"
@@ -33,13 +35,18 @@ int bus_image_method_remove(
void *userdata,
sd_bus_error *error) {
+ _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
Image *image = userdata;
Manager *m = image->userdata;
+ pid_t child;
int r;
assert(message);
assert(image);
+ if (m->n_operations >= OPERATIONS_MAX)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
+
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
@@ -54,11 +61,35 @@ int bus_image_method_remove(
if (r == 0)
return 1; /* Will call us back */
- r = image_remove(image);
- if (r < 0)
+ if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
+
+ child = fork();
+ if (child < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
+ if (child == 0) {
+ errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
+
+ r = image_remove(image);
+ if (r < 0) {
+ (void) write(errno_pipe_fd[1], &r, sizeof(r));
+ _exit(EXIT_FAILURE);
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
+
+ r = operation_new(m, NULL, child, message, errno_pipe_fd[0]);
+ if (r < 0) {
+ (void) sigkill_wait(child);
return r;
+ }
- return sd_bus_reply_method_return(message, NULL);
+ errno_pipe_fd[0] = -1;
+
+ return 1;
}
int bus_image_method_rename(
@@ -107,13 +138,19 @@ int bus_image_method_clone(
void *userdata,
sd_bus_error *error) {
+ _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
Image *image = userdata;
Manager *m = image->userdata;
const char *new_name;
int r, read_only;
+ pid_t child;
assert(message);
assert(image);
+ assert(m);
+
+ if (m->n_operations >= OPERATIONS_MAX)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
r = sd_bus_message_read(message, "sb", &new_name, &read_only);
if (r < 0)
@@ -136,11 +173,35 @@ int bus_image_method_clone(
if (r == 0)
return 1; /* Will call us back */
- r = image_clone(image, new_name, read_only);
- if (r < 0)
+ if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
+
+ child = fork();
+ if (child < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
+ if (child == 0) {
+ errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
+
+ r = image_clone(image, new_name, read_only);
+ if (r < 0) {
+ (void) write(errno_pipe_fd[1], &r, sizeof(r));
+ _exit(EXIT_FAILURE);
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
+
+ r = operation_new(m, NULL, child, message, errno_pipe_fd[0]);
+ if (r < 0) {
+ (void) sigkill_wait(child);
return r;
+ }
- return sd_bus_reply_method_return(message, NULL);
+ errno_pipe_fd[0] = -1;
+
+ return 1;
}
int bus_image_method_mark_read_only(
diff --git a/src/grp-machine/libmachine-core/machine-dbus.c b/src/grp-machine/libmachine-core/machine-dbus.c
index 71f20b3f07..7b9aa66d63 100644
--- a/src/grp-machine/libmachine-core/machine-dbus.c
+++ b/src/grp-machine/libmachine-core/machine-dbus.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <string.h>
#include <sys/mount.h>
+#include <sys/wait.h>
/* When we include libgen.h because we need dirname() we immediately
* undefine basename() since libgen.h defines it as a macro to the POSIX
@@ -45,6 +46,7 @@
#include "mkdir.h"
#include "path-util.h"
#include "process-util.h"
+#include "signal-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "user-util.h"
@@ -165,7 +167,7 @@ int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
}
- if (signo <= 0 || signo >= _NSIG)
+ if (!SIGNAL_VALID(signo))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
r = bus_verify_polkit_async(
@@ -728,7 +730,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
return r;
/* Name and mode */
- unit = strjoina("container-shell@", p, ".service", NULL);
+ unit = strjoina("container-shell@", p, ".service");
r = sd_bus_message_append(tm, "ss", unit, "fail");
if (r < 0)
return r;
@@ -1083,52 +1085,11 @@ finish:
return r;
}
-static int machine_operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- MachineOperation *o = userdata;
- int r;
-
- assert(o);
- assert(si);
-
- o->pid = 0;
-
- if (si->si_code != CLD_EXITED) {
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
- goto fail;
- }
-
- if (si->si_status != EXIT_SUCCESS) {
- if (read(o->errno_fd, &r, sizeof(r)) == sizeof(r))
- r = sd_bus_error_set_errnof(&error, r, "%m");
- else
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child failed.");
-
- goto fail;
- }
-
- r = sd_bus_reply_method_return(o->message, NULL);
- if (r < 0)
- log_error_errno(r, "Failed to reply to message: %m");
-
- machine_operation_unref(o);
- return 0;
-
-fail:
- r = sd_bus_reply_method_error(o->message, &error);
- if (r < 0)
- log_error_errno(r, "Failed to reply to message: %m");
-
- machine_operation_unref(o);
- return 0;
-}
-
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname;
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
_cleanup_close_ int hostfd = -1;
Machine *m = userdata;
- MachineOperation *o;
bool copy_from;
pid_t child;
char *t;
@@ -1137,7 +1098,7 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
assert(message);
assert(m);
- if (m->n_operations >= MACHINE_OPERATIONS_MAX)
+ if (m->manager->n_operations >= OPERATIONS_MAX)
return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing copies.");
if (m->class != MACHINE_CONTAINER)
@@ -1247,29 +1208,107 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- /* Copying might take a while, hence install a watch the
- * child, and return */
+ /* Copying might take a while, hence install a watch on the child, and return */
- o = new0(MachineOperation, 1);
- if (!o)
- return log_oom();
-
- o->pid = child;
- o->message = sd_bus_message_ref(message);
- o->errno_fd = errno_pipe_fd[0];
+ r = operation_new(m->manager, m, child, message, errno_pipe_fd[0]);
+ if (r < 0) {
+ (void) sigkill_wait(child);
+ return r;
+ }
errno_pipe_fd[0] = -1;
- r = sd_event_add_child(m->manager->event, &o->event_source, child, WEXITED, machine_operation_done, o);
- if (r < 0) {
- machine_operation_unref(o);
- return log_oom();
+ return 1;
+}
+
+int bus_machine_method_open_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_close_ int fd = -1;
+ Machine *m = userdata;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = bus_verify_polkit_async(
+ message,
+ CAP_SYS_ADMIN,
+ "org.freedesktop.machine1.manage-machines",
+ NULL,
+ false,
+ UID_INVALID,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+
+ switch (m->class) {
+
+ case MACHINE_HOST:
+ fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+ if (fd < 0)
+ return -errno;
+
+ break;
+
+ case MACHINE_CONTAINER: {
+ _cleanup_close_ int mntns_fd = -1, root_fd = -1;
+ _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ siginfo_t si;
+ pid_t child;
+
+ r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
+ if (r < 0)
+ return r;
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
+ return -errno;
+
+ child = fork();
+ if (child < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
+
+ if (child == 0) {
+ _cleanup_close_ int dfd = -1;
+
+ pair[0] = safe_close(pair[0]);
+
+ r = namespace_enter(-1, mntns_fd, -1, -1, root_fd);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ dfd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+ if (dfd < 0)
+ _exit(EXIT_FAILURE);
+
+ r = send_one_fd(pair[1], dfd, 0);
+ dfd = safe_close(dfd);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ pair[1] = safe_close(pair[1]);
+
+ r = wait_for_terminate(child, &si);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
+ if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
+
+ fd = receive_one_fd(pair[0], MSG_DONTWAIT);
+ if (fd < 0)
+ return fd;
+
+ break;
}
- LIST_PREPEND(operations, m->operations, o);
- m->n_operations++;
- o->machine = m;
+ default:
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Opening the root directory is only supported on container machines.");
+ }
- return 1;
+ return sd_bus_reply_method_return(message, "h", fd);
}
const sd_bus_vtable machine_vtable[] = {
@@ -1295,6 +1334,7 @@ const sd_bus_vtable machine_vtable[] = {
SD_BUS_METHOD("BindMount", "ssbb", NULL, bus_machine_method_bind_mount, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyFrom", "ss", NULL, bus_machine_method_copy, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyTo", "ss", NULL, bus_machine_method_copy, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("OpenRootDirectory", NULL, "h", bus_machine_method_open_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
diff --git a/src/grp-machine/libmachine-core/machine-dbus.h b/src/grp-machine/libmachine-core/machine-dbus.h
index 224f36529f..d3faf5cb07 100644
--- a/src/grp-machine/libmachine-core/machine-dbus.h
+++ b/src/grp-machine/libmachine-core/machine-dbus.h
@@ -38,6 +38,7 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_machine_method_open_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error);
int machine_send_signal(Machine *m, bool new_machine);
int machine_send_create_reply(Machine *m, sd_bus_error *error);
diff --git a/src/grp-machine/libmachine-core/machine.c b/src/grp-machine/libmachine-core/machine.c
index 468fc1fecf..135f47dafc 100644
--- a/src/grp-machine/libmachine-core/machine.c
+++ b/src/grp-machine/libmachine-core/machine.c
@@ -89,7 +89,7 @@ void machine_free(Machine *m) {
assert(m);
while (m->operations)
- machine_operation_unref(m->operations);
+ operation_free(m->operations);
if (m->in_gc_queue)
LIST_REMOVE(gc_queue, m->manager->machine_gc_queue, m);
@@ -299,17 +299,10 @@ int machine_load(Machine *m) {
m->class = c;
}
- if (realtime) {
- unsigned long long l;
- if (sscanf(realtime, "%llu", &l) > 0)
- m->timestamp.realtime = l;
- }
-
- if (monotonic) {
- unsigned long long l;
- if (sscanf(monotonic, "%llu", &l) > 0)
- m->timestamp.monotonic = l;
- }
+ if (realtime)
+ timestamp_deserialize(realtime, &m->timestamp.realtime);
+ if (monotonic)
+ timestamp_deserialize(monotonic, &m->timestamp.monotonic);
if (netif) {
size_t allocated = 0, nr = 0;
@@ -317,7 +310,7 @@ int machine_load(Machine *m) {
int *ni = NULL;
p = netif;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *word = NULL;
int ifi;
@@ -603,28 +596,6 @@ int machine_open_terminal(Machine *m, const char *path, int mode) {
}
}
-MachineOperation *machine_operation_unref(MachineOperation *o) {
- if (!o)
- return NULL;
-
- sd_event_source_unref(o->event_source);
-
- safe_close(o->errno_fd);
-
- if (o->pid > 1)
- (void) kill(o->pid, SIGKILL);
-
- sd_bus_message_unref(o->message);
-
- if (o->machine) {
- LIST_REMOVE(operations, o->machine->operations, o);
- o->machine->n_operations--;
- }
-
- free(o);
- return NULL;
-}
-
void machine_release_unit(Machine *m) {
assert(m);
diff --git a/src/grp-machine/libmachine-core/machine.h b/src/grp-machine/libmachine-core/machine.h
index 1d8cc5911a..e5d75361a9 100644
--- a/src/grp-machine/libmachine-core/machine.h
+++ b/src/grp-machine/libmachine-core/machine.h
@@ -20,11 +20,11 @@
***/
typedef struct Machine Machine;
-typedef struct MachineOperation MachineOperation;
typedef enum KillWho KillWho;
#include "list.h"
#include "machined.h"
+#include "operation.h"
typedef enum MachineState {
MACHINE_OPENING, /* Machine is being registered */
@@ -49,17 +49,6 @@ enum KillWho {
_KILL_WHO_INVALID = -1
};
-#define MACHINE_OPERATIONS_MAX 64
-
-struct MachineOperation {
- Machine *machine;
- pid_t pid;
- sd_bus_message *message;
- int errno_fd;
- sd_event_source *event_source;
- LIST_FIELDS(MachineOperation, operations);
-};
-
struct Machine {
Manager *manager;
@@ -88,10 +77,9 @@ struct Machine {
int *netif;
unsigned n_netif;
- LIST_FIELDS(Machine, gc_queue);
+ LIST_HEAD(Operation, operations);
- MachineOperation *operations;
- unsigned n_operations;
+ LIST_FIELDS(Machine, gc_queue);
};
Machine* machine_new(Manager *manager, MachineClass class, const char *name);
@@ -109,8 +97,6 @@ void machine_release_unit(Machine *m);
MachineState machine_get_state(Machine *u);
-MachineOperation *machine_operation_unref(MachineOperation *o);
-
const char* machine_class_to_string(MachineClass t) _const_;
MachineClass machine_class_from_string(const char *s) _pure_;
diff --git a/src/grp-machine/libmachine-core/machined-dbus.c b/src/grp-machine/libmachine-core/machined-dbus.c
index 96f2c4769e..41f138882b 100644
--- a/src/grp-machine/libmachine-core/machined-dbus.c
+++ b/src/grp-machine/libmachine-core/machined-dbus.c
@@ -706,6 +706,26 @@ static int method_copy_machine(sd_bus_message *message, void *userdata, sd_bus_e
return bus_machine_method_copy(message, machine, error);
}
+static int method_open_machine_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ Machine *machine;
+ const char *name;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return r;
+
+ machine = hashmap_get(m->machines, name);
+ if (!machine)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
+
+ return bus_machine_method_open_root_directory(message, machine, error);
+}
+
static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(image_unrefp) Image* i = NULL;
const char *name;
@@ -802,6 +822,93 @@ static int method_mark_image_read_only(sd_bus_message *message, void *userdata,
return bus_image_method_mark_read_only(message, i, error);
}
+static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ enum {
+ REMOVE_ALL,
+ REMOVE_HIDDEN,
+ } mode;
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
+ Manager *m = userdata;
+ Image *image;
+ const char *mm;
+ Iterator i;
+ int r;
+
+ assert(message);
+
+ r = sd_bus_message_read(message, "s", &mm);
+ if (r < 0)
+ return r;
+
+ if (streq(mm, "all"))
+ mode = REMOVE_ALL;
+ else if (streq(mm, "hidden"))
+ mode = REMOVE_HIDDEN;
+ else
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm);
+
+ r = bus_verify_polkit_async(
+ message,
+ CAP_SYS_ADMIN,
+ "org.freedesktop.machine1.manage-machines",
+ NULL,
+ false,
+ UID_INVALID,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+
+ images = hashmap_new(&string_hash_ops);
+ if (!images)
+ return -ENOMEM;
+
+ r = image_discover(images);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(st)");
+ if (r < 0)
+ return r;
+
+ HASHMAP_FOREACH(image, images, i) {
+
+ /* We can't remove vendor images (i.e. those in /usr) */
+ if (IMAGE_IS_VENDOR(image))
+ continue;
+
+ if (IMAGE_IS_HOST(image))
+ continue;
+
+ if (mode == REMOVE_HIDDEN && !IMAGE_IS_HIDDEN(image))
+ continue;
+
+ r = image_remove(image);
+ if (r == -EBUSY) /* keep images that are currently being used. */
+ continue;
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to remove image %s: %m", image->name);
+
+ r = sd_bus_message_append(reply, "(st)", image->name, image->usage_exclusive);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
uint64_t limit;
@@ -1138,12 +1245,14 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD("BindMountMachine", "sssbb", NULL, method_bind_mount_machine, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyFromMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyToMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("OpenMachineRootDirectory", "s", "h", method_open_machine_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CleanPool", "s", "a(st)", method_clean_pool, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MapFromMachineUser", "su", "u", method_map_from_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MapToMachineUser", "u", "sou", method_map_to_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MapFromMachineGroup", "su", "u", method_map_from_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -1212,7 +1321,7 @@ int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_err
r = unit_name_from_dbus_path(path, &unit);
if (r == -EINVAL) /* not for a unit */
return 0;
- if (r < 0){
+ if (r < 0) {
log_oom();
return 0;
}
diff --git a/src/grp-machine/libmachine-core/machined.h b/src/grp-machine/libmachine-core/machined.h
index 0fe50aaa66..777571ebc0 100644
--- a/src/grp-machine/libmachine-core/machined.h
+++ b/src/grp-machine/libmachine-core/machined.h
@@ -32,6 +32,7 @@ typedef struct Manager Manager;
#include "image-dbus.h"
#include "machine-dbus.h"
#include "machine.h"
+#include "operation.h"
struct Manager {
sd_event *event;
@@ -49,6 +50,9 @@ struct Manager {
LIST_HEAD(Machine, machine_gc_queue);
Machine *host_machine;
+
+ LIST_HEAD(Operation, operations);
+ unsigned n_operations;
};
Manager *manager_new(void);
diff --git a/src/grp-machine/libmachine-core/operation.c b/src/grp-machine/libmachine-core/operation.c
new file mode 100644
index 0000000000..e6ddc41a55
--- /dev/null
+++ b/src/grp-machine/libmachine-core/operation.c
@@ -0,0 +1,131 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "operation.h"
+#include "process-util.h"
+
+static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ Operation *o = userdata;
+ int r;
+
+ assert(o);
+ assert(si);
+
+ log_debug("Operating " PID_FMT " is now complete with with code=%s status=%i",
+ o->pid,
+ sigchld_code_to_string(si->si_code), si->si_status);
+
+ o->pid = 0;
+
+ if (si->si_code != CLD_EXITED) {
+ r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
+ goto fail;
+ }
+
+ if (si->si_status != EXIT_SUCCESS) {
+ if (read(o->errno_fd, &r, sizeof(r)) == sizeof(r))
+ r = sd_bus_error_set_errnof(&error, r, "%m");
+ else
+ r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child failed.");
+
+ goto fail;
+ }
+
+ r = sd_bus_reply_method_return(o->message, NULL);
+ if (r < 0)
+ log_error_errno(r, "Failed to reply to message: %m");
+
+ operation_free(o);
+ return 0;
+
+fail:
+ r = sd_bus_reply_method_error(o->message, &error);
+ if (r < 0)
+ log_error_errno(r, "Failed to reply to message: %m");
+
+ operation_free(o);
+ return 0;
+}
+
+int operation_new(Manager *manager, Machine *machine, pid_t child, sd_bus_message *message, int errno_fd) {
+ Operation *o;
+ int r;
+
+ assert(manager);
+ assert(child > 1);
+ assert(message);
+ assert(errno_fd >= 0);
+
+ o = new0(Operation, 1);
+ if (!o)
+ return -ENOMEM;
+
+ r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
+ if (r < 0) {
+ free(o);
+ return r;
+ }
+
+ o->pid = child;
+ o->message = sd_bus_message_ref(message);
+ o->errno_fd = errno_fd;
+
+ LIST_PREPEND(operations, manager->operations, o);
+ manager->n_operations++;
+ o->manager = manager;
+
+ if (machine) {
+ LIST_PREPEND(operations_by_machine, machine->operations, o);
+ o->machine = machine;
+ }
+
+ log_debug("Started new operation " PID_FMT ".", child);
+
+ /* At this point we took ownership of both the child and the errno file descriptor! */
+
+ return 0;
+}
+
+Operation *operation_free(Operation *o) {
+ if (!o)
+ return NULL;
+
+ sd_event_source_unref(o->event_source);
+
+ safe_close(o->errno_fd);
+
+ if (o->pid > 1)
+ (void) sigkill_wait(o->pid);
+
+ sd_bus_message_unref(o->message);
+
+ if (o->manager) {
+ LIST_REMOVE(operations, o->manager->operations, o);
+ o->manager->n_operations--;
+ }
+
+ if (o->machine)
+ LIST_REMOVE(operations_by_machine, o->machine->operations, o);
+
+ free(o);
+ return NULL;
+}
diff --git a/src/libcore/bus-endpoint.h b/src/grp-machine/libmachine-core/operation.h
index f2fbc4701c..9397cd5f6d 100644
--- a/src/libcore/bus-endpoint.h
+++ b/src/grp-machine/libmachine-core/operation.h
@@ -3,7 +3,7 @@
/***
This file is part of systemd.
- Copyright 2014 Daniel Mack
+ Copyright 2016 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -19,24 +19,29 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef struct BusEndpoint BusEndpoint;
-typedef struct BusEndpointPolicy BusEndpointPolicy;
+#include <sys/types.h>
-#include "bus-policy.h"
-#include "hashmap.h"
+#include <systemd/sd-bus.h>
+#include <systemd/sd-event.h>
-struct BusEndpointPolicy {
- char *name;
- BusPolicyAccess access;
-};
+#include "list.h"
-struct BusEndpoint {
- Hashmap *policy_hash;
-};
+typedef struct Operation Operation;
-int bus_endpoint_new(BusEndpoint **ep);
-void bus_endpoint_free(BusEndpoint *endpoint);
+#include "machined.h"
-int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access);
+#define OPERATIONS_MAX 64
+
+struct Operation {
+ Manager *manager;
+ Machine *machine;
+ pid_t pid;
+ sd_bus_message *message;
+ int errno_fd;
+ sd_event_source *event_source;
+ LIST_FIELDS(Operation, operations);
+ LIST_FIELDS(Operation, operations_by_machine);
+};
-int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep);
+int operation_new(Manager *manager, Machine *machine, pid_t child, sd_bus_message *message, int errno_fd);
+Operation *operation_free(Operation *o);
diff --git a/src/grp-machine/machinectl/machinectl.c b/src/grp-machine/machinectl/machinectl.c
index fb743ab6cb..92ffa8b83d 100644
--- a/src/grp-machine/machinectl/machinectl.c
+++ b/src/grp-machine/machinectl/machinectl.c
@@ -33,6 +33,7 @@
#include "alloc-util.h"
#include "bus-error.h"
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
@@ -61,6 +62,7 @@
static char **arg_property = NULL;
static bool arg_all = false;
+static bool arg_value = false;
static bool arg_full = false;
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -80,14 +82,6 @@ static const char* arg_format = NULL;
static const char *arg_uid = NULL;
static char **arg_setenv = NULL;
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static void polkit_agent_open_if_enabled(void) {
/* Open the polkit agent as a child process if necessary */
@@ -135,17 +129,16 @@ static int list_machines(int argc, char *argv[], void *userdata) {
assert(bus);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "ListMachines",
- &error,
- &reply,
- NULL);
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "ListMachines",
+ &error,
+ &reply,
+ NULL);
if (r < 0) {
log_error("Could not get machines: %s", bus_error_message(&error, -r));
return r;
@@ -180,7 +173,7 @@ static int list_machines(int argc, char *argv[], void *userdata) {
if (l > max_service)
max_service = l;
- n_machines ++;
+ n_machines++;
}
if (r < 0)
return bus_log_parse_error(r);
@@ -238,17 +231,16 @@ static int list_images(int argc, char *argv[], void *userdata) {
assert(bus);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "ListImages",
- &error,
- &reply,
- "");
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "ListImages",
+ &error,
+ &reply,
+ "");
if (r < 0) {
log_error("Could not get images: %s", bus_error_message(&error, -r));
return r;
@@ -340,8 +332,8 @@ static int list_images(int argc, char *argv[], void *userdata) {
}
static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *path = NULL;
const char *cgroup;
int r;
@@ -350,9 +342,6 @@ static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
assert(bus);
assert(unit);
- if (arg_transport == BUS_TRANSPORT_REMOTE)
- return 0;
-
path = unit_dbus_path_from_name(unit);
if (!path)
return log_oom();
@@ -366,16 +355,14 @@ static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
&error,
&reply,
"s");
- if (r < 0) {
- log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to query ControlGroup: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &cgroup);
if (r < 0)
return bus_log_parse_error(r);
- if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
+ if (isempty(cgroup))
return 0;
c = columns();
@@ -384,7 +371,21 @@ static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
else
c = 0;
- show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, get_output_flags());
+ r = unit_show_processes(bus, unit, cgroup, "\t\t ", c, get_output_flags(), &error);
+ if (r == -EBADR) {
+
+ if (arg_transport == BUS_TRANSPORT_REMOTE)
+ return 0;
+
+ /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
+
+ if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
+ return 0;
+
+ show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, &leader, leader > 0, get_output_flags());
+ } else if (r < 0)
+ return log_error_errno(r, "Failed to dump process list: %s", bus_error_message(&error, r));
+
return 0;
}
@@ -688,7 +689,7 @@ static int show_machine_properties(sd_bus *bus, const char *path, bool *new_line
*new_line = true;
- r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
+ r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_value, arg_all);
if (r < 0)
log_error_errno(r, "Could not get properties: %m");
@@ -707,7 +708,7 @@ static int show_machine(int argc, char *argv[], void *userdata) {
properties = !strstr(argv[0], "status");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (properties && argc <= 1) {
@@ -721,15 +722,14 @@ static int show_machine(int argc, char *argv[], void *userdata) {
for (i = 1; i < argc; i++) {
const char *path = NULL;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "GetMachine",
- &error,
- &reply,
- "s", argv[i]);
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetMachine",
+ &error,
+ &reply,
+ "s", argv[i]);
if (r < 0) {
log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
return r;
@@ -937,7 +937,7 @@ static int show_image_properties(sd_bus *bus, const char *path, bool *new_line)
*new_line = true;
- r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
+ r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_value, arg_all);
if (r < 0)
log_error_errno(r, "Could not get properties: %m");
@@ -956,7 +956,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
properties = !strstr(argv[0], "status");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (argc <= 1) {
@@ -1076,6 +1076,7 @@ static int terminate_machine(int argc, char *argv[], void *userdata) {
static int copy_files(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 *m = NULL;
_cleanup_free_ char *abs_host_path = NULL;
char *dest, *host_path, *container_path;
sd_bus *bus = userdata;
@@ -1099,19 +1100,28 @@ static int copy_files(int argc, char *argv[], void *userdata) {
host_path = abs_host_path;
}
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
- copy_from ? "CopyFromMachine" : "CopyToMachine",
- &error,
- NULL,
+ copy_from ? "CopyFromMachine" : "CopyToMachine");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(
+ m,
"sss",
argv[1],
copy_from ? container_path : host_path,
copy_from ? host_path : container_path);
if (r < 0)
+ return bus_log_create_error(r);
+
+ /* This is a slow operation, hence turn off any method call timeouts */
+ r = sd_bus_call(bus, m, USEC_INFINITY, &error, NULL);
+ if (r < 0)
return log_error_errno(r, "Failed to copy: %s", bus_error_message(&error, r));
return 0;
@@ -1393,7 +1403,6 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
}
static int remove_image(int argc, char *argv[], void *userdata) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata;
int r, i;
@@ -1402,19 +1411,27 @@ static int remove_image(int argc, char *argv[], void *userdata) {
polkit_agent_open_if_enabled();
for (i = 1; i < argc; i++) {
- r = sd_bus_call_method(
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
- "RemoveImage",
- &error,
- NULL,
- "s", argv[i]);
- if (r < 0) {
- log_error("Could not remove image: %s", bus_error_message(&error, -r));
- return r;
- }
+ "RemoveImage");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "s", argv[i]);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* This is a slow operation, hence turn off any method call timeouts */
+ r = sd_bus_call(bus, m, USEC_INFINITY, &error, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Could not remove image: %s", bus_error_message(&error, r));
}
return 0;
@@ -1446,24 +1463,30 @@ static int rename_image(int argc, char *argv[], void *userdata) {
static int clone_image(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 *m = NULL;
sd_bus *bus = userdata;
int r;
polkit_agent_open_if_enabled();
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
- "CloneImage",
- &error,
- NULL,
- "ssb", argv[1], argv[2], arg_read_only);
- if (r < 0) {
- log_error("Could not clone image: %s", bus_error_message(&error, -r));
- return r;
- }
+ "CloneImage");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ssb", argv[1], argv[2], arg_read_only);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* This is a slow operation, hence turn off any method call timeouts */
+ r = sd_bus_call(bus, m, USEC_INFINITY, &error, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Could not clone image: %s", bus_error_message(&error, r));
return 0;
}
@@ -1579,6 +1602,8 @@ static int start_machine(int argc, char *argv[], void *userdata) {
static int enable_machine(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
int carries_install_info = 0;
const char *method = NULL;
sd_bus *bus = userdata;
@@ -1639,9 +1664,9 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
return bus_log_parse_error(r);
}
- r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+ r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
if (r < 0)
- return r;
+ goto finish;
r = sd_bus_call_method(
bus,
@@ -1654,10 +1679,15 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
NULL);
if (r < 0) {
log_error("Failed to reload daemon: %s", bus_error_message(&error, -r));
- return r;
+ goto finish;
}
- return 0;
+ r = 0;
+
+finish:
+ unit_file_changes_free(changes, n_changes);
+
+ return r;
}
static int match_log_message(sd_bus_message *m, void *userdata, sd_bus_error *error) {
@@ -1763,7 +1793,7 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) {
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
- log_error("Failed transfer image: %s", bus_error_message(&error, -r));
+ log_error("Failed to transfer image: %s", bus_error_message(&error, -r));
return r;
}
@@ -2189,17 +2219,16 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
double progress;
int r;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.import1",
- "/org/freedesktop/import1",
- "org.freedesktop.import1.Manager",
- "ListTransfers",
- &error,
- &reply,
- NULL);
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.import1",
+ "/org/freedesktop/import1",
+ "org.freedesktop.import1.Manager",
+ "ListTransfers",
+ &error,
+ &reply,
+ NULL);
if (r < 0) {
log_error("Could not get transfers: %s", bus_error_message(&error, -r));
return r;
@@ -2236,7 +2265,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
if (id > max_id)
max_id = id;
- n_transfers ++;
+ n_transfers++;
}
if (r < 0)
return bus_log_parse_error(r);
@@ -2349,6 +2378,50 @@ static int set_limit(int argc, char *argv[], void *userdata) {
return 0;
}
+static int clean_images(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ uint64_t usage, total = 0;
+ char fb[FORMAT_BYTES_MAX];
+ sd_bus *bus = userdata;
+ const char *name;
+ unsigned c = 0;
+ int r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "CleanPool",
+ &error,
+ &reply,
+ "s", arg_all ? "all" : "hidden");
+ if (r < 0)
+ return log_error_errno(r, "Could not clean pool: %s", bus_error_message(&error, r));
+
+ r = sd_bus_message_enter_container(reply, 'a', "(st)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(reply, "(st)", &name, &usage)) > 0) {
+ log_info("Removed image '%s'. Freed exclusive disk space: %s",
+ name, format_bytes(fb, sizeof(fb), usage));
+
+ total += usage;
+ c++;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ log_info("Removed %u images in total. Total freed exclusive disk space %s.",
+ c, format_bytes(fb, sizeof(fb), total));
+
+ return 0;
+}
+
static int help(int argc, char *argv[], void *userdata) {
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
@@ -2364,11 +2437,12 @@ static int help(int argc, char *argv[], void *userdata) {
" -p --property=NAME Show only properties by this name\n"
" -q --quiet Suppress output\n"
" -a --all Show all properties, including empty ones\n"
+ " --value When showing properties, only print the value\n"
" -l --full Do not ellipsize output\n"
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
" --uid=USER Specify user ID to invoke shell as\n"
- " --setenv=VAR=VALUE Add an environment variable for shell\n"
+ " -E --setenv=VAR=VALUE Add an environment variable for shell\n"
" --read-only Create read-only bind mount\n"
" --mkdir Create directory before bind mounting, if missing\n"
" -n --lines=INTEGER Number of journal entries to show\n"
@@ -2405,7 +2479,8 @@ static int help(int argc, char *argv[], void *userdata) {
" rename NAME NAME Rename an image\n"
" read-only NAME [BOOL] Mark or unmark image read-only\n"
" remove NAME... Remove an image\n"
- " set-limit [NAME] BYTES Set image or pool size limit (disk quota)\n\n"
+ " set-limit [NAME] BYTES Set image or pool size limit (disk quota)\n"
+ " clean Remove hidden (or all) images\n\n"
"Image Transfer Commands:\n"
" pull-tar URL [NAME] Download a TAR container image\n"
" pull-raw URL [NAME] Download a RAW container or VM image\n"
@@ -2426,6 +2501,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VERSION = 0x100,
ARG_NO_PAGER,
ARG_NO_LEGEND,
+ ARG_VALUE,
ARG_KILL_WHO,
ARG_READ_ONLY,
ARG_MKDIR,
@@ -2434,7 +2510,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_FORCE,
ARG_FORMAT,
ARG_UID,
- ARG_SETENV,
};
static const struct option options[] = {
@@ -2442,6 +2517,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "property", required_argument, NULL, 'p' },
{ "all", no_argument, NULL, 'a' },
+ { "value", no_argument, NULL, ARG_VALUE },
{ "full", no_argument, NULL, 'l' },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
@@ -2459,16 +2535,38 @@ static int parse_argv(int argc, char *argv[]) {
{ "force", no_argument, NULL, ARG_FORCE },
{ "format", required_argument, NULL, ARG_FORMAT },
{ "uid", required_argument, NULL, ARG_UID },
- { "setenv", required_argument, NULL, ARG_SETENV },
+ { "setenv", required_argument, NULL, 'E' },
{}
};
+ bool reorder = false;
int c, r;
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "hp:als:H:M:qn:o:", options, NULL)) >= 0)
+ for (;;) {
+ const char * const option_string = "+hp:als:H:M:qn:o:";
+
+ c = getopt_long(argc, argv, option_string + reorder, options, NULL);
+ if (c < 0) {
+ /* We generally are fine with the fact that getopt_long() reorders the command line, and looks
+ * for switches after the main verb. However, for "shell" we really don't want that, since we
+ * want that switches passed after that are passed to the program to execute, and not processed
+ * by us. To make this possible, we'll first invoke getopt_long() with reordering disabled
+ * (i.e. with the "+" prefix in the option string), and as soon as we hit the end (i.e. the
+ * verb) we check if that's "shell". If it is, we exit the loop, since we don't want any
+ * further options processed. However, if it is anything else, we process the same argument
+ * again, but this time allow reordering. */
+
+ if (!reorder && optind < argc && !streq(argv[optind], "shell")) {
+ reorder = true;
+ optind--;
+ continue;
+ }
+
+ break;
+ }
switch (c) {
@@ -2493,6 +2591,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_all = true;
break;
+ case ARG_VALUE:
+ arg_value = true;
+ break;
+
case 'l':
arg_full = true;
break;
@@ -2583,7 +2685,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_uid = optarg;
break;
- case ARG_SETENV:
+ case 'E':
if (!env_assignment_is_valid(optarg)) {
log_error("Environment assignment invalid: %s", optarg);
return -EINVAL;
@@ -2600,6 +2702,7 @@ static int parse_argv(int argc, char *argv[]) {
default:
assert_not_reached("Unhandled option");
}
+ }
return 1;
}
@@ -2639,6 +2742,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
{ "list-transfers", VERB_ANY, 1, 0, list_transfers },
{ "cancel-transfer", 2, VERB_ANY, 0, cancel_transfer },
{ "set-limit", 2, 3, 0, set_limit },
+ { "clean", VERB_ANY, 1, 0, clean_images },
{}
};
diff --git a/src/grp-machine/nss-mymachines/nss-mymachines.c b/src/grp-machine/nss-mymachines/nss-mymachines.c
index 9d401b39dd..da09035fe7 100644
--- a/src/grp-machine/nss-mymachines/nss-mymachines.c
+++ b/src/grp-machine/nss-mymachines/nss-mymachines.c
@@ -66,7 +66,7 @@ static int count_addresses(sd_bus_message *m, int af, unsigned *ret) {
if (af != AF_UNSPEC && family != af)
continue;
- c ++;
+ c++;
}
if (r < 0)
return r;
diff --git a/src/grp-machine/systemd-machined/machined.c b/src/grp-machine/systemd-machined/machined.c
index 6ada8671f8..151f0983ec 100644
--- a/src/grp-machine/systemd-machined/machined.c
+++ b/src/grp-machine/systemd-machined/machined.c
@@ -70,6 +70,11 @@ void manager_free(Manager *m) {
assert(m);
+ while (m->operations)
+ operation_free(m->operations);
+
+ assert(m->n_operations == 0);
+
while ((machine = hashmap_first(m->machines)))
machine_free(machine);
@@ -336,6 +341,9 @@ int manager_startup(Manager *m) {
static bool check_idle(void *userdata) {
Manager *m = userdata;
+ if (m->operations)
+ return false;
+
manager_gc(m, true);
return hashmap_isempty(m->machines);
diff --git a/src/grp-resolve/nss-resolve/nss-resolve.c b/src/grp-resolve/nss-resolve/nss-resolve.c
index d369f1b0c8..4c2101d856 100644
--- a/src/grp-resolve/nss-resolve/nss-resolve.c
+++ b/src/grp-resolve/nss-resolve/nss-resolve.c
@@ -90,7 +90,7 @@ static int count_addresses(sd_bus_message *m, int af, const char **canonical) {
if (af != AF_UNSPEC && family != af)
continue;
- c ++;
+ c++;
}
if (r < 0)
return r;
@@ -117,13 +117,6 @@ enum nss_status _nss_resolve_gethostbyname4_r(
int *errnop, int *h_errnop,
int32_t *ttlp) {
- enum nss_status (*fallback)(
- const char *name,
- struct gaih_addrtuple **pat,
- char *buffer, size_t buflen,
- int *errnop, int *h_errnop,
- int32_t *ttlp);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
@@ -275,15 +268,15 @@ enum nss_status _nss_resolve_gethostbyname4_r(
return NSS_STATUS_SUCCESS;
fallback:
- fallback = (enum nss_status (*)(const char *name,
- struct gaih_addrtuple **pat,
- char *buffer, size_t buflen,
- int *errnop, int *h_errnop,
- int32_t *ttlp))
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r");
+ {
+ _nss_gethostbyname4_r_t fallback;
+
+ fallback = (_nss_gethostbyname4_r_t)
+ find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r");
- if (fallback)
- return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp);
+ if (fallback)
+ return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp);
+ }
fail:
*errnop = -r;
@@ -300,15 +293,6 @@ enum nss_status _nss_resolve_gethostbyname3_r(
int32_t *ttlp,
char **canonp) {
- enum nss_status (*fallback)(
- const char *name,
- int af,
- struct hostent *result,
- char *buffer, size_t buflen,
- int *errnop, int *h_errnop,
- int32_t *ttlp,
- char **canonp);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char *r_name, *r_aliases, *r_addr, *r_addr_list;
@@ -480,16 +464,14 @@ enum nss_status _nss_resolve_gethostbyname3_r(
return NSS_STATUS_SUCCESS;
fallback:
- fallback = (enum nss_status (*)(const char *name,
- int af,
- struct hostent *result,
- char *buffer, size_t buflen,
- int *errnop, int *h_errnop,
- int32_t *ttlp,
- char **canonp))
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r");
- if (fallback)
- return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp);
+ {
+ _nss_gethostbyname3_r_t fallback;
+
+ fallback = (_nss_gethostbyname3_r_t)
+ find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r");
+ if (fallback)
+ return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp);
+ }
fail:
*errnop = -r;
@@ -505,15 +487,6 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
int *errnop, int *h_errnop,
int32_t *ttlp) {
- enum nss_status (*fallback)(
- const void* addr, socklen_t len,
- int af,
- struct hostent *result,
- char *buffer, size_t buflen,
- int *errnop, int *h_errnop,
- int32_t *ttlp);
-
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char *r_name, *r_aliases, *r_addr, *r_addr_list;
@@ -682,17 +655,15 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
return NSS_STATUS_SUCCESS;
fallback:
- fallback = (enum nss_status (*)(
- const void* addr, socklen_t len,
- int af,
- struct hostent *result,
- char *buffer, size_t buflen,
- int *errnop, int *h_errnop,
- int32_t *ttlp))
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r");
-
- if (fallback)
- return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp);
+ {
+ _nss_gethostbyaddr2_r_t fallback;
+
+ fallback = (_nss_gethostbyaddr2_r_t)
+ find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r");
+
+ if (fallback)
+ return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp);
+ }
fail:
*errnop = -r;
diff --git a/src/grp-resolve/systemd-resolved/Makefile b/src/grp-resolve/systemd-resolved/Makefile
index 4e34240a43..f025608eab 100644
--- a/src/grp-resolve/systemd-resolved/Makefile
+++ b/src/grp-resolve/systemd-resolved/Makefile
@@ -23,8 +23,35 @@
include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
+
+$(outdir)/dns_type-list.txt: src/resolve/dns-type.h
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)$(SED) -n -r 's/.* DNS_TYPE_(\w+).*/\1/p' <$< >$@
+
+$(outdir)/dns_type-to-name.h: src/resolve/dns_type-list.txt
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)$(AWK) '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" }' <$< >$@
+
+$(outdir)/dns_type-from-name.gperf: src/resolve/dns_type-list.txt
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct dns_type_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { s=$$1; sub(/_/, "-", s); printf "%s, ", $$s; printf "DNS_TYPE_%s\n", $$1 }' <$< >$@
+
ifneq ($(ENABLE_RESOLVED),)
+basic_dns_sources = \
+ src/resolve/resolved-dns-dnssec.c \
+ src/resolve/resolved-dns-dnssec.h \
+ src/resolve/resolved-dns-packet.c \
+ src/resolve/resolved-dns-packet.h \
+ src/resolve/resolved-dns-rr.c \
+ src/resolve/resolved-dns-rr.h \
+ src/resolve/resolved-dns-answer.c \
+ src/resolve/resolved-dns-answer.h \
+ src/resolve/resolved-dns-question.c \
+ src/resolve/resolved-dns-question.h \
+ src/resolve/dns-type.c \
+ src/resolve/dns-type.h
+
systemd_resolved_SOURCES = \
src/resolve/resolved.c \
src/resolve/resolved-manager.c \
@@ -44,14 +71,7 @@ systemd_resolved_SOURCES = \
src/resolve/resolved-mdns.h \
src/resolve/resolved-mdns.c \
src/resolve/resolved-def.h \
- src/resolve/resolved-dns-rr.h \
- src/resolve/resolved-dns-rr.c \
- src/resolve/resolved-dns-question.h \
- src/resolve/resolved-dns-question.c \
- src/resolve/resolved-dns-answer.h \
- src/resolve/resolved-dns-answer.c \
- src/resolve/resolved-dns-packet.h \
- src/resolve/resolved-dns-packet.c \
+ $(basic_dns_sources) \
src/resolve/resolved-dns-query.h \
src/resolve/resolved-dns-query.c \
src/resolve/resolved-dns-synthesize.h \
@@ -70,14 +90,12 @@ systemd_resolved_SOURCES = \
src/resolve/resolved-dns-zone.c \
src/resolve/resolved-dns-stream.h \
src/resolve/resolved-dns-stream.c \
- src/resolve/resolved-dns-dnssec.h \
- src/resolve/resolved-dns-dnssec.c \
src/resolve/resolved-dns-trust-anchor.h \
src/resolve/resolved-dns-trust-anchor.c \
src/resolve/resolved-etc-hosts.h \
src/resolve/resolved-etc-hosts.c \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h
+ src/shared/gcrypt-util.c \
+ src/shared/gcrypt-util.h
nodist_systemd_resolved_SOURCES = \
src/resolve/dns_type-from-name.h \
@@ -137,18 +155,9 @@ lib_LTLIBRARIES += \
systemd_resolve_SOURCES = \
src/resolve/resolve-tool.c \
- src/resolve/resolved-dns-dnssec.c \
- src/resolve/resolved-dns-dnssec.h \
- src/resolve/resolved-dns-packet.c \
- src/resolve/resolved-dns-packet.h \
- src/resolve/resolved-dns-rr.c \
- src/resolve/resolved-dns-rr.h \
- src/resolve/resolved-dns-answer.c \
- src/resolve/resolved-dns-answer.h \
- src/resolve/resolved-dns-question.c \
- src/resolve/resolved-dns-question.h \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h
+ $(basic_dns_sources) \
+ src/shared/gcrypt-util.c \
+ src/shared/gcrypt-util.h
nodist_systemd_resolve_SOURCES = \
src/resolve/dns_type-from-name.h \
@@ -160,27 +169,57 @@ systemd_resolve_LDADD = \
bin_PROGRAMS += \
systemd-resolve
+dist_bashcompletion_data += \
+ shell-completion/bash/systemd-resolve
+
+dist_zshcompletion_data += \
+ shell-completion/zsh/_systemd-resolve
+
tests += \
- test-dns-domain \
+ test-dns-packet \
+ test-resolve-tables \
test-dnssec
manual_tests += \
test-dnssec-complex
+test_resolve_tables_SOURCES = \
+ src/resolve/test-resolve-tables.c \
+ src/resolve/dns_type-from-name.h \
+ src/resolve/dns_type-to-name.h \
+ $(basic_dns_sources) \
+ src/shared/test-tables.h
+
+test_resolve_tables_LDADD = \
+ libshared.la
+
+test_dns_packet_SOURCES = \
+ src/resolve/test-dns-packet.c \
+ $(basic_dns_sources)
+
+test_dns_packet_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DRESOLVE_TEST_DIR=\"$(abs_top_srcdir)/src/resolve/test-data\"
+
+test_dns_packet_LDADD = \
+ libshared.la
+
+EXTRA_DIST += \
+ src/resolve/test-data/_openpgpkey.fedoraproject.org.pkts \
+ src/resolve/test-data/fedoraproject.org.pkts \
+ src/resolve/test-data/gandi.net.pkts \
+ src/resolve/test-data/google.com.pkts \
+ src/resolve/test-data/root.pkts \
+ src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts \
+ src/resolve/test-data/teamits.com.pkts \
+ src/resolve/test-data/zbyszek@fedoraproject.org.pkts \
+ src/resolve/test-data/_443._tcp.fedoraproject.org.pkts \
+ src/resolve/test-data/kyhwana.org.pkts \
+ src/resolve/test-data/fake-caa.pkts
+
test_dnssec_SOURCES = \
src/resolve/test-dnssec.c \
- src/resolve/resolved-dns-packet.c \
- src/resolve/resolved-dns-packet.h \
- src/resolve/resolved-dns-rr.c \
- src/resolve/resolved-dns-rr.h \
- src/resolve/resolved-dns-answer.c \
- src/resolve/resolved-dns-answer.h \
- src/resolve/resolved-dns-question.c \
- src/resolve/resolved-dns-question.h \
- src/resolve/resolved-dns-dnssec.c \
- src/resolve/resolved-dns-dnssec.h \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h
+ $(basic_dns_sources)
test_dnssec_LDADD = \
libshared.la
diff --git a/src/grp-resolve/systemd-resolved/RFCs b/src/grp-resolve/systemd-resolved/RFCs
index 22004a00cd..09c85f9518 100644
--- a/src/grp-resolve/systemd-resolved/RFCs
+++ b/src/grp-resolve/systemd-resolved/RFCs
@@ -8,7 +8,7 @@ D = Comprehensively Implemented, by a dependency of resolved
Y https://tools.ietf.org/html/rfc1034 → DOMAIN NAMES - CONCEPTS AND FACILITIES
Y https://tools.ietf.org/html/rfc1035 → DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION
? https://tools.ietf.org/html/rfc1101 → DNS Encoding of Network Names and Other Types
-Y https://tools.ietf.org/html/rfc1123 → Requirements for Internet Hosts -- Application and Support
+Y https://tools.ietf.org/html/rfc1123 → Requirements for Internet Hosts — Application and Support
~ https://tools.ietf.org/html/rfc1464 → Using the Domain Name System To Store Arbitrary String Attributes
Y https://tools.ietf.org/html/rfc1536 → Common DNS Implementation Errors and Suggested Fixes
Y https://tools.ietf.org/html/rfc1876 → A Means for Expressing Location Information in the Domain Name System
diff --git a/src/grp-resolve/systemd-resolved/dns-type.c b/src/grp-resolve/systemd-resolved/dns-type.c
index b2f479cae5..78d9d5733f 100644
--- a/src/grp-resolve/systemd-resolved/dns-type.c
+++ b/src/grp-resolve/systemd-resolved/dns-type.c
@@ -193,6 +193,23 @@ bool dns_type_is_obsolete(uint16_t type) {
DNS_TYPE_NULL);
}
+bool dns_type_needs_authentication(uint16_t type) {
+
+ /* Returns true for all (non-obsolete) RR types where records are not useful if they aren't
+ * authenticated. I.e. everything that contains crypto keys. */
+
+ return IN_SET(type,
+ DNS_TYPE_CERT,
+ DNS_TYPE_SSHFP,
+ DNS_TYPE_IPSECKEY,
+ DNS_TYPE_DS,
+ DNS_TYPE_DNSKEY,
+ DNS_TYPE_TLSA,
+ DNS_TYPE_CDNSKEY,
+ DNS_TYPE_OPENPGPKEY,
+ DNS_TYPE_CAA);
+}
+
int dns_type_to_af(uint16_t t) {
switch (t) {
diff --git a/src/grp-resolve/systemd-resolved/dns-type.h b/src/grp-resolve/systemd-resolved/dns-type.h
index a6c1630021..7b79d29d7e 100644
--- a/src/grp-resolve/systemd-resolved/dns-type.h
+++ b/src/grp-resolve/systemd-resolved/dns-type.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include "macro.h"
/* DNS record types, taken from
@@ -124,6 +124,9 @@ enum {
_DNS_CLASS_INVALID = -1
};
+#define _DNS_CLASS_STRING_MAX (sizeof "CLASS" + DECIMAL_STR_MAX(uint16_t))
+#define _DNS_TYPE_STRING_MAX (sizeof "CLASS" + DECIMAL_STR_MAX(uint16_t))
+
bool dns_type_is_pseudo(uint16_t type);
bool dns_type_is_valid_query(uint16_t type);
bool dns_type_is_valid_rr(uint16_t type);
@@ -132,7 +135,8 @@ bool dns_type_is_dnssec(uint16_t type);
bool dns_type_is_obsolete(uint16_t type);
bool dns_type_may_wildcard(uint16_t type);
bool dns_type_apex_only(uint16_t type);
-int dns_type_to_af(uint16_t t);
+bool dns_type_needs_authentication(uint16_t type);
+int dns_type_to_af(uint16_t type);
bool dns_class_is_pseudo(uint16_t class);
bool dns_class_is_valid_rr(uint16_t class);
@@ -141,7 +145,7 @@ bool dns_class_is_valid_rr(uint16_t class);
const char *dns_type_to_string(int type);
int dns_type_from_string(const char *s);
-const char *dns_class_to_string(uint16_t type);
+const char *dns_class_to_string(uint16_t class);
int dns_class_from_string(const char *name);
/* https://tools.ietf.org/html/draft-ietf-dane-protocol-23#section-7.2 */
@@ -152,3 +156,6 @@ const char *tlsa_selector_to_string(uint8_t selector);
/* https://tools.ietf.org/html/draft-ietf-dane-protocol-23#section-7.4 */
const char *tlsa_matching_type_to_string(uint8_t selector);
+
+/* https://tools.ietf.org/html/rfc6844#section-5.1 */
+#define CAA_FLAG_CRITICAL (1u << 7)
diff --git a/src/grp-resolve/systemd-resolved/resolve-tool.c b/src/grp-resolve/systemd-resolved/resolve-tool.c
index 3f1b6e32f1..fbf7b0e4f6 100644
--- a/src/grp-resolve/systemd-resolved/resolve-tool.c
+++ b/src/grp-resolve/systemd-resolved/resolve-tool.c
@@ -28,6 +28,7 @@
#include "bus-util.h"
#include "escape.h"
#include "in-addr-util.h"
+#include "gcrypt-util.h"
#include "parse-util.h"
#include "resolved-def.h"
#include "resolved-dns-packet.h"
@@ -42,14 +43,54 @@ static uint16_t arg_class = 0;
static bool arg_legend = true;
static uint64_t arg_flags = 0;
+typedef enum ServiceFamily {
+ SERVICE_FAMILY_TCP,
+ SERVICE_FAMILY_UDP,
+ SERVICE_FAMILY_SCTP,
+ _SERVICE_FAMILY_INVALID = -1,
+} ServiceFamily;
+static ServiceFamily arg_service_family = SERVICE_FAMILY_TCP;
+
+typedef enum RawType {
+ RAW_NONE,
+ RAW_PAYLOAD,
+ RAW_PACKET,
+} RawType;
+static RawType arg_raw = RAW_NONE;
+
static enum {
MODE_RESOLVE_HOST,
MODE_RESOLVE_RECORD,
MODE_RESOLVE_SERVICE,
+ MODE_RESOLVE_OPENPGP,
+ MODE_RESOLVE_TLSA,
MODE_STATISTICS,
MODE_RESET_STATISTICS,
} arg_mode = MODE_RESOLVE_HOST;
+static ServiceFamily service_family_from_string(const char *s) {
+ if (s == NULL || streq(s, "tcp"))
+ return SERVICE_FAMILY_TCP;
+ if (streq(s, "udp"))
+ return SERVICE_FAMILY_UDP;
+ if (streq(s, "sctp"))
+ return SERVICE_FAMILY_SCTP;
+ return _SERVICE_FAMILY_INVALID;
+}
+
+static const char* service_family_to_string(ServiceFamily service) {
+ switch(service) {
+ case SERVICE_FAMILY_TCP:
+ return "_tcp";
+ case SERVICE_FAMILY_UDP:
+ return "_udp";
+ case SERVICE_FAMILY_SCTP:
+ return "_sctp";
+ default:
+ assert_not_reached("invalid service");
+ }
+}
+
static void print_source(uint64_t flags, usec_t rtt) {
char rtt_str[FORMAT_TIMESTAMP_MAX];
@@ -328,6 +369,50 @@ static int parse_address(const char *s, int *family, union in_addr_union *addres
return 0;
}
+static int output_rr_packet(const void *d, size_t l, int ifindex) {
+ _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+ int r;
+ char ifname[IF_NAMESIZE] = "";
+
+ r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
+ if (r < 0)
+ return log_oom();
+
+ p->refuse_compression = true;
+
+ r = dns_packet_append_blob(p, d, l, NULL);
+ if (r < 0)
+ return log_oom();
+
+ r = dns_packet_read_rr(p, &rr, NULL, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse RR: %m");
+
+ if (arg_raw == RAW_PAYLOAD) {
+ void *data;
+ ssize_t k;
+
+ k = dns_resource_record_payload(rr, &data);
+ if (k < 0)
+ return log_error_errno(k, "Cannot dump RR: %m");
+ fwrite(data, 1, k, stdout);
+ } else {
+ const char *s;
+
+ s = dns_resource_record_to_string(rr);
+ if (!s)
+ return log_oom();
+
+ if (ifindex > 0 && !if_indextoname(ifindex, ifname))
+ log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
+
+ printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname);
+ }
+
+ return 0;
+}
+
static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_t type) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -336,6 +421,7 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
uint64_t flags;
int r;
usec_t ts;
+ bool needs_authentication = false;
assert(name);
@@ -373,9 +459,6 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
return bus_log_parse_error(r);
while ((r = sd_bus_message_enter_container(reply, 'r', "iqqay")) > 0) {
- _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
- _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
- const char *s;
uint16_t c, t;
int ifindex;
const void *d;
@@ -395,29 +478,20 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
if (r < 0)
return bus_log_parse_error(r);
- r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
- if (r < 0)
- return log_oom();
-
- p->refuse_compression = true;
+ if (arg_raw == RAW_PACKET) {
+ uint64_t u64 = htole64(l);
- r = dns_packet_append_blob(p, d, l, NULL);
- if (r < 0)
- return log_oom();
-
- r = dns_packet_read_rr(p, &rr, NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to parse RR: %m");
+ fwrite(&u64, sizeof(u64), 1, stdout);
+ fwrite(d, 1, l, stdout);
+ } else {
+ r = output_rr_packet(d, l, ifindex);
+ if (r < 0)
+ return r;
+ }
- s = dns_resource_record_to_string(rr);
- if (!s)
- return log_oom();
+ if (dns_type_needs_authentication(t))
+ needs_authentication = true;
- ifname[0] = 0;
- if (ifindex > 0 && !if_indextoname(ifindex, ifname))
- log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
-
- printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname);
n++;
}
if (r < 0)
@@ -438,6 +512,18 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
print_source(flags, ts);
+ if ((flags & SD_RESOLVED_AUTHENTICATED) == 0 && needs_authentication) {
+ fflush(stdout);
+
+ fprintf(stderr, "\n%s"
+ "WARNING: The resources shown contain cryptographic key data which could not be\n"
+ " authenticated. It is not suitable to authenticate any communication.\n"
+ " This is usually indication that DNSSEC authentication was not enabled\n"
+ " or is not available for the selected protocol or DNS servers.%s\n",
+ ansi_highlight_red(),
+ ansi_normal());
+ }
+
return 0;
}
@@ -545,15 +631,10 @@ static int resolve_rfc4501(sd_bus *bus, const char *name) {
} else
n = p;
- if (type == 0)
- type = arg_type;
- if (type == 0)
- type = DNS_TYPE_A;
-
- if (class == 0)
- class = arg_class;
if (class == 0)
- class = DNS_CLASS_IN;
+ class = arg_class ?: DNS_CLASS_IN;
+ if (type == 0)
+ type = arg_type ?: DNS_TYPE_A;
return resolve_record(bus, n, class, type);
@@ -763,6 +844,68 @@ static int resolve_service(sd_bus *bus, const char *name, const char *type, cons
return 0;
}
+static int resolve_openpgp(sd_bus *bus, const char *address) {
+ const char *domain, *full;
+ int r;
+ _cleanup_free_ char *hashed = NULL;
+
+ assert(bus);
+ assert(address);
+
+ domain = strrchr(address, '@');
+ if (!domain) {
+ log_error("Address does not contain '@': \"%s\"", address);
+ return -EINVAL;
+ } else if (domain == address || domain[1] == '\0') {
+ log_error("Address starts or ends with '@': \"%s\"", address);
+ return -EINVAL;
+ }
+ domain++;
+
+ r = string_hashsum_sha224(address, domain - 1 - address, &hashed);
+ if (r < 0)
+ return log_error_errno(r, "Hashing failed: %m");
+
+ full = strjoina(hashed, "._openpgpkey.", domain);
+ log_debug("Looking up \"%s\".", full);
+
+ return resolve_record(bus, full,
+ arg_class ?: DNS_CLASS_IN,
+ arg_type ?: DNS_TYPE_OPENPGPKEY);
+}
+
+static int resolve_tlsa(sd_bus *bus, const char *address) {
+ const char *port;
+ uint16_t port_num = 443;
+ _cleanup_free_ char *full = NULL;
+ int r;
+
+ assert(bus);
+ assert(address);
+
+ port = strrchr(address, ':');
+ if (port) {
+ r = safe_atou16(port + 1, &port_num);
+ if (r < 0 || port_num == 0)
+ return log_error_errno(r, "Invalid port \"%s\".", port + 1);
+
+ address = strndupa(address, port - address);
+ }
+
+ r = asprintf(&full, "_%u.%s.%s",
+ port_num,
+ service_family_to_string(arg_service_family),
+ address);
+ if (r < 0)
+ return log_oom();
+
+ log_debug("Looking up \"%s\".", full);
+
+ return resolve_record(bus, full,
+ arg_class ?: DNS_CLASS_IN,
+ arg_type ?: DNS_TYPE_TLSA);
+}
+
static int show_statistics(sd_bus *bus) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
@@ -931,26 +1074,34 @@ static void help_dns_classes(void) {
}
static void help(void) {
- printf("%s [OPTIONS...] NAME...\n"
- "%s [OPTIONS...] --service [[NAME] TYPE] DOMAIN\n\n"
+ printf("%1$s [OPTIONS...] HOSTNAME|ADDRESS...\n"
+ "%1$s [OPTIONS...] --service [[NAME] TYPE] DOMAIN\n"
+ "%1$s [OPTIONS...] --openpgp EMAIL@DOMAIN...\n"
+ "%1$s [OPTIONS...] --statistics\n"
+ "%1$s [OPTIONS...] --reset-statistics\n"
+ "\n"
"Resolve domain names, IPv4 and IPv6 addresses, DNS resource records, and services.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " -4 Resolve IPv4 addresses\n"
- " -6 Resolve IPv6 addresses\n"
- " -i --interface=INTERFACE Look on interface\n"
- " -p --protocol=PROTOCOL|help Look via protocol\n"
- " -t --type=TYPE|help Query RR with DNS type\n"
- " -c --class=CLASS|help Query RR with DNS class\n"
- " --service Resolve service (SRV)\n"
- " --service-address=BOOL Do [not] resolve address for services\n"
- " --service-txt=BOOL Do [not] resolve TXT records for services\n"
- " --cname=BOOL Do [not] follow CNAME redirects\n"
- " --search=BOOL Do [not] use search domains\n"
- " --legend=BOOL Do [not] print column headers and meta information\n"
- " --statistics Show resolver statistics\n"
- " --reset-statistics Reset resolver statistics\n"
- , program_invocation_short_name, program_invocation_short_name);
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -4 Resolve IPv4 addresses\n"
+ " -6 Resolve IPv6 addresses\n"
+ " -i --interface=INTERFACE Look on interface\n"
+ " -p --protocol=PROTO|help Look via protocol\n"
+ " -t --type=TYPE|help Query RR with DNS type\n"
+ " -c --class=CLASS|help Query RR with DNS class\n"
+ " --service Resolve service (SRV)\n"
+ " --service-address=BOOL Resolve address for services (default: yes)\n"
+ " --service-txt=BOOL Resolve TXT records for services (default: yes)\n"
+ " --openpgp Query OpenPGP public key\n"
+ " --tlsa Query TLS public key\n"
+ " --cname=BOOL Follow CNAME redirects (default: yes)\n"
+ " --search=BOOL Use search domains for single-label names\n"
+ " (default: yes)\n"
+ " --raw[=payload|packet] Dump the answer as binary data\n"
+ " --legend=BOOL Print headers and additional info (default: yes)\n"
+ " --statistics Show resolver statistics\n"
+ " --reset-statistics Reset resolver statistics\n"
+ , program_invocation_short_name);
}
static int parse_argv(int argc, char *argv[]) {
@@ -961,6 +1112,9 @@ static int parse_argv(int argc, char *argv[]) {
ARG_CNAME,
ARG_SERVICE_ADDRESS,
ARG_SERVICE_TXT,
+ ARG_OPENPGP,
+ ARG_TLSA,
+ ARG_RAW,
ARG_SEARCH,
ARG_STATISTICS,
ARG_RESET_STATISTICS,
@@ -978,6 +1132,9 @@ static int parse_argv(int argc, char *argv[]) {
{ "service", no_argument, NULL, ARG_SERVICE },
{ "service-address", required_argument, NULL, ARG_SERVICE_ADDRESS },
{ "service-txt", required_argument, NULL, ARG_SERVICE_TXT },
+ { "openpgp", no_argument, NULL, ARG_OPENPGP },
+ { "tlsa", optional_argument, NULL, ARG_TLSA },
+ { "raw", optional_argument, NULL, ARG_RAW },
{ "search", required_argument, NULL, ARG_SEARCH },
{ "statistics", no_argument, NULL, ARG_STATISTICS, },
{ "reset-statistics", no_argument, NULL, ARG_RESET_STATISTICS },
@@ -1087,44 +1244,63 @@ static int parse_argv(int argc, char *argv[]) {
arg_mode = MODE_RESOLVE_SERVICE;
break;
+ case ARG_OPENPGP:
+ arg_mode = MODE_RESOLVE_OPENPGP;
+ break;
+
+ case ARG_TLSA:
+ arg_mode = MODE_RESOLVE_TLSA;
+ arg_service_family = service_family_from_string(optarg);
+ if (arg_service_family < 0) {
+ log_error("Unknown service family \"%s\".", optarg);
+ return -EINVAL;
+ }
+ break;
+
+ case ARG_RAW:
+ if (on_tty()) {
+ log_error("Refusing to write binary data to tty.");
+ return -ENOTTY;
+ }
+
+ if (optarg == NULL || streq(optarg, "payload"))
+ arg_raw = RAW_PAYLOAD;
+ else if (streq(optarg, "packet"))
+ arg_raw = RAW_PACKET;
+ else {
+ log_error("Unknown --raw specifier \"%s\".", optarg);
+ return -EINVAL;
+ }
+
+ arg_legend = false;
+ break;
+
case ARG_CNAME:
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse --cname= argument.");
- if (r == 0)
- arg_flags |= SD_RESOLVED_NO_CNAME;
- else
- arg_flags &= ~SD_RESOLVED_NO_CNAME;
+ SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0);
break;
case ARG_SERVICE_ADDRESS:
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse --service-address= argument.");
- if (r == 0)
- arg_flags |= SD_RESOLVED_NO_ADDRESS;
- else
- arg_flags &= ~SD_RESOLVED_NO_ADDRESS;
+ SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0);
break;
case ARG_SERVICE_TXT:
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse --service-txt= argument.");
- if (r == 0)
- arg_flags |= SD_RESOLVED_NO_TXT;
- else
- arg_flags &= ~SD_RESOLVED_NO_TXT;
+ SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0);
break;
case ARG_SEARCH:
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse --search argument.");
- if (r == 0)
- arg_flags |= SD_RESOLVED_NO_SEARCH;
- else
- arg_flags &= ~SD_RESOLVED_NO_SEARCH;
+ SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0);
break;
case ARG_STATISTICS:
@@ -1147,7 +1323,7 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
- if (arg_type != 0 && arg_mode != MODE_RESOLVE_RECORD) {
+ if (arg_type != 0 && arg_mode == MODE_RESOLVE_SERVICE) {
log_error("--service and --type= may not be combined.");
return -EINVAL;
}
@@ -1246,6 +1422,42 @@ int main(int argc, char **argv) {
break;
+ case MODE_RESOLVE_OPENPGP:
+ if (argc < optind + 1) {
+ log_error("E-mail address required.");
+ r = -EINVAL;
+ goto finish;
+
+ }
+
+ r = 0;
+ while (optind < argc) {
+ int k;
+
+ k = resolve_openpgp(bus, argv[optind++]);
+ if (k < 0)
+ r = k;
+ }
+ break;
+
+ case MODE_RESOLVE_TLSA:
+ if (argc < optind + 1) {
+ log_error("Domain name required.");
+ r = -EINVAL;
+ goto finish;
+
+ }
+
+ r = 0;
+ while (optind < argc) {
+ int k;
+
+ k = resolve_tlsa(bus, argv[optind++]);
+ if (k < 0)
+ r = k;
+ }
+ break;
+
case MODE_STATISTICS:
if (argc > optind) {
log_error("Too many arguments.");
diff --git a/src/grp-resolve/systemd-resolved/resolved-bus.c b/src/grp-resolve/systemd-resolved/resolved-bus.c
index fc5e6beca0..33f7c61557 100644
--- a/src/grp-resolve/systemd-resolved/resolved-bus.c
+++ b/src/grp-resolve/systemd-resolved/resolved-bus.c
@@ -23,6 +23,7 @@
#include "dns-domain.h"
#include "resolved-bus.h"
#include "resolved-def.h"
+#include "resolved-dns-synthesize.h"
#include "resolved-link-bus.h"
static int reply_query_state(DnsQuery *q) {
@@ -139,6 +140,7 @@ static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifin
static void bus_method_resolve_hostname_complete(DnsQuery *q) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_free_ char *normalized = NULL;
DnsResourceRecord *rr;
unsigned added = 0;
int ifindex, r;
@@ -186,7 +188,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
if (!canonical)
canonical = dns_resource_record_ref(rr);
- added ++;
+ added++;
}
if (added <= 0) {
@@ -198,11 +200,17 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
if (r < 0)
goto finish;
+ /* The key names are not necessarily normalized, make sure that they are when we return them to our bus
+ * clients. */
+ r = dns_name_normalize(dns_resource_key_name(canonical->key), &normalized);
+ if (r < 0)
+ goto finish;
+
/* Return the precise spelling and uppercasing and CNAME target reported by the server */
assert(canonical);
r = sd_bus_message_append(
reply, "st",
- DNS_RESOURCE_KEY_NAME(canonical->key),
+ normalized,
SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
if (r < 0)
goto finish;
@@ -233,6 +241,65 @@ static int check_ifindex_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus
return 0;
}
+static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname, int family, uint64_t flags) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_free_ char *canonical = NULL;
+ union in_addr_union parsed;
+ int r, ff;
+
+ /* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
+ * let's not attempt to look it up. */
+
+ r = in_addr_from_string_auto(hostname, &ff, &parsed);
+ if (r < 0) /* not an address */
+ return 0;
+
+ if (family != AF_UNSPEC && ff != family)
+ return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address is not of the requested family.");
+
+ r = sd_bus_message_new_method_return(m, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(iiay)");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'r', "iiay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "ii", ifindex, ff);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append_array(reply, 'y', &parsed, FAMILY_ADDRESS_SIZE(ff));
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ /* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
+ * look-up. However, we reformat it to make sure it's in a truly canonical form (i.e. on IPv6 the inner
+ * omissions are always done the same way). */
+ r = in_addr_to_string(ff, &parsed, &canonical);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "st", canonical,
+ SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true));
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(sd_bus_message_get_bus(m), reply, NULL);
+}
+
static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
Manager *m = userdata;
@@ -254,15 +321,19 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
- r = dns_name_is_valid(hostname);
+ r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
if (r < 0)
return r;
- if (r == 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
- r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
+ r = parse_as_address(message, ifindex, hostname, family, flags);
+ if (r != 0)
+ return r;
+
+ r = dns_name_is_valid(hostname);
if (r < 0)
return r;
+ if (r == 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
r = dns_question_new_address(&question_utf8, family, hostname, false);
if (r < 0)
@@ -331,24 +402,31 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
question = dns_query_question_for_protocol(q, q->answer_protocol);
DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
+ _cleanup_free_ char *normalized = NULL;
+
r = dns_question_matches_rr(question, rr, NULL);
if (r < 0)
goto finish;
if (r == 0)
continue;
- r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name);
+ r = dns_name_normalize(rr->ptr.name, &normalized);
+ if (r < 0)
+ goto finish;
+
+ r = sd_bus_message_append(reply, "(is)", ifindex, normalized);
if (r < 0)
goto finish;
- added ++;
+ added++;
}
if (added <= 0) {
_cleanup_free_ char *ip = NULL;
- in_addr_to_string(q->request_family, &q->request_address, &ip);
- r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", strna(ip));
+ (void) in_addr_to_string(q->request_family, &q->request_address, &ip);
+ r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR,
+ "Address '%s' does not have any RR of requested type", strnull(ip));
goto finish;
}
@@ -510,7 +588,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
if (r < 0)
goto finish;
- added ++;
+ added++;
}
if (added <= 0) {
@@ -607,6 +685,7 @@ fail:
static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
+ _cleanup_free_ char *normalized = NULL;
DnsQuery *aux;
int r;
@@ -663,10 +742,14 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr)
if (r < 0)
return r;
+ r = dns_name_normalize(rr->srv.name, &normalized);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_append(
reply,
"qqqs",
- rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name);
+ rr->srv.priority, rr->srv.weight, rr->srv.port, normalized);
if (r < 0)
return r;
@@ -712,9 +795,17 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr)
if (r < 0)
return r;
+ if (canonical) {
+ normalized = mfree(normalized);
+
+ r = dns_name_normalize(dns_resource_key_name(canonical->key), &normalized);
+ if (r < 0)
+ return r;
+ }
+
/* Note that above we appended the hostname as encoded in the
* SRV, and here the canonical hostname this maps to. */
- r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name);
+ r = sd_bus_message_append(reply, "s", normalized);
if (r < 0)
return r;
@@ -869,7 +960,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
goto finish;
assert(canonical);
- r = dns_service_split(DNS_RESOURCE_KEY_NAME(canonical->key), &name, &type, &domain);
+ r = dns_service_split(dns_resource_key_name(canonical->key), &name, &type, &domain);
if (r < 0)
goto finish;
@@ -1004,9 +1095,9 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
}
if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
- q->block_all_complete ++;
+ q->block_all_complete++;
r = resolve_service_hostname(q, rr, ifindex);
- q->block_all_complete --;
+ q->block_all_complete--;
if (r < 0)
goto finish;
@@ -1047,7 +1138,6 @@ finish:
static int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
const char *name, *type, *domain;
- _cleanup_free_ char *n = NULL;
Manager *m = userdata;
int family, ifindex;
uint64_t flags;
@@ -1198,7 +1288,7 @@ static int bus_property_get_dns_servers(
return sd_bus_message_close_container(reply);
}
-static int bus_property_get_search_domains(
+static int bus_property_get_domains(
sd_bus *bus,
const char *path,
const char *interface,
@@ -1396,8 +1486,8 @@ static int bus_method_set_link_dns_servers(sd_bus_message *message, void *userda
return call_link_method(userdata, message, bus_link_method_set_dns_servers, error);
}
-static int bus_method_set_link_search_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return call_link_method(userdata, message, bus_link_method_set_search_domains, error);
+static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return call_link_method(userdata, message, bus_link_method_set_domains, error);
}
static int bus_method_set_link_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -1449,7 +1539,7 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers, 0, 0),
- SD_BUS_PROPERTY("SearchDomains", "a(isb)", bus_property_get_search_domains, 0, 0),
+ SD_BUS_PROPERTY("Domains", "a(isb)", bus_property_get_domains, 0, 0),
SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0),
SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0),
SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
@@ -1462,7 +1552,7 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
- SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_search_domains, 0),
+ SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0),
SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0),
SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0),
SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0),
diff --git a/src/grp-resolve/systemd-resolved/resolved-conf.c b/src/grp-resolve/systemd-resolved/resolved-conf.c
index bb93fbfda2..990dc03b60 100644
--- a/src/grp-resolve/systemd-resolved/resolved-conf.c
+++ b/src/grp-resolve/systemd-resolved/resolved-conf.c
@@ -59,7 +59,7 @@ int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, con
assert(m);
assert(string);
- for(;;) {
+ for (;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&string, &word, NULL, 0);
@@ -114,7 +114,7 @@ int manager_parse_search_domains_and_warn(Manager *m, const char *string) {
assert(m);
assert(string);
- for(;;) {
+ for (;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&string, &word, NULL, EXTRACT_QUOTES);
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-answer.c b/src/grp-resolve/systemd-resolved/resolved-dns-answer.c
index 7eb303ab95..0dadf8b1dd 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-answer.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-answer.c
@@ -330,7 +330,7 @@ int dns_answer_contains_zone_nsec3(DnsAnswer *answer, const char *zone) {
if (rr->key->type != DNS_TYPE_NSEC3)
continue;
- p = DNS_RESOURCE_KEY_NAME(rr->key);
+ p = dns_resource_key_name(rr->key);
r = dns_name_parent(&p);
if (r < 0)
return r;
@@ -363,7 +363,7 @@ int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceReco
if (r > 0) {
if (soa) {
- r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(soa->key));
+ r = dns_name_endswith(dns_resource_key_name(rr->key), dns_resource_key_name(soa->key));
if (r < 0)
return r;
if (r > 0)
@@ -538,7 +538,7 @@ int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key) {
dns_resource_record_unref((*a)->items[i].rr);
memmove((*a)->items + i, (*a)->items + i + 1, sizeof(DnsAnswerItem) * ((*a)->n_rrs - i - 1));
- (*a)->n_rrs --;
+ (*a)->n_rrs--;
continue;
} else
@@ -624,7 +624,7 @@ int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) {
dns_resource_record_unref((*a)->items[i].rr);
memmove((*a)->items + i, (*a)->items + i + 1, sizeof(DnsAnswerItem) * ((*a)->n_rrs - i - 1));
- (*a)->n_rrs --;
+ (*a)->n_rrs--;
continue;
} else
@@ -757,7 +757,7 @@ int dns_answer_reserve_or_clone(DnsAnswer **a, unsigned n_free) {
assert(a);
/* Tries to extend the DnsAnswer object. And if that's not
- * possibly, since we are not the sole owner, then allocate a
+ * possible, since we are not the sole owner, then allocate a
* new, appropriately sized one. Either way, after this call
* the object will only have a single reference, and has room
* for at least the specified number of RRs. */
@@ -840,13 +840,13 @@ bool dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname) {
if (rr->key->class != cname->key->class)
continue;
- r = dns_name_change_suffix(cname->cname.name, rr->dname.name, DNS_RESOURCE_KEY_NAME(rr->key), &n);
+ r = dns_name_change_suffix(cname->cname.name, rr->dname.name, dns_resource_key_name(rr->key), &n);
if (r < 0)
return r;
if (r == 0)
continue;
- r = dns_name_equal(n, DNS_RESOURCE_KEY_NAME(cname->key));
+ r = dns_name_equal(n, dns_resource_key_name(cname->key));
if (r < 0)
return r;
if (r > 0)
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-answer.h b/src/grp-resolve/systemd-resolved/resolved-dns-answer.h
index 8f9c15eab4..0679c610f5 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-answer.h
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-answer.h
@@ -30,7 +30,7 @@ typedef struct DnsAnswerItem DnsAnswerItem;
* can qualify A and AAAA RRs referring to a local link with the
* right ifindex.
*
- * Note that we usually encode the the empty DnsAnswer object as a simple NULL. */
+ * Note that we usually encode the empty DnsAnswer object as a simple NULL. */
typedef enum DnsAnswerFlags {
DNS_ANSWER_AUTHENTICATED = 1, /* Item has been authenticated */
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-cache.c b/src/grp-resolve/systemd-resolved/resolved-dns-cache.c
index 9bcc71724e..77c42d7aad 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-cache.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-cache.c
@@ -17,6 +17,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <net/if.h>
+
+#include "af-list.h"
#include "alloc-util.h"
#include "dns-domain.h"
#include "resolved-dns-answer.h"
@@ -180,6 +183,7 @@ void dns_cache_prune(DnsCache *c) {
for (;;) {
DnsCacheItem *i;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
i = prioq_peek(c->by_expiry);
if (!i)
@@ -192,8 +196,12 @@ void dns_cache_prune(DnsCache *c) {
break;
/* Depending whether this is an mDNS shared entry
- * either remove only this one RR or the whole
- * RRset */
+ * either remove only this one RR or the whole RRset */
+ log_debug("Removing %scache entry for %s (expired "USEC_FMT"s ago)",
+ i->shared_owner ? "shared " : "",
+ dns_resource_key_to_string(i->key, key_str, sizeof key_str),
+ (t - i->until) / USEC_PER_SEC);
+
if (i->shared_owner)
dns_cache_item_unlink_and_free(c, i);
else {
@@ -375,8 +383,8 @@ static int dns_cache_put_positive(
const union in_addr_union *owner_address) {
_cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
- _cleanup_free_ char *key_str = NULL;
DnsCacheItem *existing;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX], ifname[IF_NAMESIZE];
int r, k;
assert(c);
@@ -392,18 +400,9 @@ static int dns_cache_put_positive(
/* New TTL is 0? Delete this specific entry... */
if (rr->ttl <= 0) {
k = dns_cache_remove_by_rr(c, rr);
-
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(rr->key, &key_str);
- if (r < 0)
- return r;
-
- if (k > 0)
- log_debug("Removed zero TTL entry from cache: %s", key_str);
- else
- log_debug("Not caching zero TTL cache entry: %s", key_str);
- }
-
+ log_debug("%s: %s",
+ k > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
+ dns_resource_key_to_string(rr->key, key_str, sizeof key_str));
return 0;
}
@@ -450,11 +449,18 @@ static int dns_cache_put_positive(
return r;
if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(i->key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("Added positive cache entry for %s", key_str);
+ _cleanup_free_ char *t = NULL;
+
+ (void) in_addr_to_string(i->owner_family, &i->owner_address, &t);
+
+ log_debug("Added positive %s%s cache entry for %s "USEC_FMT"s on %s/%s/%s",
+ i->authenticated ? "authenticated" : "unauthenticated",
+ i->shared_owner ? " shared" : "",
+ dns_resource_key_to_string(i->key, key_str, sizeof key_str),
+ (i->until - timestamp) / USEC_PER_SEC,
+ i->ifindex == 0 ? "*" : strna(if_indextoname(i->ifindex, ifname)),
+ af_to_name_short(i->owner_family),
+ strna(t));
}
i = NULL;
@@ -473,7 +479,7 @@ static int dns_cache_put_negative(
const union in_addr_union *owner_address) {
_cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
- _cleanup_free_ char *key_str = NULL;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
int r;
assert(c);
@@ -490,14 +496,8 @@ static int dns_cache_put_negative(
return 0;
if (nsec_ttl <= 0 || soa->soa.minimum <= 0 || soa->ttl <= 0) {
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("Not caching negative entry with zero SOA/NSEC/NSEC3 TTL: %s", key_str);
- }
-
+ log_debug("Not caching negative entry with zero SOA/NSEC/NSEC3 TTL: %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
return 0;
}
@@ -524,7 +524,7 @@ static int dns_cache_put_negative(
if (i->type == DNS_CACHE_NXDOMAIN) {
/* NXDOMAIN entries should apply equally to all types, so we use ANY as
* a pseudo type for this purpose here. */
- i->key = dns_resource_key_new(key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(key));
+ i->key = dns_resource_key_new(key->class, DNS_TYPE_ANY, dns_resource_key_name(key));
if (!i->key)
return -ENOMEM;
@@ -542,13 +542,10 @@ static int dns_cache_put_negative(
if (r < 0)
return r;
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(i->key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("Added %s cache entry for %s", i->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", key_str);
- }
+ log_debug("Added %s cache entry for %s "USEC_FMT"s",
+ i->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN",
+ dns_resource_key_to_string(i->key, key_str, sizeof key_str),
+ (i->until - timestamp) / USEC_PER_SEC);
i = NULL;
return 0;
@@ -628,16 +625,10 @@ int dns_cache_put(
dns_cache_remove_previous(c, key, answer);
if (dns_answer_size(answer) <= 0) {
- if (log_get_max_level() >= LOG_DEBUG) {
- _cleanup_free_ char *key_str = NULL;
-
- r = dns_resource_key_to_string(key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("Not caching negative entry without a SOA record: %s", key_str);
- }
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
+ log_debug("Not caching negative entry without a SOA record: %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
return 0;
}
@@ -649,7 +640,7 @@ int dns_cache_put(
cache_keys = dns_answer_size(answer);
if (key)
- cache_keys ++;
+ cache_keys++;
/* Make some space for our new entries */
dns_cache_make_space(c, cache_keys);
@@ -759,7 +750,7 @@ static DnsCacheItem *dns_cache_get_by_key_follow_cname_dname_nsec(DnsCache *c, D
if (i)
return i;
- n = DNS_RESOURCE_KEY_NAME(k);
+ n = dns_resource_key_name(k);
/* Check if we have an NXDOMAIN cache item for the name, notice that we use
* the pseudo-type ANY for NXDOMAIN cache items. */
@@ -801,10 +792,10 @@ static DnsCacheItem *dns_cache_get_by_key_follow_cname_dname_nsec(DnsCache *c, D
int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **ret, bool *authenticated) {
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
unsigned n = 0;
int r;
bool nxdomain = false;
- _cleanup_free_ char *key_str = NULL;
DnsCacheItem *j, *first, *nsec = NULL;
bool have_authenticated = false, have_non_authenticated = false;
@@ -814,19 +805,12 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r
assert(ret);
assert(authenticated);
- if (key->type == DNS_TYPE_ANY ||
- key->class == DNS_CLASS_ANY) {
-
+ if (key->type == DNS_TYPE_ANY || key->class == DNS_CLASS_ANY) {
/* If we have ANY lookups we don't use the cache, so
* that the caller refreshes via the network. */
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("Ignoring cache for ANY lookup: %s", key_str);
- }
+ log_debug("Ignoring cache for ANY lookup: %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
c->n_miss++;
@@ -839,13 +823,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r
if (!first) {
/* If one question cannot be answered we need to refresh */
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("Cache miss for %s", key_str);
- }
+ log_debug("Cache miss for %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
c->n_miss++;
@@ -873,13 +852,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r
/* Note that we won't derive information for DS RRs from an NSEC, because we only cache NSEC RRs from
* the lower-zone of a zone cut, but the DS RRs are on the upper zone. */
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("NSEC NODATA cache hit for %s", key_str);
- }
+ log_debug("NSEC NODATA cache hit for %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
/* We only found an NSEC record that matches our name.
* If it says the type doesn't exist report
@@ -900,16 +874,10 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r
return 0;
}
- if (log_get_max_level() >= LOG_DEBUG) {
- r = dns_resource_key_to_string(key, &key_str);
- if (r < 0)
- return r;
-
- log_debug("%s cache hit for %s",
- n > 0 ? "Positive" :
- nxdomain ? "NXDOMAIN" : "NODATA",
- key_str);
- }
+ log_debug("%s cache hit for %s",
+ n > 0 ? "Positive" :
+ nxdomain ? "NXDOMAIN" : "NODATA",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
if (n <= 0) {
c->n_hit++;
@@ -1019,7 +987,7 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
if (r < 0)
return r;
- ancount ++;
+ ancount++;
}
}
@@ -1031,7 +999,6 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
void dns_cache_dump(DnsCache *cache, FILE *f) {
Iterator iterator;
DnsCacheItem *i;
- int r;
if (!cache)
return;
@@ -1057,14 +1024,9 @@ void dns_cache_dump(DnsCache *cache, FILE *f) {
fputs(t, f);
fputc('\n', f);
} else {
- _cleanup_free_ char *z = NULL;
- r = dns_resource_key_to_string(j->key, &z);
- if (r < 0) {
- log_oom();
- continue;
- }
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
- fputs(z, f);
+ fputs(dns_resource_key_to_string(j->key, key_str, sizeof key_str), f);
fputs(" -- ", f);
fputs(j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", f);
fputc('\n', f);
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-dnssec.c b/src/grp-resolve/systemd-resolved/resolved-dns-dnssec.c
index 7123d2d3a8..a54aed3a63 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-dnssec.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-dnssec.c
@@ -23,6 +23,7 @@
#include "alloc-util.h"
#include "dns-domain.h"
+#include "gcrypt-util.h"
#include "hexdecoct.h"
#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h"
@@ -126,19 +127,6 @@ int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max) {
#ifdef HAVE_GCRYPT
-static void initialize_libgcrypt(void) {
- const char *p;
-
- if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
- return;
-
- p = gcry_check_version("1.4.5");
- assert(p);
-
- gcry_control(GCRYCTL_DISABLE_SECMEM);
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
-}
-
static int rr_compare(const void *a, const void *b) {
DnsResourceRecord **x = (DnsResourceRecord**) a, **y = (DnsResourceRecord**) b;
size_t m;
@@ -479,7 +467,7 @@ static int dnssec_rrsig_prepare(DnsResourceRecord *rrsig) {
if (rrsig->rrsig.inception > rrsig->rrsig.expiration)
return -EINVAL;
- name = DNS_RESOURCE_KEY_NAME(rrsig->key);
+ name = dns_resource_key_name(rrsig->key);
n_key_labels = dns_name_count_labels(name);
if (n_key_labels < 0)
@@ -635,9 +623,9 @@ int dnssec_verify_rrset(
assert(rrsig->key->type == DNS_TYPE_RRSIG);
assert(dnskey->key->type == DNS_TYPE_DNSKEY);
- /* Verifies the the RRSet matching the specified "key" in "a",
+ /* Verifies that the RRSet matches the specified "key" in "a",
* using the signature "rrsig" and the key "dnskey". It's
- * assumed the RRSIG and DNSKEY match. */
+ * assumed that RRSIG and DNSKEY match. */
md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm);
if (md_algorithm == -EOPNOTSUPP) {
@@ -663,7 +651,7 @@ int dnssec_verify_rrset(
return 0;
}
- name = DNS_RESOURCE_KEY_NAME(key);
+ name = dns_resource_key_name(key);
/* Some keys may only appear signed in the zone apex, and are invalid anywhere else. (SOA, NS...) */
if (dns_type_apex_only(rrsig->rrsig.type_covered)) {
@@ -737,7 +725,7 @@ int dnssec_verify_rrset(
qsort_safe(list, n, sizeof(DnsResourceRecord*), rr_compare);
/* OK, the RRs are now in canonical order. Let's calculate the digest */
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
hash_size = gcry_md_get_algo_dlen(md_algorithm);
assert(hash_size > 0);
@@ -863,7 +851,7 @@ int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnske
if (dnssec_keytag(dnskey, false) != rrsig->rrsig.key_tag)
return 0;
- return dns_name_equal(DNS_RESOURCE_KEY_NAME(dnskey->key), rrsig->rrsig.signer);
+ return dns_name_equal(dns_resource_key_name(dnskey->key), rrsig->rrsig.signer);
}
int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig) {
@@ -879,7 +867,7 @@ int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig)
if (rrsig->rrsig.type_covered != key->type)
return 0;
- return dns_name_equal(DNS_RESOURCE_KEY_NAME(rrsig->key), DNS_RESOURCE_KEY_NAME(key));
+ return dns_name_equal(dns_resource_key_name(rrsig->key), dns_resource_key_name(key));
}
int dnssec_verify_rrset_search(
@@ -1070,7 +1058,7 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
if (dnssec_keytag(dnskey, mask_revoke) != ds->ds.key_tag)
return 0;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
md_algorithm = digest_to_gcrypt_md(ds->ds.digest_type);
if (md_algorithm < 0)
@@ -1082,7 +1070,7 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
if (ds->ds.digest_size != hash_size)
return 0;
- r = dnssec_canonicalize(DNS_RESOURCE_KEY_NAME(dnskey->key), owner_name, sizeof(owner_name));
+ r = dnssec_canonicalize(dns_resource_key_name(dnskey->key), owner_name, sizeof(owner_name));
if (r < 0)
return r;
@@ -1132,7 +1120,7 @@ int dnssec_verify_dnskey_by_ds_search(DnsResourceRecord *dnskey, DnsAnswer *vali
if (ds->key->class != dnskey->key->class)
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dnskey->key), DNS_RESOURCE_KEY_NAME(ds->key));
+ r = dns_name_equal(dns_resource_key_name(dnskey->key), dns_resource_key_name(ds->key));
if (r < 0)
return r;
if (r == 0)
@@ -1189,7 +1177,7 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
if (algorithm < 0)
return algorithm;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
hash_size = gcry_md_get_algo_dlen(algorithm);
assert(hash_size > 0);
@@ -1284,14 +1272,14 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsResourceRecord *nsec3) {
if (memcmp(rr->nsec3.salt, nsec3->nsec3.salt, rr->nsec3.salt_size) != 0)
return 0;
- a = DNS_RESOURCE_KEY_NAME(rr->key);
+ a = dns_resource_key_name(rr->key);
r = dns_name_parent(&a); /* strip off hash */
if (r < 0)
return r;
if (r == 0)
return 0;
- b = DNS_RESOURCE_KEY_NAME(nsec3->key);
+ b = dns_resource_key_name(nsec3->key);
r = dns_name_parent(&b); /* strip off hash */
if (r < 0)
return r;
@@ -1365,7 +1353,7 @@ static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecR
* any NSEC3 RR in the response. Any NSEC3 record will do as all NSEC3
* records from a given zone in a response must use the same
* parameters. */
- zone = DNS_RESOURCE_KEY_NAME(key);
+ zone = dns_resource_key_name(key);
for (;;) {
DNS_ANSWER_FOREACH_FLAGS(zone_rr, flags, answer) {
r = nsec3_is_good(zone_rr, NULL);
@@ -1374,7 +1362,7 @@ static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecR
if (r == 0)
continue;
- r = dns_name_equal_skip(DNS_RESOURCE_KEY_NAME(zone_rr->key), 1, zone);
+ r = dns_name_equal_skip(dns_resource_key_name(zone_rr->key), 1, zone);
if (r < 0)
return r;
if (r > 0)
@@ -1394,7 +1382,7 @@ static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecR
found_zone:
/* Second step, find the closest encloser NSEC3 RR in 'answer' that matches 'key' */
- p = DNS_RESOURCE_KEY_NAME(key);
+ p = dns_resource_key_name(key);
for (;;) {
_cleanup_free_ char *hashed_domain = NULL;
@@ -1417,7 +1405,7 @@ found_zone:
if (enclosure_rr->nsec3.next_hashed_name_size != (size_t) hashed_size)
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(enclosure_rr->key), hashed_domain);
+ r = dns_name_equal(dns_resource_key_name(enclosure_rr->key), hashed_domain);
if (r < 0)
return r;
if (r > 0) {
@@ -1516,7 +1504,7 @@ found_closest_encloser:
if (r < 0)
return r;
- r = dns_name_between(DNS_RESOURCE_KEY_NAME(rr->key), next_closer_domain, next_hashed_domain);
+ r = dns_name_between(dns_resource_key_name(rr->key), next_closer_domain, next_hashed_domain);
if (r < 0)
return r;
if (r > 0) {
@@ -1528,7 +1516,7 @@ found_closest_encloser:
no_closer = true;
}
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), wildcard_domain);
+ r = dns_name_equal(dns_resource_key_name(rr->key), wildcard_domain);
if (r < 0)
return r;
if (r > 0) {
@@ -1537,7 +1525,7 @@ found_closest_encloser:
wildcard_rr = rr;
}
- r = dns_name_between(DNS_RESOURCE_KEY_NAME(rr->key), wildcard_domain, next_hashed_domain);
+ r = dns_name_between(dns_resource_key_name(rr->key), wildcard_domain, next_hashed_domain);
if (r < 0)
return r;
if (r > 0) {
@@ -1616,7 +1604,7 @@ static int dnssec_nsec_wildcard_equal(DnsResourceRecord *rr, const char *name) {
if (rr->n_skip_labels_source != 1)
return 0;
- n = DNS_RESOURCE_KEY_NAME(rr->key);
+ n = dns_resource_key_name(rr->key);
r = dns_label_unescape(&n, label, sizeof(label));
if (r <= 0)
return r;
@@ -1655,7 +1643,7 @@ static int dnssec_nsec_in_path(DnsResourceRecord *rr, const char *name) {
return r;
/* If the name we we are interested in is not a prefix of the common suffix of the NSEC RR's owner and next domain names, then we can't say anything either. */
- r = dns_name_common_suffix(DNS_RESOURCE_KEY_NAME(rr->key), rr->nsec.next_domain_name, &common_suffix);
+ r = dns_name_common_suffix(dns_resource_key_name(rr->key), rr->nsec.next_domain_name, &common_suffix);
if (r < 0)
return r;
@@ -1674,7 +1662,7 @@ static int dnssec_nsec_from_parent_zone(DnsResourceRecord *rr, const char *name)
if (r <= 0)
return r;
- r = dns_name_equal(name, DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_name_equal(name, dns_resource_key_name(rr->key));
if (r <= 0)
return r;
@@ -1697,7 +1685,7 @@ static int dnssec_nsec_covers(DnsResourceRecord *rr, const char *name) {
/* Checks whether the "Next Closer" is witin the space covered by the specified RR. */
- r = dns_name_common_suffix(DNS_RESOURCE_KEY_NAME(rr->key), rr->nsec.next_domain_name, &common_suffix);
+ r = dns_name_common_suffix(dns_resource_key_name(rr->key), rr->nsec.next_domain_name, &common_suffix);
if (r < 0)
return r;
@@ -1718,7 +1706,7 @@ static int dnssec_nsec_covers(DnsResourceRecord *rr, const char *name) {
/* p is now the "Next Closer". */
- return dns_name_between(DNS_RESOURCE_KEY_NAME(rr->key), p, rr->nsec.next_domain_name);
+ return dns_name_between(dns_resource_key_name(rr->key), p, rr->nsec.next_domain_name);
}
static int dnssec_nsec_covers_wildcard(DnsResourceRecord *rr, const char *name) {
@@ -1737,7 +1725,7 @@ static int dnssec_nsec_covers_wildcard(DnsResourceRecord *rr, const char *name)
* NSEC yyy.zzz.xoo.bar → bar: indicates that a number of wildcards don#t exist either...
*/
- r = dns_name_common_suffix(DNS_RESOURCE_KEY_NAME(rr->key), rr->nsec.next_domain_name, &common_suffix);
+ r = dns_name_common_suffix(dns_resource_key_name(rr->key), rr->nsec.next_domain_name, &common_suffix);
if (r < 0)
return r;
@@ -1746,8 +1734,8 @@ static int dnssec_nsec_covers_wildcard(DnsResourceRecord *rr, const char *name)
if (r <= 0)
return r;
- wc = strjoina("*.", common_suffix, NULL);
- return dns_name_between(DNS_RESOURCE_KEY_NAME(rr->key), wc, rr->nsec.next_domain_name);
+ wc = strjoina("*.", common_suffix);
+ return dns_name_between(dns_resource_key_name(rr->key), wc, rr->nsec.next_domain_name);
}
int dnssec_nsec_test(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated, uint32_t *ttl) {
@@ -1762,7 +1750,7 @@ int dnssec_nsec_test(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *r
/* Look for any NSEC/NSEC3 RRs that say something about the specified key. */
- name = DNS_RESOURCE_KEY_NAME(key);
+ name = dns_resource_key_name(key);
DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
@@ -1782,7 +1770,7 @@ int dnssec_nsec_test(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *r
continue;
/* Check if this is a direct match. If so, we have encountered a NODATA case */
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), name);
+ r = dns_name_equal(dns_resource_key_name(rr->key), name);
if (r < 0)
return r;
if (r == 0) {
@@ -1912,7 +1900,7 @@ static int dnssec_nsec_test_enclosed(DnsAnswer *answer, uint16_t type, const cha
if (r == 0)
continue;
- r = dns_name_between(DNS_RESOURCE_KEY_NAME(rr->key), name, rr->nsec.next_domain_name);
+ r = dns_name_between(dns_resource_key_name(rr->key), name, rr->nsec.next_domain_name);
if (r < 0)
return r;
@@ -1955,7 +1943,7 @@ static int dnssec_nsec_test_enclosed(DnsAnswer *answer, uint16_t type, const cha
if (r < 0)
return r;
- r = dns_name_between(DNS_RESOURCE_KEY_NAME(rr->key), hashed_domain, next_hashed_domain);
+ r = dns_name_between(dns_resource_key_name(rr->key), hashed_domain, next_hashed_domain);
if (r < 0)
return r;
@@ -1989,7 +1977,7 @@ static int dnssec_test_positive_wildcard_nsec3(
/* Run a positive NSEC3 wildcard proof. Specifically:
*
- * A proof that the the "next closer" of the generating wildcard does not exist.
+ * A proof that the "next closer" of the generating wildcard does not exist.
*
* Note a key difference between the NSEC3 and NSEC versions of the proof. NSEC RRs don't have to exist for
* empty non-transients. NSEC3 RRs however have to. This means it's sufficient to check if the next closer name
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-packet.c b/src/grp-resolve/systemd-resolved/resolved-dns-packet.c
index c940dd8929..b7907bb511 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-packet.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-packet.c
@@ -28,6 +28,19 @@
#define EDNS0_OPT_DO (1<<15)
+typedef struct DnsPacketRewinder {
+ DnsPacket *packet;
+ size_t saved_rindex;
+} DnsPacketRewinder;
+
+static void rewind_dns_packet(DnsPacketRewinder *rewinder) {
+ if (rewinder->packet)
+ dns_packet_rewind(rewinder->packet, rewinder->saved_rindex);
+}
+
+#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) {
DnsPacket *p;
size_t a;
@@ -431,8 +444,7 @@ int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_
((uint8_t*) d)[0] = (uint8_t) size;
- if (size > 0)
- memcpy(((uint8_t*) d) + 1, s, size);
+ memcpy_safe(((uint8_t*) d) + 1, s, size);
return 0;
}
@@ -565,7 +577,7 @@ int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start)
saved_size = p->size;
- r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, true, NULL);
+ r = dns_packet_append_name(p, dns_resource_key_name(k), true, true, NULL);
if (r < 0)
goto fail;
@@ -1072,6 +1084,18 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL);
break;
+ case DNS_TYPE_CAA:
+ r = dns_packet_append_uint8(p, rr->caa.flags, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_string(p, rr->caa.tag, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_blob(p, rr->caa.value, rr->caa.value_size, NULL);
+ break;
+
case DNS_TYPE_OPT:
case DNS_TYPE_OPENPGPKEY:
case _DNS_TYPE_INVALID: /* unparseable */
@@ -1230,80 +1254,67 @@ int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
}
int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
- size_t saved_rindex;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
const void *d;
char *t;
uint8_t c;
int r;
assert(p);
-
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
r = dns_packet_read_uint8(p, &c, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read(p, c, &d, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (memchr(d, 0, c)) {
- r = -EBADMSG;
- goto fail;
- }
+ if (memchr(d, 0, c))
+ return -EBADMSG;
t = strndup(d, c);
- if (!t) {
- r = -ENOMEM;
- goto fail;
- }
+ if (!t)
+ return -ENOMEM;
if (!utf8_is_valid(t)) {
free(t);
- r = -EBADMSG;
- goto fail;
+ return -EBADMSG;
}
*ret = t;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
- size_t saved_rindex;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
uint8_t c;
int r;
assert(p);
-
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
r = dns_packet_read_uint8(p, &c, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read(p, c, ret, NULL);
if (r < 0)
- goto fail;
+ return r;
if (size)
*size = c;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
int dns_packet_read_name(
@@ -1312,7 +1323,8 @@ int dns_packet_read_name(
bool allow_compression,
size_t *start) {
- size_t saved_rindex, after_rindex = 0, jump_barrier;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
+ size_t after_rindex = 0, jump_barrier;
_cleanup_free_ char *ret = NULL;
size_t n = 0, allocated = 0;
bool first = true;
@@ -1320,19 +1332,18 @@ int dns_packet_read_name(
assert(p);
assert(_ret);
+ INIT_REWINDER(rewinder, p);
+ jump_barrier = p->rindex;
if (p->refuse_compression)
allow_compression = false;
- saved_rindex = p->rindex;
- jump_barrier = p->rindex;
-
for (;;) {
uint8_t c, d;
r = dns_packet_read_uint8(p, &c, NULL);
if (r < 0)
- goto fail;
+ return r;
if (c == 0)
/* End of name */
@@ -1343,12 +1354,10 @@ int dns_packet_read_name(
/* Literal label */
r = dns_packet_read(p, c, (const void**) &label, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
- r = -ENOMEM;
- goto fail;
- }
+ if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+ return -ENOMEM;
if (first)
first = false;
@@ -1357,7 +1366,7 @@ int dns_packet_read_name(
r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
if (r < 0)
- goto fail;
+ return r;
n += r;
continue;
@@ -1367,13 +1376,11 @@ int dns_packet_read_name(
/* Pointer */
r = dns_packet_read_uint8(p, &d, NULL);
if (r < 0)
- goto fail;
+ return r;
ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
- if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
- r = -EBADMSG;
- goto fail;
- }
+ if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier)
+ return -EBADMSG;
if (after_rindex == 0)
after_rindex = p->rindex;
@@ -1381,16 +1388,12 @@ int dns_packet_read_name(
/* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
jump_barrier = ptr;
p->rindex = ptr;
- } else {
- r = -EBADMSG;
- goto fail;
- }
+ } else
+ return -EBADMSG;
}
- if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
- r = -ENOMEM;
- goto fail;
- }
+ if (!GREEDY_REALLOC(ret, allocated, n + 1))
+ return -ENOMEM;
ret[n] = 0;
@@ -1401,13 +1404,10 @@ int dns_packet_read_name(
ret = NULL;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
@@ -1417,32 +1417,31 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
uint8_t bit = 0;
unsigned i;
bool found = false;
- size_t saved_rindex;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
int r;
assert(p);
assert(types);
-
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
r = bitmap_ensure_allocated(types);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &window, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &length, NULL);
if (r < 0)
- goto fail;
+ return r;
if (length == 0 || length > 32)
return -EBADMSG;
r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
if (r < 0)
- goto fail;
+ return r;
for (i = 0; i < length; i++) {
uint8_t bitmask = 1 << 7;
@@ -1467,10 +1466,10 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
r = bitmap_set(*types, n);
if (r < 0)
- goto fail;
+ return r;
}
- bit ++;
+ bit++;
bitmask >>= 1;
}
}
@@ -1479,70 +1478,61 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
return -EBADMSG;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
- size_t saved_rindex;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
int r;
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
- while (p->rindex < saved_rindex + size) {
+ while (p->rindex < rewinder.saved_rindex + size) {
r = dns_packet_read_type_window(p, types, NULL);
if (r < 0)
- goto fail;
+ return r;
/* don't read past end of current RR */
- if (p->rindex > saved_rindex + size) {
- r = -EBADMSG;
- goto fail;
- }
+ if (p->rindex > rewinder.saved_rindex + size)
+ return -EBADMSG;
}
- if (p->rindex != saved_rindex + size) {
- r = -EBADMSG;
- goto fail;
- }
+ if (p->rindex != rewinder.saved_rindex + size)
+ return -EBADMSG;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flush, size_t *start) {
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
_cleanup_free_ char *name = NULL;
bool cache_flush = false;
uint16_t class, type;
DnsResourceKey *key;
- size_t saved_rindex;
int r;
assert(p);
assert(ret);
-
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
r = dns_packet_read_name(p, &name, true, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint16(p, &type, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint16(p, &class, NULL);
if (r < 0)
- goto fail;
+ return r;
if (p->protocol == DNS_PROTOCOL_MDNS) {
/* See RFC6762, Section 10.2 */
@@ -1554,10 +1544,8 @@ int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flus
}
key = dns_resource_key_new_consume(class, type, name);
- if (!key) {
- r = -ENOMEM;
- goto fail;
- }
+ if (!key)
+ return -ENOMEM;
name = NULL;
*ret = key;
@@ -1565,12 +1553,10 @@ int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flus
if (ret_cache_flush)
*ret_cache_flush = cache_flush;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
static bool loc_size_ok(uint8_t size) {
@@ -1582,7 +1568,8 @@ static bool loc_size_ok(uint8_t size) {
int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_flush, size_t *start) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
- size_t saved_rindex, offset;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
+ size_t offset;
uint16_t rdlength;
bool cache_flush;
int r;
@@ -1590,27 +1577,22 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
assert(p);
assert(ret);
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
r = dns_packet_read_key(p, &key, &cache_flush, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (!dns_class_is_valid_rr(key->class)||
- !dns_type_is_valid_rr(key->type)) {
- r = -EBADMSG;
- goto fail;
- }
+ if (!dns_class_is_valid_rr(key->class) || !dns_type_is_valid_rr(key->type))
+ return -EBADMSG;
rr = dns_resource_record_new(key);
- if (!rr) {
- r = -ENOMEM;
- goto fail;
- }
+ if (!rr)
+ return -ENOMEM;
r = dns_packet_read_uint32(p, &rr->ttl, NULL);
if (r < 0)
- goto fail;
+ return r;
/* RFC 2181, Section 8, suggests to
* treat a TTL with the MSB set as a zero TTL. */
@@ -1619,12 +1601,10 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
r = dns_packet_read_uint16(p, &rdlength, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (p->rindex + rdlength > p->size) {
- r = -EBADMSG;
- goto fail;
- }
+ if (p->rindex + rdlength > p->size)
+ return -EBADMSG;
offset = p->rindex;
@@ -1633,13 +1613,13 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_SRV:
r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
break;
@@ -1653,7 +1633,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_HINFO:
r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
break;
@@ -1709,27 +1689,27 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_SOA:
r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
break;
@@ -1737,7 +1717,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_MX:
r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
break;
@@ -1748,49 +1728,43 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
r = dns_packet_read_uint8(p, &t, &pos);
if (r < 0)
- goto fail;
+ return r;
if (t == 0) {
rr->loc.version = t;
r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (!loc_size_ok(rr->loc.size)) {
- r = -EBADMSG;
- goto fail;
- }
+ if (!loc_size_ok(rr->loc.size))
+ return -EBADMSG;
r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (!loc_size_ok(rr->loc.horiz_pre)) {
- r = -EBADMSG;
- goto fail;
- }
+ if (!loc_size_ok(rr->loc.horiz_pre))
+ return -EBADMSG;
r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (!loc_size_ok(rr->loc.vert_pre)) {
- r = -EBADMSG;
- goto fail;
- }
+ if (!loc_size_ok(rr->loc.vert_pre))
+ return -EBADMSG;
r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
if (r < 0)
- goto fail;
+ return r;
break;
} else {
@@ -1803,122 +1777,114 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_DS:
r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_memdup(p, rdlength - 4,
&rr->ds.digest, &rr->ds.digest_size,
NULL);
if (r < 0)
- goto fail;
+ return r;
- if (rr->ds.digest_size <= 0) {
+ if (rr->ds.digest_size <= 0)
/* the accepted size depends on the algorithm, but for now
just ensure that the value is greater than zero */
- r = -EBADMSG;
- goto fail;
- }
+ return -EBADMSG;
break;
case DNS_TYPE_SSHFP:
r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_memdup(p, rdlength - 2,
&rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
NULL);
- if (rr->sshfp.fingerprint_size <= 0) {
+ if (rr->sshfp.fingerprint_size <= 0)
/* the accepted size depends on the algorithm, but for now
just ensure that the value is greater than zero */
- r = -EBADMSG;
- goto fail;
- }
+ return -EBADMSG;
break;
case DNS_TYPE_DNSKEY:
r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_memdup(p, rdlength - 4,
&rr->dnskey.key, &rr->dnskey.key_size,
NULL);
- if (rr->dnskey.key_size <= 0) {
+ if (rr->dnskey.key_size <= 0)
/* the accepted size depends on the algorithm, but for now
just ensure that the value is greater than zero */
- r = -EBADMSG;
- goto fail;
- }
+ return -EBADMSG;
break;
case DNS_TYPE_RRSIG:
r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
&rr->rrsig.signature, &rr->rrsig.signature_size,
NULL);
- if (rr->rrsig.signature_size <= 0) {
+ if (rr->rrsig.signature_size <= 0)
/* the accepted size depends on the algorithm, but for now
just ensure that the value is greater than zero */
- r = -EBADMSG;
- goto fail;
- }
+ return -EBADMSG;
break;
@@ -1933,11 +1899,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
- if (r < 0)
- goto fail;
/* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
* is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
@@ -1950,41 +1914,39 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
if (r < 0)
- goto fail;
+ return r;
/* this may be zero */
r = dns_packet_read_uint8(p, &size, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &size, NULL);
if (r < 0)
- goto fail;
+ return r;
- if (size <= 0) {
- r = -EBADMSG;
- goto fail;
- }
+ if (size <= 0)
+ return -EBADMSG;
- r = dns_packet_read_memdup(p, size, &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size, NULL);
+ r = dns_packet_read_memdup(p, size,
+ &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size,
+ NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
- if (r < 0)
- goto fail;
/* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
@@ -1994,25 +1956,39 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_TLSA:
r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
if (r < 0)
- goto fail;
+ return r;
r = dns_packet_read_memdup(p, rdlength - 3,
&rr->tlsa.data, &rr->tlsa.data_size,
NULL);
- if (rr->tlsa.data_size <= 0) {
+
+ if (rr->tlsa.data_size <= 0)
/* the accepted size depends on the algorithm, but for now
just ensure that the value is greater than zero */
- r = -EBADMSG;
- goto fail;
- }
+ return -EBADMSG;
+
+ break;
+
+ case DNS_TYPE_CAA:
+ r = dns_packet_read_uint8(p, &rr->caa.flags, NULL);
+ if (r < 0)
+ return r;
+
+ r = dns_packet_read_string(p, &rr->caa.tag, NULL);
+ if (r < 0)
+ return r;
+
+ r = dns_packet_read_memdup(p,
+ rdlength + offset - p->rindex,
+ &rr->caa.value, &rr->caa.value_size, NULL);
break;
@@ -2021,16 +1997,13 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
default:
unparseable:
r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
- if (r < 0)
- goto fail;
+
break;
}
if (r < 0)
- goto fail;
- if (p->rindex != offset + rdlength) {
- r = -EBADMSG;
- goto fail;
- }
+ return r;
+ if (p->rindex != offset + rdlength)
+ return -EBADMSG;
*ret = rr;
rr = NULL;
@@ -2038,12 +2011,10 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
if (ret_cache_flush)
*ret_cache_flush = cache_flush;
if (start)
- *start = saved_rindex;
+ *start = rewinder.saved_rindex;
+ CANCEL_REWINDER(rewinder);
return 0;
-fail:
- dns_packet_rewind(p, saved_rindex);
- return r;
}
static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
@@ -2091,23 +2062,21 @@ static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
int dns_packet_extract(DnsPacket *p) {
_cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
- size_t saved_rindex;
+ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {};
unsigned n, i;
int r;
if (p->extracted)
return 0;
- saved_rindex = p->rindex;
+ INIT_REWINDER(rewinder, p);
dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
n = DNS_PACKET_QDCOUNT(p);
if (n > 0) {
question = dns_question_new(n);
- if (!question) {
- r = -ENOMEM;
- goto finish;
- }
+ if (!question)
+ return -ENOMEM;
for (i = 0; i < n; i++) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
@@ -2115,21 +2084,17 @@ int dns_packet_extract(DnsPacket *p) {
r = dns_packet_read_key(p, &key, &cache_flush, NULL);
if (r < 0)
- goto finish;
+ return r;
- if (cache_flush) {
- r = -EBADMSG;
- goto finish;
- }
+ if (cache_flush)
+ return -EBADMSG;
- if (!dns_type_is_valid_query(key->type)) {
- r = -EBADMSG;
- goto finish;
- }
+ if (!dns_type_is_valid_query(key->type))
+ return -EBADMSG;
r = dns_question_add(question, key);
if (r < 0)
- goto finish;
+ return r;
}
}
@@ -2139,10 +2104,8 @@ int dns_packet_extract(DnsPacket *p) {
bool bad_opt = false;
answer = dns_answer_new(n);
- if (!answer) {
- r = -ENOMEM;
- goto finish;
- }
+ if (!answer)
+ return -ENOMEM;
for (i = 0; i < n; i++) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
@@ -2150,7 +2113,7 @@ int dns_packet_extract(DnsPacket *p) {
r = dns_packet_read_rr(p, &rr, &cache_flush, NULL);
if (r < 0)
- goto finish;
+ return r;
/* Try to reduce memory usage a bit */
if (previous)
@@ -2167,7 +2130,7 @@ int dns_packet_extract(DnsPacket *p) {
continue;
}
- if (!dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key))) {
+ if (!dns_name_is_root(dns_resource_key_name(rr->key))) {
/* If the OPT RR is not owned by the root domain, then it is bad, let's ignore
* it. */
log_debug("OPT RR is not owned by root domain, ignoring.");
@@ -2213,7 +2176,7 @@ int dns_packet_extract(DnsPacket *p) {
(i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) |
(p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0));
if (r < 0)
- goto finish;
+ return r;
}
/* Remember this RR, so that we potentically can merge it's ->key object with the next RR. Note
@@ -2234,11 +2197,8 @@ int dns_packet_extract(DnsPacket *p) {
p->extracted = true;
- r = 0;
-
-finish:
- p->rindex = saved_rindex;
- return r;
+ /* no CANCEL, always rewind */
+ return 0;
}
int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-packet.h b/src/grp-resolve/systemd-resolved/resolved-dns-packet.h
index 0bf34d270c..416335d0a2 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-packet.h
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-packet.h
@@ -262,11 +262,9 @@ static inline uint64_t SD_RESOLVED_FLAGS_MAKE(DnsProtocol protocol, int family,
return f|(family == AF_INET6 ? SD_RESOLVED_LLMNR_IPV6 : SD_RESOLVED_LLMNR_IPV4);
case DNS_PROTOCOL_MDNS:
- return family == AF_INET6 ? SD_RESOLVED_MDNS_IPV6 : SD_RESOLVED_MDNS_IPV4;
+ return f|(family == AF_INET6 ? SD_RESOLVED_MDNS_IPV6 : SD_RESOLVED_MDNS_IPV4);
default:
- break;
+ return f;
}
-
- return 0;
}
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-query.c b/src/grp-resolve/systemd-resolved/resolved-dns-query.c
index a378b2b7f7..ea04e58d61 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-query.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-query.c
@@ -62,6 +62,7 @@ static void dns_query_candidate_stop(DnsQueryCandidate *c) {
while ((t = set_steal_first(c->transactions))) {
set_remove(t->notify_query_candidates, c);
+ set_remove(t->notify_query_candidates_done, c);
dns_transaction_gc(t);
}
}
@@ -139,6 +140,10 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource
if (r < 0)
goto gc;
+ r = set_ensure_allocated(&t->notify_query_candidates_done, NULL);
+ if (r < 0)
+ goto gc;
+
r = set_put(t->notify_query_candidates, c);
if (r < 0)
goto gc;
@@ -421,6 +426,7 @@ int dns_query_new(
DnsResourceKey *key;
bool good = false;
int r;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
assert(m);
@@ -471,31 +477,20 @@ int dns_query_new(
q->answer_family = AF_UNSPEC;
/* First dump UTF8 question */
- DNS_QUESTION_FOREACH(key, question_utf8) {
- _cleanup_free_ char *p = NULL;
-
- r = dns_resource_key_to_string(key, &p);
- if (r < 0)
- return r;
-
- log_debug("Looking up RR for %s.", strstrip(p));
- }
+ DNS_QUESTION_FOREACH(key, question_utf8)
+ log_debug("Looking up RR for %s.",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
/* And then dump the IDNA question, but only what hasn't been dumped already through the UTF8 question. */
DNS_QUESTION_FOREACH(key, question_idna) {
- _cleanup_free_ char *p = NULL;
-
r = dns_question_contains(question_utf8, key);
if (r < 0)
return r;
if (r > 0)
continue;
- r = dns_resource_key_to_string(key, &p);
- if (r < 0)
- return r;
-
- log_debug("Looking up IDNA RR for %s.", strstrip(p));
+ log_debug("Looking up IDNA RR for %s.",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
}
LIST_PREPEND(queries, m->dns_queries, q);
@@ -815,7 +810,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
switch (t->state) {
case DNS_TRANSACTION_SUCCESS: {
- /* We found a successfuly reply, merge it into the answer */
+ /* We found a successfully reply, merge it into the answer */
r = dns_answer_extend(&q->answer, t->answer);
if (r < 0)
goto fail;
@@ -937,7 +932,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
assert(q);
- q->n_cname_redirects ++;
+ q->n_cname_redirects++;
if (q->n_cname_redirects > CNAME_MAX)
return -ELOOP;
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-question.c b/src/grp-resolve/systemd-resolved/resolved-dns-question.c
index 8e452e79a4..c8b502d1cd 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-question.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-question.c
@@ -145,7 +145,7 @@ int dns_question_is_valid_for_query(DnsQuestion *q) {
if (q->n_keys > 65535)
return 0;
- name = DNS_RESOURCE_KEY_NAME(q->keys[0]);
+ name = dns_resource_key_name(q->keys[0]);
if (!name)
return 0;
@@ -154,7 +154,7 @@ int dns_question_is_valid_for_query(DnsQuestion *q) {
assert(q->keys[i]);
if (i > 0) {
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
+ r = dns_name_equal(dns_resource_key_name(q->keys[i]), name);
if (r <= 0)
return r;
}
@@ -235,7 +235,7 @@ int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname,
if (cname->key->type == DNS_TYPE_CNAME)
d = cname->cname.name;
else {
- r = dns_name_change_suffix(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname->key), cname->dname.name, &destination);
+ r = dns_name_change_suffix(dns_resource_key_name(key), dns_resource_key_name(cname->key), cname->dname.name, &destination);
if (r < 0)
return r;
if (r == 0)
@@ -244,7 +244,7 @@ int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname,
d = destination;
}
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(key), d);
+ r = dns_name_equal(dns_resource_key_name(key), d);
if (r < 0)
return r;
@@ -291,7 +291,7 @@ const char *dns_question_first_name(DnsQuestion *q) {
if (q->n_keys < 1)
return NULL;
- return DNS_RESOURCE_KEY_NAME(q->keys[0]);
+ return dns_resource_key_name(q->keys[0]);
}
int dns_question_new_address(DnsQuestion **ret, int family, const char *name, bool convert_idna) {
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-rr.c b/src/grp-resolve/systemd-resolved/resolved-dns-rr.c
index 40f8e28dfd..6a29a93a26 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-rr.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-rr.c
@@ -22,6 +22,7 @@
#include "alloc-util.h"
#include "dns-domain.h"
#include "dns-type.h"
+#include "escape.h"
#include "hexdecoct.h"
#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h"
@@ -65,7 +66,7 @@ DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const D
DnsResourceKey *k;
char *destination = NULL;
- r = dns_name_change_suffix(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname->key), cname->dname.name, &destination);
+ r = dns_name_change_suffix(dns_resource_key_name(key), dns_resource_key_name(cname->key), cname->dname.name, &destination);
if (r < 0)
return NULL;
if (r == 0)
@@ -95,7 +96,7 @@ int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key
return 0;
}
- r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), name, &joined);
+ r = dns_name_concat(dns_resource_key_name(key), name, &joined);
if (r < 0)
return r;
@@ -157,6 +158,23 @@ DnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
return NULL;
}
+const char* dns_resource_key_name(const DnsResourceKey *key) {
+ const char *name;
+
+ if (!key)
+ return NULL;
+
+ if (key->_name)
+ name = key->_name;
+ else
+ name = (char*) key + sizeof(DnsResourceKey);
+
+ if (dns_name_is_root(name))
+ return ".";
+ else
+ return name;
+}
+
bool dns_resource_key_is_address(const DnsResourceKey *key) {
assert(key);
@@ -171,7 +189,7 @@ int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
if (a == b)
return 1;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
+ r = dns_name_equal(dns_resource_key_name(a), dns_resource_key_name(b));
if (r <= 0)
return r;
@@ -203,18 +221,18 @@ int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr,
if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
return 0;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
+ r = dns_name_equal(dns_resource_key_name(rr->key), dns_resource_key_name(key));
if (r != 0)
return r;
if (search_domain) {
_cleanup_free_ char *joined = NULL;
- r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), search_domain, &joined);
+ r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined);
if (r < 0)
return r;
- return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), joined);
+ return dns_name_equal(dns_resource_key_name(rr->key), joined);
}
return 0;
@@ -230,9 +248,9 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
return 0;
if (cname->type == DNS_TYPE_CNAME)
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname));
+ r = dns_name_equal(dns_resource_key_name(key), dns_resource_key_name(cname));
else if (cname->type == DNS_TYPE_DNAME)
- r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname));
+ r = dns_name_endswith(dns_resource_key_name(key), dns_resource_key_name(cname));
else
return 0;
@@ -242,14 +260,14 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
if (search_domain) {
_cleanup_free_ char *joined = NULL;
- r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), search_domain, &joined);
+ r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined);
if (r < 0)
return r;
if (cname->type == DNS_TYPE_CNAME)
- return dns_name_equal(joined, DNS_RESOURCE_KEY_NAME(cname));
+ return dns_name_equal(joined, dns_resource_key_name(cname));
else if (cname->type == DNS_TYPE_DNAME)
- return dns_name_endswith(joined, DNS_RESOURCE_KEY_NAME(cname));
+ return dns_name_endswith(joined, dns_resource_key_name(cname));
}
return 0;
@@ -267,7 +285,7 @@ int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *
if (soa->type != DNS_TYPE_SOA)
return 0;
- return dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(soa));
+ return dns_name_endswith(dns_resource_key_name(key), dns_resource_key_name(soa));
}
static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
@@ -275,7 +293,7 @@ static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
assert(k);
- dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), state);
+ dns_name_hash_func(dns_resource_key_name(k), state);
siphash24_compress(&k->class, sizeof(k->class), state);
siphash24_compress(&k->type, sizeof(k->type), state);
}
@@ -284,7 +302,7 @@ static int dns_resource_key_compare_func(const void *a, const void *b) {
const DnsResourceKey *x = a, *y = b;
int ret;
- ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
+ ret = dns_name_compare_func(dns_resource_key_name(x), dns_resource_key_name(y));
if (ret != 0)
return ret;
@@ -306,32 +324,22 @@ const struct hash_ops dns_resource_key_hash_ops = {
.compare = dns_resource_key_compare_func
};
-int dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
- char cbuf[strlen("CLASS") + DECIMAL_STR_MAX(uint16_t)], tbuf[strlen("TYPE") + DECIMAL_STR_MAX(uint16_t)];
- const char *c, *t, *n;
- char *s;
+char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size) {
+ const char *c, *t;
+ char *ans = buf;
/* If we cannot convert the CLASS/TYPE into a known string,
use the format recommended by RFC 3597, Section 5. */
c = dns_class_to_string(key->class);
- if (!c) {
- sprintf(cbuf, "CLASS%u", key->class);
- c = cbuf;
- }
-
t = dns_type_to_string(key->type);
- if (!t){
- sprintf(tbuf, "TYPE%u", key->type);
- t = tbuf;
- }
- n = DNS_RESOURCE_KEY_NAME(key);
- if (asprintf(&s, "%s%s %s %-5s", n, endswith(n, ".") ? "" : ".", c, t) < 0)
- return -ENOMEM;
+ snprintf(buf, buf_size, "%s %s%s%.0u %s%s%.0u",
+ dns_resource_key_name(key),
+ c ?: "", c ? "" : "CLASS", c ? 0 : key->class,
+ t ?: "", t ? "" : "TYPE", t ? 0 : key->class);
- *ret = s;
- return 0;
+ return ans;
}
bool dns_resource_key_reduce(DnsResourceKey **a, DnsResourceKey **b) {
@@ -490,6 +498,11 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
free(rr->tlsa.data);
break;
+ case DNS_TYPE_CAA:
+ free(rr->caa.tag);
+ free(rr->caa.value);
+ break;
+
case DNS_TYPE_OPENPGPKEY:
default:
free(rr->generic.data);
@@ -697,6 +710,12 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
a->tlsa.matching_type == b->tlsa.matching_type &&
FIELD_EQUAL(a->tlsa, b->tlsa, data);
+ case DNS_TYPE_CAA:
+ return a->caa.flags == b->caa.flags &&
+ streq(a->caa.tag, b->caa.tag) &&
+ FIELD_EQUAL(a->caa, b->caa, value);
+
+ case DNS_TYPE_OPENPGPKEY:
default:
return FIELD_EQUAL(a->generic, b->generic, data);
}
@@ -818,8 +837,8 @@ static char *format_txt(DnsTxtItem *first) {
}
const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
- _cleanup_free_ char *k = NULL, *t = NULL;
- char *s;
+ _cleanup_free_ char *t = NULL;
+ char *s, k[DNS_RESOURCE_KEY_STRING_MAX];
int r;
assert(rr);
@@ -827,9 +846,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
if (rr->to_string)
return rr->to_string;
- r = dns_resource_key_to_string(rr->key, &k);
- if (r < 0)
- return NULL;
+ dns_resource_key_to_string(rr->key, k, sizeof(k));
switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
@@ -966,7 +983,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
case DNS_TYPE_DNSKEY: {
_cleanup_free_ char *alg = NULL;
char *ss;
- int n, n1;
+ int n;
uint16_t key_tag;
key_tag = dnssec_keytag(rr, true);
@@ -975,9 +992,8 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
if (r < 0)
return NULL;
- r = asprintf(&s, "%s %n%u %u %s %n",
+ r = asprintf(&s, "%s %u %u %s %n",
k,
- &n1,
rr->dnskey.flags,
rr->dnskey.protocol,
alg,
@@ -992,14 +1008,12 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
return NULL;
r = asprintf(&ss, "%s\n"
- "%*s-- Flags:%s%s%s\n"
- "%*s-- Key tag: %u",
+ " -- Flags:%s%s%s\n"
+ " -- Key tag: %u",
s,
- n1, "",
rr->dnskey.flags & DNSKEY_FLAG_SEP ? " SEP" : "",
rr->dnskey.flags & DNSKEY_FLAG_REVOKE ? " REVOKE" : "",
rr->dnskey.flags & DNSKEY_FLAG_ZONE_KEY ? " ZONE_KEY" : "",
- n1, "",
key_tag);
if (r < 0)
return NULL;
@@ -1102,40 +1116,52 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
case DNS_TYPE_TLSA: {
const char *cert_usage, *selector, *matching_type;
- char *ss;
- int n;
cert_usage = tlsa_cert_usage_to_string(rr->tlsa.cert_usage);
selector = tlsa_selector_to_string(rr->tlsa.selector);
matching_type = tlsa_matching_type_to_string(rr->tlsa.matching_type);
- r = asprintf(&s, "%s %u %u %u %n",
+ t = hexmem(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size);
+ if (!t)
+ return NULL;
+
+ r = asprintf(&s,
+ "%s %u %u %u %s\n"
+ " -- Cert. usage: %s\n"
+ " -- Selector: %s\n"
+ " -- Matching type: %s",
k,
rr->tlsa.cert_usage,
rr->tlsa.selector,
rr->tlsa.matching_type,
- &n);
+ t,
+ cert_usage,
+ selector,
+ matching_type);
if (r < 0)
return NULL;
- r = base64_append(&s, n,
- rr->tlsa.data, rr->tlsa.data_size,
- 8, columns());
- if (r < 0)
+ break;
+ }
+
+ case DNS_TYPE_CAA: {
+ _cleanup_free_ char *value;
+
+ value = octescape(rr->caa.value, rr->caa.value_size);
+ if (!value)
return NULL;
- r = asprintf(&ss, "%s\n"
- "%*s-- Cert. usage: %s\n"
- "%*s-- Selector: %s\n"
- "%*s-- Matching type: %s",
- s,
- n - 6, "", cert_usage,
- n - 6, "", selector,
- n - 6, "", matching_type);
+ r = asprintf(&s, "%s %u %s \"%s\"%s%s%s%.0u",
+ k,
+ rr->caa.flags,
+ rr->caa.tag,
+ value,
+ rr->caa.flags ? "\n -- Flags:" : "",
+ rr->caa.flags & CAA_FLAG_CRITICAL ? " critical" : "",
+ rr->caa.flags & ~CAA_FLAG_CRITICAL ? " " : "",
+ rr->caa.flags & ~CAA_FLAG_CRITICAL);
if (r < 0)
return NULL;
- free(s);
- s = ss;
break;
}
@@ -1173,6 +1199,47 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
return s;
}
+ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
+ assert(rr);
+ assert(out);
+
+ switch(rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+ case DNS_TYPE_SRV:
+ case DNS_TYPE_PTR:
+ case DNS_TYPE_NS:
+ case DNS_TYPE_CNAME:
+ case DNS_TYPE_DNAME:
+ case DNS_TYPE_HINFO:
+ case DNS_TYPE_SPF:
+ case DNS_TYPE_TXT:
+ case DNS_TYPE_A:
+ case DNS_TYPE_AAAA:
+ case DNS_TYPE_SOA:
+ case DNS_TYPE_MX:
+ case DNS_TYPE_LOC:
+ case DNS_TYPE_DS:
+ case DNS_TYPE_DNSKEY:
+ case DNS_TYPE_RRSIG:
+ case DNS_TYPE_NSEC:
+ case DNS_TYPE_NSEC3:
+ return -EINVAL;
+
+ case DNS_TYPE_SSHFP:
+ *out = rr->sshfp.fingerprint;
+ return rr->sshfp.fingerprint_size;
+
+ case DNS_TYPE_TLSA:
+ *out = rr->tlsa.data;
+ return rr->tlsa.data_size;
+
+
+ case DNS_TYPE_OPENPGPKEY:
+ default:
+ *out = rr->generic.data;
+ return rr->generic.data_size;
+ }
+}
+
int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
DnsPacket packet = {
@@ -1230,7 +1297,7 @@ int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret) {
if (rr->n_skip_labels_signer == (unsigned) -1)
return -ENODATA;
- n = DNS_RESOURCE_KEY_NAME(rr->key);
+ n = dns_resource_key_name(rr->key);
r = dns_name_skip(n, rr->n_skip_labels_signer, &n);
if (r < 0)
return r;
@@ -1253,7 +1320,7 @@ int dns_resource_record_source(DnsResourceRecord *rr, const char **ret) {
if (rr->n_skip_labels_source == (unsigned) -1)
return -ENODATA;
- n = DNS_RESOURCE_KEY_NAME(rr->key);
+ n = dns_resource_key_name(rr->key);
r = dns_name_skip(n, rr->n_skip_labels_source, &n);
if (r < 0)
return r;
@@ -1293,14 +1360,14 @@ int dns_resource_record_is_synthetic(DnsResourceRecord *rr) {
if (rr->n_skip_labels_source > 1)
return 1;
- r = dns_name_startswith(DNS_RESOURCE_KEY_NAME(rr->key), "*");
+ r = dns_name_startswith(dns_resource_key_name(rr->key), "*");
if (r < 0)
return r;
return !r;
}
-static void dns_resource_record_hash_func(const void *i, struct siphash *state) {
+void dns_resource_record_hash_func(const void *i, struct siphash *state) {
const DnsResourceRecord *rr = i;
assert(rr);
@@ -1427,7 +1494,13 @@ static void dns_resource_record_hash_func(const void *i, struct siphash *state)
siphash24_compress(&rr->tlsa.cert_usage, sizeof(rr->tlsa.cert_usage), state);
siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), state);
siphash24_compress(&rr->tlsa.matching_type, sizeof(rr->tlsa.matching_type), state);
- siphash24_compress(&rr->tlsa.data, rr->tlsa.data_size, state);
+ siphash24_compress(rr->tlsa.data, rr->tlsa.data_size, state);
+ break;
+
+ case DNS_TYPE_CAA:
+ siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state);
+ string_hash_func(rr->caa.tag, state);
+ siphash24_compress(rr->caa.value, rr->caa.value_size, state);
break;
case DNS_TYPE_OPENPGPKEY:
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-rr.h b/src/grp-resolve/systemd-resolved/resolved-dns-rr.h
index 2e0dfbaba3..020a2abd77 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-rr.h
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-rr.h
@@ -26,6 +26,7 @@
#include "hashmap.h"
#include "in-addr-util.h"
#include "list.h"
+#include "string-util.h"
typedef struct DnsResourceKey DnsResourceKey;
typedef struct DnsResourceRecord DnsResourceRecord;
@@ -81,7 +82,7 @@ enum {
struct DnsResourceKey {
unsigned n_ref; /* (unsigned -1) for const keys, see below */
uint16_t class, type;
- char *_name; /* don't access directy, use DNS_RESOURCE_KEY_NAME()! */
+ char *_name; /* don't access directly, use dns_resource_key_name()! */
};
/* Creates a temporary resource key. This is only useful to quickly
@@ -249,19 +250,17 @@ struct DnsResourceRecord {
void *data;
size_t data_size;
} tlsa;
+
+ /* https://tools.ietf.org/html/rfc6844 */
+ struct {
+ uint8_t flags;
+ char *tag;
+ void *value;
+ size_t value_size;
+ } caa;
};
};
-static inline const char* DNS_RESOURCE_KEY_NAME(const DnsResourceKey *key) {
- if (!key)
- return NULL;
-
- if (key->_name)
- return key->_name;
-
- return (char*) key + sizeof(DnsResourceKey);
-}
-
static inline const void* DNS_RESOURCE_RECORD_RDATA(DnsResourceRecord *rr) {
if (!rr)
return NULL;
@@ -289,12 +288,20 @@ int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key
DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
+const char* dns_resource_key_name(const DnsResourceKey *key);
bool dns_resource_key_is_address(const DnsResourceKey *key);
int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain);
int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *soa);
-int dns_resource_key_to_string(const DnsResourceKey *key, char **ret);
+
+/* _DNS_{CLASS,TYPE}_STRING_MAX include one byte for NUL, which we use for space instead below.
+ * DNS_HOSTNAME_MAX does not include the NUL byte, so we need to add 1. */
+#define DNS_RESOURCE_KEY_STRING_MAX (_DNS_CLASS_STRING_MAX + _DNS_TYPE_STRING_MAX + DNS_HOSTNAME_MAX + 1)
+
+char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size);
+ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
static inline bool dns_key_is_shared(const DnsResourceKey *key) {
@@ -323,6 +330,8 @@ int dns_resource_record_is_synthetic(DnsResourceRecord *rr);
DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
+void dns_resource_record_hash_func(const void *i, struct siphash *state);
+
extern const struct hash_ops dns_resource_key_hash_ops;
extern const struct hash_ops dns_resource_record_hash_ops;
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-scope.c b/src/grp-resolve/systemd-resolved/resolved-dns-scope.c
index a406872a38..66e4585c18 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-scope.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-scope.c
@@ -514,8 +514,8 @@ bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key) {
* that those should be resolved via LLMNR or search
* path only, and should not be leaked onto the
* internet. */
- return !(dns_name_is_single_label(DNS_RESOURCE_KEY_NAME(key)) ||
- dns_name_is_root(DNS_RESOURCE_KEY_NAME(key)));
+ return !(dns_name_is_single_label(dns_resource_key_name(key)) ||
+ dns_name_is_root(dns_resource_key_name(key)));
}
/* On mDNS and LLMNR, send A and AAAA queries only on the
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-server.c b/src/grp-resolve/systemd-resolved/resolved-dns-server.c
index 27342a0e04..3095c042db 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-server.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-server.c
@@ -120,7 +120,7 @@ DnsServer* dns_server_ref(DnsServer *s) {
return NULL;
assert(s->n_ref > 0);
- s->n_ref ++;
+ s->n_ref++;
return s;
}
@@ -130,7 +130,7 @@ DnsServer* dns_server_unref(DnsServer *s) {
return NULL;
assert(s->n_ref > 0);
- s->n_ref --;
+ s->n_ref--;
if (s->n_ref > 0)
return NULL;
@@ -157,6 +157,7 @@ void dns_server_unlink(DnsServer *s) {
assert(s->link);
assert(s->link->n_dns_servers > 0);
LIST_REMOVE(servers, s->link->dns_servers, s);
+ s->link->n_dns_servers--;
break;
case DNS_SERVER_SYSTEM:
@@ -290,9 +291,9 @@ void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel le
if (s->possible_feature_level == level) {
if (protocol == IPPROTO_UDP)
- s->n_failed_udp ++;
+ s->n_failed_udp++;
else if (protocol == IPPROTO_TCP)
- s->n_failed_tcp ++;
+ s->n_failed_tcp++;
}
if (s->resend_timeout > usec)
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-synthesize.c b/src/grp-resolve/systemd-resolved/resolved-dns-synthesize.c
index f4a43dee8c..e3003411f7 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-synthesize.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-synthesize.c
@@ -86,7 +86,7 @@ static int synthesize_localhost_rr(Manager *m, const DnsResourceKey *key, int if
if (IN_SET(key->type, DNS_TYPE_A, DNS_TYPE_ANY)) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
- rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, DNS_RESOURCE_KEY_NAME(key));
+ rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, dns_resource_key_name(key));
if (!rr)
return -ENOMEM;
@@ -100,7 +100,7 @@ static int synthesize_localhost_rr(Manager *m, const DnsResourceKey *key, int if
if (IN_SET(key->type, DNS_TYPE_AAAA, DNS_TYPE_ANY)) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
- rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, DNS_RESOURCE_KEY_NAME(key));
+ rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, dns_resource_key_name(key));
if (!rr)
return -ENOMEM;
@@ -140,7 +140,7 @@ static int synthesize_localhost_ptr(Manager *m, const DnsResourceKey *key, int i
if (r < 0)
return r;
- r = answer_add_ptr(answer, DNS_RESOURCE_KEY_NAME(key), "localhost", dns_synthesize_ifindex(ifindex), DNS_ANSWER_AUTHENTICATED);
+ r = answer_add_ptr(answer, dns_resource_key_name(key), "localhost", dns_synthesize_ifindex(ifindex), DNS_ANSWER_AUTHENTICATED);
if (r < 0)
return r;
}
@@ -254,11 +254,11 @@ static int synthesize_system_hostname_rr(Manager *m, const DnsResourceKey *key,
.address.in6 = in6addr_loopback,
};
- return answer_add_addresses_rr(answer, DNS_RESOURCE_KEY_NAME(key), buffer, n);
+ return answer_add_addresses_rr(answer, dns_resource_key_name(key), buffer, n);
}
}
- return answer_add_addresses_rr(answer, DNS_RESOURCE_KEY_NAME(key), addresses, n);
+ return answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n);
}
static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_addr_union *address, int ifindex, DnsAnswer **answer) {
@@ -319,7 +319,7 @@ static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifin
return n;
}
- return answer_add_addresses_rr(answer, DNS_RESOURCE_KEY_NAME(key), addresses, n);
+ return answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n);
}
static int synthesize_gateway_ptr(Manager *m, int af, const union in_addr_union *address, int ifindex, DnsAnswer **answer) {
@@ -360,7 +360,7 @@ int dns_synthesize_answer(
key->class != DNS_CLASS_ANY)
continue;
- name = DNS_RESOURCE_KEY_NAME(key);
+ name = dns_resource_key_name(key);
if (is_localhost(name)) {
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-transaction.c b/src/grp-resolve/systemd-resolved/resolved-dns-transaction.c
index d48fdd1281..a4a67623e7 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-transaction.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-transaction.c
@@ -52,6 +52,7 @@ static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
while ((z = set_steal_first(t->dnssec_transactions))) {
set_remove(z->notify_transactions, t);
+ set_remove(z->notify_transactions_done, t);
dns_transaction_gc(z);
}
}
@@ -100,20 +101,31 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) {
set_remove(c->transactions, t);
set_free(t->notify_query_candidates);
+ while ((c = set_steal_first(t->notify_query_candidates_done)))
+ set_remove(c->transactions, t);
+ set_free(t->notify_query_candidates_done);
+
while ((i = set_steal_first(t->notify_zone_items)))
i->probe_transaction = NULL;
set_free(t->notify_zone_items);
+ while ((i = set_steal_first(t->notify_zone_items_done)))
+ i->probe_transaction = NULL;
+ set_free(t->notify_zone_items_done);
+
while ((z = set_steal_first(t->notify_transactions)))
set_remove(z->dnssec_transactions, t);
set_free(t->notify_transactions);
+ while ((z = set_steal_first(t->notify_transactions_done)))
+ set_remove(z->dnssec_transactions, t);
+ set_free(t->notify_transactions_done);
+
dns_transaction_flush_dnssec_transactions(t);
set_free(t->dnssec_transactions);
dns_answer_unref(t->validated_keys);
dns_resource_key_unref(t->key);
- free(t->key_string);
free(t);
return NULL;
@@ -128,8 +140,11 @@ bool dns_transaction_gc(DnsTransaction *t) {
return true;
if (set_isempty(t->notify_query_candidates) &&
+ set_isempty(t->notify_query_candidates_done) &&
set_isempty(t->notify_zone_items) &&
- set_isempty(t->notify_transactions)) {
+ set_isempty(t->notify_zone_items_done) &&
+ set_isempty(t->notify_transactions) &&
+ set_isempty(t->notify_transactions_done)) {
dns_transaction_free(t);
return false;
}
@@ -210,7 +225,7 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key)
LIST_PREPEND(transactions_by_scope, s->transactions, t);
t->scope = s;
- s->manager->n_transactions_total ++;
+ s->manager->n_transactions_total++;
if (ret)
*ret = t;
@@ -238,6 +253,7 @@ static void dns_transaction_shuffle_id(DnsTransaction *t) {
static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
_cleanup_free_ char *pretty = NULL;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
DnsZoneItem *z;
assert(t);
@@ -246,15 +262,15 @@ static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
if (manager_our_packet(t->scope->manager, p) != 0)
return;
- in_addr_to_string(p->family, &p->sender, &pretty);
+ (void) in_addr_to_string(p->family, &p->sender, &pretty);
log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
t->id,
- dns_transaction_key_string(t),
+ dns_resource_key_to_string(t->key, key_str, sizeof key_str),
dns_protocol_to_string(t->scope->protocol),
t->scope->link ? t->scope->link->name : "*",
- t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
- pretty);
+ af_to_name_short(t->scope->family),
+ strnull(pretty));
/* RFC 4795, Section 4.1 says that the peer with the
* lexicographically smaller IP address loses */
@@ -266,6 +282,7 @@ static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
t->block_gc++;
+
while ((z = set_first(t->notify_zone_items))) {
/* First, make sure the zone item drops the reference
* to us */
@@ -284,22 +301,25 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
DnsQueryCandidate *c;
DnsZoneItem *z;
DnsTransaction *d;
- Iterator i;
const char *st;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
assert(t);
assert(!DNS_TRANSACTION_IS_LIVE(state));
- if (state == DNS_TRANSACTION_DNSSEC_FAILED)
+ if (state == DNS_TRANSACTION_DNSSEC_FAILED) {
+ dns_resource_key_to_string(t->key, key_str, sizeof key_str);
+
log_struct(LOG_NOTICE,
LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_FAILURE),
- LOG_MESSAGE("DNSSEC validation failed for question %s: %s", dns_transaction_key_string(t), dnssec_result_to_string(t->answer_dnssec_result)),
+ LOG_MESSAGE("DNSSEC validation failed for question %s: %s", key_str, dnssec_result_to_string(t->answer_dnssec_result)),
"DNS_TRANSACTION=%" PRIu16, t->id,
- "DNS_QUESTION=%s", dns_transaction_key_string(t),
+ "DNS_QUESTION=%s", key_str,
"DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
"DNS_SERVER=%s", dns_server_string(t->server),
"DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level),
NULL);
+ }
/* Note that this call might invalidate the query. Callers
* should hence not attempt to access the query or transaction
@@ -312,10 +332,10 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
t->id,
- dns_transaction_key_string(t),
+ dns_resource_key_to_string(t->key, key_str, sizeof key_str),
dns_protocol_to_string(t->scope->protocol),
t->scope->link ? t->scope->link->name : "*",
- t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
+ af_to_name_short(t->scope->family),
st,
t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
t->answer_authenticated ? "authenticated" : "unsigned");
@@ -329,39 +349,17 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
* transaction isn't freed while we are still looking at it */
t->block_gc++;
- SET_FOREACH(c, t->notify_query_candidates, i)
+ SET_FOREACH_MOVE(c, t->notify_query_candidates_done, t->notify_query_candidates)
dns_query_candidate_notify(c);
- SET_FOREACH(z, t->notify_zone_items, i)
- dns_zone_item_notify(z);
-
- if (!set_isempty(t->notify_transactions)) {
- DnsTransaction **nt;
- unsigned j, n = 0;
-
- /* We need to be careful when notifying other
- * transactions, as that might destroy other
- * transactions in our list. Hence, in order to be
- * able to safely iterate through the list of
- * transactions, take a GC lock on all of them
- * first. Then, in a second loop, notify them, but
- * first unlock that specific transaction. */
-
- nt = newa(DnsTransaction*, set_size(t->notify_transactions));
- SET_FOREACH(d, t->notify_transactions, i) {
- nt[n++] = d;
- d->block_gc++;
- }
+ SWAP_TWO(t->notify_query_candidates, t->notify_query_candidates_done);
- assert(n == set_size(t->notify_transactions));
-
- for (j = 0; j < n; j++) {
- if (set_contains(t->notify_transactions, nt[j]))
- dns_transaction_notify(nt[j], t);
+ SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
+ dns_zone_item_notify(z);
+ SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
- nt[j]->block_gc--;
- dns_transaction_gc(nt[j]);
- }
- }
+ SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
+ dns_transaction_notify(d, t);
+ SWAP_TWO(t->notify_transactions, t->notify_transactions_done);
t->block_gc--;
dns_transaction_gc(t);
@@ -522,7 +520,7 @@ static int dns_transaction_open_tcp(DnsTransaction *t) {
* the IP address, in case this is a reverse
* PTR lookup */
- r = dns_name_address(DNS_RESOURCE_KEY_NAME(t->key), &family, &address);
+ r = dns_name_address(dns_resource_key_name(t->key), &family, &address);
if (r < 0)
return r;
if (r == 0)
@@ -1209,7 +1207,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
return 0;
}
- if (dns_name_is_root(DNS_RESOURCE_KEY_NAME(t->key)) &&
+ if (dns_name_is_root(dns_resource_key_name(t->key)) &&
t->key->type == DNS_TYPE_DS) {
/* Hmm, this is a request for the root DS? A
@@ -1237,8 +1235,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
* might be DS RRs, but we don't know
* them, and the DNS server won't tell
* them to us (and even if it would,
- * we couldn't validate it and trust
- * it). */
+ * we couldn't validate and trust them. */
dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
return 0;
@@ -1372,7 +1369,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
other->state = DNS_TRANSACTION_PENDING;
other->next_attempt_after = ts;
- qdcount ++;
+ qdcount++;
if (dns_key_is_shared(other->key))
add_known_answers = true;
@@ -1425,6 +1422,7 @@ static int dns_transaction_make_packet(DnsTransaction *t) {
int dns_transaction_go(DnsTransaction *t) {
usec_t ts;
int r;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
assert(t);
@@ -1434,12 +1432,12 @@ int dns_transaction_go(DnsTransaction *t) {
if (r <= 0)
return r;
- log_debug("Excercising transaction %" PRIu16 " for <%s> on scope %s on %s/%s.",
+ log_debug("Transaction %" PRIu16 " for <%s> scope %s on %s/%s.",
t->id,
- dns_transaction_key_string(t),
+ dns_resource_key_to_string(t->key, key_str, sizeof key_str),
dns_protocol_to_string(t->scope->protocol),
t->scope->link ? t->scope->link->name : "*",
- t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
+ af_to_name_short(t->scope->family));
if (!t->initial_jitter_scheduled &&
(t->scope->protocol == DNS_PROTOCOL_LLMNR ||
@@ -1494,8 +1492,8 @@ int dns_transaction_go(DnsTransaction *t) {
return r;
if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
- (dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "in-addr.arpa") > 0 ||
- dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), "ip6.arpa") > 0)) {
+ (dns_name_endswith(dns_resource_key_name(t->key), "in-addr.arpa") > 0 ||
+ dns_name_endswith(dns_resource_key_name(t->key), "ip6.arpa") > 0)) {
/* RFC 4795, Section 2.4. says reverse lookups shall
* always be made via TCP on LLMNR */
@@ -1602,11 +1600,14 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource
if (r < 0)
return r;
if (r > 0) {
- log_debug("Detected potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
+ char s[DNS_RESOURCE_KEY_STRING_MAX], saux[DNS_RESOURCE_KEY_STRING_MAX];
+
+ log_debug("Potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
aux->id,
- strna(dns_transaction_key_string(aux)),
+ dns_resource_key_to_string(t->key, s, sizeof s),
t->id,
- strna(dns_transaction_key_string(t)));
+ dns_resource_key_to_string(aux->key, saux, sizeof saux));
+
return -ELOOP;
}
}
@@ -1619,6 +1620,10 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource
if (r < 0)
goto gc;
+ r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
+ if (r < 0)
+ goto gc;
+
r = set_put(t->dnssec_transactions, aux);
if (r < 0)
goto gc;
@@ -1678,7 +1683,7 @@ static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const
assert(t);
- /* Check whether the specified name is in the the NTA
+ /* Check whether the specified name is in the NTA
* database, either in the global one, or the link-local
* one. */
@@ -1708,7 +1713,7 @@ static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
/* Is this key explicitly listed as a negative trust anchor?
* If so, it's nothing we need to care about */
- r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key));
+ r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
if (r < 0)
return r;
if (r > 0)
@@ -1799,7 +1804,8 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
* - For unsigned SOA/NS we get the matching DS
* - For unsigned CNAME/DNAME/DS we get the parent SOA RR
* - For other unsigned RRs we get the matching SOA RR
- * - For SOA/NS/DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
+ * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
+ * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
* - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
*/
@@ -1816,7 +1822,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
continue;
/* If this RR is in the negative trust anchor, we don't need to validate it. */
- r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r > 0)
@@ -1833,7 +1839,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
* already have the DNSKEY, and we don't have
* to look for more. */
if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
- r = dns_name_equal(rr->rrsig.signer, DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r > 0)
@@ -1851,7 +1857,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
* in another transaction whose additonal RRs
* point back to the original transaction, and
* we deadlock. */
- r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), rr->rrsig.signer);
+ r = dns_name_endswith(dns_resource_key_name(t->key), rr->rrsig.signer);
if (r < 0)
return r;
if (r == 0)
@@ -1861,7 +1867,8 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
if (!dnskey)
return -ENOMEM;
- log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), rr->rrsig.key_tag);
+ log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
+ t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
r = dns_transaction_request_dnssec_rr(t, dnskey);
if (r < 0)
return r;
@@ -1879,17 +1886,18 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
* up in request loops, and want to keep
* additional traffic down. */
- r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(t->key), DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_name_endswith(dns_resource_key_name(t->key), dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r == 0)
continue;
- ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
+ ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
if (!ds)
return -ENOMEM;
- log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dnssec_keytag(rr, false));
+ log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
+ t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
r = dns_transaction_request_dnssec_rr(t, ds);
if (r < 0)
return r;
@@ -1920,11 +1928,12 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
if (r > 0)
continue;
- ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(rr->key));
+ ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
if (!ds)
return -ENOMEM;
- log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
+ log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
+ t->id, dns_resource_key_name(rr->key));
r = dns_transaction_request_dnssec_rr(t, ds);
if (r < 0)
return r;
@@ -1966,7 +1975,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
if (r > 0)
continue;
- name = DNS_RESOURCE_KEY_NAME(rr->key);
+ name = dns_resource_key_name(rr->key);
r = dns_name_parent(&name);
if (r < 0)
return r;
@@ -1977,7 +1986,8 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
if (!soa)
return -ENOMEM;
- log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).", t->id, DNS_RESOURCE_KEY_NAME(rr->key));
+ log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
+ t->id, dns_resource_key_name(rr->key));
r = dns_transaction_request_dnssec_rr(t, soa);
if (r < 0)
return r;
@@ -2007,11 +2017,12 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
if (r > 0)
continue;
- soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, DNS_RESOURCE_KEY_NAME(rr->key));
+ soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
if (!soa)
return -ENOMEM;
- log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).", t->id, DNS_RESOURCE_KEY_NAME(rr->key), dns_resource_record_to_string(rr));
+ log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
+ t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
r = dns_transaction_request_dnssec_rr(t, soa);
if (r < 0)
return r;
@@ -2028,30 +2039,42 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
return r;
if (r > 0) {
const char *name;
+ uint16_t type = 0;
- name = DNS_RESOURCE_KEY_NAME(t->key);
+ name = dns_resource_key_name(t->key);
- /* If this was a SOA or NS request, then this
- * indicates that we are not at a zone apex, hence ask
- * the parent name instead. If this was a DS request,
- * then it's signed when the parent zone is signed,
- * hence ask the parent in that case, too. */
+ /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
+ * could also be used as indication that we are not at a zone apex, but in real world setups there are
+ * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
+ * though they have further children. If this was a DS request, then it's signed when the parent zone
+ * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
+ * to see if that is signed. */
- if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
+ if (t->key->type == DNS_TYPE_DS) {
r = dns_name_parent(&name);
- if (r < 0)
- return r;
- if (r > 0)
- log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
- else
+ if (r > 0) {
+ type = DNS_TYPE_SOA;
+ log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned empty DS response).",
+ t->id, dns_resource_key_name(t->key));
+ } else
name = NULL;
- } else
- log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).", t->id, DNS_RESOURCE_KEY_NAME(t->key));
+
+ } else if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS)) {
+
+ type = DNS_TYPE_DS;
+ log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS response).",
+ t->id, dns_resource_key_name(t->key));
+
+ } else {
+ type = DNS_TYPE_SOA;
+ log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).",
+ t->id, dns_resource_key_name(t->key));
+ }
if (name) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
- soa = dns_resource_key_new(t->key->class, DNS_TYPE_SOA, name);
+ soa = dns_resource_key_new(t->key->class, type, name);
if (!soa)
return -ENOMEM;
@@ -2118,7 +2141,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
if (dns_type_is_pseudo(rr->key->type))
return -EINVAL;
- r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r > 0)
@@ -2144,7 +2167,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
if (dt->key->type != DNS_TYPE_DS)
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r == 0)
@@ -2187,7 +2210,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
continue;
if (!parent) {
- parent = DNS_RESOURCE_KEY_NAME(rr->key);
+ parent = dns_resource_key_name(rr->key);
r = dns_name_parent(&parent);
if (r < 0)
return r;
@@ -2201,7 +2224,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
}
}
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), parent);
+ r = dns_name_equal(dns_resource_key_name(dt->key), parent);
if (r < 0)
return r;
if (r == 0)
@@ -2226,7 +2249,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
if (dt->key->type != DNS_TYPE_SOA)
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r == 0)
@@ -2273,7 +2296,7 @@ static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKe
if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
- tld = DNS_RESOURCE_KEY_NAME(key);
+ tld = dns_resource_key_name(key);
r = dns_name_parent(&tld);
if (r < 0)
return r;
@@ -2288,7 +2311,7 @@ static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKe
if (dt->key->class != key->class)
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), tld);
+ r = dns_name_equal(dns_resource_key_name(dt->key), tld);
if (r < 0)
return r;
if (r == 0)
@@ -2305,8 +2328,10 @@ static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKe
}
static int dns_transaction_requires_nsec(DnsTransaction *t) {
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
DnsTransaction *dt;
const char *name;
+ uint16_t type = 0;
Iterator i;
int r;
@@ -2321,7 +2346,7 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
if (dns_type_is_pseudo(t->key->type))
return -EINVAL;
- r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key));
+ r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
if (r < 0)
return r;
if (r > 0)
@@ -2335,28 +2360,32 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
* exist, and we are in downgrade mode, hence ignore
* that fact that we didn't get any NSEC RRs.*/
- log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.", dns_transaction_key_string(t));
+ log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
+ dns_resource_key_to_string(t->key, key_str, sizeof key_str));
return false;
}
- name = DNS_RESOURCE_KEY_NAME(t->key);
+ name = dns_resource_key_name(t->key);
- if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS, DNS_TYPE_DS)) {
+ if (t->key->type == DNS_TYPE_DS) {
- /* We got a negative reply for this SOA/NS lookup? If
- * so, then we are not at a zone apex, and thus should
- * look at the result of the parent SOA lookup.
- *
- * We got a negative reply for this DS lookup? DS RRs
- * are signed when their parent zone is signed, hence
- * also check the parent SOA in this case. */
+ /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
+ * hence check the parent SOA in this case. */
r = dns_name_parent(&name);
if (r < 0)
return r;
if (r == 0)
return true;
- }
+
+ type = DNS_TYPE_SOA;
+
+ } else if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS))
+ /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
+ type = DNS_TYPE_DS;
+ else
+ /* For all other negative replies, check for the SOA lookup */
+ type = DNS_TYPE_SOA;
/* For all other RRs we check the SOA on the same level to see
* if it's signed. */
@@ -2365,10 +2394,10 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
if (dt->key->class != t->key->class)
continue;
- if (dt->key->type != DNS_TYPE_SOA)
+ if (dt->key->type != type)
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), name);
+ r = dns_name_equal(dns_resource_key_name(dt->key), name);
if (r < 0)
return r;
if (r == 0)
@@ -2390,7 +2419,7 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe
* the specified RRset is authenticated (i.e. has a matching
* DS RR). */
- r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key));
+ r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
if (r < 0)
return r;
if (r > 0)
@@ -2413,7 +2442,7 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe
if (dt->key->type == DNS_TYPE_DNSKEY) {
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
+ r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
if (r < 0)
return r;
if (r == 0)
@@ -2430,7 +2459,7 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe
} else if (dt->key->type == DNS_TYPE_DS) {
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(dt->key), rrsig->rrsig.signer);
+ r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
if (r < 0)
return r;
if (r == 0)
@@ -2460,7 +2489,7 @@ static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr
* not to be signed, there's a problem with the DNS server */
return rr->key->class == DNS_CLASS_IN &&
- dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key));
+ dns_name_is_root(dns_resource_key_name(rr->key));
}
static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
@@ -2541,343 +2570,347 @@ static int dns_transaction_copy_validated(DnsTransaction *t) {
return 0;
}
-int dns_transaction_validate_dnssec(DnsTransaction *t) {
- _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
- enum {
- PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
- PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
- PHASE_ALL, /* Phase #3, validate everything else */
- } phase;
+typedef enum {
+ DNSSEC_PHASE_DNSKEY, /* Phase #1, only validate DNSKEYs */
+ DNSSEC_PHASE_NSEC, /* Phase #2, only validate NSEC+NSEC3 */
+ DNSSEC_PHASE_ALL, /* Phase #3, validate everything else */
+} Phase;
+
+static int dnssec_validate_records(
+ DnsTransaction *t,
+ Phase phase,
+ bool *have_nsec,
+ DnsAnswer **validated) {
+
DnsResourceRecord *rr;
- DnsAnswerFlags flags;
int r;
- assert(t);
+ /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
- /* We have now collected all DS and DNSKEY RRs in
- * t->validated_keys, let's see which RRs we can now
- * authenticate with that. */
+ DNS_ANSWER_FOREACH(rr, t->answer) {
+ DnsResourceRecord *rrsig = NULL;
+ DnssecResult result;
- if (t->scope->dnssec_mode == DNSSEC_NO)
- return 0;
+ switch (rr->key->type) {
+ case DNS_TYPE_RRSIG:
+ continue;
- /* Already validated */
- if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
- return 0;
+ case DNS_TYPE_DNSKEY:
+ /* We validate DNSKEYs only in the DNSKEY and ALL phases */
+ if (phase == DNSSEC_PHASE_NSEC)
+ continue;
+ break;
- /* Our own stuff needs no validation */
- if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
- t->answer_dnssec_result = DNSSEC_VALIDATED;
- t->answer_authenticated = true;
- return 0;
- }
+ case DNS_TYPE_NSEC:
+ case DNS_TYPE_NSEC3:
+ *have_nsec = true;
- /* Cached stuff is not affected by validation. */
- if (t->answer_source != DNS_TRANSACTION_NETWORK)
- return 0;
+ /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
+ if (phase == DNSSEC_PHASE_DNSKEY)
+ continue;
+ break;
- if (!dns_transaction_dnssec_supported_full(t)) {
- /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
- t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
- log_debug("Not validating response for %" PRIu16 ", server lacks DNSSEC support.", t->id);
- return 0;
- }
+ default:
+ /* We validate all other RRs only in the ALL phases */
+ if (phase != DNSSEC_PHASE_ALL)
+ continue;
+ }
- log_debug("Validating response from transaction %" PRIu16 " (%s).", t->id, dns_transaction_key_string(t));
+ r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
+ if (r < 0)
+ return r;
- /* First, see if this response contains any revoked trust
- * anchors we care about */
- r = dns_transaction_check_revoked_trust_anchors(t);
- if (r < 0)
- return r;
+ log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
- /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
- r = dns_transaction_copy_validated(t);
- if (r < 0)
- return r;
+ if (result == DNSSEC_VALIDATED) {
- /* Second, see if there are DNSKEYs we already know a
- * validated DS for. */
- r = dns_transaction_validate_dnskey_by_ds(t);
- if (r < 0)
- return r;
+ if (rr->key->type == DNS_TYPE_DNSKEY) {
+ /* If we just validated a DNSKEY RRset, then let's add these keys to
+ * the set of validated keys for this transaction. */
- /* Fourth, remove all DNSKEY and DS RRs again that our trust
- * anchor says are revoked. After all we might have marked
- * some keys revoked above, but they might still be lingering
- * in our validated_keys list. */
- r = dns_transaction_invalidate_revoked_keys(t);
- if (r < 0)
- return r;
+ r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
+ if (r < 0)
+ return r;
- phase = PHASE_DNSKEY;
- for (;;) {
- bool changed = false, have_nsec = false;
+ /* Some of the DNSKEYs we just added might already have been revoked,
+ * remove them again in that case. */
+ r = dns_transaction_invalidate_revoked_keys(t);
+ if (r < 0)
+ return r;
+ }
- DNS_ANSWER_FOREACH(rr, t->answer) {
- DnsResourceRecord *rrsig = NULL;
- DnssecResult result;
+ /* Add the validated RRset to the new list of validated
+ * RRsets, and remove it from the unvalidated RRsets.
+ * We mark the RRset as authenticated and cacheable. */
+ r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
+ if (r < 0)
+ return r;
- switch (rr->key->type) {
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
- case DNS_TYPE_RRSIG:
- continue;
+ /* Exit the loop, we dropped something from the answer, start from the beginning */
+ return 1;
+ }
- case DNS_TYPE_DNSKEY:
- /* We validate DNSKEYs only in the DNSKEY and ALL phases */
- if (phase == PHASE_NSEC)
- continue;
- break;
+ /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
+ * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
+ * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
+ if (phase != DNSSEC_PHASE_ALL)
+ continue;
- case DNS_TYPE_NSEC:
- case DNS_TYPE_NSEC3:
- have_nsec = true;
+ if (result == DNSSEC_VALIDATED_WILDCARD) {
+ bool authenticated = false;
+ const char *source;
- /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
- if (phase == PHASE_DNSKEY)
- continue;
+ /* This RRset validated, but as a wildcard. This means we need
+ * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists.*/
- break;
+ /* First step, determine the source of synthesis */
+ r = dns_resource_record_source(rrsig, &source);
+ if (r < 0)
+ return r;
- default:
- /* We validate all other RRs only in the ALL phases */
- if (phase != PHASE_ALL)
- continue;
+ r = dnssec_test_positive_wildcard(*validated,
+ dns_resource_key_name(rr->key),
+ source,
+ rrsig->rrsig.signer,
+ &authenticated);
- break;
+ /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
+ if (r == 0)
+ result = DNSSEC_INVALID;
+ else {
+ r = dns_answer_move_by_key(validated, &t->answer, rr->key,
+ authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
+ if (r < 0)
+ return r;
+
+ manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
+
+ /* Exit the loop, we dropped something from the answer, start from the beginning */
+ return 1;
}
+ }
- r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
+ if (result == DNSSEC_NO_SIGNATURE) {
+ r = dns_transaction_requires_rrsig(t, rr);
if (r < 0)
return r;
+ if (r == 0) {
+ /* Data does not require signing. In that case, just copy it over,
+ * but remember that this is by no means authenticated.*/
+ r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
+ if (r < 0)
+ return r;
+
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
+ return 1;
+ }
- log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
+ r = dns_transaction_known_signed(t, rr);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ /* This is an RR we know has to be signed. If it isn't this means
+ * the server is not attaching RRSIGs, hence complain. */
- if (result == DNSSEC_VALIDATED) {
+ dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
- if (rr->key->type == DNS_TYPE_DNSKEY) {
- /* If we just validated a
- * DNSKEY RRset, then let's
- * add these keys to the set
- * of validated keys for this
- * transaction. */
+ if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
- r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
- if (r < 0)
- return r;
+ /* Downgrading is OK? If so, just consider the information unsigned */
- /* some of the DNSKEYs we just
- * added might already have
- * been revoked, remove them
- * again in that case. */
- r = dns_transaction_invalidate_revoked_keys(t);
+ r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
if (r < 0)
return r;
- }
- /* Add the validated RRset to the new
- * list of validated RRsets, and
- * remove it from the unvalidated
- * RRsets. We mark the RRset as
- * authenticated and cacheable. */
- r = dns_answer_move_by_key(&validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
- if (r < 0)
- return r;
-
- manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
+ return 1;
+ }
- /* Exit the loop, we dropped something from the answer, start from the beginning */
- changed = true;
- break;
+ /* Otherwise, fail */
+ t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
+ return 0;
}
- /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
- * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet, we
- * cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
- if (phase != PHASE_ALL)
- continue;
+ r = dns_transaction_in_private_tld(t, rr->key);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ char s[DNS_RESOURCE_KEY_STRING_MAX];
- if (result == DNSSEC_VALIDATED_WILDCARD) {
- bool authenticated = false;
- const char *source;
+ /* The data is from a TLD that is proven not to exist, and we are in downgrade
+ * mode, hence ignore the fact that this was not signed. */
- /* This RRset validated, but as a wildcard. This means we need to prove via NSEC/NSEC3
- * that no matching non-wildcard RR exists.*/
+ log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
+ dns_resource_key_to_string(rr->key, s, sizeof s));
- /* First step, determine the source of synthesis */
- r = dns_resource_record_source(rrsig, &source);
+ r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
if (r < 0)
return r;
- r = dnssec_test_positive_wildcard(
- validated,
- DNS_RESOURCE_KEY_NAME(rr->key),
- source,
- rrsig->rrsig.signer,
- &authenticated);
-
- /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
- if (r == 0)
- result = DNSSEC_INVALID;
- else {
- r = dns_answer_move_by_key(&validated, &t->answer, rr->key, authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
- if (r < 0)
- return r;
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
+ return 1;
+ }
+ }
- manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
+ if (IN_SET(result,
+ DNSSEC_MISSING_KEY,
+ DNSSEC_SIGNATURE_EXPIRED,
+ DNSSEC_UNSUPPORTED_ALGORITHM)) {
- /* Exit the loop, we dropped something from the answer, start from the beginning */
- changed = true;
- break;
- }
- }
+ r = dns_transaction_dnskey_authenticated(t, rr);
+ if (r < 0 && r != -ENXIO)
+ return r;
+ if (r == 0) {
+ /* The DNSKEY transaction was not authenticated, this means there's
+ * no DS for this, which means it's OK if no keys are found for this signature. */
- if (result == DNSSEC_NO_SIGNATURE) {
- r = dns_transaction_requires_rrsig(t, rr);
+ r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
if (r < 0)
return r;
- if (r == 0) {
- /* Data does not require signing. In that case, just copy it over,
- * but remember that this is by no means authenticated.*/
- r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
- if (r < 0)
- return r;
- manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
- changed = true;
- break;
- }
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
+ return 1;
+ }
+ }
- r = dns_transaction_known_signed(t, rr);
+ r = dns_transaction_is_primary_response(t, rr);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ /* Look for a matching DNAME for this CNAME */
+ r = dns_answer_has_dname_for_cname(t->answer, rr);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ /* Also look among the stuff we already validated */
+ r = dns_answer_has_dname_for_cname(*validated, rr);
if (r < 0)
return r;
- if (r > 0) {
- /* This is an RR we know has to be signed. If it isn't this means
- * the server is not attaching RRSIGs, hence complain. */
-
- dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
+ }
- if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
+ if (r == 0) {
+ if (IN_SET(result,
+ DNSSEC_INVALID,
+ DNSSEC_SIGNATURE_EXPIRED,
+ DNSSEC_NO_SIGNATURE))
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
+ else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
+ manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
+
+ /* This is a primary response to our question, and it failed validation.
+ * That's fatal. */
+ t->answer_dnssec_result = result;
+ return 0;
+ }
- /* Downgrading is OK? If so, just consider the information unsigned */
+ /* This is a primary response, but we do have a DNAME RR
+ * in the RR that can replay this CNAME, hence rely on
+ * that, and we can remove the CNAME in favour of it. */
+ }
- r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
- if (r < 0)
- return r;
+ /* This is just some auxiliary data. Just remove the RRset and continue. */
+ r = dns_answer_remove_by_key(&t->answer, rr->key);
+ if (r < 0)
+ return r;
- manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
- changed = true;
- break;
- }
+ /* We dropped something from the answer, start from the beginning. */
+ return 1;
+ }
- /* Otherwise, fail */
- t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
- return 0;
- }
+ return 2; /* Finito. */
+}
- r = dns_transaction_in_private_tld(t, rr->key);
- if (r < 0)
- return r;
- if (r > 0) {
- _cleanup_free_ char *s = NULL;
+int dns_transaction_validate_dnssec(DnsTransaction *t) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
+ Phase phase;
+ DnsAnswerFlags flags;
+ int r;
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
- /* The data is from a TLD that is proven not to exist, and we are in downgrade
- * mode, hence ignore the fact that this was not signed. */
+ assert(t);
- (void) dns_resource_key_to_string(rr->key, &s);
- log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.", strna(s ? strstrip(s) : NULL));
+ /* We have now collected all DS and DNSKEY RRs in
+ * t->validated_keys, let's see which RRs we can now
+ * authenticate with that. */
- r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
- if (r < 0)
- return r;
+ if (t->scope->dnssec_mode == DNSSEC_NO)
+ return 0;
- manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
- changed = true;
- break;
- }
- }
+ /* Already validated */
+ if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
+ return 0;
- if (IN_SET(result,
- DNSSEC_MISSING_KEY,
- DNSSEC_SIGNATURE_EXPIRED,
- DNSSEC_UNSUPPORTED_ALGORITHM)) {
+ /* Our own stuff needs no validation */
+ if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
+ t->answer_dnssec_result = DNSSEC_VALIDATED;
+ t->answer_authenticated = true;
+ return 0;
+ }
- r = dns_transaction_dnskey_authenticated(t, rr);
- if (r < 0 && r != -ENXIO)
- return r;
- if (r == 0) {
- /* The DNSKEY transaction was not authenticated, this means there's
- * no DS for this, which means it's OK if no keys are found for this signature. */
+ /* Cached stuff is not affected by validation. */
+ if (t->answer_source != DNS_TRANSACTION_NETWORK)
+ return 0;
- r = dns_answer_move_by_key(&validated, &t->answer, rr->key, 0);
- if (r < 0)
- return r;
+ if (!dns_transaction_dnssec_supported_full(t)) {
+ /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
+ t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
+ log_debug("Not validating response for %" PRIu16 ", server lacks DNSSEC support.", t->id);
+ return 0;
+ }
- manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
- changed = true;
- break;
- }
- }
+ log_debug("Validating response from transaction %" PRIu16 " (%s).",
+ t->id,
+ dns_resource_key_to_string(t->key, key_str, sizeof key_str));
- r = dns_transaction_is_primary_response(t, rr);
- if (r < 0)
- return r;
- if (r > 0) {
+ /* First, see if this response contains any revoked trust
+ * anchors we care about */
+ r = dns_transaction_check_revoked_trust_anchors(t);
+ if (r < 0)
+ return r;
- /* Look for a matching DNAME for this CNAME */
- r = dns_answer_has_dname_for_cname(t->answer, rr);
- if (r < 0)
- return r;
- if (r == 0) {
- /* Also look among the stuff we already validated */
- r = dns_answer_has_dname_for_cname(validated, rr);
- if (r < 0)
- return r;
- }
+ /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
+ r = dns_transaction_copy_validated(t);
+ if (r < 0)
+ return r;
- if (r == 0) {
- if (IN_SET(result,
- DNSSEC_INVALID,
- DNSSEC_SIGNATURE_EXPIRED,
- DNSSEC_NO_SIGNATURE))
- manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
- else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
- manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
-
- /* This is a primary response to our question, and it failed validation. That's
- * fatal. */
- t->answer_dnssec_result = result;
- return 0;
- }
+ /* Second, see if there are DNSKEYs we already know a
+ * validated DS for. */
+ r = dns_transaction_validate_dnskey_by_ds(t);
+ if (r < 0)
+ return r;
- /* This is a primary response, but we do have a DNAME RR in the RR that can replay this
- * CNAME, hence rely on that, and we can remove the CNAME in favour of it. */
- }
+ /* Fourth, remove all DNSKEY and DS RRs again that our trust
+ * anchor says are revoked. After all we might have marked
+ * some keys revoked above, but they might still be lingering
+ * in our validated_keys list. */
+ r = dns_transaction_invalidate_revoked_keys(t);
+ if (r < 0)
+ return r;
- /* This is just some auxiliary data. Just remove the RRset and continue. */
- r = dns_answer_remove_by_key(&t->answer, rr->key);
- if (r < 0)
- return r;
+ phase = DNSSEC_PHASE_DNSKEY;
+ for (;;) {
+ bool have_nsec = false;
- /* Exit the loop, we dropped something from the answer, start from the beginning */
- changed = true;
- break;
- }
+ r = dnssec_validate_records(t, phase, &have_nsec, &validated);
+ if (r <= 0)
+ return r;
- /* Restart the inner loop as long as we managed to achieve something */
- if (changed)
+ /* Try again as long as we managed to achieve something */
+ if (r == 1)
continue;
- if (phase == PHASE_DNSKEY && have_nsec) {
+ if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
/* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
- phase = PHASE_NSEC;
+ phase = DNSSEC_PHASE_NSEC;
continue;
}
- if (phase != PHASE_ALL) {
- /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now. Note that in this
- * third phase we start to remove RRs we couldn't validate. */
- phase = PHASE_ALL;
+ if (phase != DNSSEC_PHASE_ALL) {
+ /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
+ * Note that in this third phase we start to remove RRs we couldn't validate. */
+ phase = DNSSEC_PHASE_ALL;
continue;
}
@@ -2921,7 +2954,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
case DNSSEC_NSEC_NXDOMAIN:
/* NSEC proves the domain doesn't exist. Very good. */
- log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
+ log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
t->answer_dnssec_result = DNSSEC_VALIDATED;
t->answer_rcode = DNS_RCODE_NXDOMAIN;
t->answer_authenticated = authenticated;
@@ -2931,7 +2964,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
case DNSSEC_NSEC_NODATA:
/* NSEC proves that there's no data here, very good. */
- log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
+ log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
t->answer_dnssec_result = DNSSEC_VALIDATED;
t->answer_rcode = DNS_RCODE_SUCCESS;
t->answer_authenticated = authenticated;
@@ -2941,7 +2974,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
case DNSSEC_NSEC_OPTOUT:
/* NSEC3 says the data might not be signed */
- log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, dns_transaction_key_string(t));
+ log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
t->answer_dnssec_result = DNSSEC_UNSIGNED;
t->answer_authenticated = false;
@@ -2986,17 +3019,6 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
return 1;
}
-const char *dns_transaction_key_string(DnsTransaction *t) {
- assert(t);
-
- if (!t->key_string) {
- if (dns_resource_key_to_string(t->key, &t->key_string) < 0)
- return "n/a";
- }
-
- return strstrip(t->key_string);
-}
-
static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
[DNS_TRANSACTION_NULL] = "null",
[DNS_TRANSACTION_PENDING] = "pending",
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-transaction.h b/src/grp-resolve/systemd-resolved/resolved-dns-transaction.h
index 4617194711..eaece91533 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-transaction.h
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-transaction.h
@@ -64,7 +64,6 @@ struct DnsTransaction {
DnsScope *scope;
DnsResourceKey *key;
- char *key_string;
DnsTransactionState state;
@@ -119,17 +118,17 @@ struct DnsTransaction {
/* Query candidates this transaction is referenced by and that
* shall be notified about this specific transaction
* completing. */
- Set *notify_query_candidates;
+ Set *notify_query_candidates, *notify_query_candidates_done;
/* Zone items this transaction is referenced by and that shall
* be notified about completion. */
- Set *notify_zone_items;
+ Set *notify_zone_items, *notify_zone_items_done;
/* Other transactions that this transactions is referenced by
* and that shall be notified about completion. This is used
* when transactions want to validate their RRsets, but need
* another DNSKEY or DS RR to do so. */
- Set *notify_transactions;
+ Set *notify_transactions, *notify_transactions_done;
/* The opposite direction: the transactions this transaction
* created in order to request DNSKEY or DS RRs. */
@@ -153,8 +152,6 @@ void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source);
int dns_transaction_validate_dnssec(DnsTransaction *t);
int dns_transaction_request_dnssec_keys(DnsTransaction *t);
-const char *dns_transaction_key_string(DnsTransaction *t);
-
const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-trust-anchor.c b/src/grp-resolve/systemd-resolved/resolved-dns-trust-anchor.c
index a75337eb6a..77370e7dd5 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-trust-anchor.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-trust-anchor.c
@@ -651,7 +651,7 @@ static int dns_trust_anchor_check_revoked_one(DnsTrustAnchor *d, DnsResourceReco
}
}
- a = hashmap_get(d->positive_by_key, &DNS_RESOURCE_KEY_CONST(revoked_dnskey->key->class, DNS_TYPE_DS, DNS_RESOURCE_KEY_NAME(revoked_dnskey->key)));
+ a = hashmap_get(d->positive_by_key, &DNS_RESOURCE_KEY_CONST(revoked_dnskey->key->class, DNS_TYPE_DS, dns_resource_key_name(revoked_dnskey->key)));
if (a) {
DnsResourceRecord *anchor;
@@ -698,7 +698,7 @@ int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsResourceRecord *dnskey,
/* Could this be interesting to us at all? If not,
* there's no point in looking for and verifying a
* self-signed RRSIG. */
- if (!dns_trust_anchor_knows_domain_positive(d, DNS_RESOURCE_KEY_NAME(dnskey->key)))
+ if (!dns_trust_anchor_knows_domain_positive(d, dns_resource_key_name(dnskey->key)))
return 0;
/* Look for a self-signed RRSIG in the other rrs belonging to this DNSKEY */
diff --git a/src/grp-resolve/systemd-resolved/resolved-dns-zone.c b/src/grp-resolve/systemd-resolved/resolved-dns-zone.c
index f52383cfd1..850eed8cb8 100644
--- a/src/grp-resolve/systemd-resolved/resolved-dns-zone.c
+++ b/src/grp-resolve/systemd-resolved/resolved-dns-zone.c
@@ -38,6 +38,7 @@ void dns_zone_item_probe_stop(DnsZoneItem *i) {
i->probe_transaction = NULL;
set_remove(t->notify_zone_items, i);
+ set_remove(t->notify_zone_items_done, i);
dns_transaction_gc(t);
}
@@ -68,12 +69,12 @@ static void dns_zone_item_remove_and_free(DnsZone *z, DnsZoneItem *i) {
else
hashmap_remove(z->by_key, i->rr->key);
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key));
+ first = hashmap_get(z->by_name, dns_resource_key_name(i->rr->key));
LIST_REMOVE(by_name, first, i);
if (first)
- assert_se(hashmap_replace(z->by_name, DNS_RESOURCE_KEY_NAME(first->rr->key), first) >= 0);
+ assert_se(hashmap_replace(z->by_name, dns_resource_key_name(first->rr->key), first) >= 0);
else
- hashmap_remove(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key));
+ hashmap_remove(z->by_name, dns_resource_key_name(i->rr->key));
dns_zone_item_free(i);
}
@@ -147,12 +148,12 @@ static int dns_zone_link_item(DnsZone *z, DnsZoneItem *i) {
return r;
}
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key));
+ first = hashmap_get(z->by_name, dns_resource_key_name(i->rr->key));
if (first) {
LIST_PREPEND(by_name, first, i);
- assert_se(hashmap_replace(z->by_name, DNS_RESOURCE_KEY_NAME(first->rr->key), first) >= 0);
+ assert_se(hashmap_replace(z->by_name, dns_resource_key_name(first->rr->key), first) >= 0);
} else {
- r = hashmap_put(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key), i);
+ r = hashmap_put(z->by_name, dns_resource_key_name(i->rr->key), i);
if (r < 0)
return r;
}
@@ -169,11 +170,11 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
if (i->probe_transaction)
return 0;
- t = dns_scope_find_transaction(i->scope, &DNS_RESOURCE_KEY_CONST(i->rr->key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(i->rr->key)), false);
+ t = dns_scope_find_transaction(i->scope, &DNS_RESOURCE_KEY_CONST(i->rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(i->rr->key)), false);
if (!t) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
- key = dns_resource_key_new(i->rr->key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(i->rr->key));
+ key = dns_resource_key_new(i->rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(i->rr->key));
if (!key)
return -ENOMEM;
@@ -186,6 +187,10 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
if (r < 0)
goto gc;
+ r = set_ensure_allocated(&t->notify_zone_items_done, NULL);
+ if (r < 0)
+ goto gc;
+
r = set_put(t->notify_zone_items, i);
if (r < 0)
goto gc;
@@ -303,7 +308,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
* go through the list by the name and look
* for everything manually */
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ first = hashmap_get(z->by_name, dns_resource_key_name(key));
LIST_FOREACH(by_name, j, first) {
if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
continue;
@@ -339,7 +344,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (!found) {
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ first = hashmap_get(z->by_name, dns_resource_key_name(key));
LIST_FOREACH(by_name, j, first) {
if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
continue;
@@ -370,7 +375,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
bool found = false, added = false;
int k;
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ first = hashmap_get(z->by_name, dns_resource_key_name(key));
LIST_FOREACH(by_name, j, first) {
if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
continue;
@@ -393,7 +398,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (found && !added) {
- r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(key), LLMNR_DEFAULT_TTL);
+ r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL);
if (r < 0)
return r;
}
@@ -418,7 +423,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
if (!found) {
bool add_soa = false;
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ first = hashmap_get(z->by_name, dns_resource_key_name(key));
LIST_FOREACH(by_name, j, first) {
if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
continue;
@@ -430,7 +435,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (add_soa) {
- r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(key), LLMNR_DEFAULT_TTL);
+ r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL);
if (r < 0)
return r;
}
@@ -482,7 +487,7 @@ void dns_zone_item_conflict(DnsZoneItem *i) {
i->state = DNS_ZONE_ITEM_WITHDRAWN;
/* Maybe change the hostname */
- if (manager_is_own_hostname(i->scope->manager, DNS_RESOURCE_KEY_NAME(i->rr->key)) > 0)
+ if (manager_is_own_hostname(i->scope->manager, dns_resource_key_name(i->rr->key)) > 0)
manager_next_hostname(i->scope->manager);
}
@@ -562,7 +567,7 @@ int dns_zone_check_conflicts(DnsZone *zone, DnsResourceRecord *rr) {
* so, we'll verify our RRs. */
/* No conflict if we don't have the name at all. */
- first = hashmap_get(zone->by_name, DNS_RESOURCE_KEY_NAME(rr->key));
+ first = hashmap_get(zone->by_name, dns_resource_key_name(rr->key));
if (!first)
return 0;
@@ -593,7 +598,7 @@ int dns_zone_verify_conflicts(DnsZone *zone, DnsResourceKey *key) {
/* Somebody else notified us about a possible conflict. Let's
* verify if that's true. */
- first = hashmap_get(zone->by_name, DNS_RESOURCE_KEY_NAME(key));
+ first = hashmap_get(zone->by_name, dns_resource_key_name(key));
if (!first)
return 0;
diff --git a/src/grp-resolve/systemd-resolved/resolved-etc-hosts.c b/src/grp-resolve/systemd-resolved/resolved-etc-hosts.c
index ee82c96822..40d650949d 100644
--- a/src/grp-resolve/systemd-resolved/resolved-etc-hosts.c
+++ b/src/grp-resolve/systemd-resolved/resolved-etc-hosts.c
@@ -301,7 +301,7 @@ int manager_etc_hosts_read(Manager *m) {
FOREACH_LINE(line, f, return log_error_errno(errno, "Failed to read /etc/hosts: %m")) {
char *l;
- nr ++;
+ nr++;
l = strstrip(line);
if (isempty(l))
@@ -363,7 +363,7 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) {
if (!IN_SET(t->class, DNS_CLASS_IN, DNS_CLASS_ANY))
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(t), name);
+ r = dns_name_equal(dns_resource_key_name(t), name);
if (r < 0)
return r;
if (r > 0) {
@@ -413,7 +413,7 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) {
if (!IN_SET(t->class, DNS_CLASS_IN, DNS_CLASS_ANY))
continue;
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(t), name);
+ r = dns_name_equal(dns_resource_key_name(t), name);
if (r < 0)
return r;
if (r == 0)
diff --git a/src/grp-resolve/systemd-resolved/resolved-link-bus.c b/src/grp-resolve/systemd-resolved/resolved-link-bus.c
index df7516f4f4..7f21891819 100644
--- a/src/grp-resolve/systemd-resolved/resolved-link-bus.c
+++ b/src/grp-resolve/systemd-resolved/resolved-link-bus.c
@@ -239,7 +239,7 @@ clear:
return r;
}
-int bus_link_method_set_search_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Link *l = userdata;
int r;
@@ -457,10 +457,10 @@ const sd_bus_vtable link_vtable[] = {
SD_BUS_PROPERTY("MulticastDNS", "s", property_get_resolve_support, offsetof(Link, mdns_support), 0),
SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, offsetof(Link, dnssec_mode), 0),
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
- SD_BUS_PROPERTY("DNSSECSupport", "b", property_get_dnssec_supported, 0, 0),
+ SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0),
- SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_search_domains, 0),
+ SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0),
SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
diff --git a/src/grp-resolve/systemd-resolved/resolved-link-bus.h b/src/grp-resolve/systemd-resolved/resolved-link-bus.h
index 5a8ee08ec7..b1ac57961d 100644
--- a/src/grp-resolve/systemd-resolved/resolved-link-bus.h
+++ b/src/grp-resolve/systemd-resolved/resolved-link-bus.h
@@ -30,7 +30,7 @@ char *link_bus_path(Link *link);
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_link_method_set_search_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/grp-resolve/systemd-resolved/resolved-link.c b/src/grp-resolve/systemd-resolved/resolved-link.c
index 65df95bb1f..4eef20599a 100644
--- a/src/grp-resolve/systemd-resolved/resolved-link.c
+++ b/src/grp-resolve/systemd-resolved/resolved-link.c
@@ -468,7 +468,7 @@ static void link_read_settings(Link *l) {
}
if (r > 0) {
- /* If this link used to be managed, but is now unmanaged, flush all our settings -- but only once. */
+ /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
if (l->is_managed)
link_flush_settings(l);
diff --git a/src/grp-resolve/systemd-resolved/resolved-llmnr.c b/src/grp-resolve/systemd-resolved/resolved-llmnr.c
index ef12abfbb5..8b1d71a3eb 100644
--- a/src/grp-resolve/systemd-resolved/resolved-llmnr.c
+++ b/src/grp-resolve/systemd-resolved/resolved-llmnr.c
@@ -286,7 +286,7 @@ static int on_llmnr_stream_packet(DnsStream *s) {
scope = manager_find_scope(s->manager, s->read_packet);
if (!scope) {
- log_warning("Got LLMNR TCP packet on unknown scope. Ignroing.");
+ log_warning("Got LLMNR TCP packet on unknown scope. Ignoring.");
return 0;
}
diff --git a/src/grp-resolve/systemd-resolved/resolved-manager.c b/src/grp-resolve/systemd-resolved/resolved-manager.c
index e82c6ec563..7166b94d71 100644
--- a/src/grp-resolve/systemd-resolved/resolved-manager.c
+++ b/src/grp-resolve/systemd-resolved/resolved-manager.c
@@ -485,7 +485,7 @@ int manager_new(Manager **ret) {
m->llmnr_support = RESOLVE_SUPPORT_YES;
m->mdns_support = RESOLVE_SUPPORT_NO;
- m->dnssec_mode = DNSSEC_NO;
+ m->dnssec_mode = DEFAULT_DNSSEC_MODE;
m->read_resolv_conf = true;
m->need_builtin_fallbacks = true;
m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
@@ -1213,11 +1213,11 @@ void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResource
assert(verdict < _DNSSEC_VERDICT_MAX);
if (log_get_max_level() >= LOG_DEBUG) {
- _cleanup_free_ char *s = NULL;
+ char s[DNS_RESOURCE_KEY_STRING_MAX];
- (void) dns_resource_key_to_string(key, &s);
-
- log_debug("Found verdict for lookup %s: %s", s ? strstrip(s) : "n/a", dnssec_verdict_to_string(verdict));
+ log_debug("Found verdict for lookup %s: %s",
+ dns_resource_key_to_string(key, s, sizeof s),
+ dnssec_verdict_to_string(verdict));
}
m->n_dnssec_verdict[verdict]++;
diff --git a/src/grp-resolve/systemd-resolved/resolved-mdns.c b/src/grp-resolve/systemd-resolved/resolved-mdns.c
index bc8b8b809b..b13b1d0144 100644
--- a/src/grp-resolve/systemd-resolved/resolved-mdns.c
+++ b/src/grp-resolve/systemd-resolved/resolved-mdns.c
@@ -106,7 +106,7 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
dns_scope_check_conflicts(scope, p);
DNS_ANSWER_FOREACH(rr, p->answer) {
- const char *name = DNS_RESOURCE_KEY_NAME(rr->key);
+ const char *name = dns_resource_key_name(rr->key);
DnsTransaction *t;
/* If the received reply packet contains ANY record that is not .local or .in-addr.arpa,
diff --git a/src/grp-resolve/systemd-resolved/resolved-resolv-conf.c b/src/grp-resolve/systemd-resolved/resolved-resolv-conf.c
index 065427b690..ff03acc772 100644
--- a/src/grp-resolve/systemd-resolved/resolved-resolv-conf.c
+++ b/src/grp-resolve/systemd-resolved/resolved-resolv-conf.c
@@ -158,7 +158,7 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
if (*count == MAXNS)
fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f);
- (*count) ++;
+ (*count)++;
fprintf(f, "nameserver %s\n", s->server_string);
}
@@ -184,7 +184,7 @@ static void write_resolv_conf_search(
}
(*length) += strlen(domain);
- (*count) ++;
+ (*count)++;
fputc(' ', f);
fputs(domain, f);
diff --git a/src/grp-resolve/systemd-resolved/resolved.c b/src/grp-resolve/systemd-resolved/resolved.c
index 07e6bfb54a..086a2fcac7 100644
--- a/src/grp-resolve/systemd-resolved/resolved.c
+++ b/src/grp-resolve/systemd-resolved/resolved.c
@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init(NULL);
+ r = mac_selinux_init();
if (r < 0) {
log_error_errno(r, "SELinux setup failed: %m");
goto finish;
diff --git a/src/grp-resolve/systemd-resolved/resolved.conf.in b/src/grp-resolve/systemd-resolved/resolved.conf.in
index efc9c6733a..a288588924 100644
--- a/src/grp-resolve/systemd-resolved/resolved.conf.in
+++ b/src/grp-resolve/systemd-resolved/resolved.conf.in
@@ -16,4 +16,4 @@
#FallbackDNS=@DNS_SERVERS@
#Domains=
#LLMNR=yes
-#DNSSEC=no
+#DNSSEC=@DEFAULT_DNSSEC_MODE@
diff --git a/src/grp-resolve/systemd-resolved/test-data/_443._tcp.fedoraproject.org.pkts b/src/grp-resolve/systemd-resolved/test-data/_443._tcp.fedoraproject.org.pkts
new file mode 100644
index 0000000000..a383c6286d
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/_443._tcp.fedoraproject.org.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/_openpgpkey.fedoraproject.org.pkts b/src/grp-resolve/systemd-resolved/test-data/_openpgpkey.fedoraproject.org.pkts
new file mode 100644
index 0000000000..15de02e997
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/_openpgpkey.fedoraproject.org.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/fake-caa.pkts b/src/grp-resolve/systemd-resolved/test-data/fake-caa.pkts
new file mode 100644
index 0000000000..1c3ecc5491
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/fake-caa.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/fedoraproject.org.pkts b/src/grp-resolve/systemd-resolved/test-data/fedoraproject.org.pkts
new file mode 100644
index 0000000000..17874844d9
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/fedoraproject.org.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/gandi.net.pkts b/src/grp-resolve/systemd-resolved/test-data/gandi.net.pkts
new file mode 100644
index 0000000000..5ef51e0c8e
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/gandi.net.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/google.com.pkts b/src/grp-resolve/systemd-resolved/test-data/google.com.pkts
new file mode 100644
index 0000000000..f98c4cd855
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/google.com.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/kyhwana.org.pkts b/src/grp-resolve/systemd-resolved/test-data/kyhwana.org.pkts
new file mode 100644
index 0000000000..e28a725c9a
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/kyhwana.org.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/root.pkts b/src/grp-resolve/systemd-resolved/test-data/root.pkts
new file mode 100644
index 0000000000..54ba668c75
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/root.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts b/src/grp-resolve/systemd-resolved/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
new file mode 100644
index 0000000000..a854249532
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/teamits.com.pkts b/src/grp-resolve/systemd-resolved/test-data/teamits.com.pkts
new file mode 100644
index 0000000000..11deb39677
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/teamits.com.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-data/zbyszek@fedoraproject.org.pkts b/src/grp-resolve/systemd-resolved/test-data/zbyszek@fedoraproject.org.pkts
new file mode 100644
index 0000000000..f0a6f982df
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-data/zbyszek@fedoraproject.org.pkts
Binary files differ
diff --git a/src/grp-resolve/systemd-resolved/test-dns-packet.c b/src/grp-resolve/systemd-resolved/test-dns-packet.c
new file mode 100644
index 0000000000..c232a69ce1
--- /dev/null
+++ b/src/grp-resolve/systemd-resolved/test-dns-packet.c
@@ -0,0 +1,114 @@
+/***
+ 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 <net/if.h>
+#include <glob.h>
+
+#include "alloc-util.h"
+#include "fileio.h"
+#include "glob-util.h"
+#include "log.h"
+#include "macro.h"
+#include "resolved-dns-packet.h"
+#include "resolved-dns-rr.h"
+#include "string-util.h"
+#include "strv.h"
+
+#define HASH_KEY SD_ID128_MAKE(d3,1e,48,90,4b,fa,4c,fe,af,9d,d5,a1,d7,2e,8a,b1)
+
+static uint64_t hash(DnsResourceRecord *rr) {
+ struct siphash state;
+
+ siphash24_init(&state, HASH_KEY.bytes);
+ dns_resource_record_hash_func(rr, &state);
+ return siphash24_finalize(&state);
+}
+
+static void test_packet_from_file(const char* filename, bool canonical) {
+ _cleanup_free_ char *data = NULL;
+ size_t data_size, packet_size, offset;
+
+ assert_se(read_full_file(filename, &data, &data_size) >= 0);
+ assert_se(data);
+ assert_se(data_size > 8);
+
+ log_info("============== %s %s==============", filename, canonical ? "canonical " : "");
+
+ for (offset = 0; offset < data_size; offset += 8 + packet_size) {
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL, *p2 = NULL;
+ _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL, *rr2 = NULL;
+ const char *s, *s2;
+ uint64_t hash1, hash2;
+
+ packet_size = le64toh( *(uint64_t*)(data + offset) );
+ assert_se(packet_size > 0);
+ assert_se(offset + 8 + packet_size <= data_size);
+
+ assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, 0) >= 0);
+
+ assert_se(dns_packet_append_blob(p, data + offset + 8, packet_size, NULL) >= 0);
+ assert_se(dns_packet_read_rr(p, &rr, NULL, NULL) >= 0);
+
+ s = dns_resource_record_to_string(rr);
+ assert_se(s);
+ puts(s);
+
+ hash1 = hash(rr);
+
+ assert_se(dns_resource_record_to_wire_format(rr, canonical) >= 0);
+
+ assert_se(dns_packet_new(&p2, DNS_PROTOCOL_DNS, 0) >= 0);
+ assert_se(dns_packet_append_blob(p2, rr->wire_format, rr->wire_format_size, NULL) >= 0);
+ assert_se(dns_packet_read_rr(p2, &rr2, NULL, NULL) >= 0);
+
+ s2 = dns_resource_record_to_string(rr);
+ assert_se(s2);
+ assert_se(streq(s, s2));
+
+ hash2 = hash(rr);
+ assert_se(hash1 == hash2);
+ }
+}
+
+int main(int argc, char **argv) {
+ int i, N;
+ _cleanup_globfree_ glob_t g = {};
+ char **fnames;
+
+ log_parse_environment();
+
+ if (argc >= 2) {
+ N = argc - 1;
+ fnames = argv + 1;
+ } else {
+ assert_se(glob(RESOLVE_TEST_DIR "/*.pkts", GLOB_NOSORT, NULL, &g) == 0);
+ N = g.gl_pathc;
+ fnames = g.gl_pathv;
+ }
+
+ for (i = 0; i < N; i++) {
+ test_packet_from_file(fnames[i], false);
+ puts("");
+ test_packet_from_file(fnames[i], true);
+ if (i + 1 < N)
+ puts("");
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/grp-resolve/systemd-resolved/test-dnssec.c b/src/grp-resolve/systemd-resolved/test-dnssec.c
index a093d86a91..b3018e8239 100644
--- a/src/grp-resolve/systemd-resolved/test-dnssec.c
+++ b/src/grp-resolve/systemd-resolved/test-dnssec.c
@@ -27,77 +27,89 @@
#include "string-util.h"
#include "hexdecoct.h"
-static void test_dnssec_verify_rrset2(void) {
+static void test_dnssec_canonicalize_one(const char *original, const char *canonical, int r) {
+ char canonicalized[DNSSEC_CANONICAL_HOSTNAME_MAX];
- static const uint8_t signature_blob[] = {
- 0x48, 0x45, 0xc8, 0x8b, 0xc0, 0x14, 0x92, 0xf5, 0x15, 0xc6, 0x84, 0x9d, 0x2f, 0xe3, 0x32, 0x11,
- 0x7d, 0xf1, 0xe6, 0x87, 0xb9, 0x42, 0xd3, 0x8b, 0x9e, 0xaf, 0x92, 0x31, 0x0a, 0x53, 0xad, 0x8b,
- 0xa7, 0x5c, 0x83, 0x39, 0x8c, 0x28, 0xac, 0xce, 0x6e, 0x9c, 0x18, 0xe3, 0x31, 0x16, 0x6e, 0xca,
- 0x38, 0x31, 0xaf, 0xd9, 0x94, 0xf1, 0x84, 0xb1, 0xdf, 0x5a, 0xc2, 0x73, 0x22, 0xf6, 0xcb, 0xa2,
- 0xe7, 0x8c, 0x77, 0x0c, 0x74, 0x2f, 0xc2, 0x13, 0xb0, 0x93, 0x51, 0xa9, 0x4f, 0xae, 0x0a, 0xda,
- 0x45, 0xcc, 0xfd, 0x43, 0x99, 0x36, 0x9a, 0x0d, 0x21, 0xe0, 0xeb, 0x30, 0x65, 0xd4, 0xa0, 0x27,
- 0x37, 0x3b, 0xe4, 0xc1, 0xc5, 0xa1, 0x2a, 0xd1, 0x76, 0xc4, 0x7e, 0x64, 0x0e, 0x5a, 0xa6, 0x50,
- 0x24, 0xd5, 0x2c, 0xcc, 0x6d, 0xe5, 0x37, 0xea, 0xbd, 0x09, 0x34, 0xed, 0x24, 0x06, 0xa1, 0x22,
- };
+ assert_se(dnssec_canonicalize(original, canonicalized, sizeof(canonicalized)) == r);
+ if (r < 0)
+ return;
+
+ assert_se(streq(canonicalized, canonical));
+}
+static void test_dnssec_canonicalize(void) {
+ test_dnssec_canonicalize_one("", ".", 1);
+ test_dnssec_canonicalize_one(".", ".", 1);
+ test_dnssec_canonicalize_one("foo", "foo.", 4);
+ test_dnssec_canonicalize_one("foo.", "foo.", 4);
+ test_dnssec_canonicalize_one("FOO.", "foo.", 4);
+ test_dnssec_canonicalize_one("FOO.bar.", "foo.bar.", 8);
+ test_dnssec_canonicalize_one("FOO..bar.", NULL, -EINVAL);
+}
+
+#ifdef HAVE_GCRYPT
+
+static void test_dnssec_verify_dns_key(void) {
+
+ static const uint8_t ds1_fprint[] = {
+ 0x46, 0x8B, 0xC8, 0xDD, 0xC7, 0xE8, 0x27, 0x03, 0x40, 0xBB, 0x8A, 0x1F, 0x3B, 0x2E, 0x45, 0x9D,
+ 0x80, 0x67, 0x14, 0x01,
+ };
+ static const uint8_t ds2_fprint[] = {
+ 0x8A, 0xEE, 0x80, 0x47, 0x05, 0x5F, 0x83, 0xD1, 0x48, 0xBA, 0x8F, 0xF6, 0xDD, 0xA7, 0x60, 0xCE,
+ 0x94, 0xF7, 0xC7, 0x5E, 0x52, 0x4C, 0xF2, 0xE9, 0x50, 0xB9, 0x2E, 0xCB, 0xEF, 0x96, 0xB9, 0x98,
+ };
static const uint8_t dnskey_blob[] = {
- 0x03, 0x01, 0x00, 0x01, 0xc3, 0x7f, 0x1d, 0xd1, 0x1c, 0x97, 0xb1, 0x13, 0x34, 0x3a, 0x9a, 0xea,
- 0xee, 0xd9, 0x5a, 0x11, 0x1b, 0x17, 0xc7, 0xe3, 0xd4, 0xda, 0x20, 0xbc, 0x5d, 0xba, 0x74, 0xe3,
- 0x37, 0x99, 0xec, 0x25, 0xce, 0x93, 0x7f, 0xbd, 0x22, 0x73, 0x7e, 0x14, 0x71, 0xe0, 0x60, 0x07,
- 0xd4, 0x39, 0x8b, 0x5e, 0xe9, 0xba, 0x25, 0xe8, 0x49, 0xe9, 0x34, 0xef, 0xfe, 0x04, 0x5c, 0xa5,
- 0x27, 0xcd, 0xa9, 0xda, 0x70, 0x05, 0x21, 0xab, 0x15, 0x82, 0x24, 0xc3, 0x94, 0xf5, 0xd7, 0xb7,
- 0xc4, 0x66, 0xcb, 0x32, 0x6e, 0x60, 0x2b, 0x55, 0x59, 0x28, 0x89, 0x8a, 0x72, 0xde, 0x88, 0x56,
- 0x27, 0x95, 0xd9, 0xac, 0x88, 0x4f, 0x65, 0x2b, 0x68, 0xfc, 0xe6, 0x41, 0xc1, 0x1b, 0xef, 0x4e,
- 0xd6, 0xc2, 0x0f, 0x64, 0x88, 0x95, 0x5e, 0xdd, 0x3a, 0x02, 0x07, 0x50, 0xa9, 0xda, 0xa4, 0x49,
- 0x74, 0x62, 0xfe, 0xd7,
+ 0x03, 0x01, 0x00, 0x01, 0xa8, 0x12, 0xda, 0x4f, 0xd2, 0x7d, 0x54, 0x14, 0x0e, 0xcc, 0x5b, 0x5e,
+ 0x45, 0x9c, 0x96, 0x98, 0xc0, 0xc0, 0x85, 0x81, 0xb1, 0x47, 0x8c, 0x7d, 0xe8, 0x39, 0x50, 0xcc,
+ 0xc5, 0xd0, 0xf2, 0x00, 0x81, 0x67, 0x79, 0xf6, 0xcc, 0x9d, 0xad, 0x6c, 0xbb, 0x7b, 0x6f, 0x48,
+ 0x97, 0x15, 0x1c, 0xfd, 0x0b, 0xfe, 0xd3, 0xd7, 0x7d, 0x9f, 0x81, 0x26, 0xd3, 0xc5, 0x65, 0x49,
+ 0xcf, 0x46, 0x62, 0xb0, 0x55, 0x6e, 0x47, 0xc7, 0x30, 0xef, 0x51, 0xfb, 0x3e, 0xc6, 0xef, 0xde,
+ 0x27, 0x3f, 0xfa, 0x57, 0x2d, 0xa7, 0x1d, 0x80, 0x46, 0x9a, 0x5f, 0x14, 0xb3, 0xb0, 0x2c, 0xbe,
+ 0x72, 0xca, 0xdf, 0xb2, 0xff, 0x36, 0x5b, 0x4f, 0xec, 0x58, 0x8e, 0x8d, 0x01, 0xe9, 0xa9, 0xdf,
+ 0xb5, 0x60, 0xad, 0x52, 0x4d, 0xfc, 0xa9, 0x3e, 0x8d, 0x35, 0x95, 0xb3, 0x4e, 0x0f, 0xca, 0x45,
+ 0x1b, 0xf7, 0xef, 0x3a, 0x88, 0x25, 0x08, 0xc7, 0x4e, 0x06, 0xc1, 0x62, 0x1a, 0xce, 0xd8, 0x77,
+ 0xbd, 0x02, 0x65, 0xf8, 0x49, 0xfb, 0xce, 0xf6, 0xa8, 0x09, 0xfc, 0xde, 0xb2, 0x09, 0x9d, 0x39,
+ 0xf8, 0x63, 0x9c, 0x32, 0x42, 0x7c, 0xa0, 0x30, 0x86, 0x72, 0x7a, 0x4a, 0xc6, 0xd4, 0xb3, 0x2d,
+ 0x24, 0xef, 0x96, 0x3f, 0xc2, 0xda, 0xd3, 0xf2, 0x15, 0x6f, 0xda, 0x65, 0x4b, 0x81, 0x28, 0x68,
+ 0xf4, 0xfe, 0x3e, 0x71, 0x4f, 0x50, 0x96, 0x72, 0x58, 0xa1, 0x89, 0xdd, 0x01, 0x61, 0x39, 0x39,
+ 0xc6, 0x76, 0xa4, 0xda, 0x02, 0x70, 0x3d, 0xc0, 0xdc, 0x8d, 0x70, 0x72, 0x04, 0x90, 0x79, 0xd4,
+ 0xec, 0x65, 0xcf, 0x49, 0x35, 0x25, 0x3a, 0x14, 0x1a, 0x45, 0x20, 0xeb, 0x31, 0xaf, 0x92, 0xba,
+ 0x20, 0xd3, 0xcd, 0xa7, 0x13, 0x44, 0xdc, 0xcf, 0xf0, 0x27, 0x34, 0xb9, 0xe7, 0x24, 0x6f, 0x73,
+ 0xe7, 0xea, 0x77, 0x03,
};
- _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *nsec = NULL, *rrsig = NULL, *dnskey = NULL;
- _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
- DnssecResult result;
-
- nsec = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC, "nasa.gov");
- assert_se(nsec);
+ _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds1 = NULL, *ds2 = NULL;
- nsec->nsec.next_domain_name = strdup("3D-Printing.nasa.gov");
- assert_se(nsec->nsec.next_domain_name);
+ /* The two DS RRs in effect for nasa.gov on 2015-12-01. */
+ ds1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "nasa.gov");
+ assert_se(ds1);
- nsec->nsec.types = bitmap_new();
- assert_se(nsec->nsec.types);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_A) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NS) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_SOA) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_MX) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_TXT) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_RRSIG) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NSEC) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_DNSKEY) >= 0);
- assert_se(bitmap_set(nsec->nsec.types, 65534) >= 0);
+ ds1->ds.key_tag = 47857;
+ ds1->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
+ ds1->ds.digest_type = DNSSEC_DIGEST_SHA1;
+ ds1->ds.digest_size = sizeof(ds1_fprint);
+ ds1->ds.digest = memdup(ds1_fprint, ds1->ds.digest_size);
+ assert_se(ds1->ds.digest);
- log_info("NSEC: %s", strna(dns_resource_record_to_string(nsec)));
+ log_info("DS1: %s", strna(dns_resource_record_to_string(ds1)));
- rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV.");
- assert_se(rrsig);
+ ds2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "NASA.GOV");
+ assert_se(ds2);
- rrsig->rrsig.type_covered = DNS_TYPE_NSEC;
- rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
- rrsig->rrsig.labels = 2;
- rrsig->rrsig.original_ttl = 300;
- rrsig->rrsig.expiration = 0x5689002f;
- rrsig->rrsig.inception = 0x56617230;
- rrsig->rrsig.key_tag = 30390;
- rrsig->rrsig.signer = strdup("Nasa.Gov.");
- assert_se(rrsig->rrsig.signer);
- rrsig->rrsig.signature_size = sizeof(signature_blob);
- rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
- assert_se(rrsig->rrsig.signature);
+ ds2->ds.key_tag = 47857;
+ ds2->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
+ ds2->ds.digest_type = DNSSEC_DIGEST_SHA256;
+ ds2->ds.digest_size = sizeof(ds2_fprint);
+ ds2->ds.digest = memdup(ds2_fprint, ds2->ds.digest_size);
+ assert_se(ds2->ds.digest);
- log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
+ log_info("DS2: %s", strna(dns_resource_record_to_string(ds2)));
- dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV");
+ dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nasa.GOV");
assert_se(dnskey);
- dnskey->dnskey.flags = 256;
+ dnskey->dnskey.flags = 257;
dnskey->dnskey.protocol = 3;
dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
dnskey->dnskey.key_size = sizeof(dnskey_blob);
@@ -107,16 +119,8 @@ static void test_dnssec_verify_rrset2(void) {
log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
- assert_se(dnssec_key_match_rrsig(nsec->key, rrsig) > 0);
- assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
-
- answer = dns_answer_new(1);
- assert_se(answer);
- assert_se(dns_answer_add(answer, nsec, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
-
- /* Validate the RR as it if was 2015-12-11 today */
- assert_se(dnssec_verify_rrset(answer, nsec->key, rrsig, dnskey, 1449849318*USEC_PER_SEC, &result) >= 0);
- assert_se(result == DNSSEC_VALIDATED);
+ assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds1, false) > 0);
+ assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds2, false) > 0);
}
static void test_dnssec_verify_rrset(void) {
@@ -198,67 +202,77 @@ static void test_dnssec_verify_rrset(void) {
assert_se(result == DNSSEC_VALIDATED);
}
-static void test_dnssec_verify_dns_key(void) {
+static void test_dnssec_verify_rrset2(void) {
- static const uint8_t ds1_fprint[] = {
- 0x46, 0x8B, 0xC8, 0xDD, 0xC7, 0xE8, 0x27, 0x03, 0x40, 0xBB, 0x8A, 0x1F, 0x3B, 0x2E, 0x45, 0x9D,
- 0x80, 0x67, 0x14, 0x01,
- };
- static const uint8_t ds2_fprint[] = {
- 0x8A, 0xEE, 0x80, 0x47, 0x05, 0x5F, 0x83, 0xD1, 0x48, 0xBA, 0x8F, 0xF6, 0xDD, 0xA7, 0x60, 0xCE,
- 0x94, 0xF7, 0xC7, 0x5E, 0x52, 0x4C, 0xF2, 0xE9, 0x50, 0xB9, 0x2E, 0xCB, 0xEF, 0x96, 0xB9, 0x98,
+ static const uint8_t signature_blob[] = {
+ 0x48, 0x45, 0xc8, 0x8b, 0xc0, 0x14, 0x92, 0xf5, 0x15, 0xc6, 0x84, 0x9d, 0x2f, 0xe3, 0x32, 0x11,
+ 0x7d, 0xf1, 0xe6, 0x87, 0xb9, 0x42, 0xd3, 0x8b, 0x9e, 0xaf, 0x92, 0x31, 0x0a, 0x53, 0xad, 0x8b,
+ 0xa7, 0x5c, 0x83, 0x39, 0x8c, 0x28, 0xac, 0xce, 0x6e, 0x9c, 0x18, 0xe3, 0x31, 0x16, 0x6e, 0xca,
+ 0x38, 0x31, 0xaf, 0xd9, 0x94, 0xf1, 0x84, 0xb1, 0xdf, 0x5a, 0xc2, 0x73, 0x22, 0xf6, 0xcb, 0xa2,
+ 0xe7, 0x8c, 0x77, 0x0c, 0x74, 0x2f, 0xc2, 0x13, 0xb0, 0x93, 0x51, 0xa9, 0x4f, 0xae, 0x0a, 0xda,
+ 0x45, 0xcc, 0xfd, 0x43, 0x99, 0x36, 0x9a, 0x0d, 0x21, 0xe0, 0xeb, 0x30, 0x65, 0xd4, 0xa0, 0x27,
+ 0x37, 0x3b, 0xe4, 0xc1, 0xc5, 0xa1, 0x2a, 0xd1, 0x76, 0xc4, 0x7e, 0x64, 0x0e, 0x5a, 0xa6, 0x50,
+ 0x24, 0xd5, 0x2c, 0xcc, 0x6d, 0xe5, 0x37, 0xea, 0xbd, 0x09, 0x34, 0xed, 0x24, 0x06, 0xa1, 0x22,
};
+
static const uint8_t dnskey_blob[] = {
- 0x03, 0x01, 0x00, 0x01, 0xa8, 0x12, 0xda, 0x4f, 0xd2, 0x7d, 0x54, 0x14, 0x0e, 0xcc, 0x5b, 0x5e,
- 0x45, 0x9c, 0x96, 0x98, 0xc0, 0xc0, 0x85, 0x81, 0xb1, 0x47, 0x8c, 0x7d, 0xe8, 0x39, 0x50, 0xcc,
- 0xc5, 0xd0, 0xf2, 0x00, 0x81, 0x67, 0x79, 0xf6, 0xcc, 0x9d, 0xad, 0x6c, 0xbb, 0x7b, 0x6f, 0x48,
- 0x97, 0x15, 0x1c, 0xfd, 0x0b, 0xfe, 0xd3, 0xd7, 0x7d, 0x9f, 0x81, 0x26, 0xd3, 0xc5, 0x65, 0x49,
- 0xcf, 0x46, 0x62, 0xb0, 0x55, 0x6e, 0x47, 0xc7, 0x30, 0xef, 0x51, 0xfb, 0x3e, 0xc6, 0xef, 0xde,
- 0x27, 0x3f, 0xfa, 0x57, 0x2d, 0xa7, 0x1d, 0x80, 0x46, 0x9a, 0x5f, 0x14, 0xb3, 0xb0, 0x2c, 0xbe,
- 0x72, 0xca, 0xdf, 0xb2, 0xff, 0x36, 0x5b, 0x4f, 0xec, 0x58, 0x8e, 0x8d, 0x01, 0xe9, 0xa9, 0xdf,
- 0xb5, 0x60, 0xad, 0x52, 0x4d, 0xfc, 0xa9, 0x3e, 0x8d, 0x35, 0x95, 0xb3, 0x4e, 0x0f, 0xca, 0x45,
- 0x1b, 0xf7, 0xef, 0x3a, 0x88, 0x25, 0x08, 0xc7, 0x4e, 0x06, 0xc1, 0x62, 0x1a, 0xce, 0xd8, 0x77,
- 0xbd, 0x02, 0x65, 0xf8, 0x49, 0xfb, 0xce, 0xf6, 0xa8, 0x09, 0xfc, 0xde, 0xb2, 0x09, 0x9d, 0x39,
- 0xf8, 0x63, 0x9c, 0x32, 0x42, 0x7c, 0xa0, 0x30, 0x86, 0x72, 0x7a, 0x4a, 0xc6, 0xd4, 0xb3, 0x2d,
- 0x24, 0xef, 0x96, 0x3f, 0xc2, 0xda, 0xd3, 0xf2, 0x15, 0x6f, 0xda, 0x65, 0x4b, 0x81, 0x28, 0x68,
- 0xf4, 0xfe, 0x3e, 0x71, 0x4f, 0x50, 0x96, 0x72, 0x58, 0xa1, 0x89, 0xdd, 0x01, 0x61, 0x39, 0x39,
- 0xc6, 0x76, 0xa4, 0xda, 0x02, 0x70, 0x3d, 0xc0, 0xdc, 0x8d, 0x70, 0x72, 0x04, 0x90, 0x79, 0xd4,
- 0xec, 0x65, 0xcf, 0x49, 0x35, 0x25, 0x3a, 0x14, 0x1a, 0x45, 0x20, 0xeb, 0x31, 0xaf, 0x92, 0xba,
- 0x20, 0xd3, 0xcd, 0xa7, 0x13, 0x44, 0xdc, 0xcf, 0xf0, 0x27, 0x34, 0xb9, 0xe7, 0x24, 0x6f, 0x73,
- 0xe7, 0xea, 0x77, 0x03,
+ 0x03, 0x01, 0x00, 0x01, 0xc3, 0x7f, 0x1d, 0xd1, 0x1c, 0x97, 0xb1, 0x13, 0x34, 0x3a, 0x9a, 0xea,
+ 0xee, 0xd9, 0x5a, 0x11, 0x1b, 0x17, 0xc7, 0xe3, 0xd4, 0xda, 0x20, 0xbc, 0x5d, 0xba, 0x74, 0xe3,
+ 0x37, 0x99, 0xec, 0x25, 0xce, 0x93, 0x7f, 0xbd, 0x22, 0x73, 0x7e, 0x14, 0x71, 0xe0, 0x60, 0x07,
+ 0xd4, 0x39, 0x8b, 0x5e, 0xe9, 0xba, 0x25, 0xe8, 0x49, 0xe9, 0x34, 0xef, 0xfe, 0x04, 0x5c, 0xa5,
+ 0x27, 0xcd, 0xa9, 0xda, 0x70, 0x05, 0x21, 0xab, 0x15, 0x82, 0x24, 0xc3, 0x94, 0xf5, 0xd7, 0xb7,
+ 0xc4, 0x66, 0xcb, 0x32, 0x6e, 0x60, 0x2b, 0x55, 0x59, 0x28, 0x89, 0x8a, 0x72, 0xde, 0x88, 0x56,
+ 0x27, 0x95, 0xd9, 0xac, 0x88, 0x4f, 0x65, 0x2b, 0x68, 0xfc, 0xe6, 0x41, 0xc1, 0x1b, 0xef, 0x4e,
+ 0xd6, 0xc2, 0x0f, 0x64, 0x88, 0x95, 0x5e, 0xdd, 0x3a, 0x02, 0x07, 0x50, 0xa9, 0xda, 0xa4, 0x49,
+ 0x74, 0x62, 0xfe, 0xd7,
};
- _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds1 = NULL, *ds2 = NULL;
+ _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *nsec = NULL, *rrsig = NULL, *dnskey = NULL;
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ DnssecResult result;
- /* The two DS RRs in effect for nasa.gov on 2015-12-01. */
- ds1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "nasa.gov");
- assert_se(ds1);
+ nsec = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC, "nasa.gov");
+ assert_se(nsec);
- ds1->ds.key_tag = 47857;
- ds1->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
- ds1->ds.digest_type = DNSSEC_DIGEST_SHA1;
- ds1->ds.digest_size = sizeof(ds1_fprint);
- ds1->ds.digest = memdup(ds1_fprint, ds1->ds.digest_size);
- assert_se(ds1->ds.digest);
+ nsec->nsec.next_domain_name = strdup("3D-Printing.nasa.gov");
+ assert_se(nsec->nsec.next_domain_name);
- log_info("DS1: %s", strna(dns_resource_record_to_string(ds1)));
+ nsec->nsec.types = bitmap_new();
+ assert_se(nsec->nsec.types);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_A) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NS) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_SOA) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_MX) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_TXT) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_RRSIG) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NSEC) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_DNSKEY) >= 0);
+ assert_se(bitmap_set(nsec->nsec.types, 65534) >= 0);
- ds2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "NASA.GOV");
- assert_se(ds2);
+ log_info("NSEC: %s", strna(dns_resource_record_to_string(nsec)));
- ds2->ds.key_tag = 47857;
- ds2->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
- ds2->ds.digest_type = DNSSEC_DIGEST_SHA256;
- ds2->ds.digest_size = sizeof(ds2_fprint);
- ds2->ds.digest = memdup(ds2_fprint, ds2->ds.digest_size);
- assert_se(ds2->ds.digest);
+ rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV.");
+ assert_se(rrsig);
- log_info("DS2: %s", strna(dns_resource_record_to_string(ds2)));
+ rrsig->rrsig.type_covered = DNS_TYPE_NSEC;
+ rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
+ rrsig->rrsig.labels = 2;
+ rrsig->rrsig.original_ttl = 300;
+ rrsig->rrsig.expiration = 0x5689002f;
+ rrsig->rrsig.inception = 0x56617230;
+ rrsig->rrsig.key_tag = 30390;
+ rrsig->rrsig.signer = strdup("Nasa.Gov.");
+ assert_se(rrsig->rrsig.signer);
+ rrsig->rrsig.signature_size = sizeof(signature_blob);
+ rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
+ assert_se(rrsig->rrsig.signature);
- dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nasa.GOV");
+ log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
+
+ dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV");
assert_se(dnskey);
- dnskey->dnskey.flags = 257;
+ dnskey->dnskey.flags = 256;
dnskey->dnskey.protocol = 3;
dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
dnskey->dnskey.key_size = sizeof(dnskey_blob);
@@ -268,28 +282,16 @@ static void test_dnssec_verify_dns_key(void) {
log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
- assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds1, false) > 0);
- assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds2, false) > 0);
-}
-
-static void test_dnssec_canonicalize_one(const char *original, const char *canonical, int r) {
- char canonicalized[DNSSEC_CANONICAL_HOSTNAME_MAX];
-
- assert_se(dnssec_canonicalize(original, canonicalized, sizeof(canonicalized)) == r);
- if (r < 0)
- return;
+ assert_se(dnssec_key_match_rrsig(nsec->key, rrsig) > 0);
+ assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
- assert_se(streq(canonicalized, canonical));
-}
+ answer = dns_answer_new(1);
+ assert_se(answer);
+ assert_se(dns_answer_add(answer, nsec, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
-static void test_dnssec_canonicalize(void) {
- test_dnssec_canonicalize_one("", ".", 1);
- test_dnssec_canonicalize_one(".", ".", 1);
- test_dnssec_canonicalize_one("foo", "foo.", 4);
- test_dnssec_canonicalize_one("foo.", "foo.", 4);
- test_dnssec_canonicalize_one("FOO.", "foo.", 4);
- test_dnssec_canonicalize_one("FOO.bar.", "foo.bar.", 8);
- test_dnssec_canonicalize_one("FOO..bar.", NULL, -EINVAL);
+ /* Validate the RR as it if was 2015-12-11 today */
+ assert_se(dnssec_verify_rrset(answer, nsec->key, rrsig, dnskey, 1449849318*USEC_PER_SEC, &result) >= 0);
+ assert_se(result == DNSSEC_VALIDATED);
}
static void test_dnssec_nsec3_hash(void) {
@@ -324,13 +326,18 @@ static void test_dnssec_nsec3_hash(void) {
assert_se(strcasecmp(b, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM") == 0);
}
+#endif
+
int main(int argc, char*argv[]) {
test_dnssec_canonicalize();
+
+#ifdef HAVE_GCRYPT
test_dnssec_verify_dns_key();
test_dnssec_verify_rrset();
test_dnssec_verify_rrset2();
test_dnssec_nsec3_hash();
+#endif
return 0;
}
diff --git a/src/grp-resolve/systemd-resolved/test-resolve-tables.c b/src/grp-resolve/systemd-resolved/test-resolve-tables.c
index 63660afc87..2d615130e1 100644
--- a/src/grp-resolve/systemd-resolved/test-resolve-tables.c
+++ b/src/grp-resolve/systemd-resolved/test-resolve-tables.c
@@ -21,7 +21,44 @@
#include "test-tables.h"
int main(int argc, char **argv) {
+ uint16_t i;
+
test_table_sparse(dns_type, DNS_TYPE);
+ log_info("/* DNS_TYPE */");
+ for (i = 0; i < _DNS_TYPE_MAX; i++) {
+ const char *s;
+
+ s = dns_type_to_string(i);
+ assert_se(s == NULL || strlen(s) < _DNS_TYPE_STRING_MAX);
+
+ if (s)
+ log_info("%-*s %s%s%s%s%s%s%s%s%s",
+ (int) _DNS_TYPE_STRING_MAX - 1, s,
+ dns_type_is_pseudo(i) ? "pseudo " : "",
+ dns_type_is_valid_query(i) ? "valid_query " : "",
+ dns_type_is_valid_rr(i) ? "is_valid_rr " : "",
+ dns_type_may_redirect(i) ? "may_redirect " : "",
+ dns_type_is_dnssec(i) ? "dnssec " : "",
+ dns_type_is_obsolete(i) ? "obsolete " : "",
+ dns_type_may_wildcard(i) ? "wildcard " : "",
+ dns_type_apex_only(i) ? "apex_only " : "",
+ dns_type_needs_authentication(i) ? "needs_authentication" : "");
+ }
+
+ log_info("/* DNS_CLASS */");
+ for (i = 0; i < _DNS_CLASS_MAX; i++) {
+ const char *s;
+
+ s = dns_class_to_string(i);
+ assert_se(s == NULL || strlen(s) < _DNS_CLASS_STRING_MAX);
+
+ if (s)
+ log_info("%-*s %s%s",
+ (int) _DNS_CLASS_STRING_MAX - 1, s,
+ dns_class_is_pseudo(i) ? "is_pseudo " : "",
+ dns_class_is_valid_rr(i) ? "is_valid_rr " : "");
+ }
+
return EXIT_SUCCESS;
}
diff --git a/src/grp-system/systemctl/systemctl.c b/src/grp-system/systemctl/systemctl.c
index c03fca06c8..c7c00bbbc3 100644
--- a/src/grp-system/systemctl/systemctl.c
+++ b/src/grp-system/systemctl/systemctl.c
@@ -39,6 +39,7 @@
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-message.h"
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
@@ -101,8 +102,10 @@ static bool arg_no_block = false;
static bool arg_no_legend = false;
static bool arg_no_pager = false;
static bool arg_no_wtmp = false;
+static bool arg_no_sync = false;
static bool arg_no_wall = false;
static bool arg_no_reload = false;
+static bool arg_value = false;
static bool arg_show_types = false;
static bool arg_ignore_inhibitors = false;
static bool arg_dry = false;
@@ -152,7 +155,7 @@ static bool arg_now = false;
static int daemon_reload(int argc, char *argv[], void* userdata);
static int halt_now(enum action a);
-static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
+static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state);
static bool original_stdout_is_tty;
@@ -200,14 +203,6 @@ static void release_busses(void) {
busses[w] = sd_bus_flush_close_unref(busses[w]);
}
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static void ask_password_agent_open_if_enabled(void) {
/* Open the password agent as a child process if necessary */
@@ -331,6 +326,8 @@ static int compare_unit_info(const void *a, const void *b) {
}
static bool output_show_unit(const UnitInfo *u, char **patterns) {
+ assert(u);
+
if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
return false;
@@ -348,10 +345,21 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) {
if (arg_all)
return true;
+ /* Note that '--all' is not purely a state filter, but also a
+ * filter that hides units that "follow" other units (which is
+ * used for device units that appear under different names). */
+ if (!isempty(u->following))
+ return false;
+
+ if (!strv_isempty(arg_states))
+ return true;
+
+ /* By default show all units except the ones in inactive
+ * state and with no pending job */
if (u->job_id > 0)
return true;
- if (streq(u->active_state, "inactive") || u->following[0])
+ if (streq(u->active_state, "inactive"))
return false;
return true;
@@ -476,7 +484,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
}
if (circle_len > 0)
- printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
+ printf("%s%s%s ", on_circle, circle ? special_glyph(BLACK_CIRCLE) : " ", off_circle);
printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
on_active, id_len, id, off_active,
@@ -534,6 +542,7 @@ static int get_unit_list(
size_t size = c;
int r;
UnitInfo u;
+ bool fallback = false;
assert(bus);
assert(unit_infos);
@@ -545,8 +554,7 @@ static int get_unit_list(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "ListUnitsFiltered");
-
+ "ListUnitsByPatterns");
if (r < 0)
return bus_log_create_error(r);
@@ -554,7 +562,34 @@ static int get_unit_list(
if (r < 0)
return bus_log_create_error(r);
+ r = sd_bus_message_append_strv(m, patterns);
+ if (r < 0)
+ return bus_log_create_error(r);
+
r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) {
+ /* Fallback to legacy ListUnitsFiltered method */
+ fallback = true;
+ log_debug_errno(r, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error, r));
+ m = sd_bus_message_unref(m);
+ sd_bus_error_free(&error);
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "ListUnitsFiltered");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, arg_states);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ }
if (r < 0)
return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r));
@@ -565,7 +600,7 @@ static int get_unit_list(
while ((r = bus_parse_unit_info(reply, &u)) > 0) {
u.machine = machine;
- if (!output_show_unit(&u, patterns))
+ if (!output_show_unit(&u, fallback ? patterns : NULL))
continue;
if (!GREEDY_REALLOC(*unit_infos, size, c+1))
@@ -678,7 +713,7 @@ static int list_units(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -890,7 +925,7 @@ static int list_sockets(int argc, char *argv[], void *userdata) {
int r = 0, n;
sd_bus *bus;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -1197,7 +1232,7 @@ static int list_timers(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r = 0;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -1275,7 +1310,9 @@ static int compare_unit_file_list(const void *a, const void *b) {
return strcasecmp(basename(u->path), basename(v->path));
}
-static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
+static bool output_show_unit_file(const UnitFileList *u, char **states, char **patterns) {
+ assert(u);
+
if (!strv_fnmatch_or_empty(patterns, basename(u->path), FNM_NOESCAPE))
return false;
@@ -1290,8 +1327,8 @@ static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
return false;
}
- if (!strv_isempty(arg_states) &&
- !strv_find(arg_states, unit_file_state_to_string(u->state)))
+ if (!strv_isempty(states) &&
+ !strv_find(states, unit_file_state_to_string(u->state)))
return false;
return true;
@@ -1319,7 +1356,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
} else
id_cols = max_id_len;
- if (!arg_no_legend)
+ if (!arg_no_legend && c > 0)
printf("%-*s %-*s\n",
id_cols, "UNIT FILE",
state_cols, "STATE");
@@ -1364,8 +1401,9 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
const char *state;
char *path;
int r;
+ bool fallback = false;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (install_client_side()) {
Hashmap *h;
@@ -1377,7 +1415,7 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
if (!h)
return log_oom();
- r = unit_file_get_list(arg_scope, arg_root, h);
+ r = unit_file_get_list(arg_scope, arg_root, h, arg_states, strv_skip(argv, 1));
if (r < 0) {
unit_file_list_free(h);
return log_error_errno(r, "Failed to get unit file list: %m");
@@ -1385,14 +1423,14 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
n_units = hashmap_size(h);
- units = new(UnitFileList, n_units);
- if (!units && n_units > 0) {
+ units = new(UnitFileList, n_units ?: 1); /* avoid malloc(0) */
+ if (!units) {
unit_file_list_free(h);
return log_oom();
}
HASHMAP_FOREACH(u, h, i) {
- if (!output_show_unit_file(u, strv_skip(argv, 1)))
+ if (!output_show_unit_file(u, NULL, NULL))
continue;
units[c++] = *u;
@@ -1401,7 +1439,10 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
assert(c <= n_units);
hashmap_free(h);
+
+ r = 0;
} else {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
@@ -1409,15 +1450,44 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "ListUnitFiles",
- &error,
- &reply,
- NULL);
+ "ListUnitFilesByPatterns");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, arg_states);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, strv_skip(argv, 1));
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) {
+ /* Fallback to legacy ListUnitFiles method */
+ fallback = true;
+ log_debug_errno(r, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error, r));
+ m = sd_bus_message_unref(m);
+ sd_bus_error_free(&error);
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "ListUnitFiles");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ }
if (r < 0)
return log_error_errno(r, "Failed to list unit files: %s", bus_error_message(&error, r));
@@ -1435,8 +1505,10 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
unit_file_state_from_string(state)
};
- if (output_show_unit_file(&units[c], strv_skip(argv, 1)))
- c ++;
+ if (output_show_unit_file(&units[c],
+ fallback ? arg_states : NULL,
+ fallback ? strv_skip(argv, 1) : NULL))
+ c++;
}
if (r < 0)
@@ -1450,10 +1522,9 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
output_unit_file_list(units, c);
- if (install_client_side()) {
+ if (install_client_side())
for (unit = units; unit < units + c; unit++)
free(unit->path);
- }
return 0;
}
@@ -1472,7 +1543,7 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra
printf("%s...\n",max_len % 2 ? "" : " ");
return 0;
}
- printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
+ printf("%s", special_glyph(branches & (1 << i) ? TREE_VERTICAL : TREE_SPACE));
}
len += 2;
@@ -1481,10 +1552,10 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra
return 0;
}
- printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
+ printf("%s", special_glyph(last ? TREE_RIGHT : TREE_BRANCH));
}
- if (arg_full){
+ if (arg_full) {
printf("%s\n", name);
return 0;
}
@@ -1638,12 +1709,29 @@ static int list_dependencies_one(
if (arg_plain)
printf(" ");
else {
- int state;
+ UnitActiveState active_state = _UNIT_ACTIVE_STATE_INVALID;
const char *on;
- state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
- on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
- printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_normal());
+ (void) get_state_one_unit(bus, *c, &active_state);
+
+ switch (active_state) {
+ case UNIT_ACTIVE:
+ case UNIT_RELOADING:
+ case UNIT_ACTIVATING:
+ on = ansi_highlight_green();
+ break;
+
+ case UNIT_INACTIVE:
+ case UNIT_DEACTIVATING:
+ on = ansi_normal();
+ break;
+
+ default:
+ on = ansi_highlight_red();
+ break;
+ }
+
+ printf("%s%s%s ", on, special_glyph(BLACK_CIRCLE), ansi_normal());
}
r = list_dependencies_print(*c, level, branches, c[1] == NULL);
@@ -1679,7 +1767,7 @@ static int list_dependencies(int argc, char *argv[], void *userdata) {
} else
u = SPECIAL_DEFAULT_TARGET;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -1880,16 +1968,16 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n)
on_failed = off_failed = "";
if (circle_len > 0)
- printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
+ printf("%s%s%s ", on_state, circle ? special_glyph(BLACK_CIRCLE) : " ", off_state);
if (m->is_host)
- printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
+ printf("%-*s (host) %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
(int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
on_state, statelen, strna(m->state), off_state,
on_failed, failedlen, m->n_failed_units, off_failed,
jobslen, m->n_jobs);
else
- printf("%-*s %s%-*s%s %s%*u%s %*u\n",
+ printf("%-*s %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
namelen, strna(m->name),
on_state, statelen, strna(m->state), off_state,
on_failed, failedlen, m->n_failed_units, off_failed,
@@ -1910,7 +1998,7 @@ static int list_machines(int argc, char *argv[], void *userdata) {
return -EPERM;
}
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -1939,6 +2027,7 @@ static int get_default(int argc, char *argv[], void *userdata) {
return log_error_errno(r, "Failed to get default target: %m");
path = _path;
+ r = 0;
} else {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
@@ -1970,21 +2059,10 @@ static int get_default(int argc, char *argv[], void *userdata) {
return 0;
}
-static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
- unsigned i;
-
- assert(changes || n_changes == 0);
-
- for (i = 0; i < n_changes; i++) {
- if (changes[i].type == UNIT_FILE_SYMLINK)
- log_info("Created symlink %s, pointing to %s.", changes[i].path, changes[i].source);
- else
- log_info("Removed symlink %s.", changes[i].path);
- }
-}
-
static int set_default(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *unit = NULL;
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
int r;
assert(argc >= 2);
@@ -1995,18 +2073,11 @@ static int set_default(int argc, char *argv[], void *userdata) {
return log_error_errno(r, "Failed to mangle unit name: %m");
if (install_client_side()) {
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
-
r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
- if (r < 0)
- return log_error_errno(r, "Failed to set default target: %m");
+ unit_file_dump_changes(r, "set default", changes, n_changes, arg_quiet);
- if (!arg_quiet)
- dump_unit_file_changes(changes, n_changes);
-
- unit_file_changes_free(changes, n_changes);
- r = 0;
+ if (r > 0)
+ r = 0;
} else {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
@@ -2030,9 +2101,9 @@ static int set_default(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to set default target: %s", bus_error_message(&error, r));
- r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+ r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
if (r < 0)
- return r;
+ goto finish;
/* Try to reload if enabled */
if (!arg_no_reload)
@@ -2041,6 +2112,9 @@ static int set_default(int argc, char *argv[], void *userdata) {
r = 0;
}
+finish:
+ unit_file_changes_free(changes, n_changes);
+
return r;
}
@@ -2067,7 +2141,7 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp
return;
}
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
id_len = strlen("JOB");
unit_len = strlen("UNIT");
@@ -2137,7 +2211,7 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
int r;
bool skipped = false;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -2267,6 +2341,8 @@ static int need_daemon_reload(sd_bus *bus, const char *unit) {
}
static void warn_unit_file_changed(const char *name) {
+ assert(name);
+
log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
ansi_highlight_red(),
ansi_normal(),
@@ -2281,7 +2357,7 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
assert(unit_name);
assert(unit_path);
- STRV_FOREACH(p, lp->unit_path) {
+ STRV_FOREACH(p, lp->search_path) {
_cleanup_free_ char *path;
path = path_join(arg_root, *p, unit_name);
@@ -2381,7 +2457,7 @@ static int unit_find_paths(
}
if (dropin_paths) {
- r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
+ r = unit_file_find_dropin_paths(lp->search_path, NULL, names, &dropins);
if (r < 0)
return r;
}
@@ -2407,18 +2483,19 @@ static int unit_find_paths(
return r;
}
-static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
+static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *buf = NULL;
- const char *path, *state;
+ UnitActiveState state;
+ const char *path;
int r;
assert(name);
+ assert(active_state);
/* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
* isn't loaded. */
-
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -2434,7 +2511,7 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states
/* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
* considered inactive. */
- state = "inactive";
+ state = UNIT_INACTIVE;
} else {
r = sd_bus_message_read(reply, "o", &path);
@@ -2452,13 +2529,15 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states
if (r < 0)
return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r));
- state = buf;
+ state = unit_active_state_from_string(buf);
+ if (state == _UNIT_ACTIVE_STATE_INVALID) {
+ log_error("Invalid unit state '%s' for: %s", buf, name);
+ return -EINVAL;
+ }
}
- if (!quiet)
- puts(state);
-
- return nulstr_contains(good_states, state);
+ *active_state = state;
+ return 0;
}
static int check_triggering_units(
@@ -2466,9 +2545,10 @@ static int check_triggering_units(
const char *name) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
+ _cleanup_free_ char *path = NULL, *n = NULL, *load_state = NULL;
_cleanup_strv_free_ char **triggered_by = NULL;
bool print_warning_label = true;
+ UnitActiveState active_state;
char **i;
int r;
@@ -2487,11 +2567,11 @@ static int check_triggering_units(
"org.freedesktop.systemd1.Unit",
"LoadState",
&error,
- &state);
+ &load_state);
if (r < 0)
return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r));
- if (streq(state, "masked"))
+ if (streq(load_state, "masked"))
return 0;
r = sd_bus_get_property_strv(
@@ -2506,11 +2586,11 @@ static int check_triggering_units(
return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
STRV_FOREACH(i, triggered_by) {
- r = check_one_unit(bus, *i, "active\0reloading\0", true);
+ r = get_state_one_unit(bus, *i, &active_state);
if (r < 0)
- return log_error_errno(r, "Failed to check unit: %m");
+ return r;
- if (r == 0)
+ if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING))
continue;
if (print_warning_label) {
@@ -2604,7 +2684,10 @@ static int start_unit_one(
if (!sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) &&
!sd_bus_error_has_name(error, BUS_ERROR_UNIT_MASKED))
- log_error("See system logs and 'systemctl status %s' for details.", name);
+ log_error("See %s logs and 'systemctl%s status %s' for details.",
+ arg_scope == UNIT_FILE_SYSTEM ? "system" : "user",
+ arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
+ name);
return r;
}
@@ -2778,9 +2861,22 @@ static int start_unit(int argc, char *argv[], void *userdata) {
}
if (!arg_no_block) {
- int q;
+ int q, arg_count = 0;
+ const char* extra_args[4] = {};
+
+ if (arg_scope != UNIT_FILE_SYSTEM)
+ extra_args[arg_count++] = "--user";
+
+ assert(IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_REMOTE, BUS_TRANSPORT_MACHINE));
+ if (arg_transport == BUS_TRANSPORT_REMOTE) {
+ extra_args[arg_count++] = "-H";
+ extra_args[arg_count++] = arg_host;
+ } else if (arg_transport == BUS_TRANSPORT_MACHINE) {
+ extra_args[arg_count++] = "-M";
+ extra_args[arg_count++] = arg_host;
+ }
- q = bus_wait_for_jobs(w, arg_quiet, arg_scope != UNIT_FILE_SYSTEM ? "--user" : NULL);
+ q = bus_wait_for_jobs(w, arg_quiet, extra_args);
if (q < 0)
return q;
@@ -3075,7 +3171,7 @@ static int set_exit_code(uint8_t code) {
NULL,
"y", code);
if (r < 0)
- return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to set exit code: %s", bus_error_message(&error, r));
return 0;
}
@@ -3102,7 +3198,7 @@ static int start_special(int argc, char *argv[], void *userdata) {
return r;
if (a == ACTION_REBOOT && argc > 1) {
- r = update_reboot_param_file(argv[1]);
+ r = update_reboot_parameter_and_warn(argv[1]);
if (r < 0)
return r;
@@ -3158,11 +3254,12 @@ static int start_special(int argc, char *argv[], void *userdata) {
return start_unit(argc, argv, userdata);
}
-static int check_unit_generic(int code, const char *good_states, char **args) {
+static int check_unit_generic(int code, const UnitActiveState good_states[], int nb_states, char **args) {
_cleanup_strv_free_ char **names = NULL;
+ UnitActiveState active_state;
sd_bus *bus;
char **name;
- int r;
+ int r, i;
bool found = false;
r = acquire_bus(BUS_MANAGER, &bus);
@@ -3174,13 +3271,16 @@ static int check_unit_generic(int code, const char *good_states, char **args) {
return log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- int state;
+ r = get_state_one_unit(bus, *name, &active_state);
+ if (r < 0)
+ return r;
+
+ if (!arg_quiet)
+ puts(unit_active_state_to_string(active_state));
- state = check_one_unit(bus, *name, good_states, arg_quiet);
- if (state < 0)
- return state;
- if (state > 0)
- found = true;
+ for (i = 0; i < nb_states; ++i)
+ if (good_states[i] == active_state)
+ found = true;
}
/* use the given return code for the case that we won't find
@@ -3189,12 +3289,14 @@ static int check_unit_generic(int code, const char *good_states, char **args) {
}
static int check_unit_active(int argc, char *argv[], void *userdata) {
+ const UnitActiveState states[] = { UNIT_ACTIVE, UNIT_RELOADING };
/* According to LSB: 3, "program is not running" */
- return check_unit_generic(3, "active\0reloading\0", strv_skip(argv, 1));
+ return check_unit_generic(3, states, ELEMENTSOF(states), strv_skip(argv, 1));
}
static int check_unit_failed(int argc, char *argv[], void *userdata) {
- return check_unit_generic(1, "failed\0", strv_skip(argv, 1));
+ const UnitActiveState states[] = { UNIT_FAILED };
+ return check_unit_generic(1, states, ELEMENTSOF(states), strv_skip(argv, 1));
}
static int kill_unit(int argc, char *argv[], void *userdata) {
@@ -3214,7 +3316,7 @@ static int kill_unit(int argc, char *argv[], void *userdata) {
/* --fail was specified */
if (streq(arg_job_mode, "fail"))
- kill_who = strjoina(arg_kill_who, "-fail", NULL);
+ kill_who = strjoina(arg_kill_who, "-fail");
r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
if (r < 0)
@@ -3406,6 +3508,7 @@ typedef struct UnitStatusInfo {
} UnitStatusInfo;
static void print_status_info(
+ sd_bus *bus,
UnitStatusInfo *i,
bool *ellipsized) {
@@ -3416,6 +3519,7 @@ static void print_status_info(
char since2[FORMAT_TIMESTAMP_MAX], *s2;
const char *path;
char **t, **t2;
+ int r;
assert(i);
@@ -3431,7 +3535,7 @@ static void print_status_info(
} else
active_on = active_off = "";
- printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
+ printf("%s%s%s %s", active_on, special_glyph(BLACK_CIRCLE), active_off, strna(i->id));
if (i->description && !streq_ptr(i->id, i->description))
printf(" - %s", i->description);
@@ -3486,7 +3590,7 @@ static void print_status_info(
}
printf("%s\n %s", dir,
- draw_special_char(DRAW_TREE_RIGHT));
+ special_glyph(TREE_RIGHT));
}
last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
@@ -3688,25 +3792,26 @@ static void print_status_info(
printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
}
- if (i->control_group &&
- (i->main_pid > 0 || i->control_pid > 0 ||
- (!IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group) == 0))) {
+ if (i->control_group)
+ printf(" CGroup: %s\n", i->control_group);
+
+ {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ static const char prefix[] = " ";
unsigned c;
- printf(" CGroup: %s\n", i->control_group);
+ c = columns();
+ if (c > sizeof(prefix) - 1)
+ c -= sizeof(prefix) - 1;
+ else
+ c = 0;
- if (IN_SET(arg_transport,
- BUS_TRANSPORT_LOCAL,
- BUS_TRANSPORT_MACHINE)) {
+ r = unit_show_processes(bus, i->id, i->control_group, prefix, c, get_output_flags(), &error);
+ if (r == -EBADR) {
unsigned k = 0;
pid_t extra[2];
- static const char prefix[] = " ";
- c = columns();
- if (c > sizeof(prefix) - 1)
- c -= sizeof(prefix) - 1;
- else
- c = 0;
+ /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
if (i->main_pid > 0)
extra[k++] = i->main_pid;
@@ -3714,8 +3819,9 @@ static void print_status_info(
if (i->control_pid > 0)
extra[k++] = i->control_pid;
- show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
- }
+ show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, extra, k, get_output_flags());
+ } else if (r < 0)
+ log_warning_errno(r, "Failed to dump process list, ignoring: %s", bus_error_message(&error, r));
}
if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
@@ -4077,6 +4183,14 @@ skip:
return 0;
}
+#define print_prop(name, fmt, ...) \
+ do { \
+ if (arg_value) \
+ printf(fmt "\n", __VA_ARGS__); \
+ else \
+ printf("%s=" fmt "\n", name, __VA_ARGS__); \
+ } while(0)
+
static int print_property(const char *name, sd_bus_message *m, const char *contents) {
int r;
@@ -4104,9 +4218,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
if (u > 0)
- printf("%s=%"PRIu32"\n", name, u);
+ print_prop(name, "%"PRIu32, u);
else if (arg_all)
- printf("%s=\n", name);
+ print_prop(name, "%s", "");
return 0;
@@ -4118,7 +4232,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
if (arg_all || !isempty(s))
- printf("%s=%s\n", name, s);
+ print_prop(name, "%s", s);
return 0;
@@ -4130,7 +4244,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
if (arg_all || !isempty(a) || !isempty(b))
- printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
+ print_prop(name, "%s \"%s\"", strempty(a), strempty(b));
return 0;
} else if (streq_ptr(name, "SystemCallFilter")) {
@@ -4157,8 +4271,10 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
bool first = true;
char **i;
- fputs(name, stdout);
- fputc('=', stdout);
+ if (!arg_value) {
+ fputs(name, stdout);
+ fputc('=', stdout);
+ }
if (!whitelist)
fputc('~', stdout);
@@ -4190,7 +4306,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
- printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
+ print_prop("EnvironmentFile", "%s (ignore_errors=%s)\n", path, yes_no(ignore));
if (r < 0)
return bus_log_parse_error(r);
@@ -4209,7 +4325,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
- printf("%s=%s\n", type, path);
+ print_prop(type, "%s", path);
if (r < 0)
return bus_log_parse_error(r);
@@ -4227,7 +4343,10 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
- printf("Listen%s=%s\n", type, path);
+ if (arg_value)
+ puts(path);
+ else
+ printf("Listen%s=%s\n", type, path);
if (r < 0)
return bus_log_parse_error(r);
@@ -4248,10 +4367,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
- printf("%s={ value=%s ; next_elapse=%s }\n",
- base,
- format_timespan(timespan1, sizeof(timespan1), value, 0),
- format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
+ print_prop(base, "{ value=%s ; next_elapse=%s }",
+ format_timespan(timespan1, sizeof(timespan1), value, 0),
+ format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
}
if (r < 0)
return bus_log_parse_error(r);
@@ -4275,18 +4393,18 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
tt = strv_join(info.argv, " ");
- printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
- name,
- strna(info.path),
- strna(tt),
- yes_no(info.ignore),
- strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
- strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
- info.pid,
- sigchld_code_to_string(info.code),
- info.status,
- info.code == CLD_EXITED ? "" : "/",
- strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
+ print_prop(name,
+ "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }",
+ strna(info.path),
+ strna(tt),
+ yes_no(info.ignore),
+ strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
+ strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
+ info.pid,
+ sigchld_code_to_string(info.code),
+ info.status,
+ info.code == CLD_EXITED ? "" : "/",
+ strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
free(info.path);
strv_free(info.argv);
@@ -4307,7 +4425,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
- printf("%s=%s %s\n", name, strna(path), strna(rwm));
+ print_prop(name, "%s %s", strna(path), strna(rwm));
if (r < 0)
return bus_log_parse_error(r);
@@ -4317,7 +4435,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return 0;
- } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
+ } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "IODeviceWeight") || streq(name, "BlockIODeviceWeight"))) {
const char *path;
uint64_t weight;
@@ -4326,7 +4444,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
- printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
+ print_prop(name, "%s %"PRIu64, strna(path), weight);
if (r < 0)
return bus_log_parse_error(r);
@@ -4336,7 +4454,8 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return 0;
- } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
+ } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (cgroup_io_limit_type_from_string(name) >= 0 ||
+ streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
const char *path;
uint64_t bandwidth;
@@ -4345,7 +4464,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
- printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
+ print_prop(name, "%s %"PRIu64, strna(path), bandwidth);
if (r < 0)
return bus_log_parse_error(r);
@@ -4359,7 +4478,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
break;
}
- r = bus_print_property(name, m, arg_all);
+ r = bus_print_property(name, m, arg_value, arg_all);
if (r < 0)
return bus_log_parse_error(r);
@@ -4464,7 +4583,7 @@ static int show_one(
if (streq(verb, "help"))
show_unit_help(&info);
else
- print_status_info(&info, ellipsized);
+ print_status_info(bus, &info, ellipsized);
}
strv_free(info.documentation);
@@ -4546,7 +4665,7 @@ static int show_all(
if (r < 0)
return r;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
c = (unsigned) r;
@@ -4593,13 +4712,13 @@ static int show_system_status(sd_bus *bus) {
} else
on = off = "";
- printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
+ printf("%s%s%s %s\n", on, special_glyph(BLACK_CIRCLE), off, arg_host ? arg_host : hn);
printf(" State: %s%s%s\n",
on, strna(mi.state), off);
- printf(" Jobs: %u queued\n", mi.n_jobs);
- printf(" Failed: %u units\n", mi.n_failed_units);
+ printf(" Jobs: %" PRIu32 " queued\n", mi.n_jobs);
+ printf(" Failed: %" PRIu32 " units\n", mi.n_failed_units);
printf(" Since: %s; %s\n",
format_timestamp(since2, sizeof(since2), mi.timestamp),
@@ -4618,7 +4737,7 @@ static int show_system_status(sd_bus *bus) {
else
c = 0;
- show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
+ show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, get_output_flags());
}
return 0;
@@ -4641,7 +4760,7 @@ static int show(int argc, char *argv[], void *userdata) {
return -EINVAL;
}
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (show_status)
/* Increase max number of open files to 16K if we can, we
@@ -4659,7 +4778,7 @@ static int show(int argc, char *argv[], void *userdata) {
if (show_status && argc <= 1) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
show_system_status(bus);
new_line = true;
@@ -4728,34 +4847,6 @@ static int show(int argc, char *argv[], void *userdata) {
return ret;
}
-static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
- int r;
-
- assert(user_home);
- assert(user_runtime);
- assert(lp);
-
- if (arg_scope == UNIT_FILE_USER) {
- r = user_config_home(user_home);
- if (r < 0)
- return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
- else if (r == 0)
- return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
-
- r = user_runtime_dir(user_runtime);
- if (r < 0)
- return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
- else if (r == 0)
- return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
- }
-
- r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
- if (r < 0)
- return log_error_errno(r, "Failed to query unit lookup paths: %m");
-
- return 0;
-}
-
static int cat_file(const char *filename, bool newline) {
_cleanup_close_ int fd;
@@ -4774,8 +4865,6 @@ static int cat_file(const char *filename, bool newline) {
}
static int cat(int argc, char *argv[], void *userdata) {
- _cleanup_free_ char *user_home = NULL;
- _cleanup_free_ char *user_runtime = NULL;
_cleanup_lookup_paths_free_ LookupPaths lp = {};
_cleanup_strv_free_ char **names = NULL;
char **name;
@@ -4788,9 +4877,9 @@ static int cat(int argc, char *argv[], void *userdata) {
return -EINVAL;
}
- r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
+ r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to determine unit paths: %m");
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -4800,7 +4889,7 @@ static int cat(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to expand names: %m");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
STRV_FOREACH(name, names) {
_cleanup_free_ char *fragment_path = NULL;
@@ -4937,7 +5026,7 @@ static int daemon_reload(int argc, char *argv[], void *userdata) {
* reply */
r = 0;
else if (r < 0)
- return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
return r < 0 ? r : 0;
}
@@ -4990,7 +5079,7 @@ static int show_environment(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -5201,8 +5290,10 @@ static int enable_sysv_units(const char *verb, char **args) {
int r = 0;
#if defined(HAVE_SYSV_COMPAT)
- unsigned f = 0;
_cleanup_lookup_paths_free_ LookupPaths paths = {};
+ unsigned f = 0;
+
+ /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
if (arg_scope != UNIT_FILE_SYSTEM)
return 0;
@@ -5216,24 +5307,28 @@ static int enable_sysv_units(const char *verb, char **args) {
"is-enabled"))
return 0;
- /* Processes all SysV units, and reshuffles the array so that
- * afterwards only the native units remain */
-
- r = lookup_paths_init(&paths, MANAGER_SYSTEM, false, arg_root, NULL, NULL, NULL);
+ r = lookup_paths_init(&paths, arg_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
if (r < 0)
return r;
r = 0;
while (args[f]) {
- const char *name;
+
+ const char *argv[] = {
+ ROOTLIBEXECDIR "/systemd-sysv-install",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+
_cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
bool found_native = false, found_sysv;
+ siginfo_t status;
+ const char *name;
unsigned c = 1;
- const char *argv[6] = { ROOTLIBEXECDIR "/systemd-sysv-install", NULL, NULL, NULL, NULL };
- char **k;
- int j;
pid_t pid;
- siginfo_t status;
+ int j;
name = args[f++];
@@ -5243,21 +5338,13 @@ static int enable_sysv_units(const char *verb, char **args) {
if (path_is_absolute(name))
continue;
- STRV_FOREACH(k, paths.unit_path) {
- _cleanup_free_ char *path = NULL;
-
- path = path_join(arg_root, *k, name);
- if (!path)
- return log_oom();
-
- found_native = access(path, F_OK) >= 0;
- if (found_native)
- break;
- }
+ j = unit_file_exists(arg_scope, &paths, name);
+ if (j < 0 && !IN_SET(j, -ELOOP, -ERFKILL, -EADDRNOTAVAIL))
+ return log_error_errno(j, "Failed to lookup unit file state: %m");
+ found_native = j != 0;
- /* If we have both a native unit and a SysV script,
- * enable/disable them both (below); for is-enabled, prefer the
- * native unit */
+ /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
+ * prefer the native unit */
if (found_native && streq(verb, "is-enabled"))
continue;
@@ -5271,9 +5358,9 @@ static int enable_sysv_units(const char *verb, char **args) {
continue;
if (found_native)
- log_info("Synchronizing state of %s with SysV init with %s...", name, argv[0]);
+ log_info("Synchronizing state of %s with SysV service script with %s.", name, argv[0]);
else
- log_info("%s is not a native service, redirecting to systemd-sysv-install", name);
+ log_info("%s is not a native service, redirecting to systemd-sysv-install.", name);
if (!isempty(arg_root))
argv[c++] = q = strappend("--root=", arg_root);
@@ -5286,7 +5373,7 @@ static int enable_sysv_units(const char *verb, char **args) {
if (!l)
return log_oom();
- log_info("Executing %s", l);
+ log_info("Executing: %s", l);
pid = fork();
if (pid < 0)
@@ -5298,7 +5385,7 @@ static int enable_sysv_units(const char *verb, char **args) {
(void) reset_signal_mask();
execv(argv[0], (char**) argv);
- log_error_errno(r, "Failed to execute %s: %m", argv[0]);
+ log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
_exit(EXIT_FAILURE);
}
@@ -5320,9 +5407,11 @@ static int enable_sysv_units(const char *verb, char **args) {
}
} else if (status.si_status != 0)
- return -EINVAL;
- } else
+ return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */
+ } else {
+ log_error("Unexpected waitid() result.");
return -EPROTO;
+ }
if (found_native)
continue;
@@ -5380,6 +5469,7 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
int carries_install_info = -1;
+ bool ignore_carries_install_info = arg_quiet;
int r;
if (!argv[1])
@@ -5393,10 +5483,12 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
- /* If the operation was fully executed by the SysV compat,
- * let's finish early */
- if (strv_isempty(names))
- return 0;
+ /* If the operation was fully executed by the SysV compat, let's finish early */
+ if (strv_isempty(names)) {
+ if (arg_no_reload || install_client_side())
+ return 0;
+ return daemon_reload(argc, argv, userdata);
+ }
if (install_client_side()) {
if (streq(verb, "enable")) {
@@ -5411,28 +5503,24 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
else if (streq(verb, "preset")) {
r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
- carries_install_info = r;
} else if (streq(verb, "mask"))
r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
else if (streq(verb, "unmask"))
r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
+ else if (streq(verb, "revert"))
+ r = unit_file_revert(arg_scope, arg_root, names, &changes, &n_changes);
else
assert_not_reached("Unknown verb");
- if (r == -ESHUTDOWN)
- return log_error_errno(r, "Unit file is masked.");
+ unit_file_dump_changes(r, verb, changes, n_changes, arg_quiet);
if (r < 0)
- return log_error_errno(r, "Operation failed: %m");
-
- if (!arg_quiet)
- dump_unit_file_changes(changes, n_changes);
-
+ return r;
r = 0;
} else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- int expect_carries_install_info = false;
- bool send_force = true, send_preset_mode = false;
+ bool expect_carries_install_info = false;
+ bool send_runtime = true, send_force = true, send_preset_mode = false;
const char *method;
sd_bus *bus;
@@ -5462,11 +5550,15 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
method = "PresetUnitFiles";
expect_carries_install_info = true;
+ ignore_carries_install_info = true;
} else if (streq(verb, "mask"))
method = "MaskUnitFiles";
else if (streq(verb, "unmask")) {
method = "UnmaskUnitFiles";
send_force = false;
+ } else if (streq(verb, "revert")) {
+ method = "RevertUnitFiles";
+ send_runtime = send_force = false;
} else
assert_not_reached("Unknown verb");
@@ -5490,9 +5582,11 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
return bus_log_create_error(r);
}
- r = sd_bus_message_append(m, "b", arg_runtime);
- if (r < 0)
- return bus_log_create_error(r);
+ if (send_runtime) {
+ r = sd_bus_message_append(m, "b", arg_runtime);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
if (send_force) {
r = sd_bus_message_append(m, "b", arg_force);
@@ -5502,7 +5596,7 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0)
- return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to %s unit: %s", verb, bus_error_message(&error, r));
if (expect_carries_install_info) {
r = sd_bus_message_read(reply, "b", &carries_install_info);
@@ -5521,16 +5615,19 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
r = 0;
}
- if (carries_install_info == 0)
- log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
- "using systemctl.\n"
+ if (carries_install_info == 0 && !ignore_carries_install_info)
+ log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
+ "settings in the [Install] section, and DefaultInstance for template units).\n"
+ "This means they are not meant to be enabled using systemctl.\n"
"Possible reasons for having this kind of units are:\n"
"1) A unit may be statically enabled by being symlinked from another unit's\n"
" .wants/ or .requires/ directory.\n"
"2) A unit's purpose may be to act as a helper for some other unit which has\n"
" a requirement dependency on it.\n"
"3) A unit may be started when needed via activation (socket, path, timer,\n"
- " D-Bus, udev, scripted systemctl call, ...).\n");
+ " D-Bus, udev, scripted systemctl call, ...).\n"
+ "4) In case of template units, the unit is meant to be enabled with some\n"
+ " instance name specified.");
if (arg_now && n_changes > 0 && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
char *new_args[n_changes + 2];
@@ -5559,6 +5656,8 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
_cleanup_free_ char *target = NULL;
const char *verb = argv[0];
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
UnitDependency dep;
int r = 0;
@@ -5581,20 +5680,11 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
assert_not_reached("Unknown verb");
if (install_client_side()) {
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
-
r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
- if (r == -ESHUTDOWN)
- return log_error_errno(r, "Unit file is masked.");
- if (r < 0)
- return log_error_errno(r, "Can't add dependency: %m");
-
- if (!arg_quiet)
- dump_unit_file_changes(changes, n_changes);
-
- unit_file_changes_free(changes, n_changes);
+ unit_file_dump_changes(r, "add dependency on", changes, n_changes, arg_quiet);
+ if (r > 0)
+ r = 0;
} else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -5626,18 +5716,23 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0)
- return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to add dependency: %s", bus_error_message(&error, r));
- r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+ r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
if (r < 0)
- return r;
+ goto finish;
- if (!arg_no_reload)
- r = daemon_reload(argc, argv, userdata);
- else
+ if (arg_no_reload) {
r = 0;
+ goto finish;
+ }
+
+ r = daemon_reload(argc, argv, userdata);
}
+finish:
+ unit_file_changes_free(changes, n_changes);
+
return r;
}
@@ -5647,18 +5742,11 @@ static int preset_all(int argc, char *argv[], void *userdata) {
int r;
if (install_client_side()) {
-
r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
- if (r < 0) {
- log_error_errno(r, "Operation failed: %m");
- goto finish;
- }
-
- if (!arg_quiet)
- dump_unit_file_changes(changes, n_changes);
-
- r = 0;
+ unit_file_dump_changes(r, "preset", changes, n_changes, arg_quiet);
+ if (r > 0)
+ r = 0;
} else {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
@@ -5683,16 +5771,18 @@ static int preset_all(int argc, char *argv[], void *userdata) {
arg_runtime,
arg_force);
if (r < 0)
- return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to preset all units: %s", bus_error_message(&error, r));
- r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+ r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
if (r < 0)
- return r;
+ goto finish;
- if (!arg_no_reload)
- r = daemon_reload(argc, argv, userdata);
- else
+ if (arg_no_reload) {
r = 0;
+ goto finish;
+ }
+
+ r = daemon_reload(argc, argv, userdata);
}
finish:
@@ -5731,13 +5821,15 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
UNIT_FILE_ENABLED,
UNIT_FILE_ENABLED_RUNTIME,
UNIT_FILE_STATIC,
- UNIT_FILE_INDIRECT))
+ UNIT_FILE_INDIRECT,
+ UNIT_FILE_GENERATED))
enabled = true;
if (!arg_quiet)
puts(unit_file_state_to_string(state));
}
+ r = 0;
} else {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
@@ -5766,7 +5858,7 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
- if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
+ if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect", "generated"))
enabled = true;
if (!arg_quiet)
@@ -5774,7 +5866,7 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
}
}
- return !enabled;
+ return enabled ? EXIT_SUCCESS : EXIT_FAILURE;
}
static int is_system_running(int argc, char *argv[], void *userdata) {
@@ -5844,52 +5936,32 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
return 0;
}
-static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
- _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
+static int get_file_to_edit(
+ const LookupPaths *paths,
+ const char *name,
+ char **ret_path) {
+
+ _cleanup_free_ char *path = NULL, *run = NULL;
assert(name);
assert(ret_path);
- switch (arg_scope) {
- case UNIT_FILE_SYSTEM:
- path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
- if (arg_runtime)
- run = path_join(arg_root, "/run/systemd/system/", name);
- break;
- case UNIT_FILE_GLOBAL:
- path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
- if (arg_runtime)
- run = path_join(arg_root, "/run/systemd/user/", name);
- break;
- case UNIT_FILE_USER:
- assert(user_home);
- assert(user_runtime);
-
- path = path_join(arg_root, user_home, name);
- if (arg_runtime) {
- path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
- if (!path2)
- return log_oom();
- run = path_join(arg_root, user_runtime, name);
- }
- break;
- default:
- assert_not_reached("Invalid scope");
- }
- if (!path || (arg_runtime && !run))
+ path = strjoin(paths->persistent_config, "/", name, NULL);
+ if (!path)
return log_oom();
if (arg_runtime) {
+ run = strjoin(paths->runtime_config, name, NULL);
+ if (!run)
+ return log_oom();
+ }
+
+ if (arg_runtime) {
if (access(path, F_OK) >= 0) {
log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
return -EEXIST;
}
- if (path2 && access(path2, F_OK) >= 0) {
- log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path2);
- return -EEXIST;
- }
-
*ret_path = run;
run = NULL;
} else {
@@ -5900,7 +5972,12 @@ static int get_file_to_edit(const char *name, const char *user_home, const char
return 0;
}
-static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
+static int unit_file_create_dropin(
+ const LookupPaths *paths,
+ const char *unit_name,
+ char **ret_new_path,
+ char **ret_tmp_path) {
+
char *tmp_new_path, *tmp_tmp_path, *ending;
int r;
@@ -5909,7 +5986,7 @@ static int unit_file_create_dropin(const char *unit_name, const char *user_home,
assert(ret_tmp_path);
ending = strjoina(unit_name, ".d/override.conf");
- r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
+ r = get_file_to_edit(paths, ending, &tmp_new_path);
if (r < 0)
return r;
@@ -5926,10 +6003,9 @@ static int unit_file_create_dropin(const char *unit_name, const char *user_home,
}
static int unit_file_create_copy(
+ const LookupPaths *paths,
const char *unit_name,
const char *fragment_path,
- const char *user_home,
- const char *user_runtime,
char **ret_new_path,
char **ret_tmp_path) {
@@ -5941,7 +6017,7 @@ static int unit_file_create_copy(
assert(ret_new_path);
assert(ret_tmp_path);
- r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
+ r = get_file_to_edit(paths, unit_name, &tmp_new_path);
if (r < 0)
return r;
@@ -6056,8 +6132,6 @@ static int run_editor(char **paths) {
}
static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
- _cleanup_free_ char *user_home = NULL;
- _cleanup_free_ char *user_runtime = NULL;
_cleanup_lookup_paths_free_ LookupPaths lp = {};
char **name;
int r;
@@ -6065,13 +6139,12 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
assert(names);
assert(paths);
- r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
+ r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
if (r < 0)
return r;
STRV_FOREACH(name, names) {
- _cleanup_free_ char *path = NULL;
- char *new_path, *tmp_path;
+ _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL;
r = unit_find_paths(bus, *name, &lp, &path, NULL);
if (r < 0)
@@ -6085,15 +6158,16 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
}
if (arg_full)
- r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
+ r = unit_file_create_copy(&lp, *name, path, &new_path, &tmp_path);
else
- r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
+ r = unit_file_create_dropin(&lp, *name, &new_path, &tmp_path);
if (r < 0)
return r;
r = strv_push_pair(paths, new_path, tmp_path);
if (r < 0)
return log_oom();
+ new_path = tmp_path = NULL;
}
return 0;
@@ -6157,15 +6231,30 @@ static int edit(int argc, char *argv[], void *userdata) {
r = daemon_reload(argc, argv, userdata);
end:
- STRV_FOREACH_PAIR(original, tmp, paths)
+ STRV_FOREACH_PAIR(original, tmp, paths) {
(void) unlink(*tmp);
+ /* Removing empty dropin dirs */
+ if (!arg_full) {
+ _cleanup_free_ char *dir;
+
+ dir = dirname_malloc(*original);
+ if (!dir)
+ return log_oom();
+
+ /* no need to check if the dir is empty, rmdir
+ * does nothing if it is not the case.
+ */
+ (void) rmdir(dir);
+ }
+ }
+
return r;
}
static void systemctl_help(void) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Query or send control commands to the systemd manager.\n\n"
@@ -6189,6 +6278,7 @@ static void systemctl_help(void) {
" --job-mode=MODE Specify how to deal with already queued jobs, when\n"
" queueing a new job\n"
" --show-types When showing sockets, explicitly show their type\n"
+ " --value When showing properties, only print the value\n"
" -i --ignore-inhibitors\n"
" When shutting down or sleeping, ignore inhibitors\n"
" --kill-who=WHO Who to send signal to\n"
@@ -6256,6 +6346,8 @@ static void systemctl_help(void) {
" unmask NAME... Unmask one or more units\n"
" link PATH... Link one or more units files into\n"
" the search path\n"
+ " revert NAME... Revert one or more unit files to vendor\n"
+ " version\n"
" add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
" on specified one or more units\n"
" add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
@@ -6440,6 +6532,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
ARG_SHOW_TYPES,
ARG_IRREVERSIBLE,
ARG_IGNORE_DEPENDENCIES,
+ ARG_VALUE,
ARG_VERSION,
ARG_USER,
ARG_SYSTEM,
@@ -6481,6 +6574,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
{ "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
{ "ignore-inhibitors", no_argument, NULL, 'i' },
+ { "value", no_argument, NULL, ARG_VALUE },
{ "user", no_argument, NULL, ARG_USER },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "global", no_argument, NULL, ARG_GLOBAL },
@@ -6537,7 +6631,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
}
p = optarg;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *type = NULL;
r = extract_first_word(&p, &type, ",", 0);
@@ -6587,7 +6681,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return log_oom();
} else {
p = optarg;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *prop = NULL;
r = extract_first_word(&p, &prop, ",", 0);
@@ -6632,6 +6726,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_show_types = true;
break;
+ case ARG_VALUE:
+ arg_value = true;
+ break;
+
case ARG_JOB_MODE:
arg_job_mode = optarg;
break;
@@ -6677,7 +6775,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_ROOT:
- r = parse_path_argument_and_warn(optarg, true, &arg_root);
+ r = parse_path_argument_and_warn(optarg, false, &arg_root);
if (r < 0)
return r;
break;
@@ -6697,11 +6795,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_FORCE:
- arg_force ++;
+ arg_force++;
break;
case 'f':
- arg_force ++;
+ arg_force++;
break;
case ARG_NO_RELOAD:
@@ -6772,7 +6870,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
}
p = optarg;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *s = NULL;
r = extract_first_word(&p, &s, ",", 0);
@@ -6855,6 +6953,7 @@ static int halt_parse_argv(int argc, char *argv[]) {
{ "force", no_argument, NULL, 'f' },
{ "wtmp-only", no_argument, NULL, 'w' },
{ "no-wtmp", no_argument, NULL, 'd' },
+ { "no-sync", no_argument, NULL, 'n' },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{}
};
@@ -6900,13 +6999,16 @@ static int halt_parse_argv(int argc, char *argv[]) {
arg_no_wtmp = true;
break;
+ case 'n':
+ arg_no_sync = true;
+ break;
+
case ARG_NO_WALL:
arg_no_wall = true;
break;
case 'i':
case 'h':
- case 'n':
/* Compatibility nops */
break;
@@ -6918,7 +7020,7 @@ static int halt_parse_argv(int argc, char *argv[]) {
}
if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
- r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
+ r = update_reboot_parameter_and_warn(argc == optind + 1 ? argv[optind] : NULL);
if (r < 0)
return r;
} else if (optind < argc) {
@@ -7167,7 +7269,7 @@ static int telinit_parse_argv(int argc, char *argv[]) {
arg_action = table[i].to;
- optind ++;
+ optind++;
return 1;
}
@@ -7258,6 +7360,7 @@ static int parse_argv(int argc, char *argv[]) {
return systemctl_parse_argv(argc, argv);
}
+#ifdef HAVE_SYSV_COMPAT
_pure_ static int action_to_runlevel(void) {
static const char table[_ACTION_MAX] = {
@@ -7275,6 +7378,7 @@ _pure_ static int action_to_runlevel(void) {
return table[arg_action];
}
+#endif
static int talk_initctl(void) {
#ifdef HAVE_SYSV_COMPAT
@@ -7371,6 +7475,7 @@ static int systemctl_main(int argc, char *argv[]) {
{ "mask", 2, VERB_ANY, 0, enable_unit },
{ "unmask", 2, VERB_ANY, 0, enable_unit },
{ "link", 2, VERB_ANY, 0, enable_unit },
+ { "revert", 2, VERB_ANY, 0, enable_unit },
{ "switch-root", 2, VERB_ANY, VERB_NOCHROOT, switch_root },
{ "list-dependencies", VERB_ANY, 2, VERB_NOCHROOT, list_dependencies },
{ "set-default", 2, 2, 0, set_default },
@@ -7417,11 +7522,13 @@ static int start_with_fallback(void) {
}
static int halt_now(enum action a) {
+ int r;
/* The kernel will automaticall flush ATA disks and suchlike
* on reboot(), but the file systems need to be synce'd
* explicitly in advance. */
- (void) sync();
+ if (!arg_no_sync)
+ (void) sync();
/* Make sure C-A-D is handled by the kernel from this point
* on... */
@@ -7443,9 +7550,14 @@ static int halt_now(enum action a) {
case ACTION_REBOOT: {
_cleanup_free_ char *param = NULL;
- if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
+ r = read_one_line_file("/run/systemd/reboot-param", &param);
+ if (r < 0)
+ log_warning_errno(r, "Failed to read reboot parameter file: %m");
+
+ if (!isempty(param)) {
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.");
diff --git a/src/grp-system/systemd/Makefile b/src/grp-system/systemd/Makefile
index 0e34d8d829..2e6d9bbf7f 100644
--- a/src/grp-system/systemd/Makefile
+++ b/src/grp-system/systemd/Makefile
@@ -53,6 +53,9 @@ pkgconfigdata_DATA += \
nodist_rpmmacros_DATA = \
src/core/macros.systemd
+BUILT_SOURCES += \
+ src/core/triggers.systemd
+
EXTRA_DIST += \
src/core/systemd.pc.in \
src/core/macros.systemd.in \
diff --git a/src/grp-system/systemd/main.c b/src/grp-system/systemd/main.c
index bc151cde85..042cce49dd 100644
--- a/src/grp-system/systemd/main.c
+++ b/src/grp-system/systemd/main.c
@@ -81,6 +81,7 @@
#include "strv.h"
#include "switch-root.h"
#include "terminal-util.h"
+#include "umask-util.h"
#include "user-util.h"
#include "virt.h"
#include "watchdog.h"
@@ -94,7 +95,7 @@ static enum {
ACTION_DONE
} arg_action = ACTION_RUN;
static char *arg_default_unit = NULL;
-static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID;
+static bool arg_system = false;
static bool arg_dump_core = true;
static int arg_crash_chvt = -1;
static bool arg_crash_shell = false;
@@ -102,7 +103,7 @@ static bool arg_crash_reboot = false;
static bool arg_confirm_spawn = false;
static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
static bool arg_switched_root = false;
-static int arg_no_pager = -1;
+static bool arg_no_pager = false;
static char ***arg_join_controllers = NULL;
static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
@@ -121,20 +122,13 @@ static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
static Set* arg_syscall_archs = NULL;
static FILE* arg_serialization = NULL;
static bool arg_default_cpu_accounting = false;
+static bool arg_default_io_accounting = false;
static bool arg_default_blockio_accounting = false;
static bool arg_default_memory_accounting = false;
static bool arg_default_tasks_accounting = true;
static uint64_t arg_default_tasks_max = UINT64_C(512);
static sd_id128_t arg_machine_id = {};
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager <= 0)
- return;
-
- pager_open(false);
-}
-
noreturn static void freeze_or_reboot(void) {
if (arg_crash_reboot) {
@@ -296,6 +290,7 @@ static int parse_crash_chvt(const char *value) {
}
static int set_machine_id(const char *m) {
+ assert(m);
if (sd_id128_from_string(m, &arg_machine_id) < 0)
return -EINVAL;
@@ -420,6 +415,15 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
target = runlevel_to_target(key);
if (target)
return free_and_strdup(&arg_default_unit, target);
+
+ } else if (streq(key, "systemd.default_timeout_start_sec") && value) {
+
+ r = parse_sec(value, &arg_default_timeout_start_usec);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse default start timeout: %s, ignoring.", value);
+
+ if (arg_default_timeout_start_usec <= 0)
+ arg_default_timeout_start_usec = USEC_INFINITY;
}
return 0;
@@ -667,7 +671,8 @@ static int parse_config_file(void) {
{ "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_default_timeout_start_usec },
{ "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_default_timeout_stop_usec },
{ "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_default_restart_usec },
- { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval },
+ { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval }, /* obsolete alias */
+ { "Manager", "DefaultStartLimitIntervalSec",config_parse_sec, 0, &arg_default_start_limit_interval },
{ "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst },
{ "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
{ "Manager", "DefaultLimitCPU", config_parse_limit, RLIMIT_CPU, arg_default_rlimit },
@@ -687,6 +692,7 @@ static int parse_config_file(void) {
{ "Manager", "DefaultLimitRTPRIO", config_parse_limit, RLIMIT_RTPRIO, arg_default_rlimit },
{ "Manager", "DefaultLimitRTTIME", config_parse_limit, RLIMIT_RTTIME, arg_default_rlimit },
{ "Manager", "DefaultCPUAccounting", config_parse_bool, 0, &arg_default_cpu_accounting },
+ { "Manager", "DefaultIOAccounting", config_parse_bool, 0, &arg_default_io_accounting },
{ "Manager", "DefaultBlockIOAccounting", config_parse_bool, 0, &arg_default_blockio_accounting },
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting },
{ "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting },
@@ -696,11 +702,11 @@ static int parse_config_file(void) {
const char *fn, *conf_dirs_nulstr;
- fn = arg_running_as == MANAGER_SYSTEM ?
+ fn = arg_system ?
PKGSYSCONFDIR "/system.conf" :
PKGSYSCONFDIR "/user.conf";
- conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ?
+ conf_dirs_nulstr = arg_system ?
CONF_PATHS_NULSTR("systemd/system.conf.d") :
CONF_PATHS_NULSTR("systemd/user.conf.d");
@@ -729,6 +735,7 @@ static void manager_set_defaults(Manager *m) {
m->default_start_limit_interval = arg_default_start_limit_interval;
m->default_start_limit_burst = arg_default_start_limit_burst;
m->default_cpu_accounting = arg_default_cpu_accounting;
+ m->default_io_accounting = arg_default_io_accounting;
m->default_blockio_accounting = arg_default_blockio_accounting;
m->default_memory_accounting = arg_default_memory_accounting;
m->default_tasks_accounting = arg_default_tasks_accounting;
@@ -874,17 +881,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_SYSTEM:
- arg_running_as = MANAGER_SYSTEM;
+ arg_system = true;
break;
case ARG_USER:
- arg_running_as = MANAGER_USER;
+ arg_system = false;
break;
case ARG_TEST:
arg_action = ACTION_TEST;
- if (arg_no_pager < 0)
- arg_no_pager = true;
break;
case ARG_NO_PAGER:
@@ -994,8 +999,6 @@ static int parse_argv(int argc, char *argv[]) {
case 'h':
arg_action = ACTION_HELP;
- if (arg_no_pager < 0)
- arg_no_pager = true;
break;
case 'D':
@@ -1073,7 +1076,7 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
return log_error_errno(r, "Failed to create serialization file: %m");
/* Make sure nothing is really destructed when we shut down */
- m->n_reloading ++;
+ m->n_reloading++;
bus_manager_send_reloading(m, true);
fds = fdset_new();
@@ -1230,10 +1233,15 @@ static int status_welcome(void) {
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read os-release file: %m");
- return status_printf(NULL, false, false,
- "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
- isempty(ansi_color) ? "1" : ansi_color,
- isempty(pretty_name) ? "GNU/Linux" : pretty_name);
+ if (log_get_show_color())
+ return status_printf(NULL, false, false,
+ "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
+ isempty(ansi_color) ? "1" : ansi_color,
+ isempty(pretty_name) ? "GNU/Linux" : pretty_name);
+ else
+ return status_printf(NULL, false, false,
+ "\nWelcome to %s!\n",
+ isempty(pretty_name) ? "GNU/Linux" : pretty_name);
}
static int write_container_id(void) {
@@ -1244,7 +1252,8 @@ static int write_container_id(void) {
if (isempty(c))
return 0;
- r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE);
+ RUN_WITH_UMASK(0022)
+ r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE);
if (r < 0)
return log_warning_errno(r, "Failed to write /run/systemd/container, ignoring: %m");
@@ -1313,7 +1322,6 @@ int main(int argc, char *argv[]) {
/* This is compatibility support for SysV, where
* calling init as a user is identical to telinit. */
- errno = -ENOENT;
execv(SYSTEMCTL_BINARY_PATH, argv);
log_error_errno(errno, "Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
return 1;
@@ -1344,7 +1352,7 @@ int main(int argc, char *argv[]) {
saved_argv = argv;
saved_argc = argc;
- log_show_color(isatty(STDERR_FILENO) > 0);
+ log_show_color(colors_enabled());
log_set_upgrade_syslog_to_journal(true);
/* Disable the umask logic */
@@ -1354,7 +1362,7 @@ int main(int argc, char *argv[]) {
if (getpid() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */
- arg_running_as = MANAGER_SYSTEM;
+ arg_system = true;
make_null_stdio();
log_set_target(LOG_TARGET_KMSG);
log_open();
@@ -1382,13 +1390,13 @@ int main(int argc, char *argv[]) {
dual_timestamp_get(&security_finish_timestamp);
}
- if (mac_selinux_init(NULL) < 0) {
+ if (mac_selinux_init() < 0) {
error_message = "Failed to initialize SELinux policy";
goto finish;
}
if (!skip_setup) {
- if (clock_is_localtime() > 0) {
+ if (clock_is_localtime(NULL) > 0) {
int min;
/*
@@ -1438,7 +1446,7 @@ int main(int argc, char *argv[]) {
} else if (getpid() == 1) {
/* Running inside a container, as PID 1 */
- arg_running_as = MANAGER_SYSTEM;
+ arg_system = true;
log_set_target(LOG_TARGET_CONSOLE);
log_close_console(); /* force reopen of /dev/console */
log_open();
@@ -1448,12 +1456,10 @@ int main(int argc, char *argv[]) {
/* clear the kernel timestamp,
* because we are in a container */
- kernel_timestamp.monotonic = 0ULL;
- kernel_timestamp.realtime = 0ULL;
-
+ kernel_timestamp = DUAL_TIMESTAMP_NULL;
} else {
/* Running as user instance */
- arg_running_as = MANAGER_USER;
+ arg_system = false;
log_set_target(LOG_TARGET_AUTO);
log_open();
@@ -1511,7 +1517,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (arg_running_as == MANAGER_SYSTEM) {
+ if (arg_system) {
r = parse_proc_cmdline(parse_proc_cmdline_item);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
@@ -1532,14 +1538,14 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (arg_running_as == MANAGER_USER &&
+ if (!arg_system &&
arg_action == ACTION_RUN &&
sd_booted() <= 0) {
log_error("Trying to run as user instance, but the system has not been booted with systemd.");
goto finish;
}
- if (arg_running_as == MANAGER_SYSTEM &&
+ if (arg_system &&
arg_action == ACTION_RUN &&
running_in_chroot() > 0) {
log_error("Cannot be run in a chroot() environment.");
@@ -1549,7 +1555,8 @@ int main(int argc, char *argv[]) {
if (arg_action == ACTION_TEST)
skip_setup = true;
- pager_open_if_enabled();
+ if (arg_action == ACTION_TEST || arg_action == ACTION_HELP)
+ pager_open(arg_no_pager, false);
if (arg_action == ACTION_HELP) {
retval = help();
@@ -1566,7 +1573,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (arg_running_as == MANAGER_USER &&
+ if (!arg_system &&
!getenv("XDG_RUNTIME_DIR")) {
log_error("Trying to run as user instance, but $XDG_RUNTIME_DIR is not set.");
goto finish;
@@ -1589,7 +1596,7 @@ int main(int argc, char *argv[]) {
if (arg_serialization)
assert_se(fdset_remove(fds, fileno(arg_serialization)) >= 0);
- if (arg_running_as == MANAGER_SYSTEM)
+ if (arg_system)
/* Become a session leader if we aren't one yet. */
setsid();
@@ -1598,7 +1605,7 @@ int main(int argc, char *argv[]) {
/* Reset the console, but only if this is really init and we
* are freshly booted */
- if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN) {
+ if (arg_system && arg_action == ACTION_RUN) {
/* If we are init, we connect stdin/stdout/stderr to
* /dev/null and make sure we don't have a controlling
@@ -1625,7 +1632,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (arg_running_as == MANAGER_SYSTEM) {
+ if (arg_system) {
int v;
log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")",
@@ -1661,7 +1668,7 @@ int main(int argc, char *argv[]) {
arg_action == ACTION_TEST ? " test" : "", getuid(), t);
}
- if (arg_running_as == MANAGER_SYSTEM && !skip_setup) {
+ if (arg_system && !skip_setup) {
if (arg_show_status > 0)
status_welcome();
@@ -1673,7 +1680,7 @@ int main(int argc, char *argv[]) {
test_usr();
}
- if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0)
+ if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY)
watchdog_set_timeout(&arg_runtime_watchdog);
if (arg_timer_slack_nsec != NSEC_INFINITY)
@@ -1703,12 +1710,12 @@ int main(int argc, char *argv[]) {
}
}
- if (arg_running_as == MANAGER_USER)
+ if (!arg_system)
/* Become reaper of our children */
if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
log_warning_errno(errno, "Failed to make us a subreaper: %m");
- if (arg_running_as == MANAGER_SYSTEM) {
+ if (arg_system) {
bump_rlimit_nofile(&saved_rlimit_nofile);
if (empty_etc) {
@@ -1720,7 +1727,7 @@ int main(int argc, char *argv[]) {
}
}
- r = manager_new(arg_running_as, arg_action == ACTION_TEST, &m);
+ r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, arg_action == ACTION_TEST, &m);
if (r < 0) {
log_emergency_errno(r, "Failed to allocate manager object: %m");
error_message = "Failed to allocate manager object";
@@ -1883,7 +1890,7 @@ int main(int argc, char *argv[]) {
case MANAGER_EXIT:
retval = m->return_value;
- if (m->running_as == MANAGER_USER) {
+ if (MANAGER_IS_USER(m)) {
log_debug("Exit.");
goto finish;
}
@@ -1979,7 +1986,7 @@ finish:
args[i++] = SYSTEMD_BINARY_PATH;
if (switch_root_dir)
args[i++] = "--switched-root";
- args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
+ args[i++] = arg_system ? "--system" : "--user";
args[i++] = "--deserialize";
args[i++] = sfd;
args[i++] = NULL;
@@ -2104,7 +2111,7 @@ finish:
assert(pos < ELEMENTSOF(command_line));
- if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
+ if (arm_reboot_watchdog && arg_shutdown_watchdog > 0 && arg_shutdown_watchdog != USEC_INFINITY) {
char *e;
/* If we reboot let's set the shutdown
diff --git a/src/grp-system/systemd/org.freedesktop.systemd1.conf b/src/grp-system/systemd/org.freedesktop.systemd1.conf
index 6a7a37ee92..3c64f20872 100644
--- a/src/grp-system/systemd/org.freedesktop.systemd1.conf
+++ b/src/grp-system/systemd/org.freedesktop.systemd1.conf
@@ -70,14 +70,26 @@
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="ListUnitsByPatterns"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="ListUnitFiles"/>
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="ListUnitFilesByPatterns"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="GetUnitFileState"/>
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="GetUnitProcesses"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="ListJobs"/>
<allow send_destination="org.freedesktop.systemd1"
@@ -144,6 +156,10 @@
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="ListUnitsByNames"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="StartTransientUnit"/>
<allow send_destination="org.freedesktop.systemd1"
@@ -176,6 +192,10 @@
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="RevertUnitFiles"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="PresetUnitFiles"/>
<allow send_destination="org.freedesktop.systemd1"
diff --git a/src/grp-system/systemd/system.conf b/src/grp-system/systemd/system.conf
index e2ded27333..db8b7acd78 100644
--- a/src/grp-system/systemd/system.conf
+++ b/src/grp-system/systemd/system.conf
@@ -34,10 +34,11 @@
#DefaultTimeoutStartSec=90s
#DefaultTimeoutStopSec=90s
#DefaultRestartSec=100ms
-#DefaultStartLimitInterval=10s
+#DefaultStartLimitIntervalSec=10s
#DefaultStartLimitBurst=5
#DefaultEnvironment=
#DefaultCPUAccounting=no
+#DefaultIOAccounting=no
#DefaultBlockIOAccounting=no
#DefaultMemoryAccounting=no
#DefaultTasksAccounting=yes
diff --git a/src/grp-system/systemd/triggers.systemd.in b/src/grp-system/systemd/triggers.systemd.in
index 9e18a39a67..0d8c303136 100644
--- a/src/grp-system/systemd/triggers.systemd.in
+++ b/src/grp-system/systemd/triggers.systemd.in
@@ -18,6 +18,8 @@
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
# The contents of this are an example to be copied into systemd.spec.
+#
+# Minimum rpm version supported: 4.13.0
%transfiletriggerin -P 900900 -p <lua> -- @systemunitdir@ /etc/systemd/system
-- This script will run after any package is initially installed or
diff --git a/src/grp-system/systemd/user.conf b/src/grp-system/systemd/user.conf
index 87c8164378..b427f1ef6d 100644
--- a/src/grp-system/systemd/user.conf
+++ b/src/grp-system/systemd/user.conf
@@ -23,7 +23,7 @@
#DefaultTimeoutStartSec=90s
#DefaultTimeoutStopSec=90s
#DefaultRestartSec=100ms
-#DefaultStartLimitInterval=10s
+#DefaultStartLimitIntervalSec=10s
#DefaultStartLimitBurst=5
#DefaultEnvironment=
#DefaultLimitCPU=
diff --git a/src/grp-timedate/systemd-timedated/timedated.c b/src/grp-timedate/systemd-timedated/timedated.c
index f5ca319640..51a13fcf49 100644
--- a/src/grp-timedate/systemd-timedated/timedated.c
+++ b/src/grp-timedate/systemd-timedated/timedated.c
@@ -78,7 +78,7 @@ static int context_read_data(Context *c) {
c->zone = t;
t = NULL;
- c->local_rtc = clock_is_localtime() > 0;
+ c->local_rtc = clock_is_localtime(NULL) > 0;
return 0;
}
@@ -125,30 +125,44 @@ static int context_write_data_local_rtc(Context *c) {
if (!w)
return -ENOMEM;
} else {
- char *p, *e;
+ char *p;
+ const char *e = "\n"; /* default if there is less than 3 lines */
+ const char *prepend = "";
size_t a, b;
- p = strchr(s, '\n');
- if (!p)
- return -EIO;
-
- p = strchr(p+1, '\n');
- if (!p)
- return -EIO;
-
- p++;
- e = strchr(p, '\n');
- if (!e)
- return -EIO;
+ p = strchrnul(s, '\n');
+ if (*p == '\0')
+ /* only one line, no \n terminator */
+ prepend = "\n0\n";
+ else if (p[1] == '\0') {
+ /* only one line, with \n terminator */
+ ++p;
+ prepend = "0\n";
+ } else {
+ p = strchr(p+1, '\n');
+ if (!p) {
+ /* only two lines, no \n terminator */
+ prepend = "\n";
+ p = s + strlen(s);
+ } else {
+ char *end;
+ /* third line might have a \n terminator or not */
+ p++;
+ end = strchr(p, '\n');
+ /* if we actually have a fourth line, use that as suffix "e", otherwise the default \n */
+ if (end)
+ e = end;
+ }
+ }
a = p - s;
b = strlen(e);
- w = new(char, a + (c->local_rtc ? 5 : 3) + b + 1);
+ w = new(char, a + (c->local_rtc ? 5 : 3) + strlen(prepend) + b + 1);
if (!w)
return -ENOMEM;
- *(char*) mempcpy(stpcpy(mempcpy(w, s, a), c->local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
+ *(char*) mempcpy(stpcpy(stpcpy(mempcpy(w, s, a), prepend), c->local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
if (streq(w, NULL_ADJTIME_UTC)) {
if (unlink("/etc/adjtime") < 0)
@@ -159,7 +173,7 @@ static int context_write_data_local_rtc(Context *c) {
}
}
- mac_selinux_init("/etc");
+ mac_selinux_init();
return write_string_file_atomic_label("/etc/adjtime", w);
}
diff --git a/src/grp-timedate/timedatectl/timedatectl.c b/src/grp-timedate/timedatectl/timedatectl.c
index 28546a0ad1..1fd542fb49 100644
--- a/src/grp-timedate/timedatectl/timedatectl.c
+++ b/src/grp-timedate/timedatectl/timedatectl.c
@@ -40,14 +40,6 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static char *arg_host = NULL;
static bool arg_adjust_system_clock = false;
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static void polkit_agent_open_if_enabled(void) {
/* Open the polkit agent as a child process if necessary */
@@ -313,7 +305,7 @@ static int list_timezones(sd_bus *bus, char **args, unsigned n) {
if (r < 0)
return log_error_errno(r, "Failed to read list of time zones: %m");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
strv_print(zones);
return 0;
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index c37e32e96b..d11756e615 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -706,7 +706,7 @@ int main(int argc, char *argv[]) {
log_open();
umask(0022);
- mac_selinux_init("/etc");
+ mac_selinux_init();
if (argc != 1) {
log_error("This program takes no arguments.");
diff --git a/src/import/Makefile b/src/import/Makefile
index 909662b1b4..a918dd5344 100644
--- a/src/import/Makefile
+++ b/src/import/Makefile
@@ -65,8 +65,6 @@ systemd_pull_SOURCES = \
src/import/import-compress.h \
src/import/curl-util.c \
src/import/curl-util.h \
- src/import/aufs-util.c \
- src/import/aufs-util.h \
src/import/qcow2-util.c \
src/import/qcow2-util.h
diff --git a/src/import/aufs-util.c b/src/import/aufs-util.c
deleted file mode 100644
index 44aa6e2170..0000000000
--- a/src/import/aufs-util.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <ftw.h>
-
-#include "aufs-util.h"
-#include "rm-rf.h"
-#include "string-util.h"
-#include "util.h"
-
-static int nftw_cb(
- const char *fpath,
- const struct stat *sb,
- int flag,
- struct FTW *ftwbuf) {
-
- const char *fn, *original;
- char *p;
- int r;
-
- fn = fpath + ftwbuf->base;
-
- /* We remove all whiteout files, and all whiteouts */
-
- original = startswith(fn, ".wh.");
- if (!original)
- return FTW_CONTINUE;
-
- log_debug("Removing whiteout indicator %s.", fpath);
- r = rm_rf(fpath, REMOVE_ROOT|REMOVE_PHYSICAL);
- if (r < 0)
- return FTW_STOP;
-
- if (!startswith(fn, ".wh..wh.")) {
-
- p = alloca(ftwbuf->base + strlen(original));
- strcpy(mempcpy(p, fpath, ftwbuf->base), original);
-
- log_debug("Removing deleted file %s.", p);
- r = rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
- if (r < 0)
- return FTW_STOP;
- }
-
- return FTW_CONTINUE;
-}
-
-int aufs_resolve(const char *path) {
- int r;
-
- errno = 0;
- r = nftw(path, nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
- if (r == FTW_STOP)
- return errno > 0 ? -errno : -EIO;
-
- return 0;
-}
diff --git a/src/import/curl-util.c b/src/import/curl-util.c
index a04c8c49ff..6990c47f48 100644
--- a/src/import/curl-util.c
+++ b/src/import/curl-util.c
@@ -137,7 +137,7 @@ static int curl_glue_socket_callback(CURLM *curl, curl_socket_t s, int action, v
if (sd_event_add_io(g->event, &io, fd, events, curl_glue_on_io, g) < 0)
return -1;
- sd_event_source_set_description(io, "curl-io");
+ (void) sd_event_source_set_description(io, "curl-io");
r = hashmap_put(g->ios, FD_TO_PTR(s), io);
if (r < 0) {
@@ -204,7 +204,7 @@ static int curl_glue_timer_callback(CURLM *curl, long timeout_ms, void *userdata
if (sd_event_add_time(g->event, &g->timer, clock_boottime_or_monotonic(), usec, 0, curl_glue_on_timer, g) < 0)
return -1;
- sd_event_source_set_description(g->timer, "curl-timer");
+ (void) sd_event_source_set_description(g->timer, "curl-timer");
}
return 0;
diff --git a/src/import/import-common.c b/src/import/import-common.c
index 18a30be36d..287a3382a1 100644
--- a/src/import/import-common.c
+++ b/src/import/import-common.c
@@ -136,7 +136,7 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
if (r < 0)
log_error_errno(r, "Failed to drop capabilities, ignoring: %m");
- execlp("tar", "tar", "--numeric-owner", "-C", path, "-px", NULL);
+ execlp("tar", "tar", "--numeric-owner", "-C", path, "-px", "--xattrs", "--xattrs-include=*", NULL);
log_error_errno(errno, "Failed to execute tar: %m");
_exit(EXIT_FAILURE);
}
@@ -210,7 +210,7 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
if (r < 0)
log_error_errno(r, "Failed to drop capabilities, ignoring: %m");
- execlp("tar", "tar", "-C", path, "-c", ".", NULL);
+ execlp("tar", "tar", "-C", path, "-c", "--xattrs", "--xattrs-include=*", ".", NULL);
log_error_errno(errno, "Failed to execute tar: %m");
_exit(EXIT_FAILURE);
}
diff --git a/src/import/importd.c b/src/import/importd.c
index b44d0525ae..e30dfdf805 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -677,7 +677,7 @@ static int manager_new(Manager **ret) {
(void) mkdir_parents_label(sa.un.sun_path, 0755);
(void) unlink(sa.un.sun_path);
- if (bind(m->notify_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (bind(m->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return -errno;
if (setsockopt(m->notify_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index d301d4d79e..dc4e4667a9 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -330,7 +330,7 @@ int pull_verify(PullJob *main_job,
_cleanup_close_ int sig_file = -1;
const char *p, *line;
char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX";
- _cleanup_sigkill_wait_ pid_t pid = 0;
+ _cleanup_(sigkill_waitp) pid_t pid = 0;
bool gpg_home_created = false;
int r;
diff --git a/src/import/pull-job.h b/src/import/pull-job.h
index 998857035a..3a152a50e3 100644
--- a/src/import/pull-job.h
+++ b/src/import/pull-job.h
@@ -44,15 +44,6 @@ typedef enum PullJobState {
#define PULL_JOB_IS_COMPLETE(j) (IN_SET((j)->state, PULL_JOB_DONE, PULL_JOB_FAILED))
-typedef enum PullJobCompression {
- PULL_JOB_UNCOMPRESSED,
- PULL_JOB_XZ,
- PULL_JOB_GZIP,
- PULL_JOB_BZIP2,
- _PULL_JOB_COMPRESSION_MAX,
- _PULL_JOB_COMPRESSION_INVALID = -1,
-} PullJobCompression;
-
struct PullJob {
PullJobState state;
int error;
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index ca49f0c7d7..19155cc53a 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -355,10 +355,12 @@ static int raw_pull_make_local_copy(RawPull *i) {
r = copy_file_atomic(i->settings_path, local_settings, 0644, i->force_local, 0);
if (r == -EEXIST)
log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
- else if (r < 0 && r != -ENOENT)
+ else if (r == -ENOENT)
+ log_debug_errno(r, "Skipping creation of settings file, since none was found.");
+ else if (r < 0)
log_warning_errno(r, "Failed to copy settings files %s, ignoring: %m", local_settings);
else
- log_info("Created new settings file '%s.nspawn'", i->local);
+ log_info("Created new settings file %s.", local_settings);
}
return 0;
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 1fed468b7e..e0205c3841 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -251,10 +251,12 @@ static int tar_pull_make_local_copy(TarPull *i) {
r = copy_file_atomic(i->settings_path, local_settings, 0664, i->force_local, 0);
if (r == -EEXIST)
log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
- else if (r < 0 && r != -ENOENT)
+ else if (r == -ENOENT)
+ log_debug_errno(r, "Skipping creation of settings file, since none was found.");
+ else if (r < 0)
log_warning_errno(r, "Failed to copy settings files %s, ignoring: %m", local_settings);
else
- log_info("Created new settings file '%s.nspawn'", i->local);
+ log_info("Created new settings file %s.", local_settings);
}
return 0;
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index 27f1fd04a1..05285e3846 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -314,7 +314,7 @@ static int server_init(Server *s, unsigned n_sockets) {
f->fd = fd;
LIST_PREPEND(fifo, s->fifos, f);
f->server = s;
- s->n_fifos ++;
+ s->n_fifos++;
}
r = bus_connect_system_systemd(&s->bus);
diff --git a/src/journal/Makefile b/src/journal/Makefile
deleted file mode 100644
index 4a7d6122c1..0000000000
--- a/src/journal/Makefile
+++ /dev/null
@@ -1,348 +0,0 @@
-# -*- Mode: makefile; indent-tabs-mode: t -*-
-#
-# This file is part of systemd.
-#
-# Copyright 2010-2012 Lennart Poettering
-# Copyright 2010-2012 Kay Sievers
-# Copyright 2013 Zbigniew Jędrzejewski-Szmek
-# Copyright 2013 David Strauss
-# Copyright 2016 Luke Shumaker
-#
-# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
-include $(topsrcdir)/build-aux/Makefile.head.mk
-
-
-$(outdir)/dns_type-list.txt: src/resolve/dns-type.h
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)$(SED) -n -r 's/.* DNS_TYPE_(\w+).*/\1/p' <$< >$@
-
-$(outdir)/dns_type-to-name.h: src/resolve/dns_type-list.txt
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)$(AWK) '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" }' <$< >$@
-
-$(outdir)/dns_type-from-name.gperf: src/resolve/dns_type-list.txt
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct dns_type_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { s=$$1; sub(/_/, "-", s); printf "%s, ", $$s; printf "DNS_TYPE_%s\n", $$1 }' <$< >$@
-
-systemd_journald_SOURCES = \
- src/journal/journald.c \
- src/journal/journald-server.h
-
-systemd_journald_LDADD = \
- libjournal-core.la \
- libshared.la
-
-systemd_cat_SOURCES = \
- src/journal/cat.c
-
-systemd_cat_LDADD = \
- libjournal-core.la
-
-# using _CFLAGS = in the conditional below would suppress AM_CFLAGS
-journalctl_CFLAGS = \
- $(AM_CFLAGS)
-
-journalctl_SOURCES = \
- src/journal/journalctl.c
-
-journalctl_LDADD = \
- libshared.la \
- libudev-core.la
-
-ifneq ($(HAVE_QRENCODE),)
-journalctl_SOURCES += \
- src/journal/journal-qrcode.c \
- src/journal/journal-qrcode.h
-
-journalctl_CFLAGS += \
- $(QRENCODE_CFLAGS)
-
-journalctl_LDADD += \
- $(QRENCODE_LIBS)
-endif # HAVE_QRENCODE
-
-test_journal_SOURCES = \
- src/journal/test-journal.c
-
-test_journal_LDADD = \
- libjournal-core.la
-
-test_journal_send_SOURCES = \
- src/journal/test-journal-send.c
-
-test_journal_send_LDADD = \
- libjournal-core.la
-
-test_journal_syslog_SOURCES = \
- src/journal/test-journal-syslog.c
-
-test_journal_syslog_LDADD = \
- libjournal-core.la
-
-test_journal_match_SOURCES = \
- src/journal/test-journal-match.c
-
-test_journal_match_LDADD = \
- libjournal-core.la
-
-test_journal_enum_SOURCES = \
- src/journal/test-journal-enum.c
-
-test_journal_enum_LDADD = \
- libjournal-core.la
-
-test_journal_stream_SOURCES = \
- src/journal/test-journal-stream.c
-
-test_journal_stream_LDADD = \
- libjournal-core.la
-
-test_journal_flush_SOURCES = \
- src/journal/test-journal-flush.c
-
-test_journal_flush_LDADD = \
- libjournal-core.la
-
-test_journal_init_SOURCES = \
- src/journal/test-journal-init.c
-
-test_journal_init_LDADD = \
- libjournal-core.la
-
-test_journal_verify_SOURCES = \
- src/journal/test-journal-verify.c
-
-test_journal_verify_LDADD = \
- libjournal-core.la
-
-test_journal_interleaving_SOURCES = \
- src/journal/test-journal-interleaving.c
-
-test_journal_interleaving_LDADD = \
- libjournal-core.la
-
-test_mmap_cache_SOURCES = \
- src/journal/test-mmap-cache.c
-
-test_mmap_cache_LDADD = \
- libjournal-core.la
-
-test_catalog_SOURCES = \
- src/journal/test-catalog.c
-
-test_catalog_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -DCATALOG_DIR=\"$(abs_top_srcdir)/catalog\"
-
-test_catalog_LDADD = \
- libjournal-core.la
-
-test_compress_SOURCES = \
- src/journal/test-compress.c
-
-test_compress_LDADD = \
- libshared.la
-
-test_compress_benchmark_SOURCES = \
- src/journal/test-compress-benchmark.c
-
-test_compress_benchmark_LDADD = \
- libshared.la
-
-test_audit_type_SOURCES = \
- src/journal/test-audit-type.c
-
-test_audit_type_LDADD = \
- libjournal-core.la
-
-libjournal_core_la_SOURCES = \
- src/journal/journald-kmsg.c \
- src/journal/journald-kmsg.h \
- src/journal/journald-syslog.c \
- src/journal/journald-syslog.h \
- src/journal/journald-stream.c \
- src/journal/journald-stream.h \
- src/journal/journald-server.c \
- src/journal/journald-server.h \
- src/journal/journald-console.c \
- src/journal/journald-console.h \
- src/journal/journald-wall.c \
- src/journal/journald-wall.h \
- src/journal/journald-native.c \
- src/journal/journald-native.h \
- src/journal/journald-audit.c \
- src/journal/journald-audit.h \
- src/journal/journald-rate-limit.c \
- src/journal/journald-rate-limit.h \
- src/journal/journal-internal.h
-
-nodist_libjournal_core_la_SOURCES = \
- src/journal/journald-gperf.c
-
-libjournal_core_la_LIBADD = \
- libshared.la
-
-noinst_LTLIBRARIES += \
- libjournal-core.la
-
-journal-install-hook:
- -$(MKDIR_P) $(DESTDIR)/var/log/journal
- -chown 0:0 $(DESTDIR)/var/log/journal
- -chmod 755 $(DESTDIR)/var/log/journal
- -setfacl -nm g:adm:rx,d:g:adm:rx $(DESTDIR)/var/log/journal/
- -setfacl -nm g:wheel:rx,d:g:wheel:rx $(DESTDIR)/var/log/journal/
-
-journal-uninstall-hook:
- -rmdir $(DESTDIR)/var/log/journal/remote
- -rmdir $(DESTDIR)/var/log/journal/
-
-INSTALL_EXEC_HOOKS += journal-install-hook
-UNINSTALL_EXEC_HOOKS += journal-uninstall-hook
-
-# ------------------------------------------------------------------------------
-# Update catalog on installation. Do not bother if installing
-# in DESTDIR, since this is likely for packaging purposes.
-catalog-update-hook:
- -test -n "$(DESTDIR)" || $(bindir)/journalctl --update-catalog
-
-INSTALL_DATA_HOOKS += \
- catalog-update-hook
-
-catalog-remove-hook:
- -test -n "$(DESTDIR)" || rm -f $(catalogstatedir)/database
-
-UNINSTALL_DATA_HOOKS += \
- catalog-remove-hook
-
-manual_tests += \
- test-journal-enum
-
-tests += \
- test-journal \
- test-journal-send \
- test-journal-syslog \
- test-journal-match \
- test-journal-stream \
- test-journal-init \
- test-journal-verify \
- test-journal-interleaving \
- test-journal-flush \
- test-mmap-cache \
- test-catalog \
- test-audit-type
-
-ifneq ($(HAVE_COMPRESSION),)
-tests += \
- test-compress \
- test-compress-benchmark
-endif # HAVE_COMPRESSION
-
-
-libexec_PROGRAMS += \
- systemd-journald
-
-bin_PROGRAMS += \
- journalctl
-
-bin_PROGRAMS += \
- systemd-cat
-
-dist_systemunit_DATA += \
- units/systemd-journald.socket \
- units/systemd-journald-dev-log.socket \
- units/systemd-journald-audit.socket
-
-nodist_systemunit_DATA += \
- units/systemd-journald.service \
- units/systemd-journal-flush.service \
- units/systemd-journal-catalog-update.service
-
-dist_pkgsysconf_DATA += \
- src/journal/journald.conf
-
-dist_catalog_DATA = \
- catalog/systemd.be.catalog \
- catalog/systemd.be@latin.catalog \
- catalog/systemd.fr.catalog \
- catalog/systemd.it.catalog \
- catalog/systemd.pl.catalog \
- catalog/systemd.pt_BR.catalog \
- catalog/systemd.ru.catalog \
- catalog/systemd.zh_CN.catalog \
- catalog/systemd.zh_TW.catalog \
- catalog/systemd.catalog
-
-SOCKETS_TARGET_WANTS += \
- systemd-journald.socket \
- systemd-journald-dev-log.socket \
- systemd-journald-audit.socket
-
-SYSINIT_TARGET_WANTS += \
- systemd-journald.service \
- systemd-journal-flush.service \
- systemd-journal-catalog-update.service
-
-EXTRA_DIST += \
- units/systemd-journald.service.in \
- units/systemd-journal-flush.service.in \
- units/systemd-journal-catalog-update.service.in
-
-gperf_gperf_sources += \
- src/journal/journald-gperf.gperf
-
-# ------------------------------------------------------------------------------
-ifneq ($(HAVE_MICROHTTPD),)
-gatewayddocumentrootdir=$(pkgdatadir)/gatewayd
-
-libexec_PROGRAMS += \
- systemd-journal-gatewayd
-
-systemd_journal_gatewayd_SOURCES = \
- src/journal-remote/journal-gatewayd.c \
- src/journal-remote/microhttpd-util.h \
- src/journal-remote/microhttpd-util.c
-
-systemd_journal_gatewayd_LDADD = \
- libshared.la \
- $(MICROHTTPD_LIBS)
-
-ifneq ($(HAVE_GNUTLS),)
-systemd_journal_gatewayd_LDADD += \
- $(GNUTLS_LIBS)
-endif # HAVE_GNUTLS
-
-systemd_journal_gatewayd_CFLAGS = \
- $(AM_CFLAGS) \
- $(MICROHTTPD_CFLAGS)
-
-systemd_journal_gatewayd_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -DDOCUMENT_ROOT=\"$(gatewayddocumentrootdir)\"
-
-dist_systemunit_DATA += \
- units/systemd-journal-gatewayd.socket
-
-nodist_systemunit_DATA += \
- units/systemd-journal-gatewayd.service
-
-dist_gatewayddocumentroot_DATA = \
- src/journal-remote/browse.html
-
-endif # HAVE_MICROHTTPD
-
-EXTRA_DIST += \
- units/systemd-journal-gatewayd.service.in
-
-include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/libbasic/Makefile b/src/libbasic/Makefile
index b01d100a72..ded8e4de8b 100644
--- a/src/libbasic/Makefile
+++ b/src/libbasic/Makefile
@@ -28,10 +28,9 @@ noinst_LTLIBRARIES += \
libbasic_la_SOURCES = \
src/basic/missing.h \
+ src/basic/missing_syscall.h \
src/basic/capability-util.c \
src/basic/capability-util.h \
- src/basic/c-rbtree.c \
- src/basic/c-rbtree.h \
src/basic/conf-files.c \
src/basic/conf-files.h \
src/basic/stdio-util.h \
@@ -138,6 +137,8 @@ libbasic_la_SOURCES = \
src/basic/exit-status.h \
src/basic/virt.c \
src/basic/virt.h \
+ src/basic/architecture.c \
+ src/basic/architecture.h \
src/basic/smack-util.c \
src/basic/smack-util.h \
src/basic/device-nodes.c \
@@ -182,8 +183,6 @@ libbasic_la_SOURCES = \
src/basic/audit-util.h \
src/basic/xml.c \
src/basic/xml.h \
- src/basic/json.c \
- src/basic/json.h \
src/basic/barrier.c \
src/basic/barrier.h \
src/basic/async.c \
diff --git a/src/libbasic/MurmurHash2.c b/src/libbasic/MurmurHash2.c
index 2f4149dbe9..9020793930 100644
--- a/src/libbasic/MurmurHash2.c
+++ b/src/libbasic/MurmurHash2.c
@@ -50,7 +50,7 @@ uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )
const unsigned char * data = (const unsigned char *)key;
- while(len >= 4)
+ while (len >= 4)
{
uint32_t k = *(uint32_t*)data;
diff --git a/src/libbasic/af-list.h b/src/libbasic/af-list.h
index 135248dc64..6a4cc03839 100644
--- a/src/libbasic/af-list.h
+++ b/src/libbasic/af-list.h
@@ -19,7 +19,23 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "string-util.h"
+
const char *af_to_name(int id);
int af_from_name(const char *name);
+static inline const char* af_to_name_short(int id) {
+ const char *f;
+
+ if (id == AF_UNSPEC)
+ return "*";
+
+ f = af_to_name(id);
+ if (!f)
+ return "unknown";
+
+ assert(startswith(f, "AF_"));
+ return f + 3;
+}
+
int af_max(void);
diff --git a/src/libbasic/alloc-util.h b/src/libbasic/alloc-util.h
index 679ba7f398..ceeee519b7 100644
--- a/src/libbasic/alloc-util.h
+++ b/src/libbasic/alloc-util.h
@@ -51,25 +51,29 @@ static inline void freep(void *p) {
#define _cleanup_free_ _cleanup_(freep)
-_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
- if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+static inline bool size_multiply_overflow(size_t size, size_t need) {
+ return _unlikely_(need != 0 && size > (SIZE_MAX / need));
+}
+
+_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
return NULL;
- return malloc(a * b);
+ return malloc(size * need);
}
-_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
- if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
return NULL;
- return realloc(p, a * b);
+ return realloc(p, size * need);
}
-_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
- if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
return NULL;
- return memdup(p, a * b);
+ return memdup(p, size * need);
}
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
diff --git a/src/libshared/architecture.c b/src/libbasic/architecture.c
index a9ecfc1cd6..b1c8e91f50 100644
--- a/src/libshared/architecture.c
+++ b/src/libbasic/architecture.c
@@ -63,7 +63,7 @@ int uname_architecture(void) {
#elif defined(__s390__) || defined(__s390x__)
{ "s390x", ARCHITECTURE_S390X },
{ "s390", ARCHITECTURE_S390 },
-#elif defined(__sparc__) || defined(__sparc64__)
+#elif defined(__sparc__)
{ "sparc64", ARCHITECTURE_SPARC64 },
{ "sparc", ARCHITECTURE_SPARC },
#elif defined(__mips__) || defined(__mips64__)
@@ -121,6 +121,8 @@ int uname_architecture(void) {
{ "tilegx", ARCHITECTURE_TILEGX },
#elif defined(__cris__)
{ "crisv32", ARCHITECTURE_CRIS },
+#elif defined(__nios2__)
+ { "nios2", ARCHITECTURE_NIOS2 },
#else
#error "Please register your architecture here!"
#endif
@@ -171,6 +173,7 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = {
[ARCHITECTURE_M68K] = "m68k",
[ARCHITECTURE_TILEGX] = "tilegx",
[ARCHITECTURE_CRIS] = "cris",
+ [ARCHITECTURE_NIOS2] = "nios2",
};
DEFINE_STRING_TABLE_LOOKUP(architecture, int);
diff --git a/src/libshared/architecture.h b/src/libbasic/architecture.h
index 26679e28c6..b3e4d85906 100644
--- a/src/libshared/architecture.h
+++ b/src/libbasic/architecture.h
@@ -57,6 +57,7 @@ enum {
ARCHITECTURE_M68K,
ARCHITECTURE_TILEGX,
ARCHITECTURE_CRIS,
+ ARCHITECTURE_NIOS2,
_ARCHITECTURE_MAX,
_ARCHITECTURE_INVALID = -1
};
@@ -77,20 +78,20 @@ int uname_architecture(void);
#if defined(__x86_64__)
# define native_architecture() ARCHITECTURE_X86_64
# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
-# define PROC_CPUINFO_MODEL "model name"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_X86
#elif defined(__i386__)
# define native_architecture() ARCHITECTURE_X86
# define LIB_ARCH_TUPLE "i386-linux-gnu"
-# define PROC_CPUINFO_MODEL "model name"
#elif defined(__powerpc64__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC64
# define LIB_ARCH_TUPLE "ppc64-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC
# else
# define native_architecture() ARCHITECTURE_PPC64_LE
# define LIB_ARCH_TUPLE "powerpc64le-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC_LE
# endif
-# define PROC_CPUINFO_MODEL "cpu"
#elif defined(__powerpc__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC
@@ -99,32 +100,28 @@ int uname_architecture(void);
# define native_architecture() ARCHITECTURE_PPC_LE
# error "Missing LIB_ARCH_TUPLE for PPCLE"
# endif
-# define PROC_CPUINFO_MODEL "cpu"
#elif defined(__ia64__)
# define native_architecture() ARCHITECTURE_IA64
# define LIB_ARCH_TUPLE "ia64-linux-gnu"
#elif defined(__hppa64__)
# define native_architecture() ARCHITECTURE_PARISC64
# error "Missing LIB_ARCH_TUPLE for HPPA64"
-# define PROC_CPUINFO_MODEL "cpu"
#elif defined(__hppa__)
# define native_architecture() ARCHITECTURE_PARISC
# define LIB_ARCH_TUPLE "hppa‑linux‑gnu"
-# define PROC_CPUINFO_MODEL "cpu"
#elif defined(__s390x__)
# define native_architecture() ARCHITECTURE_S390X
# define LIB_ARCH_TUPLE "s390x-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_S390
#elif defined(__s390__)
# define native_architecture() ARCHITECTURE_S390
# define LIB_ARCH_TUPLE "s390-linux-gnu"
-#elif defined(__sparc64__)
+#elif defined(__sparc__) && defined (__arch64__)
# define native_architecture() ARCHITECTURE_SPARC64
# define LIB_ARCH_TUPLE "sparc64-linux-gnu"
-# define PROC_CPUINFO_MODEL "cpu"
#elif defined(__sparc__)
# define native_architecture() ARCHITECTURE_SPARC
# define LIB_ARCH_TUPLE "sparc-linux-gnu"
-# define PROC_CPUINFO_MODEL "cpu"
#elif defined(__mips64__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_MIPS64
@@ -133,7 +130,6 @@ int uname_architecture(void);
# define native_architecture() ARCHITECTURE_MIPS64_LE
# error "Missing LIB_ARCH_TUPLE for MIPS64_LE"
# endif
-# define PROC_CPUINFO_MODEL "cpu model"
#elif defined(__mips__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_MIPS
@@ -142,7 +138,6 @@ int uname_architecture(void);
# define native_architecture() ARCHITECTURE_MIPS_LE
# define LIB_ARCH_TUPLE "mipsel-linux-gnu"
# endif
-# define PROC_CPUINFO_MODEL "cpu model"
#elif defined(__alpha__)
# define native_architecture() ARCHITECTURE_ALPHA
# define LIB_ARCH_TUPLE "alpha-linux-gnu"
@@ -178,7 +173,6 @@ int uname_architecture(void);
# define LIB_ARCH_TUPLE "arm-linux-gnu"
# endif
# endif
-# define PROC_CPUINFO_MODEL "model name"
#elif defined(__sh64__)
# define native_architecture() ARCHITECTURE_SH64
# error "Missing LIB_ARCH_TUPLE for SH64"
@@ -194,14 +188,12 @@ int uname_architecture(void);
#elif defined(__cris__)
# define native_architecture() ARCHITECTURE_CRIS
# error "Missing LIB_ARCH_TUPLE for CRIS"
+#elif defined(__nios2__)
+# define native_architecture() ARCHITECTURE_NIOS2
+# define LIB_ARCH_TUPLE "nios2-linux-gnu"
#else
# error "Please register your architecture here!"
#endif
-#ifndef PROC_CPUINFO_MODEL
-#warning "PROC_CPUINFO_MODEL not defined for your architecture"
-#define PROC_CPUINFO_MODEL "model name"
-#endif
-
const char *architecture_to_string(int a) _const_;
int architecture_from_string(const char *s) _pure_;
diff --git a/src/libbasic/btrfs-util.h b/src/libbasic/btrfs-util.h
index 29f8ba63d3..db431f5b74 100644
--- a/src/libbasic/btrfs-util.h
+++ b/src/libbasic/btrfs-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
diff --git a/src/libbasic/c-rbtree.c b/src/libbasic/c-rbtree.c
deleted file mode 100644
index 914d7e5229..0000000000
--- a/src/libbasic/c-rbtree.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/***
- This file is part of systemd. See COPYING for details.
-
- 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/>.
-***/
-
-/*
- * RB-Tree Implementation
- * This implements the insertion/removal of elements in RB-Trees. You're highly
- * recommended to have an RB-Tree documentation at hand when reading this. Both
- * insertion and removal can be split into a handful of situations that can
- * occur. Those situations are enumerated as "Case 1" to "Case n" here, and
- * follow closely the cases described in most RB-Tree documentations. This file
- * does not explain why it is enough to handle just those cases, nor does it
- * provide a proof of correctness. Dig out your algorithm 101 handbook if
- * you're interested.
- *
- * This implementation is *not* straightforward. Usually, a handful of
- * rotation, reparent, swap and link helpers can be used to implement the
- * rebalance operations. However, those often perform unnecessary writes.
- * Therefore, this implementation hard-codes all the operations. You're highly
- * recommended to look at the two basic helpers before reading the code:
- * c_rbtree_swap_child()
- * c_rbtree_set_parent_and_color()
- * Those are the only helpers used, hence, you should really know what they do
- * before digging into the code.
- *
- * For a highlevel documentation of the API, see the header file and docbook
- * comments.
- */
-
-#include <assert.h>
-#include <stddef.h>
-#include "c-rbtree.h"
-
-enum {
- C_RBNODE_RED = 0,
- C_RBNODE_BLACK = 1,
-};
-
-static inline unsigned long c_rbnode_color(CRBNode *n) {
- return (unsigned long)n->__parent_and_color & 1UL;
-}
-
-static inline _Bool c_rbnode_is_red(CRBNode *n) {
- return c_rbnode_color(n) == C_RBNODE_RED;
-}
-
-static inline _Bool c_rbnode_is_black(CRBNode *n) {
- return c_rbnode_color(n) == C_RBNODE_BLACK;
-}
-
-/**
- * c_rbnode_leftmost() - return leftmost child
- * @n: current node, or NULL
- *
- * This returns the leftmost child of @n. If @n is NULL, this will return NULL.
- * In all other cases, this function returns a valid pointer. That is, if @n
- * does not have any left children, this returns @n.
- *
- * Worst case runtime (n: number of elements in tree): O(log(n))
- *
- * Return: Pointer to leftmost child, or NULL.
- */
-CRBNode *c_rbnode_leftmost(CRBNode *n) {
- if (n)
- while (n->left)
- n = n->left;
- return n;
-}
-
-/**
- * c_rbnode_rightmost() - return rightmost child
- * @n: current node, or NULL
- *
- * This returns the rightmost child of @n. If @n is NULL, this will return
- * NULL. In all other cases, this function returns a valid pointer. That is, if
- * @n does not have any right children, this returns @n.
- *
- * Worst case runtime (n: number of elements in tree): O(log(n))
- *
- * Return: Pointer to rightmost child, or NULL.
- */
-CRBNode *c_rbnode_rightmost(CRBNode *n) {
- if (n)
- while (n->right)
- n = n->right;
- return n;
-}
-
-/**
- * c_rbnode_next() - return next node
- * @n: current node, or NULL
- *
- * An RB-Tree always defines a linear order of its elements. This function
- * returns the logically next node to @n. If @n is NULL, the last node or
- * unlinked, this returns NULL.
- *
- * Worst case runtime (n: number of elements in tree): O(log(n))
- *
- * Return: Pointer to next node, or NULL.
- */
-CRBNode *c_rbnode_next(CRBNode *n) {
- CRBNode *p;
-
- if (!c_rbnode_is_linked(n))
- return NULL;
- if (n->right)
- return c_rbnode_leftmost(n->right);
-
- while ((p = c_rbnode_parent(n)) && n == p->right)
- n = p;
-
- return p;
-}
-
-/**
- * c_rbnode_prev() - return previous node
- * @n: current node, or NULL
- *
- * An RB-Tree always defines a linear order of its elements. This function
- * returns the logically previous node to @n. If @n is NULL, the first node or
- * unlinked, this returns NULL.
- *
- * Worst case runtime (n: number of elements in tree): O(log(n))
- *
- * Return: Pointer to previous node, or NULL.
- */
-CRBNode *c_rbnode_prev(CRBNode *n) {
- CRBNode *p;
-
- if (!c_rbnode_is_linked(n))
- return NULL;
- if (n->left)
- return c_rbnode_rightmost(n->left);
-
- while ((p = c_rbnode_parent(n)) && n == p->left)
- n = p;
-
- return p;
-}
-
-/**
- * c_rbtree_first() - return first node
- * @t: tree to operate on
- *
- * An RB-Tree always defines a linear order of its elements. This function
- * returns the logically first node in @t. If @t is empty, NULL is returned.
- *
- * Fixed runtime (n: number of elements in tree): O(log(n))
- *
- * Return: Pointer to first node, or NULL.
- */
-CRBNode *c_rbtree_first(CRBTree *t) {
- assert(t);
- return c_rbnode_leftmost(t->root);
-}
-
-/**
- * c_rbtree_last() - return last node
- * @t: tree to operate on
- *
- * An RB-Tree always defines a linear order of its elements. This function
- * returns the logically last node in @t. If @t is empty, NULL is returned.
- *
- * Fixed runtime (n: number of elements in tree): O(log(n))
- *
- * Return: Pointer to last node, or NULL.
- */
-CRBNode *c_rbtree_last(CRBTree *t) {
- assert(t);
- return c_rbnode_rightmost(t->root);
-}
-
-/*
- * Set the color and parent of a node. This should be treated as a simple
- * assignment of the 'color' and 'parent' fields of the node. No other magic is
- * applied. But since both fields share its backing memory, this helper
- * function is provided.
- */
-static inline void c_rbnode_set_parent_and_color(CRBNode *n, CRBNode *p, unsigned long c) {
- assert(!((unsigned long)p & 1));
- assert(c < 2);
- n->__parent_and_color = (CRBNode*)((unsigned long)p | c);
-}
-
-/* same as c_rbnode_set_parent_and_color(), but keeps the current parent */
-static inline void c_rbnode_set_color(CRBNode *n, unsigned long c) {
- c_rbnode_set_parent_and_color(n, c_rbnode_parent(n), c);
-}
-
-/* same as c_rbnode_set_parent_and_color(), but keeps the current color */
-static inline void c_rbnode_set_parent(CRBNode *n, CRBNode *p) {
- c_rbnode_set_parent_and_color(n, p, c_rbnode_color(n));
-}
-
-/*
- * This function partially replaces an existing child pointer to a new one. The
- * existing child must be given as @old, the new child as @new. @p must be the
- * parent of @old (or NULL if it has no parent).
- * This function ensures that the parent of @old now points to @new. However,
- * it does *NOT* change the parent pointer of @new. The caller must ensure
- * this.
- * If @p is NULL, this function ensures that the root-pointer is adjusted
- * instead (given as @t).
- */
-static inline void c_rbtree_swap_child(CRBTree *t, CRBNode *p, CRBNode *old, CRBNode *new) {
- if (p) {
- if (p->left == old)
- p->left = new;
- else
- p->right = new;
- } else {
- t->root = new;
- }
-}
-
-static inline CRBNode *c_rbtree_paint_one(CRBTree *t, CRBNode *n) {
- CRBNode *p, *g, *gg, *u, *x;
-
- /*
- * Paint a single node according to RB-Tree rules. The node must
- * already be linked into the tree and painted red.
- * We repaint the node or rotate the tree, if required. In case a
- * recursive repaint is required, the next node to be re-painted
- * is returned.
- * p: parent
- * g: grandparent
- * gg: grandgrandparent
- * u: uncle
- * x: temporary
- */
-
- /* node is red, so we can access the parent directly */
- p = n->__parent_and_color;
-
- if (!p) {
- /* Case 1:
- * We reached the root. Mark it black and be done. As all
- * leaf-paths share the root, the ratio of black nodes on each
- * path stays the same. */
- c_rbnode_set_parent_and_color(n, p, C_RBNODE_BLACK);
- n = NULL;
- } else if (c_rbnode_is_black(p)) {
- /* Case 2:
- * The parent is already black. As our node is red, we did not
- * change the number of black nodes on any path, nor do we have
- * multiple consecutive red nodes. */
- n = NULL;
- } else if (p == p->__parent_and_color->left) { /* parent is red, so grandparent exists */
- g = p->__parent_and_color;
- gg = c_rbnode_parent(g);
- u = g->right;
-
- if (u && c_rbnode_is_red(u)) {
- /* Case 3:
- * Parent and uncle are both red. We know the
- * grandparent must be black then. Repaint parent and
- * uncle black, the grandparent red and recurse into
- * the grandparent. */
- c_rbnode_set_parent_and_color(p, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(u, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(g, gg, C_RBNODE_RED);
- n = g;
- } else {
- /* parent is red, uncle is black */
-
- if (n == p->right) {
- /* Case 4:
- * We're the right child. Rotate on parent to
- * become left child, so we can handle it the
- * same as case 5. */
- x = n->left;
- p->right = n->left;
- n->left = p;
- if (x)
- c_rbnode_set_parent_and_color(x, p, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(p, n, C_RBNODE_RED);
- p = n;
- }
-
- /* 'n' is invalid from here on! */
- n = NULL;
-
- /* Case 5:
- * We're the red left child or a red parent, black
- * grandparent and uncle. Rotate on grandparent and
- * switch color with parent. Number of black nodes on
- * each path stays the same, but we got rid of the
- * double red path. As the grandparent is still black,
- * we're done. */
- x = p->right;
- g->left = x;
- p->right = g;
- if (x)
- c_rbnode_set_parent_and_color(x, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(p, gg, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(g, p, C_RBNODE_RED);
- c_rbtree_swap_child(t, gg, g, p);
- }
- } else /* if (p == p->__parent_and_color->left) */ { /* same as above, but mirrored */
- g = p->__parent_and_color;
- gg = c_rbnode_parent(g);
- u = g->left;
-
- if (u && c_rbnode_is_red(u)) {
- c_rbnode_set_parent_and_color(p, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(u, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(g, gg, C_RBNODE_RED);
- n = g;
- } else {
- if (n == p->left) {
- x = n->right;
- p->left = n->right;
- n->right = p;
- if (x)
- c_rbnode_set_parent_and_color(x, p, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(p, n, C_RBNODE_RED);
- p = n;
- }
-
- n = NULL;
-
- x = p->left;
- g->right = x;
- p->left = g;
- if (x)
- c_rbnode_set_parent_and_color(x, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(p, gg, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(g, p, C_RBNODE_RED);
- c_rbtree_swap_child(t, gg, g, p);
- }
- }
-
- return n;
-}
-
-static inline void c_rbtree_paint(CRBTree *t, CRBNode *n) {
- assert(t);
- assert(n);
-
- while (n)
- n = c_rbtree_paint_one(t, n);
-}
-
-/**
- * c_rbtree_add() - add node to tree
- * @t: tree to operate one
- * @p: parent node to link under, or NULL
- * @l: left/right slot of @p (or root) to link at
- * @n: node to add
- *
- * This links @n into the tree given as @t. The caller must provide the exact
- * spot where to link the node. That is, the caller must traverse the tree
- * based on their search order. Once they hit a leaf where to insert the node,
- * call this function to link it and rebalance the tree.
- *
- * A typical insertion would look like this (@t is your tree, @n is your node):
- *
- * CRBNode **i, *p;
- *
- * i = &t->root;
- * p = NULL;
- * while (*i) {
- * p = *i;
- * if (compare(n, *i) < 0)
- * i = &(*i)->left;
- * else
- * i = &(*i)->right;
- * }
- *
- * c_rbtree_add(t, p, i, n);
- *
- * Once the node is linked into the tree, a simple lookup on the same tree can
- * be coded like this:
- *
- * CRBNode *i;
- *
- * i = t->root;
- * while (i) {
- * int v = compare(n, i);
- * if (v < 0)
- * i = (*i)->left;
- * else if (v > 0)
- * i = (*i)->right;
- * else
- * break;
- * }
- *
- * When you add nodes to a tree, the memory contents of the node do not matter.
- * That is, there is no need to initialize the node via c_rbnode_init().
- * However, if you relink nodes multiple times during their lifetime, it is
- * usually very convenient to use c_rbnode_init() and c_rbtree_remove_init().
- * In those cases, you should validate that a node is unlinked before you call
- * c_rbtree_add().
- */
-void c_rbtree_add(CRBTree *t, CRBNode *p, CRBNode **l, CRBNode *n) {
- assert(t);
- assert(l);
- assert(n);
- assert(!p || l == &p->left || l == &p->right);
- assert(p || l == &t->root);
-
- c_rbnode_set_parent_and_color(n, p, C_RBNODE_RED);
- n->left = n->right = NULL;
- *l = n;
-
- c_rbtree_paint(t, n);
-}
-
-static inline CRBNode *c_rbtree_rebalance_one(CRBTree *t, CRBNode *p, CRBNode *n) {
- CRBNode *s, *x, *y, *g;
-
- /*
- * Rebalance tree after a node was removed. This happens only if you
- * remove a black node and one path is now left with an unbalanced
- * number or black nodes.
- * This function assumes all paths through p and n have one black node
- * less than all other paths. If recursive fixup is required, the
- * current node is returned.
- */
-
- if (n == p->left) {
- s = p->right;
- if (c_rbnode_is_red(s)) {
- /* Case 3:
- * We have a red node as sibling. Rotate it onto our
- * side so we can later on turn it black. This way, we
- * gain the additional black node in our path. */
- g = c_rbnode_parent(p);
- x = s->left;
- p->right = x;
- s->left = p;
- c_rbnode_set_parent_and_color(x, p, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(s, g, c_rbnode_color(p));
- c_rbnode_set_parent_and_color(p, s, C_RBNODE_RED);
- c_rbtree_swap_child(t, g, p, s);
- s = x;
- }
-
- x = s->right;
- if (!x || c_rbnode_is_black(x)) {
- y = s->left;
- if (!y || c_rbnode_is_black(y)) {
- /* Case 4:
- * Our sibling is black and has only black
- * children. Flip it red and turn parent black.
- * This way we gained a black node in our path,
- * or we fix it recursively one layer up, which
- * will rotate the red sibling as parent. */
- c_rbnode_set_parent_and_color(s, p, C_RBNODE_RED);
- if (c_rbnode_is_black(p))
- return p;
-
- c_rbnode_set_parent_and_color(p, c_rbnode_parent(p), C_RBNODE_BLACK);
- return NULL;
- }
-
- /* Case 5:
- * Left child of our sibling is red, right one is black.
- * Rotate on parent so the right child of our sibling is
- * now red, and we can fall through to case 6. */
- x = y->right;
- s->left = y->right;
- y->right = s;
- p->right = y;
- if (x)
- c_rbnode_set_parent_and_color(x, s, C_RBNODE_BLACK);
- x = s;
- s = y;
- }
-
- /* Case 6:
- * The right child of our sibling is red. Rotate left and flip
- * colors, which gains us an additional black node in our path,
- * that was previously on our sibling. */
- g = c_rbnode_parent(p);
- y = s->left;
- p->right = y;
- s->left = p;
- c_rbnode_set_parent_and_color(x, s, C_RBNODE_BLACK);
- if (y)
- c_rbnode_set_parent_and_color(y, p, c_rbnode_color(y));
- c_rbnode_set_parent_and_color(s, g, c_rbnode_color(p));
- c_rbnode_set_parent_and_color(p, s, C_RBNODE_BLACK);
- c_rbtree_swap_child(t, g, p, s);
- } else /* if (!n || n == p->right) */ { /* same as above, but mirrored */
- s = p->left;
- if (c_rbnode_is_red(s)) {
- g = c_rbnode_parent(p);
- x = s->right;
- p->left = x;
- s->right = p;
- c_rbnode_set_parent_and_color(x, p, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(s, g, C_RBNODE_BLACK);
- c_rbnode_set_parent_and_color(p, s, C_RBNODE_RED);
- c_rbtree_swap_child(t, g, p, s);
- s = x;
- }
-
- x = s->left;
- if (!x || c_rbnode_is_black(x)) {
- y = s->right;
- if (!y || c_rbnode_is_black(y)) {
- c_rbnode_set_parent_and_color(s, p, C_RBNODE_RED);
- if (c_rbnode_is_black(p))
- return p;
-
- c_rbnode_set_parent_and_color(p, c_rbnode_parent(p), C_RBNODE_BLACK);
- return NULL;
- }
-
- x = y->left;
- s->right = y->left;
- y->left = s;
- p->left = y;
- if (x)
- c_rbnode_set_parent_and_color(x, s, C_RBNODE_BLACK);
- x = s;
- s = y;
- }
-
- g = c_rbnode_parent(p);
- y = s->right;
- p->left = y;
- s->right = p;
- c_rbnode_set_parent_and_color(x, s, C_RBNODE_BLACK);
- if (y)
- c_rbnode_set_parent_and_color(y, p, c_rbnode_color(y));
- c_rbnode_set_parent_and_color(s, g, c_rbnode_color(p));
- c_rbnode_set_parent_and_color(p, s, C_RBNODE_BLACK);
- c_rbtree_swap_child(t, g, p, s);
- }
-
- return NULL;
-}
-
-static inline void c_rbtree_rebalance(CRBTree *t, CRBNode *p) {
- CRBNode *n = NULL;
-
- assert(t);
- assert(p);
-
- do {
- n = c_rbtree_rebalance_one(t, p, n);
- p = n ? c_rbnode_parent(n) : NULL;
- } while (p);
-}
-
-/**
- * c_rbtree_remove() - remove node from tree
- * @t: tree to operate one
- * @n: node to remove
- *
- * This removes the given node from its tree. Once unlinked, the tree is
- * rebalanced.
- * The caller *must* ensure that the given tree is actually the tree it is
- * linked on. Otherwise, behavior is undefined.
- *
- * This does *NOT* reset @n to being unlinked (for performance reason, this
- * function *never* modifies @n at all). If you need this, use
- * c_rbtree_remove_init().
- */
-void c_rbtree_remove(CRBTree *t, CRBNode *n) {
- CRBNode *p, *s, *gc, *x, *next = NULL;
- unsigned long c;
-
- assert(t);
- assert(n);
- assert(c_rbnode_is_linked(n));
-
- /*
- * There are three distinct cases during node removal of a tree:
- * * The node has no children, in which case it can simply be removed.
- * * The node has exactly one child, in which case the child displaces
- * its parent.
- * * The node has two children, in which case there is guaranteed to
- * be a successor to the node (successor being the node ordered
- * directly after it). This successor cannot have two children by
- * itself (two interior nodes can never be successive). Therefore,
- * we can simply swap the node with its successor (including color)
- * and have reduced this case to either of the first two.
- *
- * Whenever the node we removed was black, we have to rebalance the
- * tree. Note that this affects the actual node we _remove_, not @n (in
- * case we swap it).
- *
- * p: parent
- * s: successor
- * gc: grand-...-child
- * x: temporary
- * next: next node to rebalance on
- */
-
- if (!n->left) {
- /*
- * Case 1:
- * The node has no left child. If it neither has a right child,
- * it is a leaf-node and we can simply unlink it. If it also
- * was black, we have to rebalance, as always if we remove a
- * black node.
- * But if the node has a right child, the child *must* be red
- * (otherwise, the right path has more black nodes as the
- * non-existing left path), and the node to be removed must
- * hence be black. We simply replace the node with its child,
- * turning the red child black, and thus no rebalancing is
- * required.
- */
- p = c_rbnode_parent(n);
- c = c_rbnode_color(n);
- c_rbtree_swap_child(t, p, n, n->right);
- if (n->right)
- c_rbnode_set_parent_and_color(n->right, p, c);
- else
- next = (c == C_RBNODE_BLACK) ? p : NULL;
- } else if (!n->right) {
- /*
- * Case 1.1:
- * The node has exactly one child, and it is on the left. Treat
- * it as mirrored case of Case 1 (i.e., replace the node by its
- * child).
- */
- p = c_rbnode_parent(n);
- c = c_rbnode_color(n);
- c_rbtree_swap_child(t, p, n, n->left);
- c_rbnode_set_parent_and_color(n->left, p, c);
- } else {
- /*
- * Case 2:
- * We are dealing with a full interior node with a child not on
- * both sides. Find its successor and swap it. Then remove the
- * node similar to Case 1. For performance reasons we don't
- * perform the full swap, but skip links that are about to be
- * removed, anyway.
- */
- s = n->right;
- if (!s->left) {
- /* right child is next, no need to touch grandchild */
- p = s;
- gc = s->right;
- } else {
- /* find successor and swap partially */
- s = c_rbnode_leftmost(s);
- p = c_rbnode_parent(s);
-
- gc = s->right;
- p->left = s->right;
- s->right = n->right;
- c_rbnode_set_parent(n->right, s);
- }
-
- /* node is partially swapped, now remove as in Case 1 */
- s->left = n->left;
- c_rbnode_set_parent(n->left, s);
-
- x = c_rbnode_parent(n);
- c = c_rbnode_color(n);
- c_rbtree_swap_child(t, x, n, s);
- if (gc)
- c_rbnode_set_parent_and_color(gc, p, C_RBNODE_BLACK);
- else
- next = c_rbnode_is_black(s) ? p : NULL;
- c_rbnode_set_parent_and_color(s, x, c);
- }
-
- if (next)
- c_rbtree_rebalance(t, next);
-}
diff --git a/src/libbasic/c-rbtree.h b/src/libbasic/c-rbtree.h
deleted file mode 100644
index 20c5515ca1..0000000000
--- a/src/libbasic/c-rbtree.h
+++ /dev/null
@@ -1,297 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd. See COPYING for details.
-
- 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/>.
-***/
-
-/*
- * Standalone Red-Black-Tree Implementation in Standard ISO-C11
- *
- * This header provides an RB-Tree API, that is fully implemented in ISO-C11
- * and has no external dependencies. Furthermore, tree traversal, memory
- * allocations, and key comparisons a fully in control of the API user. The
- * implementation only provides the RB-Tree specific rebalancing and coloring.
- *
- * A tree is represented by the "CRBTree" structure. It contains a *singly*
- * field, which is a pointer to the root node. If NULL, the tree is empty. If
- * non-NULL, there is at least a single element in the tree.
- *
- * Each node of the tree is represented by the "CRBNode" structure. It has
- * three fields. The @left and @right members can be accessed by the API user
- * directly to traverse the tree. The third member is an implementation detail
- * and encodes the parent pointer and color of the node.
- * API users are required to embed the CRBNode object into their own objects
- * and then use offsetof() (i.e., container_of() and friends) to turn CRBNode
- * pointers into pointers to their own structure.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct CRBNode CRBNode;
-typedef struct CRBTree CRBTree;
-
-/**
- * struct CRBNode - Node of a Red-Black Tree
- * @__parent_and_color: internal state
- * @left: left child, or NULL
- * @right: right child, or NULL
- *
- * Each node in an RB-Tree must embed an CRBNode object. This object contains
- * pointers to its left and right child, which can be freely accessed by the
- * API user at any time. They are NULL, if the node does not have a left/right
- * child.
- *
- * The @__parent_and_color field must never be accessed directly. It encodes
- * the pointer to the parent node, and the color of the node. Use the accessor
- * functions instead.
- *
- * There is no reason to initialize a CRBNode object before linking it.
- * However, if you need a boolean state that tells you whether the node is
- * linked or not, you should initialize the node via c_rbnode_init() or
- * C_RBNODE_INIT.
- */
-struct CRBNode {
- CRBNode *__parent_and_color;
- CRBNode *left;
- CRBNode *right;
-};
-
-#define C_RBNODE_INIT(_var) { .__parent_and_color = &(_var) }
-
-CRBNode *c_rbnode_leftmost(CRBNode *n);
-CRBNode *c_rbnode_rightmost(CRBNode *n);
-CRBNode *c_rbnode_next(CRBNode *n);
-CRBNode *c_rbnode_prev(CRBNode *n);
-
-/**
- * struct CRBTree - Red-Black Tree
- * @root: pointer to the root node, or NULL
- *
- * Each Red-Black Tree is rooted in an CRBTree object. This object contains a
- * pointer to the root node of the tree. The API user is free to access the
- * @root member at any time, and use it to traverse the tree.
- *
- * To initialize an RB-Tree, set it to NULL / all zero.
- */
-struct CRBTree {
- CRBNode *root;
-};
-
-CRBNode *c_rbtree_first(CRBTree *t);
-CRBNode *c_rbtree_last(CRBTree *t);
-
-void c_rbtree_add(CRBTree *t, CRBNode *p, CRBNode **l, CRBNode *n);
-void c_rbtree_remove(CRBTree *t, CRBNode *n);
-
-/**
- * c_rbnode_init() - mark a node as unlinked
- * @n: node to operate on
- *
- * This marks the node @n as unlinked. The node will be set to a valid state
- * that can never happen if the node is linked in a tree. Furthermore, this
- * state is fully known to the implementation, and as such handled gracefully
- * in all cases.
- *
- * You are *NOT* required to call this on your node. c_rbtree_add() can handle
- * uninitialized nodes just fine. However, calling this allows to use
- * c_rbnode_is_linked() to check for the state of a node. Furthermore,
- * iterators and accessors can be called on initialized (yet unlinked) nodes.
- *
- * Use the C_RBNODE_INIT macro if you want to initialize static variables.
- */
-static inline void c_rbnode_init(CRBNode *n) {
- *n = (CRBNode)C_RBNODE_INIT(*n);
-}
-
-/**
- * c_rbnode_is_linked() - check whether a node is linked
- * @n: node to check, or NULL
- *
- * This checks whether the passed node is linked. If you pass NULL, or if the
- * node is not linked into a tree, this will return false. Otherwise, this
- * returns true.
- *
- * Note that you must have either linked the node or initialized it, before
- * calling this function. Never call this function on uninitialized nodes.
- * Furthermore, removing a node via c_rbtree_remove() does *NOT* mark the node
- * as unlinked. You have to call c_rbnode_init() yourself after removal, or use
- * the c_rbtree_remove_init() helper.
- *
- * Return: true if the node is linked, false if not.
- */
-static inline _Bool c_rbnode_is_linked(CRBNode *n) {
- return n && n->__parent_and_color != n;
-}
-
-/**
- * c_rbnode_parent() - return parent pointer
- * @n node to access
- *
- * This returns a pointer to the parent of the given node @n. If @n does not
- * have a parent, NULL is returned. If @n is not linked, @n itself is returned.
- *
- * You should not call this on unlinked or uninitialized nodes! If you do, you
- * better know how its semantics.
- *
- * Return: Pointer to parent.
- */
-static inline CRBNode *c_rbnode_parent(CRBNode *n) {
- return (CRBNode*)((unsigned long)n->__parent_and_color & ~1UL);
-}
-
-/**
- * c_rbtree_remove_init() - safely remove node from tree and reinitialize it
- * @t: tree to operate on
- * @n: node to remove, or NULL
- *
- * This is almost the same as c_rbtree_remove(), but extends it slightly, to be
- * more convenient to use in many cases:
- * - if @n is unlinked or NULL, this is a no-op
- * - @n is reinitialized after being removed
- */
-static inline void c_rbtree_remove_init(CRBTree *t, CRBNode *n) {
- if (c_rbnode_is_linked(n)) {
- c_rbtree_remove(t, n);
- c_rbnode_init(n);
- }
-}
-
-/**
- * CRBCompareFunc - compare a node to a key
- * @t: tree where the node is linked to
- * @k: key to compare
- * @n: node to compare
- *
- * If you use the tree-traversal helpers (which are optional), you need to
- * provide this callback so they can compare nodes in a tree to the key you
- * look for.
- *
- * The tree @t is provided as optional context to this callback. The key you
- * look for is provided as @k, the current node that should be compared to is
- * provided as @n. This function should work like strcmp(), that is, return -1
- * if @key orders before @n, 0 if both compare equal, and 1 if it orders after
- * @n.
- */
-typedef int (*CRBCompareFunc) (CRBTree *t, void *k, CRBNode *n);
-
-/**
- * c_rbtree_find_node() - find node
- * @t: tree to search through
- * @f: comparison function
- * @k: key to search for
- *
- * This searches through @t for a node that compares equal to @k. The function
- * @f must be provided by the caller, which is used to compare nodes to @k. See
- * the documentation of CRBCompareFunc for details.
- *
- * If there are multiple entries that compare equal to @k, this will return a
- * pseudo-randomly picked node. If you need stable lookup functions for trees
- * where duplicate entries are allowed, you better code your own lookup.
- *
- * Return: Pointer to matching node, or NULL.
- */
-static inline CRBNode *c_rbtree_find_node(CRBTree *t, CRBCompareFunc f, const void *k) {
- CRBNode *i;
-
- assert(t);
- assert(f);
-
- i = t->root;
- while (i) {
- int v = f(t, (void *)k, i);
- if (v < 0)
- i = i->left;
- else if (v > 0)
- i = i->right;
- else
- return i;
- }
-
- return NULL;
-}
-
-/**
- * c_rbtree_find_entry() - find entry
- * @_t: tree to search through
- * @_f: comparison function
- * @_k: key to search for
- * @_t: type of the structure that embeds the nodes
- * @_o: name of the node-member in type @_t
- *
- * This is very similar to c_rbtree_find_node(), but instead of returning a
- * pointer to the CRBNode, it returns a pointer to the surrounding object. This
- * object must embed the CRBNode object. The type of the surrounding object
- * must be given as @_t, and the name of the embedded CRBNode member as @_o.
- *
- * See c_rbtree_find_node() for more details.
- *
- * Return: Pointer to found entry, NULL if not found.
- */
-#define c_rbtree_find_entry(_m, _f, _k, _t, _o) \
- ((_t *)(((char *)c_rbtree_find_node((_m), (_f), (_k)) ?: \
- (char *)NULL + offsetof(_t, _o)) - offsetof(_t, _o)))
-
-/**
- * c_rbtree_find_slot() - find slot to insert new node
- * @t: tree to search through
- * @f: comparison function
- * @k: key to search for
- * @p: output storage for parent pointer
- *
- * This searches through @t just like c_rbtree_find_node() does. However,
- * instead of returning a pointer to a node that compares equal to @k, this
- * searches for a slot to insert a node with key @k. A pointer to the slot is
- * returned, and a pointer to the parent of the slot is stored in @p. Both
- * can be passed directly to c_rbtree_add(), together with your node to insert.
- *
- * If there already is a node in the tree, that compares equal to @k, this will
- * return NULL and store the conflicting node in @p. In all other cases,
- * this will return a pointer (non-NULL) to the empty slot to insert the node
- * at. @p will point to the parent node of that slot.
- *
- * If you want trees that allow duplicate nodes, you better code your own
- * insertion function.
- *
- * Return: Pointer to slot to insert node, or NULL on conflicts.
- */
-static inline CRBNode **c_rbtree_find_slot(CRBTree *t, CRBCompareFunc f, const void *k, CRBNode **p) {
- CRBNode **i;
-
- assert(t);
- assert(f);
- assert(p);
-
- i = &t->root;
- *p = NULL;
- while (*i) {
- int v = f(t, (void *)k, *i);
- *p = *i;
- if (v < 0)
- i = &(*i)->left;
- else if (v > 0)
- i = &(*i)->right;
- else
- return NULL;
- }
-
- return i;
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/libbasic/calendarspec.c b/src/libbasic/calendarspec.c
index 775879076d..6e0bab9b94 100644
--- a/src/libbasic/calendarspec.c
+++ b/src/libbasic/calendarspec.c
@@ -114,7 +114,7 @@ static void sort_chain(CalendarComponent **c) {
static void fix_year(CalendarComponent *c) {
/* Turns 12 → 2012, 89 → 1989 */
- while(c) {
+ while (c) {
CalendarComponent *n = c->next;
if (c->value >= 0 && c->value < 70)
@@ -978,7 +978,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
for (;;) {
/* Normalize the current date */
- mktime_or_timegm(&c, spec->utc);
+ (void) mktime_or_timegm(&c, spec->utc);
c.tm_isdst = -1;
c.tm_year += 1900;
@@ -990,8 +990,10 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
}
- if (r < 0 || tm_out_of_bounds(&c, spec->utc))
+ if (r < 0)
return r;
+ if (tm_out_of_bounds(&c, spec->utc))
+ return -ENOENT;
c.tm_mon += 1;
r = find_matching_component(spec->month, &c.tm_mon);
@@ -1002,7 +1004,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
}
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_year ++;
+ c.tm_year++;
c.tm_mon = 0;
c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
@@ -1013,7 +1015,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
if (r > 0)
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_mon ++;
+ c.tm_mon++;
c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
continue;
@@ -1027,18 +1029,18 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
r = find_matching_component(spec->hour, &c.tm_hour);
if (r > 0)
- c.tm_min = c.tm_sec = 0;
+ c.tm_min = c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_mday ++;
+ c.tm_mday++;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
continue;
}
r = find_matching_component(spec->minute, &c.tm_min);
if (r > 0)
- c.tm_sec = 0;
+ c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_hour ++;
+ c.tm_hour++;
c.tm_min = c.tm_sec = tm_usec = 0;
continue;
}
@@ -1049,7 +1051,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_sec /= USEC_PER_SEC;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_min ++;
+ c.tm_min++;
c.tm_sec = tm_usec = 0;
continue;
}
diff --git a/src/libbasic/cgroup-util.c b/src/libbasic/cgroup-util.c
index 6ef00d51df..7cdc97ee3c 100644
--- a/src/libbasic/cgroup-util.c
+++ b/src/libbasic/cgroup-util.c
@@ -101,6 +101,39 @@ int cg_read_pid(FILE *f, pid_t *_pid) {
return 1;
}
+int cg_read_event(const char *controller, const char *path, const char *event,
+ char **val)
+{
+ _cleanup_free_ char *events = NULL, *content = NULL;
+ char *p, *line;
+ int r;
+
+ r = cg_get_path(controller, path, "cgroup.events", &events);
+ if (r < 0)
+ return r;
+
+ r = read_full_file(events, &content, NULL);
+ if (r < 0)
+ return r;
+
+ p = content;
+ while ((line = strsep(&p, "\n"))) {
+ char *key;
+
+ key = strsep(&line, " ");
+ if (!key || !line)
+ return -EINVAL;
+
+ if (strcmp(key, event))
+ continue;
+
+ *val = strdup(line);
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
_cleanup_free_ char *fs = NULL;
int r;
@@ -1007,18 +1040,12 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
return unified;
if (unified > 0) {
- _cleanup_free_ char *populated = NULL, *t = NULL;
+ _cleanup_free_ char *t = NULL;
/* On the unified hierarchy we can check empty state
- * via the "cgroup.populated" attribute. */
+ * via the "populated" attribute of "cgroup.events". */
- r = cg_get_path(controller, path, "cgroup.populated", &populated);
- if (r < 0)
- return r;
-
- r = read_one_line_file(populated, &t);
- if (r == -ENOENT)
- return 1;
+ r = cg_read_event(controller, path, "populated", &t);
if (r < 0)
return r;
@@ -1248,7 +1275,7 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
return 0;
}
-int cg_path_decode_unit(const char *cgroup, char **unit){
+int cg_path_decode_unit(const char *cgroup, char **unit) {
char *c, *s;
size_t n;
@@ -2033,10 +2060,10 @@ int cg_mask_supported(CGroupMask *ret) {
mask |= CGROUP_CONTROLLER_TO_MASK(v);
}
- /* Currently, we only support the memory and pids
+ /* Currently, we only support the memory, io and pids
* controller in the unified hierarchy, mask
* everything else off. */
- mask &= CGROUP_MASK_MEMORY | CGROUP_MASK_PIDS;
+ mask &= CGROUP_MASK_MEMORY | CGROUP_MASK_IO | CGROUP_MASK_PIDS;
} else {
CGroupController c;
@@ -2129,7 +2156,7 @@ int cg_unified(void) {
if (statfs("/sys/fs/cgroup/", &fs) < 0)
return -errno;
- if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
+ if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
unified_cache = true;
else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
unified_cache = false;
@@ -2222,6 +2249,42 @@ bool cg_is_legacy_wanted(void) {
return !cg_is_unified_wanted();
}
+int cg_weight_parse(const char *s, uint64_t *ret) {
+ uint64_t u;
+ int r;
+
+ if (isempty(s)) {
+ *ret = CGROUP_WEIGHT_INVALID;
+ return 0;
+ }
+
+ r = safe_atou64(s, &u);
+ if (r < 0)
+ return r;
+
+ if (u < CGROUP_WEIGHT_MIN || u > CGROUP_WEIGHT_MAX)
+ return -ERANGE;
+
+ *ret = u;
+ return 0;
+}
+
+const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX] = {
+ [CGROUP_IO_RBPS_MAX] = CGROUP_LIMIT_MAX,
+ [CGROUP_IO_WBPS_MAX] = CGROUP_LIMIT_MAX,
+ [CGROUP_IO_RIOPS_MAX] = CGROUP_LIMIT_MAX,
+ [CGROUP_IO_WIOPS_MAX] = CGROUP_LIMIT_MAX,
+};
+
+static const char* const cgroup_io_limit_type_table[_CGROUP_IO_LIMIT_TYPE_MAX] = {
+ [CGROUP_IO_RBPS_MAX] = "IOReadBandwidthMax",
+ [CGROUP_IO_WBPS_MAX] = "IOWriteBandwidthMax",
+ [CGROUP_IO_RIOPS_MAX] = "IOReadIOPSMax",
+ [CGROUP_IO_WIOPS_MAX] = "IOWriteIOPSMax",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(cgroup_io_limit_type, CGroupIOLimitType);
+
int cg_cpu_shares_parse(const char *s, uint64_t *ret) {
uint64_t u;
int r;
@@ -2265,6 +2328,7 @@ int cg_blkio_weight_parse(const char *s, uint64_t *ret) {
static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
[CGROUP_CONTROLLER_CPU] = "cpu",
[CGROUP_CONTROLLER_CPUACCT] = "cpuacct",
+ [CGROUP_CONTROLLER_IO] = "io",
[CGROUP_CONTROLLER_BLKIO] = "blkio",
[CGROUP_CONTROLLER_MEMORY] = "memory",
[CGROUP_CONTROLLER_DEVICES] = "devices",
diff --git a/src/libbasic/cgroup-util.h b/src/libbasic/cgroup-util.h
index ad1edd9cdb..4bb5291296 100644
--- a/src/libbasic/cgroup-util.h
+++ b/src/libbasic/cgroup-util.h
@@ -34,6 +34,7 @@
typedef enum CGroupController {
CGROUP_CONTROLLER_CPU,
CGROUP_CONTROLLER_CPUACCT,
+ CGROUP_CONTROLLER_IO,
CGROUP_CONTROLLER_BLKIO,
CGROUP_CONTROLLER_MEMORY,
CGROUP_CONTROLLER_DEVICES,
@@ -48,6 +49,7 @@ typedef enum CGroupController {
typedef enum CGroupMask {
CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU),
CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT),
+ CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO),
CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO),
CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY),
CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES),
@@ -55,6 +57,37 @@ typedef enum CGroupMask {
_CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1
} CGroupMask;
+/* Special values for all weight knobs on unified hierarchy */
+#define CGROUP_WEIGHT_INVALID ((uint64_t) -1)
+#define CGROUP_WEIGHT_MIN UINT64_C(1)
+#define CGROUP_WEIGHT_MAX UINT64_C(10000)
+#define CGROUP_WEIGHT_DEFAULT UINT64_C(100)
+
+#define CGROUP_LIMIT_MIN UINT64_C(0)
+#define CGROUP_LIMIT_MAX ((uint64_t) -1)
+
+static inline bool CGROUP_WEIGHT_IS_OK(uint64_t x) {
+ return
+ x == CGROUP_WEIGHT_INVALID ||
+ (x >= CGROUP_WEIGHT_MIN && x <= CGROUP_WEIGHT_MAX);
+}
+
+/* IO limits on unified hierarchy */
+typedef enum CGroupIOLimitType {
+ CGROUP_IO_RBPS_MAX,
+ CGROUP_IO_WBPS_MAX,
+ CGROUP_IO_RIOPS_MAX,
+ CGROUP_IO_WIOPS_MAX,
+
+ _CGROUP_IO_LIMIT_TYPE_MAX,
+ _CGROUP_IO_LIMIT_TYPE_INVALID = -1
+} CGroupIOLimitType;
+
+extern const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX];
+
+const char* cgroup_io_limit_type_to_string(CGroupIOLimitType t) _const_;
+CGroupIOLimitType cgroup_io_limit_type_from_string(const char *s) _pure_;
+
/* Special values for the cpu.shares attribute */
#define CGROUP_CPU_SHARES_INVALID ((uint64_t) -1)
#define CGROUP_CPU_SHARES_MIN UINT64_C(2)
@@ -96,6 +129,8 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
int cg_enumerate_processes(const char *controller, const char *path, FILE **_f);
int cg_read_pid(FILE *f, pid_t *_pid);
+int cg_read_event(const char *controller, const char *path, const char *event,
+ char **val);
int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d);
int cg_read_subgroup(DIR *d, char **fn);
@@ -188,5 +223,6 @@ bool cg_is_legacy_wanted(void);
const char* cgroup_controller_to_string(CGroupController c) _const_;
CGroupController cgroup_controller_from_string(const char *s) _pure_;
+int cg_weight_parse(const char *s, uint64_t *ret);
int cg_cpu_shares_parse(const char *s, uint64_t *ret);
int cg_blkio_weight_parse(const char *s, uint64_t *ret);
diff --git a/src/libbasic/clock-util.c b/src/libbasic/clock-util.c
index 507e757ff0..7fe8d35ea5 100644
--- a/src/libbasic/clock-util.c
+++ b/src/libbasic/clock-util.c
@@ -69,9 +69,12 @@ int clock_set_hwclock(const struct tm *tm) {
return 0;
}
-int clock_is_localtime(void) {
+int clock_is_localtime(const char* adjtime_path) {
_cleanup_fclose_ FILE *f;
+ if (adjtime_path == NULL)
+ adjtime_path = "/etc/adjtime";
+
/*
* The third line of adjtime is "UTC" or "LOCAL" or nothing.
* # /etc/adjtime
@@ -79,7 +82,7 @@ int clock_is_localtime(void) {
* 0
* UTC
*/
- f = fopen("/etc/adjtime", "re");
+ f = fopen(adjtime_path, "re");
if (f) {
char line[LINE_MAX];
bool b;
@@ -88,7 +91,8 @@ int clock_is_localtime(void) {
fgets(line, sizeof(line), f) &&
fgets(line, sizeof(line), f);
if (!b)
- return -EIO;
+ /* less than three lines -> default to UTC */
+ return 0;
truncate_nl(line);
return streq(line, "LOCAL");
@@ -96,6 +100,7 @@ int clock_is_localtime(void) {
} else if (errno != ENOENT)
return -errno;
+ /* adjtime not present -> default to UTC */
return 0;
}
diff --git a/src/libbasic/clock-util.h b/src/libbasic/clock-util.h
index f471f2abcf..8830cd2f38 100644
--- a/src/libbasic/clock-util.h
+++ b/src/libbasic/clock-util.h
@@ -21,7 +21,7 @@
#include <time.h>
-int clock_is_localtime(void);
+int clock_is_localtime(const char* adjtime_path);
int clock_set_timezone(int *min);
int clock_reset_timewarp(void);
int clock_get_hwclock(struct tm *tm);
diff --git a/src/libbasic/copy.c b/src/libbasic/copy.c
index 519b412941..c3586728d0 100644
--- a/src/libbasic/copy.c
+++ b/src/libbasic/copy.c
@@ -40,17 +40,38 @@
#include "fs-util.h"
#include "io-util.h"
#include "macro.h"
+#include "missing.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
#include "umask-util.h"
#include "xattr-util.h"
-#define COPY_BUFFER_SIZE (16*1024)
+#define COPY_BUFFER_SIZE (16*1024u)
+
+static ssize_t try_copy_file_range(int fd_in, loff_t *off_in,
+ int fd_out, loff_t *off_out,
+ size_t len,
+ unsigned int flags) {
+ static int have = -1;
+ ssize_t r;
+
+ if (have == false)
+ return -ENOSYS;
+
+ r = copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
+ if (_unlikely_(have < 0))
+ have = r >= 0 || errno != ENOSYS;
+ if (r >= 0)
+ return r;
+ else
+ return -errno;
+}
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
- bool try_sendfile = true, try_splice = true;
+ bool try_cfr = true, try_sendfile = true, try_splice = true;
int r;
+ size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
assert(fdf >= 0);
assert(fdt >= 0);
@@ -67,56 +88,69 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
}
for (;;) {
- size_t m = COPY_BUFFER_SIZE;
ssize_t n;
if (max_bytes != (uint64_t) -1) {
-
if (max_bytes <= 0)
return 1; /* return > 0 if we hit the max_bytes limit */
- if ((uint64_t) m > max_bytes)
- m = (size_t) max_bytes;
+ if (m > max_bytes)
+ m = max_bytes;
+ }
+
+ /* First try copy_file_range(), unless we already tried */
+ if (try_cfr) {
+ n = try_copy_file_range(fdf, NULL, fdt, NULL, m, 0u);
+ if (n < 0) {
+ if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV, -EBADF))
+ return n;
+
+ try_cfr = false;
+ /* use fallback below */
+ } else if (n == 0) /* EOF */
+ break;
+ else
+ /* Success! */
+ goto next;
}
/* First try sendfile(), unless we already tried */
if (try_sendfile) {
-
n = sendfile(fdt, fdf, NULL, m);
if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
+ if (!IN_SET(errno, EINVAL, ENOSYS))
return -errno;
try_sendfile = false;
/* use fallback below */
} else if (n == 0) /* EOF */
break;
- else if (n > 0)
+ else
/* Success! */
goto next;
}
- /* The try splice, unless we already tried */
+ /* Then try splice, unless we already tried */
if (try_splice) {
n = splice(fdf, NULL, fdt, NULL, m, 0);
if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
+ if (!IN_SET(errno, EINVAL, ENOSYS))
return -errno;
try_splice = false;
/* use fallback below */
} else if (n == 0) /* EOF */
break;
- else if (n > 0)
+ else
/* Success! */
goto next;
}
/* As a fallback just copy bits by hand */
{
- uint8_t buf[m];
+ uint8_t buf[MIN(m, COPY_BUFFER_SIZE)];
- n = read(fdf, buf, m);
+ n = read(fdf, buf, sizeof buf);
if (n < 0)
return -errno;
if (n == 0) /* EOF */
@@ -132,6 +166,11 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
assert(max_bytes >= (uint64_t) n);
max_bytes -= n;
}
+ /* sendfile accepts at most SSIZE_MAX-offset bytes to copy,
+ * so reduce our maximum by the amount we already copied,
+ * but don't go below our copy buffer size, unless we are
+ * close the the limit of bytes we are allowed to copy. */
+ m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
}
return 0; /* return 0 if we hit EOF earlier than the size limit */
@@ -266,6 +305,8 @@ static int fd_copy_directory(
fdf = openat(df, from, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
else
fdf = fcntl(df, F_DUPFD_CLOEXEC, 3);
+ if (fdf < 0)
+ return -errno;
d = fdopendir(fdf);
if (!d)
@@ -286,22 +327,6 @@ static int fd_copy_directory(
r = 0;
- if (created) {
- struct timespec ut[2] = {
- st->st_atim,
- st->st_mtim
- };
-
- if (fchown(fdt, st->st_uid, st->st_gid) < 0)
- r = -errno;
-
- if (fchmod(fdt, st->st_mode & 07777) < 0)
- r = -errno;
-
- (void) futimens(fdt, ut);
- (void) copy_xattr(dirfd(d), fdt);
- }
-
FOREACH_DIRENT_ALL(de, d, return -errno) {
struct stat buf;
int q;
@@ -325,7 +350,7 @@ static int fd_copy_directory(
q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name);
else if (S_ISFIFO(buf.st_mode))
q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name);
- else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode))
+ else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) || S_ISSOCK(buf.st_mode))
q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name);
else
q = -EOPNOTSUPP;
@@ -337,6 +362,22 @@ static int fd_copy_directory(
r = q;
}
+ if (created) {
+ struct timespec ut[2] = {
+ st->st_atim,
+ st->st_mtim
+ };
+
+ if (fchown(fdt, st->st_uid, st->st_gid) < 0)
+ r = -errno;
+
+ if (fchmod(fdt, st->st_mode & 07777) < 0)
+ r = -errno;
+
+ (void) copy_xattr(dirfd(d), fdt);
+ (void) futimens(fdt, ut);
+ }
+
return r;
}
@@ -357,7 +398,7 @@ int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge)
return fd_copy_symlink(fdf, from, &st, fdt, to);
else if (S_ISFIFO(st.st_mode))
return fd_copy_fifo(fdf, from, &st, fdt, to);
- else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
+ else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode))
return fd_copy_node(fdf, from, &st, fdt, to);
else
return -EOPNOTSUPP;
@@ -368,7 +409,6 @@ int copy_tree(const char *from, const char *to, bool merge) {
}
int copy_directory_fd(int dirfd, const char *to, bool merge) {
-
struct stat st;
assert(dirfd >= 0);
@@ -383,6 +423,21 @@ int copy_directory_fd(int dirfd, const char *to, bool merge) {
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
}
+int copy_directory(const char *from, const char *to, bool merge) {
+ struct stat st;
+
+ assert(from);
+ assert(to);
+
+ if (lstat(from, &st) < 0)
+ return -errno;
+
+ if (!S_ISDIR(st.st_mode))
+ return -ENOTDIR;
+
+ return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, merge);
+}
+
int copy_file_fd(const char *from, int fdt, bool try_reflink) {
_cleanup_close_ int fdf = -1;
int r;
diff --git a/src/libbasic/copy.h b/src/libbasic/copy.h
index 3e5eb52506..b5d08ebafe 100644
--- a/src/libbasic/copy.h
+++ b/src/libbasic/copy.h
@@ -30,6 +30,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
int copy_tree(const char *from, const char *to, bool merge);
int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
int copy_directory_fd(int dirfd, const char *to, bool merge);
+int copy_directory(const char *from, const char *to, bool merge);
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
int copy_times(int fdf, int fdt);
int copy_xattr(int fdf, int fdt);
diff --git a/src/libbasic/def.h b/src/libbasic/def.h
index 963343eb7d..1a7a0f4928 100644
--- a/src/libbasic/def.h
+++ b/src/libbasic/def.h
@@ -41,8 +41,6 @@
#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
#define SIGNALS_IGNORE SIGPIPE
-#define REBOOT_PARAM_FILE "/run/systemd/reboot-param"
-
#ifdef HAVE_SPLIT_USR
#define KBD_KEYMAP_DIRS \
"/usr/share/keymaps/\0" \
diff --git a/src/libbasic/dirent-util.c b/src/libbasic/dirent-util.c
index 5fb535cb13..59067121b7 100644
--- a/src/libbasic/dirent-util.c
+++ b/src/libbasic/dirent-util.c
@@ -52,12 +52,10 @@ int dirent_ensure_type(DIR *d, struct dirent *de) {
bool dirent_is_file(const struct dirent *de) {
assert(de);
- if (hidden_file(de->d_name))
+ if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
return false;
- if (de->d_type != DT_REG &&
- de->d_type != DT_LNK &&
- de->d_type != DT_UNKNOWN)
+ if (hidden_or_backup_file(de->d_name))
return false;
return true;
@@ -66,12 +64,10 @@ bool dirent_is_file(const struct dirent *de) {
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
assert(de);
- if (de->d_type != DT_REG &&
- de->d_type != DT_LNK &&
- de->d_type != DT_UNKNOWN)
+ if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
return false;
- if (hidden_file_allow_backup(de->d_name))
+ if (de->d_name[0] == '.')
return false;
return endswith(de->d_name, suffix);
diff --git a/src/libbasic/dirent-util.h b/src/libbasic/dirent-util.h
index 6bf099b46c..b91d04908f 100644
--- a/src/libbasic/dirent-util.h
+++ b/src/libbasic/dirent-util.h
@@ -38,7 +38,7 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pu
on_error; \
} \
break; \
- } else if (hidden_file((de)->d_name)) \
+ } else if (hidden_or_backup_file((de)->d_name)) \
continue; \
else
diff --git a/src/libbasic/escape.c b/src/libbasic/escape.c
index 2e483880c8..01daf11ce7 100644
--- a/src/libbasic/escape.c
+++ b/src/libbasic/escape.c
@@ -413,6 +413,34 @@ char *xescape(const char *s, const char *bad) {
return r;
}
+char *octescape(const char *s, size_t len) {
+ char *r, *t;
+ const char *f;
+
+ /* Escapes all chars in bad, in addition to \ and " chars,
+ * in \nnn style escaping. */
+
+ r = new(char, len * 4 + 1);
+ if (!r)
+ return NULL;
+
+ for (f = s, t = r; f < s + len; f++) {
+
+ if (*f < ' ' || *f >= 127 || *f == '\\' || *f == '"') {
+ *(t++) = '\\';
+ *(t++) = '0' + (*f >> 6);
+ *(t++) = '0' + ((*f >> 3) & 8);
+ *(t++) = '0' + (*f & 8);
+ } else
+ *(t++) = *f;
+ }
+
+ *t = 0;
+
+ return r;
+
+}
+
static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
assert(bad);
diff --git a/src/libbasic/escape.h b/src/libbasic/escape.h
index 1b28bd10af..deaa4def28 100644
--- a/src/libbasic/escape.h
+++ b/src/libbasic/escape.h
@@ -48,6 +48,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
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);
diff --git a/src/libbasic/ether-addr-util.c b/src/libbasic/ether-addr-util.c
index ded6d31f4b..5697e8d132 100644
--- a/src/libbasic/ether-addr-util.c
+++ b/src/libbasic/ether-addr-util.c
@@ -23,6 +23,7 @@
#include "ether-addr-util.h"
#include "macro.h"
+#include "string-util.h"
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
assert(addr);
@@ -42,3 +43,83 @@ char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR
return buffer;
}
+
+bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
+ assert(a);
+ assert(b);
+
+ return a->ether_addr_octet[0] == b->ether_addr_octet[0] &&
+ a->ether_addr_octet[1] == b->ether_addr_octet[1] &&
+ a->ether_addr_octet[2] == b->ether_addr_octet[2] &&
+ a->ether_addr_octet[3] == b->ether_addr_octet[3] &&
+ a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
+ a->ether_addr_octet[5] == b->ether_addr_octet[5];
+}
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset) {
+ size_t pos = 0, n, field;
+ char sep = '\0';
+ const char *hex = HEXDIGITS, *hexoff;
+ size_t x;
+ bool touched;
+
+#define parse_fields(v) \
+ for (field = 0; field < ELEMENTSOF(v); field++) { \
+ touched = false; \
+ for (n = 0; n < (2 * sizeof(v[0])); n++) { \
+ if (s[pos] == '\0') \
+ break; \
+ hexoff = strchr(hex, s[pos]); \
+ if (hexoff == NULL) \
+ break; \
+ assert(hexoff >= hex); \
+ x = hexoff - hex; \
+ if (x >= 16) \
+ x -= 6; /* A-F */ \
+ assert(x < 16); \
+ touched = true; \
+ v[field] <<= 4; \
+ v[field] += x; \
+ pos++; \
+ } \
+ if (!touched) \
+ return -EINVAL; \
+ if (field < (ELEMENTSOF(v)-1)) { \
+ if (s[pos] != sep) \
+ return -EINVAL; \
+ else \
+ pos++; \
+ } \
+ }
+
+ assert(s);
+ assert(ret);
+
+ sep = s[strspn(s, hex)];
+ if (sep == '\n')
+ return -EINVAL;
+ if (strchr(":.-", sep) == NULL)
+ return -EINVAL;
+
+ if (sep == '.') {
+ uint16_t shorts[3] = { 0 };
+
+ parse_fields(shorts);
+
+ for (n = 0; n < ELEMENTSOF(shorts); n++) {
+ ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
+ ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
+ }
+ } else {
+ struct ether_addr out = { .ether_addr_octet = { 0 } };
+
+ parse_fields(out.ether_addr_octet);
+
+ for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
+ ret->ether_addr_octet[n] = out.ether_addr_octet[n];
+ }
+
+ if (offset)
+ *offset = pos;
+ return 0;
+}
diff --git a/src/libbasic/ether-addr-util.h b/src/libbasic/ether-addr-util.h
index 4487149efd..74e125a95f 100644
--- a/src/libbasic/ether-addr-util.h
+++ b/src/libbasic/ether-addr-util.h
@@ -20,10 +20,20 @@
***/
#include <net/ethernet.h>
+#include <stdbool.h>
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
#define ETHER_ADDR_TO_STRING_MAX (3*6)
-
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
+
+bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
+
+#define ETHER_ADDR_NULL ((const struct ether_addr){})
+
+static inline bool ether_addr_is_null(const struct ether_addr *addr) {
+ return ether_addr_equal(addr, &ETHER_ADDR_NULL);
+}
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset);
diff --git a/src/libbasic/exit-status.c b/src/libbasic/exit-status.c
index 5e0bc415c8..92fa5ace61 100644
--- a/src/libbasic/exit-status.c
+++ b/src/libbasic/exit-status.c
@@ -147,9 +147,6 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
case EXIT_MAKE_STARTER:
return "MAKE_STARTER";
- case EXIT_BUS_ENDPOINT:
- return "BUS_ENDPOINT";
-
case EXIT_SMACK_PROCESS_LABEL:
return "SMACK_PROCESS_LABEL";
}
diff --git a/src/libbasic/exit-status.h b/src/libbasic/exit-status.h
index 79525d30ee..1208c8feed 100644
--- a/src/libbasic/exit-status.h
+++ b/src/libbasic/exit-status.h
@@ -77,7 +77,6 @@ typedef enum ExitStatus {
EXIT_RUNTIME_DIRECTORY,
EXIT_MAKE_STARTER,
EXIT_CHOWN,
- EXIT_BUS_ENDPOINT,
EXIT_SMACK_PROCESS_LABEL,
} ExitStatus;
diff --git a/src/libbasic/extract-word.c b/src/libbasic/extract-word.c
index ee35d2a0ec..d6c1228463 100644
--- a/src/libbasic/extract-word.c
+++ b/src/libbasic/extract-word.c
@@ -63,12 +63,12 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
if (!GREEDY_REALLOC(s, allocated, sz+1))
return -ENOMEM;
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0)
goto finish_force_terminate;
else if (strchr(separators, c)) {
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
- (*p) ++;
+ (*p)++;
goto finish_force_next;
}
} else {
@@ -81,7 +81,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
}
}
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (backslash) {
if (!GREEDY_REALLOC(s, allocated, sz+7))
return -ENOMEM;
@@ -129,7 +129,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
backslash = false;
} else if (quote) { /* inside either single or double quotes */
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0) {
if (flags & EXTRACT_RELAX)
goto finish_force_terminate;
@@ -149,7 +149,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
}
} else {
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0)
goto finish_force_terminate;
else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
@@ -160,11 +160,11 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
break;
} else if (strchr(separators, c)) {
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
- (*p) ++;
+ (*p)++;
goto finish_force_next;
}
/* Skip additional coalesced separators. */
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0)
goto finish_force_terminate;
if (!strchr(separators, c))
diff --git a/src/libbasic/fd-util.c b/src/libbasic/fd-util.c
index ec9560cd07..8b466cff15 100644
--- a/src/libbasic/fd-util.c
+++ b/src/libbasic/fd-util.c
@@ -25,11 +25,13 @@
#include <unistd.h>
#include "fd-util.h"
+#include "fs-util.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
#include "socket-util.h"
+#include "stdio-util.h"
#include "util.h"
int close_nointr(int fd) {
@@ -229,7 +231,7 @@ int close_all_fds(const int except[], unsigned n_except) {
while ((de = readdir(d))) {
int fd = -1;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
if (safe_atoi(de->d_name, &fd) < 0)
@@ -356,3 +358,17 @@ bool fdname_is_valid(const char *s) {
return p - s < 256;
}
+
+int fd_get_path(int fd, char **ret) {
+ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+ int r;
+
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+
+ r = readlink_malloc(procfs_path, ret);
+
+ if (r == -ENOENT) /* If the file doesn't exist the fd is invalid */
+ return -EBADF;
+
+ return r;
+}
diff --git a/src/libbasic/fd-util.h b/src/libbasic/fd-util.h
index 44528c6e35..b86e41698a 100644
--- a/src/libbasic/fd-util.h
+++ b/src/libbasic/fd-util.h
@@ -72,6 +72,8 @@ void cmsg_close_all(struct msghdr *mh);
bool fdname_is_valid(const char *s);
+int fd_get_path(int fd, char **ret);
+
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
diff --git a/src/libbasic/fdset.c b/src/libbasic/fdset.c
index da1162991f..b52bf1ad05 100644
--- a/src/libbasic/fdset.c
+++ b/src/libbasic/fdset.c
@@ -94,19 +94,6 @@ int fdset_put(FDSet *s, int fd) {
return set_put(MAKE_SET(s), FD_TO_PTR(fd));
}
-int fdset_consume(FDSet *s, int fd) {
- int r;
-
- assert(s);
- assert(fd >= 0);
-
- r = fdset_put(s, fd);
- if (r <= 0)
- safe_close(fd);
-
- return r;
-}
-
int fdset_put_dup(FDSet *s, int fd) {
int copy, r;
@@ -164,7 +151,7 @@ int fdset_new_fill(FDSet **_s) {
while ((de = readdir(d))) {
int fd = -1;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
r = safe_atoi(de->d_name, &fd);
diff --git a/src/libbasic/fdset.h b/src/libbasic/fdset.h
index 12d0cef761..16efe5bdf2 100644
--- a/src/libbasic/fdset.h
+++ b/src/libbasic/fdset.h
@@ -32,7 +32,6 @@ FDSet* fdset_free(FDSet *s);
int fdset_put(FDSet *s, int fd);
int fdset_put_dup(FDSet *s, int fd);
-int fdset_consume(FDSet *s, int fd);
bool fdset_contains(FDSet *s, int fd);
int fdset_remove(FDSet *s, int fd);
diff --git a/src/libbasic/fileio.c b/src/libbasic/fileio.c
index e43ca6d29e..29f5374222 100644
--- a/src/libbasic/fileio.c
+++ b/src/libbasic/fileio.c
@@ -352,7 +352,7 @@ static int parse_env_file_internal(
case KEY:
if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
n_key = 0;
} else if (c == '=') {
state = PRE_VALUE;
@@ -376,7 +376,7 @@ static int parse_env_file_internal(
case PRE_VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
key[n_key] = 0;
if (value)
@@ -416,7 +416,7 @@ static int parse_env_file_internal(
case VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
key[n_key] = 0;
@@ -535,7 +535,7 @@ static int parse_env_file_internal(
state = COMMENT_ESCAPE;
else if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
}
break;
@@ -588,7 +588,7 @@ static int parse_env_file_push(
va_list aq, *ap = userdata;
if (!utf8_is_valid(key)) {
- _cleanup_free_ char *p;
+ _cleanup_free_ char *p = NULL;
p = utf8_escape_invalid(key);
log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p);
@@ -596,7 +596,7 @@ static int parse_env_file_push(
}
if (value && !utf8_is_valid(value)) {
- _cleanup_free_ char *p;
+ _cleanup_free_ char *p = NULL;
p = utf8_escape_invalid(value);
log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p);
@@ -908,7 +908,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin
/* Back off one char if there's nothing but whitespace
and zeros */
if (!*t || isspace(*t))
- t --;
+ t--;
}
len = strcspn(t, terminator);
@@ -1069,7 +1069,7 @@ int fflush_and_check(FILE *f) {
/* This is much like like mkostemp() but is subject to umask(). */
int mkostemp_safe(char *pattern, int flags) {
- _cleanup_umask_ mode_t u;
+ _cleanup_umask_ mode_t u = 0;
int fd;
assert(pattern);
@@ -1083,30 +1083,6 @@ int mkostemp_safe(char *pattern, int flags) {
return fd;
}
-int open_tmpfile(const char *path, int flags) {
- char *p;
- int fd;
-
- assert(path);
-
-#ifdef O_TMPFILE
- /* Try O_TMPFILE first, if it is supported */
- fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
- if (fd >= 0)
- return fd;
-#endif
-
- /* Fall back to unguessable name + unlinking */
- p = strjoina(path, "/systemd-tmp-XXXXXX");
-
- fd = mkostemp_safe(p, flags);
- if (fd < 0)
- return fd;
-
- unlink(p);
- return fd;
-}
-
int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
const char *fn;
char *t;
@@ -1278,3 +1254,103 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
return fputs(s, f);
}
+
+int open_tmpfile_unlinkable(const char *directory, int flags) {
+ char *p;
+ int fd;
+
+ assert(directory);
+
+ /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
+
+#ifdef O_TMPFILE
+ /* Try O_TMPFILE first, if it is supported */
+ fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
+ if (fd >= 0)
+ return fd;
+#endif
+
+ /* Fall back to unguessable name + unlinking */
+ p = strjoina(directory, "/systemd-tmp-XXXXXX");
+
+ fd = mkostemp_safe(p, flags);
+ if (fd < 0)
+ return fd;
+
+ (void) unlink(p);
+
+ return fd;
+}
+
+int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
+ _cleanup_free_ char *tmp = NULL;
+ int r, fd;
+
+ assert(target);
+ assert(ret_path);
+
+ /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
+ assert((flags & O_EXCL) == 0);
+
+ /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
+ * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
+ * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
+
+#ifdef O_TMPFILE
+ {
+ _cleanup_free_ char *dn = NULL;
+
+ dn = dirname_malloc(target);
+ if (!dn)
+ return -ENOMEM;
+
+ fd = open(dn, O_TMPFILE|flags, 0640);
+ if (fd >= 0) {
+ *ret_path = NULL;
+ return fd;
+ }
+
+ log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
+ }
+#endif
+
+ r = tempfn_random(target, NULL, &tmp);
+ if (r < 0)
+ return r;
+
+ fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
+ if (fd < 0)
+ return -errno;
+
+ *ret_path = tmp;
+ tmp = NULL;
+
+ return fd;
+}
+
+int link_tmpfile(int fd, const char *path, const char *target) {
+
+ assert(fd >= 0);
+ assert(target);
+
+ /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
+ * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
+ * on the directory, and renameat2() is used instead.
+ *
+ * Note that in both cases we will not replace existing files. This is because linkat() does not support this
+ * operation currently (renameat2() does), and there is no nice way to emulate this. */
+
+ if (path) {
+ if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
+ return -errno;
+ } else {
+ char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
+
+ xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
+
+ if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
+ return -errno;
+ }
+
+ return 0;
+}
diff --git a/src/libbasic/fileio.h b/src/libbasic/fileio.h
index 8084895ff3..58dbc80c24 100644
--- a/src/libbasic/fileio.h
+++ b/src/libbasic/fileio.h
@@ -72,7 +72,6 @@ int fflush_and_check(FILE *f);
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
int mkostemp_safe(char *pattern, int flags);
-int open_tmpfile(const char *path, int flags);
int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
int tempfn_random(const char *p, const char *extra, char **ret);
@@ -82,3 +81,8 @@ int write_timestamp_file_atomic(const char *fn, usec_t n);
int read_timestamp_file(const char *fn, usec_t *ret);
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space);
+
+int open_tmpfile_unlinkable(const char *directory, int flags);
+int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
+
+int link_tmpfile(int fd, const char *path, const char *target);
diff --git a/src/libbasic/formats-util.h b/src/libbasic/formats-util.h
index ce516b117d..9b4e8e98fa 100644
--- a/src/libbasic/formats-util.h
+++ b/src/libbasic/formats-util.h
@@ -49,7 +49,7 @@
#if SIZEOF_TIME_T == 8
# define PRI_TIME PRIi64
#elif SIZEOF_TIME_T == 4
-# define PRI_TIME PRIu32
+# define PRI_TIME "li"
#else
# error Unknown time_t size
#endif
diff --git a/src/libbasic/fs-util.c b/src/libbasic/fs-util.c
index 3ef1b90edd..e24e7036f7 100644
--- a/src/libbasic/fs-util.c
+++ b/src/libbasic/fs-util.c
@@ -38,6 +38,7 @@
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
+#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
@@ -283,24 +284,6 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
return 0;
}
-int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
- assert(fd >= 0);
-
- /* Under the assumption that we are running privileged we
- * first change the access mode and only then hand out
- * ownership to avoid a window where access is too open. */
-
- if (mode != MODE_INVALID)
- if (fchmod(fd, mode) < 0)
- return -errno;
-
- if (uid != UID_INVALID || gid != GID_INVALID)
- if (fchown(fd, uid, gid) < 0)
- return -errno;
-
- return 0;
-}
-
int fchmod_umask(int fd, mode_t m) {
mode_t u;
int r;
@@ -511,3 +494,17 @@ int get_files_in_directory(const char *path, char ***list) {
return n;
}
+
+int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
+ char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+ int r;
+
+ /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
+ xsprintf(path, "/proc/self/fd/%i", what);
+
+ r = inotify_add_watch(fd, path, mask);
+ if (r < 0)
+ return -errno;
+
+ return r;
+}
diff --git a/src/libbasic/fs-util.h b/src/libbasic/fs-util.h
index 0e2fcb21b9..517b599d6f 100644
--- a/src/libbasic/fs-util.h
+++ b/src/libbasic/fs-util.h
@@ -43,7 +43,6 @@ int readlink_and_canonicalize(const char *p, char **r);
int readlink_and_make_absolute_root(const char *root, const char *path, char **ret);
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
-int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
int fchmod_umask(int fd, mode_t mode);
@@ -73,3 +72,5 @@ union inotify_event_buffer {
struct inotify_event ev;
uint8_t raw[INOTIFY_EVENT_MAX];
};
+
+int inotify_add_watch_fd(int fd, int what, uint32_t mask);
diff --git a/src/libbasic/gunicode.h b/src/libbasic/gunicode.h
index b03aa43160..5975bc8fc9 100644
--- a/src/libbasic/gunicode.h
+++ b/src/libbasic/gunicode.h
@@ -1,11 +1,11 @@
+#pragma once
+
/* gunicode.h - Unicode manipulation functions
*
* Copyright (C) 1999, 2000 Tom Tromey
* Copyright 2000, 2005 Red Hat, Inc.
*/
-#pragma once
-
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/src/libbasic/hashmap.c b/src/libbasic/hashmap.c
index 6f1a049d47..49a0479592 100644
--- a/src/libbasic/hashmap.c
+++ b/src/libbasic/hashmap.c
@@ -176,7 +176,7 @@ enum HashmapType {
};
struct _packed_ indirect_storage {
- char *storage; /* where buckets and DIBs are stored */
+ void *storage; /* where buckets and DIBs are stored */
uint8_t hash_key[HASH_KEY_SIZE]; /* hash key; changes during resize */
unsigned n_entries; /* number of stored entries */
@@ -193,7 +193,7 @@ struct direct_storage {
/* This gives us 39 bytes on 64bit, or 35 bytes on 32bit.
* That's room for 4 set_entries + 4 DIB bytes + 3 unused bytes on 64bit,
* or 7 set_entries + 7 DIB bytes + 0 unused bytes on 32bit. */
- char storage[sizeof(struct indirect_storage)];
+ uint8_t storage[sizeof(struct indirect_storage)];
};
#define DIRECT_BUCKETS(entry_t) \
@@ -302,7 +302,7 @@ static void n_entries_dec(HashmapBase *h) {
h->n_direct_entries--;
}
-static char *storage_ptr(HashmapBase *h) {
+static void *storage_ptr(HashmapBase *h) {
return h->has_indirect ? h->indirect.storage
: h->direct.storage;
}
@@ -347,7 +347,7 @@ static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) {
static struct hashmap_base_entry *bucket_at(HashmapBase *h, unsigned idx) {
return (struct hashmap_base_entry*)
- (storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
+ ((uint8_t*) storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
}
static struct plain_hashmap_entry *plain_bucket_at(Hashmap *h, unsigned idx) {
@@ -381,7 +381,7 @@ static struct hashmap_base_entry *bucket_at_virtual(HashmapBase *h, struct swap_
static dib_raw_t *dib_raw_ptr(HashmapBase *h) {
return (dib_raw_t*)
- (storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
+ ((uint8_t*) storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
}
static unsigned bucket_distance(HashmapBase *h, unsigned idx, unsigned from) {
@@ -1028,7 +1028,7 @@ static int hashmap_base_put_boldly(HashmapBase *h, unsigned idx,
*/
static int resize_buckets(HashmapBase *h, unsigned entries_add) {
struct swap_entries swap;
- char *new_storage;
+ void *new_storage;
dib_raw_t *old_dibs, *new_dibs;
const struct hashmap_type_info *hi;
unsigned idx, optimal_idx;
@@ -1095,7 +1095,7 @@ static int resize_buckets(HashmapBase *h, unsigned entries_add) {
h->indirect.n_buckets = (1U << new_shift) /
(hi->entry_size + sizeof(dib_raw_t));
- old_dibs = (dib_raw_t*)(new_storage + hi->entry_size * old_n_buckets);
+ old_dibs = (dib_raw_t*)((uint8_t*) new_storage + hi->entry_size * old_n_buckets);
new_dibs = dib_raw_ptr(h);
/*
@@ -1773,20 +1773,18 @@ int set_consume(Set *s, void *value) {
int set_put_strdup(Set *s, const char *p) {
char *c;
- int r;
assert(s);
assert(p);
+ if (set_contains(s, (char*) p))
+ return 0;
+
c = strdup(p);
if (!c)
return -ENOMEM;
- r = set_consume(s, c);
- if (r == -EEXIST)
- return 0;
-
- return r;
+ return set_consume(s, c);
}
int set_put_strdupv(Set *s, char **l) {
diff --git a/src/libbasic/hexdecoct.c b/src/libbasic/hexdecoct.c
index 592df53cb5..c5bda6c4d6 100644
--- a/src/libbasic/hexdecoct.c
+++ b/src/libbasic/hexdecoct.c
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "hexdecoct.h"
#include "macro.h"
+#include "util.h"
char octchar(int x) {
return '0' + (x & 7);
@@ -275,8 +276,8 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
if (padding) {
/* strip the padding */
while (l > 0 && p[l - 1] == '=' && pad < 7) {
- pad ++;
- l --;
+ pad++;
+ l--;
}
}
@@ -504,7 +505,7 @@ int unbase64char(char c) {
if (c == '+')
return offset;
- offset ++;
+ offset++;
if (c == '/')
return offset;
@@ -572,7 +573,7 @@ static int base64_append_width(char **prefix, int plen,
if (!t)
return -ENOMEM;
- memcpy(t + plen, sep, slen);
+ memcpy_safe(t + plen, sep, slen);
for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) {
int act = MIN(width, avail);
@@ -620,9 +621,9 @@ int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
/* strip the padding */
if (l > 0 && p[l - 1] == '=')
- l --;
+ l--;
if (l > 0 && p[l - 1] == '=')
- l --;
+ l--;
/* a group of four input bytes needs three output bytes, in case of
padding we need to add two or three extra bytes */
diff --git a/src/libbasic/hostname-util.c b/src/libbasic/hostname-util.c
index 7bb23448ed..13c3bb6446 100644
--- a/src/libbasic/hostname-util.c
+++ b/src/libbasic/hostname-util.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <bits/local_lim.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
@@ -49,6 +48,10 @@ bool hostname_is_set(void) {
char* gethostname_malloc(void) {
struct utsname u;
+ /* This call tries to return something useful, either the actual hostname
+ * or it makes something up. The only reason it might fail is OOM.
+ * It might even return "localhost" if that's set. */
+
assert_se(uname(&u) >= 0);
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
@@ -57,6 +60,31 @@ char* gethostname_malloc(void) {
return strdup(u.nodename);
}
+int gethostname_strict(char **ret) {
+ struct utsname u;
+ char *k;
+
+ /* This call will rather fail than make up a name. It will not return "localhost" either. */
+
+ assert_se(uname(&u) >= 0);
+
+ if (isempty(u.nodename))
+ return -ENXIO;
+
+ if (streq(u.nodename, "(none)"))
+ return -ENXIO;
+
+ if (is_localhost(u.nodename))
+ return -ENXIO;
+
+ k = strdup(u.nodename);
+ if (!k)
+ return -ENOMEM;
+
+ *ret = k;
+ return 0;
+}
+
static bool hostname_valid_char(char c) {
return
(c >= 'a' && c <= 'z') ||
@@ -96,7 +124,7 @@ bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
return false;
dot = true;
- n_dots ++;
+ n_dots++;
} else {
if (!hostname_valid_char(*p))
return false;
@@ -122,6 +150,8 @@ char* hostname_cleanup(char *s) {
assert(s);
+ strshorten(s, HOST_NAME_MAX);
+
for (p = s, d = s, dot = true; *p; p++) {
if (*p == '.') {
if (dot)
@@ -141,8 +171,6 @@ char* hostname_cleanup(char *s) {
else
*d = 0;
- strshorten(s, HOST_NAME_MAX);
-
return s;
}
@@ -150,16 +178,16 @@ bool is_localhost(const char *hostname) {
assert(hostname);
/* This tries to identify local host and domain names
- * described in RFC6761 plus the redhatism of .localdomain */
+ * described in RFC6761 plus the redhatism of localdomain */
return strcaseeq(hostname, "localhost") ||
strcaseeq(hostname, "localhost.") ||
- strcaseeq(hostname, "localdomain.") ||
- strcaseeq(hostname, "localdomain") ||
+ strcaseeq(hostname, "localhost.localdomain") ||
+ strcaseeq(hostname, "localhost.localdomain.") ||
endswith_no_case(hostname, ".localhost") ||
endswith_no_case(hostname, ".localhost.") ||
- endswith_no_case(hostname, ".localdomain") ||
- endswith_no_case(hostname, ".localdomain.");
+ endswith_no_case(hostname, ".localhost.localdomain") ||
+ endswith_no_case(hostname, ".localhost.localdomain.");
}
bool is_gateway_hostname(const char *hostname) {
diff --git a/src/libbasic/hostname-util.h b/src/libbasic/hostname-util.h
index d062eddea1..7af4e6c7ec 100644
--- a/src/libbasic/hostname-util.h
+++ b/src/libbasic/hostname-util.h
@@ -26,6 +26,7 @@
bool hostname_is_set(void);
char* gethostname_malloc(void);
+int gethostname_strict(char **ret);
bool hostname_is_valid(const char *s, bool allow_trailing_dot) _pure_;
char* hostname_cleanup(char *s);
diff --git a/src/libbasic/io-util.c b/src/libbasic/io-util.c
index 3ec8d61236..cc6dfa8c1b 100644
--- a/src/libbasic/io-util.c
+++ b/src/libbasic/io-util.c
@@ -33,6 +33,11 @@ int flush_fd(int fd) {
.events = POLLIN,
};
+ /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
+ * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read
+ * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used
+ * was set to non-blocking too. */
+
for (;;) {
char buf[LINE_MAX];
ssize_t l;
@@ -249,7 +254,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
} else if (n > 0)
q += n;
else
- q ++;
+ q++;
}
if (q > w) {
diff --git a/src/libbasic/io-util.h b/src/libbasic/io-util.h
index 142c940d92..4684ed3bfc 100644
--- a/src/libbasic/io-util.h
+++ b/src/libbasic/io-util.h
@@ -46,7 +46,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
char *_s = (char *)(s); \
_i->iov_base = _s; \
_i->iov_len = strlen(_s); \
- } while(false)
+ } while (false)
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
unsigned j;
diff --git a/src/libbasic/json.c b/src/libbasic/json.c
deleted file mode 100644
index daa98fc815..0000000000
--- a/src/libbasic/json.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "alloc-util.h"
-#include "hexdecoct.h"
-#include "json.h"
-#include "macro.h"
-#include "string-util.h"
-#include "utf8.h"
-
-int json_variant_new(JsonVariant **ret, JsonVariantType type) {
- JsonVariant *v;
-
- v = new0(JsonVariant, 1);
- if (!v)
- return -ENOMEM;
- v->type = type;
- *ret = v;
- return 0;
-}
-
-static int json_variant_deep_copy(JsonVariant *ret, JsonVariant *variant) {
- int r;
-
- assert(ret);
- assert(variant);
-
- ret->type = variant->type;
- ret->size = variant->size;
-
- if (variant->type == JSON_VARIANT_STRING) {
- ret->string = memdup(variant->string, variant->size+1);
- if (!ret->string)
- return -ENOMEM;
- } else if (variant->type == JSON_VARIANT_ARRAY || variant->type == JSON_VARIANT_OBJECT) {
- size_t i;
-
- ret->objects = new0(JsonVariant, variant->size);
- if (!ret->objects)
- return -ENOMEM;
-
- for (i = 0; i < variant->size; ++i) {
- r = json_variant_deep_copy(&ret->objects[i], &variant->objects[i]);
- if (r < 0)
- return r;
- }
- } else
- ret->value = variant->value;
-
- return 0;
-}
-
-static JsonVariant *json_object_unref(JsonVariant *variant);
-
-static JsonVariant *json_variant_unref_inner(JsonVariant *variant) {
- if (!variant)
- return NULL;
-
- if (variant->type == JSON_VARIANT_ARRAY || variant->type == JSON_VARIANT_OBJECT)
- return json_object_unref(variant);
- else if (variant->type == JSON_VARIANT_STRING)
- free(variant->string);
-
- return NULL;
-}
-
-static JsonVariant *json_raw_unref(JsonVariant *variant, size_t size) {
- if (!variant)
- return NULL;
-
- for (size_t i = 0; i < size; ++i)
- json_variant_unref_inner(&variant[i]);
-
- free(variant);
- return NULL;
-}
-
-static JsonVariant *json_object_unref(JsonVariant *variant) {
- size_t i;
-
- assert(variant);
-
- if (!variant->objects)
- return NULL;
-
- for (i = 0; i < variant->size; ++i)
- json_variant_unref_inner(&variant->objects[i]);
-
- free(variant->objects);
- return NULL;
-}
-
-static JsonVariant **json_variant_array_unref(JsonVariant **variant) {
- size_t i = 0;
- JsonVariant *p = NULL;
-
- if (!variant)
- return NULL;
-
- while((p = (variant[i++])) != NULL) {
- if (p->type == JSON_VARIANT_STRING)
- free(p->string);
- free(p);
- }
-
- free(variant);
-
- return NULL;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(JsonVariant **, json_variant_array_unref);
-
-JsonVariant *json_variant_unref(JsonVariant *variant) {
- if (!variant)
- return NULL;
-
- if (variant->type == JSON_VARIANT_ARRAY || variant->type == JSON_VARIANT_OBJECT)
- json_object_unref(variant);
- else if (variant->type == JSON_VARIANT_STRING)
- free(variant->string);
-
- free(variant);
-
- return NULL;
-}
-
-char *json_variant_string(JsonVariant *variant){
- assert(variant);
- assert(variant->type == JSON_VARIANT_STRING);
-
- return variant->string;
-}
-
-bool json_variant_bool(JsonVariant *variant) {
- assert(variant);
- assert(variant->type == JSON_VARIANT_BOOLEAN);
-
- return variant->value.boolean;
-}
-
-intmax_t json_variant_integer(JsonVariant *variant) {
- assert(variant);
- assert(variant->type == JSON_VARIANT_INTEGER);
-
- return variant->value.integer;
-}
-
-double json_variant_real(JsonVariant *variant) {
- assert(variant);
- assert(variant->type == JSON_VARIANT_REAL);
-
- return variant->value.real;
-}
-
-JsonVariant *json_variant_element(JsonVariant *variant, unsigned index) {
- assert(variant);
- assert(variant->type == JSON_VARIANT_ARRAY || variant->type == JSON_VARIANT_OBJECT);
- assert(index < variant->size);
- assert(variant->objects);
-
- return &variant->objects[index];
-}
-
-JsonVariant *json_variant_value(JsonVariant *variant, const char *key) {
- size_t i;
-
- assert(variant);
- assert(variant->type == JSON_VARIANT_OBJECT);
- assert(variant->objects);
-
- for (i = 0; i < variant->size; i += 2) {
- JsonVariant *p = &variant->objects[i];
- if (p->type == JSON_VARIANT_STRING && streq(key, p->string))
- return &variant->objects[i + 1];
- }
-
- return NULL;
-}
-
-static void inc_lines(unsigned *line, const char *s, size_t n) {
- const char *p = s;
-
- if (!line)
- return;
-
- for (;;) {
- const char *f;
-
- f = memchr(p, '\n', n);
- if (!f)
- return;
-
- n -= (f - p) + 1;
- p = f + 1;
- (*line)++;
- }
-}
-
-static int unhex_ucs2(const char *c, uint16_t *ret) {
- int aa, bb, cc, dd;
- uint16_t x;
-
- assert(c);
- assert(ret);
-
- aa = unhexchar(c[0]);
- if (aa < 0)
- return -EINVAL;
-
- bb = unhexchar(c[1]);
- if (bb < 0)
- return -EINVAL;
-
- cc = unhexchar(c[2]);
- if (cc < 0)
- return -EINVAL;
-
- dd = unhexchar(c[3]);
- if (dd < 0)
- return -EINVAL;
-
- x = ((uint16_t) aa << 12) |
- ((uint16_t) bb << 8) |
- ((uint16_t) cc << 4) |
- ((uint16_t) dd);
-
- if (x <= 0)
- return -EINVAL;
-
- *ret = x;
-
- return 0;
-}
-
-static int json_parse_string(const char **p, char **ret) {
- _cleanup_free_ char *s = NULL;
- size_t n = 0, allocated = 0;
- const char *c;
-
- assert(p);
- assert(*p);
- assert(ret);
-
- c = *p;
-
- if (*c != '"')
- return -EINVAL;
-
- c++;
-
- for (;;) {
- int len;
-
- /* Check for EOF */
- if (*c == 0)
- return -EINVAL;
-
- /* Check for control characters 0x00..0x1f */
- if (*c > 0 && *c < ' ')
- return -EINVAL;
-
- /* Check for control character 0x7f */
- if (*c == 0x7f)
- return -EINVAL;
-
- if (*c == '"') {
- if (!s) {
- s = strdup("");
- if (!s)
- return -ENOMEM;
- } else
- s[n] = 0;
-
- *p = c + 1;
-
- *ret = s;
- s = NULL;
- return JSON_STRING;
- }
-
- if (*c == '\\') {
- char ch = 0;
- c++;
-
- if (*c == 0)
- return -EINVAL;
-
- if (IN_SET(*c, '"', '\\', '/'))
- ch = *c;
- else if (*c == 'b')
- ch = '\b';
- else if (*c == 'f')
- ch = '\f';
- else if (*c == 'n')
- ch = '\n';
- else if (*c == 'r')
- ch = '\r';
- else if (*c == 't')
- ch = '\t';
- else if (*c == 'u') {
- char16_t x;
- int r;
-
- r = unhex_ucs2(c + 1, &x);
- if (r < 0)
- return r;
-
- c += 5;
-
- if (!GREEDY_REALLOC(s, allocated, n + 4))
- return -ENOMEM;
-
- if (!utf16_is_surrogate(x))
- n += utf8_encode_unichar(s + n, (char32_t) x);
- else if (utf16_is_trailing_surrogate(x))
- return -EINVAL;
- else {
- char16_t y;
-
- if (c[0] != '\\' || c[1] != 'u')
- return -EINVAL;
-
- r = unhex_ucs2(c + 2, &y);
- if (r < 0)
- return r;
-
- c += 6;
-
- if (!utf16_is_trailing_surrogate(y))
- return -EINVAL;
-
- n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
- }
-
- continue;
- } else
- return -EINVAL;
-
- if (!GREEDY_REALLOC(s, allocated, n + 2))
- return -ENOMEM;
-
- s[n++] = ch;
- c ++;
- continue;
- }
-
- len = utf8_encoded_valid_unichar(c);
- if (len < 0)
- return len;
-
- if (!GREEDY_REALLOC(s, allocated, n + len + 1))
- return -ENOMEM;
-
- memcpy(s + n, c, len);
- n += len;
- c += len;
- }
-}
-
-static int json_parse_number(const char **p, union json_value *ret) {
- bool negative = false, exponent_negative = false, is_double = false;
- double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
- intmax_t i = 0;
- const char *c;
-
- assert(p);
- assert(*p);
- assert(ret);
-
- c = *p;
-
- if (*c == '-') {
- negative = true;
- c++;
- }
-
- if (*c == '0')
- c++;
- else {
- if (!strchr("123456789", *c) || *c == 0)
- return -EINVAL;
-
- do {
- if (!is_double) {
- int64_t t;
-
- t = 10 * i + (*c - '0');
- if (t < i) /* overflow */
- is_double = false;
- else
- i = t;
- }
-
- x = 10.0 * x + (*c - '0');
- c++;
- } while (strchr("0123456789", *c) && *c != 0);
- }
-
- if (*c == '.') {
- is_double = true;
- c++;
-
- if (!strchr("0123456789", *c) || *c == 0)
- return -EINVAL;
-
- do {
- y = 10.0 * y + (*c - '0');
- shift = 10.0 * shift;
- c++;
- } while (strchr("0123456789", *c) && *c != 0);
- }
-
- if (*c == 'e' || *c == 'E') {
- is_double = true;
- c++;
-
- if (*c == '-') {
- exponent_negative = true;
- c++;
- } else if (*c == '+')
- c++;
-
- if (!strchr("0123456789", *c) || *c == 0)
- return -EINVAL;
-
- do {
- exponent = 10.0 * exponent + (*c - '0');
- c++;
- } while (strchr("0123456789", *c) && *c != 0);
- }
-
- *p = c;
-
- if (is_double) {
- ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10((exponent_negative ? -1.0 : 1.0) * exponent);
- return JSON_REAL;
- } else {
- ret->integer = negative ? -i : i;
- return JSON_INTEGER;
- }
-}
-
-int json_tokenize(
- const char **p,
- char **ret_string,
- union json_value *ret_value,
- void **state,
- unsigned *line) {
-
- const char *c;
- int t;
- int r;
-
- enum {
- STATE_NULL,
- STATE_VALUE,
- STATE_VALUE_POST,
- };
-
- assert(p);
- assert(*p);
- assert(ret_string);
- assert(ret_value);
- assert(state);
-
- t = PTR_TO_INT(*state);
- c = *p;
-
- if (t == STATE_NULL) {
- if (line)
- *line = 1;
- t = STATE_VALUE;
- }
-
- for (;;) {
- const char *b;
-
- b = c + strspn(c, WHITESPACE);
- if (*b == 0)
- return JSON_END;
-
- inc_lines(line, c, b - c);
- c = b;
-
- switch (t) {
-
- case STATE_VALUE:
-
- if (*c == '{') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE);
- return JSON_OBJECT_OPEN;
-
- } else if (*c == '}') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_OBJECT_CLOSE;
-
- } else if (*c == '[') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE);
- return JSON_ARRAY_OPEN;
-
- } else if (*c == ']') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_ARRAY_CLOSE;
-
- } else if (*c == '"') {
- r = json_parse_string(&c, ret_string);
- if (r < 0)
- return r;
-
- *ret_value = JSON_VALUE_NULL;
- *p = c;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return r;
-
- } else if (strchr("-0123456789", *c)) {
- r = json_parse_number(&c, ret_value);
- if (r < 0)
- return r;
-
- *ret_string = NULL;
- *p = c;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return r;
-
- } else if (startswith(c, "true")) {
- *ret_string = NULL;
- ret_value->boolean = true;
- *p = c + 4;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_BOOLEAN;
-
- } else if (startswith(c, "false")) {
- *ret_string = NULL;
- ret_value->boolean = false;
- *p = c + 5;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_BOOLEAN;
-
- } else if (startswith(c, "null")) {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 4;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_NULL;
-
- } else
- return -EINVAL;
-
- case STATE_VALUE_POST:
-
- if (*c == ':') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE);
- return JSON_COLON;
- } else if (*c == ',') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE);
- return JSON_COMMA;
- } else if (*c == '}') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_OBJECT_CLOSE;
- } else if (*c == ']') {
- *ret_string = NULL;
- *ret_value = JSON_VALUE_NULL;
- *p = c + 1;
- *state = INT_TO_PTR(STATE_VALUE_POST);
- return JSON_ARRAY_CLOSE;
- } else
- return -EINVAL;
- }
-
- }
-}
-
-static bool json_is_value(JsonVariant *var) {
- assert(var);
-
- return var->type != JSON_VARIANT_CONTROL;
-}
-
-static int json_scoped_parse(JsonVariant **tokens, size_t *i, size_t n, JsonVariant *scope) {
- bool arr = scope->type == JSON_VARIANT_ARRAY;
- int terminator = arr ? JSON_ARRAY_CLOSE : JSON_OBJECT_CLOSE;
- size_t allocated = 0, size = 0;
- JsonVariant *key = NULL, *value = NULL, *var = NULL, *items = NULL;
- enum {
- STATE_KEY,
- STATE_COLON,
- STATE_COMMA,
- STATE_VALUE
- } state = arr ? STATE_VALUE : STATE_KEY;
-
- assert(tokens);
- assert(i);
- assert(scope);
-
- while((var = *i < n ? tokens[(*i)++] : NULL) != NULL) {
- bool stopper;
- int r;
-
- stopper = !json_is_value(var) && var->value.integer == terminator;
-
- if (stopper) {
- if (state != STATE_COMMA && size > 0)
- goto error;
-
- goto out;
- }
-
- if (state == STATE_KEY) {
- if (var->type != JSON_VARIANT_STRING)
- goto error;
- else {
- key = var;
- state = STATE_COLON;
- }
- }
- else if (state == STATE_COLON) {
- if (key == NULL)
- goto error;
-
- if (json_is_value(var))
- goto error;
-
- if (var->value.integer != JSON_COLON)
- goto error;
-
- state = STATE_VALUE;
- }
- else if (state == STATE_VALUE) {
- _cleanup_json_variant_unref_ JsonVariant *v = NULL;
- size_t toadd = arr ? 1 : 2;
-
- if (!json_is_value(var)) {
- int type = (var->value.integer == JSON_ARRAY_OPEN) ? JSON_VARIANT_ARRAY : JSON_VARIANT_OBJECT;
-
- r = json_variant_new(&v, type);
- if (r < 0)
- goto error;
-
- r = json_scoped_parse(tokens, i, n, v);
- if (r < 0)
- goto error;
-
- value = v;
- }
- else
- value = var;
-
- if(!GREEDY_REALLOC(items, allocated, size + toadd))
- goto error;
-
- if (arr) {
- r = json_variant_deep_copy(&items[size], value);
- if (r < 0)
- goto error;
- } else {
- r = json_variant_deep_copy(&items[size], key);
- if (r < 0)
- goto error;
-
- r = json_variant_deep_copy(&items[size+1], value);
- if (r < 0)
- goto error;
- }
-
- size += toadd;
- state = STATE_COMMA;
- }
- else if (state == STATE_COMMA) {
- if (json_is_value(var))
- goto error;
-
- if (var->value.integer != JSON_COMMA)
- goto error;
-
- key = NULL;
- value = NULL;
-
- state = arr ? STATE_VALUE : STATE_KEY;
- }
- }
-
-error:
- json_raw_unref(items, size);
- return -EBADMSG;
-
-out:
- scope->size = size;
- scope->objects = items;
-
- return scope->type;
-}
-
-static int json_parse_tokens(JsonVariant **tokens, size_t ntokens, JsonVariant **rv) {
- size_t it = 0;
- int r;
- JsonVariant *e;
- _cleanup_json_variant_unref_ JsonVariant *p = NULL;
-
- assert(tokens);
- assert(ntokens);
-
- e = tokens[it++];
- r = json_variant_new(&p, JSON_VARIANT_OBJECT);
- if (r < 0)
- return r;
-
- if (e->type != JSON_VARIANT_CONTROL && e->value.integer != JSON_OBJECT_OPEN)
- return -EBADMSG;
-
- r = json_scoped_parse(tokens, &it, ntokens, p);
- if (r < 0)
- return r;
-
- *rv = p;
- p = NULL;
-
- return 0;
-}
-
-static int json_tokens(const char *string, size_t size, JsonVariant ***tokens, size_t *n) {
- _cleanup_free_ char *buf = NULL;
- _cleanup_(json_variant_array_unrefp) JsonVariant **items = NULL;
- union json_value v = {};
- void *json_state = NULL;
- const char *p;
- int t, r;
- size_t allocated = 0, s = 0;
-
- assert(string);
- assert(n);
-
- if (size <= 0)
- return -EBADMSG;
-
- buf = strndup(string, size);
- if (!buf)
- return -ENOMEM;
-
- p = buf;
- for (;;) {
- _cleanup_json_variant_unref_ JsonVariant *var = NULL;
- _cleanup_free_ char *rstr = NULL;
-
- t = json_tokenize(&p, &rstr, &v, &json_state, NULL);
-
- if (t < 0)
- return t;
- else if (t == JSON_END)
- break;
-
- if (t <= JSON_ARRAY_CLOSE) {
- r = json_variant_new(&var, JSON_VARIANT_CONTROL);
- if (r < 0)
- return r;
- var->value.integer = t;
- } else {
- switch (t) {
- case JSON_STRING:
- r = json_variant_new(&var, JSON_VARIANT_STRING);
- if (r < 0)
- return r;
- var->size = strlen(rstr);
- var->string = strdup(rstr);
- if (!var->string) {
- return -ENOMEM;
- }
- break;
- case JSON_INTEGER:
- r = json_variant_new(&var, JSON_VARIANT_INTEGER);
- if (r < 0)
- return r;
- var->value = v;
- break;
- case JSON_REAL:
- r = json_variant_new(&var, JSON_VARIANT_REAL);
- if (r < 0)
- return r;
- var->value = v;
- break;
- case JSON_BOOLEAN:
- r = json_variant_new(&var, JSON_VARIANT_BOOLEAN);
- if (r < 0)
- return r;
- var->value = v;
- break;
- case JSON_NULL:
- r = json_variant_new(&var, JSON_VARIANT_NULL);
- if (r < 0)
- return r;
- break;
- }
- }
-
- if (!GREEDY_REALLOC(items, allocated, s+2))
- return -ENOMEM;
-
- items[s++] = var;
- items[s] = NULL;
- var = NULL;
- }
-
- *n = s;
- *tokens = items;
- items = NULL;
-
- return 0;
-}
-
-int json_parse(const char *string, JsonVariant **rv) {
- _cleanup_(json_variant_array_unrefp) JsonVariant **s = NULL;
- JsonVariant *v = NULL;
- size_t n = 0;
- int r;
-
- assert(string);
- assert(rv);
-
- r = json_tokens(string, strlen(string), &s, &n);
- if (r < 0)
- return r;
-
- r = json_parse_tokens(s, n, &v);
- if (r < 0)
- return r;
-
- *rv = v;
- return 0;
-}
diff --git a/src/libbasic/json.h b/src/libbasic/json.h
deleted file mode 100644
index a4509f680f..0000000000
--- a/src/libbasic/json.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "macro.h"
-#include "util.h"
-
-enum {
- JSON_END,
- JSON_COLON,
- JSON_COMMA,
- JSON_OBJECT_OPEN,
- JSON_OBJECT_CLOSE,
- JSON_ARRAY_OPEN,
- JSON_ARRAY_CLOSE,
- JSON_STRING,
- JSON_REAL,
- JSON_INTEGER,
- JSON_BOOLEAN,
- JSON_NULL,
-};
-
-typedef enum {
- JSON_VARIANT_CONTROL,
- JSON_VARIANT_STRING,
- JSON_VARIANT_INTEGER,
- JSON_VARIANT_BOOLEAN,
- JSON_VARIANT_REAL,
- JSON_VARIANT_ARRAY,
- JSON_VARIANT_OBJECT,
- JSON_VARIANT_NULL
-} JsonVariantType;
-
-union json_value {
- bool boolean;
- double real;
- intmax_t integer;
-};
-
-typedef struct JsonVariant {
- JsonVariantType type;
- size_t size;
- union {
- char *string;
- struct JsonVariant *objects;
- union json_value value;
- };
-} JsonVariant;
-
-int json_variant_new(JsonVariant **ret, JsonVariantType type);
-JsonVariant *json_variant_unref(JsonVariant *v);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(JsonVariant *, json_variant_unref);
-#define _cleanup_json_variant_unref_ _cleanup_(json_variant_unrefp)
-
-char *json_variant_string(JsonVariant *v);
-bool json_variant_bool(JsonVariant *v);
-intmax_t json_variant_integer(JsonVariant *v);
-double json_variant_real(JsonVariant *v);
-
-JsonVariant *json_variant_element(JsonVariant *v, unsigned index);
-JsonVariant *json_variant_value(JsonVariant *v, const char *key);
-
-#define JSON_VALUE_NULL ((union json_value) {})
-
-int json_tokenize(const char **p, char **ret_string, union json_value *ret_value, void **state, unsigned *line);
-
-int json_parse(const char *string, JsonVariant **rv);
-int json_parse_measure(const char *string, size_t *size);
diff --git a/src/libbasic/list.h b/src/libbasic/list.h
index c68185f587..5962aa4211 100644
--- a/src/libbasic/list.h
+++ b/src/libbasic/list.h
@@ -32,7 +32,7 @@
#define LIST_HEAD_INIT(head) \
do { \
(head) = NULL; } \
- while(false)
+ while (false)
/* Initialize a list item */
#define LIST_INIT(name,item) \
@@ -40,7 +40,7 @@
typeof(*(item)) *_item = (item); \
assert(_item); \
_item->name##_prev = _item->name##_next = NULL; \
- } while(false)
+ } while (false)
/* Prepend an item to the list */
#define LIST_PREPEND(name,head,item) \
@@ -51,7 +51,7 @@
_item->name##_next->name##_prev = _item; \
_item->name##_prev = NULL; \
*_head = _item; \
- } while(false)
+ } while (false)
/* Append an item to the list */
#define LIST_APPEND(name,head,item) \
@@ -59,7 +59,7 @@
typeof(*(head)) *_tail; \
LIST_FIND_TAIL(name,head,_tail); \
LIST_INSERT_AFTER(name,head,_tail,item); \
- } while(false)
+ } while (false)
/* Remove an item from the list */
#define LIST_REMOVE(name,head,item) \
@@ -75,7 +75,7 @@
*_head = _item->name##_next; \
} \
_item->name##_next = _item->name##_prev = NULL; \
- } while(false)
+ } while (false)
/* Find the head of the list */
#define LIST_FIND_HEAD(name,item,head) \
@@ -119,7 +119,7 @@
_b->name##_prev = _a; \
_a->name##_next = _b; \
} \
- } while(false)
+ } while (false)
/* Insert an item before another one (a = where, b = what) */
#define LIST_INSERT_BEFORE(name,head,a,b) \
@@ -145,7 +145,7 @@
_b->name##_next = _a; \
_a->name##_prev = _b; \
} \
- } while(false)
+ } while (false)
#define LIST_JUST_US(name,item) \
(!(item)->name##_prev && !(item)->name##_next) \
diff --git a/src/libbasic/locale-util.c b/src/libbasic/locale-util.c
index cda6b2895d..ada0a28cd8 100644
--- a/src/libbasic/locale-util.c
+++ b/src/libbasic/locale-util.c
@@ -153,6 +153,8 @@ static int add_locales_from_libdir (Set *locales) {
FOREACH_DIRENT(entry, dir, return -errno) {
char *z;
+ dirent_ensure_type(dir, entry);
+
if (entry->d_type != DT_DIR)
continue;
@@ -269,34 +271,35 @@ out:
}
-const char *draw_special_char(DrawSpecialChar ch) {
-
- static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
+const char *special_glyph(SpecialGlyph code) {
- /* UTF-8 */ {
- [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
- [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
- [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
- [DRAW_TREE_SPACE] = " ", /* */
- [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
- [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
- [DRAW_ARROW] = "\342\206\222", /* → */
- [DRAW_DASH] = "\342\200\223", /* – */
+ static const char* const draw_table[2][_SPECIAL_GLYPH_MAX] = {
+ /* ASCII fallback */
+ [false] = {
+ [TREE_VERTICAL] = "| ",
+ [TREE_BRANCH] = "|-",
+ [TREE_RIGHT] = "`-",
+ [TREE_SPACE] = " ",
+ [TRIANGULAR_BULLET] = ">",
+ [BLACK_CIRCLE] = "*",
+ [ARROW] = "->",
+ [MDASH] = "-",
},
- /* ASCII fallback */ {
- [DRAW_TREE_VERTICAL] = "| ",
- [DRAW_TREE_BRANCH] = "|-",
- [DRAW_TREE_RIGHT] = "`-",
- [DRAW_TREE_SPACE] = " ",
- [DRAW_TRIANGULAR_BULLET] = ">",
- [DRAW_BLACK_CIRCLE] = "*",
- [DRAW_ARROW] = "->",
- [DRAW_DASH] = "-",
- }
+ /* UTF-8 */
+ [ true ] = {
+ [TREE_VERTICAL] = "\342\224\202 ", /* │ */
+ [TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
+ [TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
+ [TREE_SPACE] = " ", /* */
+ [TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
+ [BLACK_CIRCLE] = "\342\227\217", /* ● */
+ [ARROW] = "\342\206\222", /* → */
+ [MDASH] = "\342\200\223", /* – */
+ },
};
- return draw_table[!is_locale_utf8()][ch];
+ return draw_table[is_locale_utf8()][code];
}
static const char * const locale_variable_table[_VARIABLE_LC_MAX] = {
diff --git a/src/libbasic/locale-util.h b/src/libbasic/locale-util.h
index b0f9679286..0630a034ab 100644
--- a/src/libbasic/locale-util.h
+++ b/src/libbasic/locale-util.h
@@ -55,19 +55,19 @@ void init_gettext(void);
bool is_locale_utf8(void);
-typedef enum DrawSpecialChar {
- DRAW_TREE_VERTICAL,
- DRAW_TREE_BRANCH,
- DRAW_TREE_RIGHT,
- DRAW_TREE_SPACE,
- DRAW_TRIANGULAR_BULLET,
- DRAW_BLACK_CIRCLE,
- DRAW_ARROW,
- DRAW_DASH,
- _DRAW_SPECIAL_CHAR_MAX
-} DrawSpecialChar;
+typedef enum {
+ TREE_VERTICAL,
+ TREE_BRANCH,
+ TREE_RIGHT,
+ TREE_SPACE,
+ TRIANGULAR_BULLET,
+ BLACK_CIRCLE,
+ ARROW,
+ MDASH,
+ _SPECIAL_GLYPH_MAX
+} SpecialGlyph;
-const char *draw_special_char(DrawSpecialChar ch);
+const char *special_glyph(SpecialGlyph code) _const_;
const char* locale_variable_to_string(LocaleVariable i) _const_;
LocaleVariable locale_variable_from_string(const char *s) _pure_;
diff --git a/src/libbasic/log.c b/src/libbasic/log.c
index f625e3bd95..05c4896f55 100644
--- a/src/libbasic/log.c
+++ b/src/libbasic/log.c
@@ -165,7 +165,7 @@ static int log_open_syslog(void) {
goto fail;
}
- if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
safe_close(syslog_fd);
/* Some legacy syslog systems still use stream
@@ -177,7 +177,7 @@ static int log_open_syslog(void) {
goto fail;
}
- if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
r = -errno;
goto fail;
}
@@ -215,7 +215,7 @@ static int log_open_journal(void) {
goto fail;
}
- if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
r = -errno;
goto fail;
}
diff --git a/src/libbasic/log.h b/src/libbasic/log.h
index 8ccbf8ed70..d2a22b5829 100644
--- a/src/libbasic/log.h
+++ b/src/libbasic/log.h
@@ -193,7 +193,7 @@ void log_assert_failed_return(
#ifdef LOG_TRACE
# define log_trace(...) log_debug(__VA_ARGS__)
#else
-# define log_trace(...) do {} while(0)
+# define log_trace(...) do {} while (0)
#endif
/* Structured logging */
@@ -246,5 +246,4 @@ int log_syntax_internal(
log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \
"String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \
} \
- -EINVAL; \
})
diff --git a/src/libbasic/login-util.h b/src/libbasic/login-util.h
index 89a337d7c1..b01ee25c88 100644
--- a/src/libbasic/login-util.h
+++ b/src/libbasic/login-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <stdbool.h>
#include <unistd.h>
diff --git a/src/libbasic/macro.h b/src/libbasic/macro.h
index 2695d0edb7..e41aa4260f 100644
--- a/src/libbasic/macro.h
+++ b/src/libbasic/macro.h
@@ -23,10 +23,15 @@
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
-#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+#ifdef __clang__
+# define _alloc_(...)
+#else
+# define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+#endif
#define _sentinel_ __attribute__ ((sentinel))
#define _unused_ __attribute__ ((unused))
#define _destructor_ __attribute__ ((destructor))
@@ -224,7 +229,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
/* We override the glibc assert() here. */
#undef assert
#ifdef NDEBUG
-#define assert(expr) do {} while(false)
+#define assert(expr) do {} while (false)
#else
#define assert(expr) assert_message_se(expr, #expr)
#endif
@@ -361,6 +366,12 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
_found; \
})
+#define SWAP_TWO(x, y) do { \
+ typeof(x) _t = (x); \
+ (x) = (y); \
+ (y) = (_t); \
+ } while (false)
+
/* Define C11 thread_local attribute even on older gcc compiler
* version */
#ifndef thread_local
diff --git a/src/libbasic/mempool.h b/src/libbasic/mempool.h
index fea7841bcf..0618b8dd22 100644
--- a/src/libbasic/mempool.h
+++ b/src/libbasic/mempool.h
@@ -36,7 +36,7 @@ void* mempool_alloc0_tile(struct mempool *mp);
void mempool_free_tile(struct mempool *mp, void *p);
#define DEFINE_MEMPOOL(pool_name, tile_type, alloc_at_least) \
-struct mempool pool_name = { \
+static struct mempool pool_name = { \
.tile_size = sizeof(tile_type), \
.at_least = alloc_at_least, \
}
diff --git a/src/libbasic/missing.h b/src/libbasic/missing.h
index 36b060496a..651e414395 100644
--- a/src/libbasic/missing.h
+++ b/src/libbasic/missing.h
@@ -31,6 +31,7 @@
#include <linux/neighbour.h>
#include <linux/oom.h>
#include <linux/rtnetlink.h>
+#include <net/ethernet.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/syscall.h>
@@ -134,84 +135,6 @@
#define SOL_SCTP 132
#endif
-#if !HAVE_DECL_PIVOT_ROOT
-static inline int pivot_root(const char *new_root, const char *put_old) {
- return syscall(SYS_pivot_root, new_root, put_old);
-}
-#endif
-
-#ifndef __NR_memfd_create
-# if defined __x86_64__
-# define __NR_memfd_create 319
-# elif defined __arm__
-# define __NR_memfd_create 385
-# elif defined __aarch64__
-# define __NR_memfd_create 279
-# elif defined __s390__
-# define __NR_memfd_create 350
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_memfd_create 4354
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_memfd_create 6318
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_memfd_create 5314
-# endif
-# elif defined __i386__
-# define __NR_memfd_create 356
-# else
-# warning "__NR_memfd_create unknown for your architecture"
-# define __NR_memfd_create 0xffffffff
-# endif
-#endif
-
-#ifndef HAVE_MEMFD_CREATE
-static inline int memfd_create(const char *name, unsigned int flags) {
- return syscall(__NR_memfd_create, name, flags);
-}
-#endif
-
-#ifndef __NR_getrandom
-# if defined __x86_64__
-# define __NR_getrandom 318
-# elif defined(__i386__)
-# define __NR_getrandom 355
-# elif defined(__arm__)
-# define __NR_getrandom 384
-# elif defined(__aarch64__)
-# define __NR_getrandom 278
-# elif defined(__ia64__)
-# define __NR_getrandom 1339
-# elif defined(__m68k__)
-# define __NR_getrandom 352
-# elif defined(__s390x__)
-# define __NR_getrandom 349
-# elif defined(__powerpc__)
-# define __NR_getrandom 359
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_getrandom 4353
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_getrandom 6317
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_getrandom 5313
-# endif
-# else
-# warning "__NR_getrandom unknown for your architecture"
-# define __NR_getrandom 0xffffffff
-# endif
-#endif
-
-#if !HAVE_DECL_GETRANDOM
-static inline int getrandom(void *buffer, size_t count, unsigned flags) {
- return syscall(__NR_getrandom, buffer, count, flags);
-}
-#endif
-
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK 0x0001
#endif
@@ -466,6 +389,10 @@ struct btrfs_ioctl_quota_ctl_args {
struct btrfs_ioctl_qgroup_limit_args)
#endif
+#ifndef BTRFS_IOC_QUOTA_RESCAN_WAIT
+#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
+#endif
+
#ifndef BTRFS_FIRST_FREE_OBJECTID
#define BTRFS_FIRST_FREE_OBJECTID 256
#endif
@@ -514,10 +441,18 @@ struct btrfs_ioctl_quota_ctl_args {
#define CGROUP_SUPER_MAGIC 0x27e0eb
#endif
+#ifndef CGROUP2_SUPER_MAGIC
+#define CGROUP2_SUPER_MAGIC 0x63677270
+#endif
+
#ifndef TMPFS_MAGIC
#define TMPFS_MAGIC 0x01021994
#endif
+#ifndef MQUEUE_MAGIC
+#define MQUEUE_MAGIC 0x19800202
+#endif
+
#ifndef MS_MOVE
#define MS_MOVE 8192
#endif
@@ -526,12 +461,6 @@ struct btrfs_ioctl_quota_ctl_args {
#define MS_PRIVATE (1 << 18)
#endif
-#if !HAVE_DECL_GETTID
-static inline pid_t gettid(void) {
- return (pid_t) syscall(SYS_gettid);
-}
-#endif
-
#ifndef SCM_SECURITY
#define SCM_SECURITY 0x03
#endif
@@ -560,32 +489,6 @@ static inline pid_t gettid(void) {
#define MAX_HANDLE_SZ 128
#endif
-#ifndef __NR_name_to_handle_at
-# if defined(__x86_64__)
-# define __NR_name_to_handle_at 303
-# elif defined(__i386__)
-# define __NR_name_to_handle_at 341
-# elif defined(__arm__)
-# define __NR_name_to_handle_at 370
-# elif defined(__powerpc__)
-# define __NR_name_to_handle_at 345
-# else
-# error "__NR_name_to_handle_at is not defined"
-# endif
-#endif
-
-#if !HAVE_DECL_NAME_TO_HANDLE_AT
-struct file_handle {
- unsigned int handle_bytes;
- int handle_type;
- unsigned char f_handle[0];
-};
-
-static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
- return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
-}
-#endif
-
#ifndef HAVE_SECURE_GETENV
# ifdef HAVE___SECURE_GETENV
# define secure_getenv __secure_getenv
@@ -634,22 +537,6 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle
#endif
-#ifndef __NR_setns
-# if defined(__x86_64__)
-# define __NR_setns 308
-# elif defined(__i386__)
-# define __NR_setns 346
-# else
-# error "__NR_setns is not defined"
-# endif
-#endif
-
-#if !HAVE_DECL_SETNS
-static inline int setns(int fd, int nstype) {
- return syscall(__NR_setns, fd, nstype);
-}
-#endif
-
#if !HAVE_DECL_LO_FLAGS_PARTSCAN
#define LO_FLAGS_PARTSCAN 8
#endif
@@ -674,7 +561,7 @@ static inline int setns(int fd, int nstype) {
#define IFLA_INET6_ADDR_GEN_MODE 8
#define __IFLA_INET6_MAX 9
-#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
#define IN6_ADDR_GEN_MODE_EUI64 0
#define IN6_ADDR_GEN_MODE_NONE 1
@@ -714,6 +601,7 @@ static inline int setns(int fd, int nstype) {
#endif
#if !HAVE_DECL_IFLA_PHYS_PORT_ID
+#define IFLA_EXT_MASK 29
#undef IFLA_PROMISCUITY
#define IFLA_PROMISCUITY 30
#define IFLA_NUM_TX_QUEUES 31
@@ -858,7 +746,7 @@ static inline int setns(int fd, int nstype) {
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
#endif
-#if !HAVE_DECL_IFLA_BR_PRIORITY
+#if !HAVE_DECL_IFLA_BR_VLAN_DEFAULT_PVID
#define IFLA_BR_UNSPEC 0
#define IFLA_BR_FORWARD_DELAY 1
#define IFLA_BR_HELLO_TIME 2
@@ -866,7 +754,40 @@ static inline int setns(int fd, int nstype) {
#define IFLA_BR_AGEING_TIME 4
#define IFLA_BR_STP_STATE 5
#define IFLA_BR_PRIORITY 6
-#define __IFLA_BR_MAX 7
+#define IFLA_BR_VLAN_FILTERING 7
+#define IFLA_BR_VLAN_PROTOCOL 8
+#define IFLA_BR_GROUP_FWD_MASK 9
+#define IFLA_BR_ROOT_ID 10
+#define IFLA_BR_BRIDGE_ID 11
+#define IFLA_BR_ROOT_PORT 12
+#define IFLA_BR_ROOT_PATH_COST 13
+#define IFLA_BR_TOPOLOGY_CHANGE 14
+#define IFLA_BR_TOPOLOGY_CHANGE_DETECTED 15
+#define IFLA_BR_HELLO_TIMER 16
+#define IFLA_BR_TCN_TIMER 17
+#define IFLA_BR_TOPOLOGY_CHANGE_TIMER 18
+#define IFLA_BR_GC_TIMER 19
+#define IFLA_BR_GROUP_ADDR 20
+#define IFLA_BR_FDB_FLUSH 21
+#define IFLA_BR_MCAST_ROUTER 22
+#define IFLA_BR_MCAST_SNOOPING 23
+#define IFLA_BR_MCAST_QUERY_USE_IFADDR 24
+#define IFLA_BR_MCAST_QUERIER 25
+#define IFLA_BR_MCAST_HASH_ELASTICITY 26
+#define IFLA_BR_MCAST_HASH_MAX 27
+#define IFLA_BR_MCAST_LAST_MEMBER_CNT 28
+#define IFLA_BR_MCAST_STARTUP_QUERY_CNT 29
+#define IFLA_BR_MCAST_LAST_MEMBER_INTVL 30
+#define IFLA_BR_MCAST_MEMBERSHIP_INTVL 31
+#define IFLA_BR_MCAST_QUERIER_INTVL 32
+#define IFLA_BR_MCAST_QUERY_INTVL 33
+#define IFLA_BR_MCAST_QUERY_RESPONSE_INTVL 34
+#define IFLA_BR_MCAST_STARTUP_QUERY_INTVL 35
+#define IFLA_BR_NF_CALL_IPTABLES 36
+#define IFLA_BR_NF_CALL_IP6TABLES 37
+#define IFLA_BR_NF_CALL_ARPTABLES 38
+#define IFLA_BR_VLAN_DEFAULT_PVID 39
+#define __IFLA_BR_MAX 40
#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
#endif
@@ -882,13 +803,16 @@ static inline int setns(int fd, int nstype) {
#define IFLA_BRPORT_FAST_LEAVE 7
#define IFLA_BRPORT_LEARNING 8
#define IFLA_BRPORT_UNICAST_FLOOD 9
-#define IFLA_BRPORT_PROXYARP 10
#define IFLA_BRPORT_LEARNING_SYNC 11
#define __IFLA_BRPORT_MAX 12
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
#endif
+#if !HAVE_DECL_IFLA_BRPORT_PROXYARP
+#define IFLA_BRPORT_PROXYARP 10
+#endif
+
#if !HAVE_DECL_NDA_IFINDEX
#define NDA_UNSPEC 0
#define NDA_DST 1
@@ -912,6 +836,10 @@ static inline int setns(int fd, int nstype) {
#define IPV6_UNICAST_IF 76
#endif
+#ifndef IPV6_MIN_MTU
+#define IPV6_MIN_MTU 1280
+#endif
+
#ifndef IFF_MULTI_QUEUE
#define IFF_MULTI_QUEUE 0x100
#endif
@@ -1013,69 +941,10 @@ static inline int setns(int fd, int nstype) {
#define CAP_AUDIT_READ 37
#endif
-static inline int raw_clone(unsigned long flags, void *child_stack) {
-#if defined(__s390__) || defined(__CRIS__)
- /* On s390 and cris the order of the first and second arguments
- * of the raw clone() system call is reversed. */
- return (int) syscall(__NR_clone, child_stack, flags);
-#else
- return (int) syscall(__NR_clone, flags, child_stack);
-#endif
-}
-
-static inline pid_t raw_getpid(void) {
-#if defined(__alpha__)
- return (pid_t) syscall(__NR_getxpid);
-#else
- return (pid_t) syscall(__NR_getpid);
-#endif
-}
-
-#if !HAVE_DECL_RENAMEAT2
-
-#ifndef __NR_renameat2
-# if defined __x86_64__
-# define __NR_renameat2 316
-# elif defined __arm__
-# define __NR_renameat2 382
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_renameat2 4351
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_renameat2 6315
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_renameat2 5311
-# endif
-# elif defined __i386__
-# define __NR_renameat2 353
-# else
-# warning "__NR_renameat2 unknown for your architecture"
-# define __NR_renameat2 0xffffffff
-# endif
-#endif
-
-static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
- return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
-}
-#endif
-
#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0)
#endif
-#if !HAVE_DECL_KCMP
-static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
-#if defined(__NR_kcmp)
- return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
-
#ifndef KCMP_FILE
#define KCMP_FILE 0
#endif
@@ -1088,39 +957,10 @@ static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, uns
#define INPUT_PROP_ACCELEROMETER 0x06
#endif
-#if !HAVE_DECL_KEY_SERIAL_T
+#ifndef HAVE_KEY_SERIAL_T
typedef int32_t key_serial_t;
#endif
-#if !HAVE_DECL_KEYCTL
-static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
-#if defined(__NR_keyctl)
- return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
-#if defined (__NR_add_key)
- return syscall(__NR_add_key, type, description, payload, plen, ringid);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
-#if defined (__NR_request_key)
- return syscall(__NR_request_key, type, description, callout_info, destringid);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
-
#ifndef KEYCTL_READ
#define KEYCTL_READ 11
#endif
@@ -1159,12 +999,18 @@ static inline key_serial_t request_key(const char *type, const char *description
#ifndef IF_OPER_UP
#define IF_OPER_UP 6
-#ifndef HAVE_DECL_CHAR32_T
+#ifndef HAVE_CHAR32_T
#define char32_t uint32_t
#endif
-#ifndef HAVE_DECL_CHAR16_T
+#ifndef HAVE_CHAR16_T
#define char16_t uint16_t
#endif
+#ifndef ETHERTYPE_LLDP
+#define ETHERTYPE_LLDP 0x88cc
#endif
+
+#endif
+
+#include "missing_syscall.h"
diff --git a/src/libbasic/missing_syscall.h b/src/libbasic/missing_syscall.h
new file mode 100644
index 0000000000..d502d3b9ca
--- /dev/null
+++ b/src/libbasic/missing_syscall.h
@@ -0,0 +1,310 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ 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/>.
+***/
+
+/* Missing glibc definitions to access certain kernel APIs */
+
+#if !HAVE_DECL_PIVOT_ROOT
+static inline int pivot_root(const char *new_root, const char *put_old) {
+ return syscall(SYS_pivot_root, new_root, put_old);
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_MEMFD_CREATE
+# ifndef __NR_memfd_create
+# if defined __x86_64__
+# define __NR_memfd_create 319
+# elif defined __arm__
+# define __NR_memfd_create 385
+# elif defined __aarch64__
+# define __NR_memfd_create 279
+# elif defined __s390__
+# define __NR_memfd_create 350
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_memfd_create 4354
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_memfd_create 6318
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_memfd_create 5314
+# endif
+# elif defined __i386__
+# define __NR_memfd_create 356
+# else
+# warning "__NR_memfd_create unknown for your architecture"
+# endif
+# endif
+
+static inline int memfd_create(const char *name, unsigned int flags) {
+# ifdef __NR_memfd_create
+ return syscall(__NR_memfd_create, name, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_GETRANDOM
+# ifndef __NR_getrandom
+# if defined __x86_64__
+# define __NR_getrandom 318
+# elif defined(__i386__)
+# define __NR_getrandom 355
+# elif defined(__arm__)
+# define __NR_getrandom 384
+# elif defined(__aarch64__)
+# define __NR_getrandom 278
+# elif defined(__ia64__)
+# define __NR_getrandom 1339
+# elif defined(__m68k__)
+# define __NR_getrandom 352
+# elif defined(__s390x__)
+# define __NR_getrandom 349
+# elif defined(__powerpc__)
+# define __NR_getrandom 359
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_getrandom 4353
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_getrandom 6317
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_getrandom 5313
+# endif
+# else
+# warning "__NR_getrandom unknown for your architecture"
+# endif
+# endif
+
+static inline int getrandom(void *buffer, size_t count, unsigned flags) {
+# ifdef __NR_getrandom
+ return syscall(__NR_getrandom, buffer, count, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_GETTID
+static inline pid_t gettid(void) {
+ return (pid_t) syscall(SYS_gettid);
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_NAME_TO_HANDLE_AT
+# ifndef __NR_name_to_handle_at
+# if defined(__x86_64__)
+# define __NR_name_to_handle_at 303
+# elif defined(__i386__)
+# define __NR_name_to_handle_at 341
+# elif defined(__arm__)
+# define __NR_name_to_handle_at 370
+# elif defined(__powerpc__)
+# define __NR_name_to_handle_at 345
+# else
+# error "__NR_name_to_handle_at is not defined"
+# endif
+# endif
+
+struct file_handle {
+ unsigned int handle_bytes;
+ int handle_type;
+ unsigned char f_handle[0];
+};
+
+static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
+# ifdef __NR_name_to_handle_at
+ return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_SETNS
+# ifndef __NR_setns
+# if defined(__x86_64__)
+# define __NR_setns 308
+# elif defined(__i386__)
+# define __NR_setns 346
+# else
+# error "__NR_setns is not defined"
+# endif
+# endif
+
+static inline int setns(int fd, int nstype) {
+# ifdef __NR_setns
+ return syscall(__NR_setns, fd, nstype);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+static inline int raw_clone(unsigned long flags, void *child_stack) {
+#if defined(__s390__) || defined(__CRIS__)
+ /* On s390 and cris the order of the first and second arguments
+ * of the raw clone() system call is reversed. */
+ return (int) syscall(__NR_clone, child_stack, flags);
+#else
+ return (int) syscall(__NR_clone, flags, child_stack);
+#endif
+}
+
+/* ======================================================================= */
+
+static inline pid_t raw_getpid(void) {
+#if defined(__alpha__)
+ return (pid_t) syscall(__NR_getxpid);
+#else
+ return (pid_t) syscall(__NR_getpid);
+#endif
+}
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_RENAMEAT2
+# ifndef __NR_renameat2
+# if defined __x86_64__
+# define __NR_renameat2 316
+# elif defined __arm__
+# define __NR_renameat2 382
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_renameat2 4351
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_renameat2 6315
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_renameat2 5311
+# endif
+# elif defined __i386__
+# define __NR_renameat2 353
+# else
+# warning "__NR_renameat2 unknown for your architecture"
+# endif
+# endif
+
+static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
+# ifdef __NR_renameat2
+ return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_KCMP
+static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
+# ifdef __NR_kcmp
+ return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_KEYCTL
+static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
+# ifdef __NR_keyctl
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
+# ifdef __NR_add_key
+ return syscall(__NR_add_key, type, description, payload, plen, ringid);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
+# ifdef __NR_request_key
+ return syscall(__NR_request_key, type, description, callout_info, destringid);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_COPY_FILE_RANGE
+# ifndef __NR_copy_file_range
+# if defined(__x86_64__)
+# define __NR_copy_file_range 326
+# elif defined(__i386__)
+# define __NR_copy_file_range 377
+# elif defined __s390__
+# define __NR_copy_file_range 375
+# elif defined __arm__
+# define __NR_copy_file_range 391
+# elif defined __aarch64__
+# define __NR_copy_file_range 285
+# else
+# warning "__NR_copy_file_range not defined for your architecture"
+# endif
+# endif
+
+static inline ssize_t copy_file_range(int fd_in, loff_t *off_in,
+ int fd_out, loff_t *off_out,
+ size_t len,
+ unsigned int flags) {
+# ifdef __NR_copy_file_range
+ return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
diff --git a/src/libbasic/mount-util.c b/src/libbasic/mount-util.c
index 33f2ee96d8..ba698959b7 100644
--- a/src/libbasic/mount-util.c
+++ b/src/libbasic/mount-util.c
@@ -47,7 +47,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id
if ((flags & AT_EMPTY_PATH) && isempty(filename))
xsprintf(path, "/proc/self/fdinfo/%i", fd);
else {
- subfd = openat(fd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
+ subfd = openat(fd, filename, O_CLOEXEC|O_PATH);
if (subfd < 0)
return -errno;
@@ -230,7 +230,7 @@ int path_is_mount_point(const char *t, int flags) {
if (!parent)
return -ENOMEM;
- fd = openat(AT_FDCWD, parent, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_PATH);
+ fd = openat(AT_FDCWD, parent, O_DIRECTORY|O_CLOEXEC|O_PATH);
if (fd < 0)
return -errno;
@@ -498,7 +498,9 @@ bool fstype_is_network(const char *fstype) {
"nfs4\0"
"gfs\0"
"gfs2\0"
- "glusterfs\0";
+ "glusterfs\0"
+ "pvfs2\0" /* OrangeFS */
+ ;
const char *x;
diff --git a/src/libbasic/nss-util.h b/src/libbasic/nss-util.h
index df565a3593..bf7c4854fc 100644
--- a/src/libbasic/nss-util.h
+++ b/src/libbasic/nss-util.h
@@ -154,3 +154,46 @@ enum nss_status _nss_##module##_getgrgid_r( \
struct group *gr, \
char *buffer, size_t buflen, \
int *errnop) _public_
+
+typedef enum nss_status (*_nss_gethostbyname4_r_t)(
+ const char *name,
+ struct gaih_addrtuple **pat,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp);
+
+typedef enum nss_status (*_nss_gethostbyname3_r_t)(
+ const char *name,
+ int af,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp,
+ char **canonp);
+
+typedef enum nss_status (*_nss_gethostbyname2_r_t)(
+ const char *name,
+ int af,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop);
+
+typedef enum nss_status (*_nss_gethostbyname_r_t)(
+ const char *name,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop);
+
+typedef enum nss_status (*_nss_gethostbyaddr2_r_t)(
+ const void* addr, socklen_t len,
+ int af,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp);
+typedef enum nss_status (*_nss_gethostbyaddr_r_t)(
+ const void* addr, socklen_t len,
+ int af,
+ struct hostent *host,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop);
diff --git a/src/libbasic/parse-util.c b/src/libbasic/parse-util.c
index a3cb81b040..6c11b605a9 100644
--- a/src/libbasic/parse-util.c
+++ b/src/libbasic/parse-util.c
@@ -505,7 +505,7 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
s = *p;
/* accept any number of digits, strtoull is limted to 19 */
- for(i=0; i < digits; i++,s++) {
+ for (i=0; i < digits; i++,s++) {
if (*s < '0' || *s > '9') {
if (i == 0)
return -EINVAL;
diff --git a/src/libbasic/parse-util.h b/src/libbasic/parse-util.h
index d8dc26a36e..7dc579a159 100644
--- a/src/libbasic/parse-util.h
+++ b/src/libbasic/parse-util.h
@@ -90,6 +90,18 @@ static inline int safe_atoli(const char *s, long int *ret_u) {
}
#endif
+#if SIZE_MAX == UINT_MAX
+static inline int safe_atozu(const char *s, size_t *ret_u) {
+ assert_cc(sizeof(size_t) == sizeof(unsigned));
+ return safe_atou(s, (unsigned *) ret_u);
+}
+#else
+static inline int safe_atozu(const char *s, size_t *ret_u) {
+ assert_cc(sizeof(size_t) == sizeof(long unsigned));
+ return safe_atolu(s, ret_u);
+}
+#endif
+
int safe_atod(const char *s, double *ret_d);
int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
diff --git a/src/libbasic/path-util.c b/src/libbasic/path-util.c
index 822c09bfba..b2fa81a294 100644
--- a/src/libbasic/path-util.c
+++ b/src/libbasic/path-util.c
@@ -569,10 +569,10 @@ static int binary_is_good(const char *binary) {
if (r < 0)
return r;
- return !path_equal(d, "true") &&
- !path_equal(d, "/bin/true") &&
- !path_equal(d, "/usr/bin/true") &&
- !path_equal(d, "/dev/null");
+ return !PATH_IN_SET(d, "true"
+ "/bin/true",
+ "/usr/bin/true",
+ "/dev/null");
}
int fsck_exists(const char *fstype) {
@@ -756,34 +756,53 @@ char *file_in_same_dir(const char *path, const char *filename) {
return ret;
}
-bool hidden_file_allow_backup(const char *filename) {
- assert(filename);
-
- return
- filename[0] == '.' ||
- streq(filename, "lost+found") ||
- streq(filename, "aquota.user") ||
- streq(filename, "aquota.group") ||
- endswith(filename, ".rpmnew") ||
- endswith(filename, ".rpmsave") ||
- endswith(filename, ".rpmorig") ||
- endswith(filename, ".dpkg-old") ||
- endswith(filename, ".dpkg-new") ||
- endswith(filename, ".dpkg-tmp") ||
- endswith(filename, ".dpkg-dist") ||
- endswith(filename, ".dpkg-bak") ||
- endswith(filename, ".dpkg-backup") ||
- endswith(filename, ".dpkg-remove") ||
- endswith(filename, ".swp");
-}
+bool hidden_or_backup_file(const char *filename) {
+ const char *p;
-bool hidden_file(const char *filename) {
assert(filename);
- if (endswith(filename, "~"))
+ if (filename[0] == '.' ||
+ streq(filename, "lost+found") ||
+ streq(filename, "aquota.user") ||
+ streq(filename, "aquota.group") ||
+ endswith(filename, "~"))
return true;
- return hidden_file_allow_backup(filename);
+ p = strrchr(filename, '.');
+ if (!p)
+ return false;
+
+ /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up
+ * with always new suffixes and that everybody else should just adjust to that, then it really should be on
+ * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt
+ * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional
+ * string. Specifically: there's now:
+ *
+ * The generic suffixes "~" and ".bak" for backup files
+ * The generic prefix "." for hidden files
+ *
+ * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist"
+ * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead.
+ */
+
+ return STR_IN_SET(p + 1,
+ "rpmnew",
+ "rpmsave",
+ "rpmorig",
+ "dpkg-old",
+ "dpkg-new",
+ "dpkg-tmp",
+ "dpkg-dist",
+ "dpkg-bak",
+ "dpkg-backup",
+ "dpkg-remove",
+ "ucf-new",
+ "ucf-old",
+ "ucf-dist",
+ "swp",
+ "bak",
+ "old",
+ "new");
}
bool is_device_path(const char *path) {
diff --git a/src/libbasic/path-util.h b/src/libbasic/path-util.h
index 2c2f87a9f2..a27c13fcc3 100644
--- a/src/libbasic/path-util.h
+++ b/src/libbasic/path-util.h
@@ -48,6 +48,23 @@ bool path_equal(const char *a, const char *b) _pure_;
bool path_equal_or_files_same(const char *a, const char *b);
char* path_join(const char *root, const char *path, const char *rest);
+static inline bool path_equal_ptr(const char *a, const char *b) {
+ return !!a == !!b && (!a || path_equal(a, b));
+}
+
+/* Note: the search terminates on the first NULL item. */
+#define PATH_IN_SET(p, ...) \
+ ({ \
+ char **s; \
+ bool _found = false; \
+ STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \
+ if (path_equal(p, *s)) { \
+ _found = true; \
+ break; \
+ } \
+ _found; \
+ })
+
int path_strv_make_absolute_cwd(char **l);
char** path_strv_resolve(char **l, const char *prefix);
char** path_strv_resolve_uniq(char **l, const char *prefix);
@@ -105,7 +122,6 @@ bool path_is_safe(const char *p) _pure_;
char *file_in_same_dir(const char *path, const char *filename);
-bool hidden_file_allow_backup(const char *filename);
-bool hidden_file(const char *filename) _pure_;
+bool hidden_or_backup_file(const char *filename) _pure_;
bool is_device_path(const char *path);
diff --git a/src/libbasic/process-util.c b/src/libbasic/process-util.c
index 189ef9ab60..1ad8816206 100644
--- a/src/libbasic/process-util.c
+++ b/src/libbasic/process-util.c
@@ -38,6 +38,7 @@
#endif
#include "alloc-util.h"
+#include "architecture.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
@@ -205,7 +206,7 @@ void rename_process(const char name[8]) {
* "systemd"). If you pass a longer string it will be
* truncated */
- prctl(PR_SET_NAME, name);
+ (void) prctl(PR_SET_NAME, name);
if (program_invocation_name)
strncpy(program_invocation_name, name, strlen(program_invocation_name));
@@ -527,14 +528,20 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_cod
return -EPROTO;
}
-void sigkill_wait(pid_t *pid) {
+void sigkill_wait(pid_t pid) {
+ assert(pid > 1);
+
+ if (kill(pid, SIGKILL) > 0)
+ (void) wait_for_terminate(pid, NULL);
+}
+
+void sigkill_waitp(pid_t *pid) {
if (!pid)
return;
if (*pid <= 1)
return;
- if (kill(*pid, SIGKILL) > 0)
- (void) wait_for_terminate(*pid, NULL);
+ sigkill_wait(*pid);
}
int kill_and_sigcont(pid_t pid, int sig) {
@@ -660,6 +667,8 @@ bool is_main_thread(void) {
noreturn void freeze(void) {
+ log_close();
+
/* Make sure nobody waits for us on a socket anymore */
close_all_fds(NULL, 0);
@@ -674,75 +683,43 @@ bool oom_score_adjust_is_valid(int oa) {
}
unsigned long personality_from_string(const char *p) {
+ int architecture;
- /* Parse a personality specifier. We introduce our own
- * identifiers that indicate specific ABIs, rather than just
- * hints regarding the register size, since we want to keep
- * things open for multiple locally supported ABIs for the
- * same register size. We try to reuse the ABI identifiers
- * used by libseccomp. */
-
-#if defined(__x86_64__)
-
- if (streq(p, "x86"))
- return PER_LINUX32;
+ if (!p)
+ return PERSONALITY_INVALID;
- if (streq(p, "x86-64"))
- return PER_LINUX;
+ /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just
+ * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for
+ * the same register size. */
-#elif defined(__i386__)
+ architecture = architecture_from_string(p);
+ if (architecture < 0)
+ return PERSONALITY_INVALID;
- if (streq(p, "x86"))
+ if (architecture == native_architecture())
return PER_LINUX;
-
-#elif defined(__s390x__)
-
- if (streq(p, "s390"))
+#ifdef SECONDARY_ARCHITECTURE
+ if (architecture == SECONDARY_ARCHITECTURE)
return PER_LINUX32;
-
- if (streq(p, "s390x"))
- return PER_LINUX;
-
-#elif defined(__s390__)
-
- if (streq(p, "s390"))
- return PER_LINUX;
#endif
return PERSONALITY_INVALID;
}
const char* personality_to_string(unsigned long p) {
-
-#if defined(__x86_64__)
-
- if (p == PER_LINUX32)
- return "x86";
-
- if (p == PER_LINUX)
- return "x86-64";
-
-#elif defined(__i386__)
-
- if (p == PER_LINUX)
- return "x86";
-
-#elif defined(__s390x__)
-
- if (p == PER_LINUX)
- return "s390x";
-
- if (p == PER_LINUX32)
- return "s390";
-
-#elif defined(__s390__)
+ int architecture = _ARCHITECTURE_INVALID;
if (p == PER_LINUX)
- return "s390";
-
+ architecture = native_architecture();
+#ifdef SECONDARY_ARCHITECTURE
+ else if (p == PER_LINUX32)
+ architecture = SECONDARY_ARCHITECTURE;
#endif
- return NULL;
+ if (architecture < 0)
+ return NULL;
+
+ return architecture_to_string(architecture);
}
void valgrind_summary_hack(void) {
@@ -762,6 +739,18 @@ void valgrind_summary_hack(void) {
#endif
}
+int pid_compare_func(const void *a, const void *b) {
+ const pid_t *p = a, *q = b;
+
+ /* Suitable for usage in qsort() */
+
+ if (*p < *q)
+ return -1;
+ if (*p > *q)
+ return 1;
+ return 0;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/libbasic/process-util.h b/src/libbasic/process-util.h
index f5d193e762..9f75088796 100644
--- a/src/libbasic/process-util.h
+++ b/src/libbasic/process-util.h
@@ -58,8 +58,8 @@ int get_process_ppid(pid_t pid, pid_t *ppid);
int wait_for_terminate(pid_t pid, siginfo_t *status);
int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
-void sigkill_wait(pid_t *pid);
-#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
+void sigkill_wait(pid_t pid);
+void sigkill_waitp(pid_t *pid);
int kill_and_sigcont(pid_t pid, int sig);
@@ -101,3 +101,5 @@ int sched_policy_from_string(const char *s);
#define PID_TO_PTR(p) ((void*) ((uintptr_t) p))
void valgrind_summary_hack(void);
+
+int pid_compare_func(const void *a, const void *b);
diff --git a/src/libbasic/rlimit-util.c b/src/libbasic/rlimit-util.c
index 7540b43215..ee063720ed 100644
--- a/src/libbasic/rlimit-util.c
+++ b/src/libbasic/rlimit-util.c
@@ -153,6 +153,56 @@ static int rlimit_parse_usec(const char *val, rlim_t *ret) {
return 0;
}
+static int rlimit_parse_nice(const char *val, rlim_t *ret) {
+ uint64_t rl;
+ int r;
+
+ /* So, Linux is weird. The range for RLIMIT_NICE is 40..1, mapping to the nice levels -20..19. However, the
+ * RLIMIT_NICE limit defaults to 0 by the kernel, i.e. a value that maps to nice level 20, which of course is
+ * bogus and does not exist. In order to permit parsing the RLIMIT_NICE of 0 here we hence implement a slight
+ * asymmetry: when parsing as positive nice level we permit 0..19. When parsing as negative nice level, we
+ * permit -20..0. But when parsing as raw resource limit value then we also allow the special value 0.
+ *
+ * Yeah, Linux is quality engineering sometimes... */
+
+ if (val[0] == '+') {
+
+ /* Prefixed with "+": Parse as positive user-friendly nice value */
+ r = safe_atou64(val + 1, &rl);
+ if (r < 0)
+ return r;
+
+ if (rl >= PRIO_MAX)
+ return -ERANGE;
+
+ rl = 20 - rl;
+
+ } else if (val[0] == '-') {
+
+ /* Prefixed with "-": Parse as negative user-friendly nice value */
+ r = safe_atou64(val + 1, &rl);
+ if (r < 0)
+ return r;
+
+ if (rl > (uint64_t) (-PRIO_MIN))
+ return -ERANGE;
+
+ rl = 20 + rl;
+ } else {
+
+ /* Not prefixed: parse as raw resource limit value */
+ r = safe_atou64(val, &rl);
+ if (r < 0)
+ return r;
+
+ if (rl > (uint64_t) (20 - PRIO_MIN))
+ return -ERANGE;
+ }
+
+ *ret = (rlim_t) rl;
+ return 0;
+}
+
static int (*const rlimit_parse_table[_RLIMIT_MAX])(const char *val, rlim_t *ret) = {
[RLIMIT_CPU] = rlimit_parse_sec,
[RLIMIT_FSIZE] = rlimit_parse_size,
@@ -167,7 +217,7 @@ static int (*const rlimit_parse_table[_RLIMIT_MAX])(const char *val, rlim_t *ret
[RLIMIT_LOCKS] = rlimit_parse_u64,
[RLIMIT_SIGPENDING] = rlimit_parse_u64,
[RLIMIT_MSGQUEUE] = rlimit_parse_size,
- [RLIMIT_NICE] = rlimit_parse_u64,
+ [RLIMIT_NICE] = rlimit_parse_nice,
[RLIMIT_RTPRIO] = rlimit_parse_u64,
[RLIMIT_RTTIME] = rlimit_parse_usec,
};
diff --git a/src/libbasic/rm-rf.h b/src/libbasic/rm-rf.h
index 6d03268919..f693a5bb7c 100644
--- a/src/libbasic/rm-rf.h
+++ b/src/libbasic/rm-rf.h
@@ -30,3 +30,12 @@ typedef enum RemoveFlags {
int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev);
int rm_rf(const char *path, RemoveFlags flags);
+
+/* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
+static inline void rm_rf_physical_and_free(char *p) {
+ if (!p)
+ return;
+ (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
+ free(p);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rm_rf_physical_and_free);
diff --git a/src/libbasic/selinux-util.c b/src/libbasic/selinux-util.c
index 6c63b9d652..10c2f39369 100644
--- a/src/libbasic/selinux-util.c
+++ b/src/libbasic/selinux-util.c
@@ -80,31 +80,23 @@ void mac_selinux_retest(void) {
#endif
}
-int mac_selinux_init(const char *prefix) {
+int mac_selinux_init(void) {
int r = 0;
#ifdef HAVE_SELINUX
usec_t before_timestamp, after_timestamp;
struct mallinfo before_mallinfo, after_mallinfo;
- if (!mac_selinux_use())
+ if (label_hnd)
return 0;
- if (label_hnd)
+ if (!mac_selinux_use())
return 0;
before_mallinfo = mallinfo();
before_timestamp = now(CLOCK_MONOTONIC);
- if (prefix) {
- struct selinux_opt options[] = {
- { .type = SELABEL_OPT_SUBSET, .value = prefix },
- };
-
- label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options));
- } else
- label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
-
+ label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
if (!label_hnd) {
log_enforcing("Failed to initialize SELinux context: %m");
r = security_getenforce() == 1 ? -errno : 0;
@@ -160,7 +152,7 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
return 0;
if (r >= 0) {
- r = lsetfilecon(path, fcon);
+ r = lsetfilecon_raw(path, fcon);
/* If the FS doesn't support labels, then exit without warning */
if (r < 0 && errno == EOPNOTSUPP)
@@ -225,7 +217,7 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
return -errno;
sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+ r = security_compute_create_raw(mycon, fcon, sclass, (security_context_t *) label);
if (r < 0)
return -errno;
#endif
@@ -270,7 +262,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
if (r < 0)
return -errno;
- r = getpeercon(socket_fd, &peercon);
+ r = getpeercon_raw(socket_fd, &peercon);
if (r < 0)
return -errno;
@@ -304,7 +296,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
return -ENOMEM;
sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+ r = security_compute_create_raw(mycon, fcon, sclass, (security_context_t *) label);
if (r < 0)
return -errno;
#endif
@@ -358,7 +350,7 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
log_enforcing("Failed to determine SELinux security context for %s: %m", path);
} else {
- if (setfscreatecon(filecon) >= 0)
+ if (setfscreatecon_raw(filecon) >= 0)
return 0; /* Success! */
log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path);
@@ -379,7 +371,7 @@ void mac_selinux_create_file_clear(void) {
if (!mac_selinux_use())
return;
- setfscreatecon(NULL);
+ setfscreatecon_raw(NULL);
#endif
}
@@ -410,7 +402,7 @@ void mac_selinux_create_socket_clear(void) {
if (!mac_selinux_use())
return;
- setsockcreatecon(NULL);
+ setsockcreatecon_raw(NULL);
#endif
}
@@ -469,7 +461,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
return -errno;
} else {
- if (setfscreatecon(fcon) < 0) {
+ if (setfscreatecon_raw(fcon) < 0) {
log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
if (security_getenforce() > 0)
return -errno;
@@ -480,7 +472,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
r = bind(fd, addr, addrlen) < 0 ? -errno : 0;
if (context_changed)
- setfscreatecon(NULL);
+ setfscreatecon_raw(NULL);
return r;
diff --git a/src/libbasic/selinux-util.h b/src/libbasic/selinux-util.h
index 27e8edb41b..ce6bc8e44c 100644
--- a/src/libbasic/selinux-util.h
+++ b/src/libbasic/selinux-util.h
@@ -29,7 +29,7 @@ bool mac_selinux_use(void);
bool mac_selinux_have(void);
void mac_selinux_retest(void);
-int mac_selinux_init(const char *prefix);
+int mac_selinux_init(void);
void mac_selinux_finish(void);
int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
diff --git a/src/libbasic/set.h b/src/libbasic/set.h
index 2bff5062da..e0d9dd001c 100644
--- a/src/libbasic/set.h
+++ b/src/libbasic/set.h
@@ -126,6 +126,9 @@ int set_put_strdupv(Set *s, char **l);
#define SET_FOREACH(e, s, i) \
for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
+#define SET_FOREACH_MOVE(e, d, s) \
+ for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); )
+
DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free);
DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
diff --git a/src/libbasic/sigbus.h b/src/libbasic/sigbus.h
index cce9eb201b..980243d9ce 100644
--- a/src/libbasic/sigbus.h
+++ b/src/libbasic/sigbus.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
void sigbus_install(void);
void sigbus_reset(void);
diff --git a/src/libbasic/signal-util.c b/src/libbasic/signal-util.c
index e3047b209b..280b5c3251 100644
--- a/src/libbasic/signal-util.c
+++ b/src/libbasic/signal-util.c
@@ -255,7 +255,7 @@ int signal_from_string(const char *s) {
}
if (safe_atou(s, &u) >= 0) {
signo = (int) u + offset;
- if (signo > 0 && signo < _NSIG)
+ if (SIGNAL_VALID(signo))
return signo;
}
return -EINVAL;
diff --git a/src/libbasic/signal-util.h b/src/libbasic/signal-util.h
index 72b10e8712..dfd6eb564d 100644
--- a/src/libbasic/signal-util.h
+++ b/src/libbasic/signal-util.h
@@ -44,9 +44,13 @@ static inline void block_signals_reset(sigset_t *ss) {
assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
}
-#define BLOCK_SIGNALS(...) \
- _cleanup_(block_signals_reset) sigset_t _saved_sigset = ({ \
- sigset_t t; \
+#define BLOCK_SIGNALS(...) \
+ _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
+ sigset_t t; \
assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \
- t; \
+ t; \
})
+
+static inline bool SIGNAL_VALID(int signo) {
+ return signo > 0 && signo < _NSIG;
+}
diff --git a/src/libbasic/socket-label.c b/src/libbasic/socket-label.c
index 35e9573aa4..6d1dc83874 100644
--- a/src/libbasic/socket-label.c
+++ b/src/libbasic/socket-label.c
@@ -23,7 +23,6 @@
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
-#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
@@ -35,6 +34,7 @@
#include "mkdir.h"
#include "selinux-util.h"
#include "socket-util.h"
+#include "umask-util.h"
int socket_address_listen(
const SocketAddress *a,
@@ -112,28 +112,24 @@ int socket_address_listen(
return -errno;
if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) {
- mode_t old_mask;
-
/* Create parents */
- mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode);
+ (void) mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode);
/* Enforce the right access mode for the socket */
- old_mask = umask(~ socket_mode);
-
- r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
-
- if (r < 0 && errno == EADDRINUSE) {
- /* Unlink and try again */
- unlink(a->sockaddr.un.sun_path);
- r = bind(fd, &a->sockaddr.sa, a->size);
+ RUN_WITH_UMASK(~socket_mode) {
+ r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
+ if (r == -EADDRINUSE) {
+ /* Unlink and try again */
+ unlink(a->sockaddr.un.sun_path);
+ if (bind(fd, &a->sockaddr.sa, a->size) < 0)
+ return -errno;
+ } else if (r < 0)
+ return r;
}
-
- umask(old_mask);
- } else
- r = bind(fd, &a->sockaddr.sa, a->size);
-
- if (r < 0)
- return -errno;
+ } else {
+ if (bind(fd, &a->sockaddr.sa, a->size) < 0)
+ return -errno;
+ }
if (socket_address_can_accept(a))
if (listen(fd, backlog) < 0)
diff --git a/src/libbasic/socket-util.c b/src/libbasic/socket-util.c
index 58512686e3..c8769a54f4 100644
--- a/src/libbasic/socket-util.c
+++ b/src/libbasic/socket-util.c
@@ -23,6 +23,7 @@
#include <net/if.h>
#include <netdb.h>
#include <netinet/ip.h>
+#include <poll.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,7 +43,9 @@
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strv.h"
#include "user-util.h"
+#include "utf8.h"
#include "util.h"
int socket_address_parse(SocketAddress *a, const char *s) {
@@ -794,6 +797,42 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
+bool ifname_valid(const char *p) {
+ bool numeric = true;
+
+ /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
+ * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
+ * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
+
+ if (isempty(p))
+ return false;
+
+ if (strlen(p) >= IFNAMSIZ)
+ return false;
+
+ if (STR_IN_SET(p, ".", ".."))
+ return false;
+
+ while (*p) {
+ if ((unsigned char) *p >= 127U)
+ return false;
+
+ if ((unsigned char) *p <= 32U)
+ return false;
+
+ if (*p == ':' || *p == '/')
+ return false;
+
+ numeric = numeric && (*p >= '0' && *p <= '9');
+ p++;
+ }
+
+ if (numeric)
+ return false;
+
+ return true;
+}
+
int getpeercred(int fd, struct ucred *ucred) {
socklen_t n = sizeof(struct ucred);
struct ucred u;
@@ -942,7 +981,7 @@ ssize_t next_datagram_size_fd(int fd) {
int k;
/* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will
- * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD dosn't
+ * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
* do. This difference is actually of major importance as we need to be sure that the size returned here
* actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of
* the wrong size. */
@@ -970,3 +1009,42 @@ fallback:
return (ssize_t) k;
}
+
+int flush_accept(int fd) {
+
+ struct pollfd pollfd = {
+ .fd = fd,
+ .events = POLLIN,
+ };
+ int r;
+
+
+ /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
+
+ for (;;) {
+ int cfd;
+
+ r = poll(&pollfd, 1, 0);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -errno;
+
+ } else if (r == 0)
+ return 0;
+
+ cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
+ if (cfd < 0) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN)
+ return 0;
+
+ return -errno;
+ }
+
+ close(cfd);
+ }
+}
diff --git a/src/libbasic/socket-util.h b/src/libbasic/socket-util.h
index d17a2f35f8..e9230e4a9f 100644
--- a/src/libbasic/socket-util.h
+++ b/src/libbasic/socket-util.h
@@ -123,6 +123,8 @@ int fd_inc_rcvbuf(int fd, size_t n);
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
+bool ifname_valid(const char *p);
+
int getpeercred(int fd, struct ucred *ucred);
int getpeersec(int fd, char **ret);
@@ -135,5 +137,18 @@ int receive_one_fd(int transport_fd, int flags);
ssize_t next_datagram_size_fd(int fd);
+int flush_accept(int fd);
+
#define CMSG_FOREACH(cmsg, mh) \
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
+
+/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
+#define SOCKADDR_UN_LEN(sa) \
+ ({ \
+ const struct sockaddr_un *_sa = &(sa); \
+ assert(_sa->sun_family == AF_UNIX); \
+ offsetof(struct sockaddr_un, sun_path) + \
+ (_sa->sun_path[0] == 0 ? \
+ 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
+ strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
+ })
diff --git a/src/libbasic/special.h b/src/libbasic/special.h
index 2fd03d9f75..084d3dfa23 100644
--- a/src/libbasic/special.h
+++ b/src/libbasic/special.h
@@ -52,6 +52,7 @@
#define SPECIAL_LOCAL_FS_TARGET "local-fs.target"
#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target"
#define SPECIAL_INITRD_FS_TARGET "initrd-fs.target"
+#define SPECIAL_INITRD_ROOT_DEVICE_TARGET "initrd-root-device.target"
#define SPECIAL_INITRD_ROOT_FS_TARGET "initrd-root-fs.target"
#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */
#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target"
diff --git a/src/libbasic/stdio-util.h b/src/libbasic/stdio-util.h
index 0a675571ff..bd1144b4c9 100644
--- a/src/libbasic/stdio-util.h
+++ b/src/libbasic/stdio-util.h
@@ -73,4 +73,4 @@ do { \
assert_not_reached("Unknown format string argument."); \
} \
} \
-} while(false)
+} while (false)
diff --git a/src/libbasic/strbuf.c b/src/libbasic/strbuf.c
index 77220c0251..4bef87d3c2 100644
--- a/src/libbasic/strbuf.c
+++ b/src/libbasic/strbuf.c
@@ -121,7 +121,7 @@ static void bubbleinsert(struct strbuf_node *node,
sizeof(struct strbuf_child_entry) * (node->children_count - left));
node->children[left] = new;
- node->children_count ++;
+ node->children_count++;
}
/* add string, return the index/offset into the buffer */
@@ -156,8 +156,13 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
return off;
}
- /* lookup child node */
c = s[len - 1 - depth];
+
+ /* bsearch is not allowed on a NULL sequence */
+ if (node->children_count == 0)
+ break;
+
+ /* lookup child node */
search.c = c;
child = bsearch(&search, node->children, node->children_count,
sizeof(struct strbuf_child_entry),
diff --git a/src/libbasic/string-table.h b/src/libbasic/string-table.h
index b180488fe8..d88625fca7 100644
--- a/src/libbasic/string-table.h
+++ b/src/libbasic/string-table.h
@@ -56,26 +56,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
}
-#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
-
-#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
-
-/* For string conversions where numbers are also acceptable */
-#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
- int name##_to_string_alloc(type i, char **str) { \
+#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \
+ scope int name##_to_string_alloc(type i, char **str) { \
char *s; \
if (i < 0 || i > max) \
return -ERANGE; \
@@ -89,7 +71,9 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
} \
*str = s; \
return 0; \
- } \
+ }
+
+#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \
type name##_from_string(const char *s) { \
type i; \
unsigned u = 0; \
@@ -102,4 +86,32 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
return (type) u; \
return (type) -1; \
} \
+
+
+#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
+#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
+#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
+
+#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
+
+/* For string conversions where numbers are also acceptable */
+#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,) \
struct __useless_struct_to_allow_trailing_semicolon__
+
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static)
diff --git a/src/libbasic/string-util.c b/src/libbasic/string-util.c
index 0bde55f9d5..293a15f9c0 100644
--- a/src/libbasic/string-util.c
+++ b/src/libbasic/string-util.c
@@ -477,7 +477,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
}
if (k > x) /* last character was wide and went over quota */
- x ++;
+ x++;
for (j = s + old_length; k < new_length && j > i; ) {
char32_t c;
diff --git a/src/libbasic/string-util.h b/src/libbasic/string-util.h
index ad0c813761..139cc8c91b 100644
--- a/src/libbasic/string-util.h
+++ b/src/libbasic/string-util.h
@@ -37,6 +37,7 @@
#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
#define ALPHANUMERICAL LETTERS DIGITS
+#define HEXDIGITS DIGITS "abcdefABCDEF"
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
diff --git a/src/libbasic/strv.c b/src/libbasic/strv.c
index b5d4d8191b..97a96e5762 100644
--- a/src/libbasic/strv.c
+++ b/src/libbasic/strv.c
@@ -371,7 +371,7 @@ char *strv_join(char **l, const char *separator) {
n = 0;
STRV_FOREACH(s, l) {
- if (n != 0)
+ if (s != l)
n += k;
n += strlen(*s);
}
@@ -382,7 +382,7 @@ char *strv_join(char **l, const char *separator) {
e = r;
STRV_FOREACH(s, l) {
- if (e != r)
+ if (s != l)
e = stpcpy(e, separator);
e = stpcpy(e, *s);
@@ -558,6 +558,42 @@ int strv_extend(char ***l, const char *value) {
return strv_consume(l, v);
}
+int strv_extend_front(char ***l, const char *value) {
+ size_t n, m;
+ char *v, **c;
+
+ assert(l);
+
+ /* Like strv_extend(), but prepends rather than appends the new entry */
+
+ if (!value)
+ return 0;
+
+ n = strv_length(*l);
+
+ /* Increase and overflow check. */
+ m = n + 2;
+ if (m < n)
+ return -ENOMEM;
+
+ v = strdup(value);
+ if (!v)
+ return -ENOMEM;
+
+ c = realloc_multiply(*l, sizeof(char*), m);
+ if (!c) {
+ free(v);
+ return -ENOMEM;
+ }
+
+ memmove(c+1, c, n * sizeof(char*));
+ c[0] = v;
+ c[n+1] = NULL;
+
+ *l = c;
+ return 0;
+}
+
char **strv_uniq(char **l) {
char **i;
diff --git a/src/libbasic/strv.h b/src/libbasic/strv.h
index 7bfa54408d..f61bbb5386 100644
--- a/src/libbasic/strv.h
+++ b/src/libbasic/strv.h
@@ -50,6 +50,7 @@ int strv_extend_strv(char ***a, char **b, bool filter_duplicates);
int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
int strv_extend(char ***l, const char *value);
int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
+int strv_extend_front(char ***l, const char *value);
int strv_push(char ***l, char *value);
int strv_push_pair(char ***l, char *a, char *b);
int strv_push_prepend(char ***l, char *value);
diff --git a/src/libbasic/terminal-util.c b/src/libbasic/terminal-util.c
index 0a9d2bbdef..9521b79daa 100644
--- a/src/libbasic/terminal-util.c
+++ b/src/libbasic/terminal-util.c
@@ -1135,14 +1135,19 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
}
bool colors_enabled(void) {
- const char *colors;
+ static int enabled = -1;
- colors = getenv("SYSTEMD_COLORS");
- if (!colors) {
- if (streq_ptr(getenv("TERM"), "dumb"))
- return false;
- return on_tty();
+ if (_unlikely_(enabled < 0)) {
+ const char *colors;
+
+ colors = getenv("SYSTEMD_COLORS");
+ if (colors)
+ enabled = parse_boolean(colors) != 0;
+ else if (streq_ptr(getenv("TERM"), "dumb"))
+ enabled = false;
+ else
+ enabled = on_tty();
}
- return parse_boolean(colors) != 0;
+ return enabled;
}
diff --git a/src/libbasic/time-util.c b/src/libbasic/time-util.c
index 3973850b44..edd9179cb8 100644
--- a/src/libbasic/time-util.c
+++ b/src/libbasic/time-util.c
@@ -42,10 +42,30 @@
static nsec_t timespec_load_nsec(const struct timespec *ts);
+static clockid_t map_clock_id(clockid_t c) {
+
+ /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will
+ * fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is
+ * when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on
+ * those archs. */
+
+ switch (c) {
+
+ case CLOCK_BOOTTIME_ALARM:
+ return CLOCK_BOOTTIME;
+
+ case CLOCK_REALTIME_ALARM:
+ return CLOCK_REALTIME;
+
+ default:
+ return c;
+ }
+}
+
usec_t now(clockid_t clock_id) {
struct timespec ts;
- assert_se(clock_gettime(clock_id, &ts) == 0);
+ assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0);
return timespec_load(&ts);
}
@@ -53,7 +73,7 @@ usec_t now(clockid_t clock_id) {
nsec_t now_nsec(clockid_t clock_id) {
struct timespec ts;
- assert_se(clock_gettime(clock_id, &ts) == 0);
+ assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0);
return timespec_load_nsec(&ts);
}
@@ -119,8 +139,7 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us
usec_t timespec_load(const struct timespec *ts) {
assert(ts);
- if (ts->tv_sec == (time_t) -1 &&
- ts->tv_nsec == (long) -1)
+ if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1)
return USEC_INFINITY;
if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
@@ -134,13 +153,13 @@ usec_t timespec_load(const struct timespec *ts) {
static nsec_t timespec_load_nsec(const struct timespec *ts) {
assert(ts);
- if (ts->tv_sec == (time_t) -1 &&
- ts->tv_nsec == (long) -1)
+ if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1)
return NSEC_INFINITY;
- return
- (nsec_t) ts->tv_sec * NSEC_PER_SEC +
- (nsec_t) ts->tv_nsec;
+ if ((nsec_t) ts->tv_sec >= (UINT64_MAX - ts->tv_nsec) / NSEC_PER_SEC)
+ return NSEC_INFINITY;
+
+ return (nsec_t) ts->tv_sec * NSEC_PER_SEC + (nsec_t) ts->tv_nsec;
}
struct timespec *timespec_store(struct timespec *ts, usec_t u) {
@@ -429,7 +448,7 @@ int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
assert(t);
if (sscanf(value, "%llu %llu", &a, &b) != 2) {
- log_debug("Failed to parse finish timestamp value %s.", value);
+ log_debug("Failed to parse dual timestamp value \"%s\": %m", value);
return -EINVAL;
}
@@ -439,6 +458,18 @@ int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
return 0;
}
+int timestamp_deserialize(const char *value, usec_t *timestamp) {
+ int r;
+
+ assert(value);
+
+ r = safe_atou64(value, timestamp);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to parse timestamp value \"%s\": %m", value);
+
+ return r;
+}
+
int parse_timestamp(const char *t, usec_t *usec) {
static const struct {
const char *name;
@@ -545,12 +576,12 @@ int parse_timestamp(const char *t, usec_t *usec) {
goto from_tm;
} else if (streq(t, "yesterday")) {
- tm.tm_mday --;
+ tm.tm_mday--;
tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
goto from_tm;
} else if (streq(t, "tomorrow")) {
- tm.tm_mday ++;
+ tm.tm_mday++;
tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
goto from_tm;
}
@@ -673,8 +704,7 @@ finish:
return 0;
}
-int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
-
+static char* extract_multiplier(char *p, usec_t *multiplier) {
static const struct {
const char *suffix;
usec_t usec;
@@ -708,7 +738,22 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
{ "usec", 1ULL },
{ "us", 1ULL },
};
+ unsigned i;
+
+ for (i = 0; i < ELEMENTSOF(table); i++) {
+ char *e;
+ e = startswith(p, table[i].suffix);
+ if (e) {
+ *multiplier = table[i].usec;
+ return e;
+ }
+ }
+
+ return p;
+}
+
+int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
const char *p, *s;
usec_t r = 0;
bool something = false;
@@ -733,8 +778,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
for (;;) {
long long l, z = 0;
char *e;
- unsigned i, n = 0;
- usec_t multiplier, k;
+ unsigned n = 0;
+ usec_t multiplier = default_unit, k;
p += strspn(p, WHITESPACE);
@@ -747,10 +792,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
errno = 0;
l = strtoll(p, &e, 10);
-
if (errno > 0)
return -errno;
-
if (l < 0)
return -ERANGE;
@@ -774,18 +817,7 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
return -EINVAL;
e += strspn(e, WHITESPACE);
-
- for (i = 0; i < ELEMENTSOF(table); i++)
- if (startswith(e, table[i].suffix)) {
- multiplier = table[i].usec;
- p = e + strlen(table[i].suffix);
- break;
- }
-
- if (i >= ELEMENTSOF(table)) {
- multiplier = default_unit;
- p = e;
- }
+ p = extract_multiplier(e, &multiplier);
something = true;
@@ -1048,22 +1080,31 @@ bool timezone_is_valid(const char *name) {
return true;
}
-clockid_t clock_boottime_or_monotonic(void) {
- static clockid_t clock = -1;
- int fd;
-
- if (clock != -1)
- return clock;
-
- fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
- if (fd < 0)
- clock = CLOCK_MONOTONIC;
- else {
- safe_close(fd);
- clock = CLOCK_BOOTTIME;
+bool clock_boottime_supported(void) {
+ static int supported = -1;
+
+ /* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */
+
+ if (supported < 0) {
+ int fd;
+
+ fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+ if (fd < 0)
+ supported = false;
+ else {
+ safe_close(fd);
+ supported = true;
+ }
}
- return clock;
+ return supported;
+}
+
+clockid_t clock_boottime_or_monotonic(void) {
+ if (clock_boottime_supported())
+ return CLOCK_BOOTTIME;
+ else
+ return CLOCK_MONOTONIC;
}
int get_timezone(char **tz) {
diff --git a/src/libbasic/time-util.h b/src/libbasic/time-util.h
index 9894e626c5..a5e3f567ec 100644
--- a/src/libbasic/time-util.h
+++ b/src/libbasic/time-util.h
@@ -99,6 +99,7 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy);
void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t);
int dual_timestamp_deserialize(const char *value, dual_timestamp *t);
+int timestamp_deserialize(const char *value, usec_t *timestamp);
int parse_timestamp(const char *t, usec_t *usec);
@@ -111,6 +112,7 @@ bool ntp_synced(void);
int get_timezones(char ***l);
bool timezone_is_valid(const char *name);
+bool clock_boottime_supported(void);
clockid_t clock_boottime_or_monotonic(void);
#define xstrftime(buf, fmt, tm) \
diff --git a/src/libbasic/user-util.c b/src/libbasic/user-util.c
index 19155bce53..f65ca3edaa 100644
--- a/src/libbasic/user-util.c
+++ b/src/libbasic/user-util.c
@@ -30,6 +30,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "missing.h"
#include "alloc-util.h"
#include "fd-util.h"
#include "formats-util.h"
diff --git a/src/libbasic/user-util.h b/src/libbasic/user-util.h
index c23f1d485d..8026eca3f4 100644
--- a/src/libbasic/user-util.h
+++ b/src/libbasic/user-util.h
@@ -21,6 +21,7 @@
#include <stdbool.h>
#include <sys/types.h>
+#include <unistd.h>
bool uid_is_valid(uid_t uid);
@@ -63,3 +64,7 @@ int take_etc_passwd_lock(const char *root);
#define PTR_TO_GID(p) ((gid_t) (((uintptr_t) (p))-1))
#define GID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1))
+
+static inline bool userns_supported(void) {
+ return access("/proc/self/uid_map", F_OK) >= 0;
+}
diff --git a/src/libbasic/utf8.c b/src/libbasic/utf8.c
index 629db123cd..6eae2b983d 100644
--- a/src/libbasic/utf8.c
+++ b/src/libbasic/utf8.c
@@ -241,7 +241,7 @@ char *utf8_escape_non_printable(const char *str) {
*(s++) = hexchar((int) *str);
str += 1;
- len --;
+ len--;
}
}
} else {
diff --git a/src/libbasic/utf8.h b/src/libbasic/utf8.h
index 12c272d66e..f9b9c9468b 100644
--- a/src/libbasic/utf8.h
+++ b/src/libbasic/utf8.h
@@ -28,6 +28,7 @@
#include "missing.h"
#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
+#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
bool unichar_is_valid(char32_t c);
diff --git a/src/libbasic/util.c b/src/libbasic/util.c
index ea1bed7ceb..756c663be4 100644
--- a/src/libbasic/util.c
+++ b/src/libbasic/util.c
@@ -55,6 +55,7 @@
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
+#include "umask-util.h"
#include "user-util.h"
#include "util.h"
@@ -419,13 +420,17 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
_exit(EXIT_FAILURE);
}
- if (!stdout_is_tty)
- dup2(fd, STDOUT_FILENO);
+ if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) {
+ log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
+ _exit(EXIT_FAILURE);
+ }
- if (!stderr_is_tty)
- dup2(fd, STDERR_FILENO);
+ if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) {
+ log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
+ _exit(EXIT_FAILURE);
+ }
- if (fd > 2)
+ if (fd > STDERR_FILENO)
close(fd);
}
@@ -517,7 +522,7 @@ int on_ac_power(void) {
if (!de)
break;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
@@ -773,15 +778,25 @@ uint64_t physical_memory(void) {
return (uint64_t) mem * (uint64_t) page_size();
}
-int update_reboot_param_file(const char *param) {
- int r = 0;
+int update_reboot_parameter_and_warn(const char *param) {
+ int r;
+
+ if (isempty(param)) {
+ if (unlink("/run/systemd/reboot-param") < 0) {
+ if (errno == ENOENT)
+ return 0;
+
+ return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m");
+ }
- if (param) {
- r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
+ return 0;
+ }
+
+ RUN_WITH_UMASK(0022) {
+ r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE);
if (r < 0)
- return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
- } else
- (void) unlink(REBOOT_PARAM_FILE);
+ return log_warning_errno(r, "Failed to write reboot parameter file: %m");
+ }
return 0;
}
diff --git a/src/libbasic/util.h b/src/libbasic/util.h
index 6f42c85a33..1c032c15c9 100644
--- a/src/libbasic/util.h
+++ b/src/libbasic/util.h
@@ -36,6 +36,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/statfs.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@@ -102,6 +103,16 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_
qsort(base, nmemb, size, compar);
}
+/**
+ * Normal memcpy requires src to be nonnull. We do nothing if n is 0.
+ */
+static inline void memcpy_safe(void *dst, const void *src, size_t n) {
+ if (n == 0)
+ return;
+ assert(src);
+ memcpy(dst, src, n);
+}
+
int on_ac_power(void);
#define memzero(x,l) (memset((x), 0, (l)))
@@ -173,6 +184,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
uint64_t physical_memory(void);
-int update_reboot_param_file(const char *param);
+int update_reboot_parameter_and_warn(const char *param);
int version(void);
diff --git a/src/libbasic/virt.c b/src/libbasic/virt.c
index 19b6318e3d..dace1f4328 100644
--- a/src/libbasic/virt.c
+++ b/src/libbasic/virt.c
@@ -98,6 +98,8 @@ static int detect_vm_cpuid(void) {
: "0" (eax)
);
+ log_debug("Virtualization found, CPUID=%s", sig.text);
+
for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++)
if (streq(sig.text, cpuid_vendor_table[j].cpuid))
return cpuid_vendor_table[j].id;
@@ -105,6 +107,7 @@ static int detect_vm_cpuid(void) {
return VIRTUALIZATION_VM_OTHER;
}
#endif
+ log_debug("No virtualization found in CPUID");
return VIRTUALIZATION_NONE;
}
@@ -121,19 +124,25 @@ static int detect_vm_device_tree(void) {
dir = opendir("/proc/device-tree");
if (!dir) {
- if (errno == ENOENT)
+ if (errno == ENOENT) {
+ log_debug_errno(errno, "/proc/device-tree: %m");
return VIRTUALIZATION_NONE;
+ }
return -errno;
}
FOREACH_DIRENT(dent, dir, return -errno)
- if (strstr(dent->d_name, "fw-cfg"))
+ if (strstr(dent->d_name, "fw-cfg")) {
+ log_debug("Virtualization QEMU: \"fw-cfg\" present in /proc/device-tree/%s", dent->d_name);
return VIRTUALIZATION_QEMU;
+ }
+ log_debug("No virtualization found in /proc/device-tree/*");
return VIRTUALIZATION_NONE;
} else if (r < 0)
return r;
+ log_debug("Virtualization %s found in /proc/device-tree/hypervisor/compatible", hvtype);
if (streq(hvtype, "linux,kvm"))
return VIRTUALIZATION_KVM;
else if (strstr(hvtype, "xen"))
@@ -141,6 +150,7 @@ static int detect_vm_device_tree(void) {
else
return VIRTUALIZATION_VM_OTHER;
#else
+ log_debug("This platform does not support /proc/device-tree");
return VIRTUALIZATION_NONE;
#endif
}
@@ -184,30 +194,58 @@ static int detect_vm_dmi(void) {
return r;
}
+
+
for (j = 0; j < ELEMENTSOF(dmi_vendor_table); j++)
- if (startswith(s, dmi_vendor_table[j].vendor))
+ if (startswith(s, dmi_vendor_table[j].vendor)) {
+ log_debug("Virtualization %s found in DMI (%s)", s, dmi_vendors[i]);
return dmi_vendor_table[j].id;
+ }
}
#endif
+ log_debug("No virtualization found in DMI");
+
return VIRTUALIZATION_NONE;
}
static int detect_vm_xen(void) {
+ /* Check for Dom0 will be executed later in detect_vm_xen_dom0
+ Thats why we dont check the content of /proc/xen/capabilities here. */
+ if (access("/proc/xen/capabilities", F_OK) < 0) {
+ log_debug("Virtualization XEN not found, /proc/xen/capabilities does not exist");
+ return VIRTUALIZATION_NONE;
+ }
+
+ log_debug("Virtualization XEN found (/proc/xen/capabilities exists)");
+ return VIRTUALIZATION_XEN;
+
+}
+
+static bool detect_vm_xen_dom0(void) {
_cleanup_free_ char *domcap = NULL;
char *cap, *i;
int r;
r = read_one_line_file("/proc/xen/capabilities", &domcap);
- if (r == -ENOENT)
- return VIRTUALIZATION_NONE;
+ if (r == -ENOENT) {
+ log_debug("Virtualization XEN not found, /proc/xen/capabilities does not exist");
+ return false;
+ }
+ if (r < 0)
+ return r;
i = domcap;
while ((cap = strsep(&i, ",")))
if (streq(cap, "control_d"))
break;
+ if (!cap) {
+ log_debug("Virtualization XEN DomU found (/proc/xen/capabilites)");
+ return false;
+ }
- return cap ? VIRTUALIZATION_NONE : VIRTUALIZATION_XEN;
+ log_debug("Virtualization XEN Dom0 ignored (/proc/xen/capabilities)");
+ return true;
}
static int detect_vm_hypervisor(void) {
@@ -220,6 +258,8 @@ static int detect_vm_hypervisor(void) {
if (r < 0)
return r;
+ log_debug("Virtualization %s found in /sys/hypervisor/type", hvtype);
+
if (streq(hvtype, "xen"))
return VIRTUALIZATION_XEN;
else
@@ -234,9 +274,13 @@ static int detect_vm_uml(void) {
r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
if (r < 0)
return r;
- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n"))
+
+ if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
+ log_debug("UML virtualization found in /proc/cpuinfo");
return VIRTUALIZATION_UML;
+ }
+ log_debug("No virtualization found in /proc/cpuinfo.");
return VIRTUALIZATION_NONE;
}
@@ -252,11 +296,13 @@ static int detect_vm_zvm(void) {
if (r < 0)
return r;
+ log_debug("Virtualization %s found in /proc/sysinfo", t);
if (streq(t, "z/VM"))
return VIRTUALIZATION_ZVM;
else
return VIRTUALIZATION_KVM;
#else
+ log_debug("This platform does not support /proc/sysinfo");
return VIRTUALIZATION_NONE;
#endif
}
@@ -324,7 +370,14 @@ int detect_vm(void) {
return r;
finish:
+ /* x86 xen Dom0 is detected as XEN in hypervisor and maybe others.
+ * In order to detect the Dom0 as not virtualization we need to
+ * double-check it */
+ if (r == VIRTUALIZATION_XEN && detect_vm_xen_dom0())
+ r = VIRTUALIZATION_NONE;
+
cached_found = r;
+ log_debug("Found VM virtualization %s", virtualization_to_string(r));
return r;
}
@@ -412,6 +465,7 @@ int detect_container(void) {
r = VIRTUALIZATION_CONTAINER_OTHER;
finish:
+ log_debug("Found container virtualization %s", virtualization_to_string(r));
cached_found = r;
return r;
}
@@ -420,10 +474,10 @@ int detect_virtualization(void) {
int r;
r = detect_container();
- if (r != 0)
- return r;
+ if (r == 0)
+ r = detect_vm();
- return detect_vm();
+ return r;
}
int running_in_chroot(void) {
diff --git a/src/libbasic/xattr-util.c b/src/libbasic/xattr-util.c
index 8d7f14f382..8256899eda 100644
--- a/src/libbasic/xattr-util.c
+++ b/src/libbasic/xattr-util.c
@@ -110,7 +110,7 @@ ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute,
/* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
- fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
+ fd = openat(dirfd, filename, O_CLOEXEC|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
if (fd < 0)
return -errno;
diff --git a/src/libbus-proxy-core/bus-xml-policy.c b/src/libbus-proxy-core/bus-xml-policy.c
deleted file mode 100644
index 86a8362142..0000000000
--- a/src/libbus-proxy-core/bus-xml-policy.c
+++ /dev/null
@@ -1,1327 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <systemd/sd-login.h>
-
-#include "alloc-util.h"
-#include "bus-internal.h"
-#include "bus-xml-policy.h"
-#include "conf-files.h"
-#include "fileio.h"
-#include "formats-util.h"
-#include "locale-util.h"
-#include "set.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "strv.h"
-#include "user-util.h"
-#include "xml.h"
-
-static void policy_item_free(PolicyItem *i) {
- assert(i);
-
- free(i->interface);
- free(i->member);
- free(i->error);
- free(i->name);
- free(i->path);
- free(i);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(PolicyItem*, policy_item_free);
-
-static void item_append(PolicyItem *i, PolicyItem **list) {
-
- PolicyItem *tail;
-
- LIST_FIND_TAIL(items, *list, tail);
- LIST_INSERT_AFTER(items, *list, tail, i);
-}
-
-static int file_load(Policy *p, const char *path) {
-
- _cleanup_free_ char *c = NULL, *policy_user = NULL, *policy_group = NULL;
- _cleanup_(policy_item_freep) PolicyItem *i = NULL;
- void *xml_state = NULL;
- unsigned n_other = 0;
- const char *q;
- int r;
-
- enum {
- STATE_OUTSIDE,
- STATE_BUSCONFIG,
- STATE_POLICY,
- STATE_POLICY_CONTEXT,
- STATE_POLICY_CONSOLE,
- STATE_POLICY_USER,
- STATE_POLICY_GROUP,
- STATE_POLICY_OTHER_ATTRIBUTE,
- STATE_ALLOW_DENY,
- STATE_ALLOW_DENY_INTERFACE,
- STATE_ALLOW_DENY_MEMBER,
- STATE_ALLOW_DENY_ERROR,
- STATE_ALLOW_DENY_PATH,
- STATE_ALLOW_DENY_MESSAGE_TYPE,
- STATE_ALLOW_DENY_NAME,
- STATE_ALLOW_DENY_OTHER_ATTRIBUTE,
- STATE_OTHER,
- } state = STATE_OUTSIDE;
-
- enum {
- POLICY_CATEGORY_NONE,
- POLICY_CATEGORY_DEFAULT,
- POLICY_CATEGORY_MANDATORY,
- POLICY_CATEGORY_ON_CONSOLE,
- POLICY_CATEGORY_NO_CONSOLE,
- POLICY_CATEGORY_USER,
- POLICY_CATEGORY_GROUP
- } policy_category = POLICY_CATEGORY_NONE;
-
- unsigned line = 0;
-
- assert(p);
-
- r = read_full_file(path, &c, NULL);
- if (r < 0) {
- if (r == -ENOENT)
- return 0;
- if (r == -EISDIR)
- return r;
-
- return log_error_errno(r, "Failed to load %s: %m", path);
- }
-
- q = c;
- for (;;) {
- _cleanup_free_ char *name = NULL;
- int t;
-
- t = xml_tokenize(&q, &name, &xml_state, &line);
- if (t < 0)
- return log_error_errno(t, "XML parse failure in %s: %m", path);
-
- switch (state) {
-
- case STATE_OUTSIDE:
-
- if (t == XML_TAG_OPEN) {
- if (streq(name, "busconfig"))
- state = STATE_BUSCONFIG;
- else {
- log_error("Unexpected tag %s at %s:%u.", name, path, line);
- return -EINVAL;
- }
-
- } else if (t == XML_END)
- return 0;
- else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token (1) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_BUSCONFIG:
-
- if (t == XML_TAG_OPEN) {
- if (streq(name, "policy")) {
- state = STATE_POLICY;
- policy_category = POLICY_CATEGORY_NONE;
- free(policy_user);
- free(policy_group);
- policy_user = policy_group = NULL;
- } else {
- state = STATE_OTHER;
- n_other = 0;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq(name, "busconfig")))
- state = STATE_OUTSIDE;
- else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token (2) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_POLICY:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq(name, "context"))
- state = STATE_POLICY_CONTEXT;
- else if (streq(name, "at_console"))
- state = STATE_POLICY_CONSOLE;
- else if (streq(name, "user"))
- state = STATE_POLICY_USER;
- else if (streq(name, "group"))
- state = STATE_POLICY_GROUP;
- else {
- log_warning("Attribute %s of <policy> tag unknown at %s:%u, ignoring.", name, path, line);
- state = STATE_POLICY_OTHER_ATTRIBUTE;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq(name, "policy")))
- state = STATE_BUSCONFIG;
- else if (t == XML_TAG_OPEN) {
- PolicyItemType it;
-
- if (streq(name, "allow"))
- it = POLICY_ITEM_ALLOW;
- else if (streq(name, "deny"))
- it = POLICY_ITEM_DENY;
- else {
- log_warning("Unknown tag %s in <policy> %s:%u.", name, path, line);
- return -EINVAL;
- }
-
- assert(!i);
- i = new0(PolicyItem, 1);
- if (!i)
- return log_oom();
-
- i->type = it;
- state = STATE_ALLOW_DENY;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token (3) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_POLICY_CONTEXT:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (streq(name, "default")) {
- policy_category = POLICY_CATEGORY_DEFAULT;
- state = STATE_POLICY;
- } else if (streq(name, "mandatory")) {
- policy_category = POLICY_CATEGORY_MANDATORY;
- state = STATE_POLICY;
- } else {
- log_error("context= parameter %s unknown for <policy> at %s:%u.", name, path, line);
- return -EINVAL;
- }
- } else {
- log_error("Unexpected token (4) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_POLICY_CONSOLE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (streq(name, "true")) {
- policy_category = POLICY_CATEGORY_ON_CONSOLE;
- state = STATE_POLICY;
- } else if (streq(name, "false")) {
- policy_category = POLICY_CATEGORY_NO_CONSOLE;
- state = STATE_POLICY;
- } else {
- log_error("at_console= parameter %s unknown for <policy> at %s:%u.", name, path, line);
- return -EINVAL;
- }
- } else {
- log_error("Unexpected token (4.1) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_POLICY_USER:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free(policy_user);
- policy_user = name;
- name = NULL;
- policy_category = POLICY_CATEGORY_USER;
- state = STATE_POLICY;
- } else {
- log_error("Unexpected token (5) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_POLICY_GROUP:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free(policy_group);
- policy_group = name;
- name = NULL;
- policy_category = POLICY_CATEGORY_GROUP;
- state = STATE_POLICY;
- } else {
- log_error("Unexpected token (6) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_POLICY_OTHER_ATTRIBUTE:
-
- if (t == XML_ATTRIBUTE_VALUE)
- state = STATE_POLICY;
- else {
- log_error("Unexpected token (7) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY:
-
- assert(i);
-
- if (t == XML_ATTRIBUTE_NAME) {
- PolicyItemClass ic;
-
- if (startswith(name, "send_"))
- ic = POLICY_ITEM_SEND;
- else if (startswith(name, "receive_"))
- ic = POLICY_ITEM_RECV;
- else if (streq(name, "own"))
- ic = POLICY_ITEM_OWN;
- else if (streq(name, "own_prefix"))
- ic = POLICY_ITEM_OWN_PREFIX;
- else if (streq(name, "user"))
- ic = POLICY_ITEM_USER;
- else if (streq(name, "group"))
- ic = POLICY_ITEM_GROUP;
- else if (STR_IN_SET(name, "eavesdrop", "log")) {
- log_debug("Unsupported attribute %s= at %s:%u, ignoring.", name, path, line);
- state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE;
- break;
- } else {
- log_error("Unknown attribute %s= at %s:%u, ignoring.", name, path, line);
- state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE;
- break;
- }
-
- if (i->class != _POLICY_ITEM_CLASS_UNSET && ic != i->class) {
- log_error("send_, receive_/eavesdrop fields mixed on same tag at %s:%u.", path, line);
- return -EINVAL;
- }
-
- i->class = ic;
-
- if (ic == POLICY_ITEM_SEND || ic == POLICY_ITEM_RECV) {
- const char *u;
-
- u = strchr(name, '_');
- assert(u);
-
- u++;
-
- if (streq(u, "interface"))
- state = STATE_ALLOW_DENY_INTERFACE;
- else if (streq(u, "member"))
- state = STATE_ALLOW_DENY_MEMBER;
- else if (streq(u, "error"))
- state = STATE_ALLOW_DENY_ERROR;
- else if (streq(u, "path"))
- state = STATE_ALLOW_DENY_PATH;
- else if (streq(u, "type"))
- state = STATE_ALLOW_DENY_MESSAGE_TYPE;
- else if ((streq(u, "destination") && ic == POLICY_ITEM_SEND) ||
- (streq(u, "sender") && ic == POLICY_ITEM_RECV))
- state = STATE_ALLOW_DENY_NAME;
- else {
- if (streq(u, "requested_reply"))
- log_debug("Unsupported attribute %s= at %s:%u, ignoring.", name, path, line);
- else
- log_error("Unknown attribute %s= at %s:%u, ignoring.", name, path, line);
- state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE;
- break;
- }
- } else
- state = STATE_ALLOW_DENY_NAME;
-
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq(name, i->type == POLICY_ITEM_ALLOW ? "allow" : "deny"))) {
-
- /* If the tag is fully empty so far, we consider it a recv */
- if (i->class == _POLICY_ITEM_CLASS_UNSET)
- i->class = POLICY_ITEM_RECV;
-
- if (policy_category == POLICY_CATEGORY_DEFAULT)
- item_append(i, &p->default_items);
- else if (policy_category == POLICY_CATEGORY_MANDATORY)
- item_append(i, &p->mandatory_items);
- else if (policy_category == POLICY_CATEGORY_ON_CONSOLE)
- item_append(i, &p->on_console_items);
- else if (policy_category == POLICY_CATEGORY_NO_CONSOLE)
- item_append(i, &p->no_console_items);
- else if (policy_category == POLICY_CATEGORY_USER) {
- const char *u = policy_user;
-
- assert_cc(sizeof(uid_t) == sizeof(uint32_t));
-
- r = hashmap_ensure_allocated(&p->user_items, NULL);
- if (r < 0)
- return log_oom();
-
- if (!u) {
- log_error("User policy without name");
- return -EINVAL;
- }
-
- r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to resolve user %s, ignoring policy: %m", u);
- free(i);
- } else {
- PolicyItem *first;
-
- first = hashmap_get(p->user_items, UID_TO_PTR(i->uid));
- item_append(i, &first);
- i->uid_valid = true;
-
- r = hashmap_replace(p->user_items, UID_TO_PTR(i->uid), first);
- if (r < 0) {
- LIST_REMOVE(items, first, i);
- return log_oom();
- }
- }
-
- } else if (policy_category == POLICY_CATEGORY_GROUP) {
- const char *g = policy_group;
-
- assert_cc(sizeof(gid_t) == sizeof(uint32_t));
-
- r = hashmap_ensure_allocated(&p->group_items, NULL);
- if (r < 0)
- return log_oom();
-
- if (!g) {
- log_error("Group policy without name");
- return -EINVAL;
- }
-
- r = get_group_creds(&g, &i->gid);
- if (r < 0) {
- log_error_errno(r, "Failed to resolve group %s, ignoring policy: %m", g);
- free(i);
- } else {
- PolicyItem *first;
-
- first = hashmap_get(p->group_items, GID_TO_PTR(i->gid));
- item_append(i, &first);
- i->gid_valid = true;
-
- r = hashmap_replace(p->group_items, GID_TO_PTR(i->gid), first);
- if (r < 0) {
- LIST_REMOVE(items, first, i);
- return log_oom();
- }
- }
- }
-
- state = STATE_POLICY;
- i = NULL;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token (8) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_INTERFACE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- assert(i);
- if (i->interface) {
- log_error("Duplicate interface at %s:%u.", path, line);
- return -EINVAL;
- }
-
- if (!streq(name, "*")) {
- i->interface = name;
- name = NULL;
- }
- state = STATE_ALLOW_DENY;
- } else {
- log_error("Unexpected token (9) at %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_MEMBER:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- assert(i);
- if (i->member) {
- log_error("Duplicate member in %s:%u.", path, line);
- return -EINVAL;
- }
-
- if (!streq(name, "*")) {
- i->member = name;
- name = NULL;
- }
- state = STATE_ALLOW_DENY;
- } else {
- log_error("Unexpected token (10) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_ERROR:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- assert(i);
- if (i->error) {
- log_error("Duplicate error in %s:%u.", path, line);
- return -EINVAL;
- }
-
- if (!streq(name, "*")) {
- i->error = name;
- name = NULL;
- }
- state = STATE_ALLOW_DENY;
- } else {
- log_error("Unexpected token (11) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_PATH:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- assert(i);
- if (i->path) {
- log_error("Duplicate path in %s:%u.", path, line);
- return -EINVAL;
- }
-
- if (!streq(name, "*")) {
- i->path = name;
- name = NULL;
- }
- state = STATE_ALLOW_DENY;
- } else {
- log_error("Unexpected token (12) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_MESSAGE_TYPE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- assert(i);
-
- if (i->message_type != 0) {
- log_error("Duplicate message type in %s:%u.", path, line);
- return -EINVAL;
- }
-
- if (!streq(name, "*")) {
- r = bus_message_type_from_string(name, &i->message_type);
- if (r < 0) {
- log_error("Invalid message type in %s:%u.", path, line);
- return -EINVAL;
- }
- }
-
- state = STATE_ALLOW_DENY;
- } else {
- log_error("Unexpected token (13) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- assert(i);
- if (i->name) {
- log_error("Duplicate name in %s:%u.", path, line);
- return -EINVAL;
- }
-
- switch (i->class) {
- case POLICY_ITEM_USER:
- if (!streq(name, "*")) {
- const char *u = name;
-
- r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
- if (r < 0)
- log_error_errno(r, "Failed to resolve user %s: %m", name);
- else
- i->uid_valid = true;
- }
- break;
- case POLICY_ITEM_GROUP:
- if (!streq(name, "*")) {
- const char *g = name;
-
- r = get_group_creds(&g, &i->gid);
- if (r < 0)
- log_error_errno(r, "Failed to resolve group %s: %m", name);
- else
- i->gid_valid = true;
- }
- break;
-
- case POLICY_ITEM_SEND:
- case POLICY_ITEM_RECV:
-
- if (streq(name, "*"))
- name = mfree(name);
- break;
-
-
- default:
- break;
- }
-
- i->name = name;
- name = NULL;
-
- state = STATE_ALLOW_DENY;
- } else {
- log_error("Unexpected token (14) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_ALLOW_DENY_OTHER_ATTRIBUTE:
-
- if (t == XML_ATTRIBUTE_VALUE)
- state = STATE_ALLOW_DENY;
- else {
- log_error("Unexpected token (15) in %s:%u.", path, line);
- return -EINVAL;
- }
-
- break;
-
- case STATE_OTHER:
-
- if (t == XML_TAG_OPEN)
- n_other++;
- else if (t == XML_TAG_CLOSE || t == XML_TAG_CLOSE_EMPTY) {
-
- if (n_other == 0)
- state = STATE_BUSCONFIG;
- else
- n_other--;
- }
-
- break;
- }
- }
-}
-
-enum {
- DENY,
- ALLOW,
- DUNNO,
-};
-
-static const char *verdict_to_string(int v) {
- switch (v) {
-
- case DENY:
- return "DENY";
- case ALLOW:
- return "ALLOW";
- case DUNNO:
- return "DUNNO";
- }
-
- return NULL;
-}
-
-struct policy_check_filter {
- PolicyItemClass class;
- uid_t uid;
- gid_t gid;
- int message_type;
- const char *name;
- const char *interface;
- const char *path;
- const char *member;
-};
-
-static int is_permissive(PolicyItem *i) {
-
- assert(i);
-
- return (i->type == POLICY_ITEM_ALLOW) ? ALLOW : DENY;
-}
-
-static int check_policy_item(PolicyItem *i, const struct policy_check_filter *filter) {
-
- assert(i);
- assert(filter);
-
- switch (i->class) {
- case POLICY_ITEM_SEND:
- case POLICY_ITEM_RECV:
-
- if (i->name && !streq_ptr(i->name, filter->name))
- break;
-
- if ((i->message_type != 0) && (i->message_type != filter->message_type))
- break;
-
- if (i->path && !streq_ptr(i->path, filter->path))
- break;
-
- if (i->member && !streq_ptr(i->member, filter->member))
- break;
-
- if (i->interface && !streq_ptr(i->interface, filter->interface))
- break;
-
- return is_permissive(i);
-
- case POLICY_ITEM_OWN:
- assert(filter->name);
-
- if (streq(i->name, "*") || streq(i->name, filter->name))
- return is_permissive(i);
- break;
-
- case POLICY_ITEM_OWN_PREFIX:
- assert(filter->name);
-
- if (streq(i->name, "*") || service_name_startswith(filter->name, i->name))
- return is_permissive(i);
- break;
-
- case POLICY_ITEM_USER:
- if (filter->uid != UID_INVALID)
- if ((streq_ptr(i->name, "*") || (i->uid_valid && i->uid == filter->uid)))
- return is_permissive(i);
- break;
-
- case POLICY_ITEM_GROUP:
- if (filter->gid != GID_INVALID)
- if ((streq_ptr(i->name, "*") || (i->gid_valid && i->gid == filter->gid)))
- return is_permissive(i);
- break;
-
- case POLICY_ITEM_IGNORE:
- default:
- break;
- }
-
- return DUNNO;
-}
-
-static int check_policy_items(PolicyItem *items, const struct policy_check_filter *filter) {
-
- PolicyItem *i;
- int verdict = DUNNO;
-
- assert(filter);
-
- /* Check all policies in a set - a broader one might be followed by a more specific one,
- * and the order of rules in policy definitions matters */
- LIST_FOREACH(items, i, items) {
- int v;
-
- if (i->class != filter->class &&
- !(i->class == POLICY_ITEM_OWN_PREFIX && filter->class == POLICY_ITEM_OWN))
- continue;
-
- v = check_policy_item(i, filter);
- if (v != DUNNO)
- verdict = v;
- }
-
- return verdict;
-}
-
-static int policy_check(Policy *p, const struct policy_check_filter *filter) {
-
- PolicyItem *items;
- int verdict, v;
-
- assert(p);
- assert(filter);
-
- assert(IN_SET(filter->class, POLICY_ITEM_SEND, POLICY_ITEM_RECV, POLICY_ITEM_OWN, POLICY_ITEM_USER, POLICY_ITEM_GROUP));
-
- /*
- * The policy check is implemented by the following logic:
- *
- * 1. Check default items
- * 2. Check group items
- * 3. Check user items
- * 4. Check on/no_console items
- * 5. Check mandatory items
- *
- * Later rules override earlier rules.
- */
-
- verdict = check_policy_items(p->default_items, filter);
-
- if (filter->gid != GID_INVALID) {
- items = hashmap_get(p->group_items, GID_TO_PTR(filter->gid));
- if (items) {
- v = check_policy_items(items, filter);
- if (v != DUNNO)
- verdict = v;
- }
- }
-
- if (filter->uid != UID_INVALID) {
- items = hashmap_get(p->user_items, UID_TO_PTR(filter->uid));
- if (items) {
- v = check_policy_items(items, filter);
- if (v != DUNNO)
- verdict = v;
- }
- }
-
- if (filter->uid != UID_INVALID && sd_uid_get_seats(filter->uid, -1, NULL) > 0)
- v = check_policy_items(p->on_console_items, filter);
- else
- v = check_policy_items(p->no_console_items, filter);
- if (v != DUNNO)
- verdict = v;
-
- v = check_policy_items(p->mandatory_items, filter);
- if (v != DUNNO)
- verdict = v;
-
- return verdict;
-}
-
-bool policy_check_own(Policy *p, uid_t uid, gid_t gid, const char *name) {
-
- struct policy_check_filter filter = {
- .class = POLICY_ITEM_OWN,
- .uid = uid,
- .gid = gid,
- .name = name,
- };
-
- int verdict;
-
- assert(p);
- assert(name);
-
- verdict = policy_check(p, &filter);
-
- log_full(LOG_AUTH | (verdict != ALLOW ? LOG_WARNING : LOG_DEBUG),
- "Ownership permission check for uid=" UID_FMT " gid=" GID_FMT" name=%s: %s",
- uid, gid, strna(name), strna(verdict_to_string(verdict)));
-
- return verdict == ALLOW;
-}
-
-bool policy_check_hello(Policy *p, uid_t uid, gid_t gid) {
-
- struct policy_check_filter filter = {
- .uid = uid,
- .gid = gid,
- };
- int verdict;
-
- assert(p);
-
- filter.class = POLICY_ITEM_USER;
- verdict = policy_check(p, &filter);
-
- if (verdict != DENY) {
- int v;
-
- filter.class = POLICY_ITEM_GROUP;
- v = policy_check(p, &filter);
- if (v != DUNNO)
- verdict = v;
- }
-
- log_full(LOG_AUTH | (verdict != ALLOW ? LOG_WARNING : LOG_DEBUG),
- "Hello permission check for uid=" UID_FMT " gid=" GID_FMT": %s",
- uid, gid, strna(verdict_to_string(verdict)));
-
- return verdict == ALLOW;
-}
-
-bool policy_check_one_recv(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- const char *name,
- const char *path,
- const char *interface,
- const char *member) {
-
- struct policy_check_filter filter = {
- .class = POLICY_ITEM_RECV,
- .uid = uid,
- .gid = gid,
- .message_type = message_type,
- .name = name,
- .interface = interface,
- .path = path,
- .member = member,
- };
-
- assert(p);
-
- return policy_check(p, &filter) == ALLOW;
-}
-
-bool policy_check_recv(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- Set *names,
- char **namesv,
- const char *path,
- const char *interface,
- const char *member,
- bool dbus_to_kernel) {
-
- char *n, **nv, *last = NULL;
- bool allow = false;
- Iterator i;
-
- assert(p);
-
- if (set_isempty(names) && strv_isempty(namesv)) {
- allow = policy_check_one_recv(p, uid, gid, message_type, NULL, path, interface, member);
- } else {
- SET_FOREACH(n, names, i) {
- last = n;
- allow = policy_check_one_recv(p, uid, gid, message_type, n, path, interface, member);
- if (allow)
- break;
- }
- if (!allow) {
- STRV_FOREACH(nv, namesv) {
- last = *nv;
- allow = policy_check_one_recv(p, uid, gid, message_type, *nv, path, interface, member);
- if (allow)
- break;
- }
- }
- }
-
- log_full(LOG_AUTH | (!allow ? LOG_WARNING : LOG_DEBUG),
- "Receive permission check %s for uid=" UID_FMT " gid=" GID_FMT" message=%s name=%s path=%s interface=%s member=%s: %s",
- dbus_to_kernel ? "dbus-1 to kernel" : "kernel to dbus-1", uid, gid, bus_message_type_to_string(message_type), strna(last),
- strna(path), strna(interface), strna(member), allow ? "ALLOW" : "DENY");
-
- return allow;
-}
-
-bool policy_check_one_send(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- const char *name,
- const char *path,
- const char *interface,
- const char *member) {
-
- struct policy_check_filter filter = {
- .class = POLICY_ITEM_SEND,
- .uid = uid,
- .gid = gid,
- .message_type = message_type,
- .name = name,
- .interface = interface,
- .path = path,
- .member = member,
- };
-
- assert(p);
-
- return policy_check(p, &filter) == ALLOW;
-}
-
-bool policy_check_send(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- Set *names,
- char **namesv,
- const char *path,
- const char *interface,
- const char *member,
- bool dbus_to_kernel,
- char **out_used_name) {
-
- char *n, **nv, *last = NULL;
- bool allow = false;
- Iterator i;
-
- assert(p);
-
- if (set_isempty(names) && strv_isempty(namesv)) {
- allow = policy_check_one_send(p, uid, gid, message_type, NULL, path, interface, member);
- } else {
- SET_FOREACH(n, names, i) {
- last = n;
- allow = policy_check_one_send(p, uid, gid, message_type, n, path, interface, member);
- if (allow)
- break;
- }
- if (!allow) {
- STRV_FOREACH(nv, namesv) {
- last = *nv;
- allow = policy_check_one_send(p, uid, gid, message_type, *nv, path, interface, member);
- if (allow)
- break;
- }
- }
- }
-
- if (out_used_name)
- *out_used_name = last;
-
- log_full(LOG_AUTH | (!allow ? LOG_WARNING : LOG_DEBUG),
- "Send permission check %s for uid=" UID_FMT " gid=" GID_FMT" message=%s name=%s path=%s interface=%s member=%s: %s",
- dbus_to_kernel ? "dbus-1 to kernel" : "kernel to dbus-1", uid, gid, bus_message_type_to_string(message_type), strna(last),
- strna(path), strna(interface), strna(member), allow ? "ALLOW" : "DENY");
-
- return allow;
-}
-
-int policy_load(Policy *p, char **files) {
- char **i;
- int r;
-
- assert(p);
-
- STRV_FOREACH(i, files) {
-
- r = file_load(p, *i);
- if (r == -EISDIR) {
- _cleanup_strv_free_ char **l = NULL;
- char **j;
-
- r = conf_files_list(&l, ".conf", NULL, *i, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to get configuration file list: %m");
-
- STRV_FOREACH(j, l)
- file_load(p, *j);
- }
-
- /* We ignore all errors but EISDIR, and just proceed. */
- }
-
- return 0;
-}
-
-void policy_free(Policy *p) {
- PolicyItem *i, *first;
-
- if (!p)
- return;
-
- while ((i = p->default_items)) {
- LIST_REMOVE(items, p->default_items, i);
- policy_item_free(i);
- }
-
- while ((i = p->mandatory_items)) {
- LIST_REMOVE(items, p->mandatory_items, i);
- policy_item_free(i);
- }
-
- while ((i = p->on_console_items)) {
- LIST_REMOVE(items, p->on_console_items, i);
- policy_item_free(i);
- }
-
- while ((i = p->no_console_items)) {
- LIST_REMOVE(items, p->no_console_items, i);
- policy_item_free(i);
- }
-
- while ((first = hashmap_steal_first(p->user_items))) {
-
- while ((i = first)) {
- LIST_REMOVE(items, first, i);
- policy_item_free(i);
- }
- }
-
- while ((first = hashmap_steal_first(p->group_items))) {
-
- while ((i = first)) {
- LIST_REMOVE(items, first, i);
- policy_item_free(i);
- }
- }
-
- hashmap_free(p->user_items);
- hashmap_free(p->group_items);
-
- p->user_items = p->group_items = NULL;
-}
-
-static void dump_items(PolicyItem *items, const char *prefix) {
-
- PolicyItem *i;
-
- if (!items)
- return;
-
- if (!prefix)
- prefix = "";
-
- LIST_FOREACH(items, i, items) {
-
- printf("%sType: %s\n"
- "%sClass: %s\n",
- prefix, policy_item_type_to_string(i->type),
- prefix, policy_item_class_to_string(i->class));
-
- if (i->interface)
- printf("%sInterface: %s\n",
- prefix, i->interface);
-
- if (i->member)
- printf("%sMember: %s\n",
- prefix, i->member);
-
- if (i->error)
- printf("%sError: %s\n",
- prefix, i->error);
-
- if (i->path)
- printf("%sPath: %s\n",
- prefix, i->path);
-
- if (i->name)
- printf("%sName: %s\n",
- prefix, i->name);
-
- if (i->message_type != 0)
- printf("%sMessage Type: %s\n",
- prefix, bus_message_type_to_string(i->message_type));
-
- if (i->uid_valid) {
- _cleanup_free_ char *user;
-
- user = uid_to_name(i->uid);
-
- printf("%sUser: %s ("UID_FMT")\n",
- prefix, strna(user), i->uid);
- }
-
- if (i->gid_valid) {
- _cleanup_free_ char *group;
-
- group = gid_to_name(i->gid);
-
- printf("%sGroup: %s ("GID_FMT")\n",
- prefix, strna(group), i->gid);
- }
- printf("%s-\n", prefix);
- }
-}
-
-static void dump_hashmap_items(Hashmap *h) {
- PolicyItem *i;
- Iterator j;
- void *k;
-
- HASHMAP_FOREACH_KEY(i, k, h, j) {
- printf("\t%s Item for " UID_FMT ":\n", draw_special_char(DRAW_ARROW), PTR_TO_UID(k));
- dump_items(i, "\t\t");
- }
-}
-
-void policy_dump(Policy *p) {
-
- printf("%s Default Items:\n", draw_special_char(DRAW_ARROW));
- dump_items(p->default_items, "\t");
-
- printf("%s Group Items:\n", draw_special_char(DRAW_ARROW));
- dump_hashmap_items(p->group_items);
-
- printf("%s User Items:\n", draw_special_char(DRAW_ARROW));
- dump_hashmap_items(p->user_items);
-
- printf("%s On-Console Items:\n", draw_special_char(DRAW_ARROW));
- dump_items(p->on_console_items, "\t");
-
- printf("%s No-Console Items:\n", draw_special_char(DRAW_ARROW));
- dump_items(p->no_console_items, "\t");
-
- printf("%s Mandatory Items:\n", draw_special_char(DRAW_ARROW));
- dump_items(p->mandatory_items, "\t");
-
- fflush(stdout);
-}
-
-int shared_policy_new(SharedPolicy **out) {
- SharedPolicy *sp;
- int r;
-
- sp = new0(SharedPolicy, 1);
- if (!sp)
- return log_oom();
-
- r = pthread_mutex_init(&sp->lock, NULL);
- if (r != 0) {
- r = log_error_errno(r, "Cannot initialize shared policy mutex: %m");
- goto exit_free;
- }
-
- r = pthread_rwlock_init(&sp->rwlock, NULL);
- if (r != 0) {
- r = log_error_errno(r, "Cannot initialize shared policy rwlock: %m");
- goto exit_mutex;
- }
-
- *out = sp;
- sp = NULL;
- return 0;
-
- /* pthread lock destruction is not fail-safe... meh! */
-exit_mutex:
- pthread_mutex_destroy(&sp->lock);
-exit_free:
- free(sp);
- return r;
-}
-
-SharedPolicy *shared_policy_free(SharedPolicy *sp) {
- if (!sp)
- return NULL;
-
- policy_free(sp->policy);
- pthread_rwlock_destroy(&sp->rwlock);
- pthread_mutex_destroy(&sp->lock);
- strv_free(sp->configuration);
- free(sp);
-
- return NULL;
-}
-
-static int shared_policy_reload_unlocked(SharedPolicy *sp, char **configuration) {
- Policy old, buffer = {};
- bool free_old;
- int r;
-
- assert(sp);
-
- r = policy_load(&buffer, configuration);
- if (r < 0)
- return log_error_errno(r, "Failed to load policy: %m");
-
- log_debug("Reloading configuration");
- /* policy_dump(&buffer); */
-
- pthread_rwlock_wrlock(&sp->rwlock);
- memcpy(&old, &sp->buffer, sizeof(old));
- memcpy(&sp->buffer, &buffer, sizeof(buffer));
- free_old = !!sp->policy;
- sp->policy = &sp->buffer;
- pthread_rwlock_unlock(&sp->rwlock);
-
- if (free_old)
- policy_free(&old);
-
- return 0;
-}
-
-int shared_policy_reload(SharedPolicy *sp) {
- int r;
-
- assert(sp);
-
- pthread_mutex_lock(&sp->lock);
- r = shared_policy_reload_unlocked(sp, sp->configuration);
- pthread_mutex_unlock(&sp->lock);
-
- return r;
-}
-
-int shared_policy_preload(SharedPolicy *sp, char **configuration) {
- _cleanup_strv_free_ char **conf = NULL;
- int r = 0;
-
- assert(sp);
-
- conf = strv_copy(configuration);
- if (!conf)
- return log_oom();
-
- pthread_mutex_lock(&sp->lock);
- if (!sp->policy) {
- r = shared_policy_reload_unlocked(sp, conf);
- if (r >= 0) {
- sp->configuration = conf;
- conf = NULL;
- }
- }
- pthread_mutex_unlock(&sp->lock);
-
- return r;
-}
-
-Policy *shared_policy_acquire(SharedPolicy *sp) {
- assert(sp);
-
- pthread_rwlock_rdlock(&sp->rwlock);
- if (sp->policy)
- return sp->policy;
- pthread_rwlock_unlock(&sp->rwlock);
-
- return NULL;
-}
-
-void shared_policy_release(SharedPolicy *sp, Policy *p) {
- assert(sp);
- assert(!p || sp->policy == p);
-
- if (p)
- pthread_rwlock_unlock(&sp->rwlock);
-}
-
-static const char* const policy_item_type_table[_POLICY_ITEM_TYPE_MAX] = {
- [_POLICY_ITEM_TYPE_UNSET] = "unset",
- [POLICY_ITEM_ALLOW] = "allow",
- [POLICY_ITEM_DENY] = "deny",
-};
-DEFINE_STRING_TABLE_LOOKUP(policy_item_type, PolicyItemType);
-
-static const char* const policy_item_class_table[_POLICY_ITEM_CLASS_MAX] = {
- [_POLICY_ITEM_CLASS_UNSET] = "unset",
- [POLICY_ITEM_SEND] = "send",
- [POLICY_ITEM_RECV] = "recv",
- [POLICY_ITEM_OWN] = "own",
- [POLICY_ITEM_OWN_PREFIX] = "own-prefix",
- [POLICY_ITEM_USER] = "user",
- [POLICY_ITEM_GROUP] = "group",
- [POLICY_ITEM_IGNORE] = "ignore",
-};
-DEFINE_STRING_TABLE_LOOKUP(policy_item_class, PolicyItemClass);
diff --git a/src/libbus-proxy-core/bus-xml-policy.h b/src/libbus-proxy-core/bus-xml-policy.h
deleted file mode 100644
index 3dcddaa048..0000000000
--- a/src/libbus-proxy-core/bus-xml-policy.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <pthread.h>
-
-#include "hashmap.h"
-#include "list.h"
-
-typedef enum PolicyItemType {
- _POLICY_ITEM_TYPE_UNSET = 0,
- POLICY_ITEM_ALLOW,
- POLICY_ITEM_DENY,
- _POLICY_ITEM_TYPE_MAX,
- _POLICY_ITEM_TYPE_INVALID = -1,
-} PolicyItemType;
-
-typedef enum PolicyItemClass {
- _POLICY_ITEM_CLASS_UNSET = 0,
- POLICY_ITEM_SEND,
- POLICY_ITEM_RECV,
- POLICY_ITEM_OWN,
- POLICY_ITEM_OWN_PREFIX,
- POLICY_ITEM_USER,
- POLICY_ITEM_GROUP,
- POLICY_ITEM_IGNORE,
- _POLICY_ITEM_CLASS_MAX,
- _POLICY_ITEM_CLASS_INVALID = -1,
-} PolicyItemClass;
-
-typedef struct PolicyItem PolicyItem;
-
-struct PolicyItem {
- PolicyItemType type;
- PolicyItemClass class;
- char *interface;
- char *member;
- char *error;
- char *path;
- char *name;
- uint8_t message_type;
- uid_t uid;
- gid_t gid;
-
- bool uid_valid, gid_valid;
-
- LIST_FIELDS(PolicyItem, items);
-};
-
-typedef struct Policy {
- LIST_HEAD(PolicyItem, default_items);
- LIST_HEAD(PolicyItem, mandatory_items);
- LIST_HEAD(PolicyItem, on_console_items);
- LIST_HEAD(PolicyItem, no_console_items);
- Hashmap *user_items;
- Hashmap *group_items;
-} Policy;
-
-typedef struct SharedPolicy {
- char **configuration;
- pthread_mutex_t lock;
- pthread_rwlock_t rwlock;
- Policy buffer;
- Policy *policy;
-} SharedPolicy;
-
-/* policy */
-
-int policy_load(Policy *p, char **files);
-void policy_free(Policy *p);
-
-bool policy_check_own(Policy *p, uid_t uid, gid_t gid, const char *name);
-bool policy_check_hello(Policy *p, uid_t uid, gid_t gid);
-bool policy_check_one_recv(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- const char *name,
- const char *path,
- const char *interface,
- const char *member);
-bool policy_check_recv(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- Set *names,
- char **namesv,
- const char *path,
- const char *interface,
- const char *member,
- bool dbus_to_kernel);
-bool policy_check_one_send(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- const char *name,
- const char *path,
- const char *interface,
- const char *member);
-bool policy_check_send(Policy *p,
- uid_t uid,
- gid_t gid,
- int message_type,
- Set *names,
- char **namesv,
- const char *path,
- const char *interface,
- const char *member,
- bool dbus_to_kernel,
- char **out_used_name);
-
-void policy_dump(Policy *p);
-
-const char* policy_item_type_to_string(PolicyItemType t) _const_;
-PolicyItemType policy_item_type_from_string(const char *s) _pure_;
-
-const char* policy_item_class_to_string(PolicyItemClass t) _const_;
-PolicyItemClass policy_item_class_from_string(const char *s) _pure_;
-
-/* shared policy */
-
-int shared_policy_new(SharedPolicy **out);
-SharedPolicy *shared_policy_free(SharedPolicy *sp);
-
-int shared_policy_reload(SharedPolicy *sp);
-int shared_policy_preload(SharedPolicy *sp, char **configuration);
-Policy *shared_policy_acquire(SharedPolicy *sp);
-void shared_policy_release(SharedPolicy *sp, Policy *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(SharedPolicy*, shared_policy_free);
diff --git a/src/libbus-proxy-core/driver.c b/src/libbus-proxy-core/driver.c
deleted file mode 100644
index 133b2e0f39..0000000000
--- a/src/libbus-proxy-core/driver.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2013 Daniel Mack
- Copyright 2014 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stddef.h>
-#include <string.h>
-
-#include <systemd/sd-bus.h>
-
-#include "alloc-util.h"
-#include "bus-internal.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "driver.h"
-#include "env-util.h"
-#include "proxy.h"
-#include "set.h"
-#include "strv.h"
-#include "synthesize.h"
-#include "util.h"
-
-static int get_creds_by_name(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
- int r;
-
- assert(bus);
- assert(name);
- assert(_creds);
-
- r = sd_bus_get_name_creds(bus, name, mask, &c);
- if (r == -ESRCH || r == -ENXIO)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
- if (r < 0)
- return r;
-
- *_creds = c;
- c = NULL;
-
- return 0;
-}
-
-static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
- const char *name;
- int r;
-
- assert(bus);
- assert(m);
- assert(_creds);
-
- r = sd_bus_message_read(m, "s", &name);
- if (r < 0)
- return r;
-
- return get_creds_by_name(bus, name, mask, _creds, error);
-}
-
-static int driver_activation(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- ProxyActivation *activation = userdata;
-
- /*
- * The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
- * whether this succeeded, failed, was not implemented or timed out. We
- * cannot assume that the target reacts to this properly. Hence, just
- * send the reply to the activation request and be done.
- */
-
- m = activation->request; /* claim reference */
-
- --activation->proxy->n_activations;
- LIST_REMOVE(activations_by_proxy, activation->proxy->activations, activation);
- sd_bus_slot_unref(activation->slot);
- free(activation);
-
- return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
-}
-
-int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names) {
- int r;
-
- assert(a);
- assert(b);
- assert(m);
-
- if (!a->is_kernel)
- return 0;
-
- if (!streq_ptr(sd_bus_message_get_destination(m), "org.freedesktop.DBus"))
- return 0;
-
- /* The "Hello()" call is is handled in process_hello() */
-
- if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
-
- if (!sd_bus_message_has_signature(m, ""))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- return synthetic_reply_method_return(m, "s",
- "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
- "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
- "<node>\n"
- " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
- " <method name=\"Introspect\">\n"
- " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
- " </method>\n"
- " </interface>\n"
- " <interface name=\"org.freedesktop.DBus\">\n"
- " <method name=\"AddMatch\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " </method>\n"
- " <method name=\"RemoveMatch\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " </method>\n"
- " <method name=\"GetConnectionCredentials\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"a{sv}\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"ay\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"GetConnectionUnixProcessID\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"GetConnectionUnixUser\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"GetId\">\n"
- " <arg type=\"s\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"GetNameOwner\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"s\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"Hello\">\n"
- " <arg type=\"s\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"ListActivatableNames\">\n"
- " <arg type=\"as\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"ListNames\">\n"
- " <arg type=\"as\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"ListQueuedOwners\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"as\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"NameHasOwner\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"b\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"ReleaseName\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"ReloadConfig\">\n"
- " </method>\n"
- " <method name=\"RequestName\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"StartServiceByName\">\n"
- " <arg type=\"s\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"in\"/>\n"
- " <arg type=\"u\" direction=\"out\"/>\n"
- " </method>\n"
- " <method name=\"UpdateActivationEnvironment\">\n"
- " <arg type=\"a{ss}\" direction=\"in\"/>\n"
- " </method>\n"
- " <signal name=\"NameAcquired\">\n"
- " <arg type=\"s\"/>\n"
- " </signal>\n"
- " <signal name=\"NameLost\">\n"
- " <arg type=\"s\"/>\n"
- " </signal>\n"
- " <signal name=\"NameOwnerChanged\">\n"
- " <arg type=\"s\"/>\n"
- " <arg type=\"s\"/>\n"
- " <arg type=\"s\"/>\n"
- " </signal>\n"
- " </interface>\n"
- "</node>\n");
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "AddMatch")) {
- const char *match;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "s", &match);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_add_match(a, NULL, match, proxy_match, p);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_reply_method_return(m, NULL);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RemoveMatch")) {
- const char *match;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "s", &match);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = bus_remove_match_by_string(a, match, NULL, NULL);
- if (r == 0)
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule not found"));
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_reply_method_return(m, NULL);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionCredentials")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = get_creds_by_message(a, m, SD_BUS_CREDS_PID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SELINUX_CONTEXT, &creds, &error);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, &error);
-
- r = sd_bus_message_new_method_return(m, &reply);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_open_container(reply, 'a', "{sv}");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- /* Due to i.e. namespace translations some data might be missing */
-
- if (creds->mask & SD_BUS_CREDS_PID) {
- r = sd_bus_message_append(reply, "{sv}", "ProcessID", "u", (uint32_t) creds->pid);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- if (creds->mask & SD_BUS_CREDS_EUID) {
- r = sd_bus_message_append(reply, "{sv}", "UnixUserID", "u", (uint32_t) creds->euid);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- if (creds->mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
- r = sd_bus_message_open_container(reply, 'e', "sv");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_append(reply, "s", "LinuxSecurityLabel");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_open_container(reply, 'v', "ay");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_append_array(reply, 'y', creds->label, strlen(creds->label));
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_driver_send(m->bus, reply);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = get_creds_by_message(a, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, &error);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, &error);
-
- if (!(creds->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
- return synthetic_reply_method_errno(m, -EOPNOTSUPP, NULL);
-
- r = sd_bus_message_new_method_return(m, &reply);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_append_array(reply, 'y', creds->label, strlen(creds->label));
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_driver_send(m->bus, reply);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = get_creds_by_message(a, m, SD_BUS_CREDS_PID, &creds, &error);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, &error);
-
- if (!(creds->mask & SD_BUS_CREDS_PID))
- return synthetic_reply_method_errno(m, -EOPNOTSUPP, NULL);
-
- return synthetic_reply_method_return(m, "u", (uint32_t) creds->pid);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = get_creds_by_message(a, m, SD_BUS_CREDS_EUID, &creds, &error);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, &error);
-
- if (!(creds->mask & SD_BUS_CREDS_EUID))
- return synthetic_reply_method_errno(m, -EOPNOTSUPP, NULL);
-
- return synthetic_reply_method_return(m, "u", (uint32_t) creds->euid);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetId")) {
- sd_id128_t server_id;
- char buf[SD_ID128_STRING_MAX];
-
- if (!sd_bus_message_has_signature(m, ""))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_get_bus_id(a, &server_id);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_reply_method_return(m, "s", sd_id128_to_string(server_id, buf));
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetNameOwner")) {
- const char *name;
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "s", &name);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (streq(name, "org.freedesktop.DBus"))
- return synthetic_reply_method_return(m, "s", "org.freedesktop.DBus");
-
- r = get_creds_by_name(a, name, SD_BUS_CREDS_UNIQUE_NAME, &creds, &error);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, &error);
-
- if (!(creds->mask & SD_BUS_CREDS_UNIQUE_NAME))
- return synthetic_reply_method_errno(m, -EOPNOTSUPP, NULL);
-
- return synthetic_reply_method_return(m, "s", creds->unique_name);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListActivatableNames")) {
- _cleanup_strv_free_ char **names = NULL;
-
- if (!sd_bus_message_has_signature(m, ""))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_list_names(a, NULL, &names);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- /* Let's sort the names list to make it stable */
- strv_sort(names);
-
- return synthetic_reply_method_return_strv(m, names);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListNames")) {
- _cleanup_strv_free_ char **names = NULL;
-
- if (!sd_bus_message_has_signature(m, ""))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_list_names(a, &names, NULL);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = strv_extend(&names, "org.freedesktop.DBus");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- /* Let's sort the names list to make it stable */
- strv_sort(names);
-
- return synthetic_reply_method_return_strv(m, names);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListQueuedOwners")) {
- struct kdbus_cmd_list cmd = {
- .flags = KDBUS_LIST_QUEUED,
- .size = sizeof(cmd),
- };
- struct kdbus_info *name_list, *name;
- _cleanup_strv_free_ char **owners = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *arg0;
- int err = 0;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "s", &arg0);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_get_name_creds(a, arg0, 0, NULL);
- if (r == -ESRCH || r == -ENXIO) {
- sd_bus_error_setf(&error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owners of name '%s': no such name.", arg0);
- return synthetic_reply_method_errno(m, r, &error);
- }
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = ioctl(a->input_fd, KDBUS_CMD_LIST, &cmd);
- if (r < 0)
- return synthetic_reply_method_errno(m, -errno, NULL);
-
- name_list = (struct kdbus_info *) ((uint8_t *) a->kdbus_buffer + cmd.offset);
-
- KDBUS_FOREACH(name, name_list, cmd.list_size) {
- struct kdbus_item *item;
- char *n;
-
- KDBUS_ITEM_FOREACH(item, name, items) {
- if (item->type == KDBUS_ITEM_OWNED_NAME) {
- if (!streq_ptr(item->name.name, arg0))
- continue;
-
- if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
- err = -ENOMEM;
- break;
- }
-
- r = strv_consume(&owners, n);
- if (r < 0) {
- err = r;
- break;
- }
- }
- }
-
- if (err < 0)
- break;
- }
-
- r = bus_kernel_cmd_free(a, cmd.offset);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (err < 0)
- return synthetic_reply_method_errno(m, err, NULL);
-
- return synthetic_reply_method_return_strv(m, owners);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "NameHasOwner")) {
- const char *name;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "s", &name);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (streq(name, "org.freedesktop.DBus"))
- return synthetic_reply_method_return(m, "b", true);
-
- r = sd_bus_get_name_creds(a, name, 0, NULL);
- if (r < 0 && r != -ESRCH && r != -ENXIO)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_reply_method_return(m, "b", r >= 0);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ReleaseName")) {
- const char *name;
-
- if (!sd_bus_message_has_signature(m, "s"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "s", &name);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_release_name(a, name);
- if (r < 0) {
- if (r == -ESRCH)
- return synthetic_reply_method_return(m, "u", BUS_NAME_NON_EXISTENT);
- if (r == -EADDRINUSE)
- return synthetic_reply_method_return(m, "u", BUS_NAME_NOT_OWNER);
-
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- set_remove(owned_names, (char*) name);
-
- return synthetic_reply_method_return(m, "u", BUS_NAME_RELEASED);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ReloadConfig")) {
- if (!sd_bus_message_has_signature(m, ""))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = shared_policy_reload(sp);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_reply_method_return(m, NULL);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RequestName")) {
- const char *name;
- uint32_t flags, param;
- bool in_queue;
-
- if (!sd_bus_message_has_signature(m, "su"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "su", &name, &flags);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (sp) {
- Policy *policy;
- bool denied;
-
- policy = shared_policy_acquire(sp);
- denied = !policy_check_own(policy, ucred->uid, ucred->gid, name);
- shared_policy_release(sp, policy);
- if (denied)
- return synthetic_reply_method_errno(m, -EPERM, NULL);
- }
-
- if ((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) != 0)
- return synthetic_reply_method_errno(m, -EINVAL, NULL);
-
- param = 0;
- if (flags & BUS_NAME_ALLOW_REPLACEMENT)
- param |= SD_BUS_NAME_ALLOW_REPLACEMENT;
- if (flags & BUS_NAME_REPLACE_EXISTING)
- param |= SD_BUS_NAME_REPLACE_EXISTING;
- if (!(flags & BUS_NAME_DO_NOT_QUEUE))
- param |= SD_BUS_NAME_QUEUE;
-
- r = set_put_strdup(owned_names, name);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_request_name(a, name, param);
- if (r < 0) {
- if (r == -EALREADY)
- return synthetic_reply_method_return(m, "u", BUS_NAME_ALREADY_OWNER);
-
- set_remove(owned_names, (char*) name);
-
- if (r == -EEXIST)
- return synthetic_reply_method_return(m, "u", BUS_NAME_EXISTS);
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- in_queue = (r == 0);
-
- if (in_queue)
- return synthetic_reply_method_return(m, "u", BUS_NAME_IN_QUEUE);
-
- return synthetic_reply_method_return(m, "u", BUS_NAME_PRIMARY_OWNER);
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "StartServiceByName")) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *msg = NULL;
- ProxyActivation *activation;
- const char *name;
- uint64_t cookie;
- uint32_t flags;
-
- if (!sd_bus_message_has_signature(m, "su"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_read(m, "su", &name, &flags);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (flags != 0)
- return synthetic_reply_method_errno(m, -EINVAL, NULL);
-
- r = sd_bus_get_name_creds(a, name, 0, NULL);
- if (r >= 0 || streq(name, "org.freedesktop.DBus"))
- return synthetic_reply_method_return(m, "u", BUS_START_REPLY_ALREADY_RUNNING);
- if (r != -ESRCH)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (p->n_activations >= PROXY_ACTIVATIONS_MAX)
- return synthetic_reply_method_errno(m, -EMFILE, NULL);
-
- r = sd_bus_message_get_cookie(m, &cookie);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_new_method_call(a,
- &msg,
- name,
- "/",
- "org.freedesktop.DBus.Peer",
- "Ping");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = bus_message_seal(msg, cookie, BUS_DEFAULT_TIMEOUT);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- activation = new0(ProxyActivation, 1);
- if (!activation)
- return synthetic_reply_method_errno(m, -ENOMEM, NULL);
-
- r = sd_bus_call_async(a,
- &activation->slot,
- msg,
- driver_activation,
- activation,
- 0);
- if (r < 0) {
- free(activation);
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- activation->proxy = p;
- activation->request = sd_bus_message_ref(m);
- LIST_PREPEND(activations_by_proxy, p->activations, activation);
- ++p->n_activations;
- return 1;
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *msg = NULL;
- _cleanup_strv_free_ char **args = NULL;
-
- if (!sd_bus_message_has_signature(m, "a{ss}"))
- return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{ss}");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "ss")) > 0) {
- _cleanup_free_ char *s = NULL;
- const char *key;
- const char *value;
-
- r = sd_bus_message_read(m, "ss", &key, &value);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- s = strjoin(key, "=", value, NULL);
- if (!s)
- return synthetic_reply_method_errno(m, -ENOMEM, NULL);
-
- if (!env_assignment_is_valid(s)) {
- log_warning("UpdateActivationEnvironment() called with invalid assignment, discarding: %s", s);
- } else {
- r = strv_extend(&args, s);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
- }
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- if (strv_isempty(args)) /* nothing to do? */
- return synthetic_reply_method_return(m, NULL);
-
- r = sd_bus_message_new_method_call(
- a,
- &msg,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "SetEnvironment");
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_message_append_strv(msg, args);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- r = sd_bus_call(a, msg, 0, NULL, NULL);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
-
- return synthetic_reply_method_return(m, NULL);
-
- } else {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method '%s'.", m->member);
-
- return synthetic_reply_method_errno(m, r, &error);
- }
-}
diff --git a/src/libbus-proxy-core/proxy.c b/src/libbus-proxy-core/proxy.c
deleted file mode 100644
index bcfbab0dad..0000000000
--- a/src/libbus-proxy-core/proxy.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2013 Daniel Mack
- Copyright 2014 Kay Sievers
- Copyright 2014 David Herrmann
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <poll.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <systemd/sd-bus.h>
-#include <systemd/sd-daemon.h>
-
-#include "alloc-util.h"
-#include "bus-control.h"
-#include "bus-internal.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "bus-xml-policy.h"
-#include "driver.h"
-#include "fd-util.h"
-#include "formats-util.h"
-#include "log.h"
-#include "proxy.h"
-#include "set.h"
-#include "strv.h"
-#include "synthesize.h"
-#include "user-util.h"
-#include "util.h"
-
-static int proxy_create_destination(Proxy *p, const char *destination, const char *local_sec, bool negotiate_fds) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *b = NULL;
- int r;
-
- r = sd_bus_new(&b);
- if (r < 0)
- return log_error_errno(r, "Failed to allocate bus: %m");
-
- r = sd_bus_set_description(b, "sd-proxy");
- if (r < 0)
- return log_error_errno(r, "Failed to set bus name: %m");
-
- r = sd_bus_set_address(b, destination);
- if (r < 0)
- return log_error_errno(r, "Failed to set address to connect to: %m");
-
- r = sd_bus_negotiate_fds(b, negotiate_fds);
- if (r < 0)
- return log_error_errno(r, "Failed to set FD negotiation: %m");
-
- r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SELINUX_CONTEXT);
- if (r < 0)
- return log_error_errno(r, "Failed to set credential negotiation: %m");
-
- if (p->local_creds.pid > 0) {
- b->fake_pids.pid = p->local_creds.pid;
- b->fake_pids_valid = true;
-
- b->fake_creds.uid = UID_INVALID;
- b->fake_creds.euid = p->local_creds.uid;
- b->fake_creds.suid = UID_INVALID;
- b->fake_creds.fsuid = UID_INVALID;
- b->fake_creds.gid = GID_INVALID;
- b->fake_creds.egid = p->local_creds.gid;
- b->fake_creds.sgid = GID_INVALID;
- b->fake_creds.fsgid = GID_INVALID;
- b->fake_creds_valid = true;
- }
-
- if (local_sec) {
- b->fake_label = strdup(local_sec);
- if (!b->fake_label)
- return log_oom();
- }
-
- b->manual_peer_interface = true;
-
- r = sd_bus_start(b);
- if (r < 0)
- return log_error_errno(r, "Failed to start bus client: %m");
-
- p->destination_bus = b;
- b = NULL;
- return 0;
-}
-
-static int proxy_create_local(Proxy *p, bool negotiate_fds) {
- sd_id128_t server_id;
- sd_bus *b;
- int r;
-
- r = sd_bus_new(&b);
- if (r < 0)
- return log_error_errno(r, "Failed to allocate bus: %m");
-
- r = sd_bus_set_fd(b, p->local_in, p->local_out);
- if (r < 0) {
- sd_bus_unref(b);
- return log_error_errno(r, "Failed to set fds: %m");
- }
-
- /* The fds are now owned by the bus, and we indicate that by
- * storing the bus object in the proxy object. */
- p->local_bus = b;
-
- r = sd_bus_get_bus_id(p->destination_bus, &server_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get server ID: %m");
-
- r = sd_bus_set_server(b, 1, server_id);
- if (r < 0)
- return log_error_errno(r, "Failed to set server mode: %m");
-
- r = sd_bus_negotiate_fds(b, negotiate_fds);
- if (r < 0)
- return log_error_errno(r, "Failed to set FD negotiation: %m");
-
- r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SELINUX_CONTEXT);
- if (r < 0)
- return log_error_errno(r, "Failed to set credential negotiation: %m");
-
- r = sd_bus_set_anonymous(b, true);
- if (r < 0)
- return log_error_errno(r, "Failed to set anonymous authentication: %m");
-
- b->manual_peer_interface = true;
-
- r = sd_bus_start(b);
- if (r < 0)
- return log_error_errno(r, "Failed to start bus client: %m");
-
- return 0;
-}
-
-static int proxy_match_synthetic(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- Proxy *p = userdata;
-
- p->synthetic_matched = true;
- return 0; /* make sure to continue processing it in further handlers */
-}
-
-/*
- * We always need NameOwnerChanged so we can synthesize NameLost and
- * NameAcquired. Furthermore, dbus-1 always passes unicast-signals through, so
- * subscribe unconditionally.
- */
-static int proxy_prepare_matches(Proxy *p) {
- _cleanup_free_ char *match = NULL;
- const char *unique;
- int r;
-
- if (!p->destination_bus->is_kernel)
- return 0;
-
- r = sd_bus_get_unique_name(p->destination_bus, &unique);
- if (r < 0)
- return log_error_errno(r, "Failed to get unique name: %m");
-
- match = strjoin("type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged',"
- "arg1='",
- unique,
- "'",
- NULL);
- if (!match)
- return log_oom();
-
- r = sd_bus_add_match(p->destination_bus, NULL, match, proxy_match_synthetic, p);
- if (r < 0)
- return log_error_errno(r, "Failed to add match for NameLost: %m");
-
- free(match);
- match = strjoin("type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged',"
- "arg2='",
- unique,
- "'",
- NULL);
- if (!match)
- return log_oom();
-
- r = sd_bus_add_match(p->destination_bus, NULL, match, proxy_match_synthetic, p);
- if (r < 0)
- return log_error_errno(r, "Failed to add match for NameAcquired: %m");
-
- free(match);
- match = strjoin("type='signal',"
- "destination='",
- unique,
- "'",
- NULL);
- if (!match)
- return log_oom();
-
- r = sd_bus_add_match(p->destination_bus, NULL, match, proxy_match_synthetic, p);
- if (r < 0)
- log_error_errno(r, "Failed to add match for directed signals: %m");
- /* FIXME: temporarily ignore error to support older kdbus versions */
-
- return 0;
-}
-
-int proxy_new(Proxy **out, int in_fd, int out_fd, const char *destination) {
- _cleanup_(proxy_freep) Proxy *p = NULL;
- _cleanup_free_ char *local_sec = NULL;
- bool is_unix;
- int r;
-
- /* This takes possession/destroys the file descriptors passed
- * in even on failure. The caller should hence forget about
- * the fds in all cases after calling this function and not
- * close them. */
-
- p = new0(Proxy, 1);
- if (!p) {
- safe_close(in_fd);
- safe_close(out_fd);
- return log_oom();
- }
-
- p->local_in = in_fd;
- p->local_out = out_fd;
-
- p->owned_names = set_new(&string_hash_ops);
- if (!p->owned_names)
- return log_oom();
-
- is_unix = sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
- sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
-
- if (is_unix) {
- (void) getpeercred(in_fd, &p->local_creds);
- (void) getpeersec(in_fd, &local_sec);
- }
-
- r = proxy_create_destination(p, destination, local_sec, is_unix);
- if (r < 0)
- return r;
-
- r = proxy_create_local(p, is_unix);
- if (r < 0)
- return r;
-
- r = proxy_prepare_matches(p);
- if (r < 0)
- return r;
-
- *out = p;
- p = NULL;
-
- return 0;
-}
-
-Proxy *proxy_free(Proxy *p) {
- ProxyActivation *activation;
-
- if (!p)
- return NULL;
-
- while ((activation = p->activations)) {
- LIST_REMOVE(activations_by_proxy, p->activations, activation);
- sd_bus_message_unref(activation->request);
- sd_bus_slot_unref(activation->slot);
- free(activation);
- }
-
- if (p->local_bus)
- sd_bus_flush_close_unref(p->local_bus);
- else {
- safe_close(p->local_in);
- if (p->local_out != p->local_in)
- safe_close(p->local_out);
- }
-
- sd_bus_flush_close_unref(p->destination_bus);
- set_free_free(p->owned_names);
- free(p);
-
- return NULL;
-}
-
-int proxy_set_policy(Proxy *p, SharedPolicy *sp, char **configuration) {
- _cleanup_strv_free_ char **strv = NULL;
- Policy *policy;
- int r;
-
- assert(p);
- assert(sp);
-
- /* no need to load legacy policy if destination is not kdbus */
- if (!p->destination_bus->is_kernel)
- return 0;
-
- p->policy = sp;
-
- policy = shared_policy_acquire(sp);
- if (policy) {
- /* policy already pre-loaded */
- shared_policy_release(sp, policy);
- return 0;
- }
-
- if (!configuration) {
- const char *scope;
-
- r = sd_bus_get_scope(p->destination_bus, &scope);
- if (r < 0)
- return log_error_errno(r, "Couldn't determine bus scope: %m");
-
- if (streq(scope, "system"))
- strv = strv_new("/usr/share/dbus-1/system.conf",
- "/etc/dbus-1/system.conf",
- "/usr/share/dbus-1/system.d/",
- "/etc/dbus-1/system.d/",
- "/etc/dbus-1/system-local.conf",
- NULL);
- else if (streq(scope, "user"))
- strv = strv_new("/usr/share/dbus-1/session.conf",
- "/etc/dbus-1/session.conf",
- "/usr/share/dbus-1/session.d/",
- "/etc/dbus-1/session.d/",
- "/etc/dbus-1/session-local.conf",
- NULL);
- else
- return log_error("Unknown scope %s, don't know which policy to load. Refusing.", scope);
-
- if (!strv)
- return log_oom();
-
- configuration = strv;
- }
-
- return shared_policy_preload(sp, configuration);
-}
-
-int proxy_hello_policy(Proxy *p, uid_t original_uid) {
- Policy *policy;
- int r = 0;
-
- assert(p);
-
- if (!p->policy)
- return 0;
-
- policy = shared_policy_acquire(p->policy);
-
- if (p->local_creds.uid == original_uid)
- log_debug("Permitting access, since bus owner matches bus client.");
- else if (policy_check_hello(policy, p->local_creds.uid, p->local_creds.gid))
- log_debug("Permitting access due to XML policy.");
- else
- r = log_error_errno(EPERM, "Policy denied connection.");
-
- shared_policy_release(p->policy, policy);
-
- return r;
-}
-
-static int proxy_wait(Proxy *p) {
- uint64_t timeout_destination, timeout_local, t;
- int events_destination, events_local, fd;
- struct timespec _ts, *ts;
- struct pollfd *pollfd;
- int r;
-
- assert(p);
-
- fd = sd_bus_get_fd(p->destination_bus);
- if (fd < 0)
- return log_error_errno(fd, "Failed to get fd: %m");
-
- events_destination = sd_bus_get_events(p->destination_bus);
- if (events_destination < 0)
- return log_error_errno(events_destination, "Failed to get events mask: %m");
-
- r = sd_bus_get_timeout(p->destination_bus, &timeout_destination);
- if (r < 0)
- return log_error_errno(r, "Failed to get timeout: %m");
-
- events_local = sd_bus_get_events(p->local_bus);
- if (events_local < 0)
- return log_error_errno(events_local, "Failed to get events mask: %m");
-
- r = sd_bus_get_timeout(p->local_bus, &timeout_local);
- if (r < 0)
- return log_error_errno(r, "Failed to get timeout: %m");
-
- t = timeout_destination;
- if (t == (uint64_t) -1 || (timeout_local != (uint64_t) -1 && timeout_local < timeout_destination))
- t = timeout_local;
-
- if (t == (uint64_t) -1)
- ts = NULL;
- else {
- usec_t nw;
-
- nw = now(CLOCK_MONOTONIC);
- if (t > nw)
- t -= nw;
- else
- t = 0;
-
- ts = timespec_store(&_ts, t);
- }
-
- pollfd = (struct pollfd[3]) {
- { .fd = fd, .events = events_destination, },
- { .fd = p->local_in, .events = events_local & POLLIN, },
- { .fd = p->local_out, .events = events_local & POLLOUT, },
- };
-
- r = ppoll(pollfd, 3, ts, NULL);
- if (r < 0)
- return log_error_errno(errno, "ppoll() failed: %m");
-
- return 0;
-}
-
-static int handle_policy_error(sd_bus_message *m, int r) {
- if (r == -ESRCH || r == -ENXIO)
- return synthetic_reply_method_errorf(m, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", m->destination);
-
- return r;
-}
-
-static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *policy, const struct ucred *our_ucred, Set *owned_names) {
- int r;
-
- assert(from);
- assert(to);
- assert(m);
-
- if (!policy)
- return 0;
-
- /*
- * dbus-1 distinguishes expected and non-expected replies by tracking
- * method-calls and timeouts. By default, DENY rules are *NEVER* applied
- * on expected replies, unless explicitly specified. But we dont track
- * method-calls, thus, we cannot know whether a reply is expected.
- * Fortunately, the kdbus forbids non-expected replies, so we can safely
- * ignore any policy on those and let the kernel deal with it.
- *
- * TODO: To be correct, we should only ignore policy-tags that are
- * applied on non-expected replies. However, so far we don't parse those
- * tags so we let everything pass. I haven't seen a DENY policy tag on
- * expected-replies, ever, so don't bother..
- */
- if (m->reply_cookie > 0)
- return 0;
-
- if (from->is_kernel) {
- uid_t sender_uid = UID_INVALID;
- gid_t sender_gid = GID_INVALID;
- char **sender_names = NULL;
-
- /* Driver messages are always OK */
- if (streq_ptr(m->sender, "org.freedesktop.DBus"))
- return 0;
-
- /* The message came from the kernel, and is sent to our legacy client. */
- (void) sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
-
- (void) sd_bus_creds_get_euid(&m->creds, &sender_uid);
- (void) sd_bus_creds_get_egid(&m->creds, &sender_gid);
-
- if (sender_uid == UID_INVALID || sender_gid == GID_INVALID) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *sender_creds = NULL;
-
- /* If the message came from another legacy
- * client, then the message creds will be
- * missing, simply because on legacy clients
- * per-message creds were unknown. In this
- * case, query the creds of the peer
- * instead. */
-
- r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID, true, &sender_creds);
- if (r < 0)
- return handle_policy_error(m, r);
-
- (void) sd_bus_creds_get_euid(sender_creds, &sender_uid);
- (void) sd_bus_creds_get_egid(sender_creds, &sender_gid);
- }
-
- /* First check whether the sender can send the message to our name */
- if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, owned_names, NULL, m->path, m->interface, m->member, false, NULL) &&
- policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, sender_names, m->path, m->interface, m->member, false))
- return 0;
-
- /* Return an error back to the caller */
- if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
- return synthetic_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML receiver policy.");
-
- /* Return 1, indicating that the message shall not be processed any further */
- return 1;
- }
-
- if (to->is_kernel) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *destination_creds = NULL;
- uid_t destination_uid = UID_INVALID;
- gid_t destination_gid = GID_INVALID;
- const char *destination_unique = NULL;
- char **destination_names = NULL;
- char *n;
-
- /* Driver messages are always OK */
- if (streq_ptr(m->destination, "org.freedesktop.DBus"))
- return 0;
-
- /* The message came from the legacy client, and is sent to kdbus. */
- if (m->destination) {
- r = bus_get_name_creds_kdbus(to, m->destination,
- SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME|
- SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID,
- true, &destination_creds);
- if (r < 0)
- return handle_policy_error(m, r);
-
- r = sd_bus_creds_get_unique_name(destination_creds, &destination_unique);
- if (r < 0)
- return handle_policy_error(m, r);
-
- (void) sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
-
- (void) sd_bus_creds_get_euid(destination_creds, &destination_uid);
- (void) sd_bus_creds_get_egid(destination_creds, &destination_gid);
- }
-
- /* First check if we (the sender) can send to this name */
- if (sd_bus_message_is_signal(m, NULL, NULL)) {
- /* If we forward a signal from dbus-1 to kdbus, we have
- * no idea who the recipient is. Therefore, we cannot
- * apply any dbus-1 policies that match on receiver
- * credentials. We know sd-bus always sets
- * KDBUS_MSG_SIGNAL, so the kernel applies policies to
- * the message. Therefore, skip policy checks in this
- * case. */
- return 0;
- } else if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, destination_names, m->path, m->interface, m->member, true, &n)) {
- if (n) {
- /* If we made a receiver decision, then remember which
- * name's policy we used, and to which unique ID it
- * mapped when we made the decision. Then, let's pass
- * this to the kernel when sending the message, so that
- * it refuses the operation should the name and unique
- * ID not map to each other anymore. */
-
- r = free_and_strdup(&m->destination_ptr, n);
- if (r < 0)
- return r;
-
- r = bus_kernel_parse_unique_name(destination_unique, &m->verify_destination_id);
- if (r < 0)
- return r;
- }
-
- if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, owned_names, NULL, m->path, m->interface, m->member, true))
- return 0;
- }
-
- /* Return an error back to the caller */
- if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
- return synthetic_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML sender policy.");
-
- /* Return 1, indicating that the message shall not be processed any further */
- return 1;
- }
-
- return 0;
-}
-
-static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, SharedPolicy *sp, const struct ucred *our_ucred, Set *owned_names) {
- Policy *policy;
- int r;
-
- assert(sp);
-
- policy = shared_policy_acquire(sp);
- r = process_policy_unlocked(from, to, m, policy, our_ucred, owned_names);
- shared_policy_release(sp, policy);
-
- return r;
-}
-
-static int process_hello(Proxy *p, sd_bus_message *m) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *n = NULL;
- bool is_hello;
- int r;
-
- assert(p);
- assert(m);
-
- /* As reaction to hello we need to respond with two messages:
- * the callback reply and the NameAcquired for the unique
- * name, since hello is otherwise obsolete on kdbus. */
-
- is_hello =
- sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "Hello") &&
- streq_ptr(m->destination, "org.freedesktop.DBus");
-
- if (!is_hello) {
- if (p->got_hello)
- return 0;
-
- return log_error_errno(EIO, "First packet isn't hello (it's %s.%s), aborting.", m->interface, m->member);
- }
-
- if (p->got_hello)
- return log_error_errno(EIO, "Got duplicate hello, aborting.");
-
- p->got_hello = true;
-
- if (!p->destination_bus->is_kernel)
- return 0;
-
- r = sd_bus_message_new_method_return(m, &n);
- if (r < 0)
- return log_error_errno(r, "Failed to generate HELLO reply: %m");
-
- r = sd_bus_message_append(n, "s", p->destination_bus->unique_name);
- if (r < 0)
- return log_error_errno(r, "Failed to append unique name to HELLO reply: %m");
-
- r = bus_message_append_sender(n, "org.freedesktop.DBus");
- if (r < 0)
- return log_error_errno(r, "Failed to append sender to HELLO reply: %m");
-
- r = bus_seal_synthetic_message(p->local_bus, n);
- if (r < 0)
- return log_error_errno(r, "Failed to seal HELLO reply: %m");
-
- r = sd_bus_send(p->local_bus, n, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to send HELLO reply: %m");
-
- n = sd_bus_message_unref(n);
- r = sd_bus_message_new_signal(
- p->local_bus,
- &n,
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "NameAcquired");
- if (r < 0)
- return log_error_errno(r, "Failed to allocate initial NameAcquired message: %m");
-
- r = sd_bus_message_append(n, "s", p->destination_bus->unique_name);
- if (r < 0)
- return log_error_errno(r, "Failed to append unique name to NameAcquired message: %m");
-
- r = bus_message_append_sender(n, "org.freedesktop.DBus");
- if (r < 0)
- return log_error_errno(r, "Failed to append sender to NameAcquired message: %m");
-
- r = sd_bus_message_set_destination(n, p->destination_bus->unique_name);
- if (r < 0)
- return log_error_errno(r, "Failed to set destination for NameAcquired message: %m");
-
- r = bus_seal_synthetic_message(p->local_bus, n);
- if (r < 0)
- return log_error_errno(r, "Failed to seal NameAcquired message: %m");
-
- r = sd_bus_send(p->local_bus, n, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to send NameAcquired message: %m");
-
- return 1;
-}
-
-static int patch_sender(sd_bus *a, sd_bus_message *m) {
- char **well_known = NULL;
- sd_bus_creds *c;
- int r;
-
- assert(a);
- assert(m);
-
- if (!a->is_kernel)
- return 0;
-
- /* We will change the sender of messages from the bus driver
- * so that they originate from the bus driver. This is a
- * speciality originating from dbus1, where the bus driver did
- * not have a unique id, but only the well-known name. */
-
- c = sd_bus_message_get_creds(m);
- if (!c)
- return 0;
-
- r = sd_bus_creds_get_well_known_names(c, &well_known);
- if (r < 0)
- return r;
-
- if (strv_contains(well_known, "org.freedesktop.DBus"))
- m->sender = "org.freedesktop.DBus";
-
- return 0;
-}
-
-static int proxy_process_destination_to_local(Proxy *p) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- bool matched, matched_synthetic;
- int r;
-
- assert(p);
-
- /*
- * Usually, we would just take any message that the bus passes to us
- * and forward it to the local connection. However, there are actually
- * applications that fail if they receive broadcasts that they didn't
- * subscribe to. Therefore, we actually emulate a real broadcast
- * matching here, and discard any broadcasts that weren't matched. Our
- * match-handlers remembers whether a message was matched by any rule,
- * by marking it in @p->message_matched.
- */
-
- r = sd_bus_process(p->destination_bus, &m);
-
- matched = p->message_matched;
- matched_synthetic = p->synthetic_matched;
- p->message_matched = false;
- p->synthetic_matched = false;
-
- if (r == -ECONNRESET || r == -ENOTCONN) /* Treat 'connection reset by peer' as clean exit condition */
- return r;
- if (r < 0) {
- log_error_errno(r, "Failed to process destination bus: %m");
- return r;
- }
- if (r == 0)
- return 0;
- if (!m)
- return 1;
-
- /* We officially got EOF, let's quit */
- if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected"))
- return -ECONNRESET;
-
- r = synthesize_name_acquired(p, p->destination_bus, p->local_bus, m);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
- if (r < 0)
- return log_error_errno(r, "Failed to synthesize message: %m");
-
- /* discard broadcasts that were not matched by any MATCH rule */
- if (!matched && !sd_bus_message_get_destination(m)) {
- if (!matched_synthetic)
- log_debug("Dropped unmatched broadcast: uid=" UID_FMT " gid=" GID_FMT " pid=" PID_FMT " message=%s path=%s interface=%s member=%s sender=%s destination=%s",
- p->local_creds.uid, p->local_creds.gid, p->local_creds.pid, bus_message_type_to_string(m->header->type),
- strna(m->path), strna(m->interface), strna(m->member), strna(m->sender), strna(m->destination));
- return 1;
- }
-
- patch_sender(p->destination_bus, m);
-
- if (p->policy) {
- r = process_policy(p->destination_bus, p->local_bus, m, p->policy, &p->local_creds, p->owned_names);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
- if (r < 0)
- return log_error_errno(r, "Failed to process policy: %m");
- if (r > 0)
- return 1;
- }
-
- r = sd_bus_send(p->local_bus, m, NULL);
- if (r < 0) {
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
-
- /* If the peer tries to send a reply and it is
- * rejected with EBADSLT by the kernel, we ignore the
- * error. This catches cases where the original
- * method-call didn't had EXPECT_REPLY set, but the
- * proxy-peer still sends a reply. This is allowed in
- * dbus1, but not in kdbus. We don't want to track
- * reply-windows in the proxy, so we simply ignore
- * EBADSLT for all replies. The only downside is, that
- * callers are no longer notified if their replies are
- * dropped. However, this is equivalent to the
- * caller's timeout to expire, so this should be
- * acceptable. Nobody sane sends replies without a
- * matching method-call, so nobody should care. */
-
- /* FIXME: remove -EPERM when kdbus is updated */
- if ((r == -EPERM || r == -EBADSLT) && m->reply_cookie > 0)
- return 1;
-
- /* Return the error to the client, if we can */
- synthetic_reply_method_errnof(m, r, "Failed to forward message we got from destination: %m");
- if (r == -ENOBUFS) {
- /* if local dbus1 peer does not dispatch its queue, warn only once */
- if (!p->queue_overflow)
- log_error("Dropped messages due to queue overflow of local peer (pid: "PID_FMT" uid: "UID_FMT")", p->local_creds.pid, p->local_creds.uid);
- p->queue_overflow = true;
- } else
- log_error_errno(r,
- "Failed to forward message we got from destination: uid=" UID_FMT " gid=" GID_FMT" message=%s destination=%s path=%s interface=%s member=%s: %m",
- p->local_creds.uid, p->local_creds.gid, bus_message_type_to_string(m->header->type),
- strna(m->destination), strna(m->path), strna(m->interface), strna(m->member));
-
- return 1;
- }
-
- p->queue_overflow = false;
- return 1;
-}
-
-static int proxy_process_local_to_destination(Proxy *p) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- int r;
-
- assert(p);
-
- r = sd_bus_process(p->local_bus, &m);
- if (r == -ECONNRESET || r == -ENOTCONN) /* Treat 'connection reset by peer' as clean exit condition */
- return r;
- if (r < 0) {
- log_error_errno(r, "Failed to process local bus: %m");
- return r;
- }
- if (r == 0)
- return 0;
- if (!m)
- return 1;
-
- /* We officially got EOF, let's quit */
- if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected"))
- return -ECONNRESET;
-
- r = process_hello(p, m);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
- if (r < 0)
- return log_error_errno(r, "Failed to process HELLO: %m");
- if (r > 0)
- return 1;
-
- r = bus_proxy_process_driver(p, p->destination_bus, p->local_bus, m, p->policy, &p->local_creds, p->owned_names);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
- if (r < 0)
- return log_error_errno(r, "Failed to process driver calls: %m");
- if (r > 0)
- return 1;
-
- for (;;) {
- if (p->policy) {
- r = process_policy(p->local_bus, p->destination_bus, m, p->policy, &p->local_creds, p->owned_names);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
- if (r < 0)
- return log_error_errno(r, "Failed to process policy: %m");
- if (r > 0)
- return 1;
- }
-
- r = sd_bus_send(p->destination_bus, m, NULL);
- if (r < 0) {
- if (r == -ECONNRESET || r == -ENOTCONN)
- return r;
-
- /* The name database changed since the policy check, hence let's check again */
- if (r == -EREMCHG)
- continue;
-
- /* see above why EBADSLT is ignored for replies */
- if ((r == -EPERM || r == -EBADSLT) && m->reply_cookie > 0)
- return 1;
-
- synthetic_reply_method_errnof(m, r, "Failed to forward message we got from local: %m");
- log_error_errno(r,
- "Failed to forward message we got from local: uid=" UID_FMT " gid=" GID_FMT" message=%s destination=%s path=%s interface=%s member=%s: %m",
- p->local_creds.uid, p->local_creds.gid, bus_message_type_to_string(m->header->type),
- strna(m->destination), strna(m->path), strna(m->interface), strna(m->member));
- return 1;
- }
-
- break;
- }
-
- return 1;
-}
-
-int proxy_match(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- Proxy *p = userdata;
-
- p->message_matched = true;
- return 0; /* make sure to continue processing it in further handlers */
-}
-
-int proxy_run(Proxy *p) {
- int r;
-
- assert(p);
-
- for (;;) {
- bool busy = false;
-
- if (p->got_hello) {
- /* Read messages from bus, to pass them on to our client */
- r = proxy_process_destination_to_local(p);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return 0;
- if (r < 0)
- return r;
- if (r > 0)
- busy = true;
- }
-
- /* Read messages from our client, to pass them on to the bus */
- r = proxy_process_local_to_destination(p);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return 0;
- if (r < 0)
- return r;
- if (r > 0)
- busy = true;
-
- if (!busy) {
- r = proxy_wait(p);
- if (r == -ECONNRESET || r == -ENOTCONN)
- return 0;
- if (r < 0)
- return r;
- }
- }
-
- return 0;
-}
diff --git a/src/libbus-proxy-core/proxy.h b/src/libbus-proxy-core/proxy.h
deleted file mode 100644
index 0e3ed8a87a..0000000000
--- a/src/libbus-proxy-core/proxy.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 David Herrmann
-
- 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 <systemd/sd-bus.h>
-
-#include "bus-xml-policy.h"
-
-typedef struct Proxy Proxy;
-typedef struct ProxyActivation ProxyActivation;
-
-#define PROXY_ACTIVATIONS_MAX (16) /* max parallel activation requests */
-
-struct Proxy {
- sd_bus *local_bus;
- struct ucred local_creds;
- int local_in;
- int local_out;
-
- sd_bus *destination_bus;
-
- Set *owned_names;
- SharedPolicy *policy;
-
- LIST_HEAD(ProxyActivation, activations);
- size_t n_activations;
-
- bool got_hello : 1;
- bool queue_overflow : 1;
- bool message_matched : 1;
- bool synthetic_matched : 1;
-};
-
-struct ProxyActivation {
- LIST_FIELDS(ProxyActivation, activations_by_proxy);
- Proxy *proxy;
- sd_bus_message *request;
- sd_bus_slot *slot;
-};
-
-int proxy_new(Proxy **out, int in_fd, int out_fd, const char *dest);
-Proxy *proxy_free(Proxy *p);
-
-int proxy_set_policy(Proxy *p, SharedPolicy *policy, char **configuration);
-int proxy_hello_policy(Proxy *p, uid_t original_uid);
-int proxy_match(sd_bus_message *m, void *userdata, sd_bus_error *error);
-int proxy_run(Proxy *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Proxy*, proxy_free);
diff --git a/src/libbus-proxy-core/synthesize.c b/src/libbus-proxy-core/synthesize.c
deleted file mode 100644
index 7562f29ecb..0000000000
--- a/src/libbus-proxy-core/synthesize.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2013 Daniel Mack
- Copyright 2014 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stddef.h>
-
-#include <systemd/sd-bus.h>
-
-#include "bus-internal.h"
-#include "bus-match.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "synthesize.h"
-#include "util.h"
-
-int synthetic_driver_send(sd_bus *b, sd_bus_message *m) {
- int r;
-
- assert(b);
- assert(m);
-
- r = bus_message_append_sender(m, "org.freedesktop.DBus");
- if (r < 0)
- return r;
-
- r = bus_seal_synthetic_message(b, m);
- if (r < 0)
- return r;
-
- return sd_bus_send(b, m, NULL);
-}
-
-int synthetic_reply_method_error(sd_bus_message *call, const sd_bus_error *e) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- int r;
-
- assert(call);
-
- if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
- return 0;
-
- r = sd_bus_message_new_method_error(call, &m, e);
- if (r < 0)
- return r;
-
- return synthetic_driver_send(call->bus, m);
-}
-
-int synthetic_reply_method_errorf(sd_bus_message *call, const char *name, const char *format, ...) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- va_list ap;
-
- va_start(ap, format);
- bus_error_setfv(&error, name, format, ap);
- va_end(ap);
-
- return synthetic_reply_method_error(call, &error);
-}
-
-int synthetic_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *p) {
- _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
-
- assert(call);
-
- if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
- return 0;
-
- if (sd_bus_error_is_set(p))
- return synthetic_reply_method_error(call, p);
-
- sd_bus_error_set_errno(&berror, error);
-
- return synthetic_reply_method_error(call, &berror);
-}
-
-int synthetic_reply_method_errnof(sd_bus_message *call, int error, const char *format, ...) {
- _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
- va_list ap;
-
- assert(call);
-
- if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
- return 0;
-
- va_start(ap, format);
- sd_bus_error_set_errnofv(&berror, error, format, ap);
- va_end(ap);
-
- return synthetic_reply_method_error(call, &berror);
-}
-
-int synthetic_reply_method_return(sd_bus_message *call, const char *types, ...) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- int r;
-
- assert(call);
-
- if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
- return 0;
-
- r = sd_bus_message_new_method_return(call, &m);
- if (r < 0)
- return r;
-
- if (!isempty(types)) {
- va_list ap;
-
- va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
- va_end(ap);
- if (r < 0)
- return r;
- }
-
- return synthetic_driver_send(call->bus, m);
-}
-
-int synthetic_reply_method_return_strv(sd_bus_message *call, char **l) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- int r;
-
- assert(call);
-
- if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
- return 0;
-
- r = sd_bus_message_new_method_return(call, &m);
- if (r < 0)
- return synthetic_reply_method_errno(call, r, NULL);
-
- r = sd_bus_message_append_strv(m, l);
- if (r < 0)
- return synthetic_reply_method_errno(call, r, NULL);
-
- return synthetic_driver_send(call->bus, m);
-}
-
-int synthesize_name_acquired(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *n = NULL;
- const char *name, *old_owner, *new_owner;
- int r;
-
- assert(p);
- assert(a);
- assert(b);
- assert(m);
-
- /* If we get NameOwnerChanged for our own name, we need to
- * synthesize NameLost/NameAcquired, since socket clients need
- * that, even though it is obsoleted on kdbus */
-
- if (!a->is_kernel)
- return 0;
-
- if (!sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged") ||
- !streq_ptr(m->path, "/org/freedesktop/DBus") ||
- !streq_ptr(m->sender, "org.freedesktop.DBus"))
- return 0;
-
- r = sd_bus_message_read(m, "sss", &name, &old_owner, &new_owner);
- if (r < 0)
- return r;
-
- r = sd_bus_message_rewind(m, true);
- if (r < 0)
- return r;
-
- if (streq(old_owner, a->unique_name)) {
-
- r = sd_bus_message_new_signal(
- b,
- &n,
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "NameLost");
-
- } else if (streq(new_owner, a->unique_name)) {
-
- r = sd_bus_message_new_signal(
- b,
- &n,
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "NameAcquired");
- } else
- return 0;
-
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(n, "s", name);
- if (r < 0)
- return r;
-
- r = bus_message_append_sender(n, "org.freedesktop.DBus");
- if (r < 0)
- return r;
-
- r = sd_bus_message_set_destination(n, a->unique_name);
- if (r < 0)
- return r;
-
- r = bus_seal_synthetic_message(b, n);
- if (r < 0)
- return r;
-
- return sd_bus_send(b, n, NULL);
-}
diff --git a/src/libbus-proxy-core/synthesize.h b/src/libbus-proxy-core/synthesize.h
deleted file mode 100644
index cb8c21cdb7..0000000000
--- a/src/libbus-proxy-core/synthesize.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <systemd/sd-bus.h>
-
-#include "proxy.h"
-
-int synthetic_driver_send(sd_bus *b, sd_bus_message *m);
-
-int synthetic_reply_method_return(sd_bus_message *call, const char *types, ...);
-int synthetic_reply_method_return_strv(sd_bus_message *call, char **l);
-
-int synthetic_reply_method_error(sd_bus_message *call, const sd_bus_error *e);
-int synthetic_reply_method_errorf(sd_bus_message *call, const char *name, const char *format, ...) _sd_printf_(3, 4);
-int synthetic_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *p);
-int synthetic_reply_method_errnof(sd_bus_message *call, int error, const char *format, ...) _sd_printf_(3, 4);
-
-int synthesize_name_acquired(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m);
diff --git a/src/libbus-proxy-core/test-bus-xml-policy.c b/src/libbus-proxy-core/test-bus-xml-policy.c
deleted file mode 100644
index 6f32c09789..0000000000
--- a/src/libbus-proxy-core/test-bus-xml-policy.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Daniel Mack
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stddef.h>
-#include <unistd.h>
-
-#include <systemd/sd-bus.h>
-
-#include "alloc-util.h"
-#include "bus-xml-policy.h"
-#include "log.h"
-#include "string-util.h"
-#include "strv.h"
-#include "util.h"
-
-static int test_policy_load(Policy *p, const char *name) {
- _cleanup_free_ char *path = NULL;
- int r = 0;
-
- path = strjoin(TEST_DIR, "/bus-policy/", name, NULL);
- assert_se(path);
-
- if (access(path, R_OK) == 0)
- r = policy_load(p, STRV_MAKE(path));
- else
- r = -ENOENT;
-
- return r;
-}
-
-static int show_policy(const char *fn) {
- Policy p = {};
- int r;
-
- r = policy_load(&p, STRV_MAKE(fn));
- if (r < 0) {
- log_error_errno(r, "Failed to load policy %s: %m", fn);
- return r;
- }
-
- policy_dump(&p);
- policy_free(&p);
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
-
- Policy p = {};
-
- printf("Showing session policy BEGIN\n");
- show_policy("/etc/dbus-1/session.conf");
- printf("Showing session policy END\n");
-
- printf("Showing system policy BEGIN\n");
- show_policy("/etc/dbus-1/system.conf");
- printf("Showing system policy END\n");
-
- /* Ownership tests */
- assert_se(test_policy_load(&p, "ownerships.conf") == 0);
-
- assert_se(policy_check_own(&p, 0, 0, "org.test.test1") == true);
- assert_se(policy_check_own(&p, 1, 0, "org.test.test1") == true);
-
- assert_se(policy_check_own(&p, 0, 0, "org.test.test2") == true);
- assert_se(policy_check_own(&p, 1, 0, "org.test.test2") == false);
-
- assert_se(policy_check_own(&p, 0, 0, "org.test.test3") == false);
- assert_se(policy_check_own(&p, 1, 0, "org.test.test3") == false);
-
- assert_se(policy_check_own(&p, 0, 0, "org.test.test4") == false);
- assert_se(policy_check_own(&p, 1, 0, "org.test.test4") == true);
-
- policy_free(&p);
-
- /* Signaltest */
- assert_se(test_policy_load(&p, "signals.conf") == 0);
-
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_SIGNAL, "bli.bla.blubb", NULL, "/an/object/path", NULL) == true);
- assert_se(policy_check_one_send(&p, 1, 0, SD_BUS_MESSAGE_SIGNAL, "bli.bla.blubb", NULL, "/an/object/path", NULL) == false);
-
- policy_free(&p);
-
- /* Method calls */
- assert_se(test_policy_load(&p, "methods.conf") == 0);
- policy_dump(&p);
-
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "bli.bla.blubb", "Member") == false);
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "bli.bla.blubb", "Member") == false);
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int1", "Member") == true);
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int2", "Member") == true);
-
- assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test3", "/an/object/path", "org.test.int3", "Member111") == true);
-
- policy_free(&p);
-
- /* User and groups */
- assert_se(test_policy_load(&p, "hello.conf") == 0);
- policy_dump(&p);
-
- assert_se(policy_check_hello(&p, 0, 0) == true);
- assert_se(policy_check_hello(&p, 1, 0) == false);
- assert_se(policy_check_hello(&p, 0, 1) == false);
-
- policy_free(&p);
-
- /* dbus1 test file: ownership */
-
- assert_se(test_policy_load(&p, "check-own-rules.conf") >= 0);
- policy_dump(&p);
-
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop") == false);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystem") == false);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems") == true);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems.foo") == true);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems.foo.bar") == true);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems2") == false);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems2.foo") == false);
- assert_se(policy_check_own(&p, 0, 0, "org.freedesktop.ManySystems2.foo.bar") == false);
-
- policy_free(&p);
-
- /* dbus1 test file: many rules */
-
- assert_se(test_policy_load(&p, "many-rules.conf") >= 0);
- policy_dump(&p);
- policy_free(&p);
-
- /* dbus1 test file: generic test */
-
- assert_se(test_policy_load(&p, "test.conf") >= 0);
- policy_dump(&p);
-
- assert_se(policy_check_own(&p, 0, 0, "org.foo.FooService") == true);
- assert_se(policy_check_own(&p, 0, 0, "org.foo.FooService2") == false);
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int2", "Member") == false);
- assert_se(policy_check_one_send(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == true);
- assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == true);
- assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface2", "Member") == false);
- assert_se(policy_check_one_recv(&p, 0, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService2", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == false);
-
- assert_se(policy_check_own(&p, 100, 0, "org.foo.FooService") == false);
- assert_se(policy_check_own(&p, 100, 0, "org.foo.FooService2") == false);
- assert_se(policy_check_one_send(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.test.int2", "Member") == false);
- assert_se(policy_check_one_send(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.test.test1", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == false);
- assert_se(policy_check_one_recv(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == true);
- assert_se(policy_check_one_recv(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService", "/an/object/path", "org.foo.FooBroadcastInterface2", "Member") == false);
- assert_se(policy_check_one_recv(&p, 100, 0, SD_BUS_MESSAGE_METHOD_CALL, "org.foo.FooService2", "/an/object/path", "org.foo.FooBroadcastInterface", "Member") == false);
-
- policy_free(&p);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/libcore/Makefile b/src/libcore/Makefile
index 5eef67be3d..f40a115042 100644
--- a/src/libcore/Makefile
+++ b/src/libcore/Makefile
@@ -45,8 +45,6 @@ libcore_la_SOURCES = \
src/core/socket.h \
src/core/busname.c \
src/core/busname.h \
- src/core/bus-endpoint.c \
- src/core/bus-endpoint.h \
src/core/bus-policy.c \
src/core/bus-policy.h \
src/core/target.c \
diff --git a/src/libcore/automount.c b/src/libcore/automount.c
index 5dc6fd98e7..f06d837e30 100644
--- a/src/libcore/automount.c
+++ b/src/libcore/automount.c
@@ -75,6 +75,9 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct expire_data*, expire_data_free);
static int open_dev_autofs(Manager *m);
static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
+static int automount_start_expire(Automount *a);
+static void automount_stop_expire(Automount *a);
+static int automount_send_ready(Automount *a, Set *tokens, int status);
static void automount_init(Unit *u) {
Automount *a = AUTOMOUNT(u);
@@ -87,8 +90,6 @@ static void automount_init(Unit *u) {
UNIT(a)->ignore_on_isolate = true;
}
-static int automount_send_ready(Automount *a, Set *tokens, int status);
-
static void unmount_autofs(Automount *a) {
int r;
@@ -149,7 +150,7 @@ static int automount_add_default_dependencies(Automount *a) {
if (!UNIT(a)->default_dependencies)
return 0;
- if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(UNIT(a)->manager))
return 0;
r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
@@ -235,6 +236,9 @@ static void automount_set_state(Automount *a, AutomountState state) {
old_state = a->state;
a->state = state;
+ if (state != AUTOMOUNT_RUNNING)
+ automount_stop_expire(a);
+
if (state != AUTOMOUNT_WAITING &&
state != AUTOMOUNT_RUNNING)
unmount_autofs(a);
@@ -408,7 +412,7 @@ static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, in
init_autofs_dev_ioctl(&param);
param.ioctlfd = ioctl_fd;
- if (status) {
+ if (status != 0) {
param.fail.token = token;
param.fail.status = status;
} else
@@ -435,7 +439,7 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
if (ioctl_fd < 0)
return ioctl_fd;
- if (status)
+ if (status != 0)
log_unit_debug_errno(UNIT(a), status, "Sending failure: %m");
else
log_unit_debug(UNIT(a), "Sending success.");
@@ -462,59 +466,54 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
return r;
}
-static int automount_start_expire(Automount *a);
-
-int automount_update_mount(Automount *a, MountState old_state, MountState state) {
+static void automount_trigger_notify(Unit *u, Unit *other) {
+ Automount *a = AUTOMOUNT(u);
int r;
assert(a);
+ assert(other);
+
+ /* Filter out invocations with bogus state */
+ if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT)
+ return;
+
+ /* Don't propagate state changes from the mount if we are already down */
+ if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))
+ return;
+
+ /* Propagate start limit hit state */
+ if (other->start_limit_hit) {
+ automount_enter_dead(a, AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT);
+ return;
+ }
+
+ /* Don't propagate anything if there's still a job queued */
+ if (other->job)
+ return;
+
+ /* The mount is successfully established */
+ if (IN_SET(MOUNT(other)->state, MOUNT_MOUNTED, MOUNT_REMOUNTING)) {
+ (void) automount_send_ready(a, a->tokens, 0);
- switch (state) {
- case MOUNT_MOUNTED:
- case MOUNT_REMOUNTING:
- automount_send_ready(a, a->tokens, 0);
r = automount_start_expire(a);
if (r < 0)
log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m");
- break;
- case MOUNT_DEAD:
- case MOUNT_UNMOUNTING:
- case MOUNT_MOUNTING_SIGTERM:
- case MOUNT_MOUNTING_SIGKILL:
- case MOUNT_REMOUNTING_SIGTERM:
- case MOUNT_REMOUNTING_SIGKILL:
- case MOUNT_UNMOUNTING_SIGTERM:
- case MOUNT_UNMOUNTING_SIGKILL:
- case MOUNT_FAILED:
- if (old_state != state)
- automount_send_ready(a, a->tokens, -ENODEV);
- (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
- break;
- default:
- break;
- }
- switch (state) {
- case MOUNT_DEAD:
- automount_send_ready(a, a->expire_tokens, 0);
- break;
- case MOUNT_MOUNTING:
- case MOUNT_MOUNTING_DONE:
- case MOUNT_MOUNTING_SIGTERM:
- case MOUNT_MOUNTING_SIGKILL:
- case MOUNT_REMOUNTING_SIGTERM:
- case MOUNT_REMOUNTING_SIGKILL:
- case MOUNT_UNMOUNTING_SIGTERM:
- case MOUNT_UNMOUNTING_SIGKILL:
- case MOUNT_FAILED:
- if (old_state != state)
- automount_send_ready(a, a->expire_tokens, -ENODEV);
- break;
- default:
- break;
+ automount_set_state(a, AUTOMOUNT_RUNNING);
}
- return 0;
+ /* The mount is in some unhappy state now, let's unfreeze any waiting clients */
+ if (IN_SET(MOUNT(other)->state,
+ MOUNT_DEAD, MOUNT_UNMOUNTING,
+ MOUNT_MOUNTING_SIGTERM, MOUNT_MOUNTING_SIGKILL,
+ MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL,
+ MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL,
+ MOUNT_FAILED)) {
+
+ (void) automount_send_ready(a, a->tokens, -ENODEV);
+
+ automount_set_state(a, AUTOMOUNT_WAITING);
+ }
}
static void automount_enter_waiting(Automount *a) {
@@ -699,6 +698,15 @@ static int automount_start_expire(Automount *a) {
return 0;
}
+static void automount_stop_expire(Automount *a) {
+ assert(a);
+
+ if (!a->expire_event_source)
+ return;
+
+ (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
+}
+
static void automount_enter_runnning(Automount *a) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
struct stat st;
@@ -751,6 +759,7 @@ fail:
static int automount_start(Unit *u) {
Automount *a = AUTOMOUNT(u);
Unit *trigger;
+ int r;
assert(a);
assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
@@ -766,6 +775,12 @@ static int automount_start(Unit *u) {
return -ENOENT;
}
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
a->result = AUTOMOUNT_SUCCESS;
automount_enter_waiting(a);
return 1;
@@ -958,7 +973,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
case autofs_ptype_expire_direct:
log_unit_debug(UNIT(a), "Got direct umount request on %s", a->where);
- (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
+ automount_stop_expire(a);
r = set_ensure_allocated(&a->expire_tokens, NULL);
if (r < 0) {
@@ -1037,7 +1052,9 @@ static bool automount_supported(void) {
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
[AUTOMOUNT_SUCCESS] = "success",
- [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
+ [AUTOMOUNT_FAILURE_RESOURCES] = "resources",
+ [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
+ [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
@@ -1050,9 +1067,6 @@ const UnitVTable automount_vtable = {
"Automount\0"
"Install\0",
- .no_alias = true,
- .no_instances = true,
-
.init = automount_init,
.load = automount_load,
.done = automount_done,
@@ -1072,6 +1086,8 @@ const UnitVTable automount_vtable = {
.check_gc = automount_check_gc,
+ .trigger_notify = automount_trigger_notify,
+
.reset_failed = automount_reset_failed,
.bus_vtable = bus_automount_vtable,
diff --git a/src/libcore/automount.h b/src/libcore/automount.h
index cf5b1cf994..76a201178e 100644
--- a/src/libcore/automount.h
+++ b/src/libcore/automount.h
@@ -26,6 +26,8 @@ typedef struct Automount Automount;
typedef enum AutomountResult {
AUTOMOUNT_SUCCESS,
AUTOMOUNT_FAILURE_RESOURCES,
+ AUTOMOUNT_FAILURE_START_LIMIT_HIT,
+ AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT,
_AUTOMOUNT_RESULT_MAX,
_AUTOMOUNT_RESULT_INVALID = -1
} AutomountResult;
@@ -53,7 +55,5 @@ struct Automount {
extern const UnitVTable automount_vtable;
-int automount_update_mount(Automount *a, MountState old_state, MountState state);
-
const char* automount_result_to_string(AutomountResult i) _const_;
AutomountResult automount_result_from_string(const char *s) _pure_;
diff --git a/src/libcore/bus-endpoint.c b/src/libcore/bus-endpoint.c
deleted file mode 100644
index d22a80c91f..0000000000
--- a/src/libcore/bus-endpoint.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Daniel Mack
-
- 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 <stdlib.h>
-
-#include "alloc-util.h"
-#include "bus-endpoint.h"
-#include "bus-kernel.h"
-#include "bus-policy.h"
-#include "kdbus.h"
-
-int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
-
- struct kdbus_cmd *update;
- struct kdbus_item *n;
- BusEndpointPolicy *po;
- Iterator i;
- size_t size;
- int r;
-
- size = ALIGN8(offsetof(struct kdbus_cmd, items));
-
- HASHMAP_FOREACH(po, ep->policy_hash, i) {
- size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
- size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
- }
-
- update = alloca0_align(size, 8);
- update->size = size;
-
- n = update->items;
-
- HASHMAP_FOREACH(po, ep->policy_hash, i) {
- n->type = KDBUS_ITEM_NAME;
- n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
- strcpy(n->str, po->name);
- n = KDBUS_ITEM_NEXT(n);
-
- n->type = KDBUS_ITEM_POLICY_ACCESS;
- n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
-
- n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
- n->policy_access.access = bus_kernel_translate_access(po->access);
- n->policy_access.id = uid;
-
- n = KDBUS_ITEM_NEXT(n);
- }
-
- r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int bus_endpoint_new(BusEndpoint **ep) {
- assert(ep);
-
- *ep = new0(BusEndpoint, 1);
- if (!*ep)
- return -ENOMEM;
-
- return 0;
-}
-
-int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access) {
- _cleanup_free_ BusEndpointPolicy *po = NULL;
- _cleanup_free_ char *key = NULL;
- int r;
-
- assert(ep);
- assert(name);
- assert(access > _BUS_POLICY_ACCESS_INVALID && access < _BUS_POLICY_ACCESS_MAX);
-
- /* check if we already have this name in the policy list. If we do, see if the new access level
- * is higher than the exising one, and upgrade the entry in that case. Otherwise, do nothing.
- */
-
- if (ep->policy_hash) {
- po = hashmap_get(ep->policy_hash, name);
- if (po) {
- if (po->access < access)
- po->access = access;
-
- return 0;
- }
- } else {
- ep->policy_hash = hashmap_new(&string_hash_ops);
- if (!ep->policy_hash)
- return -ENOMEM;
- }
-
- po = new0(BusEndpointPolicy, 1);
- if (!po)
- return -ENOMEM;
-
- key = strdup(name);
- if (!key)
- return -ENOMEM;
-
- po->name = key;
- po->access = access;
-
- r = hashmap_put(ep->policy_hash, key, po);
- if (r < 0)
- return r;
-
- po = NULL;
- key = NULL;
- return 0;
-}
-
-void bus_endpoint_free(BusEndpoint *endpoint) {
- if (!endpoint)
- return;
-
- hashmap_free_free_free(endpoint->policy_hash);
- free(endpoint);
-}
diff --git a/src/libcore/busname.c b/src/libcore/busname.c
index de2a21ccde..f03a95c24e 100644
--- a/src/libcore/busname.c
+++ b/src/libcore/busname.c
@@ -149,7 +149,7 @@ static int busname_add_default_default_dependencies(BusName *n) {
if (r < 0)
return r;
- if (UNIT(n)->manager->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(UNIT(n)->manager)) {
r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
if (r < 0)
return r;
@@ -318,7 +318,7 @@ static int busname_open_fd(BusName *n) {
if (n->starter_fd >= 0)
return 0;
- mode = UNIT(n)->manager->running_as == MANAGER_SYSTEM ? "system" : "user";
+ mode = MANAGER_IS_SYSTEM(UNIT(n)->manager) ? "system" : "user";
n->starter_fd = bus_kernel_open_bus_fd(mode, &path);
if (n->starter_fd < 0)
return log_unit_warning_errno(UNIT(n), n->starter_fd, "Failed to open %s: %m", path ?: "kdbus");
@@ -607,6 +607,7 @@ fail:
static int busname_start(Unit *u) {
BusName *n = BUSNAME(u);
+ int r;
assert(n);
@@ -632,6 +633,12 @@ static int busname_start(Unit *u) {
assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED));
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ busname_enter_dead(n, BUSNAME_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
n->result = BUSNAME_SUCCESS;
busname_enter_making(n);
@@ -999,6 +1006,14 @@ static bool busname_supported(void) {
return supported;
}
+static int busname_control_pid(Unit *u) {
+ BusName *n = BUSNAME(u);
+
+ assert(n);
+
+ return n->control_pid;
+}
+
static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
[BUSNAME_SUCCESS] = "success",
[BUSNAME_FAILURE_RESOURCES] = "resources",
@@ -1006,6 +1021,7 @@ static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
[BUSNAME_FAILURE_EXIT_CODE] = "exit-code",
[BUSNAME_FAILURE_SIGNAL] = "signal",
[BUSNAME_FAILURE_CORE_DUMP] = "core-dump",
+ [BUSNAME_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
[BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit",
};
@@ -1020,9 +1036,6 @@ const UnitVTable busname_vtable = {
"Install\0",
.private_section = "BusName",
- .no_alias = true,
- .no_instances = true,
-
.init = busname_init,
.done = busname_done,
.load = busname_load,
@@ -1052,6 +1065,8 @@ const UnitVTable busname_vtable = {
.supported = busname_supported,
+ .control_pid = busname_control_pid,
+
.bus_vtable = bus_busname_vtable,
.status_message_formats = {
diff --git a/src/libcore/busname.h b/src/libcore/busname.h
index 6b6f6c62d4..a8562db458 100644
--- a/src/libcore/busname.h
+++ b/src/libcore/busname.h
@@ -23,6 +23,7 @@ typedef struct BusName BusName;
typedef struct BusNamePolicy BusNamePolicy;
#include "unit.h"
+#include "bus-policy.h"
typedef enum BusNameResult {
BUSNAME_SUCCESS,
@@ -31,6 +32,7 @@ typedef enum BusNameResult {
BUSNAME_FAILURE_EXIT_CODE,
BUSNAME_FAILURE_SIGNAL,
BUSNAME_FAILURE_CORE_DUMP,
+ BUSNAME_FAILURE_START_LIMIT_HIT,
BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT,
_BUSNAME_RESULT_MAX,
_BUSNAME_RESULT_INVALID = -1
diff --git a/src/libcore/cgroup.c b/src/libcore/cgroup.c
index 39235a95f6..0fb63b1bd1 100644
--- a/src/libcore/cgroup.c
+++ b/src/libcore/cgroup.c
@@ -32,6 +32,7 @@
#include "special.h"
#include "string-table.h"
#include "string-util.h"
+#include "stdio-util.h"
#define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC)
@@ -47,6 +48,9 @@ void cgroup_context_init(CGroupContext *c) {
c->memory_limit = (uint64_t) -1;
+ c->io_weight = CGROUP_WEIGHT_INVALID;
+ c->startup_io_weight = CGROUP_WEIGHT_INVALID;
+
c->blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID;
c->startup_blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID;
@@ -62,6 +66,24 @@ void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a) {
free(a);
}
+void cgroup_context_free_io_device_weight(CGroupContext *c, CGroupIODeviceWeight *w) {
+ assert(c);
+ assert(w);
+
+ LIST_REMOVE(device_weights, c->io_device_weights, w);
+ free(w->path);
+ free(w);
+}
+
+void cgroup_context_free_io_device_limit(CGroupContext *c, CGroupIODeviceLimit *l) {
+ assert(c);
+ assert(l);
+
+ LIST_REMOVE(device_limits, c->io_device_limits, l);
+ free(l->path);
+ free(l);
+}
+
void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w) {
assert(c);
assert(w);
@@ -83,6 +105,12 @@ void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockI
void cgroup_context_done(CGroupContext *c) {
assert(c);
+ while (c->io_device_weights)
+ cgroup_context_free_io_device_weight(c, c->io_device_weights);
+
+ while (c->io_device_limits)
+ cgroup_context_free_io_device_limit(c, c->io_device_limits);
+
while (c->blockio_device_weights)
cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
@@ -94,6 +122,8 @@ void cgroup_context_done(CGroupContext *c) {
}
void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
+ CGroupIODeviceLimit *il;
+ CGroupIODeviceWeight *iw;
CGroupBlockIODeviceBandwidth *b;
CGroupBlockIODeviceWeight *w;
CGroupDeviceAllow *a;
@@ -106,12 +136,15 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
fprintf(f,
"%sCPUAccounting=%s\n"
+ "%sIOAccounting=%s\n"
"%sBlockIOAccounting=%s\n"
"%sMemoryAccounting=%s\n"
"%sTasksAccounting=%s\n"
"%sCPUShares=%" PRIu64 "\n"
"%sStartupCPUShares=%" PRIu64 "\n"
"%sCPUQuotaPerSecSec=%s\n"
+ "%sIOWeight=%" PRIu64 "\n"
+ "%sStartupIOWeight=%" PRIu64 "\n"
"%sBlockIOWeight=%" PRIu64 "\n"
"%sStartupBlockIOWeight=%" PRIu64 "\n"
"%sMemoryLimit=%" PRIu64 "\n"
@@ -119,12 +152,15 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
"%sDevicePolicy=%s\n"
"%sDelegate=%s\n",
prefix, yes_no(c->cpu_accounting),
+ prefix, yes_no(c->io_accounting),
prefix, yes_no(c->blockio_accounting),
prefix, yes_no(c->memory_accounting),
prefix, yes_no(c->tasks_accounting),
prefix, c->cpu_shares,
prefix, c->startup_cpu_shares,
prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1),
+ prefix, c->io_weight,
+ prefix, c->startup_io_weight,
prefix, c->blockio_weight,
prefix, c->startup_blockio_weight,
prefix, c->memory_limit,
@@ -139,6 +175,27 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
a->path,
a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
+ LIST_FOREACH(device_weights, iw, c->io_device_weights)
+ fprintf(f,
+ "%sIODeviceWeight=%s %" PRIu64,
+ prefix,
+ iw->path,
+ iw->weight);
+
+ LIST_FOREACH(device_limits, il, c->io_device_limits) {
+ char buf[FORMAT_BYTES_MAX];
+ CGroupIOLimitType type;
+
+ for (type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++)
+ if (il->limits[type] != cgroup_io_limit_defaults[type])
+ fprintf(f,
+ "%s%s=%s %s\n",
+ prefix,
+ cgroup_io_limit_type_to_string(type),
+ il->path,
+ format_bytes(buf, sizeof(buf), il->limits[type]));
+ }
+
LIST_FOREACH(device_weights, w, c->blockio_device_weights)
fprintf(f,
"%sBlockIODeviceWeight=%s %" PRIu64,
@@ -149,16 +206,22 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
char buf[FORMAT_BYTES_MAX];
- fprintf(f,
- "%s%s=%s %s\n",
- prefix,
- b->read ? "BlockIOReadBandwidth" : "BlockIOWriteBandwidth",
- b->path,
- format_bytes(buf, sizeof(buf), b->bandwidth));
+ if (b->rbps != CGROUP_LIMIT_MAX)
+ fprintf(f,
+ "%sBlockIOReadBandwidth=%s %s\n",
+ prefix,
+ b->path,
+ format_bytes(buf, sizeof(buf), b->rbps));
+ if (b->wbps != CGROUP_LIMIT_MAX)
+ fprintf(f,
+ "%sBlockIOWriteBandwidth=%s %s\n",
+ prefix,
+ b->path,
+ format_bytes(buf, sizeof(buf), b->wbps));
}
}
-static int lookup_blkio_device(const char *p, dev_t *dev) {
+static int lookup_block_device(const char *p, dev_t *dev) {
struct stat st;
int r;
@@ -295,6 +358,144 @@ fail:
return -errno;
}
+static bool cgroup_context_has_io_config(CGroupContext *c) {
+ return c->io_accounting ||
+ c->io_weight != CGROUP_WEIGHT_INVALID ||
+ c->startup_io_weight != CGROUP_WEIGHT_INVALID ||
+ c->io_device_weights ||
+ c->io_device_limits;
+}
+
+static bool cgroup_context_has_blockio_config(CGroupContext *c) {
+ return c->blockio_accounting ||
+ c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
+ c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
+ c->blockio_device_weights ||
+ c->blockio_device_bandwidths;
+}
+
+static uint64_t cgroup_context_io_weight(CGroupContext *c, ManagerState state) {
+ if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
+ c->startup_io_weight != CGROUP_WEIGHT_INVALID)
+ return c->startup_io_weight;
+ else if (c->io_weight != CGROUP_WEIGHT_INVALID)
+ return c->io_weight;
+ else
+ return CGROUP_WEIGHT_DEFAULT;
+}
+
+static uint64_t cgroup_context_blkio_weight(CGroupContext *c, ManagerState state) {
+ if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
+ c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID)
+ return c->startup_blockio_weight;
+ else if (c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID)
+ return c->blockio_weight;
+ else
+ return CGROUP_BLKIO_WEIGHT_DEFAULT;
+}
+
+static uint64_t cgroup_weight_blkio_to_io(uint64_t blkio_weight) {
+ return CLAMP(blkio_weight * CGROUP_WEIGHT_DEFAULT / CGROUP_BLKIO_WEIGHT_DEFAULT,
+ CGROUP_WEIGHT_MIN, CGROUP_WEIGHT_MAX);
+}
+
+static uint64_t cgroup_weight_io_to_blkio(uint64_t io_weight) {
+ return CLAMP(io_weight * CGROUP_BLKIO_WEIGHT_DEFAULT / CGROUP_WEIGHT_DEFAULT,
+ CGROUP_BLKIO_WEIGHT_MIN, CGROUP_BLKIO_WEIGHT_MAX);
+}
+
+static void cgroup_apply_io_device_weight(const char *path, const char *dev_path, uint64_t io_weight) {
+ char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1];
+ dev_t dev;
+ int r;
+
+ r = lookup_block_device(dev_path, &dev);
+ if (r < 0)
+ return;
+
+ xsprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), io_weight);
+ r = cg_set_attribute("io", path, "io.weight", buf);
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set io.weight on %s: %m", path);
+}
+
+static void cgroup_apply_blkio_device_weight(const char *path, const char *dev_path, uint64_t blkio_weight) {
+ char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1];
+ dev_t dev;
+ int r;
+
+ r = lookup_block_device(dev_path, &dev);
+ if (r < 0)
+ return;
+
+ xsprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), blkio_weight);
+ r = cg_set_attribute("blkio", path, "blkio.weight_device", buf);
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set blkio.weight_device on %s: %m", path);
+}
+
+static unsigned cgroup_apply_io_device_limit(const char *path, const char *dev_path, uint64_t *limits) {
+ char limit_bufs[_CGROUP_IO_LIMIT_TYPE_MAX][DECIMAL_STR_MAX(uint64_t)];
+ char buf[DECIMAL_STR_MAX(dev_t)*2+2+(6+DECIMAL_STR_MAX(uint64_t)+1)*4];
+ CGroupIOLimitType type;
+ dev_t dev;
+ unsigned n = 0;
+ int r;
+
+ r = lookup_block_device(dev_path, &dev);
+ if (r < 0)
+ return 0;
+
+ for (type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++) {
+ if (limits[type] != cgroup_io_limit_defaults[type]) {
+ xsprintf(limit_bufs[type], "%" PRIu64, limits[type]);
+ n++;
+ } else {
+ xsprintf(limit_bufs[type], "%s", limits[type] == CGROUP_LIMIT_MAX ? "max" : "0");
+ }
+ }
+
+ xsprintf(buf, "%u:%u rbps=%s wbps=%s riops=%s wiops=%s\n", major(dev), minor(dev),
+ limit_bufs[CGROUP_IO_RBPS_MAX], limit_bufs[CGROUP_IO_WBPS_MAX],
+ limit_bufs[CGROUP_IO_RIOPS_MAX], limit_bufs[CGROUP_IO_WIOPS_MAX]);
+ r = cg_set_attribute("io", path, "io.max", buf);
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set io.max on %s: %m", path);
+ return n;
+}
+
+static unsigned cgroup_apply_blkio_device_limit(const char *path, const char *dev_path, uint64_t rbps, uint64_t wbps) {
+ char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1];
+ dev_t dev;
+ unsigned n = 0;
+ int r;
+
+ r = lookup_block_device(dev_path, &dev);
+ if (r < 0)
+ return 0;
+
+ if (rbps != CGROUP_LIMIT_MAX)
+ n++;
+ sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), rbps);
+ r = cg_set_attribute("blkio", path, "blkio.throttle.read_bps_device", buf);
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set blkio.throttle.read_bps_device on %s: %m", path);
+
+ if (wbps != CGROUP_LIMIT_MAX)
+ n++;
+ sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), wbps);
+ r = cg_set_attribute("blkio", path, "blkio.throttle.write_bps_device", buf);
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set blkio.throttle.write_bps_device on %s: %m", path);
+
+ return n;
+}
+
void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, ManagerState state) {
bool is_root;
int r;
@@ -343,53 +544,120 @@ void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, M
"Failed to set cpu.cfs_quota_us on %s: %m", path);
}
- if (mask & CGROUP_MASK_BLKIO) {
- char buf[MAX(DECIMAL_STR_MAX(uint64_t)+1,
- DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1)];
- CGroupBlockIODeviceWeight *w;
- CGroupBlockIODeviceBandwidth *b;
+ if (mask & CGROUP_MASK_IO) {
+ bool has_io = cgroup_context_has_io_config(c);
+ bool has_blockio = cgroup_context_has_blockio_config(c);
if (!is_root) {
- sprintf(buf, "%" PRIu64 "\n",
- IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ? c->startup_blockio_weight :
- c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ? c->blockio_weight : CGROUP_BLKIO_WEIGHT_DEFAULT);
- r = cg_set_attribute("blkio", path, "blkio.weight", buf);
+ char buf[8+DECIMAL_STR_MAX(uint64_t)+1];
+ uint64_t weight;
+
+ if (has_io)
+ weight = cgroup_context_io_weight(c, state);
+ else if (has_blockio)
+ weight = cgroup_weight_blkio_to_io(cgroup_context_blkio_weight(c, state));
+ else
+ weight = CGROUP_WEIGHT_DEFAULT;
+
+ xsprintf(buf, "default %" PRIu64 "\n", weight);
+ r = cg_set_attribute("io", path, "io.weight", buf);
if (r < 0)
log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set blkio.weight on %s: %m", path);
+ "Failed to set io.weight on %s: %m", path);
- /* FIXME: no way to reset this list */
- LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
- dev_t dev;
+ if (has_io) {
+ CGroupIODeviceWeight *w;
- r = lookup_blkio_device(w->path, &dev);
- if (r < 0)
- continue;
+ /* FIXME: no way to reset this list */
+ LIST_FOREACH(device_weights, w, c->io_device_weights)
+ cgroup_apply_io_device_weight(path, w->path, w->weight);
+ } else if (has_blockio) {
+ CGroupBlockIODeviceWeight *w;
- sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), w->weight);
- r = cg_set_attribute("blkio", path, "blkio.weight_device", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set blkio.weight_device on %s: %m", path);
+ /* FIXME: no way to reset this list */
+ LIST_FOREACH(device_weights, w, c->blockio_device_weights)
+ cgroup_apply_io_device_weight(path, w->path, cgroup_weight_blkio_to_io(w->weight));
}
}
- /* FIXME: no way to reset this list */
- LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
- const char *a;
- dev_t dev;
+ /* Apply limits and free ones without config. */
+ if (has_io) {
+ CGroupIODeviceLimit *l, *next;
- r = lookup_blkio_device(b->path, &dev);
- if (r < 0)
- continue;
+ LIST_FOREACH_SAFE(device_limits, l, next, c->io_device_limits) {
+ if (!cgroup_apply_io_device_limit(path, l->path, l->limits))
+ cgroup_context_free_io_device_limit(c, l);
+ }
+ } else if (has_blockio) {
+ CGroupBlockIODeviceBandwidth *b, *next;
- a = b->read ? "blkio.throttle.read_bps_device" : "blkio.throttle.write_bps_device";
+ LIST_FOREACH_SAFE(device_bandwidths, b, next, c->blockio_device_bandwidths) {
+ uint64_t limits[_CGROUP_IO_LIMIT_TYPE_MAX];
+ CGroupIOLimitType type;
- sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), b->bandwidth);
- r = cg_set_attribute("blkio", path, a, buf);
+ for (type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++)
+ limits[type] = cgroup_io_limit_defaults[type];
+
+ limits[CGROUP_IO_RBPS_MAX] = b->rbps;
+ limits[CGROUP_IO_WBPS_MAX] = b->wbps;
+
+ if (!cgroup_apply_io_device_limit(path, b->path, limits))
+ cgroup_context_free_blockio_device_bandwidth(c, b);
+ }
+ }
+ }
+
+ if (mask & CGROUP_MASK_BLKIO) {
+ bool has_io = cgroup_context_has_io_config(c);
+ bool has_blockio = cgroup_context_has_blockio_config(c);
+
+ if (!is_root) {
+ char buf[DECIMAL_STR_MAX(uint64_t)+1];
+ uint64_t weight;
+
+ if (has_blockio)
+ weight = cgroup_context_blkio_weight(c, state);
+ else if (has_io)
+ weight = cgroup_weight_io_to_blkio(cgroup_context_io_weight(c, state));
+ else
+ weight = CGROUP_BLKIO_WEIGHT_DEFAULT;
+
+ xsprintf(buf, "%" PRIu64 "\n", weight);
+ r = cg_set_attribute("blkio", path, "blkio.weight", buf);
if (r < 0)
log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set %s on %s: %m", a, path);
+ "Failed to set blkio.weight on %s: %m", path);
+
+ if (has_blockio) {
+ CGroupBlockIODeviceWeight *w;
+
+ /* FIXME: no way to reset this list */
+ LIST_FOREACH(device_weights, w, c->blockio_device_weights)
+ cgroup_apply_blkio_device_weight(path, w->path, w->weight);
+ } else if (has_io) {
+ CGroupIODeviceWeight *w;
+
+ /* FIXME: no way to reset this list */
+ LIST_FOREACH(device_weights, w, c->io_device_weights)
+ cgroup_apply_blkio_device_weight(path, w->path, cgroup_weight_io_to_blkio(w->weight));
+ }
+ }
+
+ /* Apply limits and free ones without config. */
+ if (has_blockio) {
+ CGroupBlockIODeviceBandwidth *b, *next;
+
+ LIST_FOREACH_SAFE(device_bandwidths, b, next, c->blockio_device_bandwidths) {
+ if (!cgroup_apply_blkio_device_limit(path, b->path, b->rbps, b->wbps))
+ cgroup_context_free_blockio_device_bandwidth(c, b);
+ }
+ } else if (has_io) {
+ CGroupIODeviceLimit *l, *next;
+
+ LIST_FOREACH_SAFE(device_limits, l, next, c->io_device_limits) {
+ if (!cgroup_apply_blkio_device_limit(path, l->path, l->limits[CGROUP_IO_RBPS_MAX], l->limits[CGROUP_IO_WBPS_MAX]))
+ cgroup_context_free_io_device_limit(c, l);
+ }
}
}
@@ -506,12 +774,8 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) {
c->cpu_quota_per_sec_usec != USEC_INFINITY)
mask |= CGROUP_MASK_CPUACCT | CGROUP_MASK_CPU;
- if (c->blockio_accounting ||
- c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
- c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
- c->blockio_device_weights ||
- c->blockio_device_bandwidths)
- mask |= CGROUP_MASK_BLKIO;
+ if (cgroup_context_has_io_config(c) || cgroup_context_has_blockio_config(c))
+ mask |= CGROUP_MASK_IO | CGROUP_MASK_BLKIO;
if (c->memory_accounting ||
c->memory_limit != (uint64_t) -1)
@@ -765,7 +1029,7 @@ int unit_set_cgroup_path(Unit *u, const char *path) {
}
int unit_watch_cgroup(Unit *u) {
- _cleanup_free_ char *populated = NULL;
+ _cleanup_free_ char *events = NULL;
int r;
assert(u);
@@ -791,11 +1055,11 @@ int unit_watch_cgroup(Unit *u) {
if (r < 0)
return log_oom();
- r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.populated", &populated);
+ r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.events", &events);
if (r < 0)
return log_oom();
- u->cgroup_inotify_wd = inotify_add_watch(u->manager->cgroup_inotify_fd, populated, IN_MODIFY);
+ u->cgroup_inotify_wd = inotify_add_watch(u->manager->cgroup_inotify_fd, events, IN_MODIFY);
if (u->cgroup_inotify_wd < 0) {
if (errno == ENOENT) /* If the directory is already
@@ -857,6 +1121,7 @@ static int unit_create_cgroup(
/* Keep track that this is now realized */
u->cgroup_realized = true;
u->cgroup_realized_mask = target_mask;
+ u->cgroup_enabled_mask = enable_mask;
if (u->type != UNIT_SLICE && !c->delegate) {
@@ -886,10 +1151,10 @@ int unit_attach_pids_to_cgroup(Unit *u) {
return 0;
}
-static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask) {
+static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask, CGroupMask enable_mask) {
assert(u);
- return u->cgroup_realized && u->cgroup_realized_mask == target_mask;
+ return u->cgroup_realized && u->cgroup_realized_mask == target_mask && u->cgroup_enabled_mask == enable_mask;
}
/* Check if necessary controllers and attributes for a unit are in place.
@@ -910,7 +1175,9 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
}
target_mask = unit_get_target_mask(u);
- if (unit_has_mask_realized(u, target_mask))
+ enable_mask = unit_get_enable_mask(u);
+
+ if (unit_has_mask_realized(u, target_mask, enable_mask))
return 0;
/* First, realize parents */
@@ -921,7 +1188,6 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
}
/* And then do the real work */
- enable_mask = unit_get_enable_mask(u);
r = unit_create_cgroup(u, target_mask, enable_mask);
if (r < 0)
return r;
@@ -990,7 +1256,7 @@ static void unit_queue_siblings(Unit *u) {
/* If the unit doesn't need any new controllers
* and has current ones realized, it doesn't need
* any changes. */
- if (unit_has_mask_realized(m, unit_get_target_mask(m)))
+ if (unit_has_mask_realized(m, unit_get_target_mask(m), unit_get_enable_mask(m)))
continue;
unit_add_to_cgroup_queue(m);
@@ -1069,6 +1335,7 @@ void unit_prune_cgroup(Unit *u) {
u->cgroup_realized = false;
u->cgroup_realized_mask = 0;
+ u->cgroup_enabled_mask = 0;
}
int unit_search_main_pid(Unit *u, pid_t *ret) {
@@ -1265,7 +1532,7 @@ int manager_setup_cgroup(Manager *m) {
* it. This is to support live upgrades from older systemd
* versions where PID 1 was moved there. Also see
* cg_get_root_path(). */
- if (!e && m->running_as == MANAGER_SYSTEM) {
+ if (!e && MANAGER_IS_SYSTEM(m)) {
e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE);
if (!e)
e = endswith(m->cgroup_root, "/system"); /* even more legacy */
@@ -1312,13 +1579,15 @@ int manager_setup_cgroup(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to watch control group inotify object: %m");
- r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_IDLE - 5);
+ /* Process cgroup empty notifications early, but after service notifications and SIGCHLD. Also
+ * see handling of cgroup agent notifications, for the classic cgroup hierarchy support. */
+ r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_NORMAL-5);
if (r < 0)
return log_error_errno(r, "Failed to set priority of inotify event source: %m");
(void) sd_event_source_set_description(m->cgroup_inotify_event_source, "cgroup-inotify");
- } else if (m->running_as == MANAGER_SYSTEM) {
+ } else if (MANAGER_IS_SYSTEM(m)) {
/* On the legacy hierarchy we only get
* notifications via cgroup agents. (Which
@@ -1458,6 +1727,8 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) {
assert(m);
assert(cgroup);
+ log_debug("Got cgroup empty notification for: %s", cgroup);
+
u = manager_get_unit_by_cgroup(m, cgroup);
if (!u)
return 0;
@@ -1594,6 +1865,10 @@ void unit_invalidate_cgroup(Unit *u, CGroupMask m) {
if (m == 0)
return;
+ /* always invalidate compat pairs together */
+ if (m & (CGROUP_MASK_IO | CGROUP_MASK_BLKIO))
+ m |= CGROUP_MASK_IO | CGROUP_MASK_BLKIO;
+
if ((u->cgroup_realized_mask & m) == 0)
return;
@@ -1608,7 +1883,7 @@ void manager_invalidate_startup_units(Manager *m) {
assert(m);
SET_FOREACH(u, m->startup_units, i)
- unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_BLKIO);
+ unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_IO|CGROUP_MASK_BLKIO);
}
static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] = {
diff --git a/src/libcore/cgroup.h b/src/libcore/cgroup.h
index 360bbca30f..2b1edbafc4 100644
--- a/src/libcore/cgroup.h
+++ b/src/libcore/cgroup.h
@@ -23,9 +23,12 @@
#include "list.h"
#include "time-util.h"
+#include "cgroup-util.h"
typedef struct CGroupContext CGroupContext;
typedef struct CGroupDeviceAllow CGroupDeviceAllow;
+typedef struct CGroupIODeviceWeight CGroupIODeviceWeight;
+typedef struct CGroupIODeviceLimit CGroupIODeviceLimit;
typedef struct CGroupBlockIODeviceWeight CGroupBlockIODeviceWeight;
typedef struct CGroupBlockIODeviceBandwidth CGroupBlockIODeviceBandwidth;
@@ -53,6 +56,18 @@ struct CGroupDeviceAllow {
bool m:1;
};
+struct CGroupIODeviceWeight {
+ LIST_FIELDS(CGroupIODeviceWeight, device_weights);
+ char *path;
+ uint64_t weight;
+};
+
+struct CGroupIODeviceLimit {
+ LIST_FIELDS(CGroupIODeviceLimit, device_limits);
+ char *path;
+ uint64_t limits[_CGROUP_IO_LIMIT_TYPE_MAX];
+};
+
struct CGroupBlockIODeviceWeight {
LIST_FIELDS(CGroupBlockIODeviceWeight, device_weights);
char *path;
@@ -62,16 +77,24 @@ struct CGroupBlockIODeviceWeight {
struct CGroupBlockIODeviceBandwidth {
LIST_FIELDS(CGroupBlockIODeviceBandwidth, device_bandwidths);
char *path;
- uint64_t bandwidth;
- bool read;
+ uint64_t rbps;
+ uint64_t wbps;
};
struct CGroupContext {
bool cpu_accounting;
+ bool io_accounting;
bool blockio_accounting;
bool memory_accounting;
bool tasks_accounting;
+ /* For unified hierarchy */
+ uint64_t io_weight;
+ uint64_t startup_io_weight;
+ LIST_HEAD(CGroupIODeviceWeight, io_device_weights);
+ LIST_HEAD(CGroupIODeviceLimit, io_device_limits);
+
+ /* For legacy hierarchies */
uint64_t cpu_shares;
uint64_t startup_cpu_shares;
usec_t cpu_quota_per_sec_usec;
@@ -86,6 +109,7 @@ struct CGroupContext {
CGroupDevicePolicy device_policy;
LIST_HEAD(CGroupDeviceAllow, device_allow);
+ /* Common */
uint64_t tasks_max;
bool delegate;
@@ -102,6 +126,8 @@ void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, M
CGroupMask cgroup_context_get_mask(CGroupContext *c);
void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a);
+void cgroup_context_free_io_device_weight(CGroupContext *c, CGroupIODeviceWeight *w);
+void cgroup_context_free_io_device_limit(CGroupContext *c, CGroupIODeviceLimit *l);
void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w);
void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b);
diff --git a/src/libcore/dbus-cgroup.c b/src/libcore/dbus-cgroup.c
index 859d155ec1..eef1c47c14 100644
--- a/src/libcore/dbus-cgroup.c
+++ b/src/libcore/dbus-cgroup.c
@@ -28,6 +28,72 @@
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
+static int property_get_io_device_weight(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ CGroupContext *c = userdata;
+ CGroupIODeviceWeight *w;
+ int r;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ r = sd_bus_message_open_container(reply, 'a', "(st)");
+ if (r < 0)
+ return r;
+
+ LIST_FOREACH(device_weights, w, c->io_device_weights) {
+ r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_message_close_container(reply);
+}
+
+static int property_get_io_device_limits(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ CGroupContext *c = userdata;
+ CGroupIODeviceLimit *l;
+ int r;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ r = sd_bus_message_open_container(reply, 'a', "(st)");
+ if (r < 0)
+ return r;
+
+ LIST_FOREACH(device_limits, l, c->io_device_limits) {
+ CGroupIOLimitType type;
+
+ type = cgroup_io_limit_type_from_string(property);
+ if (type < 0 || l->limits[type] == cgroup_io_limit_defaults[type])
+ continue;
+
+ r = sd_bus_message_append(reply, "(st)", l->path, l->limits[type]);
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_message_close_container(reply);
+}
+
static int property_get_blockio_device_weight(
sd_bus *bus,
const char *path,
@@ -80,11 +146,17 @@ static int property_get_blockio_device_bandwidths(
return r;
LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
+ uint64_t v;
- if (streq(property, "BlockIOReadBandwidth") != b->read)
+ if (streq(property, "BlockIOReadBandwidth"))
+ v = b->rbps;
+ else
+ v = b->wbps;
+
+ if (v == CGROUP_LIMIT_MAX)
continue;
- r = sd_bus_message_append(reply, "(st)", b->path, b->bandwidth);
+ r = sd_bus_message_append(reply, "(st)", b->path, v);
if (r < 0)
return r;
}
@@ -141,6 +213,14 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
SD_BUS_PROPERTY("CPUShares", "t", NULL, offsetof(CGroupContext, cpu_shares), 0),
SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0),
SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
+ SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0),
+ SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0),
+ SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0),
+ SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight, 0, 0),
+ SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
+ SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
+ SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
+ SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
SD_BUS_PROPERTY("BlockIOWeight", "t", NULL, offsetof(CGroupContext, blockio_weight), 0),
SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL, offsetof(CGroupContext, startup_blockio_weight), 0),
@@ -197,6 +277,7 @@ int bus_cgroup_set_property(
UnitSetPropertiesMode mode,
sd_bus_error *error) {
+ CGroupIOLimitType iol_type;
int r;
assert(u);
@@ -281,6 +362,223 @@ int bus_cgroup_set_property(
return 1;
+ } else if (streq(name, "IOAccounting")) {
+ int b;
+
+ r = sd_bus_message_read(message, "b", &b);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ c->io_accounting = b;
+ unit_invalidate_cgroup(u, CGROUP_MASK_IO);
+ unit_write_drop_in_private(u, mode, name, b ? "IOAccounting=yes" : "IOAccounting=no");
+ }
+
+ return 1;
+
+ } else if (streq(name, "IOWeight")) {
+ uint64_t weight;
+
+ r = sd_bus_message_read(message, "t", &weight);
+ if (r < 0)
+ return r;
+
+ if (!CGROUP_WEIGHT_IS_OK(weight))
+ return sd_bus_error_set_errnof(error, EINVAL, "IOWeight value out of range");
+
+ if (mode != UNIT_CHECK) {
+ c->io_weight = weight;
+ unit_invalidate_cgroup(u, CGROUP_MASK_IO);
+
+ if (weight == CGROUP_WEIGHT_INVALID)
+ unit_write_drop_in_private(u, mode, name, "IOWeight=");
+ else
+ unit_write_drop_in_private_format(u, mode, name, "IOWeight=%" PRIu64, weight);
+ }
+
+ return 1;
+
+ } else if (streq(name, "StartupIOWeight")) {
+ uint64_t weight;
+
+ r = sd_bus_message_read(message, "t", &weight);
+ if (r < 0)
+ return r;
+
+ if (CGROUP_WEIGHT_IS_OK(weight))
+ return sd_bus_error_set_errnof(error, EINVAL, "StartupIOWeight value out of range");
+
+ if (mode != UNIT_CHECK) {
+ c->startup_io_weight = weight;
+ unit_invalidate_cgroup(u, CGROUP_MASK_IO);
+
+ if (weight == CGROUP_WEIGHT_INVALID)
+ unit_write_drop_in_private(u, mode, name, "StartupIOWeight=");
+ else
+ unit_write_drop_in_private_format(u, mode, name, "StartupIOWeight=%" PRIu64, weight);
+ }
+
+ return 1;
+
+ } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) {
+ const char *path;
+ unsigned n = 0;
+ uint64_t u64;
+
+ r = sd_bus_message_enter_container(message, 'a', "(st)");
+ if (r < 0)
+ return r;
+
+ while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
+
+ if (mode != UNIT_CHECK) {
+ CGroupIODeviceLimit *a = NULL, *b;
+
+ LIST_FOREACH(device_limits, b, c->io_device_limits) {
+ if (path_equal(path, b->path)) {
+ a = b;
+ break;
+ }
+ }
+
+ if (!a) {
+ CGroupIOLimitType type;
+
+ a = new0(CGroupIODeviceLimit, 1);
+ if (!a)
+ return -ENOMEM;
+
+ a->path = strdup(path);
+ if (!a->path) {
+ free(a);
+ return -ENOMEM;
+ }
+
+ for (type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++)
+ a->limits[type] = cgroup_io_limit_defaults[type];
+
+ LIST_PREPEND(device_limits, c->io_device_limits, a);
+ }
+
+ a->limits[iol_type] = u64;
+ }
+
+ n++;
+ }
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_exit_container(message);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ CGroupIODeviceLimit *a;
+ _cleanup_free_ char *buf = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ size_t size = 0;
+
+ if (n == 0) {
+ LIST_FOREACH(device_limits, a, c->io_device_limits)
+ a->limits[iol_type] = cgroup_io_limit_defaults[iol_type];
+ }
+
+ unit_invalidate_cgroup(u, CGROUP_MASK_IO);
+
+ f = open_memstream(&buf, &size);
+ if (!f)
+ return -ENOMEM;
+
+ fprintf(f, "%s=\n", name);
+ LIST_FOREACH(device_limits, a, c->io_device_limits)
+ if (a->limits[iol_type] != cgroup_io_limit_defaults[iol_type])
+ fprintf(f, "%s=%s %" PRIu64 "\n", name, a->path, a->limits[iol_type]);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
+ unit_write_drop_in_private(u, mode, name, buf);
+ }
+
+ return 1;
+
+ } else if (streq(name, "IODeviceWeight")) {
+ const char *path;
+ uint64_t weight;
+ unsigned n = 0;
+
+ r = sd_bus_message_enter_container(message, 'a', "(st)");
+ if (r < 0)
+ return r;
+
+ while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
+
+ if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID)
+ return sd_bus_error_set_errnof(error, EINVAL, "IODeviceWeight out of range");
+
+ if (mode != UNIT_CHECK) {
+ CGroupIODeviceWeight *a = NULL, *b;
+
+ LIST_FOREACH(device_weights, b, c->io_device_weights) {
+ if (path_equal(b->path, path)) {
+ a = b;
+ break;
+ }
+ }
+
+ if (!a) {
+ a = new0(CGroupIODeviceWeight, 1);
+ if (!a)
+ return -ENOMEM;
+
+ a->path = strdup(path);
+ if (!a->path) {
+ free(a);
+ return -ENOMEM;
+ }
+ LIST_PREPEND(device_weights,c->io_device_weights, a);
+ }
+
+ a->weight = weight;
+ }
+
+ n++;
+ }
+
+ r = sd_bus_message_exit_container(message);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ _cleanup_free_ char *buf = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ CGroupIODeviceWeight *a;
+ size_t size = 0;
+
+ if (n == 0) {
+ while (c->io_device_weights)
+ cgroup_context_free_io_device_weight(c, c->io_device_weights);
+ }
+
+ unit_invalidate_cgroup(u, CGROUP_MASK_IO);
+
+ f = open_memstream(&buf, &size);
+ if (!f)
+ return -ENOMEM;
+
+ fputs("IODeviceWeight=\n", f);
+ LIST_FOREACH(device_weights, a, c->io_device_weights)
+ fprintf(f, "IODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
+ unit_write_drop_in_private(u, mode, name, buf);
+ }
+
+ return 1;
+
} else if (streq(name, "BlockIOAccounting")) {
int b;
@@ -359,7 +657,7 @@ int bus_cgroup_set_property(
CGroupBlockIODeviceBandwidth *a = NULL, *b;
LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
- if (path_equal(path, b->path) && read == b->read) {
+ if (path_equal(path, b->path)) {
a = b;
break;
}
@@ -370,7 +668,8 @@ int bus_cgroup_set_property(
if (!a)
return -ENOMEM;
- a->read = read;
+ a->rbps = CGROUP_LIMIT_MAX;
+ a->wbps = CGROUP_LIMIT_MAX;
a->path = strdup(path);
if (!a->path) {
free(a);
@@ -380,7 +679,10 @@ int bus_cgroup_set_property(
LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
}
- a->bandwidth = u64;
+ if (read)
+ a->rbps = u64;
+ else
+ a->wbps = u64;
}
n++;
@@ -393,15 +695,18 @@ int bus_cgroup_set_property(
return r;
if (mode != UNIT_CHECK) {
- CGroupBlockIODeviceBandwidth *a, *next;
+ CGroupBlockIODeviceBandwidth *a;
_cleanup_free_ char *buf = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t size = 0;
if (n == 0) {
- LIST_FOREACH_SAFE(device_bandwidths, a, next, c->blockio_device_bandwidths)
- if (a->read == read)
- cgroup_context_free_blockio_device_bandwidth(c, a);
+ LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) {
+ if (read)
+ a->rbps = CGROUP_LIMIT_MAX;
+ else
+ a->wbps = CGROUP_LIMIT_MAX;
+ }
}
unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
@@ -413,13 +718,13 @@ int bus_cgroup_set_property(
if (read) {
fputs("BlockIOReadBandwidth=\n", f);
LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
- if (a->read)
- fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth);
+ if (a->rbps != CGROUP_LIMIT_MAX)
+ fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->rbps);
} else {
fputs("BlockIOWriteBandwidth=\n", f);
LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
- if (!a->read)
- fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth);
+ if (a->wbps != CGROUP_LIMIT_MAX)
+ fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->wbps);
}
r = fflush_and_check(f);
diff --git a/src/libcore/dbus-execute.c b/src/libcore/dbus-execute.c
index f2fc301f8e..06943c6365 100644
--- a/src/libcore/dbus-execute.c
+++ b/src/libcore/dbus-execute.c
@@ -312,7 +312,7 @@ static int property_get_ambient_capabilities(
return sd_bus_message_append(reply, "t", c->capability_ambient_set);
}
-static int property_get_capabilities(
+static int property_get_empty_string(
sd_bus *bus,
const char *path,
const char *interface,
@@ -321,23 +321,10 @@ static int property_get_capabilities(
void *userdata,
sd_bus_error *error) {
- ExecContext *c = userdata;
- _cleanup_cap_free_charp_ char *t = NULL;
- const char *s;
-
assert(bus);
assert(reply);
- assert(c);
-
- if (c->capabilities)
- s = t = cap_to_text(c->capabilities, NULL);
- else
- s = "";
- if (!s)
- return -ENOMEM;
-
- return sd_bus_message_append(reply, "s", s);
+ return sd_bus_message_append(reply, "s", "");
}
static int property_get_syscall_filter(
@@ -700,7 +687,7 @@ 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_capabilities, 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),
@@ -850,18 +837,10 @@ int bus_exec_context_set_transient_property(
if (mode != UNIT_CHECK) {
- if (isempty(uu)) {
+ if (isempty(uu))
c->user = mfree(c->user);
- } else {
- char *t;
-
- t = strdup(uu);
- if (!t)
- return -ENOMEM;
-
- free(c->user);
- c->user = t;
- }
+ else if (free_and_strdup(&c->user, uu) < 0)
+ return -ENOMEM;
unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
}
@@ -877,18 +856,10 @@ int bus_exec_context_set_transient_property(
if (mode != UNIT_CHECK) {
- if (isempty(gg)) {
+ if (isempty(gg))
c->group = mfree(c->group);
- } else {
- char *t;
-
- t = strdup(gg);
- if (!t)
- return -ENOMEM;
-
- free(c->group);
- c->group = t;
- }
+ else if (free_and_strdup(&c->group, gg) < 0)
+ return -ENOMEM;
unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
}
@@ -903,18 +874,10 @@ int bus_exec_context_set_transient_property(
if (mode != UNIT_CHECK) {
- if (isempty(id)) {
+ if (isempty(id))
c->syslog_identifier = mfree(c->syslog_identifier);
- } else {
- char *t;
-
- t = strdup(id);
- if (!t)
- return -ENOMEM;
-
- free(c->syslog_identifier);
- c->syslog_identifier = t;
- }
+ else if (free_and_strdup(&c->syslog_identifier, id) < 0)
+ return -ENOMEM;
unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s\n", id);
}
@@ -1491,6 +1454,24 @@ int bus_exec_context_set_transient_property(
return 1;
+ } else if (streq(name, "SELinuxContext")) {
+ const char *s;
+
+ r = sd_bus_message_read(message, "s", &s);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ if (isempty(s))
+ c->selinux_context = mfree(c->selinux_context);
+ else if (free_and_strdup(&c->selinux_context, s) < 0)
+ return -ENOMEM;
+
+ unit_write_drop_in_private_format(u, mode, name, "%s=%s\n", name, strempty(s));
+ }
+
+ return 1;
+
}
ri = rlimit_from_string(name);
diff --git a/src/libcore/dbus-job.c b/src/libcore/dbus-job.c
index 337cef8a4f..1d739787bb 100644
--- a/src/libcore/dbus-job.c
+++ b/src/libcore/dbus-job.c
@@ -75,7 +75,7 @@ int bus_job_method_cancel(sd_bus_message *message, void *userdata, sd_bus_error
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
- job_finish_and_invalidate(j, JOB_CANCELED, true);
+ job_finish_and_invalidate(j, JOB_CANCELED, true, false);
return sd_bus_reply_method_return(message, NULL);
}
diff --git a/src/libcore/dbus-kill.c b/src/libcore/dbus-kill.c
index fc50fafaad..0f54c6b84b 100644
--- a/src/libcore/dbus-kill.c
+++ b/src/libcore/dbus-kill.c
@@ -58,7 +58,7 @@ int bus_kill_context_set_transient_property(
k = kill_mode_from_string(m);
if (k < 0)
- return -EINVAL;
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Kill mode '%s' not known.", m);
if (mode != UNIT_CHECK) {
c->kill_mode = k;
@@ -75,7 +75,7 @@ int bus_kill_context_set_transient_property(
if (r < 0)
return r;
- if (sig <= 0 || sig >= _NSIG)
+ if (!SIGNAL_VALID(sig))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig);
if (mode != UNIT_CHECK) {
diff --git a/src/libcore/dbus-manager.c b/src/libcore/dbus-manager.c
index f939196397..86722e1162 100644
--- a/src/libcore/dbus-manager.c
+++ b/src/libcore/dbus-manager.c
@@ -139,7 +139,7 @@ static int property_get_tainted(
if (access("/proc/cgroups", F_OK) < 0)
e = stpcpy(e, "cgroups-missing:");
- if (clock_is_localtime() > 0)
+ if (clock_is_localtime(NULL) > 0)
e = stpcpy(e, "local-hwclock:");
/* remove the last ':' */
@@ -642,6 +642,104 @@ static int method_set_unit_properties(sd_bus_message *message, void *userdata, s
return bus_unit_method_set_properties(message, u, error);
}
+static int reply_unit_info(sd_bus_message *reply, Unit *u) {
+ _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
+ Unit *following;
+
+ following = unit_following(u);
+
+ unit_path = unit_dbus_path(u);
+ if (!unit_path)
+ return -ENOMEM;
+
+ if (u->job) {
+ job_path = job_dbus_path(u->job);
+ if (!job_path)
+ return -ENOMEM;
+ }
+
+ return sd_bus_message_append(
+ reply, "(ssssssouso)",
+ u->id,
+ unit_description(u),
+ unit_load_state_to_string(u->load_state),
+ unit_active_state_to_string(unit_active_state(u)),
+ unit_sub_state_to_string(u),
+ following ? following->id : "",
+ unit_path,
+ u->job ? u->job->id : 0,
+ u->job ? job_type_to_string(u->job->type) : "",
+ job_path ? job_path : "/");
+}
+
+static int method_list_units_by_names(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ Manager *m = userdata;
+ int r;
+ char **unit;
+ _cleanup_strv_free_ char **units = NULL;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read_strv(message, &units);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(unit, units) {
+ Unit *u;
+
+ if (!unit_name_is_valid(*unit, UNIT_NAME_ANY))
+ continue;
+
+ r = manager_load_unit(m, *unit, NULL, error, &u);
+ if (r < 0)
+ return r;
+
+ r = reply_unit_info(reply, u);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
+static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ const char *name;
+ Unit *u;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return r;
+
+ r = manager_load_unit(m, name, NULL, error, &u);
+ if (r < 0)
+ return r;
+
+ r = bus_unit_check_load_state(u, error);
+ if (r < 0)
+ return r;
+
+ return bus_unit_method_get_processes(message, u, error);
+}
+
static int transient_unit_from_message(
Manager *m,
sd_bus_message *message,
@@ -865,7 +963,7 @@ static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_e
return sd_bus_reply_method_return(message, NULL);
}
-static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
+static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
Manager *m = userdata;
const char *k;
@@ -891,42 +989,20 @@ static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_e
return r;
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
- _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
- Unit *following;
-
if (k != u->id)
continue;
- following = unit_following(u);
-
if (!strv_isempty(states) &&
!strv_contains(states, unit_load_state_to_string(u->load_state)) &&
!strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
!strv_contains(states, unit_sub_state_to_string(u)))
continue;
- unit_path = unit_dbus_path(u);
- if (!unit_path)
- return -ENOMEM;
-
- if (u->job) {
- job_path = job_dbus_path(u->job);
- if (!job_path)
- return -ENOMEM;
- }
+ if (!strv_isempty(patterns) &&
+ !strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
+ continue;
- r = sd_bus_message_append(
- reply, "(ssssssouso)",
- u->id,
- unit_description(u),
- unit_load_state_to_string(u->load_state),
- unit_active_state_to_string(unit_active_state(u)),
- unit_sub_state_to_string(u),
- following ? following->id : "",
- unit_path,
- u->job ? u->job->id : 0,
- u->job ? job_type_to_string(u->job->type) : "",
- job_path ? job_path : "/");
+ r = reply_unit_info(reply, u);
if (r < 0)
return r;
}
@@ -939,7 +1015,7 @@ static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_e
}
static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return list_units_filtered(message, userdata, error, NULL);
+ return list_units_filtered(message, userdata, error, NULL, NULL);
}
static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -950,7 +1026,23 @@ static int method_list_units_filtered(sd_bus_message *message, void *userdata, s
if (r < 0)
return r;
- return list_units_filtered(message, userdata, error, states);
+ return list_units_filtered(message, userdata, error, states, NULL);
+}
+
+static int method_list_units_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_strv_free_ char **states = NULL;
+ _cleanup_strv_free_ char **patterns = NULL;
+ int r;
+
+ r = sd_bus_message_read_strv(message, &states);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_strv(message, &patterns);
+ if (r < 0)
+ return r;
+
+ return list_units_filtered(message, userdata, error, states, patterns);
}
static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -1187,7 +1279,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *
if (r < 0)
return r;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
m->exit_code = MANAGER_REBOOT;
@@ -1206,7 +1298,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error
if (r < 0)
return r;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
m->exit_code = MANAGER_POWEROFF;
@@ -1225,7 +1317,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er
if (r < 0)
return r;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
m->exit_code = MANAGER_HALT;
@@ -1244,7 +1336,7 @@ static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *e
if (r < 0)
return r;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
m->exit_code = MANAGER_KEXEC;
@@ -1265,7 +1357,7 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
if (r < 0)
return r;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
r = sd_bus_message_read(message, "ss", &root, &init);
@@ -1433,7 +1525,7 @@ static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_
if (r < 0)
return r;
- if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0)
+ if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
m->return_value = code;
@@ -1441,7 +1533,7 @@ static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_
return sd_bus_reply_method_return(message, NULL);
}
-static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
Manager *m = userdata;
UnitFileList *item;
@@ -1466,7 +1558,7 @@ static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bu
if (!h)
return -ENOMEM;
- r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
+ r = unit_file_get_list(m->unit_file_scope, NULL, h, states, patterns);
if (r < 0)
goto fail;
@@ -1494,11 +1586,30 @@ fail:
return r;
}
+static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return list_unit_files_by_patterns(message, userdata, error, NULL, NULL);
+}
+
+static int method_list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_strv_free_ char **states = NULL;
+ _cleanup_strv_free_ char **patterns = NULL;
+ int r;
+
+ r = sd_bus_message_read_strv(message, &states);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_strv(message, &patterns);
+ if (r < 0)
+ return r;
+
+ return list_unit_files_by_patterns(message, userdata, error, states, patterns);
+}
+
static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
const char *name;
UnitFileState state;
- UnitFileScope scope;
int r;
assert(message);
@@ -1514,9 +1625,7 @@ static int method_get_unit_file_state(sd_bus_message *message, void *userdata, s
if (r < 0)
return r;
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_get_state(scope, NULL, name, &state);
+ r = unit_file_get_state(m->unit_file_scope, NULL, name, &state);
if (r < 0)
return r;
@@ -1526,7 +1635,6 @@ static int method_get_unit_file_state(sd_bus_message *message, void *userdata, s
static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *default_target = NULL;
Manager *m = userdata;
- UnitFileScope scope;
int r;
assert(message);
@@ -1538,9 +1646,7 @@ static int method_get_default_target(sd_bus_message *message, void *userdata, sd
if (r < 0)
return r;
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_get_default(scope, NULL, &default_target);
+ r = unit_file_get_default(m->unit_file_scope, NULL, &default_target);
if (r < 0)
return r;
@@ -1571,7 +1677,7 @@ static int reply_unit_file_changes_and_free(
unsigned i;
int r;
- if (n_changes > 0) {
+ if (unit_file_changes_have_modification(changes, n_changes)) {
r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
if (r < 0)
log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
@@ -1591,15 +1697,19 @@ static int reply_unit_file_changes_and_free(
if (r < 0)
goto fail;
- for (i = 0; i < n_changes; i++) {
- r = sd_bus_message_append(
- reply, "(sss)",
- unit_file_change_type_to_string(changes[i].type),
- changes[i].path,
- changes[i].source);
- if (r < 0)
- goto fail;
- }
+ for (i = 0; i < n_changes; i++)
+ if (changes[i].type >= 0) {
+ const char *change = unit_file_change_type_to_string(changes[i].type);
+ assert(change != NULL);
+
+ r = sd_bus_message_append(
+ reply, "(sss)",
+ change,
+ changes[i].path,
+ changes[i].source);
+ if (r < 0)
+ goto fail;
+ }
r = sd_bus_message_close_container(reply);
if (r < 0)
@@ -1613,10 +1723,61 @@ fail:
return r;
}
+/* Create an error reply, using the error information from changes[]
+ * if possible, and fall back to generating an error from error code c.
+ * The error message only describes the first error.
+ *
+ * Coordinate with unit_file_dump_changes() in install.c.
+ */
+static int install_error(
+ sd_bus_error *error,
+ int c,
+ UnitFileChange *changes,
+ unsigned n_changes) {
+ int r;
+ unsigned i;
+ assert(c < 0);
+
+ for (i = 0; i < n_changes; i++)
+ switch(changes[i].type) {
+ case 0 ... INT_MAX:
+ continue;
+ case -EEXIST:
+ if (changes[i].source)
+ r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
+ "File %s already exists and is a symlink to %s.",
+ changes[i].path, changes[i].source);
+ else
+ r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
+ "File %s already exists.",
+ changes[i].path);
+ goto found;
+ case -ERFKILL:
+ r = sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED,
+ "Unit file %s is masked.", changes[i].path);
+ goto found;
+ case -EADDRNOTAVAIL:
+ r = sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED,
+ "Unit %s is transient or generated.", changes[i].path);
+ goto found;
+ case -ELOOP:
+ r = sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED,
+ "Refusing to operate on linked unit file %s", changes[i].path);
+ goto found;
+ default:
+ r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path);
+ goto found;
+ }
+
+ r = c;
+ found:
+ unit_file_changes_free(changes, n_changes);
+ return r;
+}
+
static int method_enable_unit_files_generic(
sd_bus_message *message,
Manager *m,
- const char *verb,
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
bool carries_install_info,
sd_bus_error *error) {
@@ -1624,7 +1785,6 @@ static int method_enable_unit_files_generic(
_cleanup_strv_free_ char **l = NULL;
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
- UnitFileScope scope;
int runtime, force, r;
assert(message);
@@ -1644,27 +1804,23 @@ static int method_enable_unit_files_generic(
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
- if (r == -ESHUTDOWN)
- return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked");
+ r = call(m->unit_file_scope, runtime, NULL, l, force, &changes, &n_changes);
if (r < 0)
- return r;
+ return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes);
}
static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(message, userdata, "enable", unit_file_enable, true, error);
+ return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error);
}
static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(message, userdata, "enable", unit_file_reenable, true, error);
+ return method_enable_unit_files_generic(message, userdata, unit_file_reenable, true, error);
}
static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(message, userdata, "enable", unit_file_link, false, error);
+ return method_enable_unit_files_generic(message, userdata, unit_file_link, false, error);
}
static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
@@ -1672,11 +1828,11 @@ static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, cons
}
static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(message, userdata, "enable", unit_file_preset_without_mode, true, error);
+ return method_enable_unit_files_generic(message, userdata, unit_file_preset_without_mode, true, error);
}
static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(message, userdata, "disable", unit_file_mask, false, error);
+ return method_enable_unit_files_generic(message, userdata, unit_file_mask, false, error);
}
static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -1686,7 +1842,6 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
unsigned n_changes = 0;
Manager *m = userdata;
UnitFilePresetMode mm;
- UnitFileScope scope;
int runtime, force, r;
const char *mode;
@@ -1715,26 +1870,22 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
+ r = unit_file_preset(m->unit_file_scope, runtime, NULL, l, mm, force, &changes, &n_changes);
if (r < 0)
- return r;
+ return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, r, changes, n_changes);
}
static int method_disable_unit_files_generic(
sd_bus_message *message,
- Manager *m, const
- char *verb,
+ Manager *m,
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
- UnitFileScope scope;
int r, runtime;
assert(message);
@@ -1748,34 +1899,58 @@ static int method_disable_unit_files_generic(
if (r < 0)
return r;
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
r = bus_verify_manage_unit_files_async(m, message, error);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = call(scope, runtime, NULL, l, &changes, &n_changes);
+ r = call(m->unit_file_scope, runtime, NULL, l, &changes, &n_changes);
if (r < 0)
- return r;
+ return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
}
static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_disable_unit_files_generic(message, userdata, "disable", unit_file_disable, error);
+ return method_disable_unit_files_generic(message, userdata, unit_file_disable, error);
}
static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_disable_unit_files_generic(message, userdata, "enable", unit_file_unmask, error);
+ return method_disable_unit_files_generic(message, userdata, unit_file_unmask, error);
+}
+
+static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_strv_free_ char **l = NULL;
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
+ Manager *m = userdata;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read_strv(message, &l);
+ if (r < 0)
+ return r;
+
+ r = bus_verify_manage_unit_files_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+ r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes);
+ if (r < 0)
+ return install_error(error, r, changes, n_changes);
+
+ return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
}
static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
Manager *m = userdata;
- UnitFileScope scope;
const char *name;
int force, r;
@@ -1796,11 +1971,9 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
+ r = unit_file_set_default(m->unit_file_scope, NULL, name, force, &changes, &n_changes);
if (r < 0)
- return r;
+ return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
}
@@ -1810,7 +1983,6 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
unsigned n_changes = 0;
Manager *m = userdata;
UnitFilePresetMode mm;
- UnitFileScope scope;
const char *mode;
int force, runtime, r;
@@ -1839,13 +2011,9 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
- if (r < 0) {
- unit_file_changes_free(changes, n_changes);
- return r;
- }
+ r = unit_file_preset_all(m->unit_file_scope, runtime, NULL, mm, force, &changes, &n_changes);
+ if (r < 0)
+ return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
}
@@ -1855,10 +2023,8 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
Manager *m = userdata;
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
- UnitFileScope scope;
int runtime, force, r;
- char *target;
- char *type;
+ char *target, *type;
UnitDependency dep;
assert(message);
@@ -1882,13 +2048,9 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
if (dep < 0)
return -EINVAL;
- scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
- if (r == -ESHUTDOWN)
- return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked");
+ r = unit_file_add_dependency(m->unit_file_scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
if (r < 0)
- return r;
+ return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
}
@@ -1924,7 +2086,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
@@ -1936,7 +2098,8 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */
SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1992,12 +2155,15 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUnitProcesses", "s", "a(sus)", method_get_unit_processes, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListUnitsByPatterns", "asas", "a(ssssssouso)", method_list_units_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListUnitsByNames", "as", "a(ssssssouso)", method_list_units_by_names, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -2016,6 +2182,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListUnitFilesByPatterns", "asas", "a(ss)", method_list_unit_files_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -2025,6 +2192,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("RevertUnitFiles", "as", "a(sss)", method_revert_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/libcore/dbus-socket.c b/src/libcore/dbus-socket.c
index d33e494f6b..961340608d 100644
--- a/src/libcore/dbus-socket.c
+++ b/src/libcore/dbus-socket.c
@@ -149,6 +149,8 @@ const sd_bus_vtable bus_socket_vtable[] = {
SD_BUS_PROPERTY("NAccepted", "u", bus_property_get_unsigned, offsetof(Socket, n_accepted), 0),
SD_BUS_PROPERTY("FileDescriptorName", "s", property_get_fdname, 0, 0),
SD_BUS_PROPERTY("SocketProtocol", "i", bus_property_get_int, offsetof(Socket, socket_protocol), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("TriggerLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("TriggerLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, trigger_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
diff --git a/src/libcore/dbus-timer.c b/src/libcore/dbus-timer.c
index bc121b83a2..a0e61b023e 100644
--- a/src/libcore/dbus-timer.c
+++ b/src/libcore/dbus-timer.c
@@ -156,7 +156,7 @@ static int property_get_next_elapse_monotonic(
usec_t a, b;
a = now(CLOCK_MONOTONIC);
- b = now(CLOCK_BOOTTIME);
+ b = now(clock_boottime_or_monotonic());
if (t->next_elapse_monotonic_or_boottime + a > b)
x = t->next_elapse_monotonic_or_boottime + a - b;
diff --git a/src/libcore/dbus-unit.c b/src/libcore/dbus-unit.c
index 9a09f59fc2..dcd8db0898 100644
--- a/src/libcore/dbus-unit.c
+++ b/src/libcore/dbus-unit.c
@@ -24,9 +24,12 @@
#include "cgroup-util.h"
#include "dbus-unit.h"
#include "dbus.h"
+#include "fd-util.h"
#include "locale-util.h"
#include "log.h"
+#include "process-util.h"
#include "selinux-access.h"
+#include "signal-util.h"
#include "special.h"
#include "string-util.h"
#include "strv.h"
@@ -547,7 +550,7 @@ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho);
}
- if (signo <= 0 || signo >= _NSIG)
+ if (!SIGNAL_VALID(signo))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
r = bus_verify_manage_units_async_full(
@@ -701,7 +704,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0),
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -840,6 +844,145 @@ static int property_get_cgroup(
return sd_bus_message_append(reply, "s", t);
}
+static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *pids) {
+ _cleanup_free_ char *buf = NULL, *cmdline = NULL;
+ int r;
+
+ assert(reply);
+ assert(pid > 0);
+
+ r = set_put(pids, PID_TO_PTR(pid));
+ if (r == -EEXIST || r == 0)
+ return 0;
+ if (r < 0)
+ return r;
+
+ if (!p) {
+ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
+ if (r == -ESRCH)
+ return 0;
+ if (r < 0)
+ return r;
+
+ p = buf;
+ }
+
+ (void) get_process_cmdline(pid, 0, true, &cmdline);
+
+ return sd_bus_message_append(reply,
+ "(sus)",
+ p,
+ (uint32_t) pid,
+ cmdline);
+}
+
+static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
+ _cleanup_closedir_ DIR *d = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ int r;
+
+ assert(reply);
+ assert(p);
+
+ r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, p, &f);
+ if (r == ENOENT)
+ return 0;
+ if (r < 0)
+ return r;
+
+ for (;;) {
+ pid_t pid;
+
+ r = cg_read_pid(f, &pid);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ if (is_kernel_thread(pid) > 0)
+ continue;
+
+ r = append_process(reply, p, pid, pids);
+ if (r < 0)
+ return r;
+ }
+
+ r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, p, &d);
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
+ return r;
+
+ for (;;) {
+ _cleanup_free_ char *g = NULL, *j = NULL;
+
+ r = cg_read_subgroup(d, &g);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ j = strjoin(p, "/", g, NULL);
+ if (!j)
+ return -ENOMEM;
+
+ r = append_cgroup(reply, j, pids);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(set_freep) Set *pids = NULL;
+ Unit *u = userdata;
+ pid_t pid;
+ int r;
+
+ assert(message);
+
+ pids = set_new(NULL);
+ if (!pids)
+ return -ENOMEM;
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(sus)");
+ if (r < 0)
+ return r;
+
+ if (u->cgroup_path) {
+ r = append_cgroup(reply, u->cgroup_path, pids);
+ if (r < 0)
+ return r;
+ }
+
+ /* The main and control pids might live outside of the cgroup, hence fetch them separately */
+ pid = unit_main_pid(u);
+ if (pid > 0) {
+ r = append_process(reply, NULL, pid, pids);
+ if (r < 0)
+ return r;
+ }
+
+ pid = unit_control_pid(u);
+ if (pid > 0) {
+ r = append_process(reply, NULL, pid, pids);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
const sd_bus_vtable bus_unit_cgroup_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Slice", "s", property_get_slice, 0, 0),
@@ -847,6 +990,7 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
+ SD_BUS_METHOD("GetProcesses", NULL, "a(sus)", bus_unit_method_get_processes, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
@@ -1002,7 +1146,6 @@ int bus_unit_queue_job(
type = JOB_TRY_RELOAD;
}
-
if (type == JOB_STOP &&
(u->load_state == UNIT_NOT_FOUND || u->load_state == UNIT_ERROR) &&
unit_active_state(u) == UNIT_INACTIVE)
@@ -1099,7 +1242,10 @@ static int bus_unit_set_transient_property(
if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name '%s'", s);
- r = manager_load_unit(u->manager, s, NULL, error, &slice);
+ /* Note that we do not dispatch the load queue here yet, as we don't want our own transient unit to be
+ * loaded while we are still setting it up. Or in other words, we use manager_load_unit_prepare()
+ * instead of manager_load_unit() on purpose, here. */
+ r = manager_load_unit_prepare(u->manager, s, NULL, error, &slice);
if (r < 0)
return r;
@@ -1259,6 +1405,7 @@ int bus_unit_set_properties(
}
int bus_unit_check_load_state(Unit *u, sd_bus_error *error) {
+ assert(u);
if (u->load_state == UNIT_LOADED)
return 0;
diff --git a/src/libcore/dbus-unit.h b/src/libcore/dbus-unit.h
index 1a0070fce6..758045a47c 100644
--- a/src/libcore/dbus-unit.h
+++ b/src/libcore/dbus-unit.h
@@ -36,5 +36,6 @@ int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus
int bus_unit_queue_job(sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible, sd_bus_error *error);
int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitSetPropertiesMode mode, bool commit, sd_bus_error *error);
int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_unit_check_load_state(Unit *u, sd_bus_error *error);
diff --git a/src/libcore/dbus.c b/src/libcore/dbus.c
index dc939b023a..1b217da303 100644
--- a/src/libcore/dbus.c
+++ b/src/libcore/dbus.c
@@ -71,28 +71,42 @@ int bus_send_queued_message(Manager *m) {
return 0;
}
+int bus_forward_agent_released(Manager *m, const char *path) {
+ int r;
+
+ assert(m);
+ assert(path);
+
+ if (!MANAGER_IS_SYSTEM(m))
+ return 0;
+
+ if (!m->system_bus)
+ return 0;
+
+ /* If we are running a system instance we forward the agent message on the system bus, so that the user
+ * instances get notified about this, too */
+
+ r = sd_bus_emit_signal(m->system_bus,
+ "/org/freedesktop/systemd1/agent",
+ "org.freedesktop.systemd1.Agent",
+ "Released",
+ "s", path);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to propagate agent release message: %m");
+
+ return 1;
+}
+
static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- const char *cgroup, *me;
Manager *m = userdata;
+ const char *cgroup;
uid_t sender_uid;
- sd_bus *bus;
int r;
assert(message);
assert(m);
- /* ignore recursive events sent by us on the system/user bus */
- bus = sd_bus_message_get_bus(message);
- if (!sd_bus_is_server(bus)) {
- r = sd_bus_get_unique_name(bus, &me);
- if (r < 0)
- return r;
-
- if (streq_ptr(sd_bus_message_get_sender(message), me))
- return 0;
- }
-
/* only accept org.freedesktop.systemd1.Agent from UID=0 */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
@@ -110,16 +124,6 @@ static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus
}
manager_notify_cgroup_empty(m, cgroup);
-
- /* if running as system-instance, forward under our name */
- if (m->running_as == MANAGER_SYSTEM && m->system_bus) {
- r = sd_bus_message_rewind(message, 1);
- if (r >= 0)
- r = sd_bus_send(m->system_bus, message, NULL);
- if (r < 0)
- log_warning_errno(r, "Failed to forward Released message: %m");
- }
-
return 0;
}
@@ -690,25 +694,6 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
return 0;
}
- if (m->running_as == MANAGER_SYSTEM) {
- /* When we run as system instance we get the Released
- * signal via a direct connection */
-
- r = sd_bus_add_match(
- bus,
- NULL,
- "type='signal',"
- "interface='org.freedesktop.systemd1.Agent',"
- "member='Released',"
- "path='/org/freedesktop/systemd1/agent'",
- signal_agent_released, m);
-
- if (r < 0) {
- log_warning_errno(r, "Failed to register Released match on new connection bus: %m");
- return 0;
- }
- }
-
r = bus_setup_disconnected_match(m, bus);
if (r < 0)
return 0;
@@ -864,10 +849,10 @@ static int bus_init_api(Manager *m) {
return 0;
/* The API and system bus is the same if we are running in system mode */
- if (m->running_as == MANAGER_SYSTEM && m->system_bus)
+ if (MANAGER_IS_SYSTEM(m) && m->system_bus)
bus = sd_bus_ref(m->system_bus);
else {
- if (m->running_as == MANAGER_SYSTEM)
+ if (MANAGER_IS_SYSTEM(m))
r = sd_bus_open_system(&bus);
else
r = sd_bus_open_user(&bus);
@@ -906,8 +891,8 @@ static int bus_setup_system(Manager *m, sd_bus *bus) {
assert(m);
assert(bus);
- /* On kdbus or if we are a user instance we get the Released message via the system bus */
- if (m->running_as == MANAGER_USER || m->kdbus_fd >= 0) {
+ /* if we are a user instance we get the Released message via the system bus */
+ if (MANAGER_IS_USER(m)) {
r = sd_bus_add_match(
bus,
NULL,
@@ -932,7 +917,7 @@ static int bus_init_system(Manager *m) {
return 0;
/* The API and system bus is the same if we are running in system mode */
- if (m->running_as == MANAGER_SYSTEM && m->api_bus) {
+ if (MANAGER_IS_SYSTEM(m) && m->api_bus) {
m->system_bus = sd_bus_ref(m->api_bus);
return 0;
}
@@ -983,14 +968,14 @@ static int bus_init_private(Manager *m) {
if (m->kdbus_fd >= 0)
return 0;
- if (m->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(m)) {
/* We want the private bus only when running as init */
if (getpid() != 1)
return 0;
strcpy(sa.un.sun_path, "/run/systemd/private");
- salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
+ salen = SOCKADDR_UN_LEN(sa.un);
} else {
size_t left = sizeof(sa.un.sun_path);
char *p = sa.un.sun_path;
@@ -1082,7 +1067,7 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
/* Possibly flush unwritten data, but only if we are
* unprivileged, since we don't want to sync here */
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
sd_bus_flush(*bus);
/* And destroy the object */
diff --git a/src/libcore/dbus.h b/src/libcore/dbus.h
index e16a84fbb8..6baaffbd75 100644
--- a/src/libcore/dbus.h
+++ b/src/libcore/dbus.h
@@ -40,3 +40,5 @@ int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error
int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
+
+int bus_forward_agent_released(Manager *m, const char *path);
diff --git a/src/libcore/device.c b/src/libcore/device.c
index d201dc5e4b..16e56efcc3 100644
--- a/src/libcore/device.c
+++ b/src/libcore/device.c
@@ -265,7 +265,7 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
assert(u);
assert(dev);
- property = u->manager->running_as == MANAGER_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
+ property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
wants = udev_device_get_property_value(dev, property);
if (!wants)
return 0;
@@ -318,11 +318,11 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
* the GC to have garbaged it. That's desired since the device
* unit may have a dependency on the mount unit which was
* added during the loading of the later. */
- if (u && DEVICE(u)->state == DEVICE_PLUGGED) {
+ if (dev && u && DEVICE(u)->state == DEVICE_PLUGGED) {
/* This unit is in plugged state: we're sure it's
* attached to a device. */
if (!path_equal(DEVICE(u)->sysfs, sysfs)) {
- log_unit_error(u, "Dev %s appeared twice with different sysfs paths %s and %s",
+ log_unit_debug(u, "Dev %s appeared twice with different sysfs paths %s and %s",
e, DEVICE(u)->sysfs, sysfs);
return -EEXIST;
}
@@ -841,8 +841,6 @@ const UnitVTable device_vtable = {
"Device\0"
"Install\0",
- .no_instances = true,
-
.init = device_init,
.done = device_done,
.load = unit_load_fragment_and_dropin_optional,
diff --git a/src/libcore/execute.c b/src/libcore/execute.c
index 6fd35c8350..b58fb80be2 100644
--- a/src/libcore/execute.c
+++ b/src/libcore/execute.c
@@ -24,6 +24,7 @@
#include <poll.h>
#include <signal.h>
#include <string.h>
+#include <sys/capability.h>
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/socket.h>
@@ -57,7 +58,6 @@
#endif
#include "async.h"
#include "barrier.h"
-#include "bus-endpoint.h"
#include "cap-list.h"
#include "capability-util.h"
#include "def.h"
@@ -271,7 +271,7 @@ static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
}
}
- r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+ r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
r = -errno;
@@ -747,10 +747,10 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_
static int enforce_user(const ExecContext *context, uid_t uid) {
assert(context);
- /* Sets (but doesn't lookup) the uid and make sure we keep the
+ /* Sets (but doesn't look up) the uid and make sure we keep the
* capabilities while doing so. */
- if (context->capabilities || context->capability_ambient_set != 0) {
+ if (context->capability_ambient_set != 0) {
/* First step: If we need to keep capabilities but
* drop privileges we need to make sure we keep our
@@ -762,31 +762,9 @@ static int enforce_user(const ExecContext *context, uid_t uid) {
if (prctl(PR_SET_SECUREBITS, sb) < 0)
return -errno;
}
-
- /* Second step: set the capabilities. This will reduce
- * the capabilities to the minimum we need. */
-
- if (context->capabilities) {
- _cleanup_cap_free_ cap_t d = NULL;
- static const cap_value_t bits[] = {
- CAP_SETUID, /* Necessary so that we can run setresuid() below */
- CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
- };
-
- d = cap_dup(context->capabilities);
- if (!d)
- return -errno;
-
- if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
- cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0)
- return -errno;
-
- if (cap_set_proc(d) < 0)
- return -errno;
- }
}
- /* Third step: actually set the uids */
+ /* Second step: actually set the uids */
if (setresuid(uid, uid, uid) < 0)
return -errno;
@@ -1387,9 +1365,6 @@ static bool exec_needs_mount_namespace(
if (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir))
return true;
- if (params->bus_endpoint_path)
- return true;
-
if (context->private_devices ||
context->protect_system != PROTECT_SYSTEM_NO ||
context->protect_home != PROTECT_HOME_NO)
@@ -1423,9 +1398,6 @@ static int close_remaining_fds(
n_dont_close += n_fds;
}
- if (params->bus_endpoint_fd >= 0)
- dont_close[n_dont_close++] = params->bus_endpoint_fd;
-
if (runtime) {
if (runtime->netns_storage_socket[0] >= 0)
dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
@@ -1655,16 +1627,6 @@ static int exec_child(
}
}
- if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
- uid_t ep_uid = (uid == UID_INVALID) ? 0 : uid;
-
- r = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
- if (r < 0) {
- *exit_status = EXIT_BUS_ENDPOINT;
- return r;
- }
- }
-
/* If delegation is enabled we'll pass ownership of the cgroup
* (but only in systemd's own controller hierarchy!) to the
* user of the new process. */
@@ -1787,7 +1749,6 @@ static int exec_child(
context->inaccessible_dirs,
tmp,
var,
- params->bus_endpoint_path,
context->private_devices,
context->protect_home,
context->protect_system,
@@ -1864,6 +1825,11 @@ static int exec_child(
if (params->apply_permissions) {
+ bool use_address_families = context->address_families_whitelist ||
+ !set_isempty(context->address_families);
+ bool use_syscall_filter = context->syscall_whitelist ||
+ !set_isempty(context->syscall_filter) ||
+ !set_isempty(context->syscall_archs);
int secure_bits = context->secure_bits;
for (i = 0; i < _RLIMIT_MAX; i++) {
@@ -1892,21 +1858,6 @@ static int exec_child(
*exit_status = EXIT_CAPABILITIES;
return r;
}
-
- if (context->capabilities) {
-
- /* The capabilities in ambient set need to be also in the inherited
- * set. If they aren't, trying to get them will fail. Add the ambient
- * set inherited capabilities to the capability set in the context.
- * This is needed because if capabilities are set (using "Capabilities="
- * keyword), they will override whatever we set now. */
-
- r = capability_update_inherited_set(context->capabilities, context->capability_ambient_set);
- if (r < 0) {
- *exit_status = EXIT_CAPABILITIES;
- return r;
- }
- }
}
if (context->user) {
@@ -1931,7 +1882,7 @@ static int exec_child(
* also to the context secure_bits so that we don't try to
* drop the bit away next. */
- secure_bits |= 1<<SECURE_KEEP_CAPS;
+ secure_bits |= 1<<SECURE_KEEP_CAPS;
}
}
@@ -1945,21 +1896,15 @@ static int exec_child(
return -errno;
}
- if (context->capabilities)
- if (cap_set_proc(context->capabilities) < 0) {
- *exit_status = EXIT_CAPABILITIES;
- return -errno;
- }
-
- if (context->no_new_privileges)
+ if (context->no_new_privileges ||
+ (!have_effective_cap(CAP_SYS_ADMIN) && (use_address_families || use_syscall_filter)))
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
*exit_status = EXIT_NO_NEW_PRIVILEGES;
return -errno;
}
#ifdef HAVE_SECCOMP
- if (context->address_families_whitelist ||
- !set_isempty(context->address_families)) {
+ if (use_address_families) {
r = apply_address_families(context);
if (r < 0) {
*exit_status = EXIT_ADDRESS_FAMILIES;
@@ -1967,9 +1912,7 @@ static int exec_child(
}
}
- if (context->syscall_whitelist ||
- !set_isempty(context->syscall_filter) ||
- !set_isempty(context->syscall_archs)) {
+ if (use_syscall_filter) {
r = apply_seccomp(context);
if (r < 0) {
*exit_status = EXIT_SECCOMP;
@@ -2193,11 +2136,6 @@ void exec_context_done(ExecContext *c) {
c->pam_name = mfree(c->pam_name);
- if (c->capabilities) {
- cap_free(c->capabilities);
- c->capabilities = NULL;
- }
-
c->read_only_dirs = strv_free(c->read_only_dirs);
c->read_write_dirs = strv_free(c->read_write_dirs);
c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
@@ -2214,9 +2152,6 @@ void exec_context_done(ExecContext *c) {
c->address_families = set_free(c->address_families);
c->runtime_directory = strv_free(c->runtime_directory);
-
- bus_endpoint_free(c->bus_endpoint);
- c->bus_endpoint = NULL;
}
int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
@@ -2306,7 +2241,7 @@ int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
if (fn[0] == '-') {
ignore = true;
- fn ++;
+ fn++;
}
if (!path_is_absolute(fn)) {
@@ -2559,14 +2494,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
prefix, strna(lvl_str));
}
- if (c->capabilities) {
- _cleanup_cap_free_charp_ char *t;
-
- t = cap_to_text(c->capabilities, NULL);
- if (t)
- fprintf(f, "%sCapabilities: %s\n", prefix, t);
- }
-
if (c->secure_bits)
fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
prefix,
diff --git a/src/libcore/execute.h b/src/libcore/execute.h
index 578f85b6bc..41148bcea2 100644
--- a/src/libcore/execute.h
+++ b/src/libcore/execute.h
@@ -30,7 +30,6 @@ typedef struct ExecParameters ExecParameters;
#include <stdio.h>
#include <sys/capability.h>
-#include "bus-endpoint.h"
#include "fdset.h"
#include "list.h"
#include "missing.h"
@@ -156,10 +155,7 @@ struct ExecContext {
unsigned long mount_flags;
uint64_t capability_bounding_set;
-
uint64_t capability_ambient_set;
-
- cap_t capabilities;
int secure_bits;
int syslog_priority;
@@ -201,9 +197,6 @@ struct ExecContext {
bool ioprio_set:1;
bool cpu_sched_set:1;
bool no_new_privileges_set:1;
-
- /* custom dbus enpoint */
- BusEndpoint *bus_endpoint;
};
#include "cgroup-util.h"
@@ -234,9 +227,6 @@ struct ExecParameters {
int *idle_pipe;
- char *bus_endpoint_path;
- int bus_endpoint_fd;
-
int stdin_fd;
int stdout_fd;
int stderr_fd;
diff --git a/src/libcore/failure-action.c b/src/libcore/failure-action.c
index 39f5519ca1..ddae46190f 100644
--- a/src/libcore/failure-action.c
+++ b/src/libcore/failure-action.c
@@ -47,7 +47,7 @@ int failure_action(
if (action == FAILURE_ACTION_NONE)
return -ECANCELED;
- if (m->running_as == MANAGER_USER) {
+ if (!MANAGER_IS_SYSTEM(m)) {
/* Downgrade all options to simply exiting if we run
* in user mode */
@@ -61,16 +61,17 @@ int failure_action(
case FAILURE_ACTION_REBOOT:
log_and_status(m, "Rebooting as result of failure.");
- update_reboot_param_file(reboot_arg);
- (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, NULL);
+ (void) update_reboot_parameter_and_warn(reboot_arg);
+ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
break;
case FAILURE_ACTION_REBOOT_FORCE:
log_and_status(m, "Forcibly rebooting as result of failure.");
- update_reboot_param_file(reboot_arg);
+ (void) update_reboot_parameter_and_warn(reboot_arg);
m->exit_code = MANAGER_REBOOT;
+
break;
case FAILURE_ACTION_REBOOT_IMMEDIATE:
@@ -78,9 +79,10 @@ int failure_action(
sync();
- if (reboot_arg) {
+ if (!isempty(reboot_arg)) {
log_info("Rebooting with argument '%s'.", reboot_arg);
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg);
+ log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
}
log_info("Rebooting.");
@@ -89,7 +91,7 @@ int failure_action(
case FAILURE_ACTION_POWEROFF:
log_and_status(m, "Powering off as result of failure.");
- (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, NULL);
+ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
break;
case FAILURE_ACTION_POWEROFF_FORCE:
diff --git a/src/libcore/ima-setup.c b/src/libcore/ima-setup.c
index ff7558d500..d1b0ce76ef 100644
--- a/src/libcore/ima-setup.c
+++ b/src/libcore/ima-setup.c
@@ -3,7 +3,7 @@
Copyright 2010 Lennart Poettering
Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy
- TORSEC group -- http://security.polito.it
+ TORSEC group — http://security.polito.it
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
diff --git a/src/libcore/ima-setup.h b/src/libcore/ima-setup.h
index 3bad74b246..472b58cb00 100644
--- a/src/libcore/ima-setup.h
+++ b/src/libcore/ima-setup.h
@@ -5,7 +5,7 @@
Copyright 2010 Lennart Poettering
Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy
- TORSEC group -- http://security.polito.it
+ TORSEC group — http://security.polito.it
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
diff --git a/src/libcore/job.c b/src/libcore/job.c
index 1e2f12bba0..42fdcb988a 100644
--- a/src/libcore/job.c
+++ b/src/libcore/job.c
@@ -137,7 +137,7 @@ void job_uninstall(Job *j) {
/* Detach from next 'bigger' objects */
/* daemon-reload should be transparent to job observers */
- if (j->manager->n_reloading <= 0)
+ if (!MANAGER_IS_RELOADING(j->manager))
bus_job_send_removed_signal(j);
*pj = NULL;
@@ -191,7 +191,7 @@ Job* job_install(Job *j) {
if (uj) {
if (job_type_is_conflicting(uj->type, j->type))
- job_finish_and_invalidate(uj, JOB_CANCELED, false);
+ job_finish_and_invalidate(uj, JOB_CANCELED, false, false);
else {
/* not conflicting, i.e. mergeable */
@@ -222,7 +222,7 @@ Job* job_install(Job *j) {
*pj = j;
j->installed = true;
- j->manager->n_installed_jobs ++;
+ j->manager->n_installed_jobs++;
log_unit_debug(j->unit,
"Installed new job %s/%s as %u",
j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
@@ -614,19 +614,19 @@ int job_run_and_invalidate(Job *j) {
if (j) {
if (r == -EALREADY)
- r = job_finish_and_invalidate(j, JOB_DONE, true);
+ r = job_finish_and_invalidate(j, JOB_DONE, true, true);
else if (r == -EBADR)
- r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
+ r = job_finish_and_invalidate(j, JOB_SKIPPED, true, false);
else if (r == -ENOEXEC)
- r = job_finish_and_invalidate(j, JOB_INVALID, true);
+ r = job_finish_and_invalidate(j, JOB_INVALID, true, false);
else if (r == -EPROTO)
- r = job_finish_and_invalidate(j, JOB_ASSERT, true);
+ r = job_finish_and_invalidate(j, JOB_ASSERT, true, false);
else if (r == -EOPNOTSUPP)
- r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true);
+ r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true, false);
else if (r == -EAGAIN)
job_set_state(j, JOB_WAITING);
else if (r < 0)
- r = job_finish_and_invalidate(j, JOB_FAILED, true);
+ r = job_finish_and_invalidate(j, JOB_FAILED, true, false);
}
return r;
@@ -645,7 +645,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
[JOB_DONE] = "Stopped %s.",
[JOB_FAILED] = "Stopped (with error) %s.",
- [JOB_TIMEOUT] = "Timed out stoppping %s.",
+ [JOB_TIMEOUT] = "Timed out stopping %s.",
};
static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = {
[JOB_DONE] = "Reloaded %s.",
@@ -690,17 +690,20 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
}
static void job_print_status_message(Unit *u, JobType t, JobResult result) {
- static const char* const job_result_status_table[_JOB_RESULT_MAX] = {
- [JOB_DONE] = ANSI_GREEN " OK " ANSI_NORMAL,
- [JOB_TIMEOUT] = ANSI_HIGHLIGHT_RED " TIME " ANSI_NORMAL,
- [JOB_FAILED] = ANSI_HIGHLIGHT_RED "FAILED" ANSI_NORMAL,
- [JOB_DEPENDENCY] = ANSI_HIGHLIGHT_YELLOW "DEPEND" ANSI_NORMAL,
- [JOB_SKIPPED] = ANSI_HIGHLIGHT " INFO " ANSI_NORMAL,
- [JOB_ASSERT] = ANSI_HIGHLIGHT_YELLOW "ASSERT" ANSI_NORMAL,
- [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW "UNSUPP" ANSI_NORMAL,
+ static struct {
+ const char *color, *word;
+ } const statuses[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = {ANSI_GREEN, " OK "},
+ [JOB_TIMEOUT] = {ANSI_HIGHLIGHT_RED, " TIME "},
+ [JOB_FAILED] = {ANSI_HIGHLIGHT_RED, "FAILED"},
+ [JOB_DEPENDENCY] = {ANSI_HIGHLIGHT_YELLOW, "DEPEND"},
+ [JOB_SKIPPED] = {ANSI_HIGHLIGHT, " INFO "},
+ [JOB_ASSERT] = {ANSI_HIGHLIGHT_YELLOW, "ASSERT"},
+ [JOB_UNSUPPORTED] = {ANSI_HIGHLIGHT_YELLOW, "UNSUPP"},
};
const char *format;
+ const char *status;
assert(u);
assert(t >= 0);
@@ -714,11 +717,16 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
if (!format)
return;
+ if (log_get_show_color())
+ status = strjoina(statuses[result].color, statuses[result].word, ANSI_NORMAL);
+ else
+ status = statuses[result].word;
+
if (result != JOB_DONE)
manager_flip_auto_status(u->manager, true);
DISABLE_WARNING_FORMAT_NONLITERAL;
- unit_status_printf(u, job_result_status_table[result], format);
+ unit_status_printf(u, status, format);
REENABLE_WARNING;
if (t == JOB_START && result == JOB_FAILED) {
@@ -819,11 +827,11 @@ static void job_fail_dependencies(Unit *u, UnitDependency d) {
if (!IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE))
continue;
- job_finish_and_invalidate(j, JOB_DEPENDENCY, true);
+ job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
}
}
-int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
+int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
Unit *u;
Unit *other;
JobType t;
@@ -840,7 +848,9 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
log_unit_debug(u, "Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result));
- job_emit_status_message(u, t, result);
+ /* If this job did nothing to respective unit we don't log the status message */
+ if (!already)
+ job_emit_status_message(u, t, result);
job_add_to_dbus_queue(j);
@@ -856,7 +866,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
}
if (result == JOB_FAILED || result == JOB_INVALID)
- j->manager->n_failed_jobs ++;
+ j->manager->n_failed_jobs++;
job_uninstall(j);
job_free(j);
@@ -915,7 +925,7 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user
log_unit_warning(j->unit, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
u = j->unit;
- job_finish_and_invalidate(j, JOB_TIMEOUT, true);
+ job_finish_and_invalidate(j, JOB_TIMEOUT, true, false);
failure_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg);
@@ -1148,7 +1158,7 @@ void job_shutdown_magic(Job *j) {
if (j->type != JOB_START)
return;
- if (j->unit->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(j->unit->manager))
return;
if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
diff --git a/src/libcore/job.h b/src/libcore/job.h
index de130303d2..68c2089b91 100644
--- a/src/libcore/job.h
+++ b/src/libcore/job.h
@@ -219,7 +219,7 @@ void job_add_to_dbus_queue(Job *j);
int job_start_timer(Job *j);
int job_run_and_invalidate(Job *j);
-int job_finish_and_invalidate(Job *j, JobResult result, bool recursive);
+int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already);
char *job_dbus_path(Job *j);
diff --git a/src/libcore/load-dropin.c b/src/libcore/load-dropin.c
index 22b71b6f5e..f83fa09301 100644
--- a/src/libcore/load-dropin.c
+++ b/src/libcore/load-dropin.c
@@ -44,6 +44,7 @@ static int add_dependency_consumer(
}
int unit_load_dropin(Unit *u) {
+ _cleanup_strv_free_ char **l = NULL;
Iterator i;
char *t, **f;
int r;
@@ -55,7 +56,7 @@ int unit_load_dropin(Unit *u) {
SET_FOREACH(t, u->names, i) {
char **p;
- STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
+ STRV_FOREACH(p, u->manager->lookup_paths.search_path) {
unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".wants", UNIT_WANTS,
add_dependency_consumer, u, NULL);
unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".requires", UNIT_REQUIRES,
@@ -63,11 +64,19 @@ int unit_load_dropin(Unit *u) {
}
}
- u->dropin_paths = strv_free(u->dropin_paths);
- r = unit_find_dropin_paths(u, &u->dropin_paths);
+ r = unit_find_dropin_paths(u, &l);
if (r <= 0)
return 0;
+ if (!u->dropin_paths) {
+ u->dropin_paths = l;
+ l = NULL;
+ } else {
+ r = strv_extend_strv(&u->dropin_paths, l, true);
+ if (r < 0)
+ return log_oom();
+ }
+
STRV_FOREACH(f, u->dropin_paths) {
config_parse(u->id, *f, NULL,
UNIT_VTABLE(u)->sections,
diff --git a/src/libcore/load-dropin.h b/src/libcore/load-dropin.h
index d8a4aefbb3..942d26724e 100644
--- a/src/libcore/load-dropin.h
+++ b/src/libcore/load-dropin.h
@@ -25,7 +25,7 @@
/* Read service data supplementary drop-in directories */
static inline int unit_find_dropin_paths(Unit *u, char ***paths) {
- return unit_file_find_dropin_paths(u->manager->lookup_paths.unit_path,
+ return unit_file_find_dropin_paths(u->manager->lookup_paths.search_path,
u->manager->unit_path_cache,
u->names,
paths);
diff --git a/src/libcore/load-fragment-gperf.gperf.m4 b/src/libcore/load-fragment-gperf.gperf.m4
index 5024fd19a5..8193418980 100644
--- a/src/libcore/load-fragment-gperf.gperf.m4
+++ b/src/libcore/load-fragment-gperf.gperf.m4
@@ -45,7 +45,7 @@ $1.SyslogIdentifier, config_parse_unit_string_printf, 0,
$1.SyslogFacility, config_parse_log_facility, 0, offsetof($1, exec_context.syslog_priority)
$1.SyslogLevel, config_parse_log_level, 0, offsetof($1, exec_context.syslog_priority)
$1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix)
-$1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context)
+$1.Capabilities, config_parse_warn_compat, DISABLED_LEGACY, offsetof($1, exec_context)
$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context)
$1.CapabilityBoundingSet, config_parse_capability_set, 0, offsetof($1, exec_context.capability_bounding_set)
$1.AmbientCapabilities, config_parse_capability_set, 0, offsetof($1, exec_context.capability_ambient_set)
@@ -120,6 +120,14 @@ $1.MemoryAccounting, config_parse_bool, 0,
$1.MemoryLimit, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
$1.DeviceAllow, config_parse_device_allow, 0, offsetof($1, cgroup_context)
$1.DevicePolicy, config_parse_device_policy, 0, offsetof($1, cgroup_context.device_policy)
+$1.IOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.io_accounting)
+$1.IOWeight, config_parse_io_weight, 0, offsetof($1, cgroup_context.io_weight)
+$1.StartupIOWeight, config_parse_io_weight, 0, offsetof($1, cgroup_context.startup_io_weight)
+$1.IODeviceWeight, config_parse_io_device_weight, 0, offsetof($1, cgroup_context)
+$1.IOReadBandwidthMax, config_parse_io_limit, 0, offsetof($1, cgroup_context)
+$1.IOWriteBandwidthMax, config_parse_io_limit, 0, offsetof($1, cgroup_context)
+$1.IOReadIOPSMax, config_parse_io_limit, 0, offsetof($1, cgroup_context)
+$1.IOWriteIOPSMax, config_parse_io_limit, 0, offsetof($1, cgroup_context)
$1.BlockIOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.blockio_accounting)
$1.BlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context.blockio_weight)
$1.StartupBlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context.startup_blockio_weight)
@@ -164,6 +172,8 @@ Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LE
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
Unit.JobTimeoutAction, config_parse_failure_action, 0, offsetof(Unit, job_timeout_action)
Unit.JobTimeoutRebootArgument, config_parse_string, 0, offsetof(Unit, job_timeout_reboot_arg)
+Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
+m4_dnl The following is a legacy alias name for compatibility
Unit.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
Unit.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action)
@@ -220,6 +230,7 @@ Service.TimeoutStartSec, config_parse_service_timeout, 0,
Service.TimeoutStopSec, config_parse_service_timeout, 0, 0
Service.RuntimeMaxSec, config_parse_sec, 0, offsetof(Service, runtime_max_usec)
Service.WatchdogSec, config_parse_sec, 0, offsetof(Service, watchdog_usec)
+m4_dnl The following three only exist for compatibility, they moved into Unit, see above
Service.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
Service.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action)
@@ -240,7 +251,7 @@ Service.BusName, config_parse_bus_name, 0,
Service.FileDescriptorStoreMax, config_parse_unsigned, 0, offsetof(Service, n_fd_store_max)
Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access)
Service.Sockets, config_parse_service_sockets, 0, 0
-Service.BusPolicy, config_parse_bus_endpoint_policy, 0, offsetof(Service, exec_context)
+Service.BusPolicy, config_parse_warn_compat, DISABLED_LEGACY, 0
Service.USBFunctionDescriptors, config_parse_path, 0, offsetof(Service, usb_function_descriptors)
Service.USBFunctionStrings, config_parse_path, 0, offsetof(Service, usb_function_strings)
EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
@@ -297,6 +308,8 @@ Socket.RemoveOnStop, config_parse_bool, 0,
Socket.Symlinks, config_parse_unit_path_strv_printf, 0, offsetof(Socket, symlinks)
Socket.FileDescriptorName, config_parse_fdname, 0, 0
Socket.Service, config_parse_socket_service, 0, 0
+Socket.TriggerLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, trigger_limit.interval)
+Socket.TriggerLimitBurst, config_parse_unsigned, 0, offsetof(Socket, trigger_limit.burst)
m4_ifdef(`HAVE_SMACK',
`Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack)
Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in)
diff --git a/src/libcore/load-fragment.c b/src/libcore/load-fragment.c
index 8804b3ac41..86b4fb071b 100644
--- a/src/libcore/load-fragment.c
+++ b/src/libcore/load-fragment.c
@@ -119,7 +119,7 @@ int config_parse_unit_deps(
assert(rvalue);
p = rvalue;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *word = NULL, *k = NULL;
int r;
@@ -620,7 +620,7 @@ int config_parse_exec(
separate_argv0 = true;
else
break;
- f ++;
+ f++;
}
if (isempty(f)) {
@@ -668,7 +668,7 @@ int config_parse_exec(
/* Check explicitly for an unquoted semicolon as
* command separator token. */
if (p[0] == ';' && (!p[1] || strchr(WHITESPACE, p[1]))) {
- p ++;
+ p++;
p += strspn(p, WHITESPACE);
semicolon = true;
break;
@@ -732,16 +732,17 @@ int config_parse_exec(
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
-int config_parse_socket_bindtodevice(const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_socket_bindtodevice(
+ const char* unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
Socket *s = data;
char *n;
@@ -752,6 +753,11 @@ int config_parse_socket_bindtodevice(const char* unit,
assert(data);
if (rvalue[0] && !streq(rvalue, "*")) {
+ if (!ifname_valid(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is invalid, ignoring: %s", rvalue);
+ return 0;
+ }
+
n = strdup(rvalue);
if (!n)
return log_oom();
@@ -942,38 +948,6 @@ int config_parse_exec_cpu_affinity(const char *unit,
return 0;
}
-int config_parse_exec_capabilities(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ExecContext *c = data;
- cap_t cap;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- cap = cap_from_text(rvalue);
- if (!cap) {
- log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse capabilities, ignoring: %s", rvalue);
- return 0;
- }
-
- if (c->capabilities)
- cap_free(c->capabilities);
- c->capabilities = cap;
-
- return 0;
-}
-
int config_parse_exec_secure_bits(const char *unit,
const char *filename,
unsigned line,
@@ -1631,7 +1605,7 @@ int config_parse_service_sockets(
assert(data);
p = rvalue;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *word = NULL, *k = NULL;
r = extract_first_word(&p, &word, NULL, 0);
@@ -1893,59 +1867,6 @@ int config_parse_bus_policy(
return 0;
}
-int config_parse_bus_endpoint_policy(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- _cleanup_free_ char *name = NULL;
- BusPolicyAccess access;
- ExecContext *c = data;
- char *access_str;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- name = strdup(rvalue);
- if (!name)
- return log_oom();
-
- access_str = strpbrk(name, WHITESPACE);
- if (!access_str) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid endpoint policy value '%s'", rvalue);
- return 0;
- }
-
- *access_str = '\0';
- access_str++;
- access_str += strspn(access_str, WHITESPACE);
-
- access = bus_policy_access_from_string(access_str);
- if (access <= _BUS_POLICY_ACCESS_INVALID ||
- access >= _BUS_POLICY_ACCESS_MAX) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid endpoint policy access type '%s'", access_str);
- return 0;
- }
-
- if (!c->bus_endpoint) {
- r = bus_endpoint_new(&c->bus_endpoint);
- if (r < 0)
- return log_error_errno(r, "Failed to create bus endpoint object: %m");
- }
-
- return bus_endpoint_add_policy(c->bus_endpoint, name, access);
-}
-
int config_parse_working_directory(
const char *unit,
const char *filename,
@@ -2580,7 +2501,7 @@ int config_parse_syscall_filter(
/* Turn on NNP, but only if it wasn't configured explicitly
* before, and only if we are in user mode. */
- if (!c->no_new_privileges_set && u->manager->running_as == MANAGER_USER)
+ if (!c->no_new_privileges_set && MANAGER_IS_USER(u->manager))
c->no_new_privileges = true;
return 0;
@@ -2932,11 +2853,12 @@ int config_parse_device_allow(
void *data,
void *userdata) {
- _cleanup_free_ char *path = NULL;
+ _cleanup_free_ char *path = NULL, *t = NULL;
CGroupContext *c = data;
CGroupDeviceAllow *a;
- const char *m;
+ const char *m = NULL;
size_t n;
+ int r;
if (isempty(rvalue)) {
while (c->device_allow)
@@ -2945,8 +2867,16 @@ int config_parse_device_allow(
return 0;
}
- n = strcspn(rvalue, WHITESPACE);
- path = strndup(rvalue, n);
+ r = unit_full_printf(userdata, rvalue, &t);
+ if(r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to resolve specifiers in %s, ignoring: %m",
+ rvalue);
+ }
+
+ n = strcspn(t, WHITESPACE);
+
+ path = strndup(t, n);
if (!path)
return log_oom();
@@ -2957,7 +2887,7 @@ int config_parse_device_allow(
return 0;
}
- m = rvalue + n + strspn(rvalue + n, WHITESPACE);
+ m = t + n + strspn(t + n, WHITESPACE);
if (isempty(m))
m = "rwm";
@@ -2980,6 +2910,193 @@ int config_parse_device_allow(
return 0;
}
+int config_parse_io_weight(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ uint64_t *weight = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = cg_weight_parse(rvalue, weight);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid. Ignoring.", rvalue);
+ return 0;
+ }
+
+ return 0;
+}
+
+int config_parse_io_device_weight(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ _cleanup_free_ char *path = NULL;
+ CGroupIODeviceWeight *w;
+ CGroupContext *c = data;
+ const char *weight;
+ uint64_t u;
+ size_t n;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ if (isempty(rvalue)) {
+ while (c->io_device_weights)
+ cgroup_context_free_io_device_weight(c, c->io_device_weights);
+
+ return 0;
+ }
+
+ n = strcspn(rvalue, WHITESPACE);
+ weight = rvalue + n;
+ weight += strspn(weight, WHITESPACE);
+
+ if (isempty(weight)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Expected block device and device weight. Ignoring.");
+ return 0;
+ }
+
+ path = strndup(rvalue, n);
+ if (!path)
+ return log_oom();
+
+ if (!path_startswith(path, "/dev")) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+ return 0;
+ }
+
+ r = cg_weight_parse(weight, &u);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid. Ignoring.", weight);
+ return 0;
+ }
+
+ assert(u != CGROUP_WEIGHT_INVALID);
+
+ w = new0(CGroupIODeviceWeight, 1);
+ if (!w)
+ return log_oom();
+
+ w->path = path;
+ path = NULL;
+
+ w->weight = u;
+
+ LIST_PREPEND(device_weights, c->io_device_weights, w);
+ return 0;
+}
+
+int config_parse_io_limit(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ _cleanup_free_ char *path = NULL;
+ CGroupIODeviceLimit *l = NULL, *t;
+ CGroupContext *c = data;
+ CGroupIOLimitType type;
+ const char *limit;
+ uint64_t num;
+ size_t n;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ type = cgroup_io_limit_type_from_string(lvalue);
+ assert(type >= 0);
+
+ if (isempty(rvalue)) {
+ LIST_FOREACH(device_limits, l, c->io_device_limits)
+ l->limits[type] = cgroup_io_limit_defaults[type];
+ return 0;
+ }
+
+ n = strcspn(rvalue, WHITESPACE);
+ limit = rvalue + n;
+ limit += strspn(limit, WHITESPACE);
+
+ if (!*limit) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Expected space separated pair of device node and bandwidth. Ignoring.");
+ return 0;
+ }
+
+ path = strndup(rvalue, n);
+ if (!path)
+ return log_oom();
+
+ if (!path_startswith(path, "/dev")) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+ return 0;
+ }
+
+ if (streq("max", limit)) {
+ num = CGROUP_LIMIT_MAX;
+ } else {
+ r = parse_size(limit, 1000, &num);
+ if (r < 0 || num <= 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "IO Limit '%s' invalid. Ignoring.", rvalue);
+ return 0;
+ }
+ }
+
+ LIST_FOREACH(device_limits, t, c->io_device_limits) {
+ if (path_equal(path, t->path)) {
+ l = t;
+ break;
+ }
+ }
+
+ if (!l) {
+ CGroupIOLimitType ttype;
+
+ l = new0(CGroupIODeviceLimit, 1);
+ if (!l)
+ return log_oom();
+
+ l->path = path;
+ path = NULL;
+ for (ttype = 0; ttype < _CGROUP_IO_LIMIT_TYPE_MAX; ttype++)
+ l->limits[ttype] = cgroup_io_limit_defaults[ttype];
+
+ LIST_PREPEND(device_limits, c->io_device_limits, l);
+ }
+
+ l->limits[type] = num;
+
+ return 0;
+}
+
int config_parse_blockio_weight(
const char *unit,
const char *filename,
@@ -3091,7 +3208,7 @@ int config_parse_blockio_bandwidth(
void *userdata) {
_cleanup_free_ char *path = NULL;
- CGroupBlockIODeviceBandwidth *b;
+ CGroupBlockIODeviceBandwidth *b = NULL, *t;
CGroupContext *c = data;
const char *bandwidth;
uint64_t bytes;
@@ -3106,12 +3223,10 @@ int config_parse_blockio_bandwidth(
read = streq("BlockIOReadBandwidth", lvalue);
if (isempty(rvalue)) {
- CGroupBlockIODeviceBandwidth *next;
-
- LIST_FOREACH_SAFE (device_bandwidths, b, next, c->blockio_device_bandwidths)
- if (b->read == read)
- cgroup_context_free_blockio_device_bandwidth(c, b);
-
+ LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
+ b->rbps = CGROUP_LIMIT_MAX;
+ b->wbps = CGROUP_LIMIT_MAX;
+ }
return 0;
}
@@ -3139,16 +3254,30 @@ int config_parse_blockio_bandwidth(
return 0;
}
- b = new0(CGroupBlockIODeviceBandwidth, 1);
- if (!b)
- return log_oom();
+ LIST_FOREACH(device_bandwidths, t, c->blockio_device_bandwidths) {
+ if (path_equal(path, t->path)) {
+ b = t;
+ break;
+ }
+ }
- b->path = path;
- path = NULL;
- b->bandwidth = bytes;
- b->read = read;
+ if (!t) {
+ b = new0(CGroupBlockIODeviceBandwidth, 1);
+ if (!b)
+ return log_oom();
- LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, b);
+ b->path = path;
+ path = NULL;
+ b->rbps = CGROUP_LIMIT_MAX;
+ b->wbps = CGROUP_LIMIT_MAX;
+
+ LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, b);
+ }
+
+ if (read)
+ b->rbps = bytes;
+ else
+ b->wbps = bytes;
return 0;
}
@@ -3446,7 +3575,7 @@ int config_parse_protect_home(
ProtectHome h;
h = protect_home_from_string(rvalue);
- if (h < 0){
+ if (h < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue);
return 0;
}
@@ -3489,7 +3618,7 @@ int config_parse_protect_system(
ProtectSystem s;
s = protect_system_from_string(rvalue);
- if (s < 0){
+ if (s < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue);
return 0;
}
@@ -3503,10 +3632,10 @@ int config_parse_protect_system(
#define FOLLOW_MAX 8
static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
+ char *id = NULL;
unsigned c = 0;
int fd, r;
FILE *f;
- char *id = NULL;
assert(filename);
assert(*filename);
@@ -3528,7 +3657,6 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
* the names of this unit, but only if it is a valid
* unit name. */
name = basename(*filename);
-
if (unit_name_is_valid(name, UNIT_NAME_ANY)) {
id = set_get(names, name);
@@ -3568,6 +3696,7 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
*_f = f;
*_final = id;
+
return 0;
}
@@ -3592,7 +3721,19 @@ static int merge_by_names(Unit **u, Set *names, const char *id) {
* ours? Then let's try it the other way
* round */
- other = manager_get_unit((*u)->manager, k);
+ /* If the symlink name we are looking at is unit template, then
+ we must search for instance of this template */
+ if (unit_name_is_valid(k, UNIT_NAME_TEMPLATE)) {
+ _cleanup_free_ char *instance = NULL;
+
+ r = unit_name_replace_instance(k, (*u)->instance, &instance);
+ if (r < 0)
+ return r;
+
+ other = manager_get_unit((*u)->manager, instance);
+ } else
+ other = manager_get_unit((*u)->manager, k);
+
free(k);
if (other) {
@@ -3616,13 +3757,13 @@ static int merge_by_names(Unit **u, Set *names, const char *id) {
}
static int load_from_path(Unit *u, const char *path) {
- int r;
_cleanup_set_free_free_ Set *symlink_names = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *filename = NULL;
char *id = NULL;
Unit *merged;
struct stat st;
+ int r;
assert(u);
assert(path);
@@ -3647,7 +3788,7 @@ static int load_from_path(Unit *u, const char *path) {
} else {
char **p;
- STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
+ STRV_FOREACH(p, u->manager->lookup_paths.search_path) {
/* Instead of opening the path right away, we manually
* follow all symlinks and add their name to our unit
@@ -3661,18 +3802,14 @@ static int load_from_path(Unit *u, const char *path) {
r = -ENOENT;
else
r = open_follow(&filename, &f, symlink_names, &id);
+ if (r >= 0)
+ break;
+ filename = mfree(filename);
+ if (r != -ENOENT)
+ return r;
- if (r < 0) {
- filename = mfree(filename);
- if (r != -ENOENT)
- return r;
-
- /* Empty the symlink names for the next run */
- set_clear_free(symlink_names);
- continue;
- }
-
- break;
+ /* Empty the symlink names for the next run */
+ set_clear_free(symlink_names);
}
}
@@ -3680,6 +3817,11 @@ static int load_from_path(Unit *u, const char *path) {
/* Hmm, no suitable file found? */
return 0;
+ if (!unit_type_may_alias(u->type) && set_size(symlink_names) > 1) {
+ log_unit_warning(u, "Unit type of %s does not support alias names, refusing loading via symlink.", u->id);
+ return -ELOOP;
+ }
+
merged = u;
r = merge_by_names(&merged, symlink_names, id);
if (r < 0)
@@ -3693,10 +3835,12 @@ static int load_from_path(Unit *u, const char *path) {
if (fstat(fileno(f), &st) < 0)
return -errno;
- if (null_or_empty(&st))
+ if (null_or_empty(&st)) {
u->load_state = UNIT_MASKED;
- else {
+ u->fragment_mtime = 0;
+ } else {
u->load_state = UNIT_LOADED;
+ u->fragment_mtime = timespec_load(&st.st_mtim);
/* Now, parse the file contents */
r = config_parse(u->id, filename, f,
@@ -3711,8 +3855,6 @@ static int load_from_path(Unit *u, const char *path) {
u->fragment_path = filename;
filename = NULL;
- u->fragment_mtime = timespec_load(&st.st_mtim);
-
if (u->source_path) {
if (stat(u->source_path, &st) >= 0)
u->source_mtime = timespec_load(&st.st_mtim);
@@ -3841,7 +3983,6 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_input, "INPUT" },
{ config_parse_log_facility, "FACILITY" },
{ config_parse_log_level, "LEVEL" },
- { config_parse_exec_capabilities, "CAPABILITIES" },
{ config_parse_exec_secure_bits, "SECUREBITS" },
{ config_parse_capability_set, "BOUNDINGSET" },
{ config_parse_limit, "LIMIT" },
@@ -3888,6 +4029,9 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_memory_limit, "LIMIT" },
{ config_parse_device_allow, "DEVICE" },
{ config_parse_device_policy, "POLICY" },
+ { config_parse_io_limit, "LIMIT" },
+ { config_parse_io_weight, "WEIGHT" },
+ { config_parse_io_device_weight, "DEVICEWEIGHT" },
{ config_parse_blockio_bandwidth, "BANDWIDTH" },
{ config_parse_blockio_weight, "WEIGHT" },
{ config_parse_blockio_device_weight, "DEVICEWEIGHT" },
diff --git a/src/libcore/load-fragment.h b/src/libcore/load-fragment.h
index 5fb5910919..b36a2e3a02 100644
--- a/src/libcore/load-fragment.h
+++ b/src/libcore/load-fragment.h
@@ -52,7 +52,6 @@ int config_parse_exec_io_priority(const char *unit, const char *filename, unsign
int config_parse_exec_cpu_sched_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_cpu_sched_prio(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_cpu_affinity(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_exec_capabilities(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_secure_bits(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_capability_set(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_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -67,7 +66,6 @@ int config_parse_service_sockets(const char *unit, const char *filename, unsigne
int config_parse_busname_service(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_bus_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_policy_world(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_bus_endpoint_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_env_file(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_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_condition_path(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);
@@ -88,6 +86,9 @@ int config_parse_memory_limit(const char *unit, const char *filename, unsigned l
int config_parse_tasks_max(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_device_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_device_allow(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_io_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_io_device_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_io_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_blockio_device_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_blockio_bandwidth(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/libcore/machine-id-setup.c b/src/libcore/machine-id-setup.c
index 30f27ffc67..812e4b038c 100644
--- a/src/libcore/machine-id-setup.c
+++ b/src/libcore/machine-id-setup.c
@@ -101,14 +101,23 @@ static int read_machine_id(int fd, char id[34]) {
return 0;
}
-static int write_machine_id(int fd, char id[34]) {
+static int write_machine_id(int fd, const char id[34]) {
+ int r;
+
assert(fd >= 0);
assert(id);
if (lseek(fd, 0, SEEK_SET) < 0)
return -errno;
- return loop_write(fd, id, 33, false);
+ r = loop_write(fd, id, 33, false);
+ if (r < 0)
+ return r;
+
+ if (fsync(fd) < 0)
+ return -errno;
+
+ return 0;
}
static int generate_machine_id(char id[34], const char *root) {
@@ -120,10 +129,7 @@ static int generate_machine_id(char id[34], const char *root) {
assert(id);
- if (isempty(root))
- dbus_machine_id = "/var/lib/dbus/machine-id";
- else
- dbus_machine_id = strjoina(root, "/var/lib/dbus/machine-id");
+ dbus_machine_id = prefix_roota(root, "/var/lib/dbus/machine-id");
/* First, try reading the D-Bus machine id, unless it is a symlink */
fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
@@ -203,18 +209,8 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) {
char id[34]; /* 32 + \n + \0 */
int r;
- if (isempty(root)) {
- etc_machine_id = "/etc/machine-id";
- run_machine_id = "/run/machine-id";
- } else {
- char *x;
-
- x = strjoina(root, "/etc/machine-id");
- etc_machine_id = path_kill_slashes(x);
-
- x = strjoina(root, "/run/machine-id");
- run_machine_id = path_kill_slashes(x);
- }
+ etc_machine_id = prefix_roota(root, "/etc/machine-id");
+ run_machine_id = prefix_roota(root, "/run/machine-id");
RUN_WITH_UMASK(0000) {
/* We create this 0444, to indicate that this isn't really
@@ -274,10 +270,10 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) {
RUN_WITH_UMASK(0022) {
r = write_string_file(run_machine_id, id, WRITE_STRING_FILE_CREATE);
- }
- if (r < 0) {
- (void) unlink(run_machine_id);
- return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
+ if (r < 0) {
+ (void) unlink(run_machine_id);
+ return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
+ }
}
/* And now, let's mount it over */
@@ -301,14 +297,7 @@ int machine_id_commit(const char *root) {
char id[34]; /* 32 + \n + \0 */
int r;
- if (isempty(root))
- etc_machine_id = "/etc/machine-id";
- else {
- char *x;
-
- x = strjoina(root, "/etc/machine-id");
- etc_machine_id = path_kill_slashes(x);
- }
+ etc_machine_id = prefix_roota(root, "/etc/machine-id");
r = path_is_mount_point(etc_machine_id, 0);
if (r < 0)
diff --git a/src/libcore/manager.c b/src/libcore/manager.c
index 9a34742cf6..831fdbaabf 100644
--- a/src/libcore/manager.c
+++ b/src/libcore/manager.c
@@ -49,6 +49,7 @@
#include "dbus-manager.h"
#include "dbus-unit.h"
#include "dbus.h"
+#include "dirent-util.h"
#include "env-util.h"
#include "escape.h"
#include "exit-status.h"
@@ -63,6 +64,7 @@
#include "manager.h"
#include "missing.h"
#include "mkdir.h"
+#include "mkdir.h"
#include "parse-util.h"
#include "path-lookup.h"
#include "path-util.h"
@@ -85,6 +87,7 @@
#include "watchdog.h"
#define NOTIFY_RCVBUF_SIZE (8*1024*1024)
+#define CGROUPS_AGENT_RCVBUF_SIZE (8*1024*1024)
/* Initial delay and the interval for printing status messages about running jobs */
#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
@@ -92,13 +95,13 @@
#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
+static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
static int manager_run_generators(Manager *m);
-static void manager_undo_generators(Manager *m);
static void manager_watch_jobs_in_progress(Manager *m) {
usec_t next;
@@ -483,15 +486,15 @@ static int manager_setup_signals(Manager *m) {
(void) sd_event_source_set_description(m->signal_event_source, "manager-signal");
- /* Process signals a bit earlier than the rest of things, but
- * later than notify_fd processing, so that the notify
- * processing can still figure out to which process/service a
- * message belongs, before we reap the process. */
- r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-5);
+ /* Process signals a bit earlier than the rest of things, but later than notify_fd processing, so that the
+ * notify processing can still figure out to which process/service a message belongs, before we reap the
+ * process. Also, process this before handling cgroup notifications, so that we always collect child exit
+ * status information before detecting that there's no process in a cgroup. */
+ r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-6);
if (r < 0)
return r;
- if (m->running_as == MANAGER_SYSTEM)
+ if (MANAGER_IS_SYSTEM(m))
return enable_special_signals(m);
return 0;
@@ -518,7 +521,7 @@ static void manager_clean_environment(Manager *m) {
static int manager_default_environment(Manager *m) {
assert(m);
- if (m->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(m)) {
/* The system manager always starts with a clean
* environment for its children. It does not import
* the kernel or the parents exported variables.
@@ -547,52 +550,45 @@ static int manager_default_environment(Manager *m) {
}
-int manager_new(ManagerRunningAs running_as, bool test_run, Manager **_m) {
-
- static const char * const unit_log_fields[_MANAGER_RUNNING_AS_MAX] = {
- [MANAGER_SYSTEM] = "UNIT=",
- [MANAGER_USER] = "USER_UNIT=",
- };
-
- static const char * const unit_log_format_strings[_MANAGER_RUNNING_AS_MAX] = {
- [MANAGER_SYSTEM] = "UNIT=%s",
- [MANAGER_USER] = "USER_UNIT=%s",
- };
-
+int manager_new(UnitFileScope scope, bool test_run, Manager **_m) {
Manager *m;
int r;
assert(_m);
- assert(running_as >= 0);
- assert(running_as < _MANAGER_RUNNING_AS_MAX);
+ assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER));
m = new0(Manager, 1);
if (!m)
return -ENOMEM;
-#ifdef ENABLE_EFI
- if (running_as == MANAGER_SYSTEM && detect_container() <= 0)
- boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
-#endif
-
- m->running_as = running_as;
+ m->unit_file_scope = scope;
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->default_timer_accuracy_usec = USEC_PER_MINUTE;
m->default_tasks_accounting = true;
m->default_tasks_max = UINT64_C(512);
+#ifdef ENABLE_EFI
+ if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
+ boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
+#endif
+
/* Prepare log fields we can use for structured logging */
- m->unit_log_field = unit_log_fields[running_as];
- m->unit_log_format_string = unit_log_format_strings[running_as];
+ if (MANAGER_IS_SYSTEM(m)) {
+ m->unit_log_field = "UNIT=";
+ m->unit_log_format_string = "UNIT=%s";
+ } else {
+ m->unit_log_field = "USER_UNIT=";
+ m->unit_log_format_string = "USER_UNIT=%s";
+ }
m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
- m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd =
- m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = m->cgroup_inotify_fd = -1;
+ m->pin_cgroupfs_fd = m->notify_fd = m->cgroups_agent_fd = m->signal_fd = m->time_change_fd =
+ m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = m->cgroup_inotify_fd =
+ m->ask_password_inotify_fd = -1;
m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
- m->ask_password_inotify_fd = -1;
m->have_ask_password = -EINVAL; /* we don't know */
m->first_boot = -1;
@@ -683,6 +679,7 @@ static int manager_setup_notify(Manager *m) {
.sa.sa_family = AF_UNIX,
};
static const int one = 1;
+ const char *e;
/* First free all secondary fields */
m->notify_socket = mfree(m->notify_socket);
@@ -694,19 +691,13 @@ static int manager_setup_notify(Manager *m) {
fd_inc_rcvbuf(fd, NOTIFY_RCVBUF_SIZE);
- if (m->running_as == MANAGER_SYSTEM)
- m->notify_socket = strdup("/run/systemd/notify");
- else {
- const char *e;
-
- e = getenv("XDG_RUNTIME_DIR");
- if (!e) {
- log_error_errno(errno, "XDG_RUNTIME_DIR is not set: %m");
- return -EINVAL;
- }
-
- m->notify_socket = strappend(e, "/systemd/notify");
+ e = manager_get_runtime_prefix(m);
+ if (!e) {
+ log_error("Failed to determine runtime prefix.");
+ return -EINVAL;
}
+
+ m->notify_socket = strappend(e, "/systemd/notify");
if (!m->notify_socket)
return log_oom();
@@ -714,7 +705,7 @@ static int manager_setup_notify(Manager *m) {
(void) unlink(m->notify_socket);
strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
- r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+ r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
@@ -733,8 +724,8 @@ static int manager_setup_notify(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to allocate notify event source: %m");
- /* Process signals a bit earlier than SIGCHLD, so that we can
- * still identify to which service an exit message belongs */
+ /* Process notification messages a bit earlier than SIGCHLD, so that we can still identify to which
+ * service an exit message belongs. */
r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-7);
if (r < 0)
return log_error_errno(r, "Failed to set priority of notify event source: %m");
@@ -745,6 +736,79 @@ static int manager_setup_notify(Manager *m) {
return 0;
}
+static int manager_setup_cgroups_agent(Manager *m) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/cgroups-agent",
+ };
+ int r;
+
+ /* This creates a listening socket we receive cgroups agent messages on. We do not use D-Bus for delivering
+ * these messages from the cgroups agent binary to PID 1, as the cgroups agent binary is very short-living, and
+ * each instance of it needs a new D-Bus connection. Since D-Bus connections are SOCK_STREAM/AF_UNIX, on
+ * overloaded systems the backlog of the D-Bus socket becomes relevant, as not more than the configured number
+ * of D-Bus connections may be queued until the kernel will start dropping further incoming connections,
+ * possibly resulting in lost cgroups agent messages. To avoid this, we'll use a private SOCK_DGRAM/AF_UNIX
+ * socket, where no backlog is relevant as communication may take place without an actual connect() cycle, and
+ * we thus won't lose messages.
+ *
+ * Note that PID 1 will forward the agent message to system bus, so that the user systemd instance may listen
+ * to it. The system instance hence listens on this special socket, but the user instances listen on the system
+ * bus for these messages. */
+
+ if (m->test_run)
+ return 0;
+
+ if (!MANAGER_IS_SYSTEM(m))
+ return 0;
+
+ if (cg_unified() > 0) /* We don't need this anymore on the unified hierarchy */
+ return 0;
+
+ if (m->cgroups_agent_fd < 0) {
+ _cleanup_close_ int fd = -1;
+
+ /* First free all secondary fields */
+ m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
+
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to allocate cgroups agent socket: %m");
+
+ fd_inc_rcvbuf(fd, CGROUPS_AGENT_RCVBUF_SIZE);
+
+ (void) unlink(sa.un.sun_path);
+
+ /* Only allow root to connect to this socket */
+ RUN_WITH_UMASK(0077)
+ r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
+ if (r < 0)
+ return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
+
+ m->cgroups_agent_fd = fd;
+ fd = -1;
+ }
+
+ if (!m->cgroups_agent_event_source) {
+ r = sd_event_add_io(m->event, &m->cgroups_agent_event_source, m->cgroups_agent_fd, EPOLLIN, manager_dispatch_cgroups_agent_fd, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate cgroups agent event source: %m");
+
+ /* Process cgroups notifications early, but after having processed service notification messages or
+ * SIGCHLD signals, so that a cgroup running empty is always just the last safety net of notification,
+ * and we collected the metadata the notification and SIGCHLD stuff offers first. Also see handling of
+ * cgroup inotify for the unified cgroup stuff. */
+ r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-5);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set priority of cgroups agent event source: %m");
+
+ (void) sd_event_source_set_description(m->cgroups_agent_event_source, "manager-cgroups-agent");
+ }
+
+ return 0;
+}
+
static int manager_setup_kdbus(Manager *m) {
_cleanup_free_ char *p = NULL;
@@ -756,8 +820,8 @@ static int manager_setup_kdbus(Manager *m) {
return -ESOCKTNOSUPPORT;
m->kdbus_fd = bus_kernel_create_bus(
- m->running_as == MANAGER_SYSTEM ? "system" : "user",
- m->running_as == MANAGER_SYSTEM, &p);
+ MANAGER_IS_SYSTEM(m) ? "system" : "user",
+ MANAGER_IS_SYSTEM(m), &p);
if (m->kdbus_fd < 0)
return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m");
@@ -778,7 +842,7 @@ static int manager_connect_bus(Manager *m, bool reexecuting) {
try_bus_connect =
m->kdbus_fd >= 0 ||
reexecuting ||
- (m->running_as == MANAGER_USER && getenv("DBUS_SESSION_BUS_ADDRESS"));
+ (MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS"));
/* Try to connect to the buses, if possible. */
return bus_init(m, try_bus_connect);
@@ -940,7 +1004,7 @@ Manager* manager_free(Manager *m) {
* around */
manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
- manager_undo_generators(m);
+ lookup_paths_flush_generator(&m->lookup_paths);
bus_done(m);
@@ -955,12 +1019,14 @@ Manager* manager_free(Manager *m) {
sd_event_source_unref(m->signal_event_source);
sd_event_source_unref(m->notify_event_source);
+ sd_event_source_unref(m->cgroups_agent_event_source);
sd_event_source_unref(m->time_change_event_source);
sd_event_source_unref(m->jobs_in_progress_event_source);
sd_event_source_unref(m->run_queue_event_source);
safe_close(m->signal_fd);
safe_close(m->notify_fd);
+ safe_close(m->cgroups_agent_fd);
safe_close(m->time_change_fd);
safe_close(m->kdbus_fd);
@@ -1037,7 +1103,6 @@ static void manager_coldplug(Manager *m) {
static void manager_build_unit_path_cache(Manager *m) {
char **i;
- _cleanup_closedir_ DIR *d = NULL;
int r;
assert(m);
@@ -1046,29 +1111,27 @@ static void manager_build_unit_path_cache(Manager *m) {
m->unit_path_cache = set_new(&string_hash_ops);
if (!m->unit_path_cache) {
- log_error("Failed to allocate unit path cache.");
- return;
+ r = -ENOMEM;
+ goto fail;
}
/* This simply builds a list of files we know exist, so that
* we don't always have to go to disk */
- STRV_FOREACH(i, m->lookup_paths.unit_path) {
+ STRV_FOREACH(i, m->lookup_paths.search_path) {
+ _cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
d = opendir(*i);
if (!d) {
if (errno != ENOENT)
- log_error_errno(errno, "Failed to open directory %s: %m", *i);
+ log_warning_errno(errno, "Failed to open directory %s, ignoring: %m", *i);
continue;
}
- while ((de = readdir(d))) {
+ FOREACH_DIRENT(de, d, r = -errno; goto fail) {
char *p;
- if (hidden_file(de->d_name))
- continue;
-
p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
if (!p) {
r = -ENOMEM;
@@ -1079,20 +1142,15 @@ static void manager_build_unit_path_cache(Manager *m) {
if (r < 0)
goto fail;
}
-
- d = safe_closedir(d);
}
return;
fail:
- log_error_errno(r, "Failed to build unit path cache: %m");
-
- set_free_free(m->unit_path_cache);
- m->unit_path_cache = NULL;
+ log_warning_errno(r, "Failed to build unit path cache, proceeding without: %m");
+ m->unit_path_cache = set_free_free(m->unit_path_cache);
}
-
static void manager_distribute_fds(Manager *m, FDSet *fds) {
Iterator i;
Unit *u;
@@ -1116,28 +1174,29 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
assert(m);
- dual_timestamp_get(&m->generators_start_timestamp);
- r = manager_run_generators(m);
- dual_timestamp_get(&m->generators_finish_timestamp);
+ r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
+ if (r < 0)
+ return r;
+
+ /* Make sure the transient directory always exists, so that it remains in the search path */
+ r = mkdir_p_label(m->lookup_paths.transient, 0755);
if (r < 0)
return r;
- r = lookup_paths_init(
- &m->lookup_paths, m->running_as, true,
- NULL,
- m->generator_unit_path,
- m->generator_unit_path_early,
- m->generator_unit_path_late);
+ dual_timestamp_get(&m->generators_start_timestamp);
+ r = manager_run_generators(m);
+ dual_timestamp_get(&m->generators_finish_timestamp);
if (r < 0)
return r;
+ lookup_paths_reduce(&m->lookup_paths);
manager_build_unit_path_cache(m);
/* If we will deserialize make sure that during enumeration
* this is already known, so we increase the counter here
* already */
if (serialization)
- m->n_reloading ++;
+ m->n_reloading++;
/* First, enumerate what we can from all config files */
dual_timestamp_get(&m->units_load_start_timestamp);
@@ -1160,6 +1219,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
if (q < 0 && r == 0)
r = q;
+ q = manager_setup_cgroups_agent(m);
+ if (q < 0 && r == 0)
+ r = q;
+
/* We might have deserialized the kdbus control fd, but if we
* didn't, then let's create the bus now. */
manager_setup_kdbus(m);
@@ -1171,7 +1234,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
if (serialization) {
assert(m->n_reloading > 0);
- m->n_reloading --;
+ m->n_reloading--;
/* Let's wait for the UnitNew/JobNew messages being
* sent, before we notify that the reload is
@@ -1333,8 +1396,12 @@ int manager_load_unit_prepare(
t = unit_name_to_type(name);
- if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
+ if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
+ if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
+ return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is missing the instance name.", name);
+
return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
+ }
ret = manager_get_unit(m, name);
if (ret) {
@@ -1427,7 +1494,7 @@ void manager_clear_jobs(Manager *m) {
while ((j = hashmap_first(m->jobs)))
/* No need to recurse. We're cancelling all jobs. */
- job_finish_and_invalidate(j, JOB_CANCELED, false);
+ job_finish_and_invalidate(j, JOB_CANCELED, false, false);
}
static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
@@ -1493,6 +1560,35 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
return n;
}
+static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+ Manager *m = userdata;
+ char buf[PATH_MAX+1];
+ ssize_t n;
+
+ n = recv(fd, buf, sizeof(buf), 0);
+ if (n < 0)
+ return log_error_errno(errno, "Failed to read cgroups agent message: %m");
+ if (n == 0) {
+ log_error("Got zero-length cgroups agent message, ignoring.");
+ return 0;
+ }
+ if ((size_t) n >= sizeof(buf)) {
+ log_error("Got overly long cgroups agent message, ignoring.");
+ return 0;
+ }
+
+ if (memchr(buf, 0, n)) {
+ log_error("Got cgroups agent message with embedded NUL byte, ignoring.");
+ return 0;
+ }
+ buf[n] = 0;
+
+ manager_notify_cgroup_empty(m, buf);
+ bus_forward_agent_released(m, buf);
+
+ return 0;
+}
+
static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, const char *buf, size_t n, FDSet *fds) {
_cleanup_strv_free_ char **tags = NULL;
@@ -1631,7 +1727,9 @@ static void invoke_sigchld_event(Manager *m, Unit *u, const siginfo_t *si) {
log_unit_debug(u, "Child "PID_FMT" belongs to %s", si->si_pid, u->id);
unit_unwatch_pid(u, si->si_pid);
- UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
+
+ if (UNIT_VTABLE(u)->sigchld_event)
+ UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
}
static int manager_dispatch_sigchld(Manager *m) {
@@ -1738,7 +1836,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
}
log_received_signal(sfsi.ssi_signo == SIGCHLD ||
- (sfsi.ssi_signo == SIGTERM && m->running_as == MANAGER_USER)
+ (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m))
? LOG_DEBUG : LOG_INFO,
&sfsi);
@@ -1749,7 +1847,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
break;
case SIGTERM:
- if (m->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(m)) {
/* This is for compatibility with the
* original sysvinit */
m->exit_code = MANAGER_REEXECUTE;
@@ -1759,7 +1857,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
/* Fall through */
case SIGINT:
- if (m->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(m)) {
/* If the user presses C-A-D more than
* 7 times within 2s, we reboot
@@ -1785,14 +1883,14 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
break;
case SIGWINCH:
- if (m->running_as == MANAGER_SYSTEM)
+ if (MANAGER_IS_SYSTEM(m))
manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
/* This is a nop on non-init */
break;
case SIGPWR:
- if (m->running_as == MANAGER_SYSTEM)
+ if (MANAGER_IS_SYSTEM(m))
manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
/* This is a nop on non-init */
@@ -1900,7 +1998,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
break;
case 24:
- if (m->running_as == MANAGER_USER) {
+ if (MANAGER_IS_USER(m)) {
m->exit_code = MANAGER_EXIT;
return 0;
}
@@ -2016,7 +2114,7 @@ int manager_loop(Manager *m) {
while (m->exit_code == MANAGER_OK) {
usec_t wait_usec;
- if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM)
+ if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m))
watchdog_ping();
if (!ratelimit_test(&rl)) {
@@ -2041,7 +2139,7 @@ int manager_loop(Manager *m) {
continue;
/* Sleep for half the watchdog time */
- if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) {
+ if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m)) {
wait_usec = m->runtime_watchdog / 2;
if (wait_usec <= 0)
wait_usec = 1;
@@ -2112,7 +2210,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
const char *msg;
int audit_fd, r;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return;
audit_fd = get_audit_fd();
@@ -2121,7 +2219,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
/* Don't generate audit events if the service was already
* started and we're just deserializing */
- if (m->n_reloading > 0)
+ if (MANAGER_IS_RELOADING(m))
return;
if (u->type != UNIT_SERVICE)
@@ -2147,18 +2245,17 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
}
void manager_send_unit_plymouth(Manager *m, Unit *u) {
- union sockaddr_union sa = PLYMOUTH_SOCKET;
-
- int n = 0;
+ static const union sockaddr_union sa = PLYMOUTH_SOCKET;
_cleanup_free_ char *message = NULL;
_cleanup_close_ int fd = -1;
+ int n = 0;
/* Don't generate plymouth events if the service was already
* started and we're just deserializing */
- if (m->n_reloading > 0)
+ if (MANAGER_IS_RELOADING(m))
return;
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return;
if (detect_container() > 0)
@@ -2177,7 +2274,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
return;
}
- if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
log_error_errno(errno, "connect() failed: %m");
@@ -2202,8 +2299,8 @@ int manager_open_serialization(Manager *m, FILE **_f) {
assert(_f);
- path = m->running_as == MANAGER_SYSTEM ? "/run/systemd" : "/tmp";
- fd = open_tmpfile(path, O_RDWR|O_CLOEXEC);
+ path = MANAGER_IS_SYSTEM(m) ? "/run/systemd" : "/tmp";
+ fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
if (fd < 0)
return -errno;
@@ -2231,7 +2328,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
assert(f);
assert(fds);
- m->n_reloading ++;
+ m->n_reloading++;
fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
@@ -2277,6 +2374,16 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
fprintf(f, "notify-socket=%s\n", m->notify_socket);
}
+ if (m->cgroups_agent_fd >= 0) {
+ int copy;
+
+ copy = fdset_put_dup(fds, m->cgroups_agent_fd);
+ if (copy < 0)
+ return copy;
+
+ fprintf(f, "cgroups-agent-fd=%i\n", copy);
+ }
+
if (m->kdbus_fd >= 0) {
int copy;
@@ -2301,13 +2408,13 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
r = unit_serialize(u, f, fds, !switching_root);
if (r < 0) {
- m->n_reloading --;
+ m->n_reloading--;
return r;
}
}
assert(m->n_reloading > 0);
- m->n_reloading --;
+ m->n_reloading--;
if (ferror(f))
return -EIO;
@@ -2327,7 +2434,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
log_debug("Deserializing state...");
- m->n_reloading ++;
+ m->n_reloading++;
for (;;) {
char line[LINE_MAX], *l;
@@ -2444,6 +2551,17 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
free(m->notify_socket);
m->notify_socket = n;
+ } else if (startswith(l, "cgroups-agent-fd=")) {
+ int fd;
+
+ if (safe_atoi(l + 17, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_debug("Failed to parse cgroups agent fd: %s", l + 10);
+ else {
+ m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
+ safe_close(m->cgroups_agent_fd);
+ m->cgroups_agent_fd = fdset_remove(fds, fd);
+ }
+
} else if (startswith(l, "kdbus-fd=")) {
int fd;
@@ -2495,7 +2613,7 @@ finish:
r = -EIO;
assert(m->n_reloading > 0);
- m->n_reloading --;
+ m->n_reloading--;
return r;
}
@@ -2511,45 +2629,41 @@ int manager_reload(Manager *m) {
if (r < 0)
return r;
- m->n_reloading ++;
+ m->n_reloading++;
bus_manager_send_reloading(m, true);
fds = fdset_new();
if (!fds) {
- m->n_reloading --;
+ m->n_reloading--;
return -ENOMEM;
}
r = manager_serialize(m, f, fds, false);
if (r < 0) {
- m->n_reloading --;
+ m->n_reloading--;
return r;
}
if (fseeko(f, 0, SEEK_SET) < 0) {
- m->n_reloading --;
+ m->n_reloading--;
return -errno;
}
/* From here on there is no way back. */
manager_clear_jobs_and_units(m);
- manager_undo_generators(m);
+ lookup_paths_flush_generator(&m->lookup_paths);
lookup_paths_free(&m->lookup_paths);
- /* Find new unit paths */
- q = manager_run_generators(m);
+ q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
if (q < 0 && r >= 0)
r = q;
- q = lookup_paths_init(
- &m->lookup_paths, m->running_as, true,
- NULL,
- m->generator_unit_path,
- m->generator_unit_path_early,
- m->generator_unit_path_late);
+ /* Find new unit paths */
+ q = manager_run_generators(m);
if (q < 0 && r >= 0)
r = q;
+ lookup_paths_reduce(&m->lookup_paths);
manager_build_unit_path_cache(m);
/* First, enumerate what we can from all config files */
@@ -2568,6 +2682,10 @@ int manager_reload(Manager *m) {
if (q < 0 && r >= 0)
r = q;
+ q = manager_setup_cgroups_agent(m);
+ if (q < 0 && r >= 0)
+ r = q;
+
/* Third, fire things up! */
manager_coldplug(m);
@@ -2583,12 +2701,6 @@ int manager_reload(Manager *m) {
return r;
}
-bool manager_is_reloading_or_reexecuting(Manager *m) {
- assert(m);
-
- return m->n_reloading != 0;
-}
-
void manager_reset_failed(Manager *m) {
Unit *u;
Iterator i;
@@ -2620,7 +2732,7 @@ static void manager_notify_finished(Manager *m) {
if (m->test_run)
return;
- if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0) {
+ if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) {
/* Note that m->kernel_usec.monotonic is always at 0,
* and m->firmware_usec.monotonic and
@@ -2685,7 +2797,7 @@ static void manager_notify_finished(Manager *m) {
void manager_check_finished(Manager *m) {
assert(m);
- if (m->n_reloading > 0)
+ if (MANAGER_IS_RELOADING(m))
return;
/* Verify that we are actually running currently. Initially
@@ -2726,77 +2838,6 @@ void manager_check_finished(Manager *m) {
manager_invalidate_startup_units(m);
}
-static int create_generator_dir(Manager *m, char **generator, const char *name) {
- char *p;
- int r;
-
- assert(m);
- assert(generator);
- assert(name);
-
- if (*generator)
- return 0;
-
- if (m->running_as == MANAGER_SYSTEM && getpid() == 1) {
- /* systemd --system, not running --test */
-
- p = strappend("/run/systemd/", name);
- if (!p)
- return log_oom();
-
- r = mkdir_p_label(p, 0755);
- if (r < 0) {
- log_error_errno(r, "Failed to create generator directory %s: %m", p);
- free(p);
- return r;
- }
- } else if (m->running_as == MANAGER_USER) {
- const char *s = NULL;
-
- s = getenv("XDG_RUNTIME_DIR");
- if (!s)
- return -EINVAL;
- p = strjoin(s, "/systemd/", name, NULL);
- if (!p)
- return log_oom();
-
- r = mkdir_p_label(p, 0755);
- if (r < 0) {
- log_error_errno(r, "Failed to create generator directory %s: %m", p);
- free(p);
- return r;
- }
- } else {
- /* systemd --system --test */
-
- p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
- if (!p)
- return log_oom();
-
- if (!mkdtemp(p)) {
- log_error_errno(errno, "Failed to create generator directory %s: %m", p);
- free(p);
- return -errno;
- }
- }
-
- *generator = p;
- return 0;
-}
-
-static void trim_generator_dir(Manager *m, char **generator) {
- assert(m);
- assert(generator);
-
- if (!*generator)
- return;
-
- if (rmdir(*generator) >= 0)
- *generator = mfree(*generator);
-
- return;
-}
-
static int manager_run_generators(Manager *m) {
_cleanup_strv_free_ char **paths = NULL;
const char *argv[5];
@@ -2808,71 +2849,40 @@ static int manager_run_generators(Manager *m) {
if (m->test_run)
return 0;
- paths = generator_paths(m->running_as);
+ paths = generator_binary_paths(m->unit_file_scope);
if (!paths)
return log_oom();
/* Optimize by skipping the whole process by not creating output directories
* if no generators are found. */
STRV_FOREACH(path, paths) {
- r = access(*path, F_OK);
- if (r == 0)
+ if (access(*path, F_OK) >= 0)
goto found;
if (errno != ENOENT)
log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
}
+
return 0;
found:
- r = create_generator_dir(m, &m->generator_unit_path, "generator");
- if (r < 0)
- goto finish;
-
- r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
- if (r < 0)
- goto finish;
-
- r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
+ r = lookup_paths_mkdir_generator(&m->lookup_paths);
if (r < 0)
goto finish;
argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
- argv[1] = m->generator_unit_path;
- argv[2] = m->generator_unit_path_early;
- argv[3] = m->generator_unit_path_late;
+ argv[1] = m->lookup_paths.generator;
+ argv[2] = m->lookup_paths.generator_early;
+ argv[3] = m->lookup_paths.generator_late;
argv[4] = NULL;
RUN_WITH_UMASK(0022)
execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv);
finish:
- trim_generator_dir(m, &m->generator_unit_path);
- trim_generator_dir(m, &m->generator_unit_path_early);
- trim_generator_dir(m, &m->generator_unit_path_late);
+ lookup_paths_trim_generator(&m->lookup_paths);
return r;
}
-static void remove_generator_dir(Manager *m, char **generator) {
- assert(m);
- assert(generator);
-
- if (!*generator)
- return;
-
- strv_remove(m->lookup_paths.unit_path, *generator);
- (void) rm_rf(*generator, REMOVE_ROOT);
-
- *generator = mfree(*generator);
-}
-
-static void manager_undo_generators(Manager *m) {
- assert(m);
-
- remove_generator_dir(m, &m->generator_unit_path);
- remove_generator_dir(m, &m->generator_unit_path_early);
- remove_generator_dir(m, &m->generator_unit_path_late);
-}
-
int manager_environment_add(Manager *m, char **minus, char **plus) {
char **a = NULL, **b = NULL, **l;
assert(m);
@@ -2935,7 +2945,7 @@ void manager_recheck_journal(Manager *m) {
assert(m);
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return;
u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
@@ -2959,7 +2969,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode) {
assert(m);
assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY));
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return;
if (m->show_status != mode)
@@ -2976,7 +2986,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode) {
static bool manager_get_show_status(Manager *m, StatusType type) {
assert(m);
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return false;
if (m->no_console_output)
@@ -2998,7 +3008,7 @@ static bool manager_get_show_status(Manager *m, StatusType type) {
void manager_set_first_boot(Manager *m, bool b) {
assert(m);
- if (m->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(m))
return;
if (m->first_boot != (int) b) {
@@ -3044,7 +3054,7 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
const char *manager_get_runtime_prefix(Manager *m) {
assert(m);
- return m->running_as == MANAGER_SYSTEM ?
+ return MANAGER_IS_SYSTEM(m) ?
"/run" :
getenv("XDG_RUNTIME_DIR");
}
diff --git a/src/libcore/manager.h b/src/libcore/manager.h
index d6c97d8f3b..70d79ce549 100644
--- a/src/libcore/manager.h
+++ b/src/libcore/manager.h
@@ -132,6 +132,9 @@ struct Manager {
int notify_fd;
sd_event_source *notify_event_source;
+ int cgroups_agent_fd;
+ sd_event_source *cgroups_agent_event_source;
+
int signal_fd;
sd_event_source *signal_event_source;
@@ -140,6 +143,7 @@ struct Manager {
sd_event_source *jobs_in_progress_event_source;
+ UnitFileScope unit_file_scope;
LookupPaths lookup_paths;
Set *unit_path_cache;
@@ -162,10 +166,6 @@ struct Manager {
dual_timestamp units_load_start_timestamp;
dual_timestamp units_load_finish_timestamp;
- char *generator_unit_path;
- char *generator_unit_path_early;
- char *generator_unit_path_late;
-
struct udev* udev;
/* Data specific to the device subsystem */
@@ -228,7 +228,6 @@ struct Manager {
unsigned n_in_gc_queue;
/* Flags */
- ManagerRunningAs running_as;
ManagerExitCode exit_code:5;
bool dispatching_load_queue:1;
@@ -256,6 +255,7 @@ struct Manager {
bool default_cpu_accounting;
bool default_memory_accounting;
+ bool default_io_accounting;
bool default_blockio_accounting;
bool default_tasks_accounting;
@@ -304,10 +304,15 @@ struct Manager {
const char *unit_log_field;
const char *unit_log_format_string;
- int first_boot;
+ int first_boot; /* tri-state */
};
-int manager_new(ManagerRunningAs running_as, bool test_run, Manager **m);
+#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)
+#define MANAGER_IS_USER(m) ((m)->unit_file_scope != UNIT_FILE_SYSTEM)
+
+#define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0)
+
+int manager_new(UnitFileScope scope, bool test_run, Manager **m);
Manager* manager_free(Manager *m);
void manager_enumerate(Manager *m);
@@ -345,8 +350,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
int manager_reload(Manager *m);
-bool manager_is_reloading_or_reexecuting(Manager *m) _pure_;
-
void manager_reset_failed(Manager *m);
void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success);
diff --git a/src/libcore/mount-setup.c b/src/libcore/mount-setup.c
index de1a361cc4..40fc548b42 100644
--- a/src/libcore/mount-setup.c
+++ b/src/libcore/mount-setup.c
@@ -94,7 +94,7 @@ static const MountPoint mount_table[] = {
#endif
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
NULL, MNT_FATAL|MNT_IN_CONTAINER },
- { "cgroup", "/sys/fs/cgroup", "cgroup", "__DEVEL__sane_behavior", MS_NOSUID|MS_NOEXEC|MS_NODEV,
+ { "cgroup", "/sys/fs/cgroup", "cgroup2", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
cg_is_unified_wanted, MNT_FATAL|MNT_IN_CONTAINER },
{ "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
@@ -375,6 +375,7 @@ int mount_setup(bool loaded_policy) {
before_relabel = now(CLOCK_MONOTONIC);
nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+ nftw("/dev/shm", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
after_relabel = now(CLOCK_MONOTONIC);
diff --git a/src/libcore/mount.c b/src/libcore/mount.c
index d573e92759..7db9d1325b 100644
--- a/src/libcore/mount.c
+++ b/src/libcore/mount.c
@@ -86,6 +86,15 @@ static bool mount_is_network(const MountParameters *p) {
return mount_needs_network(p->options, p->fstype);
}
+static bool mount_is_loop(const MountParameters *p) {
+ assert(p);
+
+ if (fstab_test_option(p->options, "loop\0"))
+ return true;
+
+ return false;
+}
+
static bool mount_is_bind(const MountParameters *p) {
assert(p);
@@ -104,6 +113,28 @@ static bool mount_is_auto(const MountParameters *p) {
return !fstab_test_option(p->options, "noauto\0");
}
+static bool mount_is_automount(const MountParameters *p) {
+ assert(p);
+
+ return fstab_test_option(p->options,
+ "comment=systemd.automount\0"
+ "x-systemd.automount\0");
+}
+
+static bool mount_state_active(MountState state) {
+ return IN_SET(state,
+ MOUNT_MOUNTING,
+ MOUNT_MOUNTING_DONE,
+ MOUNT_REMOUNTING,
+ MOUNT_UNMOUNTING,
+ MOUNT_MOUNTING_SIGTERM,
+ MOUNT_MOUNTING_SIGKILL,
+ MOUNT_UNMOUNTING_SIGTERM,
+ MOUNT_UNMOUNTING_SIGKILL,
+ MOUNT_REMOUNTING_SIGTERM,
+ MOUNT_REMOUNTING_SIGKILL);
+}
+
static bool needs_quota(const MountParameters *p) {
assert(p);
@@ -261,12 +292,12 @@ static int mount_add_mount_links(Mount *m) {
}
/* Adds in links to other mount points that might be needed
- * for the source path (if this is a bind mount) to be
+ * for the source path (if this is a bind mount or a loop mount) to be
* available. */
pm = get_mount_parameters_fragment(m);
if (pm && pm->what &&
path_is_absolute(pm->what) &&
- !mount_is_network(pm)) {
+ (mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
r = unit_require_mounts_for(UNIT(m), pm->what);
if (r < 0)
@@ -328,7 +359,7 @@ static int mount_add_device_links(Mount *m) {
if (path_equal(m->where, "/"))
return 0;
- if (mount_is_auto(p) && UNIT(m)->manager->running_as == MANAGER_SYSTEM)
+ if (mount_is_auto(p) && !mount_is_automount(p) && MANAGER_IS_SYSTEM(UNIT(m)->manager))
device_wants_mount = true;
r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, m->from_fragment ? UNIT_BINDS_TO : UNIT_REQUIRES);
@@ -344,7 +375,7 @@ static int mount_add_quota_links(Mount *m) {
assert(m);
- if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
return 0;
p = get_mount_parameters_fragment(m);
@@ -368,8 +399,8 @@ static int mount_add_quota_links(Mount *m) {
static bool should_umount(Mount *m) {
MountParameters *p;
- if (path_equal(m->where, "/") ||
- path_equal(m->where, "/usr"))
+ if (PATH_IN_SET(m->where, "/", "/usr") ||
+ path_startswith(m->where, "/run/initramfs"))
return false;
p = get_mount_parameters(m);
@@ -390,16 +421,17 @@ static int mount_add_default_dependencies(Mount *m) {
if (!UNIT(m)->default_dependencies)
return 0;
- if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
return 0;
- /* We do not add any default dependencies to / and /usr, since
- * they are guaranteed to stay mounted the whole time, since
- * our system is on it. Also, don't bother with anything
- * mounted below virtual file systems, it's also going to be
- * virtual, and hence not worth the effort. */
- if (path_equal(m->where, "/") ||
- path_equal(m->where, "/usr") ||
+ /* We do not add any default dependencies to /, /usr or
+ * /run/initramfs/, since they are guaranteed to stay
+ * mounted the whole time, since our system is on it.
+ * Also, don't bother with anything mounted below virtual
+ * file systems, it's also going to be virtual, and hence
+ * not worth the effort. */
+ if (PATH_IN_SET(m->where, "/", "/usr") ||
+ path_startswith(m->where, "/run/initramfs") ||
path_startswith(m->where, "/proc") ||
path_startswith(m->where, "/sys") ||
path_startswith(m->where, "/dev"))
@@ -566,23 +598,6 @@ static int mount_load(Unit *u) {
return mount_verify(m);
}
-static int mount_notify_automount(Mount *m, MountState old_state, MountState state) {
- Unit *p;
- int r;
- Iterator i;
-
- assert(m);
-
- SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
- if (p->type == UNIT_AUTOMOUNT) {
- r = automount_update_mount(AUTOMOUNT(p), old_state, state);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
static void mount_set_state(Mount *m, MountState state) {
MountState old_state;
assert(m);
@@ -590,24 +605,13 @@ static void mount_set_state(Mount *m, MountState state) {
old_state = m->state;
m->state = state;
- if (state != MOUNT_MOUNTING &&
- state != MOUNT_MOUNTING_DONE &&
- state != MOUNT_REMOUNTING &&
- state != MOUNT_UNMOUNTING &&
- state != MOUNT_MOUNTING_SIGTERM &&
- state != MOUNT_MOUNTING_SIGKILL &&
- state != MOUNT_UNMOUNTING_SIGTERM &&
- state != MOUNT_UNMOUNTING_SIGKILL &&
- state != MOUNT_REMOUNTING_SIGTERM &&
- state != MOUNT_REMOUNTING_SIGKILL) {
+ if (!mount_state_active(state)) {
m->timer_event_source = sd_event_source_unref(m->timer_event_source);
mount_unwatch_control_pid(m);
m->control_command = NULL;
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
}
- mount_notify_automount(m, old_state, state);
-
if (state != old_state)
log_unit_debug(UNIT(m), "Changed %s -> %s", mount_state_to_string(old_state), mount_state_to_string(state));
@@ -633,17 +637,7 @@ static int mount_coldplug(Unit *u) {
if (m->control_pid > 0 &&
pid_is_unwaited(m->control_pid) &&
- IN_SET(new_state,
- MOUNT_MOUNTING,
- MOUNT_MOUNTING_DONE,
- MOUNT_REMOUNTING,
- MOUNT_UNMOUNTING,
- MOUNT_MOUNTING_SIGTERM,
- MOUNT_MOUNTING_SIGKILL,
- MOUNT_UNMOUNTING_SIGTERM,
- MOUNT_UNMOUNTING_SIGKILL,
- MOUNT_REMOUNTING_SIGTERM,
- MOUNT_REMOUNTING_SIGKILL)) {
+ mount_state_active(new_state)) {
r = unit_watch_pid(UNIT(m), m->control_pid);
if (r < 0)
@@ -703,7 +697,6 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
.apply_permissions = true,
.apply_chroot = true,
.apply_tty_stdin = true,
- .bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
@@ -967,6 +960,7 @@ fail:
static int mount_start(Unit *u) {
Mount *m = MOUNT(u);
+ int r;
assert(m);
@@ -985,6 +979,12 @@ static int mount_start(Unit *u) {
assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
m->result = MOUNT_SUCCESS;
m->reload_result = MOUNT_SUCCESS;
m->reset_cpu_usage = true;
@@ -1385,7 +1385,7 @@ static int mount_setup_unit(
goto fail;
}
- if (m->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(m)) {
const char* target;
target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
@@ -1413,7 +1413,7 @@ static int mount_setup_unit(
}
}
- if (m->running_as == MANAGER_SYSTEM &&
+ if (MANAGER_IS_SYSTEM(m) &&
mount_needs_network(options, fstype)) {
/* _netdev option may have shown up late, or on a
* remount. Add remote-fs dependencies, even though
@@ -1782,6 +1782,14 @@ static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
}
+static int mount_control_pid(Unit *u) {
+ Mount *m = MOUNT(u);
+
+ assert(m);
+
+ return m->control_pid;
+}
+
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
[MOUNT_EXEC_MOUNT] = "ExecMount",
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
@@ -1796,7 +1804,8 @@ static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
[MOUNT_FAILURE_TIMEOUT] = "timeout",
[MOUNT_FAILURE_EXIT_CODE] = "exit-code",
[MOUNT_FAILURE_SIGNAL] = "signal",
- [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
+ [MOUNT_FAILURE_CORE_DUMP] = "core-dump",
+ [MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
@@ -1814,9 +1823,6 @@ const UnitVTable mount_vtable = {
"Install\0",
.private_section = "Mount",
- .no_alias = true,
- .no_instances = true,
-
.init = mount_init,
.load = mount_load,
.done = mount_done,
@@ -1843,6 +1849,8 @@ const UnitVTable mount_vtable = {
.reset_failed = mount_reset_failed,
+ .control_pid = mount_control_pid,
+
.bus_vtable = bus_mount_vtable,
.bus_set_property = bus_mount_set_property,
.bus_commit_properties = bus_mount_commit_properties,
diff --git a/src/libcore/mount.h b/src/libcore/mount.h
index 3b343c6b1f..da529c44f4 100644
--- a/src/libcore/mount.h
+++ b/src/libcore/mount.h
@@ -39,6 +39,7 @@ typedef enum MountResult {
MOUNT_FAILURE_EXIT_CODE,
MOUNT_FAILURE_SIGNAL,
MOUNT_FAILURE_CORE_DUMP,
+ MOUNT_FAILURE_START_LIMIT_HIT,
_MOUNT_RESULT_MAX,
_MOUNT_RESULT_INVALID = -1
} MountResult;
diff --git a/src/libcore/namespace.c b/src/libcore/namespace.c
index 4fa381db5b..203d122810 100644
--- a/src/libcore/namespace.c
+++ b/src/libcore/namespace.c
@@ -44,6 +44,8 @@
#include "user-util.h"
#include "util.h"
+#define DEV_MOUNT_OPTIONS (MS_NOSUID|MS_STRICTATIME|MS_NOEXEC)
+
typedef enum MountMode {
/* This is ordered by priority! */
INACCESSIBLE,
@@ -51,7 +53,6 @@ typedef enum MountMode {
PRIVATE_TMP,
PRIVATE_VAR_TMP,
PRIVATE_DEV,
- PRIVATE_BUS_ENDPOINT,
READWRITE
} MountMode;
@@ -154,7 +155,7 @@ static int mount_dev(BindMount *m) {
dev = strjoina(temporary_mount, "/dev");
(void) mkdir(dev, 0755);
- if (mount("tmpfs", dev, "tmpfs", MS_NOSUID|MS_STRICTATIME, "mode=755") < 0) {
+ if (mount("tmpfs", dev, "tmpfs", DEV_MOUNT_OPTIONS, "mode=755") < 0) {
r = -errno;
goto fail;
}
@@ -238,6 +239,8 @@ static int mount_dev(BindMount *m) {
*/
(void) mkdir_p_label(m->path, 0755);
+ /* Unmount everything in old /dev */
+ umount_recursive(m->path, 0);
if (mount(dev, m->path, NULL, MS_MOVE, NULL) < 0) {
r = -errno;
goto fail;
@@ -268,78 +271,6 @@ fail:
return r;
}
-static int mount_kdbus(BindMount *m) {
-
- char temporary_mount[] = "/tmp/kdbus-dev-XXXXXX";
- _cleanup_free_ char *basepath = NULL;
- _cleanup_umask_ mode_t u;
- char *busnode = NULL, *root;
- struct stat st;
- int r;
-
- assert(m);
-
- u = umask(0000);
-
- if (!mkdtemp(temporary_mount))
- return log_error_errno(errno, "Failed create temp dir: %m");
-
- root = strjoina(temporary_mount, "/kdbus");
- (void) mkdir(root, 0755);
- if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_STRICTATIME, "mode=777") < 0) {
- r = -errno;
- goto fail;
- }
-
- /* create a new /dev/null dev node copy so we have some fodder to
- * bind-mount the custom endpoint over. */
- if (stat("/dev/null", &st) < 0) {
- r = log_error_errno(errno, "Failed to stat /dev/null: %m");
- goto fail;
- }
-
- busnode = strjoina(root, "/bus");
- if (mknod(busnode, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
- r = log_error_errno(errno, "mknod() for %s failed: %m",
- busnode);
- goto fail;
- }
-
- r = mount(m->path, busnode, NULL, MS_BIND, NULL);
- if (r < 0) {
- r = log_error_errno(errno, "bind mount of %s failed: %m",
- m->path);
- goto fail;
- }
-
- basepath = dirname_malloc(m->path);
- if (!basepath) {
- r = -ENOMEM;
- goto fail;
- }
-
- if (mount(root, basepath, NULL, MS_MOVE, NULL) < 0) {
- r = log_error_errno(errno, "bind mount of %s failed: %m",
- basepath);
- goto fail;
- }
-
- rmdir(temporary_mount);
- return 0;
-
-fail:
- if (busnode) {
- umount(busnode);
- unlink(busnode);
- }
-
- umount(root);
- rmdir(root);
- rmdir(temporary_mount);
-
- return r;
-}
-
static int apply_mount(
BindMount *m,
const char *tmp_dir,
@@ -379,9 +310,6 @@ static int apply_mount(
case PRIVATE_DEV:
return mount_dev(m);
- case PRIVATE_BUS_ENDPOINT:
- return mount_kdbus(m);
-
default:
assert_not_reached("Unknown mode");
}
@@ -404,9 +332,11 @@ static int make_read_only(BindMount *m) {
if (IN_SET(m->mode, INACCESSIBLE, READONLY))
r = bind_remount_recursive(m->path, true);
- else if (IN_SET(m->mode, READWRITE, PRIVATE_TMP, PRIVATE_VAR_TMP, PRIVATE_DEV))
+ else if (IN_SET(m->mode, READWRITE, PRIVATE_TMP, PRIVATE_VAR_TMP, PRIVATE_DEV)) {
r = bind_remount_recursive(m->path, false);
- else
+ if (r == 0 && m->mode == PRIVATE_DEV) /* can be readonly but the submounts can't*/
+ r = mount(NULL, m->path, NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL);
+ } else
r = 0;
if (m->ignore && r == -ENOENT)
@@ -422,7 +352,6 @@ int setup_namespace(
char** inaccessible_dirs,
const char* tmp_dir,
const char* var_tmp_dir,
- const char* bus_endpoint_path,
bool private_dev,
ProtectHome protect_home,
ProtectSystem protect_system,
@@ -438,7 +367,7 @@ int setup_namespace(
if (unshare(CLONE_NEWNS) < 0)
return -errno;
- n = !!tmp_dir + !!var_tmp_dir + !!bus_endpoint_path +
+ n = !!tmp_dir + !!var_tmp_dir +
strv_length(read_write_dirs) +
strv_length(read_only_dirs) +
strv_length(inaccessible_dirs) +
@@ -479,12 +408,6 @@ int setup_namespace(
m++;
}
- if (bus_endpoint_path) {
- m->path = prefix_roota(root_directory, bus_endpoint_path);
- m->mode = PRIVATE_BUS_ENDPOINT;
- m++;
- }
-
if (protect_home != PROTECT_HOME_NO) {
const char *home_dir, *run_user_dir, *root_dir;
diff --git a/src/libcore/namespace.h b/src/libcore/namespace.h
index 40bee74e2c..b54b7b47d6 100644
--- a/src/libcore/namespace.h
+++ b/src/libcore/namespace.h
@@ -45,7 +45,6 @@ int setup_namespace(const char *chroot,
char **inaccessible_dirs,
const char *tmp_dir,
const char *var_tmp_dir,
- const char *endpoint_path,
bool private_dev,
ProtectHome protect_home,
ProtectSystem protect_system,
diff --git a/src/libcore/path.c b/src/libcore/path.c
index 460c1d3bf2..0dd0d375d8 100644
--- a/src/libcore/path.c
+++ b/src/libcore/path.c
@@ -110,16 +110,14 @@ int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
} else {
exists = true;
- /* Path exists, we don't need to watch parent
- too closely. */
+ /* Path exists, we don't need to watch parent too closely. */
if (oldslash) {
char *cut2 = oldslash + (oldslash == s->path);
char tmp2 = *cut2;
*cut2 = '\0';
- inotify_add_watch(s->inotify_fd, s->path, IN_MOVE_SELF);
- /* Error is ignored, the worst can happen is
- we get spurious events. */
+ (void) inotify_add_watch(s->inotify_fd, s->path, IN_MOVE_SELF);
+ /* Error is ignored, the worst can happen is we get spurious events. */
*cut2 = tmp2;
}
@@ -320,7 +318,7 @@ static int path_add_default_dependencies(Path *p) {
if (r < 0)
return r;
- if (UNIT(p)->manager->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(UNIT(p)->manager)) {
r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
if (r < 0)
return r;
@@ -476,7 +474,7 @@ static void path_enter_running(Path *p) {
trigger = UNIT_TRIGGER(UNIT(p));
if (!trigger) {
log_unit_error(UNIT(p), "Unit to trigger vanished.");
- path_enter_dead(p, TIMER_FAILURE_RESOURCES);
+ path_enter_dead(p, PATH_FAILURE_RESOURCES);
return;
}
@@ -562,6 +560,7 @@ static void path_mkdir(Path *p) {
static int path_start(Unit *u) {
Path *p = PATH(u);
Unit *trigger;
+ int r;
assert(p);
assert(p->state == PATH_DEAD || p->state == PATH_FAILED);
@@ -572,6 +571,12 @@ static int path_start(Unit *u) {
return -ENOENT;
}
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
path_mkdir(p);
p->result = PATH_SUCCESS;
@@ -741,6 +746,7 @@ DEFINE_STRING_TABLE_LOOKUP(path_type, PathType);
static const char* const path_result_table[_PATH_RESULT_MAX] = {
[PATH_SUCCESS] = "success",
[PATH_FAILURE_RESOURCES] = "resources",
+ [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
diff --git a/src/libcore/path.h b/src/libcore/path.h
index bbbcebd78e..4230c8fb99 100644
--- a/src/libcore/path.h
+++ b/src/libcore/path.h
@@ -62,6 +62,7 @@ static inline bool path_spec_owns_inotify_fd(PathSpec *s, int fd) {
typedef enum PathResult {
PATH_SUCCESS,
PATH_FAILURE_RESOURCES,
+ PATH_FAILURE_START_LIMIT_HIT,
_PATH_RESULT_MAX,
_PATH_RESULT_INVALID = -1
} PathResult;
diff --git a/src/libcore/scope.c b/src/libcore/scope.c
index c5d0ecef04..238f63a729 100644
--- a/src/libcore/scope.c
+++ b/src/libcore/scope.c
@@ -50,8 +50,7 @@ static void scope_init(Unit *u) {
assert(u->load_state == UNIT_STUB);
s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
-
- UNIT(s)->ignore_on_isolate = true;
+ u->ignore_on_isolate = true;
}
static void scope_done(Unit *u) {
@@ -139,7 +138,7 @@ static int scope_verify(Scope *s) {
return 0;
if (set_isempty(UNIT(s)->pids) &&
- !manager_is_reloading_or_reexecuting(UNIT(s)->manager) &&
+ !MANAGER_IS_RELOADING(UNIT(s)->manager) &&
!unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) {
log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
return -EINVAL;
@@ -155,26 +154,27 @@ static int scope_load(Unit *u) {
assert(s);
assert(u->load_state == UNIT_STUB);
- if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
+ if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
+ /* Refuse to load non-transient scope units, but allow them while reloading. */
return -ENOENT;
- u->load_state = UNIT_LOADED;
-
- r = unit_load_dropin(u);
+ r = unit_load_fragment_and_dropin_optional(u);
if (r < 0)
return r;
- r = unit_patch_contexts(u);
- if (r < 0)
- return r;
+ if (u->load_state == UNIT_LOADED) {
+ r = unit_patch_contexts(u);
+ if (r < 0)
+ return r;
- r = unit_set_default_slice(u);
- if (r < 0)
- return r;
+ r = unit_set_default_slice(u);
+ if (r < 0)
+ return r;
- r = scope_add_default_dependencies(s);
- if (r < 0)
- return r;
+ r = scope_add_default_dependencies(s);
+ if (r < 0)
+ return r;
+ }
return scope_verify(s);
}
@@ -293,7 +293,7 @@ static int scope_start(Unit *u) {
assert(s->state == SCOPE_DEAD);
- if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
+ if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
return -ENOENT;
(void) unit_realize_cgroup(u);
@@ -569,8 +569,6 @@ const UnitVTable scope_vtable = {
"Install\0",
.private_section = "Scope",
- .no_alias = true,
- .no_instances = true,
.can_transient = true,
.init = scope_init,
diff --git a/src/libcore/selinux-access.c b/src/libcore/selinux-access.c
index 76fcc9a6be..2c04fb0a8f 100644
--- a/src/libcore/selinux-access.c
+++ b/src/libcore/selinux-access.c
@@ -110,6 +110,7 @@ static int callback_type_to_priority(int type) {
*/
_printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
va_list ap;
+ const char *fmt2;
#ifdef HAVE_AUDIT
int fd;
@@ -131,8 +132,10 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
}
#endif
+ fmt2 = strjoina("selinux: ", fmt);
+
va_start(ap, fmt);
- log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
+ log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt2, ap);
va_end(ap);
return 0;
diff --git a/src/libcore/selinux-setup.c b/src/libcore/selinux-setup.c
index 9a115a4387..4072df58e6 100644
--- a/src/libcore/selinux-setup.c
+++ b/src/libcore/selinux-setup.c
@@ -88,7 +88,7 @@ int mac_selinux_setup(bool *loaded_policy) {
log_open();
log_error("Failed to compute init label, ignoring.");
} else {
- r = setcon(label);
+ r = setcon_raw(label);
log_open();
if (r < 0)
diff --git a/src/libcore/service.c b/src/libcore/service.c
index ac7e41d777..7ebabca5d6 100644
--- a/src/libcore/service.c
+++ b/src/libcore/service.c
@@ -113,7 +113,6 @@ static void service_init(Unit *u) {
s->runtime_max_usec = USEC_INFINITY;
s->type = _SERVICE_TYPE_INVALID;
s->socket_fd = -1;
- s->bus_endpoint_fd = -1;
s->stdin_fd = s->stdout_fd = s->stderr_fd = -1;
s->guess_main_pid = true;
@@ -181,20 +180,17 @@ static int service_set_main_pid(Service *s, pid_t pid) {
return 0;
}
-static void service_close_socket_fd(Service *s) {
+void service_close_socket_fd(Service *s) {
assert(s);
- s->socket_fd = asynchronous_close(s->socket_fd);
-}
-
-static void service_connection_unref(Service *s) {
- assert(s);
+ /* Undo the effect of service_set_socket_fd(). */
- if (!UNIT_ISSET(s->accept_socket))
- return;
+ s->socket_fd = asynchronous_close(s->socket_fd);
- socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket)));
- unit_ref_unset(&s->accept_socket);
+ if (UNIT_ISSET(s->accept_socket)) {
+ socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket)));
+ unit_ref_unset(&s->accept_socket);
+ }
}
static void service_stop_watchdog(Service *s) {
@@ -321,9 +317,7 @@ static void service_done(Unit *u) {
s->bus_name_owner = mfree(s->bus_name_owner);
- s->bus_endpoint_fd = safe_close(s->bus_endpoint_fd);
service_close_socket_fd(s);
- service_connection_unref(s);
unit_ref_unset(&s->accept_socket);
@@ -525,7 +519,7 @@ static int service_add_default_dependencies(Service *s) {
/* Add a number of automatic dependencies useful for the
* majority of services. */
- if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) {
/* First, pull in the really early boot stuff, and
* require it, so that we fail if we can't acquire
* it. */
@@ -834,7 +828,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
return 0;
}
-static int service_search_main_pid(Service *s) {
+static void service_search_main_pid(Service *s) {
pid_t pid = 0;
int r;
@@ -843,30 +837,24 @@ static int service_search_main_pid(Service *s) {
/* If we know it anyway, don't ever fallback to unreliable
* heuristics */
if (s->main_pid_known)
- return 0;
+ return;
if (!s->guess_main_pid)
- return 0;
+ return;
assert(s->main_pid <= 0);
- r = unit_search_main_pid(UNIT(s), &pid);
- if (r < 0)
- return r;
+ if (unit_search_main_pid(UNIT(s), &pid) < 0)
+ return;
log_unit_debug(UNIT(s), "Main PID guessed: "PID_FMT, pid);
- r = service_set_main_pid(s, pid);
- if (r < 0)
- return r;
+ if (service_set_main_pid(s, pid) < 0)
+ return;
r = unit_watch_pid(UNIT(s), pid);
- if (r < 0) {
+ if (r < 0)
/* FIXME: we need to do something here */
log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" from: %m", pid);
- return r;
- }
-
- return 0;
}
static void service_set_state(Service *s, ServiceState state) {
@@ -918,17 +906,15 @@ static void service_set_state(Service *s, ServiceState state) {
SERVICE_RUNNING, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
- !(state == SERVICE_DEAD && UNIT(s)->job)) {
+ !(state == SERVICE_DEAD && UNIT(s)->job))
service_close_socket_fd(s);
- service_connection_unref(s);
- }
if (!IN_SET(state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD))
service_stop_watchdog(s);
/* For the inactive states unit_notify() will trim the cgroup,
* but for exit we have to do that ourselves... */
- if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0)
+ if (state == SERVICE_EXITED && !MANAGER_IS_RELOADING(UNIT(s)->manager))
unit_prune_cgroup(UNIT(s));
/* For remain_after_exit services, let's see if we can "release" the
@@ -944,7 +930,7 @@ static void service_set_state(Service *s, ServiceState state) {
if (ec && exec_context_may_touch_console(ec)) {
Manager *m = UNIT(s)->manager;
- m->n_on_console --;
+ m->n_on_console--;
if (m->n_on_console == 0)
/* unset no_console_output flag, since the console is free */
m->no_console_output = false;
@@ -1157,7 +1143,6 @@ static int service_spawn(
pid_t *_pid) {
_cleanup_strv_free_ char **argv = NULL, **final_env = NULL, **our_env = NULL, **fd_names = NULL;
- _cleanup_free_ char *bus_endpoint_path = NULL;
_cleanup_free_ int *fds = NULL;
unsigned n_fds = 0, n_env = 0;
const char *path;
@@ -1167,7 +1152,6 @@ static int service_spawn(
.apply_permissions = apply_permissions,
.apply_chroot = apply_chroot,
.apply_tty_stdin = apply_tty_stdin,
- .bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
@@ -1221,7 +1205,7 @@ static int service_spawn(
if (asprintf(our_env + n_env++, "MAINPID="PID_FMT, s->main_pid) < 0)
return -ENOMEM;
- if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(UNIT(s)->manager))
if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid()) < 0)
return -ENOMEM;
@@ -1267,18 +1251,6 @@ static int service_spawn(
} else
path = UNIT(s)->cgroup_path;
- if (s->exec_context.bus_endpoint) {
- r = bus_kernel_create_endpoint(UNIT(s)->manager->running_as == MANAGER_SYSTEM ? "system" : "user",
- UNIT(s)->id, &bus_endpoint_path);
- if (r < 0)
- return r;
-
- /* Pass the fd to the exec_params so that the child process can upload the policy.
- * Keep a reference to the fd in the service, so the endpoint is kept alive as long
- * as the service is running. */
- exec_params.bus_endpoint_fd = s->bus_endpoint_fd = r;
- }
-
exec_params.argv = argv;
exec_params.fds = fds;
exec_params.fd_names = fd_names;
@@ -1290,7 +1262,6 @@ static int service_spawn(
exec_params.cgroup_delegate = s->cgroup_context.delegate;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
exec_params.watchdog_usec = s->watchdog_usec;
- exec_params.bus_endpoint_path = bus_endpoint_path;
exec_params.selinux_context_net = s->socket_fd_selinux_context_net;
if (s->type == SERVICE_IDLE)
exec_params.idle_pipe = UNIT(s)->manager->idle_pipe;
@@ -1986,6 +1957,7 @@ fail:
static int service_start(Unit *u) {
Service *s = SERVICE(u);
+ int r;
assert(s);
@@ -2012,6 +1984,13 @@ static int service_start(Unit *u) {
assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
+ /* Make sure we don't enter a busy loop of some kind. */
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
+ return r;
+ }
+
s->result = SERVICE_SUCCESS;
s->reload_result = SERVICE_SUCCESS;
s->main_pid_known = false;
@@ -2126,9 +2105,6 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
r = unit_serialize_item_fd(u, f, fds, "socket-fd", s->socket_fd);
if (r < 0)
return r;
- r = unit_serialize_item_fd(u, f, fds, "endpoint-fd", s->bus_endpoint_fd);
- if (r < 0)
- return r;
LIST_FOREACH(fd_store, fs, s->fd_store) {
_cleanup_free_ char *c = NULL;
@@ -2154,8 +2130,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
}
}
- if (dual_timestamp_is_set(&s->watchdog_timestamp))
- dual_timestamp_serialize(f, "watchdog-timestamp", &s->watchdog_timestamp);
+ dual_timestamp_serialize(f, "watchdog-timestamp", &s->watchdog_timestamp);
unit_serialize_item(u, f, "forbid-restart", yes_no(s->forbid_restart));
@@ -2263,15 +2238,6 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
asynchronous_close(s->socket_fd);
s->socket_fd = fdset_remove(fds, fd);
}
- } else if (streq(key, "endpoint-fd")) {
- int fd;
-
- if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_unit_debug(u, "Failed to parse endpoint-fd value: %s", value);
- else {
- safe_close(s->bus_endpoint_fd);
- s->bus_endpoint_fd = fdset_remove(fds, fd);
- }
} else if (streq(key, "fd-store-fd")) {
const char *fdv;
size_t pf;
@@ -2759,7 +2725,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
break;
}
} else
- (void) service_search_main_pid(s);
+ service_search_main_pid(s);
service_enter_start_post(s);
break;
@@ -2781,16 +2747,15 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
break;
}
} else
- (void) service_search_main_pid(s);
+ service_search_main_pid(s);
service_enter_running(s, SERVICE_SUCCESS);
break;
case SERVICE_RELOAD:
- if (f == SERVICE_SUCCESS) {
- service_load_pid_file(s, true);
- (void) service_search_main_pid(s);
- }
+ if (f == SERVICE_SUCCESS)
+ if (service_load_pid_file(s, true) < 0)
+ service_search_main_pid(s);
s->reload_result = f;
service_enter_running(s, SERVICE_SUCCESS);
@@ -3176,9 +3141,8 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
assert(s);
assert(fd >= 0);
- /* This is called by the socket code when instantiating a new
- * service for a stream socket and the socket needs to be
- * configured. */
+ /* This is called by the socket code when instantiating a new service for a stream socket and the socket needs
+ * to be configured. We take ownership of the passed fd on success. */
if (UNIT(s)->load_state != UNIT_LOADED)
return -EINVAL;
@@ -3206,12 +3170,15 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
return r;
}
+ r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
+ if (r < 0)
+ return r;
+
s->socket_fd = fd;
s->socket_fd_selinux_context_net = selinux_context_net;
unit_ref_set(&s->accept_socket, UNIT(sock));
-
- return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
+ return 0;
}
static void service_reset_failed(Unit *u) {
@@ -3232,6 +3199,22 @@ static int service_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error);
}
+static int service_main_pid(Unit *u) {
+ Service *s = SERVICE(u);
+
+ assert(s);
+
+ return s->main_pid;
+}
+
+static int service_control_pid(Unit *u) {
+ Service *s = SERVICE(u);
+
+ assert(s);
+
+ return s->control_pid;
+}
+
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
[SERVICE_RESTART_NO] = "no",
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
@@ -3291,6 +3274,7 @@ static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
[SERVICE_FAILURE_SIGNAL] = "signal",
[SERVICE_FAILURE_CORE_DUMP] = "core-dump",
[SERVICE_FAILURE_WATCHDOG] = "watchdog",
+ [SERVICE_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
@@ -3340,6 +3324,9 @@ const UnitVTable service_vtable = {
.notify_cgroup_empty = service_notify_cgroup_empty_event,
.notify_message = service_notify_message,
+ .main_pid = service_main_pid,
+ .control_pid = service_control_pid,
+
.bus_name_owner_change = service_bus_name_owner_change,
.bus_vtable = bus_service_vtable,
diff --git a/src/libcore/service.h b/src/libcore/service.h
index d342e000bb..4af3d40439 100644
--- a/src/libcore/service.h
+++ b/src/libcore/service.h
@@ -80,12 +80,13 @@ typedef enum NotifyState {
typedef enum ServiceResult {
SERVICE_SUCCESS,
- SERVICE_FAILURE_RESOURCES,
+ SERVICE_FAILURE_RESOURCES, /* a bit of a misnomer, just our catch-all error for errnos we didn't expect */
SERVICE_FAILURE_TIMEOUT,
SERVICE_FAILURE_EXIT_CODE,
SERVICE_FAILURE_SIGNAL,
SERVICE_FAILURE_CORE_DUMP,
SERVICE_FAILURE_WATCHDOG,
+ SERVICE_FAILURE_START_LIMIT_HIT,
_SERVICE_RESULT_MAX,
_SERVICE_RESULT_INVALID = -1
} ServiceResult;
@@ -150,8 +151,6 @@ struct Service {
int socket_fd;
bool socket_fd_selinux_context_net;
- int bus_endpoint_fd;
-
bool permissions_start_only;
bool root_directory_start_only;
bool remain_after_exit;
@@ -200,6 +199,7 @@ struct Service {
extern const UnitVTable service_vtable;
int service_set_socket_fd(Service *s, int fd, struct Socket *socket, bool selinux_context_net);
+void service_close_socket_fd(Service *s);
const char* service_restart_to_string(ServiceRestart i) _const_;
ServiceRestart service_restart_from_string(const char *s) _pure_;
diff --git a/src/libcore/shutdown.c b/src/libcore/shutdown.c
index 6296b4c94a..e14755d84e 100644
--- a/src/libcore/shutdown.c
+++ b/src/libcore/shutdown.c
@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) {
goto error;
}
- cg_get_root_path(&cgroup);
+ (void) cg_get_root_path(&cgroup);
use_watchdog = !!getenv("WATCHDOG_USEC");
@@ -397,9 +397,14 @@ int main(int argc, char *argv[]) {
if (!in_container) {
_cleanup_free_ char *param = NULL;
- if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
+ r = read_one_line_file("/run/systemd/reboot-param", &param);
+ if (r < 0)
+ log_warning_errno(r, "Failed to read reboot parameter file: %m");
+
+ if (!isempty(param)) {
log_info("Rebooting with argument '%s'.", param);
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");
}
}
diff --git a/src/libcore/slice.c b/src/libcore/slice.c
index d65364c6f4..c7700b8857 100644
--- a/src/libcore/slice.c
+++ b/src/libcore/slice.c
@@ -34,6 +34,13 @@ static const UnitActiveState state_translation_table[_SLICE_STATE_MAX] = {
[SLICE_ACTIVE] = UNIT_ACTIVE
};
+static void slice_init(Unit *u) {
+ assert(u);
+ assert(u->load_state == UNIT_STUB);
+
+ u->ignore_on_isolate = true;
+}
+
static void slice_set_state(Slice *t, SliceState state) {
SliceState old_state;
assert(t);
@@ -128,6 +135,7 @@ static int slice_load(Unit *u) {
int r;
assert(s);
+ assert(u->load_state == UNIT_STUB);
r = unit_load_fragment_and_dropin_optional(u);
if (r < 0)
@@ -301,10 +309,9 @@ const UnitVTable slice_vtable = {
"Install\0",
.private_section = "Slice",
- .no_alias = true,
- .no_instances = true,
.can_transient = true,
+ .init = slice_init,
.load = slice_load,
.coldplug = slice_coldplug,
diff --git a/src/libcore/smack-setup.c b/src/libcore/smack-setup.c
index 0c26e85460..5a6d11cfa1 100644
--- a/src/libcore/smack-setup.c
+++ b/src/libcore/smack-setup.c
@@ -261,7 +261,7 @@ static int write_netlabel_rules(const char* srcdir) {
}
}
- return r;
+ return r;
}
#endif
diff --git a/src/libcore/socket.c b/src/libcore/socket.c
index f36e312f7b..f6204d04bf 100644
--- a/src/libcore/socket.c
+++ b/src/libcore/socket.c
@@ -28,7 +28,6 @@
#include <unistd.h>
#include <linux/sctp.h>
-#include <systemd/sd-event.h>
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
@@ -38,6 +37,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "formats-util.h"
+#include "io-util.h"
#include "label.h"
#include "log.h"
#include "missing.h"
@@ -99,6 +99,9 @@ static void socket_init(Unit *u) {
s->exec_context.std_error = u->manager->default_std_error;
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
+
+ s->trigger_limit.interval = USEC_INFINITY;
+ s->trigger_limit.burst = (unsigned) -1;
}
static void socket_unwatch_control_pid(Socket *s) {
@@ -227,7 +230,6 @@ int socket_instantiate_service(Socket *s) {
if (r < 0)
return r;
- u->no_gc = true;
unit_ref_set(&s->service, u);
return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
@@ -301,7 +303,7 @@ static int socket_add_default_dependencies(Socket *s) {
if (r < 0)
return r;
- if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) {
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
if (r < 0)
return r;
@@ -327,6 +329,25 @@ static int socket_add_extras(Socket *s) {
assert(s);
+ /* Pick defaults for the trigger limit, if nothing was explicitly configured. We pick a relatively high limit
+ * in Accept=yes mode, and a lower limit for Accept=no. Reason: in Accept=yes mode we are invoking accept()
+ * ourselves before the trigger limit can hit, thus incoming connections are taken off the socket queue quickly
+ * and reliably. This is different for Accept=no, where the spawned service has to take the incoming traffic
+ * off the queues, which it might not necessarily do. Moreover, while Accept=no services are supposed to
+ * process whatever is queued in one go, and thus should normally never have to be started frequently. This is
+ * different for Accept=yes where each connection is processed by a new service instance, and thus frequent
+ * service starts are typical. */
+
+ if (s->trigger_limit.interval == USEC_INFINITY)
+ s->trigger_limit.interval = 2 * USEC_PER_SEC;
+
+ if (s->trigger_limit.burst == (unsigned) -1) {
+ if (s->accept)
+ s->trigger_limit.burst = 200;
+ else
+ s->trigger_limit.burst = 20;
+ }
+
if (have_non_accept_socket(s)) {
if (!UNIT_DEREF(s->service)) {
@@ -619,8 +640,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
if (!isempty(s->user) || !isempty(s->group))
fprintf(f,
- "%sOwnerUser: %s\n"
- "%sOwnerGroup: %s\n",
+ "%sSocketUser: %s\n"
+ "%sSocketGroup: %s\n",
prefix, strna(s->user),
prefix, strna(s->group));
@@ -669,6 +690,12 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
}
+ fprintf(f,
+ "%sTriggerLimitIntervalSec: %s\n"
+ "%sTriggerLimitBurst: %u\n",
+ prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->trigger_limit.interval, USEC_PER_SEC),
+ prefix, s->trigger_limit.burst);
+
exec_context_dump(&s->exec_context, f, prefix);
kill_context_dump(&s->kill_context, f, prefix);
@@ -792,47 +819,45 @@ static void socket_close_fds(Socket *s) {
assert(s);
LIST_FOREACH(port, p, s->ports) {
+ bool was_open;
- p->event_source = sd_event_source_unref(p->event_source);
-
- if (p->fd < 0)
- continue;
+ was_open = p->fd >= 0;
+ p->event_source = sd_event_source_unref(p->event_source);
p->fd = safe_close(p->fd);
socket_cleanup_fd_list(p);
- /* One little note: we should normally not delete any
- * sockets in the file system here! After all some
- * other process we spawned might still have a
- * reference of this fd and wants to continue to use
- * it. Therefore we delete sockets in the file system
- * before we create a new one, not after we stopped
- * using one! */
+ /* One little note: we should normally not delete any sockets in the file system here! After all some
+ * other process we spawned might still have a reference of this fd and wants to continue to use
+ * it. Therefore we normally delete sockets in the file system before we create a new one, not after we
+ * stopped using one! That all said, if the user explicitly requested this, we'll delete them here
+ * anyway, but only then. */
- if (s->remove_on_stop) {
- switch (p->type) {
+ if (!was_open || !s->remove_on_stop)
+ continue;
- case SOCKET_FIFO:
- unlink(p->path);
- break;
+ switch (p->type) {
- case SOCKET_MQUEUE:
- mq_unlink(p->path);
- break;
+ case SOCKET_FIFO:
+ (void) unlink(p->path);
+ break;
- case SOCKET_SOCKET:
- socket_address_unlink(&p->address);
- break;
+ case SOCKET_MQUEUE:
+ (void) mq_unlink(p->path);
+ break;
- default:
- break;
- }
+ case SOCKET_SOCKET:
+ (void) socket_address_unlink(&p->address);
+ break;
+
+ default:
+ break;
}
}
if (s->remove_on_stop)
STRV_FOREACH(i, s->symlinks)
- unlink(*i);
+ (void) unlink(*i);
}
static void socket_apply_socket_options(Socket *s, int fd) {
@@ -1222,6 +1247,45 @@ fail:
return r;
}
+static int socket_determine_selinux_label(Socket *s, char **ret) {
+ ExecCommand *c;
+ int r;
+
+ assert(s);
+ assert(ret);
+
+ if (s->selinux_context_from_net) {
+ /* If this is requested, get label from the network label */
+
+ r = mac_selinux_get_our_label(ret);
+ if (r == -EOPNOTSUPP)
+ goto no_label;
+
+ } else {
+ /* Otherwise, get it from the executable we are about to start */
+ r = socket_instantiate_service(s);
+ if (r < 0)
+ return r;
+
+ if (!UNIT_ISSET(s->service))
+ goto no_label;
+
+ c = SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START];
+ if (!c)
+ goto no_label;
+
+ r = mac_selinux_get_create_label_from_exe(c->path, ret);
+ if (r == -EPERM || r == -EOPNOTSUPP)
+ goto no_label;
+ }
+
+ return r;
+
+no_label:
+ *ret = NULL;
+ return 0;
+}
+
static int socket_open_fds(Socket *s) {
_cleanup_(mac_selinux_freep) char *label = NULL;
bool know_label = false;
@@ -1240,46 +1304,28 @@ static int socket_open_fds(Socket *s) {
case SOCKET_SOCKET:
if (!know_label) {
- /* Figure out label, if we don't it know
- * yet. We do it once, for the first
- * socket where we need this and
- * remember it for the rest. */
-
- if (s->selinux_context_from_net) {
- /* Get it from the network label */
-
- r = mac_selinux_get_our_label(&label);
- if (r < 0 && r != -EOPNOTSUPP)
- goto rollback;
+ /* Figure out label, if we don't it know yet. We do it once, for the first socket where
+ * we need this and remember it for the rest. */
- } else {
- /* Get it from the executable we are about to start */
-
- r = socket_instantiate_service(s);
- if (r < 0)
- goto rollback;
-
- if (UNIT_ISSET(s->service) &&
- SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
- r = mac_selinux_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
- if (r < 0 && r != -EPERM && r != -EOPNOTSUPP)
- goto rollback;
- }
- }
+ r = socket_determine_selinux_label(s, &label);
+ if (r < 0)
+ goto rollback;
know_label = true;
}
/* Apply the socket protocol */
- switch(p->address.type) {
+ switch (p->address.type) {
+
case SOCK_STREAM:
case SOCK_SEQPACKET:
- if (p->socket->socket_protocol == IPPROTO_SCTP)
- p->address.protocol = p->socket->socket_protocol;
+ if (s->socket_protocol == IPPROTO_SCTP)
+ p->address.protocol = s->socket_protocol;
break;
+
case SOCK_DGRAM:
- if (p->socket->socket_protocol == IPPROTO_UDPLITE)
- p->address.protocol = p->socket->socket_protocol;
+ if (s->socket_protocol == IPPROTO_UDPLITE)
+ p->address.protocol = s->socket_protocol;
break;
}
@@ -1340,9 +1386,12 @@ static int socket_open_fds(Socket *s) {
}
break;
- case SOCKET_USB_FUNCTION:
+ case SOCKET_USB_FUNCTION: {
+ _cleanup_free_ char *ep = NULL;
- p->fd = usbffs_address_create(p->path);
+ ep = path_make_absolute("ep0", p->path);
+
+ p->fd = usbffs_address_create(ep);
if (p->fd < 0) {
r = p->fd;
goto rollback;
@@ -1357,7 +1406,7 @@ static int socket_open_fds(Socket *s) {
goto rollback;
break;
-
+ }
default:
assert_not_reached("Unknown port type");
}
@@ -1420,6 +1469,34 @@ fail:
return r;
}
+enum {
+ SOCKET_OPEN_NONE,
+ SOCKET_OPEN_SOME,
+ SOCKET_OPEN_ALL,
+};
+
+static int socket_check_open(Socket *s) {
+ bool have_open = false, have_closed = false;
+ SocketPort *p;
+
+ assert(s);
+
+ LIST_FOREACH(port, p, s->ports) {
+ if (p->fd < 0)
+ have_closed = true;
+ else
+ have_open = true;
+
+ if (have_open && have_closed)
+ return SOCKET_OPEN_SOME;
+ }
+
+ if (have_open)
+ return SOCKET_OPEN_ALL;
+
+ return SOCKET_OPEN_NONE;
+}
+
static void socket_set_state(Socket *s, SocketState state) {
SocketState old_state;
assert(s);
@@ -1499,14 +1576,24 @@ static int socket_coldplug(Unit *u) {
SOCKET_START_CHOWN,
SOCKET_START_POST,
SOCKET_LISTENING,
- SOCKET_RUNNING,
- SOCKET_STOP_PRE,
- SOCKET_STOP_PRE_SIGTERM,
- SOCKET_STOP_PRE_SIGKILL)) {
-
- r = socket_open_fds(s);
- if (r < 0)
- return r;
+ SOCKET_RUNNING)) {
+
+ /* Originally, we used to simply reopen all sockets here that we didn't have file descriptors
+ * for. However, this is problematic, as we won't traverse throught the SOCKET_START_CHOWN state for
+ * them, and thus the UID/GID wouldn't be right. Hence, instead simply check if we have all fds open,
+ * and if there's a mismatch, warn loudly. */
+
+ r = socket_check_open(s);
+ if (r == SOCKET_OPEN_NONE)
+ log_unit_warning(UNIT(s),
+ "Socket unit configuration has changed while unit has been running, "
+ "no open socket file descriptor left. "
+ "The socket unit is not functional until restarted.");
+ else if (r == SOCKET_OPEN_SOME)
+ log_unit_warning(UNIT(s),
+ "Socket unit configuration has changed while unit has been running, "
+ "and some socket file descriptors have not been opened yet. "
+ "The socket unit is not fully functional until restarted.");
}
if (s->deserialized_state == SOCKET_LISTENING) {
@@ -1527,7 +1614,6 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
.apply_permissions = true,
.apply_chroot = true,
.apply_tty_stdin = true,
- .bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
@@ -1880,38 +1966,47 @@ fail:
socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
}
+static void flush_ports(Socket *s) {
+ SocketPort *p;
+
+ /* Flush all incoming traffic, regardless if actual bytes or new connections, so that this socket isn't busy
+ * anymore */
+
+ LIST_FOREACH(port, p, s->ports) {
+ if (p->fd < 0)
+ continue;
+
+ (void) flush_accept(p->fd);
+ (void) flush_fd(p->fd);
+ }
+}
+
static void socket_enter_running(Socket *s, int cfd) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
+ /* Note that this call takes possession of the connection fd passed. It either has to assign it somewhere or
+ * close it. */
+
assert(s);
- /* We don't take connections anymore if we are supposed to
- * shut down anyway */
+ /* We don't take connections anymore if we are supposed to shut down anyway */
if (unit_stop_pending(UNIT(s))) {
log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled.");
if (cfd >= 0)
- safe_close(cfd);
- else {
- /* Flush all sockets by closing and reopening them */
- socket_close_fds(s);
-
- r = socket_open_fds(s);
- if (r < 0) {
- log_unit_warning_errno(UNIT(s), r, "Failed to listen on sockets: %m");
- socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
- return;
- }
+ cfd = safe_close(cfd);
+ else
+ flush_ports(s);
- r = socket_watch_fds(s);
- if (r < 0) {
- log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m");
- socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
- }
- }
+ return;
+ }
+ if (!ratelimit_test(&s->trigger_limit)) {
+ safe_close(cfd);
+ log_unit_warning(UNIT(s), "Trigger limit hit, refusing further activation.");
+ socket_enter_stop_pre(s, SOCKET_FAILURE_TRIGGER_LIMIT_HIT);
return;
}
@@ -1946,7 +2041,7 @@ static void socket_enter_running(Socket *s, int cfd) {
Service *service;
if (s->n_connections >= s->max_connections) {
- log_unit_warning(UNIT(s), "Too many incoming connections (%u)", s->n_connections);
+ log_unit_warning(UNIT(s), "Too many incoming connections (%u), refusing connection attempt.", s->n_connections);
safe_close(cfd);
return;
}
@@ -1962,6 +2057,7 @@ static void socket_enter_running(Socket *s, int cfd) {
/* ENOTCONN is legitimate if TCP RST was received.
* This connection is over, but the socket unit lives on. */
+ log_unit_debug(UNIT(s), "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring.");
safe_close(cfd);
return;
}
@@ -1980,22 +2076,24 @@ static void socket_enter_running(Socket *s, int cfd) {
service = SERVICE(UNIT_DEREF(s->service));
unit_ref_unset(&s->service);
- s->n_accepted ++;
-
- UNIT(service)->no_gc = false;
+ s->n_accepted++;
unit_choose_id(UNIT(service), name);
r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
if (r < 0)
goto fail;
- cfd = -1;
- s->n_connections ++;
+ cfd = -1; /* We passed ownership of the fd to the service now. Forget it here. */
+ s->n_connections++;
r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, &error, NULL);
- if (r < 0)
+ if (r < 0) {
+ /* We failed to activate the new service, but it still exists. Let's make sure the service
+ * closes and forgets the connection fd again, immediately. */
+ service_close_socket_fd(service);
goto fail;
+ }
/* Notify clients about changed counters */
unit_add_to_dbus_queue(UNIT(s));
@@ -2042,6 +2140,7 @@ fail:
static int socket_start(Unit *u) {
Socket *s = SOCKET(u);
+ int r;
assert(s);
@@ -2086,6 +2185,12 @@ static int socket_start(Unit *u) {
assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
s->result = SOCKET_SUCCESS;
s->reset_cpu_usage = true;
@@ -2720,17 +2825,26 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
assert(u);
assert(other);
- /* Don't propagate state changes from the service if we are
- already down or accepting connections */
- if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING) || s->accept)
+ /* Filter out invocations with bogus state */
+ if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
+ return;
+
+ /* Don't propagate state changes from the service if we are already down */
+ if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING))
return;
+ /* We don't care for the service state if we are in Accept=yes mode */
+ if (s->accept)
+ return;
+
+ /* Propagate start limit hit state */
if (other->start_limit_hit) {
socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_START_LIMIT_HIT);
return;
}
- if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
+ /* Don't propagate anything if there's still a job queued */
+ if (other->job)
return;
if (IN_SET(SERVICE(other)->state,
@@ -2778,6 +2892,14 @@ char *socket_fdname(Socket *s) {
return UNIT(s)->id;
}
+static int socket_control_pid(Unit *u) {
+ Socket *s = SOCKET(u);
+
+ assert(s);
+
+ return s->control_pid;
+}
+
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "StartPre",
[SOCKET_EXEC_START_CHOWN] = "StartChown",
@@ -2795,6 +2917,8 @@ static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
[SOCKET_FAILURE_EXIT_CODE] = "exit-code",
[SOCKET_FAILURE_SIGNAL] = "signal",
[SOCKET_FAILURE_CORE_DUMP] = "core-dump",
+ [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
+ [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit",
[SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit"
};
@@ -2843,6 +2967,8 @@ const UnitVTable socket_vtable = {
.reset_failed = socket_reset_failed,
+ .control_pid = socket_control_pid,
+
.bus_vtable = bus_socket_vtable,
.bus_set_property = bus_socket_set_property,
.bus_commit_properties = bus_socket_commit_properties,
diff --git a/src/libcore/socket.h b/src/libcore/socket.h
index b537b026a7..0f1ac69c6f 100644
--- a/src/libcore/socket.h
+++ b/src/libcore/socket.h
@@ -52,6 +52,8 @@ typedef enum SocketResult {
SOCKET_FAILURE_EXIT_CODE,
SOCKET_FAILURE_SIGNAL,
SOCKET_FAILURE_CORE_DUMP,
+ SOCKET_FAILURE_START_LIMIT_HIT,
+ SOCKET_FAILURE_TRIGGER_LIMIT_HIT,
SOCKET_FAILURE_SERVICE_START_LIMIT_HIT,
_SOCKET_RESULT_MAX,
_SOCKET_RESULT_INVALID = -1
@@ -156,6 +158,8 @@ struct Socket {
bool reset_cpu_usage:1;
char *fdname;
+
+ RateLimit trigger_limit;
};
/* Called from the service code when collecting fds */
diff --git a/src/libcore/swap.c b/src/libcore/swap.c
index 1bf0c0a808..a532b15be8 100644
--- a/src/libcore/swap.c
+++ b/src/libcore/swap.c
@@ -198,7 +198,7 @@ static int swap_add_device_links(Swap *s) {
return 0;
if (is_device_path(s->what))
- return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == MANAGER_SYSTEM, UNIT_BINDS_TO);
+ return unit_add_node_link(UNIT(s), s->what, MANAGER_IS_SYSTEM(UNIT(s)->manager), UNIT_BINDS_TO);
else
/* File based swap devices need to be ordered after
* systemd-remount-fs.service, since they might need a
@@ -214,7 +214,7 @@ static int swap_add_default_dependencies(Swap *s) {
if (!UNIT(s)->default_dependencies)
return 0;
- if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(UNIT(s)->manager))
return 0;
if (detect_container() > 0)
@@ -609,7 +609,6 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
.apply_permissions = true,
.apply_chroot = true,
.apply_tty_stdin = true,
- .bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
@@ -815,6 +814,7 @@ fail:
static int swap_start(Unit *u) {
Swap *s = SWAP(u), *other;
+ int r;
assert(s);
@@ -843,6 +843,12 @@ static int swap_start(Unit *u) {
if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
return -EAGAIN;
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
s->result = SWAP_SUCCESS;
s->reset_cpu_usage = true;
@@ -1427,6 +1433,14 @@ static bool swap_supported(void) {
return supported;
}
+static int swap_control_pid(Unit *u) {
+ Swap *s = SWAP(u);
+
+ assert(s);
+
+ return s->control_pid;
+}
+
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
[SWAP_EXEC_ACTIVATE] = "ExecActivate",
[SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
@@ -1440,7 +1454,8 @@ static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
[SWAP_FAILURE_TIMEOUT] = "timeout",
[SWAP_FAILURE_EXIT_CODE] = "exit-code",
[SWAP_FAILURE_SIGNAL] = "signal",
- [SWAP_FAILURE_CORE_DUMP] = "core-dump"
+ [SWAP_FAILURE_CORE_DUMP] = "core-dump",
+ [SWAP_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
@@ -1458,9 +1473,6 @@ const UnitVTable swap_vtable = {
"Install\0",
.private_section = "Swap",
- .no_alias = true,
- .no_instances = true,
-
.init = swap_init,
.load = swap_load,
.done = swap_done,
@@ -1488,6 +1500,8 @@ const UnitVTable swap_vtable = {
.reset_failed = swap_reset_failed,
+ .control_pid = swap_control_pid,
+
.bus_vtable = bus_swap_vtable,
.bus_set_property = bus_swap_set_property,
.bus_commit_properties = bus_swap_commit_properties,
diff --git a/src/libcore/swap.h b/src/libcore/swap.h
index ac7a63d81b..fbf66debdc 100644
--- a/src/libcore/swap.h
+++ b/src/libcore/swap.h
@@ -38,6 +38,7 @@ typedef enum SwapResult {
SWAP_FAILURE_EXIT_CODE,
SWAP_FAILURE_SIGNAL,
SWAP_FAILURE_CORE_DUMP,
+ SWAP_FAILURE_START_LIMIT_HIT,
_SWAP_RESULT_MAX,
_SWAP_RESULT_INVALID = -1
} SwapResult;
diff --git a/src/libcore/timer.c b/src/libcore/timer.c
index 3d0bae16e5..3206296f09 100644
--- a/src/libcore/timer.c
+++ b/src/libcore/timer.c
@@ -109,7 +109,7 @@ static int timer_add_default_dependencies(Timer *t) {
if (r < 0)
return r;
- if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
if (r < 0)
return r;
@@ -135,7 +135,7 @@ static int timer_setup_persistent(Timer *t) {
if (!t->persistent)
return 0;
- if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) {
+ if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
if (r < 0)
@@ -320,7 +320,7 @@ static usec_t monotonic_to_boottime(usec_t t) {
if (t <= 0)
return 0;
- a = now(CLOCK_BOOTTIME);
+ a = now(clock_boottime_or_monotonic());
b = now(CLOCK_MONOTONIC);
if (t + a > b)
@@ -373,7 +373,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
* rather than the monotonic clock. */
ts_realtime = now(CLOCK_REALTIME);
- ts_monotonic = now(t->wake_system ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
+ ts_monotonic = now(t->wake_system ? clock_boottime_or_monotonic() : CLOCK_MONOTONIC);
t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
LIST_FOREACH(value, v, t->values) {
@@ -599,6 +599,7 @@ static int timer_start(Unit *u) {
Timer *t = TIMER(u);
TimerValue *v;
Unit *trigger;
+ int r;
assert(t);
assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
@@ -609,6 +610,12 @@ static int timer_start(Unit *u) {
return -ENOENT;
}
+ r = unit_start_limit_test(u);
+ if (r < 0) {
+ timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
t->last_trigger = DUAL_TIMESTAMP_NULL;
/* Reenable all timers that depend on unit activation time */
@@ -808,7 +815,8 @@ DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
[TIMER_SUCCESS] = "success",
- [TIMER_FAILURE_RESOURCES] = "resources"
+ [TIMER_FAILURE_RESOURCES] = "resources",
+ [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult);
diff --git a/src/libcore/timer.h b/src/libcore/timer.h
index 698e6da2f5..9c4b64f898 100644
--- a/src/libcore/timer.h
+++ b/src/libcore/timer.h
@@ -48,6 +48,7 @@ typedef struct TimerValue {
typedef enum TimerResult {
TIMER_SUCCESS,
TIMER_FAILURE_RESOURCES,
+ TIMER_FAILURE_START_LIMIT_HIT,
_TIMER_RESULT_MAX,
_TIMER_RESULT_INVALID = -1
} TimerResult;
diff --git a/src/libcore/transaction.c b/src/libcore/transaction.c
index b28fc76785..e06a48a2f1 100644
--- a/src/libcore/transaction.c
+++ b/src/libcore/transaction.c
@@ -391,6 +391,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
if (delete) {
+ const char *status;
/* logging for j not k here here to provide consistent narrative */
log_unit_warning(j->unit,
"Breaking ordering cycle by deleting job %s/%s",
@@ -399,7 +400,13 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
"Job %s/%s deleted to break ordering cycle starting with %s/%s",
delete->unit->id, job_type_to_string(delete->type),
j->unit->id, job_type_to_string(j->type));
- unit_status_printf(delete->unit, ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL,
+
+ if (log_get_show_color())
+ status = ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL;
+ else
+ status = " SKIP ";
+
+ unit_status_printf(delete->unit, status,
"Ordering cycle found, skipping %s");
transaction_delete_unit(tr, delete->unit);
return -EAGAIN;
@@ -590,7 +597,7 @@ static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) {
/* Not invalidating recursively. Avoids triggering
* OnFailure= actions of dependent jobs. Also avoids
* invalidating our iterator. */
- job_finish_and_invalidate(j, JOB_CANCELED, false);
+ job_finish_and_invalidate(j, JOB_CANCELED, false, false);
}
}
@@ -848,7 +855,7 @@ int transaction_add_job_and_dependencies(
* This matters when jobs are spawned as part of coldplugging itself (see e. g. path_coldplug()).
* This way, we "recursively" coldplug units, ensuring that we do not look at state of
* not-yet-coldplugged units. */
- if (unit->manager->n_reloading > 0)
+ if (MANAGER_IS_RELOADING(unit->manager))
unit_coldplug(unit);
/* log_debug("Pulling in %s/%s from %s/%s", */
@@ -932,7 +939,7 @@ int transaction_add_job_and_dependencies(
if (r < 0) {
/* unit masked, job type not applicable and unit not found are not considered as errors. */
log_unit_full(dep,
- IN_SET(r, -ESHUTDOWN, -EBADR, -ENOENT) ? LOG_DEBUG : LOG_WARNING,
+ IN_SET(r, -ERFKILL, -EBADR, -ENOENT) ? LOG_DEBUG : LOG_WARNING,
r, "Cannot add dependency job, ignoring: %s",
bus_error_message(e, r));
sd_bus_error_free(e);
diff --git a/src/libcore/umount.c b/src/libcore/umount.c
index a458768e7d..c21a2be54e 100644
--- a/src/libcore/umount.c
+++ b/src/libcore/umount.c
@@ -412,6 +412,7 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
#ifndef HAVE_SPLIT_USR
|| path_equal(m->path, "/usr")
#endif
+ || path_startswith(m->path, "/run/initramfs")
)
continue;
@@ -472,7 +473,7 @@ static int loopback_points_list_detach(MountPoint **head, bool *changed) {
major(root_st.st_dev) != 0 &&
lstat(m->path, &loopback_st) >= 0 &&
root_st.st_dev == loopback_st.st_rdev) {
- n_failed ++;
+ n_failed++;
continue;
}
@@ -507,7 +508,7 @@ static int dm_points_list_detach(MountPoint **head, bool *changed) {
if (k >= 0 &&
major(root_st.st_dev) != 0 &&
root_st.st_dev == m->devnum) {
- n_failed ++;
+ n_failed++;
continue;
}
diff --git a/src/libcore/unit-printf.c b/src/libcore/unit-printf.c
index fc057d965c..f11df42af3 100644
--- a/src/libcore/unit-printf.c
+++ b/src/libcore/unit-printf.c
@@ -140,14 +140,9 @@ static int specifier_runtime(char specifier, void *data, void *userdata, char **
assert(u);
- if (u->manager->running_as == MANAGER_SYSTEM)
- e = "/run";
- else {
- e = getenv("XDG_RUNTIME_DIR");
- if (!e)
- return -EOPNOTSUPP;
- }
-
+ e = manager_get_runtime_prefix(u->manager);
+ if (!e)
+ return -EOPNOTSUPP;
n = strdup(e);
if (!n)
return -ENOMEM;
diff --git a/src/libcore/unit.c b/src/libcore/unit.c
index 4f7c0e2449..8bd39f87f9 100644
--- a/src/libcore/unit.c
+++ b/src/libcore/unit.c
@@ -47,11 +47,13 @@
#include "path-util.h"
#include "process-util.h"
#include "set.h"
+#include "signal-util.h"
#include "special.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
+#include "umask-util.h"
#include "unit-name.h"
#include "unit.h"
#include "user-util.h"
@@ -130,6 +132,7 @@ static void unit_init(Unit *u) {
* been initialized */
cc->cpu_accounting = u->manager->default_cpu_accounting;
+ cc->io_accounting = u->manager->default_io_accounting;
cc->blockio_accounting = u->manager->default_blockio_accounting;
cc->memory_accounting = u->manager->default_memory_accounting;
cc->tasks_accounting = u->manager->default_tasks_accounting;
@@ -191,7 +194,7 @@ int unit_add_name(Unit *u, const char *text) {
if (r < 0)
return r;
- if (i && unit_vtable[t]->no_instances)
+ if (i && !unit_type_may_template(t))
return -EINVAL;
/* Ensure that this unit is either instanced or not instanced,
@@ -200,7 +203,7 @@ int unit_add_name(Unit *u, const char *text) {
if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i)
return -EINVAL;
- if (unit_vtable[t]->no_alias && !set_isempty(u->names))
+ if (!unit_type_may_alias(t) && !set_isempty(u->names))
return -EEXIST;
if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES)
@@ -364,7 +367,7 @@ void unit_add_to_gc_queue(Unit *u) {
LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
u->in_gc_queue = true;
- u->manager->n_in_gc_queue ++;
+ u->manager->n_in_gc_queue++;
}
void unit_add_to_dbus_queue(Unit *u) {
@@ -418,13 +421,22 @@ static void unit_remove_transient(Unit *u) {
(void) unlink(u->fragment_path);
STRV_FOREACH(i, u->dropin_paths) {
- _cleanup_free_ char *p = NULL;
+ _cleanup_free_ char *p = NULL, *pp = NULL;
- (void) unlink(*i);
+ p = dirname_malloc(*i); /* Get the drop-in directory from the drop-in file */
+ if (!p)
+ continue;
+
+ pp = dirname_malloc(p); /* Get the config directory from the drop-in directory */
+ if (!pp)
+ continue;
- p = dirname_malloc(*i);
- if (p)
- (void) rmdir(p);
+ /* Only drop transient drop-ins */
+ if (!path_equal(u->manager->lookup_paths.transient, pp))
+ continue;
+
+ (void) unlink(*i);
+ (void) rmdir(p);
}
}
@@ -483,7 +495,10 @@ void unit_free(Unit *u) {
assert(u);
- if (u->manager->n_reloading <= 0)
+ if (u->transient_file)
+ fclose(u->transient_file);
+
+ if (!MANAGER_IS_RELOADING(u->manager))
unit_remove_transient(u);
bus_unit_send_removed_signal(u);
@@ -706,6 +721,9 @@ int unit_merge(Unit *u, Unit *other) {
if (!u->instance != !other->instance)
return -EINVAL;
+ if (!unit_type_may_alias(u->type)) /* Merging only applies to unit names that support aliases */
+ return -EEXIST;
+
if (other->load_state != UNIT_STUB &&
other->load_state != UNIT_NOT_FOUND)
return -EEXIST;
@@ -762,9 +780,9 @@ int unit_merge(Unit *u, Unit *other) {
}
int unit_merge_by_name(Unit *u, const char *name) {
+ _cleanup_free_ char *s = NULL;
Unit *other;
int r;
- _cleanup_free_ char *s = NULL;
assert(u);
assert(name);
@@ -814,7 +832,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
return r;
}
- if (u->manager->running_as != MANAGER_SYSTEM)
+ if (!MANAGER_IS_SYSTEM(u->manager))
return 0;
if (c->private_tmp) {
@@ -888,7 +906,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
"%s\tInstance: %s\n"
"%s\tUnit Load State: %s\n"
"%s\tUnit Active State: %s\n"
- "%s\nState Change Timestamp: %s\n"
+ "%s\tState Change Timestamp: %s\n"
"%s\tInactive Exit Timestamp: %s\n"
"%s\tActive Enter Timestamp: %s\n"
"%s\tActive Exit Timestamp: %s\n"
@@ -1196,6 +1214,7 @@ static int unit_add_startup_units(Unit *u) {
return 0;
if (c->startup_cpu_shares == CGROUP_CPU_SHARES_INVALID &&
+ c->startup_io_weight == CGROUP_WEIGHT_INVALID &&
c->startup_blockio_weight == CGROUP_BLKIO_WEIGHT_INVALID)
return 0;
@@ -1222,6 +1241,17 @@ int unit_load(Unit *u) {
if (u->load_state != UNIT_STUB)
return 0;
+ if (u->transient_file) {
+ r = fflush_and_check(u->transient_file);
+ if (r < 0)
+ goto fail;
+
+ fclose(u->transient_file);
+ u->transient_file = NULL;
+
+ u->fragment_mtime = now(CLOCK_REALTIME);
+ }
+
if (UNIT_VTABLE(u)->load) {
r = UNIT_VTABLE(u)->load(u);
if (r < 0)
@@ -1434,7 +1464,7 @@ void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) {
unit_status_print_starting_stopping(u, t);
}
-static int unit_start_limit_test(Unit *u) {
+int unit_start_limit_test(Unit *u) {
assert(u);
if (ratelimit_test(&u->start_limit)) {
@@ -1460,7 +1490,6 @@ static int unit_start_limit_test(Unit *u) {
int unit_start(Unit *u) {
UnitActiveState state;
Unit *following;
- int r;
assert(u);
@@ -1472,11 +1501,6 @@ int unit_start(Unit *u) {
if (UNIT_IS_ACTIVE_OR_RELOADING(state))
return -EALREADY;
- /* Make sure we don't enter a busy loop of some kind. */
- r = unit_start_limit_test(u);
- if (r < 0)
- return r;
-
/* Units that aren't loaded cannot be started */
if (u->load_state != UNIT_LOADED)
return -EINVAL;
@@ -1834,7 +1858,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
m = u->manager;
/* Update timestamps for state changes */
- if (m->n_reloading <= 0) {
+ if (!MANAGER_IS_RELOADING(m)) {
dual_timestamp_get(&u->state_change_timestamp);
if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
@@ -1864,13 +1888,13 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
ec = unit_get_exec_context(u);
if (ec && exec_context_may_touch_console(ec)) {
if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
- m->n_on_console --;
+ m->n_on_console--;
if (m->n_on_console == 0)
/* unset no_console_output flag, since the console is free */
m->no_console_output = false;
} else
- m->n_on_console ++;
+ m->n_on_console++;
}
}
@@ -1894,12 +1918,12 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
case JOB_VERIFY_ACTIVE:
if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
- job_finish_and_invalidate(u->job, JOB_DONE, true);
+ job_finish_and_invalidate(u->job, JOB_DONE, true, false);
else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
unexpected = true;
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
+ job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false);
}
break;
@@ -1910,12 +1934,12 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
if (u->job->state == JOB_RUNNING) {
if (ns == UNIT_ACTIVE)
- job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
+ job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true, false);
else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
unexpected = true;
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
+ job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false);
}
}
@@ -1926,10 +1950,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
case JOB_TRY_RESTART:
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- job_finish_and_invalidate(u->job, JOB_DONE, true);
+ job_finish_and_invalidate(u->job, JOB_DONE, true, false);
else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
unexpected = true;
- job_finish_and_invalidate(u->job, JOB_FAILED, true);
+ job_finish_and_invalidate(u->job, JOB_FAILED, true, false);
}
break;
@@ -1941,7 +1965,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
} else
unexpected = true;
- if (m->n_reloading <= 0) {
+ if (!MANAGER_IS_RELOADING(m)) {
/* If this state change happened without being
* requested by a job, then let's retroactively start
@@ -1978,7 +2002,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
if (u->type == UNIT_SERVICE &&
!UNIT_IS_ACTIVE_OR_RELOADING(os) &&
- m->n_reloading <= 0) {
+ !MANAGER_IS_RELOADING(m)) {
/* Write audit record if we have just finished starting up */
manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
u->in_audit = true;
@@ -1995,7 +2019,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
if (u->type == UNIT_SERVICE &&
UNIT_IS_INACTIVE_OR_FAILED(ns) &&
!UNIT_IS_INACTIVE_OR_FAILED(os) &&
- m->n_reloading <= 0) {
+ !MANAGER_IS_RELOADING(m)) {
/* Hmm, if there was no start record written
* write it now, so that we always have a nice
@@ -2016,7 +2040,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
manager_recheck_journal(m);
unit_trigger_notify(u);
- if (u->manager->n_reloading <= 0) {
+ if (!MANAGER_IS_RELOADING(u->manager)) {
/* Maybe we finished startup and are now ready for
* being stopped because unneeded? */
unit_check_unneeded(u);
@@ -2378,9 +2402,11 @@ int unit_set_slice(Unit *u, Unit *slice) {
if (UNIT_DEREF(u->slice) == slice)
return 0;
- if (UNIT_ISSET(u->slice))
+ /* Disallow slice changes if @u is already bound to cgroups */
+ if (UNIT_ISSET(u->slice) && u->cgroup_realized)
return -EBUSY;
+ unit_ref_unset(&u->slice);
unit_ref_set(&u->slice, slice);
return 1;
}
@@ -2413,7 +2439,7 @@ int unit_set_default_slice(Unit *u) {
if (!escaped)
return -ENOMEM;
- if (u->manager->running_as == MANAGER_SYSTEM)
+ if (MANAGER_IS_SYSTEM(u->manager))
b = strjoin("system-", escaped, ".slice", NULL);
else
b = strappend(escaped, ".slice");
@@ -2423,7 +2449,7 @@ int unit_set_default_slice(Unit *u) {
slice_name = b;
} else
slice_name =
- u->manager->running_as == MANAGER_SYSTEM && !unit_has_name(u, SPECIAL_INIT_SCOPE)
+ MANAGER_IS_SYSTEM(u->manager) && !unit_has_name(u, SPECIAL_INIT_SCOPE)
? SPECIAL_SYSTEM_SLICE
: SPECIAL_ROOT_SLICE;
@@ -2493,12 +2519,11 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
return -EBUSY;
match = strjoina("type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged',"
- "arg0='", name, "'",
- NULL);
+ "sender='org.freedesktop.DBus',"
+ "path='/org/freedesktop/DBus',"
+ "interface='org.freedesktop.DBus',"
+ "member='NameOwnerChanged',"
+ "arg0='", name, "'");
return sd_bus_add_match(bus, &u->match_bus_slot, match, signal_name_owner_changed, u);
}
@@ -2884,7 +2909,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep
return r;
r = unit_add_two_dependencies(u, UNIT_AFTER,
- u->manager->running_as == MANAGER_SYSTEM ? dep : UNIT_WANTS,
+ MANAGER_IS_SYSTEM(u->manager) ? dep : UNIT_WANTS,
device, true);
if (r < 0)
return r;
@@ -2924,59 +2949,47 @@ int unit_coldplug(Unit *u) {
return 0;
}
-bool unit_need_daemon_reload(Unit *u) {
- _cleanup_strv_free_ char **t = NULL;
- char **path;
+static bool fragment_mtime_newer(const char *path, usec_t mtime) {
struct stat st;
- unsigned loaded_cnt, current_cnt;
- assert(u);
+ if (!path)
+ return false;
- if (u->fragment_path) {
- zero(st);
- if (stat(u->fragment_path, &st) < 0)
- /* What, cannot access this anymore? */
- return true;
+ if (stat(path, &st) < 0)
+ /* What, cannot access this anymore? */
+ return true;
- if (u->fragment_mtime > 0 &&
- timespec_load(&st.st_mtim) != u->fragment_mtime)
- return true;
- }
+ if (mtime > 0)
+ /* For non-empty files check the mtime */
+ return timespec_load(&st.st_mtim) > mtime;
+ else if (!null_or_empty(&st))
+ /* For masked files check if they are still so */
+ return true;
- if (u->source_path) {
- zero(st);
- if (stat(u->source_path, &st) < 0)
- return true;
+ return false;
+}
- if (u->source_mtime > 0 &&
- timespec_load(&st.st_mtim) != u->source_mtime)
- return true;
- }
+bool unit_need_daemon_reload(Unit *u) {
+ _cleanup_strv_free_ char **t = NULL;
+ char **path;
- (void) unit_find_dropin_paths(u, &t);
- loaded_cnt = strv_length(t);
- current_cnt = strv_length(u->dropin_paths);
+ assert(u);
- if (loaded_cnt == current_cnt) {
- if (loaded_cnt == 0)
- return false;
+ if (fragment_mtime_newer(u->fragment_path, u->fragment_mtime))
+ return true;
- if (strv_overlap(u->dropin_paths, t)) {
- STRV_FOREACH(path, u->dropin_paths) {
- zero(st);
- if (stat(*path, &st) < 0)
- return true;
+ if (fragment_mtime_newer(u->source_path, u->source_mtime))
+ return true;
- if (u->dropin_mtime > 0 &&
- timespec_load(&st.st_mtim) > u->dropin_mtime)
- return true;
- }
+ (void) unit_find_dropin_paths(u, &t);
+ if (!strv_equal(u->dropin_paths, t))
+ return true;
- return false;
- } else
+ STRV_FOREACH(path, u->dropin_paths)
+ if (fragment_mtime_newer(*path, u->dropin_mtime))
return true;
- } else
- return true;
+
+ return false;
}
void unit_reset_failed(Unit *u) {
@@ -3044,8 +3057,7 @@ bool unit_active_or_pending(Unit *u) {
int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
assert(u);
assert(w >= 0 && w < _KILL_WHO_MAX);
- assert(signo > 0);
- assert(signo < _NSIG);
+ assert(SIGNAL_VALID(signo));
if (!UNIT_VTABLE(u)->kill)
return -EOPNOTSUPP;
@@ -3162,7 +3174,7 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
if (u->unit_file_state < 0 && u->fragment_path) {
r = unit_file_get_state(
- u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
+ u->manager->unit_file_scope,
NULL,
basename(u->fragment_path),
&u->unit_file_state);
@@ -3178,7 +3190,7 @@ int unit_get_unit_file_preset(Unit *u) {
if (u->unit_file_preset < 0 && u->fragment_path)
u->unit_file_preset = unit_file_query_preset(
- u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
+ u->manager->unit_file_scope,
NULL,
basename(u->fragment_path));
@@ -3203,6 +3215,10 @@ void unit_ref_unset(UnitRef *ref) {
if (!ref->unit)
return;
+ /* We are about to drop a reference to the unit, make sure the garbage collection has a look at it as it might
+ * be unreferenced now. */
+ unit_add_to_gc_queue(ref->unit);
+
LIST_REMOVE(refs, ref->unit->refs, ref);
ref->unit = NULL;
}
@@ -3229,7 +3245,7 @@ int unit_patch_contexts(Unit *u) {
return -ENOMEM;
}
- if (u->manager->running_as == MANAGER_USER &&
+ if (MANAGER_IS_USER(u->manager) &&
!ec->working_directory) {
r = get_home_dir(&ec->working_directory);
@@ -3241,7 +3257,7 @@ int unit_patch_contexts(Unit *u) {
ec->working_directory_missing_ok = true;
}
- if (u->manager->running_as == MANAGER_USER &&
+ if (MANAGER_IS_USER(u->manager) &&
(ec->syscall_whitelist ||
!set_isempty(ec->syscall_filter) ||
!set_isempty(ec->syscall_archs) ||
@@ -3319,59 +3335,62 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) {
return *(ExecRuntime**) ((uint8_t*) u + offset);
}
-static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
+static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) {
assert(u);
- if (u->manager->running_as == MANAGER_USER) {
- int r;
+ if (!IN_SET(mode, UNIT_RUNTIME, UNIT_PERSISTENT))
+ return NULL;
- if (mode == UNIT_PERSISTENT && !transient)
- r = user_config_home(dir);
- else
- r = user_runtime_dir(dir);
- if (r == 0)
- return -ENOENT;
+ if (u->transient) /* Redirect drop-ins for transient units always into the transient directory. */
+ return u->manager->lookup_paths.transient;
- return r;
- }
+ if (mode == UNIT_RUNTIME)
+ return u->manager->lookup_paths.runtime_control;
- if (mode == UNIT_PERSISTENT && !transient)
- *dir = strdup("/etc/systemd/system");
- else
- *dir = strdup("/run/systemd/system");
- if (!*dir)
- return -ENOMEM;
+ if (mode == UNIT_PERSISTENT)
+ return u->manager->lookup_paths.persistent_control;
- return 0;
+ return NULL;
}
int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
-
- _cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL;
+ _cleanup_free_ char *p = NULL, *q = NULL;
+ const char *dir, *prefixed;
int r;
assert(u);
+ if (u->transient_file) {
+ /* When this is a transient unit file in creation, then let's not create a new drop-in but instead
+ * write to the transient unit file. */
+ fputs(data, u->transient_file);
+ return 0;
+ }
+
if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
return 0;
- r = unit_drop_in_dir(u, mode, u->transient, &dir);
- if (r < 0)
- return r;
+ dir = unit_drop_in_dir(u, mode);
+ if (!dir)
+ return -EINVAL;
+
+ prefixed = strjoina("# This is a drop-in unit file extension, created via \"systemctl set-property\" or an equivalent operation. Do not edit.\n",
+ data);
- r = write_drop_in(dir, u->id, 50, name, data);
+ r = drop_in_file(dir, u->id, 50, name, &p, &q);
if (r < 0)
return r;
- r = drop_in_file(dir, u->id, 50, name, &p, &q);
+ (void) mkdir_p(p, 0755);
+ r = write_string_file_atomic_label(q, prefixed);
if (r < 0)
return r;
- r = strv_extend(&u->dropin_paths, q);
+ r = strv_push(&u->dropin_paths, q);
if (r < 0)
return r;
+ q = NULL;
- strv_sort(u->dropin_paths);
strv_uniq(u->dropin_paths);
u->dropin_mtime = now(CLOCK_REALTIME);
@@ -3402,7 +3421,7 @@ int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *n
}
int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
- _cleanup_free_ char *ndata = NULL;
+ const char *ndata;
assert(u);
assert(name);
@@ -3414,9 +3433,7 @@ int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *
if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
return 0;
- ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
- if (!ndata)
- return -ENOMEM;
+ ndata = strjoina("[", UNIT_VTABLE(u)->private_section, "]\n", data);
return unit_write_drop_in(u, mode, name, ndata);
}
@@ -3444,24 +3461,51 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const
}
int unit_make_transient(Unit *u) {
+ FILE *f;
+ char *path;
+
assert(u);
if (!UNIT_VTABLE(u)->can_transient)
return -EOPNOTSUPP;
- u->load_state = UNIT_STUB;
- u->load_error = 0;
- u->transient = true;
+ path = strjoin(u->manager->lookup_paths.transient, "/", u->id, NULL);
+ if (!path)
+ return -ENOMEM;
+
+ /* Let's open the file we'll write the transient settings into. This file is kept open as long as we are
+ * creating the transient, and is closed in unit_load(), as soon as we start loading the file. */
+
+ RUN_WITH_UMASK(0022) {
+ f = fopen(path, "we");
+ if (!f) {
+ free(path);
+ return -errno;
+ }
+ }
+
+ if (u->transient_file)
+ fclose(u->transient_file);
+ u->transient_file = f;
+
+ free(u->fragment_path);
+ u->fragment_path = path;
- u->fragment_path = mfree(u->fragment_path);
u->source_path = mfree(u->source_path);
u->dropin_paths = strv_free(u->dropin_paths);
u->fragment_mtime = u->source_mtime = u->dropin_mtime = 0;
+ u->load_state = UNIT_STUB;
+ u->load_error = 0;
+ u->transient = true;
+
unit_add_to_dbus_queue(u);
unit_add_to_gc_queue(u);
unit_add_to_load_queue(u);
+ fputs("# This is a transient unit file, created programmatically via the systemd API. Do not edit.\n",
+ u->transient_file);
+
return 0;
}
@@ -3553,7 +3597,7 @@ int unit_kill_context(
* cases. It doesn't work at all in
* containers, and outside of containers it
* can be confused easily by left-over
- * directories in the cgroup -- which however
+ * directories in the cgroup — which however
* should not exist in non-delegated units. On
* the unified hierarchy that's different,
* there we get proper events. Hence rely on
@@ -3754,3 +3798,21 @@ bool unit_is_pristine(Unit *u) {
u->job ||
u->merged_into);
}
+
+pid_t unit_control_pid(Unit *u) {
+ assert(u);
+
+ if (UNIT_VTABLE(u)->control_pid)
+ return UNIT_VTABLE(u)->control_pid(u);
+
+ return 0;
+}
+
+pid_t unit_main_pid(Unit *u) {
+ assert(u);
+
+ if (UNIT_VTABLE(u)->main_pid)
+ return UNIT_VTABLE(u)->main_pid(u);
+
+ return 0;
+}
diff --git a/src/libcore/unit.h b/src/libcore/unit.h
index 601e763ce2..08a927962d 100644
--- a/src/libcore/unit.h
+++ b/src/libcore/unit.h
@@ -95,6 +95,9 @@ struct Unit {
usec_t source_mtime;
usec_t dropin_mtime;
+ /* If this is a transient unit we are currently writing, this is where we are writing it to */
+ FILE *transient_file;
+
/* If there is something to do with this unit, then this is the installed job for it */
Job *job;
@@ -183,6 +186,7 @@ struct Unit {
/* Counterparts in the cgroup filesystem */
char *cgroup_path;
CGroupMask cgroup_realized_mask;
+ CGroupMask cgroup_enabled_mask;
CGroupMask cgroup_subtree_mask;
CGroupMask cgroup_members_mask;
int cgroup_inotify_wd;
@@ -387,6 +391,12 @@ struct UnitVTable {
/* Returns the next timeout of a unit */
int (*get_timeout)(Unit *u, usec_t *timeout);
+ /* Returns the main PID if there is any defined, or 0. */
+ pid_t (*main_pid)(Unit *u);
+
+ /* Returns the main PID if there is any defined, or 0. */
+ pid_t (*control_pid)(Unit *u);
+
/* This is called for each unit type and should be used to
* enumerate existing devices and load them. However,
* everything that is loaded here should still stay in
@@ -407,12 +417,6 @@ struct UnitVTable {
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;
- /* Can units of this type have multiple names? */
- bool no_alias:1;
-
- /* Instances make no sense for this type */
- bool no_instances:1;
-
/* True if transient units of this type are OK */
bool can_transient:1;
};
@@ -598,6 +602,9 @@ bool unit_type_supported(UnitType t);
bool unit_is_pristine(Unit *u);
+pid_t unit_control_pid(Unit *u);
+pid_t unit_main_pid(Unit *u);
+
static inline bool unit_supported(Unit *u) {
return unit_type_supported(u->type);
}
@@ -605,6 +612,8 @@ static inline bool unit_supported(Unit *u) {
void unit_warn_if_dir_nonempty(Unit *u, const char* where);
int unit_fail_if_symlink(Unit *u, const char* where);
+int unit_start_limit_test(Unit *u);
+
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_unit_full(unit, level, error, ...) \
diff --git a/src/libfirewall/firewall-util.c b/src/libfirewall/firewall-util.c
index 0d3da2e6d2..f73108eaa3 100644
--- a/src/libfirewall/firewall-util.c
+++ b/src/libfirewall/firewall-util.c
@@ -17,14 +17,22 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#warning "Temporary work-around for broken glibc vs. linux kernel header definitions"
+#warning "This really should be removed sooner rather than later, when this is fixed upstream"
+#define _NET_IF_H 1
+
#include <alloca.h>
#include <arpa/inet.h>
#include <endian.h>
#include <errno.h>
-#include <net/if.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
+#include <net/if.h>
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+#include <linux/if.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter/nf_nat.h>
#include <linux/netfilter/xt_addrtype.h>
@@ -34,6 +42,7 @@
#include "firewall-util.h"
#include "in-addr-util.h"
#include "macro.h"
+#include "socket-util.h"
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xtc_handle*, iptc_free);
@@ -49,10 +58,9 @@ static int entry_fill_basics(
assert(entry);
- if (out_interface && strlen(out_interface) >= IFNAMSIZ)
+ if (out_interface && !ifname_valid(out_interface))
return -EINVAL;
-
- if (in_interface && strlen(in_interface) >= IFNAMSIZ)
+ if (in_interface && !ifname_valid(in_interface))
return -EINVAL;
entry->ip.proto = protocol;
diff --git a/src/libshared/Makefile b/src/libshared/Makefile
index f6d3c87e42..778a6ec0ec 100644
--- a/src/libshared/Makefile
+++ b/src/libshared/Makefile
@@ -30,14 +30,13 @@ libshared_la_SOURCES = \
src/libsystemd/sd-netlink/local-addresses.h \
src/libsystemd/sd-netlink/local-addresses.c \
src/shared/output-mode.h \
+ src/shared/output-mode.c \
src/shared/gpt.h \
src/shared/udev-util.h \
src/shared/linux/auto_dev-ioctl.h \
src/shared/initreq.h \
src/shared/dns-domain.c \
src/shared/dns-domain.h \
- src/shared/architecture.c \
- src/shared/architecture.h \
src/shared/efivars.c \
src/shared/efivars.h \
src/shared/fstab-util.c \
@@ -106,7 +105,11 @@ libshared_la_SOURCES = \
src/shared/machine-pool.c \
src/shared/machine-pool.h \
src/shared/resolve-util.c \
- src/shared/resolve-util.h
+ src/shared/resolve-util.h \
+ src/shared/bus-unit-util.c \
+ src/shared/bus-unit-util.h \
+ src/shared/tests.h \
+ src/shared/tests.c
ifneq ($(HAVE_UTMP),)
libshared_la_SOURCES += \
diff --git a/src/libshared/acpi-fpdt.c b/src/libshared/acpi-fpdt.c
index 3cb9e781fd..6779691c28 100644
--- a/src/libshared/acpi-fpdt.c
+++ b/src/libshared/acpi-fpdt.c
@@ -119,7 +119,7 @@ int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) {
}
if (ptr == 0)
- return -EINVAL;
+ return -ENODATA;
/* read Firmware Basic Boot Performance Data Record */
fd = open("/dev/mem", O_CLOEXEC|O_RDONLY);
@@ -146,6 +146,10 @@ int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) {
if (brec.type != ACPI_FPDT_BOOT_REC)
return -EINVAL;
+ if (brec.exit_services_exit == 0)
+ /* Non-UEFI compatible boot. */
+ return -ENODATA;
+
if (brec.startup_start == 0 || brec.exit_services_exit < brec.startup_start)
return -EINVAL;
if (brec.exit_services_exit > NSEC_PER_HOUR)
diff --git a/src/libshared/ask-password-api.c b/src/libshared/ask-password-api.c
index 6805873f9e..4a4bd8d3b8 100644
--- a/src/libshared/ask-password-api.c
+++ b/src/libshared/ask-password-api.c
@@ -431,7 +431,7 @@ static int create_socket(char **name) {
snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%" PRIx64, random_u64());
RUN_WITH_UMASK(0177) {
- if (bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return -errno;
}
diff --git a/src/libshared/bus-unit-util.c b/src/libshared/bus-unit-util.c
new file mode 100644
index 0000000000..f68c4a41ac
--- /dev/null
+++ b/src/libshared/bus-unit-util.c
@@ -0,0 +1,1307 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "bus-internal.h"
+#include "bus-unit-util.h"
+#include "bus-util.h"
+#include "cgroup-util.h"
+#include "env-util.h"
+#include "escape.h"
+#include "hashmap.h"
+#include "list.h"
+#include "locale-util.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "process-util.h"
+#include "rlimit-util.h"
+#include "signal-util.h"
+#include "string-util.h"
+#include "syslog-util.h"
+#include "terminal-util.h"
+#include "utf8.h"
+#include "util.h"
+
+int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
+ assert(message);
+ assert(u);
+
+ u->machine = NULL;
+
+ return sd_bus_message_read(
+ message,
+ "(ssssssouso)",
+ &u->id,
+ &u->description,
+ &u->load_state,
+ &u->active_state,
+ &u->sub_state,
+ &u->following,
+ &u->unit_path,
+ &u->job_id,
+ &u->job_type,
+ &u->job_path);
+}
+
+int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
+ const char *eq, *field;
+ int r, rl;
+
+ assert(m);
+ assert(assignment);
+
+ eq = strchr(assignment, '=');
+ if (!eq) {
+ log_error("Not an assignment: %s", assignment);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ field = strndupa(assignment, eq - assignment);
+ eq++;
+
+ if (streq(field, "CPUQuota")) {
+
+ if (isempty(eq))
+ r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
+ else if (endswith(eq, "%")) {
+ double percent;
+
+ if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
+ log_error("CPU quota '%s' invalid.", eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100);
+ } else {
+ log_error("CPU quota needs to be in percent.");
+ return -EINVAL;
+ }
+
+ goto finish;
+
+ } else if (streq(field, "EnvironmentFile")) {
+
+ r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
+ eq[0] == '-' ? eq + 1 : eq,
+ eq[0] == '-');
+ goto finish;
+
+ } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec", "RuntimeMaxSec")) {
+ char *n;
+ usec_t t;
+ size_t l;
+ r = parse_sec(eq, &t);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
+
+ l = strlen(field);
+ n = newa(char, l + 2);
+ if (!n)
+ return log_oom();
+
+ /* Change suffix Sec → USec */
+ strcpy(mempcpy(n, field, l - 3), "USec");
+ r = sd_bus_message_append(m, "sv", n, "t", t);
+ goto finish;
+ }
+
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ rl = rlimit_from_string(field);
+ if (rl >= 0) {
+ const char *sn;
+ struct rlimit l;
+
+ r = rlimit_parse(rl, eq, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse resource limit: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "t", l.rlim_max);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ sn = strjoina(field, "Soft");
+ r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur);
+
+ } else if (STR_IN_SET(field,
+ "CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting", "TasksAccounting",
+ "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
+ "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
+ "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges",
+ "SyslogLevelPrefix", "Delegate", "RemainAfterElapse")) {
+
+ r = parse_boolean(eq);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse boolean assignment %s.", assignment);
+
+ r = sd_bus_message_append(m, "v", "b", r);
+
+ } else if (streq(field, "MemoryLimit")) {
+ uint64_t bytes;
+
+ if (isempty(eq) || streq(eq, "infinity"))
+ bytes = (uint64_t) -1;
+ else {
+ r = parse_size(eq, 1024, &bytes);
+ if (r < 0) {
+ log_error("Failed to parse bytes specification %s", assignment);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "t", bytes);
+
+ } else if (streq(field, "TasksMax")) {
+ uint64_t n;
+
+ if (isempty(eq) || streq(eq, "infinity"))
+ n = (uint64_t) -1;
+ else {
+ r = safe_atou64(eq, &n);
+ if (r < 0) {
+ log_error("Failed to parse maximum tasks specification %s", assignment);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "t", n);
+
+ } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) {
+ uint64_t u;
+
+ r = cg_cpu_shares_parse(eq, &u);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "t", u);
+
+ } else if (STR_IN_SET(field, "IOWeight", "StartupIOWeight")) {
+ uint64_t u;
+
+ r = cg_weight_parse(eq, &u);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "t", u);
+
+ } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
+ uint64_t u;
+
+ r = cg_blkio_weight_parse(eq, &u);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "t", u);
+
+ } else if (STR_IN_SET(field,
+ "User", "Group", "DevicePolicy", "KillMode",
+ "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
+ "StandardInput", "StandardOutput", "StandardError",
+ "Description", "Slice", "Type", "WorkingDirectory",
+ "RootDirectory", "SyslogIdentifier", "ProtectSystem",
+ "ProtectHome", "SELinuxContext"))
+ r = sd_bus_message_append(m, "v", "s", eq);
+
+ else if (streq(field, "SyslogLevel")) {
+ int level;
+
+ level = log_level_from_string(eq);
+ if (level < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", level);
+
+ } else if (streq(field, "SyslogFacility")) {
+ int facility;
+
+ facility = log_facility_unshifted_from_string(eq);
+ if (facility < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", facility);
+
+ } else if (streq(field, "DeviceAllow")) {
+
+ if (isempty(eq))
+ r = sd_bus_message_append(m, "v", "a(ss)", 0);
+ else {
+ const char *path, *rwm, *e;
+
+ e = strchr(eq, ' ');
+ if (e) {
+ path = strndupa(eq, e - eq);
+ rwm = e+1;
+ } else {
+ path = eq;
+ rwm = "";
+ }
+
+ if (!path_startswith(path, "/dev")) {
+ log_error("%s is not a device file in /dev.", path);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
+ }
+
+ } else if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
+
+ if (isempty(eq))
+ r = sd_bus_message_append(m, "v", "a(st)", 0);
+ else {
+ const char *path, *bandwidth, *e;
+ uint64_t bytes;
+
+ e = strchr(eq, ' ');
+ if (e) {
+ path = strndupa(eq, e - eq);
+ bandwidth = e+1;
+ } else {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ if (!path_startswith(path, "/dev")) {
+ log_error("%s is not a device file in /dev.", path);
+ return -EINVAL;
+ }
+
+ if (streq(bandwidth, "max")) {
+ bytes = CGROUP_LIMIT_MAX;
+ } else {
+ r = parse_size(bandwidth, 1000, &bytes);
+ if (r < 0) {
+ log_error("Failed to parse byte value %s.", bandwidth);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
+ }
+
+ } else if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) {
+
+ if (isempty(eq))
+ r = sd_bus_message_append(m, "v", "a(st)", 0);
+ else {
+ const char *path, *weight, *e;
+ uint64_t u;
+
+ e = strchr(eq, ' ');
+ if (e) {
+ path = strndupa(eq, e - eq);
+ weight = e+1;
+ } else {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ if (!path_startswith(path, "/dev")) {
+ log_error("%s is not a device file in /dev.", path);
+ return -EINVAL;
+ }
+
+ r = safe_atou64(weight, &u);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, weight);
+ return -EINVAL;
+ }
+ r = sd_bus_message_append(m, "v", "a(st)", 1, path, u);
+ }
+
+ } else if (streq(field, "Nice")) {
+ int32_t i;
+
+ r = safe_atoi32(eq, &i);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", i);
+
+ } else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
+ const char *p;
+
+ r = sd_bus_message_open_container(m, 'v', "as");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = eq;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
+ if (r < 0) {
+ log_error("Failed to parse Environment value %s", eq);
+ return -EINVAL;
+ }
+ if (r == 0)
+ break;
+
+ if (streq(field, "Environment")) {
+ if (!env_assignment_is_valid(word)) {
+ log_error("Invalid environment assignment: %s", word);
+ return -EINVAL;
+ }
+ } else { /* PassEnvironment */
+ if (!env_name_is_valid(word)) {
+ log_error("Invalid environment variable name: %s", word);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append_basic(m, 's', word);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+
+ } else if (streq(field, "KillSignal")) {
+ int sig;
+
+ sig = signal_from_string_try_harder(eq);
+ if (sig < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", sig);
+
+ } else if (streq(field, "TimerSlackNSec")) {
+ nsec_t n;
+
+ r = parse_nsec(eq, &n);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "t", n);
+ } else if (streq(field, "OOMScoreAdjust")) {
+ int oa;
+
+ r = safe_atoi(eq, &oa);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ if (!oom_score_adjust_is_valid(oa)) {
+ log_error("OOM score adjust value out of range");
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", oa);
+ } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
+ const char *p;
+
+ r = sd_bus_message_open_container(m, 'v', "as");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = eq;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ int offset;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+ if (r == 0)
+ break;
+
+ if (!utf8_is_valid(word)) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ offset = word[0] == '-';
+ if (!path_is_absolute(word + offset)) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ path_kill_slashes(word + offset);
+
+ r = sd_bus_message_append_basic(m, 's', word);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+
+ } else if (streq(field, "RuntimeDirectory")) {
+ const char *p;
+
+ r = sd_bus_message_open_container(m, 'v', "as");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = eq;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s value %s", field, eq);
+
+ if (r == 0)
+ break;
+
+ r = sd_bus_message_append_basic(m, 's', word);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+
+ } else {
+ log_error("Unknown assignment %s.", assignment);
+ return -EINVAL;
+ }
+
+finish:
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ return 0;
+}
+
+typedef struct BusWaitForJobs {
+ sd_bus *bus;
+ Set *jobs;
+
+ char *name;
+ char *result;
+
+ sd_bus_slot *slot_job_removed;
+ sd_bus_slot *slot_disconnected;
+} BusWaitForJobs;
+
+static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ assert(m);
+
+ log_error("Warning! D-Bus connection terminated.");
+ sd_bus_close(sd_bus_message_get_bus(m));
+
+ return 0;
+}
+
+static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ const char *path, *unit, *result;
+ BusWaitForJobs *d = userdata;
+ uint32_t id;
+ char *found;
+ int r;
+
+ assert(m);
+ assert(d);
+
+ r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
+ if (r < 0) {
+ bus_log_parse_error(r);
+ return 0;
+ }
+
+ found = set_remove(d->jobs, (char*) path);
+ if (!found)
+ return 0;
+
+ free(found);
+
+ if (!isempty(result))
+ d->result = strdup(result);
+
+ if (!isempty(unit))
+ d->name = strdup(unit);
+
+ return 0;
+}
+
+void bus_wait_for_jobs_free(BusWaitForJobs *d) {
+ if (!d)
+ return;
+
+ set_free_free(d->jobs);
+
+ sd_bus_slot_unref(d->slot_disconnected);
+ sd_bus_slot_unref(d->slot_job_removed);
+
+ sd_bus_unref(d->bus);
+
+ free(d->name);
+ free(d->result);
+
+ free(d);
+}
+
+int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
+ _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
+ int r;
+
+ assert(bus);
+ assert(ret);
+
+ d = new0(BusWaitForJobs, 1);
+ if (!d)
+ return -ENOMEM;
+
+ d->bus = sd_bus_ref(bus);
+
+ /* When we are a bus client we match by sender. Direct
+ * connections OTOH have no initialized sender field, and
+ * hence we ignore the sender then */
+ r = sd_bus_add_match(
+ bus,
+ &d->slot_job_removed,
+ bus->bus_client ?
+ "type='signal',"
+ "sender='org.freedesktop.systemd1',"
+ "interface='org.freedesktop.systemd1.Manager',"
+ "member='JobRemoved',"
+ "path='/org/freedesktop/systemd1'" :
+ "type='signal',"
+ "interface='org.freedesktop.systemd1.Manager',"
+ "member='JobRemoved',"
+ "path='/org/freedesktop/systemd1'",
+ match_job_removed, d);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_add_match(
+ bus,
+ &d->slot_disconnected,
+ "type='signal',"
+ "sender='org.freedesktop.DBus.Local',"
+ "interface='org.freedesktop.DBus.Local',"
+ "member='Disconnected'",
+ match_disconnected, d);
+ if (r < 0)
+ return r;
+
+ *ret = d;
+ d = NULL;
+
+ return 0;
+}
+
+static int bus_process_wait(sd_bus *bus) {
+ int r;
+
+ for (;;) {
+ r = sd_bus_process(bus, NULL);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ return 0;
+
+ r = sd_bus_wait(bus, (uint64_t) -1);
+ if (r < 0)
+ return r;
+ }
+}
+
+static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
+ _cleanup_free_ char *dbus_path = NULL;
+
+ assert(d);
+ assert(d->name);
+ assert(result);
+
+ dbus_path = unit_dbus_path_from_name(d->name);
+ if (!dbus_path)
+ return -ENOMEM;
+
+ return sd_bus_get_property_string(d->bus,
+ "org.freedesktop.systemd1",
+ dbus_path,
+ "org.freedesktop.systemd1.Service",
+ "Result",
+ NULL,
+ result);
+}
+
+static const struct {
+ const char *result, *explanation;
+} explanations [] = {
+ { "resources", "of unavailable resources or another system error" },
+ { "timeout", "a timeout was exceeded" },
+ { "exit-code", "the control process exited with error code" },
+ { "signal", "a fatal signal was delivered to the control process" },
+ { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
+ { "watchdog", "the service failed to send watchdog ping" },
+ { "start-limit", "start of the service was attempted too often" }
+};
+
+static void log_job_error_with_service_result(const char* service, const char *result, const char* const* extra_args) {
+ _cleanup_free_ char *service_shell_quoted = NULL;
+ const char *systemctl = "systemctl", *journalctl = "journalctl";
+
+ assert(service);
+
+ service_shell_quoted = shell_maybe_quote(service);
+
+ if (extra_args && extra_args[1]) {
+ _cleanup_free_ char *t;
+
+ t = strv_join((char**) extra_args, " ");
+ systemctl = strjoina("systemctl ", t ? : "<args>");
+ journalctl = strjoina("journalctl ", t ? : "<args>");
+ }
+
+ if (!isempty(result)) {
+ unsigned i;
+
+ for (i = 0; i < ELEMENTSOF(explanations); ++i)
+ if (streq(result, explanations[i].result))
+ break;
+
+ if (i < ELEMENTSOF(explanations)) {
+ log_error("Job for %s failed because %s.\n"
+ "See \"%s status %s\" and \"%s -xe\" for details.\n",
+ service,
+ explanations[i].explanation,
+ systemctl,
+ service_shell_quoted ?: "<service>",
+ journalctl);
+ goto finish;
+ }
+ }
+
+ log_error("Job for %s failed.\n"
+ "See \"%s status %s\" and \"%s -xe\" for details.\n",
+ service,
+ systemctl,
+ service_shell_quoted ?: "<service>",
+ journalctl);
+
+finish:
+ /* For some results maybe additional explanation is required */
+ if (streq_ptr(result, "start-limit"))
+ log_info("To force a start use \"%1$s reset-failed %2$s\"\n"
+ "followed by \"%1$s start %2$s\" again.",
+ systemctl,
+ service_shell_quoted ?: "<service>");
+}
+
+static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const* extra_args) {
+ int r = 0;
+
+ assert(d->result);
+
+ if (!quiet) {
+ if (streq(d->result, "canceled"))
+ log_error("Job for %s canceled.", strna(d->name));
+ else if (streq(d->result, "timeout"))
+ log_error("Job for %s timed out.", strna(d->name));
+ else if (streq(d->result, "dependency"))
+ log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
+ else if (streq(d->result, "invalid"))
+ log_error("%s is not active, cannot reload.", strna(d->name));
+ else if (streq(d->result, "assert"))
+ log_error("Assertion failed on job for %s.", strna(d->name));
+ else if (streq(d->result, "unsupported"))
+ log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
+ else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
+ if (d->name) {
+ int q;
+ _cleanup_free_ char *result = NULL;
+
+ q = bus_job_get_service_result(d, &result);
+ if (q < 0)
+ log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
+
+ log_job_error_with_service_result(d->name, result, extra_args);
+ } else
+ log_error("Job failed. See \"journalctl -xe\" for details.");
+ }
+ }
+
+ if (streq(d->result, "canceled"))
+ r = -ECANCELED;
+ else if (streq(d->result, "timeout"))
+ r = -ETIME;
+ else if (streq(d->result, "dependency"))
+ r = -EIO;
+ else if (streq(d->result, "invalid"))
+ r = -ENOEXEC;
+ else if (streq(d->result, "assert"))
+ r = -EPROTO;
+ else if (streq(d->result, "unsupported"))
+ r = -EOPNOTSUPP;
+ else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
+ r = -EIO;
+
+ return r;
+}
+
+int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char* const* extra_args) {
+ int r = 0;
+
+ assert(d);
+
+ while (!set_isempty(d->jobs)) {
+ int q;
+
+ q = bus_process_wait(d->bus);
+ if (q < 0)
+ return log_error_errno(q, "Failed to wait for response: %m");
+
+ if (d->result) {
+ q = check_wait_response(d, quiet, extra_args);
+ /* Return the first error as it is most likely to be
+ * meaningful. */
+ if (q < 0 && r == 0)
+ r = q;
+
+ log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
+ }
+
+ d->name = mfree(d->name);
+ d->result = mfree(d->result);
+ }
+
+ return r;
+}
+
+int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
+ int r;
+
+ assert(d);
+
+ r = set_ensure_allocated(&d->jobs, &string_hash_ops);
+ if (r < 0)
+ return r;
+
+ return set_put_strdup(d->jobs, path);
+}
+
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
+ int r;
+
+ r = bus_wait_for_jobs_add(d, path);
+ if (r < 0)
+ return log_oom();
+
+ return bus_wait_for_jobs(d, quiet, NULL);
+}
+
+int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
+ const char *type, *path, *source;
+ int r;
+
+ /* changes is dereferenced when calling unit_file_dump_changes() later,
+ * so we have to make sure this is not NULL. */
+ assert(changes);
+ assert(n_changes);
+
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
+ /* We expect only "success" changes to be sent over the bus.
+ Hence, reject anything negative. */
+ UnitFileChangeType ch = unit_file_change_type_from_string(type);
+
+ if (ch < 0) {
+ log_notice("Manager reported unknown change type \"%s\" for path \"%s\", ignoring.", type, path);
+ continue;
+ }
+
+ r = unit_file_changes_add(changes, n_changes, ch, path, source);
+ if (r < 0)
+ return r;
+ }
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ unit_file_dump_changes(0, NULL, *changes, *n_changes, false);
+ return 0;
+}
+
+struct CGroupInfo {
+ char *cgroup_path;
+ bool is_const; /* If false, cgroup_path should be free()'d */
+
+ Hashmap *pids; /* PID → process name */
+ bool done;
+
+ struct CGroupInfo *parent;
+ LIST_FIELDS(struct CGroupInfo, siblings);
+ LIST_HEAD(struct CGroupInfo, children);
+ size_t n_children;
+};
+
+static bool IS_ROOT(const char *p) {
+ return isempty(p) || streq(p, "/");
+}
+
+static int add_cgroup(Hashmap *cgroups, const char *path, bool is_const, struct CGroupInfo **ret) {
+ struct CGroupInfo *parent = NULL, *cg;
+ int r;
+
+ assert(cgroups);
+ assert(ret);
+
+ if (IS_ROOT(path))
+ path = "/";
+
+ cg = hashmap_get(cgroups, path);
+ if (cg) {
+ *ret = cg;
+ return 0;
+ }
+
+ if (!IS_ROOT(path)) {
+ const char *e, *pp;
+
+ e = strrchr(path, '/');
+ if (!e)
+ return -EINVAL;
+
+ pp = strndupa(path, e - path);
+ if (!pp)
+ return -ENOMEM;
+
+ r = add_cgroup(cgroups, pp, false, &parent);
+ if (r < 0)
+ return r;
+ }
+
+ cg = new0(struct CGroupInfo, 1);
+ if (!cg)
+ return -ENOMEM;
+
+ if (is_const)
+ cg->cgroup_path = (char*) path;
+ else {
+ cg->cgroup_path = strdup(path);
+ if (!cg->cgroup_path) {
+ free(cg);
+ return -ENOMEM;
+ }
+ }
+
+ cg->is_const = is_const;
+ cg->parent = parent;
+
+ r = hashmap_put(cgroups, cg->cgroup_path, cg);
+ if (r < 0) {
+ if (!is_const)
+ free(cg->cgroup_path);
+ free(cg);
+ return r;
+ }
+
+ if (parent) {
+ LIST_PREPEND(siblings, parent->children, cg);
+ parent->n_children++;
+ }
+
+ *ret = cg;
+ return 1;
+}
+
+static int add_process(
+ Hashmap *cgroups,
+ const char *path,
+ pid_t pid,
+ const char *name) {
+
+ struct CGroupInfo *cg;
+ int r;
+
+ assert(cgroups);
+ assert(name);
+ assert(pid > 0);
+
+ r = add_cgroup(cgroups, path, true, &cg);
+ if (r < 0)
+ return r;
+
+ r = hashmap_ensure_allocated(&cg->pids, &trivial_hash_ops);
+ if (r < 0)
+ return r;
+
+ return hashmap_put(cg->pids, PID_TO_PTR(pid), (void*) name);
+}
+
+static void remove_cgroup(Hashmap *cgroups, struct CGroupInfo *cg) {
+ assert(cgroups);
+ assert(cg);
+
+ while (cg->children)
+ remove_cgroup(cgroups, cg->children);
+
+ hashmap_remove(cgroups, cg->cgroup_path);
+
+ if (!cg->is_const)
+ free(cg->cgroup_path);
+
+ hashmap_free(cg->pids);
+
+ if (cg->parent)
+ LIST_REMOVE(siblings, cg->parent->children, cg);
+
+ free(cg);
+}
+
+static int cgroup_info_compare_func(const void *a, const void *b) {
+ const struct CGroupInfo *x = *(const struct CGroupInfo* const*) a, *y = *(const struct CGroupInfo* const*) b;
+
+ assert(x);
+ assert(y);
+
+ return strcmp(x->cgroup_path, y->cgroup_path);
+}
+
+static int dump_processes(
+ Hashmap *cgroups,
+ const char *cgroup_path,
+ const char *prefix,
+ unsigned n_columns,
+ OutputFlags flags) {
+
+ struct CGroupInfo *cg;
+ int r;
+
+ assert(prefix);
+
+ if (IS_ROOT(cgroup_path))
+ cgroup_path = "/";
+
+ cg = hashmap_get(cgroups, cgroup_path);
+ if (!cg)
+ return 0;
+
+ if (!hashmap_isempty(cg->pids)) {
+ const char *name;
+ size_t n = 0, i;
+ pid_t *pids;
+ void *pidp;
+ Iterator j;
+ int width;
+
+ /* Order processes by their PID */
+ pids = newa(pid_t, hashmap_size(cg->pids));
+
+ HASHMAP_FOREACH_KEY(name, pidp, cg->pids, j)
+ pids[n++] = PTR_TO_PID(pidp);
+
+ assert(n == hashmap_size(cg->pids));
+ qsort_safe(pids, n, sizeof(pid_t), pid_compare_func);
+
+ width = DECIMAL_STR_WIDTH(pids[n-1]);
+
+ for (i = 0; i < n; i++) {
+ _cleanup_free_ char *e = NULL;
+ const char *special;
+ bool more;
+
+ name = hashmap_get(cg->pids, PID_TO_PTR(pids[i]));
+ assert(name);
+
+ if (n_columns != 0) {
+ unsigned k;
+
+ k = MAX(LESS_BY(n_columns, 2U + width + 1U), 20U);
+
+ e = ellipsize(name, k, 100);
+ if (e)
+ name = e;
+ }
+
+ more = i+1 < n || cg->children;
+ special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
+
+ fprintf(stdout, "%s%s%*"PID_PRI" %s\n",
+ prefix,
+ special,
+ width, pids[i],
+ name);
+ }
+ }
+
+ if (cg->children) {
+ struct CGroupInfo **children, *child;
+ size_t n = 0, i;
+
+ /* Order subcgroups by their name */
+ children = newa(struct CGroupInfo*, cg->n_children);
+ LIST_FOREACH(siblings, child, cg->children)
+ children[n++] = child;
+ assert(n == cg->n_children);
+ qsort_safe(children, n, sizeof(struct CGroupInfo*), cgroup_info_compare_func);
+
+ n_columns = MAX(LESS_BY(n_columns, 2U), 20U);
+
+ for (i = 0; i < n; i++) {
+ _cleanup_free_ char *pp = NULL;
+ const char *name, *special;
+ bool more;
+
+ child = children[i];
+
+ name = strrchr(child->cgroup_path, '/');
+ if (!name)
+ return -EINVAL;
+ name++;
+
+ more = i+1 < n;
+ special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
+
+ fputs(prefix, stdout);
+ fputs(special, stdout);
+ fputs(name, stdout);
+ fputc('\n', stdout);
+
+ special = special_glyph(more ? TREE_VERTICAL : TREE_SPACE);
+
+ pp = strappend(prefix, special);
+ if (!pp)
+ return -ENOMEM;
+
+ r = dump_processes(cgroups, child->cgroup_path, pp, n_columns, flags);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ cg->done = true;
+ return 0;
+}
+
+static int dump_extra_processes(
+ Hashmap *cgroups,
+ const char *prefix,
+ unsigned n_columns,
+ OutputFlags flags) {
+
+ _cleanup_free_ pid_t *pids = NULL;
+ _cleanup_hashmap_free_ Hashmap *names = NULL;
+ struct CGroupInfo *cg;
+ size_t n_allocated = 0, n = 0, k;
+ Iterator i;
+ int width, r;
+
+ /* Prints the extra processes, i.e. those that are in cgroups we haven't displayed yet. We show them as
+ * combined, sorted, linear list. */
+
+ HASHMAP_FOREACH(cg, cgroups, i) {
+ const char *name;
+ void *pidp;
+ Iterator j;
+
+ if (cg->done)
+ continue;
+
+ if (hashmap_isempty(cg->pids))
+ continue;
+
+ r = hashmap_ensure_allocated(&names, &trivial_hash_ops);
+ if (r < 0)
+ return r;
+
+ if (!GREEDY_REALLOC(pids, n_allocated, n + hashmap_size(cg->pids)))
+ return -ENOMEM;
+
+ HASHMAP_FOREACH_KEY(name, pidp, cg->pids, j) {
+ pids[n++] = PTR_TO_PID(pidp);
+
+ r = hashmap_put(names, pidp, (void*) name);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ if (n == 0)
+ return 0;
+
+ qsort_safe(pids, n, sizeof(pid_t), pid_compare_func);
+ width = DECIMAL_STR_WIDTH(pids[n-1]);
+
+ for (k = 0; k < n; k++) {
+ _cleanup_free_ char *e = NULL;
+ const char *name;
+
+ name = hashmap_get(names, PID_TO_PTR(pids[k]));
+ assert(name);
+
+ if (n_columns != 0) {
+ unsigned z;
+
+ z = MAX(LESS_BY(n_columns, 2U + width + 1U), 20U);
+
+ e = ellipsize(name, z, 100);
+ if (e)
+ name = e;
+ }
+
+ fprintf(stdout, "%s%s %*" PID_PRI " %s\n",
+ prefix,
+ special_glyph(TRIANGULAR_BULLET),
+ width, pids[k],
+ name);
+ }
+
+ return 0;
+}
+
+int unit_show_processes(
+ sd_bus *bus,
+ const char *unit,
+ const char *cgroup_path,
+ const char *prefix,
+ unsigned n_columns,
+ OutputFlags flags,
+ sd_bus_error *error) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ Hashmap *cgroups = NULL;
+ struct CGroupInfo *cg;
+ int r;
+
+ assert(bus);
+ assert(unit);
+
+ if (flags & OUTPUT_FULL_WIDTH)
+ n_columns = 0;
+ else if (n_columns <= 0)
+ n_columns = columns();
+
+ prefix = strempty(prefix);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "GetUnitProcesses",
+ error,
+ &reply,
+ "s",
+ unit);
+ if (r < 0)
+ return r;
+
+ cgroups = hashmap_new(&string_hash_ops);
+ if (!cgroups)
+ return -ENOMEM;
+
+ r = sd_bus_message_enter_container(reply, 'a', "(sus)");
+ if (r < 0)
+ goto finish;
+
+ for (;;) {
+ const char *path = NULL, *name = NULL;
+ uint32_t pid;
+
+ r = sd_bus_message_read(reply, "(sus)", &path, &pid, &name);
+ if (r < 0)
+ goto finish;
+ if (r == 0)
+ break;
+
+ r = add_process(cgroups, path, pid, name);
+ if (r < 0)
+ goto finish;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ goto finish;
+
+ r = dump_processes(cgroups, cgroup_path, prefix, n_columns, flags);
+ if (r < 0)
+ goto finish;
+
+ r = dump_extra_processes(cgroups, prefix, n_columns, flags);
+
+finish:
+ while ((cg = hashmap_first(cgroups)))
+ remove_cgroup(cgroups, cg);
+
+ hashmap_free(cgroups);
+
+ return r;
+}
diff --git a/src/libshared/bus-unit-util.h b/src/libshared/bus-unit-util.h
new file mode 100644
index 0000000000..8327189a63
--- /dev/null
+++ b/src/libshared/bus-unit-util.h
@@ -0,0 +1,57 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <systemd/sd-bus.h>
+
+#include "output-mode.h"
+#include "install.h"
+
+typedef struct UnitInfo {
+ const char *machine;
+ const char *id;
+ const char *description;
+ const char *load_state;
+ const char *active_state;
+ const char *sub_state;
+ const char *following;
+ const char *unit_path;
+ uint32_t job_id;
+ const char *job_type;
+ const char *job_path;
+} UnitInfo;
+
+int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
+
+int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment);
+
+typedef struct BusWaitForJobs BusWaitForJobs;
+
+int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret);
+void bus_wait_for_jobs_free(BusWaitForJobs *d);
+int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path);
+int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char* const* extra_args);
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForJobs*, bus_wait_for_jobs_free);
+
+int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes);
+
+int unit_show_processes(sd_bus *bus, const char *unit, const char *cgroup_path, const char *prefix, unsigned n_columns, OutputFlags flags, sd_bus_error *error);
diff --git a/src/libshared/bus-util.c b/src/libshared/bus-util.c
index a874bb84cc..62b5585e84 100644
--- a/src/libshared/bus-util.c
+++ b/src/libshared/bus-util.c
@@ -39,34 +39,16 @@
#include "bus-label.h"
#include "bus-message.h"
#include "bus-util.h"
-#include "cgroup-util.h"
#include "def.h"
-#include "env-util.h"
#include "escape.h"
-#include "extract-word.h"
#include "fd-util.h"
-#include "hashmap.h"
-#include "install.h"
-#include "kdbus.h"
-#include "log.h"
-#include "macro.h"
#include "missing.h"
#include "parse-util.h"
-#include "path-util.h"
#include "proc-cmdline.h"
-#include "process-util.h"
#include "rlimit-util.h"
-#include "set.h"
-#include "signal-util.h"
#include "stdio-util.h"
-#include "string-util.h"
#include "strv.h"
-#include "syslog-util.h"
-#include "time-util.h"
-#include "unit-name.h"
#include "user-util.h"
-#include "utf8.h"
-#include "util.h"
static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
sd_event *e = userdata;
@@ -712,7 +694,15 @@ int bus_connect_user_systemd(sd_bus **_bus) {
return 0;
}
-int bus_print_property(const char *name, sd_bus_message *property, bool all) {
+#define print_property(name, fmt, ...) \
+ do { \
+ if (value) \
+ printf(fmt "\n", __VA_ARGS__); \
+ else \
+ printf("%s=" fmt "\n", name, __VA_ARGS__); \
+ } while(0)
+
+int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all) {
char type;
const char *contents;
int r;
@@ -740,7 +730,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (!escaped)
return -ENOMEM;
- printf("%s=%s\n", name, escaped);
+ print_property(name, "%s", escaped);
}
return 1;
@@ -753,7 +743,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (r < 0)
return r;
- printf("%s=%s\n", name, yes_no(b));
+ print_property(name, "%s", yes_no(b));
return 1;
}
@@ -773,14 +763,14 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
t = format_timestamp(timestamp, sizeof(timestamp), u);
if (t || all)
- printf("%s=%s\n", name, strempty(t));
+ print_property(name, "%s", strempty(t));
} else if (strstr(name, "USec")) {
char timespan[FORMAT_TIMESPAN_MAX];
- printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
+ print_property(name, "%s", format_timespan(timespan, sizeof(timespan), u, 0));
} else
- printf("%s=%llu\n", name, (unsigned long long) u);
+ print_property(name, "%"PRIu64, u);
return 1;
}
@@ -792,7 +782,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (r < 0)
return r;
- printf("%s=%lld\n", name, (long long) i);
+ print_property(name, "%"PRIi64, i);
return 1;
}
@@ -805,9 +795,9 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
return r;
if (strstr(name, "UMask") || strstr(name, "Mode"))
- printf("%s=%04o\n", name, u);
+ print_property(name, "%04o", u);
else
- printf("%s=%u\n", name, (unsigned) u);
+ print_property(name, "%"PRIu32, u);
return 1;
}
@@ -819,7 +809,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (r < 0)
return r;
- printf("%s=%i\n", name, (int) i);
+ print_property(name, "%"PRIi32, i);
return 1;
}
@@ -830,7 +820,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (r < 0)
return r;
- printf("%s=%g\n", name, d);
+ print_property(name, "%g", d);
return 1;
}
@@ -843,10 +833,10 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (r < 0)
return r;
- while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
+ while ((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
_cleanup_free_ char *escaped = NULL;
- if (first)
+ if (first && !value)
printf("%s=", name);
escaped = xescape(str, "\n ");
@@ -860,7 +850,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (r < 0)
return r;
- if (first && all)
+ if (first && all && !value)
printf("%s=", name);
if (!first || all)
puts("");
@@ -882,7 +872,8 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (all || n > 0) {
unsigned int i;
- printf("%s=", name);
+ if (!value)
+ printf("%s=", name);
for (i = 0; i < n; i++)
printf("%02x", u[i]);
@@ -903,7 +894,8 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
if (all || n > 0) {
unsigned int i;
- printf("%s=", name);
+ if (!value)
+ printf("%s=", name);
for (i = 0; i < n; i++)
printf("%08x", u[i]);
@@ -920,7 +912,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool all) {
return 0;
}
-int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
+int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
@@ -960,7 +952,7 @@ int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, ch
if (r < 0)
return r;
- r = bus_print_property(name, reply, all);
+ r = bus_print_property(name, reply, value, all);
if (r < 0)
return r;
if (r == 0) {
@@ -1068,7 +1060,7 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_
}
case SD_BUS_TYPE_UINT32: {
- uint64_t u;
+ uint32_t u;
uint32_t *p = userdata;
r = sd_bus_message_read_basic(m, type, &u);
@@ -1373,839 +1365,6 @@ int bus_log_create_error(int r) {
return log_error_errno(r, "Failed to create bus message: %m");
}
-int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
- assert(message);
- assert(u);
-
- u->machine = NULL;
-
- return sd_bus_message_read(
- message,
- "(ssssssouso)",
- &u->id,
- &u->description,
- &u->load_state,
- &u->active_state,
- &u->sub_state,
- &u->following,
- &u->unit_path,
- &u->job_id,
- &u->job_type,
- &u->job_path);
-}
-
-int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
- const char *eq, *field;
- int r, rl;
-
- assert(m);
- assert(assignment);
-
- eq = strchr(assignment, '=');
- if (!eq) {
- log_error("Not an assignment: %s", assignment);
- return -EINVAL;
- }
-
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
- if (r < 0)
- return bus_log_create_error(r);
-
- field = strndupa(assignment, eq - assignment);
- eq ++;
-
- if (streq(field, "CPUQuota")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
- else if (endswith(eq, "%")) {
- double percent;
-
- if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
- log_error("CPU quota '%s' invalid.", eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100);
- } else {
- log_error("CPU quota needs to be in percent.");
- return -EINVAL;
- }
-
- goto finish;
-
- } else if (streq(field, "EnvironmentFile")) {
-
- r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
- eq[0] == '-' ? eq + 1 : eq,
- eq[0] == '-');
- goto finish;
-
- } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec", "RuntimeMaxSec")) {
- char *n;
- usec_t t;
- size_t l;
- r = parse_sec(eq, &t);
- if (r < 0)
- return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
-
- l = strlen(field);
- n = newa(char, l + 2);
- if (!n)
- return log_oom();
-
- /* Change suffix Sec → USec */
- strcpy(mempcpy(n, field, l - 3), "USec");
- r = sd_bus_message_append(m, "sv", n, "t", t);
- goto finish;
- }
-
- r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
- if (r < 0)
- return bus_log_create_error(r);
-
- rl = rlimit_from_string(field);
- if (rl >= 0) {
- const char *sn;
- struct rlimit l;
-
- r = rlimit_parse(rl, eq, &l);
- if (r < 0)
- return log_error_errno(r, "Failed to parse resource limit: %s", eq);
-
- r = sd_bus_message_append(m, "v", "t", l.rlim_max);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
- if (r < 0)
- return bus_log_create_error(r);
-
- sn = strjoina(field, "Soft");
- r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur);
-
- } else if (STR_IN_SET(field,
- "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
- "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
- "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
- "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges",
- "SyslogLevelPrefix", "Delegate", "RemainAfterElapse")) {
-
- r = parse_boolean(eq);
- if (r < 0)
- return log_error_errno(r, "Failed to parse boolean assignment %s.", assignment);
-
- r = sd_bus_message_append(m, "v", "b", r);
-
- } else if (streq(field, "MemoryLimit")) {
- uint64_t bytes;
-
- if (isempty(eq) || streq(eq, "infinity"))
- bytes = (uint64_t) -1;
- else {
- r = parse_size(eq, 1024, &bytes);
- if (r < 0) {
- log_error("Failed to parse bytes specification %s", assignment);
- return -EINVAL;
- }
- }
-
- r = sd_bus_message_append(m, "v", "t", bytes);
-
- } else if (streq(field, "TasksMax")) {
- uint64_t n;
-
- if (isempty(eq) || streq(eq, "infinity"))
- n = (uint64_t) -1;
- else {
- r = safe_atou64(eq, &n);
- if (r < 0) {
- log_error("Failed to parse maximum tasks specification %s", assignment);
- return -EINVAL;
- }
- }
-
- r = sd_bus_message_append(m, "v", "t", n);
-
- } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) {
- uint64_t u;
-
- r = cg_cpu_shares_parse(eq, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", u);
-
- } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
- uint64_t u;
-
- r = cg_cpu_shares_parse(eq, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", u);
-
- } else if (STR_IN_SET(field,
- "User", "Group", "DevicePolicy", "KillMode",
- "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
- "StandardInput", "StandardOutput", "StandardError",
- "Description", "Slice", "Type", "WorkingDirectory",
- "RootDirectory", "SyslogIdentifier", "ProtectSystem",
- "ProtectHome"))
- r = sd_bus_message_append(m, "v", "s", eq);
-
- else if (streq(field, "SyslogLevel")) {
- int level;
-
- level = log_level_from_string(eq);
- if (level < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", level);
-
- } else if (streq(field, "SyslogFacility")) {
- int facility;
-
- facility = log_facility_unshifted_from_string(eq);
- if (facility < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", facility);
-
- } else if (streq(field, "DeviceAllow")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "v", "a(ss)", 0);
- else {
- const char *path, *rwm, *e;
-
- e = strchr(eq, ' ');
- if (e) {
- path = strndupa(eq, e - eq);
- rwm = e+1;
- } else {
- path = eq;
- rwm = "";
- }
-
- if (!path_startswith(path, "/dev")) {
- log_error("%s is not a device file in /dev.", path);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
- }
-
- } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "v", "a(st)", 0);
- else {
- const char *path, *bandwidth, *e;
- uint64_t bytes;
-
- e = strchr(eq, ' ');
- if (e) {
- path = strndupa(eq, e - eq);
- bandwidth = e+1;
- } else {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- if (!path_startswith(path, "/dev")) {
- log_error("%s is not a device file in /dev.", path);
- return -EINVAL;
- }
-
- r = parse_size(bandwidth, 1000, &bytes);
- if (r < 0) {
- log_error("Failed to parse byte value %s.", bandwidth);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
- }
-
- } else if (streq(field, "BlockIODeviceWeight")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "v", "a(st)", 0);
- else {
- const char *path, *weight, *e;
- uint64_t u;
-
- e = strchr(eq, ' ');
- if (e) {
- path = strndupa(eq, e - eq);
- weight = e+1;
- } else {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- if (!path_startswith(path, "/dev")) {
- log_error("%s is not a device file in /dev.", path);
- return -EINVAL;
- }
-
- r = safe_atou64(weight, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, weight);
- return -EINVAL;
- }
- r = sd_bus_message_append(m, "v", "a(st)", path, u);
- }
-
- } else if (streq(field, "Nice")) {
- int32_t i;
-
- r = safe_atoi32(eq, &i);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", i);
-
- } else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
- const char *p;
-
- r = sd_bus_message_open_container(m, 'v', "as");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- p = eq;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
- if (r < 0) {
- log_error("Failed to parse Environment value %s", eq);
- return -EINVAL;
- }
- if (r == 0)
- break;
-
- if (streq(field, "Environment")) {
- if (!env_assignment_is_valid(word)) {
- log_error("Invalid environment assignment: %s", word);
- return -EINVAL;
- }
- } else { /* PassEnvironment */
- if (!env_name_is_valid(word)) {
- log_error("Invalid environment variable name: %s", word);
- return -EINVAL;
- }
- }
-
- r = sd_bus_message_append_basic(m, 's', word);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
-
- } else if (streq(field, "KillSignal")) {
- int sig;
-
- sig = signal_from_string_try_harder(eq);
- if (sig < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", sig);
-
- } else if (streq(field, "TimerSlackNSec")) {
- nsec_t n;
-
- r = parse_nsec(eq, &n);
- if (r < 0) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", n);
- } else if (streq(field, "OOMScoreAdjust")) {
- int oa;
-
- r = safe_atoi(eq, &oa);
- if (r < 0) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- if (!oom_score_adjust_is_valid(oa)) {
- log_error("OOM score adjust value out of range");
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", oa);
- } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
- const char *p;
-
- r = sd_bus_message_open_container(m, 'v', "as");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- p = eq;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
- int offset;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
- if (r < 0) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
- if (r == 0)
- break;
-
- if (!utf8_is_valid(word)) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- offset = word[0] == '-';
- if (!path_is_absolute(word + offset)) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- path_kill_slashes(word + offset);
-
- r = sd_bus_message_append_basic(m, 's', word);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
-
- } else if (streq(field, "RuntimeDirectory")) {
- const char *p;
-
- r = sd_bus_message_open_container(m, 'v', "as");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- p = eq;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
- if (r < 0)
- return log_error_errno(r, "Failed to parse %s value %s", field, eq);
-
- if (r == 0)
- break;
-
- r = sd_bus_message_append_basic(m, 's', word);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
-
- } else {
- log_error("Unknown assignment %s.", assignment);
- return -EINVAL;
- }
-
-finish:
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- return 0;
-}
-
-typedef struct BusWaitForJobs {
- sd_bus *bus;
- Set *jobs;
-
- char *name;
- char *result;
-
- sd_bus_slot *slot_job_removed;
- sd_bus_slot *slot_disconnected;
-} BusWaitForJobs;
-
-static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- assert(m);
-
- log_error("Warning! D-Bus connection terminated.");
- sd_bus_close(sd_bus_message_get_bus(m));
-
- return 0;
-}
-
-static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- const char *path, *unit, *result;
- BusWaitForJobs *d = userdata;
- uint32_t id;
- char *found;
- int r;
-
- assert(m);
- assert(d);
-
- r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- found = set_remove(d->jobs, (char*) path);
- if (!found)
- return 0;
-
- free(found);
-
- if (!isempty(result))
- d->result = strdup(result);
-
- if (!isempty(unit))
- d->name = strdup(unit);
-
- return 0;
-}
-
-void bus_wait_for_jobs_free(BusWaitForJobs *d) {
- if (!d)
- return;
-
- set_free_free(d->jobs);
-
- sd_bus_slot_unref(d->slot_disconnected);
- sd_bus_slot_unref(d->slot_job_removed);
-
- sd_bus_unref(d->bus);
-
- free(d->name);
- free(d->result);
-
- free(d);
-}
-
-int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
- _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
- int r;
-
- assert(bus);
- assert(ret);
-
- d = new0(BusWaitForJobs, 1);
- if (!d)
- return -ENOMEM;
-
- d->bus = sd_bus_ref(bus);
-
- /* When we are a bus client we match by sender. Direct
- * connections OTOH have no initialized sender field, and
- * hence we ignore the sender then */
- r = sd_bus_add_match(
- bus,
- &d->slot_job_removed,
- bus->bus_client ?
- "type='signal',"
- "sender='org.freedesktop.systemd1',"
- "interface='org.freedesktop.systemd1.Manager',"
- "member='JobRemoved',"
- "path='/org/freedesktop/systemd1'" :
- "type='signal',"
- "interface='org.freedesktop.systemd1.Manager',"
- "member='JobRemoved',"
- "path='/org/freedesktop/systemd1'",
- match_job_removed, d);
- if (r < 0)
- return r;
-
- r = sd_bus_add_match(
- bus,
- &d->slot_disconnected,
- "type='signal',"
- "sender='org.freedesktop.DBus.Local',"
- "interface='org.freedesktop.DBus.Local',"
- "member='Disconnected'",
- match_disconnected, d);
- if (r < 0)
- return r;
-
- *ret = d;
- d = NULL;
-
- return 0;
-}
-
-static int bus_process_wait(sd_bus *bus) {
- int r;
-
- for (;;) {
- r = sd_bus_process(bus, NULL);
- if (r < 0)
- return r;
- if (r > 0)
- return 0;
-
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0)
- return r;
- }
-}
-
-static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
- _cleanup_free_ char *dbus_path = NULL;
-
- assert(d);
- assert(d->name);
- assert(result);
-
- dbus_path = unit_dbus_path_from_name(d->name);
- if (!dbus_path)
- return -ENOMEM;
-
- return sd_bus_get_property_string(d->bus,
- "org.freedesktop.systemd1",
- dbus_path,
- "org.freedesktop.systemd1.Service",
- "Result",
- NULL,
- result);
-}
-
-static const struct {
- const char *result, *explanation;
-} explanations [] = {
- { "resources", "a configured resource limit was exceeded" },
- { "timeout", "a timeout was exceeded" },
- { "exit-code", "the control process exited with error code" },
- { "signal", "a fatal signal was delivered to the control process" },
- { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
- { "watchdog", "the service failed to send watchdog ping" },
- { "start-limit", "start of the service was attempted too often" }
-};
-
-static void log_job_error_with_service_result(const char* service, const char *result, const char *extra_args) {
- _cleanup_free_ char *service_shell_quoted = NULL, *systemctl_extra_args = NULL;
-
- assert(service);
-
- service_shell_quoted = shell_maybe_quote(service);
-
- systemctl_extra_args = strjoin("systemctl ", extra_args, " ", NULL);
- if (!systemctl_extra_args) {
- log_oom();
- return;
- }
-
- systemctl_extra_args = strstrip(systemctl_extra_args);
-
- if (!isempty(result)) {
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(explanations); ++i)
- if (streq(result, explanations[i].result))
- break;
-
- if (i < ELEMENTSOF(explanations)) {
- log_error("Job for %s failed because %s. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
- service,
- explanations[i].explanation,
- systemctl_extra_args,
- strna(service_shell_quoted));
-
- goto finish;
- }
- }
-
- log_error("Job for %s failed. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
- service,
- systemctl_extra_args,
- strna(service_shell_quoted));
-
-finish:
- /* For some results maybe additional explanation is required */
- if (streq_ptr(result, "start-limit"))
- log_info("To force a start use \"%1$s reset-failed %2$s\" followed by \"%1$s start %2$s\" again.",
- systemctl_extra_args,
- strna(service_shell_quoted));
-}
-
-static int check_wait_response(BusWaitForJobs *d, bool quiet, const char *extra_args) {
- int r = 0;
-
- assert(d->result);
-
- if (!quiet) {
- if (streq(d->result, "canceled"))
- log_error("Job for %s canceled.", strna(d->name));
- else if (streq(d->result, "timeout"))
- log_error("Job for %s timed out.", strna(d->name));
- else if (streq(d->result, "dependency"))
- log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
- else if (streq(d->result, "invalid"))
- log_error("%s is not active, cannot reload.", strna(d->name));
- else if (streq(d->result, "assert"))
- log_error("Assertion failed on job for %s.", strna(d->name));
- else if (streq(d->result, "unsupported"))
- log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
- else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
- if (d->name) {
- int q;
- _cleanup_free_ char *result = NULL;
-
- q = bus_job_get_service_result(d, &result);
- if (q < 0)
- log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
-
- log_job_error_with_service_result(d->name, result, extra_args);
- } else
- log_error("Job failed. See \"journalctl -xe\" for details.");
- }
- }
-
- if (streq(d->result, "canceled"))
- r = -ECANCELED;
- else if (streq(d->result, "timeout"))
- r = -ETIME;
- else if (streq(d->result, "dependency"))
- r = -EIO;
- else if (streq(d->result, "invalid"))
- r = -ENOEXEC;
- else if (streq(d->result, "assert"))
- r = -EPROTO;
- else if (streq(d->result, "unsupported"))
- r = -EOPNOTSUPP;
- else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
- r = -EIO;
-
- return r;
-}
-
-int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char *extra_args) {
- int r = 0;
-
- assert(d);
-
- while (!set_isempty(d->jobs)) {
- int q;
-
- q = bus_process_wait(d->bus);
- if (q < 0)
- return log_error_errno(q, "Failed to wait for response: %m");
-
- if (d->result) {
- q = check_wait_response(d, quiet, extra_args);
- /* Return the first error as it is most likely to be
- * meaningful. */
- if (q < 0 && r == 0)
- r = q;
-
- log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
- }
-
- d->name = mfree(d->name);
- d->result = mfree(d->result);
- }
-
- return r;
-}
-
-int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
- int r;
-
- assert(d);
-
- r = set_ensure_allocated(&d->jobs, &string_hash_ops);
- if (r < 0)
- return r;
-
- return set_put_strdup(d->jobs, path);
-}
-
-int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
- int r;
-
- r = bus_wait_for_jobs_add(d, path);
- if (r < 0)
- return log_oom();
-
- return bus_wait_for_jobs(d, quiet, NULL);
-}
-
-int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
- const char *type, *path, *source;
- int r;
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
- if (r < 0)
- return bus_log_parse_error(r);
-
- while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
- if (!quiet) {
- if (streq(type, "symlink"))
- log_info("Created symlink from %s to %s.", path, source);
- else
- log_info("Removed symlink %s.", path);
- }
-
- r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
- if (r < 0)
- return r;
- }
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return bus_log_parse_error(r);
-
- return 0;
-}
-
/**
* bus_path_encode_unique() - encode unique object path
* @b: bus connection or NULL
diff --git a/src/libshared/bus-util.h b/src/libshared/bus-util.h
index 77474522be..f2b46530ba 100644
--- a/src/libshared/bus-util.h
+++ b/src/libshared/bus-util.h
@@ -24,15 +24,12 @@
#include <stdint.h>
#include <sys/types.h>
-#include <systemd/sd-bus-vtable.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include "hashmap.h"
-#include "install.h"
#include "macro.h"
#include "string-util.h"
-#include "time-util.h"
typedef enum BusTransport {
BUS_TRANSPORT_LOCAL,
@@ -78,8 +75,8 @@ int bus_connect_user_systemd(sd_bus **_bus);
int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
-int bus_print_property(const char *name, sd_bus_message *property, bool all);
-int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
+int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all);
+int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all);
int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
@@ -126,22 +123,6 @@ assert_cc(sizeof(mode_t) == sizeof(uint32_t));
int bus_log_parse_error(int r);
int bus_log_create_error(int r);
-typedef struct UnitInfo {
- const char *machine;
- const char *id;
- const char *description;
- const char *load_state;
- const char *active_state;
- const char *sub_state;
- const char *following;
- const char *unit_path;
- uint32_t job_id;
- const char *job_type;
- const char *job_path;
-} UnitInfo;
-
-int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
-
#define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type) \
int function(sd_bus *bus, \
const char *path, \
@@ -173,20 +154,6 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
SD_BUS_PROPERTY(name, "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, realtime), (flags)), \
SD_BUS_PROPERTY(name "Monotonic", "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, monotonic), (flags))
-int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment);
-
-typedef struct BusWaitForJobs BusWaitForJobs;
-
-int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret);
-void bus_wait_for_jobs_free(BusWaitForJobs *d);
-int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path);
-int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char *extra_args);
-int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForJobs*, bus_wait_for_jobs_free);
-
-int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes);
-
int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
diff --git a/src/libshared/cgroup-show.c b/src/libshared/cgroup-show.c
index f3039b23f7..3e451db715 100644
--- a/src/libshared/cgroup-show.c
+++ b/src/libshared/cgroup-show.c
@@ -37,23 +37,21 @@
#include "string-util.h"
#include "terminal-util.h"
-static int compare(const void *a, const void *b) {
- const pid_t *p = a, *q = b;
+static void show_pid_array(
+ pid_t pids[],
+ unsigned n_pids,
+ const char *prefix,
+ unsigned n_columns,
+ bool extra,
+ bool more,
+ OutputFlags flags) {
- if (*p < *q)
- return -1;
- if (*p > *q)
- return 1;
- return 0;
-}
-
-static void show_pid_array(pid_t pids[], unsigned n_pids, const char *prefix, unsigned n_columns, bool extra, bool more, bool kernel_threads, OutputFlags flags) {
unsigned i, j, pid_width;
if (n_pids == 0)
return;
- qsort(pids, n_pids, sizeof(pid_t), compare);
+ qsort(pids, n_pids, sizeof(pid_t), pid_compare_func);
/* Filter duplicates */
for (j = 0, i = 1; i < n_pids; i++) {
@@ -78,16 +76,21 @@ static void show_pid_array(pid_t pids[], unsigned n_pids, const char *prefix, un
get_process_cmdline(pids[i], n_columns, true, &t);
if (extra)
- printf("%s%s ", prefix, draw_special_char(DRAW_TRIANGULAR_BULLET));
+ printf("%s%s ", prefix, special_glyph(TRIANGULAR_BULLET));
else
- printf("%s%s", prefix, draw_special_char(((more || i < n_pids-1) ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT)));
+ printf("%s%s", prefix, special_glyph(((more || i < n_pids-1) ? TREE_BRANCH : TREE_RIGHT)));
printf("%*"PID_PRI" %s\n", pid_width, pids[i], strna(t));
}
}
+static int show_cgroup_one_by_path(
+ const char *path,
+ const char *prefix,
+ unsigned n_columns,
+ bool more,
+ OutputFlags flags) {
-static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigned n_columns, bool more, bool kernel_threads, OutputFlags flags) {
char *fn;
_cleanup_fclose_ FILE *f = NULL;
size_t n = 0, n_allocated = 0;
@@ -107,7 +110,7 @@ static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigne
while ((r = cg_read_pid(f, &pid)) > 0) {
- if (!kernel_threads && is_kernel_thread(pid) > 0)
+ if (!(flags & OUTPUT_KERNEL_THREADS) && is_kernel_thread(pid) > 0)
continue;
if (!GREEDY_REALLOC(pids, n_allocated, n + 1))
@@ -120,12 +123,17 @@ static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigne
if (r < 0)
return r;
- show_pid_array(pids, n, prefix, n_columns, false, more, kernel_threads, flags);
+ show_pid_array(pids, n, prefix, n_columns, false, more, flags);
return 0;
}
-int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, OutputFlags flags) {
+int show_cgroup_by_path(
+ const char *path,
+ const char *prefix,
+ unsigned n_columns,
+ OutputFlags flags) {
+
_cleanup_free_ char *fn = NULL, *p1 = NULL, *last = NULL, *p2 = NULL;
_cleanup_closedir_ DIR *d = NULL;
char *gn = NULL;
@@ -137,8 +145,7 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
if (n_columns <= 0)
n_columns = columns();
- if (!prefix)
- prefix = "";
+ prefix = strempty(prefix);
r = cg_mangle_path(path, &fn);
if (r < 0)
@@ -160,20 +167,20 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
continue;
if (!shown_pids) {
- show_cgroup_one_by_path(path, prefix, n_columns, true, kernel_threads, flags);
+ show_cgroup_one_by_path(path, prefix, n_columns, true, flags);
shown_pids = true;
}
if (last) {
- printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_BRANCH), cg_unescape(basename(last)));
+ printf("%s%s%s\n", prefix, special_glyph(TREE_BRANCH), cg_unescape(basename(last)));
if (!p1) {
- p1 = strappend(prefix, draw_special_char(DRAW_TREE_VERTICAL));
+ p1 = strappend(prefix, special_glyph(TREE_VERTICAL));
if (!p1)
return -ENOMEM;
}
- show_cgroup_by_path(last, p1, n_columns-2, kernel_threads, flags);
+ show_cgroup_by_path(last, p1, n_columns-2, flags);
free(last);
}
@@ -185,10 +192,10 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
return r;
if (!shown_pids)
- show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads, flags);
+ show_cgroup_one_by_path(path, prefix, n_columns, !!last, flags);
if (last) {
- printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), cg_unescape(basename(last)));
+ printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), cg_unescape(basename(last)));
if (!p2) {
p2 = strappend(prefix, " ");
@@ -196,13 +203,17 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
return -ENOMEM;
}
- show_cgroup_by_path(last, p2, n_columns-2, kernel_threads, flags);
+ show_cgroup_by_path(last, p2, n_columns-2, flags);
}
return 0;
}
-int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, OutputFlags flags) {
+int show_cgroup(const char *controller,
+ const char *path,
+ const char *prefix,
+ unsigned n_columns,
+ OutputFlags flags) {
_cleanup_free_ char *p = NULL;
int r;
@@ -212,10 +223,18 @@ int show_cgroup(const char *controller, const char *path, const char *prefix, un
if (r < 0)
return r;
- return show_cgroup_by_path(p, prefix, n_columns, kernel_threads, flags);
+ return show_cgroup_by_path(p, prefix, n_columns, flags);
}
-static int show_extra_pids(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t pids[], unsigned n_pids, OutputFlags flags) {
+static int show_extra_pids(
+ const char *controller,
+ const char *path,
+ const char *prefix,
+ unsigned n_columns,
+ const pid_t pids[],
+ unsigned n_pids,
+ OutputFlags flags) {
+
_cleanup_free_ pid_t *copy = NULL;
unsigned i, j;
int r;
@@ -247,24 +266,39 @@ static int show_extra_pids(const char *controller, const char *path, const char
copy[j++] = pids[i];
}
- show_pid_array(copy, j, prefix, n_columns, true, false, false, flags);
+ show_pid_array(copy, j, prefix, n_columns, true, false, flags);
return 0;
}
-int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags) {
+int show_cgroup_and_extra(
+ const char *controller,
+ const char *path,
+ const char *prefix,
+ unsigned n_columns,
+ const pid_t extra_pids[],
+ unsigned n_extra_pids,
+ OutputFlags flags) {
+
int r;
assert(path);
- r = show_cgroup(controller, path, prefix, n_columns, kernel_threads, flags);
+ r = show_cgroup(controller, path, prefix, n_columns, flags);
if (r < 0)
return r;
return show_extra_pids(controller, path, prefix, n_columns, extra_pids, n_extra_pids, flags);
}
-int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags) {
+int show_cgroup_and_extra_by_spec(
+ const char *spec,
+ const char *prefix,
+ unsigned n_columns,
+ const pid_t extra_pids[],
+ unsigned n_extra_pids,
+ OutputFlags flags) {
+
_cleanup_free_ char *controller = NULL, *path = NULL;
int r;
@@ -274,5 +308,5 @@ int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned
if (r < 0)
return r;
- return show_cgroup_and_extra(controller, path, prefix, n_columns, kernel_threads, extra_pids, n_extra_pids, flags);
+ return show_cgroup_and_extra(controller, path, prefix, n_columns, extra_pids, n_extra_pids, flags);
}
diff --git a/src/libshared/cgroup-show.h b/src/libshared/cgroup-show.h
index 3ab7dfb33c..5c1d6e6d98 100644
--- a/src/libshared/cgroup-show.h
+++ b/src/libshared/cgroup-show.h
@@ -25,8 +25,8 @@
#include "logs-show.h"
#include "output-mode.h"
-int show_cgroup_by_path(const char *path, const char *prefix, unsigned columns, bool kernel_threads, OutputFlags flags);
-int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned columns, bool kernel_threads, OutputFlags flags);
+int show_cgroup_by_path(const char *path, const char *prefix, unsigned columns, OutputFlags flags);
+int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned columns, OutputFlags flags);
-int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
-int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
+int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
+int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
diff --git a/src/libshared/condition.c b/src/libshared/condition.c
index 1719a4c7a6..33ca6e029e 100644
--- a/src/libshared/condition.c
+++ b/src/libshared/condition.c
@@ -295,7 +295,7 @@ static int condition_test_needs_update(Condition *c) {
return false;
/* Any other failure means we should allow the condition to be true,
- * so that we rather invoke too many update tools then too
+ * so that we rather invoke too many update tools than too
* few. */
if (!path_is_absolute(c->parameter))
diff --git a/src/libshared/conf-parser.c b/src/libshared/conf-parser.c
index e7fe9ac21e..83be79a4f5 100644
--- a/src/libshared/conf-parser.c
+++ b/src/libshared/conf-parser.c
@@ -37,6 +37,7 @@
#include "path-util.h"
#include "process-util.h"
#include "signal-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "syslog-util.h"
@@ -294,7 +295,7 @@ int config_parse(const char *unit,
_cleanup_free_ char *section = NULL, *continuation = NULL;
_cleanup_fclose_ FILE *ours = NULL;
unsigned line = 0, section_line = 0;
- bool section_ignored = false;
+ bool section_ignored = false, allow_bom = true;
int r;
assert(filename);
@@ -314,11 +315,11 @@ int config_parse(const char *unit,
fd_warn_permissions(filename, fileno(f));
- while (!feof(f)) {
- char l[LINE_MAX], *p, *c = NULL, *e;
+ for (;;) {
+ char buf[LINE_MAX], *l, *p, *c = NULL, *e;
bool escaped = false;
- if (!fgets(l, sizeof(l), f)) {
+ if (!fgets(buf, sizeof buf, f)) {
if (feof(f))
break;
@@ -326,6 +327,11 @@ int config_parse(const char *unit,
return -errno;
}
+ l = buf;
+ if (allow_bom && startswith(l, UTF8_BYTE_ORDER_MARK))
+ l += strlen(UTF8_BYTE_ORDER_MARK);
+ allow_bom = false;
+
truncate_nl(l);
if (continuation) {
@@ -727,7 +733,7 @@ int config_parse_strv(const char *unit,
for (;;) {
char *word = NULL;
int r;
- r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES);
+ r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
if (r == 0)
break;
if (r == -ENOMEM)
@@ -868,3 +874,40 @@ int config_parse_personality(
*personality = p;
return 0;
}
+
+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) {
+
+ char **s = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *s = mfree(*s);
+ return 0;
+ }
+
+ if (!ifname_valid(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ r = free_and_strdup(s, rvalue);
+ if (r < 0)
+ return log_oom();
+
+ return 0;
+}
diff --git a/src/libshared/conf-parser.h b/src/libshared/conf-parser.h
index a91c94c322..f6964e3fd4 100644
--- a/src/libshared/conf-parser.h
+++ b/src/libshared/conf-parser.h
@@ -125,6 +125,7 @@ int config_parse_log_facility(const char *unit, const char *filename, unsigned l
int config_parse_log_level(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_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);
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
int function(const char *unit, \
@@ -178,7 +179,7 @@ int config_parse_personality(const char *unit, const char *filename, unsigned li
assert(data); \
\
xs = new0(type, 1); \
- if(!xs) \
+ if (!xs) \
return -ENOMEM; \
\
*xs = invalid; \
diff --git a/src/libshared/dns-domain.c b/src/libshared/dns-domain.c
index 45d24c0079..835557c6b2 100644
--- a/src/libshared/dns-domain.c
+++ b/src/libshared/dns-domain.c
@@ -180,7 +180,7 @@ int dns_label_unescape_suffix(const char *name, const char **label_terminal, cha
unsigned slashes = 0;
for (y = terminal - 1; y >= name && *y == '\\'; y--)
- slashes ++;
+ slashes++;
if (slashes % 2 == 0) {
/* The '.' was not escaped */
@@ -192,7 +192,7 @@ int dns_label_unescape_suffix(const char *name, const char **label_terminal, cha
}
}
- terminal --;
+ terminal--;
}
r = dns_label_unescape(&name, dest, sz);
@@ -331,7 +331,7 @@ int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded
l = strlen(buffer);
- /* Verify that the the result is not longer than one DNS label. */
+ /* Verify that the result is not longer than one DNS label. */
if (l <= 0 || l > DNS_LABEL_MAX)
return -EINVAL;
if (l > decoded_max)
@@ -1172,7 +1172,7 @@ int dns_name_skip(const char *a, unsigned n_labels, const char **ret) {
assert(a);
assert(ret);
- for (; n_labels > 0; n_labels --) {
+ for (; n_labels > 0; n_labels--) {
r = dns_name_parent(&a);
if (r < 0)
return r;
diff --git a/src/libshared/dns-domain.h b/src/libshared/dns-domain.h
index 2de3642cb3..af780f0b8b 100644
--- a/src/libshared/dns-domain.h
+++ b/src/libshared/dns-domain.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,9 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
diff --git a/src/libshared/dropin.c b/src/libshared/dropin.c
index cc1acd6f23..b9cd952ac8 100644
--- a/src/libshared/dropin.c
+++ b/src/libshared/dropin.c
@@ -160,7 +160,7 @@ static int iterate_dir(
if (!de)
break;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
f = strjoin(path, "/", de->d_name, NULL);
diff --git a/src/libshared/gcrypt-util.c b/src/libshared/gcrypt-util.c
new file mode 100644
index 0000000000..39b544b6f0
--- /dev/null
+++ b/src/libshared/gcrypt-util.c
@@ -0,0 +1,71 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2012 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_GCRYPT
+#include <gcrypt.h>
+
+#include "gcrypt-util.h"
+#include "hexdecoct.h"
+
+void initialize_libgcrypt(bool secmem) {
+ const char *p;
+ if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
+ return;
+
+ p = gcry_check_version("1.4.5");
+ assert(p);
+
+ /* Turn off "secmem". Clients which wish to make use of this
+ * feature should initialize the library manually */
+ if (!secmem)
+ gcry_control(GCRYCTL_DISABLE_SECMEM);
+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+}
+
+int string_hashsum(const char *s, size_t len, int md_algorithm, char **out) {
+ gcry_md_hd_t md = NULL;
+ size_t hash_size;
+ void *hash;
+ char *enc;
+
+ initialize_libgcrypt(false);
+
+ hash_size = gcry_md_get_algo_dlen(md_algorithm);
+ assert(hash_size > 0);
+
+ gcry_md_open(&md, md_algorithm, 0);
+ if (!md)
+ return -EIO;
+
+ gcry_md_write(md, s, len);
+
+ hash = gcry_md_read(md, 0);
+ if (!hash)
+ return -EIO;
+
+ enc = hexmem(hash, hash_size);
+ if (!enc)
+ return -ENOMEM;
+
+ *out = enc;
+ return 0;
+}
+#endif
diff --git a/src/libshared/gcrypt-util.h b/src/libshared/gcrypt-util.h
new file mode 100644
index 0000000000..cf33b3c59c
--- /dev/null
+++ b/src/libshared/gcrypt-util.h
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ 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 <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifdef HAVE_GCRYPT
+#include <gcrypt.h>
+
+void initialize_libgcrypt(bool secmem);
+int string_hashsum(const char *s, size_t len, int md_algorithm, char **out);
+#endif
+
+static inline int string_hashsum_sha224(const char *s, size_t len, char **out) {
+#ifdef HAVE_GCRYPT
+ return string_hashsum(s, len, GCRY_MD_SHA224, out);
+#else
+ return -EOPNOTSUPP;
+#endif
+}
diff --git a/src/libshared/generator.c b/src/libshared/generator.c
index cd3c35cd55..70afc6a285 100644
--- a/src/libshared/generator.c
+++ b/src/libshared/generator.c
@@ -65,7 +65,7 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
"Description=File System Check on %2$s\n"
"DefaultDependencies=no\n"
"BindsTo=%3$s\n"
- "After=%3$s local-fs-pre.target\n"
+ "After=initrd-root-device.target local-fs-pre.target\n"
"Before=shutdown.target\n"
"\n"
"[Service]\n"
@@ -191,3 +191,17 @@ int generator_write_timeouts(
"[Unit]\nJobTimeoutSec=%s",
program_invocation_short_name, timeout);
}
+
+int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
+ _cleanup_free_ char *unit = NULL;
+ int r;
+
+ r = unit_name_from_path(what, ".device", &unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make unit name from path: %m");
+
+ return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
+ "# Automatically generated by %s\n\n"
+ "[Unit]\nRequires=%s\nAfter=%s",
+ program_invocation_short_name, unit, unit);
+}
diff --git a/src/libshared/generator.h b/src/libshared/generator.h
index a734e13970..a6017c1b76 100644
--- a/src/libshared/generator.h
+++ b/src/libshared/generator.h
@@ -34,3 +34,7 @@ int generator_write_timeouts(
const char *where,
const char *opts,
char **filtered);
+
+int generator_write_initrd_root_device_deps(
+ const char *dir,
+ const char *what);
diff --git a/src/libshared/gpt.h b/src/libshared/gpt.h
index 9b8f59abee..07153b51f4 100644
--- a/src/libshared/gpt.h
+++ b/src/libshared/gpt.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <endian.h>
#include <systemd/sd-id128.h>
diff --git a/src/libshared/install-printf.h b/src/libshared/install-printf.h
index acf519f4f7..8a570fc265 100644
--- a/src/libshared/install-printf.h
+++ b/src/libshared/install-printf.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include "install.h"
int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret);
diff --git a/src/libshared/install.c b/src/libshared/install.c
index ef8f485cae..64d66a45d3 100644
--- a/src/libshared/install.c
+++ b/src/libshared/install.c
@@ -40,11 +40,13 @@
#include "hashmap.h"
#include "install-printf.h"
#include "install.h"
+#include "locale-util.h"
#include "log.h"
#include "macro.h"
#include "mkdir.h"
#include "path-lookup.h"
#include "path-util.h"
+#include "rm-rf.h"
#include "set.h"
#include "special.h"
#include "stat-util.h"
@@ -65,7 +67,65 @@ typedef struct {
OrderedHashmap *have_processed;
} InstallContext;
-static int in_search_path(const char *path, char **search) {
+typedef enum {
+ PRESET_UNKNOWN,
+ PRESET_ENABLE,
+ PRESET_DISABLE,
+} PresetAction;
+
+typedef struct {
+ char *pattern;
+ PresetAction action;
+} PresetRule;
+
+typedef struct {
+ PresetRule *rules;
+ size_t n_rules;
+} Presets;
+
+static inline void presets_freep(Presets *p) {
+ size_t i;
+
+ if (!p)
+ return;
+
+ for (i = 0; i < p->n_rules; i++)
+ free(p->rules[i].pattern);
+
+ free(p->rules);
+ p->n_rules = 0;
+}
+
+static int unit_file_lookup_state(UnitFileScope scope, const LookupPaths *paths, const char *name, UnitFileState *ret);
+
+bool unit_type_may_alias(UnitType type) {
+ return IN_SET(type,
+ UNIT_SERVICE,
+ UNIT_SOCKET,
+ UNIT_TARGET,
+ UNIT_DEVICE,
+ UNIT_TIMER,
+ UNIT_PATH);
+}
+
+bool unit_type_may_template(UnitType type) {
+ return IN_SET(type,
+ UNIT_SERVICE,
+ UNIT_SOCKET,
+ UNIT_TARGET,
+ UNIT_TIMER,
+ UNIT_PATH);
+}
+
+static const char *unit_file_type_table[_UNIT_FILE_TYPE_MAX] = {
+ [UNIT_FILE_TYPE_REGULAR] = "regular",
+ [UNIT_FILE_TYPE_SYMLINK] = "symlink",
+ [UNIT_FILE_TYPE_MASKED] = "masked",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType);
+
+static int in_search_path(const LookupPaths *p, const char *path) {
_cleanup_free_ char *parent = NULL;
char **i;
@@ -75,141 +135,141 @@ static int in_search_path(const char *path, char **search) {
if (!parent)
return -ENOMEM;
- STRV_FOREACH(i, search)
+ STRV_FOREACH(i, p->search_path)
if (path_equal(parent, *i))
return true;
return false;
}
-static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
- char *p = NULL;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(ret);
+static const char* skip_root(const LookupPaths *p, const char *path) {
+ char *e;
- /* This determines where we shall create or remove our
- * installation ("configuration") symlinks */
+ assert(p);
+ assert(path);
- switch (scope) {
+ if (!p->root_dir)
+ return path;
- case UNIT_FILE_SYSTEM:
+ e = path_startswith(path, p->root_dir);
+ if (!e)
+ return NULL;
- if (runtime)
- p = path_join(root_dir, "/run/systemd/system", NULL);
- else
- p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL);
- break;
+ /* Make sure the returned path starts with a slash */
+ if (e[0] != '/') {
+ if (e == path || e[-1] != '/')
+ return NULL;
- case UNIT_FILE_GLOBAL:
+ e--;
+ }
- if (root_dir)
- return -EINVAL;
+ return e;
+}
- if (runtime)
- p = strdup("/run/systemd/user");
- else
- p = strdup(USER_CONFIG_UNIT_PATH);
- break;
+static int path_is_generator(const LookupPaths *p, const char *path) {
+ _cleanup_free_ char *parent = NULL;
- case UNIT_FILE_USER:
+ assert(p);
+ assert(path);
- if (root_dir)
- return -EINVAL;
+ parent = dirname_malloc(path);
+ if (!parent)
+ return -ENOMEM;
- if (runtime)
- r = user_runtime_dir(&p);
- else
- r = user_config_home(&p);
- if (r < 0)
- return r;
- if (r == 0)
- return -ENOENT;
+ return path_equal_ptr(parent, p->generator) ||
+ path_equal_ptr(parent, p->generator_early) ||
+ path_equal_ptr(parent, p->generator_late);
+}
- break;
+static int path_is_transient(const LookupPaths *p, const char *path) {
+ _cleanup_free_ char *parent = NULL;
- default:
- assert_not_reached("Bad scope");
- }
+ assert(p);
+ assert(path);
- if (!p)
+ parent = dirname_malloc(path);
+ if (!parent)
return -ENOMEM;
- *ret = p;
- return 0;
+ return path_equal_ptr(parent, p->transient);
}
-static bool is_config_path(UnitFileScope scope, const char *path) {
- int r;
+static int path_is_control(const LookupPaths *p, const char *path) {
+ _cleanup_free_ char *parent = NULL;
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
+ assert(p);
assert(path);
- /* Checks whether the specified path is intended for
- * configuration or is outside of it */
+ parent = dirname_malloc(path);
+ if (!parent)
+ return -ENOMEM;
- switch (scope) {
+ return path_equal_ptr(parent, p->persistent_control) ||
+ path_equal_ptr(parent, p->runtime_control);
+}
- case UNIT_FILE_SYSTEM:
- case UNIT_FILE_GLOBAL:
- return path_startswith(path, "/etc") ||
- path_startswith(path, SYSTEM_CONFIG_UNIT_PATH) ||
- path_startswith(path, "/run");
+static int path_is_config(const LookupPaths *p, const char *path) {
+ _cleanup_free_ char *parent = NULL;
+ assert(p);
+ assert(path);
- case UNIT_FILE_USER: {
- _cleanup_free_ char *p = NULL;
+ /* Note that we do *not* have generic checks for /etc or /run in place, since with them we couldn't discern
+ * configuration from transient or generated units */
- r = user_config_home(&p);
- if (r < 0)
- return r;
- if (r > 0 && path_startswith(path, p))
- return true;
+ parent = dirname_malloc(path);
+ if (!parent)
+ return -ENOMEM;
- p = mfree(p);
+ return path_equal_ptr(parent, p->persistent_config) ||
+ path_equal_ptr(parent, p->runtime_config);
+}
- r = user_runtime_dir(&p);
- if (r < 0)
- return r;
- if (r > 0 && path_startswith(path, p))
- return true;
+static int path_is_runtime(const LookupPaths *p, const char *path) {
+ _cleanup_free_ char *parent = NULL;
+ const char *rpath;
- return false;
- }
+ assert(p);
+ assert(path);
- default:
- assert_not_reached("Bad scope");
- }
-}
+ /* Everything in /run is considered runtime. On top of that we also add explicit checks for the various runtime
+ * directories, as safety net. */
+ rpath = skip_root(p, path);
+ if (rpath && path_startswith(rpath, "/run"))
+ return true;
-static int verify_root_dir(UnitFileScope scope, const char **root_dir) {
- int r;
+ parent = dirname_malloc(path);
+ if (!parent)
+ return -ENOMEM;
+
+ return path_equal_ptr(parent, p->runtime_config) ||
+ path_equal_ptr(parent, p->generator) ||
+ path_equal_ptr(parent, p->generator_early) ||
+ path_equal_ptr(parent, p->generator_late) ||
+ path_equal_ptr(parent, p->transient) ||
+ path_equal_ptr(parent, p->runtime_control);
+}
- assert(root_dir);
+static int path_is_vendor(const LookupPaths *p, const char *path) {
+ const char *rpath;
- /* Verifies that the specified root directory to operate on
- * makes sense. Reset it to NULL if it is the root directory
- * or set to empty */
+ assert(p);
+ assert(path);
- if (isempty(*root_dir) || path_equal(*root_dir, "/")) {
- *root_dir = NULL;
+ rpath = skip_root(p, path);
+ if (!rpath)
return 0;
- }
- if (scope != UNIT_FILE_SYSTEM)
- return -EINVAL;
+ if (path_startswith(rpath, "/usr"))
+ return true;
- r = is_dir(*root_dir, true);
- if (r < 0)
- return r;
- if (r == 0)
- return -ENOTDIR;
+#ifdef HAVE_SPLIT_USR
+ if (path_startswith(rpath, "/lib"))
+ return true;
+#endif
- return 0;
+ return path_equal(rpath, SYSTEM_DATA_UNIT_PATH);
}
int unit_file_changes_add(
@@ -219,8 +279,8 @@ int unit_file_changes_add(
const char *path,
const char *source) {
+ _cleanup_free_ char *p = NULL, *s = NULL;
UnitFileChange *c;
- unsigned i;
assert(path);
assert(!changes == !n_changes);
@@ -231,29 +291,22 @@ int unit_file_changes_add(
c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
if (!c)
return -ENOMEM;
-
*changes = c;
- i = *n_changes;
-
- c[i].type = type;
- c[i].path = strdup(path);
- if (!c[i].path)
- return -ENOMEM;
- path_kill_slashes(c[i].path);
+ p = strdup(path);
+ if (source)
+ s = strdup(source);
- if (source) {
- c[i].source = strdup(source);
- if (!c[i].source) {
- free(c[i].path);
- return -ENOMEM;
- }
+ if (!p || (source && !s))
+ return -ENOMEM;
- path_kill_slashes(c[i].path);
- } else
- c[i].source = NULL;
+ path_kill_slashes(p);
+ if (s)
+ path_kill_slashes(s);
- *n_changes = i+1;
+ c[*n_changes] = (UnitFileChange) { type, p, s };
+ p = s = NULL;
+ (*n_changes) ++;
return 0;
}
@@ -262,9 +315,6 @@ void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
assert(changes || n_changes == 0);
- if (!changes)
- return;
-
for (i = 0; i < n_changes; i++) {
free(changes[i].path);
free(changes[i].source);
@@ -273,6 +323,76 @@ void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
free(changes);
}
+void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, unsigned n_changes, bool quiet) {
+ unsigned i;
+ bool logged = false;
+
+ assert(changes || n_changes == 0);
+ /* If verb is not specified, errors are not allowed! */
+ assert(verb || r >= 0);
+
+ for (i = 0; i < n_changes; i++) {
+ assert(verb || changes[i].type >= 0);
+
+ switch(changes[i].type) {
+ case UNIT_FILE_SYMLINK:
+ if (!quiet)
+ log_info("Created symlink %s %s %s.",
+ changes[i].path,
+ special_glyph(ARROW),
+ changes[i].source);
+ break;
+ case UNIT_FILE_UNLINK:
+ if (!quiet)
+ log_info("Removed %s.", changes[i].path);
+ break;
+ case UNIT_FILE_IS_MASKED:
+ if (!quiet)
+ log_info("Unit %s is masked, ignoring.", changes[i].path);
+ break;
+ case UNIT_FILE_IS_DANGLING:
+ if (!quiet)
+ log_info("Unit %s is an alias to a unit that is not present, ignoring.",
+ changes[i].path);
+ break;
+ case -EEXIST:
+ if (changes[i].source)
+ log_error_errno(changes[i].type,
+ "Failed to %s unit, file %s already exists and is a symlink to %s.",
+ verb, changes[i].path, changes[i].source);
+ else
+ log_error_errno(changes[i].type,
+ "Failed to %s unit, file %s already exists.",
+ verb, changes[i].path);
+ logged = true;
+ break;
+ case -ERFKILL:
+ log_error_errno(changes[i].type, "Failed to %s unit, unit %s is masked.",
+ verb, changes[i].path);
+ logged = true;
+ break;
+ case -EADDRNOTAVAIL:
+ log_error_errno(changes[i].type, "Failed to %s unit, unit %s is transient or generated.",
+ verb, changes[i].path);
+ logged = true;
+ break;
+ case -ELOOP:
+ log_error_errno(changes[i].type, "Failed to %s unit, refusing to operate on linked unit file %s",
+ verb, changes[i].path);
+ logged = true;
+ break;
+ default:
+ assert(changes[i].type < 0);
+ log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.",
+ verb, changes[i].path);
+ logged = true;
+ }
+ }
+
+ if (r < 0 && !logged)
+ log_error_errno(r, "Failed to %s: %m.", verb);
+}
+
static int create_symlink(
const char *old_path,
const char *new_path,
@@ -288,36 +408,52 @@ static int create_symlink(
/* Actually create a symlink, and remember that we did. Is
* smart enough to check if there's already a valid symlink in
- * place. */
+ * place.
+ *
+ * Returns 1 if a symlink was created or already exists and points to
+ * the right place, or negative on error.
+ */
mkdir_parents_label(new_path, 0755);
if (symlink(old_path, new_path) >= 0) {
unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
- return 0;
+ return 1;
}
- if (errno != EEXIST)
+ if (errno != EEXIST) {
+ unit_file_changes_add(changes, n_changes, -errno, new_path, NULL);
return -errno;
+ }
r = readlink_malloc(new_path, &dest);
- if (r < 0)
+ if (r < 0) {
+ /* translate EINVAL (non-symlink exists) to EEXIST */
+ if (r == -EINVAL)
+ r = -EEXIST;
+
+ unit_file_changes_add(changes, n_changes, r, new_path, NULL);
return r;
+ }
if (path_equal(dest, old_path))
- return 0;
+ return 1;
- if (!force)
+ if (!force) {
+ unit_file_changes_add(changes, n_changes, -EEXIST, new_path, dest);
return -EEXIST;
+ }
r = symlink_atomic(old_path, new_path);
- if (r < 0)
+ if (r < 0) {
+ unit_file_changes_add(changes, n_changes, r, new_path, NULL);
return r;
+ }
unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
- return 0;
+ return 1;
}
static int mark_symlink_for_removal(
@@ -353,6 +489,7 @@ static int remove_marked_symlinks_fd(
int fd,
const char *path,
const char *config_path,
+ const LookupPaths *lp,
bool *restart,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -365,6 +502,7 @@ static int remove_marked_symlinks_fd(
assert(fd >= 0);
assert(path);
assert(config_path);
+ assert(lp);
assert(restart);
d = fdopendir(fd);
@@ -400,12 +538,13 @@ static int remove_marked_symlinks_fd(
}
/* This will close nfd, regardless whether it succeeds or not */
- q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, restart, changes, n_changes);
+ q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, lp, restart, changes, n_changes);
if (q < 0 && r == 0)
r = q;
} else if (de->d_type == DT_LNK) {
_cleanup_free_ char *p = NULL, *dest = NULL;
+ const char *rp;
bool found;
int q;
@@ -415,42 +554,43 @@ static int remove_marked_symlinks_fd(
p = path_make_absolute(de->d_name, path);
if (!p)
return -ENOMEM;
+ path_kill_slashes(p);
q = readlink_malloc(p, &dest);
+ if (q == -ENOENT)
+ continue;
if (q < 0) {
- if (q == -ENOENT)
- continue;
-
if (r == 0)
r = q;
continue;
}
- /* We remove all links pointing to a file or
- * path that is marked, as well as all files
- * sharing the same name as a file that is
- * marked. */
+ /* We remove all links pointing to a file or path that is marked, as well as all files sharing
+ * the same name as a file that is marked. */
- found =
- set_contains(remove_symlinks_to, dest) ||
+ found = set_contains(remove_symlinks_to, dest) ||
set_contains(remove_symlinks_to, basename(dest)) ||
set_contains(remove_symlinks_to, de->d_name);
if (!found)
continue;
- if (unlink(p) < 0 && errno != ENOENT) {
+ if (unlinkat(fd, de->d_name, 0) < 0 && errno != ENOENT) {
if (r == 0)
r = -errno;
+ unit_file_changes_add(changes, n_changes, -errno, p, NULL);
continue;
}
- path_kill_slashes(p);
(void) rmdir_parents(p, config_path);
unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
- q = mark_symlink_for_removal(&remove_symlinks_to, p);
+ /* Now, remember the full path (but with the root prefix removed) of
+ * the symlink we just removed, and remove any symlinks to it, too. */
+
+ rp = skip_root(lp, p);
+ q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: p);
if (q < 0)
return q;
if (q > 0)
@@ -464,6 +604,7 @@ static int remove_marked_symlinks_fd(
static int remove_marked_symlinks(
Set *remove_symlinks_to,
const char *config_path,
+ const LookupPaths *lp,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -472,6 +613,7 @@ static int remove_marked_symlinks(
int r = 0;
assert(config_path);
+ assert(lp);
if (set_size(remove_symlinks_to) <= 0)
return 0;
@@ -489,7 +631,7 @@ static int remove_marked_symlinks(
return -errno;
/* This takes possession of cfd and closes it */
- q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &restart, changes, n_changes);
+ q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, lp, &restart, changes, n_changes);
if (r == 0)
r = q;
} while (restart);
@@ -503,6 +645,7 @@ static int find_symlinks_fd(
int fd,
const char *path,
const char *config_path,
+ const LookupPaths *lp,
bool *same_name_link) {
_cleanup_closedir_ DIR *d = NULL;
@@ -513,6 +656,7 @@ static int find_symlinks_fd(
assert(fd >= 0);
assert(path);
assert(config_path);
+ assert(lp);
assert(same_name_link);
d = fdopendir(fd);
@@ -546,7 +690,7 @@ static int find_symlinks_fd(
}
/* This will close nfd, regardless whether it succeeds or not */
- q = find_symlinks_fd(root_dir, name, nfd, p, config_path, same_name_link);
+ q = find_symlinks_fd(root_dir, name, nfd, p, config_path, lp, same_name_link);
if (q > 0)
return 1;
if (r == 0)
@@ -624,6 +768,7 @@ static int find_symlinks(
const char *root_dir,
const char *name,
const char *config_path,
+ const LookupPaths *lp,
bool *same_name_link) {
int fd;
@@ -640,29 +785,25 @@ static int find_symlinks(
}
/* This takes possession of fd and closes it */
- return find_symlinks_fd(root_dir, name, fd, config_path, config_path, same_name_link);
+ return find_symlinks_fd(root_dir, name, fd, config_path, config_path, lp, same_name_link);
}
static int find_symlinks_in_scope(
UnitFileScope scope,
- const char *root_dir,
+ const LookupPaths *paths,
const char *name,
UnitFileState *state) {
- _cleanup_free_ char *normal_path = NULL, *runtime_path = NULL;
bool same_name_link_runtime = false, same_name_link = false;
int r;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
+ assert(paths);
assert(name);
- /* First look in the normal config path */
- r = get_config_path(scope, false, root_dir, &normal_path);
- if (r < 0)
- return r;
-
- r = find_symlinks(root_dir, name, normal_path, &same_name_link);
+ /* First look in the persistent config path */
+ r = find_symlinks(paths->root_dir, name, paths->persistent_config, paths, &same_name_link);
if (r < 0)
return r;
if (r > 0) {
@@ -671,11 +812,7 @@ static int find_symlinks_in_scope(
}
/* Then look in runtime config path */
- r = get_config_path(scope, true, root_dir, &runtime_path);
- if (r < 0)
- return r;
-
- r = find_symlinks(root_dir, name, runtime_path, &same_name_link_runtime);
+ r = find_symlinks(paths->root_dir, name, paths->runtime_config, paths, &same_name_link_runtime);
if (r < 0)
return r;
if (r > 0) {
@@ -742,6 +879,30 @@ static UnitFileInstallInfo *install_info_find(InstallContext *c, const char *nam
return ordered_hashmap_get(c->will_process, name);
}
+static int install_info_may_process(
+ UnitFileInstallInfo *i,
+ const LookupPaths *paths,
+ UnitFileChange **changes,
+ unsigned *n_changes) {
+ assert(i);
+ assert(paths);
+
+ /* Checks whether the loaded unit file is one we should process, or is masked, transient or generated and thus
+ * not subject to enable/disable operations. */
+
+ if (i->type == UNIT_FILE_TYPE_MASKED) {
+ unit_file_changes_add(changes, n_changes, -ERFKILL, i->path, NULL);
+ return -ERFKILL;
+ }
+ if (path_is_generator(paths, i->path) ||
+ path_is_transient(paths, i->path)) {
+ unit_file_changes_add(changes, n_changes, -EADDRNOTAVAIL, i->path, NULL);
+ return -EADDRNOTAVAIL;
+ }
+
+ return 0;
+}
+
static int install_info_add(
InstallContext *c,
const char *name,
@@ -804,18 +965,34 @@ fail:
return r;
}
-static int install_info_add_auto(
- InstallContext *c,
- const char *name_or_path,
- UnitFileInstallInfo **ret) {
+static int config_parse_alias(
+ 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) {
- assert(c);
- assert(name_or_path);
+ const char *name;
+ UnitType type;
- if (path_is_absolute(name_or_path))
- return install_info_add(c, NULL, name_or_path, ret);
- else
- return install_info_add(c, name_or_path, NULL, ret);
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ name = basename(filename);
+ type = unit_name_to_type(name);
+ if (!unit_type_may_alias(type))
+ return log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Aliases are not allowed for %s units, ignoring.",
+ unit_type_to_string(type));
+
+ return config_parse_strv(unit, filename, line, section, section_line,
+ lvalue, ltype, rvalue, data, userdata);
}
static int config_parse_also(
@@ -874,6 +1051,7 @@ static int config_parse_default_instance(
void *userdata) {
UnitFileInstallInfo *i = data;
+ const char *name;
char *printed;
int r;
@@ -881,6 +1059,15 @@ static int config_parse_default_instance(
assert(lvalue);
assert(rvalue);
+ name = basename(filename);
+ if (unit_name_is_valid(name, UNIT_NAME_INSTANCE))
+ /* When enabling an instance, we might be using a template unit file,
+ * but we should ignore DefaultInstance silently. */
+ return 0;
+ if (!unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
+ return log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "DefaultInstance only makes sense for template units, ignoring.");
+
r = install_full_printf(i, rvalue, &printed);
if (r < 0)
return r;
@@ -900,11 +1087,10 @@ static int unit_file_load(
InstallContext *c,
UnitFileInstallInfo *info,
const char *path,
- const char *root_dir,
SearchFlags flags) {
const ConfigTableItem items[] = {
- { "Install", "Alias", config_parse_strv, 0, &info->aliases },
+ { "Install", "Alias", config_parse_alias, 0, &info->aliases },
{ "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
{ "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
{ "Install", "DefaultInstance", config_parse_default_instance, 0, info },
@@ -912,6 +1098,8 @@ static int unit_file_load(
{}
};
+ const char *name;
+ UnitType type;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -1;
struct stat st;
@@ -921,7 +1109,11 @@ static int unit_file_load(
assert(info);
assert(path);
- path = prefix_roota(root_dir, path);
+ name = basename(path);
+ type = unit_name_to_type(name);
+ if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) &&
+ !unit_type_may_template(type))
+ return log_error_errno(EINVAL, "Unit type %s cannot be templated.", unit_type_to_string(type));
if (!(flags & SEARCH_LOAD)) {
r = lstat(path, &st);
@@ -983,26 +1175,26 @@ static int unit_file_load_or_readlink(
const char *root_dir,
SearchFlags flags) {
- _cleanup_free_ char *np = NULL;
+ _cleanup_free_ char *target = NULL;
int r;
- r = unit_file_load(c, info, path, root_dir, flags);
+ r = unit_file_load(c, info, path, flags);
if (r != -ELOOP)
return r;
/* This is a symlink, let's read it. */
- r = readlink_and_make_absolute_root(root_dir, path, &np);
+ r = readlink_malloc(path, &target);
if (r < 0)
return r;
- if (path_equal(np, "/dev/null"))
+ if (path_equal(target, "/dev/null"))
info->type = UNIT_FILE_TYPE_MASKED;
else {
const char *bn;
UnitType a, b;
- bn = basename(np);
+ bn = basename(target);
if (unit_name_is_valid(info->name, UNIT_NAME_PLAIN)) {
@@ -1029,9 +1221,16 @@ static int unit_file_load_or_readlink(
if (a < 0 || b < 0 || a != b)
return -EINVAL;
+ if (path_is_absolute(target))
+ /* This is an absolute path, prefix the root so that we always deal with fully qualified paths */
+ info->symlink_target = prefix_root(root_dir, target);
+ else
+ /* This is a relative path, take it relative to the dir the symlink is located in. */
+ info->symlink_target = file_in_same_dir(path, target);
+ if (!info->symlink_target)
+ return -ENOMEM;
+
info->type = UNIT_FILE_TYPE_SYMLINK;
- info->symlink_target = np;
- np = NULL;
}
return 0;
@@ -1041,9 +1240,9 @@ static int unit_file_search(
InstallContext *c,
UnitFileInstallInfo *info,
const LookupPaths *paths,
- const char *root_dir,
SearchFlags flags) {
+ _cleanup_free_ char *template = NULL;
char **p;
int r;
@@ -1056,59 +1255,53 @@ static int unit_file_search(
return 0;
if (info->path)
- return unit_file_load_or_readlink(c, info, info->path, root_dir, flags);
+ return unit_file_load_or_readlink(c, info, info->path, paths->root_dir, flags);
assert(info->name);
- STRV_FOREACH(p, paths->unit_path) {
+ STRV_FOREACH(p, paths->search_path) {
_cleanup_free_ char *path = NULL;
path = strjoin(*p, "/", info->name, NULL);
if (!path)
return -ENOMEM;
- r = unit_file_load_or_readlink(c, info, path, root_dir, flags);
- if (r < 0) {
- if (r != -ENOENT)
- return r;
- } else {
+ r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
+ if (r >= 0) {
info->path = path;
path = NULL;
return r;
- }
+ } else if (r != -ENOENT)
+ return r;
}
if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
-
/* Unit file doesn't exist, however instance
* enablement was requested. We will check if it is
* possible to load template unit file. */
- _cleanup_free_ char *template = NULL;
-
r = unit_name_template(info->name, &template);
if (r < 0)
return r;
- STRV_FOREACH(p, paths->unit_path) {
+ STRV_FOREACH(p, paths->search_path) {
_cleanup_free_ char *path = NULL;
path = strjoin(*p, "/", template, NULL);
if (!path)
return -ENOMEM;
- r = unit_file_load_or_readlink(c, info, path, root_dir, flags);
- if (r < 0) {
- if (r != -ENOENT)
- return r;
- } else {
+ r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
+ if (r >= 0) {
info->path = path;
path = NULL;
return r;
- }
+ } else if (r != -ENOENT)
+ return r;
}
}
+ log_debug("Cannot find unit %s%s%s.", info->name, template ? " or " : "", strempty(template));
return -ENOENT;
}
@@ -1140,10 +1333,14 @@ static int install_info_follow(
return unit_file_load_or_readlink(c, i, i->path, root_dir, flags);
}
+/**
+ * Search for the unit file. If the unit name is a symlink,
+ * follow the symlink to the target, maybe more than once.
+ * Propagate the instance name if present.
+ */
static int install_info_traverse(
UnitFileScope scope,
InstallContext *c,
- const char *root_dir,
const LookupPaths *paths,
UnitFileInstallInfo *start,
SearchFlags flags,
@@ -1157,7 +1354,7 @@ static int install_info_traverse(
assert(start);
assert(c);
- r = unit_file_search(c, start, paths, root_dir, flags);
+ r = unit_file_search(c, start, paths, flags);
if (r < 0)
return r;
@@ -1168,17 +1365,19 @@ static int install_info_traverse(
if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX)
return -ELOOP;
- if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS) && is_config_path(scope, i->path))
- return -ELOOP;
+ if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS)) {
+ r = path_is_config(paths, i->path);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ return -ELOOP;
+ }
- r = install_info_follow(c, i, root_dir, flags);
- if (r < 0) {
+ r = install_info_follow(c, i, paths->root_dir, flags);
+ if (r == -EXDEV) {
_cleanup_free_ char *buffer = NULL;
const char *bn;
- if (r != -EXDEV)
- return r;
-
/* Target has a different name, create a new
* install info object for that, and continue
* with that. */
@@ -1205,12 +1404,15 @@ static int install_info_traverse(
if (r < 0)
return r;
- r = unit_file_search(c, i, paths, root_dir, flags);
- if (r < 0)
- return r;
+ /* Try again, with the new target we found. */
+ r = unit_file_search(c, i, paths, flags);
+ if (r == -ENOENT)
+ /* Translate error code to highlight this specific case */
+ return -ENOLINK;
}
- /* Try again, with the new target we found. */
+ if (r < 0)
+ return r;
}
if (ret)
@@ -1219,10 +1421,28 @@ static int install_info_traverse(
return 0;
}
+static int install_info_add_auto(
+ InstallContext *c,
+ const LookupPaths *paths,
+ const char *name_or_path,
+ UnitFileInstallInfo **ret) {
+
+ assert(c);
+ assert(name_or_path);
+
+ if (path_is_absolute(name_or_path)) {
+ const char *pp;
+
+ pp = prefix_roota(paths->root_dir, name_or_path);
+
+ return install_info_add(c, NULL, pp, ret);
+ } else
+ return install_info_add(c, name_or_path, NULL, ret);
+}
+
static int install_info_discover(
UnitFileScope scope,
InstallContext *c,
- const char *root_dir,
const LookupPaths *paths,
const char *name,
SearchFlags flags,
@@ -1235,15 +1455,16 @@ static int install_info_discover(
assert(paths);
assert(name);
- r = install_info_add_auto(c, name, &i);
+ r = install_info_add_auto(c, paths, name, &i);
if (r < 0)
return r;
- return install_info_traverse(scope, c, root_dir, paths, i, flags, ret);
+ return install_info_traverse(scope, c, paths, i, flags, ret);
}
static int install_info_symlink_alias(
UnitFileInstallInfo *i,
+ const LookupPaths *paths,
const char *config_path,
bool force,
UnitFileChange **changes,
@@ -1253,10 +1474,12 @@ static int install_info_symlink_alias(
int r = 0, q;
assert(i);
+ assert(paths);
assert(config_path);
STRV_FOREACH(s, i->aliases) {
_cleanup_free_ char *alias_path = NULL, *dst = NULL;
+ const char *rp;
q = install_full_printf(i, *s, &dst);
if (q < 0)
@@ -1266,7 +1489,9 @@ static int install_info_symlink_alias(
if (!alias_path)
return -ENOMEM;
- q = create_symlink(i->path, alias_path, force, changes, n_changes);
+ rp = skip_root(paths, i->path);
+
+ q = create_symlink(rp ?: i->path, alias_path, force, changes, n_changes);
if (r == 0)
r = q;
}
@@ -1276,10 +1501,10 @@ static int install_info_symlink_alias(
static int install_info_symlink_wants(
UnitFileInstallInfo *i,
+ const LookupPaths *paths,
const char *config_path,
char **list,
const char *suffix,
- bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -1289,6 +1514,7 @@ static int install_info_symlink_wants(
int r = 0, q;
assert(i);
+ assert(paths);
assert(config_path);
if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) {
@@ -1309,6 +1535,7 @@ static int install_info_symlink_wants(
STRV_FOREACH(s, list) {
_cleanup_free_ char *path = NULL, *dst = NULL;
+ const char *rp;
q = install_full_printf(i, *s, &dst);
if (q < 0)
@@ -1323,7 +1550,9 @@ static int install_info_symlink_wants(
if (!path)
return -ENOMEM;
- q = create_symlink(i->path, path, force, changes, n_changes);
+ rp = skip_root(paths, i->path);
+
+ q = create_symlink(rp ?: i->path, path, true, changes, n_changes);
if (r == 0)
r = q;
}
@@ -1335,12 +1564,12 @@ static int install_info_symlink_link(
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
- const char *root_dir,
bool force,
UnitFileChange **changes,
unsigned *n_changes) {
_cleanup_free_ char *path = NULL;
+ const char *rp;
int r;
assert(i);
@@ -1348,22 +1577,25 @@ static int install_info_symlink_link(
assert(config_path);
assert(i->path);
- r = in_search_path(i->path, paths->unit_path);
- if (r != 0)
+ r = in_search_path(paths, i->path);
+ if (r < 0)
return r;
+ if (r > 0)
+ return 0;
path = strjoin(config_path, "/", i->name, NULL);
if (!path)
return -ENOMEM;
- return create_symlink(i->path, path, force, changes, n_changes);
+ rp = skip_root(paths, i->path);
+
+ return create_symlink(rp ?: i->path, path, force, changes, n_changes);
}
static int install_info_apply(
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
- const char *root_dir,
bool force,
UnitFileChange **changes,
unsigned *n_changes) {
@@ -1377,18 +1609,19 @@ static int install_info_apply(
if (i->type != UNIT_FILE_TYPE_REGULAR)
return 0;
- r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
+ r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes);
- q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
+ q = install_info_symlink_wants(i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
if (r == 0)
r = q;
- q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
+ q = install_info_symlink_wants(i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
if (r == 0)
r = q;
- q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
- if (r == 0)
+ q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
+ /* Do not count links to the unit file towards the "carries_install_info" count */
+ if (r == 0 && q < 0)
r = q;
return r;
@@ -1399,7 +1632,6 @@ static int install_context_apply(
InstallContext *c,
const LookupPaths *paths,
const char *config_path,
- const char *root_dir,
bool force,
SearchFlags flags,
UnitFileChange **changes,
@@ -1427,19 +1659,19 @@ static int install_context_apply(
if (q < 0)
return q;
- r = install_info_traverse(scope, c, root_dir, paths, i, flags, NULL);
+ r = install_info_traverse(scope, c, paths, i, flags, NULL);
if (r < 0)
return r;
if (i->type != UNIT_FILE_TYPE_REGULAR)
continue;
- q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
+ q = install_info_apply(i, paths, config_path, force, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
else
- r+= q;
+ r += q;
}
}
@@ -1451,8 +1683,7 @@ static int install_context_mark_for_removal(
InstallContext *c,
const LookupPaths *paths,
Set **remove_symlinks_to,
- const char *config_path,
- const char *root_dir) {
+ const char *config_path) {
UnitFileInstallInfo *i;
int r;
@@ -1476,12 +1707,18 @@ static int install_context_mark_for_removal(
if (r < 0)
return r;
- r = install_info_traverse(scope, c, root_dir, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);
- if (r < 0)
+ r = install_info_traverse(scope, c, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);
+ if (r == -ENOLINK)
+ return 0;
+ else if (r < 0)
return r;
- if (i->type != UNIT_FILE_TYPE_REGULAR)
+ if (i->type != UNIT_FILE_TYPE_REGULAR) {
+ log_debug("Unit %s has type %s, ignoring.",
+ i->name,
+ unit_file_type_to_string(i->type) ?: "invalid");
continue;
+ }
r = mark_symlink_for_removal(remove_symlinks_to, i->name);
if (r < 0)
@@ -1500,20 +1737,19 @@ int unit_file_mask(
UnitFileChange **changes,
unsigned *n_changes) {
- _cleanup_free_ char *prefix = NULL;
+ _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ const char *config_path;
char **i;
int r;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = get_config_path(scope, runtime, root_dir, &prefix);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
_cleanup_free_ char *path = NULL;
@@ -1525,7 +1761,7 @@ int unit_file_mask(
continue;
}
- path = path_make_absolute(*i, prefix);
+ path = path_make_absolute(*i, config_path);
if (!path)
return -ENOMEM;
@@ -1545,23 +1781,22 @@ int unit_file_unmask(
UnitFileChange **changes,
unsigned *n_changes) {
+ _cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- _cleanup_free_ char *config_path = NULL;
_cleanup_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
+ const char *config_path;
char **i;
int r, q;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = get_config_path(scope, runtime, root_dir, &config_path);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
_cleanup_free_ char *path = NULL;
@@ -1592,24 +1827,31 @@ int unit_file_unmask(
r = 0;
STRV_FOREACH(i, todo) {
_cleanup_free_ char *path = NULL;
+ const char *rp;
path = path_make_absolute(*i, config_path);
if (!path)
return -ENOMEM;
if (unlink(path) < 0) {
- if (errno != -ENOENT && r >= 0)
- r = -errno;
- } else {
- q = mark_symlink_for_removal(&remove_symlinks_to, path);
- if (q < 0)
- return q;
+ if (errno != ENOENT) {
+ if (r >= 0)
+ r = -errno;
+ unit_file_changes_add(changes, n_changes, -errno, path, NULL);
+ }
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+ continue;
}
+
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+
+ rp = skip_root(&paths, path);
+ q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
+ if (q < 0)
+ return q;
}
- q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
+ q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, changes, n_changes);
if (r >= 0)
r = q;
@@ -1626,26 +1868,20 @@ int unit_file_link(
unsigned *n_changes) {
_cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_free_ char *config_path = NULL;
_cleanup_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
+ const char *config_path;
char **i;
int r, q;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
- r = verify_root_dir(scope, &root_dir);
- if (r < 0)
- return r;
-
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = get_config_path(scope, runtime, root_dir, &config_path);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
_cleanup_free_ char *full = NULL;
@@ -1659,7 +1895,7 @@ int unit_file_link(
if (!unit_name_is_valid(fn, UNIT_NAME_ANY))
return -EINVAL;
- full = prefix_root(root_dir, *i);
+ full = prefix_root(paths.root_dir, *i);
if (!full)
return -ENOMEM;
@@ -1672,7 +1908,7 @@ int unit_file_link(
if (!S_ISREG(st.st_mode))
return -ENOTTY;
- q = in_search_path(*i, paths.unit_path);
+ q = in_search_path(&paths, *i);
if (q < 0)
return q;
if (q > 0)
@@ -1688,13 +1924,15 @@ int unit_file_link(
r = 0;
STRV_FOREACH(i, todo) {
- _cleanup_free_ char *path = NULL;
+ _cleanup_free_ char *new_path = NULL;
+ const char *old_path;
- path = path_make_absolute(basename(*i), config_path);
- if (!path)
+ old_path = skip_root(&paths, *i);
+ new_path = path_make_absolute(basename(*i), config_path);
+ if (!new_path)
return -ENOMEM;
- q = create_symlink(*i, path, force, changes, n_changes);
+ q = create_symlink(old_path ?: *i, new_path, force, changes, n_changes);
if (q < 0 && r >= 0)
r = q;
}
@@ -1702,6 +1940,182 @@ int unit_file_link(
return r;
}
+static int path_shall_revert(const LookupPaths *paths, const char *path) {
+ int r;
+
+ assert(paths);
+ assert(path);
+
+ /* Checks whether the path is one where the drop-in directories shall be removed. */
+
+ r = path_is_config(paths, path);
+ if (r != 0)
+ return r;
+
+ r = path_is_control(paths, path);
+ if (r != 0)
+ return r;
+
+ return path_is_transient(paths, path);
+}
+
+int unit_file_revert(
+ UnitFileScope scope,
+ const char *root_dir,
+ char **files,
+ UnitFileChange **changes,
+ unsigned *n_changes) {
+
+ _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+ /* _cleanup_(install_context_done) InstallContext c = {}; */
+ _cleanup_lookup_paths_free_ LookupPaths paths = {};
+ _cleanup_strv_free_ char **todo = NULL;
+ size_t n_todo = 0, n_allocated = 0;
+ char **i;
+ int r, q;
+
+ /* Puts a unit file back into vendor state. This means:
+ *
+ * a) we remove all drop-in snippets added by the user ("config"), add to transient units ("transient"), and
+ * added via "systemctl set-property" ("control"), but not if the drop-in is generated ("generated").
+ *
+ * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files (i.e. in
+ * "config", but not in "transient" or "control" or even "generated").
+ *
+ * We remove all that in both the runtime and the persistent directories, if that applies.
+ */
+
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(i, files) {
+ bool has_vendor = false;
+ char **p;
+
+ if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
+ return -EINVAL;
+
+ STRV_FOREACH(p, paths.search_path) {
+ _cleanup_free_ char *path = NULL, *dropin = NULL;
+ struct stat st;
+
+ path = path_make_absolute(*i, *p);
+ if (!path)
+ return -ENOMEM;
+
+ r = lstat(path, &st);
+ if (r < 0) {
+ if (errno != ENOENT)
+ return -errno;
+ } else if (S_ISREG(st.st_mode)) {
+ /* Check if there's a vendor version */
+ r = path_is_vendor(&paths, path);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ has_vendor = true;
+ }
+
+ dropin = strappend(path, ".d");
+ if (!dropin)
+ return -ENOMEM;
+
+ r = lstat(dropin, &st);
+ if (r < 0) {
+ if (errno != ENOENT)
+ return -errno;
+ } else if (S_ISDIR(st.st_mode)) {
+ /* Remove the drop-ins */
+ r = path_shall_revert(&paths, dropin);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
+ return -ENOMEM;
+
+ todo[n_todo++] = dropin;
+ dropin = NULL;
+ }
+ }
+ }
+
+ if (!has_vendor)
+ continue;
+
+ /* OK, there's a vendor version, hence drop all configuration versions */
+ STRV_FOREACH(p, paths.search_path) {
+ _cleanup_free_ char *path = NULL;
+ struct stat st;
+
+ path = path_make_absolute(*i, *p);
+ if (!path)
+ return -ENOMEM;
+
+ r = lstat(path, &st);
+ if (r < 0) {
+ if (errno != ENOENT)
+ return -errno;
+ } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
+ r = path_is_config(&paths, path);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
+ return -ENOMEM;
+
+ todo[n_todo++] = path;
+ path = NULL;
+ }
+ }
+ }
+ }
+
+ strv_uniq(todo);
+
+ r = 0;
+ STRV_FOREACH(i, todo) {
+ _cleanup_strv_free_ char **fs = NULL;
+ const char *rp;
+ char **j;
+
+ (void) get_files_in_directory(*i, &fs);
+
+ q = rm_rf(*i, REMOVE_ROOT|REMOVE_PHYSICAL);
+ if (q < 0 && q != -ENOENT && r >= 0) {
+ r = q;
+ continue;
+ }
+
+ STRV_FOREACH(j, fs) {
+ _cleanup_free_ char *t = NULL;
+
+ t = strjoin(*i, "/", *j, NULL);
+ if (!t)
+ return -ENOMEM;
+
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, t, NULL);
+ }
+
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, *i, NULL);
+
+ rp = skip_root(&paths, *i);
+ q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: *i);
+ if (q < 0)
+ return q;
+ }
+
+ q = remove_marked_symlinks(remove_symlinks_to, paths.runtime_config, &paths, changes, n_changes);
+ if (r >= 0)
+ r = q;
+
+ q = remove_marked_symlinks(remove_symlinks_to, paths.persistent_config, &paths, changes, n_changes);
+ if (r >= 0)
+ r = q;
+
+ return r;
+}
+
int unit_file_add_dependency(
UnitFileScope scope,
bool runtime,
@@ -1715,8 +2129,8 @@ int unit_file_add_dependency(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
- _cleanup_free_ char *config_path = NULL;
UnitFileInstallInfo *i, *target_info;
+ const char *config_path;
char **f;
int r;
@@ -1730,34 +2144,30 @@ int unit_file_add_dependency(
if (!unit_name_is_valid(target, UNIT_NAME_ANY))
return -EINVAL;
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
- r = get_config_path(scope, runtime, root_dir, &config_path);
+ r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, &target_info);
if (r < 0)
return r;
-
- r = install_info_discover(scope, &c, root_dir, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, &target_info);
+ r = install_info_may_process(target_info, &paths, changes, n_changes);
if (r < 0)
return r;
- if (target_info->type == UNIT_FILE_TYPE_MASKED)
- return -ESHUTDOWN;
assert(target_info->type == UNIT_FILE_TYPE_REGULAR);
STRV_FOREACH(f, files) {
char ***l;
- r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
+ r = install_info_discover(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
+ if (r < 0)
+ return r;
+ r = install_info_may_process(i, &paths, changes, n_changes);
if (r < 0)
return r;
- if (i->type == UNIT_FILE_TYPE_MASKED)
- return -ESHUTDOWN;
assert(i->type == UNIT_FILE_TYPE_REGULAR);
@@ -1776,7 +2186,7 @@ int unit_file_add_dependency(
return -ENOMEM;
}
- return install_context_apply(scope, &c, &paths, config_path, root_dir, force, SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
+ return install_context_apply(scope, &c, &paths, config_path, force, SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
}
int unit_file_enable(
@@ -1790,7 +2200,7 @@ int unit_file_enable(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
- _cleanup_free_ char *config_path = NULL;
+ const char *config_path;
UnitFileInstallInfo *i;
char **f;
int r;
@@ -1798,24 +2208,19 @@ int unit_file_enable(
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
- r = verify_root_dir(scope, &root_dir);
- if (r < 0)
- return r;
-
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = get_config_path(scope, runtime, root_dir, &config_path);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(f, files) {
- r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_LOAD, &i);
+ r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD, &i);
+ if (r < 0)
+ return r;
+ r = install_info_may_process(i, &paths, changes, n_changes);
if (r < 0)
return r;
- if (i->type == UNIT_FILE_TYPE_MASKED)
- return -ESHUTDOWN;
assert(i->type == UNIT_FILE_TYPE_REGULAR);
}
@@ -1825,7 +2230,7 @@ int unit_file_enable(
is useful to determine whether the passed files had any
installation data at all. */
- return install_context_apply(scope, &c, &paths, config_path, root_dir, force, SEARCH_LOAD, changes, n_changes);
+ return install_context_apply(scope, &c, &paths, config_path, force, SEARCH_LOAD, changes, n_changes);
}
int unit_file_disable(
@@ -1838,25 +2243,19 @@ int unit_file_disable(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
- _cleanup_free_ char *config_path = NULL;
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+ const char *config_path;
char **i;
int r;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
- r = verify_root_dir(scope, &root_dir);
- if (r < 0)
- return r;
-
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = get_config_path(scope, runtime, root_dir, &config_path);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
STRV_FOREACH(i, files) {
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
@@ -1867,11 +2266,11 @@ int unit_file_disable(
return r;
}
- r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, root_dir);
+ r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path);
if (r < 0)
return r;
- return remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
+ return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, changes, n_changes);
}
int unit_file_reenable(
@@ -1912,41 +2311,34 @@ int unit_file_set_default(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
- _cleanup_free_ char *config_path = NULL;
UnitFileInstallInfo *i;
- const char *path;
+ const char *new_path, *old_path;
int r;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(name);
- if (unit_name_to_type(name) != UNIT_TARGET)
+ if (unit_name_to_type(name) != UNIT_TARGET) /* this also validates the name */
return -EINVAL;
if (streq(name, SPECIAL_DEFAULT_TARGET))
return -EINVAL;
- r = verify_root_dir(scope, &root_dir);
- if (r < 0)
- return r;
-
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = get_config_path(scope, false, root_dir, &config_path);
+ r = install_info_discover(scope, &c, &paths, name, 0, &i);
if (r < 0)
return r;
-
- r = install_info_discover(scope, &c, root_dir, &paths, name, 0, &i);
+ r = install_info_may_process(i, &paths, changes, n_changes);
if (r < 0)
return r;
- if (i->type == UNIT_FILE_TYPE_MASKED)
- return -ESHUTDOWN;
- path = strjoina(config_path, "/" SPECIAL_DEFAULT_TARGET);
+ old_path = skip_root(&paths, i->path);
+ new_path = strjoina(paths.persistent_config, "/" SPECIAL_DEFAULT_TARGET);
- return create_symlink(i->path, path, force, changes, n_changes);
+ return create_symlink(old_path ?: i->path, new_path, force, changes, n_changes);
}
int unit_file_get_default(
@@ -1964,19 +2356,16 @@ int unit_file_get_default(
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(name);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ r = install_info_discover(scope, &c, &paths, SPECIAL_DEFAULT_TARGET, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
if (r < 0)
return r;
-
- r = install_info_discover(scope, &c, root_dir, &paths, SPECIAL_DEFAULT_TARGET, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
+ r = install_info_may_process(i, &paths, NULL, 0);
if (r < 0)
return r;
- if (i->type == UNIT_FILE_TYPE_MASKED)
- return -ESHUTDOWN;
n = strdup(i->name);
if (!n)
@@ -1986,9 +2375,8 @@ int unit_file_get_default(
return 0;
}
-int unit_file_lookup_state(
+static int unit_file_lookup_state(
UnitFileScope scope,
- const char *root_dir,
const LookupPaths *paths,
const char *name,
UnitFileState *ret) {
@@ -2004,11 +2392,7 @@ int unit_file_lookup_state(
if (!unit_name_is_valid(name, UNIT_NAME_ANY))
return -EINVAL;
- r = verify_root_dir(scope, &root_dir);
- if (r < 0)
- return r;
-
- r = install_info_discover(scope, &c, root_dir, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
+ r = install_info_discover(scope, &c, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
if (r < 0)
return r;
@@ -2019,11 +2403,31 @@ int unit_file_lookup_state(
switch (i->type) {
case UNIT_FILE_TYPE_MASKED:
- state = path_startswith(i->path, "/run") ? UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
+ r = path_is_runtime(paths, i->path);
+ if (r < 0)
+ return r;
+
+ state = r > 0 ? UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
break;
case UNIT_FILE_TYPE_REGULAR:
- r = find_symlinks_in_scope(scope, root_dir, i->name, &state);
+ r = path_is_generator(paths, i->path);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ state = UNIT_FILE_GENERATED;
+ break;
+ }
+
+ r = path_is_transient(paths, i->path);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ state = UNIT_FILE_TRANSIENT;
+ break;
+ }
+
+ r = find_symlinks_in_scope(scope, paths, i->name, &state);
if (r < 0)
return r;
if (r == 0) {
@@ -2058,32 +2462,42 @@ int unit_file_get_state(
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(name);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+ return unit_file_lookup_state(scope, &paths, name, ret);
+}
+
+int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char *name) {
+ _cleanup_(install_context_done) InstallContext c = {};
+ int r;
+
+ assert(paths);
+ assert(name);
+
+ if (!unit_name_is_valid(name, UNIT_NAME_ANY))
+ return -EINVAL;
+
+ r = install_info_discover(scope, &c, paths, name, 0, NULL);
+ if (r == -ENOENT)
+ return 0;
if (r < 0)
return r;
- return unit_file_lookup_state(scope, root_dir, &paths, name, ret);
+ return 1;
}
-int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
+static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) {
+ _cleanup_(presets_freep) Presets ps = {};
+ size_t n_allocated = 0;
_cleanup_strv_free_ char **files = NULL;
char **p;
int r;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(name);
-
- r = verify_root_dir(scope, &root_dir);
- if (r < 0)
- return r;
-
- if (!unit_name_is_valid(name, UNIT_NAME_ANY))
- return -EINVAL;
+ assert(presets);
if (scope == UNIT_FILE_SYSTEM)
r = conf_files_list(&files, ".preset", root_dir,
@@ -2100,8 +2514,11 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
"/usr/local/lib/systemd/user-preset",
"/usr/lib/systemd/user-preset",
NULL);
- else
- return 1; /* Default is "enable" */
+ else {
+ *presets = (Presets){};
+
+ return 0;
+ }
if (r < 0)
return r;
@@ -2109,6 +2526,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
STRV_FOREACH(p, files) {
_cleanup_fclose_ FILE *f;
char line[LINE_MAX];
+ int n = 0;
f = fopen(*p, "re");
if (!f) {
@@ -2119,10 +2537,12 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
}
FOREACH_LINE(line, f, return -errno) {
+ PresetRule rule = {};
const char *parameter;
char *l;
l = strstrip(line);
+ n++;
if (isempty(l))
continue;
@@ -2131,31 +2551,87 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
parameter = first_word(l, "enable");
if (parameter) {
- if (fnmatch(parameter, name, FNM_NOESCAPE) == 0) {
- log_debug("Preset file says enable %s.", name);
- return 1;
- }
+ char *pattern;
- continue;
+ pattern = strdup(parameter);
+ if (!pattern)
+ return -ENOMEM;
+
+ rule = (PresetRule) {
+ .pattern = pattern,
+ .action = PRESET_ENABLE,
+ };
}
parameter = first_word(l, "disable");
if (parameter) {
- if (fnmatch(parameter, name, FNM_NOESCAPE) == 0) {
- log_debug("Preset file says disable %s.", name);
- return 0;
- }
+ char *pattern;
+
+ pattern = strdup(parameter);
+ if (!pattern)
+ return -ENOMEM;
+
+ rule = (PresetRule) {
+ .pattern = pattern,
+ .action = PRESET_DISABLE,
+ };
+ }
+
+ if (rule.action) {
+ if (!GREEDY_REALLOC(ps.rules, n_allocated, ps.n_rules + 1))
+ return -ENOMEM;
+ ps.rules[ps.n_rules++] = rule;
continue;
}
- log_debug("Couldn't parse line '%s'", l);
+ log_syntax(NULL, LOG_WARNING, *p, n, 0, "Couldn't parse line '%s'. Ignoring.", line);
}
}
- /* Default is "enable" */
- log_debug("Preset file doesn't say anything about %s, enabling.", name);
- return 1;
+ *presets = ps;
+ ps = (Presets){};
+
+ return 0;
+}
+
+static int query_presets(const char *name, const Presets presets) {
+ PresetAction action = PRESET_UNKNOWN;
+ size_t i;
+
+ if (!unit_name_is_valid(name, UNIT_NAME_ANY))
+ return -EINVAL;
+
+ for (i = 0; i < presets.n_rules; i++)
+ if (fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) {
+ action = presets.rules[i].action;
+ break;
+ }
+
+ switch (action) {
+ case PRESET_UNKNOWN:
+ log_debug("Preset files don't specify rule for %s. Enabling.", name);
+ return 1;
+ case PRESET_ENABLE:
+ log_debug("Preset files say enable %s.", name);
+ return 1;
+ case PRESET_DISABLE:
+ log_debug("Preset files say disable %s.", name);
+ return 0;
+ default:
+ assert_not_reached("invalid preset action");
+ }
+}
+
+int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
+ _cleanup_(presets_freep) Presets presets = {};
+ int r;
+
+ r = read_presets(scope, root_dir, &presets);
+ if (r < 0)
+ return r;
+
+ return query_presets(name, presets);
}
static int execute_preset(
@@ -2164,7 +2640,6 @@ static int execute_preset(
InstallContext *minus,
const LookupPaths *paths,
const char *config_path,
- const char *root_dir,
char **files,
UnitFilePresetMode mode,
bool force,
@@ -2181,11 +2656,11 @@ static int execute_preset(
if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, root_dir);
+ r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path);
if (r < 0)
return r;
- r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
+ r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, changes, n_changes);
} else
r = 0;
@@ -2193,12 +2668,12 @@ static int execute_preset(
int q;
/* Returns number of symlinks that where supposed to be installed. */
- q = install_context_apply(scope, plus, paths, config_path, root_dir, force, SEARCH_LOAD, changes, n_changes);
+ q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
else
- r+= q;
+ r += q;
}
}
@@ -2210,9 +2685,11 @@ static int preset_prepare_one(
InstallContext *plus,
InstallContext *minus,
LookupPaths *paths,
- const char *root_dir,
UnitFilePresetMode mode,
- const char *name) {
+ const char *name,
+ Presets presets,
+ UnitFileChange **changes,
+ unsigned *n_changes) {
UnitFileInstallInfo *i;
int r;
@@ -2221,19 +2698,20 @@ static int preset_prepare_one(
install_info_find(minus, name))
return 0;
- r = unit_file_query_preset(scope, root_dir, name);
+ r = query_presets(name, presets);
if (r < 0)
return r;
if (r > 0) {
- r = install_info_discover(scope, plus, root_dir, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
+ r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
if (r < 0)
return r;
- if (i->type == UNIT_FILE_TYPE_MASKED)
- return -ESHUTDOWN;
+ r = install_info_may_process(i, paths, changes, n_changes);
+ if (r < 0)
+ return r;
} else
- r = install_info_discover(scope, minus, root_dir, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
+ r = install_info_discover(scope, minus, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
return r;
}
@@ -2250,7 +2728,8 @@ int unit_file_preset(
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
_cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_free_ char *config_path = NULL;
+ _cleanup_(presets_freep) Presets presets = {};
+ const char *config_path;
char **i;
int r;
@@ -2258,28 +2737,23 @@ int unit_file_preset(
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(mode < _UNIT_FILE_PRESET_MAX);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
- r = get_config_path(scope, runtime, root_dir, &config_path);
+ r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
STRV_FOREACH(i, files) {
- if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
- return -EINVAL;
-
- r = preset_prepare_one(scope, &plus, &minus, &paths, root_dir, mode, *i);
+ r = preset_prepare_one(scope, &plus, &minus, &paths, mode, *i, presets, changes, n_changes);
if (r < 0)
return r;
}
- return execute_preset(scope, &plus, &minus, &paths, config_path, root_dir, files, mode, force, changes, n_changes);
+ return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, force, changes, n_changes);
}
int unit_file_preset_all(
@@ -2293,7 +2767,8 @@ int unit_file_preset_all(
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
_cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_free_ char *config_path = NULL;
+ _cleanup_(presets_freep) Presets presets = {};
+ const char *config_path = NULL;
char **i;
int r;
@@ -2301,28 +2776,21 @@ int unit_file_preset_all(
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(mode < _UNIT_FILE_PRESET_MAX);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
- if (r < 0)
- return r;
+ config_path = runtime ? paths.runtime_config : paths.persistent_config;
- r = get_config_path(scope, runtime, root_dir, &config_path);
+ r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
- STRV_FOREACH(i, paths.unit_path) {
+ STRV_FOREACH(i, paths.search_path) {
_cleanup_closedir_ DIR *d = NULL;
- _cleanup_free_ char *units_dir;
struct dirent *de;
- units_dir = path_join(root_dir, *i, NULL);
- if (!units_dir)
- return -ENOMEM;
-
- d = opendir(units_dir);
+ d = opendir(*i);
if (!d) {
if (errno == ENOENT)
continue;
@@ -2340,13 +2808,20 @@ int unit_file_preset_all(
if (!IN_SET(de->d_type, DT_LNK, DT_REG))
continue;
- r = preset_prepare_one(scope, &plus, &minus, &paths, root_dir, mode, de->d_name);
+ /* we don't pass changes[] in, because we want to handle errors on our own */
+ r = preset_prepare_one(scope, &plus, &minus, &paths, mode, de->d_name, presets, NULL, 0);
+ if (r == -ERFKILL)
+ r = unit_file_changes_add(changes, n_changes,
+ UNIT_FILE_IS_MASKED, de->d_name, NULL);
+ else if (r == -ENOLINK)
+ r = unit_file_changes_add(changes, n_changes,
+ UNIT_FILE_IS_DANGLING, de->d_name, NULL);
if (r < 0)
return r;
}
}
- return execute_preset(scope, &plus, &minus, &paths, config_path, root_dir, NULL, mode, force, changes, n_changes);
+ return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, force, changes, n_changes);
}
static void unit_file_list_free_one(UnitFileList *f) {
@@ -2371,7 +2846,9 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
int unit_file_get_list(
UnitFileScope scope,
const char *root_dir,
- Hashmap *h) {
+ Hashmap *h,
+ char **states,
+ char **patterns) {
_cleanup_lookup_paths_free_ LookupPaths paths = {};
char **i;
@@ -2381,24 +2858,15 @@ int unit_file_get_list(
assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(h);
- r = verify_root_dir(scope, &root_dir);
+ r = lookup_paths_init(&paths, scope, 0, root_dir);
if (r < 0)
return r;
- r = lookup_paths_init_from_scope(&paths, scope, root_dir);
- if (r < 0)
- return r;
-
- STRV_FOREACH(i, paths.unit_path) {
+ STRV_FOREACH(i, paths.search_path) {
_cleanup_closedir_ DIR *d = NULL;
- _cleanup_free_ char *units_dir;
struct dirent *de;
- units_dir = path_join(root_dir, *i, NULL);
- if (!units_dir)
- return -ENOMEM;
-
- d = opendir(units_dir);
+ d = opendir(*i);
if (!d) {
if (errno == ENOENT)
continue;
@@ -2412,6 +2880,9 @@ int unit_file_get_list(
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
continue;
+ if (!strv_fnmatch_or_empty(patterns, de->d_name, FNM_NOESCAPE))
+ continue;
+
if (hashmap_get(h, de->d_name))
continue;
@@ -2424,14 +2895,18 @@ int unit_file_get_list(
if (!f)
return -ENOMEM;
- f->path = path_make_absolute(de->d_name, units_dir);
+ f->path = path_make_absolute(de->d_name, *i);
if (!f->path)
return -ENOMEM;
- r = unit_file_lookup_state(scope, root_dir, &paths, basename(f->path), &f->state);
+ r = unit_file_lookup_state(scope, &paths, de->d_name, &f->state);
if (r < 0)
f->state = UNIT_FILE_BAD;
+ if (!strv_isempty(states) &&
+ !strv_contains(states, unit_file_state_to_string(f->state)))
+ continue;
+
r = hashmap_put(h, basename(f->path), f);
if (r < 0)
return r;
@@ -2453,6 +2928,8 @@ static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
[UNIT_FILE_STATIC] = "static",
[UNIT_FILE_DISABLED] = "disabled",
[UNIT_FILE_INDIRECT] = "indirect",
+ [UNIT_FILE_GENERATED] = "generated",
+ [UNIT_FILE_TRANSIENT] = "transient",
[UNIT_FILE_BAD] = "bad",
};
@@ -2461,6 +2938,8 @@ DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
[UNIT_FILE_SYMLINK] = "symlink",
[UNIT_FILE_UNLINK] = "unlink",
+ [UNIT_FILE_IS_MASKED] = "masked",
+ [UNIT_FILE_IS_DANGLING] = "dangling",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
diff --git a/src/libshared/install.h b/src/libshared/install.h
index c1a43e23e7..c6aa4f6ef1 100644
--- a/src/libshared/install.h
+++ b/src/libshared/install.h
@@ -54,6 +54,8 @@ enum UnitFileState {
UNIT_FILE_STATIC,
UNIT_FILE_DISABLED,
UNIT_FILE_INDIRECT,
+ UNIT_FILE_GENERATED,
+ UNIT_FILE_TRANSIENT,
UNIT_FILE_BAD,
_UNIT_FILE_STATE_MAX,
_UNIT_FILE_STATE_INVALID = -1
@@ -70,16 +72,30 @@ enum UnitFilePresetMode {
enum UnitFileChangeType {
UNIT_FILE_SYMLINK,
UNIT_FILE_UNLINK,
+ UNIT_FILE_IS_MASKED,
+ UNIT_FILE_IS_DANGLING,
_UNIT_FILE_CHANGE_TYPE_MAX,
- _UNIT_FILE_CHANGE_TYPE_INVALID = -1
+ _UNIT_FILE_CHANGE_INVALID = INT_MIN
};
+/* type can either one of the UnitFileChangeTypes listed above, or a negative error.
+ * If source is specified, it should be the contents of the path symlink.
+ * In case of an error, source should be the existing symlink contents or NULL
+ */
struct UnitFileChange {
- UnitFileChangeType type;
+ int type; /* UnitFileChangeType or bust */
char *path;
char *source;
};
+static inline bool unit_file_changes_have_modification(const UnitFileChange* changes, unsigned n_changes) {
+ unsigned i;
+ for (i = 0; i < n_changes; i++)
+ if (IN_SET(changes[i].type, UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK))
+ return true;
+ return false;
+}
+
struct UnitFileList {
char *path;
UnitFileState state;
@@ -123,31 +139,115 @@ static inline bool UNIT_FILE_INSTALL_INFO_HAS_ALSO(UnitFileInstallInfo *i) {
return !strv_isempty(i->also);
}
-int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_preset_all(UnitFileScope scope, bool runtime, const char *root_dir, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_set_default(UnitFileScope scope, const char *root_dir, const char *file, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_get_default(UnitFileScope scope, const char *root_dir, char **name);
-int unit_file_add_dependency(UnitFileScope scope, bool runtime, const char *root_dir, char **files, const char *target, UnitDependency dep, bool force, UnitFileChange **changes, unsigned *n_changes);
-
-int unit_file_lookup_state(UnitFileScope scope, const char *root_dir,const LookupPaths *paths, const char *name, UnitFileState *ret);
+bool unit_type_may_alias(UnitType type) _const_;
+bool unit_type_may_template(UnitType type) _const_;
+
+int unit_file_enable(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_disable(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_reenable(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_preset(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ UnitFilePresetMode mode,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_preset_all(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ UnitFilePresetMode mode,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_mask(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_unmask(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_link(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_revert(
+ UnitFileScope scope,
+ const char *root_dir,
+ char **files,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_set_default(
+ UnitFileScope scope,
+ const char *root_dir,
+ const char *file,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+int unit_file_get_default(
+ UnitFileScope scope,
+ const char *root_dir,
+ char **name);
+int unit_file_add_dependency(
+ UnitFileScope scope,
+ bool runtime,
+ const char *root_dir,
+ char **files,
+ const char *target,
+ UnitDependency dep,
+ bool force,
+ UnitFileChange **changes,
+ unsigned *n_changes);
+
int unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename, UnitFileState *ret);
+int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char *name);
-int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h);
+int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h, char **states, char **patterns);
Hashmap* unit_file_list_free(Hashmap *h);
int unit_file_changes_add(UnitFileChange **changes, unsigned *n_changes, UnitFileChangeType type, const char *path, const char *source);
void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes);
+void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, unsigned n_changes, bool quiet);
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name);
const char *unit_file_state_to_string(UnitFileState s) _const_;
UnitFileState unit_file_state_from_string(const char *s) _pure_;
+/* from_string conversion is unreliable because of the overlap between -EPERM and -1 for error. */
const char *unit_file_change_type_to_string(UnitFileChangeType s) _const_;
UnitFileChangeType unit_file_change_type_from_string(const char *s) _pure_;
diff --git a/src/libshared/local-addresses.c b/src/libshared/local-addresses.c
index fafc208eca..5cceddd03c 100644
--- a/src/libshared/local-addresses.c
+++ b/src/libshared/local-addresses.c
@@ -154,8 +154,7 @@ int local_addresses(sd_netlink *context, int ifindex, int af, struct local_addre
n_list++;
};
- if (n_list > 0)
- qsort(list, n_list, sizeof(struct local_address), address_compare);
+ qsort_safe(list, n_list, sizeof(struct local_address), address_compare);
*ret = list;
list = NULL;
diff --git a/src/libshared/logs-show.c b/src/libshared/logs-show.c
index 7ac6d49549..294fa3bede 100644
--- a/src/libshared/logs-show.c
+++ b/src/libshared/logs-show.c
@@ -287,7 +287,10 @@ static int output_short(
if (r < 0)
return r;
}
-
+ if (r == -EBADMSG) {
+ log_debug_errno(r, "Skipping message we can't read: %m");
+ return 0;
+ }
if (r < 0)
return log_error_errno(r, "Failed to get journal fields: %m");
@@ -344,16 +347,22 @@ static int output_short(
t = (time_t) (x / USEC_PER_SEC);
- switch(mode) {
+ switch (mode) {
+
+ case OUTPUT_SHORT_UNIX:
+ r = snprintf(buf, sizeof(buf), "%10llu.%06llu", (unsigned long long) t, (unsigned long long) (x % USEC_PER_SEC));
+ break;
+
case OUTPUT_SHORT_ISO:
r = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm));
break;
+
case OUTPUT_SHORT_PRECISE:
r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm));
if (r > 0)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
break;
+
default:
r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm));
}
@@ -367,6 +376,12 @@ static int output_short(
n += strlen(buf);
}
+ if (hostname && (flags & OUTPUT_NO_HOSTNAME)) {
+ /* Suppress display of the hostname if this is requested. */
+ hostname = NULL;
+ hostname_len = 0;
+ }
+
if (hostname && shall_print(hostname, hostname_len, flags)) {
fprintf(f, " %.*s", (int) hostname_len, hostname);
n += hostname_len + 1;
@@ -894,6 +909,7 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(
[OUTPUT_SHORT_ISO] = output_short,
[OUTPUT_SHORT_PRECISE] = output_short,
[OUTPUT_SHORT_MONOTONIC] = output_short,
+ [OUTPUT_SHORT_UNIX] = output_short,
[OUTPUT_VERBOSE] = output_verbose,
[OUTPUT_EXPORT] = output_export,
[OUTPUT_JSON] = output_json,
@@ -997,7 +1013,7 @@ static int show_journal(FILE *f,
continue;
}
- line ++;
+ line++;
maybe_print_begin_newline(f, &flags);
r = output_journal(f, j, mode, n_columns, flags, ellipsized);
@@ -1040,8 +1056,8 @@ static int show_journal(FILE *f,
}
int add_matches_for_unit(sd_journal *j, const char *unit) {
+ const char *m1, *m2, *m3, *m4;
int r;
- char *m1, *m2, *m3, *m4;
assert(j);
assert(unit);
@@ -1073,7 +1089,9 @@ int add_matches_for_unit(sd_journal *j, const char *unit) {
);
if (r == 0 && endswith(unit, ".slice")) {
- char *m5 = strappend("_SYSTEMD_SLICE=", unit);
+ const char *m5;
+
+ m5 = strjoina("_SYSTEMD_SLICE=", unit);
/* Show all messages belonging to a slice */
(void)(
@@ -1123,7 +1141,9 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) {
);
if (r == 0 && endswith(unit, ".slice")) {
- char *m5 = strappend("_SYSTEMD_SLICE=", unit);
+ const char *m5;
+
+ m5 = strjoina("_SYSTEMD_SLICE=", unit);
/* Show all messages belonging to a slice */
(void)(
@@ -1288,18 +1308,3 @@ int show_journal_by_unit(
return show_journal(f, j, mode, n_columns, not_before, how_many, flags, ellipsized);
}
-
-static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
- [OUTPUT_SHORT] = "short",
- [OUTPUT_SHORT_ISO] = "short-iso",
- [OUTPUT_SHORT_PRECISE] = "short-precise",
- [OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
- [OUTPUT_VERBOSE] = "verbose",
- [OUTPUT_EXPORT] = "export",
- [OUTPUT_JSON] = "json",
- [OUTPUT_JSON_PRETTY] = "json-pretty",
- [OUTPUT_JSON_SSE] = "json-sse",
- [OUTPUT_CAT] = "cat"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode);
diff --git a/src/libshared/logs-show.h b/src/libshared/logs-show.h
index 682a4adc7b..15fe5b6e5c 100644
--- a/src/libshared/logs-show.h
+++ b/src/libshared/logs-show.h
@@ -68,6 +68,3 @@ void json_escape(
const char* p,
size_t l,
OutputFlags flags);
-
-const char* output_mode_to_string(OutputMode m) _const_;
-OutputMode output_mode_from_string(const char *s) _pure_;
diff --git a/src/libshared/machine-image.c b/src/libshared/machine-image.c
index ed8a29c575..529d89ee2a 100644
--- a/src/libshared/machine-image.c
+++ b/src/libshared/machine-image.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fs.h>
@@ -400,8 +401,7 @@ int image_remove(Image *i) {
assert(i);
- if (path_equal(i->path, "/") ||
- path_startswith(i->path, "/usr"))
+ if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
return -EROFS;
settings = image_settings_path(i);
@@ -423,7 +423,7 @@ int image_remove(Image *i) {
case IMAGE_DIRECTORY:
/* Allow deletion of read-only directories */
- (void) chattr_path(i->path, false, FS_IMMUTABLE_FL);
+ (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
if (r < 0)
return r;
@@ -473,8 +473,7 @@ int image_rename(Image *i, const char *new_name) {
if (!image_name_is_valid(new_name))
return -EINVAL;
- if (path_equal(i->path, "/") ||
- path_startswith(i->path, "/usr"))
+ if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
return -EROFS;
settings = image_settings_path(i);
@@ -488,7 +487,7 @@ int image_rename(Image *i, const char *new_name) {
/* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the
- * time we take possesion of it */
+ * time we take possession of it */
r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
if (r < 0)
return r;
@@ -506,7 +505,7 @@ int image_rename(Image *i, const char *new_name) {
(void) read_attr_path(i->path, &file_attr);
if (file_attr & FS_IMMUTABLE_FL)
- (void) chattr_path(i->path, false, FS_IMMUTABLE_FL);
+ (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
/* fall through */
@@ -539,7 +538,7 @@ int image_rename(Image *i, const char *new_name) {
/* Restore the immutable bit, if it was set before */
if (file_attr & FS_IMMUTABLE_FL)
- (void) chattr_path(new_path, true, FS_IMMUTABLE_FL);
+ (void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
free(i->path);
i->path = new_path;
@@ -589,7 +588,7 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
/* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the
- * time we take possesion of it */
+ * time we take possession of it */
r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
if (r < 0)
return r;
@@ -604,13 +603,21 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
case IMAGE_SUBVOLUME:
case IMAGE_DIRECTORY:
+ /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
+ * directory.*/
+
new_path = strjoina("/var/lib/machines/", new_name);
r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
+ if (r == -EOPNOTSUPP) {
+ /* No btrfs snapshots supported, create a normal directory then. */
- /* Enable "subtree" quotas for the copy, if we didn't
- * copy any quota from the source. */
- (void) btrfs_subvol_auto_qgroup(i->path, 0, true);
+ r = copy_directory(i->path, new_path, false);
+ if (r >= 0)
+ (void) chattr_path(new_path, read_only ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
+ } else if (r >= 0)
+ /* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
+ (void) btrfs_subvol_auto_qgroup(new_path, 0, true);
break;
@@ -641,8 +648,7 @@ int image_read_only(Image *i, bool b) {
int r;
assert(i);
- if (path_equal(i->path, "/") ||
- path_startswith(i->path, "/usr"))
+ if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
return -EROFS;
/* Make sure we don't interfere with a running nspawn */
@@ -672,7 +678,7 @@ int image_read_only(Image *i, bool b) {
a read-only subvolume, but at least something, and
we can read the value back.*/
- r = chattr_path(i->path, b, FS_IMMUTABLE_FL);
+ r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
if (r < 0)
return r;
@@ -750,8 +756,7 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
int image_set_limit(Image *i, uint64_t referenced_max) {
assert(i);
- if (path_equal(i->path, "/") ||
- path_startswith(i->path, "/usr"))
+ if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
return -EROFS;
if (i->type != IMAGE_SUBVOLUME)
diff --git a/src/libshared/machine-image.h b/src/libshared/machine-image.h
index 31b720d50c..7410168c4f 100644
--- a/src/libshared/machine-image.h
+++ b/src/libshared/machine-image.h
@@ -25,6 +25,8 @@
#include "hashmap.h"
#include "lockfile-util.h"
#include "macro.h"
+#include "path-util.h"
+#include "string-util.h"
#include "time-util.h"
typedef enum ImageType {
@@ -75,3 +77,27 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
int image_name_lock(const char *name, int operation, LockFile *ret);
int image_set_limit(Image *i, uint64_t referenced_max);
+
+static inline bool IMAGE_IS_HIDDEN(const struct Image *i) {
+ assert(i);
+
+ return i->name && i->name[0] == '.';
+}
+
+static inline bool IMAGE_IS_VENDOR(const struct Image *i) {
+ assert(i);
+
+ return i->path && path_startswith(i->path, "/usr");
+}
+
+static inline bool IMAGE_IS_HOST(const struct Image *i) {
+ assert(i);
+
+ if (i->name && streq(i->name, ".host"))
+ return true;
+
+ if (i->path && path_equal(i->path, "/"))
+ return true;
+
+ return false;
+}
diff --git a/src/libshared/machine-pool.c b/src/libshared/machine-pool.c
index 056b5bfae5..c36efa0102 100644
--- a/src/libshared/machine-pool.c
+++ b/src/libshared/machine-pool.c
@@ -24,6 +24,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/prctl.h>
@@ -138,7 +139,7 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) {
execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL);
if (errno == ENOENT)
- return 99;
+ _exit(99);
_exit(EXIT_FAILURE);
}
@@ -238,10 +239,8 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
}
r = mkfs_exists("btrfs");
- if (r == -ENOENT) {
- log_debug("mkfs.btrfs is missing, cannot create loopback file for /var/lib/machines.");
- return 0;
- }
+ if (r == 0)
+ return sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
if (r < 0)
return r;
diff --git a/src/libshared/output-mode.c b/src/libshared/output-mode.c
new file mode 100644
index 0000000000..bec53ee0ae
--- /dev/null
+++ b/src/libshared/output-mode.c
@@ -0,0 +1,37 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2012 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "output-mode.h"
+#include "string-table.h"
+
+static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
+ [OUTPUT_SHORT] = "short",
+ [OUTPUT_SHORT_ISO] = "short-iso",
+ [OUTPUT_SHORT_PRECISE] = "short-precise",
+ [OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
+ [OUTPUT_SHORT_UNIX] = "short-unix",
+ [OUTPUT_VERBOSE] = "verbose",
+ [OUTPUT_EXPORT] = "export",
+ [OUTPUT_JSON] = "json",
+ [OUTPUT_JSON_PRETTY] = "json-pretty",
+ [OUTPUT_JSON_SSE] = "json-sse",
+ [OUTPUT_CAT] = "cat"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode);
diff --git a/src/libshared/output-mode.h b/src/libshared/output-mode.h
index c5470e7c1b..f37189e57f 100644
--- a/src/libshared/output-mode.h
+++ b/src/libshared/output-mode.h
@@ -19,11 +19,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "macro.h"
+
typedef enum OutputMode {
OUTPUT_SHORT,
OUTPUT_SHORT_ISO,
OUTPUT_SHORT_PRECISE,
OUTPUT_SHORT_MONOTONIC,
+ OUTPUT_SHORT_UNIX,
OUTPUT_VERBOSE,
OUTPUT_EXPORT,
OUTPUT_JSON,
@@ -34,6 +37,9 @@ typedef enum OutputMode {
_OUTPUT_MODE_INVALID = -1
} OutputMode;
+/* The output flags definitions are shared by the logs and process tree output. Some apply to both, some only to the
+ * logs output, others only to the process tree output. */
+
typedef enum OutputFlags {
OUTPUT_SHOW_ALL = 1 << 0,
OUTPUT_FOLLOW = 1 << 1,
@@ -43,4 +49,9 @@ typedef enum OutputFlags {
OUTPUT_CATALOG = 1 << 5,
OUTPUT_BEGIN_NEWLINE = 1 << 6,
OUTPUT_UTC = 1 << 7,
+ OUTPUT_KERNEL_THREADS = 1 << 8,
+ OUTPUT_NO_HOSTNAME = 1 << 9,
} OutputFlags;
+
+const char* output_mode_to_string(OutputMode m) _const_;
+OutputMode output_mode_from_string(const char *s) _pure_;
diff --git a/src/libshared/pager.c b/src/libshared/pager.c
index 05b2b15e40..c16bc027be 100644
--- a/src/libshared/pager.c
+++ b/src/libshared/pager.c
@@ -52,11 +52,14 @@ noreturn static void pager_fallback(void) {
_exit(EXIT_SUCCESS);
}
-int pager_open(bool jump_to_end) {
+int pager_open(bool no_pager, bool jump_to_end) {
_cleanup_close_pair_ int fd[2] = { -1, -1 };
const char *pager;
pid_t parent_pid;
+ if (no_pager)
+ return 0;
+
if (pager_pid > 0)
return 1;
diff --git a/src/libshared/pager.h b/src/libshared/pager.h
index 9fb05796bb..893e1d2bb6 100644
--- a/src/libshared/pager.h
+++ b/src/libshared/pager.h
@@ -23,7 +23,7 @@
#include "macro.h"
-int pager_open(bool jump_to_end);
+int pager_open(bool no_pager, bool jump_to_end);
void pager_close(void);
bool pager_have(void) _pure_;
diff --git a/src/libshared/path-lookup.c b/src/libshared/path-lookup.c
index 5410620725..ca593b6963 100644
--- a/src/libshared/path-lookup.c
+++ b/src/libshared/path-lookup.c
@@ -26,61 +26,66 @@
#include "install.h"
#include "log.h"
#include "macro.h"
+#include "mkdir.h"
#include "path-lookup.h"
#include "path-util.h"
+#include "rm-rf.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
-int user_config_home(char **config_home) {
+static int user_runtime_dir(char **ret, const char *suffix) {
const char *e;
- char *r;
+ char *j;
- e = getenv("XDG_CONFIG_HOME");
- if (e) {
- r = strappend(e, "/systemd/user");
- if (!r)
- return -ENOMEM;
-
- *config_home = r;
- return 1;
- } else {
- const char *home;
+ assert(ret);
+ assert(suffix);
- home = getenv("HOME");
- if (home) {
- r = strappend(home, "/.config/systemd/user");
- if (!r)
- return -ENOMEM;
+ e = getenv("XDG_RUNTIME_DIR");
+ if (!e)
+ return -ENXIO;
- *config_home = r;
- return 1;
- }
- }
+ j = strappend(e, suffix);
+ if (!j)
+ return -ENOMEM;
+ *ret = j;
return 0;
}
-int user_runtime_dir(char **runtime_dir) {
+static int user_config_dir(char **ret, const char *suffix) {
const char *e;
- char *r;
+ char *j;
- e = getenv("XDG_RUNTIME_DIR");
- if (e) {
- r = strappend(e, "/systemd/user");
- if (!r)
- return -ENOMEM;
+ assert(ret);
+
+ e = getenv("XDG_CONFIG_HOME");
+ if (e)
+ j = strappend(e, suffix);
+ else {
+ const char *home;
- *runtime_dir = r;
- return 1;
+ home = getenv("HOME");
+ if (!home)
+ return -ENXIO;
+
+ j = strjoin(home, "/.config", suffix, NULL);
}
+ if (!j)
+ return -ENOMEM;
+
+ *ret = j;
return 0;
}
-static int user_data_home_dir(char **dir, const char *suffix) {
+static int user_data_dir(char **ret, const char *suffix) {
const char *e;
- char *res;
+ char *j;
+
+ assert(ret);
+ assert(suffix);
/* We don't treat /etc/xdg/systemd here as the spec
* suggests because we assume that that is a link to
@@ -88,27 +93,33 @@ static int user_data_home_dir(char **dir, const char *suffix) {
e = getenv("XDG_DATA_HOME");
if (e)
- res = strappend(e, suffix);
+ j = strappend(e, suffix);
else {
const char *home;
home = getenv("HOME");
- if (home)
- res = strjoin(home, "/.local/share", suffix, NULL);
- else
- return 0;
+ if (!home)
+ return -ENXIO;
+
+
+ j = strjoin(home, "/.local/share", suffix, NULL);
}
- if (!res)
+ if (!j)
return -ENOMEM;
- *dir = res;
- return 0;
+ *ret = j;
+ return 1;
}
static char** user_dirs(
+ const char *persistent_config,
+ const char *runtime_config,
const char *generator,
const char *generator_early,
- const char *generator_late) {
+ const char *generator_late,
+ const char *transient,
+ const char *persistent_control,
+ const char *runtime_control) {
const char * const config_unit_paths[] = {
USER_CONFIG_UNIT_PATH,
@@ -116,8 +127,6 @@ static char** user_dirs(
NULL
};
- const char * const runtime_unit_path = "/run/systemd/user";
-
const char * const data_unit_paths[] = {
"/usr/local/lib/systemd/user",
"/usr/local/share/systemd/user",
@@ -128,8 +137,8 @@ static char** user_dirs(
};
const char *e;
- _cleanup_free_ char *config_home = NULL, *runtime_dir = NULL, *data_home = NULL;
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
+ _cleanup_free_ char *data_home = NULL;
_cleanup_free_ char **res = NULL;
char **tmp;
int r;
@@ -143,12 +152,6 @@ static char** user_dirs(
* as data, and allow overriding as configuration.
*/
- if (user_config_home(&config_home) < 0)
- return NULL;
-
- if (user_runtime_dir(&runtime_dir) < 0)
- return NULL;
-
e = getenv("XDG_CONFIG_DIRS");
if (e) {
config_dirs = strv_split(e, ":");
@@ -156,8 +159,8 @@ static char** user_dirs(
return NULL;
}
- r = user_data_home_dir(&data_home, "/systemd/user");
- if (r < 0)
+ r = user_data_dir(&data_home, "/systemd/user");
+ if (r < 0 && r != -ENXIO)
return NULL;
e = getenv("XDG_DATA_DIRS");
@@ -171,35 +174,36 @@ static char** user_dirs(
return NULL;
/* Now merge everything we found. */
- if (generator_early)
- if (strv_extend(&res, generator_early) < 0)
- return NULL;
+ if (strv_extend(&res, persistent_control) < 0)
+ return NULL;
- if (config_home)
- if (strv_extend(&res, config_home) < 0)
- return NULL;
+ if (strv_extend(&res, runtime_control) < 0)
+ return NULL;
+
+ if (strv_extend(&res, transient) < 0)
+ return NULL;
+
+ if (strv_extend(&res, generator_early) < 0)
+ return NULL;
if (!strv_isempty(config_dirs))
if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
return NULL;
- if (strv_extend_strv(&res, (char**) config_unit_paths, false) < 0)
+ if (strv_extend(&res, persistent_config) < 0)
return NULL;
- if (runtime_dir)
- if (strv_extend(&res, runtime_dir) < 0)
- return NULL;
+ if (strv_extend_strv(&res, (char**) config_unit_paths, false) < 0)
+ return NULL;
- if (strv_extend(&res, runtime_unit_path) < 0)
+ if (strv_extend(&res, runtime_config) < 0)
return NULL;
- if (generator)
- if (strv_extend(&res, generator) < 0)
- return NULL;
+ if (strv_extend(&res, generator) < 0)
+ return NULL;
- if (data_home)
- if (strv_extend(&res, data_home) < 0)
- return NULL;
+ if (strv_extend(&res, data_home) < 0)
+ return NULL;
if (!strv_isempty(data_dirs))
if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
@@ -208,9 +212,8 @@ static char** user_dirs(
if (strv_extend_strv(&res, (char**) data_unit_paths, false) < 0)
return NULL;
- if (generator_late)
- if (strv_extend(&res, generator_late) < 0)
- return NULL;
+ if (strv_extend(&res, generator_late) < 0)
+ return NULL;
if (path_strv_make_absolute_cwd(res) < 0)
return NULL;
@@ -220,58 +223,298 @@ static char** user_dirs(
return tmp;
}
-char **generator_paths(ManagerRunningAs running_as) {
- if (running_as == MANAGER_USER)
- return strv_new("/run/systemd/user-generators",
- "/etc/systemd/user-generators",
- "/usr/local/lib/systemd/user-generators",
- USER_GENERATOR_PATH,
- NULL);
- else
- return strv_new("/run/systemd/system-generators",
- "/etc/systemd/system-generators",
- "/usr/local/lib/systemd/system-generators",
- SYSTEM_GENERATOR_PATH,
- NULL);
+static int acquire_generator_dirs(
+ UnitFileScope scope,
+ char **generator,
+ char **generator_early,
+ char **generator_late) {
+
+ _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL;
+ const char *prefix;
+
+ assert(generator);
+ assert(generator_early);
+ assert(generator_late);
+
+ switch (scope) {
+
+ case UNIT_FILE_SYSTEM:
+ prefix = "/run/systemd/";
+ break;
+
+ case UNIT_FILE_USER: {
+ const char *e;
+
+ e = getenv("XDG_RUNTIME_DIR");
+ if (!e)
+ return -ENXIO;
+
+ prefix = strjoina(e, "/systemd/");
+ break;
+ }
+
+ case UNIT_FILE_GLOBAL:
+ return -EOPNOTSUPP;
+
+ default:
+ assert_not_reached("Hmm, unexpected scope value.");
+ }
+
+ x = strappend(prefix, "generator");
+ if (!x)
+ return -ENOMEM;
+
+ y = strappend(prefix, "generator.early");
+ if (!y)
+ return -ENOMEM;
+
+ z = strappend(prefix, "generator.late");
+ if (!z)
+ return -ENOMEM;
+
+ *generator = x;
+ *generator_early = y;
+ *generator_late = z;
+
+ x = y = z = NULL;
+ return 0;
+}
+
+static int acquire_transient_dir(UnitFileScope scope, char **ret) {
+ assert(ret);
+
+ switch (scope) {
+
+ case UNIT_FILE_SYSTEM: {
+ char *transient;
+
+ transient = strdup("/run/systemd/transient");
+ if (!transient)
+ return -ENOMEM;
+
+ *ret = transient;
+ return 0;
+ }
+
+ case UNIT_FILE_USER:
+ return user_runtime_dir(ret, "/systemd/transient");
+
+ case UNIT_FILE_GLOBAL:
+ return -EOPNOTSUPP;
+
+ default:
+ assert_not_reached("Hmm, unexpected scope value.");
+ }
+}
+
+static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **runtime) {
+ _cleanup_free_ char *a = NULL, *b = NULL;
+ int r;
+
+ assert(persistent);
+ assert(runtime);
+
+ switch (scope) {
+
+ case UNIT_FILE_SYSTEM:
+ a = strdup(SYSTEM_CONFIG_UNIT_PATH);
+ b = strdup("/run/systemd/system");
+ break;
+
+ case UNIT_FILE_GLOBAL:
+ a = strdup(USER_CONFIG_UNIT_PATH);
+ b = strdup("/run/systemd/user");
+ break;
+
+ case UNIT_FILE_USER:
+ r = user_config_dir(&a, "/systemd/user");
+ if (r < 0)
+ return r;
+
+ r = user_runtime_dir(runtime, "/systemd/user");
+ if (r < 0)
+ return r;
+
+ *persistent = a;
+ a = NULL;
+
+ return 0;
+
+ default:
+ assert_not_reached("Hmm, unexpected scope value.");
+ }
+
+ if (!a || !b)
+ return -ENOMEM;
+
+ *persistent = a;
+ *runtime = b;
+ a = b = NULL;
+
+ return 0;
+}
+
+static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **runtime) {
+ _cleanup_free_ char *a = NULL;
+ int r;
+
+ assert(persistent);
+ assert(runtime);
+
+ switch (scope) {
+
+ case UNIT_FILE_SYSTEM: {
+ _cleanup_free_ char *b = NULL;
+
+ a = strdup("/etc/systemd/system.control");
+ if (!a)
+ return -ENOMEM;
+
+ b = strdup("/run/systemd/system.control");
+ if (!b)
+ return -ENOMEM;
+
+ *runtime = b;
+ b = NULL;
+
+ break;
+ }
+
+ case UNIT_FILE_USER:
+ r = user_config_dir(&a, "/systemd/system.control");
+ if (r < 0)
+ return r;
+
+ r = user_runtime_dir(runtime, "/systemd/system.control");
+ if (r < 0)
+ return r;
+
+ break;
+
+ case UNIT_FILE_GLOBAL:
+ return -EOPNOTSUPP;
+
+ default:
+ assert_not_reached("Hmm, unexpected scope value.");
+ }
+
+ *persistent = a;
+ a = NULL;
+
+ return 0;
+}
+
+static int patch_root_prefix(char **p, const char *root_dir) {
+ char *c;
+
+ assert(p);
+
+ if (!*p)
+ return 0;
+
+ c = prefix_root(root_dir, *p);
+ if (!c)
+ return -ENOMEM;
+
+ free(*p);
+ *p = c;
+
+ return 0;
+}
+
+static int patch_root_prefix_strv(char **l, const char *root_dir) {
+ char **i;
+ int r;
+
+ if (!root_dir)
+ return 0;
+
+ STRV_FOREACH(i, l) {
+ r = patch_root_prefix(i, root_dir);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
}
int lookup_paths_init(
LookupPaths *p,
- ManagerRunningAs running_as,
- bool personal,
- const char *root_dir,
- const char *generator,
- const char *generator_early,
- const char *generator_late) {
-
- const char *e;
+ UnitFileScope scope,
+ LookupPathsFlags flags,
+ const char *root_dir) {
+
+ _cleanup_free_ char
+ *root = NULL,
+ *persistent_config = NULL, *runtime_config = NULL,
+ *generator = NULL, *generator_early = NULL, *generator_late = NULL,
+ *transient = NULL,
+ *persistent_control = NULL, *runtime_control = NULL;
bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
+ _cleanup_strv_free_ char **paths = NULL;
+ const char *e;
int r;
assert(p);
+ assert(scope >= 0);
+ assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+ if (!isempty(root_dir) && !path_equal(root_dir, "/")) {
+ if (scope == UNIT_FILE_USER)
+ return -EINVAL;
+
+ r = is_dir(root_dir, true);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ENOTDIR;
- /* First priority is whatever has been passed to us via env
- * vars */
+ root = strdup(root_dir);
+ if (!root)
+ return -ENOMEM;
+ }
+
+ r = acquire_config_dirs(scope, &persistent_config, &runtime_config);
+ if (r < 0 && r != -ENXIO)
+ return r;
+
+ if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) {
+ r = acquire_generator_dirs(scope, &generator, &generator_early, &generator_late);
+ if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
+ return r;
+ }
+
+ r = acquire_transient_dir(scope, &transient);
+ if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
+ return r;
+
+ r = acquire_control_dirs(scope, &persistent_control, &runtime_control);
+ if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
+ return r;
+
+ /* First priority is whatever has been passed to us via env vars */
e = getenv("SYSTEMD_UNIT_PATH");
if (e) {
- if (endswith(e, ":")) {
- e = strndupa(e, strlen(e) - 1);
+ const char *k;
+
+ k = endswith(e, ":");
+ if (k) {
+ e = strndupa(e, k - e);
append = true;
}
/* FIXME: empty components in other places should be
* rejected. */
- r = path_split_and_make_absolute(e, &p->unit_path);
+ r = path_split_and_make_absolute(e, &paths);
if (r < 0)
return r;
- } else
- p->unit_path = NULL;
+ }
- if (!p->unit_path || append) {
+ if (!paths || append) {
/* Let's figure something out. */
- _cleanup_strv_free_ char **unit_path;
+ _cleanup_strv_free_ char **add = NULL;
/* For the user units we include share/ in the search
* path in order to comply with the XDG basedir spec.
@@ -279,17 +522,45 @@ int lookup_paths_init(
* we include /lib in the search path for the system
* stuff but avoid it for user stuff. */
- if (running_as == MANAGER_USER) {
- if (personal)
- unit_path = user_dirs(generator, generator_early, generator_late);
- else
- unit_path = strv_new(
+ switch (scope) {
+
+ case UNIT_FILE_SYSTEM:
+ add = strv_new(
+ /* If you modify this you also want to modify
+ * systemdsystemunitpath= in systemd.pc.in! */
+ STRV_IFNOTNULL(persistent_control),
+ STRV_IFNOTNULL(runtime_control),
+ STRV_IFNOTNULL(transient),
+ STRV_IFNOTNULL(generator_early),
+ persistent_config,
+ SYSTEM_CONFIG_UNIT_PATH,
+ "/etc/systemd/system",
+ runtime_config,
+ "/run/systemd/system",
+ STRV_IFNOTNULL(generator),
+ "/usr/local/lib/systemd/system",
+ SYSTEM_DATA_UNIT_PATH,
+ "/usr/lib/systemd/system",
+#ifdef HAVE_SPLIT_USR
+ "/lib/systemd/system",
+#endif
+ STRV_IFNOTNULL(generator_late),
+ NULL);
+ break;
+
+ case UNIT_FILE_GLOBAL:
+ add = strv_new(
/* If you modify this you also want to modify
* systemduserunitpath= in systemd.pc.in, and
* the arrays in user_dirs() above! */
+ STRV_IFNOTNULL(persistent_control),
+ STRV_IFNOTNULL(runtime_control),
+ STRV_IFNOTNULL(transient),
STRV_IFNOTNULL(generator_early),
+ persistent_config,
USER_CONFIG_UNIT_PATH,
"/etc/systemd/user",
+ runtime_config,
"/run/systemd/user",
STRV_IFNOTNULL(generator),
"/usr/local/lib/systemd/user",
@@ -299,143 +570,253 @@ int lookup_paths_init(
"/usr/share/systemd/user",
STRV_IFNOTNULL(generator_late),
NULL);
- } else
- unit_path = strv_new(
- /* If you modify this you also want to modify
- * systemdsystemunitpath= in systemd.pc.in! */
- STRV_IFNOTNULL(generator_early),
- SYSTEM_CONFIG_UNIT_PATH,
- "/etc/systemd/system",
- "/run/systemd/system",
- STRV_IFNOTNULL(generator),
- "/usr/local/lib/systemd/system",
- SYSTEM_DATA_UNIT_PATH,
- "/usr/lib/systemd/system",
-#ifdef HAVE_SPLIT_USR
- "/lib/systemd/system",
-#endif
- STRV_IFNOTNULL(generator_late),
- NULL);
+ break;
+
+ case UNIT_FILE_USER:
+ add = user_dirs(persistent_config, runtime_config,
+ generator, generator_early, generator_late,
+ transient,
+ persistent_config, runtime_control);
+ break;
- if (!unit_path)
+ default:
+ assert_not_reached("Hmm, unexpected scope?");
+ }
+
+ if (!add)
return -ENOMEM;
- r = strv_extend_strv(&p->unit_path, unit_path, false);
- if (r < 0)
- return r;
+ if (paths) {
+ r = strv_extend_strv(&paths, add, true);
+ if (r < 0)
+ return r;
+ } else {
+ /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it,
+ * and don't have to copy anything */
+ paths = add;
+ add = NULL;
+ }
}
- if (!path_strv_resolve_uniq(p->unit_path, root_dir))
+ r = patch_root_prefix(&persistent_config, root);
+ if (r < 0)
+ return r;
+ r = patch_root_prefix(&runtime_config, root);
+ if (r < 0)
+ return r;
+
+ r = patch_root_prefix(&generator, root);
+ if (r < 0)
+ return r;
+ r = patch_root_prefix(&generator_early, root);
+ if (r < 0)
+ return r;
+ r = patch_root_prefix(&generator_late, root);
+ if (r < 0)
+ return r;
+
+ r = patch_root_prefix(&transient, root);
+ if (r < 0)
+ return r;
+
+ r = patch_root_prefix(&persistent_control, root);
+ if (r < 0)
+ return r;
+
+ r = patch_root_prefix(&runtime_control, root);
+ if (r < 0)
+ return r;
+
+ r = patch_root_prefix_strv(paths, root);
+ if (r < 0)
return -ENOMEM;
- if (!strv_isempty(p->unit_path)) {
- _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t");
- if (!t)
- return -ENOMEM;
- log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
- } else {
- log_debug("Ignoring unit files.");
- p->unit_path = strv_free(p->unit_path);
- }
+ p->search_path = strv_uniq(paths);
+ paths = NULL;
- if (running_as == MANAGER_SYSTEM) {
-#ifdef HAVE_SYSV_COMPAT
- /* /etc/init.d/ compatibility does not matter to users */
+ p->persistent_config = persistent_config;
+ p->runtime_config = runtime_config;
+ persistent_config = runtime_config = NULL;
- e = getenv("SYSTEMD_SYSVINIT_PATH");
- if (e) {
- r = path_split_and_make_absolute(e, &p->sysvinit_path);
- if (r < 0)
- return r;
- } else
- p->sysvinit_path = NULL;
+ p->generator = generator;
+ p->generator_early = generator_early;
+ p->generator_late = generator_late;
+ generator = generator_early = generator_late = NULL;
- if (strv_isempty(p->sysvinit_path)) {
- strv_free(p->sysvinit_path);
+ p->transient = transient;
+ transient = NULL;
- p->sysvinit_path = strv_new(
- SYSTEM_SYSVINIT_PATH, /* /etc/init.d/ */
- NULL);
- if (!p->sysvinit_path)
- return -ENOMEM;
- }
+ p->persistent_control = persistent_control;
+ p->runtime_control = runtime_control;
+ persistent_control = runtime_control = NULL;
- e = getenv("SYSTEMD_SYSVRCND_PATH");
- if (e) {
- r = path_split_and_make_absolute(e, &p->sysvrcnd_path);
- if (r < 0)
- return r;
- } else
- p->sysvrcnd_path = NULL;
+ p->root_dir = root;
+ root = NULL;
- if (strv_isempty(p->sysvrcnd_path)) {
- strv_free(p->sysvrcnd_path);
+ return 0;
+}
- p->sysvrcnd_path = strv_new(
- SYSTEM_SYSVRCND_PATH, /* /etc/rcN.d/ */
- NULL);
- if (!p->sysvrcnd_path)
- return -ENOMEM;
+void lookup_paths_free(LookupPaths *p) {
+ if (!p)
+ return;
+
+ p->search_path = strv_free(p->search_path);
+
+ p->persistent_config = mfree(p->persistent_config);
+ p->runtime_config = mfree(p->runtime_config);
+
+ p->generator = mfree(p->generator);
+ p->generator_early = mfree(p->generator_early);
+ p->generator_late = mfree(p->generator_late);
+
+ p->transient = mfree(p->transient);
+
+ p->persistent_control = mfree(p->persistent_control);
+ p->runtime_control = mfree(p->runtime_control);
+
+ p->root_dir = mfree(p->root_dir);
+}
+
+int lookup_paths_reduce(LookupPaths *p) {
+ _cleanup_free_ struct stat *stats = NULL;
+ size_t n_stats = 0, allocated = 0;
+ unsigned c = 0;
+ int r;
+
+ assert(p);
+
+ /* Drop duplicates and non-existing directories from the search path. We figure out whether two directories are
+ * the same by comparing their device and inode numbers. Note one special tweak: when we have a root path set,
+ * we do not follow symlinks when retrieving them, because the kernel wouldn't take the root prefix into
+ * account when following symlinks. When we have no root path set this restriction does not apply however. */
+
+ if (!p->search_path)
+ return 0;
+
+ while (p->search_path[c]) {
+ struct stat st;
+ unsigned k;
+
+ if (p->root_dir)
+ r = lstat(p->search_path[c], &st);
+ else
+ r = stat(p->search_path[c], &st);
+ if (r < 0) {
+ if (errno == ENOENT)
+ goto remove_item;
+
+ /* If something we don't grok happened, let's better leave it in. */
+ log_debug_errno(errno, "Failed to stat %s: %m", p->search_path[c]);
+ c++;
+ continue;
}
- if (!path_strv_resolve_uniq(p->sysvinit_path, root_dir))
- return -ENOMEM;
+ for (k = 0; k < n_stats; k++) {
+ if (stats[k].st_dev == st.st_dev &&
+ stats[k].st_ino == st.st_ino)
+ break;
+ }
+
+ if (k < n_stats) /* Is there already an entry with the same device/inode? */
+ goto remove_item;
- if (!path_strv_resolve_uniq(p->sysvrcnd_path, root_dir))
+ if (!GREEDY_REALLOC(stats, allocated, n_stats+1))
return -ENOMEM;
- if (!strv_isempty(p->sysvinit_path)) {
- _cleanup_free_ char *t = strv_join(p->sysvinit_path, "\n\t");
- if (!t)
- return -ENOMEM;
- log_debug("Looking for SysV init scripts in:\n\t%s", t);
- } else {
- log_debug("Ignoring SysV init scripts.");
- p->sysvinit_path = strv_free(p->sysvinit_path);
- }
+ stats[n_stats++] = st;
+ c++;
+ continue;
- if (!strv_isempty(p->sysvrcnd_path)) {
- _cleanup_free_ char *t =
- strv_join(p->sysvrcnd_path, "\n\t");
- if (!t)
- return -ENOMEM;
+ remove_item:
+ free(p->search_path[c]);
+ memmove(p->search_path + c,
+ p->search_path + c + 1,
+ (strv_length(p->search_path + c + 1) + 1) * sizeof(char*));
+ }
- log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
- } else {
- log_debug("Ignoring SysV rcN.d links.");
- p->sysvrcnd_path = strv_free(p->sysvrcnd_path);
- }
-#else
- log_debug("SysV init scripts and rcN.d links support disabled");
-#endif
+ if (strv_isempty(p->search_path)) {
+ log_debug("Ignoring unit files.");
+ p->search_path = strv_free(p->search_path);
+ } else {
+ _cleanup_free_ char *t;
+
+ t = strv_join(p->search_path, "\n\t");
+ if (!t)
+ return -ENOMEM;
+
+ log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
}
return 0;
}
-void lookup_paths_free(LookupPaths *p) {
+int lookup_paths_mkdir_generator(LookupPaths *p) {
+ int r, q;
+
assert(p);
- p->unit_path = strv_free(p->unit_path);
+ if (!p->generator || !p->generator_early || !p->generator_late)
+ return -EINVAL;
-#ifdef HAVE_SYSV_COMPAT
- p->sysvinit_path = strv_free(p->sysvinit_path);
- p->sysvrcnd_path = strv_free(p->sysvrcnd_path);
-#endif
+ r = mkdir_p_label(p->generator, 0755);
+
+ q = mkdir_p_label(p->generator_early, 0755);
+ if (q < 0 && r >= 0)
+ r = q;
+
+ q = mkdir_p_label(p->generator_late, 0755);
+ if (q < 0 && r >= 0)
+ r = q;
+
+ return r;
}
-int lookup_paths_init_from_scope(LookupPaths *paths,
- UnitFileScope scope,
- const char *root_dir) {
- assert(paths);
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
+void lookup_paths_trim_generator(LookupPaths *p) {
+ assert(p);
- zero(*paths);
+ /* Trim empty dirs */
+
+ if (p->generator)
+ (void) rmdir(p->generator);
+ if (p->generator_early)
+ (void) rmdir(p->generator_early);
+ if (p->generator_late)
+ (void) rmdir(p->generator_late);
+}
+
+void lookup_paths_flush_generator(LookupPaths *p) {
+ assert(p);
- return lookup_paths_init(paths,
- scope == UNIT_FILE_SYSTEM ? MANAGER_SYSTEM : MANAGER_USER,
- scope == UNIT_FILE_USER,
- root_dir,
- NULL, NULL, NULL);
+ /* Flush the generated unit files in full */
+
+ if (p->generator)
+ (void) rm_rf(p->generator, REMOVE_ROOT);
+ if (p->generator_early)
+ (void) rm_rf(p->generator_early, REMOVE_ROOT);
+ if (p->generator_late)
+ (void) rm_rf(p->generator_late, REMOVE_ROOT);
+}
+
+char **generator_binary_paths(UnitFileScope scope) {
+
+ switch (scope) {
+
+ case UNIT_FILE_SYSTEM:
+ return strv_new("/run/systemd/system-generators",
+ "/etc/systemd/system-generators",
+ "/usr/local/lib/systemd/system-generators",
+ SYSTEM_GENERATOR_PATH,
+ NULL);
+
+ case UNIT_FILE_GLOBAL:
+ case UNIT_FILE_USER:
+ return strv_new("/run/systemd/user-generators",
+ "/etc/systemd/user-generators",
+ "/usr/local/lib/systemd/user-generators",
+ USER_GENERATOR_PATH,
+ NULL);
+
+ default:
+ assert_not_reached("Hmm, unexpected scope.");
+ }
}
diff --git a/src/libshared/path-lookup.h b/src/libshared/path-lookup.h
index 26c83d6111..f9bb2fe237 100644
--- a/src/libshared/path-lookup.h
+++ b/src/libshared/path-lookup.h
@@ -20,41 +20,57 @@
***/
#include <stdbool.h>
-#include "macro.h"
-typedef struct LookupPaths {
- char **unit_path;
-#ifdef HAVE_SYSV_COMPAT
- char **sysvinit_path;
- char **sysvrcnd_path;
-#endif
-} LookupPaths;
-
-typedef enum ManagerRunningAs {
- MANAGER_SYSTEM,
- MANAGER_USER,
- _MANAGER_RUNNING_AS_MAX,
- _MANAGER_RUNNING_AS_INVALID = -1
-} ManagerRunningAs;
-
-int user_config_home(char **config_home);
-int user_runtime_dir(char **runtime_dir);
-
-char **generator_paths(ManagerRunningAs running_as);
-
-int lookup_paths_init(LookupPaths *p,
- ManagerRunningAs running_as,
- bool personal,
- const char *root_dir,
- const char *generator,
- const char *generator_early,
- const char *generator_late);
+typedef struct LookupPaths LookupPaths;
#include "install.h"
+#include "macro.h"
+
+typedef enum LookupPathsFlags {
+ LOOKUP_PATHS_EXCLUDE_GENERATED = 1,
+} LookupPathsFlags;
+
+struct LookupPaths {
+ /* Where we look for unit files. This includes the individual special paths below, but also any vendor
+ * supplied, static unit file paths. */
+ char **search_path;
+
+ /* Where we shall create or remove our installation symlinks, aka "configuration", and where the user/admin
+ * shall place his own unit files. */
+ char *persistent_config;
+ char *runtime_config;
+
+ /* Where to place generated unit files (i.e. those a "generator" tool generated). Note the special semantics of
+ * this directory: the generators are flushed each time a "systemctl daemon-reload" is issued. The user should
+ * not alter these directories directly. */
+ char *generator;
+ char *generator_early;
+ char *generator_late;
-int lookup_paths_init_from_scope(LookupPaths *paths,
- UnitFileScope scope,
- const char *root_dir);
+ /* Where to place transient unit files (i.e. those created dynamically via the bus API). Note the special
+ * semantics of this directory: all units created transiently have their unit files removed as the transient
+ * unit is unloaded. The user should not alter this directory directly. */
+ char *transient;
+
+ /* Where the snippets created by "systemctl set-property" are placed. Note that for transient units, the
+ * snippets are placed in the transient directory though (see above). The user should not alter this directory
+ * directly. */
+ char *persistent_control;
+ char *runtime_control;
+
+ /* The root directory prepended to all items above, or NULL */
+ char *root_dir;
+};
+
+int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
+
+int lookup_paths_reduce(LookupPaths *p);
+
+int lookup_paths_mkdir_generator(LookupPaths *p);
+void lookup_paths_trim_generator(LookupPaths *p);
+void lookup_paths_flush_generator(LookupPaths *p);
void lookup_paths_free(LookupPaths *p);
#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)
+
+char **generator_binary_paths(UnitFileScope scope);
diff --git a/src/libshared/ptyfwd.c b/src/libshared/ptyfwd.c
index a97e0d5143..9629b50ed9 100644
--- a/src/libshared/ptyfwd.c
+++ b/src/libshared/ptyfwd.c
@@ -461,10 +461,7 @@ int pty_forward_set_ignore_vhangup(PTYForward *f, bool b) {
if (!!(f->flags & PTY_FORWARD_IGNORE_VHANGUP) == b)
return 0;
- if (b)
- f->flags |= PTY_FORWARD_IGNORE_VHANGUP;
- else
- f->flags &= ~PTY_FORWARD_IGNORE_VHANGUP;
+ SET_FLAG(f->flags, PTY_FORWARD_IGNORE_VHANGUP, b);
if (!ignore_vhangup(f)) {
diff --git a/src/libshared/sleep-config.c b/src/libshared/sleep-config.c
index a0aef66bc8..f00624d0f2 100644
--- a/src/libshared/sleep-config.c
+++ b/src/libshared/sleep-config.c
@@ -28,6 +28,7 @@
#include "alloc-util.h"
#include "conf-parser.h"
#include "def.h"
+#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "log.h"
@@ -37,7 +38,7 @@
#include "string-util.h"
#include "strv.h"
-#define USE(x, y) do{ (x) = (y); (y) = NULL; } while(0)
+#define USE(x, y) do { (x) = (y); (y) = NULL; } while (0)
int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
@@ -231,6 +232,9 @@ static bool enough_memory_for_hibernation(void) {
size_t size = 0, used = 0;
int r;
+ if (getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0)
+ return true;
+
r = hibernation_partition_size(&size, &used);
if (r < 0)
return false;
diff --git a/src/libshared/sleep-config.h b/src/libshared/sleep-config.h
index 51f4621844..ad10039ff4 100644
--- a/src/libshared/sleep-config.h
+++ b/src/libshared/sleep-config.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
int parse_sleep_config(const char *verb, char ***modes, char ***states);
int can_sleep(const char *verb);
diff --git a/src/libshared/spawn-polkit-agent.c b/src/libshared/spawn-polkit-agent.c
index cf3c8ad5a3..7dae4d14fe 100644
--- a/src/libshared/spawn-polkit-agent.c
+++ b/src/libshared/spawn-polkit-agent.c
@@ -44,6 +44,10 @@ int polkit_agent_open(void) {
if (agent_pid > 0)
return 0;
+ /* Clients that run as root don't need to activate/query polkit */
+ if (geteuid() == 0)
+ return 0;
+
/* We check STDIN here, not STDOUT, since this is about input,
* not output */
if (!isatty(STDIN_FILENO))
diff --git a/src/systemd-bootchart/store.h b/src/libshared/tests.c
index 6e9acf2a6f..409116290d 100644
--- a/src/systemd-bootchart/store.h
+++ b/src/libshared/tests.c
@@ -1,12 +1,7 @@
-#pragma once
-
/***
This file is part of systemd.
- Copyright (C) 2009-2013 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.com>
+ Copyright 2016 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -22,15 +17,17 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dirent.h>
+#include <stdlib.h>
+#include <util.h>
+
+#include "tests.h"
+
+char* setup_fake_runtime_dir(void) {
+ char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
-#include "bootchart.h"
+ assert_se(mkdtemp(t));
+ assert_se(setenv("XDG_RUNTIME_DIR", t, 1) >= 0);
+ assert_se(p = strdup(t));
-double gettime_ns(void);
-void log_uptime(void);
-int log_sample(DIR *proc,
- int sample,
- struct ps_struct *ps_first,
- struct list_sample_data **ptr,
- int *pscount,
- int *cpus);
+ return p;
+}
diff --git a/src/import/aufs-util.h b/src/libshared/tests.h
index e474a50897..93f09013a1 100644
--- a/src/import/aufs-util.h
+++ b/src/libshared/tests.h
@@ -3,7 +3,7 @@
/***
This file is part of systemd.
- Copyright 2014 Lennart Poettering
+ Copyright 2016 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -19,4 +19,4 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-int aufs_resolve(const char *path);
+char* setup_fake_runtime_dir(void);
diff --git a/src/libshared/uid-range.c b/src/libshared/uid-range.c
index eb251492c3..b6ec474390 100644
--- a/src/libshared/uid-range.c
+++ b/src/libshared/uid-range.c
@@ -54,7 +54,7 @@ static void uid_range_coalesce(UidRange **p, unsigned *n) {
if (*n > j+1)
memmove(y, y+1, sizeof(UidRange) * (*n - j -1));
- (*n) --;
+ (*n)--;
j--;
}
}
diff --git a/src/libsystemd-network/Makefile b/src/libsystemd-network/Makefile
index 45f782b184..6b16906c17 100644
--- a/src/libsystemd-network/Makefile
+++ b/src/libsystemd-network/Makefile
@@ -68,15 +68,11 @@ libsystemd_network_la_SOURCES = \
src/libsystemd-network/sd-dhcp6-lease.c \
src/libsystemd-network/dhcp-identifier.h \
src/libsystemd-network/dhcp-identifier.c \
- src/libsystemd-network/lldp.h \
- src/libsystemd-network/lldp-tlv.h \
- src/libsystemd-network/lldp-tlv.c \
+ src/libsystemd-network/lldp-internal.h \
src/libsystemd-network/lldp-network.h \
src/libsystemd-network/lldp-network.c \
- src/libsystemd-network/lldp-port.h \
- src/libsystemd-network/lldp-port.c \
- src/libsystemd-network/lldp-internal.h \
- src/libsystemd-network/lldp-internal.c \
+ src/libsystemd-network/lldp-neighbor.h \
+ src/libsystemd-network/lldp-neighbor.c \
src/libsystemd-network/sd-lldp.c
libsystemd_network_la_LIBADD = \
@@ -159,9 +155,6 @@ test_dhcp6_client_LDADD = \
libshared.la
test_lldp_SOURCES = \
- src/libsystemd-network/lldp.h \
- src/libsystemd-network/lldp-tlv.h \
- src/libsystemd-network/lldp-tlv.c \
src/libsystemd-network/test-lldp.c
test_lldp_LDADD = \
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index d58f9029cc..906d960171 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -31,6 +31,37 @@
#define SYSTEMD_PEN 43793
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
+ struct duid d;
+
+ assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
+ if (duid_len > MAX_DUID_LEN)
+ return -EINVAL;
+
+ switch (duid_type) {
+ case DUID_TYPE_LLT:
+ if (duid_len <= sizeof(d.llt))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_EN:
+ if (duid_len != sizeof(d.en))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_LL:
+ if (duid_len <= sizeof(d.ll))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_UUID:
+ if (duid_len != sizeof(d.uuid))
+ return -EINVAL;
+ break;
+ default:
+ /* accept unknown type in order to be forward compatible */
+ break;
+ }
+ return 0;
+}
+
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
sd_id128_t machine_id;
uint64_t hash;
@@ -43,7 +74,7 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
if (r < 0)
return r;
- unaligned_write_be16(&duid->type, DHCP6_DUID_EN);
+ unaligned_write_be16(&duid->type, DUID_TYPE_EN);
unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
*len = sizeof(duid->type) + sizeof(duid->en);
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
index 31f461abd1..802a0d6bc2 100644
--- a/src/libsystemd-network/dhcp-identifier.h
+++ b/src/libsystemd-network/dhcp-identifier.h
@@ -25,32 +25,42 @@
#include "sparse-endian.h"
#include "unaligned.h"
+typedef enum DUIDType {
+ DUID_TYPE_LLT = 1,
+ DUID_TYPE_EN = 2,
+ DUID_TYPE_LL = 3,
+ DUID_TYPE_UUID = 4,
+ _DUID_TYPE_MAX,
+ _DUID_TYPE_INVALID = -1,
+} DUIDType;
+
/* RFC 3315 section 9.1:
* A DUID can be no more than 128 octets long (not including the type code).
*/
#define MAX_DUID_LEN 128
+/* https://tools.ietf.org/html/rfc3315#section-9.1 */
struct duid {
- uint16_t type;
+ be16_t type;
union {
struct {
- /* DHCP6_DUID_LLT */
+ /* DUID_TYPE_LLT */
uint16_t htype;
uint32_t time;
uint8_t haddr[0];
} _packed_ llt;
struct {
- /* DHCP6_DUID_EN */
+ /* DUID_TYPE_EN */
uint32_t pen;
uint8_t id[8];
} _packed_ en;
struct {
- /* DHCP6_DUID_LL */
+ /* DUID_TYPE_LL */
int16_t htype;
uint8_t haddr[0];
} _packed_ ll;
struct {
- /* DHCP6_DUID_UUID */
+ /* DUID_TYPE_UUID */
sd_id128_t uuid;
} _packed_ uuid;
struct {
@@ -59,5 +69,6 @@ struct duid {
};
} _packed_;
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h
index 51cb193847..dda4c13919 100644
--- a/src/libsystemd-network/dhcp-internal.h
+++ b/src/libsystemd-network/dhcp-internal.h
@@ -42,10 +42,10 @@ int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_t overload,
uint8_t code, size_t optlen, const void *optval);
-typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
+typedef int (*dhcp_option_callback_t)(uint8_t code, uint8_t len,
const void *option, void *userdata);
-int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_cb_t cb, void *userdata, char **error_message);
+int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t cb, void *userdata, char **error_message);
int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
uint8_t type, uint16_t arp_type, size_t optlen,
diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c
index df1996c8ce..c105196334 100644
--- a/src/libsystemd-network/dhcp-option.c
+++ b/src/libsystemd-network/dhcp-option.c
@@ -34,7 +34,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
if (code != SD_DHCP_OPTION_END)
/* always make sure there is space for an END option */
- size --;
+ size--;
switch (code) {
@@ -54,12 +54,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
options[*offset] = code;
options[*offset + 1] = optlen;
- if (optlen) {
- assert(optval);
-
- memcpy(&options[*offset + 2], optval, optlen);
- }
-
+ memcpy_safe(&options[*offset + 2], optval, optlen);
*offset += optlen + 2;
break;
@@ -140,7 +135,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
}
static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload,
- uint8_t *message_type, char **error_message, dhcp_option_cb_t cb,
+ uint8_t *message_type, char **error_message, dhcp_option_callback_t cb,
void *userdata) {
uint8_t code, len;
const uint8_t *option;
@@ -226,7 +221,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
return 0;
}
-int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_cb_t cb, void *userdata, char **_error_message) {
+int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t cb, void *userdata, char **_error_message) {
_cleanup_free_ char *error_message = NULL;
uint8_t overload = 0;
uint8_t message_type = 0;
diff --git a/src/libsystemd-network/dhcp-packet.c b/src/libsystemd-network/dhcp-packet.c
index 8d75d49691..8be774061d 100644
--- a/src/libsystemd-network/dhcp-packet.c
+++ b/src/libsystemd-network/dhcp-packet.c
@@ -66,7 +66,7 @@ uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len) {
/* wrap around in one's complement */
sum++;
- buf_64 ++;
+ buf_64++;
}
if (len % sizeof(uint64_t)) {
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
index a5306b2907..7ba1e72155 100644
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ b/src/libsystemd-network/dhcp-server-internal.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -18,8 +20,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <systemd/sd-dhcp-server.h>
#include <systemd/sd-event.h>
@@ -63,6 +63,8 @@ struct sd_dhcp_server {
struct in_addr *ntp, *dns;
unsigned n_ntp, n_dns;
+ bool emit_router;
+
Hashmap *leases_by_client_id;
DHCPLease **bound_leases;
DHCPLease invalid_lease;
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
index 228feb49d8..4228053ade 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -55,7 +55,8 @@ struct DHCP6IA {
typedef struct DHCP6IA DHCP6IA;
-#define log_dhcp6_client(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__)
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
size_t optlen, const void *optval);
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index 91d7f8a7da..0ae381ad22 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -71,8 +71,7 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
if (r < 0)
return r;
- if (optval)
- memcpy(*buf, optval, optlen);
+ memcpy_safe(*buf, optval, optlen);
*buf += optlen;
*buflen -= optlen;
diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h
index ee4bdfb07f..2487c470ab 100644
--- a/src/libsystemd-network/dhcp6-protocol.h
+++ b/src/libsystemd-network/dhcp6-protocol.h
@@ -62,13 +62,6 @@ enum {
#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC
#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC
-enum {
- DHCP6_DUID_LLT = 1,
- DHCP6_DUID_EN = 2,
- DHCP6_DUID_LL = 3,
- DHCP6_DUID_UUID = 4,
-};
-
enum DHCP6State {
DHCP6_STATE_STOPPED = 0,
DHCP6_STATE_INFORMATION_REQUEST = 1,
diff --git a/src/libsystemd-network/lldp-internal.c b/src/libsystemd-network/lldp-internal.c
deleted file mode 100644
index 902a262f39..0000000000
--- a/src/libsystemd-network/lldp-internal.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 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 <systemd/sd-lldp.h>
-
-#include "alloc-util.h"
-#include "lldp-internal.h"
-
-/* We store maximum 1K chassis entries */
-#define LLDP_MIB_MAX_CHASSIS 1024
-
-/* Maximum Ports can be attached to any chassis */
-#define LLDP_MIB_MAX_PORT_PER_CHASSIS 32
-
-/* 10.5.5.2.2 mibUpdateObjects ()
- * The mibUpdateObjects () procedure updates the MIB objects corresponding to
- * the TLVs contained in the received LLDPDU for the LLDP remote system
- * indicated by the LLDP remote systems update process defined in 10.3.5 */
-
-int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv) {
- lldp_neighbour_port *p;
- uint16_t length, ttl;
- uint8_t *data;
- uint8_t type;
- int r;
-
- assert_return(c, -EINVAL);
- assert_return(tlv, -EINVAL);
-
- r = sd_lldp_packet_read_port_id(tlv, &type, &data, &length);
- if (r < 0)
- return r;
-
- /* Update the packet if we already have */
- LIST_FOREACH(port, p, c->ports) {
-
- if ((p->type == type && p->length == length && !memcmp(p->data, data, p->length))) {
-
- r = sd_lldp_packet_read_ttl(tlv, &ttl);
- if (r < 0)
- return r;
-
- p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic());
-
- sd_lldp_packet_unref(p->packet);
- p->packet = tlv;
-
- prioq_reshuffle(p->c->by_expiry, p, &p->prioq_idx);
-
- return 0;
- }
- }
-
- return -1;
-}
-
-int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv) {
- lldp_neighbour_port *p, *q;
- uint8_t *data;
- uint16_t length;
- uint8_t type;
- int r;
-
- assert_return(c, -EINVAL);
- assert_return(tlv, -EINVAL);
-
- r = sd_lldp_packet_read_port_id(tlv, &type, &data, &length);
- if (r < 0)
- return r;
-
- LIST_FOREACH_SAFE(port, p, q, c->ports) {
-
- /* Find the port */
- if (p->type == type && p->length == length && !memcmp(p->data, data, p->length)) {
- lldp_neighbour_port_remove_and_free(p);
- break;
- }
- }
-
- return 0;
-}
-
-int lldp_mib_add_objects(Prioq *by_expiry,
- Hashmap *neighbour_mib,
- tlv_packet *tlv) {
- _cleanup_lldp_neighbour_port_free_ lldp_neighbour_port *p = NULL;
- _cleanup_lldp_chassis_free_ lldp_chassis *c = NULL;
- lldp_chassis_id chassis_id;
- bool new_chassis = false;
- uint8_t subtype, *data;
- uint16_t ttl, length;
- int r;
-
- assert_return(by_expiry, -EINVAL);
- assert_return(neighbour_mib, -EINVAL);
- assert_return(tlv, -EINVAL);
-
- r = sd_lldp_packet_read_chassis_id(tlv, &subtype, &data, &length);
- if (r < 0)
- goto drop;
-
- r = sd_lldp_packet_read_ttl(tlv, &ttl);
- if (r < 0)
- goto drop;
-
- /* Make hash key */
- chassis_id.type = subtype;
- chassis_id.length = length;
- chassis_id.data = data;
-
- /* Try to find the Chassis */
- c = hashmap_get(neighbour_mib, &chassis_id);
- if (!c) {
-
- /* Don't create chassis if ttl 0 is received . Silently drop it */
- if (ttl == 0) {
- log_lldp("TTL value 0 received. Skiping Chassis creation.");
- goto drop;
- }
-
- /* Admission Control: Can we store this packet ? */
- if (hashmap_size(neighbour_mib) >= LLDP_MIB_MAX_CHASSIS) {
-
- log_lldp("Exceeding number of chassie: %d. Dropping ...",
- hashmap_size(neighbour_mib));
- goto drop;
- }
-
- r = lldp_chassis_new(tlv, by_expiry, neighbour_mib, &c);
- if (r < 0)
- goto drop;
-
- new_chassis = true;
-
- r = hashmap_put(neighbour_mib, &c->chassis_id, c);
- if (r < 0)
- goto drop;
-
- } else {
-
- /* When the TTL field is set to zero, the receiving LLDP agent is notified all
- * system information associated with the LLDP agent/port is to be deleted */
- if (ttl == 0) {
- log_lldp("TTL value 0 received . Deleting associated Port ...");
-
- lldp_mib_remove_objects(c, tlv);
-
- c = NULL;
- goto drop;
- }
-
- /* if we already have this port just update it */
- r = lldp_mib_update_objects(c, tlv);
- if (r >= 0) {
- c = NULL;
- return r;
- }
-
- /* Admission Control: Can this port attached to the existing chassis ? */
- if (c->n_ref >= LLDP_MIB_MAX_PORT_PER_CHASSIS) {
- log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...", c->n_ref);
-
- c = NULL;
- goto drop;
- }
- }
-
- /* This is a new port */
- r = lldp_neighbour_port_new(c, tlv, &p);
- if (r < 0)
- goto drop;
-
- r = prioq_put(c->by_expiry, p, &p->prioq_idx);
- if (r < 0)
- goto drop;
-
- /* Attach new port to chassis */
- LIST_PREPEND(port, c->ports, p);
- c->n_ref ++;
-
- p = NULL;
- c = NULL;
-
- return 0;
-
- drop:
- sd_lldp_packet_unref(tlv);
-
- if (new_chassis)
- hashmap_remove(neighbour_mib, &c->chassis_id);
-
- return r;
-}
-
-void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p) {
- lldp_chassis *c;
-
- assert(p);
- assert(p->c);
-
- c = p->c;
-
- prioq_remove(c->by_expiry, p, &p->prioq_idx);
-
- LIST_REMOVE(port, c->ports, p);
- lldp_neighbour_port_free(p);
-
- /* Drop the Chassis if no port is attached */
- c->n_ref --;
- if (c->n_ref <= 1) {
- hashmap_remove(c->neighbour_mib, &c->chassis_id);
- lldp_chassis_free(c);
- }
-}
-
-void lldp_neighbour_port_free(lldp_neighbour_port *p) {
-
- if(!p)
- return;
-
- sd_lldp_packet_unref(p->packet);
-
- free(p->data);
- free(p);
-}
-
-int lldp_neighbour_port_new(lldp_chassis *c,
- tlv_packet *tlv,
- lldp_neighbour_port **ret) {
- _cleanup_lldp_neighbour_port_free_ lldp_neighbour_port *p = NULL;
- uint16_t length, ttl;
- uint8_t *data;
- uint8_t type;
- int r;
-
- assert(tlv);
-
- r = sd_lldp_packet_read_port_id(tlv, &type, &data, &length);
- if (r < 0)
- return r;
-
- r = sd_lldp_packet_read_ttl(tlv, &ttl);
- if (r < 0)
- return r;
-
- p = new0(lldp_neighbour_port, 1);
- if (!p)
- return -ENOMEM;
-
- p->c = c;
- p->type = type;
- p->length = length;
- p->packet = tlv;
- p->prioq_idx = PRIOQ_IDX_NULL;
- p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic());
-
- p->data = memdup(data, length);
- if (!p->data)
- return -ENOMEM;
-
- *ret = p;
- p = NULL;
-
- return 0;
-}
-
-void lldp_chassis_free(lldp_chassis *c) {
-
- if (!c)
- return;
-
- if (c->n_ref > 1)
- return;
-
- free(c->chassis_id.data);
- free(c);
-}
-
-int lldp_chassis_new(tlv_packet *tlv,
- Prioq *by_expiry,
- Hashmap *neighbour_mib,
- lldp_chassis **ret) {
- _cleanup_lldp_chassis_free_ lldp_chassis *c = NULL;
- uint16_t length;
- uint8_t *data;
- uint8_t type;
- int r;
-
- assert(tlv);
-
- r = sd_lldp_packet_read_chassis_id(tlv, &type, &data, &length);
- if (r < 0)
- return r;
-
- c = new0(lldp_chassis, 1);
- if (!c)
- return -ENOMEM;
-
- c->n_ref = 1;
- c->chassis_id.type = type;
- c->chassis_id.length = length;
-
- c->chassis_id.data = memdup(data, length);
- if (!c->chassis_id.data)
- return -ENOMEM;
-
- LIST_HEAD_INIT(c->ports);
-
- c->by_expiry = by_expiry;
- c->neighbour_mib = neighbour_mib;
-
- *ret = c;
- c = NULL;
-
- return 0;
-}
-
-int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- _cleanup_(sd_lldp_packet_unrefp) tlv_packet *packet = NULL;
- tlv_packet *p;
- uint16_t length;
- int r;
-
- assert(fd);
- assert(userdata);
-
- r = tlv_packet_new(&packet);
- if (r < 0)
- return r;
-
- length = read(fd, &packet->pdu, sizeof(packet->pdu));
-
- /* Silently drop the packet */
- if ((size_t) length > ETHER_MAX_LEN)
- return 0;
-
- packet->userdata = userdata;
-
- p = packet;
- packet = NULL;
-
- return lldp_handle_packet(p, (uint16_t) length);
-}
diff --git a/src/libsystemd-network/lldp-internal.h b/src/libsystemd-network/lldp-internal.h
index 565149fbcf..a6be995e3b 100644
--- a/src/libsystemd-network/lldp-internal.h
+++ b/src/libsystemd-network/lldp-internal.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -18,74 +20,34 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <systemd/sd-event.h>
+#include <systemd/sd-lldp.h>
-#include "list.h"
-#include "lldp-tlv.h"
+#include "hashmap.h"
#include "log.h"
#include "prioq.h"
-typedef struct lldp_neighbour_port lldp_neighbour_port;
-typedef struct lldp_chassis lldp_chassis;
-typedef struct lldp_chassis_id lldp_chassis_id;
-typedef struct lldp_agent_statistics lldp_agent_statistics;
+struct sd_lldp {
+ int ifindex;
+ int fd;
-struct lldp_neighbour_port {
- uint8_t type;
- uint8_t *data;
+ sd_event *event;
+ int64_t event_priority;
+ sd_event_source *io_event_source;
+ sd_event_source *timer_event_source;
- uint16_t length;
- usec_t until;
+ Prioq *neighbor_by_expiry;
+ Hashmap *neighbor_by_id;
- unsigned prioq_idx;
+ uint64_t neighbors_max;
- lldp_chassis *c;
- tlv_packet *packet;
+ sd_lldp_callback_t callback;
+ void *userdata;
- LIST_FIELDS(lldp_neighbour_port, port);
-};
+ uint16_t capability_mask;
-int lldp_neighbour_port_new(lldp_chassis *c, tlv_packet *tlv, lldp_neighbour_port **ret);
-void lldp_neighbour_port_free(lldp_neighbour_port *p);
-void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_neighbour_port *, lldp_neighbour_port_free);
-#define _cleanup_lldp_neighbour_port_free_ _cleanup_(lldp_neighbour_port_freep)
-
-struct lldp_chassis_id {
- uint8_t type;
- uint16_t length;
-
- uint8_t *data;
+ struct ether_addr filter_address;
};
-struct lldp_chassis {
- unsigned n_ref;
-
- lldp_chassis_id chassis_id;
-
- Prioq *by_expiry;
- Hashmap *neighbour_mib;
-
- LIST_HEAD(lldp_neighbour_port, ports);
-};
-
-int lldp_chassis_new(tlv_packet *tlv,
- Prioq *by_expiry,
- Hashmap *neighbour_mib,
- lldp_chassis **ret);
-
-void lldp_chassis_free(lldp_chassis *c);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_chassis *, lldp_chassis_free);
-#define _cleanup_lldp_chassis_free_ _cleanup_(lldp_chassis_freep)
-
-int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv);
-int lldp_mib_add_objects(Prioq *by_expiry, Hashmap *neighbour_mib, tlv_packet *tlv);
-int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv);
-
-int lldp_handle_packet(tlv_packet *m, uint16_t length);
-int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata);
-#define log_lldp(fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
+#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
+#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__)
diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c
new file mode 100644
index 0000000000..6a716430e3
--- /dev/null
+++ b/src/libsystemd-network/lldp-neighbor.c
@@ -0,0 +1,794 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "escape.h"
+#include "ether-addr-util.h"
+#include "hexdecoct.h"
+#include "in-addr-util.h"
+#include "lldp-internal.h"
+#include "lldp-neighbor.h"
+#include "unaligned.h"
+
+static void lldp_neighbor_id_hash_func(const void *p, struct siphash *state) {
+ const LLDPNeighborID *id = p;
+
+ siphash24_compress(id->chassis_id, id->chassis_id_size, state);
+ siphash24_compress(&id->chassis_id_size, sizeof(id->chassis_id_size), state);
+ siphash24_compress(id->port_id, id->port_id_size, state);
+ siphash24_compress(&id->port_id_size, sizeof(id->port_id_size), state);
+}
+
+static int lldp_neighbor_id_compare_func(const void *a, const void *b) {
+ const LLDPNeighborID *x = a, *y = b;
+ int r;
+
+ r = memcmp(x->chassis_id, y->chassis_id, MIN(x->chassis_id_size, y->chassis_id_size));
+ if (r != 0)
+ return r;
+
+ if (x->chassis_id_size < y->chassis_id_size)
+ return -1;
+
+ if (x->chassis_id_size > y->chassis_id_size)
+ return 1;
+
+ r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size));
+ if (r != 0)
+ return r;
+
+ if (x->port_id_size < y->port_id_size)
+ return -1;
+ if (x->port_id_size > y->port_id_size)
+ return 1;
+
+ return 0;
+}
+
+const struct hash_ops lldp_neighbor_id_hash_ops = {
+ .hash = lldp_neighbor_id_hash_func,
+ .compare = lldp_neighbor_id_compare_func
+};
+
+int lldp_neighbor_prioq_compare_func(const void *a, const void *b) {
+ const sd_lldp_neighbor *x = a, *y = b;
+
+ if (x->until < y->until)
+ return -1;
+
+ if (x->until > y->until)
+ return 1;
+
+ return 0;
+}
+
+_public_ sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) {
+ if (!n)
+ return NULL;
+
+ assert(n->n_ref > 0 || n->lldp);
+ n->n_ref++;
+
+ return n;
+}
+
+static void lldp_neighbor_free(sd_lldp_neighbor *n) {
+ assert(n);
+
+ free(n->id.port_id);
+ free(n->id.chassis_id);
+ free(n->port_description);
+ free(n->system_name);
+ free(n->system_description);
+ free(n->chassis_id_as_string);
+ free(n->port_id_as_string);
+ free(n);
+}
+
+_public_ sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n) {
+
+ /* Drops one reference from the neighbor. Note that the object is not freed unless it is already unlinked from
+ * the sd_lldp object. */
+
+ if (!n)
+ return NULL;
+
+ assert(n->n_ref > 0);
+ n->n_ref--;
+
+ if (n->n_ref <= 0 && !n->lldp)
+ lldp_neighbor_free(n);
+
+ return NULL;
+}
+
+sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n) {
+
+ /* Removes the neighbor object from the LLDP object, and frees it if it also has no other reference. */
+
+ if (!n)
+ return NULL;
+
+ if (!n->lldp)
+ return NULL;
+
+ assert_se(hashmap_remove(n->lldp->neighbor_by_id, &n->id) == n);
+ assert_se(prioq_remove(n->lldp->neighbor_by_expiry, n, &n->prioq_idx) >= 0);
+
+ n->lldp = NULL;
+
+ if (n->n_ref <= 0)
+ lldp_neighbor_free(n);
+
+ return NULL;
+}
+
+sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size) {
+ sd_lldp_neighbor *n;
+
+ n = malloc0(ALIGN(sizeof(sd_lldp_neighbor)) + raw_size);
+ if (!n)
+ return NULL;
+
+ n->raw_size = raw_size;
+ n->n_ref = 1;
+
+ return n;
+}
+
+static int parse_string(char **s, const void *q, size_t n) {
+ const char *p = q;
+ char *k;
+
+ assert(s);
+ assert(p || n == 0);
+
+ if (*s) {
+ log_lldp("Found duplicate string, ignoring field.");
+ return 0;
+ }
+
+ /* Strip trailing NULs, just to be nice */
+ while (n > 0 && p[n-1] == 0)
+ n--;
+
+ if (n <= 0) /* Ignore empty strings */
+ return 0;
+
+ /* Look for inner NULs */
+ if (memchr(p, 0, n)) {
+ log_lldp("Found inner NUL in string, ignoring field.");
+ return 0;
+ }
+
+ /* Let's escape weird chars, for security reasons */
+ k = cescape_length(p, n);
+ if (!k)
+ return -ENOMEM;
+
+ free(*s);
+ *s = k;
+
+ return 1;
+}
+
+int lldp_neighbor_parse(sd_lldp_neighbor *n) {
+ struct ether_header h;
+ const uint8_t *p;
+ size_t left;
+ int r;
+
+ assert(n);
+
+ if (n->raw_size < sizeof(struct ether_header)) {
+ log_lldp("Recieved truncated packet, ignoring.");
+ return -EBADMSG;
+ }
+
+ memcpy(&h, LLDP_NEIGHBOR_RAW(n), sizeof(h));
+
+ if (h.ether_type != htobe16(ETHERTYPE_LLDP)) {
+ log_lldp("Received packet with wrong type, ignoring.");
+ return -EBADMSG;
+ }
+
+ if (h.ether_dhost[0] != 0x01 ||
+ h.ether_dhost[1] != 0x80 ||
+ h.ether_dhost[2] != 0xc2 ||
+ h.ether_dhost[3] != 0x00 ||
+ h.ether_dhost[4] != 0x00 ||
+ !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)) {
+ log_lldp("Received packet with wrong destination address, ignoring.");
+ return -EBADMSG;
+ }
+
+ memcpy(&n->source_address, h.ether_shost, sizeof(struct ether_addr));
+ memcpy(&n->destination_address, h.ether_dhost, sizeof(struct ether_addr));
+
+ p = (const uint8_t*) LLDP_NEIGHBOR_RAW(n) + sizeof(struct ether_header);
+ left = n->raw_size - sizeof(struct ether_header);
+
+ for (;;) {
+ uint8_t type;
+ uint16_t length;
+
+ if (left < 2) {
+ log_lldp("TLV lacks header, ignoring.");
+ return -EBADMSG;
+ }
+
+ type = p[0] >> 1;
+ length = p[1] + (((uint16_t) (p[0] & 1)) << 8);
+ p += 2, left -= 2;
+
+ if (left < length) {
+ log_lldp("TLV truncated, ignoring datagram.");
+ return -EBADMSG;
+ }
+
+ switch (type) {
+
+ case SD_LLDP_TYPE_END:
+ if (length != 0) {
+ 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;
+ }
+
+ goto end_marker;
+
+ case SD_LLDP_TYPE_CHASSIS_ID:
+ if (length < 2 || length > 256) { /* includes the chassis subtype, hence one extra byte */
+ log_lldp("Chassis ID field size out of range, ignoring datagram.");
+ return -EBADMSG;
+ }
+ if (n->id.chassis_id) {
+ log_lldp("Duplicate chassis ID field, ignoring datagram.");
+ return -EBADMSG;
+ }
+
+ n->id.chassis_id = memdup(p, length);
+ if (!n->id.chassis_id)
+ return -ENOMEM;
+
+ n->id.chassis_id_size = length;
+ break;
+
+ case SD_LLDP_TYPE_PORT_ID:
+ if (length < 2 || length > 256) { /* includes the port subtype, hence one extra byte */
+ log_lldp("Port ID field size out of range, ignoring datagram.");
+ return -EBADMSG;
+ }
+ if (n->id.port_id) {
+ log_lldp("Duplicate port ID field, ignoring datagram.");
+ return -EBADMSG;
+ }
+
+ n->id.port_id = memdup(p, length);
+ if (!n->id.port_id)
+ return -ENOMEM;
+
+ n->id.port_id_size = length;
+ break;
+
+ case SD_LLDP_TYPE_TTL:
+ if (length != 2) {
+ log_lldp("TTL field has wrong size, ignoring datagram.");
+ return -EBADMSG;
+ }
+
+ if (n->has_ttl) {
+ log_lldp("Duplicate TTL field, ignoring datagram.");
+ return -EBADMSG;
+ }
+
+ n->ttl = unaligned_read_be16(p);
+ n->has_ttl = true;
+ break;
+
+ case SD_LLDP_TYPE_PORT_DESCRIPTION:
+ r = parse_string(&n->port_description, p, length);
+ if (r < 0)
+ return r;
+ break;
+
+ case SD_LLDP_TYPE_SYSTEM_NAME:
+ r = parse_string(&n->system_name, p, length);
+ if (r < 0)
+ return r;
+ break;
+
+ case SD_LLDP_TYPE_SYSTEM_DESCRIPTION:
+ r = parse_string(&n->system_description, p, length);
+ if (r < 0)
+ return r;
+ break;
+
+ case SD_LLDP_TYPE_SYSTEM_CAPABILITIES:
+ if (length != 4)
+ log_lldp("System capabilities field has wrong size, ignoring.");
+ else {
+ n->system_capabilities = unaligned_read_be16(p);
+ n->enabled_capabilities = unaligned_read_be16(p + 2);
+ n->has_capabilities = true;
+ }
+
+ break;
+
+ case SD_LLDP_TYPE_PRIVATE:
+ if (length < 4)
+ log_lldp("Found private TLV that is too short, ignoring.");
+
+ break;
+ }
+
+
+ p += length, left -= length;
+ }
+
+end_marker:
+ if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) {
+ log_lldp("One or more mandatory TLV missing in datagram. Ignoring.");
+ return -EBADMSG;
+
+ }
+
+ n->rindex = sizeof(struct ether_header);
+
+ return 0;
+}
+
+void lldp_neighbor_start_ttl(sd_lldp_neighbor *n) {
+ assert(n);
+
+ if (n->ttl > 0)
+ n->until = usec_add(now(clock_boottime_or_monotonic()), n->ttl * USEC_PER_SEC);
+ else
+ n->until = 0;
+
+ if (n->lldp)
+ prioq_reshuffle(n->lldp->neighbor_by_expiry, n, &n->prioq_idx);
+}
+
+bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b) {
+ if (a == b)
+ return true;
+
+ if (!a || !b)
+ return false;
+
+ if (a->raw_size != b->raw_size)
+ return false;
+
+ return memcmp(LLDP_NEIGHBOR_RAW(a), LLDP_NEIGHBOR_RAW(b), a->raw_size) == 0;
+}
+
+_public_ int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address) {
+ assert_return(n, -EINVAL);
+ assert_return(address, -EINVAL);
+
+ *address = n->source_address;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address) {
+ assert_return(n, -EINVAL);
+ assert_return(address, -EINVAL);
+
+ *address = n->destination_address;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+ assert_return(size, -EINVAL);
+
+ *ret = LLDP_NEIGHBOR_RAW(n);
+ *size = n->raw_size;
+
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) {
+ assert_return(n, -EINVAL);
+ assert_return(type, -EINVAL);
+ assert_return(ret, -EINVAL);
+ assert_return(size, -EINVAL);
+
+ assert(n->id.chassis_id_size > 0);
+
+ *type = *(uint8_t*) n->id.chassis_id;
+ *ret = (uint8_t*) n->id.chassis_id + 1;
+ *size = n->id.chassis_id_size - 1;
+
+ return 0;
+}
+
+static int format_mac_address(const void *data, size_t sz, char **ret) {
+ struct ether_addr a;
+ char *k;
+
+ assert(data || sz <= 0);
+
+ if (sz != 7)
+ return 0;
+
+ memcpy(&a, (uint8_t*) data + 1, sizeof(a));
+
+ k = new(char, ETHER_ADDR_TO_STRING_MAX);
+ if (!k)
+ return -ENOMEM;
+
+ *ret = ether_addr_to_string(&a, k);
+ return 1;
+}
+
+static int format_network_address(const void *data, size_t sz, char **ret) {
+ union in_addr_union a;
+ int family, r;
+
+ if (sz == 6 && ((uint8_t*) data)[1] == 1) {
+ memcpy(&a.in, (uint8_t*) data + 2, sizeof(a.in));
+ family = AF_INET;
+ } else if (sz == 18 && ((uint8_t*) data)[1] == 2) {
+ memcpy(&a.in6, (uint8_t*) data + 2, sizeof(a.in6));
+ family = AF_INET6;
+ } else
+ return 0;
+
+ r = in_addr_to_string(family, &a, ret);
+ if (r < 0)
+ return r;
+ return 1;
+}
+
+_public_ int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, const char **ret) {
+ char *k;
+ int r;
+
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (n->chassis_id_as_string) {
+ *ret = n->chassis_id_as_string;
+ return 0;
+ }
+
+ assert(n->id.chassis_id_size > 0);
+
+ switch (*(uint8_t*) n->id.chassis_id) {
+
+ case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
+ case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
+ case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT:
+ case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
+ case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
+ k = cescape_length((char*) n->id.chassis_id + 1, n->id.chassis_id_size - 1);
+ if (!k)
+ return -ENOMEM;
+
+ goto done;
+
+ case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
+ r = format_mac_address(n->id.chassis_id, n->id.chassis_id_size, &k);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ goto done;
+
+ break;
+
+ case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS:
+ r = format_network_address(n->id.chassis_id, n->id.chassis_id_size, &k);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ goto done;
+
+ break;
+ }
+
+ /* Generic fallback */
+ k = hexmem(n->id.chassis_id, n->id.chassis_id_size);
+ if (!k)
+ return -ENOMEM;
+
+done:
+ *ret = n->chassis_id_as_string = k;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_port_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) {
+ assert_return(n, -EINVAL);
+ assert_return(type, -EINVAL);
+ assert_return(ret, -EINVAL);
+ assert_return(size, -EINVAL);
+
+ assert(n->id.port_id_size > 0);
+
+ *type = *(uint8_t*) n->id.port_id;
+ *ret = (uint8_t*) n->id.port_id + 1;
+ *size = n->id.port_id_size - 1;
+
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const char **ret) {
+ char *k;
+ int r;
+
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (n->port_id_as_string) {
+ *ret = n->port_id_as_string;
+ return 0;
+ }
+
+ assert(n->id.port_id_size > 0);
+
+ switch (*(uint8_t*) n->id.port_id) {
+
+ case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
+ case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT:
+ case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME:
+ case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
+ k = cescape_length((char*) n->id.port_id + 1, n->id.port_id_size - 1);
+ if (!k)
+ return -ENOMEM;
+
+ goto done;
+
+ case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS:
+ r = format_mac_address(n->id.port_id, n->id.port_id_size, &k);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ goto done;
+
+ break;
+
+ case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS:
+ r = format_network_address(n->id.port_id, n->id.port_id_size, &k);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ goto done;
+
+ break;
+ }
+
+ /* Generic fallback */
+ k = hexmem(n->id.port_id, n->id.port_id_size);
+ if (!k)
+ return -ENOMEM;
+
+done:
+ *ret = n->port_id_as_string = k;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ *ret = n->ttl;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (!n->system_name)
+ return -ENODATA;
+
+ *ret = n->system_name;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (!n->system_description)
+ return -ENODATA;
+
+ *ret = n->system_description;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (!n->port_description)
+ return -ENODATA;
+
+ *ret = n->port_description;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (!n->has_capabilities)
+ return -ENODATA;
+
+ *ret = n->system_capabilities;
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret) {
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ if (!n->has_capabilities)
+ return -ENODATA;
+
+ *ret = n->enabled_capabilities;
+ return 0;
+}
+
+int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) {
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
+ int r;
+
+ assert_return(ret, -EINVAL);
+ assert_return(raw || raw_size <= 0, -EINVAL);
+
+ n = lldp_neighbor_new(raw_size);
+ if (!n)
+ return -ENOMEM;
+
+ memcpy(LLDP_NEIGHBOR_RAW(n), raw, raw_size);
+ r = lldp_neighbor_parse(n);
+ if (r < 0)
+ return r;
+
+ *ret = n;
+ n = 0;
+
+ return r;
+}
+
+_public_ int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n) {
+ assert_return(n, -EINVAL);
+
+ assert(n->raw_size >= sizeof(struct ether_header));
+ n->rindex = sizeof(struct ether_header);
+
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n) {
+ size_t length;
+
+ assert_return(n, -EINVAL);
+
+ if (n->rindex == n->raw_size) /* EOF */
+ return -ESPIPE;
+
+ if (n->rindex + 2 > n->raw_size) /* Truncated message */
+ return -EBADMSG;
+
+ length = LLDP_NEIGHBOR_LENGTH(n);
+ if (n->rindex + 2 + length > n->raw_size)
+ return -EBADMSG;
+
+ n->rindex += 2 + length;
+ return n->rindex < n->raw_size;
+}
+
+_public_ int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type) {
+ assert_return(n, -EINVAL);
+ assert_return(type, -EINVAL);
+
+ if (n->rindex == n->raw_size) /* EOF */
+ return -ESPIPE;
+
+ if (n->rindex + 2 > n->raw_size)
+ return -EBADMSG;
+
+ *type = LLDP_NEIGHBOR_TYPE(n);
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type) {
+ uint8_t k;
+ int r;
+
+ assert_return(n, -EINVAL);
+
+ r = sd_lldp_neighbor_tlv_get_type(n, &k);
+ if (r < 0)
+ return r;
+
+ return type == k;
+}
+
+_public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], uint8_t *subtype) {
+ const uint8_t *d;
+ size_t length;
+ int r;
+
+ assert_return(n, -EINVAL);
+ assert_return(oui, -EINVAL);
+ assert_return(subtype, -EINVAL);
+
+ r = sd_lldp_neighbor_tlv_is_type(n, SD_LLDP_TYPE_PRIVATE);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ENXIO;
+
+ length = LLDP_NEIGHBOR_LENGTH(n);
+ if (length < 4)
+ return -EBADMSG;
+
+ if (n->rindex + 2 + length > n->raw_size)
+ return -EBADMSG;
+
+ d = LLDP_NEIGHBOR_DATA(n);
+ memcpy(oui, d, 3);
+ *subtype = d[3];
+
+ return 0;
+}
+
+_public_ int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[3], uint8_t subtype) {
+ uint8_t k[3], st;
+ int r;
+
+ r = sd_lldp_neighbor_tlv_get_oui(n, k, &st);
+ if (r == -ENXIO)
+ return 0;
+ if (r < 0)
+ return r;
+
+ return memcmp(k, oui, 3) == 0 && st == subtype;
+}
+
+_public_ int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) {
+ size_t length;
+
+ assert_return(n, -EINVAL);
+ assert_return(ret, -EINVAL);
+ assert_return(size, -EINVAL);
+
+ /* Note that this returns the full TLV, including the TLV header */
+
+ if (n->rindex + 2 > n->raw_size)
+ return -EBADMSG;
+
+ length = LLDP_NEIGHBOR_LENGTH(n);
+
+ if (n->rindex + 2 + length > n->raw_size)
+ return -EBADMSG;
+
+ *ret = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex;
+ *size = length + 2;
+
+ return 0;
+}
diff --git a/src/libsystemd-network/lldp-neighbor.h b/src/libsystemd-network/lldp-neighbor.h
new file mode 100644
index 0000000000..050159ab73
--- /dev/null
+++ b/src/libsystemd-network/lldp-neighbor.h
@@ -0,0 +1,106 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include <systemd/sd-lldp.h>
+
+#include "hash-funcs.h"
+#include "lldp-internal.h"
+#include "time-util.h"
+
+typedef struct LLDPNeighborID {
+ /* The spec calls this an "MSAP identifier" */
+ void *chassis_id;
+ size_t chassis_id_size;
+
+ void *port_id;
+ size_t port_id_size;
+} LLDPNeighborID;
+
+struct sd_lldp_neighbor {
+ /* Neighbor objects stay around as long as they are linked into an "sd_lldp" object or n_ref > 0. */
+ sd_lldp *lldp;
+ unsigned n_ref;
+
+ usec_t until;
+ unsigned prioq_idx;
+
+ struct ether_addr source_address;
+ struct ether_addr destination_address;
+
+ LLDPNeighborID id;
+
+ /* The raw packet size. The data is appended to the object, accessible via LLDP_NEIGHBOR_RAW() */
+ size_t raw_size;
+
+ /* The current read index for the iterative TLV interface */
+ size_t rindex;
+
+ /* And a couple of fields parsed out. */
+ bool has_ttl:1;
+ bool has_capabilities:1;
+ bool has_port_vlan_id:1;
+
+ uint16_t ttl;
+
+ uint16_t system_capabilities;
+ uint16_t enabled_capabilities;
+
+ char *port_description;
+ char *system_name;
+ char *system_description;
+
+ uint16_t port_vlan_id;
+
+ char *chassis_id_as_string;
+ char *port_id_as_string;
+};
+
+static inline void *LLDP_NEIGHBOR_RAW(const sd_lldp_neighbor *n) {
+ return (uint8_t*) n + ALIGN(sizeof(sd_lldp_neighbor));
+}
+
+static inline uint8_t LLDP_NEIGHBOR_TYPE(const sd_lldp_neighbor *n) {
+ return ((uint8_t*) LLDP_NEIGHBOR_RAW(n))[n->rindex] >> 1;
+}
+
+static inline size_t LLDP_NEIGHBOR_LENGTH(const sd_lldp_neighbor *n) {
+ uint8_t *p;
+
+ p = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex;
+ return p[1] + (((size_t) (p[0] & 1)) << 8);
+}
+
+static inline void* LLDP_NEIGHBOR_DATA(const sd_lldp_neighbor *n) {
+ return ((uint8_t*) LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2;
+}
+
+extern const struct hash_ops lldp_neighbor_id_hash_ops;
+int lldp_neighbor_prioq_compare_func(const void *a, const void *b);
+
+sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n);
+sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size);
+int lldp_neighbor_parse(sd_lldp_neighbor *n);
+void lldp_neighbor_start_ttl(sd_lldp_neighbor *n);
+bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b);
diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c
index 42058c4449..f031760351 100644
--- a/src/libsystemd-network/lldp-network.c
+++ b/src/libsystemd-network/lldp-network.c
@@ -19,65 +19,58 @@
***/
#include <linux/filter.h>
-#include <linux/if_ether.h>
+#include <netinet/if_ether.h>
#include "fd-util.h"
-#include "lldp-internal.h"
#include "lldp-network.h"
-#include "lldp-tlv.h"
#include "socket-util.h"
int lldp_network_bind_raw_socket(int ifindex) {
- typedef struct LLDPFrame {
- struct ethhdr hdr;
- uint8_t tlvs[0];
- } LLDPFrame;
- struct sock_filter filter[] = {
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(LLDPFrame, hdr.h_dest)), /* A <- 4 bytes of destination MAC */
+ static const struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ethhdr, h_dest)), /* A <- 4 bytes of destination MAC */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0180c200, 1, 0), /* A != 01:80:c2:00 */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(LLDPFrame, hdr.h_dest) + 4), /* A <- remaining 2 bytes of destination MAC */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_dest) + 4), /* A <- remaining 2 bytes of destination MAC */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0000, 3, 0), /* A != 00:00 */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0003, 2, 0), /* A != 00:03 */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x000e, 1, 0), /* A != 00:0e */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(LLDPFrame, hdr.h_proto)), /* A <- protocol */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_proto)), /* A <- protocol */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_LLDP, 1, 0), /* A != ETHERTYPE_LLDP */
BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1), /* accept packet */
};
- struct sock_fprog fprog = {
+ static const struct sock_fprog fprog = {
.len = ELEMENTSOF(filter),
- .filter = filter
+ .filter = (struct sock_filter*) filter,
};
- _cleanup_close_ int s = -1;
-
union sockaddr_union saddrll = {
.ll.sll_family = AF_PACKET,
.ll.sll_ifindex = ifindex,
};
+ _cleanup_close_ int fd = -1;
int r;
assert(ifindex > 0);
- s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (s < 0)
+ fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, htons(ETHERTYPE_LLDP));
+ if (fd < 0)
return -errno;
- r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
+ r = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
if (r < 0)
return -errno;
- r = bind(s, &saddrll.sa, sizeof(saddrll.ll));
+ r = bind(fd, &saddrll.sa, sizeof(saddrll.ll));
if (r < 0)
return -errno;
- r = s;
- s = -1;
+ r = fd;
+ fd = -1;
return r;
}
diff --git a/src/libsystemd-network/lldp-network.h b/src/libsystemd-network/lldp-network.h
index 3eb03a102d..43ed54b3b2 100644
--- a/src/libsystemd-network/lldp-network.h
+++ b/src/libsystemd-network/lldp-network.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -18,8 +20,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <systemd/sd-event.h>
int lldp_network_bind_raw_socket(int ifindex);
diff --git a/src/libsystemd-network/lldp-port.c b/src/libsystemd-network/lldp-port.c
deleted file mode 100644
index c86f62a6c2..0000000000
--- a/src/libsystemd-network/lldp-port.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 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 "alloc-util.h"
-#include "async.h"
-#include "lldp-internal.h"
-#include "lldp-network.h"
-#include "lldp-port.h"
-
-int lldp_port_start(lldp_port *p) {
- int r;
-
- assert_return(p, -EINVAL);
-
- r = lldp_network_bind_raw_socket(p->ifindex);
- if (r < 0)
- return r;
-
- p->rawfd = r;
-
- r = sd_event_add_io(p->event, &p->lldp_port_rx,
- p->rawfd, EPOLLIN, lldp_receive_packet, p);
- if (r < 0) {
- log_debug_errno(r, "Failed to allocate event source: %m");
- goto fail;
- }
-
- r = sd_event_source_set_priority(p->lldp_port_rx, p->event_priority);
- if (r < 0) {
- log_debug_errno(r, "Failed to set event priority: %m");
- goto fail;
- }
-
- r = sd_event_source_set_description(p->lldp_port_rx, "lldp-port-rx");
- if (r < 0) {
- log_debug_errno(r, "Failed to set event name: %m");
- goto fail;
- }
-
- return 0;
-
-fail:
- lldp_port_stop(p);
-
- return r;
-}
-
-int lldp_port_stop(lldp_port *p) {
-
- assert_return(p, -EINVAL);
-
- p->rawfd = asynchronous_close(p->rawfd);
- p->lldp_port_rx = sd_event_source_unref(p->lldp_port_rx);
-
- return 0;
-}
-
-void lldp_port_free(lldp_port *p) {
- if (!p)
- return;
-
- lldp_port_stop(p);
-
- free(p->ifname);
- free(p);
-}
-
-int lldp_port_new(int ifindex,
- const char *ifname,
- const struct ether_addr *addr,
- void *userdata,
- lldp_port **ret) {
- _cleanup_free_ lldp_port *p = NULL;
-
- assert_return(ifindex, -EINVAL);
- assert_return(ifname, -EINVAL);
- assert_return(addr, -EINVAL);
-
- p = new0(lldp_port, 1);
- if (!p)
- return -ENOMEM;
-
- p->rawfd = -1;
- p->ifindex = ifindex;
-
- p->ifname = strdup(ifname);
- if (!p->ifname)
- return -ENOMEM;
-
- memcpy(&p->mac, addr, ETH_ALEN);
-
- p->userdata = userdata;
-
- *ret = p;
-
- p = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-port.h b/src/libsystemd-network/lldp-port.h
deleted file mode 100644
index 36e1edc17c..0000000000
--- a/src/libsystemd-network/lldp-port.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 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/>.
-***/
-
-#pragma once
-
-#include <net/ethernet.h>
-
-#include <systemd/sd-event.h>
-#include <systemd/sd-lldp.h>
-
-#include "util.h"
-
-typedef struct lldp_port lldp_port;
-
-typedef enum LLDPPortStatus {
- LLDP_PORT_STATUS_NONE,
- LLDP_PORT_STATUS_ENABLED,
- LLDP_PORT_STATUS_DISABLED,
- _LLDP_PORT_STATUS_MAX,
- _LLDP_PORT_STATUS_INVALID = -1,
-} LLDPPortStatus;
-
-struct lldp_port {
- LLDPPortStatus status;
-
- int ifindex;
- char *ifname;
-
- struct ether_addr mac;
-
- int rawfd;
-
- sd_event *event;
- sd_event_source *lldp_port_rx;
-
- int event_priority;
-
- void *userdata;
-};
-
-int lldp_port_new(int ifindex,
- const char *ifname,
- const struct ether_addr *addr,
- void *userdata,
- lldp_port **ret);
-void lldp_port_free(lldp_port *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_port*, lldp_port_free);
-#define _cleanup_lldp_port_free_ _cleanup_(lldp_port_freep)
-
-int lldp_port_start(lldp_port *p);
-int lldp_port_stop(lldp_port *p);
diff --git a/src/libsystemd-network/lldp-tlv.c b/src/libsystemd-network/lldp-tlv.c
deleted file mode 100644
index 9170b50691..0000000000
--- a/src/libsystemd-network/lldp-tlv.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 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 <arpa/inet.h>
-#include <net/ethernet.h>
-
-#include "alloc-util.h"
-#include "lldp-tlv.h"
-#include "macro.h"
-
-int tlv_section_new(tlv_section **ret) {
- tlv_section *s;
-
- s = new0(tlv_section, 1);
- if (!s)
- return -ENOMEM;
-
- *ret = s;
-
- return 0;
-}
-
-void tlv_section_free(tlv_section *m) {
-
- if (!m)
- return;
-
- free(m);
-}
-
-int tlv_packet_new(tlv_packet **ret) {
- tlv_packet *m;
-
- m = new0(tlv_packet, 1);
- if (!m)
- return -ENOMEM;
-
- LIST_HEAD_INIT(m->sections);
- m->n_ref = 1;
-
- *ret = m;
-
- return 0;
-}
-
-tlv_packet *sd_lldp_packet_ref(tlv_packet *m) {
-
- if (!m)
- return NULL;
-
- assert(m->n_ref > 0);
- m->n_ref++;
-
- return m;
-}
-
-tlv_packet *sd_lldp_packet_unref(tlv_packet *m) {
- tlv_section *s, *n;
-
- if (!m)
- return NULL;
-
- assert(m->n_ref > 0);
- m->n_ref--;
-
- if (m->n_ref > 0)
- return m;
-
- LIST_FOREACH_SAFE(section, s, n, m->sections)
- tlv_section_free(s);
-
- free(m);
- return NULL;
-}
-
-int tlv_packet_append_bytes(tlv_packet *m, const void *data, size_t data_length) {
- uint8_t *p;
-
- assert_return(m, -EINVAL);
- assert_return(data, -EINVAL);
- assert_return(data_length, -EINVAL);
-
- if (m->length + data_length > ETHER_MAX_LEN)
- return -ENOMEM;
-
- p = m->pdu + m->length;
- memcpy(p, data, data_length);
- m->length += data_length;
-
- return 0;
-}
-
-int tlv_packet_append_u8(tlv_packet *m, uint8_t data) {
-
- assert_return(m, -EINVAL);
-
- return tlv_packet_append_bytes(m, &data, sizeof(uint8_t));
-}
-
-int tlv_packet_append_u16(tlv_packet *m, uint16_t data) {
- uint16_t type;
-
- assert_return(m, -EINVAL);
-
- type = htons(data);
-
- return tlv_packet_append_bytes(m, &type, sizeof(uint16_t));
-}
-
-int tlv_packet_append_u32(tlv_packet *m, uint32_t data) {
- uint32_t type;
-
- assert_return(m, -EINVAL);
-
- type = htonl(data);
-
- return tlv_packet_append_bytes(m, &type, sizeof(uint32_t));
-}
-
-int tlv_packet_append_string(tlv_packet *m, char *data, uint16_t size) {
-
- assert_return(m, -EINVAL);
-
- return tlv_packet_append_bytes(m, data, size);
-}
-
-int lldp_tlv_packet_open_container(tlv_packet *m, uint16_t type) {
-
- assert_return(m, -EINVAL);
-
- m->container_pos = m->pdu + m->length;
-
- return tlv_packet_append_u16(m, type << 9);
-}
-
-int lldp_tlv_packet_close_container(tlv_packet *m) {
- uint16_t type;
-
- assert_return(m, -EINVAL);
- assert_return(m->container_pos, -EINVAL);
-
- memcpy(&type, m->container_pos, sizeof(uint16_t));
-
- type |= htons(((m->pdu + m->length) - (m->container_pos + 2)) & 0x01ff);
- memcpy(m->container_pos, &type, sizeof(uint16_t));
-
- return 0;
-}
-
-static inline int tlv_packet_read_internal(tlv_section *m, void **data) {
-
- assert_return(m->read_pos, -EINVAL);
-
- *data = m->read_pos;
-
- return 0;
-}
-
-int tlv_packet_read_u8(tlv_packet *m, uint8_t *data) {
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- memcpy(data, val, sizeof(uint8_t));
-
- m->container->read_pos ++;
-
- return 0;
-}
-
-int tlv_packet_read_u16(tlv_packet *m, uint16_t *data) {
- uint16_t t;
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- memcpy(&t, val, sizeof(uint16_t));
- *data = ntohs(t);
-
- m->container->read_pos += 2;
-
- return 0;
-}
-
-int tlv_packet_read_u32(tlv_packet *m, uint32_t *data) {
- uint32_t t;
- void *val;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- memcpy(&t, val, sizeof(uint32_t));
- *data = ntohl(t);
-
- m->container->read_pos += 4;
-
- return r;
-}
-
-int tlv_packet_read_string(tlv_packet *m, char **data, uint16_t *data_length) {
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- *data = (char *) val;
- *data_length = m->container->data + m->container->length - m->container->read_pos;
-
- m->container->read_pos += *data_length;
-
- return 0;
-}
-
-int tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length) {
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- *data = (uint8_t *) val;
- *data_length = m->container->data + m->container->length - m->container->read_pos;
-
- m->container->read_pos += *data_length;
-
- return 0;
-}
-
-/* parse raw TLV packet */
-int tlv_packet_parse_pdu(tlv_packet *m, uint16_t size) {
- tlv_section *section, *tail;
- uint16_t t, l;
- uint8_t *p;
- int r;
-
- assert_return(m, -EINVAL);
- assert_return(size, -EINVAL);
-
- p = m->pdu;
-
- /* extract Ethernet header */
- memcpy(&m->mac, p, ETH_ALEN);
- p += sizeof(struct ether_header);
-
- for (l = 0; l <= size; ) {
- r = tlv_section_new(&section);
- if (r < 0)
- return r;
-
- memcpy(&t, p, sizeof(uint16_t));
-
- section->type = ntohs(t) >> 9;
- section->length = ntohs(t) & 0x01ff;
-
- if (section->type == LLDP_TYPE_END || section->type >=_LLDP_TYPE_MAX) {
- tlv_section_free(section);
- break;
- }
-
- p += 2;
-
- if (section->type == LLDP_TYPE_PRIVATE &&
- section->length >= LLDP_OUI_LEN + 1) {
- section->oui = p;
- p += LLDP_OUI_LEN;
- section->subtype = *p++;
-
- section->length -= LLDP_OUI_LEN + 1;
- l += LLDP_OUI_LEN + 1;
- }
-
- section->data = p;
-
- LIST_FIND_TAIL(section, m->sections, tail);
- LIST_INSERT_AFTER(section, m->sections, tail, section);
-
- p += section->length;
- l += (section->length + 2);
- }
-
- return 0;
-}
-
-int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type) {
- tlv_section *s;
-
- assert_return(m, -EINVAL);
- assert_return(type != LLDP_TYPE_PRIVATE, -EINVAL);
-
- LIST_FOREACH(section, s, m->sections)
- if (s->type == type)
- break;
- if (!s)
- return -1;
-
- m->container = s;
-
- m->container->read_pos = s->data;
- if (!m->container->read_pos) {
- m->container = NULL;
- return -1;
- }
-
- return 0;
-}
-
-int lldp_tlv_packet_enter_container_oui(tlv_packet *m, const uint8_t *oui, uint8_t subtype) {
- tlv_section *s;
-
- assert_return(m, -EINVAL);
- assert_return(oui, -EINVAL);
-
- LIST_FOREACH(section, s, m->sections) {
- if (s->type == LLDP_TYPE_PRIVATE &&
- s->oui &&
- s->subtype == subtype &&
- !memcmp(s->oui, oui, LLDP_OUI_LEN))
- break;
- }
-
- if (!s)
- return -1;
-
- m->container = s;
-
- m->container->read_pos = s->data;
- if (!m->container->read_pos) {
- m->container = NULL;
- return -1;
- }
-
- return 0;
-}
-
-int lldp_tlv_packet_exit_container(tlv_packet *m) {
- assert_return(m, -EINVAL);
-
- m->container = 0;
-
- return 0;
-}
-
-static int lldp_tlv_packet_read_u16_tlv(tlv_packet *tlv, uint16_t type, uint16_t *value) {
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, type);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u16(tlv, value);
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-static int lldp_tlv_packet_read_string_tlv(tlv_packet *tlv, uint16_t type, char **data, uint16_t *length) {
- char *s;
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, type);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_string(tlv, &s, length);
- if (r < 0)
- goto out;
-
- *data = (char *) s;
-
- out:
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_chassis_id(tlv_packet *tlv,
- uint8_t *type,
- uint8_t **data,
- uint16_t *length) {
- uint8_t subtype;
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_CHASSIS_ID);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u8(tlv, &subtype);
- if (r < 0)
- goto out;
-
- switch (subtype) {
- case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
-
- r = tlv_packet_read_bytes(tlv, data, length);
- if (r < 0)
- goto out;
-
- break;
- default:
- r = -EOPNOTSUPP;
- break;
- }
-
- *type = subtype;
-
- out:
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_port_id(tlv_packet *tlv,
- uint8_t *type,
- uint8_t **data,
- uint16_t *length) {
- uint8_t subtype;
- char *s;
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_ID);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u8(tlv, &subtype);
- if (r < 0)
- goto out;
-
- switch (subtype) {
- case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
- case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
- case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
- case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
-
- r = tlv_packet_read_string(tlv, &s, length);
- if (r < 0)
- goto out;
-
- *data = (uint8_t *) s;
-
- break;
- case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
-
- r = tlv_packet_read_bytes(tlv, data, length);
- if (r < 0)
- goto out;
-
- break;
- default:
- r = -EOPNOTSUPP;
- break;
- }
-
- *type = subtype;
-
- out:
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_ttl(tlv_packet *tlv, uint16_t *ttl) {
- return lldp_tlv_packet_read_u16_tlv(tlv, LLDP_TYPE_TTL, ttl);
-}
-
-int sd_lldp_packet_read_system_name(tlv_packet *tlv,
- char **data,
- uint16_t *length) {
- return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_SYSTEM_NAME, data, length);
-}
-
-int sd_lldp_packet_read_system_description(tlv_packet *tlv,
- char **data,
- uint16_t *length) {
- return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_SYSTEM_DESCRIPTION, data, length);
-}
-
-int sd_lldp_packet_read_port_description(tlv_packet *tlv,
- char **data,
- uint16_t *length) {
- return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_PORT_DESCRIPTION, data, length);
-}
-
-int sd_lldp_packet_read_system_capability(tlv_packet *tlv, uint16_t *data) {
- return lldp_tlv_packet_read_u16_tlv(tlv, LLDP_TYPE_SYSTEM_CAPABILITIES, data);
-}
-
-int sd_lldp_packet_read_port_vlan_id(tlv_packet *tlv, uint16_t *id) {
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_PORT_VLAN_ID);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u16(tlv, id);
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_port_protocol_vlan_id(sd_lldp_packet *tlv, uint8_t *flags, uint16_t *id) {
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_PORT_PROTOCOL_VLAN_ID);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u8(tlv, flags);
- if (r >= 0)
- r = tlv_packet_read_u16(tlv, id);
-
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_vlan_name(tlv_packet *tlv, uint16_t *vlan_id, char **name, uint16_t *length) {
- int r, r2;
- uint8_t len = 0;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_VLAN_NAME);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u16(tlv, vlan_id);
- if (r >= 0)
- r = tlv_packet_read_u8(tlv, &len);
- if (r >= 0)
- r = tlv_packet_read_string(tlv, name, length);
-
- if (r >= 0 && len < *length)
- *length = len;
-
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_management_vid(tlv_packet *tlv, uint16_t *id) {
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_MANAGEMENT_VID);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u16(tlv, id);
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_read_link_aggregation(sd_lldp_packet *tlv, uint8_t *status, uint32_t *id) {
- int r, r2;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_LINK_AGGREGATION);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u8(tlv, status);
- if (r >= 0)
- r = tlv_packet_read_u32(tlv, id);
-
- r2 = lldp_tlv_packet_exit_container(tlv);
-
- return r < 0 ? r : r2;
-}
-
-int sd_lldp_packet_get_destination_type(tlv_packet *tlv, int *dest) {
- assert_return(tlv, -EINVAL);
- assert_return(dest, -EINVAL);
-
- /* 802.1AB-2009, Table 7-1 */
- if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_BRIDGE, ETH_ALEN))
- *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE;
- else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_NON_TPMR_BRIDGE, ETH_ALEN))
- *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE;
- else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_CUSTOMER_BRIDGE, ETH_ALEN))
- *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE;
- else
- return -EINVAL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-tlv.h b/src/libsystemd-network/lldp-tlv.h
deleted file mode 100644
index 4362b2ace6..0000000000
--- a/src/libsystemd-network/lldp-tlv.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 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/>.
-***/
-
-#pragma once
-
-#include <net/ethernet.h>
-
-#include <systemd/sd-lldp.h>
-
-#include "list.h"
-#include "lldp.h"
-#include "util.h"
-
-typedef struct sd_lldp_packet tlv_packet;
-typedef struct sd_lldp_section tlv_section;
-
-#define LLDP_OUI_LEN 3
-
-struct sd_lldp_section {
- uint16_t type;
- uint16_t length;
- uint8_t *oui;
- uint8_t subtype;
-
- uint8_t *read_pos;
- uint8_t *data;
-
- LIST_FIELDS(tlv_section, section);
-};
-
-#define LLDP_MAC_NEAREST_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
-#define LLDP_MAC_NEAREST_NON_TPMR_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }
-#define LLDP_MAC_NEAREST_CUSTOMER_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }
-
-int tlv_section_new(tlv_section **ret);
-void tlv_section_free(tlv_section *ret);
-
-struct sd_lldp_packet {
- unsigned n_ref;
-
- uint16_t type;
- uint16_t length;
- usec_t ts;
-
- uint8_t *container_pos;
- uint8_t pdu[ETHER_MAX_LEN];
-
- void *userdata;
-
- struct ether_addr mac;
- tlv_section *container;
-
- LIST_HEAD(tlv_section, sections);
-};
-
-int tlv_packet_new(tlv_packet **ret);
-
-int lldp_tlv_packet_open_container(tlv_packet *m, uint16_t type);
-int lldp_tlv_packet_close_container(tlv_packet *m);
-
-int tlv_packet_append_bytes(tlv_packet *m, const void *data, size_t data_length);
-int tlv_packet_append_u8(tlv_packet *m, uint8_t data);
-int tlv_packet_append_u16(tlv_packet *m, uint16_t data);
-int tlv_packet_append_u32(tlv_packet *m, uint32_t data);
-int tlv_packet_append_string(tlv_packet *m, char *data, uint16_t size);
-
-int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type);
-int lldp_tlv_packet_enter_container_oui(tlv_packet *m, const uint8_t *oui, uint8_t subtype);
-int lldp_tlv_packet_exit_container(tlv_packet *m);
-
-int tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length);
-int tlv_packet_read_string(tlv_packet *m, char **data, uint16_t *data_length);
-int tlv_packet_read_u8(tlv_packet *m, uint8_t *data);
-int tlv_packet_read_u16(tlv_packet *m, uint16_t *data);
-int tlv_packet_read_u32(tlv_packet *m, uint32_t *data);
-
-int tlv_packet_parse_pdu(tlv_packet *t, uint16_t size);
diff --git a/src/libsystemd-network/lldp.h b/src/libsystemd-network/lldp.h
deleted file mode 100644
index d2c7164633..0000000000
--- a/src/libsystemd-network/lldp.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 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/>.
-***/
-
-#pragma once
-
-#define LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
-
-#define ETHERTYPE_LLDP 0x88cc
-
-/* IEEE 802.3AB Clause 9: TLV Types */
-typedef enum LLDPTypes {
- LLDP_TYPE_END = 0,
- LLDP_TYPE_CHASSIS_ID = 1,
- LLDP_TYPE_PORT_ID = 2,
- LLDP_TYPE_TTL = 3,
- LLDP_TYPE_PORT_DESCRIPTION = 4,
- LLDP_TYPE_SYSTEM_NAME = 5,
- LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
- LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
- LLDP_TYPE_MGMT_ADDRESS = 8,
- LLDP_TYPE_PRIVATE = 127,
- _LLDP_TYPE_MAX,
- _LLDP_TYPE_INVALID = -1,
-} LLDPTypes;
-
-/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
-typedef enum LLDPChassisSubtypes {
- LLDP_CHASSIS_SUBTYPE_RESERVED = 0,
- LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1,
- LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2,
- LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3,
- LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4,
- LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5,
- LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6,
- LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7,
- _LLDP_CHASSIS_SUBTYPE_MAX,
- _LLDP_CHASSIS_SUBTYPE_INVALID = -1,
-} LLDPChassisSubtypes;
-
-/* IEEE 802.3AB Clause 9.5.3: Port subtype */
-typedef enum LLDPPortSubtypes {
- LLDP_PORT_SUBTYPE_RESERVED = 0,
- LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
- LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
- LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
- LLDP_PORT_SUBTYPE_NETWORK = 4,
- LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
- LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
- LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
- _LLDP_PORT_SUBTYPE_MAX,
- _LLDP_PORT_SUBTYPE_INVALID = -1
-} LLDPPortSubtypes;
-
-typedef enum LLDPSystemCapabilities {
- LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
- LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
- LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
- LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
- LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
- LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
- LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
- LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
- LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
- LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
- LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10,
- _LLDP_SYSTEM_CAPABILITIES_MAX,
- _LLDP_SYSTEM_CAPABILITIES_INVALID = -1,
-} LLDPSystemCapabilities;
-
-typedef enum LLDPMedSubtype {
- LLDP_MED_SUBTYPE_RESERVED = 0,
- LLDP_MED_SUBTYPE_CAPABILITIES = 1,
- LLDP_MED_SUBTYPE_NETWORK_POLICY = 2,
- LLDP_MED_SUBTYPE_LOCATION_ID = 3,
- LLDP_MED_SUBTYPE_EXTENDED_PVMDI = 4,
- LLDP_MED_SUBTYPE_INV_HWREV = 5,
- LLDP_MED_SUBTYPE_INV_FWREV = 6,
- LLDP_MED_SUBTYPE_INV_SWREV = 7,
- LLDP_MED_SUBTYPE_INV_SERIAL = 8,
- LLDP_MED_SUBTYPE_INV_MANUFACTURER = 9,
- LLDP_MED_SUBTYPE_INV_MODELNAME = 10,
- LLDP_MED_SUBTYPE_INV_ASSETID = 11,
- _LLDP_MED_SUBTYPE_MAX,
- _LLDP_MED_SUBTYPE_INVALID = -1,
-} LLDPMedSubtype;
-
-typedef enum LLDPMedCapability {
- LLDP_MED_CAPABILITY_CAPAPILITIES = 1 << 0,
- LLDP_MED_CAPABILITY_NETWORK_POLICY = 1 << 1,
- LLDP_MED_CAPABILITY_LOCATION_ID = 1 << 2,
- LLDP_MED_CAPABILITY_EXTENDED_PSE = 1 << 3,
- LLDP_MED_CAPABILITY_EXTENDED_PD = 1 << 4,
- LLDP_MED_CAPABILITY_INVENTORY = 1 << 5,
- LLDP_MED_CAPABILITY_MAX,
- LLDP_MED_CAPABILITY_INVALID = -1,
-} LLDPMedCapability;
-
-#define LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 }
-#define LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f }
-
-enum {
- LLDP_OUI_SUBTYPE_802_1_PORT_VLAN_ID = 1,
- LLDP_OUI_SUBTYPE_802_1_PORT_PROTOCOL_VLAN_ID = 2,
- LLDP_OUI_SUBTYPE_802_1_VLAN_NAME = 3,
- LLDP_OUI_SUBTYPE_802_1_PROTOCOL_IDENTITY = 4,
- LLDP_OUI_SUBTYPE_802_1_VID_USAGE_DIGEST = 5,
- LLDP_OUI_SUBTYPE_802_1_MANAGEMENT_VID = 6,
- LLDP_OUI_SUBTYPE_802_1_LINK_AGGREGATION = 7,
-};
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 35860cf11a..d57baf8fff 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -27,11 +27,13 @@
#include "condition.h"
#include "conf-parser.h"
#include "dhcp-lease-internal.h"
+#include "ether-addr-util.c"
#include "hexdecoct.h"
#include "log.h"
#include "network-internal.h"
#include "parse-util.h"
#include "siphash24.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "utf8.h"
@@ -175,58 +177,19 @@ int config_parse_net_condition(const char *unit,
return 0;
}
-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) {
-
- char **s = data;
- _cleanup_free_ char *n = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = strdup(rvalue);
- if (!n)
- return log_oom();
-
- if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- return 0;
- }
-
- free(*s);
- if (*n) {
- *s = n;
- n = NULL;
- } else
- *s = NULL;
-
- return 0;
-}
-
-int config_parse_ifnames(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_ifnames(
+ 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) {
char ***sv = data;
- const char *word, *state;
- size_t l;
int r;
assert(filename);
@@ -234,22 +197,27 @@ int config_parse_ifnames(const char *unit,
assert(rvalue);
assert(data);
- FOREACH_WORD(word, l, rvalue, state) {
- char *n;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
- n = strndup(word, l);
- if (!n)
- return log_oom();
+ r = extract_first_word(&rvalue, &word, NULL, 0);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse interface name list: %s", rvalue);
+ return 0;
+ }
+ if (r == 0)
+ break;
- if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- free(n);
+ if (!ifname_valid(word)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
return 0;
}
- r = strv_consume(sv, n);
+ r = strv_push(sv, word);
if (r < 0)
return log_oom();
+
+ word = NULL;
}
return 0;
@@ -305,6 +273,8 @@ int config_parse_hwaddr(const char *unit,
void *userdata) {
struct ether_addr **hwaddr = data;
struct ether_addr *n;
+ const char *start;
+ size_t offset;
int r;
assert(filename);
@@ -316,14 +286,10 @@ int config_parse_hwaddr(const char *unit,
if (!n)
return log_oom();
- r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- &n->ether_addr_octet[0],
- &n->ether_addr_octet[1],
- &n->ether_addr_octet[2],
- &n->ether_addr_octet[3],
- &n->ether_addr_octet[4],
- &n->ether_addr_octet[5]);
- if (r != 6) {
+ start = rvalue + strspn(rvalue, WHITESPACE);
+ r = ether_addr_from_string(start, n, &offset);
+
+ if (r || (start[offset + strspn(start + offset, WHITESPACE)] != '\0')) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue);
free(n);
return 0;
@@ -335,6 +301,36 @@ int config_parse_hwaddr(const char *unit,
return 0;
}
+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) {
+ uint32_t iaid;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou32(rvalue, &iaid);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Unable to read IAID, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ *((uint32_t *)data) = iaid;
+
+ return 0;
+}
+
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
unsigned i;
@@ -350,32 +346,32 @@ void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
int deserialize_in_addrs(struct in_addr **ret, const char *string) {
_cleanup_free_ struct in_addr *addresses = NULL;
int size = 0;
- const char *word, *state;
- size_t len;
assert(ret);
assert(string);
- FOREACH_WORD(word, len, string, state) {
- _cleanup_free_ char *addr_str = NULL;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
struct in_addr *new_addresses;
int r;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
new_addresses = realloc(addresses, (size + 1) * sizeof(struct in_addr));
if (!new_addresses)
return -ENOMEM;
else
addresses = new_addresses;
- addr_str = strndup(word, len);
- if (!addr_str)
- return -ENOMEM;
-
- r = inet_pton(AF_INET, addr_str, &(addresses[size]));
+ r = inet_pton(AF_INET, word, &(addresses[size]));
if (r <= 0)
continue;
- size ++;
+ size++;
}
*ret = addresses;
@@ -401,28 +397,28 @@ void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
_cleanup_free_ struct in6_addr *addresses = NULL;
int size = 0;
- const char *word, *state;
- size_t len;
assert(ret);
assert(string);
- FOREACH_WORD(word, len, string, state) {
- _cleanup_free_ char *addr_str = NULL;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
struct in6_addr *new_addresses;
int r;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
new_addresses = realloc(addresses, (size + 1) * sizeof(struct in6_addr));
if (!new_addresses)
return -ENOMEM;
else
addresses = new_addresses;
- addr_str = strndup(word, len);
- if (!addr_str)
- return -ENOMEM;
-
- r = inet_pton(AF_INET6, addr_str, &(addresses[size]));
+ r = inet_pton(AF_INET6, word, &(addresses[size]));
if (r <= 0)
continue;
@@ -463,29 +459,29 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
_cleanup_free_ struct sd_dhcp_route *routes = NULL;
size_t size = 0, allocated = 0;
- const char *word, *state;
- size_t len;
assert(ret);
assert(ret_size);
assert(ret_allocated);
assert(string);
- FOREACH_WORD(word, len, string, state) {
- /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
- _cleanup_free_ char* entry = NULL;
+ /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
char *tok, *tok_end;
unsigned n;
int r;
- if (!GREEDY_REALLOC(routes, allocated, size + 1))
- return -ENOMEM;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
- entry = strndup(word, len);
- if(!entry)
+ if (!GREEDY_REALLOC(routes, allocated, size + 1))
return -ENOMEM;
- tok = entry;
+ tok = word;
/* get the subnet */
tok_end = strchr(tok, '/');
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 2549d1420e..1cafb0747f 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -50,10 +50,6 @@ int config_parse_hwaddr(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_ifnames(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);
@@ -62,6 +58,10 @@ int config_parse_ifalias(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_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 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/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index bd5ec76fc5..193f31880f 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -82,7 +82,7 @@ struct sd_dhcp_client {
} _packed_ ll;
struct {
/* 255: Node-specific (RFC 4361) */
- uint32_t iaid;
+ be32_t iaid;
struct duid duid;
} _packed_ ns;
struct {
@@ -101,7 +101,7 @@ struct sd_dhcp_client {
sd_event_source *timeout_t1;
sd_event_source *timeout_t2;
sd_event_source *timeout_expire;
- sd_dhcp_client_cb_t cb;
+ sd_dhcp_client_callback_t cb;
void *userdata;
sd_dhcp_lease *lease;
usec_t start_delay;
@@ -115,14 +115,22 @@ static const uint8_t default_req_opts[] = {
SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
};
-static int client_receive_message_raw(sd_event_source *s, int fd,
- uint32_t revents, void *userdata);
-static int client_receive_message_udp(sd_event_source *s, int fd,
- uint32_t revents, void *userdata);
+static int client_receive_message_raw(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata);
+static int client_receive_message_udp(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata);
static void client_stop(sd_dhcp_client *client, int error);
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
- void *userdata) {
+int sd_dhcp_client_set_callback(
+ sd_dhcp_client *client,
+ sd_dhcp_client_callback_t cb,
+ void *userdata) {
assert_return(client, -EINVAL);
client->cb = cb;
@@ -171,8 +179,9 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
return 0;
}
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
- const struct in_addr *last_addr) {
+int sd_dhcp_client_set_request_address(
+ sd_dhcp_client *client,
+ const struct in_addr *last_addr) {
assert_return(client, -EINVAL);
assert_return (IN_SET(client->state, DHCP_STATE_INIT,
DHCP_STATE_STOPPED), -EBUSY);
@@ -196,8 +205,12 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
return 0;
}
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type) {
+int sd_dhcp_client_set_mac(
+ sd_dhcp_client *client,
+ const uint8_t *addr,
+ size_t addr_len,
+ uint16_t arp_type) {
+
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
@@ -234,8 +247,11 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
return 0;
}
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
- const uint8_t **data, size_t *data_len) {
+int sd_dhcp_client_get_client_id(
+ sd_dhcp_client *client,
+ uint8_t *type,
+ const uint8_t **data,
+ size_t *data_len) {
assert_return(client, -EINVAL);
assert_return(type, -EINVAL);
@@ -254,8 +270,12 @@ int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
return 0;
}
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
- const uint8_t *data, size_t data_len) {
+int sd_dhcp_client_set_client_id(
+ sd_dhcp_client *client,
+ uint8_t type,
+ const uint8_t *data,
+ size_t data_len) {
+
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
@@ -298,8 +318,71 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
return 0;
}
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
- const char *hostname) {
+/**
+ * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
+ * without further modification. Otherwise, if duid_type is supported, DUID
+ * is set based on that type. Otherwise, an error is returned.
+ */
+int sd_dhcp_client_set_iaid_duid(
+ sd_dhcp_client *client,
+ uint32_t iaid,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len) {
+
+ DHCP_CLIENT_DONT_DESTROY(client);
+ int r;
+ size_t len;
+
+ assert_return(client, -EINVAL);
+ assert_return(duid_len == 0 || duid != NULL, -EINVAL);
+
+ if (duid != NULL) {
+ r = dhcp_validate_duid_len(duid_type, duid_len);
+ if (r < 0)
+ return r;
+ }
+
+ zero(client->client_id);
+ client->client_id.type = 255;
+
+ /* If IAID is not configured, generate it. */
+ if (iaid == 0) {
+ r = dhcp_identifier_set_iaid(client->index, client->mac_addr,
+ client->mac_addr_len,
+ &client->client_id.ns.iaid);
+ if (r < 0)
+ return r;
+ } else
+ client->client_id.ns.iaid = htobe32(iaid);
+
+ if (duid != NULL) {
+ client->client_id.ns.duid.type = htobe16(duid_type);
+ memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
+ len = sizeof(client->client_id.ns.duid.type) + duid_len;
+ } else if (duid_type == DUID_TYPE_EN) {
+ r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
+ if (r < 0)
+ return r;
+ } else
+ return -EOPNOTSUPP;
+
+ client->client_id_len = sizeof(client->client_id.type) + len +
+ sizeof(client->client_id.ns.iaid);
+
+ if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
+ log_dhcp_client(client, "Configured IAID+DUID, restarting.");
+ client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
+ sd_dhcp_client_start(client);
+ }
+
+ return 0;
+}
+
+int sd_dhcp_client_set_hostname(
+ sd_dhcp_client *client,
+ const char *hostname) {
+
char *new_hostname = NULL;
assert_return(client, -EINVAL);
@@ -322,8 +405,10 @@ int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
return 0;
}
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
- const char *vci) {
+int sd_dhcp_client_set_vendor_class_identifier(
+ sd_dhcp_client *client,
+ const char *vci) {
+
char *new_vci = NULL;
assert_return(client, -EINVAL);
@@ -406,9 +491,14 @@ static void client_stop(sd_dhcp_client *client, int error) {
client_initialize(client);
}
-static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
- uint8_t type, size_t *_optlen, size_t *_optoffset) {
- _cleanup_free_ DHCPPacket *packet;
+static int client_message_init(
+ sd_dhcp_client *client,
+ DHCPPacket **ret,
+ uint8_t type,
+ size_t *_optlen,
+ size_t *_optoffset) {
+
+ _cleanup_free_ DHCPPacket *packet = NULL;
size_t optlen, optoffset, size;
be16_t max_size;
usec_t time_now;
@@ -548,8 +638,12 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
return 0;
}
-static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t *optoffset,
- const char *fqdn) {
+static int client_append_fqdn_option(
+ DHCPMessage *message,
+ size_t optlen,
+ size_t *optoffset,
+ const char *fqdn) {
+
uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
int r;
@@ -566,8 +660,11 @@ static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t
return r;
}
-static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
- size_t len) {
+static int dhcp_client_send_raw(
+ sd_dhcp_client *client,
+ DHCPPacket *packet,
+ size_t len) {
+
dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
INADDR_BROADCAST, DHCP_PORT_SERVER, len);
@@ -774,8 +871,11 @@ static int client_send_request(sd_dhcp_client *client) {
static int client_start(sd_dhcp_client *client);
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_resend(
+ sd_event_source *s,
+ uint64_t usec,
+ void *userdata) {
+
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
usec_t next_timeout = 0;
@@ -919,8 +1019,10 @@ error:
return 0;
}
-static int client_initialize_io_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback) {
+static int client_initialize_io_events(
+ sd_dhcp_client *client,
+ sd_event_io_handler_t io_callback) {
+
int r;
assert(client);
@@ -958,7 +1060,7 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
if (client->start_delay) {
- sd_event_now(client->event, clock_boottime_or_monotonic(), &usec);
+ assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
usec += client->start_delay;
}
@@ -987,8 +1089,7 @@ error:
}
-static int client_initialize_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback) {
+static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
client_initialize_io_events(client, io_callback);
client_initialize_time_events(client);
@@ -1028,8 +1129,7 @@ static int client_start(sd_dhcp_client *client) {
return client_start_delayed(client);
}
-static int client_timeout_expire(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
@@ -1069,8 +1169,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
return client_initialize_events(client, client_receive_message_raw);
}
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
@@ -1080,8 +1179,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
return client_initialize_time_events(client);
}
-static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
- size_t len) {
+static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
int r;
@@ -1132,8 +1230,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
return 0;
}
-static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
- size_t len) {
+static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
int r;
r = dhcp_option_parse(force, len, NULL, NULL, NULL);
@@ -1145,8 +1242,7 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
return 0;
}
-static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
- size_t len) {
+static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
_cleanup_free_ char *error_message = NULL;
int r;
@@ -1374,8 +1470,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
return 0;
}
-static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
- int len) {
+static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
DHCP_CLIENT_DONT_DESTROY(client);
char time_string[FORMAT_TIMESPAN_MAX];
int r = 0, notify_event = 0;
@@ -1521,8 +1616,12 @@ error:
return r;
}
-static int client_receive_message_udp(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
+static int client_receive_message_udp(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata) {
+
sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPMessage *message = NULL;
const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
@@ -1541,7 +1640,7 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
if (!message)
return -ENOMEM;
- len = read(fd, message, buflen);
+ len = recv(fd, message, buflen, 0);
if (len < 0) {
if (errno == EAGAIN || errno == EINTR)
return 0;
@@ -1599,8 +1698,12 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
return client_handle_message(client, message, len);
}
-static int client_receive_message_raw(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
+static int client_receive_message_raw(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata) {
+
sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPPacket *packet = NULL;
uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
@@ -1691,8 +1794,7 @@ int sd_dhcp_client_stop(sd_dhcp_client *client) {
return 0;
}
-int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
- int priority) {
+int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
int r;
assert_return(client, -EINVAL);
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index d8d6f446ee..d4c680d485 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -825,7 +825,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len);
if (r >= 0) {
- _cleanup_free_ char *client_id_hex;
+ _cleanup_free_ char *client_id_hex = NULL;
client_id_hex = hexmem(client_id, client_id_len);
if (!client_id_hex) {
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index e11462e6ac..5e8b4e4823 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -208,8 +208,7 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
return 0;
}
-int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event,
- int priority) {
+int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event, int64_t priority) {
int r;
assert_return(server, -EINVAL);
@@ -281,10 +280,11 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
}
static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
+ uint16_t destination_port,
DHCPMessage *message, size_t len) {
union sockaddr_union dest = {
.in.sin_family = AF_INET,
- .in.sin_port = htobe16(DHCP_PORT_CLIENT),
+ .in.sin_port = htobe16(destination_port),
.in.sin_addr.s_addr = destination,
};
struct iovec iov = {
@@ -343,6 +343,7 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
DHCPRequest *req, DHCPPacket *packet,
int type, size_t optoffset) {
be32_t destination = INADDR_ANY;
+ uint16_t destination_port = DHCP_PORT_CLIENT;
int r;
assert(server);
@@ -387,17 +388,19 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
*/
if (req->message->giaddr) {
destination = req->message->giaddr;
+ destination_port = DHCP_PORT_SERVER;
if (type == DHCP_NAK)
packet->dhcp.flags = htobe16(0x8000);
} else if (req->message->ciaddr && type != DHCP_NAK)
destination = req->message->ciaddr;
if (destination != INADDR_ANY)
- return dhcp_server_send_udp(server, destination, &packet->dhcp,
+ return dhcp_server_send_udp(server, destination,
+ destination_port, &packet->dhcp,
sizeof(DHCPMessage) + optoffset);
else if (requested_broadcast(req) || type == DHCP_NAK)
return dhcp_server_send_udp(server, INADDR_BROADCAST,
- &packet->dhcp,
+ destination_port, &packet->dhcp,
sizeof(DHCPMessage) + optoffset);
else
/* we cannot send UDP packet to specific MAC address when the
@@ -465,10 +468,12 @@ static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
if (r < 0)
return r;
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- SD_DHCP_OPTION_ROUTER, 4, &server->address);
- if (r < 0)
- return r;
+ if (server->emit_router) {
+ r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+ SD_DHCP_OPTION_ROUTER, 4, &server->address);
+ if (r < 0)
+ return r;
+ }
r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset);
if (r < 0)
@@ -502,10 +507,12 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
if (r < 0)
return r;
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- SD_DHCP_OPTION_ROUTER, 4, &server->address);
- if (r < 0)
- return r;
+ if (server->emit_router) {
+ r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+ SD_DHCP_OPTION_ROUTER, 4, &server->address);
+ if (r < 0)
+ return r;
+ }
if (server->n_dns > 0) {
r = dhcp_option_append(
@@ -580,7 +587,8 @@ static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
memcpy(&packet->dhcp.chaddr, chaddr, ETH_ALEN);
- r = dhcp_server_send_udp(server, address, &packet->dhcp,
+ r = dhcp_server_send_udp(server, address, DHCP_PORT_CLIENT,
+ &packet->dhcp,
sizeof(DHCPMessage) + optoffset);
if (r < 0)
return r;
@@ -1154,3 +1162,14 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u
return 1;
}
+
+int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
+ assert_return(server, -EINVAL);
+
+ if (enabled == server->emit_router)
+ return 0;
+
+ server->emit_router = enabled;
+
+ return 1;
+}
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 494036cb54..2760b039ba 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -64,7 +64,7 @@ struct sd_dhcp6_client {
uint8_t retransmit_count;
sd_event_source *timeout_resend;
sd_event_source *timeout_resend_expire;
- sd_dhcp6_client_cb_t cb;
+ sd_dhcp6_client_callback_t cb;
void *userdata;
struct duid duid;
size_t duid_len;
@@ -111,7 +111,10 @@ DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_cb_t cb, void *userdata) {
+int sd_dhcp6_client_set_callback(
+ sd_dhcp6_client *client,
+ sd_dhcp6_client_callback_t cb,
+ void *userdata) {
assert_return(client, -EINVAL);
client->cb = cb;
@@ -131,7 +134,10 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
return 0;
}
-int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address) {
+int sd_dhcp6_client_set_local_address(
+ sd_dhcp6_client *client,
+ const struct in6_addr *local_address) {
+
assert_return(client, -EINVAL);
assert_return(local_address, -EINVAL);
assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) local_address) > 0, -EINVAL);
@@ -180,41 +186,47 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
}
+/**
+ * Sets DUID. If duid is non-null, the DUID is set to duid_type + duid
+ * without further modification. Otherwise, if duid_type is supported, DUID
+ * is set based on that type. Otherwise, an error is returned.
+ */
int sd_dhcp6_client_set_duid(
sd_dhcp6_client *client,
- uint16_t type,
- uint8_t *duid, size_t duid_len) {
- assert_return(client, -EINVAL);
- assert_return(duid, -EINVAL);
- assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len) {
+ int r;
+ assert_return(client, -EINVAL);
+ assert_return(duid_len == 0 || duid != NULL, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
- switch (type) {
- case DHCP6_DUID_LLT:
- if (duid_len <= sizeof(client->duid.llt))
- return -EINVAL;
- break;
- case DHCP6_DUID_EN:
- if (duid_len != sizeof(client->duid.en))
- return -EINVAL;
- break;
- case DHCP6_DUID_LL:
- if (duid_len <= sizeof(client->duid.ll))
- return -EINVAL;
- break;
- case DHCP6_DUID_UUID:
- if (duid_len != sizeof(client->duid.uuid))
- return -EINVAL;
- break;
- default:
- /* accept unknown type in order to be forward compatible */
- break;
+ if (duid != NULL) {
+ r = dhcp_validate_duid_len(duid_type, duid_len);
+ if (r < 0)
+ return r;
}
- client->duid.type = htobe16(type);
- memcpy(&client->duid.raw.data, duid, duid_len);
- client->duid_len = duid_len + sizeof(client->duid.type);
+ if (duid != NULL) {
+ client->duid.type = htobe16(duid_type);
+ memcpy(&client->duid.raw.data, duid, duid_len);
+ client->duid_len = sizeof(client->duid.type) + duid_len;
+ } else if (duid_type == DUID_TYPE_EN) {
+ r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
+ if (r < 0)
+ return r;
+ } else
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
+ assert_return(client, -EINVAL);
+ assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
+ client->ia_na.id = htobe32(iaid);
return 0;
}
@@ -439,8 +451,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return 0;
}
-static int client_timeout_t2(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp6_client *client = userdata;
assert_return(s, -EINVAL);
@@ -457,8 +468,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec,
return 0;
}
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp6_client *client = userdata;
assert_return(s, -EINVAL);
@@ -475,8 +485,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
return 0;
}
-static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp6_client *client = userdata;
DHCP6_CLIENT_DONT_DESTROY(client);
enum DHCP6State state;
@@ -502,8 +511,7 @@ static usec_t client_timeout_compute_random(usec_t val) {
(random_u32() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
}
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) {
int r = 0;
sd_dhcp6_client *client = userdata;
usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
@@ -670,9 +678,11 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
return 0;
}
-static int client_parse_message(sd_dhcp6_client *client,
- DHCP6Message *message, size_t len,
- sd_dhcp6_lease *lease) {
+static int client_parse_message(
+ sd_dhcp6_client *client,
+ DHCP6Message *message,
+ size_t len,
+ sd_dhcp6_lease *lease) {
int r;
uint8_t *optval, *option, *id = NULL;
uint16_t optcode, status;
@@ -907,14 +917,13 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
if (!message)
return -ENOMEM;
- len = read(fd, message, buflen);
+ len = recv(fd, message, buflen, 0);
if (len < 0) {
if (errno == EAGAIN || errno == EINTR)
return 0;
- log_dhcp6_client(client, "Could not receive message from UDP socket: %m");
+ return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m");
- return -errno;
} else if ((size_t)len < sizeof(DHCP6Message))
return 0;
@@ -937,8 +946,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
break;
default:
- log_dhcp6_client(client, "unknown message type %d",
- message->type);
+ log_dhcp6_client(client, "Unknown message type %d", message->type);
return 0;
}
@@ -997,10 +1005,9 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
return 0;
}
- if (r >= 0) {
+ if (r >= 0)
log_dhcp6_client(client, "Recv %s",
dhcp6_message_type_to_string(message->type));
- }
return 0;
}
@@ -1053,7 +1060,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
if (client->lease->ia.lifetime_t1 == 0xffffffff ||
client->lease->ia.lifetime_t2 == 0xffffffff) {
- log_dhcp6_client(client, "infinite T1 0x%08x or T2 0x%08x",
+ log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x",
be32toh(client->lease->ia.lifetime_t1),
be32toh(client->lease->ia.lifetime_t2));
@@ -1169,8 +1176,13 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
return r;
r = dhcp6_network_bind_udp_socket(client->index, &client->local_address);
- if (r < 0)
- return r;
+ if (r < 0) {
+ _cleanup_free_ char *p = NULL;
+
+ (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p);
+ return log_dhcp6_client_errno(client, r,
+ "Failed to bind to UDP socket at address %s: %m", strna(p));
+ }
client->fd = r;
@@ -1186,7 +1198,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
goto error;
r = sd_event_source_set_description(client->receive_message,
- "dhcp6-receive-message");
+ "dhcp6-receive-message");
if (r < 0)
goto error;
@@ -1194,8 +1206,8 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
state = DHCP6_STATE_INFORMATION_REQUEST;
log_dhcp6_client(client, "Started in %s mode",
- client->information_request? "Information request":
- "Managed");
+ client->information_request? "Information request":
+ "Managed");
return client_start(client, state);
@@ -1204,7 +1216,7 @@ error:
return r;
}
-int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int priority) {
+int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority) {
int r;
assert_return(client, -EINVAL);
diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c
index f97fc0bf47..f1ed7ca747 100644
--- a/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/libsystemd-network/sd-ipv4acd.c
@@ -92,7 +92,7 @@ struct sd_ipv4acd {
struct ether_addr mac_addr;
sd_event *event;
int event_priority;
- sd_ipv4acd_cb_t cb;
+ sd_ipv4acd_callback_t cb;
void* userdata;
};
@@ -428,7 +428,7 @@ int sd_ipv4acd_detach_event(sd_ipv4acd *ll) {
return 0;
}
-int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int priority) {
+int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority) {
int r;
assert_return(ll, -EINVAL);
@@ -447,7 +447,7 @@ int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int priority) {
return 0;
}
-int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_cb_t cb, void *userdata) {
+int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata) {
assert_return(ll, -EINVAL);
ll->cb = cb;
@@ -456,7 +456,7 @@ int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_cb_t cb, void *userdata)
return 0;
}
-int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address){
+int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address) {
assert_return(ll, -EINVAL);
assert_return(address, -EINVAL);
assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 7725b67548..fc27408989 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -52,7 +52,7 @@ struct sd_ipv4ll {
/* External */
be32_t claimed_address;
- sd_ipv4ll_cb_t cb;
+ sd_ipv4ll_callback_t cb;
void* userdata;
};
@@ -160,7 +160,7 @@ int sd_ipv4ll_detach_event(sd_ipv4ll *ll) {
return sd_ipv4acd_detach_event(ll->acd);
}
-int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int priority) {
+int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority) {
int r;
assert_return(ll, -EINVAL);
@@ -172,7 +172,7 @@ int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int priority) {
return 0;
}
-int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata) {
+int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata) {
assert_return(ll, -EINVAL);
ll->cb = cb;
@@ -181,7 +181,7 @@ int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata) {
return 0;
}
-int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address){
+int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address) {
assert_return(ll, -EINVAL);
assert_return(address, -EINVAL);
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
index 6bb2c7797b..5a7380cd3f 100644
--- a/src/libsystemd-network/sd-lldp.c
+++ b/src/libsystemd-network/sd-lldp.c
@@ -1,21 +1,21 @@
/***
- This file is part of systemd.
+ This file is part of systemd.
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
+ Copyright (C) 2014 Tom Gundersen
+ Copyright (C) 2014 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 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.
+ 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/>.
+ 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 <arpa/inet.h>
@@ -24,733 +24,473 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "fileio.h"
-#include "hashmap.h"
#include "lldp-internal.h"
-#include "lldp-port.h"
-#include "lldp-tlv.h"
-#include "prioq.h"
-#include "siphash24.h"
-#include "string-util.h"
-
-typedef enum LLDPAgentRXState {
- LLDP_AGENT_RX_WAIT_PORT_OPERATIONAL = 4,
- LLDP_AGENT_RX_DELETE_AGED_INFO,
- LLDP_AGENT_RX_LLDP_INITIALIZE,
- LLDP_AGENT_RX_WAIT_FOR_FRAME,
- LLDP_AGENT_RX_RX_FRAME,
- LLDP_AGENT_RX_DELETE_INFO,
- LLDP_AGENT_RX_UPDATE_INFO,
- _LLDP_AGENT_RX_STATE_MAX,
- _LLDP_AGENT_RX_INVALID = -1,
-} LLDPAgentRXState;
-
-/* Section 10.5.2.2 Reception counters */
-struct lldp_agent_statistics {
- uint64_t stats_ageouts_total;
- uint64_t stats_frames_discarded_total;
- uint64_t stats_frames_in_errors_total;
- uint64_t stats_frames_in_total;
- uint64_t stats_tlvs_discarded_total;
- uint64_t stats_tlvs_unrecognized_total;
-};
-
-struct sd_lldp {
- lldp_port *port;
-
- Prioq *by_expiry;
- Hashmap *neighbour_mib;
-
- sd_lldp_cb_t cb;
-
- void *userdata;
-
- LLDPAgentRXState rx_state;
- lldp_agent_statistics statistics;
-};
-
-static void chassis_id_hash_func(const void *p, struct siphash *state) {
- const lldp_chassis_id *id = p;
-
- assert(id);
- assert(id->data);
-
- siphash24_compress(&id->length, sizeof(id->length), state);
- siphash24_compress(id->data, id->length, state);
-}
+#include "lldp-neighbor.h"
+#include "lldp-network.h"
+#include "socket-util.h"
+#include "ether-addr-util.h"
-static int chassis_id_compare_func(const void *_a, const void *_b) {
- const lldp_chassis_id *a, *b;
+#define LLDP_DEFAULT_NEIGHBORS_MAX 128U
- a = _a;
- b = _b;
+static void lldp_flush_neighbors(sd_lldp *lldp) {
+ sd_lldp_neighbor *n;
- assert(!a->length || a->data);
- assert(!b->length || b->data);
+ assert(lldp);
- if (a->type != b->type)
- return -1;
+ while ((n = hashmap_first(lldp->neighbor_by_id)))
+ lldp_neighbor_unlink(n);
+}
- if (a->length != b->length)
- return a->length < b->length ? -1 : 1;
+static void lldp_callback(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n) {
+ assert(lldp);
+ assert(n);
- return memcmp(a->data, b->data, a->length);
-}
+ log_lldp("Invoking callback for '%c'.", event);
-static const struct hash_ops chassis_id_hash_ops = {
- .hash = chassis_id_hash_func,
- .compare = chassis_id_compare_func
-};
+ if (!lldp->callback)
+ return;
-static void lldp_mib_delete_objects(sd_lldp *lldp);
-static void lldp_set_state(sd_lldp *lldp, LLDPAgentRXState state);
-static void lldp_run_state_machine(sd_lldp *ll);
+ lldp->callback(lldp, event, n, lldp->userdata);
+}
-static int lldp_receive_frame(sd_lldp *lldp, tlv_packet *tlv) {
- int r;
+static int lldp_make_space(sd_lldp *lldp, size_t extra) {
+ usec_t t = USEC_INFINITY;
+ bool changed = false;
assert(lldp);
- assert(tlv);
-
- /* Remove expired packets */
- if (prioq_size(lldp->by_expiry) > 0) {
- lldp_set_state(lldp, LLDP_AGENT_RX_DELETE_INFO);
+ /* Remove all entries that are past their TTL, and more until at least the specified number of extra entries
+ * are free. */
- lldp_mib_delete_objects(lldp);
- }
+ for (;;) {
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
- r = lldp_mib_add_objects(lldp->by_expiry, lldp->neighbour_mib, tlv);
- if (r < 0)
- goto out;
+ n = prioq_peek(lldp->neighbor_by_expiry);
+ if (!n)
+ break;
- lldp_set_state(lldp, LLDP_AGENT_RX_UPDATE_INFO);
+ sd_lldp_neighbor_ref(n);
- log_lldp("Packet added. MIB size: %d , PQ size: %d",
- hashmap_size(lldp->neighbour_mib),
- prioq_size(lldp->by_expiry));
+ if (hashmap_size(lldp->neighbor_by_id) > LESS_BY(lldp->neighbors_max, extra))
+ goto remove_one;
- lldp->statistics.stats_frames_in_total ++;
+ if (t == USEC_INFINITY)
+ t = now(clock_boottime_or_monotonic());
- out:
- if (r < 0)
- log_lldp("Receive frame failed: %s", strerror(-r));
+ if (n->until > t)
+ break;
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_FOR_FRAME);
+ remove_one:
+ lldp_neighbor_unlink(n);
+ lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, n);
+ changed = true;
+ }
- return 0;
+ return changed;
}
-/* 10.3.2 LLDPDU validation: rxProcessFrame() */
-int lldp_handle_packet(tlv_packet *tlv, uint16_t length) {
- bool system_description = false, system_name = false, chassis_id = false;
- bool malformed = false, port_id = false, ttl = false, end = false;
- uint16_t type, len, i, l, t;
- lldp_port *port;
- uint8_t *p, *q;
- sd_lldp *lldp;
- int r;
-
- assert(tlv);
- assert(length > 0);
-
- port = (lldp_port *) tlv->userdata;
- lldp = (sd_lldp *) port->userdata;
-
- if (lldp->port->status == LLDP_PORT_STATUS_DISABLED) {
- log_lldp("Port: %s is disabled. Dropping.", lldp->port->ifname);
- goto out;
- }
+static bool lldp_keep_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
+ assert(lldp);
+ assert(n);
- lldp_set_state(lldp, LLDP_AGENT_RX_RX_FRAME);
+ /* Don't keep data with a zero TTL */
+ if (n->ttl <= 0)
+ return false;
- p = tlv->pdu;
- p += sizeof(struct ether_header);
+ /* Filter out data from the filter address */
+ if (!ether_addr_is_null(&lldp->filter_address) &&
+ ether_addr_equal(&lldp->filter_address, &n->source_address))
+ return false;
- for (i = 1, l = 0; l <= length; i++) {
+ /* Only add if the neighbor has a capability we are interested in. Note that we also store all neighbors with
+ * no caps field set. */
+ if (n->has_capabilities &&
+ (n->enabled_capabilities & lldp->capability_mask) == 0)
+ return false;
- memcpy(&t, p, sizeof(uint16_t));
+ /* Keep everything else */
+ return true;
+}
- type = ntohs(t) >> 9;
- len = ntohs(t) & 0x01ff;
+static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor);
- if (type == LLDP_TYPE_END) {
- if (len != 0) {
- log_lldp("TLV type end must be length 0 (not %d). Dropping.", len);
+static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *old = NULL;
+ bool keep;
+ int r;
- malformed = true;
- goto out;
- }
+ assert(lldp);
+ assert(n);
+ assert(!n->lldp);
- end = true;
+ keep = lldp_keep_neighbor(lldp, n);
- break;
- } else if (type >=_LLDP_TYPE_MAX) {
- log_lldp("TLV type: %d not recognized. Dropping.", type);
+ /* First retrieve the old entry for this MSAP */
+ old = hashmap_get(lldp->neighbor_by_id, &n->id);
+ if (old) {
+ sd_lldp_neighbor_ref(old);
- malformed = true;
- goto out;
+ if (!keep) {
+ lldp_neighbor_unlink(old);
+ lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, old);
+ return 0;
}
- /* skip type and length encoding */
- p += 2;
- q = p;
-
- p += len;
- l += (len + 2);
+ if (lldp_neighbor_equal(n, old)) {
+ /* Is this equal, then restart the TTL counter, but don't do anyting else. */
+ lldp_start_timer(lldp, old);
+ lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old);
+ return 0;
+ }
- if (i <= 3) {
- if (i != type) {
- log_lldp("TLV missing or out of order. Dropping.");
+ /* Data changed, remove the old entry, and add a new one */
+ lldp_neighbor_unlink(old);
- malformed = true;
- goto out;
- }
- }
+ } else if (!keep)
+ return 0;
- switch(type) {
- case LLDP_TYPE_CHASSIS_ID:
+ /* Then, make room for at least one new neighbor */
+ lldp_make_space(lldp, 1);
- if (len < 2) {
- log_lldp("Received malformed Chassis ID TLV length: %d. Dropping.", len);
+ r = hashmap_put(lldp->neighbor_by_id, &n->id, n);
+ if (r < 0)
+ goto finish;
- malformed = true;
- goto out;
- }
+ r = prioq_put(lldp->neighbor_by_expiry, n, &n->prioq_idx);
+ if (r < 0) {
+ assert_se(hashmap_remove(lldp->neighbor_by_id, &n->id) == n);
+ goto finish;
+ }
- if (chassis_id) {
- log_lldp("Duplicate Chassis ID TLV found. Dropping.");
+ n->lldp = lldp;
- malformed = true;
- goto out;
- }
+ lldp_start_timer(lldp, n);
+ lldp_callback(lldp, old ? SD_LLDP_EVENT_UPDATED : SD_LLDP_EVENT_ADDED, n);
- /* Look what subtype it has */
- if (*q == LLDP_CHASSIS_SUBTYPE_RESERVED || *q > LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED) {
- log_lldp("Unknown subtype: %d found in Chassis ID TLV. Dropping.", *q);
+ return 1;
- malformed = true;
- goto out;
+finish:
+ if (old)
+ lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, n);
- }
+ return r;
+}
- chassis_id = true;
+static int lldp_handle_datagram(sd_lldp *lldp, sd_lldp_neighbor *n) {
+ int r;
- break;
- case LLDP_TYPE_PORT_ID:
+ assert(lldp);
+ assert(n);
- if (len < 2) {
- log_lldp("Received malformed Port ID TLV length: %d. Dropping.", len);
+ r = lldp_neighbor_parse(n);
+ if (r == -EBADMSG) /* Ignore bad messages */
+ return 0;
+ if (r < 0)
+ return r;
- malformed = true;
- goto out;
- }
+ r = lldp_add_neighbor(lldp, n);
+ if (r < 0) {
+ log_lldp_errno(r, "Failed to add datagram. Ignoring.");
+ return 0;
+ }
- if (port_id) {
- log_lldp("Duplicate Port ID TLV found. Dropping.");
+ log_lldp("Successfully processed LLDP datagram.");
+ return 0;
+}
- malformed = true;
- goto out;
- }
+static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
+ ssize_t space, length;
+ sd_lldp *lldp = userdata;
- /* Look what subtype it has */
- if (*q == LLDP_PORT_SUBTYPE_RESERVED || *q > LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED) {
- log_lldp("Unknown subtype: %d found in Port ID TLV. Dropping.", *q);
+ assert(fd >= 0);
+ assert(lldp);
- malformed = true;
- goto out;
+ space = next_datagram_size_fd(fd);
+ if (space < 0)
+ return log_lldp_errno(space, "Failed to determine datagram size to read: %m");
- }
+ n = lldp_neighbor_new(space);
+ if (!n)
+ return -ENOMEM;
- port_id = true;
+ length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT);
+ if (length < 0)
+ return log_lldp_errno(errno, "Failed to read LLDP datagram: %m");
- break;
- case LLDP_TYPE_TTL:
+ if ((size_t) length != n->raw_size) {
+ log_lldp("Packet size mismatch.");
+ return -EINVAL;
+ }
- if(len != 2) {
- log_lldp("Received invalid TTL TLV lenth: %d. Dropping.", len);
+ return lldp_handle_datagram(lldp, n);
+}
- malformed = true;
- goto out;
- }
+_public_ int sd_lldp_start(sd_lldp *lldp) {
+ int r;
- if (ttl) {
- log_lldp("Duplicate TTL TLV found. Dropping.");
+ assert_return(lldp, -EINVAL);
- malformed = true;
- goto out;
- }
+ if (lldp->fd >= 0)
+ return 0;
- ttl = true;
+ assert(!lldp->io_event_source);
- break;
- case LLDP_TYPE_SYSTEM_NAME:
+ lldp->fd = lldp_network_bind_raw_socket(lldp->ifindex);
+ if (lldp->fd < 0)
+ return lldp->fd;
- /* According to RFC 1035 the length of a FQDN is limited to 255 characters */
- if (len > 255) {
- log_lldp("Received invalid system name length: %d. Dropping.", len);
- malformed = true;
- goto out;
- }
+ if (lldp->event) {
+ r = sd_event_add_io(lldp->event, &lldp->io_event_source, lldp->fd, EPOLLIN, lldp_receive_datagram, lldp);
+ if (r < 0)
+ goto fail;
- if (system_name) {
- log_lldp("Duplicate system name found. Dropping.");
- malformed = true;
- goto out;
- }
+ r = sd_event_source_set_priority(lldp->io_event_source, lldp->event_priority);
+ if (r < 0)
+ goto fail;
- system_name = true;
+ (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io");
+ }
- break;
- case LLDP_TYPE_SYSTEM_DESCRIPTION:
-
- /* 0 <= n <= 255 octets */
- if (len > 255) {
- log_lldp("Received invalid system description length: %d. Dropping.", len);
- malformed = true;
- goto out;
- }
-
- if (system_description) {
- log_lldp("Duplicate system description found. Dropping.");
- malformed = true;
- goto out;
- }
-
- system_description = true;
- break;
- default:
+ return 1;
- if (len == 0) {
- log_lldp("TLV type: %d length 0 received. Dropping.", type);
+fail:
+ lldp->io_event_source = sd_event_source_unref(lldp->io_event_source);
+ lldp->fd = safe_close(lldp->fd);
- malformed = true;
- goto out;
- }
- break;
- }
- }
+ return r;
+}
- if(!chassis_id || !port_id || !ttl || !end) {
- log_lldp("One or more mandatory TLV missing. Dropping.");
+_public_ int sd_lldp_stop(sd_lldp *lldp) {
+ assert_return(lldp, -EINVAL);
- malformed = true;
- goto out;
+ if (lldp->fd < 0)
+ return 0;
- }
+ lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source);
+ lldp->io_event_source = sd_event_source_unref(lldp->io_event_source);
+ lldp->fd = safe_close(lldp->fd);
- r = tlv_packet_parse_pdu(tlv, length);
- if (r < 0) {
- log_lldp("Failed to parse the TLV. Dropping.");
+ lldp_flush_neighbors(lldp);
- malformed = true;
- goto out;
- }
+ return 1;
+}
- return lldp_receive_frame(lldp, tlv);
+_public_ int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int64_t priority) {
+ int r;
- out:
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_FOR_FRAME);
+ assert_return(lldp, -EINVAL);
+ assert_return(lldp->fd < 0, -EBUSY);
+ assert_return(!lldp->event, -EBUSY);
- if (malformed) {
- lldp->statistics.stats_frames_discarded_total ++;
- lldp->statistics.stats_frames_in_errors_total ++;
+ if (event)
+ lldp->event = sd_event_ref(event);
+ else {
+ r = sd_event_default(&lldp->event);
+ if (r < 0)
+ return r;
}
- sd_lldp_packet_unref(tlv);
+ lldp->event_priority = priority;
return 0;
}
-static int ttl_expiry_item_prioq_compare_func(const void *a, const void *b) {
- const lldp_neighbour_port *p = a, *q = b;
+_public_ int sd_lldp_detach_event(sd_lldp *lldp) {
- if (p->until < q->until)
- return -1;
-
- if (p->until > q->until)
- return 1;
+ assert_return(lldp, -EINVAL);
+ assert_return(lldp->fd < 0, -EBUSY);
+ lldp->event = sd_event_unref(lldp->event);
return 0;
}
-static void lldp_set_state(sd_lldp *lldp, LLDPAgentRXState state) {
-
- assert(lldp);
- assert(state < _LLDP_AGENT_RX_STATE_MAX);
+_public_ int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata) {
+ assert_return(lldp, -EINVAL);
- lldp->rx_state = state;
+ lldp->callback = cb;
+ lldp->userdata = userdata;
- lldp_run_state_machine(lldp);
+ return 0;
}
-static void lldp_run_state_machine(sd_lldp *lldp) {
- if (!lldp->cb)
- return;
-
- switch (lldp->rx_state) {
- case LLDP_AGENT_RX_UPDATE_INFO:
- lldp->cb(lldp, SD_LLDP_EVENT_UPDATE_INFO, lldp->userdata);
- break;
- default:
- break;
- }
-}
+_public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) {
-/* 10.5.5.2.1 mibDeleteObjects ()
- * The mibDeleteObjects () procedure deletes all information in the LLDP remote
- * systems MIB associated with the MSAP identifier if an LLDPDU is received with
- * an rxTTL value of zero (see 10.3.2) or the timing counter rxInfoTTL expires. */
+ if (!lldp)
+ return NULL;
-static void lldp_mib_delete_objects(sd_lldp *lldp) {
- lldp_neighbour_port *p;
- usec_t t = 0;
+ lldp_flush_neighbors(lldp);
- /* Remove all entries that are past their TTL */
- for (;;) {
+ hashmap_free(lldp->neighbor_by_id);
+ prioq_free(lldp->neighbor_by_expiry);
- if (prioq_size(lldp->by_expiry) <= 0)
- break;
+ sd_event_source_unref(lldp->io_event_source);
+ sd_event_source_unref(lldp->timer_event_source);
+ sd_event_unref(lldp->event);
+ safe_close(lldp->fd);
- p = prioq_peek(lldp->by_expiry);
- if (!p)
- break;
+ free(lldp);
- if (t <= 0)
- t = now(clock_boottime_or_monotonic());
+ return NULL;
+}
- if (p->until > t)
- break;
+_public_ int sd_lldp_new(sd_lldp **ret, int ifindex) {
+ _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL;
+ int r;
- lldp_neighbour_port_remove_and_free(p);
+ assert_return(ret, -EINVAL);
+ assert_return(ifindex > 0, -EINVAL);
- lldp->statistics.stats_ageouts_total ++;
- }
-}
+ lldp = new0(sd_lldp, 1);
+ if (!lldp)
+ return -ENOMEM;
-static void lldp_mib_objects_flush(sd_lldp *lldp) {
- lldp_neighbour_port *p, *q;
- lldp_chassis *c;
+ lldp->fd = -1;
+ lldp->ifindex = ifindex;
+ lldp->neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX;
+ lldp->capability_mask = (uint16_t) -1;
- assert(lldp);
- assert(lldp->neighbour_mib);
- assert(lldp->by_expiry);
+ lldp->neighbor_by_id = hashmap_new(&lldp_neighbor_id_hash_ops);
+ if (!lldp->neighbor_by_id)
+ return -ENOMEM;
- /* Drop all packets */
- while ((c = hashmap_steal_first(lldp->neighbour_mib))) {
+ r = prioq_ensure_allocated(&lldp->neighbor_by_expiry, lldp_neighbor_prioq_compare_func);
+ if (r < 0)
+ return r;
- LIST_FOREACH_SAFE(port, p, q, c->ports) {
- lldp_neighbour_port_remove_and_free(p);
- }
- }
+ *ret = lldp;
+ lldp = NULL;
- assert(hashmap_size(lldp->neighbour_mib) == 0);
- assert(prioq_size(lldp->by_expiry) == 0);
+ return 0;
}
-int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) {
- _cleanup_free_ char *temp_path = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- uint8_t *mac, *port_id, type;
- lldp_neighbour_port *p;
- uint16_t data = 0, length = 0;
- char buf[LINE_MAX];
- lldp_chassis *c;
- usec_t time;
- Iterator i;
- int r;
+static int neighbor_compare_func(const void *a, const void *b) {
+ const sd_lldp_neighbor * const*x = a, * const *y = b;
- assert(lldp);
- assert(lldp_file);
+ return lldp_neighbor_id_hash_ops.compare(&(*x)->id, &(*y)->id);
+}
- r = fopen_temporary(lldp_file, &f, &temp_path);
- if (r < 0)
- goto fail;
-
- fchmod(fileno(f), 0644);
-
- HASHMAP_FOREACH(c, lldp->neighbour_mib, i) {
- LIST_FOREACH(port, p, c->ports) {
- _cleanup_free_ char *s = NULL;
- char *k, *t;
-
- r = sd_lldp_packet_read_chassis_id(p->packet, &type, &mac, &length);
- if (r < 0)
- continue;
-
- sprintf(buf, "'_Chassis=%02x:%02x:%02x:%02x:%02x:%02x' '_CType=%d' ",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], type);
-
- s = strdup(buf);
- if (!s) {
- r = -ENOMEM;
- goto fail;
- }
-
- r = sd_lldp_packet_read_port_id(p->packet, &type, &port_id, &length);
- if (r < 0)
- continue;
-
- if (type != LLDP_PORT_SUBTYPE_MAC_ADDRESS) {
- k = strndup((char *) port_id, length -1);
- if (!k) {
- r = -ENOMEM;
- goto fail;
- }
-
- sprintf(buf, "'_Port=%s' '_PType=%d' ", k , type);
- free(k);
- } else {
- mac = port_id;
- sprintf(buf, "'_Port=%02x:%02x:%02x:%02x:%02x:%02x' '_PType=%d' ",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], type);
- }
-
- k = strappend(s, buf);
- if (!k) {
- r = -ENOMEM;
- goto fail;
- }
-
- free(s);
- s = k;
-
- time = now(clock_boottime_or_monotonic());
-
- /* Don't write expired packets */
- if (time - p->until <= 0)
- continue;
-
- sprintf(buf, "'_TTL="USEC_FMT"' ", p->until);
-
- k = strappend(s, buf);
- if (!k) {
- r = -ENOMEM;
- goto fail;
- }
-
- free(s);
- s = k;
-
- r = sd_lldp_packet_read_system_name(p->packet, &k, &length);
- if (r < 0)
- k = strappend(s, "'_NAME=N/A' ");
- else {
- t = strndup(k, length);
- if (!t) {
- r = -ENOMEM;
- goto fail;
- }
-
- k = strjoin(s, "'_NAME=", t, "' ", NULL);
- free(t);
- }
-
- if (!k) {
- r = -ENOMEM;
- goto fail;
- }
-
- free(s);
- s = k;
-
- (void) sd_lldp_packet_read_system_capability(p->packet, &data);
-
- sprintf(buf, "'_CAP=%x'", data);
-
- k = strappend(s, buf);
- if (!k) {
- r = -ENOMEM;
- goto fail;
- }
-
- free(s);
- s = k;
-
- fprintf(f, "%s\n", s);
- }
- }
+static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
+ sd_lldp *lldp = userdata;
+ int r, q;
- r = fflush_and_check(f);
+ r = lldp_make_space(lldp, 0);
if (r < 0)
- goto fail;
+ return log_lldp_errno(r, "Failed to make space: %m");
- if (rename(temp_path, lldp_file) < 0) {
- r = -errno;
- goto fail;
- }
+ q = lldp_start_timer(lldp, NULL);
+ if (q < 0)
+ return log_lldp_errno(q, "Failed to restart timer: %m");
return 0;
-
- fail:
- if (temp_path)
- (void) unlink(temp_path);
-
- return log_error_errno(r, "Failed to save lldp data %s: %m", lldp_file);
}
-int sd_lldp_start(sd_lldp *lldp) {
+static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
+ sd_lldp_neighbor *n;
int r;
- assert_return(lldp, -EINVAL);
- assert_return(lldp->port, -EINVAL);
+ assert(lldp);
- lldp->port->status = LLDP_PORT_STATUS_ENABLED;
+ if (neighbor)
+ lldp_neighbor_start_ttl(neighbor);
- lldp_set_state(lldp, LLDP_AGENT_RX_LLDP_INITIALIZE);
+ n = prioq_peek(lldp->neighbor_by_expiry);
+ if (!n) {
- r = lldp_port_start(lldp->port);
- if (r < 0) {
- log_lldp("Failed to start Port : %s , %s",
- lldp->port->ifname,
- strerror(-r));
+ if (lldp->timer_event_source)
+ return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_OFF);
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_PORT_OPERATIONAL);
-
- return r;
+ return 0;
}
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_FOR_FRAME);
-
- return 0;
-}
-
-int sd_lldp_stop(sd_lldp *lldp) {
- int r;
+ if (lldp->timer_event_source) {
+ r = sd_event_source_set_time(lldp->timer_event_source, n->until);
+ if (r < 0)
+ return r;
- assert_return(lldp, -EINVAL);
- assert_return(lldp->port, -EINVAL);
+ return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_ONESHOT);
+ }
- lldp->port->status = LLDP_PORT_STATUS_DISABLED;
+ if (!lldp->event)
+ return 0;
- r = lldp_port_stop(lldp->port);
+ r = sd_event_add_time(lldp->event, &lldp->timer_event_source, clock_boottime_or_monotonic(), n->until, 0, on_timer_event, lldp);
if (r < 0)
return r;
- lldp_mib_objects_flush(lldp);
+ r = sd_event_source_set_priority(lldp->timer_event_source, lldp->event_priority);
+ if (r < 0)
+ return r;
+ (void) sd_event_source_set_description(lldp->timer_event_source, "lldp-timer");
return 0;
}
-int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int priority) {
- int r;
+_public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
+ sd_lldp_neighbor **l = NULL, *n;
+ Iterator i;
+ int k = 0, r;
assert_return(lldp, -EINVAL);
- assert_return(!lldp->port->event, -EBUSY);
+ assert_return(ret, -EINVAL);
- if (event)
- lldp->port->event = sd_event_ref(event);
- else {
- r = sd_event_default(&lldp->port->event);
- if (r < 0)
- return r;
+ if (hashmap_isempty(lldp->neighbor_by_id)) { /* Special shortcut */
+ *ret = NULL;
+ return 0;
}
- lldp->port->event_priority = priority;
+ l = new0(sd_lldp_neighbor*, hashmap_size(lldp->neighbor_by_id));
+ if (!l)
+ return -ENOMEM;
- return 0;
-}
+ r = lldp_start_timer(lldp, NULL);
+ if (r < 0) {
+ free(l);
+ return r;
+ }
-int sd_lldp_detach_event(sd_lldp *lldp) {
+ HASHMAP_FOREACH(n, lldp->neighbor_by_id, i)
+ l[k++] = sd_lldp_neighbor_ref(n);
- assert_return(lldp, -EINVAL);
+ assert((size_t) k == hashmap_size(lldp->neighbor_by_id));
- lldp->port->event = sd_event_unref(lldp->port->event);
+ /* Return things in a stable order */
+ qsort(l, k, sizeof(sd_lldp_neighbor*), neighbor_compare_func);
+ *ret = l;
- return 0;
+ return k;
}
-int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_cb_t cb, void *userdata) {
+_public_ int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t m) {
assert_return(lldp, -EINVAL);
+ assert_return(m <= 0, -EINVAL);
- lldp->cb = cb;
- lldp->userdata = userdata;
+ lldp->neighbors_max = m;
+ lldp_make_space(lldp, 0);
return 0;
}
-sd_lldp* sd_lldp_unref(sd_lldp *lldp) {
-
- if (!lldp)
- return NULL;
-
- /* Drop all packets */
- lldp_mib_objects_flush(lldp);
-
- lldp_port_free(lldp->port);
-
- hashmap_free(lldp->neighbour_mib);
- prioq_free(lldp->by_expiry);
-
- free(lldp);
- return NULL;
-}
-
-int sd_lldp_new(int ifindex,
- const char *ifname,
- const struct ether_addr *mac,
- sd_lldp **ret) {
- _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL;
- int r;
-
- assert_return(ret, -EINVAL);
- assert_return(ifindex > 0, -EINVAL);
- assert_return(ifname, -EINVAL);
- assert_return(mac, -EINVAL);
-
- lldp = new0(sd_lldp, 1);
- if (!lldp)
- return -ENOMEM;
-
- r = lldp_port_new(ifindex, ifname, mac, lldp, &lldp->port);
- if (r < 0)
- return r;
-
- lldp->neighbour_mib = hashmap_new(&chassis_id_hash_ops);
- if (!lldp->neighbour_mib)
- return -ENOMEM;
-
- r = prioq_ensure_allocated(&lldp->by_expiry,
- ttl_expiry_item_prioq_compare_func);
- if (r < 0)
- return r;
-
- lldp->rx_state = LLDP_AGENT_RX_WAIT_PORT_OPERATIONAL;
+_public_ int sd_lldp_match_capabilities(sd_lldp *lldp, uint16_t mask) {
+ assert_return(lldp, -EINVAL);
+ assert_return(mask != 0, -EINVAL);
- *ret = lldp;
- lldp = NULL;
+ lldp->capability_mask = mask;
return 0;
}
-int sd_lldp_get_packets(sd_lldp *lldp, sd_lldp_packet ***tlvs) {
- lldp_neighbour_port *p;
- lldp_chassis *c;
- Iterator iter;
- unsigned count = 0, i;
-
+_public_ int sd_lldp_set_filter_address(sd_lldp *lldp, const struct ether_addr *addr) {
assert_return(lldp, -EINVAL);
- assert_return(tlvs, -EINVAL);
- HASHMAP_FOREACH(c, lldp->neighbour_mib, iter) {
- LIST_FOREACH(port, p, c->ports)
- count++;
- }
+ /* In order to deal nicely with bridges that send back our own packets, allow one address to be filtered, so
+ * that our own can be filtered out here. */
- if (!count) {
- *tlvs = NULL;
+ if (!addr) {
+ zero(lldp->filter_address);
return 0;
}
- *tlvs = new(sd_lldp_packet *, count);
- if (!*tlvs)
- return -ENOMEM;
-
- i = 0;
- HASHMAP_FOREACH(c, lldp->neighbour_mib, iter) {
- LIST_FOREACH(port, p, c->ports)
- (*tlvs)[i++] = sd_lldp_packet_ref(p->packet);
- }
-
- return count;
+ lldp->filter_address = *addr;
+ return 0;
}
diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c
index cd07fc1b3f..1c0d300cb3 100644
--- a/src/libsystemd-network/sd-ndisc.c
+++ b/src/libsystemd-network/sd-ndisc.c
@@ -166,7 +166,7 @@ int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr) {
}
-int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int priority) {
+int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority) {
int r;
assert_return(nd, -EINVAL);
diff --git a/src/libsystemd-network/test-dhcp-option.c b/src/libsystemd-network/test-dhcp-option.c
index 7d8a957227..d84859c053 100644
--- a/src/libsystemd-network/test-dhcp-option.c
+++ b/src/libsystemd-network/test-dhcp-option.c
@@ -110,14 +110,9 @@ static DHCPMessage *create_message(uint8_t *options, uint16_t optlen,
message = malloc0(len);
assert_se(message);
- if (options && optlen)
- memcpy(&message->options, options, optlen);
-
- if (file && filelen <= 128)
- memcpy(&message->file, file, filelen);
-
- if (sname && snamelen <= 64)
- memcpy(&message->sname, sname, snamelen);
+ memcpy_safe(&message->options, options, optlen);
+ memcpy_safe(&message->file, file, filelen);
+ memcpy_safe(&message->sname, sname, snamelen);
return message;
}
diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c
index 0243bc132b..8c6d214d6f 100644
--- a/src/libsystemd-network/test-lldp.c
+++ b/src/libsystemd-network/test-lldp.c
@@ -22,6 +22,7 @@
#include <net/ethernet.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include <systemd/sd-event.h>
#include <systemd/sd-lldp.h>
@@ -29,8 +30,6 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "lldp-network.h"
-#include "lldp-tlv.h"
-#include "lldp.h"
#include "macro.h"
#include "string-util.h"
@@ -38,211 +37,8 @@
#define TEST_LLDP_TYPE_SYSTEM_NAME "systemd-lldp"
#define TEST_LLDP_TYPE_SYSTEM_DESC "systemd-lldp-desc"
-static int test_fd[2];
-
-static struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
-};
-
-static int lldp_build_tlv_packet(tlv_packet **ret) {
- _cleanup_(sd_lldp_packet_unrefp) tlv_packet *m = NULL;
- const uint8_t lldp_dst[] = LLDP_MULTICAST_ADDR;
- struct ether_header ether = {
- .ether_type = htons(ETHERTYPE_LLDP),
- };
-
- /* Append Ethernet header */
- memcpy(&ether.ether_dhost, lldp_dst, ETHER_ADDR_LEN);
- memcpy(&ether.ether_shost, &mac_addr, ETHER_ADDR_LEN);
-
- assert_se(tlv_packet_new(&m) >= 0);
-
- assert_se(tlv_packet_append_bytes(m, &ether, sizeof(struct ether_header)) >= 0);
-
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_CHASSIS_ID) >= 0);
-
- assert_se(tlv_packet_append_u8(m, LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS) >= 0);
- assert_se(tlv_packet_append_bytes(m, &mac_addr, ETHER_ADDR_LEN) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* port name */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_PORT_ID) >= 0);
-
- assert_se(tlv_packet_append_u8(m, LLDP_PORT_SUBTYPE_INTERFACE_NAME) >= 0);
- assert_se(tlv_packet_append_bytes(m, TEST_LLDP_PORT, strlen(TEST_LLDP_PORT) + 1) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* ttl */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_TTL) >= 0);
-
- assert_se(tlv_packet_append_u16(m, 170) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* system name */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_SYSTEM_NAME) >= 0);
-
- assert_se(tlv_packet_append_bytes(m, TEST_LLDP_TYPE_SYSTEM_NAME,
- strlen(TEST_LLDP_TYPE_SYSTEM_NAME)) >= 0);
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* system descrition */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_SYSTEM_DESCRIPTION) >= 0);
-
- assert_se(tlv_packet_append_bytes(m, TEST_LLDP_TYPE_SYSTEM_DESC,
- strlen(TEST_LLDP_TYPE_SYSTEM_DESC)) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* Mark end of packet */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_END) >= 0);
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- *ret = m;
-
- m = NULL;
-
- return 0;
-}
-
-static int lldp_parse_chassis_tlv(tlv_packet *m, uint8_t *type) {
- uint8_t *p, subtype;
- uint16_t length;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_CHASSIS_ID) >= 0);
- assert_se(tlv_packet_read_u8(m, &subtype) >= 0);
-
- switch (subtype) {
- case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
-
- *type = LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS;
- assert_se(tlv_packet_read_bytes(m, &p, &length) >= 0);
-
- assert_se(memcmp(p, &mac_addr.ether_addr_octet, ETHER_ADDR_LEN) == 0);
-
- break;
- default:
- assert_not_reached("Unhandled option");
- }
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_port_id_tlv(tlv_packet *m) {
- _cleanup_free_ char *p = NULL;
- char *str = NULL;
- uint16_t length;
- uint8_t subtype;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_PORT_ID) >= 0);
-
- assert_se(tlv_packet_read_u8(m, &subtype) >= 0);
-
- switch (subtype) {
- case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
- assert_se(tlv_packet_read_string(m, &str, &length) >= 0);
-
- p = strndup(str, length-1);
- assert_se(p);
-
- assert_se(streq(p, TEST_LLDP_PORT) == 1);
- break;
- default:
- assert_not_reached("Unhandled option");
- }
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_system_name_tlv(tlv_packet *m) {
- _cleanup_free_ char *p = NULL;
- char *str = NULL;
- uint16_t length;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_SYSTEM_NAME) >= 0);
- assert_se(tlv_packet_read_string(m, &str, &length) >= 0);
-
- p = strndup(str, length);
- assert_se(p);
-
- assert_se(streq(p, TEST_LLDP_TYPE_SYSTEM_NAME) == 1);
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 1;
-}
-
-static int lldp_parse_system_desc_tlv(tlv_packet *m) {
- _cleanup_free_ char *p = NULL;
- char *str = NULL;
- uint16_t length;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_SYSTEM_DESCRIPTION) >= 0);
- assert_se(tlv_packet_read_string(m, &str, &length) >= 0);
-
- p = strndup(str, length);
- assert_se(p);
-
- assert_se(streq(p, TEST_LLDP_TYPE_SYSTEM_DESC) == 1);
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_ttl_tlv(tlv_packet *m) {
- uint16_t ttl;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_TTL) >= 0);
- assert_se(tlv_packet_read_u16(m, &ttl) >= 0);
-
- assert_se(ttl == 170);
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_get_destination_type(tlv_packet *m) {
- int dest;
-
- assert_se(sd_lldp_packet_get_destination_type(m, &dest) >= 0);
- assert_se(dest == SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE);
-
- return 0;
-}
-
-static int lldp_parse_tlv_packet(tlv_packet *m, int len) {
- uint8_t subtype;
-
- assert_se(tlv_packet_parse_pdu(m, len) >= 0);
- assert_se(lldp_parse_chassis_tlv(m, &subtype) >= 0);
- assert_se(lldp_parse_port_id_tlv(m) >= 0);
- assert_se(lldp_parse_system_name_tlv(m) >= 0);
- assert_se(lldp_parse_ttl_tlv(m) >= 0);
- assert_se(lldp_parse_system_desc_tlv(m) >= 0);
-
- assert_se(lldp_get_destination_type(m) >= 0);
-
- return 0;
-}
-
-static void test_parser(void) {
- _cleanup_(sd_lldp_packet_unrefp) tlv_packet *tlv = NULL;
-
- /* form a packet */
- lldp_build_tlv_packet(&tlv);
- /* parse the packet */
- tlv_packet_parse_pdu(tlv, tlv->length);
- /* verify */
- lldp_parse_tlv_packet(tlv, tlv->length);
-}
+static int test_fd[2] = { -1, -1 };
+static int lldp_handler_calls;
int lldp_network_bind_raw_socket(int ifindex) {
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0)
@@ -251,28 +47,27 @@ int lldp_network_bind_raw_socket(int ifindex) {
return test_fd[0];
}
-static int lldp_handler_calls;
-static void lldp_handler (sd_lldp *lldp, int event, void *userdata) {
+static void lldp_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) {
lldp_handler_calls++;
}
-static int start_lldp(sd_lldp **lldp, sd_event *e, sd_lldp_cb_t cb, void *cb_data) {
+static int start_lldp(sd_lldp **lldp, sd_event *e, sd_lldp_callback_t cb, void *cb_data) {
int r;
- r = sd_lldp_new(42, "dummy", &mac_addr, lldp);
- if (r)
+ r = sd_lldp_new(lldp, 42);
+ if (r < 0)
return r;
r = sd_lldp_attach_event(*lldp, e, 0);
- if (r)
+ if (r < 0)
return r;
r = sd_lldp_set_callback(*lldp, cb, cb_data);
- if (r)
+ if (r < 0)
return r;
r = sd_lldp_start(*lldp);
- if (r)
+ if (r < 0)
return r;
return 0;
@@ -282,11 +77,11 @@ static int stop_lldp(sd_lldp *lldp) {
int r;
r = sd_lldp_stop(lldp);
- if (r)
+ if (r < 0)
return r;
r = sd_lldp_detach_event(lldp);
- if (r)
+ if (r < 0)
return r;
sd_lldp_unref(lldp);
@@ -296,13 +91,8 @@ static int stop_lldp(sd_lldp *lldp) {
}
static void test_receive_basic_packet(sd_event *e) {
- sd_lldp *lldp;
- sd_lldp_packet **packets;
- uint8_t type, *data;
- uint16_t length, ttl;
- int dest_type;
- char *str;
- uint8_t frame[] = {
+
+ static const uint8_t frame[] = {
/* Ethernet header */
0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */
@@ -319,51 +109,53 @@ static void test_receive_basic_packet(sd_event *e) {
0x00, 0x00 /* End Of LLDPDU */
};
+ sd_lldp *lldp;
+ sd_lldp_neighbor **neighbors;
+ uint8_t type;
+ const void *data;
+ uint16_t ttl;
+ size_t length;
+ const char *str;
+
lldp_handler_calls = 0;
assert_se(start_lldp(&lldp, e, lldp_handler, NULL) == 0);
assert_se(write(test_fd[1], frame, sizeof(frame)) == sizeof(frame));
sd_event_run(e, 0);
assert_se(lldp_handler_calls == 1);
- assert_se(sd_lldp_get_packets(lldp, &packets) == 1);
+ assert_se(sd_lldp_get_neighbors(lldp, &neighbors) == 1);
- assert_se(sd_lldp_packet_read_chassis_id(packets[0], &type, &data, &length) == 0);
- assert_se(type == LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS);
+ assert_se(sd_lldp_neighbor_get_chassis_id(neighbors[0], &type, &data, &length) == 0);
+ assert_se(type == SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS);
assert_se(length == ETH_ALEN);
assert_se(!memcmp(data, "\x00\x01\x02\x03\x04\x05", ETH_ALEN));
- assert_se(sd_lldp_packet_read_port_id(packets[0], &type, &data, &length) == 0);
- assert_se(type == LLDP_PORT_SUBTYPE_INTERFACE_NAME);
+ assert_se(sd_lldp_neighbor_get_port_id(neighbors[0], &type, &data, &length) == 0);
+ assert_se(type == SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME);
assert_se(length == 3);
assert_se(strneq((char *) data, "1/3", 3));
- assert_se(sd_lldp_packet_read_port_description(packets[0], &str, &length) == 0);
- assert_se(length == 4);
- assert_se(strneq(str, "Port", 4));
+ assert_se(sd_lldp_neighbor_get_port_description(neighbors[0], &str) == 0);
+ assert_se(streq(str, "Port"));
- assert_se(sd_lldp_packet_read_system_name(packets[0], &str, &length) == 0);
- assert_se(length == 3);
- assert_se(strneq(str, "SYS", 3));
+ assert_se(sd_lldp_neighbor_get_system_name(neighbors[0], &str) == 0);
+ assert_se(streq(str, "SYS"));
- assert_se(sd_lldp_packet_read_system_description(packets[0], &str, &length) == 0);
- assert_se(length == 4); /* This is the real length in the TLV packet */
- assert_se(strneq(str, "foo", 3));
+ assert_se(sd_lldp_neighbor_get_system_description(neighbors[0], &str) == 0);
+ assert_se(streq(str, "foo"));
- assert_se(sd_lldp_packet_read_ttl(packets[0], &ttl) == 0);
+ assert_se(sd_lldp_neighbor_get_ttl(neighbors[0], &ttl) == 0);
assert_se(ttl == 120);
- assert_se(sd_lldp_packet_get_destination_type(packets[0], &dest_type) == 0);
- assert_se(dest_type == SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE);
-
- sd_lldp_packet_unref(packets[0]);
- free(packets);
+ sd_lldp_neighbor_unref(neighbors[0]);
+ free(neighbors);
assert_se(stop_lldp(lldp) == 0);
}
static void test_receive_incomplete_packet(sd_event *e) {
sd_lldp *lldp;
- sd_lldp_packet **packets;
+ sd_lldp_neighbor **neighbors;
uint8_t frame[] = {
/* Ethernet header */
0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/
@@ -383,18 +175,14 @@ static void test_receive_incomplete_packet(sd_event *e) {
assert_se(write(test_fd[1], frame, sizeof(frame)) == sizeof(frame));
sd_event_run(e, 0);
assert_se(lldp_handler_calls == 0);
- assert_se(sd_lldp_get_packets(lldp, &packets) == 0);
+ assert_se(sd_lldp_get_neighbors(lldp, &neighbors) == 0);
assert_se(stop_lldp(lldp) == 0);
}
static void test_receive_oui_packet(sd_event *e) {
sd_lldp *lldp;
- sd_lldp_packet **packets;
- uint32_t id32;
- uint16_t id16, len;
- uint8_t flags;
- char *str;
+ sd_lldp_neighbor **neighbors;
uint8_t frame[] = {
/* Ethernet header */
0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/
@@ -426,29 +214,30 @@ static void test_receive_oui_packet(sd_event *e) {
assert_se(write(test_fd[1], frame, sizeof(frame)) == sizeof(frame));
sd_event_run(e, 0);
assert_se(lldp_handler_calls == 1);
- assert_se(sd_lldp_get_packets(lldp, &packets) == 1);
-
- assert_se(sd_lldp_packet_read_port_vlan_id(packets[0], &id16) == 0);
- assert_se(id16 == 0x1234);
-
- assert_se(sd_lldp_packet_read_port_protocol_vlan_id(packets[0], &flags, &id16) == 0);
- assert_se(flags == 1);
- assert_se(id16 == 0x7788);
-
- assert_se(sd_lldp_packet_read_vlan_name(packets[0], &id16, &str, &len) == 0);
- assert_se(id16 == 0x1234);
- assert_se(len == 6);
- assert_se(strneq(str, "Vlan51", 6));
-
- assert_se(sd_lldp_packet_read_management_vid(packets[0], &id16) == 0);
- assert_se(id16 == 0x0102);
-
- assert_se(sd_lldp_packet_read_link_aggregation(packets[0], &flags, &id32) == 0);
- assert_se(flags == 1);
- assert_se(id32 == 0x00140012);
-
- sd_lldp_packet_unref(packets[0]);
- free(packets);
+ assert_se(sd_lldp_get_neighbors(lldp, &neighbors) == 1);
+
+ assert_se(sd_lldp_neighbor_tlv_rewind(neighbors[0]) >= 0);
+ assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_CHASSIS_ID) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_PORT_ID) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_TTL) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0);
+ assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_END) > 0);
+ assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) == 0);
+
+ sd_lldp_neighbor_unref(neighbors[0]);
+ free(neighbors);
assert_se(stop_lldp(lldp) == 0);
}
@@ -456,7 +245,7 @@ static void test_receive_oui_packet(sd_event *e) {
int main(int argc, char *argv[]) {
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
- test_parser();
+ log_set_max_level(LOG_DEBUG);
/* LLDP reception tests */
assert_se(sd_event_new(&e) == 0);
diff --git a/src/libsystemd/Makefile b/src/libsystemd/Makefile
index 51bcd0fc69..ff7adf8109 100644
--- a/src/libsystemd/Makefile
+++ b/src/libsystemd/Makefile
@@ -23,27 +23,9 @@
include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
-LIBSYSTEMD_CURRENT=14
+LIBSYSTEMD_CURRENT=15
LIBSYSTEMD_REVISION=0
-LIBSYSTEMD_AGE=14
-
-# The following four libraries only exist for compatibility reasons,
-# their version info should not be bumped anymore
-LIBSYSTEMD_LOGIN_CURRENT=9
-LIBSYSTEMD_LOGIN_REVISION=3
-LIBSYSTEMD_LOGIN_AGE=9
-
-LIBSYSTEMD_DAEMON_CURRENT=0
-LIBSYSTEMD_DAEMON_REVISION=12
-LIBSYSTEMD_DAEMON_AGE=0
-
-LIBSYSTEMD_ID128_CURRENT=0
-LIBSYSTEMD_ID128_REVISION=28
-LIBSYSTEMD_ID128_AGE=0
-
-LIBSYSTEMD_JOURNAL_CURRENT=11
-LIBSYSTEMD_JOURNAL_REVISION=5
-LIBSYSTEMD_JOURNAL_AGE=11
+LIBSYSTEMD_AGE=15
EXTRA_DIST += \
src/libsystemd/libsystemd.pc.in \
@@ -95,7 +77,6 @@ tests += \
test-bus-cleanup \
test-bus-server \
test-bus-match \
- test-bus-proxy \
test-bus-kernel \
test-bus-kernel-bloom \
test-bus-zero-copy \
diff --git a/src/libsystemd/compat-libs/.gitignore b/src/libsystemd/compat-libs/.gitignore
deleted file mode 100644
index 662c154cdd..0000000000
--- a/src/libsystemd/compat-libs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/libsystemd-*.pc
diff --git a/src/libsystemd/compat-libs/Makefile b/src/libsystemd/compat-libs/Makefile
deleted file mode 100644
index 9d528431f4..0000000000
--- a/src/libsystemd/compat-libs/Makefile
+++ /dev/null
@@ -1,146 +0,0 @@
-# -*- Mode: makefile; indent-tabs-mode: t -*-
-#
-# This file is part of systemd.
-#
-# Copyright 2010-2012 Lennart Poettering
-# Copyright 2010-2012 Kay Sievers
-# Copyright 2013 Zbigniew Jędrzejewski-Szmek
-# Copyright 2013 David Strauss
-# Copyright 2016 Luke Shumaker
-#
-# 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 $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk
-include $(topsrcdir)/build-aux/Makefile.head.mk
-
-ifneq ($(ENABLE_COMPAT_LIBS),)
-libsystemd-%.c: src/compat-libs/libsystemd-%.sym
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)sed -r -n 's/^ +(sd_.*);/obsolete_lib(\1,$(notdir $(basename $<)));/p' <$< >$@
-
-BUILT_SOURCES += \
- libsystemd-journal.c \
- libsystemd-login.c \
- libsystemd-id128.c \
- libsystemd-daemon.c
-
-nodist_libsystemd_journal_la_SOURCES = \
- libsystemd-journal.c
-
-libsystemd_journal_la_SOURCES = \
- src/compat-libs/libsystemd-journal.sym
-
-libsystemd_journal_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_journal_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \
- -Wl,--version-script=$(srcdir)/libsystemd-journal.sym
-
-libsystemd_journal_la_LIBADD = \
- libsystemd-journal-internal.la \
- libsystemd-internal.la
-
-nodist_libsystemd_login_la_SOURCES = \
- libsystemd-login.c
-
-libsystemd_login_la_SOURCES = \
- src/compat-libs/libsystemd-login.sym
-
-libsystemd_login_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_login_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_LOGIN_CURRENT):$(LIBSYSTEMD_LOGIN_REVISION):$(LIBSYSTEMD_LOGIN_AGE) \
- -Wl,--version-script=$(srcdir)/libsystemd-login.sym
-
-libsystemd_login_la_LIBADD = \
- libsystemd-internal.la
-
-nodist_libsystemd_id128_la_SOURCES = \
- libsystemd-id128.c
-
-libsystemd_id128_la_SOURCES = \
- src/compat-libs/libsystemd-id128.sym
-
-libsystemd_id128_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_id128_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \
- -Wl,--version-script=$(srcdir)/libsystemd-id128.sym
-
-libsystemd_id128_la_LIBADD = \
- libsystemd-internal.la
-
-nodist_libsystemd_daemon_la_SOURCES = \
- libsystemd-daemon.c
-
-libsystemd_daemon_la_SOURCES = \
- src/compat-libs/libsystemd-daemon.sym
-
-libsystemd_daemon_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -imacros$(top_srcdir)/src/compat-libs/linkwarning.h
-
-libsystemd_daemon_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \
- -Wl,--version-script=$(srcdir)/libsystemd-daemon.sym
-
-libsystemd_daemon_la_LIBADD = \
- libsystemd-internal.la
-
-lib_LTLIBRARIES += \
- libsystemd-journal.la \
- libsystemd-login.la \
- libsystemd-id128.la \
- libsystemd-daemon.la
-
-pkgconfiglib_DATA += \
- src/compat-libs/libsystemd-journal.pc \
- src/compat-libs/libsystemd-login.pc \
- src/compat-libs/libsystemd-id128.pc \
- src/compat-libs/libsystemd-daemon.pc
-
-# move lib from $(libdir) to $(libdir) and update devel link, if needed
-compat-lib-install-hook:
- libname=libsystemd-login.so && $(move-to-libdir)
- libname=libsystemd-journal.so && $(move-to-libdir)
- libname=libsystemd-id128.so && $(move-to-libdir)
- libname=libsystemd-daemon.so && $(move-to-libdir)
-
-compat-lib-uninstall-hook:
- rm -f $(DESTDIR)$(libdir)/libsystemd-login.so*
- rm -f $(DESTDIR)$(libdir)/libsystemd-journal.so*
- rm -f $(DESTDIR)$(libdir)/libsystemd-id128.so*
- rm -f $(DESTDIR)$(libdir)/libsystemd-daemon.so*
-
-INSTALL_EXEC_HOOKS += compat-lib-install-hook
-UNINSTALL_EXEC_HOOKS += compat-lib-uninstall-hook
-endif # ENABLE_COMPAT_LIBS
-
-EXTRA_DIST += \
- src/compat-libs/linkwarning.h \
- src/compat-libs/libsystemd-journal.pc.in \
- src/compat-libs/libsystemd-login.pc.in \
- src/compat-libs/libsystemd-id128.pc.in \
- src/compat-libs/libsystemd-daemon.pc.in
-
-include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/libsystemd/compat-libs/libsystemd-daemon.pc.in b/src/libsystemd/compat-libs/libsystemd-daemon.pc.in
deleted file mode 100644
index 847afc9d60..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-daemon.pc.in
+++ /dev/null
@@ -1,19 +0,0 @@
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: systemd
-Description: systemd Daemon Utility Library - deprecated
-URL: @PACKAGE_URL@
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lsystemd
-Cflags: -I${includedir}
diff --git a/src/libsystemd/compat-libs/libsystemd-daemon.sym b/src/libsystemd/compat-libs/libsystemd-daemon.sym
deleted file mode 100644
index f440238931..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-daemon.sym
+++ /dev/null
@@ -1,27 +0,0 @@
-/***
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-***/
-
-/* Original symbols from systemd v31 */
-
-LIBSYSTEMD_DAEMON_31 {
-global:
- sd_booted;
- sd_is_fifo;
- sd_is_mq;
- sd_is_socket;
- sd_is_socket_inet;
- sd_is_socket_unix;
- sd_is_special;
- sd_listen_fds;
- sd_notify;
- sd_notifyf;
-local:
- *;
-};
diff --git a/src/libsystemd/compat-libs/libsystemd-id128.pc.in b/src/libsystemd/compat-libs/libsystemd-id128.pc.in
deleted file mode 100644
index 80f8fee6c3..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-id128.pc.in
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: systemd
-Description: systemd 128 Bit ID Utility Library - deprecated
-URL: @PACKAGE_URL@
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lsystemd
-Cflags: -I${includedir}
diff --git a/src/libsystemd/compat-libs/libsystemd-id128.sym b/src/libsystemd/compat-libs/libsystemd-id128.sym
deleted file mode 100644
index 604c0026c6..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-id128.sym
+++ /dev/null
@@ -1,21 +0,0 @@
-/***
- This file is part of systemd.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-***/
-
-/* Original symbols from systemd v38 */
-
-LIBSYSTEMD_ID128_38 {
-global:
- sd_id128_to_string;
- sd_id128_from_string;
- sd_id128_randomize;
- sd_id128_get_machine;
- sd_id128_get_boot;
-local:
- *;
-};
diff --git a/src/libsystemd/compat-libs/libsystemd-journal.pc.in b/src/libsystemd/compat-libs/libsystemd-journal.pc.in
deleted file mode 100644
index 395f71005b..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-journal.pc.in
+++ /dev/null
@@ -1,19 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: systemd
-Description: systemd Journal Utility Library - deprecated
-URL: @PACKAGE_URL@
-Version: @PACKAGE_VERSION@
-Requires: libsystemd = @PACKAGE_VERSION@
-Libs: -L${libdir} -lsystemd
-Cflags: -I${includedir}
diff --git a/src/libsystemd/compat-libs/libsystemd-journal.sym b/src/libsystemd/compat-libs/libsystemd-journal.sym
deleted file mode 100644
index 4eb15910d2..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-journal.sym
+++ /dev/null
@@ -1,111 +0,0 @@
-/***
- This file is part of systemd.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-***/
-
-/* Original symbols from systemd v38 */
-
-LIBSYSTEMD_JOURNAL_38 {
-global:
- sd_journal_print;
- sd_journal_printv;
- sd_journal_send;
- sd_journal_sendv;
- sd_journal_stream_fd;
- sd_journal_open;
- sd_journal_close;
- sd_journal_previous;
- sd_journal_next;
- sd_journal_previous_skip;
- sd_journal_next_skip;
- sd_journal_get_realtime_usec;
- sd_journal_get_monotonic_usec;
- sd_journal_get_data;
- sd_journal_enumerate_data;
- sd_journal_restart_data;
- sd_journal_add_match;
- sd_journal_flush_matches;
- sd_journal_seek_head;
- sd_journal_seek_tail;
- sd_journal_seek_monotonic_usec;
- sd_journal_seek_realtime_usec;
- sd_journal_seek_cursor;
- sd_journal_get_cursor;
- sd_journal_get_fd;
- sd_journal_process;
-local:
- *;
-};
-
-LIBSYSTEMD_JOURNAL_183 {
-global:
- sd_journal_print_with_location;
- sd_journal_printv_with_location;
- sd_journal_send_with_location;
- sd_journal_sendv_with_location;
-} LIBSYSTEMD_JOURNAL_38;
-
-LIBSYSTEMD_JOURNAL_184 {
-global:
- sd_journal_get_cutoff_realtime_usec;
- sd_journal_get_cutoff_monotonic_usec;
-} LIBSYSTEMD_JOURNAL_183;
-
-LIBSYSTEMD_JOURNAL_187 {
-global:
- sd_journal_wait;
- sd_journal_open_directory;
- sd_journal_add_disjunction;
-} LIBSYSTEMD_JOURNAL_184;
-
-LIBSYSTEMD_JOURNAL_188 {
-global:
- sd_journal_perror;
- sd_journal_perror_with_location;
-} LIBSYSTEMD_JOURNAL_187;
-
-LIBSYSTEMD_JOURNAL_190 {
-global:
- sd_journal_get_usage;
-} LIBSYSTEMD_JOURNAL_188;
-
-LIBSYSTEMD_JOURNAL_195 {
-global:
- sd_journal_test_cursor;
- sd_journal_query_unique;
- sd_journal_enumerate_unique;
- sd_journal_restart_unique;
-} LIBSYSTEMD_JOURNAL_190;
-
-LIBSYSTEMD_JOURNAL_196 {
-global:
- sd_journal_get_catalog;
- sd_journal_get_catalog_for_message_id;
- sd_journal_set_data_threshold;
- sd_journal_get_data_threshold;
-} LIBSYSTEMD_JOURNAL_195;
-
-LIBSYSTEMD_JOURNAL_198 {
-global:
- sd_journal_reliable_fd;
-} LIBSYSTEMD_JOURNAL_196;
-
-LIBSYSTEMD_JOURNAL_201 {
-global:
- sd_journal_get_events;
- sd_journal_get_timeout;
-} LIBSYSTEMD_JOURNAL_198;
-
-LIBSYSTEMD_JOURNAL_202 {
-global:
- sd_journal_add_conjunction;
-} LIBSYSTEMD_JOURNAL_201;
-
-LIBSYSTEMD_JOURNAL_205 {
-global:
- sd_journal_open_files;
-} LIBSYSTEMD_JOURNAL_202;
diff --git a/src/libsystemd/compat-libs/libsystemd-login.pc.in b/src/libsystemd/compat-libs/libsystemd-login.pc.in
deleted file mode 100644
index db3f79c99a..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-login.pc.in
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: systemd
-Description: systemd Login Utility Library - deprecated
-URL: @PACKAGE_URL@
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lsystemd
-Cflags: -I${includedir}
diff --git a/src/libsystemd/compat-libs/libsystemd-login.sym b/src/libsystemd/compat-libs/libsystemd-login.sym
deleted file mode 100644
index 54aa91c609..0000000000
--- a/src/libsystemd/compat-libs/libsystemd-login.sym
+++ /dev/null
@@ -1,87 +0,0 @@
-/***
- This file is part of systemd.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-***/
-
-/* Original symbols from systemd v31 */
-
-LIBSYSTEMD_LOGIN_31 {
-global:
- sd_get_seats;
- sd_get_sessions;
- sd_get_uids;
- sd_login_monitor_flush;
- sd_login_monitor_get_fd;
- sd_login_monitor_new;
- sd_login_monitor_unref;
- sd_pid_get_owner_uid;
- sd_pid_get_session;
- sd_seat_can_multi_session;
- sd_seat_get_active;
- sd_seat_get_sessions;
- sd_session_get_seat;
- sd_session_get_uid;
- sd_session_is_active;
- sd_uid_get_seats;
- sd_uid_get_sessions;
- sd_uid_get_state;
- sd_uid_is_on_seat;
-local:
- *;
-};
-
-LIBSYSTEMD_LOGIN_38 {
-global:
- sd_pid_get_unit;
- sd_session_get_service;
-} LIBSYSTEMD_LOGIN_31;
-
-LIBSYSTEMD_LOGIN_43 {
-global:
- sd_session_get_type;
- sd_session_get_class;
- sd_session_get_display;
-} LIBSYSTEMD_LOGIN_38;
-
-LIBSYSTEMD_LOGIN_186 {
-global:
- sd_session_get_state;
- sd_seat_can_tty;
- sd_seat_can_graphical;
-} LIBSYSTEMD_LOGIN_43;
-
-LIBSYSTEMD_LOGIN_198 {
-global:
- sd_session_get_tty;
-} LIBSYSTEMD_LOGIN_186;
-
-LIBSYSTEMD_LOGIN_201 {
-global:
- sd_login_monitor_get_events;
- sd_login_monitor_get_timeout;
-} LIBSYSTEMD_LOGIN_198;
-
-LIBSYSTEMD_LOGIN_202 {
-global:
- sd_pid_get_user_unit;
- sd_pid_get_machine_name;
-} LIBSYSTEMD_LOGIN_201;
-
-LIBSYSTEMD_LOGIN_203 {
-global:
- sd_get_machine_names;
-} LIBSYSTEMD_LOGIN_202;
-
-LIBSYSTEMD_LOGIN_205 {
-global:
- sd_pid_get_slice;
-} LIBSYSTEMD_LOGIN_203;
-
-LIBSYSTEMD_LOGIN_207 {
-global:
- sd_session_get_vt;
-} LIBSYSTEMD_LOGIN_205;
diff --git a/src/libsystemd/compat-libs/linkwarning.h b/src/libsystemd/compat-libs/linkwarning.h
deleted file mode 100644
index 79ece9e7d1..0000000000
--- a/src/libsystemd/compat-libs/linkwarning.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***
- This file is part of systemd, but is heavily based on
- glibc's libc-symbols.h.
-
- Copyright (C) 1995-1998,2000-2006,2008,2009 Free Software Foundation, Inc
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#define __make_section_unallocated(section_string) \
- asm (".section " section_string "\n\t.previous");
-
-#define __sec_comment "\n#APP\n\t#"
-
-#define link_warning(symbol, msg) \
- __make_section_unallocated (".gnu.warning." #symbol) \
- static const char __evoke_link_warning_##symbol[] \
- __attribute__ ((used, section (".gnu.warning." #symbol __sec_comment))) \
- = msg
-
-#define obsolete_lib(name, lib) \
- link_warning(name, #name " was moved to libsystemd. Do not use " #lib ".")
diff --git a/src/libsystemd/include/systemd/_sd-common.h b/src/libsystemd/include/systemd/_sd-common.h
index 2d4e1f26e1..3bb886be75 100644
--- a/src/libsystemd/include/systemd/_sd-common.h
+++ b/src/libsystemd/include/systemd/_sd-common.h
@@ -74,7 +74,7 @@
#endif
#define _SD_DEFINE_POINTER_CLEANUP_FUNC(type, func) \
- static inline void func##p(type **p) { \
+ static __inline__ void func##p(type **p) { \
if (*p) \
func(*p); \
} \
diff --git a/src/libsystemd/include/systemd/sd-bus-protocol.h b/src/libsystemd/include/systemd/sd-bus-protocol.h
index 47b256d5b9..623cee0c50 100644
--- a/src/libsystemd/include/systemd/sd-bus-protocol.h
+++ b/src/libsystemd/include/systemd/sd-bus-protocol.h
@@ -59,7 +59,7 @@ enum {
SD_BUS_TYPE_STRUCT_END = ')',
SD_BUS_TYPE_DICT_ENTRY = 'e', /* not actually used in signatures */
SD_BUS_TYPE_DICT_ENTRY_BEGIN = '{',
- SD_BUS_TYPE_DICT_ENTRY_END = '}',
+ SD_BUS_TYPE_DICT_ENTRY_END = '}'
};
/* Well-known errors. Note that this is only a sanitized subset of the
diff --git a/src/libsystemd/include/systemd/sd-bus-vtable.h b/src/libsystemd/include/systemd/sd-bus-vtable.h
index 9363f5425a..2b684b5678 100644
--- a/src/libsystemd/include/systemd/sd-bus-vtable.h
+++ b/src/libsystemd/include/systemd/sd-bus-vtable.h
@@ -34,7 +34,7 @@ enum {
_SD_BUS_VTABLE_METHOD = 'M',
_SD_BUS_VTABLE_SIGNAL = 'S',
_SD_BUS_VTABLE_PROPERTY = 'P',
- _SD_BUS_VTABLE_WRITABLE_PROPERTY = 'W',
+ _SD_BUS_VTABLE_WRITABLE_PROPERTY = 'W'
};
enum {
diff --git a/src/libsystemd/include/systemd/sd-bus.h b/src/libsystemd/include/systemd/sd-bus.h
index 2ded47c2b6..3c1b4b97a4 100644
--- a/src/libsystemd/include/systemd/sd-bus.h
+++ b/src/libsystemd/include/systemd/sd-bus.h
@@ -89,13 +89,13 @@ enum {
SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 32,
SD_BUS_CREDS_DESCRIPTION = 1ULL << 33,
SD_BUS_CREDS_AUGMENT = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
- _SD_BUS_CREDS_ALL = (1ULL << 34) -1,
+ _SD_BUS_CREDS_ALL = (1ULL << 34) -1
};
enum {
SD_BUS_NAME_REPLACE_EXISTING = 1ULL << 0,
SD_BUS_NAME_ALLOW_REPLACEMENT = 1ULL << 1,
- SD_BUS_NAME_QUEUE = 1ULL << 2,
+ SD_BUS_NAME_QUEUE = 1ULL << 2
};
/* Callbacks */
diff --git a/src/libsystemd/include/systemd/sd-device.h b/src/libsystemd/include/systemd/sd-device.h
index 5bfca6ecec..c1d07561d7 100644
--- a/src/libsystemd/include/systemd/sd-device.h
+++ b/src/libsystemd/include/systemd/sd-device.h
@@ -22,6 +22,7 @@
***/
#include <inttypes.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include "_sd-common.h"
diff --git a/src/libsystemd/include/systemd/sd-dhcp-client.h b/src/libsystemd/include/systemd/sd-dhcp-client.h
index 897a6b0223..f7bd5c4b7a 100644
--- a/src/libsystemd/include/systemd/sd-dhcp-client.h
+++ b/src/libsystemd/include/systemd/sd-dhcp-client.h
@@ -84,26 +84,57 @@ enum {
typedef struct sd_dhcp_client sd_dhcp_client;
-typedef void (*sd_dhcp_client_cb_t)(sd_dhcp_client *client, int event,
- void *userdata);
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
- void *userdata);
-
-int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option);
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
- const struct in_addr *last_address);
-int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast);
-int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type);
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
- const uint8_t *data, size_t data_len);
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
- const uint8_t **data, size_t *data_len);
-int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci);
-int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
+typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
+int sd_dhcp_client_set_callback(
+ sd_dhcp_client *client,
+ sd_dhcp_client_callback_t cb,
+ void *userdata);
+
+int sd_dhcp_client_set_request_option(
+ sd_dhcp_client *client,
+ uint8_t option);
+int sd_dhcp_client_set_request_address(
+ sd_dhcp_client *client,
+ const struct in_addr *last_address);
+int sd_dhcp_client_set_request_broadcast(
+ sd_dhcp_client *client,
+ int broadcast);
+int sd_dhcp_client_set_index(
+ sd_dhcp_client *client,
+ int interface_index);
+int sd_dhcp_client_set_mac(
+ sd_dhcp_client *client,
+ const uint8_t *addr,
+ size_t addr_len,
+ uint16_t arp_type);
+int sd_dhcp_client_set_client_id(
+ sd_dhcp_client *client,
+ uint8_t type,
+ const uint8_t *data,
+ size_t data_len);
+int sd_dhcp_client_set_iaid_duid(
+ sd_dhcp_client *client,
+ uint32_t iaid,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len);
+int sd_dhcp_client_get_client_id(
+ sd_dhcp_client *client,
+ uint8_t *type,
+ const uint8_t **data,
+ size_t *data_len);
+int sd_dhcp_client_set_mtu(
+ sd_dhcp_client *client,
+ uint32_t mtu);
+int sd_dhcp_client_set_hostname(
+ sd_dhcp_client *client,
+ const char *hostname);
+int sd_dhcp_client_set_vendor_class_identifier(
+ sd_dhcp_client *client,
+ const char *vci);
+int sd_dhcp_client_get_lease(
+ sd_dhcp_client *client,
+ sd_dhcp_lease **ret);
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);
@@ -113,7 +144,10 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
int sd_dhcp_client_new(sd_dhcp_client **ret);
-int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int priority);
+int sd_dhcp_client_attach_event(
+ sd_dhcp_client *client,
+ sd_event *event,
+ int64_t priority);
int sd_dhcp_client_detach_event(sd_dhcp_client *client);
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
diff --git a/src/libsystemd/include/systemd/sd-dhcp-server.h b/src/libsystemd/include/systemd/sd-dhcp-server.h
index ede8f18533..bbb2bb203c 100644
--- a/src/libsystemd/include/systemd/sd-dhcp-server.h
+++ b/src/libsystemd/include/systemd/sd-dhcp-server.h
@@ -37,7 +37,7 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
-int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int priority);
+int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t priority);
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
@@ -51,6 +51,7 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
+int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
diff --git a/src/libsystemd/include/systemd/sd-dhcp6-client.h b/src/libsystemd/include/systemd/sd-dhcp6-client.h
index 9c05336ab9..6bcd9862c9 100644
--- a/src/libsystemd/include/systemd/sd-dhcp6-client.h
+++ b/src/libsystemd/include/systemd/sd-dhcp6-client.h
@@ -76,29 +76,52 @@ enum {
typedef struct sd_dhcp6_client sd_dhcp6_client;
-typedef void (*sd_dhcp6_client_cb_t)(sd_dhcp6_client *client, int event,
- void *userdata);
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
- sd_dhcp6_client_cb_t cb, void *userdata);
-
-int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
-int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address);
-int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type);
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
- size_t duid_len);
-int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled);
-int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled);
-int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
- uint16_t option);
-
-int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret);
+typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event, void *userdata);
+int sd_dhcp6_client_set_callback(
+ sd_dhcp6_client *client,
+ sd_dhcp6_client_callback_t cb,
+ void *userdata);
+
+int sd_dhcp6_client_set_index(
+ sd_dhcp6_client *client,
+ int interface_index);
+int sd_dhcp6_client_set_local_address(
+ sd_dhcp6_client *client,
+ const struct in6_addr *local_address);
+int sd_dhcp6_client_set_mac(
+ sd_dhcp6_client *client,
+ const uint8_t *addr,
+ size_t addr_len,
+ uint16_t arp_type);
+int sd_dhcp6_client_set_duid(
+ sd_dhcp6_client *client,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len);
+int sd_dhcp6_client_set_iaid(
+ sd_dhcp6_client *client,
+ uint32_t iaid);
+int sd_dhcp6_client_set_information_request(
+ sd_dhcp6_client *client,
+ int enabled);
+int sd_dhcp6_client_get_information_request(
+ sd_dhcp6_client *client,
+ int *enabled);
+int sd_dhcp6_client_set_request_option(
+ sd_dhcp6_client *client,
+ uint16_t option);
+
+int sd_dhcp6_client_get_lease(
+ sd_dhcp6_client *client,
+ sd_dhcp6_lease **ret);
int sd_dhcp6_client_stop(sd_dhcp6_client *client);
int sd_dhcp6_client_start(sd_dhcp6_client *client);
int sd_dhcp6_client_is_running(sd_dhcp6_client *client);
-int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
- int priority);
+int sd_dhcp6_client_attach_event(
+ sd_dhcp6_client *client,
+ sd_event *event,
+ int64_t priority);
int sd_dhcp6_client_detach_event(sd_dhcp6_client *client);
sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client);
sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client);
diff --git a/src/libsystemd/include/systemd/sd-event.h b/src/libsystemd/include/systemd/sd-event.h
index 1ea97e47f8..531ace1c34 100644
--- a/src/libsystemd/include/systemd/sd-event.h
+++ b/src/libsystemd/include/systemd/sd-event.h
@@ -55,7 +55,7 @@ enum {
SD_EVENT_RUNNING,
SD_EVENT_EXITING,
SD_EVENT_FINISHED,
- SD_EVENT_PREPARING,
+ SD_EVENT_PREPARING
};
enum {
@@ -69,7 +69,11 @@ 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
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;
+#endif
int sd_event_default(sd_event **e);
diff --git a/src/libsystemd/include/systemd/sd-id128.h b/src/libsystemd/include/systemd/sd-id128.h
index a3bf5897b8..4dff0b9b81 100644
--- a/src/libsystemd/include/systemd/sd-id128.h
+++ b/src/libsystemd/include/systemd/sd-id128.h
@@ -100,11 +100,11 @@ int sd_id128_get_boot(sd_id128_t *ret);
((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \
0 })
-_sd_pure_ static inline int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
+_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
return memcmp(&a, &b, 16) == 0;
}
-_sd_pure_ static inline int sd_id128_is_null(sd_id128_t a) {
+_sd_pure_ static __inline__ int sd_id128_is_null(sd_id128_t a) {
return a.qwords[0] == 0 && a.qwords[1] == 0;
}
diff --git a/src/libsystemd/include/systemd/sd-ipv4acd.h b/src/libsystemd/include/systemd/sd-ipv4acd.h
index 0fb52b33f9..93db7a4a6c 100644
--- a/src/libsystemd/include/systemd/sd-ipv4acd.h
+++ b/src/libsystemd/include/systemd/sd-ipv4acd.h
@@ -37,12 +37,12 @@ enum {
};
typedef struct sd_ipv4acd sd_ipv4acd;
-typedef void (*sd_ipv4acd_cb_t)(sd_ipv4acd *ll, int event, void *userdata);
+typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *ll, int event, void *userdata);
int sd_ipv4acd_detach_event(sd_ipv4acd *ll);
-int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int priority);
+int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority);
int sd_ipv4acd_get_address(sd_ipv4acd *ll, struct in_addr *address);
-int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_cb_t cb, void *userdata);
+int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata);
int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr);
int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index);
int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address);
diff --git a/src/libsystemd/include/systemd/sd-ipv4ll.h b/src/libsystemd/include/systemd/sd-ipv4ll.h
index 2d1d51a473..9167623167 100644
--- a/src/libsystemd/include/systemd/sd-ipv4ll.h
+++ b/src/libsystemd/include/systemd/sd-ipv4ll.h
@@ -36,12 +36,12 @@ enum {
};
typedef struct sd_ipv4ll sd_ipv4ll;
-typedef void (*sd_ipv4ll_cb_t)(sd_ipv4ll *ll, int event, void *userdata);
+typedef void (*sd_ipv4ll_callback_t)(sd_ipv4ll *ll, int event, void *userdata);
int sd_ipv4ll_detach_event(sd_ipv4ll *ll);
-int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int priority);
+int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority);
int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address);
-int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata);
+int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata);
int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr);
int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index);
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address);
diff --git a/src/libsystemd/include/systemd/sd-journal.h b/src/libsystemd/include/systemd/sd-journal.h
index 559a8fa929..3e61feb81f 100644
--- a/src/libsystemd/include/systemd/sd-journal.h
+++ b/src/libsystemd/include/systemd/sd-journal.h
@@ -67,12 +67,13 @@ typedef struct sd_journal sd_journal;
/* Open flags */
enum {
- SD_JOURNAL_LOCAL_ONLY = 1,
- SD_JOURNAL_RUNTIME_ONLY = 2,
- SD_JOURNAL_SYSTEM = 4,
- SD_JOURNAL_CURRENT_USER = 8,
+ SD_JOURNAL_LOCAL_ONLY = 1 << 0,
+ SD_JOURNAL_RUNTIME_ONLY = 1 << 1,
+ SD_JOURNAL_SYSTEM = 1 << 2,
+ SD_JOURNAL_CURRENT_USER = 1 << 3,
+ SD_JOURNAL_OS_ROOT = 1 << 4,
- SD_JOURNAL_SYSTEM_ONLY = SD_JOURNAL_SYSTEM, /* deprecated name */
+ SD_JOURNAL_SYSTEM_ONLY = SD_JOURNAL_SYSTEM /* deprecated name */
};
/* Wakeup event types */
@@ -84,8 +85,10 @@ enum {
int sd_journal_open(sd_journal **ret, int flags);
int sd_journal_open_directory(sd_journal **ret, const char *path, int flags);
+int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags);
int sd_journal_open_files(sd_journal **ret, const char **paths, int flags);
-int sd_journal_open_container(sd_journal **ret, const char *machine, int flags);
+int sd_journal_open_files_fd(sd_journal **ret, int fds[], unsigned n_fds, int flags);
+int sd_journal_open_container(sd_journal **ret, const char *machine, int flags); /* deprecated */
void sd_journal_close(sd_journal *j);
int sd_journal_previous(sd_journal *j);
diff --git a/src/libsystemd/include/systemd/sd-lldp.h b/src/libsystemd/include/systemd/sd-lldp.h
index 45d8a36697..391e7c2a2e 100644
--- a/src/libsystemd/include/systemd/sd-lldp.h
+++ b/src/libsystemd/include/systemd/sd-lldp.h
@@ -30,57 +30,147 @@
_SD_BEGIN_DECLARATIONS;
+typedef struct sd_lldp sd_lldp;
+typedef struct sd_lldp_neighbor sd_lldp_neighbor;
+
+/* IEEE 802.3AB Clause 9: TLV Types */
enum {
- SD_LLDP_EVENT_UPDATE_INFO = 0,
+ SD_LLDP_TYPE_END = 0,
+ SD_LLDP_TYPE_CHASSIS_ID = 1,
+ SD_LLDP_TYPE_PORT_ID = 2,
+ SD_LLDP_TYPE_TTL = 3,
+ SD_LLDP_TYPE_PORT_DESCRIPTION = 4,
+ SD_LLDP_TYPE_SYSTEM_NAME = 5,
+ SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
+ SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
+ SD_LLDP_TYPE_MGMT_ADDRESS = 8,
+ SD_LLDP_TYPE_PRIVATE = 127,
};
+/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
enum {
- SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE,
- SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE,
- SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE,
+ SD_LLDP_CHASSIS_SUBTYPE_RESERVED = 0,
+ SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1,
+ SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2,
+ SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3,
+ SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4,
+ SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5,
+ SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6,
+ SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7,
};
-typedef struct sd_lldp sd_lldp;
-typedef struct sd_lldp_packet sd_lldp_packet;
+/* IEEE 802.3AB Clause 9.5.3: Port subtype */
+enum {
+ SD_LLDP_PORT_SUBTYPE_RESERVED = 0,
+ SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
+ SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
+ SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
+ SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4,
+ SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
+ SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
+ SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
+};
-typedef void (*sd_lldp_cb_t)(sd_lldp *lldp, int event, void *userdata);
+enum {
+ SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
+ SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
+ SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
+ SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
+ SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
+ SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
+ SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
+ SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
+ SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
+ SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
+ SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10,
+};
-int sd_lldp_new(int ifindex, const char *ifname, const struct ether_addr *mac, sd_lldp **ret);
-sd_lldp* sd_lldp_unref(sd_lldp *lldp);
+#define SD_LLDP_SYSTEM_CAPABILITIES_ALL ((uint16_t) -1)
-int sd_lldp_start(sd_lldp *lldp);
-int sd_lldp_stop(sd_lldp *lldp);
+#define SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS \
+ ((uint16_t) \
+ (SD_LLDP_SYSTEM_CAPABILITIES_REPEATER| \
+ SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE| \
+ SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP| \
+ SD_LLDP_SYSTEM_CAPABILITIES_ROUTER| \
+ SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS| \
+ SD_LLDP_SYSTEM_CAPABILITIES_CVLAN| \
+ SD_LLDP_SYSTEM_CAPABILITIES_SVLAN| \
+ SD_LLDP_SYSTEM_CAPABILITIES_TPMR))
-int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int priority);
-int sd_lldp_detach_event(sd_lldp *lldp);
+#define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 }
+#define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f }
-int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_cb_t cb, void *userdata);
-int sd_lldp_save(sd_lldp *lldp, const char *file);
+enum {
+ SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1,
+ SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2,
+ SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3,
+ SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4,
+ SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5,
+ SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6,
+ SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7,
+};
-int sd_lldp_packet_read_chassis_id(sd_lldp_packet *tlv, uint8_t *type, uint8_t **data, uint16_t *length);
-int sd_lldp_packet_read_port_id(sd_lldp_packet *tlv, uint8_t *type, uint8_t **data, uint16_t *length);
-int sd_lldp_packet_read_ttl(sd_lldp_packet *tlv, uint16_t *ttl);
-int sd_lldp_packet_read_system_name(sd_lldp_packet *tlv, char **data, uint16_t *length);
-int sd_lldp_packet_read_system_description(sd_lldp_packet *tlv, char **data, uint16_t *length);
-int sd_lldp_packet_read_system_capability(sd_lldp_packet *tlv, uint16_t *data);
-int sd_lldp_packet_read_port_description(sd_lldp_packet *tlv, char **data, uint16_t *length);
+typedef enum sd_lldp_event {
+ SD_LLDP_EVENT_ADDED = 'a',
+ SD_LLDP_EVENT_REMOVED = 'r',
+ SD_LLDP_EVENT_UPDATED = 'u',
+ SD_LLDP_EVENT_REFRESHED = 'f',
+} sd_lldp_event;
-/* IEEE 802.1 organizationally specific TLVs */
-int sd_lldp_packet_read_port_vlan_id(sd_lldp_packet *tlv, uint16_t *id);
-int sd_lldp_packet_read_port_protocol_vlan_id(sd_lldp_packet *tlv, uint8_t *flags, uint16_t *id);
-int sd_lldp_packet_read_vlan_name(sd_lldp_packet *tlv, uint16_t *vlan_id, char **name, uint16_t *length);
-int sd_lldp_packet_read_management_vid(sd_lldp_packet *tlv, uint16_t *id);
-int sd_lldp_packet_read_link_aggregation(sd_lldp_packet *tlv, uint8_t *status, uint32_t *id);
+typedef void (*sd_lldp_callback_t)(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata);
-sd_lldp_packet *sd_lldp_packet_ref(sd_lldp_packet *tlv);
-sd_lldp_packet *sd_lldp_packet_unref(sd_lldp_packet *tlv);
+int sd_lldp_new(sd_lldp **ret, int ifindex);
+sd_lldp* sd_lldp_unref(sd_lldp *lldp);
-int sd_lldp_packet_get_destination_type(sd_lldp_packet *tlv, int *dest);
+int sd_lldp_start(sd_lldp *lldp);
+int sd_lldp_stop(sd_lldp *lldp);
+
+int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int64_t priority);
+int sd_lldp_detach_event(sd_lldp *lldp);
-int sd_lldp_get_packets(sd_lldp *lldp, sd_lldp_packet ***tlvs);
+int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata);
+
+/* Controls how much and what to store in the neighbors database */
+int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t n);
+int sd_lldp_match_capabilities(sd_lldp *lldp, uint16_t mask);
+int sd_lldp_set_filter_address(sd_lldp *lldp, const struct ether_addr *address);
+
+int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***neighbors);
+
+int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size);
+sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n);
+sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n);
+
+/* Access to LLDP frame metadata */
+int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address);
+int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address);
+int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size);
+
+/* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */
+int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size);
+int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, const char **ret);
+int sd_lldp_neighbor_get_port_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size);
+int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const char **ret);
+int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret);
+int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret);
+int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret);
+int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret);
+int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
+int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
+
+/* Low-level, iterative TLV access. This is for evertyhing else, it iteratively goes through all available TLVs
+ * (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */
+int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n);
+int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n);
+int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type);
+int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type);
+int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], uint8_t *subtype);
+int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[3], uint8_t subtype);
+int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_lldp, sd_lldp_unref);
-_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_lldp_packet, sd_lldp_packet_unref);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_lldp_neighbor, sd_lldp_neighbor_unref);
_SD_END_DECLARATIONS;
diff --git a/src/libsystemd/include/systemd/sd-login.h b/src/libsystemd/include/systemd/sd-login.h
index 3c10ff032f..e3ecbd8378 100644
--- a/src/libsystemd/include/systemd/sd-login.h
+++ b/src/libsystemd/include/systemd/sd-login.h
@@ -108,7 +108,7 @@ int sd_peer_get_slice(int fd, char **slice);
int sd_peer_get_user_slice(int fd, char **slice);
/* Similar to sd_pid_get_machine_name(), but retrieves data about the
- * peer of a a connected AF_UNIX socket */
+ * peer of a connected AF_UNIX socket */
int sd_peer_get_machine_name(int fd, char **machine);
/* Similar to sd_pid_get_cgroup(), but retrieves data about the peer
diff --git a/src/libsystemd/include/systemd/sd-messages.h b/src/libsystemd/include/systemd/sd-messages.h
index 1aeac17851..1865e0492f 100644
--- a/src/libsystemd/include/systemd/sd-messages.h
+++ b/src/libsystemd/include/systemd/sd-messages.h
@@ -82,8 +82,6 @@ _SD_BEGIN_DECLARATIONS;
#define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
-#define SD_MESSAGE_BOOTCHART SD_ID128_MAKE(9f,26,aa,56,2c,f4,40,c2,b1,6c,77,3d,04,79,b5,18)
-
#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d)
#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED SD_ID128_MAKE(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65)
#define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
diff --git a/src/libsystemd/include/systemd/sd-ndisc.h b/src/libsystemd/include/systemd/sd-ndisc.h
index 734701bca3..c77a435d17 100644
--- a/src/libsystemd/include/systemd/sd-ndisc.h
+++ b/src/libsystemd/include/systemd/sd-ndisc.h
@@ -52,7 +52,7 @@ int sd_ndisc_set_callback(sd_ndisc *nd,
int sd_ndisc_set_index(sd_ndisc *nd, int interface_index);
int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr);
-int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int priority);
+int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority);
int sd_ndisc_detach_event(sd_ndisc *nd);
sd_event *sd_ndisc_get_event(sd_ndisc *nd);
diff --git a/src/libsystemd/include/systemd/sd-netlink.h b/src/libsystemd/include/systemd/sd-netlink.h
index 333df4676f..c4cefe4e30 100644
--- a/src/libsystemd/include/systemd/sd-netlink.h
+++ b/src/libsystemd/include/systemd/sd-netlink.h
@@ -64,7 +64,7 @@ int sd_netlink_wait(sd_netlink *nl, uint64_t timeout);
int sd_netlink_add_match(sd_netlink *nl, uint16_t match, sd_netlink_message_handler_t c, void *userdata);
int sd_netlink_remove_match(sd_netlink *nl, uint16_t match, sd_netlink_message_handler_t c, void *userdata);
-int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int priority);
+int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
int sd_netlink_detach_event(sd_netlink *nl);
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
@@ -131,14 +131,16 @@ int sd_rtnl_message_link_set_type(sd_netlink_message *m, unsigned type);
int sd_rtnl_message_link_set_family(sd_netlink_message *m, unsigned family);
int sd_rtnl_message_link_get_ifindex(sd_netlink_message *m, int *ifindex);
int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags);
-int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned *type);
+int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type);
int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
int sd_rtnl_message_route_set_src_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope);
int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags);
+int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table);
int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags);
int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family);
+int sd_rtnl_message_route_set_family(sd_netlink_message *m, int family);
int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol);
int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope);
int sd_rtnl_message_route_get_tos(sd_netlink_message *m, unsigned char *tos);
diff --git a/src/libsystemd/include/systemd/sd-network.h b/src/libsystemd/include/systemd/sd-network.h
index e20d12c44d..0f13e2bae7 100644
--- a/src/libsystemd/include/systemd/sd-network.h
+++ b/src/libsystemd/include/systemd/sd-network.h
@@ -99,11 +99,11 @@ int sd_network_link_get_network_file(int ifindex, char **filename);
/* Get DNS entries for a given link. These are string representations of
* IP addresses */
-int sd_network_link_get_dns(int ifindex, char ***addr);
+int sd_network_link_get_dns(int ifindex, char ***ret);
/* Get NTP entries for a given link. These are domain names or string
* representations of IP addresses */
-int sd_network_link_get_ntp(int ifindex, char ***addr);
+int sd_network_link_get_ntp(int ifindex, char ***ret);
/* Indicates whether or not LLMNR should be enabled for the link
* Possible levels of support: yes, no, resolve
@@ -133,19 +133,17 @@ int sd_network_link_get_dnssec(int ifindex, char **dnssec);
*/
int sd_network_link_get_dnssec_negative_trust_anchors(int ifindex, char ***nta);
-int sd_network_link_get_lldp(int ifindex, char **lldp);
-
/* Get the search DNS domain names for a given link. */
int sd_network_link_get_search_domains(int ifindex, char ***domains);
/* Get the route DNS domain names for a given link. */
int sd_network_link_get_route_domains(int ifindex, char ***domains);
-/* Get the CARRIERS to which current link is bound to. */
-int sd_network_link_get_carrier_bound_to(int ifindex, char ***carriers);
+/* Get the carrier interface indexes to which current link is bound to. */
+int sd_network_link_get_carrier_bound_to(int ifindex, int **ifindexes);
/* Get the CARRIERS that are bound to current link. */
-int sd_network_link_get_carrier_bound_by(int ifindex, char ***carriers);
+int sd_network_link_get_carrier_bound_by(int ifindex, int **ifindexes);
/* Get the timezone that was learnt on a specific link. */
int sd_network_link_get_timezone(int ifindex, char **timezone);
diff --git a/src/libsystemd/include/systemd/sd-resolve.h b/src/libsystemd/include/systemd/sd-resolve.h
index 9c3b0ee70f..fe3b910671 100644
--- a/src/libsystemd/include/systemd/sd-resolve.h
+++ b/src/libsystemd/include/systemd/sd-resolve.h
@@ -79,7 +79,7 @@ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec);
int sd_resolve_get_tid(sd_resolve *resolve, pid_t *tid);
-int sd_resolve_attach_event(sd_resolve *resolve, sd_event *e, int priority);
+int sd_resolve_attach_event(sd_resolve *resolve, sd_event *e, int64_t priority);
int sd_resolve_detach_event(sd_resolve *resolve);
sd_event *sd_resolve_get_event(sd_resolve *resolve);
diff --git a/src/libsystemd/libsystemd-internal/Makefile b/src/libsystemd/libsystemd-internal/Makefile
index 5608b561f6..1b3364f7f5 100644
--- a/src/libsystemd/libsystemd-internal/Makefile
+++ b/src/libsystemd/libsystemd-internal/Makefile
@@ -194,12 +194,6 @@ test_bus_match_SOURCES = \
test_bus_match_LDADD = \
libshared.la
-test_bus_proxy_SOURCES = \
- src/libsystemd/sd-bus/test-bus-proxy.c
-
-test_bus_proxy_LDADD = \
- libshared.la
-
test_bus_kernel_SOURCES = \
src/libsystemd/sd-bus/test-bus-kernel.c
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.c
index 2d8ca47987..a19e98e94b 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.c
@@ -38,6 +38,8 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_MASKED, ESHUTDOWN),
+ SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_GENERATED, EADDRNOTAVAIL),
+ SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_LINKED, ELOOP),
SD_BUS_ERROR_MAP(BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, EBADR),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_ISOLATION, EPERM),
SD_BUS_ERROR_MAP(BUS_ERROR_SHUTTING_DOWN, ECANCELED),
@@ -68,10 +70,8 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_NO_NAME_SERVERS, ESRCH),
SD_BUS_ERROR_MAP(BUS_ERROR_INVALID_REPLY, EINVAL),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_RR, ENOENT),
- SD_BUS_ERROR_MAP(BUS_ERROR_NO_RESOURCES, ENOMEM),
SD_BUS_ERROR_MAP(BUS_ERROR_CNAME_LOOP, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_ABORTED, ECANCELED),
- SD_BUS_ERROR_MAP(BUS_ERROR_CONNECTION_FAILURE, ECONNREFUSED),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SERVICE, EUNATCH),
SD_BUS_ERROR_MAP(BUS_ERROR_DNSSEC_FAILED, EHOSTUNREACH),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_TRUST_ANCHOR, EHOSTUNREACH),
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.h b/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.h
index fab8748f46..c8f369cb78 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-common-errors.h
@@ -34,6 +34,8 @@
#define BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC "org.freedesktop.systemd1.TransactionOrderIsCyclic"
#define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive"
#define BUS_ERROR_UNIT_MASKED "org.freedesktop.systemd1.UnitMasked"
+#define BUS_ERROR_UNIT_GENERATED "org.freedesktop.systemd1.UnitGenerated"
+#define BUS_ERROR_UNIT_LINKED "org.freedesktop.systemd1.UnitLinked"
#define BUS_ERROR_JOB_TYPE_NOT_APPLICABLE "org.freedesktop.systemd1.JobTypeNotApplicable"
#define BUS_ERROR_NO_ISOLATION "org.freedesktop.systemd1.NoIsolation"
#define BUS_ERROR_SHUTTING_DOWN "org.freedesktop.systemd1.ShuttingDown"
@@ -67,10 +69,8 @@
#define BUS_ERROR_NO_NAME_SERVERS "org.freedesktop.resolve1.NoNameServers"
#define BUS_ERROR_INVALID_REPLY "org.freedesktop.resolve1.InvalidReply"
#define BUS_ERROR_NO_SUCH_RR "org.freedesktop.resolve1.NoSuchRR"
-#define BUS_ERROR_NO_RESOURCES "org.freedesktop.resolve1.NoResources"
#define BUS_ERROR_CNAME_LOOP "org.freedesktop.resolve1.CNameLoop"
#define BUS_ERROR_ABORTED "org.freedesktop.resolve1.Aborted"
-#define BUS_ERROR_CONNECTION_FAILURE "org.freedesktop.resolve1.ConnectionFailure"
#define BUS_ERROR_NO_SUCH_SERVICE "org.freedesktop.resolve1.NoSuchService"
#define BUS_ERROR_DNSSEC_FAILED "org.freedesktop.resolve1.DnssecFailed"
#define BUS_ERROR_NO_TRUST_ANCHOR "org.freedesktop.resolve1.NoTrustAnchor"
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-control.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-control.c
index 9a975baa24..00de530d58 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-control.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-control.c
@@ -678,6 +678,7 @@ int bus_get_name_creds_kdbus(
(mask & (SD_BUS_CREDS_PPID|
SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|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_TID_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|
@@ -795,6 +796,7 @@ static int bus_get_name_creds_dbus1(
((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|
@@ -947,6 +949,7 @@ static int bus_get_owner_creds_kdbus(sd_bus *bus, uint64_t mask, sd_bus_creds **
(mask & (SD_BUS_CREDS_PPID|
SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|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_TID_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|
@@ -1131,8 +1134,7 @@ static int add_name_change_match(sd_bus *bus,
item->name_change.old_id.id = old_owner_id;
item->name_change.new_id.id = new_owner_id;
- if (name)
- memcpy(item->name_change.name, name, l);
+ memcpy_safe(item->name_change.name, name, l);
/* If the old name is unset or empty, then
* this can match against added names */
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-dump.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-dump.c
index 7c81e7a25d..21a6b20a11 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-dump.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-dump.c
@@ -74,7 +74,7 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
"%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
- m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_normal(),
+ m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", special_glyph(TRIANGULAR_BULLET), ansi_normal(),
ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
m->header->endian,
m->header->flags,
@@ -198,7 +198,7 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
else if (type == SD_BUS_TYPE_DICT_ENTRY)
fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
- level ++;
+ level++;
continue;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-kernel.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-kernel.c
index 0896eeb177..59398b841d 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-kernel.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-kernel.c
@@ -1693,50 +1693,6 @@ int bus_kernel_open_bus_fd(const char *bus, char **path) {
return fd;
}
-int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
- _cleanup_free_ char *path = NULL;
- struct kdbus_cmd *make;
- struct kdbus_item *n;
- const char *name;
- int fd;
-
- fd = bus_kernel_open_bus_fd(bus_name, &path);
- if (fd < 0)
- return fd;
-
- make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd, items)) +
- ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + strlen(ep_name) + 1),
- 8);
- make->size = ALIGN8(offsetof(struct kdbus_cmd, items));
- make->flags = KDBUS_MAKE_ACCESS_WORLD;
-
- n = make->items;
- sprintf(n->str, UID_FMT "-%s", getuid(), ep_name);
- n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
- n->type = KDBUS_ITEM_MAKE_NAME;
- make->size += ALIGN8(n->size);
- name = n->str;
-
- if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
- safe_close(fd);
- return -errno;
- }
-
- if (ep_path) {
- char *p;
-
- p = strjoin(dirname(path), "/", name, NULL);
- if (!p) {
- safe_close(fd);
- return -ENOMEM;
- }
-
- *ep_path = p;
- }
-
- return fd;
-}
-
int bus_kernel_try_close(sd_bus *bus) {
struct kdbus_cmd byebye = { .size = sizeof(byebye) };
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-message.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-message.c
index 6a9e87c2d8..a9359c1528 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-message.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-message.c
@@ -1131,10 +1131,7 @@ _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
assert_return(!m->sealed, -EPERM);
assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
- if (b)
- m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
- else
- m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
+ SET_FLAG(m->header->flags, BUS_MESSAGE_NO_REPLY_EXPECTED, !b);
return 0;
}
@@ -1143,10 +1140,7 @@ _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- if (b)
- m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
- else
- m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
+ SET_FLAG(m->header->flags, BUS_MESSAGE_NO_AUTO_START, !b);
return 0;
}
@@ -1155,10 +1149,7 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- if (b)
- m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
- else
- m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+ SET_FLAG(m->header->flags, BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION, b);
return 0;
}
@@ -1198,7 +1189,7 @@ struct bus_body_part *message_append_part(sd_bus_message *m) {
part->memfd = -1;
m->body_end = part;
- m->n_body_parts ++;
+ m->n_body_parts++;
return part;
}
@@ -1643,7 +1634,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
}
if (type == SD_BUS_TYPE_UNIX_FD)
- m->n_fds ++;
+ m->n_fds++;
if (c->enclosing != SD_BUS_TYPE_ARRAY)
c->index++;
@@ -2387,9 +2378,9 @@ int bus_message_append_ap(
t = types;
if (n_array != (unsigned) -1)
- n_array --;
+ n_array--;
else {
- types ++;
+ types++;
n_struct--;
}
@@ -2631,8 +2622,7 @@ _public_ int sd_bus_message_append_array(
if (r < 0)
return r;
- if (size > 0)
- memcpy(p, ptr, size);
+ memcpy_safe(p, ptr, size);
return 0;
}
@@ -3867,7 +3857,7 @@ static int build_struct_offsets(
if (r < 0)
return r;
if (r == 0 && p[n] != 0) /* except the last item */
- n_variable ++;
+ n_variable++;
n_total++;
p += n;
@@ -4467,9 +4457,9 @@ static int message_read_ap(
t = types;
if (n_array != (unsigned) -1)
- n_array --;
+ n_array--;
else {
- types ++;
+ types++;
n_struct--;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-objects.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-objects.c
index 1f285ae8a6..9bd07ffcab 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-objects.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-objects.c
@@ -145,7 +145,7 @@ static int add_enumerated_to_set(
continue;
}
- if (!object_path_is_valid(*k)){
+ if (!object_path_is_valid(*k)) {
free(*k);
r = -EINVAL;
continue;
@@ -337,7 +337,7 @@ static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c,
if (cap == 0)
cap = CAP_SYS_ADMIN;
else
- cap --;
+ cap--;
r = sd_bus_query_sender_privilege(m, cap);
if (r < 0)
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-slot.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-slot.c
index b1783cd4a9..75c1692bf5 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-slot.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-slot.c
@@ -206,7 +206,7 @@ _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
assert(slot->n_ref > 0);
if (slot->n_ref > 1) {
- slot->n_ref --;
+ slot->n_ref--;
return NULL;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-socket.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-socket.c
index a0008190c5..1486d7cd55 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-socket.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-socket.c
@@ -60,7 +60,7 @@ static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
i->iov_base = NULL;
i->iov_len = 0;
- (*idx) ++;
+ (*idx)++;
}
}
@@ -350,7 +350,7 @@ static int bus_socket_auth_write(sd_bus *b, const char *t) {
if (!p)
return -ENOMEM;
- memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
+ memcpy_safe(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
memcpy(p + b->auth_iovec[0].iov_len, t, l);
b->auth_iovec[0].iov_base = p;
@@ -787,7 +787,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
n = m->n_iovec * sizeof(struct iovec);
iov = alloca(n);
- memcpy(iov, m->iovec, n);
+ memcpy_safe(iov, m->iovec, n);
j = 0;
iovec_advance(iov, &j, *idx);
@@ -998,7 +998,7 @@ int bus_socket_read_message(sd_bus *bus) {
return -ENOMEM;
}
- memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
+ memcpy_safe(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
bus->fds = f;
bus->n_fds += n;
} else
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/bus-track.c b/src/libsystemd/libsystemd-internal/sd-bus/bus-track.c
index 5d08b0a37b..81e6d22816 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/bus-track.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/bus-track.c
@@ -129,7 +129,7 @@ _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) {
assert(track->n_ref > 0);
if (track->n_ref > 1) {
- track->n_ref --;
+ track->n_ref--;
return NULL;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/sd-bus.c b/src/libsystemd/libsystemd-internal/sd-bus/sd-bus.c
index 850949fa25..d3c194e135 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/sd-bus.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/sd-bus.c
@@ -313,10 +313,7 @@ _public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) {
assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
assert_return(!bus_pid_changed(bus), -ECHILD);
- if (b)
- bus->creds_mask |= mask;
- else
- bus->creds_mask &= ~mask;
+ SET_FLAG(bus->creds_mask, mask, b);
/* The well knowns we need unconditionally, so that matches can work */
bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
@@ -530,7 +527,7 @@ static void skip_address_key(const char **p) {
*p += strcspn(*p, ",");
if (**p == ',')
- (*p) ++;
+ (*p)++;
}
static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
@@ -695,7 +692,7 @@ static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
goto fail;
}
- (*p) ++;
+ (*p)++;
if (ul >= n_argv) {
if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
@@ -839,7 +836,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 = offsetof(struct sockaddr_un, sun_path) + strlen("/var/run/dbus/system_bus_socket");
+ b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
return 0;
}
@@ -1668,7 +1665,7 @@ static int dispatch_wqueue(sd_bus *bus) {
* it got full, then all bets are off
* anyway. */
- bus->wqueue_size --;
+ bus->wqueue_size--;
sd_bus_message_unref(bus->wqueue[0]);
memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
bus->windex = 0;
@@ -1717,7 +1714,7 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd
/* Dispatch a queued message */
*m = bus->rqueue[0];
- bus->rqueue_size --;
+ bus->rqueue_size--;
memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
return 1;
}
@@ -1781,7 +1778,7 @@ static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie,
r = bus_write_message(bus, m, hint_sync_call, &idx);
if (r < 0) {
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
return -ECONNRESET;
}
@@ -1809,7 +1806,7 @@ static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie,
if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
return -ENOMEM;
- bus->wqueue[bus->wqueue_size ++] = sd_bus_message_ref(m);
+ bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
}
finish:
@@ -2086,7 +2083,7 @@ _public_ int sd_bus_call(
r = bus_read_message(bus, false, 0);
if (r < 0) {
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
r = -ECONNRESET;
}
@@ -2119,7 +2116,7 @@ _public_ int sd_bus_call(
r = dispatch_wqueue(bus);
if (r < 0) {
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
r = -ECONNRESET;
}
@@ -2257,7 +2254,7 @@ static int process_timeout(sd_bus *bus) {
slot = container_of(c, sd_bus_slot, reply_callback);
- bus->iteration_counter ++;
+ bus->iteration_counter++;
bus->current_message = m;
bus->current_slot = sd_bus_slot_ref(slot);
@@ -2769,7 +2766,7 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
case BUS_OPENING:
r = bus_socket_process_opening(bus);
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
r = 1;
} else if (r < 0)
@@ -2780,7 +2777,7 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
case BUS_AUTHENTICATING:
r = bus_socket_process_authenticating(bus);
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
r = 1;
} else if (r < 0)
@@ -2794,7 +2791,7 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
case BUS_RUNNING:
case BUS_HELLO:
r = process_running(bus, hint_priority, priority, ret);
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
r = 1;
@@ -2917,7 +2914,7 @@ _public_ int sd_bus_flush(sd_bus *bus) {
for (;;) {
r = dispatch_wqueue(bus);
if (r < 0) {
- if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
+ if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
bus_enter_closing(bus);
return -ECONNRESET;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/test-bus-error.c b/src/libsystemd/libsystemd-internal/sd-bus/test-bus-error.c
index b9ceda7a8b..bce3cc31c9 100644
--- a/src/libsystemd/libsystemd-internal/sd-bus/test-bus-error.c
+++ b/src/libsystemd/libsystemd-internal/sd-bus/test-bus-error.c
@@ -146,7 +146,7 @@ static void dump_mapping_table(void) {
}
printf("%s -> %i/%s\n", strna(m->name), m->code, strna(errno_to_name(m->code)));
- m ++;
+ m++;
}
printf("---------------------------\n");
}
diff --git a/src/libsystemd/libsystemd-internal/sd-bus/test-bus-proxy.c b/src/libsystemd/libsystemd-internal/sd-bus/test-bus-proxy.c
deleted file mode 100644
index a9fe44e66c..0000000000
--- a/src/libsystemd/libsystemd-internal/sd-bus/test-bus-proxy.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2015 David Herrmann <dh.herrmann@gmail.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/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-#include <systemd/sd-bus.h>
-
-#include "alloc-util.h"
-#include "bus-dump.h"
-#include "bus-kernel.h"
-#include "bus-util.h"
-#include "log.h"
-#include "util.h"
-
-typedef struct {
- const char *sender;
- int matched_acquired;
-} TestProxyMatch;
-
-static int test_proxy_acquired(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- TestProxyMatch *match = userdata;
- const char *name;
- int r;
-
- r = sd_bus_message_read(m, "s", &name);
- assert_se(r >= 0);
-
- if (!streq_ptr(match->sender, name))
- return 0;
-
- ++match->matched_acquired;
- return 1;
-}
-
-static void test_proxy_matched(void) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *a = NULL;
- _cleanup_free_ char *matchstr = NULL;
- TestProxyMatch match = {};
- const char *me;
- int r;
-
- /* open bus 'a' */
-
- r = sd_bus_new(&a);
- assert_se(r >= 0);
-
- r = sd_bus_set_address(a, "unix:path=/var/run/dbus/system_bus_socket");
- assert_se(r >= 0);
-
- r = sd_bus_set_bus_client(a, true);
- assert_se(r >= 0);
-
- r = sd_bus_start(a);
- assert_se(r >= 0);
-
- r = sd_bus_get_unique_name(a, &me);
- assert_se(r >= 0);
-
- matchstr = strjoin("type='signal',"
- "member='NameAcquired',"
- "destination='",
- me,
- "'",
- NULL);
- assert_se(matchstr);
- r = sd_bus_add_match(a, NULL, matchstr, test_proxy_acquired, &match);
- assert_se(r >= 0);
-
- r = sd_bus_get_unique_name(a, &match.sender);
- assert_se(r >= 0);
-
- /* barrier to guarantee proxy/dbus-daemon handled the previous data */
- r = sd_bus_call_method(a,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetId",
- NULL, NULL, NULL);
- assert_se(r >= 0);
-
- /* now we can be sure the Name* signals were sent */
- do {
- r = sd_bus_process(a, NULL);
- } while (r > 0);
- assert_se(r == 0);
-
- assert_se(match.matched_acquired == 1);
-}
-
-int main(int argc, char **argv) {
- if (access("/var/run/dbus/system_bus_socket", F_OK) < 0)
- return EXIT_TEST_SKIP;
-
- log_parse_environment();
-
- test_proxy_matched();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/libsystemd/libsystemd-internal/sd-daemon/sd-daemon.c b/src/libsystemd/libsystemd-internal/sd-daemon/sd-daemon.c
index 7c79a938b9..fa92199c43 100644
--- a/src/libsystemd/libsystemd-internal/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/libsystemd-internal/sd-daemon/sd-daemon.c
@@ -458,14 +458,12 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
if (sockaddr.un.sun_path[0] == '@')
sockaddr.un.sun_path[0] = 0;
- msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
- if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
- msghdr.msg_namelen = sizeof(struct sockaddr_un);
+ msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un);
have_pid = pid != 0 && pid != getpid();
if (n_fds > 0 || have_pid) {
- /* CMSG_SPACE(0) may return value different then zero, which results in miscalculated controllen. */
+ /* CMSG_SPACE(0) may return value different than zero, which results in miscalculated controllen. */
msghdr.msg_controllen =
(n_fds > 0 ? CMSG_SPACE(sizeof(int) * n_fds) : 0) +
(have_pid ? CMSG_SPACE(sizeof(struct ucred)) : 0);
diff --git a/src/libsystemd/libsystemd-internal/sd-device/device-internal.h b/src/libsystemd/libsystemd-internal/sd-device/device-internal.h
index b96441de56..ab222e27de 100644
--- a/src/libsystemd/libsystemd-internal/sd-device/device-internal.h
+++ b/src/libsystemd/libsystemd-internal/sd-device/device-internal.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -18,8 +20,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include "hashmap.h"
#include "set.h"
diff --git a/src/libsystemd/libsystemd-internal/sd-device/device-private.c b/src/libsystemd/libsystemd-internal/sd-device/device-private.c
index bf7d3c6f9f..51cabcb048 100644
--- a/src/libsystemd/libsystemd-internal/sd-device/device-private.c
+++ b/src/libsystemd/libsystemd-internal/sd-device/device-private.c
@@ -890,7 +890,7 @@ void device_cleanup_tags(sd_device *device) {
set_free_free(device->tags);
device->tags = NULL;
device->property_tags_outdated = true;
- device->tags_generation ++;
+ device->tags_generation++;
}
void device_cleanup_devlinks(sd_device *device) {
@@ -899,7 +899,7 @@ void device_cleanup_devlinks(sd_device *device) {
set_free_free(device->devlinks);
device->devlinks = NULL;
device->property_devlinks_outdated = true;
- device->devlinks_generation ++;
+ device->devlinks_generation++;
}
void device_remove_tag(sd_device *device, const char *tag) {
@@ -908,7 +908,7 @@ void device_remove_tag(sd_device *device, const char *tag) {
free(set_remove(device->tags, tag));
device->property_tags_outdated = true;
- device->tags_generation ++;
+ device->tags_generation++;
}
static int device_tag(sd_device *device, const char *tag, bool add) {
diff --git a/src/libsystemd/libsystemd-internal/sd-device/sd-device.c b/src/libsystemd/libsystemd-internal/sd-device/sd-device.c
index 895002499c..d21a67cd4c 100644
--- a/src/libsystemd/libsystemd-internal/sd-device/sd-device.c
+++ b/src/libsystemd/libsystemd-internal/sd-device/sd-device.c
@@ -136,7 +136,7 @@ int device_add_property_aux(sd_device *device, const char *_key, const char *_va
}
if (!db) {
- device->properties_generation ++;
+ device->properties_generation++;
device->properties_buf_outdated = true;
}
@@ -309,7 +309,7 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s
if (name[len] == '/')
name[len] = '!';
- len ++;
+ len++;
}
syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", name);
@@ -669,7 +669,7 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
return -EINVAL;
sysname[0] = '\0';
- sysname ++;
+ sysname++;
return sd_device_new_from_subsystem_sysname(ret, subsys, sysname);
}
@@ -971,7 +971,7 @@ static int device_set_sysname(sd_device *device) {
pos = strrchr(device->devpath, '/');
if (!pos)
return -EINVAL;
- pos ++;
+ pos++;
/* devpath is not a root directory */
if (*pos == '\0' || pos <= device->devpath)
@@ -986,7 +986,7 @@ static int device_set_sysname(sd_device *device) {
if (sysname[len] == '!')
sysname[len] = '/';
- len ++;
+ len++;
}
/* trailing number */
@@ -1066,7 +1066,7 @@ int device_add_tag(sd_device *device, const char *tag) {
if (r < 0)
return r;
- device->tags_generation ++;
+ device->tags_generation++;
device->property_tags_outdated = true;
return 0;
@@ -1086,7 +1086,7 @@ int device_add_devlink(sd_device *device, const char *devlink) {
if (r < 0)
return r;
- device->devlinks_generation ++;
+ device->devlinks_generation++;
device->property_devlinks_outdated = true;
return 0;
@@ -1212,19 +1212,19 @@ int device_get_id_filename(sd_device *device, const char **ret) {
if (major(devnum) > 0) {
assert(subsystem);
- /* use dev_t -- b259:131072, c254:0 */
+ /* use dev_t — b259:131072, c254:0 */
r = asprintf(&id, "%c%u:%u",
streq(subsystem, "block") ? 'b' : 'c',
major(devnum), minor(devnum));
if (r < 0)
return -ENOMEM;
} else if (ifindex > 0) {
- /* use netdev ifindex -- n3 */
+ /* use netdev ifindex — n3 */
r = asprintf(&id, "n%u", ifindex);
if (r < 0)
return -ENOMEM;
} else {
- /* use $subsys:$sysname -- pci:0000:00:1f.2
+ /* use $subsys:$sysname — pci:0000:00:1f.2
* sysname() has '!' translated, get it from devpath
*/
const char *sysname;
@@ -1397,7 +1397,7 @@ _public_ const char *sd_device_get_tag_first(sd_device *device) {
device->tags_iterator_generation = device->tags_generation;
device->tags_iterator = ITERATOR_FIRST;
- set_iterate(device->tags, &device->tags_iterator, &v);
+ (void) set_iterate(device->tags, &device->tags_iterator, &v);
return v;
}
@@ -1411,7 +1411,7 @@ _public_ const char *sd_device_get_tag_next(sd_device *device) {
if (device->tags_iterator_generation != device->tags_generation)
return NULL;
- set_iterate(device->tags, &device->tags_iterator, &v);
+ (void) set_iterate(device->tags, &device->tags_iterator, &v);
return v;
}
@@ -1425,7 +1425,7 @@ _public_ const char *sd_device_get_devlink_first(sd_device *device) {
device->devlinks_iterator_generation = device->devlinks_generation;
device->devlinks_iterator = ITERATOR_FIRST;
- set_iterate(device->devlinks, &device->devlinks_iterator, &v);
+ (void) set_iterate(device->devlinks, &device->devlinks_iterator, &v);
return v;
}
@@ -1439,7 +1439,7 @@ _public_ const char *sd_device_get_devlink_next(sd_device *device) {
if (device->devlinks_iterator_generation != device->devlinks_generation)
return NULL;
- set_iterate(device->devlinks, &device->devlinks_iterator, &v);
+ (void) set_iterate(device->devlinks, &device->devlinks_iterator, &v);
return v;
}
@@ -1457,15 +1457,20 @@ static int device_properties_prepare(sd_device *device) {
return r;
if (device->property_devlinks_outdated) {
- char *devlinks = NULL;
+ _cleanup_free_ char *devlinks = NULL;
+ size_t devlinks_allocated = 0, devlinks_len = 0;
const char *devlink;
- devlink = sd_device_get_devlink_first(device);
- if (devlink)
- devlinks = strdupa(devlink);
+ for (devlink = sd_device_get_devlink_first(device); devlink; devlink = sd_device_get_devlink_next(device)) {
+ char *e;
- while ((devlink = sd_device_get_devlink_next(device)))
- devlinks = strjoina(devlinks, " ", devlink);
+ if (!GREEDY_REALLOC(devlinks, devlinks_allocated, devlinks_len + strlen(devlink) + 2))
+ return -ENOMEM;
+ if (devlinks_len > 0)
+ stpcpy(devlinks + devlinks_len++, " ");
+ e = stpcpy(devlinks + devlinks_len, devlink);
+ devlinks_len = e - devlinks;
+ }
r = device_add_property_internal(device, "DEVLINKS", devlinks);
if (r < 0)
@@ -1475,17 +1480,23 @@ static int device_properties_prepare(sd_device *device) {
}
if (device->property_tags_outdated) {
- char *tags = NULL;
+ _cleanup_free_ char *tags = NULL;
+ size_t tags_allocated = 0, tags_len = 0;
const char *tag;
- tag = sd_device_get_tag_first(device);
- if (tag)
- tags = strjoina(":", tag);
+ if (!GREEDY_REALLOC(tags, tags_allocated, 2))
+ return -ENOMEM;
+ stpcpy(tags, ":");
+ tags_len++;
- while ((tag = sd_device_get_tag_next(device)))
- tags = strjoina(tags, ":", tag);
+ for (tag = sd_device_get_tag_first(device); tag; tag = sd_device_get_tag_next(device)) {
+ char *e;
- tags = strjoina(tags, ":");
+ if (!GREEDY_REALLOC(tags, tags_allocated, tags_len + strlen(tag) + 2))
+ return -ENOMEM;
+ e = stpcpy(stpcpy(tags + tags_len, tag), ":");
+ tags_len = e - tags;
+ }
r = device_add_property_internal(device, "TAGS", tags);
if (r < 0)
@@ -1606,7 +1617,7 @@ _public_ const char *sd_device_get_sysattr_first(sd_device *device) {
device->sysattrs_iterator = ITERATOR_FIRST;
- set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
+ (void) set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
return v;
}
@@ -1618,7 +1629,7 @@ _public_ const char *sd_device_get_sysattr_next(sd_device *device) {
if (!device->sysattrs_read)
return NULL;
- set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
+ (void) set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
return v;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-event/sd-event.c b/src/libsystemd/libsystemd-internal/sd-event/sd-event.c
index 0fec8d71b2..7f6f485353 100644
--- a/src/libsystemd/libsystemd-internal/sd-event/sd-event.c
+++ b/src/libsystemd/libsystemd-internal/sd-event/sd-event.c
@@ -951,7 +951,7 @@ static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType t
sd_event_ref(e);
LIST_PREPEND(sources, e->sources, s);
- e->n_sources ++;
+ e->n_sources++;
return s;
}
@@ -1072,6 +1072,10 @@ _public_ int sd_event_add_time(
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
+ if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) &&
+ !clock_boottime_supported())
+ return -EOPNOTSUPP;
+
if (!callback)
callback = time_exit_callback;
@@ -1145,8 +1149,7 @@ _public_ int sd_event_add_signal(
int r;
assert_return(e, -EINVAL);
- assert_return(sig > 0, -EINVAL);
- assert_return(sig < _NSIG, -EINVAL);
+ assert_return(SIGNAL_VALID(sig), -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
@@ -1235,7 +1238,7 @@ _public_ int sd_event_add_child(
return r;
}
- e->n_enabled_child_sources ++;
+ e->n_enabled_child_sources++;
r = event_make_signal_data(e, SIGCHLD, NULL);
if (r < 0) {
@@ -2200,7 +2203,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
if (_unlikely_(n != sizeof(si)))
return -EIO;
- assert(si.ssi_signo < _NSIG);
+ assert(SIGNAL_VALID(si.ssi_signo));
read_one = true;
@@ -2528,7 +2531,8 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
}
dual_timestamp_get(&e->timestamp);
- e->timestamp_boottime = now(CLOCK_BOOTTIME);
+ if (clock_boottime_supported())
+ e->timestamp_boottime = now(CLOCK_BOOTTIME);
for (i = 0; i < m; i++) {
@@ -2762,6 +2766,9 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
CLOCK_BOOTTIME,
CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP);
+ if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported())
+ return -EOPNOTSUPP;
+
if (!dual_timestamp_is_set(&e->timestamp)) {
/* Implicitly fall back to now() if we never ran
* before and thus have no cached time. */
@@ -2780,9 +2787,13 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
*usec = e->timestamp.monotonic;
break;
- default:
+ case CLOCK_BOOTTIME:
+ case CLOCK_BOOTTIME_ALARM:
*usec = e->timestamp_boottime;
break;
+
+ default:
+ assert_not_reached("Unknown clock?");
}
return 0;
diff --git a/src/libsystemd/libsystemd-internal/sd-event/test-event.c b/src/libsystemd/libsystemd-internal/sd-event/test-event.c
index 6beb1b08cd..324ad7ee02 100644
--- a/src/libsystemd/libsystemd-internal/sd-event/test-event.c
+++ b/src/libsystemd/libsystemd-internal/sd-event/test-event.c
@@ -270,8 +270,10 @@ static void test_sd_event_now(void) {
assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0);
assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) > 0);
assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) > 0);
- assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) > 0);
- assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) > 0);
+ if (clock_boottime_supported()) {
+ assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) > 0);
+ assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) > 0);
+ }
assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP);
assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP);
@@ -280,8 +282,10 @@ static void test_sd_event_now(void) {
assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0);
assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) == 0);
assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) == 0);
- assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) == 0);
- assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) == 0);
+ if (clock_boottime_supported()) {
+ assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) == 0);
+ assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) == 0);
+ }
assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP);
assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP);
}
@@ -291,7 +295,7 @@ static int n_rtqueue = 0;
static int rtqueue_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
last_rtqueue_sigval = si->ssi_int;
- n_rtqueue ++;
+ n_rtqueue++;
return 0;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-hwdb/hwdb-internal.h b/src/libsystemd/libsystemd-internal/sd-hwdb/hwdb-internal.h
index 13fddfc8ad..8ffb5e5c74 100644
--- a/src/libsystemd/libsystemd-internal/sd-hwdb/hwdb-internal.h
+++ b/src/libsystemd/libsystemd-internal/sd-hwdb/hwdb-internal.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -16,7 +18,6 @@
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
#include "sparse-endian.h"
#include "util.h"
diff --git a/src/libsystemd/libsystemd-internal/sd-netlink/netlink-message.c b/src/libsystemd/libsystemd-internal/sd-netlink/netlink-message.c
index 0c307661f1..c00785ea41 100644
--- a/src/libsystemd/libsystemd-internal/sd-netlink/netlink-message.c
+++ b/src/libsystemd/libsystemd-internal/sd-netlink/netlink-message.c
@@ -34,7 +34,7 @@
#include "util.h"
#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
-#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
+#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
#define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
#define RTA_FLAGS(rta) ((rta)->rta_type & ~NLA_TYPE_MASK)
@@ -107,10 +107,7 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
m->hdr->nlmsg_type == RTM_GETNEIGH,
-EINVAL);
- if (dump)
- m->hdr->nlmsg_flags |= NLM_F_DUMP;
- else
- m->hdr->nlmsg_flags &= ~NLM_F_DUMP;
+ SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
return 0;
}
@@ -210,11 +207,11 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da
* and gives us too little data (so don't do that)
*/
padding = mempcpy(RTA_DATA(rta), data, data_length);
- else {
+
+ else
/* if no data was passed, make sure we still initialize the padding
note that we can have data_length > 0 (used by some containers) */
padding = RTA_DATA(rta);
- }
/* make sure also the padding at the end of the message is initialized */
padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
@@ -346,7 +343,7 @@ int sd_netlink_message_append_data(sd_netlink_message *m, unsigned short type, c
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- r = add_rtattr(m, type, &data, len);
+ r = add_rtattr(m, type, data, len);
if (r < 0)
return r;
@@ -467,7 +464,7 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type
if (r < 0)
return r;
- m->containers[m->n_containers ++].offset = r;
+ m->containers[m->n_containers++].offset = r;
return 0;
}
@@ -498,7 +495,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
if (r < 0)
return r;
- m->containers[m->n_containers ++].offset = r;
+ m->containers[m->n_containers++].offset = r;
return 0;
}
@@ -510,7 +507,7 @@ int sd_netlink_message_close_container(sd_netlink_message *m) {
assert_return(m->n_containers > 0, -EINVAL);
m->containers[m->n_containers].type_system = NULL;
- m->n_containers --;
+ m->n_containers--;
return 0;
}
@@ -528,7 +525,7 @@ static int netlink_message_read_internal(sd_netlink_message *m, unsigned short t
attribute = &m->containers[m->n_containers].attributes[type];
- if(!attribute->offset)
+ if (!attribute->offset)
return -ENODATA;
rta = (struct rtattr*)((uint8_t *) m->hdr + attribute->offset);
@@ -735,7 +732,7 @@ static int netlink_container_parse(sd_netlink_message *m,
_cleanup_free_ struct netlink_attribute *attributes = NULL;
attributes = new0(struct netlink_attribute, count);
- if(!attributes)
+ if (!attributes)
return -ENOMEM;
for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
@@ -842,7 +839,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
else
size = (size_t)r;
- m->n_containers ++;
+ m->n_containers++;
r = netlink_container_parse(m,
&m->containers[m->n_containers],
@@ -850,7 +847,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
container,
size);
if (r < 0) {
- m->n_containers --;
+ m->n_containers--;
return r;
}
@@ -867,7 +864,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
m->containers[m->n_containers].attributes = mfree(m->containers[m->n_containers].attributes);
m->containers[m->n_containers].type_system = NULL;
- m->n_containers --;
+ m->n_containers--;
return 0;
}
diff --git a/src/libsystemd/libsystemd-internal/sd-netlink/netlink-socket.c b/src/libsystemd/libsystemd-internal/sd-netlink/netlink-socket.c
index 25b7509217..d28a413c65 100644
--- a/src/libsystemd/libsystemd-internal/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/libsystemd-internal/sd-netlink/netlink-socket.c
@@ -82,7 +82,7 @@ static int broadcast_groups_get(sd_netlink *nl) {
return r;
for (i = 0; i < len; i++) {
- for (j = 0; j < sizeof(uint32_t) * 8; j ++) {
+ for (j = 0; j < sizeof(uint32_t) * 8; j++) {
uint32_t offset;
unsigned group;
@@ -168,7 +168,7 @@ int socket_broadcast_group_ref(sd_netlink *nl, unsigned group) {
n_ref = broadcast_group_get_ref(nl, group);
- n_ref ++;
+ n_ref++;
r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL);
if (r < 0)
@@ -216,7 +216,7 @@ int socket_broadcast_group_unref(sd_netlink *nl, unsigned group) {
assert(n_ref > 0);
- n_ref --;
+ n_ref--;
r = broadcast_group_set_ref(nl, group, n_ref);
if (r < 0)
@@ -444,14 +444,14 @@ int socket_read_message(sd_netlink *rtnl) {
if (r < 0)
return r;
- rtnl->rqueue[rtnl->rqueue_size ++] = first;
+ rtnl->rqueue[rtnl->rqueue_size++] = first;
first = NULL;
if (multi_part && (i < rtnl->rqueue_partial_size)) {
/* remove the message form the partial read queue */
memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
sizeof(sd_netlink_message*) * (rtnl->rqueue_partial_size - i - 1));
- rtnl->rqueue_partial_size --;
+ rtnl->rqueue_partial_size--;
}
return 1;
@@ -465,7 +465,7 @@ int socket_read_message(sd_netlink *rtnl) {
if (r < 0)
return r;
- rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
+ rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = first;
}
first = NULL;
diff --git a/src/libsystemd/libsystemd-internal/sd-netlink/netlink-types.c b/src/libsystemd/libsystemd-internal/sd-netlink/netlink-types.c
index a5758bb516..3a4bac2ced 100644
--- a/src/libsystemd/libsystemd-internal/sd-netlink/netlink-types.c
+++ b/src/libsystemd/libsystemd-internal/sd-netlink/netlink-types.c
@@ -95,12 +95,43 @@ static const NLType rtnl_link_info_data_macvlan_types[] = {
};
static const NLType rtnl_link_info_data_bridge_types[] = {
- [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 },
- [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 },
- [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 },
- [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 },
- [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 },
- [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_VLAN_FILTERING] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_ROOT_PORT] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_ROOT_PATH_COST] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_TOPOLOGY_CHANGE] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_HELLO_TIMER] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_TCN_TIMER] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_GC_TIMER] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_GROUP_ADDR] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_FDB_FLUSH] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_MCAST_ROUTER] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_MCAST_SNOOPING] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_MCAST_QUERIER] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_MCAST_HASH_MAX] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BR_NF_CALL_IPTABLES] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NETLINK_TYPE_U16 },
};
static const NLType rtnl_link_info_data_vlan_types[] = {
diff --git a/src/libsystemd/libsystemd-internal/sd-netlink/rtnl-message.c b/src/libsystemd/libsystemd-internal/sd-netlink/rtnl-message.c
index 2f1254295a..f6482a6157 100644
--- a/src/libsystemd/libsystemd-internal/sd-netlink/rtnl-message.c
+++ b/src/libsystemd/libsystemd-internal/sd-netlink/rtnl-message.c
@@ -111,6 +111,20 @@ int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags) {
return 0;
}
+int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table) {
+ struct rtmsg *rtm;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
+
+ rtm = NLMSG_DATA(m->hdr);
+
+ rtm->rtm_table = table;
+
+ return 0;
+}
+
int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) {
struct rtmsg *rtm;
@@ -126,6 +140,20 @@ int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) {
return 0;
}
+int sd_rtnl_message_route_set_family(sd_netlink_message *m, int family) {
+ struct rtmsg *rtm;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
+
+ rtm = NLMSG_DATA(m->hdr);
+
+ rtm->rtm_family = family;
+
+ return 0;
+}
+
int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol) {
struct rtmsg *rtm;
@@ -402,7 +430,6 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
int r;
assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
- assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
assert_return(ret, -EINVAL);
r = message_new(rtnl, ret, nlmsg_type);
@@ -616,7 +643,7 @@ int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags) {
return 0;
}
-int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned *type) {
+int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type) {
struct ifinfomsg *ifi;
assert_return(m, -EINVAL);
diff --git a/src/libsystemd/libsystemd-internal/sd-netlink/sd-netlink.c b/src/libsystemd/libsystemd-internal/sd-netlink/sd-netlink.c
index c536364a24..3c7488463c 100644
--- a/src/libsystemd/libsystemd-internal/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/libsystemd-internal/sd-netlink/sd-netlink.c
@@ -279,7 +279,7 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
/* Dispatch a queued message */
*message = rtnl->rqueue[0];
- rtnl->rqueue_size --;
+ rtnl->rqueue_size--;
memmove(rtnl->rqueue, rtnl->rqueue + 1, sizeof(sd_netlink_message*) * rtnl->rqueue_size);
return 1;
@@ -774,7 +774,7 @@ static int prepare_callback(sd_event_source *s, void *userdata) {
return 1;
}
-int sd_netlink_attach_event(sd_netlink *rtnl, sd_event *event, int priority) {
+int sd_netlink_attach_event(sd_netlink *rtnl, sd_event *event, int64_t priority) {
int r;
assert_return(rtnl, -EINVAL);
diff --git a/src/libsystemd/libsystemd-internal/sd-netlink/test-netlink.c b/src/libsystemd/libsystemd-internal/sd-netlink/test-netlink.c
index e16c35144d..aadd0f06a8 100644
--- a/src/libsystemd/libsystemd-internal/sd-netlink/test-netlink.c
+++ b/src/libsystemd/libsystemd-internal/sd-netlink/test-netlink.c
@@ -217,7 +217,7 @@ static void test_event_loop(int ifindex) {
assert_se(sd_netlink_open(&rtnl) >= 0);
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
- assert_se(sd_netlink_call_async(rtnl, m, &link_handler, ifname, 0, NULL) >= 0);
+ assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, NULL) >= 0);
assert_se(sd_event_default(&event) >= 0);
@@ -234,7 +234,7 @@ static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata)
int *counter = userdata;
int r;
- (*counter) --;
+ (*counter)--;
r = sd_netlink_message_get_errno(m);
@@ -258,7 +258,7 @@ static void test_async(int ifindex) {
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
- assert_se(sd_netlink_call_async(rtnl, m, &link_handler, ifname, 0, &serial) >= 0);
+ assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, &serial) >= 0);
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
assert_se(sd_netlink_process(rtnl, &r) >= 0);
@@ -276,11 +276,11 @@ static void test_pipe(int ifindex) {
assert_se(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex) >= 0);
assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
- counter ++;
- assert_se(sd_netlink_call_async(rtnl, m1, &pipe_handler, &counter, 0, NULL) >= 0);
+ counter++;
+ assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, &counter, 0, NULL) >= 0);
- counter ++;
- assert_se(sd_netlink_call_async(rtnl, m2, &pipe_handler, &counter, 0, NULL) >= 0);
+ counter++;
+ assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, &counter, 0, NULL) >= 0);
while (counter > 0) {
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
@@ -330,12 +330,12 @@ static void test_match(void) {
assert_se(sd_netlink_open(&rtnl) >= 0);
- assert_se(sd_netlink_add_match(rtnl, RTM_NEWLINK, &link_handler, NULL) >= 0);
- assert_se(sd_netlink_add_match(rtnl, RTM_NEWLINK, &link_handler, NULL) >= 0);
+ assert_se(sd_netlink_add_match(rtnl, RTM_NEWLINK, link_handler, NULL) >= 0);
+ assert_se(sd_netlink_add_match(rtnl, RTM_NEWLINK, link_handler, NULL) >= 0);
- assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
- assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
- assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 0);
+ assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, link_handler, NULL) == 1);
+ assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, link_handler, NULL) == 1);
+ assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, link_handler, NULL) == 0);
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
}
diff --git a/src/libsystemd/libsystemd-internal/sd-network/sd-network.c b/src/libsystemd/libsystemd-internal/sd-network/sd-network.c
index 5ebe7de7af..70083213f9 100644
--- a/src/libsystemd/libsystemd-internal/sd-network/sd-network.c
+++ b/src/libsystemd/libsystemd-internal/sd-network/sd-network.c
@@ -31,6 +31,7 @@
#include "fs-util.h"
#include "macro.h"
#include "parse-util.h"
+#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
@@ -102,16 +103,16 @@ _public_ int sd_network_get_route_domains(char ***ret) {
}
static int network_link_get_string(int ifindex, const char *field, char **ret) {
- _cleanup_free_ char *s = NULL, *p = NULL;
+ char path[strlen("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
+ _cleanup_free_ char *s = NULL;
int r;
assert_return(ifindex > 0, -EINVAL);
assert_return(ret, -EINVAL);
- if (asprintf(&p, "/run/systemd/netif/links/%i", ifindex) < 0)
- return -ENOMEM;
+ xsprintf(path, "/run/systemd/netif/links/%i", ifindex);
- r = parse_env_file(p, NEWLINE, field, &s, NULL);
+ r = parse_env_file(path, NEWLINE, field, &s, NULL);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
@@ -126,17 +127,16 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) {
}
static int network_link_get_strv(int ifindex, const char *key, char ***ret) {
- _cleanup_free_ char *p = NULL, *s = NULL;
+ char path[strlen("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
_cleanup_strv_free_ char **a = NULL;
+ _cleanup_free_ char *s = NULL;
int r;
assert_return(ifindex > 0, -EINVAL);
assert_return(ret, -EINVAL);
- if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
- return -ENOMEM;
-
- r = parse_env_file(p, NEWLINE, key, &s, NULL);
+ xsprintf(path, "/run/systemd/netif/links/%i", ifindex);
+ r = parse_env_file(path, NEWLINE, key, &s, NULL);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
@@ -187,32 +187,7 @@ _public_ int sd_network_link_get_dnssec_negative_trust_anchors(int ifindex, char
return network_link_get_strv(ifindex, "DNSSEC_NTA", nta);
}
-_public_ int sd_network_link_get_lldp(int ifindex, char **lldp) {
- _cleanup_free_ char *s = NULL, *p = NULL;
- size_t size;
- int r;
-
- assert_return(ifindex > 0, -EINVAL);
- assert_return(lldp, -EINVAL);
-
- if (asprintf(&p, "/run/systemd/netif/lldp/%d", ifindex) < 0)
- return -ENOMEM;
-
- r = read_full_file(p, &s, &size);
- if (r == -ENOENT)
- return -ENODATA;
- if (r < 0)
- return r;
- if (size <= 0)
- return -ENODATA;
-
- *lldp = s;
- s = NULL;
-
- return 0;
-}
-
-int sd_network_link_get_timezone(int ifindex, char **ret) {
+_public_ int sd_network_link_get_timezone(int ifindex, char **ret) {
return network_link_get_string(ifindex, "TIMEZONE", ret);
}
@@ -232,12 +207,64 @@ _public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "ROUTE_DOMAINS", ret);
}
-_public_ int sd_network_link_get_carrier_bound_to(int ifindex, char ***ret) {
- return network_link_get_strv(ifindex, "CARRIER_BOUND_TO", ret);
+static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
+ char path[strlen("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
+ _cleanup_free_ int *ifis = NULL;
+ _cleanup_free_ char *s = NULL;
+ size_t allocated = 0, c = 0;
+ const char *x;
+ int r;
+
+ assert_return(ifindex > 0, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ xsprintf(path, "/run/systemd/netif/links/%i", ifindex);
+ r = parse_env_file(path, NEWLINE, key, &s, NULL);
+ if (r == -ENOENT)
+ return -ENODATA;
+ if (r < 0)
+ return r;
+ if (isempty(s)) {
+ *ret = NULL;
+ return 0;
+ }
+
+ x = s;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&x, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ r = parse_ifindex(word, &ifindex);
+ if (r < 0)
+ return r;
+
+ if (!GREEDY_REALLOC(ifis, allocated, c + 1))
+ return -ENOMEM;
+
+ ifis[c++] = ifindex;
+ }
+
+ if (!GREEDY_REALLOC(ifis, allocated, c + 1))
+ return -ENOMEM;
+ ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice*/
+
+ *ret = ifis;
+ ifis = NULL;
+
+ return c;
+}
+
+_public_ int sd_network_link_get_carrier_bound_to(int ifindex, int **ret) {
+ return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_TO", ret);
}
-_public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) {
- return network_link_get_strv(ifindex, "CARRIER_BOUND_BY", ret);
+_public_ int sd_network_link_get_carrier_bound_by(int ifindex, int **ret) {
+ return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_BY", ret);
}
static inline int MONITOR_TO_FD(sd_network_monitor *m) {
diff --git a/src/libsystemd/libsystemd-internal/sd-path/sd-path.c b/src/libsystemd/libsystemd-internal/sd-path/sd-path.c
index 61a8b092da..6d9f3e2a61 100644
--- a/src/libsystemd/libsystemd-internal/sd-path/sd-path.c
+++ b/src/libsystemd/libsystemd-internal/sd-path/sd-path.c
@@ -89,7 +89,8 @@ static int from_home_dir(const char *envname, const char *suffix, char **buffer,
static int from_user_dir(const char *field, char **buffer, const char **ret) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *b = NULL;
- const char *fn = NULL;
+ _cleanup_free_ const char *fn = NULL;
+ const char *c = NULL;
char line[LINE_MAX];
size_t n;
int r;
@@ -98,10 +99,14 @@ static int from_user_dir(const char *field, char **buffer, const char **ret) {
assert(buffer);
assert(ret);
- r = from_home_dir(NULL, ".config/user-dirs.dirs", &b, &fn);
+ r = from_home_dir("XDG_CONFIG_HOME", ".config", &b, &c);
if (r < 0)
return r;
+ fn = strappend(c, "/user-dirs.dirs");
+ if (!fn)
+ return -ENOMEM;
+
f = fopen(fn, "re");
if (!f) {
if (errno == ENOENT)
diff --git a/src/libsystemd/libsystemd-internal/sd-resolve/sd-resolve.c b/src/libsystemd/libsystemd-internal/sd-resolve/sd-resolve.c
index 30176d7283..6eacf2b69a 100644
--- a/src/libsystemd/libsystemd-internal/sd-resolve/sd-resolve.c
+++ b/src/libsystemd/libsystemd-internal/sd-resolve/sd-resolve.c
@@ -217,9 +217,8 @@ static void *serialize_addrinfo(void *p, const struct addrinfo *ai, size_t *leng
memcpy((uint8_t*) p, &s, sizeof(AddrInfoSerialization));
memcpy((uint8_t*) p + sizeof(AddrInfoSerialization), ai->ai_addr, ai->ai_addrlen);
-
- if (ai->ai_canonname)
- memcpy((char*) p + sizeof(AddrInfoSerialization) + ai->ai_addrlen, ai->ai_canonname, cnl);
+ memcpy_safe((char*) p + sizeof(AddrInfoSerialization) + ai->ai_addrlen,
+ ai->ai_canonname, cnl);
*length += l;
return (uint8_t*) p + l;
@@ -404,7 +403,7 @@ static void* thread_worker(void *p) {
assert_se(pthread_sigmask(SIG_BLOCK, &fullset, NULL) == 0);
/* Assign a pretty name to this thread */
- prctl(PR_SET_NAME, (unsigned long) "sd-resolve");
+ (void) prctl(PR_SET_NAME, (unsigned long) "sd-resolve");
while (!resolve->dead) {
union {
@@ -448,7 +447,7 @@ static int start_threads(sd_resolve *resolve, unsigned extra) {
if (r != 0)
return -r;
- resolve->n_valid_workers ++;
+ resolve->n_valid_workers++;
}
return 0;
@@ -580,9 +579,10 @@ static void resolve_free(sd_resolve *resolve) {
(void) send(resolve->fds[REQUEST_SEND_FD], &req, req.length, MSG_NOSIGNAL);
}
- /* Now terminate them and wait until they are gone. */
+ /* Now terminate them and wait until they are gone.
+ If we get an error than most likely the thread already exited. */
for (i = 0; i < resolve->n_valid_workers; i++)
- pthread_join(resolve->workers[i], NULL);
+ (void) pthread_join(resolve->workers[i], NULL);
/* Close all communication channels */
for (i = 0; i < _FD_MAX; i++)
@@ -658,7 +658,7 @@ static int complete_query(sd_resolve *resolve, sd_resolve_query *q) {
assert(q->resolve == resolve);
q->done = true;
- resolve->n_done ++;
+ resolve->n_done++;
resolve->current = sd_resolve_query_ref(q);
@@ -1192,7 +1192,7 @@ static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userd
return 1;
}
-_public_ int sd_resolve_attach_event(sd_resolve *resolve, sd_event *event, int priority) {
+_public_ int sd_resolve_attach_event(sd_resolve *resolve, sd_event *event, int64_t priority) {
int r;
assert_return(resolve, -EINVAL);
diff --git a/src/libsystemd/libsystemd-internal/sd-resolve/test-resolve.c b/src/libsystemd/libsystemd-internal/sd-resolve/test-resolve.c
index 9e3ac16597..0209cc77e7 100644
--- a/src/libsystemd/libsystemd-internal/sd-resolve/test-resolve.c
+++ b/src/libsystemd/libsystemd-internal/sd-resolve/test-resolve.c
@@ -63,7 +63,7 @@ static int getnameinfo_handler(sd_resolve_query *q, int ret, const char *host, c
return 0;
}
- printf("Host: %s -- Serv: %s\n", strna(host), strna(serv));
+ printf("Host: %s — Serv: %s\n", strna(host), strna(serv));
return 0;
}
diff --git a/src/libsystemd/libsystemd-journal-internal/Makefile b/src/libsystemd/libsystemd-journal-internal/Makefile
index 7b7f313077..1c8547f798 100644
--- a/src/libsystemd/libsystemd-journal-internal/Makefile
+++ b/src/libsystemd/libsystemd-journal-internal/Makefile
@@ -60,7 +60,9 @@ libsystemd_journal_internal_la_SOURCES = \
src/journal/mmap-cache.h \
src/journal/compress.c \
src/journal/audit-type.h \
- src/journal/audit-type.c
+ src/journal/audit-type.c \
+ src/shared/gcrypt-util.h \
+ src/shared/gcrypt-util.c
nodist_libsystemd_journal_internal_la_SOURCES = \
src/journal/audit_type-to-name.h
diff --git a/src/libsystemd/libsystemd-journal-internal/catalog.c b/src/libsystemd/libsystemd-journal-internal/catalog.c
index 962ca238b9..70838d958c 100644
--- a/src/libsystemd/libsystemd-journal-internal/catalog.c
+++ b/src/libsystemd/libsystemd-journal-internal/catalog.c
@@ -164,14 +164,14 @@ static int finish_item(
Hashmap *h,
sd_id128_t id,
const char *language,
- char *payload) {
+ char *payload, size_t payload_size) {
_cleanup_free_ CatalogItem *i = NULL;
- _cleanup_free_ char *combined = NULL, *prev = NULL;
- int r;
+ _cleanup_free_ char *prev = NULL, *combined = NULL;
assert(h);
assert(payload);
+ assert(payload_size > 0);
i = new0(CatalogItem, 1);
if (!i)
@@ -184,23 +184,25 @@ static int finish_item(
}
prev = hashmap_get(h, i);
-
- /* Already have such an item, combine them */
if (prev) {
+ /* Already have such an item, combine them */
combined = combine_entries(payload, prev);
if (!combined)
return log_oom();
- r = hashmap_update(h, i, combined);
- if (r < 0)
- return r;
- combined = NULL;
- /* A new item */
+ if (hashmap_update(h, i, combined) < 0)
+ return log_oom();
+ combined = NULL;
} else {
- r = hashmap_put(h, i, payload);
- if (r < 0)
- return r;
+ /* A new item */
+ combined = memdup(payload, payload_size + 1);
+ if (!combined)
+ return log_oom();
+
+ if (hashmap_put(h, i, combined) < 0)
+ return log_oom();
i = NULL;
+ combined = NULL;
}
return 0;
@@ -215,7 +217,7 @@ int catalog_file_lang(const char* filename, char **lang) {
beg = end - 1;
while (beg > filename && *beg != '.' && *beg != '/' && end - beg < 32)
- beg --;
+ beg--;
if (*beg != '.' || end <= beg + 1)
return 0;
@@ -262,6 +264,7 @@ static int catalog_entry_lang(const char* filename, int line,
int catalog_import_file(Hashmap *h, const char *path) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *payload = NULL;
+ size_t payload_size = 0, payload_allocated = 0;
unsigned n = 0;
sd_id128_t id;
_cleanup_free_ char *deflang = NULL, *lang = NULL;
@@ -283,8 +286,7 @@ int catalog_import_file(Hashmap *h, const char *path) {
for (;;) {
char line[LINE_MAX];
- size_t a, b, c;
- char *t;
+ size_t line_len;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
@@ -323,17 +325,23 @@ int catalog_import_file(Hashmap *h, const char *path) {
if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) {
if (got_id) {
- r = finish_item(h, id, lang ?: deflang, payload);
+ if (payload_size == 0) {
+ log_error("[%s:%u] No payload text.", path, n);
+ return -EINVAL;
+ }
+
+ r = finish_item(h, id, lang ?: deflang, payload, payload_size);
if (r < 0)
return r;
- payload = NULL;
lang = mfree(lang);
+ payload_size = 0;
}
if (with_language) {
- t = strstrip(line + 2 + 1 + 32 + 1);
+ char *t;
+ t = strstrip(line + 2 + 1 + 32 + 1);
r = catalog_entry_lang(path, n, t, deflang, &lang);
if (r < 0)
return r;
@@ -343,9 +351,6 @@ int catalog_import_file(Hashmap *h, const char *path) {
empty_line = false;
id = jd;
- if (payload)
- payload[0] = '\0';
-
continue;
}
}
@@ -356,34 +361,30 @@ int catalog_import_file(Hashmap *h, const char *path) {
return -EINVAL;
}
- a = payload ? strlen(payload) : 0;
- b = strlen(line);
-
- c = a + (empty_line ? 1 : 0) + b + 1 + 1;
- t = realloc(payload, c);
- if (!t)
+ line_len = strlen(line);
+ if (!GREEDY_REALLOC(payload, payload_allocated,
+ payload_size + (empty_line ? 1 : 0) + line_len + 1 + 1))
return log_oom();
- if (empty_line) {
- t[a] = '\n';
- memcpy(t + a + 1, line, b);
- t[a+b+1] = '\n';
- t[a+b+2] = 0;
- } else {
- memcpy(t + a, line, b);
- t[a+b] = '\n';
- t[a+b+1] = 0;
- }
+ if (empty_line)
+ payload[payload_size++] = '\n';
+ memcpy(payload + payload_size, line, line_len);
+ payload_size += line_len;
+ payload[payload_size++] = '\n';
+ payload[payload_size] = '\0';
- payload = t;
empty_line = false;
}
if (got_id) {
- r = finish_item(h, id, lang ?: deflang, payload);
+ if (payload_size == 0) {
+ log_error("[%s:%u] No payload text.", path, n);
+ return -EINVAL;
+ }
+
+ r = finish_item(h, id, lang ?: deflang, payload, payload_size);
if (r < 0)
return r;
- payload = NULL;
}
return 0;
diff --git a/src/libsystemd/libsystemd-journal-internal/compress.c b/src/libsystemd/libsystemd-journal-internal/compress.c
index 1933b87b00..ba734b5561 100644
--- a/src/libsystemd/libsystemd-journal-internal/compress.c
+++ b/src/libsystemd/libsystemd-journal-internal/compress.c
@@ -17,6 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
@@ -111,7 +112,7 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
if (src_size < 9)
return -ENOBUFS;
- r = LZ4_compress_limitedOutput(src, dst + 8, src_size, (int) dst_alloc_size - 8);
+ r = LZ4_compress_limitedOutput(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
if (r <= 0)
return -ENOBUFS;
@@ -175,7 +176,7 @@ int decompress_blob_xz(const void *src, uint64_t src_size,
return -ENOMEM;
s.avail_out = space - used;
- s.next_out = *dst + used;
+ s.next_out = *(uint8_t**)dst + used;
}
*dst_size = space - s.avail_out;
@@ -214,7 +215,7 @@ int decompress_blob_lz4(const void *src, uint64_t src_size,
} else
out = *dst;
- r = LZ4_decompress_safe(src + 8, out, src_size - 8, size);
+ r = LZ4_decompress_safe((char*)src + 8, out, src_size - 8, size);
if (r < 0 || r != size)
return -EBADMSG;
@@ -290,7 +291,7 @@ int decompress_startswith_xz(const void *src, uint64_t src_size,
if (!(greedy_realloc(buffer, buffer_size, *buffer_size * 2, 1)))
return -ENOMEM;
- s.next_out = *buffer + *buffer_size - s.avail_out;
+ s.next_out = *(uint8_t**)buffer + *buffer_size - s.avail_out;
}
#else
@@ -323,7 +324,7 @@ int decompress_startswith_lz4(const void *src, uint64_t src_size,
if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1), 1)))
return -ENOMEM;
- r = LZ4_decompress_safe_partial(src + 8, *buffer, src_size - 8,
+ r = LZ4_decompress_safe_partial((char*)src + 8, *buffer, src_size - 8,
prefix_len + 1, *buffer_size);
if (r >= 0)
size = (unsigned) r;
@@ -498,7 +499,7 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
total_out += n;
if (max_bytes != (uint64_t) -1 && total_out > (size_t) max_bytes) {
- log_debug("Compressed stream longer than %zd bytes", max_bytes);
+ log_debug("Compressed stream longer than %"PRIu64" bytes", max_bytes);
return -EFBIG;
}
@@ -649,7 +650,7 @@ int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
total_out += produced;
if (max_bytes != (uint64_t) -1 && total_out > (size_t) max_bytes) {
- log_debug("Decompressed stream longer than %zd bytes", max_bytes);
+ log_debug("Decompressed stream longer than %"PRIu64" bytes", max_bytes);
r = -EFBIG;
goto cleanup;
}
diff --git a/src/libsystemd/libsystemd-journal-internal/fsprg.c b/src/libsystemd/libsystemd-journal-internal/fsprg.c
index 8f7e137e74..612b10f3a9 100644
--- a/src/libsystemd/libsystemd-journal-internal/fsprg.c
+++ b/src/libsystemd/libsystemd-journal-internal/fsprg.c
@@ -30,6 +30,7 @@
#include <string.h>
#include "fsprg.h"
+#include "gcrypt-util.h"
#define ISVALID_SECPAR(secpar) (((secpar) % 16 == 0) && ((secpar) >= 16) && ((secpar) <= 16384))
#define VALIDATE_SECPAR(secpar) assert(ISVALID_SECPAR(secpar));
@@ -57,7 +58,7 @@ static gcry_mpi_t mpi_import(const void *buf, size_t buflen) {
gcry_mpi_t h;
unsigned len;
- gcry_mpi_scan(&h, GCRYMPI_FMT_USG, buf, buflen, NULL);
+ assert_se(gcry_mpi_scan(&h, GCRYMPI_FMT_USG, buf, buflen, NULL) == 0);
len = (gcry_mpi_get_nbits(h) + 7) / 8;
assert(len <= buflen);
assert(gcry_mpi_cmp_ui(h, 0) >= 0);
@@ -206,20 +207,6 @@ static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq,
gcry_mpi_release(u);
}
-static void initialize_libgcrypt(void) {
- const char *p;
- if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
- return;
-
- p = gcry_check_version("1.4.5");
- assert(p);
-
- /* Turn off "secmem". Clients which whish to make use of this
- * feature should initialize the library manually */
- gcry_control(GCRYCTL_DISABLE_SECMEM);
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
-}
-
/******************************************************************************/
size_t FSPRG_mskinbytes(unsigned _secpar) {
@@ -259,7 +246,7 @@ void FSPRG_GenMK(void *msk, void *mpk, const void *seed, size_t seedlen, unsigne
VALIDATE_SECPAR(_secpar);
secpar = _secpar;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
if (!seed) {
gcry_randomize(iseed, FSPRG_RECOMMENDED_SEEDLEN, GCRY_STRONG_RANDOM);
@@ -295,7 +282,7 @@ void FSPRG_GenState0(void *state, const void *mpk, const void *seed, size_t seed
gcry_mpi_t n, x;
uint16_t secpar;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
secpar = read_secpar(mpk + 0);
n = mpi_import(mpk + 2, secpar / 8);
@@ -314,7 +301,7 @@ void FSPRG_Evolve(void *state) {
uint16_t secpar;
uint64_t epoch;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
secpar = read_secpar(state + 0);
n = mpi_import(state + 2 + 0 * secpar / 8, secpar / 8);
@@ -341,7 +328,7 @@ void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed,
gcry_mpi_t p, q, n, x, xp, xq, kp, kq, xm;
uint16_t secpar;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
secpar = read_secpar(msk + 0);
p = mpi_import(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8);
@@ -380,7 +367,7 @@ void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed,
void FSPRG_GetKey(const void *state, void *key, size_t keylen, uint32_t idx) {
uint16_t secpar;
- initialize_libgcrypt();
+ initialize_libgcrypt(false);
secpar = read_secpar(state + 0);
det_randomize(key, keylen, state + 2, 2 * secpar / 8 + 8, idx);
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-authenticate.c b/src/libsystemd/libsystemd-journal-internal/journal-authenticate.c
index 49f3c8f0f4..d8af113d3f 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-authenticate.c
+++ b/src/libsystemd/libsystemd-journal-internal/journal-authenticate.c
@@ -22,6 +22,7 @@
#include "fd-util.h"
#include "fsprg.h"
+#include "gcrypt-util.h"
#include "hexdecoct.h"
#include "journal-authenticate.h"
#include "journal-def.h"
@@ -424,25 +425,13 @@ finish:
return r;
}
-static void initialize_libgcrypt(void) {
- const char *p;
-
- if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
- return;
-
- p = gcry_check_version("1.4.5");
- assert(p);
-
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
-}
-
int journal_file_hmac_setup(JournalFile *f) {
gcry_error_t e;
if (!f->seal)
return 0;
- initialize_libgcrypt();
+ initialize_libgcrypt(true);
e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
if (e != 0)
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-file.c b/src/libsystemd/libsystemd-journal-internal/journal-file.c
index 4ea7013a53..13db5c53de 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-file.c
+++ b/src/libsystemd/libsystemd-journal-internal/journal-file.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
+#include <pthread.h>
#include <stddef.h>
#include <sys/mman.h>
#include <sys/statvfs.h>
@@ -36,8 +37,10 @@
#include "journal-file.h"
#include "lookup3.h"
#include "parse-util.h"
+#include "path-util.h"
#include "random-util.h"
#include <systemd/sd-event.h>
+#include "set.h"
#include "string-util.h"
#include "xattr-util.h"
@@ -86,33 +89,127 @@
/* The mmap context to use for the header we pick as one above the last defined typed */
#define CONTEXT_HEADER _OBJECT_TYPE_MAX
-static int journal_file_set_online(JournalFile *f) {
+/* This may be called from a separate thread to prevent blocking the caller for the duration of fsync().
+ * As a result we use atomic operations on f->offline_state for inter-thread communications with
+ * journal_file_set_offline() and journal_file_set_online(). */
+static void journal_file_set_offline_internal(JournalFile *f) {
assert(f);
+ assert(f->fd >= 0);
+ assert(f->header);
- if (!f->writable)
- return -EPERM;
+ for (;;) {
+ switch (f->offline_state) {
+ case OFFLINE_CANCEL:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_CANCEL, OFFLINE_DONE))
+ continue;
+ return;
- if (!(f->fd >= 0 && f->header))
- return -EINVAL;
+ case OFFLINE_AGAIN_FROM_SYNCING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_SYNCING, OFFLINE_SYNCING))
+ continue;
+ break;
+
+ case OFFLINE_AGAIN_FROM_OFFLINING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_OFFLINING, OFFLINE_SYNCING))
+ continue;
+ break;
+
+ case OFFLINE_SYNCING:
+ (void) fsync(f->fd);
+
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_OFFLINING))
+ continue;
+
+ f->header->state = f->archive ? STATE_ARCHIVED : STATE_OFFLINE;
+ (void) fsync(f->fd);
+ break;
+
+ case OFFLINE_OFFLINING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_OFFLINING, OFFLINE_DONE))
+ continue;
+ /* fall through */
+
+ case OFFLINE_DONE:
+ return;
+
+ case OFFLINE_JOINED:
+ log_debug("OFFLINE_JOINED unexpected offline state for journal_file_set_offline_internal()");
+ return;
+ }
+ }
+}
+
+static void * journal_file_set_offline_thread(void *arg) {
+ JournalFile *f = arg;
+
+ journal_file_set_offline_internal(f);
+
+ return NULL;
+}
+
+static int journal_file_set_offline_thread_join(JournalFile *f) {
+ int r;
+
+ assert(f);
+
+ if (f->offline_state == OFFLINE_JOINED)
+ return 0;
+
+ r = pthread_join(f->offline_thread, NULL);
+ if (r)
+ return -r;
+
+ f->offline_state = OFFLINE_JOINED;
if (mmap_cache_got_sigbus(f->mmap, f->fd))
return -EIO;
- switch (f->header->state) {
- case STATE_ONLINE:
- return 0;
+ return 0;
+}
- case STATE_OFFLINE:
- f->header->state = STATE_ONLINE;
- fsync(f->fd);
- return 0;
+/* Trigger a restart if the offline thread is mid-flight in a restartable state. */
+static bool journal_file_set_offline_try_restart(JournalFile *f) {
+ for (;;) {
+ switch (f->offline_state) {
+ case OFFLINE_AGAIN_FROM_SYNCING:
+ case OFFLINE_AGAIN_FROM_OFFLINING:
+ return true;
+
+ case OFFLINE_CANCEL:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_CANCEL, OFFLINE_AGAIN_FROM_SYNCING))
+ continue;
+ return true;
+
+ case OFFLINE_SYNCING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_AGAIN_FROM_SYNCING))
+ continue;
+ return true;
+
+ case OFFLINE_OFFLINING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_OFFLINING, OFFLINE_AGAIN_FROM_OFFLINING))
+ continue;
+ return true;
default:
- return -EINVAL;
+ return false;
+ }
}
}
-int journal_file_set_offline(JournalFile *f) {
+/* Sets a journal offline.
+ *
+ * If wait is false then an offline is dispatched in a separate thread for a
+ * subsequent journal_file_set_offline() or journal_file_set_online() of the
+ * same journal to synchronize with.
+ *
+ * If wait is true, then either an existing offline thread will be restarted
+ * and joined, or if none exists the offline is simply performed in this
+ * context without involving another thread.
+ */
+int journal_file_set_offline(JournalFile *f, bool wait) {
+ bool restarted;
+ int r;
+
assert(f);
if (!f->writable)
@@ -121,22 +218,114 @@ int journal_file_set_offline(JournalFile *f) {
if (!(f->fd >= 0 && f->header))
return -EINVAL;
- if (f->header->state != STATE_ONLINE)
+ /* An offlining journal is implicitly online and may modify f->header->state,
+ * we must also join any potentially lingering offline thread when not online. */
+ if (!journal_file_is_offlining(f) && f->header->state != STATE_ONLINE)
+ return journal_file_set_offline_thread_join(f);
+
+ /* Restart an in-flight offline thread and wait if needed, or join a lingering done one. */
+ restarted = journal_file_set_offline_try_restart(f);
+ if ((restarted && wait) || !restarted) {
+ r = journal_file_set_offline_thread_join(f);
+ if (r < 0)
+ return r;
+ }
+
+ if (restarted)
return 0;
- fsync(f->fd);
+ /* Initiate a new offline. */
+ f->offline_state = OFFLINE_SYNCING;
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
- return -EIO;
+ if (wait) /* Without using a thread if waiting. */
+ journal_file_set_offline_internal(f);
+ else {
+ r = pthread_create(&f->offline_thread, NULL, journal_file_set_offline_thread, f);
+ if (r > 0) {
+ f->offline_state = OFFLINE_JOINED;
+ return -r;
+ }
+ }
- f->header->state = STATE_OFFLINE;
+ return 0;
+}
+
+static int journal_file_set_online(JournalFile *f) {
+ bool joined = false;
+
+ assert(f);
+
+ if (!f->writable)
+ return -EPERM;
+
+ if (!(f->fd >= 0 && f->header))
+ return -EINVAL;
+
+ while (!joined) {
+ switch (f->offline_state) {
+ case OFFLINE_JOINED:
+ /* No offline thread, no need to wait. */
+ joined = true;
+ break;
+
+ case OFFLINE_SYNCING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_CANCEL))
+ continue;
+ /* Canceled syncing prior to offlining, no need to wait. */
+ break;
+
+ case OFFLINE_AGAIN_FROM_SYNCING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_SYNCING, OFFLINE_CANCEL))
+ continue;
+ /* Canceled restart from syncing, no need to wait. */
+ break;
+
+ case OFFLINE_AGAIN_FROM_OFFLINING:
+ if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_OFFLINING, OFFLINE_CANCEL))
+ continue;
+ /* Canceled restart from offlining, must wait for offlining to complete however. */
+
+ /* fall through to wait */
+ default: {
+ int r;
+
+ r = journal_file_set_offline_thread_join(f);
+ if (r < 0)
+ return r;
+
+ joined = true;
+ break;
+ }
+ }
+ }
if (mmap_cache_got_sigbus(f->mmap, f->fd))
return -EIO;
- fsync(f->fd);
+ switch (f->header->state) {
+ case STATE_ONLINE:
+ return 0;
- return 0;
+ case STATE_OFFLINE:
+ f->header->state = STATE_ONLINE;
+ (void) fsync(f->fd);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+bool journal_file_is_offlining(JournalFile *f) {
+ assert(f);
+
+ __sync_synchronize();
+
+ if (f->offline_state == OFFLINE_DONE ||
+ f->offline_state == OFFLINE_JOINED)
+ return false;
+
+ return true;
}
JournalFile* journal_file_close(JournalFile *f) {
@@ -159,7 +348,7 @@ JournalFile* journal_file_close(JournalFile *f) {
sd_event_source_unref(f->post_change_timer);
}
- journal_file_set_offline(f);
+ journal_file_set_offline(f, true);
if (f->mmap && f->fd >= 0)
mmap_cache_close_fd(f->mmap, f->fd);
@@ -176,7 +365,8 @@ JournalFile* journal_file_close(JournalFile *f) {
(void) btrfs_defrag_fd(f->fd);
}
- safe_close(f->fd);
+ if (f->close_fd)
+ safe_close(f->fd);
free(f->path);
mmap_cache_unref(f->mmap);
@@ -203,6 +393,15 @@ JournalFile* journal_file_close(JournalFile *f) {
return NULL;
}
+void journal_file_close_set(Set *s) {
+ JournalFile *f;
+
+ assert(s);
+
+ while ((f = set_steal_first(s)))
+ (void) journal_file_close(f);
+}
+
static int journal_file_init_header(JournalFile *f, JournalFile *template) {
Header h = {};
ssize_t k;
@@ -240,6 +439,39 @@ static int journal_file_init_header(JournalFile *f, JournalFile *template) {
return 0;
}
+static int fsync_directory_of_file(int fd) {
+ _cleanup_free_ char *path = NULL, *dn = NULL;
+ _cleanup_close_ int dfd = -1;
+ struct stat st;
+ int r;
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if (!S_ISREG(st.st_mode))
+ return -EBADFD;
+
+ r = fd_get_path(fd, &path);
+ if (r < 0)
+ return r;
+
+ if (!path_is_absolute(path))
+ return -EINVAL;
+
+ dn = dirname_malloc(path);
+ if (!dn)
+ return -ENOMEM;
+
+ dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+ if (dfd < 0)
+ return -errno;
+
+ if (fsync(dfd) < 0)
+ return -errno;
+
+ return 0;
+}
+
static int journal_file_refresh_header(JournalFile *f) {
sd_id128_t boot_id;
int r;
@@ -263,7 +495,10 @@ static int journal_file_refresh_header(JournalFile *f) {
r = journal_file_set_online(f);
/* Sync the online state to disk */
- fsync(f->fd);
+ (void) fsync(f->fd);
+
+ /* We likely just created a new file, also sync the directory this file is located in. */
+ (void) fsync_directory_of_file(f->fd);
return r;
}
@@ -508,7 +743,11 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset
/* Objects may only be located at multiple of 64 bit */
if (!VALID64(offset))
- return -EFAULT;
+ return -EBADMSG;
+
+ /* Object may not be located in the file header */
+ if (offset < le64toh(f->header->header_size))
+ return -EBADMSG;
r = journal_file_move_to(f, type, false, offset, sizeof(ObjectHeader), &t);
if (r < 0)
@@ -1123,8 +1362,8 @@ static int journal_file_append_data(
}
#endif
- if (compression == 0 && size > 0)
- memcpy(o->data.payload, data, size);
+ if (compression == 0)
+ memcpy_safe(o->data.payload, data, size);
r = journal_file_link_data(f, o, p, hash);
if (r < 0)
@@ -1389,7 +1628,7 @@ static int journal_file_append_entry_internal(
return r;
o->entry.seqnum = htole64(journal_file_entry_seqnum(f, seqnum));
- memcpy(o->entry.items, items, n_items * sizeof(EntryItem));
+ memcpy_safe(o->entry.items, items, n_items * sizeof(EntryItem));
o->entry.realtime = htole64(ts->realtime);
o->entry.monotonic = htole64(ts->monotonic);
o->entry.xor_hash = htole64(xor_hash);
@@ -1781,9 +2020,14 @@ static int generic_array_bisect(
i = right - 1;
lp = p = le64toh(array->entry_array.items[i]);
if (p <= 0)
- return -EBADMSG;
-
- r = test_object(f, p, needle);
+ r = -EBADMSG;
+ else
+ r = test_object(f, p, needle);
+ if (r == -EBADMSG) {
+ log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (1)");
+ n = i;
+ continue;
+ }
if (r < 0)
return r;
@@ -1859,9 +2103,14 @@ static int generic_array_bisect(
p = le64toh(array->entry_array.items[i]);
if (p <= 0)
- return -EBADMSG;
-
- r = test_object(f, p, needle);
+ r = -EBADMSG;
+ else
+ r = test_object(f, p, needle);
+ if (r == -EBADMSG) {
+ log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (2)");
+ right = n = i;
+ continue;
+ }
if (r < 0)
return r;
@@ -1977,7 +2226,7 @@ static int generic_array_bisect_plus_one(
goto found;
if (r > 0 && idx)
- (*idx) ++;
+ (*idx)++;
return r;
@@ -2266,13 +2515,18 @@ int journal_file_next_entry(
le64toh(f->header->entry_array_offset),
i,
ret, &ofs);
+ if (r == -EBADMSG && direction == DIRECTION_DOWN) {
+ /* Special case: when we iterate throught the journal file linearly, and hit an entry we can't read,
+ * consider this the end of the journal file. */
+ log_debug_errno(r, "Encountered entry we can't read while iterating through journal file. Considering this the end of the file.");
+ return 0;
+ }
if (r <= 0)
return r;
if (p > 0 &&
(direction == DIRECTION_DOWN ? ofs <= p : ofs >= p)) {
- log_debug("%s: entry array corrupted at entry %"PRIu64,
- f->path, i);
+ log_debug("%s: entry array corrupted at entry %" PRIu64, f->path, i);
return -EBADMSG;
}
@@ -2611,11 +2865,11 @@ void journal_file_print_header(JournalFile *f) {
"Data Hash Table Size: %"PRIu64"\n"
"Field Hash Table Size: %"PRIu64"\n"
"Rotate Suggested: %s\n"
- "Head Sequential Number: %"PRIu64"\n"
- "Tail Sequential Number: %"PRIu64"\n"
- "Head Realtime Timestamp: %s\n"
- "Tail Realtime Timestamp: %s\n"
- "Tail Monotonic Timestamp: %s\n"
+ "Head Sequential Number: %"PRIu64" (%"PRIx64")\n"
+ "Tail Sequential Number: %"PRIu64" (%"PRIx64")\n"
+ "Head Realtime Timestamp: %s (%"PRIx64")\n"
+ "Tail Realtime Timestamp: %s (%"PRIx64")\n"
+ "Tail Monotonic Timestamp: %s (%"PRIx64")\n"
"Objects: %"PRIu64"\n"
"Entry Objects: %"PRIu64"\n",
f->path,
@@ -2636,11 +2890,11 @@ void journal_file_print_header(JournalFile *f) {
le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
le64toh(f->header->field_hash_table_size) / sizeof(HashItem),
yes_no(journal_file_rotate_suggested(f, 0)),
- le64toh(f->header->head_entry_seqnum),
- le64toh(f->header->tail_entry_seqnum),
- format_timestamp_safe(x, sizeof(x), le64toh(f->header->head_entry_realtime)),
- format_timestamp_safe(y, sizeof(y), le64toh(f->header->tail_entry_realtime)),
- format_timespan(z, sizeof(z), le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC),
+ le64toh(f->header->head_entry_seqnum), le64toh(f->header->head_entry_seqnum),
+ le64toh(f->header->tail_entry_seqnum), le64toh(f->header->tail_entry_seqnum),
+ format_timestamp_safe(x, sizeof(x), le64toh(f->header->head_entry_realtime)), le64toh(f->header->head_entry_realtime),
+ format_timestamp_safe(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), le64toh(f->header->tail_entry_realtime),
+ format_timespan(z, sizeof(z), le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC), le64toh(f->header->tail_entry_monotonic),
le64toh(f->header->n_objects),
le64toh(f->header->n_entries));
@@ -2703,6 +2957,7 @@ static int journal_file_warn_btrfs(JournalFile *f) {
}
int journal_file_open(
+ int fd,
const char *fname,
int flags,
mode_t mode,
@@ -2710,6 +2965,7 @@ int journal_file_open(
bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
+ Set *deferred_closes,
JournalFile *template,
JournalFile **ret) {
@@ -2718,22 +2974,24 @@ int journal_file_open(
void *h;
int r;
- assert(fname);
assert(ret);
+ assert(fd >= 0 || fname);
if ((flags & O_ACCMODE) != O_RDONLY &&
(flags & O_ACCMODE) != O_RDWR)
return -EINVAL;
- if (!endswith(fname, ".journal") &&
- !endswith(fname, ".journal~"))
- return -EINVAL;
+ if (fname) {
+ if (!endswith(fname, ".journal") &&
+ !endswith(fname, ".journal~"))
+ return -EINVAL;
+ }
f = new0(JournalFile, 1);
if (!f)
return -ENOMEM;
- f->fd = -1;
+ f->fd = fd;
f->mode = mode;
f->flags = flags;
@@ -2758,7 +3016,10 @@ int journal_file_open(
}
}
- f->path = strdup(fname);
+ if (fname)
+ f->path = strdup(fname);
+ else /* If we don't know the path, fill in something explanatory and vaguely useful */
+ asprintf(&f->path, "/proc/self/%i", fd);
if (!f->path) {
r = -ENOMEM;
goto fail;
@@ -2770,10 +3031,15 @@ int journal_file_open(
goto fail;
}
- f->fd = open(f->path, f->flags|O_CLOEXEC, f->mode);
if (f->fd < 0) {
- r = -errno;
- goto fail;
+ f->fd = open(f->path, f->flags|O_CLOEXEC, f->mode);
+ if (f->fd < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ /* fds we opened here by us should also be closed by us. */
+ f->close_fd = true;
}
r = journal_file_fstat(f);
@@ -2829,6 +3095,9 @@ int journal_file_open(
f->header = h;
if (!newly_created) {
+ if (deferred_closes)
+ journal_file_close_set(deferred_closes);
+
r = journal_file_verify_header(f);
if (r < 0)
goto fail;
@@ -2891,6 +3160,9 @@ int journal_file_open(
goto fail;
}
+ /* The file is opened now successfully, thus we take possession of any passed in fd. */
+ f->close_fd = true;
+
*ret = f;
return 0;
@@ -2898,12 +3170,12 @@ fail:
if (f->fd >= 0 && mmap_cache_got_sigbus(f->mmap, f->fd))
r = -EIO;
- journal_file_close(f);
+ (void) journal_file_close(f);
return r;
}
-int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
+int journal_file_rotate(JournalFile **f, bool compress, bool seal, Set *deferred_closes) {
_cleanup_free_ char *p = NULL;
size_t l;
JournalFile *old_file, *new_file = NULL;
@@ -2917,6 +3189,11 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
if (!old_file->writable)
return -EINVAL;
+ /* Is this a journal file that was passed to us as fd? If so, we synthesized a path name for it, and we refuse
+ * rotation, since we don't know the actual path, and couldn't rename the file hence.*/
+ if (path_startswith(old_file->path, "/proc/self/fd"))
+ return -EINVAL;
+
if (!endswith(old_file->path, ".journal"))
return -EINVAL;
@@ -2936,15 +3213,29 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
if (r < 0 && errno != ENOENT)
return -errno;
- old_file->header->state = STATE_ARCHIVED;
+ /* Sync the rename to disk */
+ (void) fsync_directory_of_file(old_file->fd);
+
+ /* Set as archive so offlining commits w/state=STATE_ARCHIVED.
+ * Previously we would set old_file->header->state to STATE_ARCHIVED directly here,
+ * but journal_file_set_offline() short-circuits when state != STATE_ONLINE, which
+ * would result in the rotated journal never getting fsync() called before closing.
+ * Now we simply queue the archive state by setting an archive bit, leaving the state
+ * as STATE_ONLINE so proper offlining occurs. */
+ old_file->archive = true;
/* Currently, btrfs is not very good with out write patterns
* and fragments heavily. Let's defrag our journal files when
* we archive them */
old_file->defrag_on_close = true;
- r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file);
- journal_file_close(old_file);
+ r = journal_file_open(-1, old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, deferred_closes, old_file, &new_file);
+
+ if (deferred_closes &&
+ set_put(deferred_closes, old_file) >= 0)
+ (void) journal_file_set_offline(old_file, false);
+ else
+ (void) journal_file_close(old_file);
*f = new_file;
return r;
@@ -2958,6 +3249,7 @@ int journal_file_open_reliably(
bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
+ Set *deferred_closes,
JournalFile *template,
JournalFile **ret) {
@@ -2965,7 +3257,7 @@ int journal_file_open_reliably(
size_t l;
_cleanup_free_ char *p = NULL;
- r = journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, template, ret);
+ r = journal_file_open(-1, fname, flags, mode, compress, seal, metrics, mmap_cache, deferred_closes, template, ret);
if (!IN_SET(r,
-EBADMSG, /* corrupted */
-ENODATA, /* truncated */
@@ -3001,12 +3293,12 @@ int journal_file_open_reliably(
/* btrfs doesn't cope well with our write pattern and
* fragments heavily. Let's defrag all files we rotate */
- (void) chattr_path(p, false, FS_NOCOW_FL);
+ (void) chattr_path(p, 0, FS_NOCOW_FL);
(void) btrfs_defrag(p);
log_warning_errno(r, "File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
- return journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, template, ret);
+ return journal_file_open(-1, fname, flags, mode, compress, seal, metrics, mmap_cache, deferred_closes, template, ret);
}
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) {
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-file.h b/src/libsystemd/libsystemd-journal-internal/journal-file.h
index 0414117d98..e48e98f424 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-file.h
+++ b/src/libsystemd/libsystemd-journal-internal/journal-file.h
@@ -63,6 +63,16 @@ typedef enum LocationType {
LOCATION_SEEK
} LocationType;
+typedef enum OfflineState {
+ OFFLINE_JOINED,
+ OFFLINE_SYNCING,
+ OFFLINE_OFFLINING,
+ OFFLINE_CANCEL,
+ OFFLINE_AGAIN_FROM_SYNCING,
+ OFFLINE_AGAIN_FROM_OFFLINING,
+ OFFLINE_DONE
+} OfflineState;
+
typedef struct JournalFile {
int fd;
@@ -75,6 +85,8 @@ typedef struct JournalFile {
bool compress_lz4:1;
bool seal:1;
bool defrag_on_close:1;
+ bool close_fd:1;
+ bool archive:1;
bool tail_entry_monotonic_valid:1;
@@ -105,6 +117,9 @@ typedef struct JournalFile {
OrderedHashmap *chain_cache;
+ pthread_t offline_thread;
+ volatile OfflineState offline_state;
+
#if defined(HAVE_XZ) || defined(HAVE_LZ4)
void *compress_buffer;
size_t compress_buffer_size;
@@ -129,6 +144,7 @@ typedef struct JournalFile {
} JournalFile;
int journal_file_open(
+ int fd,
const char *fname,
int flags,
mode_t mode,
@@ -136,11 +152,14 @@ int journal_file_open(
bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
+ Set *deferred_closes,
JournalFile *template,
JournalFile **ret);
-int journal_file_set_offline(JournalFile *f);
+int journal_file_set_offline(JournalFile *f, bool wait);
+bool journal_file_is_offlining(JournalFile *f);
JournalFile* journal_file_close(JournalFile *j);
+void journal_file_close_set(Set *s);
int journal_file_open_reliably(
const char *fname,
@@ -150,6 +169,7 @@ int journal_file_open_reliably(
bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
+ Set *deferred_closes,
JournalFile *template,
JournalFile **ret);
@@ -223,7 +243,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
void journal_file_dump(JournalFile *f);
void journal_file_print_header(JournalFile *f);
-int journal_file_rotate(JournalFile **f, bool compress, bool seal);
+int journal_file_rotate(JournalFile **f, bool compress, bool seal, Set *deferred_closes);
void journal_file_post_change(JournalFile *f);
int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t);
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-internal.h b/src/libsystemd/libsystemd-journal-internal/journal-internal.h
index 8f21544ae1..d8eb11ad06 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-internal.h
+++ b/src/libsystemd/libsystemd-journal-internal/journal-internal.h
@@ -82,6 +82,8 @@ struct Directory {
};
struct sd_journal {
+ int toplevel_fd;
+
char *path;
char *prefix;
@@ -117,6 +119,7 @@ struct sd_journal {
bool on_network:1;
bool no_new_files:1;
+ bool no_inotify:1;
bool unique_file_lost:1; /* File we were iterating over got
removed, and there were no more
files, so sd_j_enumerate_unique
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-send.c b/src/libsystemd/libsystemd-journal-internal/journal-send.c
index b85d9d3c61..5a49211f85 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-send.c
+++ b/src/libsystemd/libsystemd-journal-internal/journal-send.c
@@ -50,7 +50,7 @@
*_f = alloca(_fl + 10); \
memcpy(*_f, "CODE_FUNC=", 10); \
memcpy(*_f + 10, _func, _fl); \
- } while(false)
+ } while (false)
/* We open a single fd, and we'll share it with the current process,
* all its threads, and all its subprocesses. This means we need to
@@ -208,13 +208,13 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
struct iovec *w;
uint64_t *l;
int i, j = 0;
- struct sockaddr_un sa = {
- .sun_family = AF_UNIX,
- .sun_path = "/run/systemd/journal/socket",
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/socket",
};
struct msghdr mh = {
- .msg_name = &sa,
- .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path),
+ .msg_name = (struct sockaddr*) &sa.sa,
+ .msg_namelen = SOCKADDR_UN_LEN(sa.un),
};
ssize_t k;
bool have_syslog_identifier = false;
@@ -316,7 +316,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
buffer_fd = memfd_new(NULL);
if (buffer_fd < 0) {
if (buffer_fd == -ENOSYS) {
- buffer_fd = open_tmpfile("/dev/shm", O_RDWR | O_CLOEXEC);
+ buffer_fd = open_tmpfile_unlinkable("/dev/shm", O_RDWR | O_CLOEXEC);
if (buffer_fd < 0)
return buffer_fd;
@@ -392,7 +392,7 @@ _public_ int sd_journal_perror(const char *message) {
}
_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
- union sockaddr_union sa = {
+ static const union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
.un.sun_path = "/run/systemd/journal/stdout",
};
@@ -408,7 +408,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
if (fd < 0)
return -errno;
- r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return -errno;
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-vacuum.c b/src/libsystemd/libsystemd-journal-internal/journal-vacuum.c
index 3650ab3865..cd2676ab63 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-vacuum.c
+++ b/src/libsystemd/libsystemd-journal-internal/journal-vacuum.c
@@ -239,13 +239,13 @@ int journal_directory_vacuum(
/* Vacuum corrupted files */
if (q < 1 + 16 + 1 + 16 + 8 + 1) {
- n_active_files ++;
+ n_active_files++;
continue;
}
if (de->d_name[q-1-8-16-1] != '-' ||
de->d_name[q-1-8-16-1-16-1] != '@') {
- n_active_files ++;
+ n_active_files++;
continue;
}
@@ -256,7 +256,7 @@ int journal_directory_vacuum(
}
if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) {
- n_active_files ++;
+ n_active_files++;
continue;
}
@@ -302,7 +302,7 @@ int journal_directory_vacuum(
list[n_list].realtime = realtime;
list[n_list].seqnum_id = seqnum_id;
list[n_list].have_seqnum = have_seqnum;
- n_list ++;
+ n_list++;
p = NULL;
sum += size;
diff --git a/src/libsystemd/libsystemd-journal-internal/journal-verify.c b/src/libsystemd/libsystemd-journal-internal/journal-verify.c
index b968e89bb8..26572ddd76 100644
--- a/src/libsystemd/libsystemd-journal-internal/journal-verify.c
+++ b/src/libsystemd/libsystemd-journal-internal/journal-verify.c
@@ -97,20 +97,20 @@ static void flush_progress(void) {
fflush(stdout);
}
-#define debug(_offset, _fmt, ...) do{ \
+#define debug(_offset, _fmt, ...) do { \
flush_progress(); \
log_debug(OFSfmt": " _fmt, _offset, ##__VA_ARGS__); \
- } while(0)
+ } while (0)
-#define warning(_offset, _fmt, ...) do{ \
+#define warning(_offset, _fmt, ...) do { \
flush_progress(); \
log_warning(OFSfmt": " _fmt, _offset, ##__VA_ARGS__); \
- } while(0)
+ } while (0)
-#define error(_offset, _fmt, ...) do{ \
+#define error(_offset, _fmt, ...) do { \
flush_progress(); \
log_error(OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \
- } while(0)
+ } while (0)
static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) {
uint64_t i;
@@ -838,19 +838,19 @@ int journal_file_verify(
} else if (f->seal)
return -ENOKEY;
- data_fd = open_tmpfile("/var/tmp", O_RDWR | O_CLOEXEC);
+ data_fd = open_tmpfile_unlinkable("/var/tmp", O_RDWR | O_CLOEXEC);
if (data_fd < 0) {
r = log_error_errno(data_fd, "Failed to create data file: %m");
goto fail;
}
- entry_fd = open_tmpfile("/var/tmp", O_RDWR | O_CLOEXEC);
+ entry_fd = open_tmpfile_unlinkable("/var/tmp", O_RDWR | O_CLOEXEC);
if (entry_fd < 0) {
r = log_error_errno(entry_fd, "Failed to create entry file: %m");
goto fail;
}
- entry_array_fd = open_tmpfile("/var/tmp", O_RDWR | O_CLOEXEC);
+ entry_array_fd = open_tmpfile_unlinkable("/var/tmp", O_RDWR | O_CLOEXEC);
if (entry_array_fd < 0) {
r = log_error_errno(entry_array_fd,
"Failed to create entry array file: %m");
@@ -894,7 +894,7 @@ int journal_file_verify(
goto fail;
}
- n_objects ++;
+ n_objects++;
r = journal_file_object_verify(f, p, o);
if (r < 0) {
@@ -991,7 +991,7 @@ int journal_file_verify(
entry_realtime = le64toh(o->entry.realtime);
entry_realtime_set = true;
- n_entries ++;
+ n_entries++;
break;
case OBJECT_DATA_HASH_TABLE:
@@ -1131,11 +1131,11 @@ int journal_file_verify(
last_epoch = le64toh(o->tag.epoch);
- n_tags ++;
+ n_tags++;
break;
default:
- n_weird ++;
+ n_weird++;
}
if (p == le64toh(f->header->tail_object_offset)) {
diff --git a/src/libsystemd/libsystemd-journal-internal/mmap-cache.c b/src/libsystemd/libsystemd-journal-internal/mmap-cache.c
index 9c0ce8ccbf..6bcd9b6ac8 100644
--- a/src/libsystemd/libsystemd-journal-internal/mmap-cache.c
+++ b/src/libsystemd/libsystemd-journal-internal/mmap-cache.c
@@ -107,7 +107,7 @@ MMapCache* mmap_cache_ref(MMapCache *m) {
assert(m);
assert(m->n_ref > 0);
- m->n_ref ++;
+ m->n_ref++;
return m;
}
@@ -361,7 +361,7 @@ MMapCache* mmap_cache_unref(MMapCache *m) {
assert(m->n_ref > 0);
- m->n_ref --;
+ m->n_ref--;
if (m->n_ref == 0)
mmap_cache_free(m);
@@ -598,14 +598,14 @@ int mmap_cache_get(
/* Check whether the current context is the right one already */
r = try_context(m, fd, prot, context, keep_always, offset, size, ret);
if (r != 0) {
- m->n_hit ++;
+ m->n_hit++;
return r;
}
/* Search for a matching mmap */
r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret);
if (r != 0) {
- m->n_hit ++;
+ m->n_hit++;
return r;
}
diff --git a/src/libsystemd/libsystemd-journal-internal/sd-journal.c b/src/libsystemd/libsystemd-journal-internal/sd-journal.c
index 1493f0348d..930486d65f 100644
--- a/src/libsystemd/libsystemd-journal-internal/sd-journal.c
+++ b/src/libsystemd/libsystemd-journal-internal/sd-journal.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <linux/magic.h>
#include <poll.h>
#include <stddef.h>
@@ -1063,7 +1064,7 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
if (r < 0)
return r;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *item = NULL;
unsigned long long ll;
sd_id128_t id;
@@ -1232,14 +1233,37 @@ static bool file_type_wanted(int flags, const char *filename) {
return false;
}
-static int add_any_file(sd_journal *j, const char *path) {
+static bool path_has_prefix(sd_journal *j, const char *path, const char *prefix) {
+ assert(j);
+ assert(path);
+ assert(prefix);
+
+ if (j->toplevel_fd >= 0)
+ return false;
+
+ return path_startswith(path, prefix);
+}
+
+static const char *skip_slash(const char *p) {
+
+ if (!p)
+ return NULL;
+
+ while (*p == '/')
+ p++;
+
+ return p;
+}
+
+static int add_any_file(sd_journal *j, int fd, const char *path) {
JournalFile *f = NULL;
+ bool close_fd = false;
int r, k;
assert(j);
- assert(path);
+ assert(fd >= 0 || path);
- if (ordered_hashmap_get(j->files, path))
+ if (path && ordered_hashmap_get(j->files, path))
return 0;
if (ordered_hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
@@ -1248,8 +1272,24 @@ static int add_any_file(sd_journal *j, const char *path) {
goto fail;
}
- r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
+ if (fd < 0 && j->toplevel_fd >= 0) {
+
+ /* If there's a top-level fd defined, open the file relative to this now. (Make the path relative,
+ * explicitly, since otherwise openat() ignores the first argument.) */
+
+ fd = openat(j->toplevel_fd, skip_slash(path), O_RDONLY|O_CLOEXEC);
+ if (fd < 0) {
+ r = log_debug_errno(errno, "Failed to open journal file %s: %m", path);
+ goto fail;
+ }
+
+ close_fd = true;
+ }
+
+ r = journal_file_open(fd, path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, NULL, &f);
if (r < 0) {
+ if (close_fd)
+ safe_close(fd);
log_debug_errno(r, "Failed to open journal file %s: %m", path);
goto fail;
}
@@ -1258,15 +1298,21 @@ static int add_any_file(sd_journal *j, const char *path) {
r = ordered_hashmap_put(j->files, f->path, f);
if (r < 0) {
- journal_file_close(f);
+ f->close_fd = close_fd;
+ (void) journal_file_close(f);
goto fail;
}
+ if (!j->has_runtime_files && path_has_prefix(j, f->path, "/run"))
+ j->has_runtime_files = true;
+ else if (!j->has_persistent_files && path_has_prefix(j, f->path, "/var"))
+ j->has_persistent_files = true;
+
log_debug("File %s added.", f->path);
check_network(j, f->fd);
- j->current_invalidate_counter ++;
+ j->current_invalidate_counter++;
return 0;
@@ -1285,18 +1331,14 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
assert(prefix);
assert(filename);
- if (j->no_new_files ||
- !file_type_wanted(j->flags, filename))
+ if (j->no_new_files)
return 0;
- path = strjoina(prefix, "/", filename);
-
- if (!j->has_runtime_files && path_startswith(path, "/run/log/journal"))
- j->has_runtime_files = true;
- else if (!j->has_persistent_files && path_startswith(path, "/var/log/journal"))
- j->has_persistent_files = true;
+ if (!file_type_wanted(j->flags, filename))
+ return 0;
- return add_any_file(j, path);
+ path = strjoina(prefix, "/", filename);
+ return add_any_file(j, -1, path);
}
static void remove_file(sd_journal *j, const char *prefix, const char *filename) {
@@ -1343,9 +1385,9 @@ static void remove_file_real(sd_journal *j, JournalFile *f) {
j->fields_file_lost = true;
}
- journal_file_close(f);
+ (void) journal_file_close(f);
- j->current_invalidate_counter ++;
+ j->current_invalidate_counter++;
}
static int dirname_is_machine_id(const char *fn) {
@@ -1372,21 +1414,33 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
assert(j);
assert(prefix);
- assert(dirname);
- log_debug("Considering %s/%s.", prefix, dirname);
-
- if ((j->flags & SD_JOURNAL_LOCAL_ONLY) &&
- !(dirname_is_machine_id(dirname) > 0 || path_startswith(prefix, "/run")))
- return 0;
+ /* Adds a journal file directory to watch. If the directory is already tracked this updates the inotify watch
+ * and reenumerates directory contents */
- path = strjoin(prefix, "/", dirname, NULL);
+ if (dirname)
+ path = strjoin(prefix, "/", dirname, NULL);
+ else
+ path = strdup(prefix);
if (!path) {
r = -ENOMEM;
goto fail;
}
- d = opendir(path);
+ log_debug("Considering directory %s.", path);
+
+ /* We consider everything local that is in a directory for the local machine ID, or that is stored in /run */
+ if ((j->flags & SD_JOURNAL_LOCAL_ONLY) &&
+ !((dirname && dirname_is_machine_id(dirname) > 0) || path_has_prefix(j, path, "/run")))
+ return 0;
+
+
+ if (j->toplevel_fd < 0)
+ d = opendir(path);
+ else
+ /* Open the specified directory relative to the the toplevel fd. Enforce that the path specified is
+ * relative, by dropping the initial slash */
+ d = xopendirat(j->toplevel_fd, skip_slash(path), 0);
if (!d) {
r = log_debug_errno(errno, "Failed to open directory %s: %m", path);
goto fail;
@@ -1410,7 +1464,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
}
path = NULL; /* avoid freeing in cleanup */
- j->current_invalidate_counter ++;
+ j->current_invalidate_counter++;
log_debug("Directory %s added.", m->path);
@@ -1418,17 +1472,18 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
return 0;
if (m->wd <= 0 && j->inotify_fd >= 0) {
+ /* Watch this directory, if it not being watched yet. */
- m->wd = inotify_add_watch(j->inotify_fd, m->path,
- IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
- IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_MOVED_FROM|
- IN_ONLYDIR);
+ m->wd = inotify_add_watch_fd(j->inotify_fd, dirfd(d),
+ IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
+ IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_MOVED_FROM|
+ IN_ONLYDIR);
if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
inotify_rm_watch(j->inotify_fd, m->wd);
}
- FOREACH_DIRENT_ALL(de, d, return log_debug_errno(errno, "Failed to read directory %s: %m", m->path)) {
+ FOREACH_DIRENT_ALL(de, d, r = log_debug_errno(errno, "Failed to read directory %s: %m", m->path); goto fail) {
if (dirent_is_file_with_suffix(de, ".journal") ||
dirent_is_file_with_suffix(de, ".journal~"))
@@ -1440,7 +1495,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
return 0;
fail:
- k = journal_put_error(j, r, path ?: dirname);
+ k = journal_put_error(j, r, path ?: prefix);
if (k < 0)
return k;
@@ -1448,28 +1503,62 @@ fail:
}
static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
+
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
Directory *m;
int r, k;
assert(j);
- assert(p);
- if ((j->flags & SD_JOURNAL_RUNTIME_ONLY) &&
- !path_startswith(p, "/run"))
- return -EINVAL;
+ /* Adds a root directory to our set of directories to use. If the root directory is already in the set, we
+ * update the inotify logic, and renumerate the directory entries. This call may hence be called to initially
+ * populate the set, as well as to update it later. */
- if (j->prefix)
- p = strjoina(j->prefix, p);
+ if (p) {
+ /* If there's a path specified, use it. */
- d = opendir(p);
- if (!d) {
- if (errno == ENOENT && missing_ok)
- return 0;
+ if ((j->flags & SD_JOURNAL_RUNTIME_ONLY) &&
+ !path_has_prefix(j, p, "/run"))
+ return -EINVAL;
- r = log_debug_errno(errno, "Failed to open root directory %s: %m", p);
- goto fail;
+ if (j->prefix)
+ p = strjoina(j->prefix, p);
+
+ if (j->toplevel_fd < 0)
+ d = opendir(p);
+ else
+ d = xopendirat(j->toplevel_fd, skip_slash(p), 0);
+
+ if (!d) {
+ if (errno == ENOENT && missing_ok)
+ return 0;
+
+ r = log_debug_errno(errno, "Failed to open root directory %s: %m", p);
+ goto fail;
+ }
+ } else {
+ int dfd;
+
+ /* If there's no path specified, then we use the top-level fd itself. We duplicate the fd here, since
+ * opendir() will take possession of the fd, and close it, which we don't want. */
+
+ p = "."; /* store this as "." in the directories hashmap */
+
+ dfd = fcntl(j->toplevel_fd, F_DUPFD_CLOEXEC, 3);
+ if (dfd < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ d = fdopendir(dfd);
+ if (!d) {
+ r = -errno;
+ safe_close(dfd);
+ goto fail;
+ }
+
+ rewinddir(d);
}
m = hashmap_get(j->directories_by_path, p);
@@ -1481,6 +1570,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
}
m->is_root = true;
+
m->path = strdup(p);
if (!m->path) {
free(m);
@@ -1495,7 +1585,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
goto fail;
}
- j->current_invalidate_counter ++;
+ j->current_invalidate_counter++;
log_debug("Root directory %s added.", m->path);
@@ -1504,7 +1594,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
if (m->wd <= 0 && j->inotify_fd >= 0) {
- m->wd = inotify_add_watch(j->inotify_fd, m->path,
+ m->wd = inotify_add_watch_fd(j->inotify_fd, dirfd(d),
IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
IN_ONLYDIR);
@@ -1515,7 +1605,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
if (j->no_new_files)
return 0;
- FOREACH_DIRENT_ALL(de, d, return log_debug_errno(errno, "Failed to read directory %s: %m", m->path)) {
+ FOREACH_DIRENT_ALL(de, d, r = log_debug_errno(errno, "Failed to read directory %s: %m", m->path); goto fail) {
sd_id128_t id;
if (dirent_is_file_with_suffix(de, ".journal") ||
@@ -1584,8 +1674,7 @@ static int add_current_paths(sd_journal *j) {
assert(j);
assert(j->no_new_files);
- /* Simply adds all directories for files we have open as
- * "root" directories. We don't expect errors here, so we
+ /* Simply adds all directories for files we have open as directories. We don't expect errors here, so we
* treat them as fatal. */
ORDERED_HASHMAP_FOREACH(f, j->files, i) {
@@ -1596,7 +1685,7 @@ static int add_current_paths(sd_journal *j) {
if (!dir)
return -ENOMEM;
- r = add_root_directory(j, dir, true);
+ r = add_directory(j, dir, NULL);
if (r < 0)
return r;
}
@@ -1613,13 +1702,7 @@ static int allocate_inotify(sd_journal *j) {
return -errno;
}
- if (!j->directories_by_wd) {
- j->directories_by_wd = hashmap_new(NULL);
- if (!j->directories_by_wd)
- return -ENOMEM;
- }
-
- return 0;
+ return hashmap_ensure_allocated(&j->directories_by_wd, NULL);
}
static sd_journal *journal_new(int flags, const char *path) {
@@ -1630,6 +1713,7 @@ static sd_journal *journal_new(int flags, const char *path) {
return NULL;
j->original_pid = getpid();
+ j->toplevel_fd = -1;
j->inotify_fd = -1;
j->flags = flags;
j->data_threshold = DEFAULT_DATA_THRESHOLD;
@@ -1683,6 +1767,9 @@ _public_ int sd_journal_open_container(sd_journal **ret, const char *machine, in
char *p;
int r;
+ /* This is pretty much deprecated, people should use machined's OpenMachineRootDirectory() call instead in
+ * combination with sd_journal_open_directory_fd(). */
+
assert_return(machine, -EINVAL);
assert_return(ret, -EINVAL);
assert_return((flags & ~(SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM)) == 0, -EINVAL);
@@ -1725,13 +1812,16 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f
assert_return(ret, -EINVAL);
assert_return(path, -EINVAL);
- assert_return(flags == 0, -EINVAL);
+ assert_return((flags & ~SD_JOURNAL_OS_ROOT) == 0, -EINVAL);
j = journal_new(flags, path);
if (!j)
return -ENOMEM;
- r = add_root_directory(j, path, false);
+ if (flags & SD_JOURNAL_OS_ROOT)
+ r = add_search_paths(j);
+ else
+ r = add_root_directory(j, path, false);
if (r < 0)
goto fail;
@@ -1740,7 +1830,6 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f
fail:
sd_journal_close(j);
-
return r;
}
@@ -1757,7 +1846,7 @@ _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int fla
return -ENOMEM;
STRV_FOREACH(path, paths) {
- r = add_any_file(j, *path);
+ r = add_any_file(j, -1, *path);
if (r < 0)
goto fail;
}
@@ -1769,7 +1858,96 @@ _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int fla
fail:
sd_journal_close(j);
+ return r;
+}
+
+_public_ int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags) {
+ sd_journal *j;
+ struct stat st;
+ int r;
+
+ assert_return(ret, -EINVAL);
+ assert_return(fd >= 0, -EBADF);
+ assert_return((flags & ~SD_JOURNAL_OS_ROOT) == 0, -EINVAL);
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if (!S_ISDIR(st.st_mode))
+ return -EBADFD;
+
+ j = journal_new(flags, NULL);
+ if (!j)
+ return -ENOMEM;
+
+ j->toplevel_fd = fd;
+
+ if (flags & SD_JOURNAL_OS_ROOT)
+ r = add_search_paths(j);
+ else
+ r = add_root_directory(j, NULL, false);
+ if (r < 0)
+ goto fail;
+ *ret = j;
+ return 0;
+
+fail:
+ sd_journal_close(j);
+ return r;
+}
+
+_public_ int sd_journal_open_files_fd(sd_journal **ret, int fds[], unsigned n_fds, int flags) {
+ Iterator iterator;
+ JournalFile *f;
+ sd_journal *j;
+ unsigned i;
+ int r;
+
+ assert_return(ret, -EINVAL);
+ assert_return(n_fds > 0, -EBADF);
+ assert_return(flags == 0, -EINVAL);
+
+ j = journal_new(flags, NULL);
+ if (!j)
+ return -ENOMEM;
+
+ for (i = 0; i < n_fds; i++) {
+ struct stat st;
+
+ if (fds[i] < 0) {
+ r = -EBADF;
+ goto fail;
+ }
+
+ if (fstat(fds[i], &st) < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ r = -EBADFD;
+ goto fail;
+ }
+
+ r = add_any_file(j, fds[i], NULL);
+ if (r < 0)
+ goto fail;
+ }
+
+ j->no_new_files = true;
+ j->no_inotify = true;
+
+ *ret = j;
+ return 0;
+
+fail:
+ /* If we fail, make sure we don't take possession of the files we managed to make use of successfully, and they
+ * remain open */
+ ORDERED_HASHMAP_FOREACH(f, j->files, iterator)
+ f->close_fd = false;
+
+ sd_journal_close(j);
return r;
}
@@ -1784,7 +1962,7 @@ _public_ void sd_journal_close(sd_journal *j) {
sd_journal_flush_matches(j);
while ((f = ordered_hashmap_steal_first(j->files)))
- journal_file_close(f);
+ (void) journal_file_close(f);
ordered_hashmap_free(j->files);
@@ -1957,7 +2135,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
&f->compress_buffer, &f->compress_buffer_size,
field, field_length, '=');
if (r < 0)
- log_debug_errno(r, "Cannot decompress %s object of length %zu at offset "OFSfmt": %m",
+ log_debug_errno(r, "Cannot decompress %s object of length %"PRIu64" at offset "OFSfmt": %m",
object_compressed_to_string(compression), l, p);
else if (r > 0) {
@@ -2078,7 +2256,7 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
if (r < 0)
return r;
- j->current_field ++;
+ j->current_field++;
return 1;
}
@@ -2096,6 +2274,9 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
assert_return(j, -EINVAL);
assert_return(!journal_pid_changed(j), -ECHILD);
+ if (j->no_inotify)
+ return -EMEDIUMTYPE;
+
if (j->inotify_fd >= 0)
return j->inotify_fd;
@@ -2103,10 +2284,14 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
if (r < 0)
return r;
+ log_debug("Reiterating files to get inotify watches established");
+
/* Iterate through all dirs again, to add them to the
* inotify */
if (j->no_new_files)
r = add_current_paths(j);
+ else if (j->toplevel_fd >= 0)
+ r = add_root_directory(j, NULL, false);
else if (j->path)
r = add_root_directory(j, j->path, true);
else
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 4ab637b686..0b3a1708dc 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -489,3 +489,9 @@ global:
sd_journal_enumerate_fields;
sd_journal_restart_fields;
} LIBSYSTEMD_227;
+
+LIBSYSTEMD_230 {
+global:
+ sd_journal_open_directory_fd;
+ sd_journal_open_files_fd;
+} LIBSYSTEMD_229;
diff --git a/src/libudev/include/libudev.h b/src/libudev/include/libudev.h
index eb58740d26..3f6d0ed16c 100644
--- a/src/libudev/include/libudev.h
+++ b/src/libudev/include/libudev.h
@@ -21,6 +21,7 @@
#define _LIBUDEV_H_
#include <stdarg.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#ifdef __cplusplus
diff --git a/src/libudev/src/libudev-device-internal.h b/src/libudev/src/libudev-device-internal.h
index de6f680819..f76da09407 100644
--- a/src/libudev/src/libudev-device-internal.h
+++ b/src/libudev/src/libudev-device-internal.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -18,8 +20,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include "libudev.h"
#include <systemd/sd-device.h>
diff --git a/src/libudev/src/libudev-enumerate.c b/src/libudev/src/libudev-enumerate.c
index c784da5715..9910cea957 100644
--- a/src/libudev/src/libudev-enumerate.c
+++ b/src/libudev/src/libudev-enumerate.c
@@ -112,7 +112,7 @@ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) {
**/
_public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate) {
if (udev_enumerate)
- udev_enumerate->refcount ++;
+ udev_enumerate->refcount++;
return udev_enumerate;
}
diff --git a/src/libudev/src/udev.h b/src/libudev/src/udev.h
index 91dfc950b4..00de88972a 100644
--- a/src/libudev/src/udev.h
+++ b/src/libudev/src/udev.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
@@ -16,9 +18,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
-
#include <sys/param.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include "libudev.h"
@@ -71,9 +72,9 @@ struct udev_rules;
struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
struct udev_rules *udev_rules_unref(struct udev_rules *rules);
bool udev_rules_check_timestamp(struct udev_rules *rules);
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
- usec_t timeout_usec, usec_t timeout_warn_usec,
- struct udev_list *properties_list);
+void udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
+ usec_t timeout_usec, usec_t timeout_warn_usec,
+ struct udev_list *properties_list);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
diff --git a/src/locale/Makefile b/src/locale/Makefile
index cda2d17d4c..ad60553af9 100644
--- a/src/locale/Makefile
+++ b/src/locale/Makefile
@@ -29,7 +29,7 @@ systemd_localed_SOURCES = \
systemd_localed_LDADD = \
libshared.la \
- $(XKBCOMMON_LIBS)
+ -ldl
systemd_localed_CFLAGS = \
$(AM_CFLAGS) \
diff --git a/src/locale/language-fallback-map b/src/locale/language-fallback-map
index 6aadda091a..d0b02a6b98 100644
--- a/src/locale/language-fallback-map
+++ b/src/locale/language-fallback-map
@@ -3,6 +3,10 @@ en_AU en_AU:en_GB
en_IE en_IE:en_GB
en_NZ en_NZ:en_GB
en_ZA en_ZA:en_GB
+fr_BE fr_BE:fr_FR
+fr_CA fr_CA:fr_FR
+fr_CH fr_CH:fr_FR
+fr_LU fr_LU:fr_FR
it_CH it_CH:it_IT
mai_IN mai:hi
nds_DE nds:de
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index c684ff7d90..c1b0a56346 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -46,14 +46,6 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static char *arg_host = NULL;
static bool arg_convert = true;
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static void polkit_agent_open_if_enabled(void) {
/* Open the polkit agent as a child process if necessary */
@@ -124,11 +116,11 @@ static void print_overridden_variables(void) {
if (variables[j]) {
if (print_warning) {
log_warning("Warning: Settings on kernel command line override system locale settings in /etc/locale.conf.\n"
- " Command Line: %s=%s", locale_variable_to_string(j), variables[j]);
+ " Command Line: %s=%s", locale_variable_to_string(j), variables[j]);
print_warning = false;
} else
- log_warning(" %s=%s", locale_variable_to_string(j), variables[j]);
+ log_warning(" %s=%s", locale_variable_to_string(j), variables[j]);
}
finish:
for (j = 0; j < _VARIABLE_LC_MAX; j++)
@@ -139,7 +131,7 @@ static void print_status_info(StatusInfo *i) {
assert(i);
if (strv_isempty(i->locale))
- puts(" System Locale: n/a\n");
+ puts(" System Locale: n/a");
else {
char **j;
@@ -239,7 +231,7 @@ static int list_locales(sd_bus *bus, char **args, unsigned n) {
if (r < 0)
return log_error_errno(r, "Failed to read list of locales: %m");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
strv_print(l);
return 0;
@@ -341,7 +333,7 @@ static int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) {
strv_sort(l);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
strv_print(l);
@@ -479,7 +471,7 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) {
strv_sort(list);
strv_uniq(list);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
strv_print(list);
return 0;
diff --git a/src/locale/localed.c b/src/locale/localed.c
index eb6c0565f0..7b4cbadfd0 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -24,6 +24,7 @@
#ifdef HAVE_XKBCOMMON
#include <xkbcommon/xkbcommon.h>
+#include <dlfcn.h>
#endif
#include <systemd/sd-bus.h>
@@ -542,7 +543,7 @@ static int read_next_mapping(const char* filename,
return 0;
}
- (*n) ++;
+ (*n)++;
l = strstrip(line);
if (l[0] == 0 || l[0] == '#')
@@ -1101,6 +1102,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro
}
#ifdef HAVE_XKBCOMMON
+
_printf_(3, 0)
static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char *format, va_list args) {
const char *fmt;
@@ -1109,7 +1111,24 @@ static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char
log_internalv(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, fmt, args);
}
+#define LOAD_SYMBOL(symbol, dl, name) \
+ ({ \
+ (symbol) = (typeof(symbol)) dlvsym((dl), (name), "V_0.5.0"); \
+ (symbol) ? 0 : -EOPNOTSUPP; \
+ })
+
static int verify_xkb_rmlvo(const char *model, const char *layout, const char *variant, const char *options) {
+
+ /* We dlopen() the library in order to make the dependency soft. The library (and what it pulls in) is huge
+ * after all, hence let's support XKB maps when the library is around, and refuse otherwise. The function
+ * pointers to the shared library are below: */
+
+ struct xkb_context* (*symbol_xkb_context_new)(enum xkb_context_flags flags) = NULL;
+ void (*symbol_xkb_context_unref)(struct xkb_context *context) = NULL;
+ void (*symbol_xkb_context_set_log_fn)(struct xkb_context *context, void (*log_fn)(struct xkb_context *context, enum xkb_log_level level, const char *format, va_list args)) = NULL;
+ struct xkb_keymap* (*symbol_xkb_keymap_new_from_names)(struct xkb_context *context, const struct xkb_rule_names *names, enum xkb_keymap_compile_flags flags) = NULL;
+ void (*symbol_xkb_keymap_unref)(struct xkb_keymap *keymap) = NULL;
+
const struct xkb_rule_names rmlvo = {
.model = model,
.layout = layout,
@@ -1118,35 +1137,68 @@ static int verify_xkb_rmlvo(const char *model, const char *layout, const char *v
};
struct xkb_context *ctx = NULL;
struct xkb_keymap *km = NULL;
+ void *dl;
int r;
- /* compile keymap from RMLVO information to check out its validity */
+ /* Compile keymap from RMLVO information to check out its validity */
+
+ dl = dlopen("libxkbcommon.so.0", RTLD_LAZY);
+ if (!dl)
+ return -EOPNOTSUPP;
+
+ r = LOAD_SYMBOL(symbol_xkb_context_new, dl, "xkb_context_new");
+ if (r < 0)
+ goto finish;
+
+ r = LOAD_SYMBOL(symbol_xkb_context_unref, dl, "xkb_context_unref");
+ if (r < 0)
+ goto finish;
+
+ r = LOAD_SYMBOL(symbol_xkb_context_set_log_fn, dl, "xkb_context_set_log_fn");
+ if (r < 0)
+ goto finish;
- ctx = xkb_context_new(XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
+ r = LOAD_SYMBOL(symbol_xkb_keymap_new_from_names, dl, "xkb_keymap_new_from_names");
+ if (r < 0)
+ goto finish;
+
+ r = LOAD_SYMBOL(symbol_xkb_keymap_unref, dl, "xkb_keymap_unref");
+ if (r < 0)
+ goto finish;
+
+ ctx = symbol_xkb_context_new(XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
if (!ctx) {
r = -ENOMEM;
- goto exit;
+ goto finish;
}
- xkb_context_set_log_fn(ctx, log_xkb);
+ symbol_xkb_context_set_log_fn(ctx, log_xkb);
- km = xkb_keymap_new_from_names(ctx, &rmlvo, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ km = symbol_xkb_keymap_new_from_names(ctx, &rmlvo, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!km) {
r = -EINVAL;
- goto exit;
+ goto finish;
}
r = 0;
-exit:
- xkb_keymap_unref(km);
- xkb_context_unref(ctx);
+finish:
+ if (symbol_xkb_keymap_unref && km)
+ symbol_xkb_keymap_unref(km);
+
+ if (symbol_xkb_context_unref && ctx)
+ symbol_xkb_context_unref(ctx);
+
+ (void) dlclose(dl);
return r;
}
+
#else
+
static int verify_xkb_rmlvo(const char *model, const char *layout, const char *variant, const char *options) {
return 0;
}
+
#endif
static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_error *error) {
@@ -1203,7 +1255,11 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
if (r < 0) {
log_error_errno(r, "Cannot compile XKB keymap for new x11 keyboard layout ('%s' / '%s' / '%s' / '%s'): %m",
strempty(model), strempty(layout), strempty(variant), strempty(options));
- return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot compile XKB keymap, refusing");
+
+ if (r == -EOPNOTSUPP)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Local keyboard configuration not supported on this system.");
+
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Specified keymap cannot be compiled, refusing as invalid.");
}
if (free_and_strdup(&c->x11_layout, layout) < 0 ||
@@ -1296,7 +1352,7 @@ int main(int argc, char *argv[]) {
log_open();
umask(0022);
- mac_selinux_init("/etc");
+ mac_selinux_init();
if (argc != 1) {
log_error("This program takes no arguments.");
diff --git a/src/login/.gitignore b/src/login/.gitignore
index 39088ec252..3a8ba497c1 100644
--- a/src/login/.gitignore
+++ b/src/login/.gitignore
@@ -1,4 +1,5 @@
/logind-gperf.c
+/logind.conf
/org.freedesktop.login1.policy
/71-seat.rules
/73-seat-late.rules
diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules
index 694df2cfc8..50dcd2e275 100644
--- a/src/login/70-uaccess.rules
+++ b/src/login/70-uaccess.rules
@@ -75,4 +75,7 @@ SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess"
# software-defined radio communication devices
ENV{ID_SOFTWARE_RADIO}=="?*", TAG+="uaccess"
+# 3D printers, CNC machines, laser cutters, 3D scanners, etc.
+ENV{ID_MAKER_TOOL}=="?*", TAG+="uaccess"
+
LABEL="uaccess_end"
diff --git a/src/login/Makefile b/src/login/Makefile
index 54353cbbbe..9879cecbd3 100644
--- a/src/login/Makefile
+++ b/src/login/Makefile
@@ -178,7 +178,7 @@ dist_dbussystemservice_DATA += \
dist_dbuspolicy_DATA += \
src/login/org.freedesktop.login1.conf
-dist_pkgsysconf_DATA += \
+nodist_pkgsysconf_DATA += \
src/login/logind.conf
polkitpolicy_files += \
@@ -215,7 +215,8 @@ gperf_gperf_sources += \
EXTRA_DIST += \
src/login/71-seat.rules.in \
src/login/73-seat-late.rules.in \
- units/systemd-logind.service.in
+ units/systemd-logind.service.in \
+ src/login/logind.conf.in
# ------------------------------------------------------------------------------
ifneq ($(HAVE_PAM),)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index fd8dcdc22c..f3f57b4b13 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -27,6 +27,7 @@
#include "alloc-util.h"
#include "bus-error.h"
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
@@ -48,6 +49,7 @@
static char **arg_property = NULL;
static bool arg_all = false;
+static bool arg_value = false;
static bool arg_full = false;
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -59,14 +61,6 @@ static bool arg_ask_password = true;
static unsigned arg_lines = 10;
static OutputMode arg_output = OUTPUT_SHORT;
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static void polkit_agent_open_if_enabled(void) {
/* Open the polkit agent as a child process if necessary */
@@ -101,7 +95,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
assert(bus);
assert(argv);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = sd_bus_call_method(
bus,
@@ -148,7 +142,7 @@ static int list_users(int argc, char *argv[], void *userdata) {
assert(bus);
assert(argv);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = sd_bus_call_method(
bus,
@@ -194,7 +188,7 @@ static int list_seats(int argc, char *argv[], void *userdata) {
assert(bus);
assert(argv);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = sd_bus_call_method(
bus,
@@ -234,18 +228,15 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *path = NULL;
const char *cgroup;
- int r;
unsigned c;
+ int r;
assert(bus);
assert(unit);
- if (arg_transport != BUS_TRANSPORT_LOCAL)
- return 0;
-
path = unit_dbus_path_from_name(unit);
if (!path)
- return -ENOMEM;
+ return log_oom();
r = sd_bus_get_property(
bus,
@@ -253,27 +244,40 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit
path,
interface,
"ControlGroup",
- &error, &reply, "s");
+ &error,
+ &reply,
+ "s");
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to query ControlGroup: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &cgroup);
if (r < 0)
- return r;
+ return bus_log_parse_error(r);
if (isempty(cgroup))
return 0;
- if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
- return 0;
-
c = columns();
if (c > 18)
c -= 18;
else
c = 0;
- show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, get_output_flags());
+ r = unit_show_processes(bus, unit, cgroup, "\t\t ", c, get_output_flags(), &error);
+ if (r == -EBADR) {
+
+ if (arg_transport == BUS_TRANSPORT_REMOTE)
+ return 0;
+
+ /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
+
+ if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
+ return 0;
+
+ show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, &leader, leader > 0, get_output_flags());
+ } else if (r < 0)
+ return log_error_errno(r, "Failed to dump process list: %s", bus_error_message(&error, r));
+
return 0;
}
@@ -300,6 +304,7 @@ typedef struct SessionStatusInfo {
typedef struct UserStatusInfo {
uid_t uid;
+ bool linger;
char *name;
struct dual_timestamp timestamp;
char *state;
@@ -558,6 +563,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
static const struct bus_properties_map map[] = {
{ "Name", "s", NULL, offsetof(UserStatusInfo, name) },
+ { "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
{ "Slice", "s", NULL, offsetof(UserStatusInfo, slice) },
{ "State", "s", NULL, offsetof(UserStatusInfo, state) },
{ "UID", "u", NULL, offsetof(UserStatusInfo, uid) },
@@ -602,16 +608,16 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
char **l;
printf("\tSessions:");
- STRV_FOREACH(l, i.sessions) {
- if (streq_ptr(*l, i.display))
- printf(" *%s", *l);
- else
- printf(" %s", *l);
- }
+ STRV_FOREACH(l, i.sessions)
+ printf(" %s%s",
+ streq_ptr(*l, i.display) ? "*" : "",
+ *l);
printf("\n");
}
+ printf("\t Linger: %s\n", yes_no(i.linger));
+
if (i.slice) {
printf("\t Unit: %s\n", i.slice);
show_unit_cgroup(bus, "org.freedesktop.systemd1.Slice", i.slice, 0);
@@ -687,6 +693,14 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
return 0;
}
+#define property(name, fmt, ...) \
+ do { \
+ if (arg_value) \
+ printf(fmt "\n", __VA_ARGS__); \
+ else \
+ printf("%s=" fmt "\n", name, __VA_ARGS__); \
+ } while(0)
+
static int print_property(const char *name, sd_bus_message *m, const char *contents) {
int r;
@@ -710,7 +724,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return bus_log_parse_error(r);
if (arg_all || !isempty(s))
- printf("%s=%s\n", name, s);
+ property(name, "%s", s);
return 0;
@@ -726,8 +740,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
return -EINVAL;
}
- printf("%s=" UID_FMT "\n", name, uid);
-
+ property(name, UID_FMT, uid);
return 0;
}
@@ -743,14 +756,16 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
if (r < 0)
return bus_log_parse_error(r);
- printf("%s=", name);
+ if (!arg_value)
+ printf("%s=", name);
while ((r = sd_bus_message_read(m, "(so)", &s, NULL)) > 0) {
printf("%s%s", space ? " " : "", s);
space = true;
}
- printf("\n");
+ if (space || !arg_value)
+ printf("\n");
if (r < 0)
return bus_log_parse_error(r);
@@ -765,7 +780,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
break;
}
- r = bus_print_property(name, m, arg_all);
+ r = bus_print_property(name, m, arg_value, arg_all);
if (r < 0)
return bus_log_parse_error(r);
@@ -858,7 +873,7 @@ static int show_session(int argc, char *argv[], void *userdata) {
properties = !strstr(argv[0], "status");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (argc <= 1) {
/* If not argument is specified inspect the manager
@@ -914,7 +929,7 @@ static int show_user(int argc, char *argv[], void *userdata) {
properties = !strstr(argv[0], "status");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (argc <= 1) {
/* If not argument is specified inspect the manager
@@ -974,7 +989,7 @@ static int show_seat(int argc, char *argv[], void *userdata) {
properties = !strstr(argv[0], "status");
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (argc <= 1) {
/* If not argument is specified inspect the manager
@@ -1338,6 +1353,7 @@ static int help(int argc, char *argv[], void *userdata) {
" -M --machine=CONTAINER Operate on local container\n"
" -p --property=NAME Show only properties by this name\n"
" -a --all Show all properties, including empty ones\n"
+ " --value When showing properties, only print the value\n"
" -l --full Do not ellipsize output\n"
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
@@ -1379,6 +1395,7 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
+ ARG_VALUE,
ARG_NO_PAGER,
ARG_NO_LEGEND,
ARG_KILL_WHO,
@@ -1390,6 +1407,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "property", required_argument, NULL, 'p' },
{ "all", no_argument, NULL, 'a' },
+ { "value", no_argument, NULL, ARG_VALUE },
{ "full", no_argument, NULL, 'l' },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
@@ -1435,6 +1453,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_all = true;
break;
+ case ARG_VALUE:
+ arg_value = true;
+ break;
+
case 'l':
arg_full = true;
break;
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 8bdb3a9a38..cbf8d757fe 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -364,16 +364,16 @@ bool manager_shall_kill(Manager *m, const char *user) {
assert(m);
assert(user);
- if (!m->kill_user_processes)
+ if (!m->kill_exclude_users && streq(user, "root"))
return false;
if (strv_contains(m->kill_exclude_users, user))
return false;
- if (strv_isempty(m->kill_only_users))
- return true;
+ if (!strv_isempty(m->kill_only_users))
+ return strv_contains(m->kill_only_users, user);
- return strv_contains(m->kill_only_users, user);
+ return m->kill_user_processes;
}
static int vt_is_busy(unsigned int vtnr) {
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index efcc386dce..90dcd94710 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -265,6 +265,42 @@ static int property_get_docked(
return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
}
+static int property_get_current_sessions(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Manager *m = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(m);
+
+ return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->sessions));
+}
+
+static int property_get_current_inhibitors(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Manager *m = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(m);
+
+ return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->inhibitors));
+}
+
static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
@@ -725,6 +761,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
m->seat0->positions[vtnr]->class != SESSION_GREETER)
return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
+ if (hashmap_size(m->sessions) >= m->sessions_max)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.", m->sessions_max);
+
audit_session_from_pid(leader, &audit_id);
if (audit_id > 0) {
/* Keep our session IDs and the audit session IDs in sync */
@@ -1077,11 +1116,11 @@ static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus
static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *cc = NULL;
Manager *m = userdata;
- int b, r;
+ int r, b, interactive;
struct passwd *pw;
const char *path;
uint32_t uid;
- int interactive;
+ bool self = false;
assert(message);
assert(m);
@@ -1102,6 +1141,8 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
if (r < 0)
return r;
+ self = true;
+
} else if (!uid_is_valid(uid))
return -EINVAL;
@@ -1113,7 +1154,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
- "org.freedesktop.login1.set-user-linger",
+ self ? "org.freedesktop.login1.set-self-linger" : "org.freedesktop.login1.set-user-linger",
NULL,
interactive,
UID_INVALID,
@@ -2440,6 +2481,9 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
if (r < 0)
return r;
+ if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.", m->inhibitors_max);
+
do {
id = mfree(id);
@@ -2510,6 +2554,13 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
+ SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors, 0, 0),
+ SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions, 0, 0),
+ SD_BUS_PROPERTY("UserTasksMax", "t", NULL, offsetof(Manager, user_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index 8552c464cc..6bd08adc05 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -34,4 +34,6 @@ Login.IdleAction, config_parse_handle_action, 0, offsetof(Manag
Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec)
Login.RuntimeDirectorySize, config_parse_tmpfs_size, 0, offsetof(Manager, runtime_dir_size)
Login.RemoveIPC, config_parse_bool, 0, offsetof(Manager, remove_ipc)
+Login.InhibitorsMax, config_parse_uint64, 0, offsetof(Manager, inhibitors_max)
+Login.SessionsMax, config_parse_uint64, 0, offsetof(Manager, sessions_max)
Login.UserTasksMax, config_parse_uint64, 0, offsetof(Manager, user_tasks_max)
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index a0e3ba2b7c..6c78e0dddc 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -317,7 +317,7 @@ int inhibitor_create_fifo(Inhibitor *i) {
if (r < 0)
return r;
- r = sd_event_source_set_priority(i->event_source, SD_EVENT_PRIORITY_IDLE);
+ r = sd_event_source_set_priority(i->event_source, SD_EVENT_PRIORITY_IDLE-10);
if (r < 0)
return r;
}
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
index 3cee10d009..f934a5326a 100644
--- a/src/login/logind-seat-dbus.c
+++ b/src/login/logind-seat-dbus.c
@@ -306,7 +306,7 @@ const sd_bus_vtable seat_vtable[] = {
SD_BUS_PROPERTY("CanMultiSession", "b", property_get_can_multi_session, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index ff9170683b..22dea5db1f 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -28,6 +28,7 @@
#include "logind-session-device.h"
#include "logind-session.h"
#include "logind.h"
+#include "signal-util.h"
#include "strv.h"
#include "util.h"
@@ -179,6 +180,24 @@ static int property_get_idle_since_hint(
return sd_bus_message_append(reply, "t", u);
}
+static int property_get_locked_hint(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Session *s = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(s);
+
+ return sd_bus_message_append(reply, "b", session_get_locked_hint(s) > 0);
+}
+
int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
int r;
@@ -278,6 +297,35 @@ static int method_set_idle_hint(sd_bus_message *message, void *userdata, sd_bus_
return sd_bus_reply_method_return(message, NULL);
}
+static int method_set_locked_hint(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ Session *s = userdata;
+ uid_t uid;
+ int r, b;
+
+ assert(message);
+ assert(s);
+
+ r = sd_bus_message_read(message, "b", &b);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_creds_get_euid(creds, &uid);
+ if (r < 0)
+ return r;
+
+ if (uid != 0 && uid != s->user->uid)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set locked hint");
+
+ session_set_locked_hint(s, b);
+
+ return sd_bus_reply_method_return(message, NULL);
+}
+
int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
const char *swho;
@@ -300,7 +348,7 @@ int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
}
- if (signo <= 0 || signo >= _NSIG)
+ if (!SIGNAL_VALID(signo))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
r = bus_verify_polkit_async(
@@ -486,12 +534,14 @@ const sd_bus_vtable session_vtable[] = {
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_session_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Lock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Unlock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetLockedHint", "b", NULL, method_set_locked_hint, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Kill", "si", NULL, bus_session_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("TakeControl", "b", NULL, method_take_control, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ReleaseControl", NULL, NULL, method_release_control, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index b22420deea..11a83106b1 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -446,17 +446,10 @@ int session_load(Session *s) {
safe_close(fd);
}
- if (realtime) {
- unsigned long long l;
- if (sscanf(realtime, "%llu", &l) > 0)
- s->timestamp.realtime = l;
- }
-
- if (monotonic) {
- unsigned long long l;
- if (sscanf(monotonic, "%llu", &l) > 0)
- s->timestamp.monotonic = l;
- }
+ if (realtime)
+ timestamp_deserialize(realtime, &s->timestamp.realtime);
+ if (monotonic)
+ timestamp_deserialize(monotonic, &s->timestamp.monotonic);
if (controller) {
if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0)
@@ -520,7 +513,7 @@ static int session_start_scope(Session *s) {
if (!scope)
return log_oom();
- description = strjoina("Session ", s->id, " of user ", s->user->name, NULL);
+ description = strjoina("Session ", s->id, " of user ", s->user->name);
r = manager_start_scope(
s->manager,
@@ -804,7 +797,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
/* Graphical sessions should really implement a real
* idle hint logic */
- if (s->display)
+ if (SESSION_TYPE_IS_GRAPHICAL(s->type))
goto dont_know;
/* For sessions with an explicitly configured tty, let's check
@@ -859,6 +852,23 @@ void session_set_idle_hint(Session *s, bool b) {
manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
}
+int session_get_locked_hint(Session *s) {
+ assert(s);
+
+ return s->locked_hint;
+}
+
+void session_set_locked_hint(Session *s, bool b) {
+ assert(s);
+
+ if (s->locked_hint == b)
+ return;
+
+ s->locked_hint = b;
+
+ session_send_changed(s, "LockedHint", NULL);
+}
+
static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
Session *s = userdata;
@@ -904,7 +914,9 @@ int session_create_fifo(Session *s) {
if (r < 0)
return r;
- r = sd_event_source_set_priority(s->fifo_event_source, SD_EVENT_PRIORITY_IDLE);
+ /* Let's make sure we noticed dead sessions before we process new bus requests (which might create new
+ * sessions). */
+ r = sd_event_source_set_priority(s->fifo_event_source, SD_EVENT_PRIORITY_NORMAL-10);
if (r < 0)
return r;
}
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index e24b808474..ffb7cd2d41 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -105,6 +105,8 @@ struct Session {
bool idle_hint;
dual_timestamp idle_hint_timestamp;
+ bool locked_hint;
+
bool in_gc_queue:1;
bool started:1;
bool stopping:1;
@@ -132,6 +134,8 @@ int session_activate(Session *s);
bool session_is_active(Session *s);
int session_get_idle_hint(Session *s, dual_timestamp *t);
void session_set_idle_hint(Session *s, bool b);
+int session_get_locked_hint(Session *s);
+void session_set_locked_hint(Session *s, bool b);
int session_create_fifo(Session *s);
int session_start(Session *s);
int session_stop(Session *s, bool force);
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index fd98c7beca..af6392e025 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -25,6 +25,7 @@
#include "formats-util.h"
#include "logind-user.h"
#include "logind.h"
+#include "signal-util.h"
#include "strv.h"
#include "user-util.h"
@@ -222,7 +223,7 @@ int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *
if (r < 0)
return r;
- if (signo <= 0 || signo >= _NSIG)
+ if (!SIGNAL_VALID(signo))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
r = user_kill(u, signo);
@@ -244,7 +245,7 @@ const sd_bus_vtable user_vtable[] = {
SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
- SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 6b9c69cc45..a826321bf0 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -321,17 +321,10 @@ int user_load(User *u) {
if (s && s->display && display_is_local(s->display))
u->display = s;
- if (realtime) {
- unsigned long long l;
- if (sscanf(realtime, "%llu", &l) > 0)
- u->timestamp.realtime = l;
- }
-
- if (monotonic) {
- unsigned long long l;
- if (sscanf(monotonic, "%llu", &l) > 0)
- u->timestamp.monotonic = l;
- }
+ if (realtime)
+ timestamp_deserialize(realtime, &u->timestamp.realtime);
+ if (monotonic)
+ timestamp_deserialize(monotonic, &u->timestamp.monotonic);
return r;
}
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 5106821645..47599fd466 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -65,7 +65,7 @@ bool logind_wall_tty_filter(const char *tty, void *userdata) {
assert(m);
- if (!startswith(tty, "/dev/"))
+ if (!startswith(tty, "/dev/") || !m->scheduled_shutdown_tty)
return true;
return !streq(tty + 5, m->scheduled_shutdown_tty);
diff --git a/src/login/logind.c b/src/login/logind.c
index 34d0c04a2a..925c04a344 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -41,17 +41,7 @@
static void manager_free(Manager *m);
-static Manager *manager_new(void) {
- Manager *m;
- int r;
-
- m = new0(Manager, 1);
- if (!m)
- return NULL;
-
- m->console_active_fd = -1;
- m->reserve_vt_fd = -1;
-
+static void manager_reset_config(Manager *m) {
m->n_autovts = 6;
m->reserve_vt = 6;
m->remove_ipc = true;
@@ -61,15 +51,39 @@ static Manager *manager_new(void) {
m->handle_hibernate_key = HANDLE_HIBERNATE;
m->handle_lid_switch = HANDLE_SUSPEND;
m->handle_lid_switch_docked = HANDLE_IGNORE;
+ m->power_key_ignore_inhibited = false;
+ m->suspend_key_ignore_inhibited = false;
+ m->hibernate_key_ignore_inhibited = false;
m->lid_switch_ignore_inhibited = true;
+
m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
m->idle_action_usec = 30 * USEC_PER_MINUTE;
m->idle_action = HANDLE_IGNORE;
- m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
- m->user_tasks_max = UINT64_C(12288);
+ m->user_tasks_max = 12288;
+ m->sessions_max = 8192;
+ m->inhibitors_max = 8192;
+
+ m->kill_user_processes = KILL_USER_PROCESSES;
+
+ m->kill_only_users = strv_free(m->kill_only_users);
+ m->kill_exclude_users = strv_free(m->kill_exclude_users);
+}
+
+static Manager *manager_new(void) {
+ Manager *m;
+ int r;
+
+ m = new0(Manager, 1);
+ if (!m)
+ return NULL;
+
+ m->console_active_fd = -1;
+ m->reserve_vt_fd = -1;
+
+ m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
m->devices = hashmap_new(&string_hash_ops);
m->seats = hashmap_new(&string_hash_ops);
@@ -84,10 +98,6 @@ static Manager *manager_new(void) {
if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
goto fail;
- m->kill_exclude_users = strv_new("root", NULL);
- if (!m->kill_exclude_users)
- goto fail;
-
m->udev = udev_new();
if (!m->udev)
goto fail;
@@ -98,6 +108,8 @@ static Manager *manager_new(void) {
sd_event_set_watchdog(m->event, true);
+ manager_reset_config(m);
+
return m;
fail:
@@ -676,7 +688,7 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to register name: %m");
- r = sd_bus_attach_event(m->bus, m->event, 0);
+ r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL);
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
@@ -986,6 +998,30 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
return 0;
}
+static int manager_parse_config_file(Manager *m) {
+ assert(m);
+
+ return config_parse_many(PKGSYSCONFDIR "/logind.conf",
+ 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) {
+ Manager *m = userdata;
+ int r;
+
+ manager_reset_config(m);
+ r = manager_parse_config_file(m);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse config file, using defaults: %m");
+ else
+ log_info("Config file reloaded.");
+
+ return 0;
+}
+
static int manager_startup(Manager *m) {
int r;
Seat *seat;
@@ -997,6 +1033,12 @@ static int manager_startup(Manager *m) {
assert(m);
+ assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGHUP, -1) >= 0);
+
+ r = sd_event_add_signal(m->event, NULL, SIGHUP, manager_dispatch_reload_signal, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to register SIGHUP handler: %m");
+
/* Connect to console */
r = manager_connect_console(m);
if (r < 0)
@@ -1099,16 +1141,6 @@ static int manager_run(Manager *m) {
}
}
-static int manager_parse_config_file(Manager *m) {
- assert(m);
-
- return config_parse_many(PKGSYSCONFDIR "/logind.conf",
- CONF_PATHS_NULSTR("systemd/logind.conf.d"),
- "Login\0",
- config_item_perf_lookup, logind_gperf_lookup,
- false, m);
-}
-
int main(int argc, char *argv[]) {
Manager *m = NULL;
int r;
@@ -1126,7 +1158,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- r = mac_selinux_init("/run");
+ r = mac_selinux_init();
if (r < 0) {
log_error_errno(r, "Could not initialize labelling: %m");
goto finish;
diff --git a/src/login/logind.conf b/src/login/logind.conf.in
index 6095e482ac..32c0844cb6 100644
--- a/src/login/logind.conf
+++ b/src/login/logind.conf.in
@@ -14,7 +14,7 @@
[Login]
#NAutoVTs=6
#ReserveVT=6
-#KillUserProcesses=no
+#KillUserProcesses=@KILL_USER_PROCESSES@
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
@@ -32,4 +32,6 @@
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
+#InhibitorsMax=8192
+#SessionsMax=8192
#UserTasksMax=12288
diff --git a/src/login/logind.h b/src/login/logind.h
index c642d56413..9d43c2e7ee 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -133,6 +133,8 @@ struct Manager {
size_t runtime_dir_size;
uint64_t user_tasks_max;
+ uint64_t sessions_max;
+ uint64_t inhibitors_max;
};
int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device);
diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf
index 1662d4c428..c89e40457e 100644
--- a/src/login/org.freedesktop.login1.conf
+++ b/src/login/org.freedesktop.login1.conf
@@ -234,6 +234,10 @@
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Session"
+ send_member="SetLockedHint"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Session"
send_member="Kill"/>
<allow send_destination="org.freedesktop.login1"
diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in
index 23326bb79f..1fa6441629 100644
--- a/src/login/org.freedesktop.login1.policy.in
+++ b/src/login/org.freedesktop.login1.policy.in
@@ -111,6 +111,14 @@
</defaults>
</action>
+ <action id="org.freedesktop.login1.set-self-linger">
+ <_description>Allow non-logged-in user to run programs</_description>
+ <_message>Explicit request is required to run programs as a non-logged-in user.</_message>
+ <defaults>
+ <allow_any>yes</allow_any>
+ </defaults>
+ </action>
+
<action id="org.freedesktop.login1.set-user-linger">
<_description>Allow non-logged-in users to run programs</_description>
<_message>Authentication is required to run programs as a non-logged-in user.</_message>
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 40e246bb06..98dc201340 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -150,7 +150,7 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
if (fd < 0)
return -errno;
- if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return -errno;
r = getpeercred(fd, &ucred);
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
index bd603e297d..29785e2f11 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -110,7 +110,7 @@ static int show_sysfs_one(
if (!k)
return -ENOMEM;
- printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), k);
+ printf("%s%s%s\n", prefix, special_glyph(lookahead ? TREE_BRANCH : TREE_RIGHT), k);
if (asprintf(&l,
"%s%s:%s%s%s%s",
@@ -124,13 +124,13 @@ static int show_sysfs_one(
if (!k)
return -ENOMEM;
- printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : " ", k);
+ printf("%s%s%s\n", prefix, lookahead ? special_glyph(TREE_VERTICAL) : " ", k);
*item = next;
if (*item) {
_cleanup_free_ char *p = NULL;
- p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : " ");
+ p = strappend(prefix, lookahead ? special_glyph(TREE_VERTICAL) : " ");
if (!p)
return -ENOMEM;
@@ -183,7 +183,7 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
if (first)
show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
else
- printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), "(none)");
+ printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)");
return r;
}
diff --git a/src/login/systemd-user.m4 b/src/login/systemd-user.m4
index 7933508f2b..f188a8e548 100644
--- a/src/login/systemd-user.m4
+++ b/src/login/systemd-user.m4
@@ -8,4 +8,5 @@ m4_ifdef(`HAVE_SELINUX',
session required pam_selinux.so close
session required pam_selinux.so nottys open
)m4_dnl
+session required pam_loginuid.so
session include system-auth
diff --git a/src/network/.gitignore b/src/network/.gitignore
index 8858596489..aca55206b7 100644
--- a/src/network/.gitignore
+++ b/src/network/.gitignore
@@ -1,2 +1,3 @@
/networkd-network-gperf.c
/networkd-netdev-gperf.c
+/networkd-gperf.c
diff --git a/src/network/Makefile b/src/network/Makefile
index 3453a9c56d..d43dfdfca8 100644
--- a/src/network/Makefile
+++ b/src/network/Makefile
@@ -47,6 +47,8 @@ libnetworkd_core_la_CFLAGS = \
libnetworkd_core_la_SOURCES = \
src/libsystemd-network/network-internal.h \
src/network/networkd.h \
+ src/network/networkd-conf.h \
+ src/network/networkd-conf.c \
src/network/networkd-link.h \
src/network/networkd-link.c \
src/network/networkd-netdev.h \
@@ -90,9 +92,12 @@ libnetworkd_core_la_SOURCES = \
src/network/networkd-address-pool.h \
src/network/networkd-address-pool.c \
src/network/networkd-util.h \
- src/network/networkd-util.c
+ src/network/networkd-util.c \
+ src/network/networkd-lldp-tx.h \
+ src/network/networkd-lldp-tx.c
nodist_libnetworkd_core_la_SOURCES = \
+ src/network/networkd-gperf.c \
src/network/networkd-network-gperf.c \
src/network/networkd-netdev-gperf.c
@@ -131,6 +136,12 @@ networkctl_LDADD = \
dist_bashcompletion_data += \
shell-completion/bash/networkctl
+test_networkd_conf_SOURCES = \
+ src/network/test-networkd-conf.c
+
+test_networkd_conf_LDADD = \
+ libnetworkd-core.la
+
test_network_SOURCES = \
src/network/test-network.c
@@ -156,6 +167,7 @@ test_network_tables_LDADD += \
endif # HAVE_LIBIPTC
tests += \
+ test-networkd-conf \
test-network \
test-network-tables
@@ -189,6 +201,7 @@ BUSNAMES_TARGET_WANTS += \
endif # ENABLE_NETWORKD
gperf_gperf_sources += \
+ src/network/networkd-gperf.gperf \
src/network/networkd-network-gperf.gperf \
src/network/networkd-netdev-gperf.gperf
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 6e436d2043..85635b59bc 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -23,6 +23,7 @@
#include <systemd/sd-device.h>
#include <systemd/sd-hwdb.h>
+#include <systemd/sd-lldp.h>
#include <systemd/sd-netlink.h>
#include <systemd/sd-network.h>
@@ -30,18 +31,20 @@
#include "arphrd-list.h"
#include "device-util.h"
#include "ether-addr-util.h"
+#include "fd-util.h"
#include "hwdb-util.h"
-#include "lldp.h"
#include "local-addresses.h"
#include "locale-util.h"
#include "netlink-util.h"
#include "pager.h"
#include "parse-util.h"
#include "socket-util.h"
+#include "sparse-endian.h"
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
+#include "strxcpyx.h"
#include "terminal-util.h"
#include "util.h"
#include "verbs.h"
@@ -50,15 +53,7 @@ static bool arg_no_pager = false;
static bool arg_legend = true;
static bool arg_all = false;
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
-static int link_get_type_string(int iftype, sd_device *d, char **ret) {
+static int link_get_type_string(unsigned short iftype, sd_device *d, char **ret) {
const char *t;
char *p;
@@ -70,7 +65,7 @@ static int link_get_type_string(int iftype, sd_device *d, char **ret) {
* to show a more useful type string for
* them */
- (void)sd_device_get_devtype(d, &devtype);
+ (void) sd_device_get_devtype(d, &devtype);
if (streq_ptr(devtype, "wlan"))
id = "wlan";
@@ -103,10 +98,46 @@ static int link_get_type_string(int iftype, sd_device *d, char **ret) {
return 0;
}
+static void operational_state_to_color(const char *state, const char **on, const char **off) {
+ assert(on);
+ assert(off);
+
+ if (streq_ptr(state, "routable")) {
+ *on = ansi_highlight_green();
+ *off = ansi_normal();
+ } else if (streq_ptr(state, "degraded")) {
+ *on = ansi_highlight_yellow();
+ *off = ansi_normal();
+ } else
+ *on = *off = "";
+}
+
+static void setup_state_to_color(const char *state, const char **on, const char **off) {
+ assert(on);
+ assert(off);
+
+ if (streq_ptr(state, "configured")) {
+ *on = ansi_highlight_green();
+ *off = ansi_normal();
+ } else if (streq_ptr(state, "configuring")) {
+ *on = ansi_highlight_yellow();
+ *off = ansi_normal();
+ } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) {
+ *on = ansi_highlight_red();
+ *off = ansi_normal();
+ } else
+ *on = *off = "";
+}
+
typedef struct LinkInfo {
- const char *name;
+ char name[IFNAMSIZ+1];
int ifindex;
- unsigned iftype;
+ unsigned short iftype;
+ struct ether_addr mac_address;
+ uint32_t mtu;
+
+ bool has_mac_address:1;
+ bool has_mtu:1;
} LinkInfo;
static int link_info_compare(const void *a, const void *b) {
@@ -115,44 +146,84 @@ static int link_info_compare(const void *a, const void *b) {
return x->ifindex - y->ifindex;
}
-static int decode_and_sort_links(sd_netlink_message *m, LinkInfo **ret) {
+static int decode_link(sd_netlink_message *m, LinkInfo *info) {
+ const char *name;
+ uint16_t type;
+ int r;
+
+ assert(m);
+ assert(info);
+
+ r = sd_netlink_message_get_type(m, &type);
+ if (r < 0)
+ return r;
+
+ if (type != RTM_NEWLINK)
+ return 0;
+
+ r = sd_rtnl_message_link_get_ifindex(m, &info->ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_read_string(m, IFLA_IFNAME, &name);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_link_get_type(m, &info->iftype);
+ if (r < 0)
+ return r;
+
+ strscpy(info->name, sizeof info->name, name);
+
+ info->has_mac_address =
+ sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &info->mac_address) >= 0 &&
+ memcmp(&info->mac_address, &ETHER_ADDR_NULL, sizeof(struct ether_addr)) != 0;
+
+ info->has_mtu =
+ sd_netlink_message_read_u32(m, IFLA_MTU, &info->mtu) &&
+ info->mtu > 0;
+
+ return 1;
+}
+
+static int acquire_link_info_strv(sd_netlink *rtnl, char **l, LinkInfo **ret) {
_cleanup_free_ LinkInfo *links = NULL;
- size_t size = 0, c = 0;
- sd_netlink_message *i;
+ char **i;
+ size_t c = 0;
int r;
- for (i = m; i; i = sd_netlink_message_next(i)) {
- const char *name;
- unsigned iftype;
- uint16_t type;
- int ifindex;
+ assert(rtnl);
+ assert(ret);
- r = sd_netlink_message_get_type(i, &type);
- if (r < 0)
- return r;
+ links = new(LinkInfo, strv_length(l));
+ if (!links)
+ return log_oom();
- if (type != RTM_NEWLINK)
- continue;
+ STRV_FOREACH(i, l) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
+ int ifindex;
+
+ if (parse_ifindex(*i, &ifindex) >= 0)
+ r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
+ else {
+ r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
+ if (r < 0)
+ return rtnl_log_create_error(r);
- r = sd_rtnl_message_link_get_ifindex(i, &ifindex);
+ r = sd_netlink_message_append_string(req, IFLA_IFNAME, *i);
+ }
if (r < 0)
- return r;
+ return rtnl_log_create_error(r);
- r = sd_netlink_message_read_string(i, IFLA_IFNAME, &name);
+ r = sd_netlink_call(rtnl, req, 0, &reply);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to request link: %m");
- r = sd_rtnl_message_link_get_type(i, &iftype);
+ r = decode_link(reply, links + c);
if (r < 0)
return r;
-
- if (!GREEDY_REALLOC(links, size, c+1))
- return -ENOMEM;
-
- links[c].name = name;
- links[c].ifindex = ifindex;
- links[c].iftype = iftype;
- c++;
+ if (r > 0)
+ c++;
}
qsort_safe(links, c, sizeof(LinkInfo), link_info_compare);
@@ -163,48 +234,15 @@ static int decode_and_sort_links(sd_netlink_message *m, LinkInfo **ret) {
return (int) c;
}
-static void operational_state_to_color(const char *state, const char **on, const char **off) {
- assert(on);
- assert(off);
-
- if (streq_ptr(state, "routable")) {
- *on = ansi_highlight_green();
- *off = ansi_normal();
- } else if (streq_ptr(state, "degraded")) {
- *on = ansi_highlight_yellow();
- *off = ansi_normal();
- } else
- *on = *off = "";
-}
-
-static void setup_state_to_color(const char *state, const char **on, const char **off) {
- assert(on);
- assert(off);
-
- if (streq_ptr(state, "configured")) {
- *on = ansi_highlight_green();
- *off = ansi_normal();
- } else if (streq_ptr(state, "configuring")) {
- *on = ansi_highlight_yellow();
- *off = ansi_normal();
- } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) {
- *on = ansi_highlight_red();
- *off = ansi_normal();
- } else
- *on = *off = "";
-}
-
-static int list_links(int argc, char *argv[], void *userdata) {
+static int acquire_link_info_all(sd_netlink *rtnl, LinkInfo **ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
- _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_free_ LinkInfo *links = NULL;
- int r, c, i;
-
- pager_open_if_enabled();
+ size_t allocated = 0, c = 0;
+ sd_netlink_message *i;
+ int r;
- r = sd_netlink_open(&rtnl);
- if (r < 0)
- return log_error_errno(r, "Failed to connect to netlink: %m");
+ assert(rtnl);
+ assert(ret);
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
if (r < 0)
@@ -218,12 +256,50 @@ static int list_links(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to enumerate links: %m");
- if (arg_legend)
- printf("%3s %-16s %-18s %-11s %-10s\n", "IDX", "LINK", "TYPE", "OPERATIONAL", "SETUP");
+ for (i = reply; i; i = sd_netlink_message_next(i)) {
+ if (!GREEDY_REALLOC(links, allocated, c+1))
+ return -ENOMEM;
+
+ r = decode_link(i, links + c);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ c++;
+ }
- c = decode_and_sort_links(reply, &links);
+ qsort_safe(links, c, sizeof(LinkInfo), link_info_compare);
+
+ *ret = links;
+ links = NULL;
+
+ return (int) c;
+}
+
+static int list_links(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ _cleanup_free_ LinkInfo *links = NULL;
+ int c, i, r;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ if (argc > 1)
+ c = acquire_link_info_strv(rtnl, argv + 1, &links);
+ else
+ c = acquire_link_info_all(rtnl, &links);
if (c < 0)
- return rtnl_log_parse_error(c);
+ return c;
+
+ pager_open(arg_no_pager, false);
+
+ if (arg_legend)
+ printf("%3s %-16s %-18s %-11s %-10s\n",
+ "IDX",
+ "LINK",
+ "TYPE",
+ "OPERATIONAL",
+ "SETUP");
for (i = 0; i < c; i++) {
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
@@ -233,16 +309,18 @@ static int list_links(int argc, char *argv[], void *userdata) {
char devid[2 + DECIMAL_STR_MAX(int)];
_cleanup_free_ char *t = NULL;
- sd_network_link_get_operational_state(links[i].ifindex, &operational_state);
+ (void) sd_network_link_get_operational_state(links[i].ifindex, &operational_state);
operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
- sd_network_link_get_setup_state(links[i].ifindex, &setup_state);
+ r = sd_network_link_get_setup_state(links[i].ifindex, &setup_state);
+ if (r == -ENODATA) /* If there's no info available about this iface, it's unmanaged by networkd */
+ setup_state = strdup("unmanaged");
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
- sprintf(devid, "n%i", links[i].ifindex);
- (void)sd_device_new_from_device_id(&d, devid);
+ xsprintf(devid, "n%i", links[i].ifindex);
+ (void) sd_device_new_from_device_id(&d, devid);
- link_get_type_string(links[i].iftype, d, &t);
+ (void) link_get_type_string(links[i].iftype, d, &t);
printf("%3i %-16s %-18s %s%-11s%s %s%-10s%s\n",
links[i].ifindex, links[i].name, strna(t),
@@ -257,7 +335,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
}
/* IEEE Organizationally Unique Identifier vendor string */
-static int ieee_oui(sd_hwdb *hwdb, struct ether_addr *mac, char **ret) {
+static int ieee_oui(sd_hwdb *hwdb, const struct ether_addr *mac, char **ret) {
const char *description;
char modalias[strlen("OUI:XXYYXXYYXXYY") + 1], *desc;
int r;
@@ -404,6 +482,9 @@ static int dump_gateways(
_cleanup_free_ struct local_address *local = NULL;
int r, n, i;
+ assert(rtnl);
+ assert(prefix);
+
n = local_gateways(rtnl, ifindex, AF_UNSPEC, &local);
if (n < 0)
return n;
@@ -453,6 +534,9 @@ static int dump_addresses(
_cleanup_free_ struct local_address *local = NULL;
int r, n, i;
+ assert(rtnl);
+ assert(prefix);
+
n = local_addresses(rtnl, ifindex, AF_UNSPEC, &local);
if (n < 0)
return n;
@@ -485,6 +569,116 @@ static int dump_addresses(
return 0;
}
+static int open_lldp_neighbors(int ifindex, FILE **ret) {
+ _cleanup_free_ char *p = NULL;
+ FILE *f;
+
+ if (asprintf(&p, "/run/systemd/netif/lldp/%i", ifindex) < 0)
+ return -ENOMEM;
+
+ f = fopen(p, "re");
+ if (!f)
+ return -errno;
+
+ *ret = f;
+ return 0;
+}
+
+static int next_lldp_neighbor(FILE *f, sd_lldp_neighbor **ret) {
+ _cleanup_free_ void *raw = NULL;
+ size_t l;
+ le64_t u;
+ int r;
+
+ assert(f);
+ assert(ret);
+
+ l = fread(&u, 1, sizeof(u), f);
+ if (l == 0 && feof(f))
+ return 0;
+ if (l != sizeof(u))
+ return -EBADMSG;
+
+ raw = new(uint8_t, le64toh(u));
+ if (!raw)
+ return -ENOMEM;
+
+ if (fread(raw, 1, le64toh(u), f) != le64toh(u))
+ return -EBADMSG;
+
+ r = sd_lldp_neighbor_from_raw(ret, raw, le64toh(u));
+ if (r < 0)
+ return r;
+
+ return 1;
+}
+
+static int dump_lldp_neighbors(const char *prefix, int ifindex) {
+ _cleanup_fclose_ FILE *f = NULL;
+ int r, c = 0;
+
+ assert(prefix);
+ assert(ifindex > 0);
+
+ r = open_lldp_neighbors(ifindex, &f);
+ if (r < 0)
+ return r;
+
+ for (;;) {
+ const char *system_name = NULL, *port_id = NULL, *port_description = NULL;
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
+
+ r = next_lldp_neighbor(f, &n);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ printf("%*s",
+ (int) strlen(prefix),
+ c == 0 ? prefix : "");
+
+ (void) sd_lldp_neighbor_get_system_name(n, &system_name);
+ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id);
+ (void) sd_lldp_neighbor_get_port_description(n, &port_description);
+
+ printf("%s on port %s", strna(system_name), strna(port_id));
+
+ if (!isempty(port_description))
+ printf(" (%s)", port_description);
+
+ putchar('\n');
+
+ c++;
+ }
+
+ return c;
+}
+
+static void dump_ifindexes(const char *prefix, const int *ifindexes) {
+ unsigned c;
+
+ assert(prefix);
+
+ if (!ifindexes || ifindexes[0] <= 0)
+ return;
+
+ for (c = 0; ifindexes[c] > 0; c++) {
+ char name[IF_NAMESIZE+1];
+
+ printf("%*s",
+ (int) strlen(prefix),
+ c == 0 ? prefix : "");
+
+ if (if_indextoname(ifindexes[c], name))
+ fputs(name, stdout);
+ else
+ printf("%i", ifindexes[c]);
+
+ fputc('\n', stdout);
+ }
+}
+
static void dump_list(const char *prefix, char **l) {
char **i;
@@ -502,85 +696,36 @@ static void dump_list(const char *prefix, char **l) {
static int link_status_one(
sd_netlink *rtnl,
sd_hwdb *hwdb,
- const char *name) {
+ const LinkInfo *info) {
+
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
char devid[2 + DECIMAL_STR_MAX(int)];
_cleanup_free_ char *t = NULL, *network = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
const char *on_color_operational, *off_color_operational,
*on_color_setup, *off_color_setup;
- _cleanup_strv_free_ char **carrier_bound_to = NULL;
- _cleanup_strv_free_ char **carrier_bound_by = NULL;
- struct ether_addr e;
- unsigned iftype;
- int r, ifindex;
- bool have_mac;
- uint32_t mtu;
+ _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
+ int r;
assert(rtnl);
- assert(name);
-
- if (parse_ifindex(name, &ifindex) >= 0)
- r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
- else {
- r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
- if (r < 0)
- return rtnl_log_create_error(r);
-
- r = sd_netlink_message_append_string(req, IFLA_IFNAME, name);
- }
+ assert(info);
- if (r < 0)
- return rtnl_log_create_error(r);
-
- r = sd_netlink_call(rtnl, req, 0, &reply);
- if (r < 0)
- return log_error_errno(r, "Failed to query link: %m");
-
- r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
- if (r < 0)
- return rtnl_log_parse_error(r);
-
- r = sd_netlink_message_read_string(reply, IFLA_IFNAME, &name);
- if (r < 0)
- return rtnl_log_parse_error(r);
-
- r = sd_rtnl_message_link_get_type(reply, &iftype);
- if (r < 0)
- return rtnl_log_parse_error(r);
-
- have_mac = sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
- if (have_mac) {
- const uint8_t *p;
- bool all_zeroes = true;
-
- for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
- if (*p != 0) {
- all_zeroes = false;
- break;
- }
-
- if (all_zeroes)
- have_mac = false;
- }
-
- (void) sd_netlink_message_read_u32(reply, IFLA_MTU, &mtu);
-
- (void) sd_network_link_get_operational_state(ifindex, &operational_state);
+ (void) sd_network_link_get_operational_state(info->ifindex, &operational_state);
operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
- (void) sd_network_link_get_setup_state(ifindex, &setup_state);
+ r = sd_network_link_get_setup_state(info->ifindex, &setup_state);
+ if (r == -ENODATA) /* If there's no info available about this iface, it's unmanaged by networkd */
+ setup_state = strdup("unmanaged");
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
- (void) sd_network_link_get_dns(ifindex, &dns);
- (void) sd_network_link_get_search_domains(ifindex, &search_domains);
- (void) sd_network_link_get_route_domains(ifindex, &route_domains);
- (void) sd_network_link_get_ntp(ifindex, &ntp);
+ (void) sd_network_link_get_dns(info->ifindex, &dns);
+ (void) sd_network_link_get_search_domains(info->ifindex, &search_domains);
+ (void) sd_network_link_get_route_domains(info->ifindex, &route_domains);
+ (void) sd_network_link_get_ntp(info->ifindex, &ntp);
- sprintf(devid, "n%i", ifindex);
+ xsprintf(devid, "n%i", info->ifindex);
(void) sd_device_new_from_device_id(&d, devid);
@@ -598,14 +743,14 @@ static int link_status_one(
(void) sd_device_get_property_value(d, "ID_MODEL", &model);
}
- link_get_type_string(iftype, d, &t);
+ (void) link_get_type_string(info->iftype, d, &t);
- sd_network_link_get_network_file(ifindex, &network);
+ (void) sd_network_link_get_network_file(info->ifindex, &network);
- sd_network_link_get_carrier_bound_to(ifindex, &carrier_bound_to);
- sd_network_link_get_carrier_bound_by(ifindex, &carrier_bound_by);
+ (void) sd_network_link_get_carrier_bound_to(info->ifindex, &carrier_bound_to);
+ (void) sd_network_link_get_carrier_bound_by(info->ifindex, &carrier_bound_by);
- printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
+ printf("%s%s%s %i: %s\n", on_color_operational, special_glyph(BLACK_CIRCLE), off_color_operational, info->ifindex, info->name);
printf(" Link File: %s\n"
" Network File: %s\n"
@@ -626,23 +771,23 @@ static int link_status_one(
if (model)
printf(" Model: %s\n", model);
- if (have_mac) {
+ if (info->has_mac_address) {
_cleanup_free_ char *description = NULL;
char ea[ETHER_ADDR_TO_STRING_MAX];
- ieee_oui(hwdb, &e, &description);
+ (void) ieee_oui(hwdb, &info->mac_address, &description);
if (description)
- printf(" HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description);
+ printf(" HW Address: %s (%s)\n", ether_addr_to_string(&info->mac_address, ea), description);
else
- printf(" HW Address: %s\n", ether_addr_to_string(&e, ea));
+ printf(" HW Address: %s\n", ether_addr_to_string(&info->mac_address, ea));
}
- if (mtu > 0)
- printf(" MTU: %u\n", mtu);
+ if (info->has_mtu)
+ printf(" MTU: %u\n", info->mtu);
- dump_addresses(rtnl, " Address: ", ifindex);
- dump_gateways(rtnl, hwdb, " Gateway: ", ifindex);
+ (void) dump_addresses(rtnl, " Address: ", info->ifindex);
+ (void) dump_gateways(rtnl, hwdb, " Gateway: ", info->ifindex);
dump_list(" DNS: ", dns);
dump_list(" Search Domains: ", search_domains);
@@ -650,362 +795,237 @@ static int link_status_one(
dump_list(" NTP: ", ntp);
- dump_list("Carrier Bound To: ", carrier_bound_to);
- dump_list("Carrier Bound By: ", carrier_bound_by);
+ dump_ifindexes("Carrier Bound To: ", carrier_bound_to);
+ dump_ifindexes("Carrier Bound By: ", carrier_bound_by);
- (void) sd_network_link_get_timezone(ifindex, &tz);
+ (void) sd_network_link_get_timezone(info->ifindex, &tz);
if (tz)
- printf(" Time Zone: %s", tz);
+ printf(" Time Zone: %s\n", tz);
+
+ (void) dump_lldp_neighbors(" Connected To: ", info->ifindex);
return 0;
}
-static int link_status(int argc, char *argv[], void *userdata) {
- _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
- _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
- char **name;
- int r;
-
- r = sd_netlink_open(&rtnl);
- if (r < 0)
- return log_error_errno(r, "Failed to connect to netlink: %m");
-
- r = sd_hwdb_new(&hwdb);
- if (r < 0)
- log_debug_errno(r, "Failed to open hardware database: %m");
-
- if (argc <= 1 && !arg_all) {
- _cleanup_free_ char *operational_state = NULL;
- _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains;
- const char *on_color_operational, *off_color_operational;
-
- sd_network_get_operational_state(&operational_state);
- operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
-
- printf("%s%s%s State: %s%s%s\n",
- on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational,
- on_color_operational, strna(operational_state), off_color_operational);
-
- dump_addresses(rtnl, " Address: ", 0);
- dump_gateways(rtnl, hwdb, " Gateway: ", 0);
-
- sd_network_get_dns(&dns);
- dump_list(" DNS: ", dns);
-
- sd_network_get_search_domains(&search_domains);
- dump_list("Search Domains: ", search_domains);
-
- sd_network_get_route_domains(&route_domains);
- dump_list(" Route Domains: ", route_domains);
-
- sd_network_get_ntp(&ntp);
- dump_list(" NTP: ", ntp);
-
- return 0;
- }
+static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
+ _cleanup_free_ char *operational_state = NULL;
+ _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
+ const char *on_color_operational, *off_color_operational;
- pager_open_if_enabled();
+ assert(rtnl);
- if (arg_all) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
- _cleanup_free_ LinkInfo *links = NULL;
- int c, i;
+ (void) sd_network_get_operational_state(&operational_state);
+ operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
- r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
- if (r < 0)
- return rtnl_log_create_error(r);
+ printf("%s%s%s State: %s%s%s\n",
+ on_color_operational, special_glyph(BLACK_CIRCLE), off_color_operational,
+ on_color_operational, strna(operational_state), off_color_operational);
- r = sd_netlink_message_request_dump(req, true);
- if (r < 0)
- return rtnl_log_create_error(r);
+ (void) dump_addresses(rtnl, " Address: ", 0);
+ (void) dump_gateways(rtnl, hwdb, " Gateway: ", 0);
- r = sd_netlink_call(rtnl, req, 0, &reply);
- if (r < 0)
- return log_error_errno(r, "Failed to enumerate links: %m");
+ (void) sd_network_get_dns(&dns);
+ dump_list(" DNS: ", dns);
- c = decode_and_sort_links(reply, &links);
- if (c < 0)
- return rtnl_log_parse_error(c);
+ (void) sd_network_get_search_domains(&search_domains);
+ dump_list("Search Domains: ", search_domains);
- for (i = 0; i < c; i++) {
- if (i > 0)
- fputc('\n', stdout);
+ (void) sd_network_get_route_domains(&route_domains);
+ dump_list(" Route Domains: ", route_domains);
- link_status_one(rtnl, hwdb, links[i].name);
- }
- } else {
- STRV_FOREACH(name, argv + 1) {
- if (name != argv + 1)
- fputc('\n', stdout);
-
- link_status_one(rtnl, hwdb, *name);
- }
- }
+ (void) sd_network_get_ntp(&ntp);
+ dump_list(" NTP: ", ntp);
return 0;
}
-const char *lldp_system_capability_to_string(LLDPSystemCapabilities d) _const_;
-LLDPSystemCapabilities lldp_system_capability_from_string(const char *d) _pure_;
-
-static const char* const lldp_system_capability_table[_LLDP_SYSTEM_CAPABILITIES_MAX + 1] = {
- [LLDP_SYSTEM_CAPABILITIES_OTHER] = "O",
- [LLDP_SYSTEM_CAPABILITIES_REPEATER] = "P",
- [LLDP_SYSTEM_CAPABILITIES_BRIDGE] = "B",
- [LLDP_SYSTEM_CAPABILITIES_WLAN_AP] = "W",
- [LLDP_SYSTEM_CAPABILITIES_ROUTER] = "R",
- [LLDP_SYSTEM_CAPABILITIES_PHONE] = "T",
- [LLDP_SYSTEM_CAPABILITIES_DOCSIS] = "D",
- [LLDP_SYSTEM_CAPABILITIES_STATION] = "A",
- [LLDP_SYSTEM_CAPABILITIES_CVLAN] = "C",
- [LLDP_SYSTEM_CAPABILITIES_SVLAN] = "S",
- [LLDP_SYSTEM_CAPABILITIES_TPMR] = "M",
- [_LLDP_SYSTEM_CAPABILITIES_MAX] = "N/A",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(lldp_system_capability, LLDPSystemCapabilities);
-
-static char *lldp_system_caps(uint16_t cap) {
- _cleanup_free_ char *s = NULL, *t = NULL;
- char *capability;
-
- t = strdup("[ ");
- if (!t)
- return NULL;
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_OTHER) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_OTHER), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_REPEATER) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_REPEATER), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_BRIDGE) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_BRIDGE), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_WLAN_AP) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_WLAN_AP), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_ROUTER) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_ROUTER), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_PHONE) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_PHONE), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
+static int link_status(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
+ _cleanup_free_ LinkInfo *links = NULL;
+ int r, c, i;
- if (cap & LLDP_SYSTEM_CAPABILITIES_DOCSIS) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_DOCSIS), " ", NULL);
- if (!s)
- return NULL;
+ pager_open(arg_no_pager, false);
- free(t);
- t = s;
- }
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
- if (cap & LLDP_SYSTEM_CAPABILITIES_STATION) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_STATION), " ", NULL);
- if (!s)
- return NULL;
+ r = sd_hwdb_new(&hwdb);
+ if (r < 0)
+ log_debug_errno(r, "Failed to open hardware database: %m");
- free(t);
- t = s;
- }
+ if (arg_all)
+ c = acquire_link_info_all(rtnl, &links);
+ else if (argc <= 1)
+ return system_status(rtnl, hwdb);
+ else
+ c = acquire_link_info_strv(rtnl, argv + 1, &links);
+ if (c < 0)
+ return c;
- if (cap & LLDP_SYSTEM_CAPABILITIES_CVLAN) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_CVLAN), " ", NULL);
- if (!s)
- return NULL;
+ for (i = 0; i < c; i++) {
+ if (i > 0)
+ fputc('\n', stdout);
- free(t);
- t = s;
+ link_status_one(rtnl, hwdb, links + i);
}
- if (cap & LLDP_SYSTEM_CAPABILITIES_SVLAN) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_SVLAN), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
+ return 0;
+}
- if (cap & LLDP_SYSTEM_CAPABILITIES_TPMR) {
- s = strappend(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_TPMR));
- if (!s)
- return NULL;
+static char *lldp_capabilities_to_string(uint16_t x) {
+ static const char characters[] = {
+ 'o', 'p', 'b', 'w', 'r', 't', 'd', 'a', 'c', 's', 'm',
+ };
+ char *ret;
+ unsigned i;
- free(t);
- }
+ ret = new(char, ELEMENTSOF(characters) + 1);
+ if (!ret)
+ return NULL;
- if (!s) {
- s = strappend(t, lldp_system_capability_to_string(_LLDP_SYSTEM_CAPABILITIES_MAX));
- if (!s)
- return NULL;
+ for (i = 0; i < ELEMENTSOF(characters); i++)
+ ret[i] = (x & (1U << i)) ? characters[i] : '.';
- free(t);
- }
+ ret[i] = 0;
+ return ret;
+}
- t = strappend(s, "]");
- if (!t)
- return NULL;
+static void lldp_capabilities_legend(uint16_t x) {
+ unsigned w, i, cols = columns();
+ static const char* const table[] = {
+ "o - Other",
+ "p - Repeater",
+ "b - Bridge",
+ "w - WLAN Access Point",
+ "r - Router",
+ "t - Telephone",
+ "d - DOCSIS cable device",
+ "a - Station",
+ "c - Customer VLAN",
+ "s - Service VLAN",
+ "m - Two-port MAC Relay (TPMR)",
+ };
- free(s);
- capability = t;
+ if (x == 0)
+ return;
- s = NULL;
- t = NULL;
+ printf("\nCapability Flags:\n");
+ for (w = 0, i = 0; i < ELEMENTSOF(table); i++)
+ if (x & (1U << i) || arg_all) {
+ bool newline;
- return capability;
+ newline = w + strlen(table[i]) + (w == 0 ? 0 : 2) > cols;
+ if (newline)
+ w = 0;
+ w += printf("%s%s%s", newline ? "\n" : "", w == 0 ? "" : "; ", table[i]);
+ }
+ puts("");
}
static int link_lldp_status(int argc, char *argv[], void *userdata) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_free_ LinkInfo *links = NULL;
- double ttl = -1;
- uint32_t capability;
- int i, r, c, j;
- const char *p;
- char **s;
-
- pager_open_if_enabled();
+ int i, r, c, m = 0;
+ uint16_t all = 0;
r = sd_netlink_open(&rtnl);
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
- r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
- if (r < 0)
- return rtnl_log_create_error(r);
-
- r = sd_netlink_message_request_dump(req, true);
- if (r < 0)
- return rtnl_log_create_error(r);
-
- r = sd_netlink_call(rtnl, req, 0, &reply);
- if (r < 0)
- return log_error_errno(r, "Failed to enumerate links: %m");
-
- c = decode_and_sort_links(reply, &links);
+ if (argc > 1)
+ c = acquire_link_info_strv(rtnl, argv + 1, &links);
+ else
+ c = acquire_link_info_all(rtnl, &links);
if (c < 0)
- return rtnl_log_parse_error(c);
+ return c;
+
+ pager_open(arg_no_pager, false);
if (arg_legend)
- printf("%s %16s %24s %16s %16s\n", "Local Intf", "Device ID", "Port ID", "TTL", "Capability");
+ printf("%-16s %-17s %-16s %-11s %-17s %-16s\n",
+ "LINK",
+ "CHASSIS ID",
+ "SYSTEM NAME",
+ "CAPS",
+ "PORT ID",
+ "PORT DESCRIPTION");
- for (i = j = 0; i < c; i++) {
- _cleanup_free_ char *chassis = NULL, *port = NULL, *cap = NULL, *lldp = NULL;
- _cleanup_strv_free_ char **l = NULL;
+ for (i = 0; i < c; i++) {
+ _cleanup_fclose_ FILE *f = NULL;
- r = sd_network_link_get_lldp(links[i].ifindex, &lldp);
- if (r < 0)
+ r = open_lldp_neighbors(links[i].ifindex, &f);
+ if (r == -ENOENT)
continue;
+ if (r < 0) {
+ log_warning_errno(r, "Failed to open LLDP data for %i, ignoring: %m", links[i].ifindex);
+ continue;
+ }
- l = strv_split_newlines(lldp);
- if (!l)
- return -ENOMEM;
-
- STRV_FOREACH(s, l) {
-
- p = *s;
- for (;;) {
- _cleanup_free_ char *a = NULL, *b = NULL, *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
- if (r < 0)
- return log_error_errno(r, "Failed to parse LLDP syntax \"%s\": %m", *s);
-
- if (r == 0)
- break;
-
- r = split_pair(word, "=", &a, &b);
- if (r < 0)
- continue;
-
- if (streq(a, "_Chassis")) {
- r = free_and_strdup(&chassis, b);
- if (r < 0)
- return r;
-
- } else if (streq(a, "_Port")) {
- r = free_and_strdup(&port, b);
- if (r < 0)
- return r;
-
- } else if (streq(a, "_TTL")) {
- long long unsigned x = 0;
- usec_t time;
+ for (;;) {
+ _cleanup_free_ char *cid = NULL, *pid = NULL, *sname = NULL, *pdesc = NULL;
+ const char *chassis_id = NULL, *port_id = NULL, *system_name = NULL, *port_description = NULL, *capabilities = NULL;
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
+ uint16_t cc;
- r = safe_atollu(b, &x);
- if (r < 0 || (usec_t) x != x)
- return log_warning_errno(r < 0 ? r : ERANGE,
- "Failed to parse TTL \"%s\": %m", b);
+ r = next_lldp_neighbor(f, &n);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to read neighbor data: %m");
+ break;
+ }
+ if (r == 0)
+ break;
- time = now(clock_boottime_or_monotonic());
- if (x < time)
- continue;
+ (void) sd_lldp_neighbor_get_chassis_id_as_string(n, &chassis_id);
+ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id);
+ (void) sd_lldp_neighbor_get_system_name(n, &system_name);
+ (void) sd_lldp_neighbor_get_port_description(n, &port_description);
- ttl = (double) (x - time) / USEC_PER_SEC;
+ if (chassis_id) {
+ cid = ellipsize(chassis_id, 17, 100);
+ if (cid)
+ chassis_id = cid;
+ }
- } else if (streq(a, "_CAP")) {
- sscanf(b, "%x", &capability);
+ if (port_id) {
+ pid = ellipsize(port_id, 17, 100);
+ if (pid)
+ port_id = pid;
+ }
- cap = lldp_system_caps(capability);
- }
+ if (system_name) {
+ sname = ellipsize(system_name, 16, 100);
+ if (sname)
+ system_name = sname;
+ }
+ if (port_description) {
+ pdesc = ellipsize(port_description, 16, 100);
+ if (pdesc)
+ port_description = pdesc;
}
- if (ttl >= 0) {
- printf("%10s %24s %16s %16f %16s\n",
- links[i].name,
- strna(chassis), strna(port),
- ttl, cap);
- j++;
+ if (sd_lldp_neighbor_get_enabled_capabilities(n, &cc) >= 0) {
+ capabilities = lldp_capabilities_to_string(cc);
+ all |= cc;
}
+
+ printf("%-16s %-17s %-16s %-11s %-17s %-16s\n",
+ links[i].name,
+ strna(chassis_id),
+ strna(system_name),
+ strna(capabilities),
+ strna(port_id),
+ strna(port_description));
+
+ m++;
}
}
if (arg_legend) {
- printf("\nCapability Codes:\n"
- "(O) - Other, (P) - Repeater, (B) - Bridge , (W) - WLAN Access Point, (R) = Router,\n"
- "(T) - Telephone, (D) - Data Over Cable Service Interface Specifications, (A) - Station,\n"
- "(C) - Customer VLAN, (S) - Service VLAN, (M) - Two-port MAC Relay (TPMR)\n\n");
-
- printf("Total entries displayed: %d\n", j);
+ lldp_capabilities_legend(all);
+ printf("\n%i neighbors listed.\n", m);
}
return 0;
@@ -1020,9 +1040,9 @@ static void help(void) {
" --no-legend Do not show the headers and footers\n"
" -a --all Show status for all links\n\n"
"Commands:\n"
- " list List links\n"
+ " list [LINK...] List links\n"
" status [LINK...] Show link status\n"
- " lldp Show lldp information\n"
+ " lldp [LINK...] Show LLDP neighbors\n"
, program_invocation_short_name);
}
@@ -1084,15 +1104,23 @@ static int parse_argv(int argc, char *argv[]) {
static int networkctl_main(int argc, char *argv[]) {
const Verb verbs[] = {
- { "list", VERB_ANY, 1, VERB_DEFAULT, list_links },
- { "status", 1, VERB_ANY, 0, link_status },
- { "lldp", VERB_ANY, 1, VERB_DEFAULT, link_lldp_status },
+ { "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 },
{}
};
return dispatch_verb(argc, argv, verbs, NULL);
}
+static void warn_networkd_missing(void) {
+
+ if (access("/run/systemd/netif/state", F_OK) >= 0)
+ return;
+
+ fprintf(stderr, "WARNING: systemd-networkd is not running, output will be incomplete.\n\n");
+}
+
int main(int argc, char* argv[]) {
int r;
@@ -1103,6 +1131,8 @@ int main(int argc, char* argv[]) {
if (r <= 0)
goto finish;
+ warn_networkd_missing();
+
r = networkctl_main(argc, argv);
finish:
diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c
index d9d487d805..ebc6c9eb9e 100644
--- a/src/network/networkd-address-pool.c
+++ b/src/network/networkd-address-pool.c
@@ -148,8 +148,12 @@ int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union
for (;;) {
if (!address_pool_prefix_is_taken(p, &u, prefixlen)) {
_cleanup_free_ char *s = NULL;
+ int r;
+
+ r = in_addr_to_string(p->family, &u, &s);
+ if (r < 0)
+ return r;
- in_addr_to_string(p->family, &u, &s);
log_debug("Found range %s/%u", strna(s), prefixlen);
*found = u;
diff --git a/src/network/networkd-address-pool.h b/src/network/networkd-address-pool.h
index 8e1378ff40..af30decfe0 100644
--- a/src/network/networkd-address-pool.h
+++ b/src/network/networkd-address-pool.h
@@ -22,7 +22,9 @@
typedef struct AddressPool AddressPool;
#include "in-addr-util.h"
-#include "networkd.h"
+#include "list.h"
+
+typedef struct Manager Manager;
struct AddressPool {
Manager *manager;
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 7f9a7268cc..367c340e08 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -27,6 +27,7 @@
#include "networkd.h"
#include "parse-util.h"
#include "set.h"
+#include "socket-util.h"
#include "string-util.h"
#include "utf8.h"
#include "util.h"
@@ -67,16 +68,15 @@ int address_new_static(Network *network, unsigned section, Address **ret) {
if (r < 0)
return r;
- address->network = network;
-
- LIST_APPEND(addresses, network->static_addresses, address);
-
if (section) {
address->section = section;
hashmap_put(network->addresses_by_section,
UINT_TO_PTR(address->section), address);
}
+ address->network = network;
+ LIST_APPEND(addresses, network->static_addresses, address);
+
*ret = address;
address = NULL;
@@ -98,6 +98,9 @@ void address_free(Address *address) {
if (address->link) {
set_remove(address->link->addresses, address);
set_remove(address->link->addresses_foreign, address);
+
+ if (in_addr_equal(AF_INET6, &address->in_addr, (const union in_addr_union *) &address->link->ipv6ll_address))
+ memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
}
free(address);
@@ -331,6 +334,10 @@ int address_update(Address *address, unsigned char flags, unsigned char scope, s
assert(address);
assert(cinfo);
+ assert_return(address->link, 1);
+
+ if (IN_SET(address->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
ready = address_is_ready(address);
@@ -338,19 +345,18 @@ int address_update(Address *address, unsigned char flags, unsigned char scope, s
address->scope = scope;
address->cinfo = *cinfo;
- if (address->link) {
- link_update_operstate(address->link);
-
- if (!ready && address_is_ready(address)) {
- link_check_ready(address->link);
-
- if (address->family == AF_INET6 &&
- in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
- in_addr_is_null(AF_INET6, (const union in_addr_union*) &address->link->ipv6ll_address) > 0) {
- r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
- if (r < 0)
- return r;
- }
+ link_update_operstate(address->link);
+
+ if (!ready && address_is_ready(address)) {
+ link_check_ready(address->link);
+
+ if (address->family == AF_INET6 &&
+ in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
+ in_addr_is_null(AF_INET6, (const union in_addr_union*) &address->link->ipv6ll_address) > 0) {
+
+ r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
+ if (r < 0)
+ return r;
}
}
@@ -404,8 +410,11 @@ int address_get(Link *link, int family, const union in_addr_union *in_addr, unsi
return 0;
}
-int address_remove(Address *address, Link *link,
- sd_netlink_message_handler_t callback) {
+int address_remove(
+ Address *address,
+ Link *link,
+ sd_netlink_message_handler_t callback) {
+
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
@@ -727,7 +736,8 @@ int config_parse_address(const char *unit,
return 0;
}
-int config_parse_label(const char *unit,
+int config_parse_label(
+ const char *unit,
const char *filename,
unsigned line,
const char *section,
@@ -737,9 +747,9 @@ int config_parse_label(const char *unit,
const char *rvalue,
void *data,
void *userdata) {
- Network *network = userdata;
+
_cleanup_address_free_ Address *n = NULL;
- char *label;
+ Network *network = userdata;
int r;
assert(filename);
@@ -752,25 +762,64 @@ int config_parse_label(const char *unit,
if (r < 0)
return r;
- label = strdup(rvalue);
- if (!label)
+ if (!ifname_valid(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is not valid or too long, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ r = free_and_strdup(&n->label, rvalue);
+ if (r < 0)
return log_oom();
- if (!ascii_is_valid(label) || strlen(label) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- free(label);
+ n = NULL;
+
+ return 0;
+}
+
+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) {
+ Network *network = userdata;
+ _cleanup_address_free_ Address *n = NULL;
+ unsigned k;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = address_new_static(network, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (STR_IN_SET(rvalue, "forever", "infinity")) {
+ n->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME;
+ n = NULL;
+
return 0;
}
- free(n->label);
- if (*label)
- n->label = label;
- else {
- free(label);
- n->label = NULL;
+ r = safe_atou(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse PreferredLifetime, ignoring: %s", rvalue);
+ return 0;
}
- n = NULL;
+ if (k != 0)
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid PreferredLifetime value, ignoring: %d", k);
+ else {
+ n->cinfo.ifa_prefered = k;
+ n = NULL;
+ }
return 0;
}
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 338f6eb9a2..784ab18b27 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -28,10 +28,12 @@ typedef struct Address Address;
#include "networkd-link.h"
#include "networkd-network.h"
-#include "networkd.h"
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
+typedef struct Network Network;
+typedef struct Link Link;
+
struct Address {
Network *network;
unsigned section;
@@ -74,3 +76,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
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);
diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c
new file mode 100644
index 0000000000..b67a1f6d09
--- /dev/null
+++ b/src/network/networkd-conf.c
@@ -0,0 +1,111 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.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/>.
+ ***/
+
+#include <ctype.h>
+
+#include "conf-parser.h"
+#include "def.h"
+#include "dhcp-identifier.h"
+#include "hexdecoct.h"
+#include "networkd-conf.h"
+#include "string-table.h"
+
+int manager_parse_config_file(Manager *m) {
+ assert(m);
+
+ return config_parse_many(PKGSYSCONFDIR "/networkd.conf",
+ 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] = {
+ [DUID_TYPE_LLT] = "link-layer-time",
+ [DUID_TYPE_EN] = "vendor",
+ [DUID_TYPE_LL] = "link-layer",
+ [DUID_TYPE_UUID] = "uuid",
+};
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_duid_type, duid_type, DUIDType, "Failed to parse DUID type");
+
+int config_parse_duid_rawdata(
+ 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) {
+
+ DUID *ret = data;
+ uint8_t raw_data[MAX_DUID_LEN];
+ unsigned count = 0;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(ret);
+
+ /* RawData contains DUID in format "NN:NN:NN..." */
+ for (;;) {
+ int n1, n2, len, r;
+ uint32_t byte;
+ _cleanup_free_ char *cbyte = NULL;
+
+ r = extract_first_word(&rvalue, &cbyte, ":", 0);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
+ return 0;
+ }
+ if (r == 0)
+ break;
+ if (count >= MAX_DUID_LEN) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
+ return 0;
+ }
+
+ len = strlen(cbyte);
+ if (len != 1 && len != 2) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
+ return 0;
+ }
+ n1 = unhexchar(cbyte[0]);
+ if (len == 2)
+ n2 = unhexchar(cbyte[1]);
+ else
+ n2 = 0;
+
+ if (n1 < 0 || n2 < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
+ return 0;
+ }
+
+ byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
+ raw_data[count++] = byte;
+ }
+
+ assert_cc(sizeof(raw_data) == sizeof(ret->raw_data));
+ memcpy(ret->raw_data, raw_data, count);
+ ret->raw_data_len = count;
+ return 0;
+}
diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h
new file mode 100644
index 0000000000..c7bfb42a72
--- /dev/null
+++ b/src/network/networkd-conf.h
@@ -0,0 +1,49 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.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/>.
+***/
+
+#include "networkd.h"
+
+int manager_parse_config_file(Manager *m);
+
+const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, unsigned length);
+
+int config_parse_duid_type(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata);
+int config_parse_duid_rawdata(
+ 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-dhcp4.c b/src/network/networkd-dhcp4.c
index 03c28bbcb6..2ddcee9db8 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -24,7 +24,7 @@
#include "dhcp-lease-internal.h"
#include "hostname-util.h"
#include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
void *userdata) {
@@ -34,7 +34,7 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
assert(link);
assert(link->dhcp4_messages > 0);
- link->dhcp4_messages --;
+ link->dhcp4_messages--;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@@ -57,6 +57,10 @@ static int link_set_dhcp_routes(Link *link) {
assert(link);
assert(link->dhcp_lease);
+ assert(link->network);
+
+ if (!link->network->dhcp_use_routes)
+ return 0;
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
if (r < 0 && r != -ENODATA)
@@ -92,25 +96,25 @@ static int link_set_dhcp_routes(Link *link) {
route_gw->protocol = RTPROT_DHCP;
route_gw->priority = link->network->dhcp_route_metric;
- r = route_configure(route_gw, link, &dhcp4_route_handler);
+ r = route_configure(route_gw, link, dhcp4_route_handler);
if (r < 0)
return log_link_warning_errno(link, r, "Could not set host route: %m");
- link->dhcp4_messages ++;
+ link->dhcp4_messages++;
route->family = AF_INET;
route->gw.in = gateway;
route->prefsrc.in = address;
route->priority = link->network->dhcp_route_metric;
- r = route_configure(route, link, &dhcp4_route_handler);
+ r = route_configure(route, link, dhcp4_route_handler);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set routes: %m");
link_enter_failed(link);
return r;
}
- link->dhcp4_messages ++;
+ link->dhcp4_messages++;
}
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
@@ -133,11 +137,11 @@ static int link_set_dhcp_routes(Link *link) {
assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
route->priority = link->network->dhcp_route_metric;
- r = route_configure(route, link, &dhcp4_route_handler);
+ r = route_configure(route, link, dhcp4_route_handler);
if (r < 0)
return log_link_warning_errno(link, r, "Could not set host route: %m");
- link->dhcp4_messages ++;
+ link->dhcp4_messages++;
}
return 0;
@@ -173,7 +177,7 @@ static int dhcp_lease_lost(Link *link) {
assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &route->dst_prefixlen) >= 0);
route_remove(route, link,
- &link_route_remove_handler);
+ link_route_remove_handler);
}
}
}
@@ -194,7 +198,7 @@ static int dhcp_lease_lost(Link *link) {
route_gw->scope = RT_SCOPE_LINK;
route_remove(route_gw, link,
- &link_route_remove_handler);
+ link_route_remove_handler);
}
r = route_new(&route);
@@ -203,7 +207,7 @@ static int dhcp_lease_lost(Link *link) {
route->gw.in = gateway;
route_remove(route, link,
- &link_route_remove_handler);
+ link_route_remove_handler);
}
}
@@ -217,7 +221,7 @@ static int dhcp_lease_lost(Link *link) {
address->in_addr.in = addr;
address->prefixlen = prefixlen;
- address_remove(address, link, &link_address_remove_handler);
+ address_remove(address, link, link_address_remove_handler);
}
}
@@ -305,7 +309,7 @@ static int dhcp4_update_address(Link *link,
/* allow reusing an existing address and simply update its lifetime
* in case it already exists */
- r = address_configure(addr, link, &dhcp4_address_handler, true);
+ r = address_configure(addr, link, dhcp4_address_handler, true);
if (r < 0)
return r;
@@ -624,14 +628,24 @@ int dhcp4_configure(Link *link) {
}
switch (link->network->dhcp_client_identifier) {
- case DHCP_CLIENT_ID_DUID:
- /* Library defaults to this. */
+ case DHCP_CLIENT_ID_DUID: {
+ /* If configured, apply user specified DUID and/or IAID */
+ const DUID *duid = link_duid(link);
+
+ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+ link->network->iaid,
+ duid->type,
+ duid->raw_data_len > 0 ? duid->raw_data : NULL,
+ duid->raw_data_len);
+ if (r < 0)
+ return r;
break;
+ }
case DHCP_CLIENT_ID_MAC:
r = sd_dhcp_client_set_client_id(link->dhcp_client,
ARPHRD_ETHER,
(const uint8_t *) &link->mac,
- sizeof (link->mac));
+ sizeof(link->mac));
if (r < 0)
return r;
break;
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index bf8e826368..c5a3c52e94 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -23,7 +23,7 @@
#include <systemd/sd-dhcp6-client.h>
#include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
@@ -103,8 +103,8 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) {
sd_dhcp6_lease_reset_address_iter(lease);
while (sd_dhcp6_lease_get_address(lease, &ip6_addr,
- &lifetime_preferred,
- &lifetime_valid) >= 0) {
+ &lifetime_preferred,
+ &lifetime_valid) >= 0) {
r = dhcp6_address_change(link, &ip6_addr, lifetime_preferred, lifetime_valid);
if (r < 0)
@@ -194,18 +194,13 @@ int dhcp6_request_address(Link *link) {
if (r < 0)
return r;
- if (running) {
- r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0)
- return r;
- }
-
return 0;
}
int dhcp6_configure(Link *link) {
sd_dhcp6_client *client = NULL;
int r;
+ const DUID *duid;
assert(link);
@@ -230,6 +225,18 @@ int dhcp6_configure(Link *link) {
if (r < 0)
goto error;
+ r = sd_dhcp6_client_set_iaid(client, link->network->iaid);
+ if (r < 0)
+ goto error;
+
+ duid = link_duid(link);
+ r = sd_dhcp6_client_set_duid(client,
+ duid->type,
+ duid->raw_data_len > 0 ? duid->raw_data : NULL,
+ duid->raw_data_len);
+ if (r < 0)
+ goto error;
+
r = sd_dhcp6_client_set_index(client, link->ifindex);
if (r < 0)
goto error;
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c
index 1538caa204..241f486211 100644
--- a/src/network/networkd-fdb.c
+++ b/src/network/networkd-fdb.c
@@ -37,7 +37,7 @@ int fdb_entry_new_static(Network *const network,
assert(network);
/* search entry in hashmap first. */
- if(section) {
+ if (section) {
fdb_entry = hashmap_get(network->fdb_entries_by_section, UINT_TO_PTR(section));
if (fdb_entry) {
*ret = fdb_entry;
@@ -141,10 +141,10 @@ int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry) {
/* remove and FDB entry. */
void fdb_entry_free(FdbEntry *fdb_entry) {
- if(!fdb_entry)
+ if (!fdb_entry)
return;
- if(fdb_entry->network) {
+ if (fdb_entry->network) {
LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries,
fdb_entry);
diff --git a/src/network/networkd-fdb.h b/src/network/networkd-fdb.h
index 89b3e29405..84410714f5 100644
--- a/src/network/networkd-fdb.h
+++ b/src/network/networkd-fdb.h
@@ -19,10 +19,12 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef struct FdbEntry FdbEntry;
+#include "list.h"
+#include "macro.h"
-#include "networkd-network.h"
-#include "networkd.h"
+typedef struct Network Network;
+typedef struct FdbEntry FdbEntry;
+typedef struct Link Link;
struct FdbEntry {
Network *network;
diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf
new file mode 100644
index 0000000000..3fdfe74955
--- /dev/null
+++ b/src/network/networkd-gperf.gperf
@@ -0,0 +1,18 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "networkd-conf.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name networkd_gperf_hash
+%define lookup-function-name networkd_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid.type)
+DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 949c75337c..ae323d595b 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -21,7 +21,7 @@
#include <linux/if.h>
#include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
static int ipv4ll_address_lost(Link *link) {
_cleanup_address_free_ Address *address = NULL;
@@ -51,7 +51,7 @@ static int ipv4ll_address_lost(Link *link) {
address->prefixlen = 16;
address->scope = RT_SCOPE_LINK;
- address_remove(address, link, &link_address_remove_handler);
+ address_remove(address, link, link_address_remove_handler);
r = route_new(&route);
if (r < 0) {
@@ -63,7 +63,7 @@ static int ipv4ll_address_lost(Link *link) {
route->scope = RT_SCOPE_LINK;
route->priority = IPV4LL_ROUTE_METRIC;
- route_remove(route, link, &link_route_remove_handler);
+ route_remove(route, link, link_route_remove_handler);
link_check_ready(link);
@@ -165,7 +165,7 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
return 0;
}
-static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
+static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
Link *link = userdata;
int r;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 692c0bf63d..a021fc886f 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -28,8 +28,8 @@
#include "fileio.h"
#include "netlink-util.h"
#include "network-internal.h"
-#include "networkd-link.h"
-#include "networkd-netdev.h"
+#include "networkd.h"
+#include "networkd-lldp-tx.h"
#include "set.h"
#include "socket-util.h"
#include "stdio-util.h"
@@ -38,7 +38,12 @@
#include "util.h"
#include "virt.h"
-bool link_dhcp6_enabled(Link *link) {
+static bool link_dhcp6_enabled(Link *link) {
+ assert(link);
+
+ if (!socket_ipv6_is_supported())
+ return false;
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -48,7 +53,9 @@ bool link_dhcp6_enabled(Link *link) {
return link->network->dhcp & ADDRESS_FAMILY_IPV6;
}
-bool link_dhcp4_enabled(Link *link) {
+static bool link_dhcp4_enabled(Link *link) {
+ assert(link);
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -58,7 +65,9 @@ bool link_dhcp4_enabled(Link *link) {
return link->network->dhcp & ADDRESS_FAMILY_IPV4;
}
-bool link_dhcp4_server_enabled(Link *link) {
+static bool link_dhcp4_server_enabled(Link *link) {
+ assert(link);
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -68,7 +77,9 @@ bool link_dhcp4_server_enabled(Link *link) {
return link->network->dhcp_server;
}
-bool link_ipv4ll_enabled(Link *link) {
+static bool link_ipv4ll_enabled(Link *link) {
+ assert(link);
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -78,7 +89,12 @@ bool link_ipv4ll_enabled(Link *link) {
return link->network->link_local & ADDRESS_FAMILY_IPV4;
}
-bool link_ipv6ll_enabled(Link *link) {
+static bool link_ipv6ll_enabled(Link *link) {
+ assert(link);
+
+ if (!socket_ipv6_is_supported())
+ return false;
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -88,20 +104,51 @@ bool link_ipv6ll_enabled(Link *link) {
return link->network->link_local & ADDRESS_FAMILY_IPV6;
}
-bool link_lldp_enabled(Link *link) {
+static bool link_ipv6_enabled(Link *link) {
+ assert(link);
+
+ if (!socket_ipv6_is_supported())
+ return false;
+
+ return link_dhcp6_enabled(link) || link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
+}
+
+static bool link_lldp_rx_enabled(Link *link) {
+ assert(link);
+
if (link->flags & IFF_LOOPBACK)
return false;
+ if (link->iftype != ARPHRD_ETHER)
+ return false;
+
if (!link->network)
return false;
if (link->network->bridge)
return false;
- return link->network->lldp;
+ return link->network->lldp_mode != LLDP_MODE_NO;
+}
+
+static bool link_lldp_emit_enabled(Link *link) {
+ assert(link);
+
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (link->iftype != ARPHRD_ETHER)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ return link->network->lldp_emit != LLDP_EMIT_NO;
}
static bool link_ipv4_forward_enabled(Link *link) {
+ assert(link);
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -115,6 +162,7 @@ static bool link_ipv4_forward_enabled(Link *link) {
}
static bool link_ipv6_forward_enabled(Link *link) {
+ assert(link);
if (!socket_ipv6_is_supported())
return false;
@@ -131,7 +179,27 @@ static bool link_ipv6_forward_enabled(Link *link) {
return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
}
-bool link_ipv6_accept_ra_enabled(Link *link) {
+static bool link_proxy_arp_enabled(Link *link) {
+ assert(link);
+
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ if (link->network->proxy_arp < 0)
+ return false;
+
+ return true;
+}
+
+static bool link_ipv6_accept_ra_enabled(Link *link) {
+ assert(link);
+
+ if (!socket_ipv6_is_supported())
+ return false;
+
if (link->flags & IFF_LOOPBACK)
return false;
@@ -154,6 +222,7 @@ bool link_ipv6_accept_ra_enabled(Link *link) {
}
static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
+ assert(link);
if (!socket_ipv6_is_supported())
return _IPV6_PRIVACY_EXTENSIONS_INVALID;
@@ -167,6 +236,31 @@ static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
return link->network->ipv6_privacy_extensions;
}
+static int link_enable_ipv6(Link *link) {
+ const char *p = NULL;
+ bool disabled;
+ int r;
+
+ if (link->flags & IFF_LOOPBACK)
+ return 0;
+
+ disabled = !link_ipv6_enabled(link);
+
+ p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6");
+
+ r = write_string_file(p, one_zero(disabled), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Cannot %s IPv6 for interface %s: %m", disabled ? "disable" : "enable", link->ifname);
+ else {
+ if (disabled)
+ log_link_info(link, "IPv6 disabled for interface: %m");
+ else
+ log_link_info(link, "IPv6 enabled for interface: %m");
+ }
+
+ return 0;
+}
+
void link_update_operstate(Link *link) {
LinkOperationalState operstate;
assert(link);
@@ -214,7 +308,6 @@ void link_update_operstate(Link *link) {
link->operstate = operstate;
link_send_changed(link, "OperationalState", NULL);
link_dirty(link);
- manager_dirty(link->manager);
}
}
@@ -300,6 +393,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
uint16_t type;
const char *ifname;
int r, ifindex;
+ unsigned short iftype;
assert(manager);
assert(message);
@@ -317,6 +411,10 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
else if (ifindex <= 0)
return -EINVAL;
+ r = sd_rtnl_message_link_get_type(message, &iftype);
+ if (r < 0)
+ return r;
+
r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
if (r < 0)
return r;
@@ -330,30 +428,24 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
link->state = LINK_STATE_PENDING;
link->rtnl_extended_attrs = true;
link->ifindex = ifindex;
+ link->iftype = iftype;
link->ifname = strdup(ifname);
if (!link->ifname)
return -ENOMEM;
r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
if (r < 0)
- log_link_debug(link, "MAC address not found for new device, continuing without");
+ log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
- r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
- link->ifindex);
- if (r < 0)
+ if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
return -ENOMEM;
- r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
- link->ifindex);
- if (r < 0)
+ if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
return -ENOMEM;
- r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d",
- link->ifindex);
- if (r < 0)
+ if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
return -ENOMEM;
-
r = hashmap_ensure_allocated(&manager->links, NULL);
if (r < 0)
return r;
@@ -399,10 +491,11 @@ static void link_free(Link *link) {
sd_dhcp_client_unref(link->dhcp_client);
sd_dhcp_lease_unref(link->dhcp_lease);
+ link_lldp_emit_stop(link);
+
free(link->lease_file);
sd_lldp_unref(link->lldp);
-
free(link->lldp_file);
sd_ipv4ll_unref(link->ipv4ll);
@@ -436,7 +529,7 @@ Link *link_unref(Link *link) {
assert(link->n_ref > 0);
- link->n_ref --;
+ link->n_ref--;
if (link->n_ref > 0)
return NULL;
@@ -452,7 +545,7 @@ Link *link_ref(Link *link) {
assert(link->n_ref > 0);
- link->n_ref ++;
+ link->n_ref++;
return link;
}
@@ -482,8 +575,6 @@ static void link_set_state(Link *link, LinkState state) {
link->state = state;
link_send_changed(link, "AdministrativeState", NULL);
-
- return;
}
static void link_enter_unmanaged(Link *link) {
@@ -506,33 +597,28 @@ static int link_stop_clients(Link *link) {
if (link->dhcp_client) {
k = sd_dhcp_client_stop(link->dhcp_client);
if (k < 0)
- r = log_link_warning_errno(link, r, "Could not stop DHCPv4 client: %m");
+ r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m");
}
if (link->ipv4ll) {
k = sd_ipv4ll_stop(link->ipv4ll);
if (k < 0)
- r = log_link_warning_errno(link, r, "Could not stop IPv4 link-local: %m");
+ r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
}
if (link->dhcp6_client) {
k = sd_dhcp6_client_stop(link->dhcp6_client);
if (k < 0)
- r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m");
+ r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
}
if (link->ndisc_router_discovery) {
k = sd_ndisc_stop(link->ndisc_router_discovery);
if (k < 0)
- r = log_link_warning_errno(link, r, "Could not stop IPv6 Router Discovery: %m");
- }
-
- if (link->lldp) {
- k = sd_lldp_stop(link->lldp);
- if (k < 0)
- r = log_link_warning_errno(link, r, "Could not stop LLDP: %m");
+ r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
}
+ link_lldp_emit_stop(link);
return r;
}
@@ -600,6 +686,9 @@ void link_check_ready(Link *link) {
assert(link);
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return;
+
if (!link->network)
return;
@@ -645,7 +734,7 @@ static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata
LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
LINK_STATE_LINGER));
- link->link_messages --;
+ link->link_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
@@ -674,14 +763,14 @@ static int link_enter_set_routes(Link *link) {
link_set_state(link, LINK_STATE_SETTING_ROUTES);
LIST_FOREACH(routes, rt, link->network->static_routes) {
- r = route_configure(rt, link, &route_handler);
+ r = route_configure(rt, link, route_handler);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set routes: %m");
link_enter_failed(link);
return r;
}
- link->link_messages ++;
+ link->link_messages++;
}
if (link->link_messages == 0) {
@@ -723,7 +812,7 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
LINK_STATE_FAILED, LINK_STATE_LINGER));
- link->link_messages --;
+ link->link_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
@@ -843,14 +932,14 @@ static int link_enter_set_addresses(Link *link) {
link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
LIST_FOREACH(addresses, ad, link->network->static_addresses) {
- r = address_configure(ad, link, &address_handler, false);
+ r = address_configure(ad, link, address_handler, false);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set addresses: %m");
link_enter_failed(link);
return r;
}
- link->link_messages ++;
+ link->link_messages++;
}
/* now that we can figure out a default address for the dhcp server,
@@ -934,6 +1023,12 @@ static int link_enter_set_addresses(Link *link) {
log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
}
+ r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Failed to set router emission for DHCP server: %m");
+ return r;
+ }
+
if (link->network->dhcp_server_emit_timezone) {
_cleanup_free_ char *buffer = NULL;
const char *tz = NULL;
@@ -999,7 +1094,7 @@ static int link_set_bridge_fdb(Link *const link) {
LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
r = fdb_entry_configure(link, fdb_entry);
- if(r < 0) {
+ if (r < 0) {
log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
break;
}
@@ -1008,6 +1103,22 @@ static int link_set_bridge_fdb(Link *const link) {
return r;
}
+static int link_set_proxy_arp(Link *const link) {
+ const char *p = NULL;
+ int r;
+
+ if (!link_proxy_arp_enabled(link))
+ return 0;
+
+ p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/proxy_arp");
+
+ r = write_string_file(p, one_zero(link->network->proxy_arp), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Cannot configure proxy ARP for interface: %m");
+
+ return 0;
+}
+
static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
@@ -1211,7 +1322,7 @@ static int link_set_bridge(Link *link) {
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
- if(link->network->cost != 0) {
+ if (link->network->cost != 0) {
r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
@@ -1230,23 +1341,93 @@ static int link_set_bridge(Link *link) {
return r;
}
-static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
+static int link_lldp_save(Link *link) {
+ _cleanup_free_ char *temp_path = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ sd_lldp_neighbor **l = NULL;
+ int n = 0, r, i;
+
+ assert(link);
+ assert(link->lldp_file);
+
+ if (!link->lldp) {
+ (void) unlink(link->lldp_file);
+ return 0;
+ }
+
+ r = sd_lldp_get_neighbors(link->lldp, &l);
+ if (r < 0)
+ goto finish;
+ if (r == 0) {
+ (void) unlink(link->lldp_file);
+ goto finish;
+ }
+
+ n = r;
+
+ r = fopen_temporary(link->lldp_file, &f, &temp_path);
+ if (r < 0)
+ goto finish;
+
+ fchmod(fileno(f), 0644);
+
+ for (i = 0; i < n; i++) {
+ const void *p;
+ le64_t u;
+ size_t sz;
+
+ r = sd_lldp_neighbor_get_raw(l[i], &p, &sz);
+ if (r < 0)
+ goto finish;
+
+ u = htole64(sz);
+ (void) fwrite(&u, 1, sizeof(u), f);
+ (void) fwrite(p, 1, sz, f);
+ }
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ goto finish;
+
+ if (rename(temp_path, link->lldp_file) < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+finish:
+ if (r < 0) {
+ (void) unlink(link->lldp_file);
+ if (temp_path)
+ (void) unlink(temp_path);
+
+ log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file);
+ }
+
+ if (l) {
+ for (i = 0; i < n; i++)
+ sd_lldp_neighbor_unref(l[i]);
+ free(l);
+ }
+
+ return r;
+}
+
+static void lldp_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) {
Link *link = userdata;
int r;
assert(link);
- assert(link->network);
- assert(link->manager);
- switch (event) {
- case SD_LLDP_EVENT_UPDATE_INFO:
- r = sd_lldp_save(link->lldp, link->lldp_file);
- if (r < 0)
- log_link_warning_errno(link, r, "Could not save LLDP: %m");
+ (void) link_lldp_save(link);
+
+ if (link_lldp_emit_enabled(link) && event == SD_LLDP_EVENT_ADDED) {
+ /* If we received information about a new neighbor, restart the LLDP "fast" logic */
- break;
- default:
- break;
+ log_link_debug(link, "Received LLDP datagram from previously unknown neighbor, restarting 'fast' LLDP transmission.");
+
+ r = link_lldp_emit_start(link);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Failed to restart LLDP transmission: %m");
}
}
@@ -1283,7 +1464,7 @@ static int link_acquire_ipv6_conf(Link *link) {
return 0;
}
-static int link_acquire_conf(Link *link) {
+static int link_acquire_ipv4_conf(Link *link) {
int r;
assert(link);
@@ -1311,14 +1492,28 @@ static int link_acquire_conf(Link *link) {
return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
}
- if (link_lldp_enabled(link)) {
- assert(link->lldp);
+ return 0;
+}
+
+static int link_acquire_conf(Link *link) {
+ int r;
- log_link_debug(link, "Starting LLDP");
+ assert(link);
- r = sd_lldp_start(link->lldp);
+ r = link_acquire_ipv4_conf(link);
+ if (r < 0)
+ return r;
+
+ if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
+ r = link_acquire_ipv6_conf(link);
+ if (r < 0)
+ return r;
+ }
+
+ if (link_lldp_emit_enabled(link)) {
+ r = link_lldp_emit_start(link);
if (r < 0)
- return log_link_warning_errno(link, r, "Could not start LLDP: %m");
+ return log_link_warning_errno(link, r, "Failed to start LLDP transmission: %m");
}
return 0;
@@ -1382,7 +1577,21 @@ static int link_up(Link *link) {
return log_link_error_errno(link, r, "Could not set MAC address: %m");
}
+ /* If IPv6 not configured (no static IPv6 address and neither DHCPv6 nor IPv6LL is enabled)
+ for this interface then disable IPv6 else enable it. */
+ (void) link_enable_ipv6(link);
+
if (link->network->mtu) {
+ /* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
+ on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */
+ if (link_ipv6_enabled(link) && link->network->mtu < IPV6_MIN_MTU) {
+
+ log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as "
+ "IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes: %m");
+
+ link->network->mtu = IPV6_MIN_MTU;
+ }
+
r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu);
if (r < 0)
return log_link_error_errno(link, r, "Could not set MTU: %m");
@@ -1392,7 +1601,7 @@ static int link_up(Link *link) {
if (r < 0)
return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
- if (socket_ipv6_is_supported()) {
+ if (link_ipv6_enabled(link)) {
/* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
r = sd_netlink_message_open_container(req, AF_INET6);
if (r < 0)
@@ -1559,7 +1768,7 @@ static int link_new_bound_by_list(Link *link) {
m = link->manager;
- HASHMAP_FOREACH (carrier, m->links, i) {
+ HASHMAP_FOREACH(carrier, m->links, i) {
if (!carrier->network)
continue;
@@ -1578,7 +1787,7 @@ static int link_new_bound_by_list(Link *link) {
if (list_updated)
link_dirty(link);
- HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
+ HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
r = link_put_carrier(carrier, link, &carrier->bound_to_links);
if (r < 0)
return r;
@@ -1738,7 +1947,7 @@ static int link_joined(Link *link) {
}
}
- if(link->network->bridge) {
+ if (link->network->bridge) {
r = link_set_bridge(link);
if (r < 0)
log_link_error_errno(link, r, "Could not set bridge message: %m");
@@ -1754,7 +1963,7 @@ static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *us
assert(link);
assert(link->network);
- link->enslaving --;
+ link->enslaving--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
@@ -1810,7 +2019,7 @@ static int link_enter_join_netdev(Link *link) {
return r;
}
- link->enslaving ++;
+ link->enslaving++;
}
if (link->network->bridge) {
@@ -1831,7 +2040,7 @@ static int link_enter_join_netdev(Link *link) {
return r;
}
- link->enslaving ++;
+ link->enslaving++;
}
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
@@ -1853,7 +2062,7 @@ static int link_enter_join_netdev(Link *link) {
return r;
}
- link->enslaving ++;
+ link->enslaving++;
}
return 0;
@@ -2030,6 +2239,27 @@ static int link_drop_foreign_config(Link *link) {
return 0;
}
+static int link_update_lldp(Link *link) {
+ int r;
+
+ assert(link);
+
+ if (!link->lldp)
+ return 0;
+
+ if (link->flags & IFF_UP) {
+ r = sd_lldp_start(link->lldp);
+ if (r > 0)
+ log_link_debug(link, "Started LLDP.");
+ } else {
+ r = sd_lldp_stop(link->lldp);
+ if (r > 0)
+ log_link_debug(link, "Stopped LLDP.");
+ }
+
+ return r;
+}
+
static int link_configure(Link *link) {
int r;
@@ -2049,6 +2279,10 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
+ r = link_set_proxy_arp(link);
+ if (r < 0)
+ return r;
+
r = link_set_ipv4_forward(link);
if (r < 0)
return r;
@@ -2108,8 +2342,19 @@ static int link_configure(Link *link) {
return r;
}
- if (link_lldp_enabled(link)) {
- r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
+ if (link_lldp_rx_enabled(link)) {
+ r = sd_lldp_new(&link->lldp, link->ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_lldp_match_capabilities(link->lldp,
+ link->network->lldp_mode == LLDP_MODE_ROUTERS_ONLY ?
+ SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS :
+ SD_LLDP_SYSTEM_CAPABILITIES_ALL);
+ if (r < 0)
+ return r;
+
+ r = sd_lldp_set_filter_address(link->lldp, &link->mac);
if (r < 0)
return r;
@@ -2117,8 +2362,11 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
- r = sd_lldp_set_callback(link->lldp,
- lldp_handler, link);
+ r = sd_lldp_set_callback(link->lldp, lldp_handler, link);
+ if (r < 0)
+ return r;
+
+ r = link_update_lldp(link);
if (r < 0)
return r;
}
@@ -2127,12 +2375,6 @@ static int link_configure(Link *link) {
r = link_acquire_conf(link);
if (r < 0)
return r;
-
- if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
- r = link_acquire_ipv6_conf(link);
- if (r < 0)
- return r;
- }
}
return link_enter_join_netdev(link);
@@ -2307,7 +2549,7 @@ network_file_fail:
continue;
}
- *prefixlen_str ++ = '\0';
+ *prefixlen_str++ = '\0';
r = sscanf(prefixlen_str, "%hhu", &prefixlen);
if (r != 1) {
@@ -2354,7 +2596,7 @@ network_file_fail:
continue;
}
- *prefixlen_str ++ = '\0';
+ *prefixlen_str++ = '\0';
r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
if (r != 5) {
@@ -2515,6 +2757,10 @@ static int link_carrier_gained(Link *link) {
link_enter_failed(link);
return r;
}
+
+ r = link_enter_set_addresses(link);
+ if (r < 0)
+ return r;
}
r = link_handle_bound_by_list(link);
@@ -2562,7 +2808,6 @@ int link_carrier_reset(Link *link) {
return 0;
}
-
int link_update(Link *link, sd_netlink_message *m) {
struct ether_addr mac;
const char *ifname;
@@ -2643,21 +2888,45 @@ int link_update(Link *link, sd_netlink_message *m) {
}
if (link->dhcp_client) {
+ const DUID *duid = link_duid(link);
+
r = sd_dhcp_client_set_mac(link->dhcp_client,
(const uint8_t *) &link->mac,
sizeof (link->mac),
ARPHRD_ETHER);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
+
+ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+ link->network->iaid,
+ duid->type,
+ duid->raw_data_len > 0 ? duid->raw_data : NULL,
+ duid->raw_data_len);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
}
if (link->dhcp6_client) {
+ const DUID* duid = link_duid(link);
+
r = sd_dhcp6_client_set_mac(link->dhcp6_client,
(const uint8_t *) &link->mac,
sizeof (link->mac),
ARPHRD_ETHER);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
+
+ r = sd_dhcp6_client_set_iaid(link->dhcp6_client,
+ link->network->iaid);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
+
+ r = sd_dhcp6_client_set_duid(link->dhcp6_client,
+ duid->type,
+ duid->raw_data_len > 0 ? duid->raw_data : NULL,
+ duid->raw_data_len);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
}
}
}
@@ -2668,6 +2937,10 @@ int link_update(Link *link, sd_netlink_message *m) {
if (r < 0)
return r;
+ r = link_update_lldp(link);
+ if (r < 0)
+ return r;
+
carrier_gained = !had_carrier && link_has_carrier(link);
carrier_lost = had_carrier && !link_has_carrier(link);
@@ -2683,12 +2956,34 @@ int link_update(Link *link, sd_netlink_message *m) {
r = link_carrier_lost(link);
if (r < 0)
return r;
-
}
return 0;
}
+static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
+ bool space = false;
+ Iterator i;
+ Link *link;
+
+ assert(f);
+ assert(prefix);
+
+ if (hashmap_isempty(h))
+ return;
+
+ fputs(prefix, f);
+ HASHMAP_FOREACH(link, h, i) {
+ if (space)
+ fputc(' ', f);
+
+ fprintf(f, "%i", link->ifindex);
+ space = true;
+ }
+
+ fputc('\n', f);
+}
+
int link_save(Link *link) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -2708,6 +3003,8 @@ int link_save(Link *link) {
return 0;
}
+ link_lldp_save(link);
+
admin_state = link_state_to_string(link->state);
assert(admin_state);
@@ -2887,27 +3184,8 @@ int link_save(Link *link) {
fputc('\n', f);
}
- if (!hashmap_isempty(link->bound_to_links)) {
- Link *carrier;
- bool space = false;
-
- fputs("CARRIER_BOUND_TO=", f);
- HASHMAP_FOREACH(carrier, link->bound_to_links, i)
- fputs_with_space(f, carrier->ifname, NULL, &space);
-
- fputc('\n', f);
- }
-
- if (!hashmap_isempty(link->bound_by_links)) {
- Link *carrier;
- bool space = false;
-
- fputs("CARRIER_BOUND_BY=", f);
- HASHMAP_FOREACH(carrier, link->bound_by_links, i)
- fputs_with_space(f, carrier->ifname, NULL, &space);
-
- fputc('\n', f);
- }
+ print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
+ print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
if (link->dhcp_lease) {
struct in_addr address;
@@ -2947,19 +3225,6 @@ int link_save(Link *link) {
}
}
- if (link->lldp) {
- assert(link->network);
-
- r = sd_lldp_save(link->lldp, link->lldp_file);
- if (r < 0)
- goto fail;
-
- fprintf(f,
- "LLDP_FILE=%s\n",
- link->lldp_file);
- } else
- unlink(link->lldp_file);
-
r = fflush_and_check(f);
if (r < 0)
goto fail;
@@ -2985,14 +3250,17 @@ void link_dirty(Link *link) {
assert(link);
+ /* mark manager dirty as link is dirty */
+ manager_dirty(link->manager);
+
r = set_ensure_allocated(&link->manager->dirty_links, NULL);
if (r < 0)
/* allocation errors are ignored */
return;
r = set_put(link->manager->dirty_links, link);
- if (r < 0)
- /* allocation errors are ignored */
+ if (r <= 0)
+ /* don't take another ref if the link was already dirty */
return;
link_ref(link);
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 30f01faf2a..90cb9b93f6 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -21,14 +21,17 @@
#include <endian.h>
+#include <systemd/sd-bus.h>
#include <systemd/sd-dhcp-client.h>
#include <systemd/sd-dhcp-server.h>
#include <systemd/sd-dhcp6-client.h>
#include <systemd/sd-ipv4ll.h>
#include <systemd/sd-lldp.h>
#include <systemd/sd-ndisc.h>
+#include <systemd/sd-netlink.h>
-typedef struct Link Link;
+#include "list.h"
+#include "set.h"
typedef enum LinkState {
LINK_STATE_PENDING,
@@ -54,17 +57,18 @@ typedef enum LinkOperationalState {
_LINK_OPERSTATE_INVALID = -1
} LinkOperationalState;
-#include "networkd-address.h"
-#include "networkd-network.h"
-#include "networkd.h"
+typedef struct Manager Manager;
+typedef struct Network Network;
+typedef struct Address Address;
-struct Link {
+typedef struct Link {
Manager *manager;
int n_ref;
int ifindex;
char *ifname;
+ unsigned short iftype;
char *state_file;
struct ether_addr mac;
struct in6_addr ipv6ll_address;
@@ -111,12 +115,17 @@ struct Link {
sd_dhcp6_client *dhcp6_client;
bool rtnl_extended_attrs;
+ /* This is about LLDP reception */
sd_lldp *lldp;
char *lldp_file;
+ /* This is about LLDP transmission */
+ unsigned lldp_tx_fast; /* The LLDP txFast counter (See 802.1ab-2009, section 9.2.5.18) */
+ sd_event_source *lldp_emit_event_source;
+
Hashmap *bound_by_links;
Hashmap *bound_to_links;
-};
+} Link;
Link *link_unref(Link *link);
Link *link_ref(Link *link);
@@ -154,14 +163,6 @@ int dhcp6_configure(Link *link);
int dhcp6_request_address(Link *link);
int ndisc_configure(Link *link);
-bool link_lldp_enabled(Link *link);
-bool link_ipv4ll_enabled(Link *link);
-bool link_ipv6ll_enabled(Link *link);
-bool link_dhcp4_server_enabled(Link *link);
-bool link_dhcp4_enabled(Link *link);
-bool link_dhcp6_enabled(Link *link);
-bool link_ipv6_accept_ra_enabled(Link *link);
-
const char* link_state_to_string(LinkState s) _const_;
LinkState link_state_from_string(const char *s) _pure_;
diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c
new file mode 100644
index 0000000000..3aa768388b
--- /dev/null
+++ b/src/network/networkd-lldp-tx.c
@@ -0,0 +1,416 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <endian.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "hostname-util.h"
+#include "networkd-lldp-tx.h"
+#include "networkd.h"
+#include "parse-util.h"
+#include "random-util.h"
+#include "socket-util.h"
+#include "string-util.h"
+#include "unaligned.h"
+
+/* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
+#define LLDP_TX_FAST_INIT 4U
+
+/* The LLDP spec calls this "msgTxHold", see 9.2.5.6 */
+#define LLDP_TX_HOLD 4U
+
+/* The jitter range to add, see 9.2.2. */
+#define LLDP_JITTER_USEC (400U * USEC_PER_MSEC)
+
+/* The LLDP spec calls this msgTxInterval, but we subtract half the jitter off it. */
+#define LLDP_TX_INTERVAL_USEC (30U * USEC_PER_SEC - LLDP_JITTER_USEC / 2)
+
+/* The LLDP spec calls this msgFastTx, but we subtract half the jitter off it. */
+#define LLDP_FAST_TX_USEC (1U * USEC_PER_SEC - LLDP_JITTER_USEC / 2)
+
+static const struct ether_addr lldp_multicast_addr[_LLDP_EMIT_MAX] = {
+ [LLDP_EMIT_NEAREST_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }},
+ [LLDP_EMIT_NON_TPMR_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }},
+ [LLDP_EMIT_CUSTOMER_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }},
+};
+
+static int lldp_write_tlv_header(uint8_t **p, uint8_t id, size_t sz) {
+ assert(p);
+
+ if (id > 127)
+ return -EBADMSG;
+ if (sz > 511)
+ return -ENOBUFS;
+
+ (*p)[0] = (id << 1) | !!(sz & 256);
+ (*p)[1] = sz & 255;
+
+ *p = *p + 2;
+ return 0;
+}
+
+static int lldp_make_packet(
+ LLDPEmit mode,
+ const struct ether_addr *hwaddr,
+ const char *machine_id,
+ const char *ifname,
+ uint16_t ttl,
+ const char *port_description,
+ const char *hostname,
+ const char *pretty_hostname,
+ uint16_t system_capabilities,
+ uint16_t enabled_capabilities,
+ void **ret, size_t *sz) {
+
+ size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, pretty_hostname_length = 0;
+ _cleanup_free_ void *packet = NULL;
+ struct ether_header *h;
+ uint8_t *p;
+ size_t l;
+ int r;
+
+ assert(mode > LLDP_EMIT_NO);
+ assert(mode < _LLDP_EMIT_MAX);
+ assert(hwaddr);
+ assert(machine_id);
+ assert(ifname);
+ assert(ret);
+ assert(sz);
+
+ machine_id_length = strlen(machine_id);
+ ifname_length = strlen(ifname);
+
+ if (port_description)
+ port_description_length = strlen(port_description);
+
+ if (hostname)
+ hostname_length = strlen(hostname);
+
+ if (pretty_hostname)
+ pretty_hostname_length = strlen(pretty_hostname);
+
+ l = sizeof(struct ether_header) +
+ /* Chassis ID */
+ 2 + 1 + machine_id_length +
+ /* Port ID */
+ 2 + 1 + ifname_length +
+ /* TTL */
+ 2 + 2 +
+ /* System Capabilities */
+ 2 + 4 +
+ /* End */
+ 2;
+
+ /* Port Description */
+ if (port_description)
+ l += 2 + port_description_length;
+
+ /* System Name */
+ if (hostname)
+ l += 2 + hostname_length;
+
+ /* System Description */
+ if (pretty_hostname)
+ l += 2 + pretty_hostname_length;
+
+ packet = malloc(l);
+ if (!packet)
+ return -ENOMEM;
+
+ h = (struct ether_header*) packet;
+ h->ether_type = htobe16(ETHERTYPE_LLDP);
+ memcpy(h->ether_dhost, lldp_multicast_addr + mode, ETH_ALEN);
+ memcpy(h->ether_shost, hwaddr, ETH_ALEN);
+
+ p = (uint8_t*) packet + sizeof(struct ether_header);
+
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_CHASSIS_ID, 1 + machine_id_length);
+ if (r < 0)
+ return r;
+ *(p++) = SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED;
+ p = mempcpy(p, machine_id, machine_id_length);
+
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_ID, 1 + ifname_length);
+ if (r < 0)
+ return r;
+ *(p++) = SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME;
+ p = mempcpy(p, ifname, ifname_length);
+
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_TTL, 2);
+ if (r < 0)
+ return r;
+ unaligned_write_be16(p, ttl);
+ p += 2;
+
+ if (port_description) {
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_DESCRIPTION, port_description_length);
+ if (r < 0)
+ return r;
+ p = mempcpy(p, port_description, port_description_length);
+ }
+
+ if (hostname) {
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_NAME, hostname_length);
+ if (r < 0)
+ return r;
+ p = mempcpy(p, hostname, hostname_length);
+ }
+
+ if (pretty_hostname) {
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_DESCRIPTION, pretty_hostname_length);
+ if (r < 0)
+ return r;
+ p = mempcpy(p, pretty_hostname, pretty_hostname_length);
+ }
+
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4);
+ if (r < 0)
+ return r;
+ unaligned_write_be16(p, system_capabilities);
+ p += 2;
+ unaligned_write_be16(p, enabled_capabilities);
+ p += 2;
+
+ r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_END, 0);
+ if (r < 0)
+ return r;
+
+ assert(p == (uint8_t*) packet + l);
+
+ *ret = packet;
+ *sz = l;
+
+ packet = NULL;
+ return 0;
+}
+
+static int lldp_send_packet(
+ int ifindex,
+ const struct ether_addr *address,
+ const void *packet,
+ size_t packet_size) {
+
+ union sockaddr_union sa = {
+ .ll.sll_family = AF_PACKET,
+ .ll.sll_protocol = htobe16(ETHERTYPE_LLDP),
+ .ll.sll_ifindex = ifindex,
+ .ll.sll_halen = ETH_ALEN,
+ };
+
+ _cleanup_close_ int fd = -1;
+ ssize_t l;
+
+ assert(ifindex > 0);
+ assert(address);
+ assert(packet || packet_size <= 0);
+
+ memcpy(sa.ll.sll_addr, address, ETH_ALEN);
+
+ fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC, IPPROTO_RAW);
+ if (fd < 0)
+ return -errno;
+
+ l = sendto(fd, packet, packet_size, MSG_NOSIGNAL, &sa.sa, sizeof(sa.ll));
+ if (l < 0)
+ return -errno;
+
+ if ((size_t) l != packet_size)
+ return -EIO;
+
+ return 0;
+}
+
+static int link_send_lldp(Link *link) {
+ char machine_id_string[SD_ID128_STRING_MAX];
+ _cleanup_free_ char *hostname = NULL, *pretty_hostname = NULL;
+ _cleanup_free_ void *packet = NULL;
+ size_t packet_size = 0;
+ sd_id128_t machine_id;
+ uint16_t caps;
+ usec_t ttl;
+ int r;
+
+ assert(link);
+
+ if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO)
+ return 0;
+
+ assert(link->network->lldp_emit < _LLDP_EMIT_MAX);
+
+ r = sd_id128_get_machine(&machine_id);
+ if (r < 0)
+ return r;
+
+ (void) gethostname_strict(&hostname);
+ (void) parse_env_file("/etc/machine-info", NEWLINE, "PRETTY_HOSTNAME", &pretty_hostname, NULL);
+
+ assert_cc(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1 <= (UINT16_MAX - 1) * USEC_PER_SEC);
+ ttl = DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1, USEC_PER_SEC);
+
+ caps = (link->network && link->network->ip_forward != ADDRESS_FAMILY_NO) ?
+ SD_LLDP_SYSTEM_CAPABILITIES_ROUTER :
+ SD_LLDP_SYSTEM_CAPABILITIES_STATION;
+
+ r = lldp_make_packet(link->network->lldp_emit,
+ &link->mac,
+ sd_id128_to_string(machine_id, machine_id_string),
+ link->ifname,
+ (uint16_t) ttl,
+ link->network ? link->network->description : NULL,
+ hostname,
+ pretty_hostname,
+ SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
+ caps,
+ &packet, &packet_size);
+ if (r < 0)
+ return r;
+
+ return lldp_send_packet(link->ifindex, lldp_multicast_addr + link->network->lldp_emit, packet, packet_size);
+}
+
+static int on_lldp_timer(sd_event_source *s, usec_t t, void *userdata) {
+ Link *link = userdata;
+ usec_t current, delay, next;
+ int r;
+
+ assert(s);
+ assert(userdata);
+
+ log_link_debug(link, "Sending LLDP packet...");
+
+ r = link_send_lldp(link);
+ if (r < 0)
+ log_link_debug_errno(link, r, "Failed to send LLDP packet, ignoring: %m");
+
+ if (link->lldp_tx_fast > 0)
+ link->lldp_tx_fast--;
+
+ assert_se(sd_event_now(sd_event_source_get_event(s), clock_boottime_or_monotonic(), &current) >= 0);
+
+ delay = link->lldp_tx_fast > 0 ? LLDP_FAST_TX_USEC : LLDP_TX_INTERVAL_USEC;
+ next = usec_add(usec_add(current, delay), (usec_t) random_u64() % LLDP_JITTER_USEC);
+
+ r = sd_event_source_set_time(s, next);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to restart LLDP timer: %m");
+
+ r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to enable LLDP timer: %m");
+
+ return 0;
+}
+
+int link_lldp_emit_start(Link *link) {
+ usec_t next;
+ int r;
+
+ assert(link);
+
+ if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO) {
+ link_lldp_emit_stop(link);
+ return 0;
+ }
+
+ /* Starts the LLDP transmission in "fast" mode. If it is already started, turns "fast" mode back on again. */
+
+ link->lldp_tx_fast = LLDP_TX_FAST_INIT;
+
+ next = usec_add(usec_add(now(clock_boottime_or_monotonic()), LLDP_FAST_TX_USEC),
+ (usec_t) random_u64() % LLDP_JITTER_USEC);
+
+ if (link->lldp_emit_event_source) {
+ usec_t old;
+
+ /* Lower the timeout, maybe */
+ r = sd_event_source_get_time(link->lldp_emit_event_source, &old);
+ if (r < 0)
+ return r;
+
+ if (old <= next)
+ return 0;
+
+ return sd_event_source_set_time(link->lldp_emit_event_source, next);
+ } else {
+ r = sd_event_add_time(
+ link->manager->event,
+ &link->lldp_emit_event_source,
+ clock_boottime_or_monotonic(),
+ next,
+ 0,
+ on_lldp_timer,
+ link);
+ if (r < 0)
+ return r;
+
+ (void) sd_event_source_set_description(link->lldp_emit_event_source, "lldp-tx");
+ }
+
+ return 0;
+}
+
+void link_lldp_emit_stop(Link *link) {
+ assert(link);
+
+ link->lldp_emit_event_source = sd_event_source_unref(link->lldp_emit_event_source);
+}
+
+int config_parse_lldp_emit(
+ 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) {
+
+ LLDPEmit *emit = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ if (isempty(rvalue))
+ *emit = LLDP_EMIT_NO;
+ else if (streq(rvalue, "nearest-bridge"))
+ *emit = LLDP_EMIT_NEAREST_BRIDGE;
+ else if (streq(rvalue, "non-tpmr-bridge"))
+ *emit = LLDP_EMIT_NON_TPMR_BRIDGE;
+ else if (streq(rvalue, "customer-bridge"))
+ *emit = LLDP_EMIT_CUSTOMER_BRIDGE;
+ else {
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse LLDP emission setting, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ *emit = r ? LLDP_EMIT_NEAREST_BRIDGE : LLDP_EMIT_NO;
+ }
+
+ return 0;
+}
diff --git a/src/systemd-bootchart/svg.h b/src/network/networkd-lldp-tx.h
index 6e06b5ad97..4680c9d950 100644
--- a/src/systemd-bootchart/svg.h
+++ b/src/network/networkd-lldp-tx.h
@@ -3,10 +3,7 @@
/***
This file is part of systemd.
- Copyright (C) 2009-2013 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.com>
+ Copyright 2016 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -22,14 +19,17 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-int svg_do(FILE *of,
- const char *build,
- struct list_sample_data *head,
- struct ps_struct *ps_first,
- int n_samples,
- int pscount,
- int n_cpus,
- double graph_start,
- double log_start,
- double interval,
- int overrun);
+#include "networkd-link.h"
+
+typedef enum LLDPEmit {
+ LLDP_EMIT_NO,
+ LLDP_EMIT_NEAREST_BRIDGE,
+ LLDP_EMIT_NON_TPMR_BRIDGE,
+ LLDP_EMIT_CUSTOMER_BRIDGE,
+ _LLDP_EMIT_MAX,
+} LLDPEmit;
+
+int link_lldp_emit_start(Link *link);
+void link_lldp_emit_stop(Link *link);
+
+int config_parse_lldp_emit(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-manager.c b/src/network/networkd-manager.c
index c73d313c85..7af7abaa81 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -457,11 +457,9 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo
break;
case RTM_DELROUTE:
-
- if (route)
- route_drop(route);
-
+ route_free(route);
break;
+
default:
assert_not_reached("Received invalid RTNL message type");
}
@@ -1037,6 +1035,8 @@ int manager_new(Manager **ret) {
if (r < 0)
return r;
+ m->duid.type = DUID_TYPE_EN;
+
*ret = m;
m = NULL;
@@ -1091,22 +1091,19 @@ static bool manager_check_idle(void *userdata) {
assert(m);
+ /* Check whether we are idle now. The only case when we decide to be idle is when there's only a loopback
+ * device around, for which we have no configuration, and which already left the PENDING state. In all other
+ * cases we are not idle. */
+
HASHMAP_FOREACH(link, m->links, i) {
- /* we are not woken on udev activity, so let's just wait for the
- * pending udev event */
+ /* We are not woken on udev activity, so let's just wait for the pending udev event */
if (link->state == LINK_STATE_PENDING)
return false;
- if (!link->network)
- continue;
+ if ((link->flags & IFF_LOOPBACK) == 0)
+ return false;
- /* we are not woken on netork activity, so let's stay around */
- if (link_lldp_enabled(link) ||
- link_ipv4ll_enabled(link) ||
- link_dhcp4_server_enabled(link) ||
- link_dhcp4_enabled(link) ||
- link_dhcp6_enabled(link) ||
- link_ipv6_accept_ra_enabled(link))
+ if (link->network)
return false;
}
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index ae647b0293..f3a4fc0fa5 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -19,11 +19,12 @@
#include <netinet/ether.h>
#include <netinet/icmp6.h>
+#include <netinet/in.h>
#include <linux/if.h>
#include <systemd/sd-ndisc.h>
-#include "networkd-link.h"
+#include "networkd.h"
static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
@@ -32,7 +33,7 @@ static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *
assert(link);
assert(link->ndisc_messages > 0);
- link->ndisc_messages --;
+ link->ndisc_messages--;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@@ -76,15 +77,15 @@ static void ndisc_prefix_autonomous_handler(sd_ndisc *nd, const struct in6_addr
memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8);
else {
/* see RFC4291 section 2.5.1 */
- address->in_addr.in6.__in6_u.__u6_addr8[8] = link->mac.ether_addr_octet[0];
- address->in_addr.in6.__in6_u.__u6_addr8[8] ^= 1 << 1;
- address->in_addr.in6.__in6_u.__u6_addr8[9] = link->mac.ether_addr_octet[1];
- address->in_addr.in6.__in6_u.__u6_addr8[10] = link->mac.ether_addr_octet[2];
- address->in_addr.in6.__in6_u.__u6_addr8[11] = 0xff;
- address->in_addr.in6.__in6_u.__u6_addr8[12] = 0xfe;
- address->in_addr.in6.__in6_u.__u6_addr8[13] = link->mac.ether_addr_octet[3];
- address->in_addr.in6.__in6_u.__u6_addr8[14] = link->mac.ether_addr_octet[4];
- address->in_addr.in6.__in6_u.__u6_addr8[15] = link->mac.ether_addr_octet[5];
+ address->in_addr.in6.s6_addr[8] = link->mac.ether_addr_octet[0];
+ address->in_addr.in6.s6_addr[8] ^= 1 << 1;
+ address->in_addr.in6.s6_addr[9] = link->mac.ether_addr_octet[1];
+ address->in_addr.in6.s6_addr[10] = link->mac.ether_addr_octet[2];
+ address->in_addr.in6.s6_addr[11] = 0xff;
+ address->in_addr.in6.s6_addr[12] = 0xfe;
+ address->in_addr.in6.s6_addr[13] = link->mac.ether_addr_octet[3];
+ address->in_addr.in6.s6_addr[14] = link->mac.ether_addr_octet[4];
+ address->in_addr.in6.s6_addr[15] = link->mac.ether_addr_octet[5];
}
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
@@ -98,7 +99,7 @@ static void ndisc_prefix_autonomous_handler(sd_ndisc *nd, const struct in6_addr
return;
}
- link->ndisc_messages ++;
+ link->ndisc_messages++;
}
static void ndisc_prefix_onlink_handler(sd_ndisc *nd, const struct in6_addr *prefix, unsigned prefixlen, unsigned lifetime, void *userdata) {
@@ -136,7 +137,7 @@ static void ndisc_prefix_onlink_handler(sd_ndisc *nd, const struct in6_addr *pre
return;
}
- link->ndisc_messages ++;
+ link->ndisc_messages++;
}
static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata) {
@@ -156,6 +157,10 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
if (flags & ND_RA_FLAG_MANAGED)
dhcp6_request_address(link);
+ r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
+ if (r < 0 && r != -EBUSY)
+ log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
+
r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0 && r != -EBUSY)
log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m");
@@ -186,7 +191,7 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
return;
}
- link->ndisc_messages ++;
+ link->ndisc_messages++;
}
static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
@@ -202,6 +207,10 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
case SD_NDISC_EVENT_TIMEOUT:
dhcp6_request_address(link);
+ r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
+ if (r < 0 && r != -EBUSY)
+ log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
+
r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0 && r != -EBUSY)
log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m");
diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c
index e04e78f870..7005b165d9 100644
--- a/src/network/networkd-netdev-bond.c
+++ b/src/network/networkd-netdev-bond.c
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "conf-parser.h"
+#include "extract-word.h"
#include "missing.h"
#include "networkd-netdev-bond.h"
#include "string-table.h"
@@ -375,7 +376,7 @@ int config_parse_arp_ip_target_address(const char *unit,
}
LIST_PREPEND(arp_ip_target, b->arp_ip_targets, buffer);
- b->n_arp_ip_targets ++;
+ b->n_arp_ip_targets++;
buffer = NULL;
}
diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h
index cb6baea24f..b941edb344 100644
--- a/src/network/networkd-netdev-bond.h
+++ b/src/network/networkd-netdev-bond.h
@@ -20,8 +20,7 @@
***/
#include "in-addr-util.h"
-
-typedef struct Bond Bond;
+#include "list.h"
#include "networkd-netdev.h"
@@ -106,7 +105,7 @@ typedef struct ArpIpTarget {
LIST_FIELDS(struct ArpIpTarget, arp_ip_target);
} ArpIpTarget;
-struct Bond {
+typedef struct Bond {
NetDev meta;
BondMode mode;
@@ -133,8 +132,9 @@ struct Bond {
int n_arp_ip_targets;
ArpIpTarget *arp_ip_targets;
-};
+} Bond;
+DEFINE_NETDEV_CAST(BOND, Bond);
extern const NetDevVTable bond_vtable;
const char *bond_mode_to_string(BondMode d) _const_;
diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c
index cdcd08f057..4cfd00413f 100644
--- a/src/network/networkd-netdev-bridge.c
+++ b/src/network/networkd-netdev-bridge.c
@@ -22,6 +22,7 @@
#include "missing.h"
#include "netlink-util.h"
+#include "networkd.h"
#include "networkd-netdev-bridge.h"
/* callback for brige netdev's parameter set */
@@ -89,6 +90,18 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m");
}
+ if (b->mcast_querier >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_QUERIER, b->mcast_querier);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MCAST_QUERIER attribute: %m");
+ }
+
+ if (b->mcast_snooping >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_SNOOPING, b->mcast_snooping);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MCAST_SNOOPING attribute: %m");
+ }
+
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
@@ -106,8 +119,20 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
return r;
}
+static void bridge_init(NetDev *n) {
+ Bridge *b;
+
+ b = BRIDGE(n);
+
+ assert(b);
+
+ b->mcast_querier = -1;
+ b->mcast_snooping = -1;
+}
+
const NetDevVTable bridge_vtable = {
.object_size = sizeof(Bridge),
+ .init = bridge_init,
.sections = "Match\0NetDev\0Bridge\0",
.post_create = netdev_bridge_post_create,
.create_type = NETDEV_CREATE_MASTER,
diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h
index b2bf7e15f1..f2ae21fc50 100644
--- a/src/network/networkd-netdev-bridge.h
+++ b/src/network/networkd-netdev-bridge.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,18 +19,18 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-typedef struct Bridge Bridge;
-
#include "networkd-netdev.h"
-struct Bridge {
+typedef struct Bridge {
NetDev meta;
+ int mcast_querier;
+ int mcast_snooping;
+
usec_t forward_delay;
usec_t hello_time;
usec_t max_age;
-};
+} Bridge;
+DEFINE_NETDEV_CAST(BRIDGE, Bridge);
extern const NetDevVTable bridge_vtable;
diff --git a/src/network/networkd-netdev-dummy.h b/src/network/networkd-netdev-dummy.h
index 29f75a149b..efe302267e 100644
--- a/src/network/networkd-netdev-dummy.h
+++ b/src/network/networkd-netdev-dummy.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,14 +19,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-typedef struct Dummy Dummy;
-
#include "networkd-netdev.h"
-struct Dummy {
+typedef struct Dummy {
NetDev meta;
-};
+} Dummy;
+DEFINE_NETDEV_CAST(DUMMY, Dummy);
extern const NetDevVTable dummy_vtable;
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index 8f506af092..ba04bb0165 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -1,11 +1,17 @@
%{
#include <stddef.h>
#include "conf-parser.h"
-#include "networkd-netdev.h"
-#include "networkd-netdev-tunnel.h"
+#include "network-internal.h"
#include "networkd-netdev-bond.h"
+#include "networkd-netdev-ipvlan.h"
#include "networkd-netdev-macvlan.h"
-#include "network-internal.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-tuntap.h"
+#include "networkd-netdev-veth.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-vxlan.h"
+#include "networkd-netdev-bridge.h"
+#include "networkd-netdev.h"
%}
struct ConfigPerfItem;
%null_strings
@@ -92,3 +98,5 @@ Bond.LearnPacketIntervalSec, config_parse_sec, 0,
Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
+Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)
+Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping)
diff --git a/src/network/networkd-netdev-ipvlan.h b/src/network/networkd-netdev-ipvlan.h
index 5b85ef2150..10d4079844 100644
--- a/src/network/networkd-netdev-ipvlan.h
+++ b/src/network/networkd-netdev-ipvlan.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,10 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-typedef struct IPVlan IPVlan;
-
#include "missing.h"
#include "networkd-netdev.h"
@@ -31,12 +29,13 @@ typedef enum IPVlanMode {
_NETDEV_IPVLAN_MODE_INVALID = -1
} IPVlanMode;
-struct IPVlan {
+typedef struct IPVlan {
NetDev meta;
IPVlanMode mode;
-};
+} IPVlan;
+DEFINE_NETDEV_CAST(IPVLAN, IPVlan);
extern const NetDevVTable ipvlan_vtable;
const char *ipvlan_mode_to_string(IPVlanMode d) _const_;
diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/networkd-netdev-macvlan.h
index 8b42684de6..3663f4f051 100644
--- a/src/network/networkd-netdev-macvlan.h
+++ b/src/network/networkd-netdev-macvlan.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
typedef struct MacVlan MacVlan;
#include "networkd-netdev.h"
@@ -38,6 +38,8 @@ struct MacVlan {
MacVlanMode mode;
};
+DEFINE_NETDEV_CAST(MACVLAN, MacVlan);
+DEFINE_NETDEV_CAST(MACVTAP, MacVlan);
extern const NetDevVTable macvlan_vtable;
extern const NetDevVTable macvtap_vtable;
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c
index 408ceaf55e..26a9a972f1 100644
--- a/src/network/networkd-netdev-tunnel.c
+++ b/src/network/networkd-netdev-tunnel.c
@@ -54,7 +54,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_netlin
assert(link);
assert(m);
assert(t);
- assert(t->family == AF_INET || t->family != -1);
+ assert(IN_SET(t->family, AF_INET, AF_UNSPEC));
r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0)
@@ -87,7 +87,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink
assert(link);
assert(m);
assert(t);
- assert(t->family == AF_INET || t->family != -1);
+ assert(IN_SET(t->family, AF_INET, AF_UNSPEC));
r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0)
@@ -124,7 +124,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink
t = GRETAP(netdev);
assert(t);
- assert(t->family == AF_INET || t->family != -1);
+ assert(IN_SET(t->family, AF_INET, AF_UNSPEC));
assert(link);
assert(m);
@@ -497,7 +497,7 @@ static void ipip_init(NetDev *n) {
assert(t);
t->pmtudisc = true;
- t->family = -1;
+ t->family = AF_UNSPEC;
}
static void sit_init(NetDev *n) {
@@ -507,7 +507,7 @@ static void sit_init(NetDev *n) {
assert(t);
t->pmtudisc = true;
- t->family = -1;
+ t->family = AF_UNSPEC;
}
static void vti_init(NetDev *n) {
@@ -538,7 +538,7 @@ static void gre_init(NetDev *n) {
assert(t);
t->pmtudisc = true;
- t->family = -1;
+ t->family = AF_UNSPEC;
}
static void ip6gre_init(NetDev *n) {
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h
index ea1d9a79e7..7d31e7b687 100644
--- a/src/network/networkd-netdev-tunnel.h
+++ b/src/network/networkd-netdev-tunnel.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,9 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
-typedef struct Tunnel Tunnel;
+#include "in-addr-util.h"
#include "networkd-netdev.h"
@@ -37,7 +37,7 @@ typedef enum IPv6FlowLabel {
_NETDEV_IPV6_FLOWLABEL_INVALID = -1,
} IPv6FlowLabel;
-struct Tunnel {
+typedef struct Tunnel {
NetDev meta;
uint8_t encap_limit;
@@ -56,8 +56,17 @@ struct Tunnel {
bool pmtudisc;
bool copy_dscp;
-};
-
+} Tunnel;
+
+DEFINE_NETDEV_CAST(IPIP, Tunnel);
+DEFINE_NETDEV_CAST(GRE, Tunnel);
+DEFINE_NETDEV_CAST(GRETAP, Tunnel);
+DEFINE_NETDEV_CAST(IP6GRE, Tunnel);
+DEFINE_NETDEV_CAST(IP6GRETAP, Tunnel);
+DEFINE_NETDEV_CAST(SIT, Tunnel);
+DEFINE_NETDEV_CAST(VTI, Tunnel);
+DEFINE_NETDEV_CAST(VTI6, Tunnel);
+DEFINE_NETDEV_CAST(IP6TNL, Tunnel);
extern const NetDevVTable ipip_vtable;
extern const NetDevVTable sit_vtable;
extern const NetDevVTable vti_vtable;
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
index ab9a1b0426..088a4d8d32 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/networkd-netdev-tuntap.c
@@ -17,9 +17,13 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <fcntl.h>
+#include <linux/if_tun.h>
#include <net/if.h>
+#include <netinet/if_ether.h>
#include <sys/ioctl.h>
-#include <linux/if_tun.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include "alloc-util.h"
#include "fd-util.h"
@@ -87,7 +91,7 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
assert(t);
- if(t->user_name) {
+ if (t->user_name) {
user = t->user_name;
@@ -126,7 +130,7 @@ static int netdev_create_tuntap(NetDev *netdev) {
int r;
r = netdev_fill_tuntap_message(netdev, &ifr);
- if(r < 0)
+ if (r < 0)
return r;
return netdev_tuntap_add(netdev, &ifr);
diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/networkd-netdev-tuntap.h
index b970b0ce3b..120f00a353 100644
--- a/src/network/networkd-netdev-tuntap.h
+++ b/src/network/networkd-netdev-tuntap.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
typedef struct TunTap TunTap;
#include "networkd-netdev.h"
@@ -34,5 +34,7 @@ struct TunTap {
bool vnet_hdr;
};
+DEFINE_NETDEV_CAST(TUN, TunTap);
+DEFINE_NETDEV_CAST(TAP, TunTap);
extern const NetDevVTable tun_vtable;
extern const NetDevVTable tap_vtable;
diff --git a/src/network/networkd-netdev-veth.h b/src/network/networkd-netdev-veth.h
index f7fdf906ab..e69bfbc8f0 100644
--- a/src/network/networkd-netdev-veth.h
+++ b/src/network/networkd-netdev-veth.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
typedef struct Veth Veth;
#include "networkd-netdev.h"
@@ -30,4 +30,5 @@ struct Veth {
struct ether_addr *mac_peer;
};
+DEFINE_NETDEV_CAST(VETH, Veth);
extern const NetDevVTable veth_vtable;
diff --git a/src/network/networkd-netdev-vlan.h b/src/network/networkd-netdev-vlan.h
index 8701c4b785..73aacf4a0f 100644
--- a/src/network/networkd-netdev-vlan.h
+++ b/src/network/networkd-netdev-vlan.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
typedef struct VLan VLan;
#include "networkd-netdev.h"
@@ -31,4 +31,5 @@ struct VLan {
uint64_t id;
};
+DEFINE_NETDEV_CAST(VLAN, VLan);
extern const NetDevVTable vlan_vtable;
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c
index 223d60f4db..363a6bdde6 100644
--- a/src/network/networkd-netdev-vxlan.c
+++ b/src/network/networkd-netdev-vxlan.c
@@ -23,8 +23,10 @@
#include "conf-parser.h"
#include "alloc-util.h"
+#include "extract-word.h"
#include "parse-util.h"
#include "missing.h"
+
#include "networkd-link.h"
#include "networkd-netdev-vxlan.h"
@@ -54,13 +56,13 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LINK attribute: %m");
- if(v->ttl) {
+ if (v->ttl) {
r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TTL attribute: %m");
}
- if(v->tos) {
+ if (v->tos) {
r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TOS attribute: %m");
@@ -86,7 +88,7 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L3MISS attribute: %m");
- if(v->fdb_ageing) {
+ if (v->fdb_ageing) {
r = sd_netlink_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_AGEING attribute: %m");
diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h
index 459ce53f5e..4614c66fd1 100644
--- a/src/network/networkd-netdev-vxlan.h
+++ b/src/network/networkd-netdev-vxlan.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
typedef struct VxLan VxLan;
#include "in-addr-util.h"
@@ -55,6 +55,7 @@ struct VxLan {
struct ifla_vxlan_port_range port_range;
};
+DEFINE_NETDEV_CAST(VXLAN, VxLan);
extern const NetDevVTable vxlan_vtable;
int config_parse_vxlan_group_address(const char *unit,
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index d7d014f05d..851a36290c 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -656,7 +656,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
if (!netdev->filename)
return log_oom();
- if (!netdev->mac) {
+ if (!netdev->mac && netdev->kind != NETDEV_KIND_VLAN) {
r = netdev_get_mac(netdev->ifname, &netdev->mac);
if (r < 0)
return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname);
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 3eacee824b..ab3f068167 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,17 +19,13 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
+#include <systemd/sd-netlink.h>
#include "list.h"
-
-typedef struct NetDev NetDev;
-typedef struct NetDevVTable NetDevVTable;
-
-#include "networkd-link.h"
-#include "networkd.h"
+#include "time-util.h"
typedef struct netdev_join_callback netdev_join_callback;
+typedef struct Link Link;
struct netdev_join_callback {
sd_netlink_message_handler_t callback;
@@ -78,7 +76,10 @@ typedef enum NetDevCreateType {
_NETDEV_CREATE_INVALID = -1,
} NetDevCreateType;
-struct NetDev {
+typedef struct Manager Manager;
+typedef struct Condition Condition;
+
+typedef struct NetDev {
Manager *manager;
int n_ref;
@@ -99,20 +100,9 @@ struct NetDev {
int ifindex;
LIST_HEAD(netdev_join_callback, callbacks);
-};
+} NetDev;
-#include "networkd-netdev-bond.h"
-#include "networkd-netdev-bridge.h"
-#include "networkd-netdev-dummy.h"
-#include "networkd-netdev-ipvlan.h"
-#include "networkd-netdev-macvlan.h"
-#include "networkd-netdev-tunnel.h"
-#include "networkd-netdev-tuntap.h"
-#include "networkd-netdev-veth.h"
-#include "networkd-netdev-vlan.h"
-#include "networkd-netdev-vxlan.h"
-
-struct NetDevVTable {
+typedef struct NetDevVTable {
/* How much memory does an object of this unit type need */
size_t object_size;
@@ -144,14 +134,14 @@ struct NetDevVTable {
/* verify that compulsory configuration options were specified */
int (*config_verify)(NetDev *netdev, const char *filename);
-};
+} NetDevVTable;
extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
/* For casting a netdev into the various netdev kinds */
-#define DEFINE_CAST(UPPERCASE, MixedCase) \
+#define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \
static inline MixedCase* UPPERCASE(NetDev *n) { \
if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE)) \
return NULL; \
@@ -162,27 +152,6 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
/* For casting the various netdev kinds into a netdev */
#define NETDEV(n) (&(n)->meta)
-DEFINE_CAST(BRIDGE, Bridge);
-DEFINE_CAST(BOND, Bond);
-DEFINE_CAST(VLAN, VLan);
-DEFINE_CAST(MACVLAN, MacVlan);
-DEFINE_CAST(MACVTAP, MacVlan);
-DEFINE_CAST(IPVLAN, IPVlan);
-DEFINE_CAST(VXLAN, VxLan);
-DEFINE_CAST(IPIP, Tunnel);
-DEFINE_CAST(GRE, Tunnel);
-DEFINE_CAST(GRETAP, Tunnel);
-DEFINE_CAST(IP6GRE, Tunnel);
-DEFINE_CAST(IP6GRETAP, Tunnel);
-DEFINE_CAST(SIT, Tunnel);
-DEFINE_CAST(VTI, Tunnel);
-DEFINE_CAST(VTI6, Tunnel);
-DEFINE_CAST(IP6TNL, Tunnel);
-DEFINE_CAST(VETH, Veth);
-DEFINE_CAST(DUMMY, Dummy);
-DEFINE_CAST(TUN, TunTap);
-DEFINE_CAST(TAP, TunTap);
-
int netdev_load(Manager *manager);
void netdev_drop(NetDev *netdev);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 409df1709f..03e4e3b39f 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -2,6 +2,7 @@
#include <stddef.h>
#include "conf-parser.h"
#include "networkd.h"
+#include "networkd-conf.h"
#include "network-internal.h"
%}
struct ConfigPerfItem;
@@ -40,7 +41,8 @@ Network.DHCPServer, config_parse_bool,
Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local)
Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route)
Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token)
-Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp)
+Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode)
+Network.EmitLLDP, config_parse_lldp_emit, 0, offsetof(Network, lldp_emit)
Network.Address, config_parse_address, 0, 0
Network.Gateway, config_parse_gateway, 0, 0
Network.Domains, config_parse_domains, 0, 0
@@ -56,17 +58,20 @@ Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions,
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.ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier)
Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0
Address.Broadcast, config_parse_broadcast, 0, 0
Address.Label, config_parse_label, 0, 0
+Address.PreferredLifetime, config_parse_lifetime, 0, 0
Route.Gateway, config_parse_gateway, 0, 0
Route.Destination, config_parse_destination, 0, 0
Route.Source, config_parse_destination, 0, 0
Route.Metric, config_parse_route_priority, 0, 0
Route.Scope, config_parse_route_scope, 0, 0
Route.PreferredSource, config_parse_preferred_src, 0, 0
+Route.Table, config_parse_route_table, 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)
@@ -79,14 +84,18 @@ DHCP.Hostname, config_parse_hostname,
DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
+DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid.type)
+DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric)
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
+DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid)
DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec)
DHCPServer.DefaultLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_default_lease_time_usec)
DHCPServer.EmitDNS, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_dns)
DHCPServer.DNS, config_parse_dhcp_server_dns, 0, 0
DHCPServer.EmitNTP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_ntp)
DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0
+DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router)
DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 4315790093..dd89b3770c 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -113,12 +113,15 @@ static int network_load_one(Manager *manager, const char *filename) {
network->dhcp_server_emit_dns = true;
network->dhcp_server_emit_ntp = true;
+ network->dhcp_server_emit_router = true;
network->dhcp_server_emit_timezone = true;
network->use_bpdu = true;
network->allow_port_to_be_root = true;
network->unicast_flood = true;
+ network->lldp_mode = LLDP_MODE_ROUTERS_ONLY;
+
network->llmnr = RESOLVE_SUPPORT_YES;
network->mdns = RESOLVE_SUPPORT_NO;
network->dnssec_mode = _DNSSEC_MODE_INVALID;
@@ -129,6 +132,8 @@ 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->duid.type = _DUID_TYPE_INVALID;
+ network->proxy_arp = -1;
r = config_parse(NULL, filename, file,
"Match\0"
@@ -394,6 +399,19 @@ int network_apply(Manager *manager, Network *network, Link *link) {
return 0;
}
+bool network_has_static_ipv6_addresses(Network *network) {
+ Address *address;
+
+ assert(network);
+
+ LIST_FOREACH(addresses, address, network->static_addresses) {
+ if (address->family == AF_INET6)
+ return true;
+ }
+
+ return false;
+}
+
int config_parse_netdev(const char *unit,
const char *filename,
unsigned line,
@@ -627,10 +645,7 @@ int config_parse_ipv4ll(
* config_parse_address_family_boolean(), except that it
* applies only to IPv4 */
- if (parse_boolean(rvalue))
- *link_local |= ADDRESS_FAMILY_IPV4;
- else
- *link_local &= ~ADDRESS_FAMILY_IPV4;
+ SET_FLAG(*link_local, ADDRESS_FAMILY_IPV4, parse_boolean(rvalue));
return 0;
}
@@ -994,6 +1009,10 @@ int config_parse_dnssec_negative_trust_anchors(
continue;
}
+ r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
+ if (r < 0)
+ return log_oom();
+
r = set_put(n->dnssec_negative_trust_anchors, w);
if (r < 0)
return log_oom();
@@ -1013,3 +1032,13 @@ static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains, DHCPUseDomains, DHCP_USE_DOMAINS_YES);
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode, lldp_mode, LLDPMode, "Failed to parse LLDP= setting.");
+
+static const char* const lldp_mode_table[_LLDP_MODE_MAX] = {
+ [LLDP_MODE_NO] = "no",
+ [LLDP_MODE_YES] = "yes",
+ [LLDP_MODE_ROUTERS_ONLY] = "routers-only",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode, LLDPMode, LLDP_MODE_YES);
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 03c3f206c3..177bc11ec4 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -19,17 +19,20 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <systemd/sd-bus.h>
+#include "udev.h"
+
#include "condition.h"
+#include "dhcp-identifier.h"
+#include "hashmap.h"
#include "resolve-util.h"
-typedef struct Network Network;
-
#include "networkd-address.h"
#include "networkd-fdb.h"
+#include "networkd-lldp-tx.h"
#include "networkd-netdev.h"
#include "networkd-route.h"
#include "networkd-util.h"
-#include "networkd.h"
#define DHCP_ROUTE_METRIC 1024
#define IPV4LL_ROUTE_METRIC 2048
@@ -58,6 +61,24 @@ typedef enum DHCPUseDomains {
_DHCP_USE_DOMAINS_INVALID = -1,
} DHCPUseDomains;
+typedef enum LLDPMode {
+ LLDP_MODE_NO = 0,
+ LLDP_MODE_YES = 1,
+ LLDP_MODE_ROUTERS_ONLY = 2,
+ _LLDP_MODE_MAX,
+ _LLDP_MODE_INVALID = -1,
+} LLDPMode;
+
+typedef struct DUID {
+ /* Value of Type in [DHCP] section */
+ DUIDType type;
+
+ uint8_t raw_data_len;
+ uint8_t raw_data[MAX_DUID_LEN];
+} DUID;
+
+typedef struct Manager Manager;
+
struct Network {
Manager *manager;
@@ -106,6 +127,7 @@ struct Network {
bool dhcp_server_emit_ntp;
struct in_addr *dhcp_server_ntp;
unsigned n_dhcp_server_ntp;
+ bool dhcp_server_emit_router;
bool dhcp_server_emit_timezone;
char *dhcp_server_timezone;
usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec;
@@ -130,14 +152,18 @@ struct Network {
int ipv6_accept_ra;
int ipv6_dad_transmits;
int ipv6_hop_limit;
+ int proxy_arp;
union in_addr_union ipv6_token;
IPv6PrivacyExtensions ipv6_privacy_extensions;
struct ether_addr *mac;
unsigned mtu;
+ uint32_t iaid;
+ DUID duid;
- bool lldp;
+ LLDPMode lldp_mode; /* LLDP reception */
+ LLDPEmit lldp_emit; /* LLDP transmission */
LIST_HEAD(Address, static_addresses);
LIST_HEAD(Route, static_routes);
@@ -168,6 +194,8 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret);
int network_get(Manager *manager, struct udev_device *device, const char *ifname, const struct ether_addr *mac, Network **ret);
int network_apply(Manager *manager, Network *network, Link *link);
+bool network_has_static_ipv6_addresses(Network *network);
+
int config_parse_netdev(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_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_tunnel(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);
@@ -181,6 +209,7 @@ int config_parse_dhcp_server_dns(const char *unit, const char *filename, unsigne
int config_parse_dhcp_server_ntp(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_dnssec_negative_trust_anchors(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_dhcp_use_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_lldp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* Legacy IPv4LL support */
int config_parse_ipv4ll(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);
@@ -197,3 +226,6 @@ IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_;
const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;
+
+const char* lldp_mode_to_string(LLDPMode m) _const_;
+LLDPMode lldp_mode_from_string(const char *s) _pure_;
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index e065a5a5a9..f001de772a 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -52,8 +52,7 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
int r;
if (section) {
- route = hashmap_get(network->routes_by_section,
- UINT_TO_PTR(section));
+ route = hashmap_get(network->routes_by_section, UINT_TO_PTR(section));
if (route) {
*ret = route;
route = NULL;
@@ -67,16 +66,18 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
return r;
route->protocol = RTPROT_STATIC;
- route->network = network;
-
- LIST_PREPEND(routes, network->static_routes, route);
if (section) {
route->section = section;
- hashmap_put(network->routes_by_section,
- UINT_TO_PTR(route->section), route);
+
+ r = hashmap_put(network->routes_by_section, UINT_TO_PTR(route->section), route);
+ if (r < 0)
+ return r;
}
+ route->network = network;
+ LIST_PREPEND(routes, network->static_routes, route);
+
*ret = route;
route = NULL;
@@ -323,12 +324,6 @@ int route_update(Route *route,
return 0;
}
-void route_drop(Route *route) {
- assert(route);
-
- route_free(route);
-}
-
int route_remove(Route *route, Link *link,
sd_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
@@ -374,7 +369,7 @@ int route_remove(Route *route, Link *link,
else if (route->family == AF_INET6)
r = sd_netlink_message_append_in6_addr(req, RTA_SRC, &route->src.in6);
if (r < 0)
- return log_error_errno(r, "Could not append RTA_DST attribute: %m");
+ return log_error_errno(r, "Could not append RTA_SRC attribute: %m");
r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen);
if (r < 0)
@@ -411,15 +406,45 @@ int route_remove(Route *route, Link *link,
return 0;
}
+static int route_expire_callback(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ Link *link = userdata;
+ int r;
+
+ assert(rtnl);
+ assert(m);
+ assert(link);
+ assert(link->ifname);
+ assert(link->link_messages > 0);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
+
+ link->link_messages--;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST)
+ log_link_warning_errno(link, r, "could not remove route: %m");
+
+ if (link->link_messages == 0)
+ log_link_debug(link, "route removed");
+
+ return 1;
+}
+
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
Route *route = userdata;
int r;
assert(route);
- r = route_remove(route, route->link, NULL);
+ r = route_remove(route, route->link, route_expire_callback);
if (r < 0)
log_warning_errno(r, "Could not remove route: %m");
+ else {
+ /* route may not be exist in kernel. If we fail still remove it */
+ route->link->link_messages++;
+ route_free(route);
+ }
return 1;
}
@@ -450,6 +475,10 @@ int route_configure(Route *route, Link *link,
r = sd_netlink_message_append_in6_addr(req, RTA_GATEWAY, &route->gw.in6);
if (r < 0)
return log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m");
+
+ r = sd_rtnl_message_route_set_family(req, route->family);
+ if (r < 0)
+ return log_error_errno(r, "Could not set route family: %m");
}
if (route->dst_prefixlen) {
@@ -493,7 +522,26 @@ int route_configure(Route *route, Link *link,
r = sd_rtnl_message_route_set_flags(req, route->flags);
if (r < 0)
- return log_error_errno(r, "Colud not set flags: %m");
+ return log_error_errno(r, "Could not set flags: %m");
+
+ if (route->table != RT_TABLE_DEFAULT) {
+
+ if (route->table < 256) {
+ r = sd_rtnl_message_route_set_table(req, route->table);
+ if (r < 0)
+ return log_error_errno(r, "Could not set route table: %m");
+ } else {
+
+ r = sd_rtnl_message_route_set_table(req, RT_TABLE_UNSPEC);
+ if (r < 0)
+ return log_error_errno(r, "Could not set route table: %m");
+
+ /* Table attribute to allow more than 256. */
+ r = sd_netlink_message_append_data(req, RTA_TABLE, &route->table, sizeof(route->table));
+ if (r < 0)
+ return log_error_errno(r, "Could not append RTA_TABLE attribute: %m");
+ }
+ }
r = sd_netlink_message_append_u32(req, RTA_PRIORITY, route->priority);
if (r < 0)
@@ -776,3 +824,42 @@ int config_parse_route_scope(const char *unit,
return 0;
}
+
+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) {
+ _cleanup_route_free_ Route *n = NULL;
+ Network *network = userdata;
+ uint32_t k;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = route_new_static(network, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ n->table = k;
+
+ n = NULL;
+
+ return 0;
+}
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index a4a4bf2653..39de8363ed 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -22,7 +22,6 @@
typedef struct Route Route;
#include "networkd-network.h"
-#include "networkd.h"
struct Route {
Network *network;
@@ -37,7 +36,7 @@ struct Route {
unsigned char protocol; /* RTPROT_* */
unsigned char tos;
uint32_t priority; /* note that ip(8) calls this 'metric' */
- unsigned char table;
+ uint32_t table;
unsigned char pref;
unsigned flags;
@@ -62,7 +61,6 @@ int route_get(Link *link, int family, union in_addr_union *dst, unsigned char ds
int route_add(Link *link, int family, 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, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
int route_update(Route *route, union in_addr_union *src, unsigned char src_prefixlen, union in_addr_union *gw, union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol);
-void route_drop(Route *route);
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);
@@ -74,3 +72,4 @@ int config_parse_preferred_src(const char *unit, const char *filename, unsigned
int config_parse_destination(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_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);
diff --git a/src/network/networkd-wait-online.h b/src/network/networkd-wait-online.h
index f1ea4a6494..7ac7f4018a 100644
--- a/src/network/networkd-wait-online.h
+++ b/src/network/networkd-wait-online.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <systemd/sd-event.h>
#include <systemd/sd-netlink.h>
#include <systemd/sd-network.h>
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 6cf396e478..9f5c75ac3d 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -21,6 +21,7 @@
#include "capability-util.h"
#include "networkd.h"
+#include "networkd-conf.h"
#include "signal-util.h"
#include "user-util.h"
@@ -89,6 +90,10 @@ int main(int argc, char *argv[]) {
goto out;
}
+ r = manager_parse_config_file(m);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse configuration file: %m");
+
r = manager_load_config(m);
if (r < 0) {
log_error_errno(r, "Could not load configuration files: %m");
diff --git a/src/network/networkd.h b/src/network/networkd.h
index efe70970c3..b61e03920e 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,25 +19,34 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <arpa/inet.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include <systemd/sd-netlink.h>
+#include "udev.h"
+#include "dhcp-identifier.h"
#include "hashmap.h"
#include "list.h"
-#include "udev.h"
-
-typedef struct Manager Manager;
#include "networkd-address-pool.h"
#include "networkd-link.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-bridge.h"
+#include "networkd-netdev-dummy.h"
+#include "networkd-netdev-ipvlan.h"
+#include "networkd-netdev-macvlan.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-tuntap.h"
+#include "networkd-netdev-veth.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-vxlan.h"
#include "networkd-network.h"
#include "networkd-util.h"
+extern const char* const network_dirs[];
+
struct Manager {
sd_netlink *rtnl;
sd_event *event;
@@ -61,11 +72,16 @@ struct Manager {
LIST_HEAD(AddressPool, address_pools);
usec_t network_dirs_ts_usec;
-};
-extern const char* const network_dirs[];
+ DUID duid;
+};
-/* Manager */
+static inline const DUID* link_duid(const Link *link) {
+ if (link->network->duid.type != _DUID_TYPE_INVALID)
+ return &link->network->duid;
+ else
+ return &link->manager->duid;
+}
extern const sd_bus_vtable manager_vtable[];
diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c
index ecbbe6c3c9..adbe09a5e1 100644
--- a/src/network/test-network-tables.c
+++ b/src/network/test-network-tables.c
@@ -9,7 +9,7 @@
int main(int argc, char **argv) {
test_table(bond_mode, NETDEV_BOND_MODE);
- /* test_table(link_state, LINK_STATE); -- not a reversible mapping */
+ /* test_table(link_state, LINK_STATE); — not a reversible mapping */
test_table(link_operstate, LINK_OPERSTATE);
test_table(address_family_boolean, ADDRESS_FAMILY_BOOLEAN);
test_table(netdev_kind, NETDEV_KIND);
diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c
new file mode 100644
index 0000000000..0e1a18457d
--- /dev/null
+++ b/src/network/test-networkd-conf.c
@@ -0,0 +1,142 @@
+/***
+ 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 "hexdecoct.h"
+#include "log.h"
+#include "macro.h"
+#include "string-util.h"
+#include "ether-addr-util.h"
+
+#include "networkd-conf.h"
+#include "networkd-network.h"
+#include "network-internal.h"
+
+static void test_config_parse_duid_type_one(const char *rvalue, int ret, DUIDType expected) {
+ DUIDType actual = 0;
+ int r;
+
+ r = config_parse_duid_type("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
+ log_info_errno(r, "\"%s\" → %d (%m)", rvalue, actual);
+ assert_se(r == ret);
+ assert_se(expected == actual);
+}
+
+static void test_config_parse_duid_type(void) {
+ test_config_parse_duid_type_one("", 0, 0);
+ test_config_parse_duid_type_one("link-layer-time", 0, DUID_TYPE_LLT);
+ test_config_parse_duid_type_one("vendor", 0, DUID_TYPE_EN);
+ test_config_parse_duid_type_one("link-layer", 0, DUID_TYPE_LL);
+ test_config_parse_duid_type_one("uuid", 0, DUID_TYPE_UUID);
+ test_config_parse_duid_type_one("foo", 0, 0);
+}
+
+static void test_config_parse_duid_rawdata_one(const char *rvalue, int ret, const DUID* expected) {
+ DUID actual = {};
+ int r;
+ _cleanup_free_ char *d = NULL;
+
+ r = config_parse_duid_rawdata("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
+ d = hexmem(actual.raw_data, actual.raw_data_len);
+ log_info_errno(r, "\"%s\" → \"%s\" (%m)",
+ rvalue, strnull(d));
+ assert_se(r == ret);
+ if (expected) {
+ assert_se(actual.raw_data_len == expected->raw_data_len);
+ assert_se(memcmp(actual.raw_data, expected->raw_data, expected->raw_data_len) == 0);
+ }
+}
+
+static void test_config_parse_hwaddr_one(const char *rvalue, int ret, const struct ether_addr* expected) {
+ struct ether_addr *actual = NULL;
+ int r;
+
+ r = config_parse_hwaddr("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
+ assert_se(ret == r);
+ if (expected) {
+ assert_se(actual);
+ assert(ether_addr_equal(expected, actual));
+ } else {
+ assert_se(actual == NULL);
+ }
+ free(actual);
+}
+
+#define BYTES_0_128 "0:1:2:3:4:5:6:7:8:9:a:b:c:d:e:f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27:28:29:2a:2b:2c:2d:2e:2f:30:31:32:33:34:35:36:37:38:39:3a:3b:3c:3d:3e:3f:40:41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54:55:56:57:58:59:5a:5b:5c:5d:5e:5f:60:61:62:63:64:65:66:67:68:69:6a:6b:6c:6d:6e:6f:70:71:72:73:74:75:76:77:78:79:7a:7b:7c:7d:7e:7f:80"
+
+#define BYTES_1_128 {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80}
+
+static void test_config_parse_duid_rawdata(void) {
+ test_config_parse_duid_rawdata_one("", 0, &(DUID){});
+ test_config_parse_duid_rawdata_one("00:11:22:33:44:55:66:77", 0,
+ &(DUID){0, 8, {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}});
+ test_config_parse_duid_rawdata_one("00:11:22:", 0,
+ &(DUID){0, 3, {0x00,0x11,0x22}});
+ test_config_parse_duid_rawdata_one("000:11:22", 0, &(DUID){}); /* error, output is all zeros */
+ test_config_parse_duid_rawdata_one("00:111:22", 0, &(DUID){});
+ test_config_parse_duid_rawdata_one("0:1:2:3:4:5:6:7", 0,
+ &(DUID){0, 8, {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}});
+ test_config_parse_duid_rawdata_one("11::", 0, &(DUID){0, 1, {0x11}}); /* FIXME: should this be an error? */
+ test_config_parse_duid_rawdata_one("abcdef", 0, &(DUID){});
+ test_config_parse_duid_rawdata_one(BYTES_0_128, 0, &(DUID){});
+ test_config_parse_duid_rawdata_one(BYTES_0_128 + 2, 0, &(DUID){0, 128, BYTES_1_128});
+}
+
+static void test_config_parse_hwaddr(void) {
+ const struct ether_addr t[] = {
+ { .ether_addr_octet = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } },
+ { .ether_addr_octet = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab } },
+ };
+ test_config_parse_hwaddr_one("", 0, NULL);
+ test_config_parse_hwaddr_one("no:ta:ma:ca:dd:re", 0, NULL);
+ test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:fx", 0, NULL);
+ test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff", 0, &t[0]);
+ test_config_parse_hwaddr_one(" aa:bb:cc:dd:ee:ff", 0, &t[0]);
+ test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\n", 0, &t[0]);
+ test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\nxxx", 0, NULL);
+ test_config_parse_hwaddr_one("aa:bb:cc: dd:ee:ff", 0, NULL);
+ test_config_parse_hwaddr_one("aa:bb:cc:d d:ee:ff", 0, NULL);
+ test_config_parse_hwaddr_one("aa:bb:cc:dd:ee", 0, NULL);
+ test_config_parse_hwaddr_one("9:aa:bb:cc:dd:ee:ff", 0, NULL);
+ test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff:gg", 0, NULL);
+ test_config_parse_hwaddr_one("aa:Bb:CC:dd:ee:ff", 0, &t[0]);
+ test_config_parse_hwaddr_one("01:23:45:67:89:aB", 0, &t[1]);
+ test_config_parse_hwaddr_one("1:23:45:67:89:aB", 0, &t[1]);
+ test_config_parse_hwaddr_one("aa-bb-cc-dd-ee-ff", 0, &t[0]);
+ test_config_parse_hwaddr_one("AA-BB-CC-DD-EE-FF", 0, &t[0]);
+ test_config_parse_hwaddr_one("01-23-45-67-89-ab", 0, &t[1]);
+ test_config_parse_hwaddr_one("aabb.ccdd.eeff", 0, &t[0]);
+ test_config_parse_hwaddr_one("0123.4567.89ab", 0, &t[1]);
+ test_config_parse_hwaddr_one("123.4567.89ab.", 0, NULL);
+ test_config_parse_hwaddr_one("aabbcc.ddeeff", 0, NULL);
+ test_config_parse_hwaddr_one("aabbccddeeff", 0, NULL);
+ test_config_parse_hwaddr_one("aabbccddee:ff", 0, NULL);
+ test_config_parse_hwaddr_one("012345.6789ab", 0, NULL);
+ test_config_parse_hwaddr_one("123.4567.89ab", 0, &t[1]);
+}
+
+int main(int argc, char **argv) {
+ log_parse_environment();
+ log_open();
+
+ test_config_parse_duid_type();
+ test_config_parse_duid_rawdata();
+ test_config_parse_hwaddr();
+
+ return 0;
+}
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index 2536ad2898..2b83d127b7 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -127,7 +127,8 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
memcpy(r_name, canonical, l+1);
idx = ALIGN(l+1);
- if (n_addresses <= 0) {
+ assert(n_addresses >= 0);
+ if (n_addresses == 0) {
/* Second, fill in IPv6 tuple */
r_tuple = (struct gaih_addrtuple*) (buffer + idx);
r_tuple->next = r_tuple_prev;
@@ -453,38 +454,33 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
}
n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
- if (n_addresses > 0) {
- for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
- if (af != a->family)
- continue;
+ for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
+ if (af != a->family)
+ continue;
- if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0)
- goto found;
- }
+ if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0)
+ goto found;
}
addresses = mfree(addresses);
n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
- if (n_addresses > 0) {
- for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
- if (af != a->family)
- continue;
+ for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
+ if (af != a->family)
+ continue;
- if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) {
- canonical = "gateway";
- goto found;
- }
+ if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) {
+ canonical = "gateway";
+ goto found;
}
}
*errnop = ENOENT;
*h_errnop = HOST_NOT_FOUND;
-
return NSS_STATUS_NOTFOUND;
found:
- if (!canonical || (!additional && additional_from_hostname)) {
+ if (!canonical || additional_from_hostname) {
hn = gethostname_malloc();
if (!hn) {
*errnop = ENOMEM;
@@ -494,8 +490,7 @@ found:
if (!canonical)
canonical = hn;
-
- if (!additional && additional_from_hostname)
+ else
additional = hn;
}
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index 4be8d0507f..ce226c4d66 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -400,34 +400,25 @@ static int resolve_remote(Connection *c) {
union sockaddr_union sa = {};
const char *node, *service;
- socklen_t salen;
int r;
if (path_is_absolute(arg_remote_host)) {
sa.un.sun_family = AF_UNIX;
- strncpy(sa.un.sun_path, arg_remote_host, sizeof(sa.un.sun_path)-1);
- sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
-
- salen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
-
- return connection_start(c, &sa.sa, salen);
+ strncpy(sa.un.sun_path, arg_remote_host, sizeof(sa.un.sun_path));
+ return connection_start(c, &sa.sa, SOCKADDR_UN_LEN(sa.un));
}
if (arg_remote_host[0] == '@') {
sa.un.sun_family = AF_UNIX;
sa.un.sun_path[0] = 0;
- strncpy(sa.un.sun_path+1, arg_remote_host+1, sizeof(sa.un.sun_path)-2);
- sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
-
- salen = offsetof(union sockaddr_union, un.sun_path) + 1 + strlen(sa.un.sun_path + 1);
-
- return connection_start(c, &sa.sa, salen);
+ strncpy(sa.un.sun_path+1, arg_remote_host+1, sizeof(sa.un.sun_path)-1);
+ return connection_start(c, &sa.sa, SOCKADDR_UN_LEN(sa.un));
}
service = strrchr(arg_remote_host, ':');
if (service) {
node = strndupa(arg_remote_host, service - arg_remote_host);
- service ++;
+ service++;
} else {
node = arg_remote_host;
service = "80";
diff --git a/src/systemd-activate/Makefile b/src/systemd-activate/Makefile
index 058e10809e..5e2299f00e 100644
--- a/src/systemd-activate/Makefile
+++ b/src/systemd-activate/Makefile
@@ -24,13 +24,13 @@ include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
-libexec_PROGRAMS += \
- systemd-activate
+bin_PROGRAMS += \
+ systemd-socket-activate
-systemd_activate_SOURCES = \
+systemd_socket_activate_SOURCES = \
src/activate/activate.c
-systemd_activate_LDADD = \
+systemd_socket_activate_LDADD = \
libshared.la
include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/systemd-activate/activate.c b/src/systemd-activate/activate.c
index 94f99028e5..89cc1ee813 100644
--- a/src/systemd-activate/activate.c
+++ b/src/systemd-activate/activate.c
@@ -27,6 +27,7 @@
#include <systemd/sd-daemon.h>
#include "alloc-util.h"
+#include "escape.h"
#include "fd-util.h"
#include "log.h"
#include "macro.h"
@@ -40,7 +41,7 @@ static bool arg_accept = false;
static int arg_socket_type = SOCK_STREAM;
static char** arg_args = NULL;
static char** arg_setenv = NULL;
-static const char *arg_fdname = NULL;
+static char **arg_fdnames = NULL;
static bool arg_inetd = false;
static int add_epoll(int epoll_fd, int fd) {
@@ -76,7 +77,7 @@ static int open_sockets(int *epoll_fd, bool accept) {
if (r < 0)
return r;
- count ++;
+ count++;
}
}
@@ -104,7 +105,7 @@ static int open_sockets(int *epoll_fd, bool accept) {
}
assert(fd == SD_LISTEN_FDS_START + count);
- count ++;
+ count++;
}
if (arg_listen)
@@ -134,7 +135,6 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd,
_cleanup_free_ char *joined = NULL;
unsigned n_env = 0, length;
const char *tocopy;
- unsigned i;
char **s;
int r;
@@ -176,7 +176,7 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd,
if (!envp[n_env])
return log_oom();
- n_env ++;
+ n_env++;
}
}
@@ -191,7 +191,7 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd,
if (!envp[n_env])
return log_oom();
- n_env ++;
+ n_env++;
}
if (arg_inetd) {
@@ -224,25 +224,30 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd,
if (asprintf((char**)(envp + n_env++), "LISTEN_PID=" PID_FMT, getpid()) < 0)
return log_oom();
- if (arg_fdname) {
+ if (arg_fdnames) {
+ _cleanup_free_ char *names = NULL;
+ size_t len;
char *e;
+ int i;
+
+ len = strv_length(arg_fdnames);
+ if (len == 1)
+ for (i = 1; i < n_fds; i++) {
+ r = strv_extend(&arg_fdnames, arg_fdnames[0]);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extend strv: %m");
+ }
+ else if (len != (unsigned) n_fds)
+ log_warning("The number of fd names is different than number of fds: %zu vs %d",
+ len, n_fds);
- e = strappend("LISTEN_FDNAMES=", arg_fdname);
- if (!e)
+ names = strv_join(arg_fdnames, ":");
+ if (!names)
return log_oom();
- for (i = 1; i < (unsigned) n_fds; i++) {
- char *c;
-
- c = strjoin(e, ":", arg_fdname, NULL);
- if (!c) {
- free(e);
- return log_oom();
- }
-
- free(e);
- e = c;
- }
+ e = strappend("LISTEN_FDNAMES=", names);
+ if (!e)
+ return log_oom();
envp[n_env++] = e;
}
@@ -311,19 +316,31 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) {
}
/* SIGCHLD handler. */
-static void sigchld_hdl(int sig, siginfo_t *t, void *data) {
+static void sigchld_hdl(int sig) {
PROTECT_ERRNO;
- log_info("Child %d died with code %d", t->si_pid, t->si_status);
+ for (;;) {
+ siginfo_t si;
+ int r;
+
+ si.si_pid = 0;
+ r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG);
+ if (r < 0) {
+ if (errno != ECHILD)
+ log_error_errno(errno, "Failed to reap children: %m");
+ return;
+ }
+ if (si.si_pid == 0)
+ return;
- /* Wait for a dead child. */
- (void) waitpid(t->si_pid, NULL, 0);
+ log_info("Child %d died with code %d", si.si_pid, si.si_status);
+ }
}
static int install_chld_handler(void) {
static const struct sigaction act = {
- .sa_flags = SA_SIGINFO,
- .sa_sigaction = sigchld_hdl,
+ .sa_flags = SA_NOCLDSTOP,
+ .sa_handler = sigchld_hdl,
};
int r;
@@ -339,14 +356,15 @@ static void help(void) {
printf("%s [OPTIONS...]\n\n"
"Listen on sockets and launch child on connection.\n\n"
"Options:\n"
- " -h --help Show this help and exit\n"
- " --version Print version string and exit\n"
- " -l --listen=ADDR Listen for raw connections at ADDR\n"
- " -d --datagram Listen on datagram instead of stream socket\n"
- " --seqpacket Listen on SOCK_SEQPACKET instead of stream socket\n"
- " -a --accept Spawn separate child for each connection\n"
- " -E --setenv=NAME[=VALUE] Pass an environment variable to children\n"
- " --inetd Enable inetd file descriptor passing protocol\n"
+ " -h --help Show this help and exit\n"
+ " --version Print version string and exit\n"
+ " -l --listen=ADDR Listen for raw connections at ADDR\n"
+ " -d --datagram Listen on datagram instead of stream socket\n"
+ " --seqpacket Listen on SOCK_SEQPACKET instead of stream socket\n"
+ " -a --accept Spawn separate child for each connection\n"
+ " -E --setenv=NAME[=VALUE] Pass an environment variable to children\n"
+ " --fdname=NAME[:NAME...] Specify names for file descriptors\n"
+ " --inetd Enable inetd file descriptor passing protocol\n"
"\n"
"Note: file descriptors from sd_listen_fds() will be passed through.\n"
, program_invocation_short_name);
@@ -379,7 +397,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hl:aEd", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "+hl:aE:d", options, NULL)) >= 0)
switch(c) {
case 'h':
help();
@@ -424,14 +442,30 @@ static int parse_argv(int argc, char *argv[]) {
break;
- case ARG_FDNAME:
- if (!fdname_is_valid(optarg)) {
- log_error("File descriptor name %s is not valid, refusing.", optarg);
- return -EINVAL;
- }
+ case ARG_FDNAME: {
+ _cleanup_strv_free_ char **names;
+ char **s;
+
+ names = strv_split(optarg, ":");
+ if (!names)
+ return log_oom();
- arg_fdname = optarg;
+ STRV_FOREACH(s, names)
+ if (!fdname_is_valid(*s)) {
+ _cleanup_free_ char *esc;
+
+ esc = cescape(*s);
+ log_warning("File descriptor name \"%s\" is not valid.", esc);
+ }
+
+ /* Empty optargs means one empty name */
+ r = strv_extend_strv(&arg_fdnames,
+ strv_isempty(names) ? STRV_MAKE("") : names,
+ false);
+ if (r < 0)
+ return log_error_errno(r, "strv_extend_strv: %m");
break;
+ }
case ARG_INETD:
arg_inetd = true;
diff --git a/src/systemd-analyze/analyze-verify.c b/src/systemd-analyze/analyze-verify.c
index d36c8db3d4..5fd3ee49eb 100644
--- a/src/systemd-analyze/analyze-verify.c
+++ b/src/systemd-analyze/analyze-verify.c
@@ -231,14 +231,12 @@ static int verify_unit(Unit *u, bool check_man) {
return r;
}
-int verify_units(char **filenames, ManagerRunningAs running_as, bool check_man) {
+int verify_units(char **filenames, UnitFileScope scope, bool check_man) {
_cleanup_(sd_bus_error_free) sd_bus_error err = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *var = NULL;
Manager *m = NULL;
FILE *serial = NULL;
FDSet *fdset = NULL;
-
- _cleanup_free_ char *var = NULL;
-
char **filename;
int r = 0, k;
@@ -255,7 +253,7 @@ int verify_units(char **filenames, ManagerRunningAs running_as, bool check_man)
assert_se(set_unit_path(var) >= 0);
- r = manager_new(running_as, true, &m);
+ r = manager_new(scope, true, &m);
if (r < 0)
return log_error_errno(r, "Failed to initialize manager: %m");
@@ -290,7 +288,7 @@ int verify_units(char **filenames, ManagerRunningAs running_as, bool check_man)
if (r == 0)
r = k;
} else
- count ++;
+ count++;
}
for (i = 0; i < count; i++) {
diff --git a/src/systemd-analyze/analyze-verify.h b/src/systemd-analyze/analyze-verify.h
index 54adad93e1..d8204dc69c 100644
--- a/src/systemd-analyze/analyze-verify.h
+++ b/src/systemd-analyze/analyze-verify.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,10 +19,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <stdbool.h>
#include "path-lookup.h"
-int verify_units(char **filenames, ManagerRunningAs running_as, bool check_man);
+int verify_units(char **filenames, UnitFileScope scope, bool check_man);
diff --git a/src/systemd-analyze/analyze.c b/src/systemd-analyze/analyze.c
index 13bcc8ebdd..0e1eee16ec 100644
--- a/src/systemd-analyze/analyze.c
+++ b/src/systemd-analyze/analyze.c
@@ -28,6 +28,7 @@
#include "alloc-util.h"
#include "analyze-verify.h"
#include "bus-error.h"
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "glob-util.h"
#include "hashmap.h"
@@ -60,7 +61,7 @@
svg(" <text class=\"%s\" x=\"%.03f\" y=\"%.03f\">", (b) ? "left" : "right", SCALE_X * (x) + (b ? 5.0 : -5.0), SCALE_Y * (y) + 14.0); \
svg(format, ## __VA_ARGS__); \
svg("</text>\n"); \
- } while(false)
+ } while (false)
static enum dot {
DEP_ALL,
@@ -123,14 +124,6 @@ struct host_info {
char *architecture;
};
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static int bus_get_uint64_property(sd_bus *bus, const char *path, const char *interface, const char *property, uint64_t *val) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
@@ -759,9 +752,9 @@ static int list_dependencies_print(const char *name, unsigned int level, unsigne
char ts[FORMAT_TIMESPAN_MAX], ts2[FORMAT_TIMESPAN_MAX];
for (i = level; i != 0; i--)
- printf("%s", draw_special_char(branches & (1 << (i-1)) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
+ printf("%s", special_glyph(branches & (1 << (i-1)) ? TREE_VERTICAL : TREE_SPACE));
- printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
+ printf("%s", special_glyph(last ? TREE_RIGHT : TREE_BRANCH));
if (times) {
if (times->time)
@@ -965,7 +958,7 @@ static int analyze_critical_chain(sd_bus *bus, char *names[]) {
}
unit_times_hashmap = h;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
puts("The time after the unit is active or started is printed after the \"@\" character.\n"
"The time the unit takes to start is printed after the \"+\" character.\n");
@@ -993,7 +986,7 @@ static int analyze_blame(sd_bus *bus) {
qsort(times, n, sizeof(struct unit_times), compare_unit_time);
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
for (i = 0; i < (unsigned) n; i++) {
char ts[FORMAT_TIMESPAN_MAX];
@@ -1206,7 +1199,7 @@ static int dump(sd_bus *bus, char **args) {
return -E2BIG;
}
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
r = sd_bus_call_method(
bus,
@@ -1284,7 +1277,7 @@ static int set_log_target(sd_bus *bus, char **args) {
static void help(void) {
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Profile systemd, show unit dependencies, check unit files.\n\n"
@@ -1451,7 +1444,7 @@ int main(int argc, char *argv[]) {
if (streq_ptr(argv[optind], "verify"))
r = verify_units(argv+optind+1,
- arg_user ? MANAGER_USER : MANAGER_SYSTEM,
+ arg_user ? UNIT_FILE_USER : UNIT_FILE_SYSTEM,
arg_man);
else {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
diff --git a/src/systemd-ask-password/ask-password.c b/src/systemd-ask-password/ask-password.c
index adc9286612..6d53dd982c 100644
--- a/src/systemd-ask-password/ask-password.c
+++ b/src/systemd-ask-password/ask-password.c
@@ -34,6 +34,7 @@ static const char *arg_keyname = NULL;
static char *arg_message = NULL;
static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
static bool arg_multiple = false;
+static bool arg_no_output = false;
static AskPasswordFlags arg_flags = ASK_PASSWORD_PUSH_CACHE;
static void help(void) {
@@ -48,6 +49,7 @@ static void help(void) {
" --no-tty Ask question via agent even on TTY\n"
" --accept-cached Accept cached passwords\n"
" --multiple List multiple passwords if available\n"
+ " --no-output Do not print password to standard output\n"
, program_invocation_short_name);
}
@@ -62,6 +64,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_MULTIPLE,
ARG_ID,
ARG_KEYNAME,
+ ARG_NO_OUTPUT,
};
static const struct option options[] = {
@@ -74,6 +77,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "multiple", no_argument, NULL, ARG_MULTIPLE },
{ "id", required_argument, NULL, ARG_ID },
{ "keyname", required_argument, NULL, ARG_KEYNAME },
+ { "no-output", no_argument, NULL, ARG_NO_OUTPUT },
{}
};
@@ -125,6 +129,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_keyname = optarg;
break;
+ case ARG_NO_OUTPUT:
+ arg_no_output = true;
+ break;
+
case '?':
return -EINVAL;
@@ -166,7 +174,8 @@ int main(int argc, char *argv[]) {
}
STRV_FOREACH(p, l) {
- puts(*p);
+ if (!arg_no_output)
+ puts(*p);
if (!arg_multiple)
break;
diff --git a/src/systemd-bootchart/bootchart.c b/src/systemd-bootchart/bootchart.c
deleted file mode 100644
index 8755b2d884..0000000000
--- a/src/systemd-bootchart/bootchart.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2009-2013 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.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/>.
- ***/
-
-/***
-
- Many thanks to those who contributed ideas and code:
- - Ziga Mahkovec - Original bootchart author
- - Anders Norgaard - PyBootchartgui
- - Michael Meeks - bootchart2
- - Scott James Remnant - Ubuntu C-based logger
- - Arjan van der Ven - for the idea to merge bootgraph.pl functionality
-
- ***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <systemd/sd-journal.h>
-
-#include "alloc-util.h"
-#include "bootchart.h"
-#include "conf-parser.h"
-#include "def.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "io-util.h"
-#include "list.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "store.h"
-#include "string-util.h"
-#include "strxcpyx.h"
-#include "svg.h"
-#include "util.h"
-
-static int exiting = 0;
-
-#define DEFAULT_SAMPLES_LEN 500
-#define DEFAULT_HZ 25.0
-#define DEFAULT_SCALE_X 100.0 /* 100px = 1sec */
-#define DEFAULT_SCALE_Y 20.0 /* 16px = 1 process bar */
-#define DEFAULT_INIT ROOTLIBEXECDIR "/systemd"
-#define DEFAULT_OUTPUT "/run/log"
-
-/* graph defaults */
-bool arg_entropy = false;
-bool arg_initcall = true;
-bool arg_relative = false;
-bool arg_filter = true;
-bool arg_show_cmdline = false;
-bool arg_show_cgroup = false;
-bool arg_pss = false;
-bool arg_percpu = false;
-int arg_samples_len = DEFAULT_SAMPLES_LEN; /* we record len+1 (1 start sample) */
-double arg_hz = DEFAULT_HZ;
-double arg_scale_x = DEFAULT_SCALE_X;
-double arg_scale_y = DEFAULT_SCALE_Y;
-
-char arg_init_path[PATH_MAX] = DEFAULT_INIT;
-char arg_output_path[PATH_MAX] = DEFAULT_OUTPUT;
-
-static void signal_handler(int sig) {
- exiting = 1;
-}
-
-#define BOOTCHART_MAX (16*1024*1024)
-
-static void parse_conf(void) {
- char *init = NULL, *output = NULL;
- const ConfigTableItem items[] = {
- { "Bootchart", "Samples", config_parse_int, 0, &arg_samples_len },
- { "Bootchart", "Frequency", config_parse_double, 0, &arg_hz },
- { "Bootchart", "Relative", config_parse_bool, 0, &arg_relative },
- { "Bootchart", "Filter", config_parse_bool, 0, &arg_filter },
- { "Bootchart", "Output", config_parse_path, 0, &output },
- { "Bootchart", "Init", config_parse_path, 0, &init },
- { "Bootchart", "PlotMemoryUsage", config_parse_bool, 0, &arg_pss },
- { "Bootchart", "PlotEntropyGraph", config_parse_bool, 0, &arg_entropy },
- { "Bootchart", "ScaleX", config_parse_double, 0, &arg_scale_x },
- { "Bootchart", "ScaleY", config_parse_double, 0, &arg_scale_y },
- { "Bootchart", "ControlGroup", config_parse_bool, 0, &arg_show_cgroup },
- { "Bootchart", "PerCPU", config_parse_bool, 0, &arg_percpu },
- { NULL, NULL, NULL, 0, NULL }
- };
-
- config_parse_many(PKGSYSCONFDIR "/bootchart.conf",
- CONF_PATHS_NULSTR("systemd/bootchart.conf.d"),
- NULL, config_item_table_lookup, items, true, NULL);
-
- if (init != NULL)
- strscpy(arg_init_path, sizeof(arg_init_path), init);
- if (output != NULL)
- strscpy(arg_output_path, sizeof(arg_output_path), output);
-}
-
-static void help(void) {
- printf("Usage: %s [OPTIONS]\n\n"
- "Options:\n"
- " -r --rel Record time relative to recording\n"
- " -f --freq=FREQ Sample frequency [%g]\n"
- " -n --samples=N Stop sampling at [%d] samples\n"
- " -x --scale-x=N Scale the graph horizontally [%g] \n"
- " -y --scale-y=N Scale the graph vertically [%g] \n"
- " -p --pss Enable PSS graph (CPU intensive)\n"
- " -e --entropy Enable the entropy_avail graph\n"
- " -o --output=PATH Path to output files [%s]\n"
- " -i --init=PATH Path to init executable [%s]\n"
- " -F --no-filter Disable filtering of unimportant or ephemeral processes\n"
- " -C --cmdline Display full command lines with arguments\n"
- " -c --control-group Display process control group\n"
- " --per-cpu Draw each CPU utilization and wait bar also\n"
- " -h --help Display this message\n\n"
- "See bootchart.conf for more information.\n",
- program_invocation_short_name,
- DEFAULT_HZ,
- DEFAULT_SAMPLES_LEN,
- DEFAULT_SCALE_X,
- DEFAULT_SCALE_Y,
- DEFAULT_OUTPUT,
- DEFAULT_INIT);
-}
-
-static int parse_argv(int argc, char *argv[]) {
-
- enum {
- ARG_PERCPU = 0x100,
- };
-
- static const struct option options[] = {
- {"rel", no_argument, NULL, 'r' },
- {"freq", required_argument, NULL, 'f' },
- {"samples", required_argument, NULL, 'n' },
- {"pss", no_argument, NULL, 'p' },
- {"output", required_argument, NULL, 'o' },
- {"init", required_argument, NULL, 'i' },
- {"no-filter", no_argument, NULL, 'F' },
- {"cmdline", no_argument, NULL, 'C' },
- {"control-group", no_argument, NULL, 'c' },
- {"help", no_argument, NULL, 'h' },
- {"scale-x", required_argument, NULL, 'x' },
- {"scale-y", required_argument, NULL, 'y' },
- {"entropy", no_argument, NULL, 'e' },
- {"per-cpu", no_argument, NULL, ARG_PERCPU},
- {}
- };
- int c, r;
-
- if (getpid() == 1)
- opterr = 0;
-
- while ((c = getopt_long(argc, argv, "erpf:n:o:i:FCchx:y:", options, NULL)) >= 0)
- switch (c) {
-
- case 'r':
- arg_relative = true;
- break;
- case 'f':
- r = safe_atod(optarg, &arg_hz);
- if (r < 0)
- log_warning_errno(r, "failed to parse --freq/-f argument '%s': %m",
- optarg);
- break;
- case 'F':
- arg_filter = false;
- break;
- case 'C':
- arg_show_cmdline = true;
- break;
- case 'c':
- arg_show_cgroup = true;
- break;
- case 'n':
- r = safe_atoi(optarg, &arg_samples_len);
- if (r < 0)
- log_warning_errno(r, "failed to parse --samples/-n argument '%s': %m",
- optarg);
- break;
- case 'o':
- path_kill_slashes(optarg);
- strscpy(arg_output_path, sizeof(arg_output_path), optarg);
- break;
- case 'i':
- path_kill_slashes(optarg);
- strscpy(arg_init_path, sizeof(arg_init_path), optarg);
- break;
- case 'p':
- arg_pss = true;
- break;
- case 'x':
- r = safe_atod(optarg, &arg_scale_x);
- if (r < 0)
- log_warning_errno(r, "failed to parse --scale-x/-x argument '%s': %m",
- optarg);
- break;
- case 'y':
- r = safe_atod(optarg, &arg_scale_y);
- if (r < 0)
- log_warning_errno(r, "failed to parse --scale-y/-y argument '%s': %m",
- optarg);
- break;
- case 'e':
- arg_entropy = true;
- break;
- case ARG_PERCPU:
- arg_percpu = true;
- break;
- case 'h':
- help();
- return 0;
- case '?':
- if (getpid() != 1)
- return -EINVAL;
- else
- return 0;
- default:
- assert_not_reached("Unhandled option code.");
- }
-
- if (arg_hz <= 0) {
- log_error("Frequency needs to be > 0");
- return -EINVAL;
- }
-
- return 1;
-}
-
-static int do_journal_append(char *file) {
- _cleanup_free_ char *bootchart_message = NULL;
- _cleanup_free_ char *bootchart_file = NULL;
- _cleanup_free_ char *p = NULL;
- _cleanup_close_ int fd = -1;
- struct iovec iovec[5];
- int r, j = 0;
- ssize_t n;
-
- bootchart_file = strappend("BOOTCHART_FILE=", file);
- if (!bootchart_file)
- return log_oom();
-
- IOVEC_SET_STRING(iovec[j++], bootchart_file);
- IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=9f26aa562cf440c2b16c773d0479b518");
- IOVEC_SET_STRING(iovec[j++], "PRIORITY=7");
- bootchart_message = strjoin("MESSAGE=Bootchart created: ", file, NULL);
- if (!bootchart_message)
- return log_oom();
-
- IOVEC_SET_STRING(iovec[j++], bootchart_message);
-
- p = malloc(10 + BOOTCHART_MAX);
- if (!p)
- return log_oom();
-
- memcpy(p, "BOOTCHART=", 10);
-
- fd = open(file, O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- return log_error_errno(errno, "Failed to open bootchart data \"%s\": %m", file);
-
- n = loop_read(fd, p + 10, BOOTCHART_MAX, false);
- if (n < 0)
- return log_error_errno(n, "Failed to read bootchart data: %m");
-
- iovec[j].iov_base = p;
- iovec[j].iov_len = 10 + n;
- j++;
-
- r = sd_journal_sendv(iovec, j);
- if (r < 0)
- log_error_errno(r, "Failed to send bootchart: %m");
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- static struct list_sample_data *sampledata;
- _cleanup_closedir_ DIR *proc = NULL;
- _cleanup_free_ char *build = NULL;
- _cleanup_fclose_ FILE *of = NULL;
- _cleanup_close_ int sysfd = -1;
- struct ps_struct *ps_first;
- double graph_start;
- double log_start;
- double interval;
- char output_file[PATH_MAX];
- char datestr[200];
- int pscount = 0;
- int n_cpus = 0;
- int overrun = 0;
- time_t t = 0;
- int r, samples;
- struct ps_struct *ps;
- struct rlimit rlim;
- struct list_sample_data *head;
- struct sigaction sig = {
- .sa_handler = signal_handler,
- };
-
- parse_conf();
-
- r = parse_argv(argc, argv);
- if (r < 0)
- return EXIT_FAILURE;
-
- if (r == 0)
- return EXIT_SUCCESS;
-
- /*
- * If the kernel executed us through init=/usr/lib/systemd/systemd-bootchart, then
- * fork:
- * - parent execs executable specified via init_path[] (/usr/lib/systemd/systemd by default) as pid=1
- * - child logs data
- */
- if (getpid() == 1) {
- if (fork())
- /* parent */
- execl(arg_init_path, arg_init_path, NULL);
- }
- argv[0][0] = '@';
-
- rlim.rlim_cur = 4096;
- rlim.rlim_max = 4096;
- (void) setrlimit(RLIMIT_NOFILE, &rlim);
-
- /* start with empty ps LL */
- ps_first = new0(struct ps_struct, 1);
- if (!ps_first) {
- log_oom();
- return EXIT_FAILURE;
- }
-
- /* handle TERM/INT nicely */
- sigaction(SIGHUP, &sig, NULL);
-
- interval = (1.0 / arg_hz) * 1000000000.0;
-
- if (arg_relative)
- graph_start = log_start = gettime_ns();
- else {
- struct timespec n;
- double uptime;
-
- clock_gettime(clock_boottime_or_monotonic(), &n);
- uptime = (n.tv_sec + (n.tv_nsec / (double) NSEC_PER_SEC));
-
- log_start = gettime_ns();
- graph_start = log_start - uptime;
- }
-
- if (graph_start < 0.0) {
- log_error("Failed to setup graph start time.\n\n"
- "The system uptime probably includes time that the system was suspended. "
- "Use --rel to bypass this issue.");
- return EXIT_FAILURE;
- }
-
- LIST_HEAD_INIT(head);
-
- /* main program loop */
- for (samples = 0; !exiting && samples < arg_samples_len; samples++) {
- int res;
- double sample_stop;
- double elapsed;
- double timeleft;
-
- sampledata = new0(struct list_sample_data, 1);
- if (sampledata == NULL) {
- log_oom();
- return EXIT_FAILURE;
- }
-
- sampledata->sampletime = gettime_ns();
- sampledata->counter = samples;
-
- if (sysfd < 0)
- sysfd = open("/sys", O_RDONLY|O_CLOEXEC);
-
- if (!build) {
- if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &build, NULL) == -ENOENT)
- parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &build, NULL);
- }
-
- if (proc)
- rewinddir(proc);
- else
- proc = opendir("/proc");
-
- /* wait for /proc to become available, discarding samples */
- if (proc) {
- r = log_sample(proc, samples, ps_first, &sampledata, &pscount, &n_cpus);
- if (r < 0)
- return EXIT_FAILURE;
- }
-
- sample_stop = gettime_ns();
-
- elapsed = (sample_stop - sampledata->sampletime) * 1000000000.0;
- timeleft = interval - elapsed;
-
- /*
- * check if we have not consumed our entire timeslice. If we
- * do, don't sleep and take a new sample right away.
- * we'll lose all the missed samples and overrun our total
- * time
- */
- if (timeleft > 0) {
- struct timespec req;
-
- req.tv_sec = (time_t)(timeleft / 1000000000.0);
- req.tv_nsec = (long)(timeleft - (req.tv_sec * 1000000000.0));
-
- res = nanosleep(&req, NULL);
- if (res) {
- if (errno == EINTR)
- /* caught signal, probably HUP! */
- break;
- log_error_errno(errno, "nanosleep() failed: %m");
- return EXIT_FAILURE;
- }
- } else {
- overrun++;
- /* calculate how many samples we lost and scrap them */
- arg_samples_len -= (int)(-timeleft / interval);
- }
- LIST_PREPEND(link, head, sampledata);
- }
-
- /* do some cleanup, close fd's */
- ps = ps_first;
- while (ps->next_ps) {
- ps = ps->next_ps;
- ps->schedstat = safe_close(ps->schedstat);
- ps->sched = safe_close(ps->sched);
- ps->smaps = safe_fclose(ps->smaps);
- }
-
- if (!of) {
- t = time(NULL);
- r = strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M", localtime(&t));
- assert_se(r > 0);
-
- snprintf(output_file, PATH_MAX, "%s/bootchart-%s.svg", arg_output_path, datestr);
- of = fopen(output_file, "we");
- }
-
- if (!of) {
- log_error("Error opening output file '%s': %m\n", output_file);
- return EXIT_FAILURE;
- }
-
- r = svg_do(of, strna(build), head, ps_first,
- samples, pscount, n_cpus, graph_start,
- log_start, interval, overrun);
-
- if (r < 0) {
- log_error_errno(r, "Error generating svg file: %m");
- return EXIT_FAILURE;
- }
-
- log_info("systemd-bootchart wrote %s\n", output_file);
-
- r = do_journal_append(output_file);
- if (r < 0)
- return EXIT_FAILURE;
-
- /* nitpic cleanups */
- ps = ps_first->next_ps;
- while (ps->next_ps) {
- struct ps_struct *old;
-
- old = ps;
- old->sample = ps->first;
- ps = ps->next_ps;
- while (old->sample->next) {
- struct ps_sched_struct *oldsample = old->sample;
-
- old->sample = old->sample->next;
- free(oldsample);
- }
- free(old->cgroup);
- free(old->sample);
- free(old);
- }
-
- free(ps->cgroup);
- free(ps->sample);
- free(ps);
-
- sampledata = head;
- while (sampledata->link_prev) {
- struct list_sample_data *old_sampledata = sampledata;
- sampledata = sampledata->link_prev;
- free(old_sampledata);
- }
- free(sampledata);
-
- /* don't complain when overrun once, happens most commonly on 1st sample */
- if (overrun > 1)
- log_warning("systemd-bootchart: sample time overrun %i times\n", overrun);
-
- return 0;
-}
diff --git a/src/systemd-bootchart/bootchart.conf b/src/systemd-bootchart/bootchart.conf
deleted file mode 100644
index 4f5e50936e..0000000000
--- a/src/systemd-bootchart/bootchart.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# Entries in this file show the compile time defaults.
-# You can change settings by editing this file.
-# Defaults can be restored by simply deleting this file.
-#
-# See bootchart.conf(5) for details.
-
-[Bootchart]
-#Samples=500
-#Frequency=25
-#Relative=no
-#Filter=yes
-#Output=<folder name, defaults to /run/log>
-#Init=/path/to/init-binary
-#PlotMemoryUsage=no
-#PlotEntropyGraph=no
-#ScaleX=100
-#ScaleY=20
-#ControlGroup=no
-#PerCPU=no
diff --git a/src/systemd-bootchart/bootchart.h b/src/systemd-bootchart/bootchart.h
deleted file mode 100644
index 1b445b954b..0000000000
--- a/src/systemd-bootchart/bootchart.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2009-2013 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.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/>.
-***/
-
-#include <stdbool.h>
-
-#include "list.h"
-
-#define MAXCPUS 16
-#define MAXPIDS 65535
-
-struct block_stat_struct {
- /* /proc/vmstat pgpgin & pgpgout */
- int bi;
- int bo;
-};
-
-struct cpu_stat_sample_struct {
- /* /proc/schedstat fields 10 & 11 (after name) */
- double runtime;
- double waittime;
-};
-
-/* per process, per sample data we will log */
-struct ps_sched_struct {
- /* /proc/<n>/schedstat fields 1 & 2 */
- double runtime;
- double waittime;
- int pss;
- struct list_sample_data *sampledata;
- struct ps_sched_struct *next;
- struct ps_sched_struct *prev;
- struct ps_sched_struct *cross; /* cross pointer */
- struct ps_struct *ps_new;
-};
-
-struct list_sample_data {
- double runtime[MAXCPUS];
- double waittime[MAXCPUS];
- double sampletime;
- int entropy_avail;
- struct block_stat_struct blockstat;
- LIST_FIELDS(struct list_sample_data, link); /* DLL */
- int counter;
-};
-
-/* process info */
-struct ps_struct {
- struct ps_struct *next_ps; /* SLL pointer */
- struct ps_struct *parent; /* ppid ref */
- struct ps_struct *children; /* children */
- struct ps_struct *next; /* siblings */
-
- /* must match - otherwise it's a new process with same PID */
- char name[256];
- int pid;
- int ppid;
- char *cgroup;
-
- /* cache fd's */
- int sched;
- int schedstat;
- FILE *smaps;
-
- /* pointers to first/last seen timestamps */
- struct ps_sched_struct *first;
- struct ps_sched_struct *last;
-
- /* records actual start time, may be way before bootchart runs */
- double starttime;
-
- /* record human readable total cpu time */
- double total;
-
- /* largest PSS size found */
- int pss_max;
-
- /* for drawing connection lines later */
- double pos_x;
- double pos_y;
-
- struct ps_sched_struct *sample;
-};
-
-extern bool arg_relative;
-extern bool arg_filter;
-extern bool arg_show_cmdline;
-extern bool arg_show_cgroup;
-extern bool arg_pss;
-extern bool arg_entropy;
-extern bool arg_percpu;
-extern bool arg_initcall;
-extern int arg_samples_len;
-extern double arg_hz;
-extern double arg_scale_x;
-extern double arg_scale_y;
-
-extern char arg_output_path[PATH_MAX];
-extern char arg_init_path[PATH_MAX];
diff --git a/src/systemd-bootchart/store.c b/src/systemd-bootchart/store.c
deleted file mode 100644
index 42cb8043ce..0000000000
--- a/src/systemd-bootchart/store.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2009-2013 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.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/>.
- ***/
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "bootchart.h"
-#include "cgroup-util.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "parse-util.h"
-#include "store.h"
-#include "string-util.h"
-#include "strxcpyx.h"
-#include "time-util.h"
-#include "util.h"
-
-/*
- * Alloc a static 4k buffer for stdio - primarily used to increase
- * PSS buffering from the default 1k stdin buffer to reduce
- * read() overhead.
- */
-static char smaps_buf[4096];
-static int skip = 0;
-
-double gettime_ns(void) {
- struct timespec n;
-
- clock_gettime(CLOCK_MONOTONIC, &n);
-
- return (n.tv_sec + (n.tv_nsec / (double) NSEC_PER_SEC));
-}
-
-static char *bufgetline(char *buf) {
- char *c;
-
- if (!buf)
- return NULL;
-
- c = strchr(buf, '\n');
- if (c)
- c++;
-
- return c;
-}
-
-static int pid_cmdline_strscpy(int procfd, char *buffer, size_t buf_len, int pid) {
- char filename[PATH_MAX];
- _cleanup_close_ int fd = -1;
- ssize_t n;
-
- sprintf(filename, "%d/cmdline", pid);
- fd = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- n = read(fd, buffer, buf_len-1);
- if (n > 0) {
- int i;
- for (i = 0; i < n; i++)
- if (buffer[i] == '\0')
- buffer[i] = ' ';
- buffer[n] = '\0';
- }
-
- return 0;
-}
-
-int log_sample(DIR *proc,
- int sample,
- struct ps_struct *ps_first,
- struct list_sample_data **ptr,
- int *pscount,
- int *cpus) {
-
- static int vmstat = -1;
- _cleanup_free_ char *buf_schedstat = NULL;
- char buf[4096];
- char key[256];
- char val[256];
- char rt[256];
- char wt[256];
- char *m;
- int r;
- int c;
- int p;
- int mod;
- static int e_fd = -1;
- ssize_t s;
- ssize_t n;
- struct dirent *ent;
- int fd;
- struct list_sample_data *sampledata;
- struct ps_sched_struct *ps_prev = NULL;
- int procfd;
- int taskfd = -1;
-
- sampledata = *ptr;
-
- procfd = dirfd(proc);
- if (procfd < 0)
- return -errno;
-
- if (vmstat < 0) {
- /* block stuff */
- vmstat = openat(procfd, "vmstat", O_RDONLY|O_CLOEXEC);
- if (vmstat < 0)
- return log_error_errno(errno, "Failed to open /proc/vmstat: %m");
- }
-
- n = pread(vmstat, buf, sizeof(buf) - 1, 0);
- if (n <= 0) {
- vmstat = safe_close(vmstat);
- if (n < 0)
- return -errno;
- return -ENODATA;
- }
-
- buf[n] = '\0';
-
- m = buf;
- while (m) {
- if (sscanf(m, "%s %s", key, val) < 2)
- goto vmstat_next;
- if (streq(key, "pgpgin"))
- sampledata->blockstat.bi = atoi(val);
- if (streq(key, "pgpgout")) {
- sampledata->blockstat.bo = atoi(val);
- break;
- }
-vmstat_next:
- m = bufgetline(m);
- if (!m)
- break;
- }
-
- /* Parse "/proc/schedstat" for overall CPU utilization */
- r = read_full_file("/proc/schedstat", &buf_schedstat, NULL);
- if (r < 0)
- return log_error_errno(r, "Unable to read schedstat: %m");
-
- m = buf_schedstat;
- while (m) {
- if (sscanf(m, "%s %*s %*s %*s %*s %*s %*s %s %s", key, rt, wt) < 3)
- goto schedstat_next;
-
- if (strstr(key, "cpu")) {
- r = safe_atoi((const char*)(key+3), &c);
- if (r < 0 || c > MAXCPUS -1)
- /* Oops, we only have room for MAXCPUS data */
- break;
- sampledata->runtime[c] = atoll(rt);
- sampledata->waittime[c] = atoll(wt);
-
- if (c == *cpus)
- *cpus = c + 1;
- }
-schedstat_next:
- m = bufgetline(m);
- if (!m)
- break;
- }
-
- if (arg_entropy) {
- if (e_fd < 0) {
- e_fd = openat(procfd, "sys/kernel/random/entropy_avail", O_RDONLY|O_CLOEXEC);
- if (e_fd < 0)
- return log_error_errno(errno, "Failed to open /proc/sys/kernel/random/entropy_avail: %m");
- }
-
- n = pread(e_fd, buf, sizeof(buf) - 1, 0);
- if (n <= 0) {
- e_fd = safe_close(e_fd);
- } else {
- buf[n] = '\0';
- sampledata->entropy_avail = atoi(buf);
- }
- }
-
- while ((ent = readdir(proc)) != NULL) {
- char filename[PATH_MAX];
- int pid;
- struct ps_struct *ps;
-
- if ((ent->d_name[0] < '0') || (ent->d_name[0] > '9'))
- continue;
-
- pid = atoi(ent->d_name);
-
- if (pid >= MAXPIDS)
- continue;
-
- ps = ps_first;
- while (ps->next_ps) {
- ps = ps->next_ps;
- if (ps->pid == pid)
- break;
- }
-
- /* end of our LL? then append a new record */
- if (ps->pid != pid) {
- _cleanup_fclose_ FILE *st = NULL;
- char t[32];
- struct ps_struct *parent;
-
- ps->next_ps = new0(struct ps_struct, 1);
- if (!ps->next_ps)
- return log_oom();
-
- ps = ps->next_ps;
- ps->pid = pid;
- ps->sched = -1;
- ps->schedstat = -1;
-
- ps->sample = new0(struct ps_sched_struct, 1);
- if (!ps->sample)
- return log_oom();
-
- ps->sample->sampledata = sampledata;
-
- (*pscount)++;
-
- /* mark our first sample */
- ps->first = ps->last = ps->sample;
- ps->sample->runtime = atoll(rt);
- ps->sample->waittime = atoll(wt);
-
- /* get name, start time */
- if (ps->sched < 0) {
- sprintf(filename, "%d/sched", pid);
- ps->sched = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
- if (ps->sched < 0)
- continue;
- }
-
- s = pread(ps->sched, buf, sizeof(buf) - 1, 0);
- if (s <= 0) {
- ps->sched = safe_close(ps->sched);
- continue;
- }
- buf[s] = '\0';
-
- if (!sscanf(buf, "%s %*s %*s", key))
- continue;
-
- strscpy(ps->name, sizeof(ps->name), key);
-
- /* cmdline */
- if (arg_show_cmdline)
- pid_cmdline_strscpy(procfd, ps->name, sizeof(ps->name), pid);
-
- /* discard line 2 */
- m = bufgetline(buf);
- if (!m)
- continue;
-
- m = bufgetline(m);
- if (!m)
- continue;
-
- if (!sscanf(m, "%*s %*s %s", t))
- continue;
-
- r = safe_atod(t, &ps->starttime);
- if (r < 0)
- continue;
-
- ps->starttime /= 1000.0;
-
- if (arg_show_cgroup)
- /* if this fails, that's OK */
- cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER,
- ps->pid, &ps->cgroup);
-
- /* ppid */
- sprintf(filename, "%d/stat", pid);
- fd = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- continue;
-
- st = fdopen(fd, "re");
- if (!st) {
- close(fd);
- continue;
- }
-
- if (!fscanf(st, "%*s %*s %*s %i", &p))
- continue;
-
- ps->ppid = p;
-
- /*
- * setup child pointers
- *
- * these are used to paint the tree coherently later
- * each parent has a LL of children, and a LL of siblings
- */
- if (pid == 1)
- continue; /* nothing to do for init atm */
-
- /* kthreadd has ppid=0, which breaks our tree ordering */
- if (ps->ppid == 0)
- ps->ppid = 1;
-
- parent = ps_first;
- while ((parent->next_ps && parent->pid != ps->ppid))
- parent = parent->next_ps;
-
- if (parent->pid != ps->ppid) {
- /* orphan */
- ps->ppid = 1;
- parent = ps_first->next_ps;
- }
-
- ps->parent = parent;
-
- if (!parent->children) {
- /* it's the first child */
- parent->children = ps;
- } else {
- /* walk all children and append */
- struct ps_struct *children;
- children = parent->children;
- while (children->next)
- children = children->next;
-
- children->next = ps;
- }
- }
-
- /* else -> found pid, append data in ps */
-
- /* below here is all continuous logging parts - we get here on every
- * iteration */
-
- /* rt, wt */
- if (ps->schedstat < 0) {
- sprintf(filename, "%d/schedstat", pid);
- ps->schedstat = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
- if (ps->schedstat < 0)
- continue;
- }
-
- s = pread(ps->schedstat, buf, sizeof(buf) - 1, 0);
- if (s <= 0) {
- /* clean up our file descriptors - assume that the process exited */
- close(ps->schedstat);
- ps->schedstat = -1;
- ps->sched = safe_close(ps->sched);
- continue;
- }
-
- buf[s] = '\0';
-
- if (!sscanf(buf, "%s %s %*s", rt, wt))
- continue;
-
- ps->sample->next = new0(struct ps_sched_struct, 1);
- if (!ps->sample->next)
- return log_oom();
-
- ps->sample->next->prev = ps->sample;
- ps->sample = ps->sample->next;
- ps->last = ps->sample;
- ps->sample->runtime = atoll(rt);
- ps->sample->waittime = atoll(wt);
- ps->sample->sampledata = sampledata;
- ps->sample->ps_new = ps;
- if (ps_prev)
- ps_prev->cross = ps->sample;
-
- ps_prev = ps->sample;
- ps->total = (ps->last->runtime - ps->first->runtime)
- / 1000000000.0;
-
- /* Take into account CPU runtime/waittime spent in non-main threads of the process
- * by parsing "/proc/[pid]/task/[tid]/schedstat" for all [tid] != [pid]
- * See https://github.com/systemd/systemd/issues/139
- */
-
- /* Browse directory "/proc/[pid]/task" to know the thread ids of process [pid] */
- snprintf(filename, sizeof(filename), PID_FMT "/task", pid);
- taskfd = openat(procfd, filename, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
- if (taskfd >= 0) {
- _cleanup_closedir_ DIR *taskdir = NULL;
-
- taskdir = fdopendir(taskfd);
- if (!taskdir) {
- safe_close(taskfd);
- return -errno;
- }
- FOREACH_DIRENT(ent, taskdir, break) {
- int tid = -1;
- _cleanup_close_ int tid_schedstat = -1;
- long long delta_rt;
- long long delta_wt;
-
- if ((ent->d_name[0] < '0') || (ent->d_name[0] > '9'))
- continue;
-
- /* Skip main thread as it was already accounted */
- r = safe_atoi(ent->d_name, &tid);
- if (r < 0 || tid == pid)
- continue;
-
- /* Parse "/proc/[pid]/task/[tid]/schedstat" */
- snprintf(filename, sizeof(filename), PID_FMT "/schedstat", tid);
- tid_schedstat = openat(taskfd, filename, O_RDONLY|O_CLOEXEC);
-
- if (tid_schedstat == -1)
- continue;
-
- s = pread(tid_schedstat, buf, sizeof(buf) - 1, 0);
- if (s <= 0)
- continue;
- buf[s] = '\0';
-
- if (!sscanf(buf, "%s %s %*s", rt, wt))
- continue;
-
- r = safe_atolli(rt, &delta_rt);
- if (r < 0)
- continue;
- r = safe_atolli(rt, &delta_wt);
- if (r < 0)
- continue;
- ps->sample->runtime += delta_rt;
- ps->sample->waittime += delta_wt;
- }
- }
-
- if (!arg_pss)
- goto catch_rename;
-
- /* Pss */
- if (!ps->smaps) {
- sprintf(filename, "%d/smaps", pid);
- fd = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- continue;
- ps->smaps = fdopen(fd, "re");
- if (!ps->smaps) {
- close(fd);
- continue;
- }
- setvbuf(ps->smaps, smaps_buf, _IOFBF, sizeof(smaps_buf));
- } else {
- rewind(ps->smaps);
- }
-
- /* test to see if we need to skip another field */
- if (skip == 0) {
- if (fgets(buf, sizeof(buf), ps->smaps) == NULL) {
- continue;
- }
- if (fread(buf, 1, 28 * 15, ps->smaps) != (28 * 15)) {
- continue;
- }
- if (buf[392] == 'V') {
- skip = 2;
- }
- else {
- skip = 1;
- }
- rewind(ps->smaps);
- }
-
- while (1) {
- int pss_kb;
-
- /* skip one line, this contains the object mapped. */
- if (fgets(buf, sizeof(buf), ps->smaps) == NULL) {
- break;
- }
- /* then there's a 28 char 14 line block */
- if (fread(buf, 1, 28 * 14, ps->smaps) != 28 * 14) {
- break;
- }
- pss_kb = atoi(&buf[61]);
- ps->sample->pss += pss_kb;
-
- /* skip one more line if this is a newer kernel */
- if (skip == 2) {
- if (fgets(buf, sizeof(buf), ps->smaps) == NULL)
- break;
- }
- }
-
- if (ps->sample->pss > ps->pss_max)
- ps->pss_max = ps->sample->pss;
-
-catch_rename:
- /* catch process rename, try to randomize time */
- mod = (arg_hz < 4.0) ? 4.0 : (arg_hz / 4.0);
- if (((sample - ps->pid) + pid) % (int)(mod) == 0) {
-
- /* re-fetch name */
- /* get name, start time */
- if (ps->sched < 0) {
- sprintf(filename, "%d/sched", pid);
- ps->sched = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
- if (ps->sched < 0)
- continue;
- }
-
- s = pread(ps->sched, buf, sizeof(buf) - 1, 0);
- if (s <= 0) {
- /* clean up file descriptors */
- ps->sched = safe_close(ps->sched);
- ps->schedstat = safe_close(ps->schedstat);
- continue;
- }
-
- buf[s] = '\0';
-
- if (!sscanf(buf, "%s %*s %*s", key))
- continue;
-
- strscpy(ps->name, sizeof(ps->name), key);
-
- /* cmdline */
- if (arg_show_cmdline)
- pid_cmdline_strscpy(procfd, ps->name, sizeof(ps->name), pid);
- }
- }
-
- return 0;
-}
diff --git a/src/systemd-bootchart/svg.c b/src/systemd-bootchart/svg.c
deleted file mode 100644
index f2af535061..0000000000
--- a/src/systemd-bootchart/svg.c
+++ /dev/null
@@ -1,1375 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2009-2013 Intel Corporation
-
- Authors:
- Auke Kok <auke-jan.h.kok@intel.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/>.
- ***/
-
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/utsname.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "architecture.h"
-#include "bootchart.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "list.h"
-#include "macro.h"
-#include "stdio-util.h"
-#include "store.h"
-#include "svg.h"
-#include "utf8.h"
-#include "util.h"
-
-#define time_to_graph(t) ((t) * arg_scale_x)
-#define ps_to_graph(n) ((n) * arg_scale_y)
-#define kb_to_graph(m) ((m) * arg_scale_y * 0.0001)
-#define to_color(n) (192.0 - ((n) * 192.0))
-
-static const char * const colorwheel[12] = {
- "rgb(255,32,32)", // red
- "rgb(32,192,192)", // cyan
- "rgb(255,128,32)", // orange
- "rgb(128,32,192)", // blue-violet
- "rgb(255,255,32)", // yellow
- "rgb(192,32,128)", // red-violet
- "rgb(32,255,32)", // green
- "rgb(255,64,32)", // red-orange
- "rgb(32,32,255)", // blue
- "rgb(255,192,32)", // yellow-orange
- "rgb(192,32,192)", // violet
- "rgb(32,192,32)" // yellow-green
-};
-
-static double idletime = -1.0;
-static int pfiltered = 0;
-static int pcount = 0;
-static int kcount = 0;
-static double psize = 0;
-static double ksize = 0;
-static double esize = 0;
-static struct list_sample_data *sampledata;
-static struct list_sample_data *prev_sampledata;
-
-static void svg_header(FILE *of, struct list_sample_data *head, double graph_start, int n_cpus) {
- double w;
- double h;
- struct list_sample_data *sampledata_last;
-
- assert(head);
-
- sampledata_last = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- sampledata_last = sampledata;
- }
-
- /* min width is about 1600px due to the label */
- w = 150.0 + 10.0 + time_to_graph(sampledata_last->sampletime - graph_start);
- w = ((w < 1600.0) ? 1600.0 : w);
-
- /* height is variable based on pss, psize, ksize */
- h = 400.0 + (arg_scale_y * 30.0) /* base graphs and title */
- + (arg_pss ? (100.0 * arg_scale_y) + (arg_scale_y * 7.0) : 0.0) /* pss estimate */
- + psize + ksize + esize + (n_cpus * 15 * arg_scale_y);
-
- fprintf(of, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
- fprintf(of, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ");
- fprintf(of, "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
-
- //fprintf(of, "<g transform=\"translate(10,%d)\">\n", 1000 + 150 + (pcount * 20));
- fprintf(of, "<svg width=\"%.0fpx\" height=\"%.0fpx\" version=\"1.1\" ", w, h);
- fprintf(of, "xmlns=\"http://www.w3.org/2000/svg\">\n\n");
-
- /* write some basic info as a comment, including some help */
- fprintf(of, "<!-- This file is a bootchart SVG file. It is best rendered in a browser -->\n");
- fprintf(of, "<!-- such as Chrome, Chromium, or Firefox. Other applications that -->\n");
- fprintf(of, "<!-- render these files properly but more slowly are ImageMagick, gimp, -->\n");
- fprintf(of, "<!-- inkscape, etc. To display the files on your system, just point -->\n");
- fprintf(of, "<!-- your browser to file:///run/log/ and click. This bootchart was -->\n\n");
-
- fprintf(of, "<!-- generated by bootchart version %s, running with options: -->\n", VERSION);
- fprintf(of, "<!-- hz=\"%f\" n=\"%d\" -->\n", arg_hz, arg_samples_len);
- fprintf(of, "<!-- x=\"%f\" y=\"%f\" -->\n", arg_scale_x, arg_scale_y);
- fprintf(of, "<!-- rel=\"%d\" f=\"%d\" -->\n", arg_relative, arg_filter);
- fprintf(of, "<!-- p=\"%d\" e=\"%d\" -->\n", arg_pss, arg_entropy);
- fprintf(of, "<!-- o=\"%s\" i=\"%s\" -->\n\n", arg_output_path, arg_init_path);
-
- /* style sheet */
- fprintf(of, "<defs>\n <style type=\"text/css\">\n <![CDATA[\n");
-
- fprintf(of, " rect { stroke-width: 1; }\n");
- fprintf(of, " rect.bg { fill: rgb(255,255,255); }\n");
- fprintf(of, " rect.cpu { fill: rgb(64,64,240); stroke-width: 0; fill-opacity: 0.7; }\n");
- fprintf(of, " rect.wait { fill: rgb(240,240,0); stroke-width: 0; fill-opacity: 0.7; }\n");
- fprintf(of, " rect.bi { fill: rgb(240,128,128); stroke-width: 0; fill-opacity: 0.7; }\n");
- fprintf(of, " rect.bo { fill: rgb(192,64,64); stroke-width: 0; fill-opacity: 0.7; }\n");
- fprintf(of, " rect.ps { fill: rgb(192,192,192); stroke: rgb(128,128,128); fill-opacity: 0.7; }\n");
- fprintf(of, " rect.krnl { fill: rgb(240,240,0); stroke: rgb(128,128,128); fill-opacity: 0.7; }\n");
- fprintf(of, " rect.box { fill: rgb(240,240,240); stroke: rgb(192,192,192); }\n");
- fprintf(of, " rect.clrw { stroke-width: 0; fill-opacity: 0.7;}\n");
- fprintf(of, " line { stroke: rgb(64,64,64); stroke-width: 1; }\n");
- fprintf(of, "// line.sec1 { }\n");
- fprintf(of, " line.sec5 { stroke-width: 2; }\n");
- fprintf(of, " line.sec01 { stroke: rgb(224,224,224); stroke-width: 1; }\n");
- fprintf(of, " line.dot { stroke-dasharray: 2 4; }\n");
- fprintf(of, " line.idle { stroke: rgb(64,64,64); stroke-dasharray: 10 6; stroke-opacity: 0.7; }\n");
-
- fprintf(of, " .run { font-size: 8; font-style: italic; }\n");
- fprintf(of, " text { font-family: Verdana, Helvetica; font-size: 10; }\n");
- fprintf(of, " text.sec { font-size: 8; }\n");
- fprintf(of, " text.t1 { font-size: 24; }\n");
- fprintf(of, " text.t2 { font-size: 12; }\n");
- fprintf(of, " text.idle { font-size: 18; }\n");
-
- fprintf(of, " ]]>\n </style>\n</defs>\n\n");
-}
-
-static int svg_title(FILE *of, const char *build, int pscount, double log_start, int overrun) {
- _cleanup_free_ char *cmdline = NULL;
- _cleanup_free_ char *model = NULL;
- _cleanup_free_ char *buf = NULL;
- char date[256] = "Unknown";
- const char *cpu;
- char *c;
- time_t t;
- int r;
- struct utsname uts;
-
- r = read_one_line_file("/proc/cmdline", &cmdline);
- if (r < 0) {
- log_error_errno(r, "Unable to read cmdline: %m");
- return r;
- }
-
- /* extract root fs so we can find disk model name in sysfs */
- /* FIXME: this works only in the simple case */
- c = strstr(cmdline, "root=/dev/");
- if (c) {
- char rootbdev[4];
- char filename[32];
-
- strncpy(rootbdev, &c[10], sizeof(rootbdev) - 1);
- rootbdev[3] = '\0';
- xsprintf(filename, "/sys/block/%s/device/model", rootbdev);
-
- r = read_one_line_file(filename, &model);
- if (r < 0)
- log_info("Error reading disk model for %s: %m\n", rootbdev);
- }
-
- /* various utsname parameters */
- r = uname(&uts);
- if (r < 0) {
- log_error("Error getting uname info\n");
- return -errno;
- }
-
- /* date */
- t = time(NULL);
- r = strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", localtime(&t));
- assert_se(r > 0);
-
- /* CPU type */
- r = get_proc_field("/proc/cpuinfo", PROC_CPUINFO_MODEL, "\n", &buf);
- if (r < 0)
- cpu = "Unknown";
- else
- cpu = buf;
-
- fprintf(of, "<text class=\"t1\" x=\"0\" y=\"30\">Bootchart for %s - %s</text>\n",
- uts.nodename, date);
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"50\">System: %s %s %s %s</text>\n",
- uts.sysname, uts.release, uts.version, uts.machine);
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"65\">CPU: %s</text>\n", cpu);
- if (model)
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"80\">Disk: %s</text>\n", model);
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"95\">Boot options: %s</text>\n", cmdline);
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"110\">Build: %s</text>\n", build);
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"125\">Log start time: %.03fs</text>\n", log_start);
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"140\">Idle time: ");
-
- if (idletime >= 0.0)
- fprintf(of, "%.03fs", idletime);
- else
- fprintf(of, "Not detected");
-
- fprintf(of, "</text>\n");
- fprintf(of, "<text class=\"sec\" x=\"20\" y=\"155\">Graph data: %.03f samples/sec, recorded %i total, dropped %i samples, %i processes, %i filtered</text>\n",
- arg_hz, arg_samples_len, overrun, pscount, pfiltered);
-
- return 0;
-}
-
-static void svg_graph_box(FILE *of, struct list_sample_data *head, int height, double graph_start) {
- double d = 0.0;
- int i = 0;
- double finalsample = 0.0;
- struct list_sample_data *sampledata_last;
-
- sampledata_last = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- sampledata_last = sampledata;
- }
-
- finalsample = sampledata_last->sampletime;
-
- /* outside box, fill */
- fprintf(of, "<rect class=\"box\" x=\"%.03f\" y=\"0\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(0.0),
- time_to_graph(finalsample - graph_start),
- ps_to_graph(height));
-
- for (d = graph_start; d <= finalsample;
- d += (arg_scale_x < 2.0 ? 60.0 : arg_scale_x < 10.0 ? 1.0 : 0.1)) {
- /* lines for each second */
- if (i % 50 == 0)
- fprintf(of, " <line class=\"sec5\" x1=\"%.03f\" y1=\"0\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- time_to_graph(d - graph_start),
- time_to_graph(d - graph_start),
- ps_to_graph(height));
- else if (i % 10 == 0)
- fprintf(of, " <line class=\"sec1\" x1=\"%.03f\" y1=\"0\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- time_to_graph(d - graph_start),
- time_to_graph(d - graph_start),
- ps_to_graph(height));
- else
- fprintf(of, " <line class=\"sec01\" x1=\"%.03f\" y1=\"0\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- time_to_graph(d - graph_start),
- time_to_graph(d - graph_start),
- ps_to_graph(height));
-
- /* time label */
- if (i % 10 == 0)
- fprintf(of, " <text class=\"sec\" x=\"%.03f\" y=\"%.03f\" >%.01fs</text>\n",
- time_to_graph(d - graph_start),
- -5.0, d - graph_start);
-
- i++;
- }
-}
-
-/* xml comments must not contain "--" */
-static char* xml_comment_encode(const char* name) {
- char *enc_name, *p;
-
- enc_name = strdup(name);
- if (!enc_name)
- return NULL;
-
- for (p = enc_name; *p; p++)
- if (p[0] == '-' && p[1] == '-')
- p[1] = '_';
-
- return enc_name;
-}
-
-static void svg_pss_graph(FILE *of,
- struct list_sample_data *head,
- struct ps_struct *ps_first,
- double graph_start) {
- struct ps_struct *ps;
- int i;
- struct list_sample_data *sampledata_last;
-
- sampledata_last = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- sampledata_last = sampledata;
- }
-
-
- fprintf(of, "\n\n<!-- Pss memory size graph -->\n");
-
- fprintf(of, "\n <text class=\"t2\" x=\"5\" y=\"-15\">Memory allocation - Pss</text>\n");
-
- /* vsize 1000 == 1000mb */
- svg_graph_box(of, head, 100, graph_start);
- /* draw some hlines for usable memory sizes */
- for (i = 100000; i < 1000000; i += 100000) {
- fprintf(of, " <line class=\"sec01\" x1=\"%.03f\" y1=\"%.0f\" x2=\"%.03f\" y2=\"%.0f\"/>\n",
- time_to_graph(.0),
- kb_to_graph(i),
- time_to_graph(sampledata_last->sampletime - graph_start),
- kb_to_graph(i));
- fprintf(of, " <text class=\"sec\" x=\"%.03f\" y=\"%.0f\">%dM</text>\n",
- time_to_graph(sampledata_last->sampletime - graph_start) + 5,
- kb_to_graph(i), (1000000 - i) / 1000);
- }
- fprintf(of, "\n");
-
- /* now plot the graph itself */
- i = 1;
- prev_sampledata = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int bottom;
- int top;
- struct ps_sched_struct *cross_place;
-
- bottom = 0;
- top = 0;
-
- /* put all the small pss blocks into the bottom */
- ps = ps_first;
- while (ps->next_ps) {
- ps = ps->next_ps;
- if (!ps)
- continue;
- ps->sample = ps->first;
- while (ps->sample->next) {
- ps->sample = ps->sample->next;
- if (ps->sample->sampledata == sampledata)
- break;
- }
- if (ps->sample->sampledata == sampledata) {
- if (ps->sample->pss <= (100 * arg_scale_y))
- top += ps->sample->pss;
- break;
- }
- }
- while (ps->sample->cross) {
- cross_place = ps->sample->cross;
- ps = ps->sample->cross->ps_new;
- ps->sample = cross_place;
- if (ps->sample->pss <= (100 * arg_scale_y))
- top += ps->sample->pss;
- }
-
- fprintf(of, " <rect class=\"clrw\" style=\"fill: %s\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- "rgb(64,64,64)",
- time_to_graph(prev_sampledata->sampletime - graph_start),
- kb_to_graph(1000000.0 - top),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- kb_to_graph(top - bottom));
- bottom = top;
-
- /* now plot the ones that are of significant size */
- ps = ps_first;
- while (ps->next_ps) {
- ps = ps->next_ps;
- if (!ps)
- continue;
- ps->sample = ps->first;
- while (ps->sample->next) {
- ps->sample = ps->sample->next;
- if (ps->sample->sampledata == sampledata)
- break;
- }
- /* don't draw anything smaller than 2mb */
- if (ps->sample->sampledata != sampledata)
- continue;
- if (ps->sample->pss > (100 * arg_scale_y)) {
- top = bottom + ps->sample->pss;
- fprintf(of, " <rect class=\"clrw\" style=\"fill: %s\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- colorwheel[ps->pid % 12],
- time_to_graph(prev_sampledata->sampletime - graph_start),
- kb_to_graph(1000000.0 - top),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- kb_to_graph(top - bottom));
- bottom = top;
- }
- break;
- }
-
- while ((cross_place = ps->sample->cross)) {
- ps = ps->sample->cross->ps_new;
- ps->sample = cross_place;
- if (ps->sample->pss > (100 * arg_scale_y)) {
- top = bottom + ps->sample->pss;
- fprintf(of, " <rect class=\"clrw\" style=\"fill: %s\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- colorwheel[ps->pid % 12],
- time_to_graph(prev_sampledata->sampletime - graph_start),
- kb_to_graph(1000000.0 - top),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- kb_to_graph(top - bottom));
- bottom = top;
- }
- }
-
- prev_sampledata = sampledata;
- i++;
- }
-
- /* overlay all the text labels */
- i = 1;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int bottom;
- int top = 0;
- struct ps_sched_struct *prev_sample;
- struct ps_sched_struct *cross_place;
-
- /* put all the small pss blocks into the bottom */
- ps = ps_first->next_ps;
- while (ps->next_ps) {
- ps = ps->next_ps;
- if (!ps)
- continue;
-
- ps->sample = ps->first;
- while (ps->sample->next) {
- ps->sample = ps->sample->next;
- if (ps->sample->sampledata == sampledata)
- break;
- }
-
- if (ps->sample->sampledata == sampledata) {
- if (ps->sample->pss <= (100 * arg_scale_y))
- top += ps->sample->pss;
-
- break;
- }
- }
-
- while ((cross_place = ps->sample->cross)) {
- ps = ps->sample->cross->ps_new;
- ps->sample = cross_place;
- if (ps->sample->pss <= (100 * arg_scale_y))
- top += ps->sample->pss;
- }
- bottom = top;
-
- /* now plot the ones that are of significant size */
- ps = ps_first;
- while (ps->next_ps) {
- prev_sample = ps->sample;
- ps = ps->next_ps;
- if (!ps)
- continue;
- ps->sample = ps->first;
- while (ps->sample->next) {
- prev_sample = ps->sample;
- ps->sample = ps->sample->next;
- if (ps->sample->sampledata == sampledata)
- break;
- }
- /* don't draw anything smaller than 2mb */
- if (ps->sample->sampledata == sampledata) {
- if (ps->sample->pss > (100 * arg_scale_y)) {
- top = bottom + ps->sample->pss;
- /* draw a label with the process / PID */
- if ((i == 1) || (prev_sample->pss <= (100 * arg_scale_y)))
- fprintf(of, " <text x=\"%.03f\" y=\"%.03f\"><![CDATA[%s]]> [%i]</text>\n",
- time_to_graph(sampledata->sampletime - graph_start),
- kb_to_graph(1000000.0 - bottom - ((top - bottom) / 2)),
- ps->name, ps->pid);
- bottom = top;
- }
- break;
- }
- }
- while ((cross_place = ps->sample->cross)) {
- ps = ps->sample->cross->ps_new;
- ps->sample = cross_place;
- prev_sample = ps->sample->prev;
- if (ps->sample->pss > (100 * arg_scale_y)) {
- top = bottom + ps->sample->pss;
- /* draw a label with the process / PID */
- if ((i == 1) || (prev_sample->pss <= (100 * arg_scale_y)))
- fprintf(of, " <text x=\"%.03f\" y=\"%.03f\"><![CDATA[%s]]> [%i]</text>\n",
- time_to_graph(sampledata->sampletime - graph_start),
- kb_to_graph(1000000.0 - bottom - ((top - bottom) / 2)),
- ps->name, ps->pid);
- bottom = top;
- }
- }
-
- i++;
- }
-
- /* debug output - full data dump */
- fprintf(of, "\n\n<!-- PSS map - csv format -->\n");
- ps = ps_first;
- while (ps->next_ps) {
- _cleanup_free_ char *enc_name = NULL;
- ps = ps->next_ps;
- if (!ps)
- continue;
-
- enc_name = xml_comment_encode(ps->name);
- if (!enc_name)
- continue;
-
- fprintf(of, "<!-- %s [%d] pss=", enc_name, ps->pid);
-
- ps->sample = ps->first;
- while (ps->sample->next) {
- ps->sample = ps->sample->next;
- fprintf(of, "%d," , ps->sample->pss);
- }
-
- fprintf(of, " -->\n");
- }
-
-}
-
-static void svg_io_bi_bar(FILE *of,
- struct list_sample_data *head,
- int n_samples,
- double graph_start,
- double interval) {
-
- double max = 0.0;
- double range;
- int max_here = 0;
- int i;
- int k;
- struct list_sample_data *start_sampledata;
- struct list_sample_data *stop_sampledata;
-
- fprintf(of, "<!-- IO utilization graph - In -->\n");
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">IO utilization - read</text>\n");
-
- /*
- * calculate rounding range
- *
- * We need to round IO data since IO block data is not updated on
- * each poll. Applying a smoothing function loses some burst data,
- * so keep the smoothing range short.
- */
- range = 0.25 / (1.0 / arg_hz);
- if (range < 2.0)
- range = 2.0; /* no smoothing */
-
- /* surrounding box */
- svg_graph_box(of, head, 5, graph_start);
-
- /* find the max IO first */
- i = 1;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int start;
- int stop;
- int diff;
- double tot;
-
- start = MAX(i - ((range / 2) - 1), 0);
- stop = MIN(i + (range / 2), n_samples - 1);
- diff = (stop - start);
-
- start_sampledata = sampledata;
- stop_sampledata = sampledata;
-
- for (k = 0; k < ((range/2) - 1) && start_sampledata->link_next; k++)
- start_sampledata = start_sampledata->link_next;
-
- for (k = 0; k < (range/2) && stop_sampledata->link_prev; k++)
- stop_sampledata = stop_sampledata->link_prev;
-
- tot = (double)(stop_sampledata->blockstat.bi - start_sampledata->blockstat.bi) / diff;
-
- if (tot > max) {
- max = tot;
- max_here = i;
- }
-
- tot = (double)(stop_sampledata->blockstat.bo - start_sampledata->blockstat.bo) / diff;
-
- if (tot > max)
- max = tot;
-
- i++;
- }
-
- /* plot bi */
- i = 1;
- prev_sampledata = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int start;
- int stop;
- int diff;
- double tot;
- double pbi = 0;
-
- start = MAX(i - ((range / 2) - 1), 0);
- stop = MIN(i + (range / 2), n_samples);
- diff = (stop - start);
-
- start_sampledata = sampledata;
- stop_sampledata = sampledata;
-
- for (k = 0; k < ((range/2)-1) && start_sampledata->link_next; k++)
- start_sampledata = start_sampledata->link_next;
-
- for (k = 0; k < (range/2) && stop_sampledata->link_prev; k++)
- stop_sampledata = stop_sampledata->link_prev;
-
- tot = (double)(stop_sampledata->blockstat.bi - start_sampledata->blockstat.bi) / diff;
-
- if (max > 0)
- pbi = tot / max;
-
- if (pbi > 0.001)
- fprintf(of, "<rect class=\"bi\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev_sampledata->sampletime - graph_start),
- (arg_scale_y * 5) - (pbi * (arg_scale_y * 5)),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- pbi * (arg_scale_y * 5));
-
- /* labels around highest value */
- if (i == max_here)
- fprintf(of, " <text class=\"sec\" x=\"%.03f\" y=\"%.03f\">%0.2fmb/sec</text>\n",
- time_to_graph(sampledata->sampletime - graph_start) + 5,
- ((arg_scale_y * 5) - (pbi * (arg_scale_y * 5))) + 15,
- max / 1024.0 / (interval / 1000000000.0));
-
- i++;
- prev_sampledata = sampledata;
- }
-}
-
-static void svg_io_bo_bar(FILE *of,
- struct list_sample_data *head,
- int n_samples,
- double graph_start,
- double interval) {
- double max = 0.0;
- double range;
- int max_here = 0;
- int i;
- int k;
- struct list_sample_data *start_sampledata;
- struct list_sample_data *stop_sampledata;
-
- fprintf(of, "<!-- IO utilization graph - out -->\n");
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">IO utilization - write</text>\n");
-
- /*
- * calculate rounding range
- *
- * We need to round IO data since IO block data is not updated on
- * each poll. Applying a smoothing function loses some burst data,
- * so keep the smoothing range short.
- */
- range = 0.25 / (1.0 / arg_hz);
- if (range < 2.0)
- range = 2.0; /* no smoothing */
-
- /* surrounding box */
- svg_graph_box(of, head, 5, graph_start);
-
- /* find the max IO first */
- i = 0;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int start;
- int stop;
- int diff;
- double tot;
-
- start = MAX(i - ((range / 2) - 1), 0);
- stop = MIN(i + (range / 2), n_samples - 1);
- diff = (stop - start);
-
- start_sampledata = sampledata;
- stop_sampledata = sampledata;
-
- for (k = 0; k < (range/2) - 1 && start_sampledata->link_next; k++)
- start_sampledata = start_sampledata->link_next;
-
- for (k = 0; k < (range/2) && stop_sampledata->link_prev; k++)
- stop_sampledata = stop_sampledata->link_prev;
-
- tot = (double)(stop_sampledata->blockstat.bi - start_sampledata->blockstat.bi) / diff;
- if (tot > max)
- max = tot;
-
- tot = (double)(stop_sampledata->blockstat.bo - start_sampledata->blockstat.bo) / diff;
- if (tot > max) {
- max = tot;
- max_here = i;
- }
-
- i++;
- }
-
- /* plot bo */
- prev_sampledata = head;
- i = 1;
-
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int start, stop, diff;
- double tot, pbo;
-
- pbo = 0;
-
- start = MAX(i - ((range / 2) - 1), 0);
- stop = MIN(i + (range / 2), n_samples);
- diff = (stop - start);
-
- start_sampledata = sampledata;
- stop_sampledata = sampledata;
-
- for (k = 0; k < ((range/2)-1) && start_sampledata->link_next; k++)
- start_sampledata = start_sampledata->link_next;
-
- for (k = 0; k < (range/2) && stop_sampledata->link_prev; k++)
- stop_sampledata = stop_sampledata->link_prev;
-
- tot = (double)(stop_sampledata->blockstat.bo - start_sampledata->blockstat.bo)
- / diff;
-
- if (max > 0)
- pbo = tot / max;
-
- if (pbo > 0.001)
- fprintf(of, "<rect class=\"bo\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev_sampledata->sampletime - graph_start),
- (arg_scale_y * 5) - (pbo * (arg_scale_y * 5)),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- pbo * (arg_scale_y * 5));
-
- /* labels around highest bo value */
- if (i == max_here)
- fprintf(of, " <text class=\"sec\" x=\"%.03f\" y=\"%.03f\">%0.2fmb/sec</text>\n",
- time_to_graph(sampledata->sampletime - graph_start) + 5,
- ((arg_scale_y * 5) - (pbo * (arg_scale_y * 5))),
- max / 1024.0 / (interval / 1000000000.0));
-
- i++;
- prev_sampledata = sampledata;
- }
-}
-
-static void svg_cpu_bar(FILE *of, struct list_sample_data *head, int n_cpus, int cpu_num, double graph_start) {
-
- fprintf(of, "<!-- CPU utilization graph -->\n");
-
- if (cpu_num < 0)
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">CPU[overall] utilization</text>\n");
- else
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">CPU[%d] utilization</text>\n", cpu_num);
-
- /* surrounding box */
- svg_graph_box(of, head, 5, graph_start);
-
- /* bars for each sample, proportional to the CPU util. */
- prev_sampledata = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int c;
- double trt;
- double ptrt;
-
- ptrt = trt = 0.0;
-
- if (cpu_num < 0)
- for (c = 0; c < n_cpus; c++)
- trt += sampledata->runtime[c] - prev_sampledata->runtime[c];
- else
- trt = sampledata->runtime[cpu_num] - prev_sampledata->runtime[cpu_num];
-
- trt = trt / 1000000000.0;
-
- if (cpu_num < 0)
- trt = trt / (double)n_cpus;
-
- if (trt > 0.0)
- ptrt = trt / (sampledata->sampletime - prev_sampledata->sampletime);
-
- if (ptrt > 1.0)
- ptrt = 1.0;
-
- if (ptrt > 0.001)
- fprintf(of, "<rect class=\"cpu\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev_sampledata->sampletime - graph_start),
- (arg_scale_y * 5) - (ptrt * (arg_scale_y * 5)),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- ptrt * (arg_scale_y * 5));
-
- prev_sampledata = sampledata;
- }
-}
-
-static void svg_wait_bar(FILE *of, struct list_sample_data *head, int n_cpus, int cpu_num, double graph_start) {
-
- fprintf(of, "<!-- Wait time aggregation box -->\n");
-
- if (cpu_num < 0)
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">CPU[overall] wait</text>\n");
- else
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">CPU[%d] wait</text>\n", cpu_num);
-
- /* surrounding box */
- svg_graph_box(of, head, 5, graph_start);
-
- /* bars for each sample, proportional to the CPU util. */
- prev_sampledata = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- int c;
- double twt;
- double ptwt;
-
- ptwt = twt = 0.0;
-
- if (cpu_num < 0)
- for (c = 0; c < n_cpus; c++)
- twt += sampledata->waittime[c] - prev_sampledata->waittime[c];
- else
- twt = sampledata->waittime[cpu_num] - prev_sampledata->waittime[cpu_num];
-
- twt = twt / 1000000000.0;
-
- if (cpu_num < 0)
- twt = twt / (double)n_cpus;
-
- if (twt > 0.0)
- ptwt = twt / (sampledata->sampletime - prev_sampledata->sampletime);
-
- if (ptwt > 1.0)
- ptwt = 1.0;
-
- if (ptwt > 0.001)
- fprintf(of, "<rect class=\"wait\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev_sampledata->sampletime - graph_start),
- ((arg_scale_y * 5) - (ptwt * (arg_scale_y * 5))),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- ptwt * (arg_scale_y * 5));
-
- prev_sampledata = sampledata;
- }
-}
-
-static void svg_entropy_bar(FILE *of, struct list_sample_data *head, double graph_start) {
-
- fprintf(of, "<!-- entropy pool graph -->\n");
-
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">Entropy pool size</text>\n");
- /* surrounding box */
- svg_graph_box(of, head, 5, graph_start);
-
- /* bars for each sample, scale 0-4096 */
- prev_sampledata = head;
- LIST_FOREACH_BEFORE(link, sampledata, head) {
- fprintf(of, "<rect class=\"cpu\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev_sampledata->sampletime - graph_start),
- ((arg_scale_y * 5) - ((sampledata->entropy_avail / 4096.) * (arg_scale_y * 5))),
- time_to_graph(sampledata->sampletime - prev_sampledata->sampletime),
- (sampledata->entropy_avail / 4096.) * (arg_scale_y * 5));
- prev_sampledata = sampledata;
- }
-}
-
-static struct ps_struct *get_next_ps(struct ps_struct *ps, struct ps_struct *ps_first) {
- /*
- * walk the list of processes and return the next one to be
- * painted
- */
- if (ps == ps_first)
- return ps->next_ps;
-
- /* go deep */
- if (ps->children)
- return ps->children;
-
- /* find siblings */
- if (ps->next)
- return ps->next;
-
- /* go back for parent siblings */
- for (;;) {
- if (ps->parent && ps->parent->next)
- return ps->parent->next;
-
- ps = ps->parent;
- if (!ps)
- return ps;
- }
-
- return NULL;
-}
-
-static bool ps_filter(struct ps_struct *ps) {
- if (!arg_filter)
- return false;
-
- /* can't draw data when there is only 1 sample (need start + stop) */
- if (ps->first == ps->last)
- return true;
-
- /* don't filter kthreadd */
- if (ps->pid == 2)
- return false;
-
- /* drop stuff that doesn't use any real CPU time */
- if (ps->total <= 0.001)
- return true;
-
- return 0;
-}
-
-static void svg_do_initcall(FILE *of, struct list_sample_data *head, int count_only, double graph_start) {
- _cleanup_pclose_ FILE *f = NULL;
- double t;
- char func[256];
- int ret;
- int usecs;
-
- /* can't plot initcall when disabled or in relative mode */
- if (!arg_initcall || arg_relative) {
- kcount = 0;
- return;
- }
-
- if (!count_only) {
- fprintf(of, "<!-- initcall -->\n");
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">Kernel init threads</text>\n");
- /* surrounding box */
- svg_graph_box(of, head, kcount, graph_start);
- }
-
- kcount = 0;
-
- /*
- * Initcall graphing - parses dmesg buffer and displays kernel threads
- * This somewhat uses the same methods and scaling to show processes
- * but looks a lot simpler. It's overlaid entirely onto the PS graph
- * when appropriate.
- */
-
- f = popen("dmesg", "r");
- if (!f)
- return;
-
- while (!feof(f)) {
- int c;
- int z = 0;
- char l[256];
-
- if (fgets(l, sizeof(l) - 1, f) == NULL)
- continue;
-
- c = sscanf(l, "[%lf] initcall %s %*s %d %*s %d %*s",
- &t, func, &ret, &usecs);
- if (c != 4) {
- /* also parse initcalls done by module loading */
- c = sscanf(l, "[%lf] initcall %s %*s %*s %d %*s %d %*s",
- &t, func, &ret, &usecs);
- if (c != 4)
- continue;
- }
-
- /* chop the +0xXX/0xXX stuff */
- while(func[z] != '+')
- z++;
- func[z] = 0;
-
- if (count_only) {
- /* filter out irrelevant stuff */
- if (usecs >= 1000)
- kcount++;
- continue;
- }
-
- fprintf(of, "<!-- thread=\"%s\" time=\"%.3f\" elapsed=\"%d\" result=\"%d\" -->\n",
- func, t, usecs, ret);
-
- if (usecs < 1000)
- continue;
-
- /* rect */
- fprintf(of, " <rect class=\"krnl\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(t - (usecs / 1000000.0)),
- ps_to_graph(kcount),
- time_to_graph(usecs / 1000000.0),
- ps_to_graph(1));
-
- /* label */
- fprintf(of, " <text x=\"%.03f\" y=\"%.03f\">%s <tspan class=\"run\">%.03fs</tspan></text>\n",
- time_to_graph(t - (usecs / 1000000.0)) + 5,
- ps_to_graph(kcount) + 15,
- func, usecs / 1000000.0);
-
- kcount++;
- }
-}
-
-static void svg_ps_bars(FILE *of,
- struct list_sample_data *head,
- int n_samples,
- int n_cpus,
- struct ps_struct *ps_first,
- double graph_start,
- double interval) {
-
- struct ps_struct *ps;
- int i = 0;
- int j = 0;
- int pid;
- double w = 0.0;
-
- fprintf(of, "<!-- Process graph -->\n");
- fprintf(of, "<text class=\"t2\" x=\"5\" y=\"-15\">Processes</text>\n");
-
- /* surrounding box */
- svg_graph_box(of, head, pcount, graph_start);
-
- /* pass 2 - ps boxes */
- ps = ps_first;
- while ((ps = get_next_ps(ps, ps_first))) {
- _cleanup_free_ char *enc_name = NULL, *escaped = NULL;
- double endtime;
- double starttime;
- int t;
-
- if (!utf8_is_printable(ps->name, strlen(ps->name)))
- escaped = utf8_escape_non_printable(ps->name);
-
- enc_name = xml_comment_encode(escaped ? escaped : ps->name);
- if (!enc_name)
- continue;
-
- /* leave some trace of what we actually filtered etc. */
- fprintf(of, "<!-- %s [%i] ppid=%i runtime=%.03fs -->\n", enc_name, ps->pid,
- ps->ppid, ps->total);
-
- starttime = ps->first->sampledata->sampletime;
-
- if (!ps_filter(ps)) {
- /* remember where _to_ our children need to draw a line */
- ps->pos_x = time_to_graph(starttime - graph_start);
- ps->pos_y = ps_to_graph(j+1); /* bottom left corner */
- } else if (ps->parent){
- /* hook children to our parent coords instead */
- ps->pos_x = ps->parent->pos_x;
- ps->pos_y = ps->parent->pos_y;
-
- /* if this is the last child, we might still need to draw a connecting line */
- if ((!ps->next) && (ps->parent))
- fprintf(of, " <line class=\"dot\" x1=\"%.03f\" y1=\"%.03f\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- ps->parent->pos_x,
- ps_to_graph(j-1) + 10.0, /* whee, use the last value here */
- ps->parent->pos_x,
- ps->parent->pos_y);
- continue;
- }
-
- endtime = ps->last->sampledata->sampletime;
- fprintf(of, " <rect class=\"ps\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(starttime - graph_start),
- ps_to_graph(j),
- time_to_graph(ps->last->sampledata->sampletime - starttime),
- ps_to_graph(1));
-
- /* paint cpu load over these */
- ps->sample = ps->first;
- t = 1;
- while (ps->sample->next) {
- double rt, prt;
- double wt, wrt;
- struct ps_sched_struct *prev;
-
- prev = ps->sample;
- ps->sample = ps->sample->next;
-
- /* calculate over interval */
- rt = ps->sample->runtime - prev->runtime;
- wt = ps->sample->waittime - prev->waittime;
-
- prt = (rt / 1000000000) / (ps->sample->sampledata->sampletime - prev->sampledata->sampletime);
- wrt = (wt / 1000000000) / (ps->sample->sampledata->sampletime - prev->sampledata->sampletime);
-
- /* this can happen if timekeeping isn't accurate enough */
- if (prt > 1.0)
- prt = 1.0;
- if (wrt > 1.0)
- wrt = 1.0;
-
- if ((prt < 0.1) && (wrt < 0.1)) /* =~ 26 (color threshold) */
- continue;
-
- fprintf(of, " <rect class=\"wait\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev->sampledata->sampletime - graph_start),
- ps_to_graph(j),
- time_to_graph(ps->sample->sampledata->sampletime - prev->sampledata->sampletime),
- ps_to_graph(wrt));
-
- /* draw cpu over wait - TODO figure out how/why run + wait > interval */
- fprintf(of, " <rect class=\"cpu\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n",
- time_to_graph(prev->sampledata->sampletime - graph_start),
- ps_to_graph(j + (1.0 - prt)),
- time_to_graph(ps->sample->sampledata->sampletime - prev->sampledata->sampletime),
- ps_to_graph(prt));
- t++;
- }
-
- /* determine where to display the process name */
- if ((endtime - starttime) < 1.5)
- /* too small to fit label inside the box */
- w = endtime;
- else
- w = starttime;
-
- /* text label of process name */
- fprintf(of, " <text x=\"%.03f\" y=\"%.03f\"><![CDATA[%s]]> [%i]<tspan class=\"run\">%.03fs</tspan> %s</text>\n",
- time_to_graph(w - graph_start) + 5.0,
- ps_to_graph(j) + 14.0,
- escaped ? escaped : ps->name,
- ps->pid,
- (ps->last->runtime - ps->first->runtime) / 1000000000.0,
- arg_show_cgroup ? ps->cgroup : "");
- /* paint lines to the parent process */
- if (ps->parent) {
- /* horizontal part */
- fprintf(of, " <line class=\"dot\" x1=\"%.03f\" y1=\"%.03f\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- time_to_graph(starttime - graph_start),
- ps_to_graph(j) + 10.0,
- ps->parent->pos_x,
- ps_to_graph(j) + 10.0);
-
- /* one vertical line connecting all the horizontal ones up */
- if (!ps->next)
- fprintf(of, " <line class=\"dot\" x1=\"%.03f\" y1=\"%.03f\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- ps->parent->pos_x,
- ps_to_graph(j) + 10.0,
- ps->parent->pos_x,
- ps->parent->pos_y);
- }
-
- j++; /* count boxes */
-
- fprintf(of, "\n");
- }
-
- /* last pass - determine when idle */
- pid = getpid();
- /* make sure we start counting from the point where we actually have
- * data: assume that bootchart's first sample is when data started
- */
-
- ps = ps_first;
- while (ps->next_ps) {
- ps = ps->next_ps;
- if (ps->pid == pid)
- break;
- }
-
- /* need to know last node first */
- ps->sample = ps->first;
- i = ps->sample->next->sampledata->counter;
-
- while (ps->sample->next && i<(n_samples-(arg_hz/2))) {
- double crt;
- double brt;
- int c;
- int ii;
- struct ps_sched_struct *sample_hz;
-
- ps->sample = ps->sample->next;
- sample_hz = ps->sample;
- for (ii = 0; (ii < (int)arg_hz/2) && sample_hz->next; ii++)
- sample_hz = sample_hz->next;
-
- /* subtract bootchart cpu utilization from total */
- crt = 0.0;
- for (c = 0; c < n_cpus; c++)
- crt += sample_hz->sampledata->runtime[c] - ps->sample->sampledata->runtime[c];
-
- brt = sample_hz->runtime - ps->sample->runtime;
- /*
- * our definition of "idle":
- *
- * if for (hz / 2) we've used less CPU than (interval / 2) ...
- * defaults to 4.0%, which experimentally, is where atom idles
- */
- if ((crt - brt) < (interval / 2.0)) {
- idletime = ps->sample->sampledata->sampletime - graph_start;
- fprintf(of, "\n<!-- idle detected at %.03f seconds -->\n", idletime);
- fprintf(of, "<line class=\"idle\" x1=\"%.03f\" y1=\"%.03f\" x2=\"%.03f\" y2=\"%.03f\" />\n",
- time_to_graph(idletime),
- -arg_scale_y,
- time_to_graph(idletime),
- ps_to_graph(pcount) + arg_scale_y);
- fprintf(of, "<text class=\"idle\" x=\"%.03f\" y=\"%.03f\">%.01fs</text>\n",
- time_to_graph(idletime) + 5.0,
- ps_to_graph(pcount) + arg_scale_y,
- idletime);
- break;
- }
-
- i++;
- }
-}
-
-static void svg_top_ten_cpu(FILE *of, struct ps_struct *ps_first) {
- struct ps_struct *top[10];
- struct ps_struct emptyps = {};
- struct ps_struct *ps;
- int n, m;
-
- for (n = 0; n < (int) ELEMENTSOF(top); n++)
- top[n] = &emptyps;
-
- /* walk all ps's and setup ptrs */
- ps = ps_first;
- while ((ps = get_next_ps(ps, ps_first))) {
- for (n = 0; n < 10; n++) {
- if (ps->total <= top[n]->total)
- continue;
- /* cascade insert */
- for (m = 9; m > n; m--)
- top[m] = top[m-1];
- top[n] = ps;
- break;
- }
- }
-
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"0\">Top CPU consumers:</text>\n");
- for (n = 0; n < 10; n++)
- fprintf(of, "<text class=\"t3\" x=\"20\" y=\"%d\">%3.03fs - <![CDATA[%s]]> [%d]</text>\n",
- 20 + (n * 13),
- top[n]->total,
- top[n]->name,
- top[n]->pid);
-}
-
-static void svg_top_ten_pss(FILE *of, struct ps_struct *ps_first) {
- struct ps_struct *top[10];
- struct ps_struct emptyps = {};
- struct ps_struct *ps;
- int n, m;
-
- for (n = 0; n < (int) ELEMENTSOF(top); n++)
- top[n] = &emptyps;
-
- /* walk all ps's and setup ptrs */
- ps = ps_first;
- while ((ps = get_next_ps(ps, ps_first))) {
- for (n = 0; n < 10; n++) {
- if (ps->pss_max <= top[n]->pss_max)
- continue;
-
- /* cascade insert */
- for (m = 9; m > n; m--)
- top[m] = top[m-1];
- top[n] = ps;
- break;
- }
- }
-
- fprintf(of, "<text class=\"t2\" x=\"20\" y=\"0\">Top PSS consumers:</text>\n");
- for (n = 0; n < 10; n++)
- fprintf(of, "<text class=\"t3\" x=\"20\" y=\"%d\">%dK - <![CDATA[%s]]> [%d]</text>\n",
- 20 + (n * 13),
- top[n]->pss_max,
- top[n]->name,
- top[n]->pid);
-}
-
-int svg_do(FILE *of,
- const char *build,
- struct list_sample_data *head,
- struct ps_struct *ps_first,
- int n_samples,
- int pscount,
- int n_cpus,
- double graph_start,
- double log_start,
- double interval,
- int overrun) {
-
- struct ps_struct *ps;
- double offset = 7;
- int r, c;
-
- sampledata = head;
- LIST_FIND_TAIL(link, sampledata, head);
- ps = ps_first;
-
- /* count initcall thread count first */
- svg_do_initcall(of, head, 1, graph_start);
- ksize = kcount ? ps_to_graph(kcount) + (arg_scale_y * 2) : 0;
-
- /* then count processes */
- while ((ps = get_next_ps(ps, ps_first))) {
- if (!ps_filter(ps))
- pcount++;
- else
- pfiltered++;
- }
- psize = ps_to_graph(pcount) + (arg_scale_y * 2);
-
- esize = (arg_entropy ? arg_scale_y * 7 : 0);
-
- /* after this, we can draw the header with proper sizing */
- svg_header(of, head, graph_start, arg_percpu ? n_cpus : 0);
- fprintf(of, "<rect class=\"bg\" width=\"100%%\" height=\"100%%\" />\n\n");
-
- fprintf(of, "<g transform=\"translate(10,400)\">\n");
- svg_io_bi_bar(of, head, n_samples, graph_start, interval);
- fprintf(of, "</g>\n\n");
-
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset));
- svg_io_bo_bar(of, head, n_samples, graph_start, interval);
- fprintf(of, "</g>\n\n");
-
- for (c = -1; c < (arg_percpu ? n_cpus : 0); c++) {
- offset += 7;
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset));
- svg_cpu_bar(of, head, n_cpus, c, graph_start);
- fprintf(of, "</g>\n\n");
-
- offset += 7;
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset));
- svg_wait_bar(of, head, n_cpus, c, graph_start);
- fprintf(of, "</g>\n\n");
- }
-
- if (kcount) {
- offset += 7;
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset));
- svg_do_initcall(of, head, 0, graph_start);
- fprintf(of, "</g>\n\n");
- }
-
- offset += 7;
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset) + ksize);
- svg_ps_bars(of, head, n_samples, n_cpus, ps_first, graph_start, interval);
- fprintf(of, "</g>\n\n");
-
- fprintf(of, "<g transform=\"translate(10, 0)\">\n");
- r = svg_title(of, build, pscount, log_start, overrun);
- fprintf(of, "</g>\n\n");
-
- if (r < 0)
- return r;
-
- fprintf(of, "<g transform=\"translate(10,200)\">\n");
- svg_top_ten_cpu(of, ps_first);
- fprintf(of, "</g>\n\n");
-
- if (arg_entropy) {
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset) + ksize + psize);
- svg_entropy_bar(of, head, graph_start);
- fprintf(of, "</g>\n\n");
- }
-
- if (arg_pss) {
- fprintf(of, "<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * offset) + ksize + psize + esize);
- svg_pss_graph(of, head, ps_first, graph_start);
- fprintf(of, "</g>\n\n");
-
- fprintf(of, "<g transform=\"translate(410,200)\">\n");
- svg_top_ten_pss(of, ps_first);
- fprintf(of, "</g>\n\n");
- }
-
- /* fprintf footer */
- fprintf(of, "\n</svg>\n");
-
- return 0;
-}
diff --git a/src/systemd-bus-proxyd/bus-proxyd.c b/src/systemd-bus-proxyd/bus-proxyd.c
deleted file mode 100644
index 17b80c3e9a..0000000000
--- a/src/systemd-bus-proxyd/bus-proxyd.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2013 Daniel Mack
- Copyright 2014 Kay Sievers
- Copyright 2015 David Herrmann
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <getopt.h>
-#include <pthread.h>
-#include <stddef.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <systemd/sd-daemon.h>
-
-#include "alloc-util.h"
-#include "bus-internal.h"
-#include "bus-xml-policy.h"
-#include "capability-util.h"
-#include "def.h"
-#include "fd-util.h"
-#include "formats-util.h"
-#include "log.h"
-#include "proxy.h"
-#include "string-util.h"
-#include "strv.h"
-#include "user-util.h"
-#include "util.h"
-
-static char *arg_address = NULL;
-static char **arg_configuration = NULL;
-
-typedef struct {
- int fd;
- SharedPolicy *policy;
- uid_t bus_uid;
-} ClientContext;
-
-static ClientContext *client_context_free(ClientContext *c) {
- if (!c)
- return NULL;
-
- safe_close(c->fd);
- free(c);
-
- return NULL;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(ClientContext*, client_context_free);
-
-static int client_context_new(ClientContext **out) {
- _cleanup_(client_context_freep) ClientContext *c = NULL;
-
- c = new0(ClientContext, 1);
- if (!c)
- return -ENOMEM;
-
- c->fd = -1;
-
- *out = c;
- c = NULL;
- return 0;
-}
-
-static void *run_client(void *userdata) {
- _cleanup_(client_context_freep) ClientContext *c = userdata;
- _cleanup_(proxy_freep) Proxy *p = NULL;
- char comm[16];
- int r;
-
- r = proxy_new(&p, c->fd, c->fd, arg_address);
- c->fd = -1;
-
- if (r < 0)
- goto exit;
-
- /* set comm to "p$PIDu$UID" and suffix with '*' if truncated */
- r = snprintf(comm, sizeof(comm), "p" PID_FMT "u" UID_FMT, p->local_creds.pid, p->local_creds.uid);
- if (r >= (ssize_t)sizeof(comm))
- comm[sizeof(comm) - 2] = '*';
- (void) prctl(PR_SET_NAME, comm);
-
- r = proxy_set_policy(p, c->policy, arg_configuration);
- if (r < 0)
- goto exit;
-
- r = proxy_hello_policy(p, c->bus_uid);
- if (r < 0)
- goto exit;
-
- r = proxy_run(p);
-
-exit:
- return NULL;
-}
-
-static int loop_clients(int accept_fd, uid_t bus_uid) {
- _cleanup_(shared_policy_freep) SharedPolicy *sp = NULL;
- pthread_attr_t attr;
- int r;
-
- r = pthread_attr_init(&attr);
- if (r != 0)
- return log_error_errno(r, "Cannot initialize pthread attributes: %m");
-
- r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (r != 0) {
- r = log_error_errno(r, "Cannot mark pthread attributes as detached: %m");
- goto finish;
- }
-
- r = shared_policy_new(&sp);
- if (r < 0)
- goto finish;
-
- for (;;) {
- ClientContext *c;
- pthread_t tid;
- int fd;
-
- fd = accept4(accept_fd, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
- if (fd < 0) {
- if (errno == EAGAIN || errno == EINTR)
- continue;
-
- r = log_error_errno(errno, "accept4() failed: %m");
- goto finish;
- }
-
- r = client_context_new(&c);
- if (r < 0) {
- log_oom();
- close(fd);
- continue;
- }
-
- c->fd = fd;
- c->policy = sp;
- c->bus_uid = bus_uid;
-
- r = pthread_create(&tid, &attr, run_client, c);
- if (r != 0) {
- log_warning_errno(r, "Cannot spawn thread, ignoring: %m");
- client_context_free(c);
- continue;
- }
- }
-
-finish:
- pthread_attr_destroy(&attr);
- return r;
-}
-
-static int help(void) {
-
- printf("%s [OPTIONS...]\n\n"
- "DBus proxy server.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --configuration=PATH Configuration file or directory\n"
- " --machine=MACHINE Connect to specified machine\n"
- " --address=ADDRESS Connect to the bus specified by ADDRESS\n"
- " (default: " DEFAULT_SYSTEM_BUS_ADDRESS ")\n",
- program_invocation_short_name);
-
- return 0;
-}
-
-static int parse_argv(int argc, char *argv[]) {
-
- enum {
- ARG_VERSION = 0x100,
- ARG_ADDRESS,
- ARG_CONFIGURATION,
- ARG_MACHINE,
- };
-
- static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "address", required_argument, NULL, ARG_ADDRESS },
- { "configuration", required_argument, NULL, ARG_CONFIGURATION },
- { "machine", required_argument, NULL, ARG_MACHINE },
- {},
- };
-
- int c, r;
-
- assert(argc >= 0);
- assert(argv);
-
- while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
-
- switch (c) {
-
- case 'h':
- help();
- return 0;
-
- case ARG_VERSION:
- return version();
-
- case ARG_ADDRESS:
- r = free_and_strdup(&arg_address, optarg);
- if (r < 0)
- return log_oom();
- break;
-
- case ARG_CONFIGURATION:
- r = strv_extend(&arg_configuration, optarg);
- if (r < 0)
- return log_oom();
- break;
-
- case ARG_MACHINE: {
- _cleanup_free_ char *e = NULL;
- char *a;
-
- e = bus_address_escape(optarg);
- if (!e)
- return log_oom();
-
- a = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL);
- if (!a)
- return log_oom();
-
- free(arg_address);
- arg_address = a;
-
- break;
- }
-
- case '?':
- return -EINVAL;
-
- default:
- assert_not_reached("Unhandled option");
- }
-
- if (argc > optind) {
- log_error("Too many arguments");
- return -EINVAL;
- }
-
- if (!arg_address) {
- arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
- if (!arg_address)
- return log_oom();
- }
-
- return 1;
-}
-
-int main(int argc, char *argv[]) {
- int r, accept_fd;
- uid_t uid, bus_uid;
- gid_t gid;
-
- log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
- log_parse_environment();
- log_open();
-
- bus_uid = getuid();
-
- if (geteuid() == 0) {
- const char *user = "systemd-bus-proxy";
-
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
- if (r < 0) {
- log_error_errno(r, "Cannot resolve user name %s: %m", user);
- goto finish;
- }
-
- r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
- if (r < 0) {
- log_error_errno(r, "Cannot drop privileges: %m");
- goto finish;
- }
- }
-
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
-
- r = sd_listen_fds(0);
- if (r != 1) {
- log_error("Illegal number of file descriptors passed");
- goto finish;
- }
-
- accept_fd = SD_LISTEN_FDS_START;
-
- r = fd_nonblock(accept_fd, false);
- if (r < 0) {
- log_error_errno(r, "Cannot mark accept-fd non-blocking: %m");
- goto finish;
- }
-
- r = loop_clients(accept_fd, bus_uid);
-
-finish:
- sd_notify(false,
- "STOPPING=1\n"
- "STATUS=Shutting down.");
-
- strv_free(arg_configuration);
- free(arg_address);
-
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
diff --git a/src/systemd-cgls/cgls.c b/src/systemd-cgls/cgls.c
index 5862cdb282..ed2846ee57 100644
--- a/src/systemd-cgls/cgls.c
+++ b/src/systemd-cgls/cgls.c
@@ -184,14 +184,15 @@ int main(int argc, char *argv[]) {
goto finish;
if (!arg_no_pager) {
- r = pager_open(false);
+ r = pager_open(arg_no_pager, false);
if (r > 0 && arg_full < 0)
arg_full = true;
}
output_flags =
arg_all * OUTPUT_SHOW_ALL |
- (arg_full > 0) * OUTPUT_FULL_WIDTH;
+ (arg_full > 0) * OUTPUT_FULL_WIDTH |
+ arg_kernel_threads * OUTPUT_KERNEL_THREADS;
if (optind < argc) {
_cleanup_free_ char *root = NULL;
@@ -209,7 +210,7 @@ int main(int argc, char *argv[]) {
printf("Directory %s:\n", argv[i]);
fflush(stdout);
- q = show_cgroup_by_path(argv[i], NULL, 0, arg_kernel_threads, output_flags);
+ q = show_cgroup_by_path(argv[i], NULL, 0, output_flags);
} else {
_cleanup_free_ char *c = NULL, *p = NULL, *j = NULL;
const char *controller, *path;
@@ -235,7 +236,7 @@ int main(int argc, char *argv[]) {
show_cg_info(controller, path);
- q = show_cgroup(controller, path, NULL, 0, arg_kernel_threads, output_flags);
+ q = show_cgroup(controller, path, NULL, 0, output_flags);
}
if (q < 0)
@@ -258,7 +259,7 @@ int main(int argc, char *argv[]) {
printf("Working directory %s:\n", cwd);
fflush(stdout);
- r = show_cgroup_by_path(cwd, NULL, 0, arg_kernel_threads, output_flags);
+ r = show_cgroup_by_path(cwd, NULL, 0, output_flags);
done = true;
}
}
@@ -273,7 +274,7 @@ int main(int argc, char *argv[]) {
show_cg_info(SYSTEMD_CGROUP_CONTROLLER, root);
printf("-.slice\n");
- r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, arg_kernel_threads, output_flags);
+ r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, output_flags);
}
}
diff --git a/src/systemd-cgroups-agent/cgroups-agent.c b/src/systemd-cgroups-agent/cgroups-agent.c
index 79098b5f2c..d7c722ac3d 100644
--- a/src/systemd-cgroups-agent/cgroups-agent.c
+++ b/src/systemd-cgroups-agent/cgroups-agent.c
@@ -18,15 +18,22 @@
***/
#include <stdlib.h>
+#include <sys/socket.h>
-#include <systemd/sd-bus.h>
-
-#include "bus-util.h"
+#include "fd-util.h"
#include "log.h"
+#include "socket-util.h"
int main(int argc, char *argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
- int r;
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/cgroups-agent",
+ };
+
+ _cleanup_close_ int fd = -1;
+ ssize_t n;
+ size_t l;
if (argc != 2) {
log_error("Incorrect number of arguments.");
@@ -37,27 +44,22 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- /* We send this event to the private D-Bus socket and then the
- * system instance will forward this to the system bus. We do
- * this to avoid an activation loop when we start dbus when we
- * are called when the dbus service is shut down. */
-
- r = bus_connect_system_systemd(&bus);
- if (r < 0) {
- /* If we couldn't connect we assume this was triggered
- * while systemd got restarted/transitioned from
- * initrd to the system, so let's ignore this */
- log_debug_errno(r, "Failed to get D-Bus connection: %m");
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ log_debug_errno(errno, "Failed to allocate socket: %m");
+ return EXIT_FAILURE;
+ }
+
+ l = strlen(argv[1]);
+
+ n = sendto(fd, argv[1], l, 0, &sa.sa, SOCKADDR_UN_LEN(sa.un));
+ if (n < 0) {
+ log_debug_errno(errno, "Failed to send cgroups agent message: %m");
return EXIT_FAILURE;
}
- r = sd_bus_emit_signal(bus,
- "/org/freedesktop/systemd1/agent",
- "org.freedesktop.systemd1.Agent",
- "Released",
- "s", argv[1]);
- if (r < 0) {
- log_debug_errno(r, "Failed to send signal message on private connection: %m");
+ if ((size_t) n != l) {
+ log_debug("Datagram size mismatch");
return EXIT_FAILURE;
}
diff --git a/src/systemd-cgtop/cgtop.c b/src/systemd-cgtop/cgtop.c
index 5d021e5ef4..6cbea86070 100644
--- a/src/systemd-cgtop/cgtop.c
+++ b/src/systemd-cgtop/cgtop.c
@@ -72,13 +72,13 @@ static bool arg_batch = false;
static bool arg_raw = false;
static usec_t arg_delay = 1*USEC_PER_SEC;
static char* arg_machine = NULL;
+static bool arg_recursive = true;
-enum {
+static enum {
COUNT_PIDS,
COUNT_USERSPACE_PROCESSES,
COUNT_ALL_PROCESSES,
} arg_count = COUNT_PIDS;
-static bool arg_recursive = true;
static enum {
ORDER_PATH,
@@ -269,13 +269,15 @@ static int process(
if (g->memory > 0)
g->memory_valid = true;
- } else if (streq(controller, "blkio") && cg_unified() <= 0) {
+ } else if ((streq(controller, "io") && cg_unified() > 0) ||
+ (streq(controller, "blkio") && cg_unified() <= 0)) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
+ bool unified = cg_unified() > 0;
uint64_t wr = 0, rd = 0;
nsec_t timestamp;
- r = cg_get_path(controller, path, "blkio.io_service_bytes", &p);
+ r = cg_get_path(controller, path, unified ? "io.stat" : "blkio.io_service_bytes", &p);
if (r < 0)
return r;
@@ -293,25 +295,38 @@ static int process(
if (!fgets(line, sizeof(line), f))
break;
+ /* Trim and skip the device */
l = strstrip(line);
l += strcspn(l, WHITESPACE);
l += strspn(l, WHITESPACE);
- if (first_word(l, "Read")) {
- l += 4;
- q = &rd;
- } else if (first_word(l, "Write")) {
- l += 5;
- q = &wr;
- } else
- continue;
+ if (unified) {
+ while (!isempty(l)) {
+ if (sscanf(l, "rbytes=%" SCNu64, &k))
+ rd += k;
+ else if (sscanf(l, "wbytes=%" SCNu64, &k))
+ wr += k;
- l += strspn(l, WHITESPACE);
- r = safe_atou64(l, &k);
- if (r < 0)
- continue;
-
- *q += k;
+ l += strcspn(l, WHITESPACE);
+ l += strspn(l, WHITESPACE);
+ }
+ } else {
+ if (first_word(l, "Read")) {
+ l += 4;
+ q = &rd;
+ } else if (first_word(l, "Write")) {
+ l += 5;
+ q = &wr;
+ } else
+ continue;
+
+ l += strspn(l, WHITESPACE);
+ r = safe_atou64(l, &k);
+ if (r < 0)
+ continue;
+
+ *q += k;
+ }
}
timestamp = now_nsec(CLOCK_MONOTONIC);
@@ -362,7 +377,7 @@ static int refresh_one(
Group **ret) {
_cleanup_closedir_ DIR *d = NULL;
- Group *ours;
+ Group *ours = NULL;
int r;
assert(controller);
@@ -439,6 +454,9 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration)
r = refresh_one("memory", root, a, b, iteration, 0, NULL);
if (r < 0)
return r;
+ r = refresh_one("io", root, a, b, iteration, 0, NULL);
+ if (r < 0)
+ return r;
r = refresh_one("blkio", root, a, b, iteration, 0, NULL);
if (r < 0)
return r;
diff --git a/src/systemd-cryptsetup/cryptsetup.c b/src/systemd-cryptsetup/cryptsetup.c
index 9d8156697d..8024f80e36 100644
--- a/src/systemd-cryptsetup/cryptsetup.c
+++ b/src/systemd-cryptsetup/cryptsetup.c
@@ -719,8 +719,12 @@ int main(int argc, char *argv[]) {
int k;
k = crypt_init_by_name(&cd, argv[2]);
- if (k) {
- log_error_errno(k, "crypt_init() failed: %m");
+ if (k == -ENODEV) {
+ log_info("Volume %s already inactive.", argv[2]);
+ r = EXIT_SUCCESS;
+ goto finish;
+ } else if (k) {
+ log_error_errno(k, "crypt_init_by_name() failed: %m");
goto finish;
}
diff --git a/src/systemd-delta/delta.c b/src/systemd-delta/delta.c
index a54fc89de6..f32744def2 100644
--- a/src/systemd-delta/delta.c
+++ b/src/systemd-delta/delta.c
@@ -85,14 +85,6 @@ static enum {
(SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN | SHOW_EXTENDED)
} arg_flags = 0;
-static void pager_open_if_enabled(void) {
-
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
static int equivalent(const char *a, const char *b) {
_cleanup_free_ char *x = NULL, *y = NULL;
@@ -113,7 +105,7 @@ static int notify_override_masked(const char *top, const char *bottom) {
printf("%s%s%s %s %s %s\n",
ansi_highlight_red(), "[MASKED]", ansi_normal(),
- top, draw_special_char(DRAW_ARROW), bottom);
+ top, special_glyph(ARROW), bottom);
return 1;
}
@@ -123,7 +115,7 @@ static int notify_override_equivalent(const char *top, const char *bottom) {
printf("%s%s%s %s %s %s\n",
ansi_highlight_green(), "[EQUIVALENT]", ansi_normal(),
- top, draw_special_char(DRAW_ARROW), bottom);
+ top, special_glyph(ARROW), bottom);
return 1;
}
@@ -133,7 +125,7 @@ static int notify_override_redirected(const char *top, const char *bottom) {
printf("%s%s%s %s %s %s\n",
ansi_highlight(), "[REDIRECTED]", ansi_normal(),
- top, draw_special_char(DRAW_ARROW), bottom);
+ top, special_glyph(ARROW), bottom);
return 1;
}
@@ -143,7 +135,7 @@ static int notify_override_overridden(const char *top, const char *bottom) {
printf("%s%s%s %s %s %s\n",
ansi_highlight(), "[OVERRIDDEN]", ansi_normal(),
- top, draw_special_char(DRAW_ARROW), bottom);
+ top, special_glyph(ARROW), bottom);
return 1;
}
@@ -153,7 +145,7 @@ static int notify_override_extended(const char *top, const char *bottom) {
printf("%s%s%s %s %s %s\n",
ansi_highlight(), "[EXTENDED]", ansi_normal(),
- top, draw_special_char(DRAW_ARROW), bottom);
+ top, special_glyph(ARROW), bottom);
return 1;
}
@@ -255,7 +247,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
return -ENOMEM;
d = p + strlen(toppath) + 1;
- log_debug("Adding at top: %s %s %s", d, draw_special_char(DRAW_ARROW), p);
+ log_debug("Adding at top: %s %s %s", d, special_glyph(ARROW), p);
k = hashmap_put(top, d, p);
if (k >= 0) {
p = strdup(p);
@@ -267,7 +259,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
return k;
}
- log_debug("Adding at bottom: %s %s %s", d, draw_special_char(DRAW_ARROW), p);
+ log_debug("Adding at bottom: %s %s %s", d, special_glyph(ARROW), p);
free(hashmap_remove(bottom, d));
k = hashmap_put(bottom, d, p);
if (k < 0) {
@@ -291,7 +283,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
return -ENOMEM;
log_debug("Adding to drops: %s %s %s %s %s",
- unit, draw_special_char(DRAW_ARROW), basename(p), draw_special_char(DRAW_ARROW), p);
+ unit, special_glyph(ARROW), basename(p), special_glyph(ARROW), p);
k = hashmap_put(h, basename(p), p);
if (k < 0) {
free(p);
@@ -342,7 +334,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
if (!p)
return -ENOMEM;
- log_debug("Adding at top: %s %s %s", basename(p), draw_special_char(DRAW_ARROW), p);
+ log_debug("Adding at top: %s %s %s", basename(p), special_glyph(ARROW), p);
k = hashmap_put(top, basename(p), p);
if (k >= 0) {
p = strdup(p);
@@ -353,7 +345,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
return k;
}
- log_debug("Adding at bottom: %s %s %s", basename(p), draw_special_char(DRAW_ARROW), p);
+ 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) {
@@ -431,7 +423,7 @@ finish:
hashmap_free_free(top);
hashmap_free_free(bottom);
- HASHMAP_FOREACH_KEY(h, key, drops, i){
+ HASHMAP_FOREACH_KEY(h, key, drops, i) {
hashmap_free_free(hashmap_remove(drops, key));
hashmap_remove(drops, key);
free(key);
@@ -610,7 +602,7 @@ int main(int argc, char *argv[]) {
else if (arg_diff)
arg_flags |= SHOW_OVERRIDDEN;
- pager_open_if_enabled();
+ pager_open(arg_no_pager, false);
if (optind < argc) {
int i;
diff --git a/src/systemd-firstboot/firstboot.c b/src/systemd-firstboot/firstboot.c
index 8e57a24a70..1e1a592b7c 100644
--- a/src/systemd-firstboot/firstboot.c
+++ b/src/systemd-firstboot/firstboot.c
@@ -160,7 +160,7 @@ static int prompt_loop(const char *text, char **l, bool (*is_valid)(const char *
_cleanup_free_ char *p = NULL;
unsigned u;
- r = ask_string(&p, "%s %s (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET), text);
+ r = ask_string(&p, "%s %s (empty to skip): ", special_glyph(TRIANGULAR_BULLET), text);
if (r < 0)
return log_error_errno(r, "Failed to query user: %m");
@@ -245,7 +245,7 @@ static int process_locale(void) {
int r;
etc_localeconf = prefix_roota(arg_root, "/etc/locale.conf");
- if (faccessat(AT_FDCWD, etc_localeconf, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (laccess(etc_localeconf, F_OK) >= 0)
return 0;
if (arg_copy_locale && arg_root) {
@@ -319,7 +319,7 @@ static int process_timezone(void) {
int r;
etc_localtime = prefix_roota(arg_root, "/etc/localtime");
- if (faccessat(AT_FDCWD, etc_localtime, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (laccess(etc_localtime, F_OK) >= 0)
return 0;
if (arg_copy_timezone && arg_root) {
@@ -371,7 +371,7 @@ static int prompt_hostname(void) {
for (;;) {
_cleanup_free_ char *h = NULL;
- r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET));
+ r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", special_glyph(TRIANGULAR_BULLET));
if (r < 0)
return log_error_errno(r, "Failed to query hostname: %m");
@@ -399,7 +399,7 @@ static int process_hostname(void) {
int r;
etc_hostname = prefix_roota(arg_root, "/etc/hostname");
- if (faccessat(AT_FDCWD, etc_hostname, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (laccess(etc_hostname, F_OK) >= 0)
return 0;
r = prompt_hostname();
@@ -424,7 +424,7 @@ static int process_machine_id(void) {
int r;
etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
- if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (laccess(etc_machine_id, F_OK) >= 0)
return 0;
if (sd_id128_equal(arg_machine_id, SD_ID128_NULL))
@@ -450,14 +450,14 @@ static int prompt_root_password(void) {
return 0;
etc_shadow = prefix_roota(arg_root, "/etc/shadow");
- if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (laccess(etc_shadow, F_OK) >= 0)
return 0;
print_welcome();
putchar('\n');
- msg1 = strjoina(draw_special_char(DRAW_TRIANGULAR_BULLET), " Please enter a new root password (empty to skip): ");
- msg2 = strjoina(draw_special_char(DRAW_TRIANGULAR_BULLET), " Please enter new root password again: ");
+ msg1 = strjoina(special_glyph(TRIANGULAR_BULLET), " Please enter a new root password (empty to skip): ");
+ msg2 = strjoina(special_glyph(TRIANGULAR_BULLET), " Please enter new root password again: ");
for (;;) {
_cleanup_string_free_erase_ char *a = NULL, *b = NULL;
@@ -533,7 +533,7 @@ static int process_root_password(void) {
int r;
etc_shadow = prefix_roota(arg_root, "/etc/shadow");
- if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (laccess(etc_shadow, F_OK) >= 0)
return 0;
mkdir_parents(etc_shadow, 0755);
diff --git a/src/systemd-fsck/fsck.c b/src/systemd-fsck/fsck.c
index f21433c0ad..d7f0829ffc 100644
--- a/src/systemd-fsck/fsck.c
+++ b/src/systemd-fsck/fsck.c
@@ -262,7 +262,7 @@ static int fsck_progress_socket(void) {
if (fd < 0)
return log_warning_errno(errno, "socket(): %m");
- if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
r = log_full_errno(errno == ECONNREFUSED || errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);
safe_close(fd);
diff --git a/src/systemd-fstab-generator/fstab-generator.c b/src/systemd-fstab-generator/fstab-generator.c
index 97a48764ae..108522873e 100644
--- a/src/systemd-fstab-generator/fstab-generator.c
+++ b/src/systemd-fstab-generator/fstab-generator.c
@@ -336,8 +336,8 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
- if (!noauto) {
- lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
+ if (!noauto && !automount) {
+ lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", name, NULL);
if (!lnk)
return log_oom();
@@ -379,6 +379,7 @@ static int add_mount(
}
fprintf(f,
+ "\n"
"[Automount]\n"
"Where=%s\n",
where);
@@ -488,6 +489,7 @@ static int parse_fstab(bool initrd) {
static int add_sysroot_mount(void) {
_cleanup_free_ char *what = NULL;
const char *opts;
+ int r;
if (isempty(arg_root_what)) {
log_debug("Could not find a root= entry on the kernel command line.");
@@ -507,6 +509,13 @@ static int add_sysroot_mount(void) {
opts = arg_root_options;
log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
+
+ if (is_device_path(what)) {
+ r = generator_write_initrd_root_device_deps(arg_dest, what);
+ if (r < 0)
+ return r;
+ }
+
return add_mount(what,
"/sysroot",
arg_root_fstype,
diff --git a/src/systemd-gpt-auto-generator/gpt-auto-generator.c b/src/systemd-gpt-auto-generator/gpt-auto-generator.c
index a8149b8756..73e32da751 100644
--- a/src/systemd-gpt-auto-generator/gpt-auto-generator.c
+++ b/src/systemd-gpt-auto-generator/gpt-auto-generator.c
@@ -956,6 +956,12 @@ static int add_root_mount(void) {
* wait for a root device to show up. A udev rule will create
* the link for us under the right name. */
+ if (in_initrd()) {
+ r = generator_write_initrd_root_device_deps(arg_dest, "/dev/gpt-auto-root");
+ if (r < 0)
+ return 0;
+ }
+
return add_mount(
"root",
"/dev/gpt-auto-root",
diff --git a/src/systemd-nspawn/Makefile b/src/systemd-nspawn/Makefile
index 380266ea7f..9702abcbc5 100644
--- a/src/systemd-nspawn/Makefile
+++ b/src/systemd-nspawn/Makefile
@@ -41,10 +41,14 @@ systemd_nspawn_SOURCES = \
src/nspawn/nspawn-setuid.h \
src/nspawn/nspawn-stub-pid1.c \
src/nspawn/nspawn-stub-pid1.h \
+ src/nspawn/nspawn-patch-uid.c \
+ src/nspawn/nspawn-patch-uid.h \
src/core/mount-setup.c \
src/core/mount-setup.h \
src/core/loopback-setup.c \
- src/core/loopback-setup.h
+ src/core/loopback-setup.h \
+ src/core/machine-id-setup.c \
+ src/core/machine-id-setup.h
nodist_systemd_nspawn_SOURCES = \
src/nspawn/nspawn-gperf.c
@@ -66,6 +70,17 @@ systemd_nspawn_LDADD += \
libfirewall.la
endif # HAVE_LIBIPTC
+test_patch_uid_SOURCES = \
+ src/nspawn/nspawn-patch-uid.c \
+ src/nspawn/nspawn-patch-uid.h \
+ src/nspawn/test-patch-uid.c
+
+test_patch_uid_LDADD = \
+ libshared.la
+
+manual_tests += \
+ test-patch-uid
+
bin_PROGRAMS += systemd-nspawn
systemd_nspawn_LDADD += libsystemd.la # was hidden by libshared->libsystemd
systemd_nspawn_LDADD += libbasic.la # was hidden by libshared->libsystemd->libbasic
diff --git a/src/systemd-nspawn/nspawn-cgroup.c b/src/systemd-nspawn/nspawn-cgroup.c
index 1db5ba7116..f50f1ad6c2 100644
--- a/src/systemd-nspawn/nspawn-cgroup.c
+++ b/src/systemd-nspawn/nspawn-cgroup.c
@@ -55,8 +55,7 @@ int chown_cgroup(pid_t pid, uid_t uid_shift) {
"cgroup.events",
"cgroup.clone_children",
"cgroup.controllers",
- "cgroup.subtree_control",
- "cgroup.populated")
+ "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);
@@ -73,7 +72,7 @@ int sync_cgroup(pid_t pid, bool unified_requested) {
unified = cg_unified();
if (unified < 0)
- return log_error_errno(unified, "Failed to determine whether the unified hierachy is used: %m");
+ return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
if ((unified > 0) == unified_requested)
return 0;
@@ -94,7 +93,7 @@ int sync_cgroup(pid_t pid, bool unified_requested) {
if (unified)
r = mount("cgroup", tree, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
else
- r = mount("cgroup", tree, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "__DEVEL__sane_behavior");
+ r = mount("cgroup", tree, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
if (r < 0) {
r = log_error_errno(errno, "Failed to mount unified hierarchy: %m");
goto finish;
@@ -135,7 +134,7 @@ int create_subcgroup(pid_t pid, bool unified_requested) {
unified = cg_unified();
if (unified < 0)
- return log_error_errno(unified, "Failed to determine whether the unified hierachy is used: %m");
+ return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
if (unified == 0)
return 0;
diff --git a/src/systemd-nspawn/nspawn-gperf.gperf b/src/systemd-nspawn/nspawn-gperf.gperf
index 116655cdd2..2b5d452662 100644
--- a/src/systemd-nspawn/nspawn-gperf.gperf
+++ b/src/systemd-nspawn/nspawn-gperf.gperf
@@ -16,7 +16,7 @@ struct ConfigPerfItem;
%includes
%%
Exec.Boot, config_parse_boot, 0, 0
-Exec.ProcessTwo, config_parse_pid2, 0, 0,
+Exec.ProcessTwo, config_parse_pid2, 0, 0
Exec.Parameters, config_parse_strv, 0, offsetof(Settings, parameters)
Exec.Environment, config_parse_strv, 0, offsetof(Settings, environment)
Exec.User, config_parse_string, 0, offsetof(Settings, user)
@@ -26,16 +26,19 @@ Exec.KillSignal, config_parse_signal, 0, offsetof(Settings,
Exec.Personality, config_parse_personality, 0, offsetof(Settings, personality)
Exec.MachineID, config_parse_id128, 0, offsetof(Settings, machine_id)
Exec.WorkingDirectory, config_parse_path, 0, offsetof(Settings, working_directory)
+Exec.PrivateUsers, config_parse_private_users, 0, 0
Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only)
Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode)
Files.Bind, config_parse_bind, 0, 0
Files.BindReadOnly, config_parse_bind, 1, 0
Files.TemporaryFileSystem, config_parse_tmpfs, 0, 0
+Files.PrivateUsersChown, config_parse_tristate, 0, offsetof(Settings, userns_chown)
Network.Private, config_parse_tristate, 0, offsetof(Settings, private_network)
Network.Interface, config_parse_strv, 0, offsetof(Settings, network_interfaces)
Network.MACVLAN, config_parse_strv, 0, offsetof(Settings, network_macvlan)
Network.IPVLAN, config_parse_strv, 0, offsetof(Settings, network_ipvlan)
Network.VirtualEthernet, config_parse_tristate, 0, offsetof(Settings, network_veth)
Network.VirtualEthernetExtra, config_parse_veth_extra, 0, 0
-Network.Bridge, config_parse_string, 0, offsetof(Settings, network_bridge)
+Network.Bridge, config_parse_ifname, 0, offsetof(Settings, network_bridge)
+Network.Zone, config_parse_network_zone, 0, 0
Network.Port, config_parse_expose_port, 0, 0
diff --git a/src/systemd-nspawn/nspawn-mount.c b/src/systemd-nspawn/nspawn-mount.c
index 70cca15278..8e2d2d543c 100644
--- a/src/systemd-nspawn/nspawn-mount.c
+++ b/src/systemd-nspawn/nspawn-mount.c
@@ -438,21 +438,22 @@ static int mount_bind(const char *dest, CustomMount *m) {
r = mkdir_parents_label(where, 0755);
if (r < 0)
return log_error_errno(r, "Failed to make parents of %s: %m", where);
+
+ /* Create the mount point. Any non-directory file can be
+ * mounted on any non-directory file (regular, fifo, socket,
+ * char, block).
+ */
+ if (S_ISDIR(source_st.st_mode))
+ r = mkdir_label(where, 0755);
+ else
+ r = touch(where);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create mount point %s: %m", where);
+
} else {
return log_error_errno(errno, "Failed to stat %s: %m", where);
}
- /* Create the mount point. Any non-directory file can be
- * mounted on any non-directory file (regular, fifo, socket,
- * char, block).
- */
- if (S_ISDIR(source_st.st_mode))
- r = mkdir_label(where, 0755);
- else
- r = touch(where);
- if (r < 0 && r != -EEXIST)
- return log_error_errno(r, "Failed to create mount point %s: %m", where);
-
if (mount(m->source, where, NULL, mount_flags, mount_opts) < 0)
return log_error_errno(errno, "mount(%s) failed: %m", where);
@@ -750,7 +751,7 @@ static int mount_unified_cgroups(const char *dest) {
return -EINVAL;
}
- if (mount("cgroup", p, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "__DEVEL__sane_behavior") < 0)
+ if (mount("cgroup", p, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0)
return log_error_errno(errno, "Failed to mount unified cgroup hierarchy to %s: %m", p);
return 0;
diff --git a/src/systemd-nspawn/nspawn-network.c b/src/systemd-nspawn/nspawn-network.c
index 58d6035ddb..917827eac1 100644
--- a/src/systemd-nspawn/nspawn-network.c
+++ b/src/systemd-nspawn/nspawn-network.c
@@ -26,8 +26,11 @@
#include "alloc-util.h"
#include "ether-addr-util.h"
+#include "lockfile-util.h"
#include "nspawn-network.h"
#include "siphash24.h"
+#include "socket-util.h"
+#include "stat-util.h"
#include "string-util.h"
#include "udev-util.h"
#include "util.h"
@@ -38,6 +41,30 @@
#define VETH_EXTRA_CONTAINER_HASH_KEY SD_ID128_MAKE(af,50,17,61,ce,f9,4d,35,84,0d,2b,20,54,be,ce,59)
#define MACVLAN_HASH_KEY SD_ID128_MAKE(00,13,6d,bc,66,83,44,81,bb,0c,f9,51,1f,24,a6,6f)
+static int remove_one_link(sd_netlink *rtnl, const char *name) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+ int r;
+
+ if (isempty(name))
+ return 0;
+
+ r = sd_rtnl_message_new_link(rtnl, &m, RTM_DELLINK, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate netlink message: %m");
+
+ r = sd_netlink_message_append_string(m, IFLA_IFNAME, name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add netlink interface name: %m");
+
+ r = sd_netlink_call(rtnl, m, 0, NULL);
+ if (r == -ENODEV) /* Already gone */
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to remove interface %s: %m", name);
+
+ return 1;
+}
+
static int generate_mac(
const char *machine_name,
struct ether_addr *mac,
@@ -231,51 +258,155 @@ int setup_veth_extra(
if (r < 0)
return r;
- idx ++;
+ idx++;
}
return 0;
}
-int setup_bridge(const char *veth_name, const char *bridge_name) {
+static int join_bridge(sd_netlink *rtnl, const char *veth_name, const char *bridge_name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
- _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
int r, bridge_ifi;
+ assert(rtnl);
assert(veth_name);
assert(bridge_name);
bridge_ifi = (int) if_nametoindex(bridge_name);
if (bridge_ifi <= 0)
- return log_error_errno(errno, "Failed to resolve interface %s: %m", bridge_name);
-
- r = sd_netlink_open(&rtnl);
- if (r < 0)
- return log_error_errno(r, "Failed to connect to netlink: %m");
+ return -errno;
r = sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, 0);
if (r < 0)
- return log_error_errno(r, "Failed to allocate netlink message: %m");
+ return r;
r = sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP);
if (r < 0)
- return log_error_errno(r, "Failed to set IFF_UP flag: %m");
+ return r;
r = sd_netlink_message_append_string(m, IFLA_IFNAME, veth_name);
if (r < 0)
- return log_error_errno(r, "Failed to add netlink interface name field: %m");
+ return r;
r = sd_netlink_message_append_u32(m, IFLA_MASTER, bridge_ifi);
if (r < 0)
- return log_error_errno(r, "Failed to add netlink master field: %m");
+ return r;
r = sd_netlink_call(rtnl, m, 0, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to add veth interface to bridge: %m");
+ return r;
return bridge_ifi;
}
+static int create_bridge(sd_netlink *rtnl, const char *bridge_name) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+ int r;
+
+ r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_string(m, IFLA_IFNAME, bridge_name);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "bridge");
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_close_container(m);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_close_container(m);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(rtnl, m, 0, NULL);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+int setup_bridge(const char *veth_name, const char *bridge_name, bool create) {
+ _cleanup_release_lock_file_ LockFile bridge_lock = LOCK_FILE_INIT;
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ int r, bridge_ifi;
+ unsigned n = 0;
+
+ assert(veth_name);
+ assert(bridge_name);
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ if (create) {
+ /* We take a system-wide lock here, so that we can safely check whether there's still a member in the
+ * bridge before removing it, without risking interferance from other nspawn instances. */
+
+ r = make_lock_file("/run/systemd/nspawn-network-zone", LOCK_EX, &bridge_lock);
+ if (r < 0)
+ return log_error_errno(r, "Failed to take network zone lock: %m");
+ }
+
+ for (;;) {
+ bridge_ifi = join_bridge(rtnl, veth_name, bridge_name);
+ if (bridge_ifi >= 0)
+ return bridge_ifi;
+ if (bridge_ifi != -ENODEV || !create || n > 10)
+ return log_error_errno(bridge_ifi, "Failed to add interface %s to bridge %s: %m", veth_name, bridge_name);
+
+ /* Count attempts, so that we don't enter an endless loop here. */
+ n++;
+
+ /* The bridge doesn't exist yet. Let's create it */
+ r = create_bridge(rtnl, bridge_name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create bridge interface %s: %m", bridge_name);
+
+ /* Try again, now that the bridge exists */
+ }
+}
+
+int remove_bridge(const char *bridge_name) {
+ _cleanup_release_lock_file_ LockFile bridge_lock = LOCK_FILE_INIT;
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ const char *path;
+ int r;
+
+ /* Removes the specified bridge, but only if it is currently empty */
+
+ if (isempty(bridge_name))
+ return 0;
+
+ r = make_lock_file("/run/systemd/nspawn-network-zone", LOCK_EX, &bridge_lock);
+ if (r < 0)
+ return log_error_errno(r, "Failed to take network zone lock: %m");
+
+ path = strjoina("/sys/class/net/", bridge_name, "/brif");
+
+ r = dir_is_empty(path);
+ if (r == -ENOENT) /* Already gone? */
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Can't detect if bridge %s is empty: %m", bridge_name);
+ if (r == 0) /* Still populated, leave it around */
+ return 0;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ return remove_one_link(rtnl, bridge_name);
+}
+
static int parse_interface(struct udev *udev, const char *name) {
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
char ifi_str[2 + DECIMAL_STR_MAX(int)];
@@ -514,13 +645,13 @@ int veth_extra_parse(char ***l, const char *p) {
r = extract_first_word(&p, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
if (r < 0)
return r;
- if (r == 0 || isempty(a))
+ if (r == 0 || !ifname_valid(a))
return -EINVAL;
r = extract_first_word(&p, &b, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
if (r < 0)
return r;
- if (r == 0 || isempty(b)) {
+ if (r == 0 || !ifname_valid(b)) {
free(b);
b = strdup(a);
if (!b)
@@ -537,3 +668,26 @@ int veth_extra_parse(char ***l, const char *p) {
a = b = NULL;
return 0;
}
+
+int remove_veth_links(const char *primary, char **pairs) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ char **a, **b;
+ int r;
+
+ /* In some cases the kernel might pin the veth links between host and container even after the namespace
+ * died. Hence, let's better remove them explicitly too. */
+
+ if (isempty(primary) && strv_isempty(pairs))
+ return 0;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ remove_one_link(rtnl, primary);
+
+ STRV_FOREACH_PAIR(a, b, pairs)
+ remove_one_link(rtnl, *a);
+
+ return 0;
+}
diff --git a/src/systemd-nspawn/nspawn-network.h b/src/systemd-nspawn/nspawn-network.h
index 9ab1606d1c..3d8861e1e5 100644
--- a/src/systemd-nspawn/nspawn-network.h
+++ b/src/systemd-nspawn/nspawn-network.h
@@ -26,7 +26,8 @@
int setup_veth(const char *machine_name, pid_t pid, char iface_name[IFNAMSIZ], bool bridge);
int setup_veth_extra(const char *machine_name, pid_t pid, char **pairs);
-int setup_bridge(const char *veth_name, const char *bridge_name);
+int setup_bridge(const char *veth_name, const char *bridge_name, bool create);
+int remove_bridge(const char *bridge_name);
int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces);
int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces);
@@ -34,3 +35,5 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces);
int move_network_interfaces(pid_t pid, char **ifaces);
int veth_extra_parse(char ***l, const char *p);
+
+int remove_veth_links(const char *primary, char **pairs);
diff --git a/src/systemd-nspawn/nspawn-patch-uid.c b/src/systemd-nspawn/nspawn-patch-uid.c
new file mode 100644
index 0000000000..c7382d412d
--- /dev/null
+++ b/src/systemd-nspawn/nspawn-patch-uid.c
@@ -0,0 +1,469 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <linux/magic.h>
+#ifdef HAVE_ACL
+#include <sys/acl.h>
+#endif
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+
+#include "acl-util.h"
+#include "dirent-util.h"
+#include "fd-util.h"
+#include "missing.h"
+#include "nspawn-patch-uid.h"
+#include "stat-util.h"
+#include "stdio-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "user-util.h"
+
+#ifdef HAVE_ACL
+
+static int get_acl(int fd, const char *name, acl_type_t type, acl_t *ret) {
+ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+ acl_t acl;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ if (name) {
+ _cleanup_close_ int child_fd = -1;
+
+ child_fd = openat(fd, name, O_PATH|O_CLOEXEC|O_NOFOLLOW);
+ if (child_fd < 0)
+ return -errno;
+
+ xsprintf(procfs_path, "/proc/self/fd/%i", child_fd);
+ acl = acl_get_file(procfs_path, type);
+ } else if (type == ACL_TYPE_ACCESS)
+ acl = acl_get_fd(fd);
+ else {
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+ acl = acl_get_file(procfs_path, type);
+ }
+ if (!acl)
+ return -errno;
+
+ *ret = acl;
+ return 0;
+}
+
+static int set_acl(int fd, const char *name, acl_type_t type, acl_t acl) {
+ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+ int r;
+
+ assert(fd >= 0);
+ assert(acl);
+
+ if (name) {
+ _cleanup_close_ int child_fd = -1;
+
+ child_fd = openat(fd, name, O_PATH|O_CLOEXEC|O_NOFOLLOW);
+ if (child_fd < 0)
+ return -errno;
+
+ xsprintf(procfs_path, "/proc/self/fd/%i", child_fd);
+ r = acl_set_file(procfs_path, type, acl);
+ } else if (type == ACL_TYPE_ACCESS)
+ r = acl_set_fd(fd, acl);
+ else {
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+ r = acl_set_file(procfs_path, type, acl);
+ }
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
+static int shift_acl(acl_t acl, uid_t shift, acl_t *ret) {
+ _cleanup_(acl_freep) acl_t copy = NULL;
+ acl_entry_t i;
+ int r;
+
+ assert(acl);
+ assert(ret);
+
+ r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
+ if (r < 0)
+ return -errno;
+ while (r > 0) {
+ uid_t *old_uid, new_uid;
+ bool modify = false;
+ acl_tag_t tag;
+
+ if (acl_get_tag_type(i, &tag) < 0)
+ return -errno;
+
+ if (IN_SET(tag, ACL_USER, ACL_GROUP)) {
+
+ /* We don't distuingish here between uid_t and gid_t, let's make sure the compiler checks that
+ * this is actually OK */
+ assert_cc(sizeof(uid_t) == sizeof(gid_t));
+
+ old_uid = acl_get_qualifier(i);
+ if (!old_uid)
+ return -errno;
+
+ new_uid = shift | (*old_uid & UINT32_C(0xFFFF));
+ if (!uid_is_valid(new_uid))
+ return -EINVAL;
+
+ modify = new_uid != *old_uid;
+ if (modify && !copy) {
+ int n;
+
+ /* There's no copy of the ACL yet? if so, let's create one, and start the loop from the
+ * beginning, so that we copy all entries, starting from the first, this time. */
+
+ n = acl_entries(acl);
+ if (n < 0)
+ return -errno;
+
+ copy = acl_init(n);
+ if (!copy)
+ return -errno;
+
+ /* Seek back to the beginning */
+ r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
+ if (r < 0)
+ return -errno;
+ continue;
+ }
+ }
+
+ if (copy) {
+ acl_entry_t new_entry;
+
+ if (acl_create_entry(&copy, &new_entry) < 0)
+ return -errno;
+
+ if (acl_copy_entry(new_entry, i) < 0)
+ return -errno;
+
+ if (modify)
+ if (acl_set_qualifier(new_entry, &new_uid) < 0)
+ return -errno;
+ }
+
+ r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i);
+ if (r < 0)
+ return -errno;
+ }
+
+ *ret = copy;
+ copy = NULL;
+
+ return !!*ret;
+}
+
+static int patch_acls(int fd, const char *name, const struct stat *st, uid_t shift) {
+ _cleanup_(acl_freep) acl_t acl = NULL, shifted = NULL;
+ bool changed = false;
+ int r;
+
+ assert(fd >= 0);
+ assert(st);
+
+ /* ACLs are not supported on symlinks, there's no point in trying */
+ if (S_ISLNK(st->st_mode))
+ return 0;
+
+ r = get_acl(fd, name, ACL_TYPE_ACCESS, &acl);
+ if (r == -EOPNOTSUPP)
+ return 0;
+ if (r < 0)
+ return r;
+
+ r = shift_acl(acl, shift, &shifted);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ r = set_acl(fd, name, ACL_TYPE_ACCESS, shifted);
+ if (r < 0)
+ return r;
+
+ changed = true;
+ }
+
+ if (S_ISDIR(st->st_mode)) {
+ acl_free(acl);
+ acl_free(shifted);
+
+ acl = shifted = NULL;
+
+ r = get_acl(fd, name, ACL_TYPE_DEFAULT, &acl);
+ if (r < 0)
+ return r;
+
+ r = shift_acl(acl, shift, &shifted);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ r = set_acl(fd, name, ACL_TYPE_DEFAULT, shifted);
+ if (r < 0)
+ return r;
+
+ changed = true;
+ }
+ }
+
+ return changed;
+}
+
+#else
+
+static int patch_acls(int fd, const char *name, const struct stat *st, uid_t shift) {
+ return 0;
+}
+
+#endif
+
+static int patch_fd(int fd, const char *name, const struct stat *st, uid_t shift) {
+ uid_t new_uid;
+ gid_t new_gid;
+ bool changed = false;
+ int r;
+
+ assert(fd >= 0);
+ assert(st);
+
+ new_uid = shift | (st->st_uid & UINT32_C(0xFFFF));
+ new_gid = (gid_t) shift | (st->st_gid & UINT32_C(0xFFFF));
+
+ if (!uid_is_valid(new_uid) || !gid_is_valid(new_gid))
+ return -EINVAL;
+
+ if (st->st_uid != new_uid || st->st_gid != new_gid) {
+ if (name)
+ r = fchownat(fd, name, new_uid, new_gid, AT_SYMLINK_NOFOLLOW);
+ else
+ r = fchown(fd, new_uid, new_gid);
+ if (r < 0)
+ return -errno;
+
+ /* The Linux kernel alters the mode in some cases of chown(). Let's undo this. */
+ if (name && !S_ISLNK(st->st_mode))
+ r = fchmodat(fd, name, st->st_mode, 0);
+ else
+ r = fchmod(fd, st->st_mode);
+ if (r < 0)
+ return -errno;
+
+ changed = true;
+ }
+
+ r = patch_acls(fd, name, st, shift);
+ if (r < 0)
+ return r;
+
+ return r > 0 || changed;
+}
+
+static int is_procfs_sysfs_or_suchlike(int fd) {
+ struct statfs sfs;
+
+ assert(fd >= 0);
+
+ if (fstatfs(fd, &sfs) < 0)
+ return -errno;
+
+ return F_TYPE_EQUAL(sfs.f_type, BINFMTFS_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, CGROUP_SUPER_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, CGROUP2_SUPER_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, DEBUGFS_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, DEVPTS_SUPER_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, EFIVARFS_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, HUGETLBFS_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, MQUEUE_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, PROC_SUPER_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, PSTOREFS_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, SELINUX_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, SMACK_MAGIC) ||
+ F_TYPE_EQUAL(sfs.f_type, SYSFS_MAGIC);
+}
+
+static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift, bool is_toplevel) {
+ bool changed = false;
+ int r;
+
+ assert(fd >= 0);
+
+ /* We generally want to permit crossing of mount boundaries when patching the UIDs/GIDs. However, we
+ * probably shouldn't do this for /proc and /sys if that is already mounted into place. Hence, let's
+ * stop the recursion when we hit a procfs or sysfs file system. */
+ r = is_procfs_sysfs_or_suchlike(fd);
+ if (r < 0)
+ goto finish;
+ if (r > 0) {
+ r = 0; /* don't recurse */
+ goto finish;
+ }
+
+ r = patch_fd(fd, NULL, st, shift);
+ if (r == -EROFS) {
+ _cleanup_free_ char *name = NULL;
+
+ if (!is_toplevel) {
+ /* When we hit a ready-only subtree we simply skip it, but log about it. */
+ (void) fd_get_path(fd, &name);
+ log_debug("Skippping read-only file or directory %s.", strna(name));
+ r = 0;
+ }
+
+ goto finish;
+ }
+ if (r < 0)
+ goto finish;
+
+ if (S_ISDIR(st->st_mode)) {
+ _cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
+
+ if (!donate_fd) {
+ int copy;
+
+ copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (copy < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+ fd = copy;
+ donate_fd = true;
+ }
+
+ d = fdopendir(fd);
+ if (!d) {
+ r = -errno;
+ goto finish;
+ }
+ fd = -1;
+
+ FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
+ struct stat fst;
+
+ if (STR_IN_SET(de->d_name, ".", ".."))
+ continue;
+
+ if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+ if (S_ISDIR(fst.st_mode)) {
+ int subdir_fd;
+
+ subdir_fd = openat(dirfd(d), de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+ if (subdir_fd < 0) {
+ r = -errno;
+ goto finish;
+
+ }
+
+ r = recurse_fd(subdir_fd, true, &fst, shift, false);
+ if (r < 0)
+ goto finish;
+ if (r > 0)
+ changed = true;
+
+ } else {
+ r = patch_fd(dirfd(d), de->d_name, &fst, shift);
+ if (r < 0)
+ goto finish;
+ if (r > 0)
+ changed = true;
+ }
+ }
+ }
+
+ r = changed;
+
+finish:
+ if (donate_fd)
+ safe_close(fd);
+
+ return r;
+}
+
+static int fd_patch_uid_internal(int fd, bool donate_fd, uid_t shift, uid_t range) {
+ struct stat st;
+ int r;
+
+ assert(fd >= 0);
+
+ /* Recursively adjusts the UID/GIDs of all files of a directory tree. This is used to automatically fix up an
+ * OS tree to the used user namespace UID range. Note that this automatic adjustment only works for UID ranges
+ * following the concept that the upper 16bit of a UID identify the container, and the lower 16bit are the actual
+ * UID within the container. */
+
+ if ((shift & 0xFFFF) != 0) {
+ /* We only support containers where the shift starts at a 2^16 boundary */
+ r = -EOPNOTSUPP;
+ goto finish;
+ }
+
+ if (range != 0x10000) {
+ /* We only support containers with 16bit UID ranges for the patching logic */
+ r = -EOPNOTSUPP;
+ goto finish;
+ }
+
+ if (fstat(fd, &st) < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+ if ((uint32_t) st.st_uid >> 16 != (uint32_t) st.st_gid >> 16) {
+ /* We only support containers where the uid/gid container ID match */
+ r = -EBADE;
+ goto finish;
+ }
+
+ /* Try to detect if the range is already right. Of course, this a pretty drastic optimization, as we assume
+ * that if the top-level dir has the right upper 16bit assigned, then everything below will have too... */
+ if (((uint32_t) (st.st_uid ^ shift) >> 16) == 0)
+ return 0;
+
+ return recurse_fd(fd, donate_fd, &st, shift, true);
+
+finish:
+ if (donate_fd)
+ safe_close(fd);
+
+ return r;
+}
+
+int fd_patch_uid(int fd, uid_t shift, uid_t range) {
+ return fd_patch_uid_internal(fd, false, shift, range);
+}
+
+int path_patch_uid(const char *path, uid_t shift, uid_t range) {
+ int fd;
+
+ fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+ if (fd < 0)
+ return -errno;
+
+ return fd_patch_uid_internal(fd, true, shift, range);
+}
diff --git a/src/libbus-proxy-core/driver.h b/src/systemd-nspawn/nspawn-patch-uid.h
index cad7aa7851..55d0990016 100644
--- a/src/libbus-proxy-core/driver.h
+++ b/src/systemd-nspawn/nspawn-patch-uid.h
@@ -1,9 +1,7 @@
-#pragma once
-
/***
This file is part of systemd.
- Copyright 2014 Lennart Poettering
+ Copyright 2016 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -19,9 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <systemd/sd-bus.h>
-
-#include "bus-xml-policy.h"
-#include "proxy.h"
+#include <sys/types.h>
-int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names);
+int fd_patch_uid(int fd, uid_t shift, uid_t range);
+int path_patch_uid(const char *path, uid_t shift, uid_t range);
diff --git a/src/systemd-nspawn/nspawn-register.c b/src/systemd-nspawn/nspawn-register.c
index de1433a5e2..08cbff9731 100644
--- a/src/systemd-nspawn/nspawn-register.c
+++ b/src/systemd-nspawn/nspawn-register.c
@@ -20,6 +20,7 @@
#include <systemd/sd-bus.h>
#include "bus-error.h" /* for bus_error_message */
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "nspawn-register.h"
#include "stat-util.h"
diff --git a/src/systemd-nspawn/nspawn-settings.c b/src/systemd-nspawn/nspawn-settings.c
index 4fb0054698..5f1522cfb6 100644
--- a/src/systemd-nspawn/nspawn-settings.c
+++ b/src/systemd-nspawn/nspawn-settings.c
@@ -24,7 +24,10 @@
#include "nspawn-settings.h"
#include "parse-util.h"
#include "process-util.h"
+#include "socket-util.h"
+#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
int settings_load(FILE *f, const char *path, Settings **ret) {
@@ -40,9 +43,13 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
s->start_mode = _START_MODE_INVALID;
s->personality = PERSONALITY_INVALID;
+ s->userns_mode = _USER_NAMESPACE_MODE_INVALID;
+ s->uid_shift = UID_INVALID;
+ s->uid_range = UID_INVALID;
s->read_only = -1;
s->volatile_mode = _VOLATILE_MODE_INVALID;
+ s->userns_chown = -1;
s->private_network = -1;
s->network_veth = -1;
@@ -59,6 +66,16 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
if (r < 0)
return r;
+ /* Make sure that if userns_mode is set, userns_chown is set to something appropriate, and vice versa. Either
+ * both fields shall be initialized or neither. */
+ if (s->userns_mode == USER_NAMESPACE_PICK)
+ s->userns_chown = true;
+ else if (s->userns_mode != _USER_NAMESPACE_MODE_INVALID && s->userns_chown < 0)
+ s->userns_chown = false;
+
+ if (s->userns_chown >= 0 && s->userns_mode == _USER_NAMESPACE_MODE_INVALID)
+ s->userns_mode = USER_NAMESPACE_NO;
+
*ret = s;
s = NULL;
@@ -80,6 +97,7 @@ Settings* settings_free(Settings *s) {
strv_free(s->network_ipvlan);
strv_free(s->network_veth_extra);
free(s->network_bridge);
+ free(s->network_zone);
expose_port_free_all(s->expose_ports);
custom_mount_free_all(s->custom_mounts, s->n_custom_mounts);
@@ -95,6 +113,7 @@ bool settings_private_network(Settings *s) {
s->private_network > 0 ||
s->network_veth > 0 ||
s->network_bridge ||
+ s->network_zone ||
s->network_interfaces ||
s->network_macvlan ||
s->network_ipvlan ||
@@ -106,7 +125,8 @@ bool settings_network_veth(Settings *s) {
return
s->network_veth > 0 ||
- s->network_bridge;
+ s->network_bridge ||
+ s->network_zone;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_volatile_mode, volatile_mode, VolatileMode, "Failed to parse volatile mode");
@@ -303,6 +323,38 @@ int config_parse_veth_extra(
return 0;
}
+int config_parse_network_zone(
+ 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) {
+
+ Settings *settings = data;
+ _cleanup_free_ char *j = NULL;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ j = strappend("vz-", rvalue);
+ if (!ifname_valid(j)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid network zone name %s, ignoring: %m", rvalue);
+ return 0;
+ }
+
+ free(settings->network_zone);
+ settings->network_zone = j;
+ j = NULL;
+
+ return 0;
+}
+
int config_parse_boot(
const char *unit,
const char *filename,
@@ -392,3 +444,73 @@ conflict:
log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
return 0;
}
+
+int config_parse_private_users(
+ 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) {
+
+ Settings *settings = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = parse_boolean(rvalue);
+ if (r == 0) {
+ /* no: User namespacing off */
+ settings->userns_mode = USER_NAMESPACE_NO;
+ settings->uid_shift = UID_INVALID;
+ settings->uid_range = UINT32_C(0x10000);
+ } else if (r > 0) {
+ /* yes: User namespacing on, UID range is read from root dir */
+ settings->userns_mode = USER_NAMESPACE_FIXED;
+ settings->uid_shift = UID_INVALID;
+ settings->uid_range = UINT32_C(0x10000);
+ } else if (streq(rvalue, "pick")) {
+ /* pick: User namespacing on, UID range is picked randomly */
+ settings->userns_mode = USER_NAMESPACE_PICK;
+ settings->uid_shift = UID_INVALID;
+ settings->uid_range = UINT32_C(0x10000);
+ } else {
+ const char *range, *shift;
+ uid_t sh, rn;
+
+ /* anything else: User namespacing on, UID range is explicitly configured */
+
+ range = strchr(rvalue, ':');
+ if (range) {
+ shift = strndupa(rvalue, range - rvalue);
+ range++;
+
+ r = safe_atou32(range, &rn);
+ if (r < 0 || rn <= 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "UID/GID range invalid, ignoring: %s", range);
+ return 0;
+ }
+ } else {
+ shift = rvalue;
+ rn = UINT32_C(0x10000);
+ }
+
+ r = parse_uid(shift, &sh);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "UID/GID shift invalid, ignoring: %s", range);
+ return 0;
+ }
+
+ settings->userns_mode = USER_NAMESPACE_FIXED;
+ settings->uid_shift = sh;
+ settings->uid_range = rn;
+ }
+
+ return 0;
+}
diff --git a/src/systemd-nspawn/nspawn-settings.h b/src/systemd-nspawn/nspawn-settings.h
index a017405cd9..1c47e37912 100644
--- a/src/systemd-nspawn/nspawn-settings.h
+++ b/src/systemd-nspawn/nspawn-settings.h
@@ -33,6 +33,14 @@ typedef enum StartMode {
_START_MODE_INVALID = -1
} StartMode;
+typedef enum UserNamespaceMode {
+ USER_NAMESPACE_NO,
+ USER_NAMESPACE_FIXED,
+ USER_NAMESPACE_PICK,
+ _USER_NAMESPACE_MODE_MAX,
+ _USER_NAMESPACE_MODE_INVALID = -1,
+} UserNamespaceMode;
+
typedef enum SettingsMask {
SETTING_START_MODE = 1 << 0,
SETTING_ENVIRONMENT = 1 << 1,
@@ -47,7 +55,8 @@ typedef enum SettingsMask {
SETTING_VOLATILE_MODE = 1 << 10,
SETTING_CUSTOM_MOUNTS = 1 << 11,
SETTING_WORKING_DIRECTORY = 1 << 12,
- _SETTINGS_MASK_ALL = (1 << 13) -1
+ SETTING_USERNS = 1 << 13,
+ _SETTINGS_MASK_ALL = (1 << 14) -1
} SettingsMask;
typedef struct Settings {
@@ -62,17 +71,21 @@ typedef struct Settings {
unsigned long personality;
sd_id128_t machine_id;
char *working_directory;
+ UserNamespaceMode userns_mode;
+ uid_t uid_shift, uid_range;
/* [Image] */
int read_only;
VolatileMode volatile_mode;
CustomMount *custom_mounts;
unsigned n_custom_mounts;
+ int userns_chown;
/* [Network] */
int private_network;
int network_veth;
char *network_bridge;
+ char *network_zone;
char **network_interfaces;
char **network_macvlan;
char **network_ipvlan;
@@ -97,5 +110,7 @@ int config_parse_volatile_mode(const char *unit, const char *filename, unsigned
int config_parse_bind(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_tmpfs(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_veth_extra(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_network_zone(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_boot(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_pid2(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_private_users(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/systemd-nspawn/nspawn.c b/src/systemd-nspawn/nspawn.c
index 1de527b57b..6390197646 100644
--- a/src/systemd-nspawn/nspawn.c
+++ b/src/systemd-nspawn/nspawn.c
@@ -22,7 +22,9 @@
#endif
#include <errno.h>
#include <getopt.h>
+#include <grp.h>
#include <linux/loop.h>
+#include <pwd.h>
#include <sched.h>
#ifdef HAVE_SECCOMP
#include <seccomp.h>
@@ -64,6 +66,7 @@
#include "hostname-util.h"
#include "log.h"
#include "loopback-setup.h"
+#include "machine-id-setup.h"
#include "machine-image.h"
#include "macro.h"
#include "missing.h"
@@ -73,6 +76,7 @@
#include "nspawn-expose-ports.h"
#include "nspawn-mount.h"
#include "nspawn-network.h"
+#include "nspawn-patch-uid.h"
#include "nspawn-register.h"
#include "nspawn-settings.h"
#include "nspawn-setuid.h"
@@ -86,6 +90,7 @@
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
#endif
+#include "selinux-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "stat-util.h"
@@ -98,6 +103,11 @@
#include "user-util.h"
#include "util.h"
+/* Note that devpts's gid= parameter parses GIDs as signed values, hence we stay away from the upper half of the 32bit
+ * UID range here */
+#define UID_SHIFT_PICK_MIN ((uid_t) UINT32_C(0x00080000))
+#define UID_SHIFT_PICK_MAX ((uid_t) UINT32_C(0x6FFF0000))
+
typedef enum ContainerStatus {
CONTAINER_TERMINATED,
CONTAINER_REBOOTED
@@ -165,13 +175,15 @@ static char **arg_network_ipvlan = NULL;
static bool arg_network_veth = false;
static char **arg_network_veth_extra = NULL;
static char *arg_network_bridge = NULL;
+static char *arg_network_zone = NULL;
static unsigned long arg_personality = PERSONALITY_INVALID;
static char *arg_image = NULL;
static VolatileMode arg_volatile_mode = VOLATILE_NO;
static ExposePort *arg_expose_ports = NULL;
static char **arg_property = NULL;
+static UserNamespaceMode arg_userns_mode = USER_NAMESPACE_NO;
static uid_t arg_uid_shift = UID_INVALID, arg_uid_range = 0x10000U;
-static bool arg_userns = false;
+static bool arg_userns_chown = false;
static int arg_kill_signal = 0;
static bool arg_unified_cgroup_hierarchy = false;
static SettingsMask arg_settings_mask = 0;
@@ -199,8 +211,10 @@ static void help(void) {
" --uuid=UUID Set a specific machine UUID for the container\n"
" -S --slice=SLICE Place the container in the specified slice\n"
" --property=NAME=VALUE Set scope unit property\n"
+ " -U --private-users=pick Run within user namespace, pick UID/GID range automatically\n"
" --private-users[=UIDBASE[:NUIDS]]\n"
- " Run within user namespace\n"
+ " Run within user namespace, user configured UID/GID range\n"
+ " --private-user-chown Adjust OS tree file ownership for private UID/GID range\n"
" --private-network Disable network in container\n"
" --network-interface=INTERFACE\n"
" Assign an existing network interface to the\n"
@@ -220,6 +234,8 @@ static void help(void) {
" Add a virtual Ethernet connection between host\n"
" and container and add it to an existing bridge on\n"
" the host\n"
+ " --network-zone=NAME Add a virtual Ethernet connection to the container,\n"
+ " and add it to an automatically managed bridge interface\n"
" -p --port=[PROTOCOL:]HOSTPORT[:CONTAINERPORT]\n"
" Expose a container IP port on the host\n"
" -Z --selinux-context=SECLABEL\n"
@@ -247,7 +263,7 @@ static void help(void) {
" the container\n"
" --overlay-ro=PATH[:PATH...]:PATH\n"
" Similar, but creates a read-only overlay mount\n"
- " --setenv=NAME=VALUE Pass an environment variable to PID 1\n"
+ " -E --setenv=NAME=VALUE Pass an environment variable to PID 1\n"
" --share-system Share system namespaces with host\n"
" --register=BOOLEAN Register container as machine\n"
" --keep-unit Do not register a scope for the machine, reuse\n"
@@ -269,9 +285,15 @@ static int custom_mounts_prepare(void) {
for (i = 0; i < arg_n_custom_mounts; i++) {
CustomMount *m = &arg_custom_mounts[i];
- if (arg_userns && arg_uid_shift == UID_INVALID && path_equal(m->destination, "/")) {
- log_error("--private-users with automatic UID shift may not be combined with custom root mounts.");
- return -EINVAL;
+ if (path_equal(m->destination, "/") && arg_userns_mode != USER_NAMESPACE_NO) {
+
+ if (arg_userns_chown) {
+ log_error("--private-users-chown may not be combined with custom root mounts.");
+ return -EINVAL;
+ } else if (arg_uid_shift == UID_INVALID) {
+ log_error("--private-users with automatic UID shift may not be combined with custom root mounts.");
+ return -EINVAL;
+ }
}
if (m->type != CUSTOM_MOUNT_OVERLAY)
@@ -330,7 +352,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_TMPFS,
ARG_OVERLAY,
ARG_OVERLAY_RO,
- ARG_SETENV,
ARG_SHARE_SYSTEM,
ARG_REGISTER,
ARG_KEEP_UNIT,
@@ -338,6 +359,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NETWORK_MACVLAN,
ARG_NETWORK_IPVLAN,
ARG_NETWORK_BRIDGE,
+ ARG_NETWORK_ZONE,
ARG_NETWORK_VETH_EXTRA,
ARG_PERSONALITY,
ARG_VOLATILE,
@@ -347,6 +369,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_KILL_SIGNAL,
ARG_SETTINGS,
ARG_CHDIR,
+ ARG_PRIVATE_USERS_CHOWN,
};
static const struct option options[] = {
@@ -371,7 +394,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "overlay-ro", required_argument, NULL, ARG_OVERLAY_RO },
{ "machine", required_argument, NULL, 'M' },
{ "slice", required_argument, NULL, 'S' },
- { "setenv", required_argument, NULL, ARG_SETENV },
+ { "setenv", required_argument, NULL, 'E' },
{ "selinux-context", required_argument, NULL, 'Z' },
{ "selinux-apifs-context", required_argument, NULL, 'L' },
{ "quiet", no_argument, NULL, 'q' },
@@ -384,12 +407,14 @@ static int parse_argv(int argc, char *argv[]) {
{ "network-veth", no_argument, NULL, 'n' },
{ "network-veth-extra", required_argument, NULL, ARG_NETWORK_VETH_EXTRA},
{ "network-bridge", required_argument, NULL, ARG_NETWORK_BRIDGE },
+ { "network-zone", required_argument, NULL, ARG_NETWORK_ZONE },
{ "personality", required_argument, NULL, ARG_PERSONALITY },
{ "image", required_argument, NULL, 'i' },
{ "volatile", optional_argument, NULL, ARG_VOLATILE },
{ "port", required_argument, NULL, 'p' },
{ "property", required_argument, NULL, ARG_PROPERTY },
{ "private-users", optional_argument, NULL, ARG_PRIVATE_USERS },
+ { "private-users-chown", optional_argument, NULL, ARG_PRIVATE_USERS_CHOWN},
{ "kill-signal", required_argument, NULL, ARG_KILL_SIGNAL },
{ "settings", required_argument, NULL, ARG_SETTINGS },
{ "chdir", required_argument, NULL, ARG_CHDIR },
@@ -404,7 +429,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hD:u:abL:M:jS:Z:qi:xp:n", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "+hD:u:abL:M:jS:Z:qi:xp:nU", options, NULL)) >= 0)
switch (c) {
@@ -445,7 +470,35 @@ static int parse_argv(int argc, char *argv[]) {
arg_settings_mask |= SETTING_USER;
break;
+ case ARG_NETWORK_ZONE: {
+ char *j;
+
+ j = strappend("vz-", optarg);
+ if (!j)
+ return log_oom();
+
+ if (!ifname_valid(j)) {
+ log_error("Network zone name not valid: %s", j);
+ free(j);
+ return -EINVAL;
+ }
+
+ free(arg_network_zone);
+ arg_network_zone = j;
+
+ arg_network_veth = true;
+ arg_private_network = true;
+ arg_settings_mask |= SETTING_NETWORK;
+ break;
+ }
+
case ARG_NETWORK_BRIDGE:
+
+ if (!ifname_valid(optarg)) {
+ log_error("Bridge interface name not valid: %s", optarg);
+ return -EINVAL;
+ }
+
r = free_and_strdup(&arg_network_bridge, optarg);
if (r < 0)
return log_oom();
@@ -468,6 +521,12 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_NETWORK_INTERFACE:
+
+ if (!ifname_valid(optarg)) {
+ log_error("Network interface name not valid: %s", optarg);
+ return -EINVAL;
+ }
+
if (strv_extend(&arg_network_interfaces, optarg) < 0)
return log_oom();
@@ -476,6 +535,12 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_NETWORK_MACVLAN:
+
+ if (!ifname_valid(optarg)) {
+ log_error("MACVLAN network interface name not valid: %s", optarg);
+ return -EINVAL;
+ }
+
if (strv_extend(&arg_network_macvlan, optarg) < 0)
return log_oom();
@@ -484,6 +549,12 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_NETWORK_IPVLAN:
+
+ if (!ifname_valid(optarg)) {
+ log_error("IPVLAN network interface name not valid: %s", optarg);
+ return -EINVAL;
+ }
+
if (strv_extend(&arg_network_ipvlan, optarg) < 0)
return log_oom();
@@ -560,7 +631,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_CAPABILITY:
case ARG_DROP_CAPABILITY: {
p = optarg;
- for(;;) {
+ for (;;) {
_cleanup_free_ char *t = NULL;
r = extract_first_word(&p, &t, ",", 0);
@@ -708,7 +779,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
- case ARG_SETENV: {
+ case 'E': {
char **n;
if (!env_assignment_is_valid(optarg)) {
@@ -795,10 +866,29 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_PRIVATE_USERS:
- if (optarg) {
+
+ r = optarg ? parse_boolean(optarg) : 1;
+ if (r == 0) {
+ /* no: User namespacing off */
+ arg_userns_mode = USER_NAMESPACE_NO;
+ arg_uid_shift = UID_INVALID;
+ arg_uid_range = UINT32_C(0x10000);
+ } else if (r > 0) {
+ /* yes: User namespacing on, UID range is read from root dir */
+ arg_userns_mode = USER_NAMESPACE_FIXED;
+ arg_uid_shift = UID_INVALID;
+ arg_uid_range = UINT32_C(0x10000);
+ } else if (streq(optarg, "pick")) {
+ /* pick: User namespacing on, UID range is picked randomly */
+ arg_userns_mode = USER_NAMESPACE_PICK;
+ arg_uid_shift = UID_INVALID;
+ arg_uid_range = UINT32_C(0x10000);
+ } else {
_cleanup_free_ char *buffer = NULL;
const char *range, *shift;
+ /* anything else: User namespacing on, UID range is explicitly configured */
+
range = strchr(optarg, ':');
if (range) {
buffer = strndup(optarg, range - optarg);
@@ -818,9 +908,28 @@ static int parse_argv(int argc, char *argv[]) {
log_error("Failed to parse UID: %s", optarg);
return -EINVAL;
}
+
+ arg_userns_mode = USER_NAMESPACE_FIXED;
}
- arg_userns = true;
+ arg_settings_mask |= SETTING_USERNS;
+ break;
+
+ case 'U':
+ if (userns_supported()) {
+ arg_userns_mode = USER_NAMESPACE_PICK;
+ arg_uid_shift = UID_INVALID;
+ arg_uid_range = UINT32_C(0x10000);
+
+ arg_settings_mask |= SETTING_USERNS;
+ }
+
+ break;
+
+ case ARG_PRIVATE_USERS_CHOWN:
+ arg_userns_chown = true;
+
+ arg_settings_mask |= SETTING_USERNS;
break;
case ARG_KILL_SIGNAL:
@@ -891,6 +1000,9 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_share_system)
arg_register = false;
+ if (arg_userns_mode == USER_NAMESPACE_PICK)
+ arg_userns_chown = true;
+
if (arg_start_mode != START_PID1 && arg_share_system) {
log_error("--boot and --share-system may not be combined.");
return -EINVAL;
@@ -931,8 +1043,20 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
- if (arg_userns && access("/proc/self/uid_map", F_OK) < 0)
- return log_error_errno(EOPNOTSUPP, "--private-users= is not supported, kernel compiled without user namespace support.");
+ if (arg_userns_mode != USER_NAMESPACE_NO && !userns_supported()) {
+ log_error("--private-users= is not supported, kernel compiled without user namespace support.");
+ return -EOPNOTSUPP;
+ }
+
+ if (arg_userns_chown && arg_read_only) {
+ log_error("--read-only and --private-users-chown may not be combined.");
+ return -EINVAL;
+ }
+
+ if (arg_network_bridge && arg_network_zone) {
+ log_error("--network-bridge= and --network-zone= may not be combined.");
+ return -EINVAL;
+ }
if (argc > optind) {
arg_parameters = strv_copy(argv + optind);
@@ -975,6 +1099,13 @@ static int verify_arguments(void) {
return -EINVAL;
}
+#ifndef HAVE_LIBIPTC
+ if (arg_expose_ports) {
+ log_error("--port= is not supported, compiled without libiptc support.");
+ return -EOPNOTSUPP;
+ }
+#endif
+
if (arg_start_mode == START_BOOT && arg_kill_signal <= 0)
arg_kill_signal = SIGRTMIN+3;
@@ -984,7 +1115,7 @@ static int verify_arguments(void) {
static int userns_lchown(const char *p, uid_t uid, gid_t gid) {
assert(p);
- if (!arg_userns)
+ if (arg_userns_mode == USER_NAMESPACE_NO)
return 0;
if (uid == UID_INVALID && gid == GID_INVALID)
@@ -1366,11 +1497,11 @@ static int setup_hostname(void) {
}
static int setup_journal(const char *directory) {
- sd_id128_t machine_id, this_id;
- _cleanup_free_ char *b = NULL, *d = NULL;
- const char *etc_machine_id, *p, *q;
+ sd_id128_t this_id;
+ _cleanup_free_ char *d = NULL;
+ const char *p, *q;
bool try;
- char *id;
+ char id[33];
int r;
/* Don't link journals in ephemeral mode */
@@ -1382,30 +1513,13 @@ static int setup_journal(const char *directory) {
try = arg_link_journal_try || arg_link_journal == LINK_AUTO;
- etc_machine_id = prefix_roota(directory, "/etc/machine-id");
-
- r = read_one_line_file(etc_machine_id, &b);
- if (r == -ENOENT && try)
- return 0;
- else if (r < 0)
- return log_error_errno(r, "Failed to read machine ID from %s: %m", etc_machine_id);
-
- id = strstrip(b);
- if (isempty(id) && try)
- return 0;
-
- /* Verify validity */
- r = sd_id128_from_string(id, &machine_id);
- if (r < 0)
- return log_error_errno(r, "Failed to parse machine ID from %s: %m", etc_machine_id);
-
r = sd_id128_get_machine(&this_id);
if (r < 0)
return log_error_errno(r, "Failed to retrieve machine ID: %m");
- if (sd_id128_equal(machine_id, this_id)) {
+ if (sd_id128_equal(arg_uuid, this_id)) {
log_full(try ? LOG_WARNING : LOG_ERR,
- "Host and machine ids are equal (%s): refusing to link journals", id);
+ "Host and machine ids are equal (%s): refusing to link journals", sd_id128_to_string(arg_uuid, id));
if (try)
return 0;
return -EEXIST;
@@ -1423,6 +1537,8 @@ static int setup_journal(const char *directory) {
if (r < 0)
return log_error_errno(r, "Failed to create /var/log/journal: %m");
+ (void) sd_id128_to_string(arg_uuid, id);
+
p = strjoina("/var/log/journal/", id);
q = prefix_roota(directory, p);
@@ -1487,7 +1603,7 @@ static int setup_journal(const char *directory) {
}
if (arg_link_journal == LINK_HOST) {
- /* don't create parents here -- if the host doesn't have
+ /* don't create parents here — if the host doesn't have
* permanent journal set up, don't force it here */
if (mkdir(p, 0755) < 0 && errno != EEXIST) {
@@ -1596,7 +1712,6 @@ static int setup_seccomp(void) {
}
}
-
/*
Audit is broken in containers, much of the userspace audit
hookup will fail if running inside a container. We don't
@@ -2192,6 +2307,61 @@ static int mount_device(const char *what, const char *where, const char *directo
#endif
}
+static int setup_machine_id(const char *directory) {
+ int r;
+ const char *etc_machine_id, *t;
+ _cleanup_free_ char *s = NULL;
+
+ etc_machine_id = prefix_roota(directory, "/etc/machine-id");
+
+ r = read_one_line_file(etc_machine_id, &s);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read machine ID from %s: %m", etc_machine_id);
+
+ t = strstrip(s);
+
+ if (!isempty(t)) {
+ r = sd_id128_from_string(t, &arg_uuid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse machine ID from %s: %m", etc_machine_id);
+ } else {
+ if (sd_id128_is_null(arg_uuid)) {
+ r = sd_id128_randomize(&arg_uuid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate random machine ID: %m");
+ }
+ }
+
+ r = machine_id_setup(directory, arg_uuid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to setup machine ID: %m");
+
+ return 0;
+}
+
+static int recursive_chown(const char *directory, uid_t shift, uid_t range) {
+ int r;
+
+ assert(directory);
+
+ if (arg_userns_mode == USER_NAMESPACE_NO || !arg_userns_chown)
+ return 0;
+
+ r = path_patch_uid(directory, arg_uid_shift, arg_uid_range);
+ if (r == -EOPNOTSUPP)
+ return log_error_errno(r, "Automatic UID/GID adjusting is only supported for UID/GID ranges starting at multiples of 2^16 with a range of 2^16.");
+ if (r == -EBADE)
+ return log_error_errno(r, "Upper 16 bits of root directory UID and GID do not match.");
+ if (r < 0)
+ return log_error_errno(r, "Failed to adjust UID/GID shift of OS tree: %m");
+ if (r == 0)
+ log_debug("Root directory of image is already owned by the right UID/GID range, skipping recursive chown operation.");
+ else
+ log_debug("Patched directory tree to match UID/GID range.");
+
+ return r;
+}
+
static int mount_devices(
const char *where,
const char *root_device, bool root_device_rw,
@@ -2409,7 +2579,7 @@ static int determine_names(void) {
static int determine_uid_shift(const char *directory) {
int r;
- if (!arg_userns) {
+ if (arg_userns_mode == USER_NAMESPACE_NO) {
arg_uid_shift = 0;
return 0;
}
@@ -2436,7 +2606,6 @@ static int determine_uid_shift(const char *directory) {
return -EINVAL;
}
- log_info("Using user namespaces with base " UID_FMT " and range " UID_FMT ".", arg_uid_shift, arg_uid_range);
return 0;
}
@@ -2449,6 +2618,7 @@ static int inner_child(
FDSet *fds) {
_cleanup_free_ char *home = NULL;
+ char as_uuid[37];
unsigned n_env = 1;
const char *envp[] = {
"PATH=" DEFAULT_PATH_SPLIT_USR,
@@ -2472,7 +2642,7 @@ static int inner_child(
cg_unified_flush();
- if (arg_userns) {
+ if (arg_userns_mode != USER_NAMESPACE_NO) {
/* Tell the parent, that it now can write the UID map. */
(void) barrier_place(barrier); /* #1 */
@@ -2483,7 +2653,14 @@ static int inner_child(
}
}
- r = mount_all(NULL, arg_userns, true, arg_uid_shift, arg_private_network, arg_uid_range, arg_selinux_apifs_context);
+ r = mount_all(NULL,
+ arg_userns_mode != USER_NAMESPACE_NO,
+ true,
+ arg_private_network,
+ arg_uid_shift,
+ arg_uid_range,
+ arg_selinux_apifs_context);
+
if (r < 0)
return r;
@@ -2559,19 +2736,17 @@ static int inner_child(
envp[n_env] = strv_find_prefix(environ, "TERM=");
if (envp[n_env])
- n_env ++;
+ n_env++;
if ((asprintf((char**)(envp + n_env++), "HOME=%s", home ? home: "/root") < 0) ||
(asprintf((char**)(envp + n_env++), "USER=%s", arg_user ? arg_user : "root") < 0) ||
(asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0))
return log_oom();
- if (!sd_id128_equal(arg_uuid, SD_ID128_NULL)) {
- char as_uuid[37];
+ assert(!sd_id128_equal(arg_uuid, SD_ID128_NULL));
- if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_format_as_uuid(arg_uuid, as_uuid)) < 0)
- return log_oom();
- }
+ if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_format_as_uuid(arg_uuid, as_uuid)) < 0)
+ return log_oom();
if (fdset_size(fds) > 0) {
r = fdset_cloexec(fds, false);
@@ -2622,12 +2797,10 @@ static int inner_child(
/* Automatically search for the init system */
- m = 1 + strv_length(arg_parameters);
- a = newa(char*, m + 1);
- if (strv_isempty(arg_parameters))
- a[1] = NULL;
- else
- memcpy(a + 1, arg_parameters, m * sizeof(char*));
+ m = strv_length(arg_parameters);
+ a = newa(char*, m + 2);
+ memcpy_safe(a + 1, arg_parameters, m * sizeof(char*));
+ a[1 + m] = NULL;
a[0] = (char*) "/usr/lib/systemd/systemd";
execve(a[0], a, env_use);
@@ -2641,7 +2814,8 @@ static int inner_child(
execvpe(arg_parameters[0], arg_parameters, env_use);
else {
if (!arg_chdir)
- chdir(home ?: "/root");
+ /* If we cannot change the directory, we'll end up in /, that is expected. */
+ (void) chdir(home ?: "/root");
execle("/bin/bash", "-bash", NULL, env_use);
execle("/bin/sh", "-sh", NULL, env_use);
@@ -2662,6 +2836,7 @@ static int outer_child(
bool interactive,
bool secondary,
int pid_socket,
+ int uuid_socket,
int kmsg_socket,
int rtnl_socket,
int uid_shift_socket,
@@ -2675,6 +2850,7 @@ static int outer_child(
assert(directory);
assert(console);
assert(pid_socket >= 0);
+ assert(uuid_socket >= 0);
assert(kmsg_socket >= 0);
cg_unified_flush();
@@ -2723,7 +2899,8 @@ static int outer_child(
if (r < 0)
return r;
- if (arg_userns) {
+ if (arg_userns_mode != USER_NAMESPACE_NO) {
+ /* Let the parent know which UID shift we read from the image */
l = send(uid_shift_socket, &arg_uid_shift, sizeof(arg_uid_shift), MSG_NOSIGNAL);
if (l < 0)
return log_error_errno(errno, "Failed to send UID shift: %m");
@@ -2731,17 +2908,49 @@ static int outer_child(
log_error("Short write while sending UID shift.");
return -EIO;
}
+
+ if (arg_userns_mode == USER_NAMESPACE_PICK) {
+ /* When we are supposed to pick the UID shift, the parent will check now whether the UID shift
+ * we just read from the image is available. If yes, it will send the UID shift back to us, if
+ * not it will pick a different one, and send it back to us. */
+
+ l = recv(uid_shift_socket, &arg_uid_shift, sizeof(arg_uid_shift), 0);
+ if (l < 0)
+ return log_error_errno(errno, "Failed to recv UID shift: %m");
+ if (l != sizeof(arg_uid_shift)) {
+ log_error("Short read while recieving UID shift.");
+ return -EIO;
+ }
+ }
+
+ log_info("Selected user namespace base " UID_FMT " and range " UID_FMT ".", arg_uid_shift, arg_uid_range);
}
/* Turn directory into bind mount */
if (mount(directory, directory, NULL, MS_BIND|MS_REC, NULL) < 0)
return log_error_errno(errno, "Failed to make bind mount: %m");
- r = setup_volatile(directory, arg_volatile_mode, arg_userns, arg_uid_shift, arg_uid_range, arg_selinux_context);
+ r = recursive_chown(directory, arg_uid_shift, arg_uid_range);
if (r < 0)
return r;
- r = setup_volatile_state(directory, arg_volatile_mode, arg_userns, arg_uid_shift, arg_uid_range, arg_selinux_context);
+ r = setup_volatile(
+ directory,
+ arg_volatile_mode,
+ arg_userns_mode != USER_NAMESPACE_NO,
+ arg_uid_shift,
+ arg_uid_range,
+ arg_selinux_context);
+ if (r < 0)
+ return r;
+
+ r = setup_volatile_state(
+ directory,
+ arg_volatile_mode,
+ arg_userns_mode != USER_NAMESPACE_NO,
+ arg_uid_shift,
+ arg_uid_range,
+ arg_selinux_context);
if (r < 0)
return r;
@@ -2755,7 +2964,13 @@ static int outer_child(
return log_error_errno(r, "Failed to make tree read-only: %m");
}
- r = mount_all(directory, arg_userns, false, arg_private_network, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+ r = mount_all(directory,
+ arg_userns_mode != USER_NAMESPACE_NO,
+ false,
+ arg_private_network,
+ arg_uid_shift,
+ arg_uid_range,
+ arg_selinux_apifs_context);
if (r < 0)
return r;
@@ -2789,15 +3004,32 @@ static int outer_child(
if (r < 0)
return r;
+ r = setup_machine_id(directory);
+ if (r < 0)
+ return r;
+
r = setup_journal(directory);
if (r < 0)
return r;
- r = mount_custom(directory, arg_custom_mounts, arg_n_custom_mounts, arg_userns, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+ r = mount_custom(
+ directory,
+ arg_custom_mounts,
+ arg_n_custom_mounts,
+ arg_userns_mode != USER_NAMESPACE_NO,
+ arg_uid_shift,
+ arg_uid_range,
+ arg_selinux_apifs_context);
if (r < 0)
return r;
- r = mount_cgroups(directory, arg_unified_cgroup_hierarchy, arg_userns, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+ r = mount_cgroups(
+ directory,
+ arg_unified_cgroup_hierarchy,
+ arg_userns_mode != USER_NAMESPACE_NO,
+ arg_uid_shift,
+ arg_uid_range,
+ arg_selinux_apifs_context);
if (r < 0)
return r;
@@ -2808,12 +3040,13 @@ static int outer_child(
pid = raw_clone(SIGCHLD|CLONE_NEWNS|
(arg_share_system ? 0 : CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS) |
(arg_private_network ? CLONE_NEWNET : 0) |
- (arg_userns ? CLONE_NEWUSER : 0),
+ (arg_userns_mode != USER_NAMESPACE_NO ? CLONE_NEWUSER : 0),
NULL);
if (pid < 0)
return log_error_errno(errno, "Failed to fork inner child: %m");
if (pid == 0) {
pid_socket = safe_close(pid_socket);
+ uuid_socket = safe_close(uuid_socket);
uid_shift_socket = safe_close(uid_shift_socket);
/* The inner child has all namespaces that are
@@ -2835,13 +3068,77 @@ static int outer_child(
return -EIO;
}
+ l = send(uuid_socket, &arg_uuid, sizeof(arg_uuid), MSG_NOSIGNAL);
+ if (l < 0)
+ return log_error_errno(errno, "Failed to send machine ID: %m");
+ if (l != sizeof(arg_uuid)) {
+ log_error("Short write while sending machine ID.");
+ return -EIO;
+ }
+
pid_socket = safe_close(pid_socket);
+ uuid_socket = safe_close(uuid_socket);
kmsg_socket = safe_close(kmsg_socket);
rtnl_socket = safe_close(rtnl_socket);
return 0;
}
+static int uid_shift_pick(uid_t *shift, LockFile *ret_lock_file) {
+ unsigned n_tries = 100;
+ uid_t candidate;
+ int r;
+
+ assert(shift);
+ assert(ret_lock_file);
+ assert(arg_userns_mode == USER_NAMESPACE_PICK);
+ assert(arg_uid_range == 0x10000U);
+
+ candidate = *shift;
+
+ (void) mkdir("/run/systemd/nspawn-uid", 0755);
+
+ for (;;) {
+ char lock_path[strlen("/run/systemd/nspawn-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
+ _cleanup_release_lock_file_ LockFile lf = LOCK_FILE_INIT;
+
+ if (--n_tries <= 0)
+ return -EBUSY;
+
+ if (candidate < UID_SHIFT_PICK_MIN || candidate > UID_SHIFT_PICK_MAX)
+ goto next;
+ if ((candidate & UINT32_C(0xFFFF)) != 0)
+ goto next;
+
+ xsprintf(lock_path, "/run/systemd/nspawn-uid/" UID_FMT, candidate);
+ r = make_lock_file(lock_path, LOCK_EX|LOCK_NB, &lf);
+ if (r == -EBUSY) /* Range already taken by another nspawn instance */
+ goto next;
+ if (r < 0)
+ return r;
+
+ /* Make some superficial checks whether the range is currently known in the user database */
+ if (getpwuid(candidate))
+ goto next;
+ if (getpwuid(candidate + UINT32_C(0xFFFE)))
+ goto next;
+ if (getgrgid(candidate))
+ goto next;
+ if (getgrgid(candidate + UINT32_C(0xFFFE)))
+ goto next;
+
+ *ret_lock_file = lf;
+ lf = (struct LockFile) LOCK_FILE_INIT;
+ *shift = candidate;
+ return 0;
+
+ next:
+ random_bytes(&candidate, sizeof(candidate));
+ candidate = (candidate % (UID_SHIFT_PICK_MAX - UID_SHIFT_PICK_MIN)) + UID_SHIFT_PICK_MIN;
+ candidate &= (uid_t) UINT32_C(0xFFFF0000);
+ }
+}
+
static int setup_uid_map(pid_t pid) {
char uid_map[strlen("/proc//uid_map") + DECIMAL_STR_MAX(uid_t) + 1], line[DECIMAL_STR_MAX(uid_t)*3+3+1];
int r;
@@ -3028,6 +3325,7 @@ static int load_settings(void) {
(settings->private_network >= 0 ||
settings->network_veth >= 0 ||
settings->network_bridge ||
+ settings->network_zone ||
settings->network_interfaces ||
settings->network_macvlan ||
settings->network_ipvlan ||
@@ -3058,6 +3356,10 @@ static int load_settings(void) {
free(arg_network_bridge);
arg_network_bridge = settings->network_bridge;
settings->network_bridge = NULL;
+
+ free(arg_network_zone);
+ arg_network_zone = settings->network_zone;
+ settings->network_zone = NULL;
}
}
@@ -3073,6 +3375,19 @@ static int load_settings(void) {
}
}
+ if ((arg_settings_mask & SETTING_USERNS) == 0 &&
+ settings->userns_mode != _USER_NAMESPACE_MODE_INVALID) {
+
+ if (!arg_settings_trusted)
+ log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", p);
+ else {
+ arg_userns_mode = settings->userns_mode;
+ arg_uid_shift = settings->uid_shift;
+ arg_uid_range = settings->uid_range;
+ arg_userns_chown = settings->userns_chown;
+ }
+ }
+
return 0;
}
@@ -3083,14 +3398,14 @@ int main(int argc, char *argv[]) {
_cleanup_close_ int master = -1, image_fd = -1;
_cleanup_fdset_free_ FDSet *fds = NULL;
int r, n_fd_passed, loop_nr = -1;
- char veth_name[IFNAMSIZ];
+ char veth_name[IFNAMSIZ] = "";
bool secondary = false, remove_subvol = false;
sigset_t mask_chld;
pid_t pid = 0;
int ret = EXIT_SUCCESS;
union in_addr_union exposed = {};
_cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
- bool interactive;
+ bool interactive, veth_created = false;
log_parse_environment();
log_open();
@@ -3285,6 +3600,12 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ if (arg_selinux_apifs_context) {
+ r = mac_selinux_apply(console, arg_selinux_apifs_context);
+ if (r < 0)
+ goto finish;
+ }
+
if (unlockpt(master) < 0) {
r = log_error_errno(errno, "Failed to unlock tty: %m");
goto finish;
@@ -3305,19 +3626,42 @@ int main(int argc, char *argv[]) {
}
for (;;) {
- _cleanup_close_pair_ int kmsg_socket_pair[2] = { -1, -1 }, rtnl_socket_pair[2] = { -1, -1 }, pid_socket_pair[2] = { -1, -1 }, uid_shift_socket_pair[2] = { -1, -1 };
- ContainerStatus container_status;
- _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
static const struct sigaction sa = {
.sa_handler = nop_signal_handler,
.sa_flags = SA_NOCLDSTOP,
};
- int ifi = 0;
- ssize_t l;
+
+ _cleanup_release_lock_file_ LockFile uid_shift_lock = LOCK_FILE_INIT;
+ _cleanup_close_ int etc_passwd_lock = -1;
+ _cleanup_close_pair_ int
+ kmsg_socket_pair[2] = { -1, -1 },
+ rtnl_socket_pair[2] = { -1, -1 },
+ pid_socket_pair[2] = { -1, -1 },
+ uuid_socket_pair[2] = { -1, -1 },
+ uid_shift_socket_pair[2] = { -1, -1 };
+ _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ ContainerStatus container_status;
char last_char = 0;
+ int ifi = 0;
+ ssize_t l;
+
+ if (arg_userns_mode == USER_NAMESPACE_PICK) {
+ /* When we shall pick the UID/GID range, let's first lock /etc/passwd, so that we can safely
+ * check with getpwuid() if the specific user already exists. Note that /etc might be
+ * read-only, in which case this will fail with EROFS. But that's really OK, as in that case we
+ * can be reasonably sure that no users are going to be added. Note that getpwuid() checks are
+ * really just an extra safety net. We kinda assume that the UID range we allocate from is
+ * really ours. */
+
+ etc_passwd_lock = take_etc_passwd_lock(NULL);
+ if (etc_passwd_lock < 0 && etc_passwd_lock != -EROFS) {
+ log_error_errno(r, "Failed to take /etc/passwd lock: %m");
+ goto finish;
+ }
+ }
r = barrier_create(&barrier);
if (r < 0) {
@@ -3340,7 +3684,12 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (arg_userns)
+ if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, uuid_socket_pair) < 0) {
+ r = log_error_errno(errno, "Failed to create id socket pair: %m");
+ goto finish;
+ }
+
+ if (arg_userns_mode != USER_NAMESPACE_NO)
if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, uid_shift_socket_pair) < 0) {
r = log_error_errno(errno, "Failed to create uid shift socket pair: %m");
goto finish;
@@ -3380,6 +3729,7 @@ int main(int argc, char *argv[]) {
kmsg_socket_pair[0] = safe_close(kmsg_socket_pair[0]);
rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]);
pid_socket_pair[0] = safe_close(pid_socket_pair[0]);
+ uuid_socket_pair[0] = safe_close(uuid_socket_pair[0]);
uid_shift_socket_pair[0] = safe_close(uid_shift_socket_pair[0]);
(void) reset_all_signal_handlers();
@@ -3394,6 +3744,7 @@ int main(int argc, char *argv[]) {
interactive,
secondary,
pid_socket_pair[1],
+ uuid_socket_pair[1],
kmsg_socket_pair[1],
rtnl_socket_pair[1],
uid_shift_socket_pair[1],
@@ -3411,8 +3762,46 @@ int main(int argc, char *argv[]) {
kmsg_socket_pair[1] = safe_close(kmsg_socket_pair[1]);
rtnl_socket_pair[1] = safe_close(rtnl_socket_pair[1]);
pid_socket_pair[1] = safe_close(pid_socket_pair[1]);
+ uuid_socket_pair[1] = safe_close(uuid_socket_pair[1]);
uid_shift_socket_pair[1] = safe_close(uid_shift_socket_pair[1]);
+ if (arg_userns_mode != USER_NAMESPACE_NO) {
+ /* The child just let us know the UID shift it might have read from the image. */
+ l = recv(uid_shift_socket_pair[0], &arg_uid_shift, sizeof(arg_uid_shift), 0);
+ if (l < 0) {
+ r = log_error_errno(errno, "Failed to read UID shift: %m");
+ goto finish;
+ }
+ if (l != sizeof(arg_uid_shift)) {
+ log_error("Short read while reading UID shift.");
+ r = EIO;
+ goto finish;
+ }
+
+ if (arg_userns_mode == USER_NAMESPACE_PICK) {
+ /* If we are supposed to pick the UID shift, let's try to use the shift read from the
+ * image, but if that's already in use, pick a new one, and report back to the child,
+ * which one we now picked. */
+
+ r = uid_shift_pick(&arg_uid_shift, &uid_shift_lock);
+ if (r < 0) {
+ log_error_errno(r, "Failed to pick suitable UID/GID range: %m");
+ goto finish;
+ }
+
+ l = send(uid_shift_socket_pair[0], &arg_uid_shift, sizeof(arg_uid_shift), MSG_NOSIGNAL);
+ if (l < 0) {
+ r = log_error_errno(errno, "Failed to send UID shift: %m");
+ goto finish;
+ }
+ if (l != sizeof(arg_uid_shift)) {
+ log_error("Short write while writing UID shift.");
+ r = -EIO;
+ goto finish;
+ }
+ }
+ }
+
/* Wait for the outer child. */
r = wait_for_terminate_and_warn("namespace helper", pid, NULL);
if (r < 0)
@@ -3435,26 +3824,27 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ /* We also retrieve container UUID in case it was generated by outer child */
+ l = recv(uuid_socket_pair[0], &arg_uuid, sizeof(arg_uuid), 0);
+ if (l < 0) {
+ r = log_error_errno(errno, "Failed to read container machine ID: %m");
+ goto finish;
+ }
+ if (l != sizeof(arg_uuid)) {
+ log_error("Short read while reading container machined ID.");
+ r = EIO;
+ goto finish;
+ }
+
log_debug("Init process invoked as PID " PID_FMT, pid);
- if (arg_userns) {
+ if (arg_userns_mode != USER_NAMESPACE_NO) {
if (!barrier_place_and_sync(&barrier)) { /* #1 */
log_error("Child died too early.");
r = -ESRCH;
goto finish;
}
- l = recv(uid_shift_socket_pair[0], &arg_uid_shift, sizeof(arg_uid_shift), 0);
- if (l < 0) {
- r = log_error_errno(errno, "Failed to read UID shift: %m");
- goto finish;
- }
- if (l != sizeof(arg_uid_shift)) {
- log_error("Short read while reading UID shift.");
- r = EIO;
- goto finish;
- }
-
r = setup_uid_map(pid);
if (r < 0)
goto finish;
@@ -3469,14 +3859,23 @@ int main(int argc, char *argv[]) {
goto finish;
if (arg_network_veth) {
- r = setup_veth(arg_machine, pid, veth_name, !!arg_network_bridge);
+ r = setup_veth(arg_machine, pid, veth_name,
+ arg_network_bridge || arg_network_zone);
if (r < 0)
goto finish;
else if (r > 0)
ifi = r;
if (arg_network_bridge) {
- r = setup_bridge(veth_name, arg_network_bridge);
+ /* Add the interface to a bridge */
+ r = setup_bridge(veth_name, arg_network_bridge, false);
+ if (r < 0)
+ goto finish;
+ if (r > 0)
+ ifi = r;
+ } else if (arg_network_zone) {
+ /* Add the interface to a bridge, possibly creating it */
+ r = setup_bridge(veth_name, arg_network_zone, true);
if (r < 0)
goto finish;
if (r > 0)
@@ -3488,6 +3887,12 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
+ /* We created the primary and extra veth links now; let's remember this, so that we know to
+ remove them later on. Note that we don't bother with removing veth links that were created
+ here when their setup failed half-way, because in that case the kernel should be able to
+ remove them on its own, since they cannot be referenced by anything yet. */
+ veth_created = true;
+
r = setup_macvlan(arg_machine, pid, arg_network_macvlan);
if (r < 0)
goto finish;
@@ -3552,6 +3957,10 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ /* At this point we have made use of the UID we picked, and thus nss-mymachines will make them appear
+ * in getpwuid(), thus we can release the /etc/passwd lock. */
+ etc_passwd_lock = safe_close(etc_passwd_lock);
+
sd_notifyf(false,
"READY=1\n"
"STATUS=Container running.\n"
@@ -3619,7 +4028,7 @@ int main(int argc, char *argv[]) {
/* We failed to wait for the container, or the
* container exited abnormally */
goto finish;
- else if (r > 0 || container_status == CONTAINER_TERMINATED){
+ else if (r > 0 || container_status == CONTAINER_TERMINATED) {
/* The container exited with a non-zero
* status, or with zero status and no reboot
* was requested. */
@@ -3646,6 +4055,9 @@ int main(int argc, char *argv[]) {
}
expose_port_flush(arg_expose_ports, &exposed);
+
+ (void) remove_veth_links(veth_name, arg_network_veth_extra);
+ veth_created = false;
}
finish:
@@ -3679,6 +4091,10 @@ finish:
expose_port_flush(arg_expose_ports, &exposed);
+ if (veth_created)
+ (void) remove_veth_links(veth_name, arg_network_veth_extra);
+ (void) remove_bridge(arg_network_zone);
+
free(arg_directory);
free(arg_template);
free(arg_image);
diff --git a/src/systemd-nspawn/test-patch-uid.c b/src/systemd-nspawn/test-patch-uid.c
new file mode 100644
index 0000000000..11c5321788
--- /dev/null
+++ b/src/systemd-nspawn/test-patch-uid.c
@@ -0,0 +1,61 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+
+#include "log.h"
+#include "nspawn-patch-uid.h"
+#include "user-util.h"
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+ uid_t shift, range;
+ int r;
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ if (argc != 4) {
+ log_error("Expected PATH SHIFT RANGE parameters.");
+ return EXIT_FAILURE;
+ }
+
+ r = parse_uid(argv[2], &shift);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse UID shift %s.", argv[2]);
+ return EXIT_FAILURE;
+ }
+
+ r = parse_gid(argv[3], &range);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse UID range %s.", argv[3]);
+ return EXIT_FAILURE;
+ }
+
+ r = path_patch_uid(argv[1], shift, range);
+ if (r < 0) {
+ log_error_errno(r, "Failed to patch directory tree: %m");
+ return EXIT_FAILURE;
+ }
+
+ log_info("Changed: %s", yes_no(r));
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/systemd-rc-local-generator/rc-local-generator.c b/src/systemd-rc-local-generator/rc-local-generator.c
index 9e9c161993..618bbe428d 100644
--- a/src/systemd-rc-local-generator/rc-local-generator.c
+++ b/src/systemd-rc-local-generator/rc-local-generator.c
@@ -36,7 +36,7 @@
#define RC_LOCAL_SCRIPT_PATH_STOP "/sbin/halt.local"
#endif
-const char *arg_dest = "/tmp";
+static const char *arg_dest = "/tmp";
static int add_symlink(const char *service, const char *where) {
_cleanup_free_ char *from = NULL, *to = NULL;
diff --git a/src/systemd-reply-password/reply-password.c b/src/systemd-reply-password/reply-password.c
index e291758969..17eab9772e 100644
--- a/src/systemd-reply-password/reply-password.c
+++ b/src/systemd-reply-password/reply-password.c
@@ -26,14 +26,12 @@
#include "fd-util.h"
#include "log.h"
#include "macro.h"
+#include "socket-util.h"
#include "string-util.h"
#include "util.h"
static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) {
- union {
- struct sockaddr sa;
- struct sockaddr_un un;
- } sa = {
+ union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
};
@@ -43,7 +41,7 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
- if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0)
+ if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return log_error_errno(errno, "Failed to send: %m");
return 0;
diff --git a/src/systemd-run/run.c b/src/systemd-run/run.c
index 67706f84a0..29b5131f70 100644
--- a/src/systemd-run/run.c
+++ b/src/systemd-run/run.c
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "bus-error.h"
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "calendarspec.h"
#include "env-util.h"
@@ -83,8 +84,8 @@ static void polkit_agent_open_if_enabled(void) {
static void help(void) {
printf("%s [OPTIONS...] {COMMAND} [ARGS...]\n\n"
"Run the specified command in a transient scope or service or timer\n"
- "unit. If timer option is specified and unit is exist which is\n"
- "specified with --unit option then command can be omitted.\n\n"
+ "unit. If a timer option is specified and the unit specified with\n"
+ "the --unit option exists, the command can be omitted.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --no-ask-password Do not prompt for password\n"
@@ -103,7 +104,7 @@ static void help(void) {
" --uid=USER Run as system user\n"
" --gid=GROUP Run as system group\n"
" --nice=NICE Nice level\n"
- " --setenv=NAME=VALUE Set environment\n"
+ " -E --setenv=NAME=VALUE Set environment\n"
" -t --pty Run service on pseudo tty\n"
" -q --quiet Suppress information messages during runtime\n\n"
"Timer options:\n\n"
@@ -125,7 +126,6 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
- ARG_NO_ASK_PASSWORD,
ARG_USER,
ARG_SYSTEM,
ARG_SCOPE,
@@ -133,12 +133,10 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DESCRIPTION,
ARG_SLICE,
ARG_SEND_SIGHUP,
+ ARG_SERVICE_TYPE,
ARG_EXEC_USER,
ARG_EXEC_GROUP,
- ARG_SERVICE_TYPE,
ARG_NICE,
- ARG_SETENV,
- ARG_TTY,
ARG_ON_ACTIVE,
ARG_ON_BOOT,
ARG_ON_STARTUP,
@@ -147,6 +145,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_ON_CALENDAR,
ARG_TIMER_PROPERTY,
ARG_NO_BLOCK,
+ ARG_NO_ASK_PASSWORD,
};
static const struct option options[] = {
@@ -166,9 +165,10 @@ static int parse_argv(int argc, char *argv[]) {
{ "uid", required_argument, NULL, ARG_EXEC_USER },
{ "gid", required_argument, NULL, ARG_EXEC_GROUP },
{ "nice", required_argument, NULL, ARG_NICE },
- { "setenv", required_argument, NULL, ARG_SETENV },
+ { "setenv", required_argument, NULL, 'E' },
{ "property", required_argument, NULL, 'p' },
- { "tty", no_argument, NULL, 't' },
+ { "tty", no_argument, NULL, 't' }, /* deprecated */
+ { "pty", no_argument, NULL, 't' },
{ "quiet", no_argument, NULL, 'q' },
{ "on-active", required_argument, NULL, ARG_ON_ACTIVE },
{ "on-boot", required_argument, NULL, ARG_ON_BOOT },
@@ -266,7 +266,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_nice_set = true;
break;
- case ARG_SETENV:
+ case 'E':
if (strv_extend(&arg_environment, optarg) < 0)
return log_oom();
@@ -621,6 +621,10 @@ static int transient_scope_set_properties(sd_bus_message *m) {
if (r < 0)
return r;
+ r = transient_cgroup_set_properties(m);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid());
if (r < 0)
return r;
@@ -756,6 +760,7 @@ static int start_transient_service(
} else if (arg_transport == BUS_TRANSPORT_MACHINE) {
_cleanup_(sd_bus_unrefp) sd_bus *system_bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *pty_reply = NULL;
const char *s;
r = sd_bus_default_system(&system_bus);
@@ -768,19 +773,17 @@ static int start_transient_service(
"org.freedesktop.machine1.Manager",
"OpenMachinePTY",
&error,
- &reply,
+ &pty_reply,
"s", arg_host);
if (r < 0) {
log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
return r;
}
- r = sd_bus_message_read(reply, "hs", &master, &s);
+ r = sd_bus_message_read(pty_reply, "hs", &master, &s);
if (r < 0)
return bus_log_parse_error(r);
- reply = sd_bus_message_unref(reply);
-
master = fcntl(master, F_DUPFD_CLOEXEC, 3);
if (master < 0)
return log_error_errno(errno, "Failed to duplicate master fd: %m");
@@ -878,7 +881,7 @@ static int start_transient_service(
(void) sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
if (!arg_quiet)
- log_info("Running as unit %s.\nPress ^] three times within 1s to disconnect TTY.", service);
+ log_info("Running as unit: %s\nPress ^] three times within 1s to disconnect TTY.", service);
r = pty_forward_new(event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &forward);
if (r < 0)
@@ -896,7 +899,7 @@ static int start_transient_service(
fputc('\n', stdout);
} else if (!arg_quiet)
- log_info("Running as unit %s.", service);
+ log_info("Running as unit: %s", service);
return 0;
}
@@ -1038,7 +1041,7 @@ static int start_transient_scope(
return r;
if (!arg_quiet)
- log_info("Running scope as unit %s.", scope);
+ log_info("Running scope as unit: %s", scope);
execvpe(argv[0], argv, env);
@@ -1189,9 +1192,9 @@ static int start_transient_timer(
if (r < 0)
return r;
- log_info("Running timer as unit %s.", timer);
+ log_info("Running timer as unit: %s", timer);
if (argv[0])
- log_info("Will run service as unit %s.", service);
+ log_info("Will run service as unit: %s", service);
return 0;
}
diff --git a/src/systemd-stdio-bridge/Makefile b/src/systemd-stdio-bridge/Makefile
index 650240a908..dd6d433fc6 100644
--- a/src/systemd-stdio-bridge/Makefile
+++ b/src/systemd-stdio-bridge/Makefile
@@ -24,10 +24,9 @@ include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
include $(topsrcdir)/build-aux/Makefile.head.mk
systemd_stdio_bridge_SOURCES = \
- src/bus-proxyd/stdio-bridge.c
+ src/stdio-bridge/stdio-bridge.c
systemd_stdio_bridge_LDADD = \
- libbus-proxy-core.la \
libshared.la
include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/systemd-stdio-bridge/stdio-bridge.c b/src/systemd-stdio-bridge/stdio-bridge.c
index 60c4a08325..dce959cae3 100644
--- a/src/systemd-stdio-bridge/stdio-bridge.c
+++ b/src/systemd-stdio-bridge/stdio-bridge.c
@@ -2,8 +2,6 @@
This file is part of systemd.
Copyright 2010 Lennart Poettering
- Copyright 2013 Daniel Mack
- Copyright 2014 Kay Sievers
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +19,7 @@
#include <errno.h>
#include <getopt.h>
+#include <poll.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
@@ -28,30 +27,24 @@
#include <systemd/sd-bus.h>
#include <systemd/sd-daemon.h>
-#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-util.h"
-#include "def.h"
-#include "formats-util.h"
+#include "build.h"
#include "log.h"
-#include "proxy.h"
-#include "strv.h"
-#include "user-util.h"
#include "util.h"
-static char *arg_address = NULL;
-static char *arg_command_line_buffer = NULL;
+#define DEFAULT_BUS_PATH "unix:path=/run/dbus/system_bus_socket"
+
+const char *arg_bus_path = DEFAULT_BUS_PATH;
static int help(void) {
printf("%s [OPTIONS...]\n\n"
- "Connect STDIO to a given bus address.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --machine=MACHINE Connect to specified machine\n"
- " --address=ADDRESS Connect to the bus specified by ADDRESS\n"
- " (default: " DEFAULT_SYSTEM_BUS_ADDRESS ")\n",
- program_invocation_short_name);
+ "STDIO or socket-activatable proxy to a given DBus endpoint.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --bus-path=PATH Path to the kernel bus (default: %s)\n",
+ program_invocation_short_name, DEFAULT_BUS_PATH);
return 0;
}
@@ -60,16 +53,12 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
- ARG_ADDRESS,
- ARG_MACHINE,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "address", required_argument, NULL, ARG_ADDRESS },
- { "machine", required_argument, NULL, ARG_MACHINE },
- {},
+ { "help", no_argument, NULL, 'h' },
+ { "bus-path", required_argument, NULL, 'p' },
+ { NULL, 0, NULL, 0 }
};
int c;
@@ -77,7 +66,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "hsup:", options, NULL)) >= 0) {
switch (c) {
@@ -88,157 +77,226 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_VERSION:
return version();
- case ARG_ADDRESS: {
- char *a;
-
- a = strdup(optarg);
- if (!a)
- return log_oom();
+ case '?':
+ return -EINVAL;
- free(arg_address);
- arg_address = a;
+ case 'p':
+ arg_bus_path = optarg;
break;
+
+ default:
+ log_error("Unknown option code %c", c);
+ return -EINVAL;
}
+ }
- case ARG_MACHINE: {
- _cleanup_free_ char *e = NULL;
- char *a;
+ return 1;
+}
- e = bus_address_escape(optarg);
- if (!e)
- return log_oom();
+int main(int argc, char *argv[]) {
+ _cleanup_(sd_bus_unrefp) sd_bus *a = NULL, *b = NULL;
+ sd_id128_t server_id;
+ bool is_unix;
+ int r, in_fd, out_fd;
- a = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL);
- if (!a)
- return log_oom();
+ log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+ log_parse_environment();
+ log_open();
- free(arg_address);
- arg_address = a;
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto finish;
- break;
- }
+ r = sd_listen_fds(0);
+ if (r == 0) {
+ in_fd = STDIN_FILENO;
+ out_fd = STDOUT_FILENO;
+ } else if (r == 1) {
+ in_fd = SD_LISTEN_FDS_START;
+ out_fd = SD_LISTEN_FDS_START;
+ } else {
+ log_error("Illegal number of file descriptors passed\n");
+ goto finish;
+ }
- case '?':
- return -EINVAL;
+ is_unix =
+ sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
+ sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
- default:
- assert_not_reached("Unhandled option");
- }
+ r = sd_bus_new(&a);
+ if (r < 0) {
+ log_error_errno(r, "Failed to allocate bus: %m");
+ goto finish;
+ }
- /* If the first command line argument is only "x" characters
- * we'll write who we are talking to into it, so that "ps" is
- * explanatory */
- arg_command_line_buffer = argv[optind];
- if (argc > optind + 1 || (arg_command_line_buffer && !in_charset(arg_command_line_buffer, "x"))) {
- log_error("Too many arguments");
- return -EINVAL;
+ r = sd_bus_set_address(a, arg_bus_path);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set address to connect to: %m");
+ goto finish;
}
- if (!arg_address) {
- arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
- if (!arg_address)
- return log_oom();
+ r = sd_bus_negotiate_fds(a, is_unix);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set FD negotiation: %m");
+ goto finish;
}
- return 1;
-}
+ r = sd_bus_start(a);
+ if (r < 0) {
+ log_error_errno(r, "Failed to start bus client: %m");
+ goto finish;
+ }
-static int rename_service(sd_bus *a, sd_bus *b) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- _cleanup_free_ char *p = NULL, *name = NULL;
- const char *comm;
- char **cmdline;
- uid_t uid;
- pid_t pid;
- int r;
-
- assert(a);
- assert(b);
-
- r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_euid(creds, &uid);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_cmdline(creds, &cmdline);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_comm(creds, &comm);
- if (r < 0)
- return r;
-
- name = uid_to_name(uid);
- if (!name)
- return -ENOMEM;
-
- p = strv_join(cmdline, " ");
- if (!p)
- return -ENOMEM;
-
- /* The status string gets the full command line ... */
- sd_notifyf(false,
- "STATUS=Processing requests from client PID "PID_FMT" (%s); UID "UID_FMT" (%s)",
- pid, p,
- uid, name);
-
- /* ... and the argv line only the short comm */
- if (arg_command_line_buffer) {
- size_t m, w;
-
- m = strlen(arg_command_line_buffer);
- w = snprintf(arg_command_line_buffer, m,
- "[PID "PID_FMT"/%s; UID "UID_FMT"/%s]",
- pid, comm,
- uid, name);
-
- if (m > w)
- memzero(arg_command_line_buffer + w, m - w);
+ r = sd_bus_get_bus_id(a, &server_id);
+ if (r < 0) {
+ log_error_errno(r, "Failed to get server ID: %m");
+ goto finish;
}
- log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s",
- pid, p,
- uid, name,
- a->unique_name);
+ r = sd_bus_new(&b);
+ if (r < 0) {
+ log_error_errno(r, "Failed to allocate bus: %m");
+ goto finish;
+ }
- return 0;
-}
+ r = sd_bus_set_fd(b, in_fd, out_fd);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set fds: %m");
+ goto finish;
+ }
-int main(int argc, char *argv[]) {
- _cleanup_(proxy_freep) Proxy *p = NULL;
- int r;
+ r = sd_bus_set_server(b, 1, server_id);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set server mode: %m");
+ goto finish;
+ }
- log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
- log_parse_environment();
- log_open();
+ r = sd_bus_negotiate_fds(b, is_unix);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set FD negotiation: %m");
+ goto finish;
+ }
- r = parse_argv(argc, argv);
- if (r <= 0)
+ r = sd_bus_set_anonymous(b, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set anonymous authentication: %m");
goto finish;
+ }
- r = proxy_new(&p, STDIN_FILENO, STDOUT_FILENO, arg_address);
- if (r < 0)
+ r = sd_bus_start(b);
+ if (r < 0) {
+ log_error_errno(r, "Failed to start bus client: %m");
goto finish;
+ }
- r = rename_service(p->destination_bus, p->local_bus);
- if (r < 0)
- log_debug_errno(r, "Failed to rename process: %m");
+ for (;;) {
+ _cleanup_(sd_bus_message_unrefp)sd_bus_message *m = NULL;
+ int events_a, events_b, fd;
+ uint64_t timeout_a, timeout_b, t;
+ struct timespec _ts, *ts;
- r = proxy_run(p);
+ r = sd_bus_process(a, &m);
+ if (r < 0) {
+ log_error_errno(r, "Failed to process bus a: %m");
+ goto finish;
+ }
-finish:
- sd_notify(false,
- "STOPPING=1\n"
- "STATUS=Shutting down.");
+ if (m) {
+ r = sd_bus_send(b, m, NULL);
+ if (r < 0) {
+ log_error_errno(r, "Failed to send message: %m");
+ goto finish;
+ }
+ }
+
+ if (r > 0)
+ continue;
+
+ r = sd_bus_process(b, &m);
+ if (r < 0) {
+ /* treat 'connection reset by peer' as clean exit condition */
+ if (r == -ECONNRESET)
+ r = 0;
- free(arg_address);
+ goto finish;
+ }
+
+ if (m) {
+ r = sd_bus_send(a, m, NULL);
+ if (r < 0) {
+ log_error_errno(r, "Failed to send message: %m");
+ goto finish;
+ }
+ }
+ if (r > 0)
+ continue;
+
+ fd = sd_bus_get_fd(a);
+ if (fd < 0) {
+ r = fd;
+ log_error_errno(r, "Failed to get fd: %m");
+ goto finish;
+ }
+
+ events_a = sd_bus_get_events(a);
+ if (events_a < 0) {
+ r = events_a;
+ log_error_errno(r, "Failed to get events mask: %m");
+ goto finish;
+ }
+
+ r = sd_bus_get_timeout(a, &timeout_a);
+ if (r < 0) {
+ log_error_errno(r, "Failed to get timeout: %m");
+ goto finish;
+ }
+
+ events_b = sd_bus_get_events(b);
+ if (events_b < 0) {
+ r = events_b;
+ log_error_errno(r, "Failed to get events mask: %m");
+ goto finish;
+ }
+
+ r = sd_bus_get_timeout(b, &timeout_b);
+ if (r < 0) {
+ log_error_errno(r, "Failed to get timeout: %m");
+ goto finish;
+ }
+
+ t = timeout_a;
+ if (t == (uint64_t) -1 || (timeout_b != (uint64_t) -1 && timeout_b < timeout_a))
+ t = timeout_b;
+
+ if (t == (uint64_t) -1)
+ ts = NULL;
+ else {
+ usec_t nw;
+
+ nw = now(CLOCK_MONOTONIC);
+ if (t > nw)
+ t -= nw;
+ else
+ t = 0;
+
+ ts = timespec_store(&_ts, t);
+ }
+
+ {
+ struct pollfd p[3] = {
+ {.fd = fd, .events = events_a, },
+ {.fd = STDIN_FILENO, .events = events_b & POLLIN, },
+ {.fd = STDOUT_FILENO, .events = events_b & POLLOUT, }};
+
+ r = ppoll(p, ELEMENTSOF(p), ts, NULL);
+ }
+ if (r < 0) {
+ log_error("ppoll() failed: %m");
+ goto finish;
+ }
+ }
+
+finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/systemd-sysv-generator/sysv-generator.c b/src/systemd-sysv-generator/sysv-generator.c
index 5a6818a79d..fe4bbeeb75 100644
--- a/src/systemd-sysv-generator/sysv-generator.c
+++ b/src/systemd-sysv-generator/sysv-generator.c
@@ -70,7 +70,7 @@ static const struct {
UP must be read before DOWN */
};
-const char *arg_dest = "/tmp";
+static const char *arg_dest = "/tmp";
typedef struct SysvStub {
char *name;
@@ -729,14 +729,50 @@ static int fix_order(SysvStub *s, Hashmap *all_services) {
return 0;
}
+static int acquire_search_path(const char *def, const char *envvar, char ***ret) {
+ _cleanup_strv_free_ char **l = NULL;
+ const char *e;
+ int r;
+
+ assert(def);
+ assert(envvar);
+
+ e = getenv(envvar);
+ if (e) {
+ r = path_split_and_make_absolute(e, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make $%s search path absolute: %m", envvar);
+ }
+
+ if (strv_isempty(l)) {
+ strv_free(l);
+
+ l = strv_new(def, NULL);
+ if (!l)
+ return log_oom();
+ }
+
+ if (!path_strv_resolve_uniq(l, NULL))
+ return log_oom();
+
+ *ret = l;
+ l = NULL;
+
+ return 0;
+}
+
static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
+ _cleanup_strv_free_ char **sysvinit_path = NULL;
char **path;
int r;
assert(lp);
- assert(all_services);
- STRV_FOREACH(path, lp->sysvinit_path) {
+ r = acquire_search_path(SYSTEM_SYSVINIT_PATH, "SYSTEMD_SYSVINIT_PATH", &sysvinit_path);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(path, sysvinit_path) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
@@ -770,11 +806,11 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
if (hashmap_contains(all_services, name))
continue;
- r = unit_file_lookup_state(UNIT_FILE_SYSTEM, NULL, lp, name, NULL);
- if (r < 0 && r != -ENOENT) {
+ r = unit_file_exists(UNIT_FILE_SYSTEM, lp, name);
+ if (r < 0 && !IN_SET(r, -ELOOP, -ERFKILL, -EADDRNOTAVAIL)) {
log_debug_errno(r, "Failed to detect whether %s exists, skipping: %m", name);
continue;
- } else if (r >= 0) {
+ } else if (r != 0) {
log_debug("Native unit for %s already exists, skipping.", name);
continue;
}
@@ -806,6 +842,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_services) {
Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
_cleanup_set_free_ Set *shutdown_services = NULL;
+ _cleanup_strv_free_ char **sysvrcnd_path = NULL;
SysvStub *service;
unsigned i;
Iterator j;
@@ -814,7 +851,11 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
assert(lp);
- STRV_FOREACH(p, lp->sysvrcnd_path) {
+ r = acquire_search_path(SYSTEM_SYSVRCND_PATH, "SYSTEMD_SYSVRCND_PATH", &sysvrcnd_path);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(p, sysvrcnd_path) {
for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
_cleanup_closedir_ DIR *d = NULL;
@@ -864,7 +905,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
}
service = hashmap_get(all_services, name);
- if (!service){
+ if (!service) {
log_debug("Ignoring %s symlink in %s, not generating %s.", de->d_name, rcnd_table[i].path, name);
continue;
}
@@ -963,7 +1004,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = lookup_paths_init(&lp, MANAGER_SYSTEM, true, NULL, NULL, NULL, NULL);
+ r = lookup_paths_init(&lp, UNIT_FILE_SYSTEM, LOOKUP_PATHS_EXCLUDE_GENERATED, NULL);
if (r < 0) {
log_error_errno(r, "Failed to find lookup paths: %m");
goto finish;
diff --git a/src/systemd-timesync/timesyncd.c b/src/systemd-timesync/timesyncd.c
index 388eefac48..9e538a82f2 100644
--- a/src/systemd-timesync/timesyncd.c
+++ b/src/systemd-timesync/timesyncd.c
@@ -122,7 +122,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (clock_is_localtime() > 0) {
+ if (clock_is_localtime(NULL) > 0) {
log_info("The system is configured to read the RTC time in the local time zone. "
"This mode can not be fully supported. All system time to RTC updates are disabled.");
m->rtc_local_time = true;
diff --git a/src/systemd-tmpfiles/tmpfiles.c b/src/systemd-tmpfiles/tmpfiles.c
index 7b105a6bd4..2053d35a67 100644
--- a/src/systemd-tmpfiles/tmpfiles.c
+++ b/src/systemd-tmpfiles/tmpfiles.c
@@ -94,6 +94,7 @@ typedef enum ItemType {
/* These ones take globs */
WRITE_FILE = 'w',
+ EMPTY_DIRECTORY = 'e',
SET_XATTR = 't',
RECURSIVE_SET_XATTR = 'T',
SET_ACL = 'a',
@@ -179,6 +180,7 @@ static bool needs_glob(ItemType t) {
IGNORE_DIRECTORY_PATH,
REMOVE_PATH,
RECURSIVE_REMOVE_PATH,
+ EMPTY_DIRECTORY,
ADJUST_MODE,
RELABEL_PATH,
RECURSIVE_RELABEL_PATH,
@@ -195,6 +197,7 @@ static bool takes_ownership(ItemType t) {
CREATE_FILE,
TRUNCATE_FILE,
CREATE_DIRECTORY,
+ EMPTY_DIRECTORY,
TRUNCATE_DIRECTORY,
CREATE_SUBVOLUME,
CREATE_SUBVOLUME_INHERIT_QUOTA,
@@ -613,7 +616,7 @@ static int path_set_perms(Item *i, const char *path) {
* with AT_SYMLINK_NOFOLLOW, hence we emulate it here via
* O_PATH. */
- fd = open(path, O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH|O_NOATIME);
+ fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
if (fd < 0)
return log_error_errno(errno, "Adjusting owner and mode for %s failed: %m", path);
@@ -804,7 +807,7 @@ static int path_set_acls(Item *item, const char *path) {
assert(item);
assert(path);
- fd = open(path, O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH|O_NOATIME);
+ fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
if (fd < 0)
return log_error_errno(errno, "Adjusting ACL of %s failed: %m", path);
@@ -917,10 +920,7 @@ static int parse_attribute_from_arg(Item *item) {
v = attributes[i].value;
- if (mode == MODE_ADD || mode == MODE_SET)
- value |= v;
- else
- value &= ~v;
+ SET_FLAG(value, v, (mode == MODE_ADD || mode == MODE_SET));
mask |= v;
}
@@ -1220,7 +1220,6 @@ static int create_item(Item *i) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
-
RUN_WITH_UMASK(0000)
mkdir_parents_label(i->path, 0755);
@@ -1279,11 +1278,11 @@ static int create_item(Item *i) {
if (IN_SET(i->type, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)) {
r = btrfs_subvol_auto_qgroup(i->path, 0, i->type == CREATE_SUBVOLUME_NEW_QUOTA);
if (r == -ENOTTY)
- log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of unsupported file system or because directory is not a subvolume: %m", i->path);
+ log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (unsupported fs or dir not a subvolume): %m", i->path);
else if (r == -EROFS)
- log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of read-only file system: %m", i->path);
+ log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (fs is read-only).", i->path);
else if (r == -ENOPROTOOPT)
- log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because quota support is disabled: %m", i->path);
+ log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (quota support is disabled).", i->path);
else if (r < 0)
q = log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path);
else if (r > 0)
@@ -1292,6 +1291,9 @@ static int create_item(Item *i) {
log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
}
+ /* fall through */
+
+ case EMPTY_DIRECTORY:
r = path_set_perms(i, i->path);
if (q < 0)
return q;
@@ -1301,7 +1303,6 @@ static int create_item(Item *i) {
break;
case CREATE_FIFO:
-
RUN_WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, S_IFIFO);
r = mkfifo(i->path, i->mode);
@@ -1538,47 +1539,20 @@ static int remove_item_instance(Item *i, const char *instance) {
}
static int remove_item(Item *i) {
- int r = 0;
-
assert(i);
log_debug("Running remove action for entry %c %s", (char) i->type, i->path);
switch (i->type) {
- case CREATE_FILE:
- case TRUNCATE_FILE:
- case CREATE_DIRECTORY:
- case CREATE_SUBVOLUME:
- case CREATE_SUBVOLUME_INHERIT_QUOTA:
- case CREATE_SUBVOLUME_NEW_QUOTA:
- case CREATE_FIFO:
- case CREATE_SYMLINK:
- case CREATE_CHAR_DEVICE:
- case CREATE_BLOCK_DEVICE:
- case IGNORE_PATH:
- case IGNORE_DIRECTORY_PATH:
- case ADJUST_MODE:
- case RELABEL_PATH:
- case RECURSIVE_RELABEL_PATH:
- case WRITE_FILE:
- case COPY_FILES:
- case SET_XATTR:
- case RECURSIVE_SET_XATTR:
- case SET_ACL:
- case RECURSIVE_SET_ACL:
- case SET_ATTRIBUTE:
- case RECURSIVE_SET_ATTRIBUTE:
- break;
-
case REMOVE_PATH:
case TRUNCATE_DIRECTORY:
case RECURSIVE_REMOVE_PATH:
- r = glob_item(i, remove_item_instance, false);
- break;
- }
+ return glob_item(i, remove_item_instance, false);
- return r;
+ default:
+ return 0;
+ }
}
static int clean_item_instance(Item *i, const char* instance) {
@@ -1633,8 +1607,6 @@ static int clean_item_instance(Item *i, const char* instance) {
}
static int clean_item(Item *i) {
- int r = 0;
-
assert(i);
log_debug("Running clean action for entry %c %s", (char) i->type, i->path);
@@ -1644,19 +1616,17 @@ static int clean_item(Item *i) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
+ case EMPTY_DIRECTORY:
case TRUNCATE_DIRECTORY:
case IGNORE_PATH:
case COPY_FILES:
clean_item_instance(i, i->path);
- break;
+ return 0;
case IGNORE_DIRECTORY_PATH:
- r = glob_item(i, clean_item_instance, false);
- break;
+ return glob_item(i, clean_item_instance, false);
default:
- break;
+ return 0;
}
-
- return r;
}
static int process_item_array(ItemArray *array);
@@ -1882,6 +1852,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
+ case EMPTY_DIRECTORY:
case TRUNCATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
@@ -2201,7 +2172,8 @@ static int parse_argv(int argc, char *argv[]) {
}
static int read_config_file(const char *fn, bool ignore_enoent) {
- _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_fclose_ FILE *_f = NULL;
+ FILE *f;
char line[LINE_MAX];
Iterator iterator;
unsigned v = 0;
@@ -2210,16 +2182,23 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
assert(fn);
- r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
- if (r < 0) {
- if (ignore_enoent && r == -ENOENT) {
- log_debug_errno(r, "Failed to open \"%s\": %m", fn);
- return 0;
- }
+ if (streq(fn, "-")) {
+ log_debug("Reading config from stdin.");
+ fn = "<stdin>";
+ f = stdin;
+ } else {
+ r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &_f);
+ if (r < 0) {
+ if (ignore_enoent && r == -ENOENT) {
+ log_debug_errno(r, "Failed to open \"%s\", ignoring: %m", fn);
+ return 0;
+ }
- return log_error_errno(r, "Failed to open '%s', ignoring: %m", fn);
+ return log_error_errno(r, "Failed to open '%s': %m", fn);
+ }
+ log_debug("Reading config file \"%s\".", fn);
+ f = _f;
}
- log_debug("Reading config file \"%s\".", fn);
FOREACH_LINE(line, f, break) {
char *l;
@@ -2288,7 +2267,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- mac_selinux_init(NULL);
+ mac_selinux_init();
items = ordered_hashmap_new(&string_hash_ops);
globs = ordered_hashmap_new(&string_hash_ops);
diff --git a/src/systemd-tty-ask-password-agent/tty-ask-password-agent.c b/src/systemd-tty-ask-password-agent/tty-ask-password-agent.c
index 7b67831e54..ee879c7b89 100644
--- a/src/systemd-tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/systemd-tty-ask-password-agent/tty-ask-password-agent.c
@@ -65,8 +65,8 @@ static int ask_password_plymouth(
const char *flag_file,
char ***ret) {
+ static const union sockaddr_union sa = PLYMOUTH_SOCKET;
_cleanup_close_ int fd = -1, notify = -1;
- union sockaddr_union sa = PLYMOUTH_SOCKET;
_cleanup_free_ char *packet = NULL;
ssize_t k;
int r, n;
@@ -94,7 +94,7 @@ static int ask_password_plymouth(
if (fd < 0)
return -errno;
- r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
+ r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return -errno;
@@ -269,8 +269,7 @@ static int send_passwords(const char *socket_name, char **passwords) {
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
- r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa,
- offsetof(struct sockaddr_un, sun_path) + strlen(socket_name));
+ r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
r = log_debug_errno(errno, "sendto(): %m");
@@ -481,7 +480,7 @@ static int show_passwords(void) {
if (de->d_type != DT_REG)
continue;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
if (!startswith(de->d_name, "ask."))
diff --git a/src/systemd-update-done/update-done.c b/src/systemd-update-done/update-done.c
index 931e583785..da306a4444 100644
--- a/src/systemd-update-done/update-done.c
+++ b/src/systemd-update-done/update-done.c
@@ -101,7 +101,7 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- r = mac_selinux_init(NULL);
+ r = mac_selinux_init();
if (r < 0) {
log_error_errno(r, "SELinux setup failed: %m");
goto finish;
diff --git a/src/systemd-user-sessions/user-sessions.c b/src/systemd-user-sessions/user-sessions.c
index 8bf44e2100..9b29b5ba1d 100644
--- a/src/systemd-user-sessions/user-sessions.c
+++ b/src/systemd-user-sessions/user-sessions.c
@@ -40,7 +40,7 @@ int main(int argc, char*argv[]) {
umask(0022);
- mac_selinux_init(NULL);
+ mac_selinux_init();
if (streq(argv[1], "start")) {
int r = 0;
diff --git a/src/systemd-vconsole/vconsole-setup.c b/src/systemd-vconsole/vconsole-setup.c
index 8a1b824e65..1118118450 100644
--- a/src/systemd-vconsole/vconsole-setup.c
+++ b/src/systemd-vconsole/vconsole-setup.c
@@ -195,9 +195,15 @@ static void font_copy_to_all_vcs(int fd) {
unsigned char map8[E_TABSZ];
unsigned short map16[E_TABSZ];
struct unimapdesc unimapd;
- struct unipair unipairs[USHRT_MAX];
+ _cleanup_free_ struct unipair* unipairs = NULL;
int i, r;
+ unipairs = new(struct unipair, USHRT_MAX);
+ if (!unipairs) {
+ log_oom();
+ return;
+ }
+
/* get active, and 16 bit mask of used VT numbers */
r = ioctl(fd, VT_GETSTATE, &vcs);
if (r < 0) {
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 863c628323..4377f1b910 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -1820,7 +1820,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = mac_selinux_init(NULL);
+ r = mac_selinux_init();
if (r < 0) {
log_error_errno(r, "SELinux setup failed: %m");
goto finish;
diff --git a/src/test/test-alloc-util.c b/src/test/test-alloc-util.c
new file mode 100644
index 0000000000..cc4821eaf5
--- /dev/null
+++ b/src/test/test-alloc-util.c
@@ -0,0 +1,55 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "macro.h"
+#include "util.h"
+
+static void test_alloca(void) {
+ static const uint8_t zero[997] = { };
+ char *t;
+
+ t = alloca_align(17, 512);
+ assert_se(!((uintptr_t)t & 0xff));
+ memzero(t, 17);
+
+ t = alloca0_align(997, 1024);
+ assert_se(!((uintptr_t)t & 0x1ff));
+ assert_se(!memcmp(t, zero, 997));
+}
+
+static void test_memdup_multiply(void) {
+ int org[] = {1, 2, 3};
+ int *dup;
+
+ dup = (int*)memdup_multiply(org, sizeof(int), 3);
+
+ assert_se(dup);
+ assert_se(dup[0] == 1);
+ assert_se(dup[1] == 2);
+ assert_se(dup[2] == 3);
+ free(dup);
+}
+
+int main(int argc, char *argv[]) {
+ test_alloca();
+ test_memdup_multiply();
+
+ return 0;
+}
diff --git a/src/test/test-boot-timestamps.c b/src/test/test-boot-timestamps.c
index d2add5880c..8e68d6510d 100644
--- a/src/test/test-boot-timestamps.c
+++ b/src/test/test-boot-timestamps.c
@@ -34,17 +34,18 @@ static int test_acpi_fpdt(void) {
r = acpi_get_boot_usec(&loader_start, &loader_exit);
if (r < 0) {
- if (r != -ENOENT)
- log_error_errno(r, "Failed to read ACPI FPDT: %m");
- return r;
+ bool ok = r == -ENOENT || (getuid() != 0 && r == -EACCES) || r == -ENODATA;
+
+ log_full_errno(ok ? LOG_DEBUG : LOG_ERR,
+ r, "Failed to read ACPI FPDT: %m");
+ return ok ? 0 : r;
}
log_info("ACPI FPDT: loader start=%s exit=%s duration=%s",
format_timespan(ts_start, sizeof(ts_start), loader_start, USEC_PER_MSEC),
format_timespan(ts_exit, sizeof(ts_exit), loader_exit, USEC_PER_MSEC),
format_timespan(ts_span, sizeof(ts_span), loader_exit - loader_start, USEC_PER_MSEC));
-
- return 0;
+ return 1;
}
static int test_efi_loader(void) {
@@ -57,33 +58,34 @@ static int test_efi_loader(void) {
r = efi_loader_get_boot_usec(&loader_start, &loader_exit);
if (r < 0) {
- if (r != -ENOENT)
- log_error_errno(r, "Failed to read EFI loader data: %m");
- return r;
+ bool ok = r == -ENOENT || (getuid() != 0 && r == -EACCES);
+
+ log_full_errno(ok ? LOG_DEBUG : LOG_ERR,
+ r, "Failed to read EFI loader data: %m");
+ return ok ? 0 : r;
}
log_info("EFI Loader: start=%s exit=%s duration=%s",
format_timespan(ts_start, sizeof(ts_start), loader_start, USEC_PER_MSEC),
format_timespan(ts_exit, sizeof(ts_exit), loader_exit, USEC_PER_MSEC),
format_timespan(ts_span, sizeof(ts_span), loader_exit - loader_start, USEC_PER_MSEC));
-
- return 0;
+ return 1;
}
-int main(int argc, char* argv[]) {
+static int test_boot_timestamps(void) {
char s[MAX(FORMAT_TIMESPAN_MAX, FORMAT_TIMESTAMP_MAX)];
int r;
dual_timestamp fw, l, k;
- test_acpi_fpdt();
- test_efi_loader();
-
dual_timestamp_from_monotonic(&k, 0);
r = boot_timestamps(NULL, &fw, &l);
if (r < 0) {
- log_error_errno(r, "Failed to read variables: %m");
- return 1;
+ bool ok = r == -ENOENT || (getuid() != 0 && r == -EACCES);
+
+ log_full_errno(ok ? LOG_DEBUG : LOG_ERR,
+ r, "Failed to read variables: %m");
+ return ok ? 0 : r;
}
log_info("Firmware began %s before kernel.", format_timespan(s, sizeof(s), fw.monotonic, 0));
@@ -91,6 +93,21 @@ int main(int argc, char* argv[]) {
log_info("Firmware began %s.", format_timestamp(s, sizeof(s), fw.realtime));
log_info("Loader began %s.", format_timestamp(s, sizeof(s), l.realtime));
log_info("Kernel began %s.", format_timestamp(s, sizeof(s), k.realtime));
+ return 1;
+}
+
+int main(int argc, char* argv[]) {
+ int p, q, r;
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
+ p = test_acpi_fpdt();
+ assert(p >= 0);
+ q = test_efi_loader();
+ assert(q >= 0);
+ r = test_boot_timestamps();
+ assert(r >= 0);
- return 0;
+ return (p > 0 || q > 0 || r >> 0) ? EXIT_SUCCESS : EXIT_TEST_SKIP;
}
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index 8754cb3381..5a8c6cbfb6 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -137,6 +137,7 @@ int main(int argc, char* argv[]) {
test_next("2015-11-13 09:11:23.42", "EET", 12345, 1447398683420000);
test_next("2015-11-13 09:11:23.42/1.77", "EET", 1447398683420000, 1447398685190000);
test_next("2015-11-13 09:11:23.42/1.77", "EET", 1447398683419999, 1447398683420000);
+ test_next("Sun 16:00:00", "CET", 1456041600123456, 1456066800000000);
assert_se(calendar_spec_from_string("test", &c) < 0);
assert_se(calendar_spec_from_string("", &c) < 0);
diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c
index ad15075a5b..a027eb0fd2 100644
--- a/src/test/test-cgroup-mask.c
+++ b/src/test/test-cgroup-mask.c
@@ -21,7 +21,9 @@
#include "macro.h"
#include "manager.h"
+#include "rm-rf.h"
#include "test-helper.h"
+#include "tests.h"
#include "unit.h"
static int test_cgroup_mask(void) {
@@ -33,7 +35,7 @@ static int test_cgroup_mask(void) {
/* Prepare the manager. */
assert_se(set_unit_path(TEST_DIR) >= 0);
- r = manager_new(MANAGER_USER, true, &m);
+ r = manager_new(UNIT_FILE_USER, true, &m);
if (r == -EPERM || r == -EACCES) {
puts("manager_new: Permission denied. Skipping test.");
return EXIT_TEST_SKIP;
@@ -46,6 +48,7 @@ static int test_cgroup_mask(void) {
m->default_cpu_accounting =
m->default_memory_accounting =
m->default_blockio_accounting =
+ m->default_io_accounting =
m->default_tasks_accounting = false;
m->default_tasks_max = (uint64_t) -1;
@@ -74,7 +77,7 @@ static int test_cgroup_mask(void) {
assert_se(unit_get_own_mask(daughter) == 0);
assert_se(unit_get_own_mask(grandchild) == 0);
assert_se(unit_get_own_mask(parent_deep) == CGROUP_MASK_MEMORY);
- assert_se(unit_get_own_mask(parent) == CGROUP_MASK_BLKIO);
+ assert_se(unit_get_own_mask(parent) == (CGROUP_MASK_IO | CGROUP_MASK_BLKIO));
assert_se(unit_get_own_mask(root) == 0);
/* Verify aggregation of member masks */
@@ -83,23 +86,23 @@ static int test_cgroup_mask(void) {
assert_se(unit_get_members_mask(grandchild) == 0);
assert_se(unit_get_members_mask(parent_deep) == 0);
assert_se(unit_get_members_mask(parent) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
- assert_se(unit_get_members_mask(root) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
+ assert_se(unit_get_members_mask(root) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
/* Verify aggregation of sibling masks. */
assert_se(unit_get_siblings_mask(son) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
assert_se(unit_get_siblings_mask(daughter) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
assert_se(unit_get_siblings_mask(grandchild) == 0);
assert_se(unit_get_siblings_mask(parent_deep) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
- assert_se(unit_get_siblings_mask(parent) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
- assert_se(unit_get_siblings_mask(root) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
+ assert_se(unit_get_siblings_mask(parent) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
+ assert_se(unit_get_siblings_mask(root) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
/* Verify aggregation of target masks. */
assert_se(unit_get_target_mask(son) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY) & m->cgroup_supported));
assert_se(unit_get_target_mask(daughter) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY) & m->cgroup_supported));
assert_se(unit_get_target_mask(grandchild) == 0);
assert_se(unit_get_target_mask(parent_deep) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY) & m->cgroup_supported));
- assert_se(unit_get_target_mask(parent) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
- assert_se(unit_get_target_mask(root) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+ assert_se(unit_get_target_mask(parent) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+ assert_se(unit_get_target_mask(root) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
manager_free(m);
@@ -107,7 +110,11 @@ static int test_cgroup_mask(void) {
}
int main(int argc, char* argv[]) {
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int rc = 0;
+
+ assert_se(runtime_dir = setup_fake_runtime_dir());
TEST_REQ_RUNNING_SYSTEMD(rc = test_cgroup_mask());
+
return rc;
}
diff --git a/src/test/test-clock.c b/src/test/test-clock.c
new file mode 100644
index 0000000000..84f775e5bc
--- /dev/null
+++ b/src/test/test-clock.c
@@ -0,0 +1,96 @@
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2016 Canonical Ltd.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "clock-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "log.h"
+#include "macro.h"
+
+static void test_clock_is_localtime(void) {
+ char adjtime[] = "/tmp/test-adjtime.XXXXXX";
+ int fd = -1;
+ _cleanup_fclose_ FILE* f = NULL;
+
+ static const struct scenario {
+ const char* contents;
+ int expected_result;
+ } scenarios[] = {
+ /* adjtime configures UTC */
+ {"0.0 0 0\n0\nUTC\n", 0},
+ /* adjtime configures local time */
+ {"0.0 0 0\n0\nLOCAL\n", 1},
+ /* no final EOL */
+ {"0.0 0 0\n0\nUTC", 0},
+ {"0.0 0 0\n0\nLOCAL", 1},
+ /* empty value -> defaults to UTC */
+ {"0.0 0 0\n0\n", 0},
+ /* unknown value -> defaults to UTC */
+ {"0.0 0 0\n0\nFOO\n", 0},
+ /* no third line */
+ {"0.0 0 0", 0},
+ {"0.0 0 0\n", 0},
+ {"0.0 0 0\n0", 0},
+ };
+
+ /* without an adjtime file we default to UTC */
+ assert_se(clock_is_localtime("/nonexisting/adjtime") == 0);
+
+ fd = mkostemp_safe(adjtime, O_WRONLY|O_CLOEXEC);
+ assert_se(fd >= 0);
+ log_info("adjtime test file: %s", adjtime);
+ f = fdopen(fd, "w");
+ assert_se(f);
+
+ for (size_t i = 0; i < ELEMENTSOF(scenarios); ++i) {
+ log_info("scenario #%zu:, expected result %i", i, scenarios[i].expected_result);
+ log_info("%s", scenarios[i].contents);
+ rewind(f);
+ ftruncate(fd, 0);
+ assert_se(write_string_stream(f, scenarios[i].contents, false) == 0);
+ assert_se(clock_is_localtime(adjtime) == scenarios[i].expected_result);
+ }
+
+ unlink(adjtime);
+}
+
+/* Test with the real /etc/adjtime */
+static void test_clock_is_localtime_system(void) {
+ int r;
+ r = clock_is_localtime(NULL);
+
+ if (access("/etc/adjtime", F_OK) == 0) {
+ log_info("/etc/adjtime exists, clock_is_localtime() == %i", r);
+ /* if /etc/adjtime exists we expect some answer, no error or
+ * crash */
+ assert_se(r == 0 || r == 1);
+ } else
+ /* default is UTC if there is no /etc/adjtime */
+ assert_se(r == 0);
+}
+
+int main(int argc, char *argv[]) {
+ test_clock_is_localtime();
+ test_clock_is_localtime_system();
+
+ return 0;
+}
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
index b3a4c40339..be5d2611f8 100644
--- a/src/test/test-conf-parser.c
+++ b/src/test/test-conf-parser.c
@@ -215,6 +215,14 @@ static void test_config_parse_nsec(void) {
test_config_parse_nsec_one("garbage", 0);
}
+static void test_config_parse_iec_uint64(void) {
+ uint64_t offset = 0;
+ assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
+ assert_se(offset == 4 * 1024 * 1024);
+
+ assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
+}
+
int main(int argc, char **argv) {
log_parse_environment();
log_open();
@@ -230,6 +238,7 @@ int main(int argc, char **argv) {
test_config_parse_mode();
test_config_parse_sec();
test_config_parse_nsec();
+ test_config_parse_iec_uint64();
return 0;
}
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index ad57cb0202..68154fc4e8 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -24,6 +24,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
+#include "log.h"
#include "macro.h"
#include "mkdir.h"
#include "path-util.h"
@@ -39,6 +40,8 @@ static void test_copy_file(void) {
size_t sz = 0;
int fd;
+ log_info("%s", __func__);
+
fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
close(fd);
@@ -66,6 +69,8 @@ static void test_copy_file_fd(void) {
char text[] = "boohoo\nfoo\n\tbar\n";
char buf[64] = {0};
+ log_info("%s", __func__);
+
in_fd = mkostemp_safe(in_fn, O_RDWR);
assert_se(in_fd >= 0);
out_fd = mkostemp_safe(out_fn, O_RDWR);
@@ -90,31 +95,43 @@ static void test_copy_tree(void) {
char **links = STRV_MAKE("link", "file",
"link2", "dir1/file");
char **p, **link;
+ const char *unixsockp;
+ struct stat st;
+
+ log_info("%s", __func__);
(void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
(void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
STRV_FOREACH(p, files) {
- char *f = strjoina(original_dir, *p);
+ _cleanup_free_ char *f;
+
+ assert_se(f = strappend(original_dir, *p));
assert_se(mkdir_parents(f, 0755) >= 0);
assert_se(write_string_file(f, "file", WRITE_STRING_FILE_CREATE) == 0);
}
STRV_FOREACH_PAIR(link, p, links) {
- char *f = strjoina(original_dir, *p);
- char *l = strjoina(original_dir, *link);
+ _cleanup_free_ char *f, *l;
+
+ assert_se(f = strappend(original_dir, *p));
+ assert_se(l = strappend(original_dir, *link));
assert_se(mkdir_parents(l, 0755) >= 0);
assert_se(symlink(f, l) == 0);
}
+ unixsockp = strjoina(original_dir, "unixsock");
+ assert_se(mknod(unixsockp, S_IFSOCK|0644, 0) >= 0);
+
assert_se(copy_tree(original_dir, copy_dir, true) == 0);
STRV_FOREACH(p, files) {
- _cleanup_free_ char *buf = NULL;
+ _cleanup_free_ char *buf = NULL, *f;
size_t sz = 0;
- char *f = strjoina(copy_dir, *p);
+
+ assert_se(f = strappend(copy_dir, *p));
assert_se(access(f, F_OK) == 0);
assert_se(read_full_file(f, &buf, &sz) == 0);
@@ -122,14 +139,19 @@ static void test_copy_tree(void) {
}
STRV_FOREACH_PAIR(link, p, links) {
- _cleanup_free_ char *target = NULL;
- char *f = strjoina(original_dir, *p);
- char *l = strjoina(copy_dir, *link);
+ _cleanup_free_ char *target = NULL, *f, *l;
+
+ assert_se(f = strjoin(original_dir, *p, NULL));
+ assert_se(l = strjoin(copy_dir, *link, NULL));
assert_se(readlink_and_canonicalize(l, &target) == 0);
assert_se(path_equal(f, target));
}
+ unixsockp = strjoina(copy_dir, "unixsock");
+ assert_se(stat(unixsockp, &st) >= 0);
+ assert_se(S_ISSOCK(st.st_mode));
+
assert_se(copy_tree(original_dir, copy_dir, false) < 0);
assert_se(copy_tree("/tmp/inexistent/foo/bar/fsdoi", copy_dir, false) < 0);
@@ -173,11 +195,65 @@ static void test_copy_bytes(void) {
assert_se(r == -EBADF);
}
+static void test_copy_bytes_regular_file(const char *src, bool try_reflink, uint64_t max_bytes) {
+ char fn2[] = "/tmp/test-copy-file-XXXXXX";
+ char fn3[] = "/tmp/test-copy-file-XXXXXX";
+ _cleanup_close_ int fd = -1, fd2 = -1, fd3 = -1;
+ int r;
+ struct stat buf, buf2, buf3;
+
+ log_info("%s try_reflink=%s max_bytes=%" PRIu64, __func__, yes_no(try_reflink), max_bytes);
+
+ fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+ assert_se(fd >= 0);
+
+ fd2 = mkostemp_safe(fn2, O_RDWR);
+ assert_se(fd2 >= 0);
+
+ fd3 = mkostemp_safe(fn3, O_WRONLY);
+ assert_se(fd3 >= 0);
+
+ r = copy_bytes(fd, fd2, max_bytes, try_reflink);
+ if (max_bytes == (uint64_t) -1)
+ assert_se(r == 0);
+ else
+ assert_se(IN_SET(r, 0, 1));
+
+ assert_se(lseek(fd2, 0, SEEK_SET) == 0);
+
+ r = copy_bytes(fd2, fd3, max_bytes, try_reflink);
+ if (max_bytes == (uint64_t) -1)
+ assert_se(r == 0);
+ else
+ /* We cannot distinguish between the input being exactly max_bytes
+ * or longer than max_bytes (without trying to read one more byte,
+ * or calling stat, or FION_READ, etc, and we don't want to do any
+ * of that). So we expect "truncation" since we know that file we
+ * are copying is exactly max_bytes bytes. */
+ assert_se(r == 1);
+
+ assert_se(fstat(fd, &buf) == 0);
+ assert_se(fstat(fd2, &buf2) == 0);
+ assert_se(fstat(fd3, &buf3) == 0);
+
+ assert_se((uint64_t) buf2.st_size == MIN((uint64_t) buf.st_size, max_bytes));
+ assert_se(buf3.st_size == buf2.st_size);
+
+ unlink(fn2);
+ unlink(fn3);
+}
+
int main(int argc, char *argv[]) {
test_copy_file();
test_copy_file_fd();
test_copy_tree();
test_copy_bytes();
+ test_copy_bytes_regular_file(argv[0], false, (uint64_t) -1);
+ test_copy_bytes_regular_file(argv[0], true, (uint64_t) -1);
+ test_copy_bytes_regular_file(argv[0], false, 1000); /* smaller than copy buffer size */
+ test_copy_bytes_regular_file(argv[0], true, 1000);
+ test_copy_bytes_regular_file(argv[0], false, 32000); /* larger than copy buffer size */
+ test_copy_bytes_regular_file(argv[0], true, 32000);
return 0;
}
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
new file mode 100644
index 0000000000..8818d1ffb7
--- /dev/null
+++ b/src/test/test-cpu-set-util.c
@@ -0,0 +1,143 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "cpu-set-util.h"
+#include "macro.h"
+
+static void test_parse_cpu_set(void) {
+ cpu_set_t *c = NULL;
+ int ncpus;
+ int cpu;
+
+ /* Simple range (from CPUAffinity example) */
+ ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
+ c = mfree(c);
+
+ /* A more interesting range */
+ ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ for (cpu = 0; cpu < 4; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ for (cpu = 8; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Quoted strings */
+ ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
+ for (cpu = 8; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Use commas as separators */
+ ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ for (cpu = 0; cpu < 4; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ for (cpu = 8; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Commas with spaces (and trailing comma, space) */
+ ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ for (cpu = 0; cpu < 8; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Ranges */
+ ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ for (cpu = 0; cpu < 4; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ for (cpu = 8; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Ranges with trailing comma, space */
+ ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ for (cpu = 0; cpu < 4; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ for (cpu = 8; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Negative range (returns empty cpu_set) */
+ ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
+ c = mfree(c);
+
+ /* Overlapping ranges */
+ ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
+ for (cpu = 0; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Mix ranges and individual CPUs */
+ ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus >= 1024);
+ assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
+ assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
+ for (cpu = 4; cpu < 12; cpu++)
+ assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ c = mfree(c);
+
+ /* Garbage */
+ ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus < 0);
+ assert_se(!c);
+
+ /* Range with garbage */
+ ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus < 0);
+ assert_se(!c);
+
+ /* Empty string */
+ c = NULL;
+ ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus == 0); /* empty string returns 0 */
+ assert_se(!c);
+
+ /* Runnaway quoted string */
+ ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
+ assert_se(ncpus < 0);
+ assert_se(!c);
+}
+
+int main(int argc, char *argv[]) {
+ test_parse_cpu_set();
+
+ return 0;
+}
diff --git a/src/test/test-daemon.c b/src/test/test-daemon.c
index d181bee214..b2cd3c7663 100644
--- a/src/test/test-daemon.c
+++ b/src/test/test-daemon.c
@@ -38,27 +38,27 @@ int main(int argc, char*argv[]) {
sd_notify(0,
"STATUS=Starting up");
- sleep(5);
+ sleep(1);
sd_notify(0,
"STATUS=Running\n"
"READY=1");
- sleep(5);
+ sleep(1);
sd_notify(0,
"STATUS=Reloading\n"
"RELOADING=1");
- sleep(5);
+ sleep(1);
sd_notify(0,
"STATUS=Running\n"
"READY=1");
- sleep(5);
+ sleep(1);
sd_notify(0,
"STATUS=Quitting\n"
"STOPPING=1");
- sleep(5);
+ sleep(1);
return EXIT_SUCCESS;
}
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index ca66f5b684..23da10fa1a 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -23,9 +23,12 @@
#include "bus-util.h"
#include "manager.h"
+#include "rm-rf.h"
#include "test-helper.h"
+#include "tests.h"
int main(int argc, char *argv[]) {
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error err = SD_BUS_ERROR_NULL;
Manager *m = NULL;
Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL;
@@ -34,9 +37,11 @@ int main(int argc, char *argv[]) {
Job *j;
int r;
+ assert_se(runtime_dir = setup_fake_runtime_dir());
+
/* prepare the test */
assert_se(set_unit_path(TEST_DIR) >= 0);
- r = manager_new(MANAGER_USER, true, &m);
+ r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
printf("Skipping test: manager_new: %s\n", strerror(-r));
return EXIT_TEST_SKIP;
diff --git a/src/test/test-env-replace.c b/src/test/test-env-util.c
index 264acc6ea6..35bb62906e 100644
--- a/src/test/test-env-replace.c
+++ b/src/test/test-env-util.c
@@ -2,6 +2,7 @@
This file is part of systemd.
Copyright 2010 Lennart Poettering
+ 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
@@ -177,10 +178,37 @@ static void test_env_name_is_valid(void) {
assert_se(!env_name_is_valid(NULL));
assert_se(!env_name_is_valid(""));
+ assert_se(!env_name_is_valid("xxx\a"));
+ assert_se(!env_name_is_valid("xxx\007b"));
+ assert_se(!env_name_is_valid("\007\009"));
assert_se(!env_name_is_valid("5_starting_with_a_number_is_wrong"));
assert_se(!env_name_is_valid("#¤%&?_only_numbers_letters_and_underscore_allowed"));
}
+static void test_env_value_is_valid(void) {
+ assert_se(env_value_is_valid(""));
+ assert_se(env_value_is_valid("głąb kapuściany"));
+ assert_se(env_value_is_valid("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
+}
+
+static void test_env_assignment_is_valid(void) {
+ assert_se(env_assignment_is_valid("a="));
+ assert_se(env_assignment_is_valid("b=głąb kapuściany"));
+ assert_se(env_assignment_is_valid("c=\\007\\009\\011"));
+ assert_se(env_assignment_is_valid("e=printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
+
+ assert_se(!env_assignment_is_valid("="));
+ assert_se(!env_assignment_is_valid("a b="));
+ assert_se(!env_assignment_is_valid("a ="));
+ assert_se(!env_assignment_is_valid(" b="));
+ /* no dots or dashes: http://tldp.org/LDP/abs/html/gotchas.html */
+ assert_se(!env_assignment_is_valid("a.b="));
+ assert_se(!env_assignment_is_valid("a-b="));
+ assert_se(!env_assignment_is_valid("\007=głąb kapuściany"));
+ assert_se(!env_assignment_is_valid("c\009=\007\009\011"));
+ assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
+}
+
int main(int argc, char *argv[]) {
test_strv_env_delete();
test_strv_env_unset();
@@ -189,6 +217,8 @@ int main(int argc, char *argv[]) {
test_replace_env_arg();
test_env_clean();
test_env_name_is_valid();
+ test_env_value_is_valid();
+ test_env_assignment_is_valid();
return 0;
}
diff --git a/src/test/test-escape.c b/src/test/test-escape.c
new file mode 100644
index 0000000000..6cbb8443fe
--- /dev/null
+++ b/src/test/test-escape.c
@@ -0,0 +1,114 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "escape.h"
+#include "macro.h"
+
+static void test_cescape(void) {
+ _cleanup_free_ char *escaped;
+
+ assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
+ assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
+}
+
+static void test_cunescape(void) {
+ _cleanup_free_ char *unescaped;
+
+ assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
+ assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
+ unescaped = mfree(unescaped);
+
+ /* incomplete sequences */
+ assert_se(cunescape("\\x0", 0, &unescaped) < 0);
+ assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "\\x0"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("\\x", 0, &unescaped) < 0);
+ assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "\\x"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("\\", 0, &unescaped) < 0);
+ assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "\\"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("\\11", 0, &unescaped) < 0);
+ assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "\\11"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("\\1", 0, &unescaped) < 0);
+ assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "\\1"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
+ assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "ßßΠA"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("\\073", 0, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, ";"));
+}
+
+static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
+ _cleanup_free_ char *r;
+
+ assert_se(r = shell_escape(s, bad));
+ assert_se(streq_ptr(r, expected));
+}
+
+static void test_shell_escape(void) {
+ test_shell_escape_one("", "", "");
+ test_shell_escape_one("\\", "", "\\\\");
+ test_shell_escape_one("foobar", "", "foobar");
+ test_shell_escape_one("foobar", "o", "f\\o\\obar");
+ 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;
+
+ assert_se(r = shell_maybe_quote(s));
+ assert_se(streq(r, 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\"");
+}
+
+int main(int argc, char *argv[]) {
+ test_cescape();
+ test_cunescape();
+ test_shell_escape();
+ test_shell_maybe_quote();
+
+ return 0;
+}
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 92857cb5e2..77ef4e8b2a 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -91,7 +91,7 @@ static void test_exec_personality(Manager *m) {
#elif defined(__s390__)
test(m, "exec-personality-s390.service", 0, CLD_EXITED);
-#else
+#elif defined(__i386__)
test(m, "exec-personality-x86.service", 0, CLD_EXITED);
#endif
}
@@ -130,18 +130,33 @@ static void test_exec_systemcallerrornumber(Manager *m) {
#endif
}
+static void test_exec_systemcall_system_mode_with_user(Manager *m) {
+#ifdef HAVE_SECCOMP
+ if (getpwnam("nobody"))
+ test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
+ else if (getpwnam("nfsnobody"))
+ test(m, "exec-systemcallfilter-system-user-nfsnobody.service", 0, CLD_EXITED);
+ else
+ log_error_errno(errno, "Skipping test_exec_systemcall_system_mode_with_user, could not find nobody/nfsnobody user: %m");
+#endif
+}
+
static void test_exec_user(Manager *m) {
if (getpwnam("nobody"))
test(m, "exec-user.service", 0, CLD_EXITED);
+ else if (getpwnam("nfsnobody"))
+ test(m, "exec-user-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_user, could not find nobody user: %m");
+ log_error_errno(errno, "Skipping test_exec_user, could not find nobody/nfsnobody user: %m");
}
static void test_exec_group(Manager *m) {
if (getgrnam("nobody"))
test(m, "exec-group.service", 0, CLD_EXITED);
+ else if (getgrnam("nfsnobody"))
+ test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_group, could not find nobody group: %m");
+ log_error_errno(errno, "Skipping test_exec_group, could not find nobody/nfsnobody group: %m");
}
static void test_exec_environment(Manager *m) {
@@ -204,8 +219,10 @@ static void test_exec_runtimedirectory(Manager *m) {
test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
if (getgrnam("nobody"))
test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
+ else if (getgrnam("nfsnobody"))
+ test(m, "exec-runtimedirectory-owner-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_runtimedirectory-owner, could not find nobody group: %m");
+ log_error_errno(errno, "Skipping test_exec_runtimedirectory-owner, could not find nobody/nfsnobody group: %m");
}
static void test_exec_capabilityboundingset(Manager *m) {
@@ -234,9 +251,16 @@ static void test_exec_capabilityambientset(Manager *m) {
* in the first place for the tests. */
r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
if (r >= 0 || errno != EINVAL) {
- test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
- test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
- }
+ if (getpwnam("nobody")) {
+ test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
+ test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
+ } else if (getpwnam("nfsnobody")) {
+ test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
+ test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
+ } else
+ log_error_errno(errno, "Skipping test_exec_capabilityambientset, could not find nobody/nfsnobody user: %m");
+ } else
+ log_error_errno(errno, "Skipping test_exec_capabilityambientset, the kernel does not support ambient capabilities: %m");
}
static void test_exec_privatenetwork(Manager *m) {
@@ -263,8 +287,35 @@ static void test_exec_ioschedulingclass(Manager *m) {
test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
}
+static void test_exec_spec_interpolation(Manager *m) {
+ test(m, "exec-spec-interpolation.service", 0, CLD_EXITED);
+}
+
+static int run_tests(UnitFileScope scope, test_function_t *tests) {
+ test_function_t *test = NULL;
+ Manager *m = NULL;
+ int r;
+
+ assert_se(tests);
+
+ r = manager_new(scope, true, &m);
+ if (MANAGER_SKIP_TEST(r)) {
+ printf("Skipping test: manager_new: %s\n", strerror(-r));
+ return EXIT_TEST_SKIP;
+ }
+ assert_se(r >= 0);
+ assert_se(manager_startup(m, NULL, NULL) >= 0);
+
+ for (test = tests; test && *test; test++)
+ (*test)(m);
+
+ manager_free(m);
+
+ return 0;
+}
+
int main(int argc, char *argv[]) {
- test_function_t tests[] = {
+ test_function_t user_tests[] = {
test_exec_workingdirectory,
test_exec_personality,
test_exec_ignoresigpipe,
@@ -284,10 +335,13 @@ int main(int argc, char *argv[]) {
test_exec_capabilityambientset,
test_exec_oomscoreadjust,
test_exec_ioschedulingclass,
+ test_exec_spec_interpolation,
+ NULL,
+ };
+ test_function_t system_tests[] = {
+ test_exec_systemcall_system_mode_with_user,
NULL,
};
- test_function_t *test = NULL;
- Manager *m = NULL;
int r;
log_parse_environment();
@@ -312,18 +366,9 @@ int main(int argc, char *argv[]) {
assert_se(unsetenv("VAR2") == 0);
assert_se(unsetenv("VAR3") == 0);
- r = manager_new(MANAGER_USER, true, &m);
- if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
- return EXIT_TEST_SKIP;
- }
- assert_se(r >= 0);
- assert_se(manager_startup(m, NULL, NULL) >= 0);
-
- for (test = tests; test && *test; test++)
- (*test)(m);
+ r = run_tests(UNIT_FILE_USER, user_tests);
+ if (r != 0)
+ return r;
- manager_free(m);
-
- return 0;
+ return run_tests(UNIT_FILE_SYSTEM, system_tests);
}
diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c
new file mode 100644
index 0000000000..421d3bdeb3
--- /dev/null
+++ b/src/test/test-fd-util.c
@@ -0,0 +1,103 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "macro.h"
+
+static void test_close_many(void) {
+ int fds[3];
+ char name0[] = "/tmp/test-close-many.XXXXXX";
+ char name1[] = "/tmp/test-close-many.XXXXXX";
+ char name2[] = "/tmp/test-close-many.XXXXXX";
+
+ fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
+ fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
+ fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
+
+ close_many(fds, 2);
+
+ assert_se(fcntl(fds[0], F_GETFD) == -1);
+ assert_se(fcntl(fds[1], F_GETFD) == -1);
+ assert_se(fcntl(fds[2], F_GETFD) >= 0);
+
+ safe_close(fds[2]);
+
+ unlink(name0);
+ unlink(name1);
+ unlink(name2);
+}
+
+static void test_close_nointr(void) {
+ char name[] = "/tmp/test-test-close_nointr.XXXXXX";
+ int fd;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ assert_se(close_nointr(fd) >= 0);
+ assert_se(close_nointr(fd) < 0);
+
+ unlink(name);
+}
+
+static void test_same_fd(void) {
+ _cleanup_close_pair_ int p[2] = { -1, -1 };
+ _cleanup_close_ int a = -1, b = -1, c = -1;
+
+ assert_se(pipe2(p, O_CLOEXEC) >= 0);
+ assert_se((a = dup(p[0])) >= 0);
+ assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
+ assert_se((c = dup(a)) >= 0);
+
+ assert_se(same_fd(p[0], p[0]) > 0);
+ assert_se(same_fd(p[1], p[1]) > 0);
+ assert_se(same_fd(a, a) > 0);
+ assert_se(same_fd(b, b) > 0);
+
+ assert_se(same_fd(a, p[0]) > 0);
+ assert_se(same_fd(p[0], a) > 0);
+ assert_se(same_fd(c, p[0]) > 0);
+ assert_se(same_fd(p[0], c) > 0);
+ assert_se(same_fd(a, c) > 0);
+ assert_se(same_fd(c, a) > 0);
+
+ assert_se(same_fd(p[0], p[1]) == 0);
+ assert_se(same_fd(p[1], p[0]) == 0);
+ assert_se(same_fd(p[0], b) == 0);
+ assert_se(same_fd(b, p[0]) == 0);
+ assert_se(same_fd(p[1], a) == 0);
+ assert_se(same_fd(a, p[1]) == 0);
+ assert_se(same_fd(p[1], b) == 0);
+ assert_se(same_fd(b, p[1]) == 0);
+
+ assert_se(same_fd(a, b) == 0);
+ assert_se(same_fd(b, a) == 0);
+}
+
+int main(int argc, char *argv[]) {
+ test_close_many();
+ test_close_nointr();
+ test_same_fd();
+
+ return 0;
+}
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index 5586a2d6c1..79609765e0 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -27,6 +27,7 @@
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "parse-util.h"
#include "process-util.h"
#include "string-util.h"
@@ -288,7 +289,7 @@ static void test_capeff(void) {
assert_se(r == 0);
assert_se(*capeff);
- p = capeff[strspn(capeff, DIGITS "abcdefABCDEF")];
+ p = capeff[strspn(capeff, HEXDIGITS)];
assert_se(!p || isspace(p));
}
}
@@ -425,6 +426,134 @@ static void test_load_env_file_pairs(void) {
unlink(fn);
}
+static void test_search_and_fopen(void) {
+ const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
+ char name[] = "/tmp/test-search_and_fopen.XXXXXX";
+ int fd = -1;
+ int r;
+ FILE *f;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ close(fd);
+
+ r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
+ assert_se(r >= 0);
+ fclose(f);
+
+ r = search_and_fopen(name, "r", NULL, dirs, &f);
+ assert_se(r >= 0);
+ fclose(f);
+
+ r = search_and_fopen(basename(name), "r", "/", dirs, &f);
+ assert_se(r >= 0);
+ fclose(f);
+
+ r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
+ assert_se(r < 0);
+ r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
+ assert_se(r < 0);
+
+ r = unlink(name);
+ assert_se(r == 0);
+
+ r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
+ assert_se(r < 0);
+}
+
+
+static void test_search_and_fopen_nulstr(void) {
+ const char dirs[] = "/tmp/foo/bar\0/tmp\0";
+ char name[] = "/tmp/test-search_and_fopen.XXXXXX";
+ int fd = -1;
+ int r;
+ FILE *f;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ close(fd);
+
+ r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
+ assert_se(r >= 0);
+ fclose(f);
+
+ r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
+ assert_se(r >= 0);
+ fclose(f);
+
+ r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
+ assert_se(r < 0);
+ r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
+ assert_se(r < 0);
+
+ r = unlink(name);
+ assert_se(r == 0);
+
+ r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
+ assert_se(r < 0);
+}
+
+static void test_writing_tmpfile(void) {
+ char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
+ _cleanup_free_ char *contents = NULL;
+ size_t size;
+ int fd, r;
+ struct iovec iov[3];
+
+ IOVEC_SET_STRING(iov[0], "abc\n");
+ IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
+ IOVEC_SET_STRING(iov[2], "");
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ printf("tmpfile: %s", name);
+
+ r = writev(fd, iov, 3);
+ assert_se(r >= 0);
+
+ r = read_full_file(name, &contents, &size);
+ assert_se(r == 0);
+ printf("contents: %s", contents);
+ assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
+
+ unlink(name);
+}
+
+static void test_tempfn(void) {
+ char *ret = NULL, *p;
+
+ assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
+ assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
+ free(ret);
+
+ assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
+ assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
+ free(ret);
+
+ assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
+ assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
+ assert_se(strlen(p) == 16);
+ assert_se(in_charset(p, "0123456789abcdef"));
+ free(ret);
+
+ assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
+ assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
+ assert_se(strlen(p) == 16);
+ assert_se(in_charset(p, "0123456789abcdef"));
+ free(ret);
+
+ assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
+ assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
+ assert_se(strlen(p) == 16);
+ assert_se(in_charset(p, "0123456789abcdef"));
+ free(ret);
+
+ assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
+ assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
+ assert_se(strlen(p) == 16);
+ assert_se(in_charset(p, "0123456789abcdef"));
+ free(ret);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -439,6 +568,10 @@ int main(int argc, char *argv[]) {
test_write_string_file_no_create();
test_write_string_file_verify();
test_load_env_file_pairs();
+ test_search_and_fopen();
+ test_search_and_fopen_nulstr();
+ test_writing_tmpfile();
+ test_tempfn();
return 0;
}
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
new file mode 100644
index 0000000000..6db2c2b6f1
--- /dev/null
+++ b/src/test/test-fs-util.c
@@ -0,0 +1,91 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fileio.h"
+#include "fd-util.h"
+#include "fs-util.h"
+#include "macro.h"
+#include "mkdir.h"
+#include "rm-rf.h"
+#include "string-util.h"
+#include "strv.h"
+#include "util.h"
+
+static void test_unlink_noerrno(void) {
+ char name[] = "/tmp/test-close_nointr.XXXXXX";
+ int fd;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ assert_se(close_nointr(fd) >= 0);
+
+ {
+ PROTECT_ERRNO;
+ errno = -42;
+ assert_se(unlink_noerrno(name) >= 0);
+ assert_se(errno == -42);
+ assert_se(unlink_noerrno(name) < 0);
+ assert_se(errno == -42);
+ }
+}
+
+static void test_readlink_and_make_absolute(void) {
+ char tempdir[] = "/tmp/test-readlink_and_make_absolute";
+ char name[] = "/tmp/test-readlink_and_make_absolute/original";
+ char name2[] = "test-readlink_and_make_absolute/original";
+ char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
+ char *r = NULL;
+
+ assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
+ assert_se(touch(name) >= 0);
+
+ assert_se(symlink(name, name_alias) >= 0);
+ assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
+ assert_se(streq(r, name));
+ free(r);
+ assert_se(unlink(name_alias) >= 0);
+
+ assert_se(chdir(tempdir) >= 0);
+ assert_se(symlink(name2, name_alias) >= 0);
+ assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
+ assert_se(streq(r, name));
+ free(r);
+ assert_se(unlink(name_alias) >= 0);
+
+ assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
+}
+
+static void test_get_files_in_directory(void) {
+ _cleanup_strv_free_ char **l = NULL, **t = NULL;
+
+ assert_se(get_files_in_directory("/tmp", &l) >= 0);
+ assert_se(get_files_in_directory(".", &t) >= 0);
+ assert_se(get_files_in_directory(".", NULL) >= 0);
+}
+
+int main(int argc, char *argv[]) {
+ test_unlink_noerrno();
+ test_readlink_and_make_absolute();
+ test_get_files_in_directory();
+
+ return 0;
+}
diff --git a/src/test/test-fstab-util.c b/src/test/test-fstab-util.c
index ea3d1a6909..63a4b8c243 100644
--- a/src/test/test-fstab-util.c
+++ b/src/test/test-fstab-util.c
@@ -131,8 +131,45 @@ static void test_fstab_yes_no_option(void) {
assert_se(fstab_test_yes_no_option("nofail,nofail=0,fail=0", "nofail\0fail\0") == false);
}
+static void test_fstab_node_to_udev_node(void) {
+ char *n;
+
+ n = fstab_node_to_udev_node("LABEL=applé/jack");
+ puts(n);
+ assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
+ free(n);
+
+ n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
+ puts(n);
+ assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
+ free(n);
+
+ n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
+ puts(n);
+ assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
+ free(n);
+
+ n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
+ puts(n);
+ assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
+ free(n);
+
+ n = fstab_node_to_udev_node("PONIES=awesome");
+ puts(n);
+ assert_se(streq(n, "PONIES=awesome"));
+ free(n);
+
+ n = fstab_node_to_udev_node("/dev/xda1");
+ puts(n);
+ assert_se(streq(n, "/dev/xda1"));
+ free(n);
+}
+
int main(void) {
test_fstab_filter_options();
test_fstab_find_pri();
test_fstab_yes_no_option();
+ test_fstab_node_to_udev_node();
+
+ return 0;
}
diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c
new file mode 100644
index 0000000000..227d4290f0
--- /dev/null
+++ b/src/test/test-glob-util.c
@@ -0,0 +1,50 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fileio.h"
+#include "glob-util.h"
+#include "macro.h"
+
+static void test_glob_exists(void) {
+ char name[] = "/tmp/test-glob_exists.XXXXXX";
+ int fd = -1;
+ int r;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ close(fd);
+
+ r = glob_exists("/tmp/test-glob_exists*");
+ assert_se(r == 1);
+
+ r = unlink(name);
+ assert_se(r == 0);
+ r = glob_exists("/tmp/test-glob_exists*");
+ assert_se(r == 0);
+}
+
+int main(void) {
+ test_glob_exists();
+
+ return 0;
+}
diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c
index 6bf33306a9..1bd5c02f87 100644
--- a/src/test/test-hashmap-plain.c
+++ b/src/test/test-hashmap-plain.c
@@ -323,26 +323,29 @@ static void test_hashmap_remove_value(void) {
_cleanup_hashmap_free_ Hashmap *m = NULL;
char *r;
- r = hashmap_remove_value(NULL, "key 1", (void*) "val 1");
+ char val1[] = "val 1";
+ char val2[] = "val 2";
+
+ r = hashmap_remove_value(NULL, "key 1", val1);
assert_se(r == NULL);
m = hashmap_new(&string_hash_ops);
assert_se(m);
- r = hashmap_remove_value(m, "key 1", (void*) "val 1");
+ r = hashmap_remove_value(m, "key 1", val1);
assert_se(r == NULL);
- hashmap_put(m, "key 1", (void*) "val 1");
- hashmap_put(m, "key 2", (void*) "val 2");
+ hashmap_put(m, "key 1", val1);
+ hashmap_put(m, "key 2", val2);
- r = hashmap_remove_value(m, "key 1", (void*) "val 1");
+ r = hashmap_remove_value(m, "key 1", val1);
assert_se(streq(r, "val 1"));
r = hashmap_get(m, "key 2");
assert_se(streq(r, "val 2"));
assert_se(!hashmap_get(m, "key 1"));
- r = hashmap_remove_value(m, "key 2", (void*) "val 1");
+ r = hashmap_remove_value(m, "key 2", val1);
assert_se(r == NULL);
r = hashmap_get(m, "key 2");
diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c
new file mode 100644
index 0000000000..276f25d091
--- /dev/null
+++ b/src/test/test-hexdecoct.c
@@ -0,0 +1,387 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "hexdecoct.h"
+#include "macro.h"
+#include "string-util.h"
+
+static void test_hexchar(void) {
+ assert_se(hexchar(0xa) == 'a');
+ assert_se(hexchar(0x0) == '0');
+}
+
+static void test_unhexchar(void) {
+ assert_se(unhexchar('a') == 0xA);
+ assert_se(unhexchar('A') == 0xA);
+ assert_se(unhexchar('0') == 0x0);
+}
+
+static void test_base32hexchar(void) {
+ assert_se(base32hexchar(0) == '0');
+ assert_se(base32hexchar(9) == '9');
+ assert_se(base32hexchar(10) == 'A');
+ assert_se(base32hexchar(31) == 'V');
+}
+
+static void test_unbase32hexchar(void) {
+ assert_se(unbase32hexchar('0') == 0);
+ assert_se(unbase32hexchar('9') == 9);
+ assert_se(unbase32hexchar('A') == 10);
+ assert_se(unbase32hexchar('V') == 31);
+ assert_se(unbase32hexchar('=') == -EINVAL);
+}
+
+static void test_base64char(void) {
+ assert_se(base64char(0) == 'A');
+ assert_se(base64char(26) == 'a');
+ assert_se(base64char(63) == '/');
+}
+
+static void test_unbase64char(void) {
+ assert_se(unbase64char('A') == 0);
+ assert_se(unbase64char('Z') == 25);
+ assert_se(unbase64char('a') == 26);
+ assert_se(unbase64char('z') == 51);
+ assert_se(unbase64char('0') == 52);
+ assert_se(unbase64char('9') == 61);
+ assert_se(unbase64char('+') == 62);
+ assert_se(unbase64char('/') == 63);
+ assert_se(unbase64char('=') == -EINVAL);
+}
+
+static void test_octchar(void) {
+ assert_se(octchar(00) == '0');
+ assert_se(octchar(07) == '7');
+}
+
+static void test_unoctchar(void) {
+ assert_se(unoctchar('0') == 00);
+ assert_se(unoctchar('7') == 07);
+}
+
+static void test_decchar(void) {
+ assert_se(decchar(0) == '0');
+ assert_se(decchar(9) == '9');
+}
+
+static void test_undecchar(void) {
+ assert_se(undecchar('0') == 0);
+ assert_se(undecchar('9') == 9);
+}
+
+static void test_unhexmem(void) {
+ const char *hex = "efa214921";
+ const char *hex_invalid = "efa214921o";
+ _cleanup_free_ char *hex2 = NULL;
+ _cleanup_free_ void *mem = NULL;
+ size_t len;
+
+ assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
+ assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
+ assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
+
+ assert_se((hex2 = hexmem(mem, len)));
+
+ free(mem);
+
+ assert_se(memcmp(hex, hex2, strlen(hex)) == 0);
+
+ free(hex2);
+
+ assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == 0);
+ assert_se((hex2 = hexmem(mem, len)));
+ assert_se(memcmp(hex, hex2, strlen(hex) - 1) == 0);
+}
+
+/* https://tools.ietf.org/html/rfc4648#section-10 */
+static void test_base32hexmem(void) {
+ char *b32;
+
+ b32 = base32hexmem("", strlen(""), true);
+ assert_se(b32);
+ assert_se(streq(b32, ""));
+ free(b32);
+
+ b32 = base32hexmem("f", strlen("f"), true);
+ assert_se(b32);
+ assert_se(streq(b32, "CO======"));
+ free(b32);
+
+ b32 = base32hexmem("fo", strlen("fo"), true);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNG===="));
+ free(b32);
+
+ b32 = base32hexmem("foo", strlen("foo"), true);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMU==="));
+ free(b32);
+
+ b32 = base32hexmem("foob", strlen("foob"), true);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMUOG="));
+ free(b32);
+
+ b32 = base32hexmem("fooba", strlen("fooba"), true);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMUOJ1"));
+ free(b32);
+
+ b32 = base32hexmem("foobar", strlen("foobar"), true);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMUOJ1E8======"));
+ free(b32);
+
+ b32 = base32hexmem("", strlen(""), false);
+ assert_se(b32);
+ assert_se(streq(b32, ""));
+ free(b32);
+
+ b32 = base32hexmem("f", strlen("f"), false);
+ assert_se(b32);
+ assert_se(streq(b32, "CO"));
+ free(b32);
+
+ b32 = base32hexmem("fo", strlen("fo"), false);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNG"));
+ free(b32);
+
+ b32 = base32hexmem("foo", strlen("foo"), false);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMU"));
+ free(b32);
+
+ b32 = base32hexmem("foob", strlen("foob"), false);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMUOG"));
+ free(b32);
+
+ b32 = base32hexmem("fooba", strlen("fooba"), false);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMUOJ1"));
+ free(b32);
+
+ b32 = base32hexmem("foobar", strlen("foobar"), false);
+ assert_se(b32);
+ assert_se(streq(b32, "CPNMUOJ1E8"));
+ free(b32);
+}
+
+static void test_unbase32hexmem(void) {
+ void *mem;
+ size_t len;
+
+ assert_se(unbase32hexmem("", strlen(""), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), ""));
+ free(mem);
+
+ assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "f"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "fo"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foo"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foob"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "fooba"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foobar"));
+ free(mem);
+
+ assert_se(unbase32hexmem("A", strlen("A"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem, &len) == -EINVAL);
+
+ assert_se(unbase32hexmem("XPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CXNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPXMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPNXUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPNMXOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPNMUXJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPNMUOX1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPNMUOJX", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+
+ assert_se(unbase32hexmem("", strlen(""), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), ""));
+ free(mem);
+
+ assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "f"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "fo"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foo"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foob"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "fooba"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foobar"));
+ free(mem);
+
+ assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem, &len) == -EINVAL);
+ assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem, &len) == -EINVAL);
+}
+
+/* https://tools.ietf.org/html/rfc4648#section-10 */
+static void test_base64mem(void) {
+ char *b64;
+
+ assert_se(base64mem("", strlen(""), &b64) == 0);
+ assert_se(streq(b64, ""));
+ free(b64);
+
+ assert_se(base64mem("f", strlen("f"), &b64) == 4);
+ assert_se(streq(b64, "Zg=="));
+ free(b64);
+
+ assert_se(base64mem("fo", strlen("fo"), &b64) == 4);
+ assert_se(streq(b64, "Zm8="));
+ free(b64);
+
+ assert_se(base64mem("foo", strlen("foo"), &b64) == 4);
+ assert_se(streq(b64, "Zm9v"));
+ free(b64);
+
+ assert_se(base64mem("foob", strlen("foob"), &b64) == 8);
+ assert_se(streq(b64, "Zm9vYg=="));
+ free(b64);
+
+ assert_se(base64mem("fooba", strlen("fooba"), &b64) == 8);
+ assert_se(streq(b64, "Zm9vYmE="));
+ free(b64);
+
+ assert_se(base64mem("foobar", strlen("foobar"), &b64) == 8);
+ assert_se(streq(b64, "Zm9vYmFy"));
+ free(b64);
+}
+
+static void test_unbase64mem(void) {
+ void *mem;
+ size_t len;
+
+ assert_se(unbase64mem("", strlen(""), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), ""));
+ free(mem);
+
+ assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "f"));
+ free(mem);
+
+ assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "fo"));
+ free(mem);
+
+ assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foo"));
+ free(mem);
+
+ assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foob"));
+ free(mem);
+
+ assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "fooba"));
+ free(mem);
+
+ assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem, &len) == 0);
+ assert_se(streq(strndupa(mem, len), "foobar"));
+ free(mem);
+
+ assert_se(unbase64mem("A", strlen("A"), &mem, &len) == -EINVAL);
+ assert_se(unbase64mem("A====", strlen("A===="), &mem, &len) == -EINVAL);
+ assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem, &len) == -EINVAL);
+ assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem, &len) == -EINVAL);
+}
+
+static void test_hexdump(void) {
+ uint8_t data[146];
+ unsigned i;
+
+ hexdump(stdout, NULL, 0);
+ hexdump(stdout, "", 0);
+ hexdump(stdout, "", 1);
+ hexdump(stdout, "x", 1);
+ hexdump(stdout, "x", 2);
+ hexdump(stdout, "foobar", 7);
+ hexdump(stdout, "f\nobar", 7);
+ hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
+
+ for (i = 0; i < ELEMENTSOF(data); i++)
+ data[i] = i*2;
+
+ hexdump(stdout, data, sizeof(data));
+}
+
+int main(int argc, char *argv[]) {
+ test_hexchar();
+ test_unhexchar();
+ test_base32hexchar();
+ test_unbase32hexchar();
+ test_base64char();
+ test_unbase64char();
+ test_octchar();
+ test_unoctchar();
+ test_decchar();
+ test_undecchar();
+ test_unhexmem();
+ test_base32hexmem();
+ test_unbase32hexmem();
+ test_base64mem();
+ test_unbase64mem();
+ test_hexdump();
+
+ return 0;
+}
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index cd250ca7b8..4b9a74fca4 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -30,6 +30,8 @@ static void test_basic_mask_and_enable(const char *root) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
+ log_set_max_level(LOG_DEBUG);
+
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", NULL) == -ENOENT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) == -ENOENT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) == -ENOENT);
@@ -78,7 +80,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_MASKED);
/* Enabling a masked unit should fail! */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == -ESHUTDOWN);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == -ERFKILL);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
@@ -105,7 +107,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
/* Enabling it again should succeed but be a NOP */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == 1);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
@@ -604,7 +606,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(h = hashmap_new(&string_hash_ops));
- assert_se(unit_file_get_list(UNIT_FILE_SYSTEM, root, h) >= 0);
+ assert_se(unit_file_get_list(UNIT_FILE_SYSTEM, root, h, NULL, NULL) >= 0);
p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service");
q = strjoina(root, "/usr/lib/systemd/system/preset-no.service");
@@ -628,6 +630,104 @@ static void test_preset_and_list(const char *root) {
assert_se(got_yes && got_no);
}
+static void test_revert(const char *root) {
+ const char *p;
+ UnitFileState state;
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
+
+ assert(root);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", NULL) == -ENOENT);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "yy.service", NULL) == -ENOENT);
+
+ p = strjoina(root, "/usr/lib/systemd/system/xx.service");
+ assert_se(write_string_file(p, "# Empty\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", NULL) >= 0);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", &state) >= 0 && state == UNIT_FILE_STATIC);
+
+ /* Initially there's nothing to revert */
+ assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
+ assert_se(n_changes == 0);
+ unit_file_changes_free(changes, n_changes);
+ changes = NULL; n_changes = 0;
+
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service");
+ assert_se(write_string_file(p, "# Empty override\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ /* Revert the override file */
+ assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
+ assert_se(n_changes == 1);
+ assert_se(changes[0].type == UNIT_FILE_UNLINK);
+ assert_se(streq(changes[0].path, p));
+ unit_file_changes_free(changes, n_changes);
+ changes = NULL; n_changes = 0;
+
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service.d/dropin.conf");
+ assert_se(mkdir_parents(p, 0755) >= 0);
+ assert_se(write_string_file(p, "# Empty dropin\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ /* Revert the dropin file */
+ assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
+ assert_se(n_changes == 2);
+ assert_se(changes[0].type == UNIT_FILE_UNLINK);
+ assert_se(streq(changes[0].path, p));
+
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service.d");
+ assert_se(changes[1].type == UNIT_FILE_UNLINK);
+ assert_se(streq(changes[1].path, p));
+ unit_file_changes_free(changes, n_changes);
+ changes = NULL; n_changes = 0;
+}
+
+static void test_preset_order(const char *root) {
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
+ const char *p;
+ UnitFileState state;
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) == -ENOENT);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) == -ENOENT);
+
+ p = strjoina(root, "/usr/lib/systemd/system/prefix-1.service");
+ assert_se(write_string_file(p,
+ "[Install]\n"
+ "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ p = strjoina(root, "/usr/lib/systemd/system/prefix-2.service");
+ assert_se(write_string_file(p,
+ "[Install]\n"
+ "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset");
+ assert_se(write_string_file(p,
+ "enable prefix-1.service\n"
+ "disable prefix-*.service\n"
+ "enable prefix-2.service\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(n_changes == 1);
+ assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+ assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service"));
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/prefix-1.service");
+ assert_se(streq(changes[0].path, p));
+ unit_file_changes_free(changes, n_changes);
+ changes = NULL; n_changes = 0;
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(n_changes == 0);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+}
+
int main(int argc, char *argv[]) {
char root[] = "/tmp/rootXXXXXX";
const char *p;
@@ -656,6 +756,8 @@ int main(int argc, char *argv[]) {
test_template_enable(root);
test_indirect(root);
test_preset_and_list(root);
+ test_preset_order(root);
+ test_revert(root);
assert_se(rm_rf(root, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
diff --git a/src/test/test-install.c b/src/test/test-install.c
index 874d617621..0ac85f040a 100644
--- a/src/test/test-install.c
+++ b/src/test/test-install.c
@@ -46,8 +46,11 @@ int main(int argc, char* argv[]) {
unsigned n_changes = 0;
UnitFileState state = 0;
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
h = hashmap_new(&string_hash_ops);
- r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
+ r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h, NULL, NULL);
assert_se(r == 0);
HASHMAP_FOREACH(p, h, i) {
@@ -65,12 +68,12 @@ int main(int argc, char* argv[]) {
unit_file_list_free(h);
- log_error("enable");
+ log_info("/*** enable **/");
r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
assert_se(r >= 0);
- log_error("enable2");
+ log_info("/*** enable2 **/");
r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
assert_se(r >= 0);
@@ -82,8 +85,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);
- log_error("disable");
-
+ log_info("/*** disable ***/");
changes = NULL;
n_changes = 0;
@@ -97,13 +99,13 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_DISABLED);
- log_error("mask");
+ log_info("/*** mask ***/");
changes = NULL;
n_changes = 0;
r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
assert_se(r >= 0);
- log_error("mask2");
+ log_info("/*** mask2 ***/");
r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
assert_se(r >= 0);
@@ -114,13 +116,13 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_MASKED);
- log_error("unmask");
+ log_info("/*** unmask ***/");
changes = NULL;
n_changes = 0;
r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
- log_error("unmask2");
+ log_info("/*** unmask2 ***/");
r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
@@ -131,7 +133,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_DISABLED);
- log_error("mask");
+ log_info("/*** mask ***/");
changes = NULL;
n_changes = 0;
@@ -145,13 +147,13 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_MASKED);
- log_error("disable");
+ log_info("/*** disable ***/");
changes = NULL;
n_changes = 0;
r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
- log_error("disable2");
+ log_info("/*** disable2 ***/");
r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
@@ -162,7 +164,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_MASKED);
- log_error("umask");
+ log_info("/*** umask ***/");
changes = NULL;
n_changes = 0;
@@ -176,7 +178,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_DISABLED);
- log_error("enable files2");
+ log_info("/*** enable files2 ***/");
changes = NULL;
n_changes = 0;
@@ -190,7 +192,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);
- log_error("disable files2");
+ log_info("/*** disable files2 ***/");
changes = NULL;
n_changes = 0;
@@ -203,7 +205,7 @@ int main(int argc, char* argv[]) {
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r < 0);
- log_error("link files2");
+ log_info("/*** link files2 ***/");
changes = NULL;
n_changes = 0;
@@ -217,7 +219,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_LINKED);
- log_error("disable files2");
+ log_info("/*** disable files2 ***/");
changes = NULL;
n_changes = 0;
@@ -230,7 +232,7 @@ int main(int argc, char* argv[]) {
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r < 0);
- log_error("link files2");
+ log_info("/*** link files2 ***/");
changes = NULL;
n_changes = 0;
@@ -244,7 +246,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_LINKED);
- log_error("reenable files2");
+ log_info("/*** reenable files2 ***/");
changes = NULL;
n_changes = 0;
@@ -258,7 +260,7 @@ int main(int argc, char* argv[]) {
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);
- log_error("disable files2");
+ log_info("/*** disable files2 ***/");
changes = NULL;
n_changes = 0;
@@ -270,7 +272,7 @@ int main(int argc, char* argv[]) {
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r < 0);
- log_error("preset files");
+ log_info("/*** preset files ***/");
changes = NULL;
n_changes = 0;
diff --git a/src/test/test-io-util.c b/src/test/test-io-util.c
new file mode 100644
index 0000000000..10bd3833bc
--- /dev/null
+++ b/src/test/test-io-util.c
@@ -0,0 +1,69 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "io-util.h"
+#include "macro.h"
+
+static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
+ char check[n];
+
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
+ assert_se(ftruncate(fd, 0) >= 0);
+ assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
+
+ assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
+ assert_se(ftruncate(fd, n) >= 0);
+
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
+ assert_se(read(fd, check, n) == (ssize_t) n);
+
+ assert_se(memcmp(buffer, check, n) == 0);
+}
+
+static void test_sparse_write(void) {
+ const char test_a[] = "test";
+ const char test_b[] = "\0\0\0\0test\0\0\0\0";
+ const char test_c[] = "\0\0test\0\0\0\0";
+ const char test_d[] = "\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0\0\0\0";
+ const char test_e[] = "test\0\0\0\0test";
+ _cleanup_close_ int fd = -1;
+ char fn[] = "/tmp/sparseXXXXXX";
+
+ fd = mkostemp(fn, O_CLOEXEC);
+ assert_se(fd >= 0);
+ unlink(fn);
+
+ test_sparse_write_one(fd, test_a, sizeof(test_a));
+ test_sparse_write_one(fd, test_b, sizeof(test_b));
+ test_sparse_write_one(fd, test_c, sizeof(test_c));
+ test_sparse_write_one(fd, test_d, sizeof(test_d));
+ test_sparse_write_one(fd, test_e, sizeof(test_e));
+}
+
+int main(void) {
+ test_sparse_write();
+
+ return 0;
+}
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
index 2464d32458..c5bcaf47bb 100644
--- a/src/test/test-ipcrm.c
+++ b/src/test/test-ipcrm.c
@@ -23,9 +23,14 @@
int main(int argc, char *argv[]) {
uid_t uid;
-
- assert_se(argc == 2);
- assert_se(parse_uid(argv[1], &uid) >= 0);
+ int r;
+ const char* name = argv[1] ?: "nfsnobody";
+
+ r = get_user_creds(&name, &uid, NULL, NULL, NULL);
+ if (r < 0) {
+ log_error_errno(r, "Failed to resolve \"%s\": %m", name);
+ return EXIT_FAILURE;
+ }
return clean_ipc(uid) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/test/test-json.c b/src/test/test-json.c
deleted file mode 100644
index 3fe2f58d04..0000000000
--- a/src/test/test-json.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <math.h>
-
-#include "alloc-util.h"
-#include "json.h"
-#include "string-util.h"
-#include "util.h"
-
-static void test_one(const char *data, ...) {
- void *state = NULL;
- va_list ap;
-
- va_start(ap, data);
-
- for (;;) {
- _cleanup_free_ char *str = NULL;
- union json_value v = {};
- int t, tt;
-
- t = json_tokenize(&data, &str, &v, &state, NULL);
- tt = va_arg(ap, int);
-
- assert_se(t == tt);
-
- if (t == JSON_END || t < 0)
- break;
-
- else if (t == JSON_STRING) {
- const char *nn;
-
- nn = va_arg(ap, const char *);
- assert_se(streq_ptr(nn, str));
-
- } else if (t == JSON_REAL) {
- double d;
-
- d = va_arg(ap, double);
- assert_se(fabs(d - v.real) < 0.001);
-
- } else if (t == JSON_INTEGER) {
- intmax_t i;
-
- i = va_arg(ap, intmax_t);
- assert_se(i == v.integer);
-
- } else if (t == JSON_BOOLEAN) {
- bool b;
-
- b = va_arg(ap, int);
- assert_se(b == v.boolean);
- }
- }
-
- va_end(ap);
-}
-
-typedef void (*Test)(JsonVariant *);
-
-static void test_file(const char *data, Test test) {
- _cleanup_json_variant_unref_ JsonVariant *v = NULL;
- int r;
-
- r = json_parse(data, &v);
- assert_se(r == 0);
- assert_se(v != NULL);
- assert_se(v->type == JSON_VARIANT_OBJECT);
-
- if (test)
- test(v);
-}
-
-static void test_1(JsonVariant *v) {
- JsonVariant *p, *q;
- unsigned i;
-
- /* 3 keys + 3 values */
- assert_se(v->size == 6);
-
- /* has k */
- p = json_variant_value(v, "k");
- assert_se(p && p->type == JSON_VARIANT_STRING);
-
- /* k equals v */
- assert_se(streq(json_variant_string(p), "v"));
-
- /* has foo */
- p = json_variant_value(v, "foo");
- assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 3);
-
- /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */
- for (i = 0; i < 3; ++i) {
- q = json_variant_element(p, i);
- assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == (i+1));
- }
-
- /* has bar */
- p = json_variant_value(v, "bar");
- assert_se(p && p->type == JSON_VARIANT_OBJECT && p->size == 2);
-
- /* zap is null */
- q = json_variant_value(p, "zap");
- assert_se(q && q->type == JSON_VARIANT_NULL);
-}
-
-static void test_2(JsonVariant *v) {
- JsonVariant *p, *q;
-
- /* 2 keys + 2 values */
- assert_se(v->size == 4);
-
- /* has mutant */
- p = json_variant_value(v, "mutant");
- assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 4);
-
- /* mutant[0] == 1 */
- q = json_variant_element(p, 0);
- assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
-
- /* mutant[1] == null */
- q = json_variant_element(p, 1);
- assert_se(q && q->type == JSON_VARIANT_NULL);
-
- /* mutant[2] == "1" */
- q = json_variant_element(p, 2);
- assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
-
- /* mutant[3] == JSON_VARIANT_OBJECT */
- q = json_variant_element(p, 3);
- assert_se(q && q->type == JSON_VARIANT_OBJECT && q->size == 2);
-
- /* has 1 */
- p = json_variant_value(q, "1");
- assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 2);
-
- /* "1"[0] == 1 */
- q = json_variant_element(p, 0);
- assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1);
-
- /* "1"[1] == "1" */
- q = json_variant_element(p, 1);
- assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
-
- /* has blah */
- p = json_variant_value(v, "blah");
- assert_se(p && p->type == JSON_VARIANT_REAL && fabs(json_variant_real(p) - 1.27) < 0.001);
-}
-
-int main(int argc, char *argv[]) {
-
- test_one("x", -EINVAL);
- test_one("", JSON_END);
- test_one(" ", JSON_END);
- test_one("0", JSON_INTEGER, (intmax_t) 0, JSON_END);
- test_one("1234", JSON_INTEGER, (intmax_t) 1234, JSON_END);
- test_one("3.141", JSON_REAL, 3.141, JSON_END);
- test_one("0.0", JSON_REAL, 0.0, JSON_END);
- test_one("7e3", JSON_REAL, 7e3, JSON_END);
- test_one("-7e-3", JSON_REAL, -7e-3, JSON_END);
- test_one("true", JSON_BOOLEAN, true, JSON_END);
- test_one("false", JSON_BOOLEAN, false, JSON_END);
- test_one("null", JSON_NULL, JSON_END);
- test_one("{}", JSON_OBJECT_OPEN, JSON_OBJECT_CLOSE, JSON_END);
- test_one("\t {\n} \n", JSON_OBJECT_OPEN, JSON_OBJECT_CLOSE, JSON_END);
- test_one("[]", JSON_ARRAY_OPEN, JSON_ARRAY_CLOSE, JSON_END);
- test_one("\t [] \n\n", JSON_ARRAY_OPEN, JSON_ARRAY_CLOSE, JSON_END);
- test_one("\"\"", JSON_STRING, "", JSON_END);
- test_one("\"foo\"", JSON_STRING, "foo", JSON_END);
- test_one("\"foo\\nfoo\"", JSON_STRING, "foo\nfoo", JSON_END);
- test_one("{\"foo\" : \"bar\"}", JSON_OBJECT_OPEN, JSON_STRING, "foo", JSON_COLON, JSON_STRING, "bar", JSON_OBJECT_CLOSE, JSON_END);
- test_one("{\"foo\" : [true, false]}", JSON_OBJECT_OPEN, JSON_STRING, "foo", JSON_COLON, JSON_ARRAY_OPEN, JSON_BOOLEAN, true, JSON_COMMA, JSON_BOOLEAN, false, JSON_ARRAY_CLOSE, JSON_OBJECT_CLOSE, JSON_END);
- test_one("\"\xef\xbf\xbd\"", JSON_STRING, "\xef\xbf\xbd", JSON_END);
- test_one("\"\\ufffd\"", JSON_STRING, "\xef\xbf\xbd", JSON_END);
- test_one("\"\\uf\"", -EINVAL);
- test_one("\"\\ud800a\"", -EINVAL);
- test_one("\"\\udc00\\udc00\"", -EINVAL);
- test_one("\"\\ud801\\udc37\"", JSON_STRING, "\xf0\x90\x90\xb7", JSON_END);
-
- test_one("[1, 2]", JSON_ARRAY_OPEN, JSON_INTEGER, (intmax_t) 1, JSON_COMMA, JSON_INTEGER, (intmax_t) 2, JSON_ARRAY_CLOSE, JSON_END);
-
- test_file("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1);
- test_file("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"blah\": 1.27}", test_2);
-
- return 0;
-}
diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c
index a7eb60e8cf..e28de9b37b 100644
--- a/src/test/test-libudev.c
+++ b/src/test/test-libudev.c
@@ -24,170 +24,140 @@
#include "libudev.h"
+#include "fd-util.h"
+#include "log.h"
#include "stdio-util.h"
#include "string-util.h"
#include "udev-util.h"
#include "util.h"
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
static void print_device(struct udev_device *device) {
const char *str;
dev_t devnum;
int count;
struct udev_list_entry *list_entry;
- printf("*** device: %p ***\n", device);
+ log_info("*** device: %p ***", device);
str = udev_device_get_action(device);
if (str != NULL)
- printf("action: '%s'\n", str);
+ log_info("action: '%s'", str);
str = udev_device_get_syspath(device);
- printf("syspath: '%s'\n", str);
+ log_info("syspath: '%s'", str);
str = udev_device_get_sysname(device);
- printf("sysname: '%s'\n", str);
+ log_info("sysname: '%s'", str);
str = udev_device_get_sysnum(device);
if (str != NULL)
- printf("sysnum: '%s'\n", str);
+ log_info("sysnum: '%s'", str);
str = udev_device_get_devpath(device);
- printf("devpath: '%s'\n", str);
+ log_info("devpath: '%s'", str);
str = udev_device_get_subsystem(device);
if (str != NULL)
- printf("subsystem: '%s'\n", str);
+ log_info("subsystem: '%s'", str);
str = udev_device_get_devtype(device);
if (str != NULL)
- printf("devtype: '%s'\n", str);
+ log_info("devtype: '%s'", str);
str = udev_device_get_driver(device);
if (str != NULL)
- printf("driver: '%s'\n", str);
+ log_info("driver: '%s'", str);
str = udev_device_get_devnode(device);
if (str != NULL)
- printf("devname: '%s'\n", str);
+ log_info("devname: '%s'", str);
devnum = udev_device_get_devnum(device);
if (major(devnum) > 0)
- printf("devnum: %u:%u\n", major(devnum), minor(devnum));
+ log_info("devnum: %u:%u", major(devnum), minor(devnum));
count = 0;
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
- printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
+ log_info("link: '%s'", udev_list_entry_get_name(list_entry));
count++;
}
if (count > 0)
- printf("found %i links\n", count);
+ log_info("found %i links", count);
count = 0;
udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
- printf("property: '%s=%s'\n",
+ log_info("property: '%s=%s'",
udev_list_entry_get_name(list_entry),
udev_list_entry_get_value(list_entry));
count++;
}
if (count > 0)
- printf("found %i properties\n", count);
+ log_info("found %i properties", count);
str = udev_device_get_property_value(device, "MAJOR");
if (str != NULL)
- printf("MAJOR: '%s'\n", str);
+ log_info("MAJOR: '%s'", str);
str = udev_device_get_sysattr_value(device, "dev");
if (str != NULL)
- printf("attr{dev}: '%s'\n", str);
-
- printf("\n");
+ log_info("attr{dev}: '%s'", str);
}
-static int test_device(struct udev *udev, const char *syspath) {
+static void test_device(struct udev *udev, const char *syspath) {
_cleanup_udev_device_unref_ struct udev_device *device;
- printf("looking at device: %s\n", syspath);
+ log_info("looking at device: %s", syspath);
device = udev_device_new_from_syspath(udev, syspath);
- if (device == NULL) {
- printf("no device found\n");
- return -1;
- }
- print_device(device);
-
- return 0;
+ if (device == NULL)
+ log_warning_errno(errno, "udev_device_new_from_syspath: %m");
+ else
+ print_device(device);
}
-static int test_device_parents(struct udev *udev, const char *syspath) {
+static void test_device_parents(struct udev *udev, const char *syspath) {
_cleanup_udev_device_unref_ struct udev_device *device;
struct udev_device *device_parent;
- printf("looking at device: %s\n", syspath);
+ log_info("looking at device: %s", syspath);
device = udev_device_new_from_syspath(udev, syspath);
if (device == NULL)
- return -1;
+ return;
- printf("looking at parents\n");
+ log_info("looking at parents");
device_parent = device;
do {
print_device(device_parent);
device_parent = udev_device_get_parent(device_parent);
} while (device_parent != NULL);
- printf("looking at parents again\n");
+ log_info("looking at parents again");
device_parent = device;
do {
print_device(device_parent);
device_parent = udev_device_get_parent(device_parent);
} while (device_parent != NULL);
-
- return 0;
}
-static int test_device_devnum(struct udev *udev) {
+static void test_device_devnum(struct udev *udev) {
dev_t devnum = makedev(1, 3);
- struct udev_device *device;
+ _cleanup_udev_device_unref_ struct udev_device *device;
- printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
+ log_info("looking up device: %u:%u", major(devnum), minor(devnum));
device = udev_device_new_from_devnum(udev, 'c', devnum);
if (device == NULL)
- return -1;
- print_device(device);
- udev_device_unref(device);
- return 0;
+ log_warning_errno(errno, "udev_device_new_from_devnum: %m");
+ else
+ print_device(device);
}
-static int test_device_subsys_name(struct udev *udev) {
- struct udev_device *device;
-
- printf("looking up device: 'block':'sda'\n");
- device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
- if (device == NULL)
- return -1;
- print_device(device);
- udev_device_unref(device);
-
- printf("looking up device: 'subsystem':'pci'\n");
- device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
- if (device == NULL)
- return -1;
- print_device(device);
- udev_device_unref(device);
-
- printf("looking up device: 'drivers':'scsi:sd'\n");
- device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
- if (device == NULL)
- return -1;
- print_device(device);
- udev_device_unref(device);
+static void test_device_subsys_name(struct udev *udev, const char *subsys, const char *dev) {
+ _cleanup_udev_device_unref_ struct udev_device *device;
- printf("looking up device: 'module':'printk'\n");
- device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
+ log_info("looking up device: '%s:%s'", subsys, dev);
+ device = udev_device_new_from_subsystem_sysname(udev, subsys, dev);
if (device == NULL)
- return -1;
- print_device(device);
- udev_device_unref(device);
- return 0;
+ log_warning_errno(errno, "udev_device_new_from_subsystem_sysname: %m");
+ else
+ print_device(device);
}
static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
@@ -200,63 +170,45 @@ static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
udev_list_entry_get_name(list_entry));
if (device != NULL) {
- printf("device: '%s' (%s)\n",
- udev_device_get_syspath(device),
- udev_device_get_subsystem(device));
+ log_info("device: '%s' (%s)",
+ udev_device_get_syspath(device),
+ udev_device_get_subsystem(device));
udev_device_unref(device);
count++;
}
}
- printf("found %i devices\n\n", count);
+ log_info("found %i devices", count);
return count;
}
-static int test_monitor(struct udev *udev) {
- struct udev_monitor *udev_monitor = NULL;
- int fd_ep;
- int fd_udev = -1;
- struct epoll_event ep_udev, ep_stdin;
+static void test_monitor(struct udev *udev) {
+ _cleanup_udev_monitor_unref_ struct udev_monitor *udev_monitor;
+ _cleanup_close_ int fd_ep;
+ int fd_udev;
+ struct epoll_event ep_udev = {
+ .events = EPOLLIN,
+ }, ep_stdin = {
+ .events = EPOLLIN,
+ .data.fd = STDIN_FILENO,
+ };
fd_ep = epoll_create1(EPOLL_CLOEXEC);
- if (fd_ep < 0) {
- printf("error creating epoll fd: %m\n");
- goto out;
- }
+ assert_se(fd_ep >= 0);
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
- if (udev_monitor == NULL) {
- printf("no socket\n");
- goto out;
- }
+ assert_se(udev_monitor != NULL);
+
fd_udev = udev_monitor_get_fd(udev_monitor);
+ ep_udev.data.fd = fd_udev;
- if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
- udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
- udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
- printf("filter failed\n");
- goto out;
- }
+ assert_se(udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) >= 0);
+ assert_se(udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) >= 0);
+ assert_se(udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") >= 0);
- if (udev_monitor_enable_receiving(udev_monitor) < 0) {
- printf("bind failed\n");
- goto out;
- }
+ assert_se(udev_monitor_enable_receiving(udev_monitor) >= 0);
- memzero(&ep_udev, sizeof(struct epoll_event));
- ep_udev.events = EPOLLIN;
- ep_udev.data.fd = fd_udev;
- if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
- printf("fail to add fd to epoll: %m\n");
- goto out;
- }
-
- memzero(&ep_stdin, sizeof(struct epoll_event));
- ep_stdin.events = EPOLLIN;
- ep_stdin.data.fd = STDIN_FILENO;
- if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
- printf("fail to add fd to epoll: %m\n");
- goto out;
- }
+ assert_se(epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) >= 0);
+ assert_se(epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) >= 0);
for (;;) {
int fdcount;
@@ -265,7 +217,7 @@ static int test_monitor(struct udev *udev) {
int i;
printf("waiting for events from udev, press ENTER to exit\n");
- fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
+ fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
printf("epoll fd count: %i\n", fdcount);
for (i = 0; i < fdcount; i++) {
@@ -279,36 +231,29 @@ static int test_monitor(struct udev *udev) {
udev_device_unref(device);
} else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
printf("exiting loop\n");
- goto out;
+ return;
}
}
}
-out:
- if (fd_ep >= 0)
- close(fd_ep);
- udev_monitor_unref(udev_monitor);
- return 0;
}
-static int test_queue(struct udev *udev) {
+static void test_queue(struct udev *udev) {
struct udev_queue *udev_queue;
+ bool empty;
udev_queue = udev_queue_new(udev);
- if (udev_queue == NULL)
- return -1;
-
- if (udev_queue_get_queue_is_empty(udev_queue))
- printf("queue is empty\n");
+ assert_se(udev_queue);
+ empty = udev_queue_get_queue_is_empty(udev_queue);
+ log_info("queue is %s", empty ? "empty" : "not empty");
udev_queue_unref(udev_queue);
- return 0;
}
static int test_enumerate(struct udev *udev, const char *subsystem) {
struct udev_enumerate *udev_enumerate;
int r;
- printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
+ log_info("enumerate '%s'", subsystem == NULL ? "<all>" : subsystem);
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -317,7 +262,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) {
test_enumerate_print_list(udev_enumerate);
udev_enumerate_unref(udev_enumerate);
- printf("enumerate 'net' + duplicated scan + null + zero\n");
+ log_info("enumerate 'net' + duplicated scan + null + zero");
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -337,7 +282,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) {
test_enumerate_print_list(udev_enumerate);
udev_enumerate_unref(udev_enumerate);
- printf("enumerate 'block'\n");
+ log_info("enumerate 'block'");
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -351,7 +296,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) {
test_enumerate_print_list(udev_enumerate);
udev_enumerate_unref(udev_enumerate);
- printf("enumerate 'not block'\n");
+ log_info("enumerate 'not block'");
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -360,7 +305,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) {
test_enumerate_print_list(udev_enumerate);
udev_enumerate_unref(udev_enumerate);
- printf("enumerate 'pci, mem, vc'\n");
+ log_info("enumerate 'pci, mem, vc'");
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -371,7 +316,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) {
test_enumerate_print_list(udev_enumerate);
udev_enumerate_unref(udev_enumerate);
- printf("enumerate 'subsystem'\n");
+ log_info("enumerate 'subsystem'");
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -379,7 +324,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) {
test_enumerate_print_list(udev_enumerate);
udev_enumerate_unref(udev_enumerate);
- printf("enumerate 'property IF_FS_*=filesystem'\n");
+ log_info("enumerate 'property IF_FS_*=filesystem'");
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
return -1;
@@ -397,32 +342,32 @@ static void test_hwdb(struct udev *udev, const char *modalias) {
hwdb = udev_hwdb_new(udev);
udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
- printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
- printf("\n");
+ log_info("'%s'='%s'", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
hwdb = udev_hwdb_unref(hwdb);
assert_se(hwdb == NULL);
}
int main(int argc, char *argv[]) {
- struct udev *udev = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ bool arg_monitor = false;
static const struct option options[] = {
- { "syspath", required_argument, NULL, 'p' },
+ { "syspath", required_argument, NULL, 'p' },
{ "subsystem", required_argument, NULL, 's' },
- { "debug", no_argument, NULL, 'd' },
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'V' },
+ { "debug", no_argument, NULL, 'd' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "monitor", no_argument, NULL, 'm' },
{}
};
const char *syspath = "/devices/virtual/mem/null";
const char *subsystem = NULL;
- char path[1024];
int c;
udev = udev_new();
- printf("context: %p\n", udev);
+ log_info("context: %p", udev);
if (udev == NULL) {
- printf("no context\n");
+ log_info("no context");
return 1;
}
@@ -444,14 +389,18 @@ int main(int argc, char *argv[]) {
case 'h':
printf("--debug --syspath= --subsystem= --help\n");
- goto out;
+ return EXIT_SUCCESS;
case 'V':
printf("%s\n", VERSION);
- goto out;
+ return EXIT_SUCCESS;
+
+ case 'm':
+ arg_monitor = true;
+ break;
case '?':
- goto out;
+ return EXIT_FAILURE;
default:
assert_not_reached("Unhandled option code.");
@@ -459,14 +408,16 @@ int main(int argc, char *argv[]) {
/* add sys path if needed */
- if (!startswith(syspath, "/sys")) {
- xsprintf(path, "/sys/%s", syspath);
- syspath = path;
- }
+ if (!startswith(syspath, "/sys"))
+ syspath = strjoina("/sys/", syspath);
test_device(udev, syspath);
test_device_devnum(udev);
- test_device_subsys_name(udev);
+ test_device_subsys_name(udev, "block", "sda");
+ test_device_subsys_name(udev, "subsystem", "pci");
+ test_device_subsys_name(udev, "drivers", "scsi:sd");
+ test_device_subsys_name(udev, "module", "printk");
+
test_device_parents(udev, syspath);
test_enumerate(udev, subsystem);
@@ -475,8 +426,8 @@ int main(int argc, char *argv[]) {
test_hwdb(udev, "usb:v0D50p0011*");
- test_monitor(udev);
-out:
- udev_unref(udev);
- return 0;
+ if (arg_monitor)
+ test_monitor(udev);
+
+ return EXIT_SUCCESS;
}
diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c
index 2748395ade..7b67337331 100644
--- a/src/test/test-loopback.c
+++ b/src/test/test-loopback.c
@@ -31,7 +31,7 @@ int main(int argc, char* argv[]) {
r = loopback_setup();
if (r < 0)
- fprintf(stderr, "loopback: %s\n", strerror(-r));
+ log_error("loopback: %m");
- return 0;
+ return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c
index 0b2f9e9173..ff9f35cecd 100644
--- a/src/test/test-namespace.c
+++ b/src/test/test-namespace.c
@@ -69,8 +69,10 @@ static void test_netns(void) {
int r, n = 0;
siginfo_t si;
- if (geteuid() > 0)
- return;
+ if (geteuid() > 0) {
+ log_info("Skipping test: not root");
+ exit(EXIT_TEST_SKIP);
+ }
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, s) >= 0);
@@ -124,6 +126,9 @@ int main(int argc, char *argv[]) {
char boot_id[SD_ID128_STRING_MAX];
_cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;
+ log_parse_environment();
+ log_open();
+
assert_se(sd_id128_get_boot(&bid) >= 0);
sd_id128_to_string(bid, boot_id);
diff --git a/src/test/test-netlink-manual.c b/src/test/test-netlink-manual.c
index fe15a56aba..57e244eb79 100644
--- a/src/test/test-netlink-manual.c
+++ b/src/test/test-netlink-manual.c
@@ -68,10 +68,10 @@ static int test_tunnel_configure(sd_netlink *rtnl) {
/* skip test if module cannot be loaded */
r = load_module("ipip");
- if(r < 0)
+ if (r < 0)
return EXIT_TEST_SKIP;
- if(getuid() != 0)
+ if (getuid() != 0)
return EXIT_TEST_SKIP;
/* IPIP tunnel */
@@ -99,7 +99,7 @@ static int test_tunnel_configure(sd_netlink *rtnl) {
assert_se((m = sd_netlink_message_unref(m)) == NULL);
r = load_module("sit");
- if(r < 0)
+ if (r < 0)
return EXIT_TEST_SKIP;
/* sit */
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
index cf627be6c5..9248f2987c 100644
--- a/src/test/test-ns.c
+++ b/src/test/test-ns.c
@@ -68,7 +68,6 @@ int main(int argc, char *argv[]) {
(char **) inaccessible,
tmp_dir,
var_tmp_dir,
- NULL,
true,
PROTECT_HOME_NO,
PROTECT_SYSTEM_NO,
diff --git a/src/test/test-nss.c b/src/test/test-nss.c
new file mode 100644
index 0000000000..55af592287
--- /dev/null
+++ b/src/test/test-nss.c
@@ -0,0 +1,454 @@
+/***
+ 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 <net/if.h>
+
+#include "log.h"
+#include "nss-util.h"
+#include "path-util.h"
+#include "string-util.h"
+#include "alloc-util.h"
+#include "in-addr-util.h"
+#include "hexdecoct.h"
+#include "af-list.h"
+#include "stdio-util.h"
+#include "strv.h"
+#include "errno-list.h"
+#include "hostname-util.h"
+#include "local-addresses.h"
+
+static const char* nss_status_to_string(enum nss_status status, char *buf, size_t buf_len) {
+ switch (status) {
+ case NSS_STATUS_TRYAGAIN:
+ return "NSS_STATUS_TRYAGAIN";
+ case NSS_STATUS_UNAVAIL:
+ return "NSS_STATUS_UNAVAIL";
+ case NSS_STATUS_NOTFOUND:
+ return "NSS_STATUS_NOTFOUND";
+ case NSS_STATUS_SUCCESS:
+ return "NSS_STATUS_SUCCESS";
+ case NSS_STATUS_RETURN:
+ return "NSS_STATUS_RETURN";
+ default:
+ snprintf(buf, buf_len, "%i", status);
+ return buf;
+ }
+};
+
+static const char* af_to_string(int family, char *buf, size_t buf_len) {
+ const char *name;
+
+ if (family == AF_UNSPEC)
+ return "*";
+
+ name = af_to_name(family);
+ if (name)
+ return name;
+
+ snprintf(buf, buf_len, "%i", family);
+ return buf;
+}
+
+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
+ path = strjoina("libnss_", module, ".so.2");
+
+ handle = dlopen(path, flags);
+ assert_se(handle);
+ return handle;
+}
+
+static int print_gaih_addrtuples(const struct gaih_addrtuple *tuples) {
+ const struct gaih_addrtuple *it;
+ int n = 0;
+
+ for (it = tuples; it; it = it->next) {
+ _cleanup_free_ char *a = NULL;
+ union in_addr_union u;
+ int r;
+ char family_name[DECIMAL_STR_MAX(int)];
+ char ifname[IF_NAMESIZE];
+
+ memcpy(&u, it->addr, 16);
+ r = in_addr_to_string(it->family, &u, &a);
+ assert_se(r == 0 || r == -EAFNOSUPPORT);
+ if (r == -EAFNOSUPPORT)
+ assert_se((a = hexmem(it->addr, 16)));
+
+ if (it->scopeid == 0)
+ goto numerical_index;
+
+ if (if_indextoname(it->scopeid, ifname) == NULL) {
+ log_warning("if_indextoname(%d) failed: %m", it->scopeid);
+ numerical_index:
+ xsprintf(ifname, "%i", it->scopeid);
+ };
+
+ log_info(" \"%s\" %s %s %%%s",
+ it->name,
+ af_to_string(it->family, family_name, sizeof family_name),
+ a,
+ ifname);
+ n ++;
+ }
+ return n;
+}
+
+static void print_struct_hostent(struct hostent *host, const char *canon) {
+ char **s;
+
+ log_info(" \"%s\"", host->h_name);
+ STRV_FOREACH(s, host->h_aliases)
+ log_info(" alias \"%s\"", *s);
+ STRV_FOREACH(s, host->h_addr_list) {
+ union in_addr_union u;
+ _cleanup_free_ char *a = NULL;
+ char family_name[DECIMAL_STR_MAX(int)];
+ int r;
+
+ assert_se((unsigned) host->h_length == FAMILY_ADDRESS_SIZE(host->h_addrtype));
+ memcpy(&u, *s, host->h_length);
+ r = in_addr_to_string(host->h_addrtype, &u, &a);
+ assert_se(r == 0);
+ log_info(" %s %s",
+ af_to_string(host->h_addrtype, family_name, sizeof family_name),
+ a);
+ }
+ if (canon)
+ log_info(" canonical: \"%s\"", canon);
+}
+
+static void test_gethostbyname4_r(void *handle, const char *module, const char *name) {
+ const char *fname;
+ _nss_gethostbyname4_r_t f;
+ char buffer[2000];
+ struct gaih_addrtuple *pat = NULL;
+ int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
+ int32_t ttl = INT32_MAX; /* nss-dns wants to return the lowest ttl,
+ and will access this variable through *ttlp,
+ so we need to set it to something.
+ I'm not sure if this is a bug in nss-dns
+ or not. */
+ enum nss_status status;
+ char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+ int n;
+
+ fname = strjoina("_nss_", module, "_gethostbyname4_r");
+ f = dlsym(handle, fname);
+ log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+ assert_se(f);
+
+ status = f(name, &pat, buffer, sizeof buffer, &errno1, &errno2, &ttl);
+ if (status == NSS_STATUS_SUCCESS) {
+ log_info("%s(\"%s\") → status=%s%-20spat=buffer+0x%tx errno=%d/%s h_errno=%d/%s ttl=%"PRIi32,
+ fname, name,
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ pat ? (char*) pat - buffer : 0,
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2),
+ ttl);
+ n = print_gaih_addrtuples(pat);
+ } else {
+ log_info("%s(\"%s\") → status=%s%-20spat=0x%p errno=%d/%s h_errno=%d/%s",
+ fname, name,
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ pat,
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2));
+ n = 0;
+ }
+
+ if (STR_IN_SET(module, "resolve", "mymachines") && status == NSS_STATUS_UNAVAIL)
+ return;
+
+ if (STR_IN_SET(module, "myhostname", "resolve") && streq(name, "localhost")) {
+ assert_se(status == NSS_STATUS_SUCCESS);
+ assert_se(n == 2);
+ }
+}
+
+
+static void test_gethostbyname3_r(void *handle, const char *module, const char *name, int af) {
+ const char *fname;
+ _nss_gethostbyname3_r_t f;
+ char buffer[2000];
+ int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
+ int32_t ttl = INT32_MAX; /* nss-dns wants to return the lowest ttl,
+ and will access this variable through *ttlp,
+ so we need to set it to something.
+ I'm not sure if this is a bug in nss-dns
+ or not. */
+ enum nss_status status;
+ char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+ struct hostent host;
+ char *canon;
+ char family_name[DECIMAL_STR_MAX(int)];
+
+ fname = strjoina("_nss_", module, "_gethostbyname3_r");
+ f = dlsym(handle, fname);
+ log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+ assert_se(f);
+
+ status = f(name, af, &host, buffer, sizeof buffer, &errno1, &errno2, &ttl, &canon);
+ log_info("%s(\"%s\", %s) → status=%s%-20serrno=%d/%s h_errno=%d/%s ttl=%"PRIi32,
+ fname, name, af_to_string(af, family_name, sizeof family_name),
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2),
+ ttl);
+ if (status == NSS_STATUS_SUCCESS)
+ print_struct_hostent(&host, canon);
+}
+
+static void test_gethostbyname2_r(void *handle, const char *module, const char *name, int af) {
+ const char *fname;
+ _nss_gethostbyname2_r_t f;
+ char buffer[2000];
+ int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
+ enum nss_status status;
+ char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+ struct hostent host;
+ char family_name[DECIMAL_STR_MAX(int)];
+
+ fname = strjoina("_nss_", module, "_gethostbyname2_r");
+ f = dlsym(handle, fname);
+ log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+ assert_se(f);
+
+ status = f(name, af, &host, buffer, sizeof buffer, &errno1, &errno2);
+ log_info("%s(\"%s\", %s) → status=%s%-20serrno=%d/%s h_errno=%d/%s",
+ fname, name, af_to_string(af, family_name, sizeof family_name),
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2));
+ if (status == NSS_STATUS_SUCCESS)
+ print_struct_hostent(&host, NULL);
+}
+
+static void test_gethostbyname_r(void *handle, const char *module, const char *name) {
+ const char *fname;
+ _nss_gethostbyname_r_t f;
+ char buffer[2000];
+ int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
+ enum nss_status status;
+ char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+ struct hostent host;
+
+ fname = strjoina("_nss_", module, "_gethostbyname_r");
+ f = dlsym(handle, fname);
+ log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+ assert_se(f);
+
+ status = f(name, &host, buffer, sizeof buffer, &errno1, &errno2);
+ log_info("%s(\"%s\") → status=%s%-20serrno=%d/%s h_errno=%d/%s",
+ fname, name,
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2));
+ if (status == NSS_STATUS_SUCCESS)
+ print_struct_hostent(&host, NULL);
+}
+
+static void test_gethostbyaddr2_r(void *handle,
+ const char *module,
+ const void* addr, socklen_t len,
+ int af) {
+
+ const char *fname;
+ _nss_gethostbyaddr2_r_t f;
+ char buffer[2000];
+ int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
+ enum nss_status status;
+ char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+ struct hostent host;
+ int32_t ttl = INT32_MAX;
+ _cleanup_free_ char *addr_pretty = NULL;
+
+ fname = strjoina("_nss_", module, "_gethostbyaddr2_r");
+ f = dlsym(handle, fname);
+
+ log_full_errno(f ? LOG_DEBUG : LOG_INFO, errno,
+ "dlsym(0x%p, %s) → 0x%p: %m", handle, fname, f);
+ if (!f)
+ return;
+
+ assert_se(in_addr_to_string(af, addr, &addr_pretty) >= 0);
+
+ status = f(addr, len, af, &host, buffer, sizeof buffer, &errno1, &errno2, &ttl);
+ log_info("%s(\"%s\") → status=%s%-20serrno=%d/%s h_errno=%d/%s ttl=%"PRIi32,
+ fname, addr_pretty,
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2),
+ ttl);
+ if (status == NSS_STATUS_SUCCESS)
+ print_struct_hostent(&host, NULL);
+}
+
+static void test_gethostbyaddr_r(void *handle,
+ const char *module,
+ const void* addr, socklen_t len,
+ int af) {
+
+ const char *fname;
+ _nss_gethostbyaddr_r_t f;
+ char buffer[2000];
+ int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
+ enum nss_status status;
+ char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+ struct hostent host;
+ _cleanup_free_ char *addr_pretty = NULL;
+
+ fname = strjoina("_nss_", module, "_gethostbyaddr_r");
+ f = dlsym(handle, fname);
+
+ log_full_errno(f ? LOG_DEBUG : LOG_INFO, errno,
+ "dlsym(0x%p, %s) → 0x%p: %m", handle, fname, f);
+ if (!f)
+ return;
+
+ assert_se(in_addr_to_string(af, addr, &addr_pretty) >= 0);
+
+ status = f(addr, len, af, &host, buffer, sizeof buffer, &errno1, &errno2);
+ log_info("%s(\"%s\") → status=%s%-20serrno=%d/%s h_errno=%d/%s",
+ fname, addr_pretty,
+ nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+ errno1, errno_to_name(errno1) ?: "---",
+ errno2, hstrerror(errno2));
+ if (status == NSS_STATUS_SUCCESS)
+ print_struct_hostent(&host, NULL);
+}
+
+static void test_byname(void *handle, const char *module, const char *name) {
+ test_gethostbyname4_r(handle, module, name);
+ puts("");
+
+ test_gethostbyname3_r(handle, module, name, AF_INET);
+ puts("");
+ test_gethostbyname3_r(handle, module, name, AF_INET6);
+ puts("");
+ test_gethostbyname3_r(handle, module, name, AF_UNSPEC);
+ puts("");
+ test_gethostbyname3_r(handle, module, name, AF_LOCAL);
+ puts("");
+
+ test_gethostbyname2_r(handle, module, name, AF_INET);
+ puts("");
+ test_gethostbyname2_r(handle, module, name, AF_INET6);
+ puts("");
+ test_gethostbyname2_r(handle, module, name, AF_UNSPEC);
+ puts("");
+ test_gethostbyname2_r(handle, module, name, AF_LOCAL);
+ puts("");
+
+ test_gethostbyname_r(handle, module, name);
+ puts("");
+}
+
+static void test_byaddr(void *handle,
+ const char *module,
+ const void* addr, socklen_t len,
+ int af) {
+ test_gethostbyaddr2_r(handle, module, addr, len, af);
+ puts("");
+
+ test_gethostbyaddr_r(handle, module, addr, len, af);
+ puts("");
+}
+
+#ifdef HAVE_MYHOSTNAME
+# define MODULE1 "myhostname\0"
+#else
+# define MODULE1
+#endif
+#ifdef HAVE_RESOLVED
+# define MODULE2 "resolve\0"
+#else
+# define MODULE2
+#endif
+#ifdef HAVE_MACHINED
+# define MODULE3 "mymachines\0"
+#else
+# define MODULE3
+#endif
+#define MODULE4 "dns\0"
+
+int main(int argc, char **argv) {
+ _cleanup_free_ char *dir = NULL, *hostname = NULL;
+ const char *module;
+
+ const uint32_t local_address_ipv4 = htonl(0x7F000001);
+ const uint32_t local_address_ipv4_2 = htonl(0x7F000002);
+ _cleanup_free_ struct local_address *addresses = NULL;
+ int n_addresses;
+
+ log_set_max_level(LOG_INFO);
+ log_parse_environment();
+
+ dir = dirname_malloc(argv[0]);
+ assert_se(dir);
+
+ hostname = gethostname_malloc();
+ assert_se(hostname);
+
+ n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
+ if (n_addresses < 0) {
+ log_info_errno(n_addresses, "Failed to query local addresses: %m");
+ n_addresses = 0;
+ }
+
+ NULSTR_FOREACH(module, MODULE1 MODULE2 MODULE3 MODULE4) {
+ void *handle;
+ const char *name;
+ int i;
+
+ log_info("======== %s ========", module);
+
+ handle = open_handle(streq(module, "dns") ? NULL : dir,
+ module,
+ RTLD_LAZY|RTLD_NODELETE);
+ NULSTR_FOREACH(name, "localhost\0" "gateway\0" "foo_no_such_host\0")
+ test_byname(handle, module, name);
+
+ test_byname(handle, module, hostname);
+
+ test_byaddr(handle, module, &local_address_ipv4, sizeof local_address_ipv4, AF_INET);
+ test_byaddr(handle, module, &local_address_ipv4_2, sizeof local_address_ipv4_2, AF_INET);
+ test_byaddr(handle, module, &in6addr_loopback, sizeof in6addr_loopback, AF_INET6);
+
+ for (i = 0; i < n_addresses; i++)
+ test_byaddr(handle, module,
+ &addresses[i].address,
+ FAMILY_ADDRESS_SIZE(addresses[i].family),
+ addresses[i].family);
+
+ dlclose(handle);
+
+ log_info(" ");
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/test/test-path-lookup.c b/src/test/test-path-lookup.c
index 268da002a9..096326d176 100644
--- a/src/test/test-path-lookup.c
+++ b/src/test/test-path-lookup.c
@@ -26,41 +26,38 @@
#include "string-util.h"
#include "strv.h"
-static void test_paths(ManagerRunningAs running_as, bool personal) {
+static void test_paths(UnitFileScope scope) {
char template[] = "/tmp/test-path-lookup.XXXXXXX";
_cleanup_lookup_paths_free_ LookupPaths lp_without_env = {};
_cleanup_lookup_paths_free_ LookupPaths lp_with_env = {};
- char *exists, *not, *systemd_unit_path;
+ char *systemd_unit_path;
assert_se(mkdtemp(template));
- exists = strjoina(template, "/exists");
- assert_se(mkdir(exists, 0755) == 0);
- not = strjoina(template, "/not");
assert_se(unsetenv("SYSTEMD_UNIT_PATH") == 0);
- assert_se(lookup_paths_init(&lp_without_env, running_as, personal, NULL, exists, not, not) == 0);
-
- assert_se(!strv_isempty(lp_without_env.unit_path));
- assert_se(strv_contains(lp_without_env.unit_path, exists));
- assert_se(strv_contains(lp_without_env.unit_path, not));
+ assert_se(lookup_paths_init(&lp_without_env, scope, 0, NULL) >= 0);
+ assert_se(!strv_isempty(lp_without_env.search_path));
+ assert_se(lookup_paths_reduce(&lp_without_env) >= 0);
systemd_unit_path = strjoina(template, "/systemd-unit-path");
assert_se(setenv("SYSTEMD_UNIT_PATH", systemd_unit_path, 1) == 0);
- assert_se(lookup_paths_init(&lp_with_env, running_as, personal, NULL, exists, not, not) == 0);
- assert_se(strv_length(lp_with_env.unit_path) == 1);
- assert_se(streq(lp_with_env.unit_path[0], systemd_unit_path));
+ assert_se(lookup_paths_init(&lp_with_env, scope, 0, NULL) == 0);
+ assert_se(strv_length(lp_with_env.search_path) == 1);
+ assert_se(streq(lp_with_env.search_path[0], systemd_unit_path));
+ assert_se(lookup_paths_reduce(&lp_with_env) >= 0);
+ assert_se(strv_length(lp_with_env.search_path) == 0);
assert_se(rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}
-static void print_generator_paths(ManagerRunningAs running_as) {
+static void print_generator_binary_paths(UnitFileScope scope) {
_cleanup_strv_free_ char **paths;
char **dir;
- log_info("Generators dirs (%s):", running_as == MANAGER_SYSTEM ? "system" : "user");
+ log_info("Generators dirs (%s):", scope == UNIT_FILE_SYSTEM ? "system" : "user");
- paths = generator_paths(running_as);
+ paths = generator_binary_paths(scope);
STRV_FOREACH(dir, paths)
log_info(" %s", *dir);
}
@@ -70,13 +67,12 @@ int main(int argc, char **argv) {
log_parse_environment();
log_open();
- test_paths(MANAGER_SYSTEM, false);
- test_paths(MANAGER_SYSTEM, true);
- test_paths(MANAGER_USER, false);
- test_paths(MANAGER_USER, true);
+ test_paths(UNIT_FILE_SYSTEM);
+ test_paths(UNIT_FILE_USER);
+ test_paths(UNIT_FILE_GLOBAL);
- print_generator_paths(MANAGER_SYSTEM);
- print_generator_paths(MANAGER_USER);
+ print_generator_binary_paths(UNIT_FILE_SYSTEM);
+ print_generator_binary_paths(UNIT_FILE_USER);
return EXIT_SUCCESS;
}
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index 53a585290a..b53324b5e6 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -90,6 +90,18 @@ static void test_path(void) {
assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
assert_se(path_equal(path_kill_slashes(p3), "/./"));
}
+
+ assert_se(PATH_IN_SET("/bin", "/", "/bin", "/foo"));
+ assert_se(PATH_IN_SET("/bin", "/bin"));
+ assert_se(PATH_IN_SET("/bin", "/foo/bar", "/bin"));
+ assert_se(PATH_IN_SET("/", "/", "/", "/foo/bar"));
+ assert_se(!PATH_IN_SET("/", "/abc", "/def"));
+
+ assert_se(path_equal_ptr(NULL, NULL));
+ assert_se(path_equal_ptr("/a", "/a"));
+ assert_se(!path_equal_ptr("/a", "/b"));
+ assert_se(!path_equal_ptr("/a", NULL));
+ assert_se(!path_equal_ptr(NULL, "/a"));
}
static void test_find_binary(const char *self) {
@@ -433,6 +445,71 @@ static void test_path_is_mount_point(void) {
assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
}
+static void test_file_in_same_dir(void) {
+ char *t;
+
+ t = file_in_same_dir("/", "a");
+ assert_se(streq(t, "/a"));
+ free(t);
+
+ t = file_in_same_dir("/", "/a");
+ assert_se(streq(t, "/a"));
+ free(t);
+
+ t = file_in_same_dir("", "a");
+ assert_se(streq(t, "a"));
+ free(t);
+
+ t = file_in_same_dir("a/", "a");
+ assert_se(streq(t, "a/a"));
+ free(t);
+
+ t = file_in_same_dir("bar/foo", "bar");
+ assert_se(streq(t, "bar/bar"));
+ free(t);
+}
+
+static void test_filename_is_valid(void) {
+ char foo[FILENAME_MAX+2];
+ int i;
+
+ assert_se(!filename_is_valid(""));
+ assert_se(!filename_is_valid("/bar/foo"));
+ assert_se(!filename_is_valid("/"));
+ assert_se(!filename_is_valid("."));
+ assert_se(!filename_is_valid(".."));
+
+ for (i=0; i<FILENAME_MAX+1; i++)
+ foo[i] = 'a';
+ foo[FILENAME_MAX+1] = '\0';
+
+ assert_se(!filename_is_valid(foo));
+
+ assert_se(filename_is_valid("foo_bar-333"));
+ assert_se(filename_is_valid("o.o"));
+}
+
+static void test_hidden_or_backup_file(void) {
+ assert_se(hidden_or_backup_file(".hidden"));
+ assert_se(hidden_or_backup_file("..hidden"));
+ assert_se(!hidden_or_backup_file("hidden."));
+
+ assert_se(hidden_or_backup_file("backup~"));
+ assert_se(hidden_or_backup_file(".backup~"));
+
+ assert_se(hidden_or_backup_file("lost+found"));
+ assert_se(hidden_or_backup_file("aquota.user"));
+ assert_se(hidden_or_backup_file("aquota.group"));
+
+ assert_se(hidden_or_backup_file("test.rpmnew"));
+ assert_se(hidden_or_backup_file("test.dpkg-old"));
+ assert_se(hidden_or_backup_file("test.dpkg-remove"));
+ assert_se(hidden_or_backup_file("test.swp"));
+
+ assert_se(!hidden_or_backup_file("test.rpmnew."));
+ assert_se(!hidden_or_backup_file("test.dpkg-old.foo"));
+}
+
int main(int argc, char **argv) {
test_path();
test_find_binary(argv[0]);
@@ -444,6 +521,9 @@ int main(int argc, char **argv) {
test_path_startswith();
test_prefix_root();
test_path_is_mount_point();
+ test_file_in_same_dir();
+ test_filename_is_valid();
+ test_hidden_or_backup_file();
return 0;
}
diff --git a/src/test/test-path.c b/src/test/test-path.c
index 7a3b145414..62181e22a0 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -30,6 +30,7 @@
#include "string-util.h"
#include "strv.h"
#include "test-helper.h"
+#include "tests.h"
#include "unit.h"
#include "util.h"
@@ -44,7 +45,7 @@ static int setup_test(Manager **m) {
assert_se(m);
- r = manager_new(MANAGER_USER, true, &tmp);
+ r = manager_new(UNIT_FILE_USER, true, &tmp);
if (MANAGER_SKIP_TEST(r)) {
printf("Skipping test: manager_new: %s\n", strerror(-r));
return -EXIT_TEST_SKIP;
@@ -93,7 +94,7 @@ static void check_stop_unlink(Manager *m, Unit *unit, const char *test_path, con
ts = now(CLOCK_MONOTONIC);
/* We process events until the service related to the path has been successfully started */
- while(service->result != SERVICE_SUCCESS || service->state != SERVICE_START) {
+ while (service->result != SERVICE_SUCCESS || service->state != SERVICE_START) {
usec_t n;
int r;
@@ -243,7 +244,7 @@ static void test_path_makedirectory_directorymode(Manager *m) {
}
int main(int argc, char *argv[]) {
- test_function_t tests[] = {
+ static const test_function_t tests[] = {
test_path_exists,
test_path_existsglob,
test_path_changed,
@@ -253,12 +254,15 @@ int main(int argc, char *argv[]) {
test_path_makedirectory_directorymode,
NULL,
};
- test_function_t *test = NULL;
+
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
+ const test_function_t *test = NULL;
Manager *m = NULL;
log_parse_environment();
log_open();
+ assert_se(runtime_dir = setup_fake_runtime_dir());
assert_se(set_unit_path(TEST_DIR "/test-path/") >= 0);
for (test = tests; test && *test; test++) {
diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c
new file mode 100644
index 0000000000..a7a8f621a2
--- /dev/null
+++ b/src/test/test-proc-cmdline.c
@@ -0,0 +1,52 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "log.h"
+#include "macro.h"
+#include "proc-cmdline.h"
+#include "special.h"
+#include "string-util.h"
+
+static int parse_item(const char *key, const char *value) {
+ assert_se(key);
+
+ log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
+ return 0;
+}
+
+static void test_parse_proc_cmdline(void) {
+ assert_se(parse_proc_cmdline(parse_item) >= 0);
+}
+
+static void test_runlevel_to_target(void) {
+ assert_se(streq_ptr(runlevel_to_target(NULL), NULL));
+ assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL));
+ assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET));
+}
+
+int main(void) {
+ log_parse_environment();
+ log_open();
+
+ test_parse_proc_cmdline();
+ test_runlevel_to_target();
+
+ return 0;
+}
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 48be5a3a87..4616314200 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -18,12 +18,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/personality.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "alloc-util.h"
+#include "architecture.h"
#include "log.h"
#include "macro.h"
#include "process-util.h"
@@ -128,6 +130,29 @@ static void test_pid_is_alive(void) {
assert_se(!pid_is_alive(-1));
}
+static void test_personality(void) {
+
+ assert_se(personality_to_string(PER_LINUX));
+ assert_se(!personality_to_string(PERSONALITY_INVALID));
+
+ assert_se(streq(personality_to_string(PER_LINUX), architecture_to_string(native_architecture())));
+
+ assert_se(personality_from_string(personality_to_string(PER_LINUX)) == PER_LINUX);
+ assert_se(personality_from_string(architecture_to_string(native_architecture())) == PER_LINUX);
+
+#ifdef __x86_64__
+ assert_se(streq_ptr(personality_to_string(PER_LINUX), "x86-64"));
+ assert_se(streq_ptr(personality_to_string(PER_LINUX32), "x86"));
+
+ assert_se(personality_from_string("x86-64") == PER_LINUX);
+ assert_se(personality_from_string("x86") == PER_LINUX32);
+ assert_se(personality_from_string("ia64") == PERSONALITY_INVALID);
+ assert_se(personality_from_string(NULL) == PERSONALITY_INVALID);
+
+ assert_se(personality_from_string(personality_to_string(PER_LINUX32)) == PER_LINUX32);
+#endif
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -135,6 +160,7 @@ int main(int argc, char *argv[]) {
test_get_process_comm();
test_pid_is_unwaited();
test_pid_is_alive();
+ test_personality();
return 0;
}
diff --git a/src/test/test-rbtree.c b/src/test/test-rbtree.c
deleted file mode 100644
index 8ae416c557..0000000000
--- a/src/test/test-rbtree.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/***
- This file is part of systemd. See COPYING for details.
-
- 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/>.
-***/
-
-/*
- * Tests for RB-Tree
- */
-
-#undef NDEBUG
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include "c-rbtree.h"
-
-/* verify that all API calls are exported */
-static void test_api(void) {
- CRBTree t = {};
- CRBNode n = C_RBNODE_INIT(n);
-
- assert(!c_rbnode_is_linked(&n));
-
- /* init, is_linked, add, remove, remove_init */
-
- c_rbtree_add(&t, NULL, &t.root, &n);
- assert(c_rbnode_is_linked(&n));
-
- c_rbtree_remove_init(&t, &n);
- assert(!c_rbnode_is_linked(&n));
-
- c_rbtree_add(&t, NULL, &t.root, &n);
- assert(c_rbnode_is_linked(&n));
-
- c_rbtree_remove(&t, &n);
- assert(c_rbnode_is_linked(&n)); /* @n wasn't touched */
-
- c_rbnode_init(&n);
- assert(!c_rbnode_is_linked(&n));
-
- /* first, last, leftmost, rightmost, next, prev */
-
- assert(!c_rbtree_first(&t));
- assert(!c_rbtree_last(&t));
- assert(&n == c_rbnode_leftmost(&n));
- assert(&n == c_rbnode_rightmost(&n));
- assert(!c_rbnode_next(&n));
- assert(!c_rbnode_prev(&n));
-}
-
-/* copied from c-rbtree.c, relies on internal representation */
-static inline _Bool c_rbnode_is_red(CRBNode *n) {
- return !((unsigned long)n->__parent_and_color & 1UL);
-}
-
-/* copied from c-rbtree.c, relies on internal representation */
-static inline _Bool c_rbnode_is_black(CRBNode *n) {
- return !!((unsigned long)n->__parent_and_color & 1UL);
-}
-
-static size_t validate(CRBTree *t) {
- unsigned int i_black, n_black;
- CRBNode *n, *p, *o;
- size_t count = 0;
-
- assert(t);
- assert(!t->root || c_rbnode_is_black(t->root));
-
- /* traverse to left-most child, count black nodes */
- i_black = 0;
- n = t->root;
- while (n && n->left) {
- if (c_rbnode_is_black(n))
- ++i_black;
- n = n->left;
- }
- n_black = i_black;
-
- /*
- * Traverse tree and verify correctness:
- * 1) A node is either red or black
- * 2) The root is black
- * 3) All leaves are black
- * 4) Every red node must have two black child nodes
- * 5) Every path to a leaf contains the same number of black nodes
- *
- * Note that NULL nodes are considered black, which is why we don't
- * check for 3).
- */
- o = NULL;
- while (n) {
- ++count;
-
- /* verify natural order */
- assert(n > o);
- o = n;
-
- /* verify consistency */
- assert(!n->right || c_rbnode_parent(n->right) == n);
- assert(!n->left || c_rbnode_parent(n->left) == n);
-
- /* verify 2) */
- if (!c_rbnode_parent(n))
- assert(c_rbnode_is_black(n));
-
- if (c_rbnode_is_red(n)) {
- /* verify 4) */
- assert(!n->left || c_rbnode_is_black(n->left));
- assert(!n->right || c_rbnode_is_black(n->right));
- } else {
- /* verify 1) */
- assert(c_rbnode_is_black(n));
- }
-
- /* verify 5) */
- if (!n->left && !n->right)
- assert(i_black == n_black);
-
- /* get next node */
- if (n->right) {
- n = n->right;
- if (c_rbnode_is_black(n))
- ++i_black;
-
- while (n->left) {
- n = n->left;
- if (c_rbnode_is_black(n))
- ++i_black;
- }
- } else {
- while ((p = c_rbnode_parent(n)) && n == p->right) {
- n = p;
- if (c_rbnode_is_black(p->right))
- --i_black;
- }
-
- n = p;
- if (p && c_rbnode_is_black(p->left))
- --i_black;
- }
- }
-
- return count;
-}
-
-static void insert(CRBTree *t, CRBNode *n) {
- CRBNode **i, *p;
-
- assert(t);
- assert(n);
- assert(!c_rbnode_is_linked(n));
-
- i = &t->root;
- p = NULL;
- while (*i) {
- p = *i;
- if (n < *i) {
- i = &(*i)->left;
- } else {
- assert(n > *i);
- i = &(*i)->right;
- }
- }
-
- c_rbtree_add(t, p, i, n);
-}
-
-static void shuffle(void **nodes, size_t n_memb) {
- unsigned int i, j;
- void *t;
-
- for (i = 0; i < n_memb; ++i) {
- j = rand() % n_memb;
- t = nodes[j];
- nodes[j] = nodes[i];
- nodes[i] = t;
- }
-}
-
-/* run some pseudo-random tests on the tree */
-static void test_shuffle(void) {
- CRBNode *nodes[256];
- CRBTree t = {};
- unsigned int i, j;
- size_t n;
-
- /* allocate and initialize all nodes */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- nodes[i] = malloc(sizeof(*nodes[i]));
- assert(nodes[i]);
- c_rbnode_init(nodes[i]);
- }
-
- /* shuffle nodes and validate *empty* tree */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
- n = validate(&t);
- assert(n == 0);
-
- /* add all nodes and validate after each insertion */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- insert(&t, nodes[i]);
- n = validate(&t);
- assert(n == i + 1);
- }
-
- /* shuffle nodes again */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
-
- /* remove all nodes (in different order) and validate on each round */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- c_rbtree_remove(&t, nodes[i]);
- n = validate(&t);
- assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
- c_rbnode_init(nodes[i]);
- }
-
- /* shuffle nodes and validate *empty* tree again */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
- n = validate(&t);
- assert(n == 0);
-
- /* add all nodes again */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- insert(&t, nodes[i]);
- n = validate(&t);
- assert(n == i + 1);
- }
-
- /* 4 times, remove half of the nodes and add them again */
- for (j = 0; j < 4; ++j) {
- /* shuffle nodes again */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
-
- /* remove half of the nodes */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes) / 2; ++i) {
- c_rbtree_remove(&t, nodes[i]);
- n = validate(&t);
- assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
- c_rbnode_init(nodes[i]);
- }
-
- /* shuffle the removed half */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes) / 2);
-
- /* add the removed half again */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes) / 2; ++i) {
- insert(&t, nodes[i]);
- n = validate(&t);
- assert(n == sizeof(nodes) / sizeof(*nodes) / 2 + i + 1);
- }
- }
-
- /* shuffle nodes again */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
-
- /* remove all */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- c_rbtree_remove(&t, nodes[i]);
- n = validate(&t);
- assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
- c_rbnode_init(nodes[i]);
- }
-
- /* free nodes again */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i)
- free(nodes[i]);
-}
-
-typedef struct {
- unsigned long key;
- CRBNode rb;
-} Node;
-
-#define node_from_rb(_rb) ((Node *)((char *)(_rb) - offsetof(Node, rb)))
-
-static int compare(CRBTree *t, void *k, CRBNode *n) {
- unsigned long key = (unsigned long)k;
- Node *node = node_from_rb(n);
-
- return (key < node->key) ? -1 : (key > node->key) ? 1 : 0;
-}
-
-/* run tests against the c_rbtree_find*() helpers */
-static void test_map(void) {
- CRBNode **slot, *p;
- CRBTree t = {};
- Node *nodes[2048];
- unsigned long i;
-
- /* allocate and initialize all nodes */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- nodes[i] = malloc(sizeof(*nodes[i]));
- assert(nodes[i]);
- nodes[i]->key = i;
- c_rbnode_init(&nodes[i]->rb);
- }
-
- /* shuffle nodes */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
-
- /* add all nodes, and verify that each node is linked */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- assert(!c_rbnode_is_linked(&nodes[i]->rb));
- assert(!c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
-
- slot = c_rbtree_find_slot(&t, compare, (void *)nodes[i]->key, &p);
- assert(slot);
- c_rbtree_add(&t, p, slot, &nodes[i]->rb);
-
- assert(c_rbnode_is_linked(&nodes[i]->rb));
- assert(nodes[i] == c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
- }
-
- /* shuffle nodes again */
- shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
-
- /* remove all nodes (in different order) */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
- assert(c_rbnode_is_linked(&nodes[i]->rb));
- assert(nodes[i] == c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
-
- c_rbtree_remove_init(&t, &nodes[i]->rb);
-
- assert(!c_rbnode_is_linked(&nodes[i]->rb));
- assert(!c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
- }
-
- /* free nodes again */
- for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i)
- free(nodes[i]);
-}
-
-int main(int argc, char **argv) {
- unsigned int i;
-
- /* we want stable tests, so use fixed seed */
- srand(0xdeadbeef);
-
- test_api();
-
- /*
- * The tests are pseudo random; run them multiple times, each run will
- * have different orders and thus different results.
- */
- for (i = 0; i < 4; ++i) {
- test_shuffle();
- test_map();
- }
-
- return 0;
-}
diff --git a/src/test/test-rlimit-util.c b/src/test/test-rlimit-util.c
index d9ac9368cd..62afd2de5e 100644
--- a/src/test/test-rlimit-util.c
+++ b/src/test/test-rlimit-util.c
@@ -99,6 +99,18 @@ int main(int argc, char *argv[]) {
test_rlimit_parse_format(RLIMIT_NOFILE, "", 0, 0, -EINVAL, NULL);
test_rlimit_parse_format(RLIMIT_NOFILE, "5:4", 0, 0, -EILSEQ, NULL);
test_rlimit_parse_format(RLIMIT_NOFILE, "5:4:3", 0, 0, -EINVAL, NULL);
+ test_rlimit_parse_format(RLIMIT_NICE, "20", 20, 20, 0, "20");
+ test_rlimit_parse_format(RLIMIT_NICE, "40", 40, 40, 0, "40");
+ test_rlimit_parse_format(RLIMIT_NICE, "41", 41, 41, -ERANGE, "41");
+ test_rlimit_parse_format(RLIMIT_NICE, "0", 0, 0, 0, "0");
+ test_rlimit_parse_format(RLIMIT_NICE, "-7", 27, 27, 0, "27");
+ test_rlimit_parse_format(RLIMIT_NICE, "-20", 40, 40, 0, "40");
+ test_rlimit_parse_format(RLIMIT_NICE, "-21", 41, 41, -ERANGE, "41");
+ test_rlimit_parse_format(RLIMIT_NICE, "-0", 20, 20, 0, "20");
+ test_rlimit_parse_format(RLIMIT_NICE, "+7", 13, 13, 0, "13");
+ test_rlimit_parse_format(RLIMIT_NICE, "+19", 1, 1, 0, "1");
+ test_rlimit_parse_format(RLIMIT_NICE, "+20", 0, 0, -ERANGE, "0");
+ test_rlimit_parse_format(RLIMIT_NICE, "+0", 20, 20, 0, "20");
return 0;
}
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index 7f515b53d8..c068f5c39e 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -21,9 +21,12 @@
#include "macro.h"
#include "manager.h"
+#include "rm-rf.h"
#include "test-helper.h"
+#include "tests.h"
int main(int argc, char *argv[]) {
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
Manager *m = NULL;
Unit *idle_ok, *idle_bad, *rr_ok, *rr_bad, *rr_sched;
Service *ser;
@@ -31,9 +34,11 @@ int main(int argc, char *argv[]) {
FDSet *fdset = NULL;
int r;
+ assert_se(runtime_dir = setup_fake_runtime_dir());
+
/* prepare the test */
assert_se(set_unit_path(TEST_DIR) >= 0);
- r = manager_new(MANAGER_USER, true, &m);
+ r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
printf("Skipping test: manager_new: %s\n", strerror(-r));
return EXIT_TEST_SKIP;
diff --git a/src/test/test-selinux.c b/src/test/test-selinux.c
new file mode 100644
index 0000000000..7545ad3764
--- /dev/null
+++ b/src/test/test-selinux.c
@@ -0,0 +1,122 @@
+/***
+ 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 <sys/stat.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "log.h"
+#include "selinux-util.h"
+#include "string-util.h"
+#include "time-util.h"
+#include "util.h"
+
+static void test_testing(void) {
+ bool b;
+
+ log_info("============ %s ==========", __func__);
+
+ 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));
+
+ 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));
+}
+
+static void test_loading(void) {
+ usec_t n1, n2;
+ int r;
+
+ log_info("============ %s ==========", __func__);
+
+ n1 = now(CLOCK_MONOTONIC);
+ r = mac_selinux_init();
+ n2 = now(CLOCK_MONOTONIC);
+ log_info_errno(r, "mac_selinux_init → %d (%m) %.2fs", r, (n2 - n1)/1e6);
+}
+
+static void test_cleanup(void) {
+ usec_t n1, n2;
+
+ log_info("============ %s ==========", __func__);
+
+ n1 = now(CLOCK_MONOTONIC);
+ mac_selinux_finish();
+ n2 = now(CLOCK_MONOTONIC);
+ log_info("mac_selinux_finish → %.2fs", (n2 - n1)/1e6);
+}
+
+static void test_misc(const char* fname) {
+ _cleanup_(mac_selinux_freep) char *label = NULL, *label2 = NULL, *label3 = NULL;
+ int r;
+ _cleanup_close_ int fd = -1;
+
+ log_info("============ %s ==========", __func__);
+
+ r = mac_selinux_get_our_label(&label);
+ log_info_errno(r, "mac_selinux_get_our_label → %d (%m), \"%s\"",
+ r, strnull(label));
+
+ r = mac_selinux_get_create_label_from_exe(fname, &label2);
+ log_info_errno(r, "mac_selinux_create_label_from_exe → %d (%m), \"%s\"",
+ r, strnull(label2));
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+
+ r = mac_selinux_get_child_mls_label(fd, fname, label2, &label3);
+ log_info_errno(r, "mac_selinux_get_child_mls_label → %d (%m), \"%s\"",
+ r, strnull(label3));
+}
+
+static void test_create_file_prepare(const char* fname) {
+ int r;
+
+ log_info("============ %s ==========", __func__);
+
+ r = mac_selinux_create_file_prepare(fname, S_IRWXU);
+ log_info_errno(r, "mac_selinux_create_file_prepare → %d (%m)", r);
+
+ mac_selinux_create_file_clear();
+}
+
+int main(int argc, char **argv) {
+ const char *path = SYSTEMD_BINARY_PATH;
+ if (argc >= 2)
+ path = argv[1];
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
+ test_testing();
+ test_loading();
+ test_misc(path);
+ test_create_file_prepare(path);
+ test_cleanup();
+
+ return 0;
+}
diff --git a/src/test/test-signal-util.c b/src/test/test-signal-util.c
index 3083501ce9..671eb869cb 100644
--- a/src/test/test-signal-util.c
+++ b/src/test/test-signal-util.c
@@ -17,6 +17,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <signal.h>
+#include <unistd.h>
+
+#include "macro.h"
#include "signal-util.h"
static void test_block_signals(void) {
@@ -44,6 +48,20 @@ static void test_block_signals(void) {
assert_se(sigismember(&ss, SIGVTALRM) == 0);
}
+static void test_ignore_signals(void) {
+ assert_se(ignore_signals(SIGINT, -1) >= 0);
+ assert_se(kill(getpid(), 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(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
+}
+
int main(int argc, char *argv[]) {
test_block_signals();
+ test_ignore_signals();
+
+ return 0;
}
diff --git a/src/test/test-siphash24.c b/src/test/test-siphash24.c
index caae911f30..b74b7ad2dd 100644
--- a/src/test/test-siphash24.c
+++ b/src/test/test-siphash24.c
@@ -22,9 +22,9 @@
#define ITERATIONS 10000000ULL
-static int do_test(const uint8_t *in, size_t len, const uint8_t *key) {
+static void do_test(const uint8_t *in, size_t len, const uint8_t *key) {
struct siphash state = {};
- uint64_t out = 0;
+ uint64_t out;
unsigned i, j;
out = siphash24(in, len, key);
@@ -60,7 +60,46 @@ static int do_test(const uint8_t *in, size_t len, const uint8_t *key) {
assert_se(out == 0xa129ca6149be45e5);
}
}
- return 0;
+}
+
+static void test_short_hashes(void) {
+ const uint8_t one[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
+ const uint8_t key[16] = { 0x22, 0x24, 0x41, 0x22, 0x55, 0x77, 0x88, 0x07,
+ 0x23, 0x09, 0x23, 0x14, 0x0c, 0x33, 0x0e, 0x0f};
+ uint8_t two[sizeof one] = {};
+
+ struct siphash state1 = {}, state2 = {};
+ unsigned i, j;
+
+ siphash24_init(&state1, key);
+ siphash24_init(&state2, key);
+
+ /* hashing 1, 2, 3, 4, 5, ..., 16 bytes, with the byte after the buffer different */
+ for (i = 1; i <= sizeof one; i++) {
+ siphash24_compress(one, i, &state1);
+
+ two[i-1] = one[i-1];
+ siphash24_compress(two, i, &state2);
+
+ assert_se(memcmp(&state1, &state2, sizeof state1) == 0);
+ }
+
+ /* hashing n and 1, n and 2, n and 3, ..., n-1 and 1, n-2 and 2, ... */
+ for (i = sizeof one; i > 0; i--) {
+ zero(two);
+
+ for (j = 1; j <= sizeof one; j++) {
+ siphash24_compress(one, i, &state1);
+ siphash24_compress(one, j, &state1);
+
+ siphash24_compress(one, i, &state2);
+ two[j-1] = one[j-1];
+ siphash24_compress(two, j, &state2);
+
+ assert_se(memcmp(&state1, &state2, sizeof state1) == 0);
+ }
+ }
}
/* see https://131002.net/siphash/siphash.pdf, Appendix A */
@@ -80,4 +119,6 @@ int main(int argc, char *argv[]) {
do_test(in_buf + 2, sizeof(in), key);
memcpy(in_buf + 4, in, sizeof(in));
do_test(in_buf + 4, sizeof(in), key);
+
+ test_short_hashes();
}
diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c
new file mode 100644
index 0000000000..8f99a13772
--- /dev/null
+++ b/src/test/test-sizeof.c
@@ -0,0 +1,53 @@
+/***
+ 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 "log.h"
+#include "time-util.h"
+
+/* Print information about various types. Useful when diagnosing
+ * gcc diagnostics on an unfamiliar architecture. */
+
+#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"));
+
+int main(void) {
+ info(char);
+ info(signed char);
+ info(unsigned char);
+ info(short unsigned);
+ info(unsigned);
+ info(long unsigned);
+ info(long long unsigned);
+
+ info(float);
+ info(double);
+ info(long double);
+
+ info(size_t);
+ info(ssize_t);
+ info(time_t);
+ info(usec_t);
+
+ return 0;
+}
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 33ff3755bc..b480fdaa9c 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -27,6 +27,29 @@
#include "string-util.h"
#include "util.h"
+static void test_ifname_valid(void) {
+ assert(ifname_valid("foo"));
+ assert(ifname_valid("eth0"));
+
+ assert(!ifname_valid("0"));
+ assert(!ifname_valid("99"));
+ assert(ifname_valid("a99"));
+ assert(ifname_valid("99a"));
+
+ assert(!ifname_valid(NULL));
+ assert(!ifname_valid(""));
+ assert(!ifname_valid(" "));
+ assert(!ifname_valid(" foo"));
+ assert(!ifname_valid("bar\n"));
+ assert(!ifname_valid("."));
+ assert(!ifname_valid(".."));
+ assert(ifname_valid("foo.bar"));
+ assert(!ifname_valid("x:y"));
+
+ assert(ifname_valid("xxxxxxxxxxxxxxx"));
+ assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
+}
+
static void test_socket_address_parse(void) {
SocketAddress a;
@@ -343,10 +366,27 @@ static void test_sockaddr_equal(void) {
assert_se(!sockaddr_equal(&b, &c));
}
+static void test_sockaddr_un_len(void) {
+ static const struct sockaddr_un fs = {
+ .sun_family = AF_UNIX,
+ .sun_path = "/foo/bar/waldo",
+ };
+
+ static const struct sockaddr_un abstract = {
+ .sun_family = AF_UNIX,
+ .sun_path = "\0foobar",
+ };
+
+ assert_se(SOCKADDR_UN_LEN(fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path));
+ assert_se(SOCKADDR_UN_LEN(abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1));
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
+ test_ifname_valid();
+
test_socket_address_parse();
test_socket_address_parse_netlink();
test_socket_address_equal();
@@ -363,5 +403,7 @@ int main(int argc, char *argv[]) {
test_sockaddr_equal();
+ test_sockaddr_un_len();
+
return 0;
}
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
new file mode 100644
index 0000000000..a10227f823
--- /dev/null
+++ b/src/test/test-stat-util.c
@@ -0,0 +1,68 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "macro.h"
+#include "stat-util.h"
+
+static void test_files_same(void) {
+ _cleanup_close_ int fd = -1;
+ char name[] = "/tmp/test-files_same.XXXXXX";
+ char name_alias[] = "/tmp/test-files_same.alias";
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ assert_se(symlink(name, name_alias) >= 0);
+
+ assert_se(files_same(name, name));
+ assert_se(files_same(name, name_alias));
+
+ unlink(name);
+ unlink(name_alias);
+}
+
+static void test_is_symlink(void) {
+ char name[] = "/tmp/test-is_symlink.XXXXXX";
+ char name_link[] = "/tmp/test-is_symlink.link";
+ _cleanup_close_ int fd = -1;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ assert_se(symlink(name, name_link) >= 0);
+
+ assert_se(is_symlink(name) == 0);
+ assert_se(is_symlink(name_link) == 1);
+ assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
+
+
+ unlink(name);
+ unlink(name_link);
+}
+
+int main(int argc, char *argv[]) {
+ test_files_same();
+ test_is_symlink();
+
+ return 0;
+}
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index 9b48e95998..d0f84d70bc 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -17,7 +17,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "alloc-util.h"
+#include "macro.h"
#include "string-util.h"
+#include "strv.h"
static void test_string_erase(void) {
char *x;
@@ -97,9 +100,271 @@ static void test_ascii_strcasecmp_nn(void) {
assert_se(ascii_strcasecmp_nn("BBbb", 4, "aaaa", 4) > 0);
}
+static void test_streq_ptr(void) {
+ assert_se(streq_ptr(NULL, NULL));
+ assert_se(!streq_ptr("abc", "cdef"));
+}
+
+static void test_strstrip(void) {
+ char *r;
+ char input[] = " hello, waldo. ";
+
+ r = strstrip(input);
+ assert_se(streq(r, "hello, waldo."));
+}
+
+static void test_strextend(void) {
+ _cleanup_free_ char *str = strdup("0123");
+ strextend(&str, "456", "78", "9", NULL);
+ assert_se(streq(str, "0123456789"));
+}
+
+static void test_strrep(void) {
+ _cleanup_free_ char *one, *three, *zero;
+ one = strrep("waldo", 1);
+ three = strrep("waldo", 3);
+ zero = strrep("waldo", 0);
+
+ assert_se(streq(one, "waldo"));
+ assert_se(streq(three, "waldowaldowaldo"));
+ assert_se(streq(zero, ""));
+}
+
+
+static void test_strappend(void) {
+ _cleanup_free_ char *t1, *t2, *t3, *t4;
+
+ t1 = strappend(NULL, NULL);
+ assert_se(streq(t1, ""));
+
+ t2 = strappend(NULL, "suf");
+ assert_se(streq(t2, "suf"));
+
+ t3 = strappend("pre", NULL);
+ assert_se(streq(t3, "pre"));
+
+ t4 = strappend("pre", "suf");
+ assert_se(streq(t4, "presuf"));
+}
+
+static void test_string_has_cc(void) {
+ assert_se(string_has_cc("abc\1", NULL));
+ assert_se(string_has_cc("abc\x7f", NULL));
+ assert_se(string_has_cc("abc\x7f", NULL));
+ assert_se(string_has_cc("abc\t\x7f", "\t"));
+ assert_se(string_has_cc("abc\t\x7f", "\t"));
+ assert_se(string_has_cc("\x7f", "\t"));
+ assert_se(string_has_cc("\x7f", "\t\a"));
+
+ assert_se(!string_has_cc("abc\t\t", "\t"));
+ assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
+ assert_se(!string_has_cc("a\ab\tc", "\t\a"));
+}
+
+static void test_ascii_strlower(void) {
+ char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
+ assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
+}
+
+static void test_strshorten(void) {
+ char s[] = "foobar";
+
+ assert_se(strlen(strshorten(s, 6)) == 6);
+ assert_se(strlen(strshorten(s, 12)) == 6);
+ assert_se(strlen(strshorten(s, 2)) == 2);
+ assert_se(strlen(strshorten(s, 0)) == 0);
+}
+
+static void test_strjoina(void) {
+ char *actual;
+
+ actual = strjoina("", "foo", "bar");
+ assert_se(streq(actual, "foobar"));
+
+ actual = strjoina("foo", "bar", "baz");
+ assert_se(streq(actual, "foobarbaz"));
+
+ actual = strjoina("foo", "", "bar", "baz");
+ assert_se(streq(actual, "foobarbaz"));
+
+ actual = strjoina("foo");
+ assert_se(streq(actual, "foo"));
+
+ actual = strjoina(NULL);
+ assert_se(streq(actual, ""));
+
+ actual = strjoina(NULL, "foo");
+ assert_se(streq(actual, ""));
+
+ actual = strjoina("foo", NULL, "bar");
+ assert_se(streq(actual, "foo"));
+}
+
+static void test_strcmp_ptr(void) {
+ assert_se(strcmp_ptr(NULL, NULL) == 0);
+ assert_se(strcmp_ptr("", NULL) > 0);
+ assert_se(strcmp_ptr("foo", NULL) > 0);
+ assert_se(strcmp_ptr(NULL, "") < 0);
+ assert_se(strcmp_ptr(NULL, "bar") < 0);
+ assert_se(strcmp_ptr("foo", "bar") > 0);
+ assert_se(strcmp_ptr("bar", "baz") < 0);
+ assert_se(strcmp_ptr("foo", "foo") == 0);
+ assert_se(strcmp_ptr("", "") == 0);
+}
+
+static void test_foreach_word(void) {
+ const char *word, *state;
+ size_t l;
+ int i = 0;
+ const char test[] = "test abc d\te f ";
+ const char * const expected[] = {
+ "test",
+ "abc",
+ "d",
+ "e",
+ "f",
+ "",
+ NULL
+ };
+
+ FOREACH_WORD(word, l, test, state)
+ assert_se(strneq(expected[i++], word, l));
+}
+
+static void check(const char *test, char** expected, bool trailing) {
+ const char *word, *state;
+ size_t l;
+ int i = 0;
+
+ printf("<<<%s>>>\n", test);
+ FOREACH_WORD_QUOTED(word, l, test, state) {
+ _cleanup_free_ char *t = NULL;
+
+ assert_se(t = strndup(word, l));
+ assert_se(strneq(expected[i++], word, l));
+ printf("<%s>\n", t);
+ }
+ printf("<<<%s>>>\n", state);
+ assert_se(expected[i] == NULL);
+ assert_se(isempty(state) == !trailing);
+}
+
+static void test_foreach_word_quoted(void) {
+ check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
+ STRV_MAKE("test",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "",
+ "",
+ "hhh",
+ "",
+ "",
+ "a b c"),
+ false);
+
+ check("test \"xxx",
+ STRV_MAKE("test"),
+ true);
+
+ check("test\\",
+ STRV_MAKE_EMPTY,
+ true);
+}
+
+static void test_endswith(void) {
+ assert_se(endswith("foobar", "bar"));
+ assert_se(endswith("foobar", ""));
+ assert_se(endswith("foobar", "foobar"));
+ assert_se(endswith("", ""));
+
+ assert_se(!endswith("foobar", "foo"));
+ assert_se(!endswith("foobar", "foobarfoofoo"));
+}
+
+static void test_endswith_no_case(void) {
+ assert_se(endswith_no_case("fooBAR", "bar"));
+ assert_se(endswith_no_case("foobar", ""));
+ assert_se(endswith_no_case("foobar", "FOOBAR"));
+ assert_se(endswith_no_case("", ""));
+
+ assert_se(!endswith_no_case("foobar", "FOO"));
+ assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
+}
+
+static void test_delete_chars(void) {
+ char *r;
+ char input[] = " hello, waldo. abc";
+
+ r = delete_chars(input, WHITESPACE);
+ assert_se(streq(r, "hello,waldo.abc"));
+}
+
+static void test_in_charset(void) {
+ assert_se(in_charset("dddaaabbbcccc", "abcd"));
+ assert_se(!in_charset("dddaaabbbcccc", "abc f"));
+}
+
+static void test_split_pair(void) {
+ _cleanup_free_ char *a = NULL, *b = NULL;
+
+ assert_se(split_pair("", "", &a, &b) == -EINVAL);
+ assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
+ assert_se(split_pair("", "=", &a, &b) == -EINVAL);
+ assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
+ assert_se(streq(a, "foo"));
+ assert_se(streq(b, "bar"));
+ free(a);
+ free(b);
+ assert_se(split_pair("==", "==", &a, &b) >= 0);
+ assert_se(streq(a, ""));
+ assert_se(streq(b, ""));
+ free(a);
+ free(b);
+
+ assert_se(split_pair("===", "==", &a, &b) >= 0);
+ assert_se(streq(a, ""));
+ assert_se(streq(b, "="));
+}
+
+static void test_first_word(void) {
+ assert_se(first_word("Hello", ""));
+ assert_se(first_word("Hello", "Hello"));
+ assert_se(first_word("Hello world", "Hello"));
+ assert_se(first_word("Hello\tworld", "Hello"));
+ assert_se(first_word("Hello\nworld", "Hello"));
+ assert_se(first_word("Hello\rworld", "Hello"));
+ assert_se(first_word("Hello ", "Hello"));
+
+ assert_se(!first_word("Hello", "Hellooo"));
+ assert_se(!first_word("Hello", "xxxxx"));
+ assert_se(!first_word("Hellooo", "Hello"));
+}
+
int main(int argc, char *argv[]) {
test_string_erase();
test_ascii_strcasecmp_n();
test_ascii_strcasecmp_nn();
+ test_streq_ptr();
+ test_strstrip();
+ test_strextend();
+ test_strrep();
+ test_strappend();
+ test_string_has_cc();
+ test_ascii_strlower();
+ test_strshorten();
+ test_strjoina();
+ test_strcmp_ptr();
+ test_foreach_word();
+ test_foreach_word_quoted();
+ test_endswith();
+ test_endswith_no_case();
+ test_delete_chars();
+ test_in_charset();
+ test_split_pair();
+ test_first_word();
+
return 0;
}
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index 2b2f76cc7f..fc01dcfaf1 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -70,6 +70,18 @@ static const char* const input_table_none[] = {
NULL,
};
+static const char* const input_table_two_empties[] = {
+ "",
+ "",
+ NULL,
+};
+
+static const char* const input_table_one_empty[] = {
+ "",
+ NULL,
+};
+
+
static const char* const input_table_quotes[] = {
"\"",
"'",
@@ -130,7 +142,7 @@ static void test_strv_find_startswith(void) {
}
static void test_strv_join(void) {
- _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
+ _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
p = strv_join((char **)input_table_multiple, ", ");
assert_se(p);
@@ -151,6 +163,14 @@ static void test_strv_join(void) {
t = strv_join((char **)input_table_none, ", ");
assert_se(t);
assert_se(streq(t, ""));
+
+ v = strv_join((char **)input_table_two_empties, ", ");
+ assert_se(v);
+ assert_se(streq(v, ", "));
+
+ w = strv_join((char **)input_table_one_empty, ", ");
+ assert_se(w);
+ assert_se(streq(w, ""));
}
static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
@@ -338,7 +358,7 @@ static void test_strv_extend_strv_concat(void) {
}
static void test_strv_extend_strv(void) {
- _cleanup_strv_free_ char **a = NULL, **b = NULL;
+ _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
a = strv_new("abc", "def", "ghi", NULL);
b = strv_new("jkl", "mno", "abc", "pqr", NULL);
@@ -353,8 +373,14 @@ static void test_strv_extend_strv(void) {
assert_se(streq(a[3], "jkl"));
assert_se(streq(a[4], "mno"));
assert_se(streq(a[5], "pqr"));
-
assert_se(strv_length(a) == 6);
+
+ assert_se(strv_extend_strv(&n, b, false) >= 0);
+ assert_se(streq(n[0], "jkl"));
+ assert_se(streq(n[1], "mno"));
+ assert_se(streq(n[2], "abc"));
+ assert_se(streq(n[3], "pqr"));
+ assert_se(strv_length(n) == 4);
}
static void test_strv_extend(void) {
@@ -640,6 +666,25 @@ static void test_strv_make_nulstr(void) {
test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
}
+static void test_foreach_string(void) {
+ const char * const t[] = {
+ "foo",
+ "bar",
+ "waldo",
+ NULL
+ };
+ const char *x;
+ unsigned i = 0;
+
+ FOREACH_STRING(x, "foo", "bar", "waldo")
+ assert_se(streq_ptr(t[i++], x));
+
+ assert_se(i == 3);
+
+ FOREACH_STRING(x, "zzz")
+ assert_se(streq(x, "zzz"));
+}
+
int main(int argc, char *argv[]) {
test_specifier_printf();
test_strv_foreach();
@@ -653,6 +698,8 @@ int main(int argc, char *argv[]) {
test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
test_strv_quote_unquote(input_table_one, "\"one\"");
test_strv_quote_unquote(input_table_none, "");
+ test_strv_quote_unquote(input_table_one_empty, "\"\"");
+ test_strv_quote_unquote(input_table_two_empties, "\"\" \"\"");
test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
@@ -702,5 +749,7 @@ int main(int argc, char *argv[]) {
test_strv_extend_n();
test_strv_make_nulstr();
+ test_foreach_string();
+
return 0;
}
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index aef992ee3c..0be74921fc 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -19,7 +19,6 @@
#include "architecture.h"
#include "automount.h"
-#include "bus-xml-policy.h"
#include "busname.h"
#include "cgroup.h"
#include "compress.h"
@@ -83,8 +82,6 @@ int main(int argc, char **argv) {
test_table(path_result, PATH_RESULT);
test_table(path_state, PATH_STATE);
test_table(path_type, PATH_TYPE);
- test_table(policy_item_class, POLICY_ITEM_CLASS);
- test_table(policy_item_type, POLICY_ITEM_TYPE);
test_table(protect_home, PROTECT_HOME);
test_table(protect_system, PROTECT_SYSTEM);
test_table(rlimit, RLIMIT);
diff --git a/src/test/test-time.c b/src/test/test-time.c
index 9062c3f3c1..ee7d55c5ab 100644
--- a/src/test/test-time.c
+++ b/src/test/test-time.c
@@ -220,7 +220,7 @@ int main(int argc, char *argv[]) {
/* Ensure TIME_T_MAX works correctly */
x = (uintmax_t) TIME_T_MAX;
- x ++;
+ x++;
assert((time_t) x < 0);
return 0;
diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c
index d7223dd2bf..b34ebeefb2 100644
--- a/src/test/test-tmpfiles.c
+++ b/src/test/test-tmpfiles.c
@@ -32,15 +32,17 @@
#include "util.h"
int main(int argc, char** argv) {
+ _cleanup_free_ char *cmd = NULL, *cmd2 = NULL, *ans = NULL, *ans2 = NULL, *d = NULL, *tmp = NULL, *line = NULL;
+ _cleanup_close_ int fd = -1, fd2 = -1;
const char *p = argv[1] ?: "/tmp";
- char *pattern = strjoina(p, "/systemd-test-XXXXXX");
- _cleanup_close_ int fd, fd2;
- _cleanup_free_ char *cmd, *cmd2, *ans, *ans2;
+ char *pattern;
log_set_max_level(LOG_DEBUG);
log_parse_environment();
- fd = open_tmpfile(p, O_RDWR|O_CLOEXEC);
+ pattern = strjoina(p, "/systemd-test-XXXXXX");
+
+ 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);
@@ -59,5 +61,21 @@ int main(int argc, char** argv) {
log_debug("link2: %s", ans2);
assert_se(endswith(ans2, " (deleted)"));
+ pattern = strjoina(p, "/tmpfiles-test");
+ assert_se(tempfn_random(pattern, NULL, &d) >= 0);
+
+ fd = open_tmpfile_linkable(d, O_RDWR|O_CLOEXEC, &tmp);
+ assert_se(fd >= 0);
+ assert_se(write(fd, "foobar\n", 7) == 7);
+
+ assert_se(touch(d) >= 0);
+ assert_se(link_tmpfile(fd, tmp, d) == -EEXIST);
+ assert_se(unlink(d) >= 0);
+ assert_se(link_tmpfile(fd, tmp, d) >= 0);
+
+ assert_se(read_one_line_file(d, &line) >= 0);
+ assert_se(streq(line, "foobar"));
+ assert_se(unlink(d) >= 0);
+
return 0;
}
diff --git a/src/test/test-udev.c b/src/test/test-udev.c
index 9cc64f7c68..e965b4494a 100644
--- a/src/test/test-udev.c
+++ b/src/test/test-udev.c
@@ -27,6 +27,7 @@
#include <unistd.h>
#include "fs-util.h"
+#include "log.h"
#include "missing.h"
#include "selinux-util.h"
#include "signal-util.h"
@@ -39,39 +40,31 @@ static int fake_filesystems(void) {
const char *src;
const char *target;
const char *error;
+ bool ignore_mount_error;
} fakefss[] = {
- { "test/sys", "/sys", "failed to mount test /sys" },
- { "test/dev", "/dev", "failed to mount test /dev" },
- { "test/run", "/run", "failed to mount test /run" },
- { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" },
- { "test/run", UDEVLIBEXECDIR "/rules.d","failed to mount empty " UDEVLIBEXECDIR "/rules.d" },
+ { "test/tmpfs/sys", "/sys", "failed to mount test /sys", false },
+ { "test/tmpfs/dev", "/dev", "failed to mount test /dev", false },
+ { "test/run", "/run", "failed to mount test /run", false },
+ { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d", true },
+ { "test/run", UDEVLIBEXECDIR "/rules.d", "failed to mount empty " UDEVLIBEXECDIR "/rules.d", true },
};
unsigned int i;
- int err;
- err = unshare(CLONE_NEWNS);
- if (err < 0) {
- err = -errno;
- fprintf(stderr, "failed to call unshare(): %m\n");
- goto out;
- }
+ if (unshare(CLONE_NEWNS) < 0)
+ return log_error_errno(errno, "failed to call unshare(): %m");
- if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
- err = -errno;
- fprintf(stderr, "failed to mount / as private: %m\n");
- goto out;
- }
+ if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0)
+ return log_error_errno(errno, "failed to mount / as private: %m");
for (i = 0; i < ELEMENTSOF(fakefss); i++) {
- err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
- if (err < 0) {
- err = -errno;
- fprintf(stderr, "%s %m\n", fakefss[i].error);
- return err;
+ if (mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL) < 0) {
+ log_full_errno(fakefss[i].ignore_mount_error ? LOG_DEBUG : LOG_ERR, errno, "%s: %m", fakefss[i].error);
+ if (!fakefss[i].ignore_mount_error)
+ return -errno;
}
}
-out:
- return err;
+
+ return 0;
}
int main(int argc, char *argv[]) {
@@ -84,6 +77,9 @@ int main(int argc, char *argv[]) {
const char *action;
int err;
+ log_parse_environment();
+ log_open();
+
err = fake_filesystems();
if (err < 0)
return EXIT_FAILURE;
@@ -93,7 +89,7 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
log_debug("version %s", VERSION);
- mac_selinux_init("/dev");
+ mac_selinux_init();
action = argv[1];
if (action == NULL) {
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index b0c343590d..ade0ff2a63 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -35,10 +35,12 @@
#include "install.h"
#include "load-fragment.h"
#include "macro.h"
+#include "rm-rf.h"
#include "specifier.h"
#include "string-util.h"
#include "strv.h"
#include "test-helper.h"
+#include "tests.h"
#include "user-util.h"
#include "util.h"
@@ -51,7 +53,7 @@ static int test_unit_file_get_set(void) {
h = hashmap_new(&string_hash_ops);
assert_se(h);
- r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
+ r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h, NULL, NULL);
if (r == -EPERM || r == -EACCES) {
printf("Skipping test: unit_file_get_list: %s", strerror(-r));
@@ -113,7 +115,7 @@ static void test_config_parse_exec(void) {
Manager *m = NULL;
Unit *u = NULL;
- r = manager_new(MANAGER_USER, true, &m);
+ r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
printf("Skipping test: manager_new: %s\n", strerror(-r));
return;
@@ -606,7 +608,7 @@ static void test_install_printf(void) {
} else assert_se(t == NULL); \
strcpy(i.name, d1); \
strcpy(i.path, d2); \
- } while(false)
+ } while (false)
expect(i, "%n", "name.service");
expect(i, "%N", "name");
@@ -840,11 +842,14 @@ static void test_config_parse_pass_environ(void) {
}
int main(int argc, char *argv[]) {
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int r;
log_parse_environment();
log_open();
+ assert_se(runtime_dir = setup_fake_runtime_dir());
+
r = test_unit_file_get_set();
test_config_parse_exec();
test_config_parse_capability_set();
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
index 3de94ef425..2fd83f321c 100644
--- a/src/test/test-unit-name.c
+++ b/src/test/test-unit-name.c
@@ -209,7 +209,7 @@ static int test_unit_printf(void) {
assert_se(get_home_dir(&home) >= 0);
assert_se(get_shell(&shell) >= 0);
- r = manager_new(MANAGER_USER, true, &m);
+ r = manager_new(UNIT_FILE_USER, true, &m);
if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) {
puts("manager_new: Permission denied. Skipping test.");
return EXIT_TEST_SKIP;
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
index 42c6a8d5e2..8d1ec19f17 100644
--- a/src/test/test-user-util.c
+++ b/src/test/test-user-util.c
@@ -37,6 +37,30 @@ static void test_gid_to_name_one(gid_t gid, const char *name) {
assert_se(streq_ptr(t, name));
}
+static void test_parse_uid(void) {
+ int r;
+ uid_t uid;
+
+ r = parse_uid("100", &uid);
+ assert_se(r == 0);
+ assert_se(uid == 100);
+
+ r = parse_uid("65535", &uid);
+ assert_se(r == -ENXIO);
+
+ r = parse_uid("asdsdas", &uid);
+ assert_se(r == -EINVAL);
+}
+
+static void test_uid_ptr(void) {
+
+ assert_se(UID_TO_PTR(0) != NULL);
+ assert_se(UID_TO_PTR(1000) != NULL);
+
+ assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
+ assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
+}
+
int main(int argc, char*argv[]) {
test_uid_to_name_one(0, "root");
@@ -48,5 +72,8 @@ int main(int argc, char*argv[]) {
test_gid_to_name_one(0xFFFF, "65535");
test_gid_to_name_one(0xFFFFFFFF, "4294967295");
+ test_parse_uid();
+ test_uid_ptr();
+
return 0;
}
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 9a8a265790..05cb1eae76 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -19,47 +19,16 @@
***/
#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/wait.h>
-#include <sys/xattr.h>
#include <unistd.h>
-#include "alloc-util.h"
-#include "conf-parser.h"
-#include "cpu-set-util.h"
#include "def.h"
-#include "escape.h"
-#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
-#include "fstab-util.h"
-#include "glob-util.h"
-#include "hexdecoct.h"
-#include "io-util.h"
-#include "mkdir.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "proc-cmdline.h"
-#include "process-util.h"
#include "rm-rf.h"
-#include "signal-util.h"
-#include "special.h"
-#include "stat-util.h"
#include "string-util.h"
-#include "strv.h"
-#include "user-util.h"
#include "util.h"
-#include "virt.h"
-#include "web-util.h"
-#include "xattr-util.h"
-
-static void test_streq_ptr(void) {
- assert_se(streq_ptr(NULL, NULL));
- assert_se(!streq_ptr("abc", "cdef"));
-}
static void test_align_power2(void) {
unsigned long i, p2;
@@ -151,19 +120,6 @@ static void test_container_of(void) {
v1) == &myval);
}
-static void test_alloca(void) {
- static const uint8_t zero[997] = { };
- char *t;
-
- t = alloca_align(17, 512);
- assert_se(!((uintptr_t)t & 0xff));
- memzero(t, 17);
-
- t = alloca0_align(997, 1024);
- assert_se(!((uintptr_t)t & 0x1ff));
- assert_se(!memcmp(t, zero, 997));
-}
-
static void test_div_round_up(void) {
int div;
@@ -197,544 +153,6 @@ static void test_div_round_up(void) {
assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
}
-static void test_first_word(void) {
- assert_se(first_word("Hello", ""));
- assert_se(first_word("Hello", "Hello"));
- assert_se(first_word("Hello world", "Hello"));
- assert_se(first_word("Hello\tworld", "Hello"));
- assert_se(first_word("Hello\nworld", "Hello"));
- assert_se(first_word("Hello\rworld", "Hello"));
- assert_se(first_word("Hello ", "Hello"));
-
- assert_se(!first_word("Hello", "Hellooo"));
- assert_se(!first_word("Hello", "xxxxx"));
- assert_se(!first_word("Hellooo", "Hello"));
-}
-
-static void test_close_many(void) {
- int fds[3];
- char name0[] = "/tmp/test-close-many.XXXXXX";
- char name1[] = "/tmp/test-close-many.XXXXXX";
- char name2[] = "/tmp/test-close-many.XXXXXX";
-
- fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
- fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
- fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
-
- close_many(fds, 2);
-
- assert_se(fcntl(fds[0], F_GETFD) == -1);
- assert_se(fcntl(fds[1], F_GETFD) == -1);
- assert_se(fcntl(fds[2], F_GETFD) >= 0);
-
- safe_close(fds[2]);
-
- unlink(name0);
- unlink(name1);
- unlink(name2);
-}
-
-static void test_parse_uid(void) {
- int r;
- uid_t uid;
-
- r = parse_uid("100", &uid);
- assert_se(r == 0);
- assert_se(uid == 100);
-
- r = parse_uid("65535", &uid);
- assert_se(r == -ENXIO);
-
- r = parse_uid("asdsdas", &uid);
- assert_se(r == -EINVAL);
-}
-
-static void test_strappend(void) {
- _cleanup_free_ char *t1, *t2, *t3, *t4;
-
- t1 = strappend(NULL, NULL);
- assert_se(streq(t1, ""));
-
- t2 = strappend(NULL, "suf");
- assert_se(streq(t2, "suf"));
-
- t3 = strappend("pre", NULL);
- assert_se(streq(t3, "pre"));
-
- t4 = strappend("pre", "suf");
- assert_se(streq(t4, "presuf"));
-}
-
-static void test_strstrip(void) {
- char *r;
- char input[] = " hello, waldo. ";
-
- r = strstrip(input);
- assert_se(streq(r, "hello, waldo."));
-}
-
-static void test_delete_chars(void) {
- char *r;
- char input[] = " hello, waldo. abc";
-
- r = delete_chars(input, WHITESPACE);
- assert_se(streq(r, "hello,waldo.abc"));
-}
-
-static void test_in_charset(void) {
- assert_se(in_charset("dddaaabbbcccc", "abcd"));
- assert_se(!in_charset("dddaaabbbcccc", "abc f"));
-}
-
-static void test_hexchar(void) {
- assert_se(hexchar(0xa) == 'a');
- assert_se(hexchar(0x0) == '0');
-}
-
-static void test_unhexchar(void) {
- assert_se(unhexchar('a') == 0xA);
- assert_se(unhexchar('A') == 0xA);
- assert_se(unhexchar('0') == 0x0);
-}
-
-static void test_base32hexchar(void) {
- assert_se(base32hexchar(0) == '0');
- assert_se(base32hexchar(9) == '9');
- assert_se(base32hexchar(10) == 'A');
- assert_se(base32hexchar(31) == 'V');
-}
-
-static void test_unbase32hexchar(void) {
- assert_se(unbase32hexchar('0') == 0);
- assert_se(unbase32hexchar('9') == 9);
- assert_se(unbase32hexchar('A') == 10);
- assert_se(unbase32hexchar('V') == 31);
- assert_se(unbase32hexchar('=') == -EINVAL);
-}
-
-static void test_base64char(void) {
- assert_se(base64char(0) == 'A');
- assert_se(base64char(26) == 'a');
- assert_se(base64char(63) == '/');
-}
-
-static void test_unbase64char(void) {
- assert_se(unbase64char('A') == 0);
- assert_se(unbase64char('Z') == 25);
- assert_se(unbase64char('a') == 26);
- assert_se(unbase64char('z') == 51);
- assert_se(unbase64char('0') == 52);
- assert_se(unbase64char('9') == 61);
- assert_se(unbase64char('+') == 62);
- assert_se(unbase64char('/') == 63);
- assert_se(unbase64char('=') == -EINVAL);
-}
-
-static void test_octchar(void) {
- assert_se(octchar(00) == '0');
- assert_se(octchar(07) == '7');
-}
-
-static void test_unoctchar(void) {
- assert_se(unoctchar('0') == 00);
- assert_se(unoctchar('7') == 07);
-}
-
-static void test_decchar(void) {
- assert_se(decchar(0) == '0');
- assert_se(decchar(9) == '9');
-}
-
-static void test_undecchar(void) {
- assert_se(undecchar('0') == 0);
- assert_se(undecchar('9') == 9);
-}
-
-static void test_unhexmem(void) {
- const char *hex = "efa214921";
- const char *hex_invalid = "efa214921o";
- _cleanup_free_ char *hex2 = NULL;
- _cleanup_free_ void *mem = NULL;
- size_t len;
-
- assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
- assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
- assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
-
- assert_se((hex2 = hexmem(mem, len)));
-
- free(mem);
-
- assert_se(memcmp(hex, hex2, strlen(hex)) == 0);
-
- free(hex2);
-
- assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == 0);
- assert_se((hex2 = hexmem(mem, len)));
- assert_se(memcmp(hex, hex2, strlen(hex) - 1) == 0);
-}
-
-/* https://tools.ietf.org/html/rfc4648#section-10 */
-static void test_base32hexmem(void) {
- char *b32;
-
- b32 = base32hexmem("", strlen(""), true);
- assert_se(b32);
- assert_se(streq(b32, ""));
- free(b32);
-
- b32 = base32hexmem("f", strlen("f"), true);
- assert_se(b32);
- assert_se(streq(b32, "CO======"));
- free(b32);
-
- b32 = base32hexmem("fo", strlen("fo"), true);
- assert_se(b32);
- assert_se(streq(b32, "CPNG===="));
- free(b32);
-
- b32 = base32hexmem("foo", strlen("foo"), true);
- assert_se(b32);
- assert_se(streq(b32, "CPNMU==="));
- free(b32);
-
- b32 = base32hexmem("foob", strlen("foob"), true);
- assert_se(b32);
- assert_se(streq(b32, "CPNMUOG="));
- free(b32);
-
- b32 = base32hexmem("fooba", strlen("fooba"), true);
- assert_se(b32);
- assert_se(streq(b32, "CPNMUOJ1"));
- free(b32);
-
- b32 = base32hexmem("foobar", strlen("foobar"), true);
- assert_se(b32);
- assert_se(streq(b32, "CPNMUOJ1E8======"));
- free(b32);
-
- b32 = base32hexmem("", strlen(""), false);
- assert_se(b32);
- assert_se(streq(b32, ""));
- free(b32);
-
- b32 = base32hexmem("f", strlen("f"), false);
- assert_se(b32);
- assert_se(streq(b32, "CO"));
- free(b32);
-
- b32 = base32hexmem("fo", strlen("fo"), false);
- assert_se(b32);
- assert_se(streq(b32, "CPNG"));
- free(b32);
-
- b32 = base32hexmem("foo", strlen("foo"), false);
- assert_se(b32);
- assert_se(streq(b32, "CPNMU"));
- free(b32);
-
- b32 = base32hexmem("foob", strlen("foob"), false);
- assert_se(b32);
- assert_se(streq(b32, "CPNMUOG"));
- free(b32);
-
- b32 = base32hexmem("fooba", strlen("fooba"), false);
- assert_se(b32);
- assert_se(streq(b32, "CPNMUOJ1"));
- free(b32);
-
- b32 = base32hexmem("foobar", strlen("foobar"), false);
- assert_se(b32);
- assert_se(streq(b32, "CPNMUOJ1E8"));
- free(b32);
-}
-
-static void test_unbase32hexmem(void) {
- void *mem;
- size_t len;
-
- assert_se(unbase32hexmem("", strlen(""), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), ""));
- free(mem);
-
- assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "f"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "fo"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foo"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foob"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "fooba"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foobar"));
- free(mem);
-
- assert_se(unbase32hexmem("A", strlen("A"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem, &len) == -EINVAL);
-
- assert_se(unbase32hexmem("XPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CXNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPXMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPNXUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPNMXOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPNMUXJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPNMUOX1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPNMUOJX", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-
- assert_se(unbase32hexmem("", strlen(""), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), ""));
- free(mem);
-
- assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "f"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "fo"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foo"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foob"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "fooba"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foobar"));
- free(mem);
-
- assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem, &len) == -EINVAL);
- assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem, &len) == -EINVAL);
-}
-
-/* https://tools.ietf.org/html/rfc4648#section-10 */
-static void test_base64mem(void) {
- char *b64;
-
- assert_se(base64mem("", strlen(""), &b64) == 0);
- assert_se(streq(b64, ""));
- free(b64);
-
- assert_se(base64mem("f", strlen("f"), &b64) == 4);
- assert_se(streq(b64, "Zg=="));
- free(b64);
-
- assert_se(base64mem("fo", strlen("fo"), &b64) == 4);
- assert_se(streq(b64, "Zm8="));
- free(b64);
-
- assert_se(base64mem("foo", strlen("foo"), &b64) == 4);
- assert_se(streq(b64, "Zm9v"));
- free(b64);
-
- assert_se(base64mem("foob", strlen("foob"), &b64) == 8);
- assert_se(streq(b64, "Zm9vYg=="));
- free(b64);
-
- assert_se(base64mem("fooba", strlen("fooba"), &b64) == 8);
- assert_se(streq(b64, "Zm9vYmE="));
- free(b64);
-
- assert_se(base64mem("foobar", strlen("foobar"), &b64) == 8);
- assert_se(streq(b64, "Zm9vYmFy"));
- free(b64);
-}
-
-static void test_unbase64mem(void) {
- void *mem;
- size_t len;
-
- assert_se(unbase64mem("", strlen(""), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), ""));
- free(mem);
-
- assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "f"));
- free(mem);
-
- assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "fo"));
- free(mem);
-
- assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foo"));
- free(mem);
-
- assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foob"));
- free(mem);
-
- assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "fooba"));
- free(mem);
-
- assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem, &len) == 0);
- assert_se(streq(strndupa(mem, len), "foobar"));
- free(mem);
-
- assert_se(unbase64mem("A", strlen("A"), &mem, &len) == -EINVAL);
- assert_se(unbase64mem("A====", strlen("A===="), &mem, &len) == -EINVAL);
- assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem, &len) == -EINVAL);
- assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem, &len) == -EINVAL);
-}
-
-static void test_cescape(void) {
- _cleanup_free_ char *escaped;
-
- assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
- assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
-}
-
-static void test_cunescape(void) {
- _cleanup_free_ char *unescaped;
-
- assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
- assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
- unescaped = mfree(unescaped);
-
- /* incomplete sequences */
- assert_se(cunescape("\\x0", 0, &unescaped) < 0);
- assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "\\x0"));
- unescaped = mfree(unescaped);
-
- assert_se(cunescape("\\x", 0, &unescaped) < 0);
- assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "\\x"));
- unescaped = mfree(unescaped);
-
- assert_se(cunescape("\\", 0, &unescaped) < 0);
- assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "\\"));
- unescaped = mfree(unescaped);
-
- assert_se(cunescape("\\11", 0, &unescaped) < 0);
- assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "\\11"));
- unescaped = mfree(unescaped);
-
- assert_se(cunescape("\\1", 0, &unescaped) < 0);
- assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "\\1"));
- unescaped = mfree(unescaped);
-
- assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
- assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, "ßßΠA"));
- unescaped = mfree(unescaped);
-
- assert_se(cunescape("\\073", 0, &unescaped) >= 0);
- assert_se(streq_ptr(unescaped, ";"));
-}
-
-static void test_foreach_word(void) {
- const char *word, *state;
- size_t l;
- int i = 0;
- const char test[] = "test abc d\te f ";
- const char * const expected[] = {
- "test",
- "abc",
- "d",
- "e",
- "f",
- "",
- NULL
- };
-
- FOREACH_WORD(word, l, test, state)
- assert_se(strneq(expected[i++], word, l));
-}
-
-static void check(const char *test, char** expected, bool trailing) {
- const char *word, *state;
- size_t l;
- int i = 0;
-
- printf("<<<%s>>>\n", test);
- FOREACH_WORD_QUOTED(word, l, test, state) {
- _cleanup_free_ char *t = NULL;
-
- assert_se(t = strndup(word, l));
- assert_se(strneq(expected[i++], word, l));
- printf("<%s>\n", t);
- }
- printf("<<<%s>>>\n", state);
- assert_se(expected[i] == NULL);
- assert_se(isempty(state) == !trailing);
-}
-
-static void test_foreach_word_quoted(void) {
- check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
- STRV_MAKE("test",
- "a",
- "b",
- "c",
- "d",
- "e",
- "",
- "",
- "hhh",
- "",
- "",
- "a b c"),
- false);
-
- check("test \"xxx",
- STRV_MAKE("test"),
- true);
-
- check("test\\",
- STRV_MAKE_EMPTY,
- true);
-}
-
-static void test_memdup_multiply(void) {
- int org[] = {1, 2, 3};
- int *dup;
-
- dup = (int*)memdup_multiply(org, sizeof(int), 3);
-
- assert_se(dup);
- assert_se(dup[0] == 1);
- assert_se(dup[1] == 2);
- assert_se(dup[2] == 3);
- free(dup);
-}
-
static void test_u64log2(void) {
assert_se(u64log2(0) == 0);
assert_se(u64log2(8) == 3);
@@ -754,210 +172,6 @@ static void test_protect_errno(void) {
assert_se(errno == 12);
}
-static void test_parse_cpu_set(void) {
- cpu_set_t *c = NULL;
- int ncpus;
- int cpu;
-
- /* Simple range (from CPUAffinity example) */
- ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
- c = mfree(c);
-
- /* A more interesting range */
- ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
- for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Quoted strings */
- ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
- for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Use commas as separators */
- ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
- for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Commas with spaces (and trailing comma, space) */
- ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
- for (cpu = 0; cpu < 8; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Ranges */
- ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
- for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Ranges with trailing comma, space */
- ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
- for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Negative range (returns empty cpu_set) */
- ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
- c = mfree(c);
-
- /* Overlapping ranges */
- ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
- for (cpu = 0; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Mix ranges and individual CPUs */
- ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
- assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
- for (cpu = 4; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- c = mfree(c);
-
- /* Garbage */
- ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus < 0);
- assert_se(!c);
-
- /* Range with garbage */
- ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus < 0);
- assert_se(!c);
-
- /* Empty string */
- c = NULL;
- ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus == 0); /* empty string returns 0 */
- assert_se(!c);
-
- /* Runnaway quoted string */
- ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus < 0);
- assert_se(!c);
-}
-
-static void test_config_parse_iec_uint64(void) {
- uint64_t offset = 0;
- assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
- assert_se(offset == 4 * 1024 * 1024);
-
- assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
-}
-
-static void test_strextend(void) {
- _cleanup_free_ char *str = strdup("0123");
- strextend(&str, "456", "78", "9", NULL);
- assert_se(streq(str, "0123456789"));
-}
-
-static void test_strrep(void) {
- _cleanup_free_ char *one, *three, *zero;
- one = strrep("waldo", 1);
- three = strrep("waldo", 3);
- zero = strrep("waldo", 0);
-
- assert_se(streq(one, "waldo"));
- assert_se(streq(three, "waldowaldowaldo"));
- assert_se(streq(zero, ""));
-}
-
-static void test_split_pair(void) {
- _cleanup_free_ char *a = NULL, *b = NULL;
-
- assert_se(split_pair("", "", &a, &b) == -EINVAL);
- assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
- assert_se(split_pair("", "=", &a, &b) == -EINVAL);
- assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
- assert_se(streq(a, "foo"));
- assert_se(streq(b, "bar"));
- free(a);
- free(b);
- assert_se(split_pair("==", "==", &a, &b) >= 0);
- assert_se(streq(a, ""));
- assert_se(streq(b, ""));
- free(a);
- free(b);
-
- assert_se(split_pair("===", "==", &a, &b) >= 0);
- assert_se(streq(a, ""));
- assert_se(streq(b, "="));
-}
-
-static void test_fstab_node_to_udev_node(void) {
- char *n;
-
- n = fstab_node_to_udev_node("LABEL=applé/jack");
- puts(n);
- assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
- free(n);
-
- n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
- puts(n);
- assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
- free(n);
-
- n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
- puts(n);
- assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
- free(n);
-
- n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
- puts(n);
- assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
- free(n);
-
- n = fstab_node_to_udev_node("PONIES=awesome");
- puts(n);
- assert_se(streq(n, "PONIES=awesome"));
- free(n);
-
- n = fstab_node_to_udev_node("/dev/xda1");
- puts(n);
- assert_se(streq(n, "/dev/xda1"));
- free(n);
-}
-
-static void test_get_files_in_directory(void) {
- _cleanup_strv_free_ char **l = NULL, **t = NULL;
-
- assert_se(get_files_in_directory("/tmp", &l) >= 0);
- assert_se(get_files_in_directory(".", &t) >= 0);
- assert_se(get_files_in_directory(".", NULL) >= 0);
-}
-
static void test_in_set(void) {
assert_se(IN_SET(1, 1));
assert_se(IN_SET(1, 1, 2, 3, 4));
@@ -968,50 +182,6 @@ static void test_in_set(void) {
assert_se(!IN_SET(0, 1, 2, 3, 4));
}
-static void test_writing_tmpfile(void) {
- char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
- _cleanup_free_ char *contents = NULL;
- size_t size;
- int fd, r;
- struct iovec iov[3];
-
- IOVEC_SET_STRING(iov[0], "abc\n");
- IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
- IOVEC_SET_STRING(iov[2], "");
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- printf("tmpfile: %s", name);
-
- r = writev(fd, iov, 3);
- assert_se(r >= 0);
-
- r = read_full_file(name, &contents, &size);
- assert_se(r == 0);
- printf("contents: %s", contents);
- assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
-
- unlink(name);
-}
-
-static void test_hexdump(void) {
- uint8_t data[146];
- unsigned i;
-
- hexdump(stdout, NULL, 0);
- hexdump(stdout, "", 0);
- hexdump(stdout, "", 1);
- hexdump(stdout, "x", 1);
- hexdump(stdout, "x", 2);
- hexdump(stdout, "foobar", 7);
- hexdump(stdout, "f\nobar", 7);
- hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
-
- for (i = 0; i < ELEMENTSOF(data); i++)
- data[i] = i*2;
-
- hexdump(stdout, data, sizeof(data));
-}
-
static void test_log2i(void) {
assert_se(log2i(1) == 0);
assert_se(log2i(2) == 1);
@@ -1023,341 +193,6 @@ static void test_log2i(void) {
assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
}
-static void test_foreach_string(void) {
- const char * const t[] = {
- "foo",
- "bar",
- "waldo",
- NULL
- };
- const char *x;
- unsigned i = 0;
-
- FOREACH_STRING(x, "foo", "bar", "waldo")
- assert_se(streq_ptr(t[i++], x));
-
- assert_se(i == 3);
-
- FOREACH_STRING(x, "zzz")
- assert_se(streq(x, "zzz"));
-}
-
-static void test_filename_is_valid(void) {
- char foo[FILENAME_MAX+2];
- int i;
-
- assert_se(!filename_is_valid(""));
- assert_se(!filename_is_valid("/bar/foo"));
- assert_se(!filename_is_valid("/"));
- assert_se(!filename_is_valid("."));
- assert_se(!filename_is_valid(".."));
-
- for (i=0; i<FILENAME_MAX+1; i++)
- foo[i] = 'a';
- foo[FILENAME_MAX+1] = '\0';
-
- assert_se(!filename_is_valid(foo));
-
- assert_se(filename_is_valid("foo_bar-333"));
- assert_se(filename_is_valid("o.o"));
-}
-
-static void test_string_has_cc(void) {
- assert_se(string_has_cc("abc\1", NULL));
- assert_se(string_has_cc("abc\x7f", NULL));
- assert_se(string_has_cc("abc\x7f", NULL));
- assert_se(string_has_cc("abc\t\x7f", "\t"));
- assert_se(string_has_cc("abc\t\x7f", "\t"));
- assert_se(string_has_cc("\x7f", "\t"));
- assert_se(string_has_cc("\x7f", "\t\a"));
-
- assert_se(!string_has_cc("abc\t\t", "\t"));
- assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
- assert_se(!string_has_cc("a\ab\tc", "\t\a"));
-}
-
-static void test_ascii_strlower(void) {
- char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
- assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
-}
-
-static void test_files_same(void) {
- _cleanup_close_ int fd = -1;
- char name[] = "/tmp/test-files_same.XXXXXX";
- char name_alias[] = "/tmp/test-files_same.alias";
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- assert_se(symlink(name, name_alias) >= 0);
-
- assert_se(files_same(name, name));
- assert_se(files_same(name, name_alias));
-
- unlink(name);
- unlink(name_alias);
-}
-
-static void test_is_valid_documentation_url(void) {
- assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
- assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
- assert_se(documentation_url_is_valid("file:/foo/foo"));
- assert_se(documentation_url_is_valid("man:systemd.special(7)"));
- assert_se(documentation_url_is_valid("info:bar"));
-
- assert_se(!documentation_url_is_valid("foo:"));
- assert_se(!documentation_url_is_valid("info:"));
- assert_se(!documentation_url_is_valid(""));
-}
-
-static void test_file_in_same_dir(void) {
- char *t;
-
- t = file_in_same_dir("/", "a");
- assert_se(streq(t, "/a"));
- free(t);
-
- t = file_in_same_dir("/", "/a");
- assert_se(streq(t, "/a"));
- free(t);
-
- t = file_in_same_dir("", "a");
- assert_se(streq(t, "a"));
- free(t);
-
- t = file_in_same_dir("a/", "a");
- assert_se(streq(t, "a/a"));
- free(t);
-
- t = file_in_same_dir("bar/foo", "bar");
- assert_se(streq(t, "bar/bar"));
- free(t);
-}
-
-static void test_endswith(void) {
- assert_se(endswith("foobar", "bar"));
- assert_se(endswith("foobar", ""));
- assert_se(endswith("foobar", "foobar"));
- assert_se(endswith("", ""));
-
- assert_se(!endswith("foobar", "foo"));
- assert_se(!endswith("foobar", "foobarfoofoo"));
-}
-
-static void test_endswith_no_case(void) {
- assert_se(endswith_no_case("fooBAR", "bar"));
- assert_se(endswith_no_case("foobar", ""));
- assert_se(endswith_no_case("foobar", "FOOBAR"));
- assert_se(endswith_no_case("", ""));
-
- assert_se(!endswith_no_case("foobar", "FOO"));
- assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
-}
-
-static void test_close_nointr(void) {
- char name[] = "/tmp/test-test-close_nointr.XXXXXX";
- int fd;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- assert_se(close_nointr(fd) >= 0);
- assert_se(close_nointr(fd) < 0);
-
- unlink(name);
-}
-
-
-static void test_unlink_noerrno(void) {
- char name[] = "/tmp/test-close_nointr.XXXXXX";
- int fd;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- assert_se(close_nointr(fd) >= 0);
-
- {
- PROTECT_ERRNO;
- errno = -42;
- assert_se(unlink_noerrno(name) >= 0);
- assert_se(errno == -42);
- assert_se(unlink_noerrno(name) < 0);
- assert_se(errno == -42);
- }
-}
-
-static void test_readlink_and_make_absolute(void) {
- char tempdir[] = "/tmp/test-readlink_and_make_absolute";
- char name[] = "/tmp/test-readlink_and_make_absolute/original";
- char name2[] = "test-readlink_and_make_absolute/original";
- char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
- char *r = NULL;
-
- assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
- assert_se(touch(name) >= 0);
-
- assert_se(symlink(name, name_alias) >= 0);
- assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
- assert_se(streq(r, name));
- free(r);
- assert_se(unlink(name_alias) >= 0);
-
- assert_se(chdir(tempdir) >= 0);
- assert_se(symlink(name2, name_alias) >= 0);
- assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
- assert_se(streq(r, name));
- free(r);
- assert_se(unlink(name_alias) >= 0);
-
- assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
-}
-
-static void test_ignore_signals(void) {
- assert_se(ignore_signals(SIGINT, -1) >= 0);
- assert_se(kill(getpid(), 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(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
-}
-
-static void test_strshorten(void) {
- char s[] = "foobar";
-
- assert_se(strlen(strshorten(s, 6)) == 6);
- assert_se(strlen(strshorten(s, 12)) == 6);
- assert_se(strlen(strshorten(s, 2)) == 2);
- assert_se(strlen(strshorten(s, 0)) == 0);
-}
-
-static void test_strjoina(void) {
- char *actual;
-
- actual = strjoina("", "foo", "bar");
- assert_se(streq(actual, "foobar"));
-
- actual = strjoina("foo", "bar", "baz");
- assert_se(streq(actual, "foobarbaz"));
-
- actual = strjoina("foo", "", "bar", "baz");
- assert_se(streq(actual, "foobarbaz"));
-
- actual = strjoina("foo");
- assert_se(streq(actual, "foo"));
-
- actual = strjoina(NULL);
- assert_se(streq(actual, ""));
-
- actual = strjoina(NULL, "foo");
- assert_se(streq(actual, ""));
-
- actual = strjoina("foo", NULL, "bar");
- assert_se(streq(actual, "foo"));
-}
-
-static void test_is_symlink(void) {
- char name[] = "/tmp/test-is_symlink.XXXXXX";
- char name_link[] = "/tmp/test-is_symlink.link";
- _cleanup_close_ int fd = -1;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- assert_se(symlink(name, name_link) >= 0);
-
- assert_se(is_symlink(name) == 0);
- assert_se(is_symlink(name_link) == 1);
- assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
-
-
- unlink(name);
- unlink(name_link);
-}
-
-static void test_search_and_fopen(void) {
- const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
- char name[] = "/tmp/test-search_and_fopen.XXXXXX";
- int fd = -1;
- int r;
- FILE *f;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- close(fd);
-
- r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
- assert_se(r >= 0);
- fclose(f);
-
- r = search_and_fopen(name, "r", NULL, dirs, &f);
- assert_se(r >= 0);
- fclose(f);
-
- r = search_and_fopen(basename(name), "r", "/", dirs, &f);
- assert_se(r >= 0);
- fclose(f);
-
- r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
- assert_se(r < 0);
- r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
- assert_se(r < 0);
-
- r = unlink(name);
- assert_se(r == 0);
-
- r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
- assert_se(r < 0);
-}
-
-
-static void test_search_and_fopen_nulstr(void) {
- const char dirs[] = "/tmp/foo/bar\0/tmp\0";
- char name[] = "/tmp/test-search_and_fopen.XXXXXX";
- int fd = -1;
- int r;
- FILE *f;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- close(fd);
-
- r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
- assert_se(r >= 0);
- fclose(f);
-
- r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
- assert_se(r >= 0);
- fclose(f);
-
- r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
- assert_se(r < 0);
- r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
- assert_se(r < 0);
-
- r = unlink(name);
- assert_se(r == 0);
-
- r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
- assert_se(r < 0);
-}
-
-static void test_glob_exists(void) {
- char name[] = "/tmp/test-glob_exists.XXXXXX";
- int fd = -1;
- int r;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- close(fd);
-
- r = glob_exists("/tmp/test-glob_exists*");
- assert_se(r == 1);
-
- r = unlink(name);
- assert_se(r == 0);
- r = glob_exists("/tmp/test-glob_exists*");
- assert_se(r == 0);
-}
-
static void test_execute_directory(void) {
char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
@@ -1402,17 +237,6 @@ static void test_execute_directory(void) {
(void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
}
-static int parse_item(const char *key, const char *value) {
- assert_se(key);
-
- log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
- return 0;
-}
-
-static void test_parse_proc_cmdline(void) {
- assert_se(parse_proc_cmdline(parse_item) >= 0);
-}
-
static void test_raw_clone(void) {
pid_t parent, pid, pid2;
@@ -1438,285 +262,20 @@ static void test_raw_clone(void) {
}
}
-static void test_same_fd(void) {
- _cleanup_close_pair_ int p[2] = { -1, -1 };
- _cleanup_close_ int a = -1, b = -1, c = -1;
-
- assert_se(pipe2(p, O_CLOEXEC) >= 0);
- assert_se((a = dup(p[0])) >= 0);
- assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
- assert_se((c = dup(a)) >= 0);
-
- assert_se(same_fd(p[0], p[0]) > 0);
- assert_se(same_fd(p[1], p[1]) > 0);
- assert_se(same_fd(a, a) > 0);
- assert_se(same_fd(b, b) > 0);
-
- assert_se(same_fd(a, p[0]) > 0);
- assert_se(same_fd(p[0], a) > 0);
- assert_se(same_fd(c, p[0]) > 0);
- assert_se(same_fd(p[0], c) > 0);
- assert_se(same_fd(a, c) > 0);
- assert_se(same_fd(c, a) > 0);
-
- assert_se(same_fd(p[0], p[1]) == 0);
- assert_se(same_fd(p[1], p[0]) == 0);
- assert_se(same_fd(p[0], b) == 0);
- assert_se(same_fd(b, p[0]) == 0);
- assert_se(same_fd(p[1], a) == 0);
- assert_se(same_fd(a, p[1]) == 0);
- assert_se(same_fd(p[1], b) == 0);
- assert_se(same_fd(b, p[1]) == 0);
-
- assert_se(same_fd(a, b) == 0);
- assert_se(same_fd(b, a) == 0);
-}
-
-static void test_uid_ptr(void) {
-
- assert_se(UID_TO_PTR(0) != NULL);
- assert_se(UID_TO_PTR(1000) != NULL);
-
- assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
- assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
-}
-
-static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
- char check[n];
-
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
- assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
-
- assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
- assert_se(ftruncate(fd, n) >= 0);
-
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(read(fd, check, n) == (ssize_t) n);
-
- assert_se(memcmp(buffer, check, n) == 0);
-}
-
-static void test_sparse_write(void) {
- const char test_a[] = "test";
- const char test_b[] = "\0\0\0\0test\0\0\0\0";
- const char test_c[] = "\0\0test\0\0\0\0";
- const char test_d[] = "\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0\0\0\0";
- const char test_e[] = "test\0\0\0\0test";
- _cleanup_close_ int fd = -1;
- char fn[] = "/tmp/sparseXXXXXX";
-
- fd = mkostemp(fn, O_CLOEXEC);
- assert_se(fd >= 0);
- unlink(fn);
-
- test_sparse_write_one(fd, test_a, sizeof(test_a));
- test_sparse_write_one(fd, test_b, sizeof(test_b));
- test_sparse_write_one(fd, test_c, sizeof(test_c));
- test_sparse_write_one(fd, test_d, sizeof(test_d));
- test_sparse_write_one(fd, test_e, sizeof(test_e));
-}
-
-static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
- _cleanup_free_ char *r;
-
- assert_se(r = shell_escape(s, bad));
- assert_se(streq_ptr(r, expected));
-}
-
-static void test_shell_escape(void) {
- test_shell_escape_one("", "", "");
- test_shell_escape_one("\\", "", "\\\\");
- test_shell_escape_one("foobar", "", "foobar");
- test_shell_escape_one("foobar", "o", "f\\o\\obar");
- 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;
-
- assert_se(r = shell_maybe_quote(s));
- assert_se(streq(r, 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\"");
-}
-
-static void test_tempfn(void) {
- char *ret = NULL, *p;
-
- assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
- assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
- free(ret);
-
- assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
- assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
- free(ret);
-
- assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
- assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
- assert_se(strlen(p) == 16);
- assert_se(in_charset(p, "0123456789abcdef"));
- free(ret);
-
- assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
- assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
- assert_se(strlen(p) == 16);
- assert_se(in_charset(p, "0123456789abcdef"));
- free(ret);
-
- assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
- assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
- assert_se(strlen(p) == 16);
- assert_se(in_charset(p, "0123456789abcdef"));
- free(ret);
-
- assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
- assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
- assert_se(strlen(p) == 16);
- assert_se(in_charset(p, "0123456789abcdef"));
- free(ret);
-}
-
-static void test_strcmp_ptr(void) {
- assert_se(strcmp_ptr(NULL, NULL) == 0);
- assert_se(strcmp_ptr("", NULL) > 0);
- assert_se(strcmp_ptr("foo", NULL) > 0);
- assert_se(strcmp_ptr(NULL, "") < 0);
- assert_se(strcmp_ptr(NULL, "bar") < 0);
- assert_se(strcmp_ptr("foo", "bar") > 0);
- assert_se(strcmp_ptr("bar", "baz") < 0);
- assert_se(strcmp_ptr("foo", "foo") == 0);
- assert_se(strcmp_ptr("", "") == 0);
-}
-
-static void test_fgetxattrat_fake(void) {
- char t[] = "/var/tmp/xattrtestXXXXXX";
- _cleanup_close_ int fd = -1;
- const char *x;
- char v[3] = {};
- int r;
-
- assert_se(mkdtemp(t));
- x = strjoina(t, "/test");
- assert_se(touch(x) >= 0);
-
- r = setxattr(x, "user.foo", "bar", 3, 0);
- if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
- goto cleanup;
- assert_se(r >= 0);
-
- fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
- assert_se(fd >= 0);
-
- assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
- assert_se(memcmp(v, "bar", 3) == 0);
-
- safe_close(fd);
- fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
- assert_se(fd >= 0);
- assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
-
-cleanup:
- assert_se(unlink(x) >= 0);
- assert_se(rmdir(t) >= 0);
-}
-
-static void test_runlevel_to_target(void) {
- assert_se(streq_ptr(runlevel_to_target(NULL), NULL));
- assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL));
- assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET));
-}
-
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- test_streq_ptr();
test_align_power2();
test_max();
test_container_of();
- test_alloca();
test_div_round_up();
- test_first_word();
- test_close_many();
- test_parse_uid();
- test_strappend();
- test_strstrip();
- test_delete_chars();
- test_in_charset();
- test_hexchar();
- test_unhexchar();
- test_base32hexchar();
- test_unbase32hexchar();
- test_base64char();
- test_unbase64char();
- test_octchar();
- test_unoctchar();
- test_decchar();
- test_undecchar();
- test_unhexmem();
- test_base32hexmem();
- test_unbase32hexmem();
- test_base64mem();
- test_unbase64mem();
- test_cescape();
- test_cunescape();
- test_foreach_word();
- test_foreach_word_quoted();
- test_memdup_multiply();
test_u64log2();
test_protect_errno();
- test_parse_cpu_set();
- test_config_parse_iec_uint64();
- test_strextend();
- test_strrep();
- test_split_pair();
- test_fstab_node_to_udev_node();
- test_get_files_in_directory();
test_in_set();
- test_writing_tmpfile();
- test_hexdump();
test_log2i();
- test_foreach_string();
- test_filename_is_valid();
- test_string_has_cc();
- test_ascii_strlower();
- test_files_same();
- test_is_valid_documentation_url();
- test_file_in_same_dir();
- test_endswith();
- test_endswith_no_case();
- test_close_nointr();
- test_unlink_noerrno();
- test_readlink_and_make_absolute();
- test_ignore_signals();
- test_strshorten();
- test_strjoina();
- test_is_symlink();
- test_search_and_fopen();
- test_search_and_fopen_nulstr();
- test_glob_exists();
test_execute_directory();
- test_parse_proc_cmdline();
test_raw_clone();
- test_same_fd();
- test_uid_ptr();
- test_sparse_write();
- test_shell_escape();
- test_shell_maybe_quote();
- test_tempfn();
- test_strcmp_ptr();
- test_fgetxattrat_fake();
- test_runlevel_to_target();
return 0;
}
diff --git a/src/test/test-web-util.c b/src/test/test-web-util.c
new file mode 100644
index 0000000000..79a3a13af6
--- /dev/null
+++ b/src/test/test-web-util.c
@@ -0,0 +1,39 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+#include "web-util.h"
+
+static void test_is_valid_documentation_url(void) {
+ assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
+ assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
+ assert_se(documentation_url_is_valid("file:/foo/foo"));
+ assert_se(documentation_url_is_valid("man:systemd.special(7)"));
+ assert_se(documentation_url_is_valid("info:bar"));
+
+ assert_se(!documentation_url_is_valid("foo:"));
+ assert_se(!documentation_url_is_valid("info:"));
+ assert_se(!documentation_url_is_valid(""));
+}
+
+int main(int argc, char *argv[]) {
+ test_is_valid_documentation_url();
+
+ return 0;
+}
diff --git a/src/test/test-xattr-util.c b/src/test/test-xattr-util.c
new file mode 100644
index 0000000000..267f29426c
--- /dev/null
+++ b/src/test/test-xattr-util.c
@@ -0,0 +1,69 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fs-util.h"
+#include "macro.h"
+#include "string-util.h"
+#include "xattr-util.h"
+
+static void test_fgetxattrat_fake(void) {
+ char t[] = "/var/tmp/xattrtestXXXXXX";
+ _cleanup_close_ int fd = -1;
+ const char *x;
+ char v[3] = {};
+ int r;
+
+ assert_se(mkdtemp(t));
+ x = strjoina(t, "/test");
+ assert_se(touch(x) >= 0);
+
+ r = setxattr(x, "user.foo", "bar", 3, 0);
+ if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
+ goto cleanup;
+ assert_se(r >= 0);
+
+ fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
+ assert_se(fd >= 0);
+
+ assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
+ assert_se(memcmp(v, "bar", 3) == 0);
+
+ safe_close(fd);
+ fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
+ assert_se(fd >= 0);
+ assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
+
+cleanup:
+ assert_se(unlink(x) >= 0);
+ assert_se(rmdir(t) >= 0);
+}
+
+int main(void) {
+ test_fgetxattrat_fake();
+
+ return 0;
+}
diff --git a/src/udev/Makefile b/src/udev/Makefile
index 8449d56635..1c8fbe52a6 100644
--- a/src/udev/Makefile
+++ b/src/udev/Makefile
@@ -29,7 +29,8 @@ INSTALL_DIRS += \
dist_network_DATA = \
network/99-default.link \
network/80-container-host0.network \
- network/80-container-ve.network
+ network/80-container-ve.network \
+ network/80-container-vz.network
dist_udevrules_DATA += \
rules/50-udev-default.rules \
diff --git a/src/udev/mtd_probe/mtd_probe.h b/src/udev/mtd_probe/mtd_probe.h
index caea5c2693..68e4954537 100644
--- a/src/udev/mtd_probe/mtd_probe.h
+++ b/src/udev/mtd_probe/mtd_probe.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) 2010 - Maxim Levitsky
*
@@ -17,8 +19,6 @@
* Boston, MA 02110-1301 USA
*/
-#pragma once
-
#include <mtd/mtd-user.h>
#include "macro.h"
diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c
index 6a6c5522a7..2a7ba17637 100644
--- a/src/udev/mtd_probe/probe_smartmedia.c
+++ b/src/udev/mtd_probe/probe_smartmedia.c
@@ -73,7 +73,7 @@ void probe_smart_media(int mtd_fd, mtd_info_t* info)
for (offset = 0 ; offset < block_size * spare_count ;
offset += sector_size) {
lseek(mtd_fd, SEEK_SET, offset);
- if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE){
+ if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE) {
cis_found = 1;
break;
}
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 2e6e1d7150..7716516e76 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <macro.h>
/* we can't use DUPLEX_ prefix, as it
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index e712d2ce73..350cd24e9c 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -18,7 +18,6 @@
***/
#include <netinet/ether.h>
-#include <linux/netdevice.h>
#include <systemd/sd-netlink.h>
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index f525fe2116..9df5529d05 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include "libudev.h"
#include "condition.h"
diff --git a/src/udev/scsi_id/scsi.h b/src/udev/scsi_id/scsi.h
index 3bf1a94200..a27a84a40a 100644
--- a/src/udev/scsi_id/scsi.h
+++ b/src/udev/scsi_id/scsi.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* scsi.h
*
@@ -10,8 +12,6 @@
* Free Software Foundation version 2 of the License.
*/
-#pragma once
-
#include <scsi/scsi.h>
struct scsi_ioctl_command {
diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h
index 141b116a88..5c2e1c28ee 100644
--- a/src/udev/scsi_id/scsi_id.h
+++ b/src/udev/scsi_id/scsi_id.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) IBM Corp. 2003
*
@@ -15,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
-
#define MAX_PATH_LEN 512
/*
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 3a3d8a1770..51a55cdbc4 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -177,7 +177,7 @@ static bool test_pointers(struct udev_device *dev,
has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
/* unset has_mt_coordinates if devices claims to have all abs axis */
- if(has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
+ if (has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
has_mt_coordinates = false;
is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props);
has_touch = test_bit(BTN_TOUCH, bitmask_key);
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 8b1bcefe2d..a7be2a4eed 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -27,21 +27,21 @@
* http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
*
* Two character prefixes based on the type of interface:
- * en -- Ethernet
- * sl -- serial line IP (slip)
- * wl -- wlan
- * ww -- wwan
+ * en — Ethernet
+ * sl — serial line IP (slip)
+ * wl — wlan
+ * ww — wwan
*
* Type of names:
- * b<number> -- BCMA bus core number
- * c<bus_id> -- CCW bus group name, without leading zeros [s390]
- * o<index>[d<dev_port>] -- on-board device index number
- * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number
- * x<MAC> -- MAC address
+ * b<number> — BCMA bus core number
+ * c<bus_id> — CCW bus group name, without leading zeros [s390]
+ * o<index>[d<dev_port>] — on-board device index number
+ * s<slot>[f<function>][d<dev_port>] — hotplug slot index number
+ * x<MAC> — MAC address
* [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
- * -- PCI geographical location
+ * — PCI geographical location
* [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
- * -- USB port number chain
+ * — USB port number chain
*
* All multi-function PCI devices will carry the [f<function>] number in the
* device name, including the function 0 device.
@@ -140,9 +140,9 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
const char *attr;
int idx;
- /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
+ /* ACPI _DSM — device specific method for naming a PCI or PCI Express device */
attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
- /* SMBIOS type 41 -- Onboard Devices Extended Information */
+ /* SMBIOS type 41 — Onboard Devices Extended Information */
if (!attr)
attr = udev_device_get_sysattr_value(names->pcidev, "index");
if (!attr)
@@ -230,7 +230,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
if (l == 0)
names->pci_path[0] = '\0';
- /* ACPI _SUN -- slot user number */
+ /* ACPI _SUN — slot user number */
pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
if (!pci) {
err = -ENOENT;
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index b6ed45d8ba..6e9adc6e96 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -712,7 +712,7 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
* devices do not expose their buses and do not provide a unique
* and predictable name that way.
*/
- if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport)
+ if (streq_ptr(udev_device_get_subsystem(dev), "block") && !supported_transport)
path = mfree(path);
if (path != NULL) {
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index 962de22f43..f68a09d7a8 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -105,7 +105,7 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
uctrl->saddr.un.sun_family = AF_LOCAL;
strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control");
- uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.un.sun_path);
+ uctrl->addrlen = SOCKADDR_UN_LEN(uctrl->saddr.un);
return uctrl;
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index c06ace09cf..26fa52cf6c 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -33,9 +33,11 @@
#include "conf-files.h"
#include "escape.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "glob-util.h"
#include "path-util.h"
#include "stat-util.h"
+#include "stdio-util.h"
#include "strbuf.h"
#include "string-util.h"
#include "strv.h"
@@ -327,8 +329,8 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
enum token_type type = token->type;
enum operation_type op = token->key.op;
enum string_glob_type glob = token->key.glob;
- const char *value = str(rules, token->key.value_off);
- const char *attr = &rules->buf[token->key.attr_off];
+ const char *value = rules_str(rules, token->key.value_off);
+ const char *attr = &rules->strbuf->buf[token->key.attr_off];
switch (type) {
case TK_RULE:
@@ -338,9 +340,9 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token);
log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'",
- &rules->buf[token->rule.filename_off], token->rule.filename_line,
+ &rules->strbuf->buf[token->rule.filename_off], token->rule.filename_line,
idx, token->rule.token_count,
- &rules->buf[token->rule.label_off]);
+ &rules->strbuf->buf[token->rule.label_off]);
break;
}
case TK_M_ACTION:
@@ -437,11 +439,11 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
static void dump_rules(struct udev_rules *rules) {
unsigned int i;
- log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings",
+ log_debug("dumping %u (%zu bytes) tokens, %zu (%zu bytes) strings",
rules->token_cur,
rules->token_cur * sizeof(struct token),
- rules->buf_count,
- rules->buf_cur);
+ rules->strbuf->nodes_count,
+ rules->strbuf->len);
for (i = 0; i < rules->token_cur; i++)
dump_token(rules, &rules->tokens[i]);
}
@@ -686,41 +688,31 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
return 0;
}
-static int attr_subst_subdir(char *attr, size_t len) {
- bool found = false;
+static void attr_subst_subdir(char *attr, size_t len) {
+ const char *pos, *tail, *path;
+ _cleanup_closedir_ DIR *dir = NULL;
+ struct dirent *dent;
- if (strstr(attr, "/*/")) {
- char *pos;
- char dirname[UTIL_PATH_SIZE];
- const char *tail;
- DIR *dir;
+ pos = strstr(attr, "/*/");
+ if (!pos)
+ return;
- strscpy(dirname, sizeof(dirname), attr);
- pos = strstr(dirname, "/*/");
- if (pos == NULL)
- return -1;
- pos[0] = '\0';
- tail = &pos[2];
- dir = opendir(dirname);
- if (dir != NULL) {
- struct dirent *dent;
+ tail = pos + 2;
+ path = strndupa(attr, pos - attr + 1); /* include slash at end */
+ dir = opendir(path);
+ if (dir == NULL)
+ return;
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- struct stat stats;
+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir))
+ if (dent->d_name[0] != '.') {
+ char n[strlen(dent->d_name) + strlen(tail) + 1];
- if (dent->d_name[0] == '.')
- continue;
- strscpyl(attr, len, dirname, "/", dent->d_name, tail, NULL);
- if (stat(attr, &stats) == 0) {
- found = true;
- break;
- }
+ strscpyl(n, sizeof n, dent->d_name, tail, NULL);
+ if (faccessat(dirfd(dir), n, F_OK, 0) == 0) {
+ strscpyl(attr, len, path, n, NULL);
+ break;
}
- closedir(dir);
}
- }
-
- return found;
}
static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) {
@@ -831,12 +823,13 @@ static const char *get_key_attribute(struct udev *udev, char *str) {
return NULL;
}
-static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
- enum operation_type op,
- const char *value, const void *data) {
- struct token *token = &rule_tmp->token[rule_tmp->token_cur];
+static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
+ enum operation_type op,
+ const char *value, const void *data) {
+ struct token *token = rule_tmp->token + rule_tmp->token_cur;
const char *attr = NULL;
+ assert(rule_tmp->token_cur < ELEMENTSOF(rule_tmp->token));
memzero(token, sizeof(struct token));
switch (type) {
@@ -919,8 +912,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_M_MAX:
case TK_END:
case TK_UNSET:
- log_error("wrong type %u", type);
- return -1;
+ assert_not_reached("wrong type");
}
if (value != NULL && type < TK_M_MAX) {
@@ -969,11 +961,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
token->key.type = type;
token->key.op = op;
rule_tmp->token_cur++;
- if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) {
- log_error("temporary rule array too small");
- return -1;
- }
- return 0;
}
static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) {
@@ -1010,8 +997,13 @@ static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) {
return 0;
}
-static int add_rule(struct udev_rules *rules, char *line,
- const char *filename, unsigned int filename_off, unsigned int lineno) {
+#define LOG_RULE_ERROR(fmt, ...) log_error("Invalid rule %s:%u: " fmt, filename, lineno, ##__VA_ARGS__)
+#define LOG_RULE_WARNING(fmt, ...) log_warning("%s:%u: " fmt, filename, lineno, ##__VA_ARGS__)
+#define LOG_RULE_DEBUG(fmt, ...) log_debug("%s:%u: " fmt, filename, lineno, ##__VA_ARGS__)
+#define LOG_AND_RETURN(fmt, ...) { LOG_RULE_ERROR(fmt, __VA_ARGS__); return; }
+
+static void add_rule(struct udev_rules *rules, char *line,
+ const char *filename, unsigned int filename_off, unsigned int lineno) {
char *linepos;
const char *attr;
struct rule_tmp rule_tmp = {
@@ -1052,427 +1044,322 @@ static int add_rule(struct udev_rules *rules, char *line,
break;
}
+ if (rule_tmp.token_cur >= ELEMENTSOF(rule_tmp.token))
+ LOG_AND_RETURN("temporary rule array too small, aborting event processing with %u items", rule_tmp.token_cur);
+
if (streq(key, "ACTION")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid ACTION operation");
- goto invalid;
- }
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL);
- continue;
- }
- if (streq(key, "DEVPATH")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid DEVPATH operation");
- goto invalid;
- }
+ } else if (streq(key, "DEVPATH")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL);
- continue;
- }
- if (streq(key, "KERNEL")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid KERNEL operation");
- goto invalid;
- }
+ } else if (streq(key, "KERNEL")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL);
- continue;
- }
- if (streq(key, "SUBSYSTEM")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid SUBSYSTEM operation");
- goto invalid;
- }
+ } else if (streq(key, "SUBSYSTEM")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
/* bus, class, subsystem events should all be the same */
- if (streq(value, "subsystem") ||
- streq(value, "bus") ||
- streq(value, "class")) {
- if (streq(value, "bus") || streq(value, "class"))
- log_error("'%s' must be specified as 'subsystem' "
- "please fix it in %s:%u", value, filename, lineno);
+ if (STR_IN_SET(value, "subsystem", "bus", "class")) {
+ if (!streq(value, "subsystem"))
+ LOG_RULE_WARNING("'%s' must be specified as 'subsystem'; please fix", value);
+
rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL);
} else
rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, value, NULL);
- continue;
- }
- if (streq(key, "DRIVER")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid DRIVER operation");
- goto invalid;
- }
+ } else if (streq(key, "DRIVER")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL);
- continue;
- }
- if (startswith(key, "ATTR{")) {
+ } else if (startswith(key, "ATTR{")) {
attr = get_key_attribute(rules->udev, key + strlen("ATTR"));
- if (attr == NULL) {
- log_error("error parsing ATTR attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid ATTR operation");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ATTR");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "ATTR");
+
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr);
else
rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr);
- continue;
- }
- if (startswith(key, "SYSCTL{")) {
+ } else if (startswith(key, "SYSCTL{")) {
attr = get_key_attribute(rules->udev, key + strlen("SYSCTL"));
- if (attr == NULL) {
- log_error("error parsing SYSCTL attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid SYSCTL operation");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ATTR");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "ATTR");
+
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_SYSCTL, op, value, attr);
else
rule_add_key(&rule_tmp, TK_A_SYSCTL, op, value, attr);
- continue;
- }
- if (startswith(key, "SECLABEL{")) {
+ } else if (startswith(key, "SECLABEL{")) {
attr = get_key_attribute(rules->udev, key + strlen("SECLABEL"));
- if (!attr) {
- log_error("error parsing SECLABEL attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid SECLABEL operation");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "SECLABEL");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "SECLABEL");
rule_add_key(&rule_tmp, TK_A_SECLABEL, op, value, attr);
- continue;
- }
- if (streq(key, "KERNELS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid KERNELS operation");
- goto invalid;
- }
+ } else if (streq(key, "KERNELS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL);
- continue;
- }
- if (streq(key, "SUBSYSTEMS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid SUBSYSTEMS operation");
- goto invalid;
- }
+ } else if (streq(key, "SUBSYSTEMS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL);
- continue;
- }
- if (streq(key, "DRIVERS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid DRIVERS operation");
- goto invalid;
- }
+ } else if (streq(key, "DRIVERS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL);
- continue;
- }
- if (startswith(key, "ATTRS{")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid ATTRS operation");
- goto invalid;
- }
+ } else if (startswith(key, "ATTRS{")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", "ATTRS");
+
attr = get_key_attribute(rules->udev, key + strlen("ATTRS"));
- if (attr == NULL) {
- log_error("error parsing ATTRS attribute");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ATTRS");
+
if (startswith(attr, "device/"))
- log_error("the 'device' link may not be available in a future kernel, "
- "please fix it in %s:%u", filename, lineno);
- else if (strstr(attr, "../") != NULL)
- log_error("do not reference parent sysfs directories directly, "
- "it may break with a future kernel, please fix it in %s:%u", filename, lineno);
+ LOG_RULE_WARNING("'device' link may not be available in future kernels; please fix");
+ if (strstr(attr, "../") != NULL)
+ LOG_RULE_WARNING("direct reference to parent sysfs directory, may break in future kernels; please fix");
rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr);
- continue;
- }
- if (streq(key, "TAGS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid TAGS operation");
- goto invalid;
- }
+ } else if (streq(key, "TAGS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
- continue;
- }
- if (startswith(key, "ENV{")) {
+ } else if (startswith(key, "ENV{")) {
attr = get_key_attribute(rules->udev, key + strlen("ENV"));
- if (attr == NULL) {
- log_error("error parsing ENV attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid ENV operation");
- goto invalid;
- }
- if (op < OP_MATCH_MAX) {
- if (rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr) != 0)
- goto invalid;
- } else {
- static const char *blacklist[] = {
- "ACTION",
- "SUBSYSTEM",
- "DEVTYPE",
- "MAJOR",
- "MINOR",
- "DRIVER",
- "IFINDEX",
- "DEVNAME",
- "DEVLINKS",
- "DEVPATH",
- "TAGS",
- };
- unsigned int i;
-
- for (i = 0; i < ELEMENTSOF(blacklist); i++) {
- if (!streq(attr, blacklist[i]))
- continue;
- log_error("invalid ENV attribute, '%s' can not be set %s:%u", attr, filename, lineno);
- goto invalid;
- }
- if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0)
- goto invalid;
- }
- continue;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ENV");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "ENV");
- if (streq(key, "TAG")) {
+ if (op < OP_MATCH_MAX)
+ rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr);
+ else {
+ if (STR_IN_SET(attr,
+ "ACTION",
+ "SUBSYSTEM",
+ "DEVTYPE",
+ "MAJOR",
+ "MINOR",
+ "DRIVER",
+ "IFINDEX",
+ "DEVNAME",
+ "DEVLINKS",
+ "DEVPATH",
+ "TAGS"))
+ LOG_AND_RETURN("invalid ENV attribute, '%s' cannot be set", attr);
+
+ rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr);
+ }
+
+ } else if (streq(key, "TAG")) {
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
else
rule_add_key(&rule_tmp, TK_A_TAG, op, value, NULL);
- continue;
- }
- if (streq(key, "PROGRAM")) {
- if (op == OP_REMOVE) {
- log_error("invalid PROGRAM operation");
- goto invalid;
- }
+ } else if (streq(key, "PROGRAM")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL);
- continue;
- }
- if (streq(key, "RESULT")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid RESULT operation");
- goto invalid;
- }
+ } else if (streq(key, "RESULT")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL);
- continue;
- }
- if (startswith(key, "IMPORT")) {
+ } else if (startswith(key, "IMPORT")) {
attr = get_key_attribute(rules->udev, key + strlen("IMPORT"));
if (attr == NULL) {
- log_error("IMPORT{} type missing, ignoring IMPORT %s:%u", filename, lineno);
+ LOG_RULE_WARNING("ignoring IMPORT{} with missing type");
continue;
}
- if (op == OP_REMOVE) {
- log_error("invalid IMPORT operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "IMPORT");
+
if (streq(attr, "program")) {
/* find known built-in command */
if (value[0] != '/') {
- enum udev_builtin_cmd cmd;
+ const enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
- cmd = udev_builtin_lookup(value);
if (cmd < UDEV_BUILTIN_MAX) {
- log_debug("IMPORT found builtin '%s', replacing %s:%u",
- value, filename, lineno);
+ LOG_RULE_DEBUG("IMPORT found builtin '%s', replacing", value);
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
continue;
}
}
rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL);
} else if (streq(attr, "builtin")) {
- enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
+ const enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
- if (cmd < UDEV_BUILTIN_MAX)
- rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
+ if (cmd >= UDEV_BUILTIN_MAX)
+ LOG_RULE_WARNING("IMPORT{builtin} '%s' unknown", value);
else
- log_error("IMPORT{builtin}: '%s' unknown %s:%u", value, filename, lineno);
- } else if (streq(attr, "file")) {
+ rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
+ } else if (streq(attr, "file"))
rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL);
- } else if (streq(attr, "db")) {
+ else if (streq(attr, "db"))
rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL);
- } else if (streq(attr, "cmdline")) {
+ else if (streq(attr, "cmdline"))
rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL);
- } else if (streq(attr, "parent")) {
+ else if (streq(attr, "parent"))
rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL);
- } else
- log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u", filename, lineno);
- continue;
- }
+ else
+ LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "IMPORT", attr);
- if (startswith(key, "TEST")) {
+ } else if (startswith(key, "TEST")) {
mode_t mode = 0;
- if (op > OP_MATCH_MAX) {
- log_error("invalid TEST operation");
- goto invalid;
- }
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", "TEST");
+
attr = get_key_attribute(rules->udev, key + strlen("TEST"));
if (attr != NULL) {
mode = strtol(attr, NULL, 8);
rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode);
- } else {
+ } else
rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL);
- }
- continue;
- }
- if (startswith(key, "RUN")) {
+ } else if (startswith(key, "RUN")) {
attr = get_key_attribute(rules->udev, key + strlen("RUN"));
if (attr == NULL)
attr = "program";
- if (op == OP_REMOVE) {
- log_error("invalid RUN operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "RUN");
if (streq(attr, "builtin")) {
- enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
+ const enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
if (cmd < UDEV_BUILTIN_MAX)
rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd);
else
- log_error("RUN{builtin}: '%s' unknown %s:%u", value, filename, lineno);
+ LOG_RULE_ERROR("RUN{builtin}: '%s' unknown", value);
} else if (streq(attr, "program")) {
- enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
+ const enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
- } else {
- log_error("RUN{} unknown type, ignoring RUN %s:%u", filename, lineno);
- }
+ } else
+ LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "RUN", attr);
- continue;
- }
+ } else if (streq(key, "LABEL")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
- if (streq(key, "LABEL")) {
- if (op == OP_REMOVE) {
- log_error("invalid LABEL operation");
- goto invalid;
- }
rule_tmp.rule.rule.label_off = rules_add_string(rules, value);
- continue;
- }
- if (streq(key, "GOTO")) {
- if (op == OP_REMOVE) {
- log_error("invalid GOTO operation");
- goto invalid;
- }
+ } else if (streq(key, "GOTO")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL);
- continue;
- }
- if (startswith(key, "NAME")) {
- if (op == OP_REMOVE) {
- log_error("invalid NAME operation");
- goto invalid;
- }
- if (op < OP_MATCH_MAX) {
+ } else if (startswith(key, "NAME")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
+ if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL);
- } else {
+ else {
if (streq(value, "%k")) {
- log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, "
- "please remove it from %s:%u\n", filename, lineno);
+ LOG_RULE_WARNING("NAME=\"%%k\" is ignored, because it breaks kernel supplied names; please remove");
continue;
}
- if (value[0] == '\0') {
- log_debug("NAME=\"\" is ignored, because udev will not delete any device nodes, "
- "please remove it from %s:%u\n", filename, lineno);
+ if (isempty(value)) {
+ LOG_RULE_DEBUG("NAME=\"\" is ignored, because udev will not delete any device nodes; please remove");
continue;
}
rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
}
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "SYMLINK")) {
- if (op == OP_REMOVE) {
- log_error("invalid SYMLINK operation");
- goto invalid;
- }
+ } else if (streq(key, "SYMLINK")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
else
rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "OWNER")) {
+ } else if (streq(key, "OWNER")) {
uid_t uid;
char *endptr;
- if (op == OP_REMOVE) {
- log_error("invalid OWNER operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
uid = strtoul(value, &endptr, 10);
- if (endptr[0] == '\0') {
+ if (endptr[0] == '\0')
rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
- } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+ else if (rules->resolve_names > 0 && strchr("$%", value[0]) == NULL) {
uid = add_uid(rules, value);
rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
} else if (rules->resolve_names >= 0)
rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "GROUP")) {
+ } else if (streq(key, "GROUP")) {
gid_t gid;
char *endptr;
- if (op == OP_REMOVE) {
- log_error("invalid GROUP operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
gid = strtoul(value, &endptr, 10);
- if (endptr[0] == '\0') {
+ if (endptr[0] == '\0')
rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
- } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+ else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
gid = add_gid(rules, value);
rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
} else if (rules->resolve_names >= 0)
rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "MODE")) {
+ } else if (streq(key, "MODE")) {
mode_t mode;
char *endptr;
- if (op == OP_REMOVE) {
- log_error("invalid MODE operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
mode = strtol(value, &endptr, 8);
if (endptr[0] == '\0')
@@ -1480,27 +1367,23 @@ static int add_rule(struct udev_rules *rules, char *line,
else
rule_add_key(&rule_tmp, TK_A_MODE, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "OPTIONS")) {
+ } else if (streq(key, "OPTIONS")) {
const char *pos;
- if (op == OP_REMOVE) {
- log_error("invalid OPTIONS operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
pos = strstr(value, "link_priority=");
if (pos != NULL) {
- int prio = atoi(&pos[strlen("link_priority=")]);
+ int prio = atoi(pos + strlen("link_priority="));
rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
}
pos = strstr(value, "string_escape=");
if (pos != NULL) {
- pos = &pos[strlen("string_escape=")];
+ pos += strlen("string_escape=");
if (startswith(pos, "none"))
rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL);
else if (startswith(pos, "replace"))
@@ -1527,30 +1410,19 @@ static int add_rule(struct udev_rules *rules, char *line,
pos = strstr(value, "static_node=");
if (pos != NULL) {
- rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, &pos[strlen("static_node=")], NULL);
+ pos += strlen("static_node=");
+ rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, pos, NULL);
rule_tmp.rule.rule.has_static_node = true;
}
- continue;
- }
-
- log_error("unknown key '%s' in %s:%u", key, filename, lineno);
- goto invalid;
+ } else
+ LOG_AND_RETURN("unknown key '%s'", key);
}
- /* add rule token */
+ /* add rule token and sort tokens */
rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur;
- if (add_token(rules, &rule_tmp.rule) != 0)
- goto invalid;
-
- /* add tokens to list, sorted by type */
- if (sort_token(rules, &rule_tmp) != 0)
- goto invalid;
-
- return 0;
-invalid:
- log_error("invalid rule '%s:%u'", filename, lineno);
- return -1;
+ if (add_token(rules, &rule_tmp.rule) != 0 || sort_token(rules, &rule_tmp) != 0)
+ LOG_RULE_ERROR("failed to add rule token");
}
static int parse_file(struct udev_rules *rules, const char *filename) {
@@ -1849,18 +1721,18 @@ enum escape_type {
ESCAPE_REPLACE,
};
-int udev_rules_apply_to_event(struct udev_rules *rules,
- struct udev_event *event,
- usec_t timeout_usec,
- usec_t timeout_warn_usec,
- struct udev_list *properties_list) {
+void udev_rules_apply_to_event(struct udev_rules *rules,
+ struct udev_event *event,
+ usec_t timeout_usec,
+ usec_t timeout_warn_usec,
+ struct udev_list *properties_list) {
struct token *cur;
struct token *rule;
enum escape_type esc = ESCAPE_UNSET;
bool can_set_name;
if (rules->tokens == NULL)
- return -1;
+ return;
can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
(major(udev_device_get_devnum(event->dev)) > 0 ||
@@ -2168,7 +2040,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
break;
}
case TK_M_IMPORT_CMDLINE: {
- FILE *f;
+ _cleanup_fclose_ FILE *f = NULL;
bool imported = false;
f = fopen("/proc/cmdline", "re");
@@ -2181,12 +2053,12 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
pos = strstr(cmdline, key);
if (pos != NULL) {
+ imported = true;
pos += strlen(key);
- if (pos[0] == '\0' || isspace(pos[0])) {
+ if (pos[0] == '\0' || isspace(pos[0]))
/* we import simple flags as 'FLAG=1' */
udev_device_add_property(event->dev, key, "1");
- imported = true;
- } else if (pos[0] == '=') {
+ else if (pos[0] == '=') {
const char *value;
pos++;
@@ -2195,11 +2067,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
pos++;
pos[0] = '\0';
udev_device_add_property(event->dev, key, value);
- imported = true;
}
}
}
- fclose(f);
}
if (!imported && cur->key.op != OP_NOMATCH)
goto nomatch;
@@ -2428,13 +2298,17 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
log_debug("%i character(s) replaced", count);
}
if (major(udev_device_get_devnum(event->dev)) &&
- (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) {
- log_error("NAME=\"%s\" ignored, kernel device nodes "
- "can not be renamed; please fix it in %s:%u\n", name,
- rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
+ !streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/"))) {
+ log_error("NAME=\"%s\" ignored, kernel device nodes cannot be renamed; please fix it in %s:%u\n",
+ name,
+ rules_str(rules, rule->rule.filename_off),
+ rule->rule.filename_line);
break;
}
- free_and_strdup(&event->name, name_str);
+ if (free_and_strdup(&event->name, name_str) < 0) {
+ log_oom();
+ return;
+ }
log_debug("NAME '%s' %s:%u",
event->name,
rules_str(rules, rule->rule.filename_off),
@@ -2491,7 +2365,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
const char *key_name = rules_str(rules, cur->key.attr_off);
char attr[UTIL_PATH_SIZE];
char value[UTIL_NAME_SIZE];
- FILE *f;
+ _cleanup_fclose_ FILE *f = NULL;
if (util_resolve_subsys_kernel(event->udev, key_name, attr, sizeof(attr), 0) != 0)
strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL);
@@ -2502,13 +2376,10 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
f = fopen(attr, "we");
- if (f != NULL) {
- if (fprintf(f, "%s", value) <= 0)
- log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
- fclose(f);
- } else {
+ if (f == NULL)
log_error_errno(errno, "error opening ATTR{%s} for writing: %m", attr);
- }
+ else if (fprintf(f, "%s", value) <= 0)
+ log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
break;
}
case TK_A_SYSCTL: {
@@ -2546,7 +2417,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
cur = &rules->tokens[cur->key.rule_goto];
continue;
case TK_END:
- return 0;
+ return;
case TK_M_PARENTS_MIN:
case TK_M_PARENTS_MAX:
@@ -2574,7 +2445,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
char **t;
FILE *f = NULL;
_cleanup_free_ char *path = NULL;
- int r = 0;
+ int r;
if (rules->tokens == NULL)
return 0;
@@ -2645,8 +2516,6 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
if (r < 0 && errno != EEXIST)
return log_error_errno(errno, "failed to create symlink %s -> %s: %m",
tag_symlink, device_node);
- else
- r = 0;
}
}
@@ -2698,12 +2567,11 @@ finish:
fflush(f);
fchmod(fileno(f), 0644);
if (ferror(f) || rename(path, "/run/udev/static_node-tags") < 0) {
- r = -errno;
- unlink("/run/udev/static_node-tags");
- unlink(path);
+ unlink_noerrno("/run/udev/static_node-tags");
+ unlink_noerrno(path);
+ return -errno;
}
- fclose(f);
}
- return r;
+ return 0;
}
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index f9cb5e63a2..c0ef073476 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -40,7 +40,7 @@ static void sig_handler(int signum) {
static void print_device(struct udev_device *device, const char *source, int prop) {
struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
printf("%-6s[%"PRI_TIME".%06ld] %-8s %s (%s)\n",
source,
ts.tv_sec, ts.tv_nsec/1000,
@@ -100,7 +100,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
udev_list_init(udev, &subsystem_match_list, true);
udev_list_init(udev, &tag_match_list, true);
- while((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0)
switch (c) {
case 'p':
case 'e':
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index ff427cf292..702dbe5282 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -61,7 +61,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
log_debug("version %s", VERSION);
- while((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
switch (c) {
case 'a':
action = optarg;
diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h
index 37e4fe8369..dc712b0d93 100644
--- a/src/udev/udevadm-util.h
+++ b/src/udev/udevadm-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) 2014 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
*
@@ -15,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
-
#include "udev.h"
struct udev_device *find_device(struct udev *udev,
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index 7bd2c1ea42..a6a873e5de 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -93,7 +93,7 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- mac_selinux_init("/dev");
+ mac_selinux_init();
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 37489c6ce7..89006e6e3a 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -400,10 +400,11 @@ static void worker_spawn(Manager *manager, struct event *event) {
goto out;
}
- /* request TERM signal if parent exits */
- prctl(PR_SET_PDEATHSIG, SIGTERM);
+ /* Request TERM signal if parent exits.
+ Ignore error, not much we can do in that case. */
+ (void) prctl(PR_SET_PDEATHSIG, SIGTERM);
- /* reset OOM score, we only protect the main daemon */
+ /* Reset OOM score, we only protect the main daemon. */
write_string_file("/proc/self/oom_score_adj", "0", 0);
for (;;) {
@@ -1695,7 +1696,7 @@ int main(int argc, char *argv[]) {
umask(022);
- r = mac_selinux_init("/dev");
+ r = mac_selinux_init();
if (r < 0) {
log_error_errno(r, "could not initialize labelling: %m");
goto exit;
diff --git a/sysusers.d/systemd.conf.m4 b/sysusers.d/systemd.conf.m4
index 317240a9fd..af97509c05 100644
--- a/sysusers.d/systemd.conf.m4
+++ b/sysusers.d/systemd.conf.m4
@@ -6,7 +6,6 @@
# (at your option) any later version.
g systemd-journal - -
-u systemd-bus-proxy - "systemd Bus Proxy"
m4_ifdef(`ENABLE_NETWORKD',
u systemd-network - "systemd Network Management"
)m4_dnl
diff --git a/test/Makefile b/test/Makefile
index 36298f2b25..bc794e0d6c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -26,19 +26,17 @@ include $(topsrcdir)/build-aux/Makefile.head.mk
manual_tests += \
test-ns \
- test-loopback \
- test-hostname \
- test-daemon \
test-cgroup \
test-install \
- test-watchdog \
- test-log \
- test-ipcrm \
test-btrfs \
test-acd \
test-ipv4ll-manual \
test-ask-password-api
+unsafe_tests = \
+ test-hostname \
+ test-ipcrm
+
ifneq ($(HAVE_LIBIPTC),)
manual_tests += \
test-firewall-util
@@ -50,10 +48,14 @@ manual_tests += \
endif # HAVE_KMOD
tests += \
+ test-daemon \
+ test-log \
+ test-loopback \
test-engine \
+ test-watchdog \
test-cgroup-mask \
test-job-type \
- test-env-replace \
+ test-env-util \
test-strbuf \
test-strv \
test-path \
@@ -65,6 +67,18 @@ tests += \
test-utf8 \
test-ellipsize \
test-util \
+ test-cpu-set-util \
+ test-hexdecoct \
+ test-escape \
+ test-alloc-util \
+ test-proc-cmdline \
+ test-io-util \
+ test-glob-util \
+ test-xattr-util \
+ test-fs-util \
+ test-web-util \
+ test-stat-util \
+ test-fd-util \
test-string-util \
test-extract-word \
test-parse-util \
@@ -87,6 +101,7 @@ tests += \
test-prioq \
test-fileio \
test-time \
+ test-clock \
test-hashmap \
test-set \
test-bitmap \
@@ -95,7 +110,6 @@ tests += \
test-tables \
test-device-nodes \
test-xml \
- test-json \
test-architecture \
test-socket-util \
test-fdset \
@@ -106,21 +120,20 @@ tests += \
test-ratelimit \
test-condition \
test-uid-range \
- test-bus-policy \
test-locale-util \
test-execute \
test-copy \
test-cap-list \
test-sigbus \
- test-rbtree \
test-verbs \
test-af-list \
test-arphrd-list \
test-dns-domain \
- test-resolve-tables \
test-install-root \
test-rlimit-util \
- test-signal-util
+ test-signal-util \
+ test-selinux \
+ test-sizeof
ifneq ($(HAVE_ACL),)
tests += \
@@ -183,6 +196,7 @@ EXTRA_DIST += \
test/test-execute/exec-passenvironment-repeated.service \
test/test-execute/exec-passenvironment.service \
test/test-execute/exec-group.service \
+ test/test-execute/exec-group-nfsnobody.service \
test/test-execute/exec-ignoresigpipe-no.service \
test/test-execute/exec-ignoresigpipe-yes.service \
test/test-execute/exec-personality-x86-64.service \
@@ -192,12 +206,16 @@ EXTRA_DIST += \
test/test-execute/exec-privatedevices-yes.service \
test/test-execute/exec-privatetmp-no.service \
test/test-execute/exec-privatetmp-yes.service \
+ test/test-execute/exec-spec-interpolation.service \
test/test-execute/exec-systemcallerrornumber.service \
test/test-execute/exec-systemcallfilter-failing2.service \
test/test-execute/exec-systemcallfilter-failing.service \
test/test-execute/exec-systemcallfilter-not-failing2.service \
test/test-execute/exec-systemcallfilter-not-failing.service \
+ test/test-execute/exec-systemcallfilter-system-user.service \
+ test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service \
test/test-execute/exec-user.service \
+ test/test-execute/exec-user-nfsnobody.service \
test/test-execute/exec-workingdirectory.service \
test/test-execute/exec-umask-0177.service \
test/test-execute/exec-umask-default.service \
@@ -213,6 +231,14 @@ EXTRA_DIST += \
test/test-execute/exec-capabilityboundingset-merge.service \
test/test-execute/exec-capabilityboundingset-reset.service \
test/test-execute/exec-capabilityboundingset-simple.service \
+ test/test-execute/exec-capabilityambientset.service \
+ test/test-execute/exec-capabilityambientset-nfsnobody.service \
+ test/test-execute/exec-capabilityambientset-merge.service \
+ test/test-execute/exec-capabilityambientset-merge-nfsnobody.service \
+ test/test-execute/exec-runtimedirectory.service \
+ test/test-execute/exec-runtimedirectory-mode.service \
+ test/test-execute/exec-runtimedirectory-owner.service \
+ test/test-execute/exec-runtimedirectory-owner-nfsnobody.service \
test/bus-policy/hello.conf \
test/bus-policy/methods.conf \
test/bus-policy/ownerships.conf \
@@ -282,25 +308,15 @@ test_dns_domain_LDADD = \
libsystemd-network.la \
libshared.la
-test_resolve_tables_SOURCES = \
- src/resolve/test-resolve-tables.c \
- src/shared/test-tables.h \
- src/resolve/dns-type.c \
- src/resolve/dns-type.h \
- src/resolve/dns_type-from-name.h \
- src/resolve/dns_type-to-name.h
-
-test_resolve_tables_LDADD = \
- libshared.la
ifneq ($(ENABLE_EFI),)
-manual_tests += \
- test-boot-timestamp
+tests += \
+ test-boot-timestamps
-test_boot_timestamp_SOURCES = \
+test_boot_timestamps_SOURCES = \
src/test/test-boot-timestamps.c
-test_boot_timestamp_LDADD = \
+test_boot_timestamps_LDADD = \
libshared.la
endif # ENABLE_EFI
@@ -362,12 +378,6 @@ test_sigbus_SOURCES = \
test_sigbus_LDADD = \
libshared.la
-test_rbtree_SOURCES = \
- src/test/test-rbtree.c
-
-test_rbtree_LDADD = \
- libshared.la
-
test_condition_SOURCES = \
src/test/test-condition.c
@@ -398,6 +408,78 @@ test_util_SOURCES = \
test_util_LDADD = \
libshared.la
+test_hexdecoct_SOURCES = \
+ src/test/test-hexdecoct.c
+
+test_hexdecoct_LDADD = \
+ libbasic.la
+
+test_alloc_util_SOURCES = \
+ src/test/test-alloc-util.c
+
+test_alloc_util_LDADD = \
+ libbasic.la
+
+test_xattr_util_SOURCES = \
+ src/test/test-xattr-util.c
+
+test_xattr_util_LDADD = \
+ libbasic.la
+
+test_io_util_SOURCES = \
+ src/test/test-io-util.c
+
+test_io_util_LDADD = \
+ libbasic.la
+
+test_glob_util_SOURCES = \
+ src/test/test-glob-util.c
+
+test_glob_util_LDADD = \
+ libbasic.la
+
+test_fs_util_SOURCES = \
+ src/test/test-fs-util.c
+
+test_fs_util_LDADD = \
+ libbasic.la
+
+test_proc_cmdline_SOURCES = \
+ src/test/test-proc-cmdline.c
+
+test_proc_cmdline_LDADD = \
+ libbasic.la
+
+test_fd_util_SOURCES = \
+ src/test/test-fd-util.c
+
+test_fd_util_LDADD = \
+ libbasic.la
+
+test_web_util_SOURCES = \
+ src/test/test-web-util.c
+
+test_web_util_LDADD = \
+ libbasic.la
+
+test_cpu_set_util_SOURCES = \
+ src/test/test-cpu-set-util.c
+
+test_cpu_set_util_LDADD = \
+ libbasic.la
+
+test_stat_util_SOURCES = \
+ src/test/test-stat-util.c
+
+test_stat_util_LDADD = \
+ libbasic.la
+
+test_escape_SOURCES = \
+ src/test/test-escape.c
+
+test_escape_LDADD = \
+ libbasic.la
+
test_string_util_SOURCES = \
src/test/test-string-util.c
@@ -518,6 +600,18 @@ test_signal_util_SOURCES = \
test_signal_util_LDADD = \
libshared.la
+test_selinux_SOURCES = \
+ src/test/test-selinux.c
+
+test_selinux_LDADD = \
+ libshared.la
+
+test_sizeof_SOURCES = \
+ src/test/test-sizeof.c
+
+test_sizeof_LDADD = \
+ libshared.la
+
BUILT_SOURCES += \
src/test/test-hashmap-ordered.c
@@ -558,12 +652,6 @@ test_xml_SOURCES = \
test_xml_LDADD = \
libshared.la
-test_json_SOURCES = \
- src/test/test-json.c
-
-test_json_LDADD = \
- libshared.la
-
test_list_SOURCES = \
src/test/test-list.c
@@ -579,14 +667,11 @@ test_unaligned_SOURCES = \
test_tables_SOURCES = \
src/test/test-tables.c \
src/shared/test-tables.h \
- src/bus-proxyd/bus-xml-policy.c \
- src/bus-proxyd/bus-xml-policy.h \
src/journal/journald-server.c \
src/journal/journald-server.h
test_tables_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -I$(top_srcdir)/src/bus-proxyd
+ $(AM_CPPFLAGS)
test_tables_CFLAGS = \
$(AM_CFLAGS) \
@@ -616,6 +701,12 @@ test_time_SOURCES = \
test_time_LDADD = \
libshared.la
+test_clock_SOURCES = \
+ src/test/test-clock.c
+
+test_clock_LDADD = \
+ libshared.la
+
test_architecture_SOURCES = \
src/test/test-architecture.c
@@ -733,10 +824,10 @@ test_cgroup_util_SOURCES = \
test_cgroup_util_LDADD = \
libshared.la
-test_env_replace_SOURCES = \
- src/test/test-env-replace.c
+test_env_util_SOURCES = \
+ src/test/test-env-util.c
-test_env_replace_LDADD = \
+test_env_util_LDADD = \
libshared.la
test_strbuf_SOURCES = \
@@ -827,13 +918,6 @@ test_conf_parser_SOURCES = \
test_conf_parser_LDADD = \
libshared.la
-test_bus_policy_SOURCES = \
- src/bus-proxyd/test-bus-xml-policy.c
-
-test_bus_policy_LDADD = \
- libbus-proxy-core.la \
- libshared.la
-
test_af_list_SOURCES = \
src/test/test-af-list.c
diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh
index 6963d8c88d..21eed9b22a 100755
--- a/test/TEST-01-BASIC/test.sh
+++ b/test/TEST-01-BASIC/test.sh
@@ -53,7 +53,7 @@ Description=Testsuite service
After=multi-user.target
[Service]
-ExecStart=/bin/sh -x -c 'systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok'
+ExecStart=/bin/sh -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok'
Type=oneshot
EOF
diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
index 242090c761..aea0fc53f6 100755
--- a/test/TEST-02-CRYPTSETUP/test.sh
+++ b/test/TEST-02-CRYPTSETUP/test.sh
@@ -59,7 +59,7 @@ Description=Testsuite service
After=multi-user.target
[Service]
-ExecStart=/bin/sh -x -c 'systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok'
+ExecStart=/bin/sh -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok'
Type=oneshot
EOF
diff --git a/test/TEST-07-ISSUE-1981/test.sh b/test/TEST-07-ISSUE-1981/test.sh
index dcb6ece4d4..d97c4ec27d 100755
--- a/test/TEST-07-ISSUE-1981/test.sh
+++ b/test/TEST-07-ISSUE-1981/test.sh
@@ -8,7 +8,8 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/1981"
test_run() {
dwarn "skipping QEMU"
if check_nspawn; then
- timeout --foreground 30s systemd-nspawn --kill-signal=SIGKILL --boot --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND
+ NSPAWN_TIMEOUT=30s
+ run_nspawn
check_result_nspawn || return 1
else
dwarn "can't run systemd-nspawn, skipping"
diff --git a/test/TEST-08-ISSUE-2730/test.sh b/test/TEST-08-ISSUE-2730/test.sh
new file mode 100755
index 0000000000..409140157a
--- /dev/null
+++ b/test/TEST-08-ISSUE-2730/test.sh
@@ -0,0 +1,108 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730"
+
+. $TEST_BASE_DIR/test-functions
+SKIP_INITRD=yes
+QEMU_TIMEOUT=180
+FSTYPE=ext4
+
+check_result_qemu() {
+ ret=1
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+ [[ -e $TESTDIR/root/testok ]] && ret=0
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ umount $TESTDIR/root
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
+ ls -l $TESTDIR/journal/*/*.journal
+ test -s $TESTDIR/failed && ret=$(($ret+1))
+ return $ret
+}
+
+test_run() {
+ run_qemu || return 1
+ check_result_qemu || return 1
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/bin/sh -x -c 'mount -o remount,rw /dev/sda1 && echo OK > /testok; systemctl poweroff'
+Type=oneshot
+EOF
+
+ rm $initdir/etc/fstab
+ cat >$initdir/etc/systemd/system/-.mount <<EOF
+[Unit]
+Before=local-fs.target
+
+[Mount]
+What=/dev/sda1
+Where=/
+Type=ext4
+Options=errors=remount-ro,noatime
+
+[Install]
+WantedBy=local-fs.target
+Alias=root.mount
+EOF
+
+ cat >$initdir/etc/systemd/system/systemd-remount-fs.service <<EOF
+[Unit]
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-fsck-root.service
+Before=local-fs-pre.target local-fs.target shutdown.target
+Wants=local-fs-pre.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/systemctl reload /
+EOF
+
+ setup_testsuite
+ ) || return 1
+
+ ln -s /etc/systemd/system/-.mount $initdir/etc/systemd/system/root.mount
+ mkdir -p $initdir/etc/systemd/system/local-fs.target.wants
+ ln -s /etc/systemd/system/-.mount $initdir/etc/systemd/system/local-fs.target.wants/-.mount
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-09-ISSUE-2691/test.sh b/test/TEST-09-ISSUE-2691/test.sh
new file mode 100755
index 0000000000..e247694f01
--- /dev/null
+++ b/test/TEST-09-ISSUE-2691/test.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691"
+
+. $TEST_BASE_DIR/test-functions
+SKIP_INITRD=yes
+QEMU_TIMEOUT=90
+
+check_result_qemu() {
+ ret=1
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+ [[ -e $TESTDIR/root/testok ]] && ret=0
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ umount $TESTDIR/root
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
+ ls -l $TESTDIR/journal/*/*.journal
+ test -s $TESTDIR/failed && ret=$(($ret+1))
+ return $ret
+}
+
+test_run() {
+ run_qemu || return 1
+ check_result_qemu || return 1
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/bin/sh -c '>/testok'
+RemainAfterExit=yes
+ExecStop=/bin/sh -c 'kill -SEGV $$$$'
+TimeoutStopSec=180s
+EOF
+
+ setup_testsuite
+ ) || return 1
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
new file mode 100755
index 0000000000..a652b0d812
--- /dev/null
+++ b/test/TEST-10-ISSUE-2467/test.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
+
+. $TEST_BASE_DIR/test-functions
+SKIP_INITRD=yes
+
+check_result_qemu() {
+ ret=1
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+ [[ -e $TESTDIR/root/testok ]] && ret=0
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ umount $TESTDIR/root
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
+ ls -l $TESTDIR/journal/*/*.journal
+ test -s $TESTDIR/failed && ret=$(($ret+1))
+ return $ret
+}
+
+test_run() {
+ run_qemu || return 1
+ check_result_qemu || return 1
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+ dracut_install nc true rm
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; echo a | nc -U /run/test.ctl; >/testok'
+TimeoutStartSec=10s
+EOF
+
+ cat >$initdir/etc/systemd/system/test.socket <<'EOF'
+[Socket]
+ListenStream=/run/test.ctl
+EOF
+
+ cat > $initdir/etc/systemd/system/test.service <<'EOF'
+[Unit]
+Requires=test.socket
+ConditionPathExistsGlob=/tmp/nonexistent
+
+[Service]
+ExecStart=/bin/true
+EOF
+
+ setup_testsuite
+ ) || return 1
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh
new file mode 100755
index 0000000000..7913537e9b
--- /dev/null
+++ b/test/TEST-11-ISSUE-3166/test.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166"
+
+. $TEST_BASE_DIR/test-functions
+SKIP_INITRD=yes
+
+check_result_qemu() {
+ ret=1
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+ [[ -e $TESTDIR/root/testok ]] && ret=0
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ umount $TESTDIR/root
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
+ ls -l $TESTDIR/journal/*/*.journal
+ test -s $TESTDIR/failed && ret=$(($ret+1))
+ return $ret
+}
+
+test_run() {
+ run_qemu || return 1
+ check_result_qemu || return 1
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+ dracut_install false touch
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/test-fail-on-restart.sh
+Type=oneshot
+EOF
+
+ cat >$initdir/etc/systemd/system/fail-on-restart.service <<EOF
+[Unit]
+Description=Fail on restart
+
+[Service]
+Type=simple
+ExecStart=/bin/false
+Restart=always
+EOF
+
+
+ cat >$initdir/test-fail-on-restart.sh <<'EOF'
+#!/bin/bash -x
+
+systemctl start fail-on-restart.service
+active_state=$(systemctl show --property ActiveState fail-on-restart.service)
+while [[ "$active_state" == "ActiveState=activating" || "$active_state" == "ActiveState=active" ]]; do
+ sleep 1
+ active_state=$(systemctl show --property ActiveState fail-on-restart.service)
+done
+systemctl is-failed fail-on-restart.service || exit 1
+touch /testok
+EOF
+
+ chmod 0755 $initdir/test-fail-on-restart.sh
+ setup_testsuite
+ ) || return 1
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
new file mode 100755
index 0000000000..925dcad9ea
--- /dev/null
+++ b/test/TEST-12-ISSUE-3171/test.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3171"
+
+. $TEST_BASE_DIR/test-functions
+
+test_run() {
+ run_nspawn || return 1
+ check_result_nspawn || return 1
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+ dracut_install cat mv stat nc
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/test-socket-group.sh
+Type=oneshot
+EOF
+
+
+ cat >$initdir/test-socket-group.sh <<'EOF'
+#!/bin/bash
+set -x
+set -e
+set -o pipefail
+
+U=/run/systemd/system/test.socket
+cat <<'EOL' >$U
+[Unit]
+Description=Test socket
+[Socket]
+Accept=yes
+ListenStream=/run/test.socket
+SocketGroup=adm
+SocketMode=0660
+EOL
+
+cat <<'EOL' > /run/systemd/system/test@.service
+[Unit]
+Description=Test service
+[Service]
+StandardInput=socket
+ExecStart=/bin/sh -x -c cat
+EOL
+
+systemctl start test.socket
+systemctl is-active test.socket
+[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
+echo A | nc -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
+
+mv ${U}.disabled $U
+systemctl daemon-reload
+systemctl is-active test.socket
+echo C | nc -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
+[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
+
+
+touch /testok
+EOF
+
+ chmod 0755 $initdir/test-socket-group.sh
+ setup_testsuite
+ ) || return 1
+
+ setup_nspawn_root
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"
diff --git a/test/networkd-test.py b/test/networkd-test.py
index d76ab507d2..d4de5adf1a 100755
--- a/test/networkd-test.py
+++ b/test/networkd-test.py
@@ -5,7 +5,12 @@
# does not write anything on disk or change any system configuration;
# but it assumes (and checks at the beginning) that networkd is not currently
# running.
-# This can be run on a normal installation, in QEMU, nspawn, or LXC.
+#
+# This can be run on a normal installation, in QEMU, nspawn (with
+# --private-network), LXD (with "--config raw.lxc=lxc.aa_profile=unconfined"),
+# or LXC system containers. You need at least the "ip" tool from the iproute
+# package; it is recommended to install dnsmasq too to get full test coverage.
+#
# ATTENTION: This uses the *installed* networkd, not the one from the built
# source tree.
#
diff --git a/test/parent.slice b/test/parent.slice
index 0222f8eb47..a95f90392d 100644
--- a/test/parent.slice
+++ b/test/parent.slice
@@ -2,4 +2,4 @@
Description=Parent Slice
[Slice]
-BlockIOWeight=200
+IOWeight=200
diff --git a/test/sys.tar.xz b/test/sys.tar.xz
index 052c77d182..49ee8027b2 100644
--- a/test/sys.tar.xz
+++ b/test/sys.tar.xz
Binary files differ
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
index aca5f1eec6..838dd57a6f 100644..100755
--- a/test/sysv-generator-test.py
+++ b/test/sysv-generator-test.py
@@ -1,3 +1,5 @@
+#!/usr/bin/python
+#
# systemd-sysv-generator integration test
#
# (C) 2015 Canonical Ltd.
@@ -395,11 +397,12 @@ class SysvGeneratorTest(unittest.TestCase):
# backup files (not enabled in rcN.d/)
shutil.copy(script, script + '.bak')
shutil.copy(script, script + '.old')
+ shutil.copy(script, script + '.tmp')
+ shutil.copy(script, script + '.new')
err, results = self.run_generator()
print(err)
- self.assertEqual(sorted(results),
- ['foo.bak.service', 'foo.old.service', 'foo.service'])
+ self.assertEqual(sorted(results), ['foo.service', 'foo.tmp.service'])
# ensure we don't try to create a symlink to itself
self.assertNotIn('itself', err)
diff --git a/test/test-execute/exec-capabilityambientset-merge-nfsnobody.service b/test/test-execute/exec-capabilityambientset-merge-nfsnobody.service
new file mode 100644
index 0000000000..00bec581b5
--- /dev/null
+++ b/test/test-execute/exec-capabilityambientset-merge-nfsnobody.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Test for AmbientCapabilities
+
+[Service]
+ExecStart=/bin/sh -x -c 'c=$$(grep "CapAmb:" /proc/self/status); test "$$c" = "CapAmb: 0000000000003000"'
+Type=oneshot
+User=nfsnobody
+AmbientCapabilities=CAP_NET_ADMIN
+AmbientCapabilities=CAP_NET_RAW
diff --git a/test/test-execute/exec-capabilityambientset-nfsnobody.service b/test/test-execute/exec-capabilityambientset-nfsnobody.service
new file mode 100644
index 0000000000..614cfdd584
--- /dev/null
+++ b/test/test-execute/exec-capabilityambientset-nfsnobody.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Test for AmbientCapabilities
+
+[Service]
+ExecStart=/bin/sh -x -c 'c=$$(grep "CapAmb:" /proc/self/status); test "$$c" = "CapAmb: 0000000000003000"'
+Type=oneshot
+User=nfsnobody
+AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
diff --git a/test/test-execute/exec-group-nfsnobody.service b/test/test-execute/exec-group-nfsnobody.service
new file mode 100644
index 0000000000..e02100a869
--- /dev/null
+++ b/test/test-execute/exec-group-nfsnobody.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test for Group
+
+[Service]
+ExecStart=/bin/sh -x -c 'test "$$(id -n -g)" = "nfsnobody"'
+Type=oneshot
+Group=nfsnobody
diff --git a/test/test-execute/exec-runtimedirectory-owner-nfsnobody.service b/test/test-execute/exec-runtimedirectory-owner-nfsnobody.service
new file mode 100644
index 0000000000..e962af8a4b
--- /dev/null
+++ b/test/test-execute/exec-runtimedirectory-owner-nfsnobody.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
+
+[Service]
+ExecStart=/bin/sh -x -c 'group=$$(stat -c %%G /tmp/test-exec_runtimedirectory-owner); test "$$group" = "nfsnobody"'
+Type=oneshot
+Group=nfsnobody
+User=root
+RuntimeDirectory=test-exec_runtimedirectory-owner
diff --git a/test/test-execute/exec-spec-interpolation.service b/test/test-execute/exec-spec-interpolation.service
new file mode 100644
index 0000000000..3e62662aa9
--- /dev/null
+++ b/test/test-execute/exec-spec-interpolation.service
@@ -0,0 +1,6 @@
+[Unit]
+Description=https://github.com/systemd/systemd/issues/2637
+
+[Service]
+Type=oneshot
+ExecStart=/bin/sh -x -c "perl -e 'exit(!(qq{%%U} eq qq{\\x25U}))'"
diff --git a/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service b/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
new file mode 100644
index 0000000000..9393e0a998
--- /dev/null
+++ b/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Test for SystemCallFilter in system mode with User set
+
+[Service]
+ExecStart=/bin/echo "Foo bar"
+Type=oneshot
+User=nfsnobody
+SystemCallFilter=~read write open execve ioperm
+SystemCallFilter=ioctl
+SystemCallFilter=read write open execve
+SystemCallFilter=~ioperm
diff --git a/test/test-execute/exec-systemcallfilter-system-user.service b/test/test-execute/exec-systemcallfilter-system-user.service
new file mode 100644
index 0000000000..462f94133d
--- /dev/null
+++ b/test/test-execute/exec-systemcallfilter-system-user.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Test for SystemCallFilter in system mode with User set
+
+[Service]
+ExecStart=/bin/echo "Foo bar"
+Type=oneshot
+User=nobody
+SystemCallFilter=~read write open execve ioperm
+SystemCallFilter=ioctl
+SystemCallFilter=read write open execve
+SystemCallFilter=~ioperm
diff --git a/test/test-execute/exec-user-nfsnobody.service b/test/test-execute/exec-user-nfsnobody.service
new file mode 100644
index 0000000000..aafda3aa26
--- /dev/null
+++ b/test/test-execute/exec-user-nfsnobody.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test for User
+
+[Service]
+ExecStart=/bin/sh -x -c 'test "$$USER" = "nfsnobody"'
+Type=oneshot
+User=nfsnobody
diff --git a/test/test-functions b/test/test-functions
index 6667e0524f..e2e07a833c 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -7,6 +7,9 @@ export PATH
LOOKS_LIKE_DEBIAN=$(source /etc/os-release && [[ "$ID" = "debian" || "$ID_LIKE" = "debian" ]] && echo yes)
KERNEL_VER=${KERNEL_VER-$(uname -r)}
KERNEL_MODS="/lib/modules/$KERNEL_VER/"
+QEMU_TIMEOUT="${QEMU_TIMEOUT:-infinity}"
+NSPAWN_TIMEOUT="${NSPAWN_TIMEOUT:-infinity}"
+FSTYPE="${FSTYPE:-ext3}"
if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
echo "WARNING! Cannot determine rootlibdir from pkg-config, assuming /usr/lib/systemd" >&2
@@ -61,7 +64,6 @@ run_qemu() {
find_qemu_bin || return 1
KERNEL_APPEND="root=/dev/sda1 \
-systemd.log_level=debug \
raid=noautodetect \
loglevel=2 \
init=$ROOTLIBDIR/systemd \
@@ -76,9 +78,10 @@ $KERNEL_APPEND \
-m 512M \
-nographic \
-kernel $KERNEL_BIN \
+-drive format=raw,cache=unsafe,file=${TESTDIR}/rootdisk.img \
"
- if [ "$INITRD" ]; then
+ if [[ "$INITRD" && "$SKIP_INITRD" != "yes" ]]; then
QEMU_OPTIONS="$QEMU_OPTIONS -initrd $INITRD"
fi
@@ -86,13 +89,20 @@ $KERNEL_APPEND \
QEMU_OPTIONS="$QEMU_OPTIONS -machine accel=kvm -enable-kvm -cpu host"
fi
+ if [[ "$QEMU_TIMEOUT" != "infinity" ]]; then
+ QEMU_BIN="timeout --foreground $QEMU_TIMEOUT $QEMU_BIN"
+ fi
( set -x
- $QEMU_BIN $QEMU_OPTIONS -append "$KERNEL_APPEND" $TESTDIR/rootdisk.img ) || return 1
+ $QEMU_BIN $QEMU_OPTIONS -append "$KERNEL_APPEND" ) || return 1
}
run_nspawn() {
+ local _nspawn_cmd="../../systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND"
+ if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then
+ _nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd"
+ fi
set -x
- ../../systemd-nspawn --register=no --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND
+ $_nspawn_cmd
}
setup_basic_environment() {
@@ -194,9 +204,23 @@ EOF
chmod 0755 $_valgrind_wrapper
}
+create_strace_wrapper() {
+ local _strace_wrapper=$initdir/$ROOTLIBDIR/systemd-under-strace
+ ddebug "Create $_strace_wrapper"
+ cat >$_strace_wrapper <<EOF
+#!/bin/bash
+
+exec strace -D -o /strace.out $ROOTLIBDIR/systemd "\$@"
+EOF
+ chmod 0755 $_strace_wrapper
+}
+
install_fsck() {
dracut_install /sbin/fsck*
dracut_install -o /bin/fsck*
+
+ # fskc.reiserfs calls reiserfsck. so, install it
+ dracut_install -o reiserfsck
}
install_dmevent() {
@@ -220,6 +244,9 @@ install_systemd() {
# we strip binaries since debug symbols increase binaries size a lot
# and it could fill the available space
strip_binaries
+
+ # enable debug logging in PID1
+ echo LogLevel=debug >> $initdir/etc/systemd/system.conf
}
install_missing_libraries() {
@@ -241,7 +268,13 @@ create_empty_image() {
,
EOF
- mkfs.ext3 -L systemd "${LOOPDEV}p1"
+ local _label="-L systemd"
+ # mkfs.reiserfs doesn't know -L. so, use --label instead
+ [[ "$FSTYPE" == "reiserfs" ]] && _label="--label systemd"
+ if ! mkfs -t "${FSTYPE}" ${_label} "${LOOPDEV}p1" -q; then
+ dfatal "Failed to mkfs -t ${FSTYPE}"
+ exit 1
+ fi
}
check_result_nspawn() {
@@ -335,7 +368,7 @@ install_config_files() {
echo systemd-testsuite > $initdir/etc/hostname
# fstab
cat >$initdir/etc/fstab <<EOF
-LABEL=systemd / ext3 rw 0 1
+LABEL=systemd / ${FSTYPE} rw 0 1
EOF
}
@@ -385,6 +418,9 @@ install_pam() {
[[ "$LOOKS_LIKE_DEBIAN" ]] &&
cp /etc/pam.d/systemd-user $initdir/etc/pam.d/
+
+ # set empty root password for easy debugging
+ sed -i 's/^root:x:/root::/' $initdir/etc/passwd
}
install_keymaps() {
diff --git a/test/udev-test.pl b/test/udev-test.pl
index 638c3e8f4e..da0a4e1f6b 100755
--- a/test/udev-test.pl
+++ b/test/udev-test.pl
@@ -23,14 +23,23 @@ use strict;
my $udev_bin = "./test-udev";
my $valgrind = 0;
my $gdb = 0;
+my $strace = 0;
my $udev_bin_valgrind = "valgrind --tool=memcheck --leak-check=yes --track-origins=yes --quiet $udev_bin";
my $udev_bin_gdb = "gdb --args $udev_bin";
-my $udev_dev = "test/dev";
+my $udev_bin_strace = "strace -efile $udev_bin";
my $udev_run = "test/run";
+my $udev_tmpfs = "test/tmpfs";
+my $udev_sys = "${udev_tmpfs}/sys";
+my $udev_dev = "${udev_tmpfs}/dev";
my $udev_rules_dir = "$udev_run/udev/rules.d";
my $udev_rules = "$udev_rules_dir/udev-test.rules";
my $EXIT_TEST_SKIP = 77;
+my $rules_10k_tags = "";
+for (my $i = 1; $i <= 10000; ++$i) {
+ $rules_10k_tags .= 'KERNEL=="sda", TAG+="test' . $i . "\"\n";
+}
+
my @tests = (
{
desc => "no rules",
@@ -700,7 +709,7 @@ EOF
desc => "big major number test",
devpath => "/devices/virtual/misc/misc-fake1",
exp_name => "node",
- exp_majorminor => "511:1",
+ exp_majorminor => "4095:1",
rules => <<EOF
KERNEL=="misc-fake1", SYMLINK+="node"
EOF
@@ -709,7 +718,7 @@ EOF
desc => "big major and big minor number test",
devpath => "/devices/virtual/misc/misc-fake89999",
exp_name => "node",
- exp_majorminor => "511:89999",
+ exp_majorminor => "4095:89999",
rules => <<EOF
KERNEL=="misc-fake89999", SYMLINK+="node"
EOF
@@ -1315,6 +1324,25 @@ KERNEL=="sda", IMPORT{builtin}="path_id"
KERNEL=="sda", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/\$env{ID_PATH}"
EOF
},
+ {
+ desc => "add and match tag",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "found",
+ not_exp_name => "bad" ,
+ rules => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", TAG+="green"
+TAGS=="green", SYMLINK+="found"
+TAGS=="blue", SYMLINK+="bad"
+EOF
+ },
+ {
+ desc => "don't crash with lots of tags",
+ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+ exp_name => "found",
+ rules => $rules_10k_tags . <<EOF
+TAGS=="test1", TAGS=="test500", TAGS=="test1234", TAGS=="test9999", TAGS=="test10000", SYMLINK+="found"
+EOF
+ },
);
sub udev {
@@ -1327,11 +1355,13 @@ sub udev {
close CONF;
if ($valgrind > 0) {
- system("$udev_bin_valgrind $action $devpath");
+ return system("$udev_bin_valgrind $action $devpath");
} elsif ($gdb > 0) {
- system("$udev_bin_gdb $action $devpath");
+ return system("$udev_bin_gdb $action $devpath");
+ } elsif ($strace > 0) {
+ return system("$udev_bin_strace $action $devpath");
} else {
- system("$udev_bin", "$action", "$devpath");
+ return system("$udev_bin", "$action", "$devpath");
}
}
@@ -1401,23 +1431,34 @@ sub major_minor_test {
}
sub udev_setup {
- system("rm", "-rf", "$udev_dev");
+ system("umount", $udev_tmpfs);
+ rmdir($udev_tmpfs);
+ mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n";
+ system("mount", "-o", "rw,mode=755,nosuid,noexec,nodev", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs";
+
mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n";
# setting group and mode of udev_dev ensures the tests work
# even if the parent directory has setgid bit enabled.
chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n";
chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n";
+ system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys";
+
system("rm", "-rf", "$udev_run");
}
sub run_test {
my ($rules, $number) = @_;
+ my $rc;
print "TEST $number: $rules->{desc}\n";
print "device \'$rules->{devpath}\' expecting node/link \'$rules->{exp_name}\'\n";
- udev("add", $rules->{devpath}, \$rules->{rules});
+ $rc = udev("add", $rules->{devpath}, \$rules->{rules});
+ if ($rc != 0) {
+ print "$udev_bin add failed with code $rc\n";
+ $error++;
+ }
if (defined($rules->{not_exp_name})) {
if ((-e "$udev_dev/$rules->{not_exp_name}") ||
(-l "$udev_dev/$rules->{not_exp_name}")) {
@@ -1458,7 +1499,11 @@ sub run_test {
return;
}
- udev("remove", $rules->{devpath}, \$rules->{rules});
+ $rc = udev("remove", $rules->{devpath}, \$rules->{rules});
+ if ($rc != 0) {
+ print "$udev_bin remove failed with code $rc\n";
+ $error++;
+ }
if ((-e "$udev_dev/$rules->{exp_name}") ||
(-l "$udev_dev/$rules->{exp_name}")) {
print "remove: error";
@@ -1509,6 +1554,9 @@ foreach my $arg (@ARGV) {
} elsif ($arg =~ m/--gdb/) {
$gdb = 1;
printf("using gdb\n");
+ } elsif ($arg =~ m/--strace/) {
+ $strace = 1;
+ printf("using strace\n");
} else {
push(@list, $arg);
}
@@ -1536,8 +1584,9 @@ if ($list[0]) {
print "$error errors occurred\n\n";
# cleanup
-system("rm", "-rf", "$udev_dev");
system("rm", "-rf", "$udev_run");
+system("umount", "$udev_tmpfs");
+rmdir($udev_tmpfs);
if ($error > 0) {
exit(1);
diff --git a/tmpfiles.d/systemd.conf.m4 b/tmpfiles.d/systemd.conf.m4
index 0575408dbe..2cd58e9121 100644
--- a/tmpfiles.d/systemd.conf.m4
+++ b/tmpfiles.d/systemd.conf.m4
@@ -26,21 +26,48 @@ d /run/log 0755 root root -
z /run/log/journal 2755 root systemd-journal - -
Z /run/log/journal/%m ~2750 root systemd-journal - -
-m4_ifdef(`HAVE_ACL',``
+m4_ifdef(`HAVE_ACL',`m4_dnl
+m4_ifdef(`ENABLE_ADM_GROUP',`m4_dnl
+m4_ifdef(`ENABLE_WHEEL_GROUP',``
a+ /run/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x
-A+ /run/log/journal/%m - - - - group:adm:r-x,group:wheel:r-x
-'')m4_dnl
+a+ /run/log/journal/%m - - - - group:adm:r-x,group:wheel:r-x
+a+ /run/log/journal/%m/*.journal* - - - - group:adm:r--,group:wheel:r--
+'',``
+a+ /run/log/journal/%m - - - - d:group:adm:r-x
+a+ /run/log/journal/%m - - - - group:adm:r-x
+a+ /run/log/journal/%m/*.journal* - - - - group:adm:r--
+'')',`m4_dnl
+m4_ifdef(`ENABLE_WHEEL_GROUP',``
+a+ /run/log/journal/%m - - - - d:group:wheel:r-x
+a+ /run/log/journal/%m - - - - group:wheel:r-x
+a+ /run/log/journal/%m/*.journal* - - - - group:wheel:r--
+'')')')m4_dnl
z /var/log/journal 2755 root systemd-journal - -
z /var/log/journal/%m 2755 root systemd-journal - -
z /var/log/journal/%m/system.journal 0640 root systemd-journal - -
-m4_ifdef(`HAVE_ACL',``
+m4_ifdef(`HAVE_ACL',`m4_dnl
+m4_ifdef(`ENABLE_ADM_GROUP',`m4_dnl
+m4_ifdef(`ENABLE_WHEEL_GROUP',``
a+ /var/log/journal - - - - d:group:adm:r-x,d:group:wheel:r-x
a+ /var/log/journal - - - - group:adm:r-x,group:wheel:r-x
a+ /var/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x
a+ /var/log/journal/%m - - - - group:adm:r-x,group:wheel:r-x
a+ /var/log/journal/%m/system.journal - - - - group:adm:r--,group:wheel:r--
-'')m4_dnl
+'', ``
+a+ /var/log/journal - - - - d:group:adm:r-x
+a+ /var/log/journal - - - - group:adm:r-x
+a+ /var/log/journal/%m - - - - d:group:adm:r-x
+a+ /var/log/journal/%m - - - - group:adm:r-x
+a+ /var/log/journal/%m/system.journal - - - - group:adm:r--
+'')',`m4_dnl
+m4_ifdef(`ENABLE_WHEEL_GROUP',``
+a+ /var/log/journal - - - - d:group:wheel:r-x
+a+ /var/log/journal - - - - group:wheel:r-x
+a+ /var/log/journal/%m - - - - d:group:wheel:r-x
+a+ /var/log/journal/%m - - - - group:wheel:r-x
+a+ /var/log/journal/%m/system.journal - - - - group:wheel:r--
+'')')')m4_dnl
d /var/lib/systemd 0755 root root -
d /var/lib/systemd/coredump 0755 root root 3d
diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py
index 8091683fee..256ff3dc5d 100755
--- a/tools/make-directive-index.py
+++ b/tools/make-directive-index.py
@@ -132,15 +132,6 @@ TEMPLATE = '''\
</refsect1>
<refsect1>
- <title>bootchart.conf directives</title>
-
- <para>Directives for configuring the behaviour of the
- systemd-bootchart process.</para>
-
- <variablelist id='bootchart-directives' />
- </refsect1>
-
- <refsect1>
<title>command line options</title>
<para>Command-line options accepted by programs in the
diff --git a/units/.gitignore b/units/.gitignore
index 2fff20a052..47e99154ee 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -1,4 +1,3 @@
-/systemd-bus-proxyd.service.m4
/user@.service.m4
/console-getty.service
/console-getty.service.m4
@@ -23,8 +22,6 @@
/systemd-ask-password-wall.service
/systemd-backlight@.service
/systemd-binfmt.service
-/systemd-bootchart.service
-/systemd-bus-proxyd.service
/systemd-coredump@.service
/systemd-firstboot.service
/systemd-fsck-root.service
diff --git a/units/emergency.service.in b/units/emergency.service.in
index fb390eacfe..0de16f24e8 100644
--- a/units/emergency.service.in
+++ b/units/emergency.service.in
@@ -11,6 +11,7 @@ Documentation=man:sulogin(8)
DefaultDependencies=no
Conflicts=shutdown.target
Conflicts=rescue.service
+Conflicts=syslog.socket
Before=shutdown.target
[Service]
diff --git a/units/systemd-bus-proxyd.socket b/units/initrd-root-device.target
index 3f80a1d547..9d44d2d303 100644
--- a/units/systemd-bus-proxyd.socket
+++ b/units/initrd-root-device.target
@@ -6,7 +6,10 @@
# (at your option) any later version.
[Unit]
-Description=Legacy D-Bus Protocol Compatibility Socket
-
-[Socket]
-ListenStream=/var/run/dbus/system_bus_socket
+Description=Initrd Root Device
+Documentation=man:systemd.special(7)
+ConditionPathExists=/etc/initrd-release
+OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
+DefaultDependencies=no
+Conflicts=shutdown.target
diff --git a/units/initrd.target b/units/initrd.target
index eae7c703c1..8be7e2b399 100644
--- a/units/initrd.target
+++ b/units/initrd.target
@@ -12,6 +12,6 @@ OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release
Requires=basic.target
-Wants=initrd-root-fs.target initrd-fs.target initrd-parse-etc.service
-After=initrd-root-fs.target initrd-fs.target basic.target rescue.service rescue.target
+Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-parse-etc.service
+After=initrd-root-fs.target initrd-root-device.target initrd-fs.target basic.target rescue.service rescue.target
AllowIsolate=yes
diff --git a/units/ldconfig.service b/units/ldconfig.service
index 994edd9908..d7b78bacf9 100644
--- a/units/ldconfig.service
+++ b/units/ldconfig.service
@@ -10,7 +10,7 @@ Description=Rebuild Dynamic Linker Cache
Documentation=man:ldconfig(8)
DefaultDependencies=no
Conflicts=shutdown.target
-After=systemd-remount-fs.service
+After=local-fs.target
Before=sysinit.target shutdown.target systemd-update-done.service
ConditionNeedsUpdate=|/etc
ConditionFileNotEmpty=|!/etc/ld.so.cache
diff --git a/units/rc-local.service.in b/units/rc-local.service.in
index d4db1747ed..480dddbe37 100644
--- a/units/rc-local.service.in
+++ b/units/rc-local.service.in
@@ -17,3 +17,4 @@ Type=forking
ExecStart=@RC_LOCAL_SCRIPT_PATH_START@ start
TimeoutSec=0
RemainAfterExit=yes
+GuessMainPID=no
diff --git a/units/systemd-bootchart.service.in b/units/systemd-bootchart.service.in
deleted file mode 100644
index 396817f0ce..0000000000
--- a/units/systemd-bootchart.service.in
+++ /dev/null
@@ -1,20 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-# Note: it's usually a better idea to run systemd-bootchart via the
-# init= kernel command line switch. See the man page for details.
-
-[Unit]
-Description=Boot Process Profiler
-Documentation=man:systemd-bootchart.service(1) man:bootchart.conf(5)
-DefaultDependencies=no
-
-[Service]
-ExecStart=@rootlibexecdir@/systemd-bootchart -r
-
-[Install]
-WantedBy=sysinit.target
diff --git a/units/systemd-bus-proxyd.service.m4.in b/units/systemd-bus-proxyd.service.m4.in
deleted file mode 100644
index e75cdb1a59..0000000000
--- a/units/systemd-bus-proxyd.service.m4.in
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Legacy D-Bus Protocol Compatibility Daemon
-
-[Service]
-ExecStart=@rootlibexecdir@/systemd-bus-proxyd --address=kernel:path=/sys/fs/kdbus/0-system/bus
-ExecReload=@bindir@/busctl --address=unix:path=/run/dbus/system_bus_socket call org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus ReloadConfig
-NotifyAccess=main
-CapabilityBoundingSet=CAP_IPC_OWNER CAP_SETUID CAP_SETGID CAP_SETPCAP m4_ifdef(`HAVE_SMACK', CAP_MAC_ADMIN )
-PrivateTmp=yes
-PrivateDevices=yes
-PrivateNetwork=yes
-ProtectSystem=full
-ProtectHome=yes
-
-# The proxy manages connections of all users, so it needs an elevated file
-# limit. It does proper per-user accounting (indirectly via kdbus), therefore,
-# the effective per-user limits stay the same.
-LimitNOFILE=16384
diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in
index 0468392dc4..6ca6b07e9e 100644
--- a/units/systemd-fsck@.service.in
+++ b/units/systemd-fsck@.service.in
@@ -11,7 +11,7 @@ Documentation=man:systemd-fsck@.service(8)
DefaultDependencies=no
BindsTo=%i.device
After=%i.device systemd-fsck-root.service local-fs-pre.target
-Before=shutdown.target
+Before=systemd-quotacheck.service shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-importd.service.in b/units/systemd-importd.service.in
index d3238cf8f5..b74ad72cdc 100644
--- a/units/systemd-importd.service.in
+++ b/units/systemd-importd.service.in
@@ -8,6 +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
[Service]
ExecStart=@rootlibexecdir@/systemd-importd
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index 3710c595ca..685baab21d 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -15,7 +15,7 @@ After=machine.slice
[Service]
ExecStart=@rootlibexecdir@/systemd-machined
BusName=org.freedesktop.machine1
-CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER CAP_FSETID
+CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD
WatchdogSec=3min
# Note that machined cannot be placed in a mount namespace, since it
diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in
index eb10343ac6..ea28941507 100644
--- a/units/systemd-nspawn@.service.in
+++ b/units/systemd-nspawn@.service.in
@@ -6,14 +6,14 @@
# (at your option) any later version.
[Unit]
-Description=Container %I
+Description=Container %i
Documentation=man:systemd-nspawn(1)
PartOf=machines.target
Before=machines.target
After=network.target
[Service]
-ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --settings=override --machine=%I
+ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth -U --settings=override --machine=%i
KillMode=mixed
Type=notify
RestartForceExitStatus=133
diff --git a/units/systemd-resolved.service.m4.in b/units/systemd-resolved.service.m4.in
index c674b27ced..8e1c1dea79 100644
--- a/units/systemd-resolved.service.m4.in
+++ b/units/systemd-resolved.service.m4.in
@@ -8,6 +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
After=systemd-networkd.service network.target
# On kdbus systems we pull in the busname explicitly, because it
diff --git a/units/systemd-user-sessions.service.in b/units/systemd-user-sessions.service.in
index c09c05d4d5..b4ea5a134b 100644
--- a/units/systemd-user-sessions.service.in
+++ b/units/systemd-user-sessions.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Permit User Sessions
Documentation=man:systemd-user-sessions.service(8)
-After=remote-fs.target nss-user-lookup.target
+After=remote-fs.target nss-user-lookup.target network.target
[Service]
Type=oneshot
diff --git a/units/tmp.mount.m4 b/units/tmp.mount.m4
index 00a0d28722..1448bd268a 100644
--- a/units/tmp.mount.m4
+++ b/units/tmp.mount.m4
@@ -13,6 +13,7 @@ ConditionPathIsSymbolicLink=!/tmp
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
+After=swap.target
[Mount]
What=tmpfs
diff --git a/units/user/.gitignore b/units/user/.gitignore
index ce9df9e7e1..41a74f5461 100644
--- a/units/user/.gitignore
+++ b/units/user/.gitignore
@@ -1,2 +1 @@
/systemd-exit.service
-/systemd-bus-proxyd.service
diff --git a/units/user/systemd-bus-proxyd.service.in b/units/user/systemd-bus-proxyd.service.in
deleted file mode 100644
index 6f79707b46..0000000000
--- a/units/user/systemd-bus-proxyd.service.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Legacy D-Bus Protocol Compatibility Daemon
-
-[Service]
-ExecStart=@rootlibexecdir@/systemd-bus-proxyd --address=kernel:path=/sys/fs/kdbus/%U-user/bus
-ExecReload=@bindir@/busctl --address=unix:path=/run/user/%U/bus call org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus ReloadConfig
-NotifyAccess=main
diff --git a/units/user/systemd-bus-proxyd.socket b/units/user/systemd-bus-proxyd.socket
deleted file mode 100644
index b9efc0e7ce..0000000000
--- a/units/user/systemd-bus-proxyd.socket
+++ /dev/null
@@ -1,12 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Legacy D-Bus Protocol Compatibility Socket
-
-[Socket]
-ListenStream=%t/bus