]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #18990 from yuwata/network-dhcpv6-use-domains
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 31 Mar 2021 08:38:37 +0000 (10:38 +0200)
committerGitHub <noreply@github.com>
Wed, 31 Mar 2021 08:38:37 +0000 (10:38 +0200)
network: also introduce UseDomains= for [DHCPv6] section

242 files changed:
.github/ISSUE_TEMPLATE/Bug_report.md
.mailmap
NEWS
TODO
coccinelle/flags-set.cocci
coccinelle/run-coccinelle.sh
coccinelle/strjoina.cocci
docs/DISCOVERABLE_PARTITIONS.md
docs/ENVIRONMENT.md
docs/RELEASE.md
docs/TRANSIENT-SETTINGS.md
docs/_includes/footer.html
hwdb.d/20-OUI.hwdb
hwdb.d/20-acpi-vendor.hwdb
hwdb.d/20-acpi-vendor.hwdb.patch
hwdb.d/20-pci-vendor-model.hwdb
hwdb.d/60-autosuspend-fingerprint-reader.hwdb
hwdb.d/70-mouse.hwdb
hwdb.d/README [new file with mode: 0644]
hwdb.d/acpi_id_registry.html
hwdb.d/ma-large.txt
hwdb.d/ma-medium.txt
hwdb.d/ma-small.txt
hwdb.d/meson.build
hwdb.d/pci.ids
hwdb.d/pnp_id_registry.html
man/org.freedesktop.systemd1.xml
man/sd_bus_add_object.xml
man/systemd-ask-password.xml
man/systemd-firstboot.xml
man/systemd-machine-id-setup.xml
man/systemd-nspawn.xml
man/systemd-sysusers.xml
man/systemd.device.xml
man/systemd.exec.xml
man/systemd.network.xml
man/systemd.service.xml
man/systemd.unit.xml
meson.build
meson_options.txt
modprobe.d/README [new file with mode: 0644]
po/LINGUAS
po/ko.po
po/nl.po [new file with mode: 0644]
rules.d/README [new file with mode: 0644]
rules.d/meson.build
shell-completion/bash/systemd-run
shell-completion/zsh/_systemd-run
src/ask-password/ask-password.c
src/basic/blockdev-util.c
src/basic/cgroup-util.c
src/basic/creds-util.c [new file with mode: 0644]
src/basic/creds-util.h [new file with mode: 0644]
src/basic/fileio.c
src/basic/fs-util.h
src/basic/log.c
src/basic/log.h
src/basic/meson.build
src/basic/mountpoint-util.c
src/basic/nss-util.h
src/basic/ordered-set.c
src/basic/ordered-set.h
src/basic/path-util.c
src/basic/path-util.h
src/basic/process-util.c
src/basic/rm-rf.h
src/basic/selinux-util.c
src/boot/efi/meson.build
src/core/dbus-execute.c
src/core/dbus-manager.c
src/core/dbus-service.c
src/core/execute.c
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/manager.c
src/core/namespace.c
src/core/namespace.h
src/core/service.c
src/core/service.h
src/core/system.conf.in
src/core/transaction.c
src/coredump/coredump.c
src/coredump/coredump.conf
src/cryptenroll/cryptenroll-password.c
src/cryptenroll/cryptenroll.c
src/cryptsetup/cryptsetup-fido2.c
src/cryptsetup/cryptsetup-pkcs11.c
src/cryptsetup/cryptsetup.c
src/dissect/dissect.c
src/firstboot/firstboot.c
src/gpt-auto-generator/gpt-auto-generator.c
src/home/homectl.c
src/home/homed-home.c
src/home/homed.conf
src/home/homework-fscrypt.c
src/home/homework-luks.c
src/journal-remote/journal-gatewayd.c
src/journal-remote/journal-upload.c
src/journal/journalctl.c
src/journal/journald-stream.c
src/journal/journald.conf
src/libsystemd-network/dhcp-internal.h
src/libsystemd-network/dhcp-server-internal.h
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/lldp-internal.h
src/libsystemd-network/lldp-neighbor.c
src/libsystemd-network/meson.build
src/libsystemd-network/ndisc-internal.h
src/libsystemd-network/ndisc-router.c
src/libsystemd-network/ndisc-router.h
src/libsystemd-network/network-common.c [new file with mode: 0644]
src/libsystemd-network/network-common.h [new file with mode: 0644]
src/libsystemd-network/radv-internal.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-dhcp6-lease.c
src/libsystemd-network/sd-ipv4acd.c
src/libsystemd-network/sd-ipv4ll.c
src/libsystemd-network/sd-lldp.c
src/libsystemd-network/sd-ndisc.c
src/libsystemd-network/sd-radv.c
src/libsystemd-network/test-dhcp6-client.c
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-bus/bus-error.h
src/libsystemd/sd-device/device-enumerator.c
src/libsystemd/sd-device/device-monitor.c
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-device/test-sd-device-thread.c
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-event/test-event.c
src/libsystemd/sd-journal/compress.c
src/libudev/test-udev-device-thread.c
src/login/logind-brightness.c
src/login/logind.conf.in
src/machine-id-setup/machine-id-setup-main.c
src/network/netdev/batadv.c
src/network/netdev/tunnel.c
src/network/networkctl.c
src/network/networkd-link-bus.c
src/network/networkd-link.c
src/network/networkd-network.c
src/network/networkd-state-file.c
src/network/networkd.c
src/nspawn/nspawn.c
src/oom/oomd-manager.c
src/oom/oomd-manager.h
src/oom/oomd-util.c
src/oom/oomd-util.h
src/oom/oomd.conf
src/oom/test-oomd-util.c
src/partition/repart.c
src/portable/portable.c
src/pstore/pstore.c
src/resolve/meson.build
src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-dns-answer.c
src/resolve/resolved-dns-answer.h
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-query.h
src/resolve/resolved-dns-question.c
src/resolve/resolved-dns-question.h
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-server.c
src/resolve/resolved-dns-stub.c
src/resolve/resolved-manager.c
src/resolve/resolved-mdns.c
src/resolve/resolved-util.c [new file with mode: 0644]
src/resolve/resolved-util.h [new file with mode: 0644]
src/resolve/resolved-varlink.c
src/resolve/resolved.conf.in
src/shared/acpi-fpdt.c
src/shared/ask-password-api.c
src/shared/ask-password-api.h
src/shared/bus-unit-util.c
src/shared/calendarspec.c
src/shared/discover-image.c
src/shared/dissect-image.c
src/shared/dissect-image.h
src/shared/firewall-util-nft.c
src/shared/firewall-util-private.h
src/shared/firewall-util.c
src/shared/firewall-util.h
src/shared/libfido2-util.c
src/shared/local-addresses.c
src/shared/logs-show.c
src/shared/mount-util.c
src/shared/pkcs11-util.c
src/shared/pkcs11-util.h
src/shutdown/shutdown.c
src/sysext/sysext.c
src/systemctl/systemctl-edit.c
src/systemd/sd-dhcp-client.h
src/systemd/sd-dhcp-server.h
src/systemd/sd-dhcp6-client.h
src/systemd/sd-ipv4acd.h
src/systemd/sd-ipv4ll.h
src/systemd/sd-lldp.h
src/systemd/sd-ndisc.h
src/systemd/sd-radv.h
src/sysusers/sysusers.c
src/test/meson.build
src/test/nss-test-util.c [new file with mode: 0644]
src/test/nss-test-util.h [new file with mode: 0644]
src/test/test-calendarspec.c
src/test/test-copy.c
src/test/test-fileio.c
src/test/test-firewall-util.c
src/test/test-mount-util.c
src/test/test-namespace.c
src/test/test-ns.c
src/test/test-nss-hosts.c [moved from src/test/test-nss.c with 87% similarity]
src/test/test-nss-users.c [new file with mode: 0644]
src/test/test-ordered-set.c
src/test/test-process-util.c
src/test/test-random-util.c
src/tmpfiles/tmpfiles.c
src/udev/net/link-config.c
src/veritysetup/veritysetup-generator.c
src/xdg-autostart-generator/xdg-autostart-service.c
sysctl.d/README [new file with mode: 0644]
sysctl.d/meson.build
sysusers.d/README [new file with mode: 0644]
sysusers.d/meson.build
test/TEST-56-EXIT-TYPE/Makefile [new symlink]
test/TEST-56-EXIT-TYPE/test.sh [new file with mode: 0755]
test/fuzz/fuzz-unit-file/directives.service
test/test-functions
test/units/testsuite-50.sh
test/units/testsuite-56.service [new file with mode: 0644]
test/units/testsuite-56.sh [new file with mode: 0755]
tmpfiles.d/README [new file with mode: 0644]
tmpfiles.d/meson.build
tools/git-contrib.sh
units/systemd-firstboot.service
units/systemd-localed.service.in
units/systemd-sysusers.service

index 61e4b984a567bd00e5735b502dcd918f81196b5c..ca8213863c1133e959516c5119b0fd099134f2a1 100644 (file)
@@ -7,8 +7,10 @@ about: A report of an error in a recent systemd version
 **systemd version the issue has been seen with**
  > …
 
-<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released (non-rc) systemd versions upstream! -->
-<!-- See https://github.com/systemd/systemd/releases for the list of most recent releases. -->
+<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released *major* systemd versions upstream! -->
+<!--           If there have been multiple stable releases for that major version, please consider updating to a recent one before reporting an issue. -->
+<!--           When using a distro package, please make sure that the version reported is meaningful for upstream. -->
+<!-- See https://github.com/systemd/systemd-stable/releases for the list of most recent releases. -->
 <!-- For older version please use distribution trackers (see https://systemd.io/CONTRIBUTING#filing-issues). -->
 
 **Used distribution**
index 662ea13a609f11c53599ded097eb23d972f7d673..7abaedc87996f3f127afbf35042b777052327395 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -115,12 +115,14 @@ Michael Biebl <biebl@debian.org> <mbiebl@gmail.com>
 Michael Buesch <mbuesch@freenet.de>
 Michael Hoy <rimmington@gmail.com>
 Michael Olbrich <m.olbrich@pengutronix.de>
+Michael Trapp <michael.trapp@sap.com>
 Michal Soltys <soltys@ziu.info> <nozo@ziu.info>
 Michal Suchanek <msuchanek@suse.de>
 Michal Suchanek <msuchanek@suse.de> <hramrach@gmail.com>
 Michal Sekletár <msekleta@redhat.com>
 Michał Szczepański <skrzatu@hotmail.com> <skrzatu@gmail.com>
 Michel Kraus <github@demonsphere.de> <27o@users.noreply.github.com>
+Michele Guerini Rocco <rnhmjoj@inventati.org>
 Miklos Vajna <vmiklos@frugalware.org> <vmiklos@gmail.com>
 Milan Pässler <me@petabyteboy.de>
 Neil Brown <neil@brown.name>
@@ -209,3 +211,4 @@ Andrey Yashkin <38919268+AndreyYashkin@users.noreply.github.com>
 Ronald Tschalär <ronald@innovation.ch>
 Jay Burger <jay.burger@fujitsu.com> <root@new-host-3.home>
 Yi Gao <ymuemc@163.com>
+Weblate <noreply@weblate.org>
diff --git a/NEWS b/NEWS
index 8ffcba7ba4d8c157eedee4e9f784041f2e595fa1..52c646f864b6610b7474a89bbcbb9ca1118cb8d0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -224,7 +224,7 @@ CHANGES WITH 248:
           systemd.network files gained a new ActivationPolicy= setting which
           allows configuring how the UP state of an interface shall be managed,
           i.e. whether the interface is always upped, always downed, or may be
-          upped/downed by the user using "ip dev".
+          upped/downed by the user using "ip link set dev".
 
         * The default for the Broadcast= setting in .network files has slightly
           changed: the broadcast address will not be configured for wireguard
@@ -437,41 +437,48 @@ CHANGES WITH 248:
         * portablectl gained a new "reattach" verb for detaching/reattaching a
           portable service image, useful for updating images on-the-fly.
 
-        Contributions from: Adam Nielsen, Adrian Vovk, AJ Jordan, Alan Perry,
-        Alastair Pharo, Alexander Batischev, Ali Abdallah, Andrew Balmos, Anita
-        Zhang, Annika Wickert, Ansgar Burchardt, Antonius Frie, Ardy, Arian van
-        Putten, Ariel Fermani, Arnaud T, A S Alam, Bastien Nocera, Benjamin
-        Berg, Benjamin Robin, Björn Daase, caoxia, Carlo Wood, Charles Lee,
-        ChopperRob, chri2, Christian Ehrhardt, Christian Hesse, Christopher
-        Obbard, clayton craft, corvusnix, cprn, d032747, Daan De Meyer, Daniele
-        Medri, Daniel Rusek, Dan Streetman, Darren Ng, David Edmundson, Deepak
-        Rawat, Devon Pringle, Dmitry Borodaenko, dropsignal, Einsler Lee, Endre
-        Szabo, Evgeny Vereshchagin, Fabian Affolter, Felipe Borges,
-        feliperodriguesfr, Felix Stupp, Florian Hülsmann, Florian Klink,
-        Florian Westphal, Franck Bui, Frantisek Sumsal, Gablegritule, Gaël
-        PORTAY, Gaurav, Giedrius Statkevičius, Greg Depoire--Ferrer, Gustavo
-        Costa, Hans de Goede, Hela Basa, heretoenhance, Iago López Galeiras,
-        igo95862, Ilya Dmitrichenko, Jameer Pathan, Jan Tojnar, Jiehong,
-        Jinyuan Si, Joerg Behrmann, John Slade, Jonathan G. Underwood, Jonathan
-        McDowell, Josh Triplett, Joshua Watt, Julia Cartwright, Julien Humbert,
-        Kairui Song, Karel Zak, Kevin P. Fleming, Khem Raj, Konomi, krissgjeng,
-        l4gfcm, Lajos Veres, Lennart Poettering, Luca Boccassi, Luca BRUNO,
-        Lucas Werkmeister, Luka Kudra, Luna Jernberg, Marc-André Lureau, Martin
-        Wilck, Matthias Klumpp, Matt Turner, Michael Marley, Michal Fabik,
-        Michał Kopeć, Michal Koutný, Michal Sekletár, Mike Gilbert, milovlad,
-        moson-mo, Nick, nihilix-melix, Oğuz Ersen, Ondrej Mosnacek, pali, Pavel
-        Hrdina, Pavel Sapezhko, Perry Yuan, Peter Hutterer, Pierre Dubouilh,
-        Piotr Drąg, Richard Laager, rnhmjoj, RussianNeuroMancer, Sebastiaan van
-        Stijn, Sergey Bugaev, shenyangyang4, simmon, Simonas Kazlauskas,
-        Slimane Selyan Amiri, Stefan Agner, Steve Ramage, Susant Sahani, Sven
-        Mueller, Tad Fisher, Takashi Iwai, Thomas Haller, Tom Shield, Topi
-        Miettinen, Torsten Hilbrich, Tyler Hicks, Ulrich Ölmann, Vincent
-        Pelletier, Vinnie Magro, Vito Caputo, Vlad, walbit-de, Weblate, Weblate
-        (bot), Whired Planck, wouter bolsterlee, Xℹ Ruoyao, Yuri Chornoivan, Yu
-        Watanabe, Zach Smith, Zbigniew Jędrzejewski-Szmek, Zmicer Turok, Дамјан
-        Георгиевски
-
-        — Warsaw, 2021-03-11
+        * Intel SGX enclave device nodes (which expose a security feature of
+          newer Intel CPUs) will now be owned by a new system group "sgx".
+
+        Contributions from: Adam Nielsen, Adrian Vovk, AJ Jordan, Alan Perry,
+        Alastair Pharo, Alexander Batischev, Ali Abdallah, Andrew Balmos,
+        Anita Zhang, Annika Wickert, Ansgar Burchardt, Antonio Terceiro,
+        Antonius Frie, Ardy, Arian van Putten, Ariel Fermani, Arnaud T,
+        A S Alam, Bastien Nocera, Benjamin Berg, Benjamin Robin, Björn Daase,
+        caoxia, Carlo Wood, Charles Lee, ChopperRob, chri2, Christian Ehrhardt,
+        Christian Hesse, Christopher Obbard, clayton craft, corvusnix, cprn,
+        Daan De Meyer, Daniele Medri, Daniel Rusek, Dan Sanders, Dan Streetman,
+        Darren Ng, David Edmundson, David Tardon, Deepak Rawat, Devon Pringle,
+        Dmitry Borodaenko, dropsignal, Einsler Lee, Endre Szabo,
+        Evgeny Vereshchagin, Fabian Affolter, Fangrui Song, Felipe Borges,
+        feliperodriguesfr, Felix Stupp, Florian Hülsmann, Florian Klink,
+        Florian Westphal, Franck Bui, Frantisek Sumsal, Gablegritule,
+        Gaël PORTAY, Gaurav, Giedrius Statkevičius, Greg Depoire-Ferrer,
+        Gustavo Costa, Hans de Goede, Hela Basa, heretoenhance, hide,
+        Iago López Galeiras, igo95862, Ilya Dmitrichenko, Jameer Pathan,
+        Jan Tojnar, Jiehong, Jinyuan Si, Joerg Behrmann, John Slade,
+        Jonathan G. Underwood, Jonathan McDowell, Josh Triplett, Joshua Watt,
+        Julia Cartwright, Julien Humbert, Kairui Song, Karel Zak,
+        Kevin Backhouse, Kevin P. Fleming, Khem Raj, Konomi, krissgjeng,
+        l4gfcm, Lajos Veres, Lennart Poettering, Lincoln Ramsay, Luca Boccassi,
+        Luca BRUNO, Lucas Werkmeister, Luka Kudra, Luna Jernberg,
+        Marc-André Lureau, Martin Wilck, Matthias Klumpp, Matt Turner,
+        Michael Gisbers, Michael Marley, Michael Trapp, Michal Fabik,
+        Michał Kopeć, Michal Koutný, Michal Sekletár, Michele Guerini Rocco,
+        Mike Gilbert, milovlad, moson-mo, Nick, nihilix-melix, Oğuz Ersen,
+        Ondrej Mosnacek, pali, Pavel Hrdina, Pavel Sapezhko, Perry Yuan,
+        Peter Hutterer, Pierre Dubouilh, Piotr Drąg, Pjotr Vertaalt,
+        Richard Laager, RussianNeuroMancer, Sam Lunt, Sebastiaan van Stijn,
+        Sergey Bugaev, shenyangyang4, simmon, Simonas Kazlauskas,
+        Slimane Selyan Amiri, Stefan Agner, Steve Ramage, Susant Sahani,
+        Sven Mueller, Tad Fisher, Takashi Iwai, Thomas Haller, Tom Shield,
+        Topi Miettinen, Torsten Hilbrich, tpgxyz, Tyler Hicks, ulf-f,
+        Ulrich Ölmann, Vincent Pelletier, Vinnie Magro, Vito Caputo, Vlad,
+        walbit-de, Whired Planck, wouter bolsterlee, Xℹ Ruoyao, Yangyang Shen,
+        Yuri Chornoivan, Yu Watanabe, Zach Smith, Zbigniew Jędrzejewski-Szmek,
+        Zmicer Turok, Дамјан Георгиевски
+
+        — Berlin, 2021-03-30
 
 CHANGES WITH 247:
 
diff --git a/TODO b/TODO
index 51a18295f4533ca464cb67918ed0e71764705c38..f3e0ddaac01d207df7448e5755a5faffd9569178 100644 (file)
--- a/TODO
+++ b/TODO
@@ -22,6 +22,31 @@ Janitorial Clean-ups:
 
 Features:
 
+* maybe add a tool that displays most recent journal logs as QR code to scan
+  off screen and run it automatically on boot failures, emergency logs and
+  such. Use DRM APIs directly, see
+  https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset.c for an example
+  for doing that.
+
+* pass systemd-detect-virt result to generators as env var. Modifying behaviour
+  based on whether we are virtualized or not is a pretty common thing, hence
+  maybe just pass that info along for free in an env var. We cache the result
+  anyway, so it's basically free.
+
+* systemd-repart: read LUKS encryption key from $CREDENTIALS_PATH
+
+* introduce /dev/disk/root/* symlinks that allow referencing partitions on the
+  disk the rootfs is on in a reasonably secure way.
+
+* systemd-repart: add a switch to factory reset the partition table without
+  immediately applying the new configuration again. i.e. --factory-reset=leave
+  or so. (this is useful to factory reset an image, then putting it into
+  another machine, ensuring that luks key is generated on new machine, not old)
+
+* move logind udev rules to top-level rule.d/ directory
+
+* move multiseat vid/pid matches from logind udev rule to hwdb
+
 * nspawn: default to 1:1 userns
 
 * Provide a reasonably bespoke solution for mounting host $HOME directories
@@ -36,11 +61,6 @@ Features:
   With all that in place if nspawn host and container payload are up-to-date
   enough we have a very simple way to make host users available in containers.
 
-* systemd-sysusers: pick up passwords from credentials logic, so that users can
-  easily set root user pw. enable cred inheriting for root user from PID 1, so
-  that for containers we can configure the root pw automatically via nspawn's
-  --set-credential= switch. (Also do this for systemd-firstboot)
-
 * whenever we receive fds via SCM_RIGHTS make sure none got dropped due to the
   reception limit the kernel silently enforces.
 
@@ -296,12 +316,6 @@ Features:
 * busctl: maybe expose a verb "ping" for pinging a dbus service to see if it
   exists and responds.
 
-* when systemd-nspawn and suchlike dissect an OS image, and there are multiple
-  root partitions, do an strverscmp() on the partition label and boot
-  first. That is inspired how sd-boot figures out which kernel to boot, and
-  thus allows defining OS images which can be A/B updated and we default to the
-  newest version automatically, both in nspawn and in sd-boot
-
 * systemd-gpt-auto should probably set x-systemd.growfs on the mounts it
   creates
 
@@ -823,9 +837,6 @@ Features:
 
 * journalctl: make sure -f ends when the container indicated by -M terminates
 
-* mount: automatically search for "main" partition of an image has multiple
-  partitions
-
 * in nss-systemd, if we run inside of RootDirectory= with PrivateUsers= set,
   find a way to map the User=/Group= of the service to the right name. This way
   a user/group for a service only has to exist on the host for the right
index f6cc8ba68a08aac2ddbb286e58171bf452bd45d5..22620f184903b470ea3bc9645977d556e599ff9d 100644 (file)
@@ -8,7 +8,8 @@ position p : script:python() {
                  p[0].current_element == "log_set_max_level_realm" or
                  p[0].current_element == "unichar_is_valid")
         };
-expression x, y;
+expression x;
+constant y;
 @@
 (
 - ((x@p) & (y)) == (y)
index 871547a881d20c6a0b3dba06d64329976573b7d1..d1af412acce427636e788e75194531a578871de5 100755 (executable)
@@ -7,6 +7,7 @@ EXCLUDED_PATHS=(
     "src/basic/linux/*"
     # Symlinked to test-bus-vtable-cc.cc, which causes issues with the IN_SET macro
     "src/libsystemd/sd-bus/test-bus-vtable.c"
+    "src/libsystemd/sd-journal/lookup3.c"
 )
 
 top="$(git rev-parse --show-toplevel)"
index a6236eb0f9686e26236b405610b281adfe8583ff..b2096334805a61153f6653f34a9cd76312089a79 100644 (file)
@@ -1,6 +1,7 @@
 @@
+position p : script:python() { p[0].current_element != "test_strjoina" };
 expression n, m;
 expression list s;
 @@
-- n = strjoina(m, s, NULL);
+- n = strjoina@p(m, s, NULL);
 + n = strjoina(m, s);
index 9ce4ebc9407f58326430a046bbf6de831cf20ff1..81d07f88a65535baf429d5d9201420d637263963 100644 (file)
@@ -162,7 +162,14 @@ partition is listed in `/etc/fstab` or with `root=` on the kernel command line,
 it _must_ take precedence over automatically discovered partitions.  If a
 `/home/`, `/usr/`, `/srv/`, `/boot/`, `/var/`, `/var/tmp/`, `/efi/` or `/boot/`
 directory is found to be populated already in the root partition, the automatic
-discovery _must not_ mount any discovered file system over it.
+discovery _must not_ mount any discovered file system over it. Optionally, in
+case of the root, `/usr/` and their Verity partitions instead of strictly
+mounting the first suitable partition an OS might choose to mount the partition
+whose label compares the highest according to `strverscmp()` or a similar
+logic, in order to implement a simple partition-based A/B versioning
+scheme. The precise rules are left for the implementation to decide, but when
+in doubt earlier partitions (by their index) should always win over later
+partitions if the label comparison is inconclusive.
 
 A *container* *manager* should automatically discover and mount the root,
 `/usr/`, `/home/`, `/srv/`, `/var/`, `/var/tmp/` partitions inside a container
index ad2d3ad84b8edef0d3bd2c41a73586bfd9c3bc4a..2cec3bdc1666d6344eb6ba39a1f18afcda9e4eb3 100644 (file)
@@ -198,11 +198,6 @@ All tools:
   prefixed with `:` in which case the kernel command line option takes
   precedence, if it is specified as well.
 
-installed systemd tests:
-
-* `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if
-  a test executable is moved to an arbitrary location.
-
 `nss-systemd`:
 
 * `$SYSTEMD_NSS_BYPASS_SYNTHETIC=1` — if set, `nss-systemd` won't synthesize
@@ -302,6 +297,14 @@ installed systemd tests:
 * `$SYSTEMD_SYSVRCND_PATH` — Controls where `systemd-sysv-generator` looks for
   SysV init script runlevel link farms.
 
+systemd tests:
+
+* `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if
+  a test executable is moved to an arbitrary location.
+
+* `$SYSTEMD_TEST_NSS_BUFSIZE` — size of scratch buffers for "reentrant"
+  functions exported by the nss modules.
+
 fuzzers:
 
 * `$SYSTEMD_FUZZ_OUTPUT` — A boolean that specifies whether to write output to
index 31a06515a114eec91b9caceb54eac5192f4db692..cafe766e0373e375497539b0c3fd86007b129c0f 100644 (file)
@@ -9,14 +9,15 @@ layout: default
 1. Add all items to NEWS
 2. Update the contributors list in NEWS (`meson compile -C build git-contrib`)
 3. Update the time and place in NEWS
-4. [RC1] Update version and library numbers in `meson.build`
-5. Check dbus docs with `meson compile -C build update-dbus-docs`
-6. Tag the release: `version=vXXX-rcY && git tag -s "${version}" -m "systemd ${version}"`
-7. Do `meson compile -C build`
-8. Make sure that the version string and package string match: `build/systemctl --version`
-9. Upload the documentation: `meson compile -C build doc-sync`
-10. [FINAL] Close the github milestone and open a new one (https://github.com/systemd/systemd/milestones)
-11. "Draft" a new release on github (https://github.com/systemd/systemd/releases/new), mark "This is a pre-release" if appropriate.
-12. Check that announcement to systemd-devel, with a copy&paste from NEWS, was sent. This should happen automatically.
-13. Update IRC topic (`/msg chanserv TOPIC #systemd Version NNN released`)
-14. [FINAL] Push commits to stable, create an empty -stable branch: `git push systemd-stable origin/master:master origin/master:refs/heads/${version}-stable`, and change the default branch to latest release (https://github.com/systemd/systemd-stable/settings/branches).
+4. Update hwb (`meson compile -C build update-hwdb update-hwdb-autosuspend`)
+5. [RC1] Update version and library numbers in `meson.build`
+6. Check dbus docs with `meson compile -C build update-dbus-docs`
+7. Tag the release: `version=vXXX-rcY && git tag -s "${version}" -m "systemd ${version}"`
+8. Do `meson compile -C build`
+9. Make sure that the version string and package string match: `build/systemctl --version`
+10. Upload the documentation: `meson compile -C build doc-sync`
+11. [FINAL] Close the github milestone and open a new one (https://github.com/systemd/systemd/milestones)
+12. "Draft" a new release on github (https://github.com/systemd/systemd/releases/new), mark "This is a pre-release" if appropriate.
+13. Check that announcement to systemd-devel, with a copy&paste from NEWS, was sent. This should happen automatically.
+14. Update IRC topic (`/msg chanserv TOPIC #systemd Version NNN released`)
+15. [FINAL] Push commits to stable, create an empty -stable branch: `git push systemd-stable origin/master:master origin/master:refs/heads/${version}-stable`, and change the default branch to latest release (https://github.com/systemd/systemd-stable/settings/branches).
index 9f69a3162a0d8e7cb1c08a51eba8f26dee2479af..9fa856ec21c91ecc6e42fd8f558f71a9714dbc37 100644 (file)
@@ -303,6 +303,7 @@ Most service unit settings are available for transient units.
 ✓ ExecStartPre=
 ✓ ExecStop=
 ✓ ExecStopPost=
+✓ ExitType=
 ✓ FileDescriptorStoreMax=
 ✓ GuessMainPID=
 ✓ NonBlocking=
index 95289732b7b350353887b77a4e977303a2aa029c..e103a278c4032e0861770aa269e045c36a4df6f8 100644 (file)
@@ -1,5 +1,5 @@
 <footer class="site-footer">
-  <p>&copy; systemd, 2020</p>
+  <p>&copy; systemd, 2021</p>
 
-  <p><a href="https://github.com/systemd/systemd">Website source</a></p>
+  <p><a href="https://github.com/systemd/systemd/tree/main/docs">Website source</a></p>
 </footer>
index ca98de803751dec96b9ed7499653d5cdb952f432..5deed1b78504c93ba04ff7de2a754b40f38991a1 100644 (file)
@@ -2418,7 +2418,7 @@ OUI:000323*
  ID_OUI_FROM_DATABASE=Cornet Technology, Inc.
 
 OUI:000324*
- ID_OUI_FROM_DATABASE=SANYO Consumer Electronics Co., Ltd.
+ ID_OUI_FROM_DATABASE=SANYO Techno Solutions Tottori Co., Ltd.
 
 OUI:000325*
  ID_OUI_FROM_DATABASE=Arima Computer Corp.
@@ -8544,7 +8544,7 @@ OUI:000B39*
  ID_OUI_FROM_DATABASE=Keisoku Giken Co.,Ltd.
 
 OUI:000B3A*
- ID_OUI_FROM_DATABASE=QuStream Corporation
+ ID_OUI_FROM_DATABASE=PESA
 
 OUI:000B3B*
  ID_OUI_FROM_DATABASE=devolo AG
@@ -39431,6 +39431,9 @@ OUI:00FA21*
 OUI:00FA3B*
  ID_OUI_FROM_DATABASE=CLOOS ELECTRONIC GMBH
 
+OUI:00FAB6*
+ ID_OUI_FROM_DATABASE=Kontakt Micro-Location Sp z o.o.
+
 OUI:00FC58*
  ID_OUI_FROM_DATABASE=WebSilicon Ltd.
 
@@ -39908,6 +39911,9 @@ OUI:04714BD*
 OUI:04714BE*
  ID_OUI_FROM_DATABASE=Gimso Mobile Ltd
 
+OUI:047153*
+ ID_OUI_FROM_DATABASE=SERNET (SUZHOU) TECHNOLOGIES CORPORATION
+
 OUI:047295*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -40103,6 +40109,9 @@ OUI:04B466*
 OUI:04B648*
  ID_OUI_FROM_DATABASE=ZENNER
 
+OUI:04B9E3*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:04BA1C*
  ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
 
@@ -40412,6 +40421,9 @@ OUI:04EE03*
 OUI:04EE91*
  ID_OUI_FROM_DATABASE=x-fabric GmbH
 
+OUI:04EEEE*
+ ID_OUI_FROM_DATABASE=Laplace System Co., Ltd.
+
 OUI:04F021*
  ID_OUI_FROM_DATABASE=Compex Systems Pte Ltd
 
@@ -40919,6 +40931,9 @@ OUI:080581*
 OUI:0805CD*
  ID_OUI_FROM_DATABASE=DongGuang EnMai Electronic Product Co.Ltd.
 
+OUI:0805E2*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
 OUI:0808C2*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -41876,6 +41891,9 @@ OUI:0C41E9*
 OUI:0C42A1*
  ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
 
+OUI:0C4314*
+ ID_OUI_FROM_DATABASE=Silicon Laboratories
+
 OUI:0C45BA*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -42002,6 +42020,9 @@ OUI:0C5CD8*
 OUI:0C5F35*
  ID_OUI_FROM_DATABASE=Niagara Video Corporation
 
+OUI:0C6046*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
 OUI:0C6076*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
@@ -42242,6 +42263,9 @@ OUI:0C96E6*
 OUI:0C9838*
  ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
 
+OUI:0C9A3C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:0C9A42*
  ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED
 
@@ -42737,6 +42761,9 @@ OUI:1008B1*
 OUI:10090C*
  ID_OUI_FROM_DATABASE=Janome Sewing Machine Co., Ltd.
 
+OUI:1009F9*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:100BA9*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -42992,6 +43019,9 @@ OUI:105172*
 OUI:10521C*
  ID_OUI_FROM_DATABASE=Espressif Inc.
 
+OUI:105403*
+ ID_OUI_FROM_DATABASE=INTARSO GmbH
+
 OUI:105611*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -43070,6 +43100,9 @@ OUI:10683F*
 OUI:106F3F*
  ID_OUI_FROM_DATABASE=BUFFALO.INC
 
+OUI:106FD9*
+ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD.
+
 OUI:106FEF*
  ID_OUI_FROM_DATABASE=Ad-Sol Nissin Corp
 
@@ -44084,6 +44117,9 @@ OUI:1489FD*
 OUI:148A70*
  ID_OUI_FROM_DATABASE=ADS GmbH
 
+OUI:148C4A*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:148F21*
  ID_OUI_FROM_DATABASE=Garmin International
 
@@ -44876,6 +44912,21 @@ OUI:1871D5*
 OUI:18742E*
  ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
 
+OUI:1874E21*
+ ID_OUI_FROM_DATABASE=Sartorius Lab Instruments GmbH & Co. KG
+
+OUI:1874E25*
+ ID_OUI_FROM_DATABASE=HANGZHOU ZHOUJU ELECTRONIC TECHNOLOGICAL CO.,LTD
+
+OUI:1874E27*
+ ID_OUI_FROM_DATABASE=Sansec Technology Co.,Ltd
+
+OUI:1874E28*
+ ID_OUI_FROM_DATABASE=Kano Computing Limited
+
+OUI:1874E2C*
+ ID_OUI_FROM_DATABASE=NextGen RF Design, Inc.
+
 OUI:187532*
  ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD
 
@@ -45635,6 +45686,9 @@ OUI:1C3B8F*
 OUI:1C3BF3*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
+OUI:1C3CD4*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:1C3D2F*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -46880,6 +46934,9 @@ OUI:203B69*
 OUI:203CAE*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:203CC0*
+ ID_OUI_FROM_DATABASE=Beijing Tosee Technology Co., Ltd.
+
 OUI:203D66*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -47303,6 +47360,9 @@ OUI:20C047*
 OUI:20C06D*
  ID_OUI_FROM_DATABASE=SHENZHEN SPACETEK TECHNOLOGY CO.,LTD
 
+OUI:20C19B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:20C1AF*
  ID_OUI_FROM_DATABASE=i Wit Digital Co., Limited
 
@@ -47384,6 +47444,9 @@ OUI:20CEC4*
 OUI:20CF30*
  ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
 
+OUI:20CFAE*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:20D160*
  ID_OUI_FROM_DATABASE=Private
 
@@ -47393,6 +47456,9 @@ OUI:20D21F*
 OUI:20D25F*
  ID_OUI_FROM_DATABASE=SmartCap Technologies
 
+OUI:20D276*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
 OUI:20D390*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -47711,6 +47777,9 @@ OUI:24240E*
 OUI:242642*
  ID_OUI_FROM_DATABASE=SHARP Corporation.
 
+OUI:2428FD*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
 OUI:2429FE*
  ID_OUI_FROM_DATABASE=KYOCERA Corporation
 
@@ -48104,6 +48173,9 @@ OUI:249504*
 OUI:2497ED*
  ID_OUI_FROM_DATABASE=Techvision Intelligent Technology Limited
 
+OUI:249AC8*
+ ID_OUI_FROM_DATABASE=Shenzhen Skyworth  Digital  Technology  CO., Ltd
+
 OUI:249AD8*
  ID_OUI_FROM_DATABASE=YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD.
 
@@ -48312,7 +48384,7 @@ OUI:24DFA7*
  ID_OUI_FROM_DATABASE=Hangzhou BroadLink Technology Co.,Ltd
 
 OUI:24E124*
- ID_OUI_FROM_DATABASE=Xiamen Ursalink Technology Co., Ltd.
+ ID_OUI_FROM_DATABASE=Xiamen Milesight IoT Co., Ltd.
 
 OUI:24E271*
  ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
@@ -48455,6 +48527,9 @@ OUI:280E8B*
 OUI:280FC5*
  ID_OUI_FROM_DATABASE=Beijing Leadsec Technology Co., Ltd.
 
+OUI:280FEB*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
 OUI:28101B*
  ID_OUI_FROM_DATABASE=MagnaCom
 
@@ -48464,6 +48539,9 @@ OUI:28107B*
 OUI:2811A5*
  ID_OUI_FROM_DATABASE=Bose Corporation
 
+OUI:2811A8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:2811EC*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -49196,6 +49274,9 @@ OUI:28DEE5*
 OUI:28DEF6*
  ID_OUI_FROM_DATABASE=bioMerieux Inc.
 
+OUI:28DFEB*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:28E02C*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -49331,12 +49412,18 @@ OUI:28F537E*
 OUI:28F606*
  ID_OUI_FROM_DATABASE=Syes srl
 
+OUI:28FA19*
+ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd
+
 OUI:28FA7A*
  ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd.
 
 OUI:28FAA0*
  ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
 
+OUI:28FBAE*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:28FBD3*
  ID_OUI_FROM_DATABASE=Ragentek Technology Group
 
@@ -49835,6 +49922,9 @@ OUI:2C4835D*
 OUI:2C4835E*
  ID_OUI_FROM_DATABASE=IROOTECH TECHNOLOGY CO.,LTD
 
+OUI:2C4881*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
 OUI:2C4A11*
  ID_OUI_FROM_DATABASE=Ciena Corporation
 
@@ -50012,6 +50102,9 @@ OUI:2C6B7D*
 OUI:2C6BF5*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
+OUI:2C6DC1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:2C6E85*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -50372,6 +50465,9 @@ OUI:2CDD95*
 OUI:2CDDA3*
  ID_OUI_FROM_DATABASE=Point Grey Research Inc.
 
+OUI:2CDDE9*
+ ID_OUI_FROM_DATABASE=Arista Networks
+
 OUI:2CE2A8*
  ID_OUI_FROM_DATABASE=DeviceDesign
 
@@ -50802,7 +50898,7 @@ OUI:304950C*
  ID_OUI_FROM_DATABASE=Anacove LLC
 
 OUI:304950D*
- ID_OUI_FROM_DATABASE=Xio Research, Inc
+ ID_OUI_FROM_DATABASE=Merlyn Mind, Inc.
 
 OUI:304950E*
  ID_OUI_FROM_DATABASE=IoTmaxx GmbH
@@ -51062,6 +51158,9 @@ OUI:309FFB*
 OUI:30A023*
  ID_OUI_FROM_DATABASE=ROCK PATH S.R.L
 
+OUI:30A176*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:30A1FA*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -51125,6 +51224,9 @@ OUI:30B216*
 OUI:30B237*
  ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd.
 
+OUI:30B346*
+ ID_OUI_FROM_DATABASE=CJSC NORSI-TRANS
+
 OUI:30B3A2*
  ID_OUI_FROM_DATABASE=Shenzhen Heguang Measurement & Control Technology Co.,Ltd
 
@@ -53228,6 +53330,9 @@ OUI:38E26E*
 OUI:38E2DD*
  ID_OUI_FROM_DATABASE=zte corporation
 
+OUI:38E39F*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
 OUI:38E3C5*
  ID_OUI_FROM_DATABASE=Taicang T&W Electronics
 
@@ -55211,6 +55316,9 @@ OUI:40C245*
 OUI:40C3C6*
  ID_OUI_FROM_DATABASE=SnapRoute
 
+OUI:40C48C*
+ ID_OUI_FROM_DATABASE=N-iTUS CO.,LTD.
+
 OUI:40C4D6*
  ID_OUI_FROM_DATABASE=ChongQing Camyu Technology Development Co.,Ltd.
 
@@ -55784,6 +55892,9 @@ OUI:44599F*
 OUI:4459E3*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:445BED*
+ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company
+
 OUI:445CE9*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -55829,6 +55940,9 @@ OUI:4466FC*
 OUI:446747*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:446752*
+ ID_OUI_FROM_DATABASE=Wistron INFOCOMM (Zhongshan) CORPORATION
+
 OUI:446755*
  ID_OUI_FROM_DATABASE=Orbit Irrigation
 
@@ -56507,6 +56621,9 @@ OUI:48210B*
 OUI:48216C*
  ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited
 
+OUI:482218*
+ ID_OUI_FROM_DATABASE=Shenzhen Yipingfang Network Technology Co., Ltd.
+
 OUI:482335*
  ID_OUI_FROM_DATABASE=Dialog Semiconductor Hellas SA
 
@@ -56915,6 +57032,9 @@ OUI:489D24*
 OUI:489DD1*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:489EBD*
+ ID_OUI_FROM_DATABASE=HP Inc.
+
 OUI:48A0F8*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
@@ -57140,6 +57260,9 @@ OUI:48E695*
 OUI:48E6C0*
  ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd.
 
+OUI:48E7DA*
+ ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+
 OUI:48E9F1*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -57203,6 +57326,9 @@ OUI:48F8DB*
 OUI:48F8E1*
  ID_OUI_FROM_DATABASE=Nokia
 
+OUI:48F8FF*
+ ID_OUI_FROM_DATABASE=CHENGDU KT ELECTRONIC HI-TECH CO.,LTD
+
 OUI:48F925*
  ID_OUI_FROM_DATABASE=Maestronic
 
@@ -57632,6 +57758,9 @@ OUI:4C710C*
 OUI:4C710D*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:4C7167*
+ ID_OUI_FROM_DATABASE=PoLabs d.o.o.
+
 OUI:4C72B9*
  ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
 
@@ -58070,6 +58199,9 @@ OUI:4CD1A1*
 OUI:4CD3AF*
  ID_OUI_FROM_DATABASE=HMD Global Oy
 
+OUI:4CD577*
+ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD.
+
 OUI:4CD637*
  ID_OUI_FROM_DATABASE=Qsono Electronics Co., Ltd
 
@@ -58271,6 +58403,9 @@ OUI:5006AB*
 OUI:500959*
  ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
 
+OUI:5009E5*
+ ID_OUI_FROM_DATABASE=Drimsys,Inc
+
 OUI:500B32*
  ID_OUI_FROM_DATABASE=Foxda Technology Industrial(ShenZhen)Co.,LTD
 
@@ -58718,6 +58853,9 @@ OUI:506F9A*
 OUI:507043*
  ID_OUI_FROM_DATABASE=BSkyB Ltd
 
+OUI:507097*
+ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
+
 OUI:5070E5*
  ID_OUI_FROM_DATABASE=He Shan World Fair Electronics Technology Limited
 
@@ -59456,6 +59594,9 @@ OUI:5435DF*
 OUI:54369B*
  ID_OUI_FROM_DATABASE=1Verge Internet Technology (Beijing) Co., Ltd.
 
+OUI:5437BB*
+ ID_OUI_FROM_DATABASE=Taicang T&W Electronics
+
 OUI:543968*
  ID_OUI_FROM_DATABASE=Edgewater Networks Inc
 
@@ -59912,6 +60053,9 @@ OUI:54BEF7*
 OUI:54BF64*
  ID_OUI_FROM_DATABASE=Dell Inc.
 
+OUI:54C250*
+ ID_OUI_FROM_DATABASE=Iskratel d.o.o.
+
 OUI:54C33E*
  ID_OUI_FROM_DATABASE=Ciena Corporation
 
@@ -60338,6 +60482,9 @@ OUI:584C19*
 OUI:584CEE*
  ID_OUI_FROM_DATABASE=Digital One Technologies, Limited
 
+OUI:584D42*
+ ID_OUI_FROM_DATABASE=Dragos, Inc.
+
 OUI:585076*
  ID_OUI_FROM_DATABASE=Linear Equipamentos Eletronicos SA
 
@@ -60755,6 +60902,9 @@ OUI:58D56E*
 OUI:58D67A*
  ID_OUI_FROM_DATABASE=TCPlink
 
+OUI:58D697*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
 OUI:58D6D3*
  ID_OUI_FROM_DATABASE=Dairy Cheq Inc
 
@@ -61472,6 +61622,9 @@ OUI:5CA5BC*
 OUI:5CA62D*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:5CA721*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
 OUI:5CA86A*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -61688,6 +61841,9 @@ OUI:5CE30E*
 OUI:5CE3B6*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
+OUI:5CE42A*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:5CE50C*
  ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd
 
@@ -61997,6 +62153,9 @@ OUI:6023A4*
 OUI:6024C1*
  ID_OUI_FROM_DATABASE=Jiangsu Zhongxun Electronic Technology Co., Ltd
 
+OUI:6026EF*
+ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company
+
 OUI:60271C*
  ID_OUI_FROM_DATABASE=VIDEOR E. Hartig GmbH
 
@@ -62279,6 +62438,9 @@ OUI:6089B1*
 OUI:6089B7*
  ID_OUI_FROM_DATABASE=KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ
 
+OUI:608A10*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
 OUI:608B0E*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -62387,6 +62549,9 @@ OUI:609AC1*
 OUI:609B2D*
  ID_OUI_FROM_DATABASE=JMACS Japan Co., Ltd.
 
+OUI:609BB4*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:609BC8*
  ID_OUI_FROM_DATABASE=Hipad Intelligent Technology Co., Ltd.
 
@@ -62420,6 +62585,9 @@ OUI:60A4B7*
 OUI:60A4D0*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:60A5E2*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:60A730*
  ID_OUI_FROM_DATABASE=Shenzhen Yipinfang Internet Technology Co.,Ltd
 
@@ -62468,6 +62636,9 @@ OUI:60B606*
 OUI:60B617*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
+OUI:60B6E1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:60B76E*
  ID_OUI_FROM_DATABASE=Google, Inc.
 
@@ -62636,6 +62807,9 @@ OUI:60DA23*
 OUI:60DA83*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
+OUI:60DB15*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
 OUI:60DB2A*
  ID_OUI_FROM_DATABASE=HNS
 
@@ -62729,6 +62903,9 @@ OUI:60F677*
 OUI:60F81D*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:60F8F2*
+ ID_OUI_FROM_DATABASE=Synaptec
+
 OUI:60FA9D*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -63389,6 +63566,9 @@ OUI:64B310*
 OUI:64B370*
  ID_OUI_FROM_DATABASE=PowerComm Solutions LLC
 
+OUI:64B379*
+ ID_OUI_FROM_DATABASE=Private
+
 OUI:64B473*
  ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
 
@@ -63468,7 +63648,7 @@ OUI:64CFD9*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
 OUI:64D02D*
- ID_OUI_FROM_DATABASE=Next Generation Integration (NGI)
+ ID_OUI_FROM_DATABASE=NEXT GENERATION INTEGRATION LIMITED (NGI)
 
 OUI:64D154*
  ID_OUI_FROM_DATABASE=Routerboard.com
@@ -64412,6 +64592,9 @@ OUI:68EBC5*
 OUI:68EC62*
  ID_OUI_FROM_DATABASE=YODO Technology Corp. Ltd.
 
+OUI:68EC8A*
+ ID_OUI_FROM_DATABASE=Private
+
 OUI:68ECC5*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -64517,6 +64700,9 @@ OUI:6C0EE6*
 OUI:6C0F6A*
  ID_OUI_FROM_DATABASE=JDC Tech Co., Ltd.
 
+OUI:6C108B*
+ ID_OUI_FROM_DATABASE=WeLink Communications
+
 OUI:6C13D5*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -64691,6 +64877,9 @@ OUI:6C416A*
 OUI:6C42AB*
  ID_OUI_FROM_DATABASE=Subscriber Networks, Inc.
 
+OUI:6C433C*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
 OUI:6C4418*
  ID_OUI_FROM_DATABASE=Zappware
 
@@ -64892,6 +65081,9 @@ OUI:6C7637*
 OUI:6C7660*
  ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
 
+OUI:6C79B8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:6C81FE*
  ID_OUI_FROM_DATABASE=Mitsuba Corporation
 
@@ -65945,6 +66137,9 @@ OUI:709383*
 OUI:7093F8*
  ID_OUI_FROM_DATABASE=Space Monkey, Inc.
 
+OUI:709741*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
 OUI:709756*
  ID_OUI_FROM_DATABASE=Happyelectronics Co.,Ltd
 
@@ -65990,6 +66185,9 @@ OUI:70A41C*
 OUI:70A66A*
  ID_OUI_FROM_DATABASE=Prox Dynamics AS
 
+OUI:70A6CC*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:70A84C*
  ID_OUI_FROM_DATABASE=MONAD., Inc.
 
@@ -66192,7 +66390,7 @@ OUI:70B3D5035*
  ID_OUI_FROM_DATABASE=HKW-Elektronik GmbH
 
 OUI:70B3D5036*
- ID_OUI_FROM_DATABASE=PARAGON ID
+ ID_OUI_FROM_DATABASE=Vema Venturi AB
 
 OUI:70B3D5037*
  ID_OUI_FROM_DATABASE=EIFFAGE ENERGIE ELECTRONIQUE
@@ -66887,6 +67085,9 @@ OUI:70B3D511C*
 OUI:70B3D511D*
  ID_OUI_FROM_DATABASE=Dakton Microlabs LLC
 
+OUI:70B3D511E*
+ ID_OUI_FROM_DATABASE=KBPR LLC
+
 OUI:70B3D511F*
  ID_OUI_FROM_DATABASE=Geppetto Electronics
 
@@ -67358,6 +67559,9 @@ OUI:70B3D51BA*
 OUI:70B3D51BB*
  ID_OUI_FROM_DATABASE=EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
 
+OUI:70B3D51BC*
+ ID_OUI_FROM_DATABASE=Flextronics International Kft
+
 OUI:70B3D51BD*
  ID_OUI_FROM_DATABASE=Shenzhen Siera Technology Ltd
 
@@ -67499,6 +67703,9 @@ OUI:70B3D51EA*
 OUI:70B3D51EB*
  ID_OUI_FROM_DATABASE=Xavant
 
+OUI:70B3D51ED*
+ ID_OUI_FROM_DATABASE=SUS Corporation
+
 OUI:70B3D51EE*
  ID_OUI_FROM_DATABASE=MEGGITT
 
@@ -67658,6 +67865,9 @@ OUI:70B3D5221*
 OUI:70B3D5222*
  ID_OUI_FROM_DATABASE=Marioff Corporation Oy
 
+OUI:70B3D5223*
+ ID_OUI_FROM_DATABASE=Research Laboratory of Design Automation, Ltd.
+
 OUI:70B3D5224*
  ID_OUI_FROM_DATABASE=Urbana Smart Solutions Pte Ltd
 
@@ -67886,6 +68096,9 @@ OUI:70B3D526F*
 OUI:70B3D5270*
  ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
 
+OUI:70B3D5271*
+ ID_OUI_FROM_DATABASE=Code Blue Corporation
+
 OUI:70B3D5272*
  ID_OUI_FROM_DATABASE=TELECOM SANTE
 
@@ -68090,6 +68303,9 @@ OUI:70B3D52B4*
 OUI:70B3D52B5*
  ID_OUI_FROM_DATABASE=Dosepack India LLP
 
+OUI:70B3D52B6*
+ ID_OUI_FROM_DATABASE=HLT Micro
+
 OUI:70B3D52B7*
  ID_OUI_FROM_DATABASE=Matrix Orbital Corporation
 
@@ -68369,12 +68585,18 @@ OUI:70B3D5313*
 OUI:70B3D5314*
  ID_OUI_FROM_DATABASE=Grau Elektronik GmbH
 
+OUI:70B3D5315*
+ ID_OUI_FROM_DATABASE=Private
+
 OUI:70B3D5316*
  ID_OUI_FROM_DATABASE=Austco Marketing & Service (USA) ltd.
 
 OUI:70B3D5317*
  ID_OUI_FROM_DATABASE=Iotopia Solutions
 
+OUI:70B3D5318*
+ ID_OUI_FROM_DATABASE=Exemplar Medical, LLC
+
 OUI:70B3D5319*
  ID_OUI_FROM_DATABASE=ISO/TC 22/SC 31
 
@@ -68453,6 +68675,9 @@ OUI:70B3D5331*
 OUI:70B3D5332*
  ID_OUI_FROM_DATABASE=InnoSenT
 
+OUI:70B3D5333*
+ ID_OUI_FROM_DATABASE=Orlaco Products B.V.
+
 OUI:70B3D5334*
  ID_OUI_FROM_DATABASE=Dokuen Co. Ltd.
 
@@ -68840,6 +69065,9 @@ OUI:70B3D53B4*
 OUI:70B3D53B5*
  ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience
 
+OUI:70B3D53B6*
+ ID_OUI_FROM_DATABASE=MedRx, Inc
+
 OUI:70B3D53B7*
  ID_OUI_FROM_DATABASE=Paul Scherrer Institut (PSI)
 
@@ -69656,6 +69884,9 @@ OUI:70B3D54C9*
 OUI:70B3D54CA*
  ID_OUI_FROM_DATABASE=PCB Piezotronics
 
+OUI:70B3D54CB*
+ ID_OUI_FROM_DATABASE=Cucos Retail Systems GmbH
+
 OUI:70B3D54CC*
  ID_OUI_FROM_DATABASE=FRESENIUS MEDICAL CARE
 
@@ -69668,6 +69899,9 @@ OUI:70B3D54CE*
 OUI:70B3D54CF*
  ID_OUI_FROM_DATABASE=GREEN HOUSE CO., LTD.
 
+OUI:70B3D54D0*
+ ID_OUI_FROM_DATABASE=Codewerk GmbH
+
 OUI:70B3D54D1*
  ID_OUI_FROM_DATABASE=Contraves Advanced Devices Sdn. Bhd.
 
@@ -70973,6 +71207,9 @@ OUI:70B3D5683*
 OUI:70B3D5684*
  ID_OUI_FROM_DATABASE=LECO Corporation
 
+OUI:70B3D5685*
+ ID_OUI_FROM_DATABASE=LDA Audiotech
+
 OUI:70B3D5686*
  ID_OUI_FROM_DATABASE=Access Protocol Pty Ltd
 
@@ -71027,6 +71264,9 @@ OUI:70B3D5696*
 OUI:70B3D5697*
  ID_OUI_FROM_DATABASE=Alazar Technologies Inc.
 
+OUI:70B3D5698*
+ ID_OUI_FROM_DATABASE=ZIEHL-ABEGG SE
+
 OUI:70B3D5699*
  ID_OUI_FROM_DATABASE=Flextronics International Kft
 
@@ -71034,7 +71274,7 @@ OUI:70B3D569A*
  ID_OUI_FROM_DATABASE=Altaneos
 
 OUI:70B3D569B*
- ID_OUI_FROM_DATABASE=Horizon Co., Ltd
+ ID_OUI_FROM_DATABASE=HORIZON.INC
 
 OUI:70B3D569C*
  ID_OUI_FROM_DATABASE=Keepen
@@ -71429,6 +71669,9 @@ OUI:70B3D571D*
 OUI:70B3D571E*
  ID_OUI_FROM_DATABASE=Motec Pty Ltd
 
+OUI:70B3D571F*
+ ID_OUI_FROM_DATABASE=Grayshift
+
 OUI:70B3D5720*
  ID_OUI_FROM_DATABASE=Jeio Tech
 
@@ -72191,6 +72434,9 @@ OUI:70B3D581D*
 OUI:70B3D581E*
  ID_OUI_FROM_DATABASE=Novathings
 
+OUI:70B3D581F*
+ ID_OUI_FROM_DATABASE=CAR-connect GmbH
+
 OUI:70B3D5820*
  ID_OUI_FROM_DATABASE=Becker Nachrichtentechnik GmbH
 
@@ -73175,6 +73421,9 @@ OUI:70B3D5968*
 OUI:70B3D5969*
  ID_OUI_FROM_DATABASE=Emtel System Sp. z o.o.
 
+OUI:70B3D596A*
+ ID_OUI_FROM_DATABASE=Anello Photonics
+
 OUI:70B3D596B*
  ID_OUI_FROM_DATABASE=FOCAL-JMLab
 
@@ -73502,6 +73751,9 @@ OUI:70B3D59D6*
 OUI:70B3D59D7*
  ID_OUI_FROM_DATABASE=KM OptoElektronik GmbH
 
+OUI:70B3D59D8*
+ ID_OUI_FROM_DATABASE=JOLANYEE  Technology Co., Ltd.
+
 OUI:70B3D59D9*
  ID_OUI_FROM_DATABASE=ATX Networks Corp
 
@@ -73655,6 +73907,9 @@ OUI:70B3D5A0A*
 OUI:70B3D5A0B*
  ID_OUI_FROM_DATABASE=ambiHome GmbH
 
+OUI:70B3D5A0C*
+ ID_OUI_FROM_DATABASE=Lumiplan Duhamel
+
 OUI:70B3D5A0D*
  ID_OUI_FROM_DATABASE=Globalcom Engineering SPA
 
@@ -73676,6 +73931,9 @@ OUI:70B3D5A12*
 OUI:70B3D5A13*
  ID_OUI_FROM_DATABASE=Uplevel Systems Inc
 
+OUI:70B3D5A14*
+ ID_OUI_FROM_DATABASE=aelettronica group srl
+
 OUI:70B3D5A15*
  ID_OUI_FROM_DATABASE=Intercore GmbH
 
@@ -73910,6 +74168,9 @@ OUI:70B3D5A61*
 OUI:70B3D5A62*
  ID_OUI_FROM_DATABASE=Environexus
 
+OUI:70B3D5A63*
+ ID_OUI_FROM_DATABASE=DesignA Electronics Limited
+
 OUI:70B3D5A64*
  ID_OUI_FROM_DATABASE=Newshine
 
@@ -74039,6 +74300,9 @@ OUI:70B3D5A8D*
 OUI:70B3D5A8E*
  ID_OUI_FROM_DATABASE=OMESH CITY GROUP
 
+OUI:70B3D5A8F*
+ ID_OUI_FROM_DATABASE=VK Integrated Systems
+
 OUI:70B3D5A90*
  ID_OUI_FROM_DATABASE=ERA a.s.
 
@@ -74222,6 +74486,9 @@ OUI:70B3D5ACC*
 OUI:70B3D5ACD*
  ID_OUI_FROM_DATABASE=CRDE
 
+OUI:70B3D5ACE*
+ ID_OUI_FROM_DATABASE=FARHO DOMOTICA SL
+
 OUI:70B3D5ACF*
  ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC
 
@@ -74360,6 +74627,9 @@ OUI:70B3D5AFB*
 OUI:70B3D5AFC*
  ID_OUI_FROM_DATABASE=BAE Systems
 
+OUI:70B3D5AFD*
+ ID_OUI_FROM_DATABASE=dongsheng
+
 OUI:70B3D5AFE*
  ID_OUI_FROM_DATABASE=MESOTECHNIC
 
@@ -75095,6 +75365,9 @@ OUI:70B3D5BF5*
 OUI:70B3D5BF6*
  ID_OUI_FROM_DATABASE=comtac AG
 
+OUI:70B3D5BF7*
+ ID_OUI_FROM_DATABASE=Fischer Connectors
+
 OUI:70B3D5BF8*
  ID_OUI_FROM_DATABASE=RCH ITALIA SPA
 
@@ -75194,6 +75467,9 @@ OUI:70B3D5C17*
 OUI:70B3D5C18*
  ID_OUI_FROM_DATABASE=Sanmina Israel
 
+OUI:70B3D5C19*
+ ID_OUI_FROM_DATABASE=Zumbach Electronic AG
+
 OUI:70B3D5C1A*
  ID_OUI_FROM_DATABASE=Xylon
 
@@ -75455,6 +75731,9 @@ OUI:70B3D5C6F*
 OUI:70B3D5C70*
  ID_OUI_FROM_DATABASE=Magnetek
 
+OUI:70B3D5C71*
+ ID_OUI_FROM_DATABASE=The Engineerix Group
+
 OUI:70B3D5C72*
  ID_OUI_FROM_DATABASE=Scharco Elektronik GmbH
 
@@ -76157,6 +76436,9 @@ OUI:70B3D5D5B*
 OUI:70B3D5D5C*
  ID_OUI_FROM_DATABASE=Critical Link LLC
 
+OUI:70B3D5D5D*
+ ID_OUI_FROM_DATABASE=SEASONS 4 INC
+
 OUI:70B3D5D5E*
  ID_OUI_FROM_DATABASE=Barcelona Smart Technologies
 
@@ -76652,9 +76934,15 @@ OUI:70B3D5E01*
 OUI:70B3D5E02*
  ID_OUI_FROM_DATABASE=YEHL & JORDAN LLC
 
+OUI:70B3D5E03*
+ ID_OUI_FROM_DATABASE=MBJ
+
 OUI:70B3D5E04*
  ID_OUI_FROM_DATABASE=Combilent
 
+OUI:70B3D5E05*
+ ID_OUI_FROM_DATABASE=Lobaro GmbH
+
 OUI:70B3D5E06*
  ID_OUI_FROM_DATABASE=System West dba ICS Electronics
 
@@ -76679,6 +76967,9 @@ OUI:70B3D5E0C*
 OUI:70B3D5E0D*
  ID_OUI_FROM_DATABASE=Sigma Connectivity AB
 
+OUI:70B3D5E0E*
+ ID_OUI_FROM_DATABASE=VulcanForms
+
 OUI:70B3D5E0F*
  ID_OUI_FROM_DATABASE=Vtron Pty Ltd
 
@@ -77588,6 +77879,9 @@ OUI:70B3D5F3E*
 OUI:70B3D5F3F*
  ID_OUI_FROM_DATABASE=comtac AG
 
+OUI:70B3D5F40*
+ ID_OUI_FROM_DATABASE=HORIZON.INC
+
 OUI:70B3D5F41*
  ID_OUI_FROM_DATABASE=DUEVI SRL
 
@@ -78170,6 +78464,9 @@ OUI:70B7E2*
 OUI:70B921*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
+OUI:70B950*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:70BAEF*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
@@ -78797,6 +79094,9 @@ OUI:745C4B*
 OUI:745C9F*
  ID_OUI_FROM_DATABASE=TCT mobile ltd
 
+OUI:745D68*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:745E1C*
  ID_OUI_FROM_DATABASE=PIONEER CORPORATION
 
@@ -79169,6 +79469,9 @@ OUI:74CD0C*
 OUI:74CE56*
  ID_OUI_FROM_DATABASE=Packet Force Technology Limited Company
 
+OUI:74CF00*
+ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd.
+
 OUI:74D02B*
  ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
 
@@ -79289,6 +79592,9 @@ OUI:74E19A*
 OUI:74E1B6*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:74E20C*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:74E277*
  ID_OUI_FROM_DATABASE=Vizmonet Pte Ltd
 
@@ -79874,6 +80180,9 @@ OUI:7884EE*
 OUI:7885F4*
  ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
 
+OUI:7886B6*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
 OUI:78870D*
  ID_OUI_FROM_DATABASE=Unifiedgateways India Private Limited
 
@@ -80084,6 +80393,9 @@ OUI:78BAD0*
 OUI:78BAF9*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:78BB88*
+ ID_OUI_FROM_DATABASE=Maxio Technology (Hangzhou) Ltd.
+
 OUI:78BC1A*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -80324,6 +80636,9 @@ OUI:78D66F*
 OUI:78D6B2*
  ID_OUI_FROM_DATABASE=Toshiba
 
+OUI:78D6DC*
+ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
+
 OUI:78D6F0*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD.
 
@@ -80669,6 +80984,9 @@ OUI:7C2634*
 OUI:7C2664*
  ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
 
+OUI:7C27BC*
+ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD
+
 OUI:7C2A31*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -80981,6 +81299,9 @@ OUI:7C70BCE*
 OUI:7C70BCF*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:7C70DB*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:7C7176*
  ID_OUI_FROM_DATABASE=Wuxi iData Technology Company Ltd.
 
@@ -81041,6 +81362,9 @@ OUI:7C8274*
 OUI:7C8306*
  ID_OUI_FROM_DATABASE=Glen Dimplex Nordic as
 
+OUI:7C8530*
+ ID_OUI_FROM_DATABASE=Nokia
+
 OUI:7C8956*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -81524,6 +81848,9 @@ OUI:7CF31B*
 OUI:7CF429*
  ID_OUI_FROM_DATABASE=NUUO Inc.
 
+OUI:7CF462*
+ ID_OUI_FROM_DATABASE=BEIJING HUAWOO TECHNOLOGIES CO.LTD
+
 OUI:7CF666*
  ID_OUI_FROM_DATABASE=Tuya Smart Inc.
 
@@ -82283,6 +82610,9 @@ OUI:80CA4B*
 OUI:80CC12*
  ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
 
+OUI:80CC9C*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
 OUI:80CE62*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
@@ -83444,6 +83774,9 @@ OUI:84EB18*
 OUI:84EB3E*
  ID_OUI_FROM_DATABASE=Vivint Smart Home
 
+OUI:84EBEF*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:84ED33*
  ID_OUI_FROM_DATABASE=BBMC Co.,Ltd
 
@@ -84071,6 +84404,9 @@ OUI:889FFA*
 OUI:88A084*
  ID_OUI_FROM_DATABASE=Formation Data Systems
 
+OUI:88A0BE*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:88A25E*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -84161,6 +84497,9 @@ OUI:88AE07*
 OUI:88AE1D*
  ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
 
+OUI:88AEDD*
+ ID_OUI_FROM_DATABASE=EliteGroup Computer Systems Co., LTD
+
 OUI:88B111*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -84443,6 +84782,9 @@ OUI:88F7C7*
 OUI:88F872*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:88FCA6*
+ ID_OUI_FROM_DATABASE=devolo AG
+
 OUI:88FD15*
  ID_OUI_FROM_DATABASE=LINEEYE CO., LTD
 
@@ -84980,6 +85322,9 @@ OUI:8C640B*
 OUI:8C6422*
  ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc
 
+OUI:8C64A2*
+ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd
+
 OUI:8C64D4*
  ID_OUI_FROM_DATABASE=Hyeco Smart Tech Co.,Ltd
 
@@ -85157,6 +85502,9 @@ OUI:8C9351*
 OUI:8C941F*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:8C94CC*
+ ID_OUI_FROM_DATABASE=SFR
+
 OUI:8C94CF*
  ID_OUI_FROM_DATABASE=Encell Technology, Inc.
 
@@ -85178,6 +85526,9 @@ OUI:8CA048*
 OUI:8CA2FD*
  ID_OUI_FROM_DATABASE=Starry, Inc.
 
+OUI:8CA399*
+ ID_OUI_FROM_DATABASE=SERVERCOM (INDIA) PRIVATE LIMITED
+
 OUI:8CA5A1*
  ID_OUI_FROM_DATABASE=Oregano Systems - Design & Consulting GmbH
 
@@ -85925,6 +86276,9 @@ OUI:9067F3*
 OUI:9068C3*
  ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
 
+OUI:906976*
+ ID_OUI_FROM_DATABASE=Withrobot Inc.
+
 OUI:906CAC*
  ID_OUI_FROM_DATABASE=Fortinet, Inc.
 
@@ -86000,6 +86354,9 @@ OUI:907EBA*
 OUI:907F61*
  ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd.
 
+OUI:908060*
+ ID_OUI_FROM_DATABASE=Nilfisk A/S
+
 OUI:90808F*
  ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
 
@@ -86918,6 +87275,9 @@ OUI:948FCF*
 OUI:948FEE*
  ID_OUI_FROM_DATABASE=Verizon Telematics
 
+OUI:949010*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:949034*
  ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
 
@@ -86993,6 +87353,9 @@ OUI:94A7B7*
 OUI:94A7BC*
  ID_OUI_FROM_DATABASE=BodyMedia, Inc.
 
+OUI:94AA0A*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:94AAB8*
  ID_OUI_FROM_DATABASE=Joview(Beijing) Technology Co. Ltd.
 
@@ -87752,6 +88115,9 @@ OUI:984265*
 OUI:9843DA*
  ID_OUI_FROM_DATABASE=INTERTECH
 
+OUI:9843FA*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:9844B6*
  ID_OUI_FROM_DATABASE=INFRANOR SAS
 
@@ -87776,6 +88142,9 @@ OUI:984874*
 OUI:984914*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
 
+OUI:98499F*
+ ID_OUI_FROM_DATABASE=Domo Tactical Communications
+
 OUI:9849E1*
  ID_OUI_FROM_DATABASE=Boeing Defence Australia
 
@@ -88289,6 +88658,9 @@ OUI:98EF9B*
 OUI:98F058*
  ID_OUI_FROM_DATABASE=Lynxspring, Incl.
 
+OUI:98F083*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:98F0AB*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -88301,6 +88673,9 @@ OUI:98F181*
 OUI:98F199*
  ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
 
+OUI:98F217*
+ ID_OUI_FROM_DATABASE=Castlenet Technology Inc.
+
 OUI:98F2B3*
  ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
 
@@ -90122,6 +90497,9 @@ OUI:A0AFBD*
 OUI:A0B045*
  ID_OUI_FROM_DATABASE=Halong Mining
 
+OUI:A0B086*
+ ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH
+
 OUI:A0B100*
  ID_OUI_FROM_DATABASE=ShenZhen Cando Electronics Co.,Ltd
 
@@ -90386,6 +90764,9 @@ OUI:A0E617*
 OUI:A0E6F8*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:A0E70B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:A0E9DB*
  ID_OUI_FROM_DATABASE=Ningbo FreeWings Technologies Co.,Ltd
 
@@ -90641,6 +91022,9 @@ OUI:A42985*
 OUI:A429B7*
  ID_OUI_FROM_DATABASE=bluesky
 
+OUI:A42A71*
+ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD
+
 OUI:A42B8C*
  ID_OUI_FROM_DATABASE=NETGEAR
 
@@ -91052,6 +91436,9 @@ OUI:A47758*
 OUI:A47760*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:A47806*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:A47886*
  ID_OUI_FROM_DATABASE=Avaya Inc
 
@@ -91371,7 +91758,7 @@ OUI:A4CFD2*
  ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
 
 OUI:A4D094*
- ID_OUI_FROM_DATABASE=Erwin Peters Systemtechnik GmbH
+ ID_OUI_FROM_DATABASE=VIVAVIS AG
 
 OUI:A4D18C*
  ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -91394,6 +91781,9 @@ OUI:A4D4B2*
 OUI:A4D578*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:A4D73C*
+ ID_OUI_FROM_DATABASE=Seiko Epson Corporation
+
 OUI:A4D795*
  ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co.,Ltd
 
@@ -91700,6 +92090,9 @@ OUI:A81FAF*
 OUI:A82066*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:A82316*
+ ID_OUI_FROM_DATABASE=Nokia
+
 OUI:A823FE*
  ID_OUI_FROM_DATABASE=LG Electronics
 
@@ -91866,7 +92259,7 @@ OUI:A854B2*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
 
 OUI:A8556A*
- ID_OUI_FROM_DATABASE=Pocketnet Technology Inc.
+ ID_OUI_FROM_DATABASE=3S System Technology Inc.
 
 OUI:A8574E*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
@@ -91925,6 +92318,9 @@ OUI:A863F2*
 OUI:A86405*
  ID_OUI_FROM_DATABASE=nimbus 9, Inc
 
+OUI:A864F1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:A865B2*
  ID_OUI_FROM_DATABASE=DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED
 
@@ -92843,6 +93239,9 @@ OUI:AC7289*
 OUI:AC7409*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
+OUI:AC74B1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:AC74C4*
  ID_OUI_FROM_DATABASE=Maytronics Ltd.
 
@@ -94058,6 +94457,9 @@ OUI:B0D7C5*
 OUI:B0D7CC*
  ID_OUI_FROM_DATABASE=Tridonic GmbH & Co KG
 
+OUI:B0D888*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation Automotive
+
 OUI:B0DA00*
  ID_OUI_FROM_DATABASE=CERA ELECTRONIQUE
 
@@ -95585,6 +95987,9 @@ OUI:B89BE4*
 OUI:B89F09*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
 
+OUI:B8A14A*
+ ID_OUI_FROM_DATABASE=Raisecom Technology CO.,LTD
+
 OUI:B8A175*
  ID_OUI_FROM_DATABASE=Roku, Inc.
 
@@ -95771,6 +96176,9 @@ OUI:B8D50B*
 OUI:B8D526*
  ID_OUI_FROM_DATABASE=Zyxel Communications Corporation
 
+OUI:B8D56B*
+ ID_OUI_FROM_DATABASE=Mirka Ltd.
+
 OUI:B8D6F6*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -96602,6 +97010,9 @@ OUI:BCA042*
 OUI:BCA13A*
  ID_OUI_FROM_DATABASE=SES-imagotag
 
+OUI:BCA37F*
+ ID_OUI_FROM_DATABASE=Rail-Mil Sp. z o.o. Sp. K.
+
 OUI:BCA4E1*
  ID_OUI_FROM_DATABASE=Nabto
 
@@ -96926,6 +97337,9 @@ OUI:C0210D*
 OUI:C02250*
  ID_OUI_FROM_DATABASE=Koss Corporation
 
+OUI:C0238D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:C02506*
  ID_OUI_FROM_DATABASE=AVM GmbH
 
@@ -97013,6 +97427,9 @@ OUI:C0395A*
 OUI:C03B8F*
  ID_OUI_FROM_DATABASE=Minicom Digital Signage
 
+OUI:C03C04*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
 OUI:C03C59*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -97739,6 +98156,54 @@ OUI:C0F945*
 OUI:C0F991*
  ID_OUI_FROM_DATABASE=GME Standard Communications P/L
 
+OUI:C0F9B0*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C0FBF90*
+ ID_OUI_FROM_DATABASE=Xerox Corporation
+
+OUI:C0FBF91*
+ ID_OUI_FROM_DATABASE=LIXIL Corporation
+
+OUI:C0FBF92*
+ ID_OUI_FROM_DATABASE=Dongguan Chuan OptoElectronics Limited
+
+OUI:C0FBF93*
+ ID_OUI_FROM_DATABASE=SHENZHEN HEQIANG ELECTRONICS LIMITED
+
+OUI:C0FBF94*
+ ID_OUI_FROM_DATABASE=Minato Advanced Technologies inc
+
+OUI:C0FBF95*
+ ID_OUI_FROM_DATABASE=HAGUENET
+
+OUI:C0FBF96*
+ ID_OUI_FROM_DATABASE=IVT corporation
+
+OUI:C0FBF97*
+ ID_OUI_FROM_DATABASE=LongSung Technology (Shanghai) Co.,Ltd.
+
+OUI:C0FBF98*
+ ID_OUI_FROM_DATABASE=Dongmengling
+
+OUI:C0FBF99*
+ ID_OUI_FROM_DATABASE=zxsolution
+
+OUI:C0FBF9A*
+ ID_OUI_FROM_DATABASE=Tiandi(Changzhou) Automation Co., Ltd.
+
+OUI:C0FBF9B*
+ ID_OUI_FROM_DATABASE=SHENZHEN COMIX HST CLOUD COMPUTING CO., LTD.
+
+OUI:C0FBF9C*
+ ID_OUI_FROM_DATABASE=SHENZHEN ELSKY TECHNOLOGY CO., LTD
+
+OUI:C0FBF9D*
+ ID_OUI_FROM_DATABASE=Dropbeats Technology Co., Ltd.
+
+OUI:C0FBF9E*
+ ID_OUI_FROM_DATABASE=Navitas Digital Safety Ltd
+
 OUI:C0FD84*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -98078,6 +98543,9 @@ OUI:C45D83*
 OUI:C45DD8*
  ID_OUI_FROM_DATABASE=HDMI Forum
 
+OUI:C45E5C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:C46044*
  ID_OUI_FROM_DATABASE=Everex Electronics Limited
 
@@ -99551,6 +100019,12 @@ OUI:C8F5D60*
 OUI:C8F5D61*
  ID_OUI_FROM_DATABASE=Valeo Interior Controls (Shenzhen) Co.,Ltd
 
+OUI:C8F5D62*
+ ID_OUI_FROM_DATABASE=Qbic Technology Co., Ltd
+
+OUI:C8F5D63*
+ ID_OUI_FROM_DATABASE=BBPOS International Limited
+
 OUI:C8F5D64*
  ID_OUI_FROM_DATABASE=EVOTOR LLC
 
@@ -99566,15 +100040,24 @@ OUI:C8F5D67*
 OUI:C8F5D68*
  ID_OUI_FROM_DATABASE=Yarward Electronics  Co., Ltd.
 
+OUI:C8F5D69*
+ ID_OUI_FROM_DATABASE=Shanghai Mo xiang Network Technology CO.,Ltd
+
 OUI:C8F5D6A*
  ID_OUI_FROM_DATABASE=HENAN FOXSTAR DIGITAL DISPLAY Co.,Ltd.
 
 OUI:C8F5D6B*
  ID_OUI_FROM_DATABASE=United Barcode Systems
 
+OUI:C8F5D6C*
+ ID_OUI_FROM_DATABASE=Eltako GmbH
+
 OUI:C8F5D6D*
  ID_OUI_FROM_DATABASE=Volansys technologies pvt ltd
 
+OUI:C8F5D6E*
+ ID_OUI_FROM_DATABASE=HEITEC AG
+
 OUI:C8F650*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -99695,6 +100178,9 @@ OUI:CC10A3*
 OUI:CC14A6*
  ID_OUI_FROM_DATABASE=Yichun MyEnergy Domain, Inc
 
+OUI:CC1531*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:CC167E*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -99894,7 +100380,7 @@ OUI:CC3A61*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD.
 
 OUI:CC3ADF*
- ID_OUI_FROM_DATABASE=Private
+ ID_OUI_FROM_DATABASE=Neptune Technology Group Inc.
 
 OUI:CC3B27*
  ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
@@ -100322,6 +100808,9 @@ OUI:CCB3F8*
 OUI:CCB55A*
  ID_OUI_FROM_DATABASE=Fraunhofer ITWM
 
+OUI:CCB5D1*
+ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd
+
 OUI:CCB691*
  ID_OUI_FROM_DATABASE=NECMagnusCommunications
 
@@ -100796,6 +101285,9 @@ OUI:D015A6*
 OUI:D016B4*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:D01769*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
 OUI:D0176A*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -100814,6 +101306,9 @@ OUI:D01C3C*
 OUI:D01CBB*
  ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd.
 
+OUI:D01E1D*
+ ID_OUI_FROM_DATABASE=SaiNXT Technologies LLP
+
 OUI:D021AC*
  ID_OUI_FROM_DATABASE=Yo Labs LLC
 
@@ -100940,6 +101435,9 @@ OUI:D03DC3*
 OUI:D03E5C*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:D03E7D*
+ ID_OUI_FROM_DATABASE=CHIPSEA TECHNOLOGIES (SHENZHEN) CORP.
+
 OUI:D03FAA*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -100994,6 +101492,9 @@ OUI:D05349*
 OUI:D0542D*
  ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
 
+OUI:D05475*
+ ID_OUI_FROM_DATABASE=SAVI Controls
+
 OUI:D05509*
  ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
 
@@ -101330,6 +101831,51 @@ OUI:D09D0A*
 OUI:D09DAB*
  ID_OUI_FROM_DATABASE=TCT mobile ltd
 
+OUI:D09FD90*
+ ID_OUI_FROM_DATABASE=Lemei Intelligent IOT (Shenzhen) Co., Ltd
+
+OUI:D09FD91*
+ ID_OUI_FROM_DATABASE=elecgator bvba
+
+OUI:D09FD92*
+ ID_OUI_FROM_DATABASE=Westar Display Technologies
+
+OUI:D09FD93*
+ ID_OUI_FROM_DATABASE=Sanken-Densetsu Co.,LTD.
+
+OUI:D09FD94*
+ ID_OUI_FROM_DATABASE=Poten (Shanghai) Technology Co.,Ltd.
+
+OUI:D09FD95*
+ ID_OUI_FROM_DATABASE=Carbon Mobile GmbH
+
+OUI:D09FD96*
+ ID_OUI_FROM_DATABASE=Elevoc Technology Co., Ltd.
+
+OUI:D09FD97*
+ ID_OUI_FROM_DATABASE=Raymax Technology Ltd.
+
+OUI:D09FD98*
+ ID_OUI_FROM_DATABASE=Queclink Wireless Solutions Co., Ltd.
+
+OUI:D09FD99*
+ ID_OUI_FROM_DATABASE=ENTTEC Pty Ltd.
+
+OUI:D09FD9A*
+ ID_OUI_FROM_DATABASE=Eurolan Ltd
+
+OUI:D09FD9B*
+ ID_OUI_FROM_DATABASE=Cablewireless Laboratory Co., Ltd
+
+OUI:D09FD9C*
+ ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd.
+
+OUI:D09FD9D*
+ ID_OUI_FROM_DATABASE=Shenzhen eloT Technology Co.,Ltd
+
+OUI:D09FD9E*
+ ID_OUI_FROM_DATABASE=Minibems Ltd
+
 OUI:D0A0D6*
  ID_OUI_FROM_DATABASE=Chengdu TD Tech Ltd.
 
@@ -101966,6 +102512,9 @@ OUI:D45383*
 OUI:D453AF*
  ID_OUI_FROM_DATABASE=VIGO System S.A.
 
+OUI:D4548B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:D45556*
  ID_OUI_FROM_DATABASE=Fiber Mountain Inc.
 
@@ -103115,6 +103664,9 @@ OUI:D89ED4*
 OUI:D89EF3*
  ID_OUI_FROM_DATABASE=Dell Inc.
 
+OUI:D8A011*
+ ID_OUI_FROM_DATABASE=WiZ
+
 OUI:D8A01D*
  ID_OUI_FROM_DATABASE=Espressif Inc.
 
@@ -103529,6 +104081,9 @@ OUI:DC1EA3*
 OUI:DC2008*
  ID_OUI_FROM_DATABASE=ASD Electronics Ltd
 
+OUI:DC2148*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:DC215C*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -104607,7 +105162,7 @@ OUI:E05A9F7*
  ID_OUI_FROM_DATABASE=OMB Guitars LLC
 
 OUI:E05A9F8*
- ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co.,Ltd.
+ ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd.
 
 OUI:E05A9F9*
  ID_OUI_FROM_DATABASE=Gemalto Document Readers
@@ -105194,6 +105749,9 @@ OUI:E405F8*
 OUI:E408E7*
  ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co.,Ltd.
 
+OUI:E40CFD*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
 OUI:E40EEE*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -106358,6 +106916,9 @@ OUI:E85BB7*
 OUI:E85BF0*
  ID_OUI_FROM_DATABASE=Imaging Diagnostics
 
+OUI:E85C0A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:E85D6B*
  ID_OUI_FROM_DATABASE=Luminate Wireless
 
@@ -106721,6 +107282,9 @@ OUI:E8C1B8*
 OUI:E8C1D7*
  ID_OUI_FROM_DATABASE=Philips
 
+OUI:E8C1E8*
+ ID_OUI_FROM_DATABASE=Shenzhen Xiao Bi En Culture Education Technology Co.,Ltd.
+
 OUI:E8C229*
  ID_OUI_FROM_DATABASE=H-Displays (MSC) Bhd
 
@@ -106955,6 +107519,9 @@ OUI:EC0441*
 OUI:EC086B*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
+OUI:EC08E5*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
 OUI:EC0BAE*
  ID_OUI_FROM_DATABASE=Hangzhou BroadLink Technology Co.,Ltd
 
@@ -108410,6 +108977,9 @@ OUI:F0C42F*
 OUI:F0C77F*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:F0C814*
+ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
+
 OUI:F0C850*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -108983,6 +109553,9 @@ OUI:F45FF7*
 OUI:F4600D*
  ID_OUI_FROM_DATABASE=Panoptic Technology, Inc
 
+OUI:F46077*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:F460E2*
  ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
 
@@ -108995,6 +109568,9 @@ OUI:F4631F*
 OUI:F46349*
  ID_OUI_FROM_DATABASE=Diffon Corporation
 
+OUI:F463E7*
+ ID_OUI_FROM_DATABASE=Nanjing Maxon O.E. Tech. Co., LTD
+
 OUI:F4645D*
  ID_OUI_FROM_DATABASE=Toshiba
 
@@ -109352,6 +109928,9 @@ OUI:F4BF80*
 OUI:F4BFA8*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
+OUI:F4C02F*
+ ID_OUI_FROM_DATABASE=BlueBite
+
 OUI:F4C114*
  ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
 
@@ -109475,6 +110054,9 @@ OUI:F4E204*
 OUI:F4E3FB*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:F4E451*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:F4E4AD*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -110195,6 +110777,9 @@ OUI:F88DEF*
 OUI:F88E85*
  ID_OUI_FROM_DATABASE=Comtrend Corporation
 
+OUI:F88EA1*
+ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation
+
 OUI:F88F07*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -111077,6 +111662,9 @@ OUI:FC9114*
 OUI:FC923B*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:FC9257*
+ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd.
+
 OUI:FC9435*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
index 34e3c57d8863273a4f9ecd993426f6afa78cf26d..c6d3798e1b18980b471b2b01d6d801fc213bc87e 100644 (file)
@@ -96,6 +96,9 @@ acpi:ESSX*:
 acpi:EXAR*:
  ID_VENDOR_FROM_DATABASE=Exar Corporation
 
+acpi:FRMW*:
+ ID_VENDOR_FROM_DATABASE=Framework Computer LLC
+
 acpi:FRSC*:
  ID_VENDOR_FROM_DATABASE=Freescale, Inc
 
@@ -171,6 +174,9 @@ acpi:IP3T*:
 acpi:IPHI*:
  ID_VENDOR_FROM_DATABASE=Inphi Corporation
 
+acpi:JSYS*:
+ ID_VENDOR_FROM_DATABASE=Juniper Systems, Inc.
+
 acpi:KIOX*:
  ID_VENDOR_FROM_DATABASE=Kionix, Inc.
 
@@ -231,6 +237,9 @@ acpi:PHYT*:
 acpi:PIXA*:
  ID_VENDOR_FROM_DATABASE=PixArt imaging inc.
 
+acpi:PNSO*:
+ ID_VENDOR_FROM_DATABASE=Pensando Systems, Inc.
+
 acpi:QCOM*:
  ID_VENDOR_FROM_DATABASE=Qualcomm Inc
 
@@ -598,7 +607,7 @@ acpi:ALO*:
  ID_VENDOR_FROM_DATABASE=Algolith Inc.
 
 acpi:ALP*:
- ID_VENDOR_FROM_DATABASE=Alps Electric Company Ltd
+ ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD.
 
 acpi:ALR*:
  ID_VENDOR_FROM_DATABASE=Advanced Logic
@@ -724,7 +733,7 @@ acpi:APD*:
  ID_VENDOR_FROM_DATABASE=AppliAdata
 
 acpi:APE*:
- ID_VENDOR_FROM_DATABASE=Alpine Electronics, Inc.
+ ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD.
 
 acpi:APG*:
  ID_VENDOR_FROM_DATABASE=Horner Electric Inc
@@ -889,7 +898,7 @@ acpi:AUG*:
  ID_VENDOR_FROM_DATABASE=August Home, Inc.
 
 acpi:AUI*:
- ID_VENDOR_FROM_DATABASE=Alps Electric Inc
+ ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD.
 
 acpi:AUO*:
  ID_VENDOR_FROM_DATABASE=AU Optronics
@@ -1530,6 +1539,9 @@ acpi:CNB*:
 acpi:CNC*:
  ID_VENDOR_FROM_DATABASE=Alvedon Computers Ltd
 
+acpi:CND*:
+ ID_VENDOR_FROM_DATABASE=Micro-Star Int'l Co., Ltd.
+
 acpi:CNE*:
  ID_VENDOR_FROM_DATABASE=Cine-tal
 
@@ -1629,6 +1641,9 @@ acpi:CRI*:
 acpi:CRL*:
  ID_VENDOR_FROM_DATABASE=Creative Logic
 
+acpi:CRM*:
+ ID_VENDOR_FROM_DATABASE=CORSAIR MEMORY Inc.
+
 acpi:CRN*:
  ID_VENDOR_FROM_DATABASE=Cornerstone Imaging
 
@@ -4998,6 +5013,9 @@ acpi:NVT*:
 acpi:NWC*:
  ID_VENDOR_FROM_DATABASE=NW Computer Engineering
 
+acpi:NWL*:
+ ID_VENDOR_FROM_DATABASE=Newline Interactive Inc.
+
 acpi:NWP*:
  ID_VENDOR_FROM_DATABASE=NovaWeb Technologies Inc
 
index 9d3a07de71fc4ee04f0938adfd58715979b95f47..a5f1dacda156c47b91331ac036c389dac42acb95 100644 (file)
@@ -1,5 +1,5 @@
---- 20-acpi-vendor.hwdb.base   2021-03-08 12:40:32.635298395 +0100
-+++ 20-acpi-vendor.hwdb        2021-03-08 12:40:32.673298742 +0100
+--- 20-acpi-vendor.hwdb.base   2021-03-30 13:03:54.632421502 +0200
++++ 20-acpi-vendor.hwdb        2021-03-30 13:03:54.650421692 +0200
 @@ -3,6 +3,8 @@
  # Data imported from:
  #     https://uefi.org/uefi-pnp-export
@@ -19,7 +19,7 @@
  acpi:AMDI*:
   ID_VENDOR_FROM_DATABASE=AMD
  
-@@ -301,6 +300,9 @@
+@@ -310,6 +309,9 @@
  acpi:AAA*:
   ID_VENDOR_FROM_DATABASE=Avolites Ltd
  
@@ -29,7 +29,7 @@
  acpi:AAE*:
   ID_VENDOR_FROM_DATABASE=Anatek Electronics Inc.
  
-@@ -328,6 +330,9 @@
+@@ -337,6 +339,9 @@
  acpi:ABO*:
   ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
  
@@ -39,7 +39,7 @@
  acpi:ABS*:
   ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
  
-@@ -373,7 +378,7 @@
+@@ -382,7 +387,7 @@
  acpi:ACO*:
   ID_VENDOR_FROM_DATABASE=Allion Computer Inc.
  
@@ -48,7 +48,7 @@
   ID_VENDOR_FROM_DATABASE=Aspen Tech Inc
  
  acpi:ACR*:
-@@ -646,6 +651,9 @@
+@@ -655,6 +660,9 @@
  acpi:AMT*:
   ID_VENDOR_FROM_DATABASE=AMT International Industry
  
@@ -58,7 +58,7 @@
  acpi:AMX*:
   ID_VENDOR_FROM_DATABASE=AMX LLC
  
-@@ -694,6 +702,9 @@
+@@ -703,6 +711,9 @@
  acpi:AOA*:
   ID_VENDOR_FROM_DATABASE=AOpen Inc.
  
@@ -68,7 +68,7 @@
  acpi:AOE*:
   ID_VENDOR_FROM_DATABASE=Advanced Optics Electronics, Inc.
  
-@@ -703,6 +714,9 @@
+@@ -712,6 +723,9 @@
  acpi:AOT*:
   ID_VENDOR_FROM_DATABASE=Alcatel
  
@@ -78,8 +78,8 @@
  acpi:APC*:
   ID_VENDOR_FROM_DATABASE=American Power Conversion
  
-@@ -878,7 +892,7 @@
-  ID_VENDOR_FROM_DATABASE=Alps Electric Inc
+@@ -887,7 +901,7 @@
+  ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD.
  
  acpi:AUO*:
 - ID_VENDOR_FROM_DATABASE=DO NOT USE - AUO
@@ -87,7 +87,7 @@
  
  acpi:AUR*:
   ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
-@@ -958,6 +972,9 @@
+@@ -967,6 +981,9 @@
  acpi:AXE*:
   ID_VENDOR_FROM_DATABASE=Axell Corporation
  
@@ -97,7 +97,7 @@
  acpi:AXI*:
   ID_VENDOR_FROM_DATABASE=American Magnetics
  
-@@ -1108,6 +1125,9 @@
+@@ -1117,6 +1134,9 @@
  acpi:BML*:
   ID_VENDOR_FROM_DATABASE=BIOMED Lab
  
  acpi:BMS*:
   ID_VENDOR_FROM_DATABASE=BIOMEDISYS
  
-@@ -1120,6 +1140,9 @@
+@@ -1129,6 +1149,9 @@
  acpi:BNO*:
   ID_VENDOR_FROM_DATABASE=Bang & Olufsen
  
  acpi:BNS*:
   ID_VENDOR_FROM_DATABASE=Boulder Nonlinear Systems
  
-@@ -1363,6 +1386,9 @@
+@@ -1372,6 +1395,9 @@
  acpi:CHA*:
   ID_VENDOR_FROM_DATABASE=Chase Research PLC
  
  acpi:CHD*:
   ID_VENDOR_FROM_DATABASE=ChangHong Electric Co.,Ltd
  
-@@ -1522,6 +1548,9 @@
+@@ -1534,6 +1560,9 @@
  acpi:COD*:
   ID_VENDOR_FROM_DATABASE=CODAN Pty. Ltd.
  
  acpi:COI*:
   ID_VENDOR_FROM_DATABASE=Codec Inc.
  
-@@ -1928,7 +1957,7 @@
+@@ -1943,7 +1972,7 @@
   ID_VENDOR_FROM_DATABASE=Dragon Information Technology
  
  acpi:DJE*:
  
  acpi:DJP*:
   ID_VENDOR_FROM_DATABASE=Maygay Machines, Ltd
-@@ -2260,6 +2289,9 @@
+@@ -2275,6 +2304,9 @@
  acpi:EIN*:
   ID_VENDOR_FROM_DATABASE=Elegant Invention
  
  acpi:EKA*:
   ID_VENDOR_FROM_DATABASE=MagTek Inc.
  
-@@ -2521,6 +2553,9 @@
+@@ -2536,6 +2568,9 @@
  acpi:FCG*:
   ID_VENDOR_FROM_DATABASE=First International Computer Ltd
  
  acpi:FCS*:
   ID_VENDOR_FROM_DATABASE=Focus Enhancements, Inc.
  
-@@ -2894,7 +2929,7 @@
+@@ -2909,7 +2944,7 @@
   ID_VENDOR_FROM_DATABASE=General Standards Corporation
  
  acpi:GSM*:
  
  acpi:GSN*:
   ID_VENDOR_FROM_DATABASE=Grandstream Networks, Inc.
-@@ -2995,6 +3030,9 @@
+@@ -3010,6 +3045,9 @@
  acpi:HEC*:
   ID_VENDOR_FROM_DATABASE=Hisense Electric Co., Ltd.
  
  acpi:HEL*:
   ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems Europe Ltd
  
-@@ -3124,6 +3162,9 @@
+@@ -3139,6 +3177,9 @@
  acpi:HSD*:
   ID_VENDOR_FROM_DATABASE=HannStar Display Corp
  
  acpi:HSM*:
   ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
  
-@@ -3247,6 +3288,9 @@
+@@ -3262,6 +3303,9 @@
  acpi:ICI*:
   ID_VENDOR_FROM_DATABASE=Infotek Communication Inc
  
  acpi:ICM*:
   ID_VENDOR_FROM_DATABASE=Intracom SA
  
-@@ -3343,6 +3387,9 @@
+@@ -3358,6 +3402,9 @@
  acpi:IKE*:
   ID_VENDOR_FROM_DATABASE=Ikegami Tsushinki Co. Ltd.
  
  acpi:IKS*:
   ID_VENDOR_FROM_DATABASE=Ikos Systems Inc
  
-@@ -3388,6 +3435,9 @@
+@@ -3403,6 +3450,9 @@
  acpi:IMT*:
   ID_VENDOR_FROM_DATABASE=Inmax Technology Corporation
  
  acpi:INA*:
   ID_VENDOR_FROM_DATABASE=Inventec Corporation
  
-@@ -3898,6 +3948,9 @@
+@@ -3913,6 +3963,9 @@
  acpi:LAN*:
   ID_VENDOR_FROM_DATABASE=Sodeman Lancom Inc
  
  acpi:LAS*:
   ID_VENDOR_FROM_DATABASE=LASAT Comm. A/S
  
-@@ -3943,6 +3996,9 @@
+@@ -3958,6 +4011,9 @@
  acpi:LED*:
   ID_VENDOR_FROM_DATABASE=Long Engineering Design Inc
  
  acpi:LEG*:
   ID_VENDOR_FROM_DATABASE=Legerity, Inc
  
-@@ -3958,6 +4014,9 @@
+@@ -3973,6 +4029,9 @@
  acpi:LGC*:
   ID_VENDOR_FROM_DATABASE=Logic Ltd
  
  acpi:LGI*:
   ID_VENDOR_FROM_DATABASE=Logitech Inc
  
-@@ -4012,6 +4071,9 @@
+@@ -4027,6 +4086,9 @@
  acpi:LND*:
   ID_VENDOR_FROM_DATABASE=Land Computer Company Ltd
  
  acpi:LNK*:
   ID_VENDOR_FROM_DATABASE=Link Tech Inc
  
-@@ -4046,7 +4108,7 @@
+@@ -4061,7 +4123,7 @@
   ID_VENDOR_FROM_DATABASE=Design Technology
  
  acpi:LPL*:
  
  acpi:LSC*:
   ID_VENDOR_FROM_DATABASE=LifeSize Communications
-@@ -4222,6 +4284,9 @@
+@@ -4237,6 +4299,9 @@
  acpi:MCX*:
   ID_VENDOR_FROM_DATABASE=Millson Custom Solutions Inc.
  
  acpi:MDA*:
   ID_VENDOR_FROM_DATABASE=Media4 Inc
  
-@@ -4462,6 +4527,9 @@
+@@ -4477,6 +4542,9 @@
  acpi:MOM*:
   ID_VENDOR_FROM_DATABASE=Momentum Data Systems
  
  acpi:MOS*:
   ID_VENDOR_FROM_DATABASE=Moses Corporation
  
-@@ -4690,6 +4758,9 @@
+@@ -4705,6 +4773,9 @@
  acpi:NAL*:
   ID_VENDOR_FROM_DATABASE=Network Alchemy
  
  acpi:NAT*:
   ID_VENDOR_FROM_DATABASE=NaturalPoint Inc.
  
-@@ -5197,6 +5268,9 @@
+@@ -5215,6 +5286,9 @@
  acpi:PCX*:
   ID_VENDOR_FROM_DATABASE=PC Xperten
  
  acpi:PDM*:
   ID_VENDOR_FROM_DATABASE=Psion Dacom Plc.
  
-@@ -5260,9 +5334,6 @@
+@@ -5278,9 +5352,6 @@
  acpi:PHE*:
   ID_VENDOR_FROM_DATABASE=Philips Medical Systems Boeblingen GmbH
  
  acpi:PHL*:
   ID_VENDOR_FROM_DATABASE=Philips Consumer Electronics Company
  
-@@ -5350,9 +5421,6 @@
+@@ -5368,9 +5439,6 @@
  acpi:PNL*:
   ID_VENDOR_FROM_DATABASE=Panelview, Inc.
  
  acpi:PNR*:
   ID_VENDOR_FROM_DATABASE=Planar Systems, Inc.
  
-@@ -5488,15 +5556,9 @@
+@@ -5506,15 +5574,9 @@
  acpi:PTS*:
   ID_VENDOR_FROM_DATABASE=Plain Tree Systems Inc
  
  acpi:PVG*:
   ID_VENDOR_FROM_DATABASE=Proview Global Co., Ltd
  
-@@ -5812,9 +5874,6 @@
+@@ -5830,9 +5892,6 @@
  acpi:RTI*:
   ID_VENDOR_FROM_DATABASE=Rancho Tech Inc
  
  acpi:RTL*:
   ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Company Ltd
  
-@@ -5980,9 +6039,6 @@
+@@ -5998,9 +6057,6 @@
  acpi:SEE*:
   ID_VENDOR_FROM_DATABASE=SeeColor Corporation
  
  acpi:SEI*:
   ID_VENDOR_FROM_DATABASE=Seitz & Associates Inc
  
-@@ -6442,6 +6498,9 @@
+@@ -6460,6 +6516,9 @@
  acpi:SVD*:
   ID_VENDOR_FROM_DATABASE=SVD Computer
  
  acpi:SVI*:
   ID_VENDOR_FROM_DATABASE=Sun Microsystems
  
-@@ -6526,6 +6585,9 @@
+@@ -6544,6 +6603,9 @@
  acpi:SZM*:
   ID_VENDOR_FROM_DATABASE=Shenzhen MTC Co., Ltd
  
  acpi:TAA*:
   ID_VENDOR_FROM_DATABASE=Tandberg
  
-@@ -6616,6 +6678,9 @@
+@@ -6634,6 +6696,9 @@
  acpi:TDG*:
   ID_VENDOR_FROM_DATABASE=Six15 Technologies
  
  acpi:TDM*:
   ID_VENDOR_FROM_DATABASE=Tandem Computer Europe Inc
  
-@@ -6658,6 +6723,9 @@
+@@ -6676,6 +6741,9 @@
  acpi:TEV*:
   ID_VENDOR_FROM_DATABASE=Televés, S.A.
  
  acpi:TEZ*:
   ID_VENDOR_FROM_DATABASE=Tech Source Inc.
  
-@@ -6778,9 +6846,6 @@
+@@ -6796,9 +6864,6 @@
  acpi:TNC*:
   ID_VENDOR_FROM_DATABASE=TNC Industrial Company Ltd
  
  acpi:TNM*:
   ID_VENDOR_FROM_DATABASE=TECNIMAGEN SA
  
-@@ -7087,14 +7152,14 @@
+@@ -7105,14 +7170,14 @@
  acpi:UNC*:
   ID_VENDOR_FROM_DATABASE=Unisys Corporation
  
  
  acpi:UNI*:
   ID_VENDOR_FROM_DATABASE=Uniform Industry Corp.
-@@ -7129,6 +7194,9 @@
+@@ -7147,6 +7212,9 @@
  acpi:USA*:
   ID_VENDOR_FROM_DATABASE=Utimaco Safeware AG
  
  acpi:USD*:
   ID_VENDOR_FROM_DATABASE=U.S. Digital Corporation
  
-@@ -7375,9 +7443,6 @@
+@@ -7393,9 +7461,6 @@
  acpi:WAL*:
   ID_VENDOR_FROM_DATABASE=Wave Access
  
  acpi:WAV*:
   ID_VENDOR_FROM_DATABASE=Wavephore
  
-@@ -7502,7 +7567,7 @@
+@@ -7520,7 +7585,7 @@
   ID_VENDOR_FROM_DATABASE=WyreStorm Technologies LLC
  
  acpi:WYS*:
  
  acpi:WYT*:
   ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd.
-@@ -7516,9 +7581,6 @@
+@@ -7534,9 +7599,6 @@
  acpi:XDM*:
   ID_VENDOR_FROM_DATABASE=XDM Ltd.
  
  acpi:XES*:
   ID_VENDOR_FROM_DATABASE=Extreme Engineering Solutions, Inc.
  
-@@ -7549,9 +7611,6 @@
+@@ -7567,9 +7629,6 @@
  acpi:XNT*:
   ID_VENDOR_FROM_DATABASE=XN Technologies, Inc.
  
  acpi:XQU*:
   ID_VENDOR_FROM_DATABASE=SHANGHAI SVA-DAV ELECTRONICS CO., LTD
  
-@@ -7618,6 +7677,9 @@
+@@ -7636,6 +7695,9 @@
  acpi:ZBX*:
   ID_VENDOR_FROM_DATABASE=Zebax Technologies
  
index b2ca43cbc4f14d4a906dc24196c686ee4198fa06..269f6959f6607688cb30cc6449b4c6f3eda9d37b 100644 (file)
@@ -2453,6 +2453,18 @@ pci:v00001000d000010E1sv00001D49sd0000060F*
 pci:v00001000d000010E2*
  ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx
 
+pci:v00001000d000010E2sv00001000sd00004000*
+ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9560-16i)
+
+pci:v00001000d000010E2sv00001000sd00004010*
+ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9560-8i)
+
+pci:v00001000d000010E2sv00001000sd00004020*
+ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9580-8i8e)
+
+pci:v00001000d000010E2sv00001000sd000040B0*
+ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9562-16i)
+
 pci:v00001000d000010E2sv00001028sd00001AE0*
  ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H755 Adapter)
 
@@ -2708,6 +2720,9 @@ pci:v00001002d000015D8*
 pci:v00001002d000015D8sv0000103Csd00008615*
  ID_MODEL_FROM_DATABASE=Picasso (Pavilion Laptop 15-cw1xxx)
 
+pci:v00001002d000015D8sv000017AAsd00003181*
+ ID_MODEL_FROM_DATABASE=Picasso (ThinkCentre M75n IoT)
+
 pci:v00001002d000015D8sv000017AAsd00005124*
  ID_MODEL_FROM_DATABASE=Picasso (ThinkPad E595)
 
@@ -5538,10 +5553,10 @@ pci:v00001002d00005F57*
  ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT]
 
 pci:v00001002d00006600*
- ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M]
+ ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M / R7 M370]
 
 pci:v00001002d00006600sv0000103Csd00001952*
- ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M] (ProBook 455 G1)
+ ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M / R7 M370] (ProBook 455 G1)
 
 pci:v00001002d00006601*
  ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8730M]
@@ -6531,61 +6546,79 @@ pci:v00001002d00006758sv00001787sd00002309*
  ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 6670)
 
 pci:v00001002d00006759*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550]
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230]
 
 pci:v00001002d00006759sv0000103Csd00003130*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001043sd00000403*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001462sd00002500*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001462sd00002509*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570)
 
 pci:v00001002d00006759sv0000148Csd00007570*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570)
 
 pci:v00001002d00006759sv00001642sd00003A67*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001682sd00003280*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570)
 
 pci:v00001002d00006759sv00001682sd00003530*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 8550)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 8550)
+
+pci:v00001002d00006759sv00001682sd00005230*
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon R5 230 series)
+
+pci:v00001002d00006759sv00001682sd00006450*
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6450 series)
 
 pci:v00001002d00006759sv0000174Bsd00007570*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570)
+
+pci:v00001002d00006759sv0000174Bsd00008550*
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD8550 OEM)
+
+pci:v00001002d00006759sv0000174Bsd00008570*
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD8550 OEM)
 
 pci:v00001002d00006759sv0000174Bsd0000E142*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv0000174Bsd0000E181*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
+
+pci:v00001002d00006759sv00001787sd0000A230*
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon R5 230 series)
+
+pci:v00001002d00006759sv00001787sd0000A450*
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6450 series)
 
 pci:v00001002d00006759sv00001B0Asd0000908F*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd00009090*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd00009091*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd00009092*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd0000909E*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd000090B5*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570)
 
 pci:v00001002d00006759sv00001B0Asd000090B6*
- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570)
 
 pci:v00001002d0000675B*
  ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7600 Series]
@@ -10652,6 +10685,9 @@ pci:v00001002d00007310*
 pci:v00001002d00007312*
  ID_MODEL_FROM_DATABASE=Navi 10 [Radeon Pro W5700]
 
+pci:v00001002d00007314*
+ ID_MODEL_FROM_DATABASE=Navi 10 USB
+
 pci:v00001002d0000731F*
  ID_MODEL_FROM_DATABASE=Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT]
 
@@ -10691,6 +10727,12 @@ pci:v00001002d0000738C*
 pci:v00001002d0000738E*
  ID_MODEL_FROM_DATABASE=Arcturus GL-XL
 
+pci:v00001002d000073A4*
+ ID_MODEL_FROM_DATABASE=Navi 21 USB
+
+pci:v00001002d000073AF*
+ ID_MODEL_FROM_DATABASE=Navi 21 [Radeon RX 6900 XT]
+
 pci:v00001002d000073BF*
  ID_MODEL_FROM_DATABASE=Navi 21 [Radeon RX 6800/6800 XT / 6900 XT]
 
@@ -10700,12 +10742,21 @@ pci:v00001002d000073BFsv00001EAEsd00006701*
 pci:v00001002d000073C3*
  ID_MODEL_FROM_DATABASE=Navi 22
 
+pci:v00001002d000073C4*
+ ID_MODEL_FROM_DATABASE=Navi 22 USB
+
 pci:v00001002d000073DF*
- ID_MODEL_FROM_DATABASE=Navi 22 [Radeon RX 6700/6700 XT]
+ ID_MODEL_FROM_DATABASE=Navi 22 [Radeon RX 6700/6700 XT / 6800M]
 
 pci:v00001002d000073E0*
  ID_MODEL_FROM_DATABASE=Navi 23
 
+pci:v00001002d000073E1*
+ ID_MODEL_FROM_DATABASE=Navi 23
+
+pci:v00001002d000073E4*
+ ID_MODEL_FROM_DATABASE=Navi 23 USB
+
 pci:v00001002d000073FF*
  ID_MODEL_FROM_DATABASE=Navi 23 [Radeon RX 6600/6600 XT]
 
@@ -20447,6 +20498,9 @@ pci:v0000106Bd00000004*
 pci:v0000106Bd00000007*
  ID_MODEL_FROM_DATABASE=O'Hare I/O
 
+pci:v0000106Bd0000000B*
+ ID_MODEL_FROM_DATABASE=Apple Camera
+
 pci:v0000106Bd0000000C*
  ID_MODEL_FROM_DATABASE=DOS on Mac
 
@@ -36194,11 +36248,14 @@ pci:v000010DEd000021C4*
 pci:v000010DEd000021D1*
  ID_MODEL_FROM_DATABASE=TU116BM [GeForce GTX 1660 Ti Mobile]
 
+pci:v000010DEd00002200*
+ ID_MODEL_FROM_DATABASE=GA102
+
 pci:v000010DEd00002204*
  ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3090]
 
 pci:v000010DEd00002205*
- ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 Ti]
+ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 20GB]
 
 pci:v000010DEd00002206*
  ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080]
@@ -36224,18 +36281,27 @@ pci:v000010DEd0000222F*
 pci:v000010DEd00002230*
  ID_MODEL_FROM_DATABASE=GA102GL [RTX A6000]
 
+pci:v000010DEd00002231*
+ ID_MODEL_FROM_DATABASE=GA102GL
+
 pci:v000010DEd00002235*
  ID_MODEL_FROM_DATABASE=GA102GL [RTX A40]
 
 pci:v000010DEd00002236*
  ID_MODEL_FROM_DATABASE=GA102GL
 
+pci:v000010DEd00002237*
+ ID_MODEL_FROM_DATABASE=GA102GL
+
 pci:v000010DEd0000223F*
  ID_MODEL_FROM_DATABASE=GA102GL
 
 pci:v000010DEd0000228B*
  ID_MODEL_FROM_DATABASE=GA104 High Definition Audio Controller
 
+pci:v000010DEd00002302*
+ ID_MODEL_FROM_DATABASE=GA103
+
 pci:v000010DEd00002321*
  ID_MODEL_FROM_DATABASE=GA103
 
@@ -41985,7 +42051,7 @@ pci:v00001134d0000000D*
  ID_MODEL_FROM_DATABASE=POET PSDMS Device
 
 pci:v00001135*
- ID_VENDOR_FROM_DATABASE=Fuji Xerox Co Ltd
+ ID_VENDOR_FROM_DATABASE=FUJIFILM Business Innovation Corp.
 
 pci:v00001135d00000001*
  ID_MODEL_FROM_DATABASE=Printer controller
@@ -52217,6 +52283,9 @@ pci:v00001414d00000001*
 pci:v00001414d00000002*
  ID_MODEL_FROM_DATABASE=MN-130 (ADMtek Centaur-P based)
 
+pci:v00001414d0000008C*
+ ID_MODEL_FROM_DATABASE=Basic Render Driver
+
 pci:v00001414d00005353*
  ID_MODEL_FROM_DATABASE=Hyper-V virtual VGA
 
@@ -56184,34 +56253,34 @@ pci:v000014E4d0000165Esv000010CFsd00001279*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet (LifeBook E8010D)
 
 pci:v000014E4d0000165F*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe
 
 pci:v000014E4d0000165Fsv00001028sd000004F7*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (PowerEdge R320 server)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge R320 server)
 
 pci:v000014E4d0000165Fsv00001028sd000008FD*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (PowerEdge R6515/R7515 LOM)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge R6515/R7515 LOM)
 
 pci:v000014E4d0000165Fsv00001028sd000008FF*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (PowerEdge Rx5xx LOM Board)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge Rx5xx LOM Board)
 
 pci:v000014E4d0000165Fsv00001028sd00000900*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (PowerEdge C6525 LOM)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge C6525 LOM)
 
 pci:v000014E4d0000165Fsv0000103Csd00001786*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (NC332T Adapter)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332T Adapter)
 
 pci:v000014E4d0000165Fsv0000103Csd0000193D*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (NC332i Adapter)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter)
 
 pci:v000014E4d0000165Fsv0000103Csd00002133*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (NC332i Adapter)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter)
 
 pci:v000014E4d0000165Fsv0000103Csd000022E8*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (NC332i Adapter)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter)
 
 pci:v000014E4d0000165Fsv0000103Csd000022EB*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 2-port Gigabit Ethernet PCIe (NC332i Adapter)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter)
 
 pci:v000014E4d00001662*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet
@@ -56885,6 +56954,9 @@ pci:v000014E4d000016D5*
 pci:v000014E4d000016D6*
  ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller
 
+pci:v000014E4d000016D6sv000014E4sd00001202*
+ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller (BCM957412M4122C OCP 1x25G Type1 wRoCE)
+
 pci:v000014E4d000016D6sv000014E4sd00004120*
  ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller (NetXtreme E-Series Advanced Dual-port 10Gb SFP+ Ethernet Network Daughter Card)
 
@@ -56900,9 +56972,6 @@ pci:v000014E4d000016D6sv0000152Dsd00008B22*
 pci:v000014E4d000016D7*
  ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller
 
-pci:v000014E4d000016D7sv000014E4sd00001202*
- ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957412M4122C OCP 1x25G Type1 wRoCE)
-
 pci:v000014E4d000016D7sv000014E4sd00001402*
  ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957414A4142CC 10Gb/25Gb Ethernet PCIe)
 
@@ -59396,6 +59465,9 @@ pci:v00001542d00009271*
 pci:v00001542d00009272*
  ID_MODEL_FROM_DATABASE=Pulse Width Modulator Card
 
+pci:v00001542d00009273*
+ ID_MODEL_FROM_DATABASE=RCIM-IV Real-Time Clock & Interrupt Module (PCIe)
+
 pci:v00001542d00009277*
  ID_MODEL_FROM_DATABASE=5 Volt Delta Sigma Converter Card
 
@@ -60260,9 +60332,18 @@ pci:v000015B3d00001015sv000015B3sd00000025*
 pci:v000015B3d00001015sv0000193Dsd0000100A*
  ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (620F-B)
 
+pci:v000015B3d00001015sv0000193Dsd00001023*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH540F-LP-2P)
+
 pci:v000015B3d00001015sv0000193Dsd00001031*
  ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH640i-Mb-2x25G)
 
+pci:v000015B3d00001015sv0000193Dsd00001083*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH640F-3S-2P)
+
+pci:v000015B3d00001015sv0000193Dsd00001084*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH540F-3S-2P)
+
 pci:v000015B3d00001016*
  ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx Virtual Function]
 
@@ -63545,6 +63626,9 @@ pci:v000017A0d0000E763*
 pci:v000017AA*
  ID_VENDOR_FROM_DATABASE=Lenovo
 
+pci:v000017AAd00003181*
+ ID_MODEL_FROM_DATABASE=ThinkCentre M75n IoT
+
 pci:v000017AAd0000402B*
  ID_MODEL_FROM_DATABASE=Intel 82599ES 10Gb 2-port Server Adapter X520-2
 
@@ -68111,6 +68195,18 @@ pci:v00001BD0d00001004*
 pci:v00001BD0d00001005*
  ID_MODEL_FROM_DATABASE=PE1000 (Multi-Protocol PCIe/104 Interface Card)
 
+pci:v00001BD0d00001006*
+ ID_MODEL_FROM_DATABASE=webCS Wireless Aircraft Communications Server
+
+pci:v00001BD0d00001007*
+ ID_MODEL_FROM_DATABASE=AB3000 Series Rugged Computer (Series N)
+
+pci:v00001BD0d00001008*
+ ID_MODEL_FROM_DATABASE=ME1000 mPCIe Avionics Interface Card
+
+pci:v00001BD0d0000100A*
+ ID_MODEL_FROM_DATABASE=NG1 Series Avionics Converter
+
 pci:v00001BD0d00001101*
  ID_MODEL_FROM_DATABASE=OmniBus II PCIe Multi-Protocol Interface Card
 
@@ -68120,6 +68216,18 @@ pci:v00001BD0d00001102*
 pci:v00001BD0d00001103*
  ID_MODEL_FROM_DATABASE=OmniBus II cPCIe/PXIe Multi-Protocol Interface Card
 
+pci:v00001BD0d00001200*
+ ID_MODEL_FROM_DATABASE=NG3 Series Mil-Std-1553 Interface
+
+pci:v00001BD0d00001201*
+ ID_MODEL_FROM_DATABASE=NG3 Series ARINC 429 Interface
+
+pci:v00001BD0d00001202*
+ ID_MODEL_FROM_DATABASE=NG3 Series Avionics Discrete & Serial Interface
+
+pci:v00001BD0d00001203*
+ ID_MODEL_FROM_DATABASE=NG3 Series Avionics Discrete Interface
+
 pci:v00001BD4*
  ID_VENDOR_FROM_DATABASE=Inspur Electronic Information Industry Co., Ltd.
 
@@ -68216,6 +68324,9 @@ pci:v00001C1Fd0000001C*
 pci:v00001C1Fd0000001D*
  ID_MODEL_FROM_DATABASE=Vega
 
+pci:v00001C1Fd0000001F*
+ ID_MODEL_FROM_DATABASE=FD940
+
 pci:v00001C28*
  ID_VENDOR_FROM_DATABASE=Lite-On IT Corp. / Plextor
 
@@ -68636,6 +68747,9 @@ pci:v00001CE4d0000000A*
 pci:v00001CE4d0000000B*
  ID_MODEL_FROM_DATABASE=ExaNIC V9P
 
+pci:v00001CE4d0000000C*
+ ID_MODEL_FROM_DATABASE=ExaNIC V9P-3
+
 pci:v00001CE4d00000100*
  ID_MODEL_FROM_DATABASE=ExaDISK FX1
 
@@ -69653,6 +69767,12 @@ pci:v00001DF3d00000206sv00001DF3sd00000000*
 pci:v00001DF3d00000206sv00001DF3sd00000001*
  ID_MODEL_FROM_DATABASE=ACE-NIC200 Programmable Network Accelerator (ENA2200F)
 
+pci:v00001DF3d00000207*
+ ID_MODEL_FROM_DATABASE=ACE-NIC50RN Programmable Network Accelerator
+
+pci:v00001DF3d00000208*
+ ID_MODEL_FROM_DATABASE=ACE-NIC100RN Programmable Network Accelerator
+
 pci:v00001DF7*
  ID_VENDOR_FROM_DATABASE=opencpi.org
 
@@ -70734,7 +70854,7 @@ pci:v00004348d00007173*
  ID_MODEL_FROM_DATABASE=CH355 PCI Quad Serial Port Controller
 
 pci:v0000434E*
- ID_VENDOR_FROM_DATABASE=CAST Navigation LLC
+ ID_VENDOR_FROM_DATABASE=Cornelis Networks
 
 pci:v000043BC*
  ID_VENDOR_FROM_DATABASE=Tiger Lake-H PCIe Root Port #5
@@ -74162,6 +74282,12 @@ pci:v00008086d00000B60sv00001028sd00002104*
 pci:v00008086d00000B60sv00008086sd00008008*
  ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe Datacenter SSD [3DNAND] SE 2.5" U.2 (P5510))
 
+pci:v00008086d00000B60sv00008086sd00008D08*
+ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe Datacenter SSD [3DNAND] VE 2.5" U.2 (P5316))
+
+pci:v00008086d00000B60sv00008086sd00008D1D*
+ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe Datacenter SSD [3DNAND] VE E1.L 9.5/18mm (P5316))
+
 pci:v00008086d00000BE0*
  ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
 
@@ -77522,6 +77648,9 @@ pci:v00008086d00001521sv0000193Dsd00001005*
 pci:v00008086d00001521sv0000193Dsd00001007*
  ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (360T-L)
 
+pci:v00008086d00001521sv0000193Dsd00001080*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (NIC-ETH360T-3S-4P)
+
 pci:v00008086d00001521sv00001BD4sd0000001D*
  ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (1G base-T QP EP014Ti1 Adapter)
 
@@ -78041,6 +78170,9 @@ pci:v00008086d00001572sv0000193Dsd00001020*
 pci:v00008086d00001572sv0000193Dsd00001021*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (NIC-ETH561F-sL-2x10G)
 
+pci:v00008086d00001572sv0000193Dsd00001081*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (NIC-ETH561F-3S-2P)
+
 pci:v00008086d00001572sv000019E5sd0000D11C*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 2-port X710 10Gb SFP+ Adapter SP330)
 
@@ -78443,6 +78575,9 @@ pci:v00008086d00001592sv00008086sd0000000C*
 pci:v00008086d00001592sv00008086sd0000000D*
  ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-L-Q2 for OCP 3.0)
 
+pci:v00008086d00001592sv00008086sd0000000E*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-2C-Q2)
+
 pci:v00008086d00001593*
  ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP
 
@@ -78791,6 +78926,9 @@ pci:v00008086d000015FFsv00001137sd000002D9*
 pci:v00008086d000015FFsv00001137sd000002DA*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T4L OCP 3.0)
 
+pci:v00008086d000015FFsv0000193Dsd00001082*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (NIC-ETH565T-3S-2P)
+
 pci:v00008086d000015FFsv00008086sd00000000*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-TL)
 
@@ -83129,6 +83267,9 @@ pci:v00008086d000024F0sv00001CB8sd00000003*
 pci:v00008086d000024F0sv00001CB8sd00000004*
  ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16, TC4600E QSFP28)
 
+pci:v00008086d000024F0sv0000434Esd00000001*
+ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI 100 Series, 1 Port, OCP 3.0 Adapter)
+
 pci:v00008086d000024F0sv00008086sd00002628*
  ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16)
 
@@ -91817,6 +91958,9 @@ pci:v00008086d000043ED*
 pci:v00008086d000043EF*
  ID_MODEL_FROM_DATABASE=Tiger Lake-H Shared SRAM
 
+pci:v00008086d000043F0*
+ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX201
+
 pci:v00008086d0000444E*
  ID_MODEL_FROM_DATABASE=Turbo Memory Controller
 
@@ -94074,7 +94218,7 @@ pci:v00008086d000096A1*
  ID_MODEL_FROM_DATABASE=Integrated RAID
 
 pci:v00008086d00009A01*
- ID_MODEL_FROM_DATABASE=11th Gen Core Processor PCIe Controller
+ ID_MODEL_FROM_DATABASE=11th Gen Core Processor PCIe Controller #1
 
 pci:v00008086d00009A03*
  ID_MODEL_FROM_DATABASE=TigerLake-LP Dynamic Tuning Processor Participant
@@ -94088,6 +94232,9 @@ pci:v00008086d00009A0B*
 pci:v00008086d00009A0D*
  ID_MODEL_FROM_DATABASE=Tiger Lake-LP Telemetry Aggregator
 
+pci:v00008086d00009A0F*
+ ID_MODEL_FROM_DATABASE=11th Gen Core Processor PCIe Controller #0
+
 pci:v00008086d00009A11*
  ID_MODEL_FROM_DATABASE=GNA Scoring Accelerator module
 
@@ -95894,6 +96041,9 @@ pci:v00008086d0000A324sv00001028sd00000869*
 pci:v00008086d0000A328*
  ID_MODEL_FROM_DATABASE=Cannon Lake PCH Serial IO UART Host Controller
 
+pci:v00008086d0000A32B*
+ ID_MODEL_FROM_DATABASE=Cannon Lake PCH SPI Host Controller
+
 pci:v00008086d0000A32C*
  ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #21
 
@@ -98915,6 +99065,9 @@ pci:v0000F1D0d0000EB24*
 pci:v0000F1D0d0000EB25*
  ID_MODEL_FROM_DATABASE=Corvid 44 12g
 
+pci:v0000F1D0d0000EB26*
+ ID_MODEL_FROM_DATABASE=T-Tap Pro
+
 pci:v0000F1D0d0000EFAC*
  ID_MODEL_FROM_DATABASE=Xena SD-MM/SD-22-MM
 
index c3384a994ee9962d3a2a46a47084f4430d8cabfc..8923e12ea0816dd6bf410e90467b0133867e3c26 100644 (file)
@@ -147,7 +147,7 @@ usb:v06CBp00F9*
 usb:v06CBp00FC*
 usb:v06CBp00C2*
 usb:v06CBp00C9*
-usb:v06CBp00E7*
+usb:v06CBp0100*
  ID_AUTOSUSPEND=1
 
 # Supported by libfprint driver upeksonly
@@ -199,6 +199,10 @@ usb:v138Ap0017*
 usb:v138Ap0018*
  ID_AUTOSUSPEND=1
 
+# Supported by libfprint driver vfs7552
+usb:v138Ap0091*
+ ID_AUTOSUSPEND=1
+
 # Known unsupported devices
 usb:v04F3p036B*
 usb:v04F3p0C00*
@@ -237,7 +241,6 @@ usb:v138Ap003C*
 usb:v138Ap003D*
 usb:v138Ap003F*
 usb:v138Ap0090*
-usb:v138Ap0091*
 usb:v138Ap0092*
 usb:v138Ap0094*
 usb:v138Ap0097*
index 17c9e2e507a851eaf98671079c6bc1535093cb5b..a609b30d695703cf844d329da8cb5bc3b34bd56c 100644 (file)
@@ -491,7 +491,9 @@ mouse:bluetooth:v046dpb019:name:MX Master 2S Mouse:*
  MOUSE_WHEEL_CLICK_COUNT=24
  MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14
 
-# Logitech MX Ergo (via Bluetooth)
+# Logitech MX Ergo
+mouse:usb:v046dp406f:name:Logitech MX Ergo:*
+mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:406f:*
 mouse:bluetooth:v046dpb01d:name:MX Ergo Mouse:*
  ID_INPUT_TRACKBALL=1
 
diff --git a/hwdb.d/README b/hwdb.d/README
new file mode 100644 (file)
index 0000000..594f5bf
--- /dev/null
@@ -0,0 +1,11 @@
+Files in this directory specify a description of hardware devices, in the form
+of mappings from modalias-like keys (which identify specific hardware devices)
+to udev properties.
+
+Files in this directory are not read by udev directly. Instead,
+man:systemd-hwdb(8) compiles them into a binary database.
+
+See man:hwdb(7) for an overview of the configuration file format, and
+man:systemd-udevd.service(8) for a description of the udev daemon.
+
+Use 'systemd-analyze cat-config udev/hwdb.d' to display the effective config.
index 3906f9c50f2784cdd52ab985b2012749eedd88d0..d22bb22b99cd0e33c6bd0c8f0413737c3d98fb8a 100644 (file)
  <tr class="even"><td>Loongson Technology Corporation Limited</td><td>LOON</td><td>09/10/2020</td> </tr>
  <tr class="odd"><td>Seiko Epson Corporation</td><td>SECC</td><td>02/16/2021</td> </tr>
  <tr class="even"><td>Alibaba Co., Ltd.</td><td>BABA</td><td>02/02/2021</td> </tr>
+ <tr class="odd"><td>Juniper Systems, Inc.</td><td>JSYS</td><td>03/18/2021</td> </tr>
+ <tr class="even"><td>Framework Computer LLC</td><td>FRMW</td><td>03/22/2021</td> </tr>
+ <tr class="odd"><td>Pensando Systems, Inc.</td><td>PNSO</td><td>03/24/2021</td> </tr>
       </tbody>
     </table>
   </body>
index 34681459ac386066f47a7abcd2a71457a330afa3..5de04e9291b796715a75111e191baa8a3c148064 100644 (file)
@@ -17741,12 +17741,6 @@ F8D756     (base 16)           Simm Tronic Limited
                                Dublin     12\r
                                IE\r
 \r
-64-D0-2D   (hex)               Next Generation Integration (NGI)\r
-64D02D     (base 16)           Next Generation Integration (NGI)\r
-                               137 rue de Versailles\r
-                               Le Chesnay    78150\r
-                               FR\r
-\r
 90-51-3F   (hex)               Elettronica Santerno SpA\r
 90513F     (base 16)           Elettronica Santerno SpA\r
                                Via della Concia 7\r
@@ -35663,6 +35657,180 @@ A45590     (base 16)          Xiaomi Communications Co Ltd
                                Seongnam-si  Gyeonggi-do  13590\r
                                KR\r
 \r
+4C-71-67   (hex)               PoLabs d.o.o.\r
+4C7167     (base 16)           PoLabs d.o.o.\r
+                               Volavlje 30\r
+                               Ljubljana    1000\r
+                               SI\r
+\r
+04-71-53   (hex)               SERNET (SUZHOU) TECHNOLOGIES CORPORATION\r
+047153     (base 16)           SERNET (SUZHOU) TECHNOLOGIES CORPORATION\r
+                               NO.8 Tangzhuang Road,Suzhou Industrial Park,Su ZhouCity,JiangSu Province,China\r
+                               Suzhou    215021\r
+                               CN\r
+\r
+48-E7-DA   (hex)               AzureWave Technology Inc.\r
+48E7DA     (base 16)           AzureWave Technology Inc.\r
+                               8F., No. 94, Baozhong Rd.\r
+                               New Taipei City  Taiwan  231\r
+                               TW\r
+\r
+40-C4-8C   (hex)               N-iTUS CO.,LTD.\r
+40C48C     (base 16)           N-iTUS CO.,LTD.\r
+                               NiTUS 85, Deokcheon-ro\r
+                               Anyang-si  Gyeonggi-do, Korea  14086\r
+                               KR\r
+\r
+48-22-18   (hex)               Shenzhen Yipingfang Network Technology Co., Ltd.\r
+482218     (base 16)           Shenzhen Yipingfang Network Technology Co., Ltd.\r
+                               21 / F, Kangjia R & D building, No.28, Keji South 12th Road, Nanshan District, Shenzhen City, Guangdong Province, China\r
+                               Shenzhen  Nanshan District  518000\r
+                               CN\r
+\r
+E4-0C-FD   (hex)               GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+E40CFD     (base 16)           GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+                               NO.18 HAIBIN ROAD,\r
+                               DONG GUAN  GUANG DONG  523860\r
+                               CN\r
+\r
+58-D6-97   (hex)               GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+58D697     (base 16)           GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+                               NO.18 HAIBIN ROAD,\r
+                               DONG GUAN  GUANG DONG  523860\r
+                               CN\r
+\r
+54-37-BB   (hex)               Taicang T&W Electronics\r
+5437BB     (base 16)           Taicang T&W Electronics\r
+                               89# Jiang Nan RD\r
+                               Suzhou  Jiangsu  215412\r
+                               CN\r
+\r
+60-F8-F2   (hex)               Synaptec\r
+60F8F2     (base 16)           Synaptec\r
+                               204 George Street\r
+                               Glasgow    G1 1XW\r
+                               GB\r
+\r
+AC-74-B1   (hex)               Intel Corporate\r
+AC74B1     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+30-A1-76   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+30A176     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+F4-E4-51   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+F4E451     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+1C-3C-D4   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+1C3CD4     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+F4-60-77   (hex)               Texas Instruments\r
+F46077     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+24-9A-C8   (hex)               Shenzhen Skyworth  Digital  Technology  CO., Ltd\r
+249AC8     (base 16)           Shenzhen Skyworth  Digital  Technology  CO., Ltd\r
+                               4F,Block A, Skyworth?Building,\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+C0-3C-04   (hex)               Sagemcom Broadband SAS\r
+C03C04     (base 16)           Sagemcom Broadband SAS\r
+                               250, route de l'Empereur\r
+                               Rueil Malmaison Cedex  hauts de seine  92848\r
+                               FR\r
+\r
+A4-D7-3C   (hex)               Seiko Epson Corporation\r
+A4D73C     (base 16)           Seiko Epson Corporation\r
+                               2070 Kotobuki Koaka\r
+                               Matsumoto-shi  Nagano-ken  399-8702\r
+                               JP\r
+\r
+2C-48-81   (hex)               vivo Mobile Communication Co., Ltd.\r
+2C4881     (base 16)           vivo Mobile Communication Co., Ltd.\r
+                               #283,BBK Road\r
+                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+                               CN\r
+\r
+60-26-EF   (hex)               Aruba, a Hewlett Packard Enterprise Company\r
+6026EF     (base 16)           Aruba, a Hewlett Packard Enterprise Company\r
+                               3333 Scott Blvd\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+F8-8E-A1   (hex)               Edgecore Networks Corporation\r
+F88EA1     (base 16)           Edgecore Networks Corporation\r
+                               1 Creation RD 3.\r
+                               Hsinchu    30077\r
+                               TW\r
+\r
+7C-85-30   (hex)               Nokia\r
+7C8530     (base 16)           Nokia\r
+                               600 March Road\r
+                               Kanata  Ontario  K2K 2E6\r
+                               CA\r
+\r
+64-D0-2D   (hex)               NEXT GENERATION INTEGRATION LIMITED (NGI)\r
+64D02D     (base 16)           NEXT GENERATION INTEGRATION LIMITED (NGI)\r
+                               Unit 1102, 11 / F, 29 Austin Road, TSIM SHA TSUI\r
+                               KOWLOON  Hong Kong  999077\r
+                               HK\r
+\r
+24-28-FD   (hex)               Hangzhou Hikvision Digital Technology Co.,Ltd.\r
+2428FD     (base 16)           Hangzhou Hikvision Digital Technology Co.,Ltd.\r
+                               No.555 Qianmo Road\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+88-AE-DD   (hex)               EliteGroup Computer Systems Co., LTD\r
+88AEDD     (base 16)           EliteGroup Computer Systems Co., LTD\r
+                               No. 239, Sec. 2, Ti ding Blvd.\r
+                               Taipei City    11493\r
+                               TW\r
+\r
+A0-E7-0B   (hex)               Intel Corporate\r
+A0E70B     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+B0-D8-88   (hex)               Panasonic Corporation Automotive\r
+B0D888     (base 16)           Panasonic Corporation Automotive\r
+                               5652\r
+                               Matsumoto City  Nagano  399-8730\r
+                               JP\r
+\r
+F4-63-E7   (hex)               Nanjing Maxon O.E. Tech. Co., LTD\r
+F463E7     (base 16)           Nanjing Maxon O.E. Tech. Co., LTD\r
+                               6/F, Building A3, Zidong International Creative Park, Zidong Road, Qixia District, Nanjing\r
+                               NAN JING  JIANG SU  210000\r
+                               CN\r
+\r
+04-EE-EE   (hex)               Laplace System Co., Ltd.\r
+04EEEE     (base 16)           Laplace System Co., Ltd.\r
+                               1-245 Kyo-machi\r
+                               Fushimi, Kyoto  Kyoto  6128083\r
+                               JP\r
+\r
+6C-10-8B   (hex)               WeLink Communications\r
+6C108B     (base 16)           WeLink Communications\r
+                               4186 N Red Maple Court\r
+                               Lehi  UT  84043\r
+                               US\r
+\r
 9C-FF-C2   (hex)               AVI Systems GmbH\r
 9CFFC2     (base 16)           AVI Systems GmbH\r
                                Dr. Franz Wilhelmstraße 2A\r
@@ -48998,12 +49166,6 @@ F48139     (base 16)           CANON INC.
                                Olathe  KS  66061\r
                                US\r
 \r
-A4-D0-94   (hex)               Erwin Peters Systemtechnik GmbH\r
-A4D094     (base 16)           Erwin Peters Systemtechnik GmbH\r
-                               Josef Baumann Strasse 37\r
-                               Bochum    D44805\r
-                               DE\r
-\r
 88-23-64   (hex)               Watchnet DVR Inc\r
 882364     (base 16)           Watchnet DVR Inc\r
                                Unit 5 - 351 Ferrier St.\r
@@ -62249,12 +62411,6 @@ D4AAFF     (base 16)           MICRO WORLD
                                    \r
                                KR\r
 \r
-00-03-24   (hex)               SANYO Consumer Electronics Co., Ltd.\r
-000324     (base 16)           SANYO Consumer Electronics Co., Ltd.\r
-                               7-101 Tachikawa-cho\r
-                               Tottori City    680-8634\r
-                               JP\r
-\r
 00-02-BF   (hex)               dotRocket, Inc.\r
 0002BF     (base 16)           dotRocket, Inc.\r
                                1901 S. Bascom, Suite 300\r
@@ -70793,6 +70949,30 @@ B027CF     (base 16)           Extreme Networks, Inc.
                                Mountain View  CA  94043\r
                                US\r
 \r
+48-F8-FF   (hex)               CHENGDU KT ELECTRONIC HI-TECH CO.,LTD\r
+48F8FF     (base 16)           CHENGDU KT ELECTRONIC HI-TECH CO.,LTD\r
+                               No.9, 3rd Wuke Road, Wuhou District\r
+                               Chengdu  Sichuan Province  610045\r
+                               CN\r
+\r
+E8-C1-E8   (hex)               Shenzhen Xiao Bi En Culture Education Technology Co.,Ltd.\r
+E8C1E8     (base 16)           Shenzhen Xiao Bi En Culture Education Technology Co.,Ltd.\r
+                               4GH Unit,Block D,Central Avenue,Intersection of Xixiang Avenue and Baoyuan Road,Labor Community,Xixiang Street,Baoan District\r
+                               Shenzhen  China  518102\r
+                               CN\r
+\r
+2C-DD-E9   (hex)               Arista Networks\r
+2CDDE9     (base 16)           Arista Networks\r
+                               5453 Great America Parkway\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+70-97-41   (hex)               Arcadyan Corporation\r
+709741     (base 16)           Arcadyan Corporation\r
+                               No.8, Sec.2, Guangfu Rd.\r
+                               Hsinchu City  Hsinchu  30071\r
+                               TW\r
+\r
 C4-FF-22   (hex)               Huawei Device Co., Ltd.\r
 C4FF22     (base 16)           Huawei Device Co., Ltd.\r
                                No.2 of Xincheng Road, Songshan Lake Zone\r
@@ -70817,6 +70997,192 @@ E408E7     (base 16)          Quectel Wireless Solutions Co.,Ltd.
                                Shanghai    200233\r
                                CN\r
 \r
+7C-70-DB   (hex)               Intel Corporate\r
+7C70DB     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+8C-94-CC   (hex)               SFR\r
+8C94CC     (base 16)           SFR\r
+                               12 rue jean-philippe Rameau CS 80001\r
+                               La plaine saint denis   FRANCE  93634\r
+                               FR\r
+\r
+60-DB-15   (hex)               New H3C Technologies Co., Ltd\r
+60DB15     (base 16)           New H3C Technologies Co., Ltd\r
+                               466 Changhe Road, Binjiang District\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+5C-A7-21   (hex)               New H3C Technologies Co., Ltd\r
+5CA721     (base 16)           New H3C Technologies Co., Ltd\r
+                               466 Changhe Road, Binjiang District\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+98-F2-17   (hex)               Castlenet Technology Inc.\r
+98F217     (base 16)           Castlenet Technology Inc.\r
+                               5F., No. 10, Daye Rd., Beitou Dist.\r
+                               Taipei City    112030\r
+                               TW\r
+\r
+6C-43-3C   (hex)               TECNO MOBILE LIMITED\r
+6C433C     (base 16)           TECNO MOBILE LIMITED\r
+                               ROOMS 05-15, 13A/F., SOUTH TOWER, WORLD FINANCE CENTRE, HARBOUR CITY, 17 CANTON ROAD, TSIM SHA TSUI, KOWLOON, HONG KONG\r
+                               Hong Kong  Hong Kong  999077\r
+                               HK\r
+\r
+44-5B-ED   (hex)               Aruba, a Hewlett Packard Enterprise Company\r
+445BED     (base 16)           Aruba, a Hewlett Packard Enterprise Company\r
+                               3333 Scott Blvd\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+70-A6-CC   (hex)               Intel Corporate\r
+70A6CC     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+84-EB-EF   (hex)               Cisco Systems, Inc\r
+84EBEF     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+90-80-60   (hex)               Nilfisk A/S\r
+908060     (base 16)           Nilfisk A/S\r
+                               Kornmarksvej 1\r
+                               Broendby     2605\r
+                               DK\r
+\r
+10-09-F9   (hex)               Amazon Technologies Inc.\r
+1009F9     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102 \r
+                               Reno  NV  89507\r
+                               US\r
+\r
+D0-3E-7D   (hex)               CHIPSEA TECHNOLOGIES (SHENZHEN) CORP.\r
+D03E7D     (base 16)           CHIPSEA TECHNOLOGIES (SHENZHEN) CORP.\r
+                               9F,BLOCK A,GARDEN CITY DIGITAL BUILDING,NO.1079 NANHAI ROAD,NANSHAN DISTRICT\r
+                               SHEN ZHEN  GUANG DONG  518000\r
+                               CN\r
+\r
+6C-79-B8   (hex)               Texas Instruments\r
+6C79B8     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+A4-D0-94   (hex)               VIVAVIS AG\r
+A4D094     (base 16)           VIVAVIS AG\r
+                               Nobelstr. 18\r
+                               Ettlingen    D-76375\r
+                               DE\r
+\r
+8C-A3-99   (hex)               SERVERCOM (INDIA) PRIVATE LIMITED\r
+8CA399     (base 16)           SERVERCOM (INDIA) PRIVATE LIMITED\r
+                               E-43/1 OKHLA INDUSTRIAL AREA PHASE-II NEW DELHI SOUTH DELHI\r
+                               NEW DELHI    NA\r
+                               IN\r
+\r
+D4-54-8B   (hex)               Intel Corporate\r
+D4548B     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+60-A5-E2   (hex)               Intel Corporate\r
+60A5E2     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+FC-92-57   (hex)               Renesas Electronics (Penang) Sdn. Bhd.\r
+FC9257     (base 16)           Renesas Electronics (Penang) Sdn. Bhd.\r
+                               Phase 3, Bayan Lepas FIZ\r
+                               Bayan Lepas  Penang  11900\r
+                               MY\r
+\r
+90-69-76   (hex)               Withrobot Inc.\r
+906976     (base 16)           Withrobot Inc.\r
+                               #1001, Seoul Forest M-tower, 31, Ttukseom-ro 1-gil, Seongdong-gu\r
+                               Seoul  Seoul  04778\r
+                               KR\r
+\r
+60-B6-E1   (hex)               Texas Instruments\r
+60B6E1     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+D0-1E-1D   (hex)               SaiNXT Technologies LLP\r
+D01E1D     (base 16)           SaiNXT Technologies LLP\r
+                               Shop No. 7, Sonawala Building, 1st Floor, Proctor Road, Grant Road (E)\r
+                               Mumbai  Maharashtra  400007\r
+                               IN\r
+\r
+A8-23-16   (hex)               Nokia\r
+A82316     (base 16)           Nokia\r
+                               600 March Road\r
+                               Kanata  Ontario  K2K 2E6\r
+                               CA\r
+\r
+38-E3-9F   (hex)               Motorola Mobility LLC, a Lenovo Company\r
+38E39F     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
+                               222 West Merchandise Mart Plaza\r
+                               Chicago  IL  60654\r
+                               US\r
+\r
+A4-2A-71   (hex)               Sichuan Tianyi Comheart Telecom Co.,LTD\r
+A42A71     (base 16)           Sichuan Tianyi Comheart Telecom Co.,LTD\r
+                               No.198,First Section,Snow Mountain Avenue, Jinyuan Town, Dayi County\r
+                               Chengdu  Sichuan  611330\r
+                               CN\r
+\r
+44-67-52   (hex)               Wistron INFOCOMM (Zhongshan) CORPORATION\r
+446752     (base 16)           Wistron INFOCOMM (Zhongshan) CORPORATION\r
+                               15 Cuiwei Road, Cuiheng New District\r
+                               zhongshan  Guangdong  528400\r
+                               CN\r
+\r
+78-BB-88   (hex)               Maxio Technology (Hangzhou) Ltd.\r
+78BB88     (base 16)           Maxio Technology (Hangzhou) Ltd.\r
+                               6F, Building C, No.459 Qianmo Road, Juguang Center\r
+                               Hangzhou  Zhejiang  310051\r
+                               CN\r
+\r
+A8-64-F1   (hex)               Intel Corporate\r
+A864F1     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+58-4D-42   (hex)               Dragos, Inc.\r
+584D42     (base 16)           Dragos, Inc.\r
+                               1745 Dorsey Rd, Suite R\r
+                               Hanover  MD  21076\r
+                               US\r
+\r
+60-8A-10   (hex)               Microchip Technology Inc.\r
+608A10     (base 16)           Microchip Technology Inc.\r
+                               2355 W. Chandler Blvd.\r
+                               Chandler  AZ  85224\r
+                               US\r
+\r
+10-6F-D9   (hex)               CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD.\r
+106FD9     (base 16)           CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD.\r
+                               B22 Building,NO.51 Tongle Road, Shajing Town, Jiangnan District, Nanning, Guangxi Province, China\r
+                               Nanning  Guangxi  530007\r
+                               CN\r
+\r
+00-03-24   (hex)               SANYO Techno Solutions Tottori Co., Ltd.\r
+000324     (base 16)           SANYO Techno Solutions Tottori Co., Ltd.\r
+                               7-101 Tachikawa-cho\r
+                               Tottori City    680-8634\r
+                               JP\r
+\r
 84-80-94   (hex)               Meter, Inc.\r
 848094     (base 16)           Meter, Inc.\r
                                148 Townsend St\r
@@ -71264,9 +71630,6 @@ FCBCD1     (base 16)            HUAWEI TECHNOLOGIES CO.,LTD
                                Dongguan     523808\r
                                CN\r
 \r
-CC-3A-DF   (hex)               Private\r
-CC3ADF     (base 16)           Private\r
-\r
 38-EF-E3   (hex)                INGENICO TERMINALS SAS\r
 38EFE3     (base 16)            INGENICO TERMINALS SAS\r
                                28-32 BOULEVARD DE GRENELLE\r
@@ -88154,12 +88517,6 @@ C8A1B6     (base 16)           Shenzhen Longway Technologies Co., Ltd
                                Shenzhen  Guangdong  518057\r
                                CN\r
 \r
-A8-55-6A   (hex)               Pocketnet Technology Inc.\r
-A8556A     (base 16)           Pocketnet Technology Inc.\r
-                               Suite B, 7F., No. 550, Ruie Kwang Rd., Neihu District,\r
-                               Taipei    11429\r
-                               TW\r
-\r
 B4-C8-10   (hex)               UMPI Elettronica\r
 B4C810     (base 16)           UMPI Elettronica\r
                                Via Respighi, 15\r
@@ -95564,12 +95921,6 @@ D8D67E     (base 16)           GSK CNC EQUIPMENT CO.,LTD
                                Yokohama  Kanagawa  224-0037\r
                                JP\r
 \r
-00-0B-3A   (hex)               QuStream Corporation\r
-000B3A     (base 16)           QuStream Corporation\r
-                               3305 Breckinridge Blvd.\r
-                               Duluth  Georgia  30096\r
-                               US\r
-\r
 00-0B-33   (hex)               Vivato Technologies\r
 000B33     (base 16)           Vivato Technologies\r
                                444 Cedros Ave\r
@@ -106391,36 +106742,171 @@ B0A7B9     (base 16)               TP-Link Corporation Limited
                                Mountain View  CA  94043\r
                                US\r
 \r
-C8-F5-D6   (hex)               IEEE Registration Authority\r
-C8F5D6     (base 16)           IEEE Registration Authority\r
-                               445 Hoes Lane\r
-                               Piscataway  NJ  08554\r
-                               US\r
-\r
-8C-4D-EA   (hex)               Cerio Corporation\r
-8C4DEA     (base 16)           Cerio Corporation\r
-                               4F.-3., No.192, Sec. 2, Zhongxing Rd., Xindian Dist.\r
-                               New Taipei City    231\r
-                               TW\r
-\r
 B8-25-B5   (hex)               Trakm8 Ltd\r
 B825B5     (base 16)           Trakm8 Ltd\r
                                4 Roman Park, Roman Way\r
                                Coleshill   West Midlands  B46 1HG\r
                                GB\r
 \r
+20-D2-76   (hex)               ITEL MOBILE LIMITED\r
+20D276     (base 16)           ITEL MOBILE LIMITED\r
+                               RM B3 & B4 BLOCK B, KO FAI INDUSTRIAL BUILDING  NO.7 KO FAI ROAD, YAU TONG, KLN, H.K\r
+                               Hong Kong  KOWLOON  999077\r
+                               HK\r
+\r
 08-A8-42   (hex)               Huawei Device Co., Ltd.\r
 08A842     (base 16)           Huawei Device Co., Ltd.\r
                                No.2 of Xincheng Road, Songshan Lake Zone\r
                                Dongguan  Guangdong  523808\r
                                CN\r
 \r
+C8-F5-D6   (hex)               IEEE Registration Authority\r
+C8F5D6     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
 40-58-99   (hex)               Logitech Far East\r
 405899     (base 16)           Logitech Far East\r
                                #2 Creation Rd. 4,\r
                                Hsinchu    300\r
                                TW\r
 \r
+8C-4D-EA   (hex)               Cerio Corporation\r
+8C4DEA     (base 16)           Cerio Corporation\r
+                               4F.-3., No.192, Sec. 2, Zhongxing Rd., Xindian Dist.\r
+                               New Taipei City    231\r
+                               TW\r
+\r
+98-43-FA   (hex)               Intel Corporate\r
+9843FA     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+94-AA-0A   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+94AA0A     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+7C-F4-62   (hex)               BEIJING HUAWOO TECHNOLOGIES CO.LTD\r
+7CF462     (base 16)           BEIJING HUAWOO TECHNOLOGIES CO.LTD\r
+                               A411-3, floor 3, block A, 9 Shangdi 3rd Street, Haidian District, Beijing\r
+                               beijing    100094\r
+                               CN\r
+\r
+04-B9-E3   (hex)               Samsung Electronics Co.,Ltd\r
+04B9E3     (base 16)           Samsung Electronics Co.,Ltd\r
+                               129, Samsung-ro, Youngtongl-Gu\r
+                               Suwon  Gyeonggi-Do  16677\r
+                               KR\r
+\r
+C4-5E-5C   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+C45E5C     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+E8-5C-0A   (hex)               Cisco Systems, Inc\r
+E85C0A     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+70-B9-50   (hex)               Texas Instruments\r
+70B950     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+D0-9F-D9   (hex)               IEEE Registration Authority\r
+D09FD9     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+A0-B0-86   (hex)               Hirschmann Automation and Control GmbH\r
+A0B086     (base 16)           Hirschmann Automation and Control GmbH\r
+                               Stuttgarter Straße 45-51\r
+                               Neckartenzlingen    D-72654\r
+                               DE\r
+\r
+30-B3-46   (hex)               CJSC NORSI-TRANS\r
+30B346     (base 16)           CJSC NORSI-TRANS\r
+                               B.Novodmitrovskaya, 12/15 floor 2 r. 36\r
+                               Moscow  MOSCOW  127015\r
+                               RU\r
+\r
+20-C1-9B   (hex)               Intel Corporate\r
+20C19B     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+2C-6D-C1   (hex)               Intel Corporate\r
+2C6DC1     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+00-FA-B6   (hex)               Kontakt Micro-Location Sp z o.o.\r
+00FAB6     (base 16)           Kontakt Micro-Location Sp z o.o.\r
+                               Stoczniowcow 3\r
+                               Krakow    30-709\r
+                               PL\r
+\r
+54-C2-50   (hex)               Iskratel d.o.o.\r
+54C250     (base 16)           Iskratel d.o.o.\r
+                               Ljubljanska cesta 24a\r
+                               Kranj    4000\r
+                               SI\r
+\r
+00-0B-3A   (hex)               PESA\r
+000B3A     (base 16)           PESA\r
+                               103 Quality Circle, Suite 210\r
+                               Huntsville  AL  35806\r
+                               US\r
+\r
+5C-E4-2A   (hex)               Intel Corporate\r
+5CE42A     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+18-74-E2   (hex)               IEEE Registration Authority\r
+1874E2     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+F0-C8-14   (hex)               SHENZHEN BILIAN ELECTRONIC CO.,LTD\r
+F0C814     (base 16)           SHENZHEN BILIAN ELECTRONIC CO.,LTD\r
+                               NO.268? Fuqian Rd, Jutang community, Guanlan Town, Longhua New district\r
+                               shenzhen  guangdong  518000\r
+                               CN\r
+\r
+D0-17-69   (hex)               Murata Manufacturing Co., Ltd.\r
+D01769     (base 16)           Murata Manufacturing Co., Ltd.\r
+                               1-10-1, Higashikotari\r
+                               Nagaokakyo-shi  Kyoto  617-8555\r
+                               JP\r
+\r
+CC-3A-DF   (hex)               Neptune Technology Group Inc.\r
+CC3ADF     (base 16)           Neptune Technology Group Inc.\r
+                               1600 AL Highway 229 S\r
+                               Tallassee  AL  36078\r
+                               US\r
+\r
+A8-55-6A   (hex)               3S System Technology Inc.\r
+A8556A     (base 16)           3S System Technology Inc.\r
+                               6F, No. 5, Ln. 16, Sec. 2, Sichuan Rd., Banqiao Dist.,\r
+                               New Taipei City    220620\r
+                               TW\r
+\r
+68-EC-8A   (hex)               Private\r
+68EC8A     (base 16)           Private\r
+\r
 F8-D0-27   (hex)               Seiko Epson Corporation\r
 F8D027     (base 16)           Seiko Epson Corporation\r
                                2070 Kotobuki Koaka\r
@@ -130733,12 +131219,6 @@ A07332     (base 16)         Cashmaster International Limited
                                Palo Alto  CA  94303\r
                                US\r
 \r
-00-0C-04   (hex)               Tecnova\r
-000C04     (base 16)           Tecnova\r
-                               1486 St. Paul Ave.\r
-                               Gurnee  Illinois  60031\r
-                               US\r
-\r
 00-0C-01   (hex)               Abatron AG\r
 000C01     (base 16)           Abatron AG\r
                                Lettenstrasse 9\r
@@ -141785,30 +142265,6 @@ B81332     (base 16)         AMPAK Technology,Inc.
                                Beijing    100053\r
                                CN\r
 \r
-AC-97-6C   (hex)               Greenliant\r
-AC976C     (base 16)           Greenliant\r
-                               3970 Freedom Circle, Suite 100\r
-                               Santa Clara  CA  95054\r
-                               US\r
-\r
-2C-EA-DC   (hex)               ASKEY COMPUTER CORP\r
-2CEADC     (base 16)           ASKEY COMPUTER CORP\r
-                               10F,No.119,JIANKANG RD,ZHONGHE DIST\r
-                               NEW TAIPEI  TAIWAN  23585\r
-                               TW\r
-\r
-38-14-28   (hex)               Dell Inc.\r
-381428     (base 16)           Dell Inc.\r
-                               One Dell Way\r
-                               Round Rock  TX  78682\r
-                               US\r
-\r
-AC-E1-4F   (hex)               Autonomic Controls, Inc.\r
-ACE14F     (base 16)           Autonomic Controls, Inc.\r
-                               28 Kaysal Ct\r
-                               ARMONK  NY  10504\r
-                               US\r
-\r
 44-DB-60   (hex)               Nanjing Baihezhengliu Technology Co., Ltd\r
 44DB60     (base 16)           Nanjing Baihezhengliu Technology Co., Ltd\r
                                Science and technology innovation center, Shiqiu street, Lishui District\r
@@ -141833,6 +142289,168 @@ C478A2     (base 16)                Huawei Device Co., Ltd.
                                Dongguan  Guangdong  523808\r
                                CN\r
 \r
+0C-9A-3C   (hex)               Intel Corporate\r
+0C9A3C     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+DC-21-48   (hex)               Intel Corporate\r
+DC2148     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+74-CF-00   (hex)               Shenzhen SuperElectron Technology Co.,Ltd.\r
+74CF00     (base 16)           Shenzhen SuperElectron Technology Co.,Ltd.\r
+                               1213-1214, haosheng business center, dongbin road, nanshan street, nanshan district, shenzhen city\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+2C-EA-DC   (hex)               ASKEY COMPUTER CORP\r
+2CEADC     (base 16)           ASKEY COMPUTER CORP\r
+                               10F,No.119,JIANKANG RD,ZHONGHE DIST\r
+                               NEW TAIPEI  TAIWAN  23585\r
+                               TW\r
+\r
+AC-E1-4F   (hex)               Autonomic Controls, Inc.\r
+ACE14F     (base 16)           Autonomic Controls, Inc.\r
+                               28 Kaysal Ct\r
+                               ARMONK  NY  10504\r
+                               US\r
+\r
+AC-97-6C   (hex)               Greenliant\r
+AC976C     (base 16)           Greenliant\r
+                               3970 Freedom Circle, Suite 100\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+38-14-28   (hex)               Dell Inc.\r
+381428     (base 16)           Dell Inc.\r
+                               One Dell Way\r
+                               Round Rock  TX  78682\r
+                               US\r
+\r
+98-49-9F   (hex)               Domo Tactical Communications\r
+98499F     (base 16)           Domo Tactical Communications\r
+                               DTC Fusion 2, 1100 Parkway\r
+                               Whiteley  Hampshire  PO15 7AB\r
+                               GB\r
+\r
+C0-23-8D   (hex)               Samsung Electronics Co.,Ltd\r
+C0238D     (base 16)           Samsung Electronics Co.,Ltd\r
+                               129, Samsung-ro, Youngtongl-Gu\r
+                               Suwon  Gyeonggi-Do  16677\r
+                               KR\r
+\r
+28-11-A8   (hex)               Intel Corporate\r
+2811A8     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+20-CF-AE   (hex)               Cisco Systems, Inc\r
+20CFAE     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+C0-FB-F9   (hex)               IEEE Registration Authority\r
+C0FBF9     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+60-9B-B4   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+609BB4     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+7C-27-BC   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+7C27BC     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+74-5D-68   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+745D68     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+EC-08-E5   (hex)               Motorola Mobility LLC, a Lenovo Company\r
+EC08E5     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
+                               222 West Merchandise Mart Plaza\r
+                               Chicago  IL  60654\r
+                               US\r
+\r
+80-CC-9C   (hex)               NETGEAR\r
+80CC9C     (base 16)           NETGEAR\r
+                               350 East Plumeria Drive\r
+                               San Jose  CA  95134\r
+                               US\r
+\r
+0C-60-46   (hex)               vivo Mobile Communication Co., Ltd.\r
+0C6046     (base 16)           vivo Mobile Communication Co., Ltd.\r
+                               #283,BBK Road\r
+                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+                               CN\r
+\r
+C0-F9-B0   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+C0F9B0     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+14-8C-4A   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+148C4A     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+50-70-97   (hex)               China Mobile Group Device Co.,Ltd.\r
+507097     (base 16)           China Mobile Group Device Co.,Ltd.\r
+                               32 Xuanwumen West Street,Xicheng District\r
+                               Beijing    100053\r
+                               CN\r
+\r
+CC-15-31   (hex)               Intel Corporate\r
+CC1531     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+28-0F-EB   (hex)               LG Innotek\r
+280FEB     (base 16)           LG Innotek\r
+                               26, Hanamsandan 5beon-ro\r
+                               Gwangju  Gwangsan-gu  506-731\r
+                               KR\r
+\r
+4C-D5-77   (hex)               CHONGQING FUGUI ELECTRONICS CO.,LTD.\r
+4CD577     (base 16)           CHONGQING FUGUI ELECTRONICS CO.,LTD.\r
+                               Building D21,No.1, East Zone 1st Road,Xiyong Town,Shapingba District\r
+                               Chongqing  Chongqing  401332\r
+                               CN\r
+\r
+74-E2-0C   (hex)               Amazon Technologies Inc.\r
+74E20C     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102 \r
+                               Reno  NV  89507\r
+                               US\r
+\r
+00-0C-04   (hex)               Tecnova\r
+000C04     (base 16)           Tecnova\r
+                               2383 N Delany Rd\r
+                               Waukegan  IL  60087-1836\r
+                               US\r
+\r
+10-54-03   (hex)               INTARSO GmbH\r
+105403     (base 16)           INTARSO GmbH\r
+                               Schuchardstr. 3\r
+                               Düsseldorf  NRW  40595\r
+                               DE\r
+\r
 7C-8A-E1   (hex)               COMPAL INFORMATION (KUNSHAN) CO., LTD. \r
 7C8AE1     (base 16)           COMPAL INFORMATION (KUNSHAN) CO., LTD. \r
                                NO. 25, THE 3RD Street KUNSHAN EXPORT PROCESSING ZONE \r
@@ -157091,12 +157709,6 @@ F40F9B     (base 16)         WAVELINK
                                Middleton  WI  53562\r
                                US\r
 \r
-AC-7A-42   (hex)               iConnectivity\r
-AC7A42     (base 16)           iConnectivity\r
-                               #21, 1725 30th Ave NE\r
-                               Calgary  Alberta  T2E 7P6\r
-                               CA\r
-\r
 70-0B-C0   (hex)               Dewav Technology Company\r
 700BC0     (base 16)           Dewav Technology Company\r
                                Room 1408, Real Estate Mansion\r
@@ -167588,12 +168200,6 @@ EC6C9F     (base 16)         Chengdu Volans Technology CO.,LTD
                                    224-0034\r
                                JP\r
 \r
-00-08-18   (hex)               Pixelworks, Inc.\r
-000818     (base 16)           Pixelworks, Inc.\r
-                               7700 SW Mohawk Street\r
-                               Tualatin  OR  97062\r
-                               US\r
-\r
 00-08-2A   (hex)               Powerwallz Network Security\r
 00082A     (base 16)           Powerwallz Network Security\r
                                120-13160 Vanier Place,\r
@@ -174461,12 +175067,6 @@ CCAB2C     (base 16)         HUMAX Co., Ltd.
                                Takarazuka  Hyogo  665-0051\r
                                JP\r
 \r
-24-E1-24   (hex)                Xiamen Ursalink Technology Co., Ltd.\r
-24E124     (base 16)            Xiamen Ursalink Technology Co., Ltd.\r
-                               4/F, No. 63-2 Wanghai Road, 2nd Software Park\r
-                               Xiamen  Fujian  361008\r
-                               CN\r
-\r
 24-43-E2   (hex)               DASAN Network Solutions\r
 2443E2     (base 16)           DASAN Network Solutions\r
                                DASAN Tower 8F, 49 Daewangpangyo-ro644beon-gil Bundang-gu\r
@@ -177238,3 +177838,162 @@ E8DA00     (base 16)                Kivo Technology, Inc.
                                218 Main Street, Suite #724\r
                                Kirkland    98033\r
                                US\r
+\r
+78-D6-DC   (hex)               Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.\r
+78D6DC     (base 16)           Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.\r
+                               No.19, Gaoxin 4th Road, Wuhan East Lake High-tech Zone, Wuhan\r
+                               Wuhan  Hubei  430000\r
+                               CN\r
+\r
+0C-43-14   (hex)               Silicon Laboratories\r
+0C4314     (base 16)           Silicon Laboratories\r
+                               400 West Cesar Chavez Street\r
+                               Austin  TX  78701\r
+                               US\r
+\r
+F4-C0-2F   (hex)               BlueBite\r
+F4C02F     (base 16)           BlueBite\r
+                               230, Simin-daero\r
+                               Anyang-si  Gyeonggi-do  14067\r
+                               KR\r
+\r
+78-86-B6   (hex)               Shenzhen YOUHUA Technology Co., Ltd\r
+7886B6     (base 16)           Shenzhen YOUHUA Technology Co., Ltd\r
+                               Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District\r
+                               Shenzhen  Guangdong  518055\r
+                               CN\r
+\r
+CC-B5-D1   (hex)               Beijing Xiaomi Mobile Software Co., Ltd\r
+CCB5D1     (base 16)           Beijing Xiaomi Mobile Software Co., Ltd\r
+                               The Rainbow City Office Building, 68 Qinghe Middle Street Haidian District\r
+                               Beijing  Beijing  100085\r
+                               CN\r
+\r
+24-E1-24   (hex)               Xiamen Milesight IoT Co., Ltd.\r
+24E124     (base 16)           Xiamen Milesight IoT Co., Ltd.\r
+                               4/F, No. 63-2 Wanghai Road, 2nd Software Park\r
+                               Xiamen  Fujian  361008\r
+                               CN\r
+\r
+28-FB-AE   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+28FBAE     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+88-A0-BE   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+88A0BE     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+A4-78-06   (hex)               Cisco Systems, Inc\r
+A47806     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+D0-54-75   (hex)               SAVI Controls\r
+D05475     (base 16)           SAVI Controls\r
+                               2420 Tarpley Rd, Suite 205\r
+                               Carrollton  TX  75006\r
+                               US\r
+\r
+08-05-E2   (hex)               Juniper Networks\r
+0805E2     (base 16)           Juniper Networks\r
+                               1133 Innovation Way\r
+                               Sunnyvale  CA  94089\r
+                               US\r
+\r
+B8-D5-6B   (hex)               Mirka Ltd.\r
+B8D56B     (base 16)           Mirka Ltd.\r
+                               Pensalavägen 210\r
+                               Jeppo    66850\r
+                               FI\r
+\r
+B8-A1-4A   (hex)               Raisecom Technology CO.,LTD\r
+B8A14A     (base 16)           Raisecom Technology CO.,LTD\r
+                               No. 11, East Area, No. 10 Block, East Xibeiwang Road\r
+                               Beijing    100094\r
+                               CN\r
+\r
+BC-A3-7F   (hex)               Rail-Mil Sp. z o.o. Sp. K.\r
+BCA37F     (base 16)           Rail-Mil Sp. z o.o. Sp. K.\r
+                               Kosmatki 82\r
+                               Warsaw    03-982\r
+                               PL\r
+\r
+00-08-18   (hex)               Pixelworks, Inc.\r
+000818     (base 16)           Pixelworks, Inc.\r
+                               226 Airport Parkway, Suite 595\r
+                               San Jose  CA  95110\r
+                               US\r
+\r
+94-90-10   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+949010     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+98-F0-83   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+98F083     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+8C-64-A2   (hex)               OnePlus Technology (Shenzhen) Co., Ltd\r
+8C64A2     (base 16)           OnePlus Technology (Shenzhen) Co., Ltd\r
+                               18C02, 18C03, 18C04 ,18C05,TAIRAN BUILDING,\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+28-FA-19   (hex)               Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd\r
+28FA19     (base 16)           Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd\r
+                               3/F,A5 Building Zhiyuan Community No.1001,Xueyuan Road Nanshan District\r
+                               Shenzhen  Guangdong  518055\r
+                               CN\r
+\r
+20-3C-C0   (hex)               Beijing Tosee Technology Co., Ltd.\r
+203CC0     (base 16)           Beijing Tosee Technology Co., Ltd.\r
+                               Room S125, 1st Floor, Building 1, No. 9, Keyuan Road, Economic Development Zone, Daxing District\r
+                               beijing    102600 \r
+                               CN\r
+\r
+D8-A0-11   (hex)               WiZ\r
+D8A011     (base 16)           WiZ\r
+                               Unit 1203-5, 12/F, Tower 1, Enterprise Square, 9 Sheung Yuet Road\r
+                               Kowloon Bay  Hong Kong  0000\r
+                               HK\r
+\r
+50-09-E5   (hex)               Drimsys,Inc\r
+5009E5     (base 16)           Drimsys,Inc\r
+                               147, Baumoe-ro\r
+                               Seocho-gu  Seoul  06752\r
+                               KR\r
+\r
+64-B3-79   (hex)               Private\r
+64B379     (base 16)           Private\r
+\r
+28-DF-EB   (hex)               Intel Corporate\r
+28DFEB     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3  \r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+88-FC-A6   (hex)               devolo AG\r
+88FCA6     (base 16)           devolo AG\r
+                               Charlottenburger Allee 67\r
+                               Aachen  NRW  52068\r
+                               DE\r
+\r
+AC-7A-42   (hex)               iConnectivity\r
+AC7A42     (base 16)           iConnectivity\r
+                               4620 Manilla Road SE, Unit 58\r
+                               Calgary  Alberta  T2G 4B7\r
+                               CA\r
+\r
+48-9E-BD   (hex)               HP Inc.\r
+489EBD     (base 16)           HP Inc.\r
+                               10300 Energy Dr\r
+                               Spring  TX  77389\r
+                               US\r
index f6956650efb5c3e1c3b26f690ffc192f64f1f772..ffc4ae59b837311f39413792d620828f69936e9c 100644 (file)
@@ -4421,12 +4421,42 @@ C8-F5-D6   (hex)                Valeo Interior Controls (Shenzhen) Co.,Ltd
                                Shenzhen  Guangzhong  518103\r
                                CN\r
 \r
+C0-FB-F9   (hex)               Dongmengling\r
+800000-8FFFFF     (base 16)            Dongmengling\r
+                               Floor 1, pool-side building, Villa district, Jiuwei Xiange Musical Instrument Co. , Ltd. , Jiuwei community, Hangcheng Street, Bao 'an district\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+C8-F5-D6   (hex)               Qbic Technology Co., Ltd\r
+200000-2FFFFF     (base 16)            Qbic Technology Co., Ltd\r
+                               26F.-12, No.99, Sec. 1, Xintai 5th Rd., Xizhi Dist.,\r
+                               New Taipei     22175\r
+                               TW\r
+\r
 C8-F5-D6   (hex)               EVOTOR LLC\r
 400000-4FFFFF     (base 16)            EVOTOR LLC\r
                                Timura Frunze Str., 24\r
                                Moscow    119021\r
                                RU\r
 \r
+C0-FB-F9   (hex)               Dongguan Chuan OptoElectronics Limited\r
+200000-2FFFFF     (base 16)            Dongguan Chuan OptoElectronics Limited\r
+                               No.43 Songshui Road,Songmushan Village, Dalang Town\r
+                               Dongguan  Guangdong  523795\r
+                               CN\r
+\r
+C0-FB-F9   (hex)               IVT corporation\r
+600000-6FFFFF     (base 16)            IVT corporation\r
+                               5/F, Zhongguancun Fazhan Building, No 12, Shangdi Xinxi Road, Haidian District, Beijing, 100085, P.R. CHINA\r
+                               Beijing    100085\r
+                               CN\r
+\r
+18-74-E2   (hex)               HANGZHOU ZHOUJU ELECTRONIC TECHNOLOGICAL CO.,LTD \r
+500000-5FFFFF     (base 16)            HANGZHOU ZHOUJU ELECTRONIC TECHNOLOGICAL CO.,LTD \r
+                               Floor 6,A Building, Xianxing Road NO.32,Xianlin Town,Yuhang District\r
+                               Hangzhou  Zhejiang  311122\r
+                               CN\r
+\r
 4C-4B-F9   (hex)               Shenzhen dingsheng technology co., LTD\r
 400000-4FFFFF     (base 16)            Shenzhen dingsheng technology co., LTD\r
                                Floor 3, building 5, kaijeda industrial zone, no.97, huaxing road, langkou community, dalang street, longhua district\r
@@ -8507,6 +8537,60 @@ C8-F5-D6   (hex)         Pinmicro K K
                                Chiyoda Ku  Tokyo  1010051\r
                                JP\r
 \r
+D0-9F-D9   (hex)               Shenzhen eloT Technology Co.,Ltd\r
+D00000-DFFFFF     (base 16)            Shenzhen eloT Technology Co.,Ltd\r
+                               North Wing of 2/F, Block 2, Viseen Technology & Business Park, No.43 Gaoxin South Ring Road\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+C0-FB-F9   (hex)               Tiandi(Changzhou) Automation Co., Ltd.\r
+A00000-AFFFFF     (base 16)            Tiandi(Changzhou) Automation Co., Ltd.\r
+                               Tiandi(Changzhou) Automation Co., Ltd.\r
+                               Changzhou  Jiangsu  213015\r
+                               CN\r
+\r
+C0-FB-F9   (hex)               Navitas Digital Safety Ltd\r
+E00000-EFFFFF     (base 16)            Navitas Digital Safety Ltd\r
+                               1ST FLOOR, 13  PHOENIX PARK \r
+                               COALVILLE  Leicestershire  LE673HB\r
+                               GB\r
+\r
+D0-9F-D9   (hex)               Poten (Shanghai) Technology Co.,Ltd.\r
+400000-4FFFFF     (base 16)            Poten (Shanghai) Technology Co.,Ltd.\r
+                               Rm.B,6th Fl., No.5, Caoxi Rd.251\r
+                               Shanghai  Shanghai  200235\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Raymax Technology Ltd.\r
+700000-7FFFFF     (base 16)            Raymax Technology Ltd.\r
+                               604, Building D, No.1001 Wen Yi Xi Road\r
+                               Hangzhou  China  310012\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Queclink Wireless Solutions Co., Ltd.\r
+800000-8FFFFF     (base 16)            Queclink Wireless Solutions Co., Ltd.\r
+                               No.30, Lane 500, Xinlong Road, Minhang District\r
+                               Shanghai    201101\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Fujian Newland Auto-ID Tech. Co,.Ltd.\r
+C00000-CFFFFF     (base 16)            Fujian Newland Auto-ID Tech. Co,.Ltd.\r
+                               Newland Science & Technology Park, No.1 Rujiang West Rd,Mawei,Fuzhou, P.R.China\r
+                               Fuzhou    350015\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Lemei Intelligent IOT (Shenzhen) Co., Ltd\r
+000000-0FFFFF     (base 16)            Lemei Intelligent IOT (Shenzhen) Co., Ltd\r
+                               #1101, Building #1, Yishang Sanwei Inductry Park, Zhongwu, Hangcheng Street, Baoan District\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+18-74-E2   (hex)               Kano Computing Limited\r
+800000-8FFFFF     (base 16)            Kano Computing Limited\r
+                               Unit 12.1 - 12.2, 11-29 Fashion Street\r
+                               London    E1 6PX\r
+                               GB\r
+\r
 20-85-93   (hex)               UNILUMIN GROUP CO.,LTD\r
 300000-3FFFFF     (base 16)            UNILUMIN GROUP CO.,LTD\r
                                No.112 Yongfu Rd.,BaoanDistrict,\r
@@ -12170,12 +12254,6 @@ D0-14-11   (hex)               Video Security, Inc.
                                Kaohsiung, Taiwan, R.O.C.  Kaohsiung City  807\r
                                TW\r
 \r
-30-49-50   (hex)               Xio Research, Inc\r
-D00000-DFFFFF     (base 16)            Xio Research, Inc\r
-                               405 Lexington Avenue, Suite 3504\r
-                               New York  NY  10174\r
-                               US\r
-\r
 D0-14-11   (hex)               Realwave Inc.\r
 700000-7FFFFF     (base 16)            Realwave Inc.\r
                                5857 Owens Avenue, Suite 300\r
@@ -12764,6 +12842,60 @@ D00000-DFFFFF     (base 16)            Volansys technologies pvt ltd
                                Ahmedabad  Gujarat  380015\r
                                IN\r
 \r
+C0-FB-F9   (hex)               HAGUENET\r
+500000-5FFFFF     (base 16)            HAGUENET\r
+                                Nieuwe Parklaan 17\r
+                               The Hague    2597 LA\r
+                               NL\r
+\r
+C0-FB-F9   (hex)               LIXIL Corporation\r
+100000-1FFFFF     (base 16)            LIXIL Corporation\r
+                               2-1-1 Ojima, Koto-ku\r
+                               Tokyo  Select Stat  136-8535\r
+                               JP\r
+\r
+C0-FB-F9   (hex)               SHENZHEN COMIX HST CLOUD COMPUTING CO., LTD.\r
+B00000-BFFFFF     (base 16)            SHENZHEN COMIX HST CLOUD COMPUTING CO., LTD.\r
+                               1408? Qiancheng Commercial Center, No. 5 Haicheng Road, Mabu Community, Xixiang Sub-district, Bao'an District\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+C0-FB-F9   (hex)               SHENZHEN HEQIANG ELECTRONICS LIMITED\r
+300000-3FFFFF     (base 16)            SHENZHEN HEQIANG ELECTRONICS LIMITED\r
+                               ROOM F7, 6TH FLOOR, A1 BUILDING, RED BOX LOFT, NO. 3 SOUTH HUANCHENG ROAD, LONGGANG DISTRICT,\r
+                               SHENZHEN  GUANGDONG  518129\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Carbon Mobile GmbH\r
+500000-5FFFFF     (base 16)            Carbon Mobile GmbH\r
+                               Winterfeldtstr. 21\r
+                               Berlin    10781\r
+                               DE\r
+\r
+D0-9F-D9   (hex)               ENTTEC Pty Ltd.\r
+900000-9FFFFF     (base 16)            ENTTEC Pty Ltd.\r
+                               po box 4051\r
+                               ringwood  vic  3134\r
+                               AU\r
+\r
+D0-9F-D9   (hex)               elecgator bvba\r
+100000-1FFFFF     (base 16)            elecgator bvba\r
+                               Heerbaan, 308\r
+                               Beringen  Limburg  3582\r
+                               BE\r
+\r
+D0-9F-D9   (hex)               Minibems Ltd\r
+E00000-EFFFFF     (base 16)            Minibems Ltd\r
+                               Oxford Point, 19 Oxford Road\r
+                               Bournemouth    BH88GS\r
+                               GB\r
+\r
+30-49-50   (hex)               Merlyn Mind, Inc.\r
+D00000-DFFFFF     (base 16)            Merlyn Mind, Inc.\r
+                               405 Lexington Avenue, Suite 3504\r
+                               New York  NY  10174\r
+                               US\r
+\r
 4C-4B-F9   (hex)               Shandong Linkotech Electronic Co., Ltd.\r
 600000-6FFFFF     (base 16)            Shandong Linkotech Electronic Co., Ltd.\r
                                22nd Floor, Building 2, Aosheng Building, No.1166 Xinyi Street, High-tech Zone\r
@@ -13325,12 +13457,6 @@ D00000-DFFFFF     (base 16)            Elink Technology (Shenzhen) Co., Limited
                                Shenzhen  Guangdong  518101\r
                                CN\r
 \r
-E0-5A-9F   (hex)               Fujian Newland Auto-ID Tech. Co.,Ltd.\r
-800000-8FFFFF     (base 16)            Fujian Newland Auto-ID Tech. Co.,Ltd.\r
-                               Newland Science & Technology Park, No.1 Rujiang West Rd,Mawei,Fuzhou, P.R.China\r
-                               Fuzhou  Fujian  350015\r
-                               CN\r
-\r
 4C-BC-98   (hex)               Charge-Amps AB\r
 000000-0FFFFF     (base 16)            Charge-Amps AB\r
                                GUSTAV III:S BOULEVARD 42, 8TR\r
@@ -16946,12 +17072,72 @@ D00000-DFFFFF     (base 16)           Origins Technology Limited
                                Beijing    100027\r
                                CN\r
 \r
+C8-F5-D6   (hex)               Shanghai Mo xiang Network Technology CO.,Ltd\r
+900000-9FFFFF     (base 16)            Shanghai Mo xiang Network Technology CO.,Ltd\r
+                               Room#418-421, ShaHeXiLi, 2-2 XiLi North Road, LiCheng Community, Xili Street, NanShan District\r
+                               Shenzhen  Guangdong  518071\r
+                               CN\r
+\r
 C8-F5-D6   (hex)               United Barcode Systems\r
 B00000-BFFFFF     (base 16)            United Barcode Systems\r
                                Av. Progres 56, Pol. Ind. els Garrofers\r
                                Vilassar de Mar  Barcelona  08340\r
                                ES\r
 \r
+C8-F5-D6   (hex)               Eltako GmbH\r
+C00000-CFFFFF     (base 16)            Eltako GmbH\r
+                               Hofener Straße 54\r
+                               Fellbach  BW  70736\r
+                               DE\r
+\r
+C0-FB-F9   (hex)               SHENZHEN ELSKY TECHNOLOGY CO., LTD\r
+C00000-CFFFFF     (base 16)            SHENZHEN ELSKY TECHNOLOGY CO., LTD\r
+                               1F BUILDING 2# ASIA INDUSTIAL PARK BANTIAN STREET LONGGANG DISTRICT \r
+                               SHENZHEN  GUANGDONG  518000\r
+                               CN\r
+\r
+C0-FB-F9   (hex)               Dropbeats Technology Co., Ltd.\r
+D00000-DFFFFF     (base 16)            Dropbeats Technology Co., Ltd.\r
+                               Room 304, Building 4?Juli Road ? Pudong New District\r
+                               Shanghai  Shanghai  201203\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Elevoc Technology Co., Ltd.\r
+600000-6FFFFF     (base 16)            Elevoc Technology Co., Ltd.\r
+                               5/F,Unit B,Block12,ShenZhenwan Science and Technology Ecological Garden,Nanshan Dist.\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Eurolan Ltd\r
+A00000-AFFFFF     (base 16)            Eurolan Ltd\r
+                               jk. Drujba 1, ul. 5028, do bl. 15\r
+                               Sofia  Sofia (stolitsa)  1592\r
+                               BG\r
+\r
+E0-5A-9F   (hex)               Fujian Newland Auto-ID Tech. Co,.Ltd.\r
+800000-8FFFFF     (base 16)            Fujian Newland Auto-ID Tech. Co,.Ltd.\r
+                               Newland Science & Technology Park, No.1 Rujiang West Rd,Mawei,Fuzhou, P.R.China\r
+                               Fuzhou  Fujian  350015\r
+                               CN\r
+\r
+18-74-E2   (hex)               NextGen RF Design, Inc.\r
+C00000-CFFFFF     (base 16)            NextGen RF Design, Inc.\r
+                               2130 Howard Dr W\r
+                               North Mankato  MN  56003\r
+                               US\r
+\r
+18-74-E2   (hex)               Sartorius Lab Instruments GmbH & Co. KG\r
+100000-1FFFFF     (base 16)            Sartorius Lab Instruments GmbH & Co. KG\r
+                               Otto-Brenner-Straße 20\r
+                               Goettingen    37079\r
+                               DE\r
+\r
+D0-9F-D9   (hex)               Sanken-Densetsu Co.,LTD.\r
+300000-3FFFFF     (base 16)            Sanken-Densetsu Co.,LTD.\r
+                               677 Shimoakasaka-Ohnohara\r
+                               Kawagoe-Shi  Saitama  350-1155\r
+                               JP\r
+\r
 20-85-93   (hex)               Great Lite International\r
 700000-7FFFFF     (base 16)            Great Lite International\r
                                11F., No.207-2, Sec. 3, Beixin Rd., Xindian Dist.,\r
@@ -21257,8 +21443,62 @@ C8-F5-D6   (hex)               MEIRYO TECHNICA CORPORATION
                                Owariasahi-city  Aichi  488-0052\r
                                JP\r
 \r
+C0-FB-F9   (hex)               Minato Advanced Technologies inc\r
+400000-4FFFFF     (base 16)            Minato Advanced Technologies inc\r
+                               4105, Minami Yamata-cho, Tsuzuki-ku,\r
+                               YOKOHAMA  Kanagawa  224-0026\r
+                               JP\r
+\r
+C0-FB-F9   (hex)                LongSung Technology (Shanghai) Co.,Ltd.   \r
+700000-7FFFFF     (base 16)             LongSung Technology (Shanghai) Co.,Ltd.   \r
+                                Room 606, Block B, Bldg. 1, No. 3000 Longdong Avenue., Zhangjiang Hi-Tech Park, Pudong District\r
+                               ShangHai    201203\r
+                               CN\r
+\r
+C8-F5-D6   (hex)               HEITEC AG\r
+E00000-EFFFFF     (base 16)            HEITEC AG\r
+                               Güterbahnhofstrasse 5\r
+                               Erlangen  Please select state  91052\r
+                               DE\r
+\r
+C8-F5-D6   (hex)               BBPOS International Limited\r
+300000-3FFFFF     (base 16)            BBPOS International Limited\r
+                               Suite 1602, Tower 2, Nina Tower, 8 Yeung Uk Road, Tsuen Wan, NT\r
+                               Hong Kong  China  00000\r
+                               HK\r
+\r
 88-C9-B3   (hex)               Fortive Setra-ICG(Tianjin)Co.,Ltd\r
 300000-3FFFFF     (base 16)            Fortive Setra-ICG(Tianjin)Co.,Ltd\r
                                28 weiwu Road,Micro-electronics Industrial Park,Xiqing District Tianjin,P,R,China\r
                                Tianjin    300380\r
                                CN\r
+\r
+C0-FB-F9   (hex)               Xerox Corporation\r
+000000-0FFFFF     (base 16)            Xerox Corporation\r
+                               800 Phillips Rd, Mailstop 0207-2Z\r
+                               Webster  NY  14580\r
+                               US\r
+\r
+C0-FB-F9   (hex)               zxsolution\r
+900000-9FFFFF     (base 16)            zxsolution\r
+                               nanshan shenzhen\r
+                               shenzhen    518000\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Westar Display Technologies\r
+200000-2FFFFF     (base 16)            Westar Display Technologies\r
+                               4 Research Park Dr\r
+                               St Charles  MO  63304\r
+                               US\r
+\r
+18-74-E2   (hex)               Sansec Technology Co.,Ltd\r
+700000-7FFFFF     (base 16)            Sansec Technology Co.,Ltd\r
+                               Bejing Chaoyang District Guangshun North Street Hostpital No.16 No.2 building 14 room 1406\r
+                               Bejing   Bejing   100102\r
+                               CN\r
+\r
+D0-9F-D9   (hex)               Cablewireless Laboratory Co., Ltd\r
+B00000-BFFFFF     (base 16)            Cablewireless Laboratory Co., Ltd\r
+                               Room 218,  Block E1, Yuanchenxin Building, 12 Yumin Road, Chaoyang District\r
+                               Beijing    100029\r
+                               CN\r
index d76aafcceb2b40e5e37f7eb46d841d288ebe1062..b987a916deee771756afbc0f7655bfff83e2f5ec 100644 (file)
@@ -4967,12 +4967,6 @@ B70000-B70FFF     (base 16)              Torion Plasma Corporation
                                Ellicott City  MD  21043\r
                                US\r
 \r
-70-B3-D5   (hex)               Horizon Co., Ltd\r
-69B000-69BFFF     (base 16)            Horizon Co., Ltd\r
-                               1600 Aza-Shironoshita Asahi\r
-                               Shin Asahi-cho  Takashima, Shiga  520-1501\r
-                               JP\r
-\r
 70-B3-D5   (hex)               Smart Systems LLC\r
 746000-746FFF     (base 16)            Smart Systems LLC\r
                                Flat 1, building 7, Izmalkova street\r
@@ -5105,6 +5099,54 @@ EC0000-EC0FFF     (base 16)              ProtoConvert Pty Ltd
                                Hayward  CA  94545\r
                                US\r
 \r
+70-B3-D5   (hex)               Zumbach Electronic AG\r
+C19000-C19FFF     (base 16)            Zumbach Electronic AG\r
+                               Hauptstrasse 93\r
+                               Orpund  Bern  2552\r
+                               CH\r
+\r
+70-B3-D5   (hex)               Lobaro GmbH\r
+E05000-E05FFF     (base 16)            Lobaro GmbH\r
+                               Stadtdeich 7\r
+                               Hamburg      20097\r
+                               DE\r
+\r
+70-B3-D5   (hex)               LDA Audiotech\r
+685000-685FFF     (base 16)            LDA Audiotech\r
+                               C/Severo Ochoa, 31\r
+                               Malaga  Malaga  29590\r
+                               ES\r
+\r
+70-B3-D5   (hex)               HORIZON.INC\r
+69B000-69BFFF     (base 16)            HORIZON.INC\r
+                               1600 Aza-Shironoshita Asahi\r
+                               Shin Asahi-cho  Takashima, Shiga  520-1501\r
+                               JP\r
+\r
+70-B3-D5   (hex)               aelettronica group srl\r
+A14000-A14FFF     (base 16)            aelettronica group srl\r
+                               via matteotti,22\r
+                               gaggiano  milano  20083\r
+                               IT\r
+\r
+70-B3-D5   (hex)               MedRx, Inc\r
+3B6000-3B6FFF     (base 16)            MedRx, Inc\r
+                               1200 Starkey Rd Ste.105\r
+                               Largo  FL  33771\r
+                               US\r
+\r
+70-B3-D5   (hex)               ZIEHL-ABEGG SE\r
+698000-698FFF     (base 16)            ZIEHL-ABEGG SE\r
+                               Heinz-Ziehl-Strasse 1\r
+                               Kuenzelsau    74653\r
+                               DE\r
+\r
+70-B3-D5   (hex)               Vema Venturi AB\r
+036000-036FFF     (base 16)            Vema Venturi AB\r
+                               Johan på gårdas gata 5A\r
+                               Gothenburg  Västra Götaland  41250\r
+                               SE\r
+\r
 70-B3-D5   (hex)               EVCO SPA\r
 A80000-A80FFF     (base 16)            EVCO SPA\r
                                VIA FELTRE N. 81\r
@@ -10175,6 +10217,36 @@ F74000-F74FFF     (base 16)            TESSA AGRITECH SRL
                                Trento  Trento  38123\r
                                IT\r
 \r
+70-B3-D5   (hex)               CAR-connect GmbH\r
+81F000-81FFFF     (base 16)            CAR-connect GmbH\r
+                               Am Egelingsberg 8\r
+                               Leiferde  Niedersachsen  38542\r
+                               DE\r
+\r
+70-B3-D5   (hex)               MBJ\r
+E03000-E03FFF     (base 16)            MBJ\r
+                               Jochim-Klindt-Straße 7\r
+                               Ahrensburg  Schleswig Holstein  22926\r
+                               DE\r
+\r
+70-B3-D5   (hex)               Code Blue Corporation \r
+271000-271FFF     (base 16)            Code Blue Corporation \r
+                               259 Hedcor Street\r
+                               Holland  MI  49423\r
+                               US\r
+\r
+70-B3-D5   (hex)               Fischer Connectors\r
+BF7000-BF7FFF     (base 16)            Fischer Connectors\r
+                               11 Waterberry drive\r
+                               Waterlooville  Hampshire  PO7 7YH\r
+                               GB\r
+\r
+70-B3-D5   (hex)               VK Integrated Systems\r
+A8F000-A8FFFF     (base 16)            VK Integrated Systems\r
+                               810 Crossland Ave\r
+                               Clarksville  TN  37040\r
+                               US\r
+\r
 70-B3-D5   (hex)               System West dba ICS Electronics\r
 E06000-E06FFF     (base 16)            System West dba ICS Electronics\r
                                7034 Commerce Circle Suite A\r
@@ -15176,6 +15248,42 @@ ED6000-ED6FFF     (base 16)            Metrasens Limited
                                Shenzhen City  Guangdong  518129\r
                                CN\r
 \r
+70-B3-D5   (hex)               DesignA Electronics Limited\r
+A63000-A63FFF     (base 16)            DesignA Electronics Limited\r
+                               Unit 6\r
+                               Christchurch  New Zealand  8011\r
+                               NZ\r
+\r
+70-B3-D5   (hex)               Grayshift\r
+71F000-71FFFF     (base 16)            Grayshift\r
+                               931 Monroe Dr NE, Suite A102-340\r
+                               Atlanta  GA  30308\r
+                               US\r
+\r
+70-B3-D5   (hex)               dongsheng\r
+AFD000-AFDFFF     (base 16)            dongsheng\r
+                               No. 2, Sec. 2, Beiyi Rd., Xindian Dist.,\r
+                               New Taipei City    231067\r
+                               TW\r
+\r
+70-B3-D5   (hex)               Exemplar Medical, LLC\r
+318000-318FFF     (base 16)            Exemplar Medical, LLC\r
+                               4521 Wornall Road, #106\r
+                               Kansas City  MO  64111\r
+                               US\r
+\r
+70-B3-D5   (hex)               HLT Micro \r
+2B6000-2B6FFF     (base 16)            HLT Micro \r
+                               Bld 6, 4th Park, Xitian, GM Distinct\r
+                               shenzhen    511088\r
+                               CN\r
+\r
+70-B3-D5   (hex)               Cucos Retail Systems GmbH\r
+4CB000-4CBFFF     (base 16)            Cucos Retail Systems GmbH\r
+                               Detmolder Straße 7\r
+                               Soest    59494\r
+                               DE\r
+\r
 70-B3-D5   (hex)               YUYAMA MFG Co.,Ltd\r
 BBB000-BBBFFF     (base 16)            YUYAMA MFG Co.,Ltd\r
                                3-3-1\r
@@ -20369,6 +20477,51 @@ B33000-B33FFF     (base 16)            Aplex Technology Inc.
                                Shenzhen City  Guangdong  518129\r
                                CN\r
 \r
+70-B3-D5   (hex)               FARHO DOMOTICA SL\r
+ACE000-ACEFFF     (base 16)            FARHO DOMOTICA SL\r
+                               POLIGONO DE TABAZA II, NAVES 9-13\r
+                               TABAZA  ASTURIAS  33439\r
+                               ES\r
+\r
+70-B3-D5   (hex)               The Engineerix Group\r
+C71000-C71FFF     (base 16)            The Engineerix Group\r
+                               1418 Beech Ave 119A\r
+                               McAllen  TX  78501\r
+                               US\r
+\r
+70-B3-D5   (hex)               Flextronics International Kft\r
+1BC000-1BCFFF     (base 16)            Flextronics International Kft\r
+                               38. Zrinyi Str.\r
+                               Zalaegerszeg  Zala  8900\r
+                               HU\r
+\r
+70-B3-D5   (hex)               Research Laboratory of Design Automation, Ltd.\r
+223000-223FFF     (base 16)            Research Laboratory of Design Automation, Ltd.\r
+                               8 Birzhevoy Spusk\r
+                               Taganrog    347900\r
+                               RU\r
+\r
+70-B3-D5   (hex)               Private\r
+315000-315FFF     (base 16)            Private\r
+\r
+70-B3-D5   (hex)               JOLANYEE  Technology Co., Ltd.\r
+9D8000-9D8FFF     (base 16)            JOLANYEE  Technology Co., Ltd.\r
+                               2F., No. 13, Sec. 1, Yonghe Rd.\r
+                               Yonghe Dist., New Taipei City    234014\r
+                               TW\r
+\r
+70-B3-D5   (hex)               SEASONS 4 INC\r
+D5D000-D5DFFF     (base 16)            SEASONS 4 INC\r
+                               3601 LA GRANGE PKWY, SUITE 500\r
+                               TOANO  VA  23168\r
+                               US\r
+\r
+70-B3-D5   (hex)               VulcanForms\r
+E0E000-E0EFFF     (base 16)            VulcanForms\r
+                               20 North Ave.\r
+                               Burlington  MA  01803\r
+                               US\r
+\r
 70-B3-D5   (hex)               DISMUNTEL SAL\r
 92C000-92CFFF     (base 16)            DISMUNTEL SAL\r
                                Pol ind cotes\r
@@ -25319,12 +25472,6 @@ DEF000-DEFFFF     (base 16)            ISG Nordic AB
                                Seattle  WA  98104\r
                                US\r
 \r
-70-B3-D5   (hex)               PARAGON ID\r
-036000-036FFF     (base 16)            PARAGON ID\r
-                               Les Aubépins\r
-                               ARGENT SUR SAULDRE  CHER  18410\r
-                               FR\r
-\r
 70-B3-D5   (hex)               Deep Secure Limited\r
 DD0000-DD0FFF     (base 16)            Deep Secure Limited\r
                                1 Nimrod House, Sandys Road\r
@@ -25361,8 +25508,50 @@ EAA000-EAAFFF     (base 16)            Druck Ltd.
                                Neuilly sur Marne  Ile-de-France  93330\r
                                FR\r
 \r
+70-B3-D5   (hex)               Codewerk GmbH\r
+4D0000-4D0FFF     (base 16)            Codewerk GmbH\r
+                               Siemensallee 75\r
+                               Karlsruhe    76187 \r
+                               DE\r
+\r
+70-B3-D5   (hex)               Orlaco Products B.V.\r
+333000-333FFF     (base 16)            Orlaco Products B.V.\r
+                               Albert Plesmanstraat 42\r
+                               Barneveld    3772MN\r
+                               NL\r
+\r
 70-B3-D5   (hex)               ScopeSensor Oy\r
 DF7000-DF7FFF     (base 16)            ScopeSensor Oy\r
                                Teollisuustie 1\r
                                Haukipudas    90830\r
                                FI\r
+\r
+70-B3-D5   (hex)               KBPR LLC\r
+11E000-11EFFF     (base 16)            KBPR LLC\r
+                               Raketny bulvar street 16\r
+                               Moscow  Select State  129164\r
+                               RU\r
+\r
+70-B3-D5   (hex)               Anello Photonics\r
+96A000-96AFFF     (base 16)            Anello Photonics\r
+                               3964 Rivermark Plaza, Suite 144\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+70-B3-D5   (hex)               HORIZON.INC\r
+F40000-F40FFF     (base 16)            HORIZON.INC\r
+                               1600 Aza-Shironoshita Asahi\r
+                               Shin Asahi-cho  Takashima, Shiga  520-1501\r
+                               JP\r
+\r
+70-B3-D5   (hex)               SUS Corporation\r
+1ED000-1EDFFF     (base 16)            SUS Corporation\r
+                               6F, S-patio Bldg. 14-25 Minami-cho, Suruga-ku,\r
+                               Shizuoka city,  Shizuoka  422-8067\r
+                               JP\r
+\r
+70-B3-D5   (hex)               Lumiplan Duhamel\r
+A0C000-A0CFFF     (base 16)            Lumiplan Duhamel\r
+                               2 rue de l'industrie\r
+                               Domène  Isère  38420\r
+                               FR\r
index 54c6f4d5e2def43cae06b6fda8a4cbdafb84a75c..7221a1ae9f64bf0b5eba5df3a6f7e8ba174757bb 100644 (file)
@@ -4,6 +4,7 @@
 # they are very long but quite repetitive and the parser is not very fast.
 # So we don't "test" them.
 hwdb_files_notest = files('''
+        README
         20-dmi-id.hwdb
         20-pci-vendor-model.hwdb
         20-pci-classes.hwdb
index 346a0b9af8626f0d3719ddb8defd129deb2d0c3c..604fba5eb938f38932d7980913cc8040559beb07 100644 (file)
@@ -1,8 +1,8 @@
 #
 #      List of PCI ID's
 #
-#      Version: 2021.03.06
-#      Date:    2021-03-06 03:15:02
+#      Version: 2021.03.22
+#      Date:    2021-03-22 03:15:01
 #
 #      Maintained by Albert Pool, Martin Mares, and other volunteers from
 #      the PCI ID Project at https://pci-ids.ucw.cz/.
                1d49 060e  ThinkSystem RAID 940-32i 8GB Flash PCIe Gen4 12Gb Adapter
                1d49 060f  ThinkSystem RAID 940-8e 4GB Flash PCIe Gen4 12Gb Adapter
        10e2  MegaRAID 12GSAS/PCIe Secure SAS39xx
+# 9560 16 internal port RAID controller
+               1000 4000  MegaRAID 9560-16i
+# 9560 8 internal port RAID controller
+               1000 4010  MegaRAID 9560-8i
+# 9580 8 internal & 8 external port RAID controller
+               1000 4020  MegaRAID 9580-8i8e
+# MegaRAID 9562-16i 9562 16 internal port RAID controller
+               1000 40b0  MegaRAID 9562-16i
                1028 1ae0  PERC H755 Adapter
                1028 1ae1  PERC H755 Front
                1028 1ae2  PERC H755N Front
        1561  Anubis
        15d8  Picasso
                103c 8615  Pavilion Laptop 15-cw1xxx
+               17aa 3181  ThinkCentre M75n IoT
                17aa 5124  ThinkPad E595
                ea50 cc10  RXi2-BP
        15dd  Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series]
        5e6d  RV410 [Radeon X700] (Secondary)
                148c 2117  Bravo X700 (Secondary)
        5f57  R423 [Radeon X800 XT]
-       6600  Mars [Radeon HD 8670A/8670M/8750M]
+       6600  Mars [Radeon HD 8670A/8670M/8750M / R7 M370]
                103c 1952  ProBook 455 G1
        6601  Mars [Radeon HD 8730M]
                103c 2100  FirePro M4100
                174b 7670  Radeon HD 7670
                174b e181  Radeon HD 6670
                1787 2309  Radeon HD 6670
-       6759  Turks PRO [Radeon HD 6570/7570/8550]
+       6759  Turks PRO [Radeon HD 6570/7570/8550 / R5 230]
                103c 3130  Radeon HD 6570
                1043 0403  Radeon HD 6570
                1462 2500  Radeon HD 6570
                1642 3a67  Radeon HD 6570
                1682 3280  Radeon HD 7570
                1682 3530  Radeon HD 8550
+               1682 5230  Radeon R5 230 series
+               1682 6450  Radeon HD 6450 series
                174b 7570  Radeon HD 7570
+               174b 8550  Radeon HD8550 OEM
+               174b 8570  Radeon HD8550 OEM
                174b e142  Radeon HD 6570
                174b e181  Radeon HD 6570
+               1787 a230  Radeon R5 230 series
+               1787 a450  Radeon HD 6450 series
                1b0a 908f  Radeon HD 6570
                1b0a 9090  Radeon HD 6570
                1b0a 9091  Radeon HD 6570
                174b e329  Radeon R9 FURY
        7310  Navi 10 [Radeon Pro W5700X]
        7312  Navi 10 [Radeon Pro W5700]
+       7314  Navi 10 USB
        731f  Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT]
                1458 2313  Radeon RX 5700 XT Gaming OC
                1682 5701  RX 5700 XT RAW II
        7388  Arcturus GL-XL
        738c  Arcturus GL-XL [AMD Instinct MI100]
        738e  Arcturus GL-XL
+       73a4  Navi 21 USB
+       73af  Navi 21 [Radeon RX 6900 XT]
        73bf  Navi 21 [Radeon RX 6800/6800 XT / 6900 XT]
                1eae 6701  XFX Speedster MERC 319 AMD Radeon RX 6800 XT Black
        73c3  Navi 22
-       73df  Navi 22 [Radeon RX 6700/6700 XT]
+       73c4  Navi 22 USB
+       73df  Navi 22 [Radeon RX 6700/6700 XT / 6800M]
        73e0  Navi 23
+       73e1  Navi 23
+       73e4  Navi 23 USB
        73ff  Navi 23 [Radeon RX 6600/6600 XT]
        7833  RS350 Host Bridge
        7834  RS350 [Radeon 9100 PRO/XT IGP]
        0003  Control Video
        0004  PlanB Video-In
        0007  O'Hare I/O
+       000b  Apple Camera
        000c  DOS on Mac
        000e  Hydra Mac I/O
        0010  Heathrow Mac I/O
        21c2  TU116
        21c4  TU116 [GeForce GTX 1660 SUPER]
        21d1  TU116BM [GeForce GTX 1660 Ti Mobile]
+       2200  GA102
        2204  GA102 [GeForce RTX 3090]
-       2205  GA102 [GeForce RTX 3080 Ti]
+       2205  GA102 [GeForce RTX 3080 20GB]
        2206  GA102 [GeForce RTX 3080]
                10de 1467  GA102 [GeForce RTX 3080]
                10de 146d  GA102 [GeForce RTX 3080 20GB]
        222b  GA102 [GeForce RTX 3090 Engineering Sample]
        222f  GA102 [GeForce RTX 3080 11GB / 12GB Engineering Sample]
        2230  GA102GL [RTX A6000]
+       2231  GA102GL
        2235  GA102GL [RTX A40]
        2236  GA102GL
+       2237  GA102GL
        223f  GA102GL
        228b  GA104 High Definition Audio Controller
+       2302  GA103
        2321  GA103
        2482  GA104 [GeForce RTX 3070 Ti]
        2484  GA104 [GeForce RTX 3070]
        0002  Dual PCI to RapidIO Bridge
        000b  POET Serial RapidIO Bridge
        000d  POET PSDMS Device
-1135  Fuji Xerox Co Ltd
+1135  FUJIFILM Business Innovation Corp.
        0001  Printer controller
 1136  Momentum Data Systems
        0002  PCI-JTAG
 1414  Microsoft Corporation
        0001  MN-120 (ADMtek Centaur-C based)
        0002  MN-130 (ADMtek Centaur-P based)
+# Virtual Video Card Device for Windows Remote Desktop (RDP)
+       008c  Basic Render Driver
        5353  Hyper-V virtual VGA
        5801  XMA Decoder (Xenon)
        5802  SATA Controller - CdRom (Xenon)
                103c 0890  NC6000 laptop
                103c 099c  NX6110/NC6120
                10cf 1279  LifeBook E8010D
-       165f  NetXtreme BCM5720 2-port Gigabit Ethernet PCIe
+       165f  NetXtreme BCM5720 Gigabit Ethernet PCIe
                1028 04f7  PowerEdge R320 server
                1028 08fd  PowerEdge R6515/R7515 LOM
                1028 08ff  PowerEdge Rx5xx LOM Board
        16d4  BCM57402 NetXtreme-E Ethernet Partition
        16d5  BCM57407 NetXtreme-E 10GBase-T Ethernet Controller
        16d6  BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller
+               14e4 1202  BCM957412M4122C OCP 1x25G Type1 wRoCE
                14e4 4120  NetXtreme E-Series Advanced Dual-port 10Gb SFP+ Ethernet Network Daughter Card
                14e4 4126  NetXtreme-E Dual-port 10G SFP+ Ethernet OCP 3.0 Adapter (BCM957412N4120C)
                152d 8b20  BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller
                152d 8b22  BCM57412 NetXtreme-E 25Gb RDMA Ethernet Controller
        16d7  BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller
-               14e4 1202  BCM957412M4122C OCP 1x25G Type1 wRoCE
                14e4 1402  BCM957414A4142CC 10Gb/25Gb Ethernet PCIe
                14e4 1404  BCM957414M4142C OCP 2x25G Type1 wRoCE
                14e4 4140  NetXtreme E-Series Advanced Dual-port 25Gb SFP28 Network Daughter Card
        9260  RCIM-II Real-Time Clock & Interrupt Module
        9271  RCIM-III Real-Time Clock & Interrupt Module (PCIe)
        9272  Pulse Width Modulator Card
+       9273  RCIM-IV Real-Time Clock & Interrupt Module (PCIe)
        9277  5 Volt Delta Sigma Converter Card
        9278  10 Volt Delta Sigma Converter Card
        9287  Analog Output Card
                15b3 0021  MCX4421A-ACQN ConnectX-4 Lx EN OCP,2x25G
                15b3 0025  ConnectX-4 Lx 25 GbE Dual Port SFP28 rNDC
                193d 100a  620F-B
+# NIC-ETH540F-LP-2P SFP+ Ethernet Card
+               193d 1023  NIC-ETH540F-LP-2P
                193d 1031  NIC-ETH640i-Mb-2x25G
+# NIC-ETH640F-3S-2P OCP3.0 Card
+               193d 1083  NIC-ETH640F-3S-2P
+# NIC-ETH540F-3S-2P OCP3.0 2x10G Card
+               193d 1084  NIC-ETH540F-3S-2P
        1016  MT27710 Family [ConnectX-4 Lx Virtual Function]
        1017  MT27800 Family [ConnectX-5]
                15b3 0006  ConnectX®-5 EN network interface card, 100GbE single-port QSFP28, PCIe3.0 x16, tall bracket; MCX515A-CCAT
        9750  GL9750 SD Host Controller
        e763  GL9763E eMMC Controller
 17aa  Lenovo
+       3181  ThinkCentre M75n IoT
        402b  Intel 82599ES 10Gb 2-port Server Adapter X520-2
 17ab  Phillips Components
 17af  Hightech Information System Ltd.
        1002  PM1553-5 (PC/104+ MIL-STD-1553 Interface Card)
        1004  AB3000 Series Rugged Computer
        1005  PE1000 (Multi-Protocol PCIe/104 Interface Card)
+       1006  webCS Wireless Aircraft Communications Server
+       1007  AB3000 Series Rugged Computer (Series N)
+       1008  ME1000 mPCIe Avionics Interface Card
+       100a  NG1 Series Avionics Converter
        1101  OmniBus II PCIe Multi-Protocol Interface Card
        1102  OmniBusBox II Multi-Protocol Interface Core
        1103  OmniBus II cPCIe/PXIe Multi-Protocol Interface Card
+       1200  NG3 Series Mil-Std-1553 Interface
+       1201  NG3 Series ARINC 429 Interface
+       1202  NG3 Series Avionics Discrete & Serial Interface
+       1203  NG3 Series Avionics Discrete Interface
 1bd4  Inspur Electronic Information Industry Co., Ltd.
        0911  Arria10_PCIe_F10A1150
 1bee  IXXAT Automation GmbH
        001b  FD720
        001c  FD922
        001d  Vega
+       001f  FD940
 1c28  Lite-On IT Corp. / Plextor
        0122  M6e PCI Express SSD [Marvell 88SS9183]
 # previously Fiberblaze
        0009  ExaNIC X25
        000a  ExaNIC X100
        000b  ExaNIC V9P
+       000c  ExaNIC V9P-3
        0100  ExaDISK FX1
 1cf0  Akitio
 1cf7  Subspace Dynamics
        0206  ACE-NIC200 Programmable Network Accelerator
                1df3 0000  Maintenance Mode
                1df3 0001  ENA2200F
+       0207  ACE-NIC50RN Programmable Network Accelerator
+       0208  ACE-NIC100RN Programmable Network Accelerator
 1df7  opencpi.org
        0001  ml605
        0002  alst4
        7053  CH353 PCI Dual Serial and Parallel Ports Controller
        7073  CH356 PCI Quad Serial and Parallel Ports Controller
        7173  CH355 PCI Quad Serial Port Controller
-434e  CAST Navigation LLC
+434e  Cornelis Networks
 43bc  Tiger Lake-H PCIe Root Port #5
 4444  Internext Compression Inc
        0016  iTVC16 (CX23416) Video Decoder
                1028 2103  NVMe RI U.2 3.84TB (P5500)
                1028 2104  NVMe RI U.2 7.68TB (P5500)
                8086 8008  NVMe Datacenter SSD [3DNAND] SE 2.5" U.2 (P5510)
+               8086 8d08  NVMe Datacenter SSD [3DNAND] VE 2.5" U.2 (P5316)
+               8086 8d1d  NVMe Datacenter SSD [3DNAND] VE E1.L 9.5/18mm (P5316)
        0be0  Atom Processor D2xxx/N2xxx Integrated Graphics Controller
        0be1  Atom Processor D2xxx/N2xxx Integrated Graphics Controller
                105b 0d7c  D270S/D250S Motherboard
                18d4 0c07  I350 1Gb 2-port RJ45 OCP Mezz Card MOP41-I-1GT2
                193d 1005  360T-B
                193d 1007  360T-L
+# NIC-ETH360T-3S-4P OCP3.0 4x1G Base-T Card
+               193d 1080  NIC-ETH360T-3S-4P
                1bd4 001d  1G base-T QP EP014Ti1 Adapter
                1bd4 0035  1G base-T QP EP014Ti1 Adapter
                8086 0001  Ethernet Server Adapter I350-T4
                17aa 4002  ThinkServer X710-2 AnyFabric for 10GbE SFP+
                193d 1020  NIC-ETH561F-sL-4x10G
                193d 1021  NIC-ETH561F-sL-2x10G
+# NIC-ETH561F-3S-2P OCP3.0 2x10G SFP+ Card
+               193d 1081  NIC-ETH561F-3S-2P
                19e5 d11c  Ethernet 2-port X710 10Gb SFP+ Adapter SP330
                1bd4 0042  10G SFP+ DP EP102Fi4 Adapter
                1bd4 0056  Ethernet Network Adapter X710-BM2 for OCP NIC 3.0
                8086 000b  Ethernet 100G 2P E810-C Adapter
                8086 000c  Ethernet 100G 2P E810-C OCP
                8086 000d  Ethernet Network Adapter E810-L-Q2 for OCP 3.0
+               8086 000e  Ethernet Network Adapter E810-2C-Q2
        1593  Ethernet Controller E810-C for SFP
                1137 02c3  E810XXVDA4 4x25/10 GbE SFP28 PCIe NIC
                8086 0002  Ethernet Network Adapter E810-L-2
                1137 02c2  X710T4LG 4x10 GbE RJ45 PCIe NIC
                1137 02d9  Ethernet Network Adapter X710-T2L OCP 3.0
                1137 02da  Ethernet Network Adapter X710-T4L OCP 3.0
+# NIC-ETH565T-3S-2P OCP3.0 2x10G Base-T Card
+               193d 1082  NIC-ETH565T-3S-2P
                8086 0000  Ethernet Network Adapter X710-TL
                8086 0001  Ethernet Network Adapter X710-T4L
                8086 0002  Ethernet Network Adapter X710-T4L
                1cb8 0002  Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16, TC6600 Fixed Port
                1cb8 0003  Omni-Path HFI Adapter 100 Series, 2 Port, 2 PCIe x16, Earth Simulation QSFP28
                1cb8 0004  Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16, TC4600E QSFP28
+               434e 0001  Omni-Path HFI 100 Series, 1 Port, OCP 3.0 Adapter
                8086 2628  Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16
                8086 2629  Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x8
                8086 262a  Omni-Path HFI Adapter 100 Series, 2 Ports, Split PCIe x16
        43e8  Tiger Lake-H Serial IO I2C Controller #0
        43ed  Tiger Lake-H USB 3.2 Gen 2x1 xHCI Host Controller
        43ef  Tiger Lake-H Shared SRAM
+       43f0  Wi-Fi 6 AX201
        444e  Turbo Memory Controller
        467f  Volume Management Device NVMe RAID Controller
        4680  AlderLake-S GT1
        9622  Integrated RAID
        9641  Integrated RAID
        96a1  Integrated RAID
-       9a01  11th Gen Core Processor PCIe Controller
+       9a01  11th Gen Core Processor PCIe Controller #1
        9a03  TigerLake-LP Dynamic Tuning Processor Participant
        9a09  11th Gen Core Processor PCIe Controller
        9a0b  Volume Management Device NVMe RAID Controller
        9a0d  Tiger Lake-LP Telemetry Aggregator
+       9a0f  11th Gen Core Processor PCIe Controller #0
        9a11  GNA Scoring Accelerator module
        9a13  Tiger Lake-LP Thunderbolt 4 USB Controller
        9a14  11th Gen Core Processor Host Bridge/DRAM Registers
        a324  Cannon Lake PCH SPI Controller
                1028 0869  Vostro 3470
        a328  Cannon Lake PCH Serial IO UART Host Controller
+       a32b  Cannon Lake PCH SPI Host Controller
        a32c  Cannon Lake PCH PCI Express Root Port #21
        a32d  Cannon Lake PCH PCI Express Root Port #22
        a32e  Cannon Lake PCH PCI Express Root Port #23
@@ -33595,6 +33656,7 @@ f1d0  AJA Video
        eb23  Kona 1
        eb24  Kona HDMI
        eb25  Corvid 44 12g
+       eb26  T-Tap Pro
        efac  Xena SD-MM/SD-22-MM
        facd  Xena HD-MM
 f5f5  F5 Networks, Inc.
index bb03e34387b984bf5cb294e749c9070eaaee9027..607efd8e05f05b2d7303a20bdc255bc01a860663 100644 (file)
  <tr class="even"><td>Alpha Telecom Inc</td><td>ATD</td><td>09/26/1997</td> </tr>
  <tr class="odd"><td>Alpha-Top Corporation</td><td>ATP</td><td>12/04/1996</td> </tr>
  <tr class="even"><td>AlphaView LCD</td><td>ALV</td><td>11/01/2008</td> </tr>
- <tr class="odd"><td>Alpine Electronics, Inc.</td><td>APE</td><td>01/22/2013</td> </tr>
- <tr class="even"><td>Alps Electric Company Ltd</td><td>ALP</td><td>11/29/1996</td> </tr>
- <tr class="odd"><td>Alps Electric Inc</td><td>AUI</td><td>11/29/1996</td> </tr>
+ <tr class="odd"><td>ALPS ALPINE CO., LTD.</td><td>APE</td><td>01/22/2013</td> </tr>
+ <tr class="even"><td>ALPS ALPINE CO., LTD.</td><td>ALP</td><td>11/29/1996</td> </tr>
+ <tr class="odd"><td>ALPS ALPINE CO., LTD.</td><td>AUI</td><td>11/29/1996</td> </tr>
  <tr class="even"><td>Alta Research Corporation</td><td>ARC</td><td>11/29/1996</td> </tr>
  <tr class="odd"><td>Altec Corporation</td><td>ALC</td><td>08/04/1998</td> </tr>
  <tr class="even"><td>Altec Lansing</td><td>ALJ</td><td>01/13/2000</td> </tr>
  <tr class="odd"><td>Clover Electronics</td><td>CLR</td><td>02/02/2021</td> </tr>
  <tr class="even"><td>Kyokko Communication System Co., Ltd.</td><td>KTS</td><td>02/18/2021</td> </tr>
  <tr class="odd"><td>Terumo Corporation</td><td>TMO</td><td>02/02/2021</td> </tr>
+ <tr class="even"><td>Micro-Star Int&#039;l Co., Ltd.</td><td>CND</td><td>02/17/2021</td> </tr>
+ <tr class="odd"><td>Newline Interactive Inc.</td><td>NWL</td><td>12/03/2020</td> </tr>
+ <tr class="even"><td>CORSAIR MEMORY Inc.</td><td>CRM</td><td>02/05/2021</td> </tr>
       </tbody>
     </table>
   </body>
index aff43217e1690703a7bcaeaafd900f3b88651668..614871bce206ec72004e6973fa8e3e3fb57fca66 100644 (file)
@@ -2250,6 +2250,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly s Type = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+      readonly s ExitType = '...';
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly s Restart = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly s PIDFile = '...';
@@ -2808,6 +2810,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <!--property Type is not documented!-->
 
+    <!--property ExitType is not documented!-->
+
     <!--property Restart is not documented!-->
 
     <!--property PIDFile is not documented!-->
@@ -3320,6 +3324,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="Type"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ExitType"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Restart"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="PIDFile"/>
index 00e4110739df3b44301a9a9da2ec3fe1a3286b0b..31a3344bbd7629315c37323a0e15c7d716dd8ff5 100644 (file)
     returns zero, an error reply is sent back to the caller indicating no matching object for the
     request was found.</para>
 
-    <para>Note that you can return a positive integer from a callback without
+    <para>Note that you can return a positive integer from a <parameter>method</parameter> callback without
     immediately sending a reply. This informs sd-bus this callback will take responsibility for
     replying to the request without forcing the callback to produce a reply immediately. This allows
     a callback to perform any number of asynchronous operations required to construct a reply.
-    However, if producing a reply takes too long, the method call will time out at the caller.</para>
+    However, if producing a reply takes too long, the method call will time out at the caller. This is
+    only available to methods and not properties.</para>
 
     <para>If a callback was invoked to handle a request that expects a reply and the callback
     returns a negative value, the value is interpreted as a negative errno-style error code and sent
index 433260475dc2d9bf39cc42b316405fbbea829e2c..f241064d8bbefef7a393272193a9b3cb47451fe9 100644 (file)
         directly. Example: <literal>--keyname=cryptsetup</literal></para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--credential=</option></term>
+        <listitem><para>Configure a credential to read the password from – if it exists. This may be used in
+        conjunction with the <varname>LoadCredential=</varname> and <varname>SetCredential=</varname>
+        settings in unit files. See
+        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+        details. If not specified, defaults to <literal>password</literal>. This option has no effect if no
+        credentials directory is passed to the program (i.e. <varname>$CREDENTIALS_DIRECTORY</varname> is not
+        set) or if the no credential of the specified name exists.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--timeout=</option></term>
 
index 100192490230d8caea9dd8844489d63a8b771fc9..46fe0a0682cea690e80d61c50ad62ed2185f81d7 100644 (file)
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Credentials</title>
+
+    <para><command>systemd-firstboot</command> supports the service credentials logic as implemented by
+    <varname>LoadCredential=</varname>/<varname>SetCredential=</varname> (see
+    <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+    details). The following credentials are used when passed in:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><literal>passwd.hashed-password.root</literal></term>
+        <term><literal>passwd.plaintext-password.root</literal></term>
+
+        <listitem><para>A hashed or plaintext version of the root password to use, in place of prompting the
+        user. These credentials are equivalent to the same ones defined for the
+        <citerefentry><refentrytitle>systemd-sysusers.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        service.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><literal>passwd.shell.root</literal></term>
+
+        <listitem><para>Specifies the shell binary to use for the the specified account when creating
+        it. Equivalent to the credential of the same name defined for the
+        <citerefentry><refentrytitle>systemd-sysusers.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        service.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><literal>firstboot.locale</literal></term>
+        <term><literal>firstboot.locale-messages</literal></term>
+
+        <listitem><para>These credentials specify the locale settings to set during first boot, in place of
+        prompting the user.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><literal>firstboot.keymap</literal></term>
+
+        <listitem><para>This credential specifies the keyboard setting to set during first boot, in place of
+        prompting the user.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><literal>firstboot.timezone</literal></term>
+
+        <listitem><para>This credential specifies the system timezone setting to set during first boot, in
+        place of prompting the user.</para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>Note that by default the <filename>systemd-firstboot.service</filename> unit file is set up to
+    inherit the listed credentials
+    from the service manager. Thus, when invoking a container with an unpopulated <filename>/etc/</filename>
+    for the first time it is possible to configure the root user's password to be <literal>systemd</literal>
+    like this:</para>
+
+    <para><programlisting># systemd-nspawn --image=… --set-credential=firstboot.locale:de_DE.UTF-8 …</programlisting></para>
 
+    <para>Note that these credentials are only read and applied during the first boot process. Once they are
+    applied they remain applied for subsequent boots, and the credentials are not considered anymore.</para>
   </refsect1>
 
   <refsect1>
index 2c2a0964932b7325758d9dd3772da3061a7dbb30..a9c52d842c54bb9c16c800a35090832ededa14cb 100644 (file)
     <variablelist>
 
       <varlistentry>
-        <term><option>--root=<replaceable>root</replaceable></option></term>
-        <listitem><para>Takes a directory path as argument. All paths
-        operated will be prefixed with the given alternate
-        <replaceable>root</replaceable> path, including the path for
+        <term><option>--root=<replaceable>path</replaceable></option></term>
+        <listitem><para>Takes a directory path as argument. All paths operated on will be prefixed with the
+        given alternate <replaceable>root</replaceable> path, including the path for
         <filename>/etc/machine-id</filename> itself.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--image=<replaceable>path</replaceable></option></term>
+        <listitem><para>Takes a path to a device node or refular file as argument. This is similar to
+        <option>--root=</option> as described above, but operates on a disk image instead of a directory
+        tree.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--commit</option></term>
         <listitem><para>Commit a transient machine ID to disk. This
index 6a27bab1e30639c793644dfb150d40fe5ac8265e..c4732507df0b23e013392478674a1525f807bdc0 100644 (file)
@@ -1487,7 +1487,31 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
         <para>In order to embed binary data into the credential data for <option>--set-credential=</option>
         use C-style escaping (i.e. <literal>\n</literal> to embed a newline, or <literal>\x00</literal> to
         embed a <constant>NUL</constant> byte. Note that the invoking shell might already apply unescaping
-        once, hence this might require double escaping!).</para></listitem>
+        once, hence this might require double escaping!).</para>
+
+        <para>The
+        <citerefentry><refentrytitle>systemd-sysusers.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        and
+        <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+        services read credentials configured this way for the purpose of configuring the container's root
+        user's password and shell, as well as system locale, keymap and timezone during the first boot
+        process of the container. This is particularly useful in combination with
+        <option>--volatile=yes</option> where every single boot appears as first boot, since configuration
+        applied to <filename>/etc/</filename> is lost on container reboot cycles. See the respective man
+        pages for details. Example:</para>
+
+        <programlisting># systemd-nspawn -i image.raw \
+        --volatile=yes \
+        --set-credential=firstboot.locale:de_DE.UTF-8 \
+        --set-credential=passwd.hashed-password.root:'$y$j9T$yAuRJu1o5HioZAGDYPU5d.$F64ni6J2y2nNQve90M/p0ZP0ECP/qqzipNyaY9fjGpC' \
+        -b</programlisting>
+
+        <para>The above command line will invoke the specified image file <filename>image.raw</filename> in
+        volatile mode, i.e with an empty <filename>/etc/</filename> and <filename>/var/</filename>, so that
+        the container's payload recognizes this as first boot condition, and will invoke
+        <filename>systemd-firstboot.service</filename>, which then read the two passed credentials to
+        configure the system's initial locale and root password.</para>
+        </listitem>
         </varlistentry>
 
     </variablelist>
index 950a8b4499bbb9e306cbacd2bf94468929b9026c..466a4601514fffcaffef13e12c80af9f00774868 100644 (file)
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Credentials</title>
+
+    <para><command>systemd-sysusers</command> supports the service credentials logic as implemented by
+    <varname>LoadCredential=</varname>/<varname>SetCredential=</varname> (see
+    <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+    details). The following credentials are used when passed in:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><literal>passwd.hashed-password.<replaceable>user</replaceable></literal></term>
+        <listitem><para>A UNIX hashed password string to use for the specified user, when creating an entry
+        for it. This is particularly useful for the <literal>root</literal> user as it allows provisioning
+        the default root password to use via a unit file drop-in or from a container manager passing in this
+        credential. Note that setting this credential has no effect if the specified user account already
+        exists. This credential is hence primarily useful in first boot scenarios or systems that are fully
+        stateless and come up with an empty <filename>/etc/</filename> on every boot.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><literal>passwd.plaintext-password.<replaceable>user</replaceable></literal></term>
+
+        <listitem><para>Similar to <literal>passwd.hashed-password.<replaceable>user</replaceable></literal>
+        but expect a literal, plaintext password, which is then automatically hashed before used for the user
+        account. If both the hashed and the plaintext credential are specified for the same user the
+        former takes precedence. It's generally recommended to specify the hashed version; however in test
+        environments with weaker requirements on security it might be easier to pass passwords in plaintext
+        instead.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><literal>passwd.shell.<replaceable>user</replaceable></literal></term>
+
+        <listitem><para>Specifies the shell binary to use for the the specified account when creating it.</para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>Note that by default the <filename>systemd-sysusers.service</filename> unit file is set up to
+    inherit the <literal>passwd.hashed-password.root</literal>,
+    <literal>passwd.plaintext-password.root</literal> and <literal>passwd.shell.root</literal> credentials
+    from the service manager. Thus, when invoking a container with an unpopulated <filename>/etc/</filename>
+    for the first time it is possible to configure the root user's password to be <literal>systemd</literal>
+    like this:</para>
+
+    <para><programlisting># systemd-nspawn --image=… --set-credential=password.hashed-password.root:'$y$j9T$yAuRJu1o5HioZAGDYPU5d.$F64ni6J2y2nNQve90M/p0ZP0ECP/qqzipNyaY9fjGpC' …</programlisting></para>
+
+    <para>Note again that the data specified in these credentials is consulted only when creating an account
+    for the first time, it may not be used for changing the password or shell of an account that already
+    exists.</para>
 
+    <para>Use <citerefentry><refentrytitle>mkpasswd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    for generating UNIX password hashes from the command line.</para>
   </refsect1>
 
   <refsect1>
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sysusers.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-      <ulink url="https://systemd.io/UIDS-GIDS">Users, Groups, UIDs and GIDs on systemd systems</ulink>
+      <ulink url="https://systemd.io/UIDS-GIDS">Users, Groups, UIDs and GIDs on systemd systems</ulink>,
+      <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>mkpasswd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     </para>
   </refsect1>
 
index 255ca3373bbcb354856066011f361f13c29a16f5..596d334d5df575a7a601d839159d4fb140ce433f 100644 (file)
   <refsect1>
     <title>Description</title>
 
-    <para>A unit configuration file whose name ends in
-    <literal>.device</literal> encodes information about a device unit
-    as exposed in the
-    sysfs/<citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-    device tree.</para>
+    <para>A unit configuration file whose name ends in <literal>.device</literal> encodes information about a
+    device unit as exposed in the
+    sysfs/<citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry> device
+    tree. This may be used to define dependencies between devices and other units.</para>
 
     <para>This unit type has no specific options. See
     <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
     sections. A separate [Device] section does not
     exist, since no device-specific options may be configured.</para>
 
-    <para>systemd will dynamically create device units for all kernel
-    devices that are marked with the "systemd" udev tag (by default
-    all block and network devices, and a few others). This may be used
-    to define dependencies between devices and other units. To tag a
-    udev device, use <literal>TAG+="systemd"</literal> in the udev
-    rules file, see
-    <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-    for details.</para>
+    <para>systemd will dynamically create device units for all kernel devices that are marked with the
+    <literal>systemd</literal> udev tag (by default all block and network devices, and a few others). Note
+    that <emphasis>if <filename>systemd-udev.service</filename> is not running, no device units will be
+    available (for example in a typical container)</emphasis>.</para>
 
     <para>Device units are named after the <filename>/sys/</filename>
     and <filename>/dev/</filename> paths they control. Example: the
     name see
     <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
 
+    <para>To tag a udev device, use <literal>TAG+="systemd"</literal> in the udev rules file, see
+    <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details.
+    </para>
+
     <para>Device units will be reloaded by systemd whenever the
     corresponding device generates a <literal>changed</literal> event.
     Other units can use <varname>ReloadPropagatedFrom=</varname> to react
index 8d4e1143e3e0c71f776477d9131452a5db561a11..6ae630f615462634381742de4bf62927a8d1c71b 100644 (file)
         Filesystem</ulink>. It is generally recommended to run most system services with this option set to
         <literal>invisible</literal>. This option is implemented via file system namespacing, and thus cannot
         be used with services that shall be able to install mount points in the host file system
-        hierarchy. It also cannot be used for services that need to access metainformation about other users'
-        processes. This option implies <varname>MountAPIVFS=</varname>.</para>
+        hierarchy. Note that the root user is unaffected by this option, so to be effective it has to be used
+        together with <varname>User=</varname> or <varname>DynamicUser=yes</varname>, and also without the
+        <literal>CAP_SYS_PTRACE</literal> capability, which also allows a process to bypass this feature. It
+        cannot be used for services that need to access metainformation about other users' processes. This
+        option implies <varname>MountAPIVFS=</varname>.</para>
 
         <para>If the kernel doesn't support per-mount point <option>hidepid=</option> mount options this
         setting remains without effect, and the unit's processes will be able to access and see other process
@@ -2818,7 +2821,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
     <variablelist class='unit-directives'>
 
       <varlistentry>
-        <term><varname>LoadCredential=</varname><replaceable>ID</replaceable>:<replaceable>PATH</replaceable></term>
+        <term><varname>LoadCredential=</varname><replaceable>ID</replaceable><optional>:<replaceable>PATH</replaceable></optional></term>
 
         <listitem><para>Pass a credential to the unit. Credentials are limited-size binary or textual objects
         that may be passed to unit processes. They are primarily used for passing cryptographic keys (both
@@ -2831,19 +2834,21 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
         environment variable to the unit's processes.</para>
 
         <para>The <varname>LoadCredential=</varname> setting takes a textual ID to use as name for a
-        credential plus a file system path. The ID must be a short ASCII string suitable as filename in the
-        filesystem, and may be chosen freely by the user. If the specified path is absolute it is opened as
-        regular file and the credential data is read from it. If the absolute path refers to an
-        <constant>AF_UNIX</constant> stream socket in the file system a connection is made to it (only once
-        at unit start-up) and the credential data read from the connection, providing an easy IPC integration
-        point for dynamically providing credentials from other services. If the specified path is not
-        absolute and itself qualifies as valid credential identifier it is understood to refer to a
-        credential that the service manager itself received via the <varname>$CREDENTIALS_DIRECTORY</varname>
-        environment variable, which may be used to propagate credentials from an invoking environment (e.g. a
-        container manager that invoked the service manager) into a service. The contents of the file/socket
-        may be arbitrary binary or textual data, including newline characters and <constant>NUL</constant>
-        bytes. This option may be used multiple times, each time defining an additional credential to pass to
-        the unit.</para>
+        credential plus a file system path, separated by a colon. The ID must be a short ASCII string
+        suitable as filename in the filesystem, and may be chosen freely by the user. If the specified path
+        is absolute it is opened as regular file and the credential data is read from it. If the absolute
+        path refers to an <constant>AF_UNIX</constant> stream socket in the file system a connection is made
+        to it (only once at unit start-up) and the credential data read from the connection, providing an
+        easy IPC integration point for dynamically providing credentials from other services. If the
+        specified path is not absolute and itself qualifies as valid credential identifier it is understood
+        to refer to a credential that the service manager itself received via the
+        <varname>$CREDENTIALS_DIRECTORY</varname> environment variable, which may be used to propagate
+        credentials from an invoking environment (e.g. a container manager that invoked the service manager)
+        into a service. The contents of the file/socket may be arbitrary binary or textual data, including
+        newline characters and <constant>NUL</constant> bytes. If the file system path is omitted it is
+        chosen identical to the credential name, i.e. this is a terse way do declare credentials to inherit
+        from the service manager into a service. This option may be used multiple times, each time defining
+        an additional credential to pass to the unit.</para>
 
         <para>The credential files/IPC sockets must be accessible to the service manager, but don't have to
         be directly accessible to the unit's processes: the credential data is read and copied into separate,
index 087dbf3bac926d9474ed4b9a850fb6818bbba768..66759607d3468ce78363eff7173e085c2e22f0e2 100644 (file)
@@ -1597,9 +1597,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
         <varlistentry>
           <term><varname>UseDNS=</varname></term>
           <listitem>
-            <para>When true (the default), the DNS servers received
-            from the DHCP server will be used and take precedence over
-            any statically configured ones.</para>
+            <para>When true (the default), the DNS servers received from the DHCP server will be used.</para>
 
             <para>This corresponds to the <option>nameserver</option>
             option in <citerefentry
@@ -1618,8 +1616,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           <term><varname>UseNTP=</varname></term>
           <listitem>
             <para>When true (the default), the NTP servers received from the DHCP server will be used by
-            <filename>systemd-timesyncd.service</filename> and take precedence over any statically configured
-            ones.</para>
+            <filename>systemd-timesyncd.service</filename>.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
@@ -1739,13 +1736,12 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           <term><varname>UseGateway=</varname></term>
           <listitem>
             <para>When true, the gateway will be requested from the DHCP server and added to the routing table with a
-            metric of 1024, and a scope of "link".  When unset, the value specified with <option>UseRoutes=</option>
+            metric of 1024, and a scope of "link". When unset, the value specified with <option>UseRoutes=</option>
             is used.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
           <term><varname>UseTimezone=</varname></term>
-
           <listitem><para>When true, the timezone received from the
           DHCP server will be set as timezone of the local
           system. Defaults to <literal>no</literal>.</para></listitem>
@@ -2164,8 +2160,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
         <varlistentry>
           <term><varname>UseDNS=</varname></term>
           <listitem>
-            <para>When true (the default), the DNS servers received in the Router Advertisement will be used and take
-            precedence over any statically configured ones.</para>
+            <para>When true (the default), the DNS servers received in the Router Advertisement will be used.</para>
 
             <para>This corresponds to the <option>nameserver</option> option in <citerefentry
             project='man-pages'><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
index 501da54b8aa54e36fc9ba5c1f39272c69bd74662..50d1a1d85d638f2404c2b943df6226bb48924a76 100644 (file)
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>ExitType=</varname></term>
+
+        <listitem>
+          <para>Configures the process exit type for this service unit. One of <option>main</option> or
+          <option>cgroup</option>:</para>
+
+          <itemizedlist>
+            <listitem><para>If set to <option>main</option> (the default), the service manager
+            will consider the unit stopped when the main process, which is determined according to the `Type`, exits.
+            </para></listitem>
+
+            <listitem><para>The <option>cgroup</option> exit type is meant for applications whose forking model is not
+            known ahead of time and which might not have a specific main process. The service will stay running as long
+            as at least one process in the cgroup is running. The exit status of the service is that of the last
+            process in the cgroup to exit.</para></listitem>
+          </itemizedlist>
+
+          <para>It is generally recommended to use <varname>ExitType=</varname><option>main</option> when a service has
+          a known forking model and a main process can reliably be determined. <varname>ExitType=</varname>
+          <option>cgroup</option> is well suited for transient or automatically generated services, such as graphical
+          applications inside of a desktop environment.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>RemainAfterExit=</varname></term>
 
         If set to <option>no</option> (the default), the service will
         not be restarted. If set to <option>on-success</option>, it
         will be restarted only when the service process exits cleanly.
-        In this context, a clean exit means an exit code of 0, or one
-        of the signals
-        <constant>SIGHUP</constant>,
-        <constant>SIGINT</constant>,
-        <constant>SIGTERM</constant> or
-        <constant>SIGPIPE</constant>, and
-        additionally, exit statuses and signals specified in
-        <varname>SuccessExitStatus=</varname>. If set to
+        In this context, a clean exit means any of the following:
+        <itemizedlist>
+            <listitem><simpara>exit code of 0;</simpara></listitem>
+            <listitem><simpara>for types other than
+            <varname>Type=oneshot</varname>, one of the signals
+                <constant>SIGHUP</constant>,
+                <constant>SIGINT</constant>,
+                <constant>SIGTERM</constant>, or
+                <constant>SIGPIPE</constant>;</simpara></listitem>
+            <listitem><simpara>exit statuses and signals specified in
+                <varname>SuccessExitStatus=</varname>.</simpara></listitem>
+        </itemizedlist>
+        If set to
         <option>on-failure</option>, the service will be restarted
         when the process exits with a non-zero exit code, is
         terminated by a signal (including on core dump, but excluding
 
         <listitem><para>Takes a list of exit status definitions that, when returned by the main service
         process, will be considered successful termination, in addition to the normal successful exit status
-        0 and the signals <constant>SIGHUP</constant>, <constant>SIGINT</constant>,
+        0 and, except for <varname>Type=oneshot</varname>, the signals <constant>SIGHUP</constant>, <constant>SIGINT</constant>,
         <constant>SIGTERM</constant>, and <constant>SIGPIPE</constant>. Exit status definitions can be
         numeric termination statuses, termination status names, or termination signal names, separated by
         spaces. See the Process Exit Codes section in
index 20e52c566423f940cd2ffd6ea0cf78f2dddf6cad..42dcbac72ca3e19a4cb71ed9583158c18d0f6383 100644 (file)
         <varname>Restart=</varname> logic.</para>
 
         <para>Note that units which are configured for <varname>Restart=</varname>, and which reach the start
-        limit are not attempted to be restarted anymore; however, they may still be restarted manually at a
-        later point, after the <replaceable>interval</replaceable> has passed. From that point on, the
-        restart logic is activated again. <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. Rate-limiting is enforced after any unit
-        condition checks are executed, and hence unit activations with failing conditions do not count
-        towards the rate limit.</para>
+        limit are not attempted to be restarted anymore; however, they may still be restarted manually or
+        from a timer or socket at a later point, after the <replaceable>interval</replaceable> has passed.
+        From that point on, the restart logic is activated again. <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. Rate-limiting is enforced
+        after any unit condition checks are executed, and hence unit activations with failing conditions do
+        not count towards the rate limit.</para>
 
         <para>When a unit is unloaded due to the garbage collection logic (see above) its rate limit counters
         are flushed out too. This means that configuring start rate limiting for a unit that is not
index 8fbfd5fc494a8c3852c1045397f6eb4080e802da..6a474afdac33a284350f96f48bb7526e4bb49d9b 100644 (file)
@@ -14,7 +14,7 @@ project('systemd', 'c',
        )
 
 libsystemd_version = '0.31.0'
-libudev_version = '1.7.0'
+libudev_version = '1.7.1'
 
 # We need the same data in two different formats, ugh!
 # Also, for hysterical reasons, we use different variable
@@ -144,7 +144,7 @@ pkgconfiglibdir = get_option('pkgconfiglibdir') == '' ? join_paths(libdir, 'pkgc
 polkitpolicydir = join_paths(datadir, 'polkit-1/actions')
 polkitrulesdir = join_paths(datadir, 'polkit-1/rules.d')
 polkitpkladir = join_paths(localstatedir, 'lib/polkit-1/localauthority/10-vendor.d')
-xinitrcdir = join_paths(sysconfdir, 'X11/xinit/xinitrc.d')
+xinitrcdir = get_option('xinitrcdir') == '' ? join_paths(sysconfdir, 'X11/xinit/xinitrc.d') : get_option('xinitrcdir')
 rpmmacrosdir = get_option('rpmmacrosdir')
 if rpmmacrosdir != 'no'
         rpmmacrosdir = join_paths(prefixdir, rpmmacrosdir)
@@ -857,10 +857,13 @@ conf.set_quoted('SYSTEMD_DEFAULT_LOCALE', default_locale)
 
 localegen_path = get_option('localegen-path')
 have = false
+writable = ''
 if localegen_path != ''
         conf.set_quoted('LOCALEGEN_PATH', localegen_path)
         have = true
+        writable = ' /usr/lib/locale'
 endif
+substs.set('SERVICE_LOCALEGEN_WRITABLE', writable)
 conf.set10('HAVE_LOCALEGEN', have)
 
 conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
@@ -3472,7 +3475,8 @@ if install_sysconfdir
         install_data('xorg/50-systemd-user.sh',
                      install_dir : xinitrcdir)
 endif
-install_data('modprobe.d/systemd.conf',
+install_data('README',
+             'modprobe.d/systemd.conf',
              install_dir : modprobedir)
 install_data('LICENSE.GPL2',
              'LICENSE.LGPL2.1',
index 425e958ba20af3f6d783fd64752a7e87ff91350e..d96d4e3f047c859832ea384d75f054d4d1feccc6 100644 (file)
@@ -178,6 +178,8 @@ option('pkgconfigdatadir', type : 'string', value : '',
        description : 'directory for arch-independent pkg-config files')
 option('pkgconfiglibdir', type : 'string', value : '',
        description : 'directory for standard pkg-config files')
+option('xinitrcdir', type : 'string', value : '',
+       description : 'directory for xinitrc files')
 option('rpmmacrosdir', type : 'string', value : 'lib/rpm/macros.d',
        description : 'directory for rpm macros ["no" disables]')
 option('pamlibdir', type : 'string',
@@ -360,7 +362,7 @@ option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'],
        description : 'gnu-efi support for sd-boot')
 option('efi-cc', type : 'array',
        description : 'the compiler to use for EFI modules')
-option('efi-ld', type : 'string',
+option('efi-ld', type : 'string', value : 'ld',
        description : 'the linker to use for EFI modules')
 option('efi-libdir', type : 'string',
        description : 'path to the EFI lib directory')
diff --git a/modprobe.d/README b/modprobe.d/README
new file mode 100644 (file)
index 0000000..4c11e46
--- /dev/null
@@ -0,0 +1,7 @@
+Files in this directory contain configuration for modprobe, a program to load
+kernel modules.
+
+See man:modprobe.d(5) for explanation of the configuration file format, and
+man:modprobe(8) for a description of the program itself.
+
+Use 'systemd-analyze cat-config modprobe.d' to display the effective config.
index c9ebc006aa7aabc4475e1fc5d338462b152ab2d2..b5b60ef985c36f0f5433d8c4b59f82694b169171 100644 (file)
@@ -30,3 +30,4 @@ zh_TW
 pa
 kab
 si
+nl
index 4052fbe8126622e05cee8227d9b131d76a8dfaa7..3713b161ecfe9865ca03528279969ce1ff0bde84 100644 (file)
--- a/po/ko.po
+++ b/po/ko.po
@@ -9,7 +9,7 @@ msgstr ""
 "Project-Id-Version: systemd\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2021-01-08 17:48+0100\n"
-"PO-Revision-Date: 2021-03-09 12:01+0000\n"
+"PO-Revision-Date: 2021-03-25 03:01+0000\n"
 "Last-Translator: simmon <simmon@nplob.com>\n"
 "Language-Team: Korean <https://translate.fedoraproject.org/projects/systemd/"
 "master/ko/>\n"
@@ -168,11 +168,11 @@ msgstr "가상 머신 또는 컨테이너의 이미지를 내보내려면 인증
 
 #: src/import/org.freedesktop.import1.policy:42
 msgid "Download a VM or container image"
-msgstr "ê°\80ì\83\81머ì\8b  ë\98\90ë\8a\94 ì»¨í\85\8cì\9d´ë\84\88 ì\9d´ë¯¸ì§\80 ë\8b¤ì\9a´ë¡\9cë\93\9c"
+msgstr "ê°\80ì\83\81머ì\8b  ë\98\90ë\8a\94 ì»¨í\85\8cì\9d´ë\84\88 ì\9d´ë¯¸ì§\80 ë\82´ë ¤ë°\9b기"
 
 #: src/import/org.freedesktop.import1.policy:43
 msgid "Authentication is required to download a VM or container image"
-msgstr "ê°\80ì\83\81머ì\8b  ë\98\90ë\8a\94 ì»¨í\85\8cì\9d´ë\84\88 ì\9d´ë¯¸ì§\80를 ë\8b¤ì\9a´ë¡\9cë\93\9c하려면 인증이 필요합니다"
+msgstr "ê°\80ì\83\81머ì\8b  ë\98\90ë\8a\94 ì»¨í\85\8cì\9d´ë\84\88 ì\9d´ë¯¸ì§\80를 ë\82´ë ¤ë°\9b기하려면 인증이 필요합니다"
 
 #: src/locale/org.freedesktop.locale1.policy:22
 msgid "Set system locale"
@@ -498,10 +498,8 @@ msgid "Set the reboot \"reason\" in the kernel"
 msgstr "커널이 재시작 \"원인\"을 설정합니다"
 
 #: src/login/org.freedesktop.login1.policy:353
-#, fuzzy
-#| msgid "Authentication is required to set the system timezone."
 msgid "Authentication is required to set the reboot \"reason\" in the kernel."
-msgstr "ì\8b\9cì\8a¤í\85\9c ì\8b\9cê°\84ë\8c\80를 설정하려면 인증이 필요합니다."
+msgstr "커ë\84\90ì\97\90ì\84\9c \"reason\"ì\9c¼ë¡\9c ì\9e¬ë\8f\99ì\9e\91 설정하려면 인증이 필요합니다."
 
 #: src/login/org.freedesktop.login1.policy:363
 msgid "Indicate to the firmware to boot to setup interface"
@@ -518,28 +516,20 @@ msgid "Indicate to the boot loader to boot to the boot loader menu"
 msgstr "부트로더 메뉴에 부팅하기 위해 부트로더에 표시하기"
 
 #: src/login/org.freedesktop.login1.policy:375
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to indicate to the firmware to boot to setup "
-#| "interface."
 msgid ""
 "Authentication is required to indicate to the boot loader to boot to the "
 "boot loader menu."
-msgstr "설정 화면으로 부팅하도록 펌웨어에게 지시하려면 인증이 필요합니다."
+msgstr "부트로더에 부팅하려면 부트로더 메뉴에 표시하려면 인증이 필요합니다."
 
 #: src/login/org.freedesktop.login1.policy:385
 msgid "Indicate to the boot loader to boot a specific entry"
 msgstr "특정 항목으로 재시작 하기 위해 부트로더 표시"
 
 #: src/login/org.freedesktop.login1.policy:386
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to indicate to the firmware to boot to setup "
-#| "interface."
 msgid ""
 "Authentication is required to indicate to the boot loader to boot into a "
 "specific boot loader entry."
-msgstr "설정 화면으로 부팅하도록 펌웨어에게 지시하려면 인증이 필요합니다."
+msgstr "부트로더에 지정한 부트로더 에서 부트하거나 지정한 부트로더 진입을 표시하려면 인증이 필요합니다."
 
 #: src/login/org.freedesktop.login1.policy:396
 msgid "Set a wall message"
@@ -554,10 +544,8 @@ msgid "Change Session"
 msgstr "세션 변경"
 
 #: src/login/org.freedesktop.login1.policy:407
-#, fuzzy
-#| msgid "Authentication is required to set the local hostname."
 msgid "Authentication is required to change the virtual terminal."
-msgstr "로컬 호스트 이름을 설정하려면 인증이 필요합니다."
+msgstr "가상 터미널을 변경하려면 인증이 필요합니다."
 
 #: src/machine/org.freedesktop.machine1.policy:22
 msgid "Log into a local container"
@@ -632,10 +620,8 @@ msgid "Set NTP servers"
 msgstr "NTP 서버 설정"
 
 #: src/network/org.freedesktop.network1.policy:23
-#, fuzzy
-#| msgid "Authentication is required to set the system time."
 msgid "Authentication is required to set NTP servers."
-msgstr "시스템 시간을 설정하려면 인증이 필요합니다."
+msgstr "NTP 서버 설정에 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:33
 #: src/resolve/org.freedesktop.resolve1.policy:44
@@ -644,10 +630,8 @@ msgstr "DNS 서버 설정"
 
 #: src/network/org.freedesktop.network1.policy:34
 #: src/resolve/org.freedesktop.resolve1.policy:45
-#, fuzzy
-#| msgid "Authentication is required to set the system time."
 msgid "Authentication is required to set DNS servers."
-msgstr "시스템 시간을 설정하려면 인증이 필요합니다."
+msgstr "DNS 서버를 설정하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:44
 #: src/resolve/org.freedesktop.resolve1.policy:55
@@ -656,10 +640,8 @@ msgstr "도메인 설정"
 
 #: src/network/org.freedesktop.network1.policy:45
 #: src/resolve/org.freedesktop.resolve1.policy:56
-#, fuzzy
-#| msgid "Authentication is required to stop '$(unit)'."
 msgid "Authentication is required to set domains."
-msgstr "'$(unit)' 서비스 유닛을 멈추려면 인증이 필요합니다."
+msgstr "도메인을 설정하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:55
 #: src/resolve/org.freedesktop.resolve1.policy:66
@@ -668,10 +650,8 @@ msgstr "기본 라우트 설정"
 
 #: src/network/org.freedesktop.network1.policy:56
 #: src/resolve/org.freedesktop.resolve1.policy:67
-#, fuzzy
-#| msgid "Authentication is required to set the local hostname."
 msgid "Authentication is required to set default route."
-msgstr "로컬 호스트 이름을 설정하려면 인증이 필요합니다."
+msgstr "기본 라우트 설정하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:66
 #: src/resolve/org.freedesktop.resolve1.policy:77
@@ -680,10 +660,8 @@ msgstr "LLMNR 활성화/비활성화"
 
 #: src/network/org.freedesktop.network1.policy:67
 #: src/resolve/org.freedesktop.resolve1.policy:78
-#, fuzzy
-#| msgid "Authentication is required to hibernate the system."
 msgid "Authentication is required to enable or disable LLMNR."
-msgstr "시스템을 최대 절전 상태로 놓으려면 인증이 필요합니다."
+msgstr "LLMNR을 활성화 또는 비활성화 하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:77
 #: src/resolve/org.freedesktop.resolve1.policy:88
@@ -692,10 +670,8 @@ msgstr "멀티캐스트 DNS 활성화/비활성화"
 
 #: src/network/org.freedesktop.network1.policy:78
 #: src/resolve/org.freedesktop.resolve1.policy:89
-#, fuzzy
-#| msgid "Authentication is required to log into the local host."
 msgid "Authentication is required to enable or disable multicast DNS."
-msgstr "ë¡\9c컬 í\98¸ì\8a¤í\8a¸ë¡\9c ë¡\9cê·¸ì\9d¸하려면 인증이 필요합니다."
+msgstr "ë©\80í\8b°ìº\90ì\8a¤í\8a¸ DNS í\99\9cì\84±í\99\94 ë\98\90ë\8a\94 ë¹\84í\99\9cì\84±í\99\94하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:88
 #: src/resolve/org.freedesktop.resolve1.policy:99
@@ -704,10 +680,8 @@ msgstr "TLS를 통한 DNS 활성화/비활성화"
 
 #: src/network/org.freedesktop.network1.policy:89
 #: src/resolve/org.freedesktop.resolve1.policy:100
-#, fuzzy
-#| msgid "Authentication is required to set the local hostname."
 msgid "Authentication is required to enable or disable DNS over TLS."
-msgstr "로컬 호스트 이름을 설정하려면 인증이 필요합니다."
+msgstr "TLS를 통 DNS를 활성화 또는 비활성화하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:99
 #: src/resolve/org.freedesktop.resolve1.policy:110
@@ -716,10 +690,8 @@ msgstr "DNSSEC 활성화/비활성화"
 
 #: src/network/org.freedesktop.network1.policy:100
 #: src/resolve/org.freedesktop.resolve1.policy:111
-#, fuzzy
-#| msgid "Authentication is required to hibernate the system."
 msgid "Authentication is required to enable or disable DNSSEC."
-msgstr "시스템을 최대 절전 상태로 놓으려면 인증이 필요합니다."
+msgstr "DNSSEC를 활성화 또는 비활성화 하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:110
 #: src/resolve/org.freedesktop.resolve1.policy:121
@@ -728,30 +700,24 @@ msgstr "DNSSEC 부정적인 신뢰 고정 설정"
 
 #: src/network/org.freedesktop.network1.policy:111
 #: src/resolve/org.freedesktop.resolve1.policy:122
-#, fuzzy
-#| msgid "Authentication is required to set the system locale."
 msgid "Authentication is required to set DNSSEC Negative Trust Anchors."
-msgstr "시스템 로캘을 설정하려면 인증이 필요합니다."
+msgstr "DNSSEC 부정적인 신뢰 고정을 설정하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:121
 msgid "Revert NTP settings"
 msgstr "NTP 설정 되돌리기"
 
 #: src/network/org.freedesktop.network1.policy:122
-#, fuzzy
-#| msgid "Authentication is required to set the system time."
 msgid "Authentication is required to reset NTP settings."
-msgstr "시스템 시간을 설정하려면 인증이 필요합니다."
+msgstr "NTP 설정을 재시작하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:132
 msgid "Revert DNS settings"
 msgstr "DNS 설정 되돌리기"
 
 #: src/network/org.freedesktop.network1.policy:133
-#, fuzzy
-#| msgid "Authentication is required to set the system time."
 msgid "Authentication is required to reset DNS settings."
-msgstr "시스템 시간을 설정하려면 인증이 필요합니다."
+msgstr "DNS 설정을 재시작하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:143
 msgid "DHCP server sends force renew message"
@@ -774,20 +740,16 @@ msgid "Reload network settings"
 msgstr "네트웍설정 다시 적재함"
 
 #: src/network/org.freedesktop.network1.policy:166
-#, fuzzy
-#| msgid "Authentication is required to reload the systemd state."
 msgid "Authentication is required to reload network settings."
-msgstr "systemd 상태를 다시 불러오려면 인증이 필요합니다."
+msgstr "네트웍 설정을 재적재하려면 인증이 필요합니다."
 
 #: src/network/org.freedesktop.network1.policy:176
 msgid "Reconfigure network interface"
 msgstr "네트워크 인터페이스 재설정"
 
 #: src/network/org.freedesktop.network1.policy:177
-#, fuzzy
-#| msgid "Authentication is required to reboot the system."
 msgid "Authentication is required to reconfigure network interface."
-msgstr "시스템을 다시 시작하려면 인증이 필요합니다."
+msgstr "네트웍 연결장치를 재설정하려면 인증이 필요합니다."
 
 #: src/portable/org.freedesktop.portable1.policy:13
 msgid "Inspect a portable service image"
@@ -802,11 +764,9 @@ msgid "Attach or detach a portable service image"
 msgstr "이동 서비스 첨부 또는 분리"
 
 #: src/portable/org.freedesktop.portable1.policy:24
-#, fuzzy
-#| msgid "Authentication is required to attach a device to a seat."
 msgid ""
 "Authentication is required to attach or detach a portable service image."
-msgstr "ì\8b\9cí\8a¸ì\97\90 ì\9e¥ì¹\98 ë¶\80ì°©ì\9d\84 í\97\88ì\9a©í\95\98려면 인증이 필요합니다."
+msgstr "ì\9d´ë\8f\99 ì\84\9cë¹\84ì\8a¤ ì\9e¥ì°© ë\98\90ë\8a\94 ë¶\84리ì\97\90ë\8a\94 인증이 필요합니다."
 
 #: src/portable/org.freedesktop.portable1.policy:34
 msgid "Delete or modify portable service image"
@@ -822,30 +782,24 @@ msgid "Register a DNS-SD service"
 msgstr "DNS-SD 서비스 등록"
 
 #: src/resolve/org.freedesktop.resolve1.policy:23
-#, fuzzy
-#| msgid "Authentication is required to set a wall message"
 msgid "Authentication is required to register a DNS-SD service"
-msgstr "wall 메시지를 설정하려면 인증이 필요합니다"
+msgstr "DNS-SD 서비스 등록에는 인증이 필요합니다"
 
 #: src/resolve/org.freedesktop.resolve1.policy:33
 msgid "Unregister a DNS-SD service"
 msgstr "DNS-SD 서비스 해제"
 
 #: src/resolve/org.freedesktop.resolve1.policy:34
-#, fuzzy
-#| msgid "Authentication is required to set a wall message"
 msgid "Authentication is required to unregister a DNS-SD service"
-msgstr "wall 메시지를 설정하려면 인증이 필요합니다"
+msgstr "DNS-SD 서비스 등록해제에는 인증이 필요합니다"
 
 #: src/resolve/org.freedesktop.resolve1.policy:132
 msgid "Revert name resolution settings"
 msgstr "이름 확인 설정 되돌리기"
 
 #: src/resolve/org.freedesktop.resolve1.policy:133
-#, fuzzy
-#| msgid "Authentication is required to set the system keyboard settings."
 msgid "Authentication is required to reset name resolution settings."
-msgstr "ì\8b\9cì\8a¤í\85\9c í\82¤ë³´ë\93\9c를 ì\84¤ì \95하려면 인증이 필요합니다."
+msgstr "ì\9d´ë¦\84 í\95´ê²° ì\84¤ì \95ì\9d\84 ì\9e¬ì\8b\9cì\9e\91하려면 인증이 필요합니다."
 
 #: src/timedate/org.freedesktop.timedate1.policy:22
 msgid "Set system time"
@@ -902,12 +856,10 @@ msgid "Authentication is required to restart '$(unit)'."
 msgstr "'$(unit)' 서비스 유닛을 다시 시작하려면 인증이 필요합니다."
 
 #: src/core/dbus-unit.c:535
-#, fuzzy
-#| msgid "Authentication is required to set properties on '$(unit)'."
 msgid ""
 "Authentication is required to send a UNIX signal to the processes of "
 "'$(unit)'."
-msgstr "'$(unit)' 서비스 유닛 속성을 설정하려면 인증이 필요합니다."
+msgstr "'$(unit)'의 처리에 유닉스 신호를 전송하려면 인증이 필요합니다."
 
 #: src/core/dbus-unit.c:566
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
@@ -918,21 +870,15 @@ msgid "Authentication is required to set properties on '$(unit)'."
 msgstr "'$(unit)' 서비스 유닛 속성을 설정하려면 인증이 필요합니다."
 
 #: src/core/dbus-unit.c:708
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgid ""
 "Authentication is required to delete files and directories associated with "
 "'$(unit)'."
-msgstr "'$(unit)' 서비스 유닛의 \"실패\" 상태를 되돌리려면 인증이 필요합니다."
+msgstr "'$(unit)' 과 함께 지정된 파일 또는 디렉토리 삭제에는 인증이 필요합니다."
 
 #: src/core/dbus-unit.c:757
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgid ""
 "Authentication is required to freeze or thaw the processes of '$(unit)' unit."
-msgstr "'$(unit)' 서비스 유닛의 \"실패\" 상태를 되돌리려면 인증이 필요합니다."
+msgstr "'$(unit)'단위의 처리를 동결 또는 해제하기 위해서는 인증이 필요합니다."
 
 #~ msgid "Authentication is required to kill '$(unit)'."
 #~ msgstr "'$(unit)' 서비스 유닛을 강제로 끝내려면 인증이 필요합니다."
diff --git a/po/nl.po b/po/nl.po
new file mode 100644 (file)
index 0000000..efd7f24
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,1015 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Pjotr Vertaalt <pjotrvertaalt@gmail.com>, 2021.
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-01-08 17:48+0100\n"
+"PO-Revision-Date: 2021-03-24 09:16+0000\n"
+"Last-Translator: Pjotr Vertaalt <pjotrvertaalt@gmail.com>\n"
+"Language-Team: Dutch <https://translate.fedoraproject.org/projects/systemd/"
+"master/nl/>\n"
+"Language: nl\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: Weblate 4.5.1\n"
+
+#: src/core/org.freedesktop.systemd1.policy.in:22
+msgid "Send passphrase back to system"
+msgstr "Stuur wachtwoordzin terug naar systeem"
+
+#: src/core/org.freedesktop.systemd1.policy.in:23
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr ""
+"Authenticatie is vereist voor het terugsturen van de ingevulde wachtwoordzin "
+"naar het systeem."
+
+#: src/core/org.freedesktop.systemd1.policy.in:33
+msgid "Manage system services or other units"
+msgstr "Beheer systeemdiensten of andere eenheden"
+
+#: src/core/org.freedesktop.systemd1.policy.in:34
+msgid "Authentication is required to manage system services or other units."
+msgstr ""
+"Authenticatie is vereist voor het beheren van systeemdiensten of andere "
+"eenheden."
+
+#: src/core/org.freedesktop.systemd1.policy.in:43
+msgid "Manage system service or unit files"
+msgstr "Beheer systeemdienst of eenheidbestanden"
+
+#: src/core/org.freedesktop.systemd1.policy.in:44
+msgid "Authentication is required to manage system service or unit files."
+msgstr ""
+"Authenticatie is vereist voor het beheren van systeemdienst of "
+"eenheidbestanden."
+
+#: src/core/org.freedesktop.systemd1.policy.in:54
+msgid "Set or unset system and service manager environment variables"
+msgstr "Stel omgevingsvariabelen in voor systeem en dienstenbeheerder"
+
+#: src/core/org.freedesktop.systemd1.policy.in:55
+msgid ""
+"Authentication is required to set or unset system and service manager "
+"environment variables."
+msgstr ""
+"Authenticatie is vereist voor het instellen van omgevingsvariabelen voor "
+"systeem en dienstenbeheerder."
+
+#: src/core/org.freedesktop.systemd1.policy.in:64
+msgid "Reload the systemd state"
+msgstr "Herlaad de status van systemd"
+
+#: src/core/org.freedesktop.systemd1.policy.in:65
+msgid "Authentication is required to reload the systemd state."
+msgstr "Authenticatie is vereist voor het herladen van de status van systemd."
+
+#: src/home/org.freedesktop.home1.policy:13
+msgid "Create a home area"
+msgstr "Maak een persoonlijke gebruikersmap"
+
+#: src/home/org.freedesktop.home1.policy:14
+msgid "Authentication is required to create a user's home area."
+msgstr ""
+"Authenticatie is vereist voor het maken van een persoonlijke gebruikersmap."
+
+#: src/home/org.freedesktop.home1.policy:23
+msgid "Remove a home area"
+msgstr "Verwijder een persoonlijke gebruikersmap"
+
+#: src/home/org.freedesktop.home1.policy:24
+msgid "Authentication is required to remove a user's home area."
+msgstr ""
+"Authenticatie is vereist voor het verwijderen van een persoonlijke "
+"gebruikersmap."
+
+#: src/home/org.freedesktop.home1.policy:33
+msgid "Check credentials of a home area"
+msgstr "Controleer de verificatiegegevens van een persoonlijke gebruikersmap"
+
+#: src/home/org.freedesktop.home1.policy:34
+msgid ""
+"Authentication is required to check credentials against a user's home area."
+msgstr ""
+"Authenticatie is vereist voor het controleren van verificatiegegevens voor "
+"een persoonlijke gebruikersmap."
+
+#: src/home/org.freedesktop.home1.policy:43
+msgid "Update a home area"
+msgstr "Werk een persoonlijke gebruikersmap bij"
+
+#: src/home/org.freedesktop.home1.policy:44
+msgid "Authentication is required to update a user's home area."
+msgstr ""
+"Authenticatie is vereist voor het bijwerken van een persoonlijke "
+"gebruikersmap."
+
+#: src/home/org.freedesktop.home1.policy:53
+msgid "Resize a home area"
+msgstr "Verander de grootte van een persoonlijke gebruikersmap"
+
+#: src/home/org.freedesktop.home1.policy:54
+msgid "Authentication is required to resize a user's home area."
+msgstr ""
+"Authenticatie is vereist voor het veranderen van de grootte van een "
+"persoonlijke gebruikersmap."
+
+#: src/home/org.freedesktop.home1.policy:63
+msgid "Change password of a home area"
+msgstr "Verander het wachtwoord van een persoonlijke gebruikersmap"
+
+#: src/home/org.freedesktop.home1.policy:64
+msgid ""
+"Authentication is required to change the password of a user's home area."
+msgstr ""
+"Authenticatie is vereist voor het wijzigen van het wachtwoord van een "
+"persoonlijke gebruikersmap."
+
+#: src/hostname/org.freedesktop.hostname1.policy:20
+msgid "Set hostname"
+msgstr "Stel computernaam in"
+
+#: src/hostname/org.freedesktop.hostname1.policy:21
+msgid "Authentication is required to set the local hostname."
+msgstr ""
+"Authenticatie is vereist voor het instellen van de plaatselijke computernaam."
+
+#: src/hostname/org.freedesktop.hostname1.policy:30
+msgid "Set static hostname"
+msgstr "Stel statische computernaam in"
+
+#: src/hostname/org.freedesktop.hostname1.policy:31
+msgid ""
+"Authentication is required to set the statically configured local hostname, "
+"as well as the pretty hostname."
+msgstr ""
+"Authenticatie is vereist voor het instellen van de statische plaatselijke "
+"computernaam en voor de 'mooie' computernaam."
+
+#: src/hostname/org.freedesktop.hostname1.policy:41
+msgid "Set machine information"
+msgstr "Stel machine-informatie in"
+
+#: src/hostname/org.freedesktop.hostname1.policy:42
+msgid "Authentication is required to set local machine information."
+msgstr ""
+"Authenticatie is vereist voor het instellen van de plaatselijke machine-"
+"informatie."
+
+#: src/hostname/org.freedesktop.hostname1.policy:51
+msgid "Get product UUID"
+msgstr "Verkrijg de UUID van het product"
+
+#: src/hostname/org.freedesktop.hostname1.policy:52
+msgid "Authentication is required to get product UUID."
+msgstr ""
+"Authenticatie is vereist voor het verkrijgen van de UUID van het product."
+
+#: src/import/org.freedesktop.import1.policy:22
+msgid "Import a VM or container image"
+msgstr "Importeer een VM of een container-schijfkopie"
+
+#: src/import/org.freedesktop.import1.policy:23
+msgid "Authentication is required to import a VM or container image"
+msgstr ""
+"Authenticatie is vereist voor het importeren van een VM of een container-"
+"schijfkopie"
+
+#: src/import/org.freedesktop.import1.policy:32
+msgid "Export a VM or container image"
+msgstr "Exporteer een VM of een container-schijfkopie"
+
+#: src/import/org.freedesktop.import1.policy:33
+msgid "Authentication is required to export a VM or container image"
+msgstr ""
+"Authenticatie is vereist voor het exporteren van een VM of container-"
+"schijfkopie"
+
+#: src/import/org.freedesktop.import1.policy:42
+msgid "Download a VM or container image"
+msgstr "Haal een VM of container-schijfkopie binnen"
+
+#: src/import/org.freedesktop.import1.policy:43
+msgid "Authentication is required to download a VM or container image"
+msgstr ""
+"Authenticatie is vereist voor het binnenhalen van een VM of container-"
+"schijfkopie"
+
+#: src/locale/org.freedesktop.locale1.policy:22
+msgid "Set system locale"
+msgstr "Stel de systeemtaal in"
+
+#: src/locale/org.freedesktop.locale1.policy:23
+msgid "Authentication is required to set the system locale."
+msgstr "Authenticatie is vereist voor het instellen van de systeemtaal."
+
+#: src/locale/org.freedesktop.locale1.policy:33
+msgid "Set system keyboard settings"
+msgstr "Stel de instellingen in van het systeemtoetsenbord"
+
+#: src/locale/org.freedesktop.locale1.policy:34
+msgid "Authentication is required to set the system keyboard settings."
+msgstr ""
+"Authenticatie is vereist voor het instellen van de configuratie van het "
+"systeemtoetsenbord."
+
+#: src/login/org.freedesktop.login1.policy:22
+msgid "Allow applications to inhibit system shutdown"
+msgstr "Sta toepassingen toe om afsluiten van het systeem te verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:23
+msgid ""
+"Authentication is required for an application to inhibit system shutdown."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing afsluiten van het systeem "
+"kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:33
+msgid "Allow applications to delay system shutdown"
+msgstr "Sta toepassingen toe om afsluiten van het systeem uit te stellen"
+
+#: src/login/org.freedesktop.login1.policy:34
+msgid "Authentication is required for an application to delay system shutdown."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing het afsluiten van het "
+"systeem kan uitstellen."
+
+#: src/login/org.freedesktop.login1.policy:44
+msgid "Allow applications to inhibit system sleep"
+msgstr "Sta toepassingen toe om slaapstand van het systeem te verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:45
+msgid "Authentication is required for an application to inhibit system sleep."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing slaapstand van het systeem "
+"kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:55
+msgid "Allow applications to delay system sleep"
+msgstr "Sta toepassingen toe om slaapstand van het systeem uit te stellen"
+
+#: src/login/org.freedesktop.login1.policy:56
+msgid "Authentication is required for an application to delay system sleep."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing slaapstand van het systeem "
+"kan uitstellen."
+
+#: src/login/org.freedesktop.login1.policy:65
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr ""
+"Sta toepassingen toe om automatische pauzestand van het systeem te "
+"verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:66
+msgid ""
+"Authentication is required for an application to inhibit automatic system "
+"suspend."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing automatische pauzestand van "
+"het systeem kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:75
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr ""
+"Sta toepassingen toe om het bedienen van de aan/uit-toets door het systeem "
+"te verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:76
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the power key."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing het bedienen van de aan/uit-"
+"toets door het systeem kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:86
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr ""
+"Sta toepassingen toe om bediening door het systeem van de pauzestandtoets te "
+"verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:87
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the suspend key."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing de bediening door het "
+"systeem van de pauzestandtoets kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:97
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr ""
+"Sta toepassingen toe om behandeling door het systeem van de slaapstandtoets "
+"te verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:98
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the hibernate key."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing de behandeling door het "
+"systeem van de slaapstandtoets kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:107
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr ""
+"Sta toepassingen toe om de behandeling door het systeem van de "
+"klepschakelaar te verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:108
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the lid switch."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing de behandeling door het "
+"systeem van de klepschakelaar kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:117
+msgid "Allow applications to inhibit system handling of the reboot key"
+msgstr ""
+"Sta toepassingen toe om de behandeling door het systeem van de herstarttoets "
+"te verhinderen"
+
+#: src/login/org.freedesktop.login1.policy:118
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the reboot key."
+msgstr ""
+"Authenticatie is vereist alvorens een toepassing de behandeling door het "
+"systeem van de herstarttoets kan verhinderen."
+
+#: src/login/org.freedesktop.login1.policy:128
+msgid "Allow non-logged-in user to run programs"
+msgstr "Sta niet-aangemelde gebruiker toe om programma's te draaien"
+
+#: src/login/org.freedesktop.login1.policy:129
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Expliciet verzoek is vereist om programma's te draaien als een niet-"
+"aangemelde gebruiker."
+
+#: src/login/org.freedesktop.login1.policy:138
+msgid "Allow non-logged-in users to run programs"
+msgstr "Sta niet-aangemelde gebruikers toe om programma's te draaien"
+
+#: src/login/org.freedesktop.login1.policy:139
+msgid "Authentication is required to run programs as a non-logged-in user."
+msgstr ""
+"Authenticatie is vereist alvorens een niet-aangemelde gebruiker programma's "
+"kan draaien."
+
+#: src/login/org.freedesktop.login1.policy:148
+msgid "Allow attaching devices to seats"
+msgstr "Sta het verbinden van apparaten aan zittingen toe"
+
+#: src/login/org.freedesktop.login1.policy:149
+msgid "Authentication is required to attach a device to a seat."
+msgstr ""
+"Authenticatie is vereist voor het verbinden van een apparaat aan een zitting."
+
+#: src/login/org.freedesktop.login1.policy:159
+msgid "Flush device to seat attachments"
+msgstr "Verwijder alle apparaat-zitting-koppelingen"
+
+#: src/login/org.freedesktop.login1.policy:160
+msgid "Authentication is required to reset how devices are attached to seats."
+msgstr ""
+"Authenticatie is vereist voor het terugzetten van de wijze waarop apparaten "
+"zijn verbonden aan zittingen."
+
+#: src/login/org.freedesktop.login1.policy:169
+msgid "Power off the system"
+msgstr "Sluit het systeem af"
+
+#: src/login/org.freedesktop.login1.policy:170
+msgid "Authentication is required to power off the system."
+msgstr "Authenticatie is vereist voor het afsluiten van het systeem."
+
+#: src/login/org.freedesktop.login1.policy:180
+msgid "Power off the system while other users are logged in"
+msgstr "Sluit het systeem af terwijl er nog andere gebruikers zijn aangemeld"
+
+#: src/login/org.freedesktop.login1.policy:181
+msgid ""
+"Authentication is required to power off the system while other users are "
+"logged in."
+msgstr ""
+"Authenticatie is vereist voor het afsluiten van het systeem terwijl er nog "
+"andere gebruikers zijn aangemeld."
+
+#: src/login/org.freedesktop.login1.policy:191
+msgid "Power off the system while an application is inhibiting this"
+msgstr "Sluit het systeem af terwijl er een toepassing is die dit verhindert"
+
+#: src/login/org.freedesktop.login1.policy:192
+msgid ""
+"Authentication is required to power off the system while an application is "
+"inhibiting this."
+msgstr ""
+"Authenticatie is vereist voor het afsluiten van het systeem terwijl er een "
+"toepassing is die dit verhindert."
+
+#: src/login/org.freedesktop.login1.policy:202
+msgid "Reboot the system"
+msgstr "Herstart het systeem"
+
+#: src/login/org.freedesktop.login1.policy:203
+msgid "Authentication is required to reboot the system."
+msgstr "Authenticatie is vereist voor het herstarten van het systeem."
+
+#: src/login/org.freedesktop.login1.policy:213
+msgid "Reboot the system while other users are logged in"
+msgstr "Herstart het systeem terwijl er nog andere gebruikers zijn aangemeld"
+
+#: src/login/org.freedesktop.login1.policy:214
+msgid ""
+"Authentication is required to reboot the system while other users are logged "
+"in."
+msgstr ""
+"Authenticatie is vereist voor het herstarten van het systeem terwijl er nog "
+"andere gebruikers zijn aangemeld."
+
+#: src/login/org.freedesktop.login1.policy:224
+msgid "Reboot the system while an application is inhibiting this"
+msgstr "Herstart het systeem terwijl er een toepassing is die dit verhindert"
+
+#: src/login/org.freedesktop.login1.policy:225
+msgid ""
+"Authentication is required to reboot the system while an application is "
+"inhibiting this."
+msgstr ""
+"Authenticatie is vereist voor het herstarten van het systeem terwijl er een "
+"toepassing is die dit verhindert."
+
+#: src/login/org.freedesktop.login1.policy:235
+msgid "Halt the system"
+msgstr "Zet het systeem stil"
+
+#: src/login/org.freedesktop.login1.policy:236
+msgid "Authentication is required to halt the system."
+msgstr "Authenticatie is vereist voor het stilzetten van het systeem."
+
+#: src/login/org.freedesktop.login1.policy:246
+msgid "Halt the system while other users are logged in"
+msgstr "Zet het systeem stil terwijl er nog andere gebruikers zijn aangemeld"
+
+#: src/login/org.freedesktop.login1.policy:247
+msgid ""
+"Authentication is required to halt the system while other users are logged "
+"in."
+msgstr ""
+"Authenticatie is vereist voor het stilzetten van het systeem terwijl er nog "
+"andere gebruikers zijn aangemeld."
+
+#: src/login/org.freedesktop.login1.policy:257
+msgid "Halt the system while an application is inhibiting this"
+msgstr "Zet het systeem stil terwijl er een toepassing is die dit verhindert"
+
+#: src/login/org.freedesktop.login1.policy:258
+msgid ""
+"Authentication is required to halt the system while an application is "
+"inhibiting this."
+msgstr ""
+"Authenticatie is vereist voor het stilzetten van het systeem terwijl er een "
+"toepassing is die dit verhindert."
+
+#: src/login/org.freedesktop.login1.policy:268
+msgid "Suspend the system"
+msgstr "Breng het systeem in pauzestand"
+
+#: src/login/org.freedesktop.login1.policy:269
+msgid "Authentication is required to suspend the system."
+msgstr ""
+"Authenticatie is vereist voor het in pauzestand brengen van het systeem."
+
+#: src/login/org.freedesktop.login1.policy:278
+msgid "Suspend the system while other users are logged in"
+msgstr ""
+"Breng het systeem in pauzestand terwijl er nog andere gebruikers zijn "
+"aangemeld"
+
+#: src/login/org.freedesktop.login1.policy:279
+msgid ""
+"Authentication is required to suspend the system while other users are "
+"logged in."
+msgstr ""
+"Authenticatie is vereist voor het in pauzestand brengen van het systeem "
+"terwijl er nog andere gebruikers zijn aangemeld."
+
+#: src/login/org.freedesktop.login1.policy:289
+msgid "Suspend the system while an application is inhibiting this"
+msgstr ""
+"Breng het systeem in pauzestand terwijl er een toepassing is die dit "
+"verhindert"
+
+#: src/login/org.freedesktop.login1.policy:290
+msgid ""
+"Authentication is required to suspend the system while an application is "
+"inhibiting this."
+msgstr ""
+"Authenticatie is vereist voor het in pauzestand brengen van het systeem "
+"terwijl er een toepassing is die dit verhindert."
+
+#: src/login/org.freedesktop.login1.policy:300
+msgid "Hibernate the system"
+msgstr "Breng het systeem in slaapstand"
+
+#: src/login/org.freedesktop.login1.policy:301
+msgid "Authentication is required to hibernate the system."
+msgstr ""
+"Authenticatie is vereist voor het in slaapstand brengen van het systeem."
+
+#: src/login/org.freedesktop.login1.policy:310
+msgid "Hibernate the system while other users are logged in"
+msgstr ""
+"Breng het systeem in slaapstand terwijl er nog andere gebruikers zijn "
+"aangemeld"
+
+#: src/login/org.freedesktop.login1.policy:311
+msgid ""
+"Authentication is required to hibernate the system while other users are "
+"logged in."
+msgstr ""
+"Authenticatie is vereist voor het in slaapstand brengen van het systeem "
+"terwijl er nog andere gebruikers zijn aangemeld."
+
+#: src/login/org.freedesktop.login1.policy:321
+msgid "Hibernate the system while an application is inhibiting this"
+msgstr ""
+"Breng het systeem in slaapstand terwijl er een toepassing is die dit "
+"verhindert"
+
+#: src/login/org.freedesktop.login1.policy:322
+msgid ""
+"Authentication is required to hibernate the system while an application is "
+"inhibiting this."
+msgstr ""
+"Authenticatie is vereist voor het in slaapstand brengen van het systeem "
+"terwijl er een toepassing is die dit verhindert."
+
+#: src/login/org.freedesktop.login1.policy:332
+msgid "Manage active sessions, users and seats"
+msgstr "Beheer actieve sessies, gebruikers en zittingen"
+
+#: src/login/org.freedesktop.login1.policy:333
+msgid "Authentication is required to manage active sessions, users and seats."
+msgstr ""
+"Authenticatie is vereist voor het beheren van actieve sessies, gebruikers en "
+"zittingen."
+
+#: src/login/org.freedesktop.login1.policy:342
+msgid "Lock or unlock active sessions"
+msgstr "Vergrendel of ontgrendel actieve sessies"
+
+#: src/login/org.freedesktop.login1.policy:343
+msgid "Authentication is required to lock or unlock active sessions."
+msgstr ""
+"Authenticatie is vereist voor het vergrendelen of ontgrendelen van actieve "
+"sessies."
+
+#: src/login/org.freedesktop.login1.policy:352
+msgid "Set the reboot \"reason\" in the kernel"
+msgstr "Stel de herstart-'reden' in de systeemkern in"
+
+#: src/login/org.freedesktop.login1.policy:353
+msgid "Authentication is required to set the reboot \"reason\" in the kernel."
+msgstr ""
+"Authenticatie is vereist voor het instellen van de herstart-'reden' in de "
+"systeemkern."
+
+#: src/login/org.freedesktop.login1.policy:363
+msgid "Indicate to the firmware to boot to setup interface"
+msgstr ""
+"Geef aan de firmware aan om op te starten ten einde een apparaat in te "
+"stellen"
+
+#: src/login/org.freedesktop.login1.policy:364
+msgid ""
+"Authentication is required to indicate to the firmware to boot to setup "
+"interface."
+msgstr ""
+"Authenticatie is vereist voor het aangeven aan de firmware dat die moet "
+"opstarten om een apparaat in te stellen."
+
+#: src/login/org.freedesktop.login1.policy:374
+msgid "Indicate to the boot loader to boot to the boot loader menu"
+msgstr ""
+"Geef aan de opstartlader aan dat die moet opstarten naar het opstartmenu"
+
+#: src/login/org.freedesktop.login1.policy:375
+msgid ""
+"Authentication is required to indicate to the boot loader to boot to the "
+"boot loader menu."
+msgstr ""
+"Authenticatie is vereist voor het aangeven aan de opstartlader dat die moet "
+"opstarten naar het opstartmenu."
+
+#: src/login/org.freedesktop.login1.policy:385
+msgid "Indicate to the boot loader to boot a specific entry"
+msgstr ""
+"Geef aan de opstartlader aan dat die een bepaalde vermelding moet opstarten"
+
+#: src/login/org.freedesktop.login1.policy:386
+msgid ""
+"Authentication is required to indicate to the boot loader to boot into a "
+"specific boot loader entry."
+msgstr ""
+"Authenticatie is vereist voor het aangeven aan de opstartlader dat die een "
+"bepaalde opstartvermelding moet opstarten."
+
+#: src/login/org.freedesktop.login1.policy:396
+msgid "Set a wall message"
+msgstr "Stel een gebruikersmuurboodschap in"
+
+#: src/login/org.freedesktop.login1.policy:397
+msgid "Authentication is required to set a wall message"
+msgstr ""
+"Authenticatie is vereist voor het instellen van een gebruikersmuurboodschap"
+
+#: src/login/org.freedesktop.login1.policy:406
+msgid "Change Session"
+msgstr "Verander van sessie"
+
+#: src/login/org.freedesktop.login1.policy:407
+msgid "Authentication is required to change the virtual terminal."
+msgstr "Authenticatie is vereist voor het wijzigen van de virtuele terminal."
+
+#: src/machine/org.freedesktop.machine1.policy:22
+msgid "Log into a local container"
+msgstr "Meld aan bij een plaatselijke container"
+
+#: src/machine/org.freedesktop.machine1.policy:23
+msgid "Authentication is required to log into a local container."
+msgstr ""
+"Authenticatie is vereist voor het aanmelden bij een plaatselijke container."
+
+#: src/machine/org.freedesktop.machine1.policy:32
+msgid "Log into the local host"
+msgstr "Meld aan bij de plaatselijke computer"
+
+#: src/machine/org.freedesktop.machine1.policy:33
+msgid "Authentication is required to log into the local host."
+msgstr ""
+"Authenticatie is vereist voor het aanmelden bij de plaatselijke computer."
+
+#: src/machine/org.freedesktop.machine1.policy:42
+msgid "Acquire a shell in a local container"
+msgstr "Verkrijg een bedieningsvenster in een plaatselijke container"
+
+#: src/machine/org.freedesktop.machine1.policy:43
+msgid "Authentication is required to acquire a shell in a local container."
+msgstr ""
+"Authenticatie is vereist voor het verkrijgen van een bedieningsvenster in "
+"een plaatselijke container."
+
+#: src/machine/org.freedesktop.machine1.policy:53
+msgid "Acquire a shell on the local host"
+msgstr "Verkrijg een bedieningsvenster op de plaatselijke computer"
+
+#: src/machine/org.freedesktop.machine1.policy:54
+msgid "Authentication is required to acquire a shell on the local host."
+msgstr ""
+"Authenticatie is vereist voor het verkrijgen van een bedieningsvenster op de "
+"plaatselijke computer."
+
+#: src/machine/org.freedesktop.machine1.policy:64
+msgid "Acquire a pseudo TTY in a local container"
+msgstr "Verkrijg een pseudo-TTY in een plaatselijke container"
+
+#: src/machine/org.freedesktop.machine1.policy:65
+msgid ""
+"Authentication is required to acquire a pseudo TTY in a local container."
+msgstr ""
+"Authenticatie is vereist voor het verkrijgen van een pseudo-TTY in een "
+"plaatselijke container."
+
+#: src/machine/org.freedesktop.machine1.policy:74
+msgid "Acquire a pseudo TTY on the local host"
+msgstr "Verkrijg een pseudo-TTY op de plaatselijke computer"
+
+#: src/machine/org.freedesktop.machine1.policy:75
+msgid "Authentication is required to acquire a pseudo TTY on the local host."
+msgstr ""
+"Authenticatie is vereist voor het verkrijgen van een pseudo-TTY op de "
+"plaatselijke computer."
+
+#: src/machine/org.freedesktop.machine1.policy:84
+msgid "Manage local virtual machines and containers"
+msgstr "Beheer lokale virtuele machines en containers"
+
+#: src/machine/org.freedesktop.machine1.policy:85
+msgid ""
+"Authentication is required to manage local virtual machines and containers."
+msgstr ""
+"Authenticatie is vereist voor het beheren van lokale virtuele machines en "
+"containers."
+
+#: src/machine/org.freedesktop.machine1.policy:95
+msgid "Manage local virtual machine and container images"
+msgstr "Beheer plaatselijke virtuele machine en container-schijfkopieën"
+
+#: src/machine/org.freedesktop.machine1.policy:96
+msgid ""
+"Authentication is required to manage local virtual machine and container "
+"images."
+msgstr ""
+"Authenticatie is vereist voor het beheren van plaatselijke virtuele machine "
+"en container-schijfkopieën."
+
+#: src/network/org.freedesktop.network1.policy:22
+msgid "Set NTP servers"
+msgstr "Stel NTP-servers in"
+
+#: src/network/org.freedesktop.network1.policy:23
+msgid "Authentication is required to set NTP servers."
+msgstr "Authenticatie is vereist voor het instellen van NTP-servers."
+
+#: src/network/org.freedesktop.network1.policy:33
+#: src/resolve/org.freedesktop.resolve1.policy:44
+msgid "Set DNS servers"
+msgstr "Stel DNS-servers in"
+
+#: src/network/org.freedesktop.network1.policy:34
+#: src/resolve/org.freedesktop.resolve1.policy:45
+msgid "Authentication is required to set DNS servers."
+msgstr "Authenticatie is vereist voor het instellen van DNS-servers."
+
+#: src/network/org.freedesktop.network1.policy:44
+#: src/resolve/org.freedesktop.resolve1.policy:55
+msgid "Set domains"
+msgstr "Stel domeinen in"
+
+#: src/network/org.freedesktop.network1.policy:45
+#: src/resolve/org.freedesktop.resolve1.policy:56
+msgid "Authentication is required to set domains."
+msgstr "Authenticatie is vereist voor het instellen van domeinen."
+
+#: src/network/org.freedesktop.network1.policy:55
+#: src/resolve/org.freedesktop.resolve1.policy:66
+msgid "Set default route"
+msgstr "Stel standaardroute in"
+
+#: src/network/org.freedesktop.network1.policy:56
+#: src/resolve/org.freedesktop.resolve1.policy:67
+msgid "Authentication is required to set default route."
+msgstr "Authenticatie is vereist voor het instellen van een standaardroute."
+
+#: src/network/org.freedesktop.network1.policy:66
+#: src/resolve/org.freedesktop.resolve1.policy:77
+msgid "Enable/disable LLMNR"
+msgstr "Schakel LLMNR in of uit"
+
+#: src/network/org.freedesktop.network1.policy:67
+#: src/resolve/org.freedesktop.resolve1.policy:78
+msgid "Authentication is required to enable or disable LLMNR."
+msgstr "Authenticatie is vereist voor het in- of uitschakelen van LLMNR."
+
+#: src/network/org.freedesktop.network1.policy:77
+#: src/resolve/org.freedesktop.resolve1.policy:88
+msgid "Enable/disable multicast DNS"
+msgstr "Schakel multicast-DNS in of uit"
+
+#: src/network/org.freedesktop.network1.policy:78
+#: src/resolve/org.freedesktop.resolve1.policy:89
+msgid "Authentication is required to enable or disable multicast DNS."
+msgstr ""
+"Authenticatie is vereist voor het in- of uitschakelen van multicast-DNS."
+
+#: src/network/org.freedesktop.network1.policy:88
+#: src/resolve/org.freedesktop.resolve1.policy:99
+msgid "Enable/disable DNS over TLS"
+msgstr "Schakel DNS over TLS in of uit"
+
+#: src/network/org.freedesktop.network1.policy:89
+#: src/resolve/org.freedesktop.resolve1.policy:100
+msgid "Authentication is required to enable or disable DNS over TLS."
+msgstr ""
+"Authenticatie is vereist voor het inschakelen of uitschakelen van DNS over "
+"TLS."
+
+#: src/network/org.freedesktop.network1.policy:99
+#: src/resolve/org.freedesktop.resolve1.policy:110
+msgid "Enable/disable DNSSEC"
+msgstr "Schakel DNSSEC in of uit"
+
+#: src/network/org.freedesktop.network1.policy:100
+#: src/resolve/org.freedesktop.resolve1.policy:111
+msgid "Authentication is required to enable or disable DNSSEC."
+msgstr "Authenticatie is vereist voor het in- of uitschakelen van DNSSEC."
+
+#: src/network/org.freedesktop.network1.policy:110
+#: src/resolve/org.freedesktop.resolve1.policy:121
+msgid "Set DNSSEC Negative Trust Anchors"
+msgstr "Stel DNSSEC Negative Trust Anchors in"
+
+#: src/network/org.freedesktop.network1.policy:111
+#: src/resolve/org.freedesktop.resolve1.policy:122
+msgid "Authentication is required to set DNSSEC Negative Trust Anchors."
+msgstr ""
+"Authenticatie is vereist voor het instellen van DNSSEC Negative Trust "
+"Anchors."
+
+#: src/network/org.freedesktop.network1.policy:121
+msgid "Revert NTP settings"
+msgstr "Draai NTP-instellingen terug"
+
+#: src/network/org.freedesktop.network1.policy:122
+msgid "Authentication is required to reset NTP settings."
+msgstr "Authenticatie is vereist voor het terugzetten van NTP-instellingen."
+
+#: src/network/org.freedesktop.network1.policy:132
+msgid "Revert DNS settings"
+msgstr "Draai DNS-instellingen terug"
+
+#: src/network/org.freedesktop.network1.policy:133
+msgid "Authentication is required to reset DNS settings."
+msgstr "Authenticatie is vereist voor het terugzetten van DNS-instellingen."
+
+#: src/network/org.freedesktop.network1.policy:143
+msgid "DHCP server sends force renew message"
+msgstr "DHCP-server verstuurt 'gedwongen hernieuwing'-boodschap"
+
+#: src/network/org.freedesktop.network1.policy:144
+msgid "Authentication is required to send force renew message."
+msgstr ""
+"Authenticatie is vereist voor het verzenden van een 'gedwongen "
+"hernieuwing'-boodschap."
+
+#: src/network/org.freedesktop.network1.policy:154
+msgid "Renew dynamic addresses"
+msgstr "Hernieuw dynamische adressen"
+
+#: src/network/org.freedesktop.network1.policy:155
+msgid "Authentication is required to renew dynamic addresses."
+msgstr "Authenticatie is vereist voor het hernieuwen van dynamische adressen."
+
+#: src/network/org.freedesktop.network1.policy:165
+msgid "Reload network settings"
+msgstr "Herlaad netwerkinstellingen"
+
+#: src/network/org.freedesktop.network1.policy:166
+msgid "Authentication is required to reload network settings."
+msgstr "Authenticatie is vereist voor het herladen van netwerkinstellingen."
+
+#: src/network/org.freedesktop.network1.policy:176
+msgid "Reconfigure network interface"
+msgstr "Stel netwerkkaart opnieuw in"
+
+#: src/network/org.freedesktop.network1.policy:177
+msgid "Authentication is required to reconfigure network interface."
+msgstr ""
+"Authenticatie is vereist voor het opnieuw instellen van de netwerkkaart."
+
+#: src/portable/org.freedesktop.portable1.policy:13
+msgid "Inspect a portable service image"
+msgstr "Inspecteer een portable service schijfkopie"
+
+#: src/portable/org.freedesktop.portable1.policy:14
+msgid "Authentication is required to inspect a portable service image."
+msgstr ""
+"Authenticatie is vereist voor het inspecteren van een portable service "
+"schijfkopie."
+
+#: src/portable/org.freedesktop.portable1.policy:23
+msgid "Attach or detach a portable service image"
+msgstr "Koppel een portable service schijfkopie aan of af"
+
+#: src/portable/org.freedesktop.portable1.policy:24
+msgid ""
+"Authentication is required to attach or detach a portable service image."
+msgstr ""
+"Authenticatie is vereist voor het aan- of afkoppelen van een portable "
+"service schijfkopie."
+
+#: src/portable/org.freedesktop.portable1.policy:34
+msgid "Delete or modify portable service image"
+msgstr "Verwijder of wijzig een portable service schijfkopie"
+
+#: src/portable/org.freedesktop.portable1.policy:35
+msgid ""
+"Authentication is required to delete or modify a portable service image."
+msgstr ""
+"Authenticatie is vereist voor het verwijderen of aanpassen van een portable "
+"service schijfkopie."
+
+#: src/resolve/org.freedesktop.resolve1.policy:22
+msgid "Register a DNS-SD service"
+msgstr "Registreer een DNS-SD-dienst"
+
+#: src/resolve/org.freedesktop.resolve1.policy:23
+msgid "Authentication is required to register a DNS-SD service"
+msgstr "Authenticatie is vereist voor het registreren van een DNS-SD-dienst"
+
+#: src/resolve/org.freedesktop.resolve1.policy:33
+msgid "Unregister a DNS-SD service"
+msgstr "Ontregistreer een DNS-SD-dienst"
+
+#: src/resolve/org.freedesktop.resolve1.policy:34
+msgid "Authentication is required to unregister a DNS-SD service"
+msgstr "Authenticatie is vereist voor het ontregistreren van een DNS-SD-dienst"
+
+#: src/resolve/org.freedesktop.resolve1.policy:132
+msgid "Revert name resolution settings"
+msgstr "Draai instellingen voor naamoplossing terug"
+
+#: src/resolve/org.freedesktop.resolve1.policy:133
+msgid "Authentication is required to reset name resolution settings."
+msgstr ""
+"Authenticatie is vereist voor het terugzetten van de instellingen voor "
+"naamoplossing."
+
+#: src/timedate/org.freedesktop.timedate1.policy:22
+msgid "Set system time"
+msgstr "Stel systeemtijd in"
+
+#: src/timedate/org.freedesktop.timedate1.policy:23
+msgid "Authentication is required to set the system time."
+msgstr "Authenticatie is vereist voor het instellen van de systeemtijd."
+
+#: src/timedate/org.freedesktop.timedate1.policy:33
+msgid "Set system timezone"
+msgstr "Stel de tijdzone van het systeem in"
+
+#: src/timedate/org.freedesktop.timedate1.policy:34
+msgid "Authentication is required to set the system timezone."
+msgstr ""
+"Authenticatie is vereist voor het instellen van de tijdzone van het systeem."
+
+#: src/timedate/org.freedesktop.timedate1.policy:43
+msgid "Set RTC to local timezone or UTC"
+msgstr "Stel RTC in op plaatselijke tijdzone of UTC"
+
+#: src/timedate/org.freedesktop.timedate1.policy:44
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+"Authenticatie is vereist voor het bepalen of RTC de plaatselijke tijd of de "
+"UTC-tijd opslaat."
+
+#: src/timedate/org.freedesktop.timedate1.policy:53
+msgid "Turn network time synchronization on or off"
+msgstr "Schakel netwerktijdsynchronisatie in of uit"
+
+#: src/timedate/org.freedesktop.timedate1.policy:54
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Authenticatie is vereist voor het bepalen of netwerktijdsynchronisatie "
+"ingeschakeld zal zijn."
+
+#: src/core/dbus-unit.c:359
+msgid "Authentication is required to start '$(unit)'."
+msgstr "Authenticatie is vereist voor het starten van '$(unit)'."
+
+#: src/core/dbus-unit.c:360
+msgid "Authentication is required to stop '$(unit)'."
+msgstr "Authenticatie is vereist voor het stilzetten van '$(unit)'."
+
+#: src/core/dbus-unit.c:361
+msgid "Authentication is required to reload '$(unit)'."
+msgstr "Authenticatie is vereist voor het herladen van '$(unit)'."
+
+#: src/core/dbus-unit.c:362 src/core/dbus-unit.c:363
+msgid "Authentication is required to restart '$(unit)'."
+msgstr "Authenticatie is vereist voor het herstarten van '$(unit)'."
+
+#: src/core/dbus-unit.c:535
+msgid ""
+"Authentication is required to send a UNIX signal to the processes of "
+"'$(unit)'."
+msgstr ""
+"Authenticatie is vereist voor het zenden van een UNIX-signaal naar de "
+"processen van '$(unit)'."
+
+#: src/core/dbus-unit.c:566
+msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
+msgstr ""
+"Authenticatie is vereist voor het terugzetten van de 'mislukt'-status van "
+"'$(unit)'."
+
+#: src/core/dbus-unit.c:599
+msgid "Authentication is required to set properties on '$(unit)'."
+msgstr ""
+"Authenticatie is vereist voor het instellen van eigenschappen op '$(unit)'."
+
+#: src/core/dbus-unit.c:708
+msgid ""
+"Authentication is required to delete files and directories associated with "
+"'$(unit)'."
+msgstr ""
+"Authenticatie is vereist voor het verwijderen van bestanden en mappen die "
+"verbonden zijn aan '$(unit)'."
+
+#: src/core/dbus-unit.c:757
+msgid ""
+"Authentication is required to freeze or thaw the processes of '$(unit)' unit."
+msgstr ""
+"Authenticatie is vereist voor het bevriezen of ontdooien van de processen "
+"van '$(unit)' unit."
diff --git a/rules.d/README b/rules.d/README
new file mode 100644 (file)
index 0000000..294d6ee
--- /dev/null
@@ -0,0 +1,8 @@
+Files in this directory contain configuration for systemd-udev.service, a
+daemon that manages symlinks to device nodes, permissions of devices nodes,
+emits device events for userspace, and renames network interfaces.
+
+See man:udev(7) for an overview of the configuration file format, and
+man:systemd-udevd.service(8) for a description of service itself.
+
+Use 'systemd-analyze cat-config udev/rules.d' to display the effective config.
index d29564513da1567e6559b034622901d1430ae158..42fa451c6bac73102697dfb71e90dfa4fa6fb87b 100644 (file)
@@ -1,5 +1,9 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
+install_data(
+        'README',
+        install_dir : udevrulesdir)
+
 rules = files('''
         60-autosuspend.rules
         60-block.rules
index 884065187bbdc376f7e26b3b79006551ace05eca..c5db8b77bd8f3dbee88a07494fdd47a8360e2ff0 100644 (file)
@@ -31,20 +31,20 @@ __get_machines() {
 
 _systemd_run() {
     local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-    local OPTS='-h --help --version --user --system --scope --unit --description --slice
-                -r --remain-after-exit --send-sighup -H --host -M --machine --service-type
-                --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive
-                --on-calendar --timer-property --path-property --socket-property -t --pty
-                -q --quiet --no-block --uid --gid --nice -E --setenv -p --property
-                --no-ask-password --wait -P --pipe -G --collect --working-directory
-                -d --same-dir -S --shell'
+    local OPTS='--no-ask-password --scope -u --unit -p --property --description --slice --slice-inherit
+                -r --remain-after-exit --send-sighup --service-type --uid --gid --nice
+                --working-directory -d --same-dir -E --setenv -t --pty -P --pipe -S --shell -q --quiet
+                --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar
+                --on-clock-change --on-timezone-change --path-property --socket-property
+                --timer-property --no-block --wait -G --collect --user --system -H --host -M --machine
+                -h --help --version'
 
     local mode=--system
     local i
     local opts_with_values=(
-        --unit --description --slice --service-type -H --host -M --machine -p --property --on-active
-        --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar --timer-property
-        --path-property --socket-property --uid --gid --nice -E --setenv --working-directory
+        --unit -p --property --slice --description --service-type --uid --gid --nice --working-directory
+        -E --setenv --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar
+        --path-property --socket-property --timer-property -H --host -M --machine
     )
     for (( i=1; i <= COMP_CWORD; i++ )); do
         if [[ ${COMP_WORDS[i]} != -* ]]; then
@@ -78,7 +78,7 @@ _systemd_run() {
         -p|--property)
             local comps='CPUAccounting= MemoryAccounting= BlockIOAccounting= SendSIGHUP=
                          SendSIGKILL= MemoryLimit= CPUShares= BlockIOWeight= User= Group=
-                         DevicePolicy= KillMode= DeviceAllow= BlockIOReadBandwidth=
+                         DevicePolicy= KillMode= ExitType= DeviceAllow= BlockIOReadBandwidth=
                          BlockIOWriteBandwidth= BlockIODeviceWeight= Nice= Environment=
                          KillSignal= RestartKillSignal= FinalKillSignal= LimitCPU= LimitFSIZE= LimitDATA=
                          LimitSTACK= LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC=
index d9998e5dfb15ad9942177a277c68e76e841ce2a5..d7af226105e7ad86180ec4f4b179373e2923e7b2 100644 (file)
@@ -23,17 +23,29 @@ __systemctl() {
     }
 
 _arguments \
+    {-G,--collect}'[Unload the transient unit after it completed]' \
+    '--description=[Description for unit]:description' \
+    '--gid=[Run as system group]:group:_groups' \
     {-h,--help}'[Show help message]' \
-    '--version[Show package version]' \
-    '--user[Run as user unit]' \
     {-H+,--host=}'[Operate on remote host]:[user@]host:_sd_hosts_or_user_at_host' \
     {-M+,--machine=}'[Operate on local container]:machines:_sd_machines' \
-    '--scope[Run this as scope rather than service]' \
-    '--unit=[Run under the specified unit name]:unit name' \
+    '--nice=[Nice level]:nice level' \
+    '--no-ask-password[Do not query the user for authentication]' \
+    '--no-block[Do not synchronously wait for the unit start operation to finish]' \
+    '--on-active=[Run after SEC seconds]:SEC' \
+    '--on-boot=[Run SEC seconds after machine was booted up]:SEC' \
+    '--on-calendar=[Realtime timer]:SPEC' \
+    '--on-clock-change[Defines a trigger based on system clock jumps]' \
+    '--on-startup=[Run SEC seconds after systemd was first started]:SEC' \
+    '--on-timezone-change[Defines a trigger based on system timezone changes]' \
+    '--on-unit-active=[Run SEC seconds after the last activation]:SEC' \
+    '--on-unit-inactive=[Run SEC seconds after the last deactivation]:SEC' \
+    '--path-property=[Set path unit property]:NAME=VALUE' \
+    {-P,--pipe}'[Inherit standard input, output, and error]' \
     {-p+,--property=}'[Set unit property]:NAME=VALUE:(( \
                 CPUAccounting= MemoryAccounting= BlockIOAccounting= SendSIGHUP= \
                 SendSIGKILL= MemoryLimit= CPUShares= BlockIOWeight= User= Group= \
-                DevicePolicy= KillMode= DeviceAllow= BlockIOReadBandwidth= \
+                DevicePolicy= KillMode= ExitType= DeviceAllow= BlockIOReadBandwidth= \
                 BlockIOWriteBandwidth= BlockIODeviceWeight= Nice= Environment= \
                 KillSignal= RestartKillSignal= FinalKillSignal= LimitCPU= LimitFSIZE= LimitDATA= \
                 LimitSTACK= LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC= \
@@ -45,21 +57,24 @@ _arguments \
                 ReadOnlyPaths= InaccessiblePaths= EnvironmentFile= \
                 ProtectSystem= ProtectHome= RuntimeDirectory= PassEnvironment= \
                 ))' \
-    '--description=[Description for unit]:description' \
-    '--slice=[Run in the specified slice]:slices:__systemd-run_slices' \
+    {-t,--pty}'[The service connects to the terminal]' \
+    {-q,--quiet}'[Suppresses additional informational output]' \
     {-r,--remain-after-exit}'[Leave service around until explicitly stopped]' \
+    {-d,--same-dir}'[Run on the current working directory]' \
+    '--scope[Run this as scope rather than service]' \
     '--send-sighup[Send SIGHUP when terminating]' \
     '--service-type=[Service type]:type:(simple forking oneshot dbus notify idle)' \
-    '--uid=[Run as system user]:user:_users' \
-    '--gid=[Run as system group]:group:_groups' \
-    '--nice=[Nice level]:nice level' \
-    '--setenv=[Set environment]:NAME=VALUE' \
-    '--on-active=[Run after SEC seconds]:SEC' \
-    '--on-boot=[Run SEC seconds after machine was booted up]:SEC' \
-    '--on-startup=[Run SEC seconds after systemd was first started]:SEC' \
-    '--on-unit-active=[Run SEC seconds after the last activation]:SEC' \
-    '--on-unit-inactive=[Run SEC seconds after the last deactivation]:SEC' \
-    '--on-calendar=[Realtime timer]:SPEC' \
+    {-E+,--setenv=}'[Set environment]:NAME=VALUE' \
+    {-S,--shell}'[requests an interactive shell in the current working directory]' \
+    '--slice=[Run in the specified slice]:slices:__systemd-run_slices' \
+    '--slice-inherit[Run in the inherited slice]' \
+    '--socket-property=[Set socket unit property]:NAME=VALUE' \
+    '--system[Run as system unit]' \
     '--timer-property=[Set timer unit property]:NAME=VALUE' \
+    '--uid=[Run as system user]:user:_users' \
+    {-u+,--unit=}'[Run under the specified unit name]:unit name' \
+    '--user[Run as user unit]' \
+    '--version[Show package version]' \
     '--wait=[Wait until service stopped again]' \
+    '--working-directory=[Run with the specified working directory]' \
     '*::command:_command'
index 6b89f57e1b71a8ebc9b5a4d71b62a85a71f8e518..09bcefbe66d4e95be0b9e5ab98a8574157266f14 100644 (file)
 #include "main-func.h"
 #include "pretty-print.h"
 #include "strv.h"
+#include "terminal-util.h"
 
 static const char *arg_icon = NULL;
-static const char *arg_id = NULL;
-static const char *arg_keyname = NULL;
+static const char *arg_id = NULL;               /* identifier for 'ask-password' protocol */
+static const char *arg_key_name = NULL;         /* name in kernel keyring */
+static const char *arg_credential_name = NULL;  /* name in $CREDENTIALS_DIRECTORY directory */
 static char *arg_message = NULL;
 static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
 static bool arg_multiple = false;
@@ -32,21 +34,26 @@ static int help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%s [OPTIONS...] MESSAGE\n\n"
-               "Query the user for a system passphrase, via the TTY or an UI agent.\n\n"
+        printf("%1$s [OPTIONS...] MESSAGE\n\n"
+               "%3$sQuery the user for a system passphrase, via the TTY or an UI agent.%4$s\n\n"
                "  -h --help           Show this help\n"
                "     --icon=NAME      Icon name\n"
                "     --id=ID          Query identifier (e.g. \"cryptsetup:/dev/sda5\")\n"
                "     --keyname=NAME   Kernel key name for caching passwords (e.g. \"cryptsetup\")\n"
+               "     --credential=NAME\n"
+               "                      Credential name for LoadCredential=/SetCredential=\n"
+               "                      credentials\n"
                "     --timeout=SEC    Timeout in seconds\n"
                "     --echo           Do not mask input (useful for usernames)\n"
                "     --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"
-               "\nSee the %s for details.\n",
+               "\nSee the %2$s for details.\n",
                program_invocation_short_name,
-               link);
+               link,
+               ansi_highlight(),
+               ansi_normal());
 
         return 0;
 }
@@ -64,6 +71,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_KEYNAME,
                 ARG_NO_OUTPUT,
                 ARG_VERSION,
+                ARG_CREDENTIAL,
         };
 
         static const struct option options[] = {
@@ -78,6 +86,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "id",            required_argument, NULL, ARG_ID            },
                 { "keyname",       required_argument, NULL, ARG_KEYNAME       },
                 { "no-output",     no_argument,       NULL, ARG_NO_OUTPUT     },
+                { "credential",    required_argument, NULL, ARG_CREDENTIAL    },
                 {}
         };
 
@@ -128,13 +137,17 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_KEYNAME:
-                        arg_keyname = optarg;
+                        arg_key_name = optarg;
                         break;
 
                 case ARG_NO_OUTPUT:
                         arg_no_output = true;
                         break;
 
+                case ARG_CREDENTIAL:
+                        arg_credential_name = optarg;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -170,7 +183,7 @@ static int run(int argc, char *argv[]) {
         else
                 timeout = 0;
 
-        r = ask_password_auto(arg_message, arg_icon, arg_id, arg_keyname, timeout, arg_flags, &l);
+        r = ask_password_auto(arg_message, arg_icon, arg_id, arg_key_name, arg_credential_name ?: "password", timeout, arg_flags, &l);
         if (r < 0)
                 return log_error_errno(r, "Failed to query password: %m");
 
index 0f1e30ccd971ce6a2880858cf79a5ce2874df334..676ad9351b25e7c2c7daa3d86a9eca4534bda379 100644 (file)
@@ -68,7 +68,7 @@ int get_block_device(const char *path, dev_t *ret) {
         /* Gets the block device directly backing a file system. If the block device is encrypted, returns
          * the device mapper block device. */
 
-        fd = open(path, O_NOFOLLOW|O_CLOEXEC);
+        fd = open(path, O_RDONLY|O_NOFOLLOW|O_CLOEXEC);
         if (fd < 0)
                 return -errno;
 
@@ -94,7 +94,8 @@ int block_get_originating(dev_t dt, dev_t *ret) {
         _cleanup_closedir_ DIR *d = NULL;
         _cleanup_free_ char *t = NULL;
         char p[SYS_BLOCK_PATH_MAX("/slaves")];
-        struct dirent *de, *found = NULL;
+        _cleanup_free_ char *first_found = NULL;
+        struct dirent *de;
         const char *q;
         dev_t devt;
         int r;
@@ -115,20 +116,22 @@ int block_get_originating(dev_t dt, dev_t *ret) {
                 if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
                         continue;
 
-                if (found) {
+                if (first_found) {
                         _cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL;
 
-                        /* We found a device backed by multiple other devices. We don't really support automatic
-                         * discovery on such setups, with the exception of dm-verity partitions. In this case there are
-                         * two backing devices: the data partition and the hash partition. We are fine with such
-                         * setups, however, only if both partitions are on the same physical device. Hence, let's
-                         * verify this. */
+                        /* We found a device backed by multiple other devices. We don't really support
+                         * automatic discovery on such setups, with the exception of dm-verity partitions. In
+                         * this case there are two backing devices: the data partition and the hash
+                         * partition. We are fine with such setups, however, only if both partitions are on
+                         * the same physical device.  Hence, let's verify this by iterating over every node
+                         * in the 'slaves/' directory and comparing them with the first that gets returned by
+                         * readdir(), to ensure they all point to the same device. */
 
                         u = path_join(p, de->d_name, "../dev");
                         if (!u)
                                 return -ENOMEM;
 
-                        v = path_join(p, found->d_name, "../dev");
+                        v = path_join(p, first_found, "../dev");
                         if (!v)
                                 return -ENOMEM;
 
@@ -144,15 +147,17 @@ int block_get_originating(dev_t dt, dev_t *ret) {
                          * different physical devices, and we don't support that. */
                         if (!streq(a, b))
                                 return -ENOTUNIQ;
+                } else {
+                        first_found = strdup(de->d_name);
+                        if (!first_found)
+                                return -ENOMEM;
                 }
-
-                found = de;
         }
 
-        if (!found)
+        if (!first_found)
                 return -ENOENT;
 
-        q = strjoina(p, "/", found->d_name, "/dev");
+        q = strjoina(p, "/", first_found, "/dev");
 
         r = read_one_line_file(q, &t);
         if (r < 0)
index 527043a2b39048bd11a470e8301460e304691a22..8dd3f8cd95018b46a9cef8800e3835e665b908da 100644 (file)
@@ -100,7 +100,7 @@ int cg_read_event(
         if (r < 0)
                 return r;
 
-        r = read_full_file(events, &content, NULL);
+        r = read_full_virtual_file(events, &content, NULL);
         if (r < 0)
                 return r;
 
@@ -2052,8 +2052,14 @@ int cg_unified_cached(bool flush) {
                         unified_cache = CGROUP_UNIFIED_SYSTEMD;
                         unified_systemd_v232 = false;
                 } else {
-                        if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
+                        if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0) {
+                                if (errno == ENOENT) {
+                                        /* Some other software may have set up /sys/fs/cgroup in a configuration we do not recognize. */
+                                        log_debug_errno(errno, "Unsupported cgroupsv1 setup detected: name=systemd hierarchy not found.");
+                                        return -ENOMEDIUM;
+                                }
                                 return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/systemd\" failed: %m");
+                        }
 
                         if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
                                 log_debug("Found cgroup2 on /sys/fs/cgroup/systemd, unified hierarchy for systemd controller (v232 variant)");
diff --git a/src/basic/creds-util.c b/src/basic/creds-util.c
new file mode 100644 (file)
index 0000000..5807670
--- /dev/null
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "creds-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "path-util.h"
+
+bool credential_name_valid(const char *s) {
+        /* We want that credential names are both valid in filenames (since that's our primary way to pass
+         * them around) and as fdnames (which is how we might want to pass them around eventually) */
+        return filename_is_valid(s) && fdname_is_valid(s);
+}
+
+int get_credentials_dir(const char **ret) {
+        const char *e;
+
+        assert(ret);
+
+        e = secure_getenv("CREDENTIALS_DIRECTORY");
+        if (!e)
+                return -ENXIO;
+
+        if (!path_is_absolute(e) || !path_is_normalized(e))
+                return -EINVAL;
+
+        *ret = e;
+        return 0;
+}
+
+int read_credential(const char *name, void **ret, size_t *ret_size) {
+        _cleanup_free_ char *fn = NULL;
+        const char *d;
+        int r;
+
+        assert(ret);
+
+        if (!credential_name_valid(name))
+                return -EINVAL;
+
+        r = get_credentials_dir(&d);
+        if (r < 0)
+                return r;
+
+        fn = path_join(d, name);
+        if (!fn)
+                return -ENOMEM;
+
+        return read_full_file_full(
+                        AT_FDCWD, fn,
+                        UINT64_MAX, SIZE_MAX,
+                        READ_FULL_FILE_SECURE,
+                        NULL,
+                        (char**) ret, ret_size);
+}
diff --git a/src/basic/creds-util.h b/src/basic/creds-util.h
new file mode 100644 (file)
index 0000000..5e33ca3
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+bool credential_name_valid(const char *s);
+
+int get_credentials_dir(const char **ret);
+
+int read_credential(const char *name, void **ret, size_t *ret_size);
index 8560982aab209b0f2624e7a4c2bc90018be1e303..df30870a1a25f90c76fb2d9d251891958349bc55 100644 (file)
@@ -27,7 +27,8 @@
 #include "string-util.h"
 #include "tmpfile-util.h"
 
-#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
+/* The maximum size of the file we'll read in one go. */
+#define READ_FULL_BYTES_MAX (4U*1024U*1024U - 1)
 
 int fopen_unlocked(const char *path, const char *options, FILE **ret) {
         assert(ret);
@@ -368,7 +369,6 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re
         struct stat st;
         size_t n, size;
         int n_retries;
-        char *p;
 
         assert(ret_contents);
 
@@ -385,18 +385,10 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re
         if (fd < 0)
                 return -errno;
 
-        /* Start size for files in /proc/ which usually report a file size of 0. (Files in /sys/ report a
-         * file size of 4K, which is probably OK for sizing our initial buffer, and sysfs attributes can't be
-         * larger anyway.) */
-        size = LINE_MAX / 2;
-
         /* Limit the number of attempts to read the number of bytes returned by fstat(). */
         n_retries = 3;
 
         for (;;) {
-                if (n_retries <= 0)
-                        return -EIO;
-
                 if (fstat(fd, &st) < 0)
                         return -errno;
 
@@ -404,19 +396,23 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re
                         return -EBADF;
 
                 /* Be prepared for files from /proc which generally report a file size of 0. */
+                assert_cc(READ_FULL_BYTES_MAX < SSIZE_MAX);
                 if (st.st_size > 0) {
+                        if (st.st_size > READ_FULL_BYTES_MAX)
+                                return -EFBIG;
+
                         size = st.st_size;
                         n_retries--;
-                } else
-                        size = size * 2;
-
-                if (size > READ_FULL_BYTES_MAX)
-                        return -E2BIG;
+                } else {
+                        size = READ_FULL_BYTES_MAX;
+                        n_retries = 0;
+                }
 
-                p = realloc(buf, size + 1);
-                if (!p)
+                buf = malloc(size + 1);
+                if (!buf)
                         return -ENOMEM;
-                buf = TAKE_PTR(p);
+                /* Use a bigger allocation if we got it anyway, but not more than the limit. */
+                size = MIN(malloc_usable_size(buf) - 1, READ_FULL_BYTES_MAX);
 
                 for (;;) {
                         ssize_t k;
@@ -443,27 +439,32 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re
                  * processing, let's try again either with a bigger guessed size or the new
                  * file size. */
 
+                if (n_retries <= 0)
+                        return st.st_size > 0 ? -EIO : -EFBIG;
+
                 if (lseek(fd, 0, SEEK_SET) < 0)
                         return -errno;
+
+                buf = mfree(buf);
         }
 
         if (n < size) {
+                char *p;
+
+                /* Return rest of the buffer to libc */
                 p = realloc(buf, n + 1);
                 if (!p)
                         return -ENOMEM;
-                buf = TAKE_PTR(p);
+                buf = p;
         }
 
-        if (!ret_size) {
-                /* Safety check: if the caller doesn't want to know the size of what we
-                 * just read it will rely on the trailing NUL byte. But if there's an
-                 * embedded NUL byte, then we should refuse operation as otherwise
-                 * there'd be ambiguity about what we just read. */
-
-                if (memchr(buf, 0, n))
-                        return -EBADMSG;
-        } else
+        if (ret_size)
                 *ret_size = n;
+        else if (memchr(buf, 0, n))
+                /* Safety check: if the caller doesn't want to know the size of what we just read it will
+                 * rely on the trailing NUL byte. But if there's an embedded NUL byte, then we should refuse
+                 * operation as otherwise there'd be ambiguity about what we just read. */
+                return -EBADMSG;
 
         buf[n] = 0;
         *ret_contents = TAKE_PTR(buf);
index f036a19eb5df7ca4b33b22a91debcef4306a86bd..45115fd3db18581fc2dbb6863ab7b7f452b91da2 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "alloc-util.h"
 #include "errno-util.h"
 #include "time-util.h"
 
@@ -107,8 +108,7 @@ static inline char *rmdir_and_free(char *p) {
                 return NULL;
 
         (void) rmdir(p);
-        free(p);
-        return NULL;
+        return mfree(p);
 }
 DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
 
@@ -117,8 +117,7 @@ static inline char* unlink_and_free(char *p) {
                 return NULL;
 
         (void) unlink_noerrno(p);
-        free(p);
-        return NULL;
+        return mfree(p);
 }
 DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
 
index c8cca96bca48615ab765143877180680b38dc265..595db0c395ac44ebc51bbdf4144741a7097df713 100644 (file)
@@ -252,11 +252,14 @@ int log_open(void) {
 
         /* Do not call from library code. */
 
-        /* If we don't use the console we close it here, to not get
-         * killed by SAK. If we don't use syslog we close it here so
-         * that we are not confused by somebody deleting the socket in
-         * the fs, and to make sure we don't use it if prohibit_ipc is
-         * set. If we don't use /dev/kmsg we still keep it open,
+        /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
+         * so that a call to a logging function immediately following a log_open() call can still easily
+         * reference an error that happened immediately before the log_open() call. */
+        PROTECT_ERRNO;
+
+        /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
+         * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
+         * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
          * because there is no reason to close it. */
 
         if (log_target == LOG_TARGET_NULL) {
index 52fd58d5b48ee676db668c602facc0cdd38ac11b..b3d32abfc84f9b992b491ac4edbd7dbc8cb5d73a 100644 (file)
@@ -216,7 +216,7 @@ int log_emergency_level(void);
 #define log_error_errno(error, ...)     log_full_errno(LOG_ERR,     error, __VA_ARGS__)
 #define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__)
 
-#ifdef LOG_TRACE
+#if LOG_TRACE
 #  define log_trace(...) log_debug(__VA_ARGS__)
 #else
 #  define log_trace(...) do {} while (0)
index 60ef801a253037097a03ef49bc784ef136f8f531..a7b8be26accc486665f715e489fb85b5ec7b1c94 100644 (file)
@@ -35,6 +35,8 @@ basic_sources = files('''
         conf-files.h
         copy.c
         copy.h
+        creds-util.c
+        creds-util.h
         def.h
         device-nodes.c
         device-nodes.h
index adf10a454813b447d9f4d1a8b747f4e409503af6..1d617e87b276a97946230feb350e157bf5163ea4 100644 (file)
@@ -114,7 +114,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *ret_mn
                 xsprintf(path, "/proc/self/fdinfo/%i", subfd);
         }
 
-        r = read_full_file(path, &fdinfo, NULL);
+        r = read_full_virtual_file(path, &fdinfo, NULL);
         if (r == -ENOENT) /* The fdinfo directory is a relatively new addition */
                 return -EOPNOTSUPP;
         if (r < 0)
@@ -196,13 +196,15 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
 
         if (statx(fd, filename, (FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? 0 : AT_SYMLINK_NOFOLLOW) |
                                 (flags & AT_EMPTY_PATH) |
-                                AT_NO_AUTOMOUNT, 0, &sx) < 0) {
+                                AT_NO_AUTOMOUNT, STATX_TYPE, &sx) < 0) {
                 if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
                         return -errno;
 
                 /* If statx() is not available or forbidden, fall back to name_to_handle_at() below */
         } else if (FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) /* yay! */
                 return FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT);
+        else if (FLAGS_SET(sx.stx_mask, STATX_TYPE) && S_ISLNK(sx.stx_mode))
+                return false; /* symlinks are never mount points */
 
         r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags);
         if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL))
@@ -231,16 +233,13 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
         } else if (r < 0)
                 return r;
 
-        /* The parent can do name_to_handle_at() but the
-         * directory we are interested in can't? If so, it
-         * must be a mount point. */
+        /* The parent can do name_to_handle_at() but the directory we are interested in can't? If so, it must
+         * be a mount point. */
         if (nosupp)
                 return 1;
 
-        /* If the file handle for the directory we are
-         * interested in and its parent are identical, we
-         * assume this is the root directory, which is a mount
-         * point. */
+        /* If the file handle for the directory we are interested in and its parent are identical, we assume
+         * this is the root directory, which is a mount point. */
 
         if (h->handle_bytes == h_parent->handle_bytes &&
             h->handle_type == h_parent->handle_type &&
@@ -263,23 +262,22 @@ fallback_fdinfo:
         if (mount_id != mount_id_parent)
                 return 1;
 
-        /* Hmm, so, the mount ids are the same. This leaves one
-         * special case though for the root file system. For that,
-         * let's see if the parent directory has the same inode as we
-         * are interested in. Hence, let's also do fstat() checks now,
-         * too, but avoid the st_dev comparisons, since they aren't
-         * that useful on unionfs mounts. */
+        /* Hmm, so, the mount ids are the same. This leaves one special case though for the root file
+         * system. For that, let's see if the parent directory has the same inode as we are interested
+         * in. Hence, let's also do fstat() checks now, too, but avoid the st_dev comparisons, since they
+         * aren't that useful on unionfs mounts. */
         check_st_dev = false;
 
 fallback_fstat:
-        /* yay for fstatat() taking a different set of flags than the other
-         * _at() above */
+        /* yay for fstatat() taking a different set of flags than the other _at() above */
         if (flags & AT_SYMLINK_FOLLOW)
                 flags &= ~AT_SYMLINK_FOLLOW;
         else
                 flags |= AT_SYMLINK_NOFOLLOW;
         if (fstatat(fd, filename, &a, flags) < 0)
                 return -errno;
+        if (S_ISLNK(a.st_mode)) /* Symlinks are never mount points */
+                return false;
 
         if (fstatat(fd, "", &b, AT_EMPTY_PATH) < 0)
                 return -errno;
index dfc0d3fb200e64bd4e06d59d1eeed4f09348d385..3c59dcc03c363b5106c4a8624c9b3d9aef65171b 100644 (file)
@@ -213,3 +213,25 @@ typedef enum nss_status (*_nss_gethostbyaddr_r_t)(
                 struct hostent *host,
                 char *buffer, size_t buflen,
                 int *errnop, int *h_errnop);
+
+typedef enum nss_status (*_nss_getpwnam_r_t)(
+                const char *name,
+                struct passwd *pwd,
+                char *buffer, size_t buflen,
+                int *errnop);
+typedef enum nss_status (*_nss_getpwuid_r_t)(
+                uid_t uid,
+                struct passwd *pwd,
+                char *buffer, size_t buflen,
+                int *errnop);
+
+typedef enum nss_status (*_nss_getgrnam_r_t)(
+                const char *name,
+                struct group *gr,
+                char *buffer, size_t buflen,
+                int *errnop);
+typedef enum nss_status (*_nss_getgrgid_r_t)(
+                gid_t gid,
+                struct group *gr,
+                char *buffer, size_t buflen,
+                int *errnop);
index 58fa8af1b7371c68035fe3eaf0086e8dbb317da6..0a76f0456165b46a48aaeabda7d4c2396c19cf95 100644 (file)
@@ -35,30 +35,33 @@ int ordered_set_consume(OrderedSet *s, void *p) {
         return r;
 }
 
-int ordered_set_put_strdup(OrderedSet *s, const char *p) {
+int _ordered_set_put_strdup(OrderedSet **s, const char *p  HASHMAP_DEBUG_PARAMS) {
         char *c;
         int r;
 
         assert(s);
         assert(p);
 
+        r = _ordered_set_ensure_allocated(s, &string_hash_ops_free  HASHMAP_DEBUG_PASS_ARGS);
+        if (r < 0)
+                return r;
+
+        if (ordered_set_contains(*s, p))
+                return 0;
+
         c = strdup(p);
         if (!c)
                 return -ENOMEM;
 
-        r = ordered_set_consume(s, c);
-        if (r == -EEXIST)
-                return 0;
-
-        return r;
+        return ordered_set_consume(*s, c);
 }
 
-int ordered_set_put_strdupv(OrderedSet *s, char **l) {
+int _ordered_set_put_strdupv(OrderedSet **s, char **l  HASHMAP_DEBUG_PARAMS) {
         int n = 0, r;
         char **i;
 
         STRV_FOREACH(i, l) {
-                r = ordered_set_put_strdup(s, *i);
+                r = _ordered_set_put_strdup(s, *i  HASHMAP_DEBUG_PASS_ARGS);
                 if (r < 0)
                         return r;
 
@@ -68,7 +71,7 @@ int ordered_set_put_strdupv(OrderedSet *s, char **l) {
         return n;
 }
 
-int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l) {
+int ordered_set_put_string_set(OrderedSet **s, OrderedSet *l) {
         int n = 0, r;
         char *p;
 
index baf82020887517d827e3b1e516ac5862c2f333c1..a377f20b1f254c8705486a0b56beb60ee10173eb 100644 (file)
@@ -26,6 +26,10 @@ static inline OrderedSet* ordered_set_free_free(OrderedSet *s) {
         return (OrderedSet*) ordered_hashmap_free_free((OrderedHashmap*) s);
 }
 
+static inline int ordered_set_contains(OrderedSet *s, const void *p) {
+        return ordered_hashmap_contains((OrderedHashmap*) s, p);
+}
+
 static inline int ordered_set_put(OrderedSet *s, void *p) {
         return ordered_hashmap_put((OrderedHashmap*) s, p, p);
 }
@@ -59,9 +63,11 @@ static inline char** ordered_set_get_strv(OrderedSet *s) {
 }
 
 int ordered_set_consume(OrderedSet *s, void *p);
-int ordered_set_put_strdup(OrderedSet *s, const char *p);
-int ordered_set_put_strdupv(OrderedSet *s, char **l);
-int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l);
+int _ordered_set_put_strdup(OrderedSet **s, const char *p  HASHMAP_DEBUG_PARAMS);
+#define ordered_set_put_strdup(s, p) _ordered_set_put_strdup(s, p  HASHMAP_DEBUG_SRC_ARGS)
+int _ordered_set_put_strdupv(OrderedSet **s, char **l  HASHMAP_DEBUG_PARAMS);
+#define ordered_set_put_strdupv(s, l) _ordered_set_put_strdupv(s, l  HASHMAP_DEBUG_SRC_ARGS)
+int ordered_set_put_string_set(OrderedSet **s, OrderedSet *l);
 void ordered_set_print(FILE *f, const char *field, OrderedSet *s);
 
 #define _ORDERED_SET_FOREACH(e, s, i) \
index 50ba44492e502bd8ad624243959d9be1a1afa0e7..f40f3f27e96c862c64bdf1dfd0736404c39f553c 100644 (file)
@@ -1190,9 +1190,3 @@ bool prefixed_path_strv_contains(char **l, const char *path) {
 
         return false;
 }
-
-bool credential_name_valid(const char *s) {
-        /* We want that credential names are both valid in filenames (since that's our primary way to pass
-         * them around) and as fdnames (which is how we might want to pass them around eventually) */
-        return filename_is_valid(s) && fdname_is_valid(s);
-}
index 74ee6362eacb9147c24ae5c6a012b46b9a139325..c0746f68d7aea12331861700c5c5109751c7d906 100644 (file)
@@ -183,5 +183,3 @@ static inline const char *empty_to_root(const char *path) {
 
 bool path_strv_contains(char **l, const char *path);
 bool prefixed_path_strv_contains(char **l, const char *path);
-
-bool credential_name_valid(const char *s);
index d3eb3ad18bade336795f54c0cb9f3164567d9cca..7d4301eadb8a3388689829a22fb23ce0660f6bd5 100644 (file)
@@ -124,14 +124,10 @@ int get_process_comm(pid_t pid, char **ret) {
 }
 
 int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line) {
-        _cleanup_fclose_ FILE *f = NULL;
         _cleanup_free_ char *t = NULL, *ans = NULL;
         const char *p;
-        int r;
         size_t k;
-
-        /* This is supposed to be a safety guard against runaway command lines. */
-        size_t max_length = sc_arg_max();
+        int r;
 
         assert(line);
         assert(pid >= 0);
@@ -147,36 +143,18 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
          * comm_fallback is false). Returns 0 and sets *line otherwise. */
 
         p = procfs_file_alloca(pid, "cmdline");
-        r = fopen_unlocked(p, "re", &f);
+        r = read_full_virtual_file(p, &t, &k);
         if (r == -ENOENT)
                 return -ESRCH;
         if (r < 0)
                 return r;
 
-        /* We assume that each four-byte character uses one or two columns. If we ever check for combining
-         * characters, this assumption will need to be adjusted. */
-        if ((size_t) 4 * max_columns + 1 < max_columns)
-                max_length = MIN(max_length, (size_t) 4 * max_columns + 1);
-
-        t = new(char, max_length);
-        if (!t)
-                return -ENOMEM;
-
-        k = fread(t, 1, max_length, f);
         if (k > 0) {
                 /* Arguments are separated by NULs. Let's replace those with spaces. */
                 for (size_t i = 0; i < k - 1; i++)
                         if (t[i] == '\0')
                                 t[i] = ' ';
-
-                t[k] = '\0'; /* Normally, t[k] is already NUL, so this is just a guard in case of short read */
         } else {
-                /* We only treat getting nothing as an error. We *could* also get an error after reading some
-                 * data, but we ignore that case, as such an error is rather unlikely and we prefer to get
-                 * some data rather than none. */
-                if (ferror(f))
-                        return -errno;
-
                 if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
                         return -ENOENT;
 
@@ -187,7 +165,7 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
                 if (r < 0)
                         return r;
 
-                mfree(t);
+                free(t);
                 t = strjoin("[", t2, "]");
                 if (!t)
                         return -ENOMEM;
@@ -1467,7 +1445,11 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
 
         /* Spawns a temporary TTY agent, making sure it goes away when we go away */
 
-        r = safe_fork_full(name, except, n_except, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS, ret_pid);
+        r = safe_fork_full(name,
+                           except,
+                           n_except,
+                           FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG,
+                           ret_pid);
         if (r < 0)
                 return r;
         if (r > 0)
@@ -1548,7 +1530,7 @@ int pidfd_get_pid(int fd, pid_t *ret) {
 
         xsprintf(path, "/proc/self/fdinfo/%i", fd);
 
-        r = read_full_file(path, &fdinfo, NULL);
+        r = read_full_virtual_file(path, &fdinfo, NULL);
         if (r == -ENOENT) /* if fdinfo doesn't exist we assume the process does not exist */
                 return -ESRCH;
         if (r < 0)
index d954146a2ebdef7fc3eeaa4c7ce9e8ed1eec5c9a..87be9b34102b0dcc47080698519663b5f495a05a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <sys/stat.h>
 
+#include "alloc-util.h"
 #include "errno-util.h"
 
 typedef enum RemoveFlags {
@@ -25,8 +26,7 @@ static inline char *rm_rf_physical_and_free(char *p) {
                 return NULL;
 
         (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_MISSING_OK|REMOVE_CHMOD);
-        free(p);
-        return NULL;
+        return mfree(p);
 }
 DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rm_rf_physical_and_free);
 
@@ -38,7 +38,6 @@ static inline char *rm_rf_subvolume_and_free(char *p) {
                 return NULL;
 
         (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME|REMOVE_MISSING_OK|REMOVE_CHMOD);
-        free(p);
-        return NULL;
+        return mfree(p);
 }
 DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rm_rf_subvolume_and_free);
index cfc8464c66dd1a1cf3ed01bd756a6c0a8260908d..ee9e34ed47cb676fba1fc92449fecd9ec3aadca8 100644 (file)
@@ -272,6 +272,8 @@ int mac_selinux_fix_container_fd(int fd, const char *path, const char *inside_pa
 
         /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
         mac_selinux_maybe_reload();
+        if (!label_hnd)
+                return 0;
 
         if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) < 0) {
                 /* If there's no label to set, then exit without warning */
@@ -484,6 +486,8 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
 
         /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
         mac_selinux_maybe_reload();
+        if (!label_hnd)
+                return 0;
 
         r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode);
         if (r < 0) {
@@ -506,7 +510,6 @@ int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode)
         _cleanup_free_ char *abspath = NULL;
         int r;
 
-
         assert(path);
 
         if (!label_hnd)
@@ -628,6 +631,8 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
 
         /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
         mac_selinux_maybe_reload();
+        if (!label_hnd)
+                goto skipped;
 
         if (path_is_absolute(path))
                 r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
index fdbbed6f839da2a17eaff3ccc8b28a55d4407d61..2a37b0a9ac69f96689610ccb833882f6315b1564 100644 (file)
@@ -45,10 +45,15 @@ if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
         if efi_cc.length() == 0
                 efi_cc = cc.cmd_array()
         endif
-        efi_ld = get_option('efi-ld')
-        if efi_ld == ''
-                efi_ld = find_program('ld', required: true)
+
+        efi_ld = find_program(get_option('efi-ld'), required: true)
+        efi_ld_name = efi_ld.path().split('/')[-1]
+        if efi_ld_name == 'lld' or efi_ld_name == 'ld.lld'
+                # LLVM/LLD does not support PE/COFF relocations
+                # https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html
+                error('LLVM/lld does not support PE/COFF relocations. Use different linker for EFI image.')
         endif
+
         efi_incdir = get_option('efi-includedir')
 
         gnu_efi_path_arch = ''
index 4a1585f663313d3025f1ebb87e12606ca80ccb73..eda21f4734ec71b9a90aafcd20c7caccf346178b 100644 (file)
@@ -13,6 +13,7 @@
 #include "cap-list.h"
 #include "capability-util.h"
 #include "cpu-set-util.h"
+#include "creds-util.h"
 #include "dbus-execute.h"
 #include "dbus-util.h"
 #include "env-util.h"
index f54e73684e8d1c8bb73174acd0213ab38e95c601..e33896f9763f49a3f1293a0f67b460c6a0d24b19 100644 (file)
@@ -2664,7 +2664,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_PROPERTY("ShowStatus", "b", property_get_show_status, 0, 0),
         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_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_error), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", property_get_runtime_watchdog, property_set_runtime_watchdog, 0, 0),
         SD_BUS_WRITABLE_PROPERTY("RebootWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, 0),
         /* The following item is an obsolete alias */
index f7cdb51eba883c83b8472173dc01342f47326788..73906ebab73d23862b6ae4e71e1f752cb20fe479 100644 (file)
@@ -27,6 +27,7 @@
 #include "unit.h"
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exit_type, service_exit_type, ServiceExitType);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
@@ -192,6 +193,7 @@ int bus_service_method_mount_image(sd_bus_message *message, void *userdata, sd_b
 const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ExitType", "s", property_get_exit_type, offsetof(Service, exit_type), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, offsetof(Service, notify_access), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -377,6 +379,7 @@ static int bus_set_transient_std_fd(
 }
 static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access, NotifyAccess, notify_access_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type, ServiceType, service_type_from_string);
+static BUS_DEFINE_SET_TRANSIENT_PARSE(service_exit_type, ServiceExitType, service_exit_type_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart, ServiceRestart, service_restart_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy, OOMPolicy, oom_policy_from_string);
 static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, sd_bus_service_name_is_valid);
@@ -414,6 +417,9 @@ static int bus_service_set_transient_property(
         if (streq(name, "Type"))
                 return bus_set_transient_service_type(u, name, &s->type, message, flags, error);
 
+        if (streq(name, "ExitType"))
+                return bus_set_transient_service_exit_type(u, name, &s->exit_type, message, flags, error);
+
         if (streq(name, "OOMPolicy"))
                 return bus_set_transient_oom_policy(u, name, &s->oom_policy, message, flags, error);
 
index 35aea2f83015ca01d0d2501f655e4b3331a15989..2152fa8500077021eb7fe879a826fc6390eb0268 100644 (file)
@@ -2564,6 +2564,7 @@ static int acquire_credentials(
                 ReadFullFileFlags flags = READ_FULL_FILE_SECURE;
                 _cleanup_(erase_and_freep) char *data = NULL;
                 _cleanup_free_ char *j = NULL, *bindname = NULL;
+                bool missing_ok = true;
                 const char *source;
                 size_t size, add;
 
@@ -2577,6 +2578,8 @@ static int acquire_credentials(
                         if (asprintf(&bindname, "@%" PRIx64"/unit/%s/%s", random_u64(), unit, *id) < 0)
                                 return -ENOMEM;
 
+                        missing_ok = false;
+
                 } else if (params->received_credentials) {
                         /* If this is a relative path, take it relative to the credentials we received
                          * ourselves. We don't support the AF_UNIX stuff in this mode, since we are operating
@@ -2589,16 +2592,23 @@ static int acquire_credentials(
                 } else
                         source = NULL;
 
-
                 if (source)
                         r = read_full_file_full(AT_FDCWD, source, UINT64_MAX, SIZE_MAX, flags, bindname, &data, &size);
                 else
                         r = -ENOENT;
-                if (r == -ENOENT &&
-                    faccessat(dfd, *id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) /* If the source file doesn't exist, but we already acquired the key otherwise, then don't fail */
+                if (r == -ENOENT && (missing_ok || faccessat(dfd, *id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)) {
+                        /* Make a missing inherited credential non-fatal, let's just continue. After all apps
+                         * will get clear errors if we don't pass such a missing credential on as they
+                         * themselves will get ENOENT when trying to read them, which should not be much
+                         * worse than when we handle the error here and make it fatal.
+                         *
+                         * Also, if the source file doesn't exist, but we already acquired the key otherwise,
+                         * then don't fail either. */
+                        log_debug_errno(r, "Couldn't read inherited credential '%s', skipping: %m", *fn);
                         continue;
+                }
                 if (r < 0)
-                        return r;
+                        return log_debug_errno(r, "Failed to read credential '%s': %m", *fn);
 
                 add = strlen(*id) + size;
                 if (add > left)
@@ -3247,7 +3257,6 @@ static int apply_mount_namespace(
                             propagate_dir,
                             incoming_dir,
                             root_dir || root_image ? params->notify_socket : NULL,
-                            DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
                             error_path);
 
         /* If we couldn't set up the namespace this is probably due to a missing capability. setup_namespace() reports
index 21bbcffe41af6d84ecbcc4f31c287a318b4dc579..5ef785c0deea156e4606834653ab5282c47faeb1 100644 (file)
@@ -359,6 +359,7 @@ Service.StartLimitAction,                config_parse_emergency_action,
 Service.FailureAction,                   config_parse_emergency_action,               0,                                  offsetof(Unit, failure_action)
 Service.RebootArgument,                  config_parse_unit_string_printf,             0,                                  offsetof(Unit, reboot_arg)
 Service.Type,                            config_parse_service_type,                   0,                                  offsetof(Service, type)
+Service.ExitType,                        config_parse_service_exit_type,              0,                                  offsetof(Service, exit_type)
 Service.Restart,                         config_parse_service_restart,                0,                                  offsetof(Service, restart)
 Service.PermissionsStartOnly,            config_parse_bool,                           0,                                  offsetof(Service, permissions_start_only)
 Service.RootDirectoryStartOnly,          config_parse_bool,                           0,                                  offsetof(Service, root_directory_start_only)
index c6fc4fe083f989f74956979430c0ee69f2bf1222..1a1e58976ae3310d2302b142b9fa8dd6156ff052 100644 (file)
@@ -16,8 +16,8 @@
 #include "sd-messages.h"
 
 #include "af-list.h"
-#include "alloc-util.h"
 #include "all-units.h"
+#include "alloc-util.h"
 #include "bpf-firewall.h"
 #include "bus-error.h"
 #include "bus-internal.h"
@@ -28,6 +28,7 @@
 #include "conf-parser.h"
 #include "core-varlink.h"
 #include "cpu-set-util.h"
+#include "creds-util.h"
 #include "env-util.h"
 #include "errno-list.h"
 #include "escape.h"
@@ -130,6 +131,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_home, protect_home, ProtectHome, "
 DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_system, protect_system, ProtectSystem, "Failed to parse protect system value");
 DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode");
 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_service_exit_type, service_exit_type, ServiceExitType, "Failed to parse service exit type");
 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
 DEFINE_CONFIG_PARSE_ENUM(config_parse_service_timeout_failure_mode, service_timeout_failure_mode, ServiceTimeoutFailureMode, "Failed to parse timeout failure mode");
 DEFINE_CONFIG_PARSE_ENUM(config_parse_socket_bind, socket_address_bind_ipv6_only_or_bool, SocketAddressBindIPv6Only, "Failed to parse bind IPv6 only value");
@@ -4606,14 +4608,23 @@ int config_parse_load_credential(
                 log_syntax(unit, LOG_WARNING, filename, line, 0, "Credential name \"%s\" not valid, ignoring.", k);
                 return 0;
         }
-        r = unit_full_printf(u, p, &q);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in \"%s\", ignoring: %m", p);
-                return 0;
-        }
-        if (path_is_absolute(q) ? !path_is_normalized(q) : !credential_name_valid(q)) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Credential source \"%s\" not valid, ignoring.", q);
-                return 0;
+
+        if (isempty(p)) {
+                /* If only one field field is specified take it as shortcut for inheriting a credential named
+                 * the same way from our parent */
+                q = strdup(k);
+                if (!q)
+                        return log_oom();
+        } else {
+                r = unit_full_printf(u, p, &q);
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in \"%s\", ignoring: %m", p);
+                        return 0;
+                }
+                if (path_is_absolute(q) ? !path_is_normalized(q) : !credential_name_valid(q)) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r, "Credential source \"%s\" not valid, ignoring.", q);
+                        return 0;
+                }
         }
 
         r = strv_consume_pair(&context->load_credentials, TAKE_PTR(k), TAKE_PTR(q));
@@ -5748,6 +5759,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_unit_deps,             "UNIT [...]" },
                 { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
                 { config_parse_service_type,          "SERVICETYPE" },
+                { config_parse_service_exit_type,     "SERVICEEXITTYPE" },
                 { config_parse_service_restart,       "SERVICERESTART" },
                 { config_parse_service_timeout_failure_mode, "TIMEOUTMODE" },
                 { config_parse_kill_mode,             "KILLMODE" },
index b8a6d5feadc57fed460cfea1bf516c8e6c1af75e..4746a8a792b2674f841bb3c9673be6b359d099bc 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout);
 CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout_abort);
 CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout_failure_mode);
 CONFIG_PARSER_PROTOTYPE(config_parse_service_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_service_exit_type);
 CONFIG_PARSER_PROTOTYPE(config_parse_service_restart);
 CONFIG_PARSER_PROTOTYPE(config_parse_socket_bindtodevice);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_output);
index 629966ea60edef121b4afb36b6448c123293996b..57bb25ca2543507ff5a82dc989af453a81435abe 100644 (file)
@@ -30,6 +30,7 @@
 #include "clean-ipc.h"
 #include "clock-util.h"
 #include "core-varlink.h"
+#include "creds-util.h"
 #include "dbus-job.h"
 #include "dbus-manager.h"
 #include "dbus-unit.h"
@@ -49,8 +50,8 @@
 #include "install.h"
 #include "io-util.h"
 #include "label.h"
-#include "locale-setup.h"
 #include "load-fragment.h"
+#include "locale-setup.h"
 #include "log.h"
 #include "macro.h"
 #include "manager.h"
@@ -852,8 +853,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
         if (r < 0)
                 return r;
 
-        e = secure_getenv("CREDENTIALS_DIRECTORY");
-        if (e) {
+        r = get_credentials_dir(&e);
+        if (r >= 0) {
                 m->received_credentials = strdup(e);
                 if (!m->received_credentials)
                         return -ENOMEM;
index c5897c6c944be52fda33757abdf39c6c5663cb01..ccea336fee39e997eaade1b0f4d2688ff3a4d288 100644 (file)
@@ -1802,7 +1802,6 @@ int setup_namespace(
                 const char *propagate_dir,
                 const char *incoming_dir,
                 const char *notify_socket,
-                DissectImageFlags dissect_image_flags,
                 char **error_path) {
 
         _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
@@ -1813,6 +1812,13 @@ int setup_namespace(
         MountEntry *m = NULL, *mounts = NULL;
         bool require_prefix = false, setup_propagate = false;
         const char *root, *extension_dir = "/run/systemd/unit-extensions";
+        DissectImageFlags dissect_image_flags =
+                DISSECT_IMAGE_GENERIC_ROOT |
+                DISSECT_IMAGE_REQUIRE_ROOT |
+                DISSECT_IMAGE_DISCARD_ON_LOOP |
+                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                DISSECT_IMAGE_FSCK |
+                DISSECT_IMAGE_USR_NO_ROOT;
         size_t n_mounts;
         int r;
 
@@ -1825,8 +1831,6 @@ int setup_namespace(
                 mount_flags = MS_SHARED;
 
         if (root_image) {
-                dissect_image_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
-
                 /* Make the whole image read-only if we can determine that we only access it in a read-only fashion. */
                 if (root_read_only(read_only_paths,
                                    ns_info->protect_system) &&
@@ -2051,13 +2055,12 @@ int setup_namespace(
                         };
                 }
 
-                if (ns_info->private_ipc) {
+                if (ns_info->private_ipc)
                         *(m++) = (MountEntry) {
                                 .path_const = "/dev/mqueue",
                                 .mode = MQUEUEFS,
                                 .flags = MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME,
                         };
-                }
 
                 if (creds_path) {
                         /* If our service has a credentials store configured, then bind that one in, but hide
@@ -2150,11 +2153,10 @@ int setup_namespace(
         if (setup_propagate)
                 (void) mkdir_p(propagate_dir, 0600);
 
-        if (n_extension_images > 0) {
+        if (n_extension_images > 0)
                 /* ExtensionImages mountpoint directories will be created
                  * while parsing the mounts to create, so have the parent ready */
                 (void) mkdir_p(extension_dir, 0600);
-        }
 
         /* Remount / as SLAVE so that nothing now mounted in the namespace
          * shows up in the parent */
index 2806db8fd1bf0aace57b52a8d4628f39f77ace16..737d6eae8b1e5d25d66fdc4d9e280bb971b4d94f 100644 (file)
@@ -143,7 +143,6 @@ int setup_namespace(
                 const char *propagate_dir,
                 const char *incoming_dir,
                 const char *notify_socket,
-                DissectImageFlags dissected_image_flags,
                 char **error_path);
 
 #define RUN_SYSTEMD_EMPTY "/run/systemd/empty"
index df3ed05cfc6e8e6114af3b6f52dd0c45816dd858..550db4063126337f8e03f1c3ad1c3ba16612441d 100644 (file)
@@ -1621,18 +1621,25 @@ static int control_pid_good(Service *s) {
         return s->control_pid > 0;
 }
 
-static int cgroup_good(Service *s) {
-        int r;
-
+static int cgroup_empty(Service *s) {
         assert(s);
 
-        /* Returns 0 if the cgroup is empty or doesn't exist, > 0 if it is exists and is populated, < 0 if we can't
-         * figure it out */
+        /* Returns 0 if there is no cgroup, > 0 if is empty or doesn't exist, < 0 if we can't figure it out */
 
         if (!UNIT(s)->cgroup_path)
                 return 0;
 
-        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, UNIT(s)->cgroup_path);
+        return cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, UNIT(s)->cgroup_path);
+}
+
+
+static int cgroup_good(Service *s) {
+        int r;
+
+        /* Returns 0 if the cgroup is empty or doesn't exist, > 0 if it is exists and is populated, < 0 if we can't
+         * figure it out */
+
+        r = cgroup_empty(s);
         if (r < 0)
                 return r;
 
@@ -3398,7 +3405,14 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         else
                 assert_not_reached("Unknown code");
 
-        if (s->main_pid == pid) {
+        /* Services with ExitType=cgroup ignore the main PID for purposes of exit status */
+        if (s->exit_type == SERVICE_EXIT_CGROUP && s->main_pid == pid) {
+                service_unwatch_main_pid(s);
+                s->main_pid_known = false;
+        }
+
+        if ((s->exit_type == SERVICE_EXIT_MAIN && s->main_pid == pid) ||
+            (s->exit_type == SERVICE_EXIT_CGROUP && cgroup_empty(s) && !control_pid_good(s))) {
                 /* Forking services may occasionally move to a new PID.
                  * As long as they update the PID file before exiting the old
                  * PID, they're fine. */
@@ -3431,7 +3445,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 
                 unit_log_process_exit(
                                 u,
-                                "Main process",
+                                s->exit_type == SERVICE_EXIT_CGROUP ? "Last process" : "Main process",
                                 service_exec_command_to_string(SERVICE_EXEC_START),
                                 f == SERVICE_SUCCESS,
                                 code, status);
@@ -4448,6 +4462,13 @@ static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType);
 
+static const char* const service_exit_type_table[_SERVICE_EXIT_TYPE_MAX] = {
+        [SERVICE_EXIT_MAIN] = "main",
+        [SERVICE_EXIT_CGROUP] = "cgroup",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_exit_type, ServiceExitType);
+
 static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] = {
         [SERVICE_EXEC_CONDITION] = "ExecCondition",
         [SERVICE_EXEC_START_PRE] = "ExecStartPre",
index af474aa40e90a0ebe6d7aac8a47cfafb987702b9..92c1caf79491131c8fa8fc67af7cc6b0622057c2 100644 (file)
@@ -35,6 +35,13 @@ typedef enum ServiceType {
         _SERVICE_TYPE_INVALID = -EINVAL,
 } ServiceType;
 
+typedef enum ServiceExitType {
+        SERVICE_EXIT_MAIN,    /* we consider the main PID when deciding if the service exited */
+        SERVICE_EXIT_CGROUP,  /* we wait for the last process in the cgroup to exit */
+        _SERVICE_EXIT_TYPE_MAX,
+        _SERVICE_EXIT_TYPE_INVALID = -EINVAL,
+} ServiceExitType;
+
 typedef enum ServiceExecCommand {
         SERVICE_EXEC_CONDITION,
         SERVICE_EXEC_START_PRE,
@@ -97,6 +104,7 @@ struct Service {
         Unit meta;
 
         ServiceType type;
+        ServiceExitType exit_type;
         ServiceRestart restart;
         ExitStatusSet restart_prevent_status;
         ExitStatusSet restart_force_status;
@@ -226,6 +234,9 @@ ServiceRestart service_restart_from_string(const char *s) _pure_;
 const char* service_type_to_string(ServiceType i) _const_;
 ServiceType service_type_from_string(const char *s) _pure_;
 
+const char* service_exit_type_to_string(ServiceExitType i) _const_;
+ServiceExitType service_exit_type_from_string(const char *s) _pure_;
+
 const char* service_exec_command_to_string(ServiceExecCommand i) _const_;
 ServiceExecCommand service_exec_command_from_string(const char *s) _pure_;
 
index b8805b02fa365b5d1a982a2cfd2ee89fc2bcf383..fa6fb690c7806a11348de5573089e1469e62f253 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/system.conf' to display the full config.
+#
 # See systemd-system.conf(5) for details.
 
 [Manager]
index d7388e2367a3967b49eb6f409016b7eaf3a40217..1d3cf8f1fc61c4eafb5bb2bb7045b95c181c2715 100644 (file)
@@ -405,7 +405,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
                                    j->unit->id,
                                    unit_id == array ? "ordering cycle" : "dependency",
                                    *unit_id, *job_type,
-                                   unit_ids);
+                                   "%s", unit_ids);
 
                 if (delete) {
                         const char *status;
@@ -414,7 +414,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
                                    "MESSAGE=%s: Job %s/%s deleted to break ordering cycle starting with %s/%s",
                                    j->unit->id, delete->unit->id, job_type_to_string(delete->type),
                                    j->unit->id, job_type_to_string(j->type),
-                                   unit_ids);
+                                   "%s", unit_ids);
 
                         if (log_get_show_color())
                                 status = ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL;
@@ -432,7 +432,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
                 log_struct(LOG_ERR,
                            "MESSAGE=%s: Unable to break cycle starting with %s/%s",
                            j->unit->id, j->unit->id, job_type_to_string(j->type),
-                           unit_ids);
+                           "%s", unit_ids);
 
                 return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC,
                                          "Transaction order is cyclic. See system logs for details.");
index 72e859a565dafb7a1e7429f1aa921aae82ea7d78..2fb2404500e88c026241b69ad03c71178ac831e8 100644 (file)
@@ -1125,23 +1125,23 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) {
                 (void) iovw_put_string_field_free(iovw, "COREDUMP_OPEN_FDS=", t);
 
         p = procfs_file_alloca(pid, "status");
-        if (read_full_file(p, &t, NULL) >= 0)
+        if (read_full_virtual_file(p, &t, NULL) >= 0)
                 (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_STATUS=", t);
 
         p = procfs_file_alloca(pid, "maps");
-        if (read_full_file(p, &t, NULL) >= 0)
+        if (read_full_virtual_file(p, &t, NULL) >= 0)
                 (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_MAPS=", t);
 
         p = procfs_file_alloca(pid, "limits");
-        if (read_full_file(p, &t, NULL) >= 0)
+        if (read_full_virtual_file(p, &t, NULL) >= 0)
                 (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_LIMITS=", t);
 
         p = procfs_file_alloca(pid, "cgroup");
-        if (read_full_file(p, &t, NULL) >=0)
+        if (read_full_virtual_file(p, &t, NULL) >=0)
                 (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_CGROUP=", t);
 
         p = procfs_file_alloca(pid, "mountinfo");
-        if (read_full_file(p, &t, NULL) >=0)
+        if (read_full_virtual_file(p, &t, NULL) >=0)
                 (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_MOUNTINFO=", t);
 
         if (get_process_cwd(pid, &t) >= 0)
index 738c45bed25af9a7200eda60acf394755ee85394..56c100824524185386bc7c40de63286e06e309d8 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/coredump.conf' to display the full config.
+#
 # See coredump.conf(5) for details.
 
 [Coredump]
index e08f564d3faff5c1abb774c17fde40438c1c5c9d..0314831174be1ea6cb996b99d9ef7260f52cc78f 100644 (file)
@@ -57,7 +57,7 @@ int enroll_password(
                         if (!question)
                                 return log_oom();
 
-                        r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", USEC_INFINITY, 0, &passwords);
+                        r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY, 0, &passwords);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to query password: %m");
 
@@ -68,7 +68,7 @@ int enroll_password(
                         if (!question)
                                 return log_oom();
 
-                        r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", USEC_INFINITY, 0, &passwords2);
+                        r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY, 0, &passwords2);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to query password: %m");
 
index a137a41c9d7cfda6d75696671b48008c886e0b3c..7d12c427b3099f6feaf2e9f2e471b2a7767e627a 100644 (file)
@@ -417,7 +417,7 @@ static int prepare_luks(
                                                        "Too many attempts, giving up:");
 
                         r = ask_password_auto(
-                                        question, "drive-harddisk", id, "cryptenroll", USEC_INFINITY,
+                                        question, "drive-harddisk", id, "cryptenroll", "cryptenroll.passphrase", USEC_INFINITY,
                                         ask_password_flags,
                                         &passwords);
                         if (r < 0)
index dfdb964360a7998e9cecfc527726641dc3c35b6e..82b83ee47705ecbce7f0b7d89c9b1e2999a23817 100644 (file)
@@ -88,7 +88,7 @@ int acquire_fido2_key(
 
                 pins = strv_free_erase(pins);
 
-                r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", until, flags, &pins);
+                r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, flags, &pins);
                 if (r < 0)
                         return log_error_errno(r, "Failed to ask for user password: %m");
 
index 8d7d74fb75b1294725db55248dfaa8be9d88bc57..6d7b01176cbe0960706efee68997b16903ed1525 100644 (file)
@@ -70,6 +70,7 @@ static int pkcs11_callback(
                         data->friendly_name,
                         "drive-harddisk",
                         "pkcs11-pin",
+                        "cryptsetup.pkcs11-pin",
                         data->until,
                         NULL);
         if (r < 0)
index dba26a54a3f15faa45c1d82e557bb31f5e52088b..5c55dcd19757e559334f1a89c67e622733410c8d 100644 (file)
@@ -545,7 +545,7 @@ static int get_password(
 
         id = strjoina("cryptsetup:", disk_path);
 
-        r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until,
+        r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", "cryptsetup.passphrase", until,
                               ASK_PASSWORD_PUSH_CACHE | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED),
                               &passwords);
         if (r < 0)
@@ -561,7 +561,7 @@ static int get_password(
 
                 id = strjoina("cryptsetup-verification:", disk_path);
 
-                r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE, &passwords2);
+                r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", "cryptsetup.passphrase", until, ASK_PASSWORD_PUSH_CACHE, &passwords2);
                 if (r < 0)
                         return log_error_errno(r, "Failed to query verification password: %m");
 
index cb96a57abee41b6987c1f0c7ef0a022307bc2a05..65ddb1d14936c0e6ab7fa97046bd5b59388478a5 100644 (file)
@@ -44,7 +44,12 @@ static const char *arg_image = NULL;
 static const char *arg_path = NULL;
 static const char *arg_source = NULL;
 static const char *arg_target = NULL;
-static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK;
+static DissectImageFlags arg_flags =
+        DISSECT_IMAGE_GENERIC_ROOT |
+        DISSECT_IMAGE_DISCARD_ON_LOOP |
+        DISSECT_IMAGE_RELAX_VAR_CHECK |
+        DISSECT_IMAGE_FSCK |
+        DISSECT_IMAGE_USR_NO_ROOT;
 static VeritySettings arg_verity_settings = VERITY_SETTINGS_DEFAULT;
 static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
 static PagerFlags arg_pager_flags = 0;
@@ -293,6 +298,7 @@ static int parse_argv(int argc, char *argv[]) {
 
                 arg_image = argv[optind];
                 arg_path = argv[optind + 1];
+                arg_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
                 break;
 
         case ACTION_COPY_FROM:
@@ -304,7 +310,7 @@ static int parse_argv(int argc, char *argv[]) {
                 arg_source = argv[optind + 1];
                 arg_target = argc > optind + 2 ? argv[optind + 2] : "-" /* this means stdout */ ;
 
-                arg_flags |= DISSECT_IMAGE_READ_ONLY;
+                arg_flags |= DISSECT_IMAGE_READ_ONLY | DISSECT_IMAGE_REQUIRE_ROOT;
                 break;
 
         case ACTION_COPY_TO:
@@ -322,6 +328,7 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_target = argv[optind + 1];
                 }
 
+                arg_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
                 break;
 
         default:
@@ -460,7 +467,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
                         return log_oom();
         }
 
-        t = table_new("rw", "designator", "partition uuid", "fstype", "architecture", "verity", "node", "partno");
+        t = table_new("rw", "designator", "partition uuid", "partition label", "fstype", "architecture", "verity", "node", "partno");
         if (!t)
                 return log_oom();
 
@@ -489,6 +496,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
 
                 r = table_add_many(
                                 t,
+                                TABLE_STRING, p->label,
                                 TABLE_STRING, p->fstype,
                                 TABLE_STRING, architecture_to_string(p->architecture));
                 if (r < 0)
index 8e3028717e79dbccc4d07acb3e93d9e331befabb..ba0b360cc1a526fb0b671d498603615c5a295940 100644 (file)
@@ -10,6 +10,7 @@
 #include "alloc-util.h"
 #include "ask-password-api.h"
 #include "copy.h"
+#include "creds-util.h"
 #include "dissect-image.h"
 #include "env-file.h"
 #include "fd-util.h"
@@ -43,8 +44,8 @@
 static char *arg_root = NULL;
 static char *arg_image = NULL;
 static char *arg_locale = NULL;  /* $LANG */
-static char *arg_keymap = NULL;
 static char *arg_locale_messages = NULL; /* $LC_MESSAGES */
+static char *arg_keymap = NULL;
 static char *arg_timezone = NULL;
 static char *arg_hostname = NULL;
 static sd_id128_t arg_machine_id = {};
@@ -232,11 +233,29 @@ static bool locale_is_ok(const char *name) {
 
 static int prompt_locale(void) {
         _cleanup_strv_free_ char **locales = NULL;
+        bool acquired_from_creds = false;
         int r;
 
         if (arg_locale || arg_locale_messages)
                 return 0;
 
+        r = read_credential("firstboot.locale", (void**) &arg_locale, NULL);
+        if (r < 0)
+                log_debug_errno(r, "Failed to read credential firstboot.locale, ignoring: %m");
+        else
+                acquired_from_creds = true;
+
+        r = read_credential("firstboot.locale-messages", (void**) &arg_locale_messages, NULL);
+        if (r < 0)
+                log_debug_errno(r, "Failed to read credential firstboot.locale-message, ignoring: %m");
+        else
+                acquired_from_creds = true;
+
+        if (acquired_from_creds) {
+                log_debug("Acquired locale from credentials.");
+                return 0;
+        }
+
         if (!arg_prompt_locale)
                 return 0;
 
@@ -336,6 +355,14 @@ static int prompt_keymap(void) {
         if (arg_keymap)
                 return 0;
 
+        r = read_credential("firstboot.keymap", (void**) &arg_keymap, NULL);
+        if (r < 0)
+                log_debug_errno(r, "Failed to read credential firstboot.keymap, ignoring: %m");
+        else {
+                log_debug("Acquired keymap from credential.");
+                return 0;
+        }
+
         if (!arg_prompt_keymap)
                 return 0;
 
@@ -407,6 +434,14 @@ static int prompt_timezone(void) {
         if (arg_timezone)
                 return 0;
 
+        r = read_credential("firstboot.timezone", (void**) &arg_timezone, NULL);
+        if (r < 0)
+                log_debug_errno(r, "Failed to read credential firstboot.timezone, ignoring: %m");
+        else {
+                log_debug("Acquired timezone from credential.");
+                return 0;
+        }
+
         if (!arg_prompt_timezone)
                 return 0;
 
@@ -558,6 +593,22 @@ static int prompt_root_password(void) {
         if (arg_root_password)
                 return 0;
 
+        r = read_credential("passwd.hashed-password.root", (void**) &arg_root_password, NULL);
+        if (r == -ENOENT) {
+                r = read_credential("passwd.plaintext-password.root", (void**) &arg_root_password, NULL);
+                if (r < 0)
+                        log_debug_errno(r, "Couldn't read credential 'passwd.{hashed|plaintext}-password.root', ignoring: %m");
+                else {
+                        arg_root_password_is_hashed = false;
+                        return 0;
+                }
+        } else if (r < 0)
+                log_debug_errno(r, "Couldn't read credential 'passwd.hashed-password.root', ignoring: %m");
+        else {
+                arg_root_password_is_hashed = true;
+                return 0;
+        }
+
         if (!arg_prompt_root_password)
                 return 0;
 
@@ -631,7 +682,18 @@ static int find_shell(const char *path, const char *root) {
 static int prompt_root_shell(void) {
         int r;
 
-        if (arg_root_shell || !arg_prompt_root_shell)
+        if (arg_root_shell)
+                return 0;
+
+        r = read_credential("passwd.shell.root", (void**) &arg_root_shell, NULL);
+        if (r < 0)
+                log_debug_errno(r, "Failed to read credential passwd.shell.root, ignoring: %m");
+        else {
+                log_debug("Acquired root shell from credential.");
+                return 0;
+        }
+
+        if (!arg_prompt_root_shell)
                 return 0;
 
         print_welcome();
@@ -1291,7 +1353,11 @@ static int run(int argc, char *argv[]) {
 
                 r = mount_image_privately_interactively(
                                 arg_image,
-                                DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_VALIDATE_OS |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_FSCK,
                                 &unlink_dir,
                                 &loop_device,
                                 &decrypted_image);
index f9d0ca54214749a2ce6f94ad6c43d04158d16c77..dda9b1881581b058b07907e8c05bca0159908877 100644 (file)
@@ -665,7 +665,13 @@ static int enumerate_partitions(dev_t devnum) {
         if (r <= 0)
                 return r;
 
-        r = dissect_image(fd, NULL, NULL, DISSECT_IMAGE_GPT_ONLY|DISSECT_IMAGE_NO_UDEV, &m);
+        r = dissect_image(
+                        fd,
+                        NULL, NULL,
+                        DISSECT_IMAGE_GPT_ONLY|
+                        DISSECT_IMAGE_NO_UDEV|
+                        DISSECT_IMAGE_USR_NO_ROOT,
+                        &m);
         if (r == -ENOPKG) {
                 log_debug_errno(r, "No suitable partition table found, ignoring.");
                 return 0;
index 9d12b9abae528ff5d36d4d26cf6704a83d6e18a2..cf1a2d9f9bb4e2a3477dc89d240b2e654d2f3f31 100644 (file)
@@ -221,7 +221,7 @@ static int acquire_existing_password(const char *user_name, UserRecord *hr, bool
                      user_name) < 0)
                 return log_oom();
 
-        r = ask_password_auto(question, "user-home", NULL, "home-password", USEC_INFINITY, ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE, &password);
+        r = ask_password_auto(question, "user-home", NULL, "home-password", "home.password", USEC_INFINITY, ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE, &password);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire password: %m");
 
@@ -257,7 +257,7 @@ static int acquire_token_pin(const char *user_name, UserRecord *hr) {
                 return log_oom();
 
         /* We never cache or use cached PINs, since usually there are only very few attempts allowed before the PIN is blocked */
-        r = ask_password_auto(question, "user-home", NULL, "token-pin", USEC_INFINITY, 0, &pin);
+        r = ask_password_auto(question, "user-home", NULL, "token-pin", "home.token-pin", USEC_INFINITY, 0, &pin);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire security token PIN: %m");
 
@@ -1010,7 +1010,7 @@ static int acquire_new_password(
                 if (asprintf(&question, "Please enter new password for user %s:", user_name) < 0)
                         return log_oom();
 
-                r = ask_password_auto(question, "user-home", NULL, "home-password", USEC_INFINITY, 0, &first);
+                r = ask_password_auto(question, "user-home", NULL, "home-password", "home.new-password", USEC_INFINITY, 0, &first);
                 if (r < 0)
                         return log_error_errno(r, "Failed to acquire password: %m");
 
@@ -1018,7 +1018,7 @@ static int acquire_new_password(
                 if (asprintf(&question, "Please enter new password for user %s (repeat):", user_name) < 0)
                         return log_oom();
 
-                r = ask_password_auto(question, "user-home", NULL, "home-password", USEC_INFINITY, 0, &second);
+                r = ask_password_auto(question, "user-home", NULL, "home-password", "home.new-password", USEC_INFINITY, 0, &second);
                 if (r < 0)
                         return log_error_errno(r, "Failed to acquire password: %m");
 
index 5a777e88ef7e4e4a64a4a70d8c2bd210ec408847..b0c5ce4232a6b6429f443b7910a707d773316c70 100644 (file)
@@ -1007,7 +1007,7 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
 
         r = safe_fork_full("(sd-homework)",
                            (int[]) { stdin_fd, stdout_fd }, 2,
-                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG, &pid);
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -1838,7 +1838,9 @@ int home_killall(Home *h) {
         assert(h->uid > 0); /* We never should be UID 0 */
 
         /* Let's kill everything matching the specified UID */
-        r = safe_fork("(sd-killer)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
+        r = safe_fork("(sd-killer)",
+                      FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG,
+                      NULL);
         if (r < 0)
                 return r;
         if (r == 0) {
index 86b6266895ca6a5836424f8fc54e4061c2c1168d..ba854641df78f5b3e6d50ebcd6be07ece3fead1d 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/homed.conf' to display the full config.
+#
 # See homed.conf(5) for details.
 
 [Home]
index d0676f8ae6dffdb8d825ca5b432636b2bd4522aa..037e4853fd349f1b9a98c532132681b2adf871e9 100644 (file)
@@ -324,7 +324,9 @@ int home_prepare_fscrypt(
         /* Also install the access key in the user's own keyring */
 
         if (uid_is_valid(h->uid)) {
-                r = safe_fork("(sd-addkey)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
+                r = safe_fork("(sd-addkey)",
+                              FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG,
+                              NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed install encryption key in user's keyring: %m");
                 if (r == 0) {
index 1d012c5d02ba7c678a65a57b47b181ed4ef7e7ce..07d5bcfdb6136eb79fd9f6f4708f6f4bdadb74ac 100644 (file)
@@ -199,12 +199,15 @@ static int run_fsck(const char *node, const char *fstype) {
                 return 0;
         }
 
-        r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR, &fsck_pid);
+        r = safe_fork("(fsck)",
+                      FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+                      &fsck_pid);
         if (r < 0)
                 return r;
         if (r == 0) {
                 /* Child */
                 execl("/sbin/fsck", "/sbin/fsck", "-aTl", node, NULL);
+                log_open();
                 log_error_errno(errno, "Failed to execute fsck: %m");
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
@@ -2351,12 +2354,15 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc
         log_info("Temporary unmounting of file system completed.");
 
         /* resize2fs requires that the file system is force checked first, do so. */
-        r = safe_fork("(e2fsck)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR, &fsck_pid);
+        r = safe_fork("(e2fsck)",
+                      FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+                      &fsck_pid);
         if (r < 0)
                 return r;
         if (r == 0) {
                 /* Child */
                 execlp("e2fsck" ,"e2fsck", "-fp", setup->dm_node, NULL);
+                log_open();
                 log_error_errno(errno, "Failed to execute e2fsck: %m");
                 _exit(EXIT_FAILURE);
         }
@@ -2380,12 +2386,15 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc
                 return log_oom();
 
         /* Resize the thing */
-        r = safe_fork("(e2resize)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, &resize_pid);
+        r = safe_fork("(e2resize)",
+                      FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+                      &resize_pid);
         if (r < 0)
                 return r;
         if (r == 0) {
                 /* Child */
                 execlp("resize2fs" ,"resize2fs", setup->dm_node, size_str, NULL);
+                log_open();
                 log_error_errno(errno, "Failed to execute resize2fs: %m");
                 _exit(EXIT_FAILURE);
         }
index 86df022b64aa64729f23f779210061057a4882df..4cefe3918c9d60dc4180dc7cbd9fa3c8f0d28a07 100644 (file)
@@ -641,7 +641,7 @@ static int request_handler_redirect(
                 struct MHD_Connection *connection,
                 const char *target) {
 
-        char *page;
+        _cleanup_free_ char *page = NULL;
         _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
 
         assert(connection);
@@ -651,10 +651,9 @@ static int request_handler_redirect(
                 return respond_oom(connection);
 
         response = MHD_create_response_from_buffer(strlen(page), page, MHD_RESPMEM_MUST_FREE);
-        if (!response) {
-                free(page);
+        if (!response)
                 return respond_oom(connection);
-        }
+        TAKE_PTR(page);
 
         if (MHD_add_response_header(response, "Content-Type", "text/html") == MHD_NO ||
             MHD_add_response_header(response, "Location", target) == MHD_NO)
index e56e336b4f7ecae14fdef81df888cb5ae53069bb..a8f1f7e5115b4793605d291b34019ad6c9a246eb 100644 (file)
@@ -71,6 +71,9 @@ static void close_fd_input(Uploader *u);
                 }                                                       \
         } while (0)
 
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CURL*, curl_easy_cleanup, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct curl_slist*, curl_slist_free_all, NULL);
+
 static size_t output_callback(char *buf,
                               size_t size,
                               size_t nmemb,
@@ -180,29 +183,28 @@ int start_upload(Uploader *u,
         assert(input_callback);
 
         if (!u->header) {
-                struct curl_slist *h;
+                _cleanup_(curl_slist_free_allp) struct curl_slist *h = NULL;
+                struct curl_slist *l;
 
                 h = curl_slist_append(NULL, "Content-Type: application/vnd.fdo.journal");
                 if (!h)
                         return log_oom();
 
-                h = curl_slist_append(h, "Transfer-Encoding: chunked");
-                if (!h) {
-                        curl_slist_free_all(h);
+                l = curl_slist_append(h, "Transfer-Encoding: chunked");
+                if (!l)
                         return log_oom();
-                }
+                h = l;
 
-                h = curl_slist_append(h, "Accept: text/plain");
-                if (!h) {
-                        curl_slist_free_all(h);
+                l = curl_slist_append(h, "Accept: text/plain");
+                if (!l)
                         return log_oom();
-                }
+                h = l;
 
-                u->header = h;
+                u->header = TAKE_PTR(h);
         }
 
         if (!u->easy) {
-                CURL *curl;
+                _cleanup_(curl_easy_cleanupp) CURL *curl = NULL;
 
                 curl = curl_easy_init();
                 if (!curl)
@@ -260,7 +262,7 @@ int start_upload(Uploader *u,
                         easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1,
                                     LOG_WARNING, );
 
-                u->easy = curl;
+                u->easy = TAKE_PTR(curl);
         } else {
                 /* truncate the potential old error message */
                 u->error[0] = '\0';
index 6b06320d78285fd53119cd3fc2be9225a0e26be3..4b3e697855b34ab389e26c587410063129710fbe 100644 (file)
@@ -2150,7 +2150,10 @@ int main(int argc, char *argv[]) {
 
                 r = mount_image_privately_interactively(
                                 arg_image,
-                                DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_VALIDATE_OS |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
                                 (arg_action == ACTION_UPDATE_CATALOG ? DISSECT_IMAGE_FSCK : DISSECT_IMAGE_READ_ONLY),
                                 &unlink_dir,
                                 &loop_device,
index 73b3240677a279351bf294c98f4599106c9d535a..7bc26097f3a2a20b84b7e1a6bae2b02ffca3fe80 100644 (file)
@@ -334,6 +334,22 @@ static int stdout_stream_log(
         return 0;
 }
 
+static int syslog_parse_priority_and_facility(const char *s) {
+        int prio, r;
+
+        /* Parses both facility and priority in one value, i.e. is different from log_level_from_string()
+         * which only parses the priority and refuses any facility value */
+
+        r = safe_atoi(s, &prio);
+        if (r < 0)
+                return r;
+
+        if (prio < 0 || prio > 999)
+                return -ERANGE;
+
+        return prio;
+}
+
 static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
         char *orig;
         int r;
@@ -373,22 +389,22 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
                 s->state = STDOUT_STREAM_PRIORITY;
                 return 0;
 
-        case STDOUT_STREAM_PRIORITY:
-                r = safe_atoi(p, &s->priority);
-                if (r < 0 || s->priority < 0 || s->priority > 999) {
-                        log_warning("Failed to parse log priority line.");
-                        return -EINVAL;
-                }
+        case STDOUT_STREAM_PRIORITY: {
+                int priority;
+
+                priority = syslog_parse_priority_and_facility(p);
+                if (priority < 0)
+                        return log_warning_errno(priority, "Failed to parse log priority line: %m");
 
+                s->priority = priority;
                 s->state = STDOUT_STREAM_LEVEL_PREFIX;
                 return 0;
+        }
 
         case STDOUT_STREAM_LEVEL_PREFIX:
                 r = parse_boolean(p);
-                if (r < 0) {
-                        log_warning("Failed to parse level prefix line.");
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to parse level prefix line: %m");
 
                 s->level_prefix = r;
                 s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
@@ -396,10 +412,8 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
 
         case STDOUT_STREAM_FORWARD_TO_SYSLOG:
                 r = parse_boolean(p);
-                if (r < 0) {
-                        log_warning("Failed to parse forward to syslog line.");
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to parse forward to syslog line: %m");
 
                 s->forward_to_syslog = r;
                 s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
@@ -407,10 +421,8 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
 
         case STDOUT_STREAM_FORWARD_TO_KMSG:
                 r = parse_boolean(p);
-                if (r < 0) {
-                        log_warning("Failed to parse copy to kmsg line.");
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to parse copy to kmsg line: %m");
 
                 s->forward_to_kmsg = r;
                 s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
@@ -418,10 +430,8 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
 
         case STDOUT_STREAM_FORWARD_TO_CONSOLE:
                 r = parse_boolean(p);
-                if (r < 0) {
-                        log_warning("Failed to parse copy to console line.");
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to parse copy to console line.");
 
                 s->forward_to_console = r;
                 s->state = STDOUT_STREAM_RUNNING;
@@ -750,7 +760,7 @@ static int stdout_stream_load(StdoutStream *stream, const char *fname) {
         if (priority) {
                 int p;
 
-                p = log_level_from_string(priority);
+                p = syslog_parse_priority_and_facility(priority);
                 if (p >= 0)
                         stream->priority = p;
         }
index ee674ebefed4bb93b25f46d5e121129b1b825a2e..18d6b30773bad40962631dc8b50c727ff01382f6 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/journald.conf' to display the full config.
+#
 # See journald.conf(5) for details.
 
 [Journal]
index 40e6b1f26f7a3c7e4d38f352f23dc9f23647e804..c5c851c57506526ffb540024b84d83d2d9488822 100644 (file)
@@ -12,6 +12,7 @@
 #include "sd-dhcp-client.h"
 
 #include "dhcp-protocol.h"
+#include "log-link.h"
 #include "socket-util.h"
 
 typedef struct sd_dhcp_option {
@@ -65,5 +66,15 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui
 #define DHCP_CLIENT_DONT_DESTROY(client) \
         _cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
 
-#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
-#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__)
+#define log_dhcp_client_errno(client, error, fmt, ...)                  \
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                sd_dhcp_client_get_ifname(client),      \
+                                LOG_DEBUG, _e, "DHCPv4 client: " fmt,   \
+                                ##__VA_ARGS__);                         \
+                -ERRNO_VALUE(_e);                                       \
+        })
+#define log_dhcp_client(client, fmt, ...)                       \
+        log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__)
index b5293c3ed66996913223a5c7738c6d270e78f541..33e236627f08b89e38fdcfe8f833b4f063a85903 100644 (file)
@@ -10,7 +10,7 @@
 
 #include "dhcp-internal.h"
 #include "ordered-set.h"
-#include "log.h"
+#include "log-link.h"
 #include "time-util.h"
 
 typedef enum DHCPRawOption {
@@ -48,6 +48,7 @@ struct sd_dhcp_server {
         int fd_raw;
 
         int ifindex;
+        char *ifname;
         be32_t address;
         be32_t netmask;
         be32_t subnet;
@@ -85,9 +86,6 @@ typedef struct DHCPRequest {
         uint32_t lifetime;
 } DHCPRequest;
 
-#define log_dhcp_server(client, fmt, ...) log_internal(LOG_DEBUG, 0, PROJECT_FILE, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
-#define log_dhcp_server_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
-
 int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
                                size_t length);
 int dhcp_server_send_packet(sd_dhcp_server *server,
@@ -96,3 +94,16 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
 
 void client_id_hash_func(const DHCPClientId *p, struct siphash *state);
 int client_id_compare_func(const DHCPClientId *a, const DHCPClientId *b);
+
+#define log_dhcp_server_errno(server, error, fmt, ...)                  \
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_dhcp_server_get_ifname(server),  \
+                                    LOG_DEBUG, _e, "DHCPv4 server: " fmt, \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
+#define log_dhcp_server(server, fmt, ...)                       \
+        log_dhcp_server_errno(server, 0, fmt, ##__VA_ARGS__)
index 681c462315587cfea3cbc0b1ff32db791983716f..274b14b056e2a56d25be36c1f45c58179ce47a68 100644 (file)
@@ -9,9 +9,11 @@
 #include <netinet/in.h>
 
 #include "sd-event.h"
+#include "sd-dhcp6-client.h"
 
-#include "list.h"
 #include "hashmap.h"
+#include "list.h"
+#include "log-link.h"
 #include "macro.h"
 #include "sparse-endian.h"
 
@@ -78,7 +80,7 @@ struct ia_ta {
         be32_t id;
 } _packed_;
 
-struct DHCP6IA {
+typedef struct DHCP6IA {
         uint16_t type;
         union {
                 struct ia_na ia_na;
@@ -87,12 +89,7 @@ struct DHCP6IA {
         };
 
         LIST_HEAD(DHCP6Address, addresses);
-};
-
-typedef struct DHCP6IA DHCP6IA;
-
-#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
-#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__)
+} DHCP6IA;
 
 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                         size_t optlen, const void *optval);
@@ -105,7 +102,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
 int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
                        size_t *optlen, uint8_t **optvalue);
 int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
-int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
+int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
 int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
                                 struct in6_addr **addrs, size_t count,
                                 size_t *allocated);
@@ -121,3 +118,16 @@ const char *dhcp6_message_type_to_string(int s) _const_;
 int dhcp6_message_type_from_string(const char *s) _pure_;
 const char *dhcp6_message_status_to_string(int s) _const_;
 int dhcp6_message_status_from_string(const char *s) _pure_;
+
+#define log_dhcp6_client_errno(client, error, fmt, ...)                 \
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_dhcp6_client_get_ifname(client), \
+                                    LOG_DEBUG, _e, "DHCPv6 client: " fmt, \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
+#define log_dhcp6_client(client, fmt, ...)                       \
+        log_dhcp6_client_errno(client, 0, fmt, ##__VA_ARGS__)
index 93140160245380ac293256df80b32cff8f43bf38..ff51758e0bc05f51bbfdbf0b38044d97dd1a0ce4 100644 (file)
@@ -257,9 +257,9 @@ int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd, con
                 len += r;
         }
 
-        if (hint_pd_prefix) {
+        if (hint_pd_prefix && hint_pd_prefix->iapdprefix.prefixlen > 0) {
                 r = option_append_pd_prefix(buf, buflen, hint_pd_prefix);
-                if (r < 0 && r != -EINVAL)
+                if (r < 0)
                         return r;
 
                 len += r;
@@ -425,7 +425,7 @@ int dhcp6_option_parse_status(DHCP6Option *option, size_t len) {
         return be16toh(statusopt->status);
 }
 
-static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
+static int dhcp6_option_parse_address(sd_dhcp6_client *client, DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
         DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option;
         DHCP6Address *addr;
         uint32_t lt_valid, lt_pref;
@@ -437,23 +437,20 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t
         lt_valid = be32toh(addr_option->iaaddr.lifetime_valid);
         lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred);
 
-        if (lt_valid == 0 || lt_pref > lt_valid) {
-                log_dhcp6_client(client,
-                                 "Valid lifetime of an IA address is zero or "
-                                 "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
-                                 lt_pref, lt_valid);
-                return -EINVAL;
-        }
+        if (lt_valid == 0 || lt_pref > lt_valid)
+                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                              "Valid lifetime of an IA address is zero or "
+                                              "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
+                                              lt_pref, lt_valid);
 
         if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*addr_option)) {
                 r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*addr_option));
                 if (r < 0)
                         return r;
-                if (r > 0) {
-                        log_dhcp6_client(client, "Non-zero status code '%s' for address is received",
-                                         dhcp6_message_status_to_string(r));
-                        return -EINVAL;
-                }
+                if (r > 0)
+                        return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                      "Non-zero status code '%s' for address is received",
+                                                      dhcp6_message_status_to_string(r));
         }
 
         addr = new0(DHCP6Address, 1);
@@ -470,7 +467,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t
         return 0;
 }
 
-static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
+static int dhcp6_option_parse_pdprefix(sd_dhcp6_client *client, DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
         DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option;
         DHCP6Address *prefix;
         uint32_t lt_valid, lt_pref;
@@ -482,23 +479,20 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_
         lt_valid = be32toh(pdprefix_option->iapdprefix.lifetime_valid);
         lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred);
 
-        if (lt_valid == 0 || lt_pref > lt_valid) {
-                log_dhcp6_client(client,
-                                 "Valid lifetieme of a PD prefix is zero or "
-                                 "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
-                                 lt_pref, lt_valid);
-                return -EINVAL;
-        }
+        if (lt_valid == 0 || lt_pref > lt_valid)
+                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                              "Valid lifetieme of a PD prefix is zero or "
+                                              "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
+                                              lt_pref, lt_valid);
 
         if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*pdprefix_option)) {
                 r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*pdprefix_option));
                 if (r < 0)
                         return r;
-                if (r > 0) {
-                        log_dhcp6_client(client, "Non-zero status code '%s' for PD prefix is received",
-                                         dhcp6_message_status_to_string(r));
-                        return -EINVAL;
-                }
+                if (r > 0)
+                        return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                      "Non-zero status code '%s' for PD prefix is received",
+                                                      dhcp6_message_status_to_string(r));
         }
 
         prefix = new0(DHCP6Address, 1);
@@ -515,7 +509,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_
         return 0;
 }
 
-int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) {
+int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) {
         uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX;
         uint16_t iatype, optlen;
         size_t iaaddr_offset;
@@ -541,10 +535,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
                 lt_t1 = be32toh(ia->ia_na.lifetime_t1);
                 lt_t2 = be32toh(ia->ia_na.lifetime_t2);
 
-                if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
-                        log_dhcp6_client(client, "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2);
-                        return -EINVAL;
-                }
+                if (lt_t1 > lt_t2)
+                        return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                      "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec",
+                                                      lt_t1, lt_t2);
 
                 break;
 
@@ -559,10 +553,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
                 lt_t1 = be32toh(ia->ia_pd.lifetime_t1);
                 lt_t2 = be32toh(ia->ia_pd.lifetime_t2);
 
-                if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
-                        log_dhcp6_client(client, "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2);
-                        return -EINVAL;
-                }
+                if (lt_t1 > lt_t2)
+                        return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                      "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec",
+                                                      lt_t1, lt_t2);
 
                 break;
 
@@ -594,12 +588,11 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
                 switch (opt) {
                 case SD_DHCP6_OPTION_IAADDR:
 
-                        if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) {
-                                log_dhcp6_client(client, "IA Address option not in IA NA or TA option");
-                                return -EINVAL;
-                        }
+                        if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA))
+                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                              "IA Address option not in IA NA or TA option");
 
-                        r = dhcp6_option_parse_address(option, ia, &lt_valid);
+                        r = dhcp6_option_parse_address(client, option, ia, &lt_valid);
                         if (r < 0 && r != -EINVAL)
                                 return r;
                         if (r >= 0 && lt_valid < lt_min)
@@ -609,12 +602,11 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
 
                 case SD_DHCP6_OPTION_IA_PD_PREFIX:
 
-                        if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) {
-                                log_dhcp6_client(client, "IA PD Prefix option not in IA PD option");
-                                return -EINVAL;
-                        }
+                        if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD))
+                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
+                                                              "IA PD Prefix option not in IA PD option");
 
-                        r = dhcp6_option_parse_pdprefix(option, ia, &lt_valid);
+                        r = dhcp6_option_parse_pdprefix(client, option, ia, &lt_valid);
                         if (r < 0 && r != -EINVAL)
                                 return r;
                         if (r >= 0 && lt_valid < lt_min)
@@ -650,7 +642,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
 
         switch(iatype) {
         case SD_DHCP6_OPTION_IA_NA:
-                if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2 && lt_min != UINT32_MAX) {
+                if (ia->ia_na.lifetime_t1 == 0 && ia->ia_na.lifetime_t2 == 0 && lt_min != UINT32_MAX) {
                         lt_t1 = lt_min / 2;
                         lt_t2 = lt_min / 10 * 8;
                         ia->ia_na.lifetime_t1 = htobe32(lt_t1);
@@ -663,7 +655,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
                 break;
 
         case SD_DHCP6_OPTION_IA_PD:
-                if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2 && lt_min != UINT32_MAX) {
+                if (ia->ia_pd.lifetime_t1 == 0 && ia->ia_pd.lifetime_t2 == 0 && lt_min != UINT32_MAX) {
                         lt_t1 = lt_min / 2;
                         lt_t2 = lt_min / 10 * 8;
                         ia->ia_pd.lifetime_t1 = htobe32(lt_t1);
index daedbb088fbb767eb6567b9fd4a8e6a880c7f8c4..f13555d35c46d922e463a5bf4ca2ae11b10e1bca 100644 (file)
@@ -5,13 +5,14 @@
 #include "sd-lldp.h"
 
 #include "hashmap.h"
-#include "log.h"
+#include "log-link.h"
 #include "prioq.h"
 
 struct sd_lldp {
         unsigned n_ref;
 
         int ifindex;
+        char *ifname;
         int fd;
 
         sd_event *event;
@@ -32,8 +33,18 @@ struct sd_lldp {
         struct ether_addr filter_address;
 };
 
-#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
-#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__)
-
 const char* lldp_event_to_string(sd_lldp_event_t e) _const_;
 sd_lldp_event_t lldp_event_from_string(const char *s) _pure_;
+
+#define log_lldp_errno(lldp, error, fmt, ...)                           \
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_lldp_get_ifname(lldp),           \
+                                    LOG_DEBUG, _e, "LLDP: " fmt,        \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
+#define log_lldp(lldp, fmt, ...)                       \
+        log_lldp_errno(lldp, 0, fmt, ##__VA_ARGS__)
index 546ae1c980fa167f4f35d4d4f15b6bb1f31cfff8..3bd775158efdbb6c3ea8858f5f9241f415ea0b9c 100644 (file)
@@ -112,7 +112,7 @@ sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size) {
         return n;
 }
 
-static int parse_string(char **s, const void *q, size_t n) {
+static int parse_string(sd_lldp *lldp, char **s, const void *q, size_t n) {
         const char *p = q;
         char *k;
 
@@ -120,7 +120,7 @@ static int parse_string(char **s, const void *q, size_t n) {
         assert(p || n == 0);
 
         if (*s) {
-                log_lldp("Found duplicate string, ignoring field.");
+                log_lldp(lldp, "Found duplicate string, ignoring field.");
                 return 0;
         }
 
@@ -133,14 +133,14 @@ static int parse_string(char **s, const void *q, size_t n) {
 
         /* Look for inner NULs */
         if (memchr(p, 0, n)) {
-                log_lldp("Found inner NUL in string, ignoring field.");
+                log_lldp(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;
+                return log_oom_debug();
 
         free(*s);
         *s = k;
@@ -156,27 +156,24 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
 
         assert(n);
 
-        if (n->raw_size < sizeof(struct ether_header)) {
-                log_lldp("Received truncated packet, ignoring.");
-                return -EBADMSG;
-        }
+        if (n->raw_size < sizeof(struct ether_header))
+                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                      "Received truncated packet, ignoring.");
 
         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_type != htobe16(ETHERTYPE_LLDP))
+                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                      "Received packet with wrong type, ignoring.");
 
         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;
-        }
+            !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e))
+                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                      "Received packet with wrong destination address, ignoring.");
 
         memcpy(&n->source_address, h.ether_shost, sizeof(struct ether_addr));
         memcpy(&n->destination_address, h.ether_dhost, sizeof(struct ether_addr));
@@ -188,27 +185,24 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
                 uint8_t type;
                 uint16_t length;
 
-                if (left < 2) {
-                        log_lldp("TLV lacks header, ignoring.");
-                        return -EBADMSG;
-                }
+                if (left < 2)
+                        return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                              "TLV lacks header, ignoring.");
 
                 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;
-                }
+                if (left < length)
+                        return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                              "TLV truncated, ignoring datagram.");
 
                 switch (type) {
 
                 case SD_LLDP_TYPE_END:
-                        if (length != 0) {
-                                log_lldp("End marker TLV not zero-sized, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (length != 0)
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "End marker TLV not zero-sized, ignoring datagram.");
 
                         /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0
                          * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */
@@ -216,98 +210,93 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
                         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;
-                        }
+                        if (length < 2 || length > 256)
+                                /* includes the chassis subtype, hence one extra byte */
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "Chassis ID field size out of range, ignoring datagram.");
+
+                        if (n->id.chassis_id)
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "Duplicate chassis ID field, ignoring datagram.");
 
                         n->id.chassis_id = memdup(p, length);
                         if (!n->id.chassis_id)
-                                return -ENOMEM;
+                                return log_oom_debug();
 
                         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;
-                        }
+                        if (length < 2 || length > 256)
+                                /* includes the port subtype, hence one extra byte */
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "Port ID field size out of range, ignoring datagram.");
+
+                        if (n->id.port_id)
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "Duplicate port ID field, ignoring datagram.");
 
                         n->id.port_id = memdup(p, length);
                         if (!n->id.port_id)
-                                return -ENOMEM;
+                                return log_oom_debug();
 
                         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 (length != 2)
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "TTL field has wrong size, ignoring datagram.");
 
-                        if (n->has_ttl) {
-                                log_lldp("Duplicate TTL field, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (n->has_ttl)
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "Duplicate TTL field, ignoring datagram.");
 
                         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);
+                        r = parse_string(n->lldp, &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);
+                        r = parse_string(n->lldp, &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);
+                        r = parse_string(n->lldp, &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;
-                        }
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "System capabilities field has wrong size.");
 
+                        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: {
+                case SD_LLDP_TYPE_PRIVATE:
                         if (length < 4)
-                                log_lldp("Found private TLV that is too short, ignoring.");
-                        else {
-                                /* RFC 8520: MUD URL */
-                                if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 &&
-                                    p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) {
-                                        r = parse_string(&n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1,
-                                                         length - 1 - sizeof(SD_LLDP_OUI_MUD));
-                                        if (r < 0)
-                                                return r;
-                                }
+                                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                                      "Found private TLV that is too short, ignoring.");
+
+                        /* RFC 8520: MUD URL */
+                        if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 &&
+                            p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) {
+                                r = parse_string(n->lldp, &n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1,
+                                                 length - 1 - sizeof(SD_LLDP_OUI_MUD));
+                                if (r < 0)
+                                        return r;
                         }
-                }
-
                         break;
                 }
 
@@ -315,11 +304,9 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
         }
 
 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;
-
-        }
+        if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl)
+                return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG),
+                                      "One or more mandatory TLV missing in datagram. Ignoring.");
 
         n->rindex = sizeof(struct ether_header);
 
index 6bc4a3f54b56a632735fbf97b038455e9f9c9a1b..ca3393eff367425d4908f56cb35b92c7a9c7f653 100644 (file)
@@ -16,6 +16,8 @@ sources = files('''
         sd-ipv4acd.c
         arp-util.h
         arp-util.c
+        network-common.c
+        network-common.h
         network-internal.c
         network-internal.h
         sd-ndisc.c
index 70b254867bbf81bd5ec9c63989d4f55688430e57..44a7e76c21e38b0ef425c35e49a8c3819cc3bd62 100644 (file)
@@ -5,11 +5,11 @@
   Copyright © 2014 Intel Corporation. All rights reserved.
 ***/
 
-#include "log.h"
-#include "time-util.h"
-
 #include "sd-ndisc.h"
 
+#include "log-link.h"
+#include "time-util.h"
+
 #define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
 #define NDISC_MAX_ROUTER_SOLICITATION_INTERVAL (3600U * USEC_PER_SEC)
 #define NDISC_MAX_ROUTER_SOLICITATIONS 3U
@@ -18,6 +18,7 @@ struct sd_ndisc {
         unsigned n_ref;
 
         int ifindex;
+        char *ifname;
         int fd;
 
         sd_event *event;
@@ -37,8 +38,18 @@ struct sd_ndisc {
         void *userdata;
 };
 
-#define log_ndisc_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "NDISC: " fmt, ##__VA_ARGS__)
-#define log_ndisc(fmt, ...) log_ndisc_errno(0, fmt, ##__VA_ARGS__)
-
 const char* ndisc_event_to_string(sd_ndisc_event_t e) _const_;
 sd_ndisc_event_t ndisc_event_from_string(const char *s) _pure_;
+
+#define log_ndisc_errno(ndisc, error, fmt, ...)                         \
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_ndisc_get_ifname(ndisc),         \
+                                    LOG_DEBUG, _e, "NDISC: " fmt,       \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
+#define log_ndisc(ndisc, fmt, ...)                       \
+        log_ndisc_errno(ndisc, 0, fmt, ##__VA_ARGS__)
index c88293a9239cf5b3d05b8cf3973f2e5c70e94c4b..46f30332bbf8ffbeb82b2e2d62760bfb39047e6e 100644 (file)
@@ -43,7 +43,7 @@ _public_ int sd_ndisc_router_from_raw(sd_ndisc_router **ret, const void *raw, si
                 return -ENOMEM;
 
         memcpy(NDISC_ROUTER_RAW(rt), raw, raw_size);
-        r = ndisc_router_parse(rt);
+        r = ndisc_router_parse(NULL, rt);
         if (r < 0)
                 return r;
 
@@ -87,7 +87,7 @@ _public_ int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size
         return 0;
 }
 
-int ndisc_router_parse(sd_ndisc_router *rt) {
+int ndisc_router_parse(sd_ndisc *nd, sd_ndisc_router *rt) {
         struct nd_router_advert *a;
         const uint8_t *p;
         bool has_mtu = false, has_flag_extension = false;
@@ -95,23 +95,20 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
 
         assert(rt);
 
-        if (rt->raw_size < sizeof(struct nd_router_advert)) {
-                log_ndisc("Too small to be a router advertisement, ignoring.");
-                return -EBADMSG;
-        }
+        if (rt->raw_size < sizeof(struct nd_router_advert))
+                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                       "Too small to be a router advertisement, ignoring.");
 
         /* Router advertisement packets are neatly aligned to 64bit boundaries, hence we can access them directly */
         a = NDISC_ROUTER_RAW(rt);
 
-        if (a->nd_ra_type != ND_ROUTER_ADVERT) {
-                log_ndisc("Received ND packet that is not a router advertisement, ignoring.");
-                return -EBADMSG;
-        }
+        if (a->nd_ra_type != ND_ROUTER_ADVERT)
+                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                       "Received ND packet that is not a router advertisement, ignoring.");
 
-        if (a->nd_ra_code != 0) {
-                log_ndisc("Received ND packet with wrong RA code, ignoring.");
-                return -EBADMSG;
-        }
+        if (a->nd_ra_code != 0)
+                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                       "Received ND packet with wrong RA code, ignoring.");
 
         rt->hop_limit = a->nd_ra_curhoplimit;
         rt->flags = a->nd_ra_flags_reserved; /* the first 8bit */
@@ -131,36 +128,31 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
                 if (left == 0)
                         break;
 
-                if (left < 2) {
-                        log_ndisc("Option lacks header, ignoring datagram.");
-                        return -EBADMSG;
-                }
+                if (left < 2)
+                        return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                               "Option lacks header, ignoring datagram.");
 
                 type = p[0];
                 length = p[1] * 8;
 
-                if (length == 0) {
-                        log_ndisc("Zero-length option, ignoring datagram.");
-                        return -EBADMSG;
-                }
-                if (left < length) {
-                        log_ndisc("Option truncated, ignoring datagram.");
-                        return -EBADMSG;
-                }
+                if (length == 0)
+                        return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                               "Zero-length option, ignoring datagram.");
+                if (left < length)
+                        return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                               "Option truncated, ignoring datagram.");
 
                 switch (type) {
 
                 case SD_NDISC_OPTION_PREFIX_INFORMATION:
 
-                        if (length != 4*8) {
-                                log_ndisc("Prefix option of invalid size, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (length != 4*8)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "Prefix option of invalid size, ignoring datagram.");
 
-                        if (p[2] > 128) {
-                                log_ndisc("Bad prefix length, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (p[2] > 128)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "Bad prefix length, ignoring datagram.");
 
                         break;
 
@@ -168,14 +160,13 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
                         uint32_t m;
 
                         if (has_mtu) {
-                                log_ndisc("MTU option specified twice, ignoring.");
+                                log_ndisc(nd, "MTU option specified twice, ignoring.");
                                 break;
                         }
 
-                        if (length != 8) {
-                                log_ndisc("MTU option of invalid size, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (length != 8)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "MTU option of invalid size, ignoring datagram.");
 
                         m = be32toh(*(uint32_t*) (p + 4));
                         if (m >= IPV6_MIN_MTU) /* ignore invalidly small MTUs */
@@ -186,37 +177,32 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
                 }
 
                 case SD_NDISC_OPTION_ROUTE_INFORMATION:
-                        if (length < 1*8 || length > 3*8) {
-                                log_ndisc("Route information option of invalid size, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (length < 1*8 || length > 3*8)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "Route information option of invalid size, ignoring datagram.");
 
-                        if (p[2] > 128) {
-                                log_ndisc("Bad route prefix length, ignoring datagram.");
-                                return -EBADMSG;
-                        }
+                        if (p[2] > 128)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "Bad route prefix length, ignoring datagram.");
 
                         break;
 
                 case SD_NDISC_OPTION_RDNSS:
-                        if (length < 3*8 || (length % (2*8)) != 1*8) {
-                                log_ndisc("RDNSS option has invalid size.");
-                                return -EBADMSG;
-                        }
+                        if (length < 3*8 || (length % (2*8)) != 1*8)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG), "RDNSS option has invalid size.");
 
                         break;
 
                 case SD_NDISC_OPTION_FLAGS_EXTENSION:
 
                         if (has_flag_extension) {
-                                log_ndisc("Flags extension option specified twice, ignoring.");
+                                log_ndisc(nd, "Flags extension option specified twice, ignoring.");
                                 break;
                         }
 
-                        if (length < 1*8) {
-                                log_ndisc("Flags extension option has invalid size.");
-                                return -EBADMSG;
-                        }
+                        if (length < 1*8)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "Flags extension option has invalid size.");
 
                         /* Add in the additional flags bits */
                         rt->flags |=
@@ -231,10 +217,9 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
                         break;
 
                 case SD_NDISC_OPTION_DNSSL:
-                        if (length < 2*8) {
-                                log_ndisc("DNSSL option has invalid size.");
-                                return -EBADMSG;
-                        }
+                        if (length < 2*8)
+                                return log_ndisc_errno(nd, SYNTHETIC_ERRNO(EBADMSG),
+                                                       "DNSSL option has invalid size.");
 
                         break;
                 }
@@ -437,7 +422,7 @@ _public_ int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret)
         flags = pi->nd_opt_pi_flags_reserved;
 
         if ((flags & ND_OPT_PI_FLAG_AUTO) && (pi->nd_opt_pi_prefix_len != 64)) {
-                log_ndisc("Invalid prefix length, ignoring prefix for stateless autoconfiguration.");
+                log_ndisc(NULL, "Invalid prefix length, ignoring prefix for stateless autoconfiguration.");
                 flags &= ~ND_OPT_PI_FLAG_AUTO;
         }
 
index cb3a56452be69f7ad3a2b45225ed19ad6b3ff377..f5293c96e01df8d4c0eebc7e05a4079b3610cf33 100644 (file)
@@ -45,4 +45,4 @@ static inline size_t NDISC_ROUTER_OPTION_LENGTH(const sd_ndisc_router *rt) {
 }
 
 sd_ndisc_router *ndisc_router_new(size_t raw_size);
-int ndisc_router_parse(sd_ndisc_router *rt);
+int ndisc_router_parse(sd_ndisc *nd, sd_ndisc_router *rt);
diff --git a/src/libsystemd-network/network-common.c b/src/libsystemd-network/network-common.c
new file mode 100644 (file)
index 0000000..9bc0da9
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "format-util.h"
+#include "network-common.h"
+#include "string-util.h"
+
+const char *get_ifname(int ifindex, char **ifname) {
+        char buf[IF_NAMESIZE + 1];
+
+        assert(ifname);
+
+        /* This sets ifname only when it is not set yet. */
+
+        if (*ifname)
+                return *ifname;
+
+        if (ifindex <= 0)
+                return NULL;
+
+        if (!format_ifname(ifindex, buf))
+                return NULL;
+
+        return *ifname = strdup(buf);
+}
diff --git a/src/libsystemd-network/network-common.h b/src/libsystemd-network/network-common.h
new file mode 100644 (file)
index 0000000..76a6c4a
--- /dev/null
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+const char *get_ifname(int ifindex, char **ifname);
index 3dbeffe0c65a5a3e147f7bcee04a0786b49af33b..fe5d74fda41042fce17842446e2539d46de839d1 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "sd-radv.h"
 
-#include "log.h"
+#include "log-link.h"
 #include "list.h"
 #include "sparse-endian.h"
 
@@ -41,6 +41,7 @@ struct sd_radv {
         RAdvState state;
 
         int ifindex;
+        char *ifname;
 
         sd_event *event;
         int event_priority;
@@ -124,6 +125,15 @@ struct sd_radv_route_prefix {
         LIST_FIELDS(struct sd_radv_route_prefix, prefix);
 };
 
-#define log_radv_full(level, error, fmt, ...) log_internal(level, error, PROJECT_FILE, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
-#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
-#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)
+#define log_radv_errno(radv, error, fmt, ...)                           \
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_radv_get_ifname(radv),           \
+                                    LOG_DEBUG, _e, "RADV: " fmt,        \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
+#define log_radv(radv, fmt, ...)                       \
+        log_radv_errno(radv, 0, fmt, ##__VA_ARGS__)
index fb94fdc88289ace602f0f5e552498245de141175..d516162266a4145bcbaa1382bc60a4c2e200db21 100644 (file)
@@ -24,6 +24,7 @@
 #include "hostname-util.h"
 #include "io-util.h"
 #include "memory-util.h"
+#include "network-common.h"
 #include "random-util.h"
 #include "set.h"
 #include "sort-util.h"
@@ -76,6 +77,7 @@ struct sd_dhcp_client {
         int event_priority;
         sd_event_source *timeout_resend;
         int ifindex;
+        char *ifname;
         int fd;
         uint16_t port;
         union sockaddr_union link;
@@ -282,6 +284,23 @@ int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) {
         return 0;
 }
 
+int sd_dhcp_client_set_ifname(sd_dhcp_client *client, const char *ifname) {
+        assert_return(client, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&client->ifname, ifname);
+}
+
+const char *sd_dhcp_client_get_ifname(sd_dhcp_client *client) {
+        if (!client)
+                return NULL;
+
+        return get_ifname(client->ifindex, &client->ifname);
+}
+
 int sd_dhcp_client_set_mac(
                 sd_dhcp_client *client,
                 const uint8_t *addr,
@@ -2205,6 +2224,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
         client->user_class = strv_free(client->user_class);
         ordered_hashmap_free(client->extra_options);
         ordered_hashmap_free(client->vendor_options);
+        free(client->ifname);
         return mfree(client);
 }
 
index 2b1384cff085ae78785ebd63a92289debf1b1029..0036cddbf93cd031e601e486eb978ecb759cfc53 100644 (file)
@@ -15,6 +15,7 @@
 #include "fd-util.h"
 #include "in-addr-util.h"
 #include "io-util.h"
+#include "network-common.h"
 #include "ordered-set.h"
 #include "siphash24.h"
 #include "string-util.h"
@@ -158,6 +159,8 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
         ordered_set_free(server->vendor_options);
 
         free(server->bound_leases);
+
+        free(server->ifname);
         return mfree(server);
 }
 
@@ -169,29 +172,47 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
         assert_return(ret, -EINVAL);
         assert_return(ifindex > 0, -EINVAL);
 
-        server = new0(sd_dhcp_server, 1);
+        server = new(sd_dhcp_server, 1);
         if (!server)
                 return -ENOMEM;
 
-        server->n_ref = 1;
-        server->fd_raw = -1;
-        server->fd = -1;
-        server->address = htobe32(INADDR_ANY);
-        server->netmask = htobe32(INADDR_ANY);
-        server->ifindex = ifindex;
+        *server = (sd_dhcp_server) {
+                .n_ref = 1,
+                .fd_raw = -1,
+                .fd = -1,
+                .address = htobe32(INADDR_ANY),
+                .netmask = htobe32(INADDR_ANY),
+                .ifindex = ifindex,
+                .default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC),
+                .max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC),
+        };
 
         server->leases_by_client_id = hashmap_new(&dhcp_lease_hash_ops);
         if (!server->leases_by_client_id)
                 return -ENOMEM;
 
-        server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC);
-        server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC);
-
         *ret = TAKE_PTR(server);
 
         return 0;
 }
 
+int sd_dhcp_server_set_ifname(sd_dhcp_server *server, const char *ifname) {
+        assert_return(server, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&server->ifname, ifname);
+}
+
+const char *sd_dhcp_server_get_ifname(sd_dhcp_server *server) {
+        if (!server)
+                return NULL;
+
+        return get_ifname(server->ifindex, &server->ifname);
+}
+
 int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event, int64_t priority) {
         int r;
 
index 410bfda10eaaab91f96f466c3e55be7a40eea771..c8a4c79ffe6e52f21c4cc2d34b387ee7b60ba347 100644 (file)
@@ -21,6 +21,7 @@
 #include "hexdecoct.h"
 #include "hostname-util.h"
 #include "in-addr-util.h"
+#include "network-common.h"
 #include "random-util.h"
 #include "socket-util.h"
 #include "string-table.h"
@@ -47,6 +48,7 @@ struct sd_dhcp6_client {
         sd_event *event;
         int event_priority;
         int ifindex;
+        char *ifname;
         DHCP6Address hint_pd_prefix;
         struct in6_addr local_address;
         uint8_t mac_addr[MAX_MAC_ADDR_LEN];
@@ -165,6 +167,23 @@ int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) {
         return 0;
 }
 
+int sd_dhcp6_client_set_ifname(sd_dhcp6_client *client, const char *ifname) {
+        assert_return(client, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&client->ifname, ifname);
+}
+
+const char *sd_dhcp6_client_get_ifname(sd_dhcp6_client *client) {
+        if (!client)
+                return NULL;
+
+        return get_ifname(client->ifindex, &client->ifname);
+}
+
 int sd_dhcp6_client_set_local_address(
                 sd_dhcp6_client *client,
                 const struct in6_addr *local_address) {
@@ -1172,7 +1191,7 @@ static int client_parse_message(
                                 break;
                         }
 
-                        r = dhcp6_option_parse_ia(option, &lease->ia, &ia_na_status);
+                        r = dhcp6_option_parse_ia(client, option, &lease->ia, &ia_na_status);
                         if (r < 0 && r != -ENOMSG)
                                 return r;
 
@@ -1205,7 +1224,7 @@ static int client_parse_message(
                                 break;
                         }
 
-                        r = dhcp6_option_parse_ia(option, &lease->pd, &ia_pd_status);
+                        r = dhcp6_option_parse_ia(client, option, &lease->pd, &ia_pd_status);
                         if (r < 0 && r != -ENOMSG)
                                 return r;
 
@@ -1787,6 +1806,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
         ordered_hashmap_free(client->extra_options);
         strv_free(client->user_class);
         strv_free(client->vendor_class);
+        free(client->ifname);
 
         return mfree(client);
 }
index d6f0708c942a81220485288113bd692195d06091..aca2c1f7e072546929bf5a2d7beb3965bb0cab85 100644 (file)
@@ -206,7 +206,7 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
                                         lease->dns_count,
                                         &lease->dns_allocated);
         if (r < 0)
-                return log_dhcp6_client_errno(client, r, "Invalid DNS server option: %m");
+                return r;
 
         lease->dns_count = r;
 
@@ -321,19 +321,16 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen)
         if (!optlen)
                 return 0;
 
-        if (lease->ntp || lease->ntp_fqdn) {
-                log_dhcp6_client(client, "NTP information already provided");
+        if (lease->ntp || lease->ntp_fqdn)
+                return -EEXIST;
 
-                return 0;
-        }
-
-        log_dhcp6_client(client, "Using deprecated SNTP information");
+        /* Using deprecated SNTP information */
 
         r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp,
                                         lease->ntp_count,
                                         &lease->ntp_allocated);
         if (r < 0)
-                return log_dhcp6_client_errno(client, r, "Invalid SNTP server option: %m");
+                return r;
 
         lease->ntp_count = r;
 
index defd23d85a76201d0b424aea308e6b31b62a80c4..643bdc4ba9ca34dec946f7fe10ef1cdd257e72d9 100644 (file)
@@ -16,9 +16,9 @@
 #include "ether-addr-util.h"
 #include "event-util.h"
 #include "fd-util.h"
-#include "format-util.h"
 #include "in-addr-util.h"
 #include "log-link.h"
+#include "network-common.h"
 #include "random-util.h"
 #include "siphash24.h"
 #include "string-table.h"
@@ -56,7 +56,7 @@ struct sd_ipv4acd {
         int ifindex;
         int fd;
 
-        char ifname[IF_NAMESIZE + 1];
+        char *ifname;
         unsigned n_iteration;
         unsigned n_conflict;
 
@@ -76,7 +76,15 @@ struct sd_ipv4acd {
 };
 
 #define log_ipv4acd_errno(acd, error, fmt, ...)                         \
-        log_interface_full_errno(sd_ipv4acd_get_ifname(acd), LOG_DEBUG, error, "IPV4ACD: " fmt, ##__VA_ARGS__)
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_ipv4acd_get_ifname(acd),         \
+                                    LOG_DEBUG, _e, "IPv4ACD: " fmt,     \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
 #define log_ipv4acd(acd, fmt, ...)                      \
         log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__)
 
@@ -125,7 +133,7 @@ static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) {
 
         ipv4acd_reset(acd);
         sd_ipv4acd_detach_event(acd);
-
+        free(acd->ifname);
         return mfree(acd);
 }
 
@@ -398,16 +406,10 @@ fail:
 }
 
 int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int ifindex) {
-        char ifname[IF_NAMESIZE + 1];
-
         assert_return(acd, -EINVAL);
         assert_return(ifindex > 0, -EINVAL);
         assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
 
-        if (!format_ifname(ifindex, ifname))
-                return -ENODEV;
-
-        strcpy(acd->ifname, ifname);
         acd->ifindex = ifindex;
 
         return 0;
@@ -420,11 +422,21 @@ int sd_ipv4acd_get_ifindex(sd_ipv4acd *acd) {
         return acd->ifindex;
 }
 
+int sd_ipv4acd_set_ifname(sd_ipv4acd *acd, const char *ifname) {
+        assert_return(acd, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&acd->ifname, ifname);
+}
+
 const char *sd_ipv4acd_get_ifname(sd_ipv4acd *acd) {
         if (!acd)
                 return NULL;
 
-        return empty_to_null(acd->ifname);
+        return get_ifname(acd->ifindex, &acd->ifname);
 }
 
 int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr) {
index a83c9b06de50d7557286449e58b95cc287866183..49e9350fba51363c9c7bbd98f8ca19ed92eab633 100644 (file)
@@ -50,7 +50,15 @@ struct sd_ipv4ll {
 };
 
 #define log_ipv4ll_errno(ll, error, fmt, ...)                           \
-        log_interface_full_errno(sd_ipv4ll_get_ifname(ll), LOG_DEBUG, error, "IPV4LL: " fmt, ##__VA_ARGS__)
+        ({                                                              \
+                int _e = (error);                                       \
+                if (DEBUG_LOGGING)                                      \
+                        log_interface_full_errno(                       \
+                                    sd_ipv4ll_get_ifname(ll),           \
+                                    LOG_DEBUG, _e, "IPv4LL: " fmt,      \
+                                    ##__VA_ARGS__);                     \
+                -ERRNO_VALUE(_e);                                       \
+        })
 #define log_ipv4ll(ll, fmt, ...)                        \
         log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__)
 
@@ -112,6 +120,13 @@ int sd_ipv4ll_get_ifindex(sd_ipv4ll *ll) {
         return sd_ipv4acd_get_ifindex(ll->acd);
 }
 
+int sd_ipv4ll_set_ifname(sd_ipv4ll *ll, const char *ifname) {
+        assert_return(ll, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        return sd_ipv4acd_set_ifname(ll->acd, ifname);
+}
+
 const char *sd_ipv4ll_get_ifname(sd_ipv4ll *ll) {
         if (!ll)
                 return NULL;
index 3c0285df4e92308856af3294e111210ffeacad1a..49aa876a530f2714b2ecc83505a1b68cd3f670cf 100644 (file)
@@ -14,6 +14,7 @@
 #include "lldp-neighbor.h"
 #include "lldp-network.h"
 #include "memory-util.h"
+#include "network-common.h"
 #include "socket-util.h"
 #include "sort-util.h"
 #include "string-table.h"
@@ -39,12 +40,10 @@ static void lldp_callback(sd_lldp *lldp, sd_lldp_event_t event, sd_lldp_neighbor
         assert(lldp);
         assert(event >= 0 && event < _SD_LLDP_EVENT_MAX);
 
-        if (!lldp->callback) {
-                log_lldp("Received '%s' event.", lldp_event_to_string(event));
-                return;
-        }
+        if (!lldp->callback)
+                return (void) log_lldp(lldp, "Received '%s' event.", lldp_event_to_string(event));
 
-        log_lldp("Invoking callback for '%s' event.", lldp_event_to_string(event));
+        log_lldp(lldp, "Invoking callback for '%s' event.", lldp_event_to_string(event));
         lldp->callback(lldp, event, n, lldp->userdata);
 }
 
@@ -186,11 +185,11 @@ static int lldp_handle_datagram(sd_lldp *lldp, sd_lldp_neighbor *n) {
 
         r = lldp_add_neighbor(lldp, n);
         if (r < 0) {
-                log_lldp_errno(r, "Failed to add datagram. Ignoring.");
+                log_lldp_errno(lldp, r, "Failed to add datagram. Ignoring.");
                 return 0;
         }
 
-        log_lldp("Successfully processed LLDP datagram.");
+        log_lldp(lldp, "Successfully processed LLDP datagram.");
         return 0;
 }
 
@@ -204,8 +203,10 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v
         assert(lldp);
 
         space = next_datagram_size_fd(fd);
-        if (space < 0)
-                return log_lldp_errno(space, "Failed to determine datagram size to read: %m");
+        if (space < 0) {
+                log_lldp_errno(lldp, space, "Failed to determine datagram size to read, ignoring: %m");
+                return 0;
+        }
 
         n = lldp_neighbor_new(space);
         if (!n)
@@ -216,12 +217,13 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v
                 if (IN_SET(errno, EAGAIN, EINTR))
                         return 0;
 
-                return log_lldp_errno(errno, "Failed to read LLDP datagram: %m");
+                log_lldp_errno(lldp, errno, "Failed to read LLDP datagram, ignoring: %m");
+                return 0;
         }
 
         if ((size_t) length != n->raw_size) {
-                log_lldp("Packet size mismatch.");
-                return -EINVAL;
+                log_lldp(lldp, "Packet size mismatch, ignoring");
+                return 0;
         }
 
         /* Try to get the timestamp of this packet if it is known */
@@ -267,7 +269,7 @@ _public_ int sd_lldp_start(sd_lldp *lldp) {
 
         (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io");
 
-        log_lldp("Started LLDP client");
+        log_lldp(lldp, "Started LLDP client");
         return 1;
 
 fail:
@@ -282,7 +284,7 @@ _public_ int sd_lldp_stop(sd_lldp *lldp) {
         if (lldp->fd < 0)
                 return 0;
 
-        log_lldp("Stopping LLDP client");
+        log_lldp(lldp, "Stopping LLDP client");
 
         lldp_reset(lldp);
         lldp_flush_neighbors(lldp);
@@ -343,6 +345,23 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) {
         return 0;
 }
 
+int sd_lldp_set_ifname(sd_lldp *lldp, const char *ifname) {
+        assert_return(lldp, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&lldp->ifname, ifname);
+}
+
+const char *sd_lldp_get_ifname(sd_lldp *lldp) {
+        if (!lldp)
+                return NULL;
+
+        return get_ifname(lldp->ifindex, &lldp->ifname);
+}
+
 static sd_lldp* lldp_free(sd_lldp *lldp) {
         assert(lldp);
 
@@ -354,6 +373,7 @@ static sd_lldp* lldp_free(sd_lldp *lldp) {
 
         hashmap_free(lldp->neighbor_by_id);
         prioq_free(lldp->neighbor_by_expiry);
+        free(lldp->ifname);
         return mfree(lldp);
 }
 
@@ -398,12 +418,16 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
         int r;
 
         r = lldp_make_space(lldp, 0);
-        if (r < 0)
-                return log_lldp_errno(r, "Failed to make space: %m");
+        if (r < 0) {
+                log_lldp_errno(lldp, r, "Failed to make space, ignoring: %m");
+                return 0;
+        }
 
         r = lldp_start_timer(lldp, NULL);
-        if (r < 0)
-                return log_lldp_errno(r, "Failed to restart timer: %m");
+        if (r < 0) {
+                log_lldp_errno(lldp, r, "Failed to restart timer, ignoring: %m");
+                return 0;
+        }
 
         return 0;
 }
index 8f04001755ac4c85e61962f3c44a204ac8cb798d..4d5f1b54cd4d5f01a50604a3d3cba9c5ffd446fa 100644 (file)
@@ -16,6 +16,7 @@
 #include "memory-util.h"
 #include "ndisc-internal.h"
 #include "ndisc-router.h"
+#include "network-common.h"
 #include "random-util.h"
 #include "socket-util.h"
 #include "string-table.h"
@@ -34,12 +35,10 @@ static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event_t event, sd_ndisc_rou
         assert(ndisc);
         assert(event >= 0 && event < _SD_NDISC_EVENT_MAX);
 
-        if (!ndisc->callback) {
-                log_ndisc("Received '%s' event.", ndisc_event_to_string(event));
-                return;
-        }
+        if (!ndisc->callback)
+                return (void) log_ndisc(ndisc, "Received '%s' event.", ndisc_event_to_string(event));
 
-        log_ndisc("Invoking callback for '%s' event.", ndisc_event_to_string(event));
+        log_ndisc(ndisc, "Invoking callback for '%s' event.", ndisc_event_to_string(event));
         ndisc->callback(ndisc, event, rt, ndisc->userdata);
 }
 
@@ -65,6 +64,23 @@ _public_ int sd_ndisc_set_ifindex(sd_ndisc *nd, int ifindex) {
         return 0;
 }
 
+int sd_ndisc_set_ifname(sd_ndisc *nd, const char *ifname) {
+        assert_return(nd, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&nd->ifname, ifname);
+}
+
+const char *sd_ndisc_get_ifname(sd_ndisc *nd) {
+        if (!nd)
+                return NULL;
+
+        return get_ifname(nd->ifindex, &nd->ifname);
+}
+
 _public_ int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr) {
         assert_return(nd, -EINVAL);
 
@@ -129,6 +145,7 @@ static sd_ndisc *ndisc_free(sd_ndisc *nd) {
 
         ndisc_reset(nd);
         sd_ndisc_detach_event(nd);
+        free(nd->ifname);
         return mfree(nd);
 }
 
@@ -181,7 +198,7 @@ static int ndisc_handle_datagram(sd_ndisc *nd, sd_ndisc_router *rt) {
         assert(nd);
         assert(rt);
 
-        r = ndisc_router_parse(rt);
+        r = ndisc_router_parse(nd, rt);
         if (r == -EBADMSG) /* Bad packet */
                 return 0;
         if (r < 0)
@@ -193,7 +210,7 @@ static int ndisc_handle_datagram(sd_ndisc *nd, sd_ndisc_router *rt) {
         if (rt->hop_limit > 0)
                 nd->hop_limit = rt->hop_limit;
 
-        log_ndisc("Received Router Advertisement: flags %s preference %s lifetime %" PRIu16 " sec",
+        log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %" PRIu16 " sec",
                   rt->flags & ND_RA_FLAG_MANAGED ? "MANAGED" : rt->flags & ND_RA_FLAG_OTHER ? "OTHER" : "none",
                   rt->preference == SD_NDISC_PREFERENCE_HIGH ? "high" : rt->preference == SD_NDISC_PREFERENCE_LOW ? "low" : "medium",
                   rt->lifetime);
@@ -214,8 +231,10 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
         assert(nd->event);
 
         buflen = next_datagram_size_fd(fd);
-        if (buflen < 0)
-                return log_ndisc_errno(buflen, "Failed to determine datagram size to read: %m");
+        if (buflen < 0) {
+                log_ndisc_errno(nd, buflen, "Failed to determine datagram size to read, ignoring: %m");
+                return 0;
+        }
 
         rt = ndisc_router_new(buflen);
         if (!rt)
@@ -226,22 +245,22 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
                 switch (r) {
                 case -EADDRNOTAVAIL:
                         (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &rt->address, &addr);
-                        log_ndisc("Received RA from non-link-local address %s. Ignoring", addr);
+                        log_ndisc(nd, "Received RA from non-link-local address %s. Ignoring", addr);
                         break;
 
                 case -EMULTIHOP:
-                        log_ndisc("Received RA with invalid hop limit. Ignoring.");
+                        log_ndisc(nd, "Received RA with invalid hop limit. Ignoring.");
                         break;
 
                 case -EPFNOSUPPORT:
-                        log_ndisc("Received invalid source address from ICMPv6 socket. Ignoring.");
+                        log_ndisc(nd, "Received invalid source address from ICMPv6 socket. Ignoring.");
                         break;
 
                 case -EAGAIN: /* ignore spurious wakeups */
                         break;
 
                 default:
-                        log_ndisc_errno(r, "Unexpected error while reading from ICMPv6, ignoring: %m");
+                        log_ndisc_errno(nd, r, "Unexpected error while reading from ICMPv6, ignoring: %m");
                         break;
                 }
 
@@ -290,11 +309,11 @@ static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
 
         r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
         if (r < 0) {
-                log_ndisc_errno(r, "Error sending Router Solicitation: %m");
+                log_ndisc_errno(nd, r, "Error sending Router Solicitation: %m");
                 goto fail;
         }
 
-        log_ndisc("Sent Router Solicitation, next solicitation in %s",
+        log_ndisc(nd, "Sent Router Solicitation, next solicitation in %s",
                   format_timespan(time_string, FORMAT_TIMESPAN_MAX,
                                   nd->retransmit_time, USEC_PER_SEC));
 
@@ -311,7 +330,7 @@ static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata
         assert(s);
         assert(nd);
 
-        log_ndisc("No RA received before link confirmation timeout");
+        log_ndisc(nd, "No RA received before link confirmation timeout");
 
         (void) event_source_disable(nd->timeout_no_ra);
         ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
@@ -326,7 +345,7 @@ _public_ int sd_ndisc_stop(sd_ndisc *nd) {
         if (nd->fd < 0)
                 return 0;
 
-        log_ndisc("Stopping IPv6 Router Solicitation client");
+        log_ndisc(nd, "Stopping IPv6 Router Solicitation client");
 
         ndisc_reset(nd);
         return 1;
@@ -379,7 +398,7 @@ _public_ int sd_ndisc_start(sd_ndisc *nd) {
         if (r < 0)
                 goto fail;
 
-        log_ndisc("Started IPv6 Router Solicitation client");
+        log_ndisc(nd, "Started IPv6 Router Solicitation client");
         return 1;
 
 fail:
index 164b24c6847f40ea49e2bf035fad4b61414a594b..857401bf6e06df3245ad54769c5153681782250e 100644 (file)
@@ -19,6 +19,7 @@
 #include "io-util.h"
 #include "macro.h"
 #include "memory-util.h"
+#include "network-common.h"
 #include "radv-internal.h"
 #include "random-util.h"
 #include "socket-util.h"
@@ -122,6 +123,7 @@ static sd_radv *radv_free(sd_radv *ra) {
         sd_radv_detach_event(ra);
 
         ra->fd = safe_close(ra->fd);
+        free(ra->ifname);
 
         return mfree(ra);
 }
@@ -245,22 +247,22 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
                 switch (r) {
                 case -EADDRNOTAVAIL:
                         (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &src, &addr);
-                        log_radv("Received RS from non-link-local address %s. Ignoring", addr);
+                        log_radv(ra, "Received RS from non-link-local address %s. Ignoring", addr);
                         break;
 
                 case -EMULTIHOP:
-                        log_radv("Received RS with invalid hop limit. Ignoring.");
+                        log_radv(ra, "Received RS with invalid hop limit. Ignoring.");
                         break;
 
                 case -EPFNOSUPPORT:
-                        log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
+                        log_radv(ra, "Received invalid source address from ICMPv6 socket. Ignoring.");
                         break;
 
                 case -EAGAIN: /* ignore spurious wakeups */
                         break;
 
                 default:
-                        log_radv_errno(r, "Unexpected error receiving from ICMPv6 socket: %m");
+                        log_radv_errno(ra, r, "Unexpected error receiving from ICMPv6 socket, Ignoring: %m");
                         break;
                 }
 
@@ -268,7 +270,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
         }
 
         if ((size_t) buflen < sizeof(struct nd_router_solicit)) {
-                log_radv("Too short packet received");
+                log_radv(ra, "Too short packet received, ignoring");
                 return 0;
         }
 
@@ -276,9 +278,9 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
 
         r = radv_send(ra, &src, ra->lifetime);
         if (r < 0)
-                log_radv_errno(r, "Unable to send solicited Router Advertisement to %s: %m", strnull(addr));
+                log_radv_errno(ra, r, "Unable to send solicited Router Advertisement to %s, ignoring: %m", strnull(addr));
         else
-                log_radv("Sent solicited Router Advertisement to %s", strnull(addr));
+                log_radv(ra, "Sent solicited Router Advertisement to %s", strnull(addr));
 
         return 0;
 }
@@ -311,7 +313,7 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
 
         r = radv_send(ra, NULL, ra->lifetime);
         if (r < 0)
-                log_radv_errno(r, "Unable to send Router Advertisement: %m");
+                log_radv_errno(ra, r, "Unable to send Router Advertisement: %m");
 
         /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
         if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
@@ -328,7 +330,7 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
 
         timeout = radv_compute_timeout(min_timeout, max_timeout);
 
-        log_radv("Next Router Advertisement in %s",
+        log_radv(ra, "Next Router Advertisement in %s",
                  format_timespan(time_string, FORMAT_TIMESPAN_MAX,
                                  timeout, USEC_PER_SEC));
 
@@ -359,13 +361,13 @@ _public_ int sd_radv_stop(sd_radv *ra) {
         if (ra->state == SD_RADV_STATE_IDLE)
                 return 0;
 
-        log_radv("Stopping IPv6 Router Advertisement daemon");
+        log_radv(ra, "Stopping IPv6 Router Advertisement daemon");
 
         /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
            with zero lifetime  */
         r = radv_send(ra, NULL, 0);
         if (r < 0)
-                log_radv_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
+                log_radv_errno(ra, r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
 
         radv_reset(ra);
         ra->fd = safe_close(ra->fd);
@@ -410,7 +412,7 @@ _public_ int sd_radv_start(sd_radv *ra) {
 
         ra->state = SD_RADV_STATE_ADVERTISING;
 
-        log_radv("Started IPv6 Router Advertisement daemon");
+        log_radv(ra, "Started IPv6 Router Advertisement daemon");
 
         return 0;
 
@@ -432,6 +434,23 @@ _public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
         return 0;
 }
 
+int sd_radv_set_ifname(sd_radv *ra, const char *ifname) {
+        assert_return(ra, -EINVAL);
+        assert_return(ifname, -EINVAL);
+
+        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
+                return -EINVAL;
+
+        return free_and_strdup(&ra->ifname, ifname);
+}
+
+const char *sd_radv_get_ifname(sd_radv *ra) {
+        if (!ra)
+                return NULL;
+
+        return get_ifname(ra->ifindex, &ra->ifname);
+}
+
 _public_ int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) {
         assert_return(ra, -EINVAL);
 
@@ -562,10 +581,9 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
                 (void) in_addr_prefix_to_string(AF_INET6,
                                                 (const union in_addr_union*) &cur->opt.in6_addr,
                                                 cur->opt.prefixlen, &addr_cur);
-                log_radv("IPv6 prefix %s already configured, ignoring %s",
-                         strna(addr_cur), strna(addr_p));
-
-                return -EEXIST;
+                return log_radv_errno(ra, SYNTHETIC_ERRNO(EEXIST),
+                                      "IPv6 prefix %s already configured, ignoring %s",
+                                      strna(addr_cur), strna(addr_p));
         }
 
         p = sd_radv_prefix_ref(p);
@@ -575,7 +593,7 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
         ra->n_prefixes++;
 
         if (!dynamic) {
-                log_radv("Added prefix %s", strna(addr_p));
+                log_radv(ra, "Added prefix %s", strna(addr_p));
                 return 0;
         }
 
@@ -585,9 +603,9 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
         if (ra->ra_sent > 0) {
                 r = radv_send(ra, NULL, ra->lifetime);
                 if (r < 0)
-                        log_radv_errno(r, "Unable to send Router Advertisement for added prefix: %m");
+                        log_radv_errno(ra, r, "Unable to send Router Advertisement for added prefix: %m");
                 else
-                        log_radv("Sent Router Advertisement for added prefix");
+                        log_radv(ra, "Sent Router Advertisement for added prefix");
         }
 
  update:
@@ -608,7 +626,7 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
         cur->valid_until = valid_until;
         cur->preferred_until = preferred_until;
 
-        log_radv("Updated prefix %s preferred %s valid %s",
+        log_radv(ra, "Updated prefix %s preferred %s valid %s",
                  strna(addr_p),
                  format_timespan(time_string_preferred, FORMAT_TIMESPAN_MAX,
                                  preferred, USEC_PER_SEC),
@@ -678,10 +696,9 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
                 (void) in_addr_prefix_to_string(AF_INET6,
                                                 (const union in_addr_union*) &cur->opt.in6_addr,
                                                 cur->opt.prefixlen, &addr);
-                log_radv("IPv6 route prefix %s already configured, ignoring %s",
-                         strna(addr), strna(pretty));
-
-                return -EEXIST;
+                return log_radv_errno(ra, SYNTHETIC_ERRNO(EEXIST),
+                                      "IPv6 route prefix %s already configured, ignoring %s",
+                                      strna(addr), strna(pretty));
         }
 
         p = sd_radv_route_prefix_ref(p);
@@ -690,7 +707,7 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
         ra->n_route_prefixes++;
 
         if (!dynamic) {
-                log_radv("Added prefix %s", strna(pretty));
+                log_radv(ra, "Added prefix %s", strna(pretty));
                 return 0;
         }
 
@@ -698,9 +715,9 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
         if (ra->ra_sent > 0) {
                 r = radv_send(ra, NULL, ra->lifetime);
                 if (r < 0)
-                        log_radv_errno(r, "Unable to send Router Advertisement for added route prefix: %m");
+                        log_radv_errno(ra, r, "Unable to send Router Advertisement for added route prefix: %m");
                 else
-                        log_radv("Sent Router Advertisement for added route prefix");
+                        log_radv(ra, "Sent Router Advertisement for added route prefix");
         }
 
  update:
@@ -713,7 +730,7 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
         if (valid_until == USEC_INFINITY)
                 return -EOVERFLOW;
 
-        log_radv("Updated route prefix %s valid %s",
+        log_radv(ra, "Updated route prefix %s valid %s",
                  strna(pretty),
                  format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, valid, USEC_PER_SEC));
 
@@ -842,7 +859,7 @@ _public_ int sd_radv_prefix_set_prefix(sd_radv_prefix *p, const struct in6_addr
 
         if (prefixlen > 64)
                 /* unusual but allowed, log it */
-                log_radv("Unusual prefix length %d greater than 64", prefixlen);
+                log_radv(NULL, "Unusual prefix length %d greater than 64", prefixlen);
 
         p->opt.in6_addr = *in6_addr;
         p->opt.prefixlen = prefixlen;
@@ -932,7 +949,7 @@ _public_ int sd_radv_prefix_set_route_prefix(sd_radv_route_prefix *p, const stru
 
         if (prefixlen > 64)
                 /* unusual but allowed, log it */
-                log_radv("Unusual prefix length %u greater than 64", prefixlen);
+                log_radv(NULL, "Unusual prefix length %u greater than 64", prefixlen);
 
         p->opt.in6_addr = *in6_addr;
         p->opt.prefixlen = prefixlen;
index cb363b3973ff244dc8050eed8dc819f6435ff185..5d0c5ed2a21624a4602520e80e7c2bc733585885 100644 (file)
@@ -295,17 +295,17 @@ static int test_option_status(sd_event *e) {
         option = (DHCP6Option *)option1;
         assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
 
-        r = dhcp6_option_parse_ia(option, &ia, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
         assert_se(r == 0);
         assert_se(ia.addresses == NULL);
 
         option->len = htobe16(17);
-        r = dhcp6_option_parse_ia(option, &ia, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
         assert_se(r == -ENOBUFS);
         assert_se(ia.addresses == NULL);
 
         option->len = htobe16(sizeof(DHCP6Option));
-        r = dhcp6_option_parse_ia(option, &ia, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
         assert_se(r == -ENOBUFS);
         assert_se(ia.addresses == NULL);
 
@@ -313,7 +313,7 @@ static int test_option_status(sd_event *e) {
         option = (DHCP6Option *)option2;
         assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
 
-        r = dhcp6_option_parse_ia(option, &ia, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
         assert_se(r >= 0);
         assert_se(ia.addresses == NULL);
 
@@ -321,7 +321,7 @@ static int test_option_status(sd_event *e) {
         option = (DHCP6Option *)option3;
         assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
 
-        r = dhcp6_option_parse_ia(option, &ia, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
         assert_se(r >= 0);
         assert_se(ia.addresses != NULL);
         dhcp6_lease_free_ia(&ia);
@@ -330,7 +330,7 @@ static int test_option_status(sd_event *e) {
         option = (DHCP6Option *)option4;
         assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
 
-        r = dhcp6_option_parse_ia(option, &pd, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &pd, NULL);
         assert_se(r >= 0);
         assert_se(pd.addresses != NULL);
         assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
@@ -342,7 +342,7 @@ static int test_option_status(sd_event *e) {
         option = (DHCP6Option *)option5;
         assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
 
-        r = dhcp6_option_parse_ia(option, &pd, NULL);
+        r = dhcp6_option_parse_ia(NULL, option, &pd, NULL);
         assert_se(r >= 0);
         assert_se(pd.addresses != NULL);
         dhcp6_lease_free_ia(&pd);
@@ -449,6 +449,7 @@ static int test_advertise_option(sd_event *e) {
 
                 case SD_DHCP6_OPTION_IA_NA:
                         assert_se(optlen == 94);
+                        assert_se(optval == &msg_advertise[26]);
                         assert_se(!memcmp(optval, &msg_advertise[26], optlen));
 
                         val = htobe32(0x0ecfa37d);
@@ -460,12 +461,13 @@ static int test_advertise_option(sd_event *e) {
                         val = htobe32(120);
                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
 
-                        assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
+                        assert_se(dhcp6_option_parse_ia(NULL, option, &lease->ia, NULL) >= 0);
 
                         break;
 
                 case SD_DHCP6_OPTION_SERVERID:
                         assert_se(optlen == 14);
+                        assert_se(optval == &msg_advertise[179]);
                         assert_se(!memcmp(optval, &msg_advertise[179], optlen));
 
                         assert_se(dhcp6_lease_set_serverid(lease, optval,
@@ -656,7 +658,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
 
                         /* Then, this should refuse all addresses. */
-                        assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
+                        assert_se(dhcp6_option_parse_ia(NULL, option, &lease->ia, NULL) >= 0);
 
                         break;
 
index 3134d8ef1723aac663de573ab174c3ccf535b1b1..5e748fdb462b986bf4877327e0ca51886e3c6e5c 100644 (file)
@@ -1002,7 +1002,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                 const char *p;
 
                 p = procfs_file_alloca(pid, "cmdline");
-                r = read_full_file(p, &c->cmdline, &c->cmdline_size);
+                r = read_full_virtual_file(p, &c->cmdline, &c->cmdline_size);
                 if (r == -ENOENT)
                         return -ESRCH;
                 if (r < 0) {
index 557284faf8258ca9d21cdb9a93bae878c0922f5d..d981f72449ee26e07d979fe1ddb75b9ccf10e6ef 100644 (file)
@@ -28,11 +28,17 @@ int bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_lis
  * the bus error table, and BUS_ERROR_MAP_ELF_USE has to be used at
  * least once per compilation unit (i.e. per library), to ensure that
  * the error map is really added to the final binary.
+ *
+ * In addition, set the retain attribute so that the section cannot be
+ * discarded by ld --gc-sections -z start-stop-gc. Older compilers would
+ * warn for the unknown attribute, so just disable -Wattributes.
  */
 
 #define BUS_ERROR_MAP_ELF_REGISTER                                      \
+        _Pragma("GCC diagnostic ignored \"-Wattributes\"")              \
         _section_("SYSTEMD_BUS_ERROR_MAP")                              \
         _used_                                                          \
+        __attribute__((retain))                                         \
         _alignptr_                                                      \
         _variable_no_sanitize_address_
 
index c98b029af23c84c26373e8fed865aa9d63afae71..2434fb625e58dbccdedc909097eb88e01a8124ca 100644 (file)
@@ -116,6 +116,8 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer
         else
                 hashmap = &enumerator->nomatch_sysattr;
 
+        /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
+         * multiple times with the same sysattr but different value. */
         r = hashmap_put_strdup_full(hashmap, &trivial_hash_ops_free_free, sysattr, value);
         if (r <= 0)
                 return r;
@@ -131,6 +133,8 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
         assert_return(enumerator, -EINVAL);
         assert_return(property, -EINVAL);
 
+        /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
+         * multiple times with the same property but different value. */
         r = hashmap_put_strdup_full(&enumerator->match_property, &trivial_hash_ops_free_free, property, value);
         if (r <= 0)
                 return r;
index 203106ab44929546f2f5404761d923a15aeb0a4d..3948e862a9f81be01cda8e70e90f4c07b09b78c8 100644 (file)
@@ -83,8 +83,8 @@ static int monitor_set_nl_address(sd_device_monitor *m) {
 }
 
 int device_monitor_allow_unicast_sender(sd_device_monitor *m, sd_device_monitor *sender) {
-        assert_return(m, -EINVAL);
-        assert_return(sender, -EINVAL);
+        assert(m);
+        assert(sender);
 
         m->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
         return 0;
@@ -104,7 +104,7 @@ int device_monitor_disconnect(sd_device_monitor *m) {
 }
 
 int device_monitor_get_fd(sd_device_monitor *m) {
-        assert_return(m, -EINVAL);
+        assert(m);
 
         return m->sock;
 }
@@ -114,8 +114,8 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
         _cleanup_close_ int sock = -1;
         int r;
 
+        assert(group >= 0 && group < _MONITOR_NETLINK_GROUP_MAX);
         assert_return(ret, -EINVAL);
-        assert_return(group >= 0 && group < _MONITOR_NETLINK_GROUP_MAX, -EINVAL);
 
         if (group == MONITOR_GROUP_UDEV &&
             access("/run/udev/control", F_OK) < 0 &&
@@ -304,7 +304,7 @@ _public_ sd_event_source *sd_device_monitor_get_event_source(sd_device_monitor *
 int device_monitor_enable_receiving(sd_device_monitor *m) {
         int r;
 
-        assert_return(m, -EINVAL);
+        assert(m);
 
         r = sd_device_monitor_filter_update(m);
         if (r < 0)
@@ -334,8 +334,8 @@ static sd_device_monitor *device_monitor_free(sd_device_monitor *m) {
 
         (void) sd_device_monitor_detach_event(m);
 
-        hashmap_free_free_free(m->subsystem_filter);
-        set_free_free(m->tag_filter);
+        hashmap_free(m->subsystem_filter);
+        set_free(m->tag_filter);
 
         return mfree(m);
 }
@@ -346,8 +346,8 @@ static int passes_filter(sd_device_monitor *m, sd_device *device) {
         const char *tag, *subsystem, *devtype, *s, *d = NULL;
         int r;
 
-        assert_return(m, -EINVAL);
-        assert_return(device, -EINVAL);
+        assert(m);
+        assert(device);
 
         if (hashmap_isempty(m->subsystem_filter))
                 goto tag;
@@ -413,6 +413,7 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
         bool is_initialized = false;
         int r;
 
+        assert(m);
         assert(ret);
 
         buflen = recvmsg(m->sock, &smsg, 0);
@@ -507,10 +508,10 @@ static uint64_t string_bloom64(const char *str) {
         uint64_t bits = 0;
         uint32_t hash = string_hash32(str);
 
-        bits |= 1LLU << (hash & 63);
-        bits |= 1LLU << ((hash >> 6) & 63);
-        bits |= 1LLU << ((hash >> 12) & 63);
-        bits |= 1LLU << ((hash >> 18) & 63);
+        bits |= UINT64_C(1) << (hash & 63);
+        bits |= UINT64_C(1) << ((hash >> 6) & 63);
+        bits |= UINT64_C(1) << ((hash >> 12) & 63);
+        bits |= UINT64_C(1) << ((hash >> 18) & 63);
         return bits;
 }
 
@@ -717,41 +718,32 @@ _public_ int sd_device_monitor_filter_update(sd_device_monitor *m) {
 }
 
 _public_ int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor *m, const char *subsystem, const char *devtype) {
-        _cleanup_free_ char *s = NULL, *d = NULL;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(subsystem, -EINVAL);
 
-        s = strdup(subsystem);
-        if (!s)
-                return -ENOMEM;
-
-        if (devtype) {
-                d = strdup(devtype);
-                if (!d)
-                        return -ENOMEM;
-        }
-
-        r = hashmap_ensure_put(&m->subsystem_filter, NULL, s, d);
-        if (r < 0)
+        /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
+         * multiple times with the same subsystem but different devtypes. */
+        r = hashmap_put_strdup_full(&m->subsystem_filter, &trivial_hash_ops_free_free, subsystem, devtype);
+        if (r <= 0)
                 return r;
 
-        TAKE_PTR(s);
-        TAKE_PTR(d);
-
         m->filter_uptodate = false;
-
-        return 0;
+        return r;
 }
 
 _public_ int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag) {
+        int r;
+
         assert_return(m, -EINVAL);
         assert_return(tag, -EINVAL);
 
-        int r = set_put_strdup(&m->tag_filter, tag);
-        if (r > 0)
-                m->filter_uptodate = false;
+        r = set_put_strdup(&m->tag_filter, tag);
+        if (r <= 0)
+                return r;
+
+        m->filter_uptodate = false;
         return r;
 }
 
@@ -760,8 +752,8 @@ _public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) {
 
         assert_return(m, -EINVAL);
 
-        m->subsystem_filter = hashmap_free_free_free(m->subsystem_filter);
-        m->tag_filter = set_free_free(m->tag_filter);
+        m->subsystem_filter = hashmap_free(m->subsystem_filter);
+        m->tag_filter = set_free(m->tag_filter);
 
         if (setsockopt(m->sock, SOL_SOCKET, SO_DETACH_FILTER, &filter, sizeof(filter)) < 0)
                 return -errno;
index 964ef1318edfeaf2efb75d07567e0a659bfe8f45..e556a6f838ca9237913c5b747296c8b8d0ae40d7 100644 (file)
@@ -513,7 +513,7 @@ int device_read_uevent_file(sd_device *device) {
 
         path = strjoina(syspath, "/uevent");
 
-        r = read_full_file(path, &uevent, &uevent_len);
+        r = read_full_virtual_file(path, &uevent, &uevent_len);
         if (r == -EACCES) {
                 /* empty uevent files may be write-only */
                 device->uevent_loaded = true;
index 763e98c114d837b1d356475e5afb6d4e0c336def..644f3c2aeeec87c8411892863fe0a774d07a7063 100644 (file)
@@ -30,8 +30,6 @@ int main(int argc, char *argv[]) {
         const char *key, *value;
         int r;
 
-        unsetenv("SYSTEMD_MEMPOOL");
-
         r = sd_device_new_from_syspath(&loopback, "/sys/class/net/lo");
         if (r < 0)
                 return handle_error_errno(r, "Failed to create loopback device object");
index 8ab9d419af5cdab7c084fba029a3d9c3bded949d..b76b0623fe3562f80f8751ac3a0ec177931dbc3b 100644 (file)
@@ -1039,7 +1039,7 @@ static int source_set_pending(sd_event_source *s, bool b) {
                 }
         }
 
-        return 0;
+        return 1;
 }
 
 static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) {
@@ -3116,11 +3116,19 @@ static int process_timer(
         return 0;
 }
 
-static int process_child(sd_event *e) {
+static int process_child(sd_event *e, int64_t threshold, int64_t *ret_min_priority) {
+        int64_t min_priority = threshold;
+        bool something_new = false;
         sd_event_source *s;
         int r;
 
         assert(e);
+        assert(ret_min_priority);
+
+        if (!e->need_process_child) {
+                *ret_min_priority = min_priority;
+                return 0;
+        }
 
         e->need_process_child = false;
 
@@ -3145,6 +3153,9 @@ static int process_child(sd_event *e) {
         HASHMAP_FOREACH(s, e->child_sources) {
                 assert(s->type == SOURCE_CHILD);
 
+                if (s->priority > threshold)
+                        continue;
+
                 if (s->pending)
                         continue;
 
@@ -3181,10 +3192,15 @@ static int process_child(sd_event *e) {
                         r = source_set_pending(s, true);
                         if (r < 0)
                                 return r;
+                        if (r > 0) {
+                                something_new = true;
+                                min_priority = MIN(min_priority, s->priority);
+                        }
                 }
         }
 
-        return 0;
+        *ret_min_priority = min_priority;
+        return something_new;
 }
 
 static int process_pidfd(sd_event *e, sd_event_source *s, uint32_t revents) {
@@ -3214,13 +3230,13 @@ static int process_pidfd(sd_event *e, sd_event_source *s, uint32_t revents) {
         return source_set_pending(s, true);
 }
 
-static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
-        bool read_one = false;
+static int process_signal(sd_event *e, struct signal_data *d, uint32_t events, int64_t *min_priority) {
         int r;
 
         assert(e);
         assert(d);
         assert_return(events == EPOLLIN, -EIO);
+        assert(min_priority);
 
         /* If there's a signal queued on this priority and SIGCHLD is
            on this priority too, then make sure to recheck the
@@ -3246,7 +3262,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
                 n = read(d->fd, &si, sizeof(si));
                 if (n < 0) {
                         if (IN_SET(errno, EAGAIN, EINTR))
-                                return read_one;
+                                return 0;
 
                         return -errno;
                 }
@@ -3256,8 +3272,6 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
 
                 assert(SIGNAL_VALID(si.ssi_signo));
 
-                read_one = true;
-
                 if (e->signal_sources)
                         s = e->signal_sources[si.ssi_signo];
                 if (!s)
@@ -3271,12 +3285,16 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
                 r = source_set_pending(s, true);
                 if (r < 0)
                         return r;
+                if (r > 0 && *min_priority >= s->priority) {
+                        *min_priority = s->priority;
+                        return 1; /* an event source with smaller priority is queued. */
+                }
 
-                return 1;
+                return 0;
         }
 }
 
-static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t revents) {
+static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t revents, int64_t threshold) {
         ssize_t n;
 
         assert(e);
@@ -3292,6 +3310,9 @@ static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t
         if (d->buffer_filled > 0)
                 return 0;
 
+        if (d->priority > threshold)
+                return 0;
+
         n = read(d->fd, &d->buffer, sizeof(d->buffer));
         if (n < 0) {
                 if (IN_SET(errno, EAGAIN, EINTR))
@@ -3787,10 +3808,15 @@ static int epoll_wait_usec(
                 int maxevents,
                 usec_t timeout) {
 
-        static bool epoll_pwait2_absent = false;
         int r, msec;
+#if 0
+        static bool epoll_pwait2_absent = false;
 
-        /* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not */
+        /* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not.
+         *
+         * FIXME: this is temporarily disabled until epoll_pwait2() becomes more widely available.
+         * See https://github.com/systemd/systemd/pull/18973 and
+         * https://github.com/systemd/systemd/issues/19052. */
 
         if (!epoll_pwait2_absent && timeout != USEC_INFINITY) {
                 struct timespec ts;
@@ -3802,12 +3828,13 @@ static int epoll_wait_usec(
                                  NULL);
                 if (r >= 0)
                         return r;
-                if (!ERRNO_IS_NOT_SUPPORTED(r) && !ERRNO_IS_PRIVILEGE(r))
+                if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
                         return -errno; /* Only fallback to old epoll_wait() if the syscall is masked or not
                                         * supported. */
 
                 epoll_pwait2_absent = true;
         }
+#endif
 
         if (timeout == USEC_INFINITY)
                 msec = -1;
@@ -3831,20 +3858,14 @@ static int epoll_wait_usec(
         return r;
 }
 
-_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
+static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t *ret_min_priority) {
+        int64_t min_priority = threshold;
+        bool something_new = false;
         size_t n_event_queue, m;
         int r;
 
-        assert_return(e, -EINVAL);
-        assert_return(e = event_resolve(e), -ENOPKG);
-        assert_return(!event_pid_changed(e), -ECHILD);
-        assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
-        assert_return(e->state == SD_EVENT_ARMED, -EBUSY);
-
-        if (e->exit_requested) {
-                e->state = SD_EVENT_PENDING;
-                return 1;
-        }
+        assert(e);
+        assert(ret_min_priority);
 
         n_event_queue = MAX(e->n_sources, 1u);
         if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, n_event_queue))
@@ -3856,12 +3877,8 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
 
         for (;;) {
                 r = epoll_wait_usec(e->epoll_fd, e->event_queue, e->event_queue_allocated, timeout);
-                if (r == -EINTR) {
-                        e->state = SD_EVENT_PENDING;
-                        return 1;
-                }
                 if (r < 0)
-                        goto finish;
+                        return r;
 
                 m = (size_t) r;
 
@@ -3877,7 +3894,9 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
                 timeout = 0;
         }
 
-        triple_timestamp_get(&e->timestamp);
+        /* Set timestamp only when this is called first time. */
+        if (threshold == INT64_MAX)
+                triple_timestamp_get(&e->timestamp);
 
         for (size_t i = 0; i < m; i++) {
 
@@ -3893,6 +3912,11 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
 
                                 assert(s);
 
+                                if (s->priority > threshold)
+                                        continue;
+
+                                min_priority = MIN(min_priority, s->priority);
+
                                 switch (s->type) {
 
                                 case SOURCE_IO:
@@ -3920,19 +3944,75 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
                         }
 
                         case WAKEUP_SIGNAL_DATA:
-                                r = process_signal(e, e->event_queue[i].data.ptr, e->event_queue[i].events);
+                                r = process_signal(e, e->event_queue[i].data.ptr, e->event_queue[i].events, &min_priority);
                                 break;
 
                         case WAKEUP_INOTIFY_DATA:
-                                r = event_inotify_data_read(e, e->event_queue[i].data.ptr, e->event_queue[i].events);
+                                r = event_inotify_data_read(e, e->event_queue[i].data.ptr, e->event_queue[i].events, threshold);
                                 break;
 
                         default:
                                 assert_not_reached("Invalid wake-up pointer");
                         }
                 }
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        something_new = true;
+        }
+
+        *ret_min_priority = min_priority;
+        return something_new;
+}
+
+_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
+        int r;
+
+        assert_return(e, -EINVAL);
+        assert_return(e = event_resolve(e), -ENOPKG);
+        assert_return(!event_pid_changed(e), -ECHILD);
+        assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
+        assert_return(e->state == SD_EVENT_ARMED, -EBUSY);
+
+        if (e->exit_requested) {
+                e->state = SD_EVENT_PENDING;
+                return 1;
+        }
+
+        for (int64_t threshold = INT64_MAX; ; threshold--) {
+                int64_t epoll_min_priority, child_min_priority;
+
+                /* There may be a possibility that new epoll (especially IO) and child events are
+                 * triggered just after process_epoll() call but before process_child(), and the new IO
+                 * events may have higher priority than the child events. To salvage these events,
+                 * let's call epoll_wait() again, but accepts only events with higher priority than the
+                 * previous. See issue https://github.com/systemd/systemd/issues/18190 and comments
+                 * https://github.com/systemd/systemd/pull/18750#issuecomment-785801085
+                 * https://github.com/systemd/systemd/pull/18922#issuecomment-792825226 */
+
+                r = process_epoll(e, timeout, threshold, &epoll_min_priority);
+                if (r == -EINTR) {
+                        e->state = SD_EVENT_PENDING;
+                        return 1;
+                }
                 if (r < 0)
                         goto finish;
+                if (r == 0 && threshold < INT64_MAX)
+                        /* No new epoll event. */
+                        break;
+
+                r = process_child(e, threshold, &child_min_priority);
+                if (r < 0)
+                        goto finish;
+                if (r == 0)
+                        /* No new child event. */
+                        break;
+
+                threshold = MIN(epoll_min_priority, child_min_priority);
+                if (threshold == INT64_MIN)
+                        break;
+
+                timeout = 0;
         }
 
         r = process_watchdog(e);
@@ -3959,19 +4039,12 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
         if (r < 0)
                 goto finish;
 
-        if (e->need_process_child) {
-                r = process_child(e);
-                if (r < 0)
-                        goto finish;
-        }
-
         r = process_inotify(e);
         if (r < 0)
                 goto finish;
 
         if (event_next_pending(e)) {
                 e->state = SD_EVENT_PENDING;
-
                 return 1;
         }
 
index 737595bc33ea40c4ce89e4d07adac4bc93d03bca..0bc2f507aa78850b868291285753134f6544c388 100644 (file)
@@ -13,6 +13,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "random-util.h"
 #include "rm-rf.h"
 #include "signal-util.h"
 #include "stdio-util.h"
@@ -693,9 +694,30 @@ static void test_ratelimit(void) {
         assert_se(count == 20);
 }
 
+static void test_simple_timeout(void) {
+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+        usec_t f, t, some_time;
+
+        some_time = random_u64_range(2 * USEC_PER_SEC);
+
+        assert_se(sd_event_default(&e) >= 0);
+
+        assert_se(sd_event_prepare(e) == 0);
+
+        f = now(CLOCK_MONOTONIC);
+        assert_se(sd_event_wait(e, some_time) >= 0);
+        t = now(CLOCK_MONOTONIC);
+
+        /* The event loop may sleep longer than the specified time (timer accuracy, scheduling latencies, …),
+         * but never shorter. Let's check that. */
+        assert_se(t >= usec_add(f, some_time));
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
+        test_simple_timeout();
+
         test_basic(true);   /* test with pidfd */
         test_basic(false);  /* test without pidfd */
 
index bdcf47a25bf4b87abf8e174eeccaf6c52f2563a7..f366a597b5a5b2693a965a8c633ddfe5a9c78228 100644 (file)
@@ -614,14 +614,10 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
 #if HAVE_LZ4
         LZ4F_errorCode_t c;
         _cleanup_(LZ4F_freeCompressionContextp) LZ4F_compressionContext_t ctx = NULL;
-        _cleanup_free_ char *buf = NULL;
-        char *src = NULL;
-        size_t size, n, total_in = 0, total_out, offset = 0, frame_size;
-        struct stat st;
+        _cleanup_free_ void *in_buff = NULL;
+        _cleanup_free_ char *out_buff = NULL;
+        size_t out_allocsize, n, total_in = 0, total_out, offset = 0, frame_size;
         int r;
-        static const LZ4F_compressOptions_t options = {
-                .stableSrc = 1,
-        };
         static const LZ4F_preferences_t preferences = {
                 .frameInfo.blockSizeID = 5,
         };
@@ -630,74 +626,66 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
         if (LZ4F_isError(c))
                 return -ENOMEM;
 
-        if (fstat(fdf, &st) < 0)
-                return log_debug_errno(errno, "fstat() failed: %m");
-
         frame_size = LZ4F_compressBound(LZ4_BUFSIZE, &preferences);
-        size =  frame_size + 64*1024; /* add some space for header and trailer */
-        buf = malloc(size);
-        if (!buf)
+        out_allocsize = frame_size + 64*1024; /* add some space for header and trailer */
+        out_buff = malloc(out_allocsize);
+        if (!out_buff)
                 return -ENOMEM;
 
-        n = offset = total_out = LZ4F_compressBegin(ctx, buf, size, &preferences);
+        in_buff = malloc(LZ4_BUFSIZE);
+        if (!in_buff)
+                return -ENOMEM;
+
+        n = offset = total_out = LZ4F_compressBegin(ctx, out_buff, out_allocsize, &preferences);
         if (LZ4F_isError(n))
                 return -EINVAL;
 
-        src = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fdf, 0);
-        if (src == MAP_FAILED)
-                return -errno;
-
-        log_debug("Buffer size is %zu bytes, header size %zu bytes.", size, n);
+        log_debug("Buffer size is %zu bytes, header size %zu bytes.", out_allocsize, n);
 
-        while (total_in < (size_t) st.st_size) {
+        for (;;) {
                 ssize_t k;
 
-                k = MIN(LZ4_BUFSIZE, st.st_size - total_in);
-                n = LZ4F_compressUpdate(ctx, buf + offset, size - offset,
-                                        src + total_in, k, &options);
-                if (LZ4F_isError(n)) {
-                        r = -ENOTRECOVERABLE;
-                        goto cleanup;
-                }
+                k = loop_read(fdf, in_buff, LZ4_BUFSIZE, true);
+                if (k < 0)
+                        return k;
+                if (k == 0)
+                        break;
+                n = LZ4F_compressUpdate(ctx, out_buff + offset, out_allocsize - offset,
+                                        in_buff, k, NULL);
+                if (LZ4F_isError(n))
+                        return -ENOTRECOVERABLE;
 
                 total_in += k;
                 offset += n;
                 total_out += n;
 
-                if (max_bytes != UINT64_MAX && total_out > (size_t) max_bytes) {
-                        r = log_debug_errno(SYNTHETIC_ERRNO(EFBIG),
-                                            "Compressed stream longer than %" PRIu64 " bytes", max_bytes);
-                        goto cleanup;
-                }
+                if (max_bytes != UINT64_MAX && total_out > (size_t) max_bytes)
+                        return log_debug_errno(SYNTHETIC_ERRNO(EFBIG),
+                                               "Compressed stream longer than %" PRIu64 " bytes", max_bytes);
 
-                if (size - offset < frame_size + 4) {
-                        k = loop_write(fdt, buf, offset, false);
-                        if (k < 0) {
-                                r = k;
-                                goto cleanup;
-                        }
+                if (out_allocsize - offset < frame_size + 4) {
+                        k = loop_write(fdt, out_buff, offset, false);
+                        if (k < 0)
+                                return k;
                         offset = 0;
                 }
         }
 
-        n = LZ4F_compressEnd(ctx, buf + offset, size - offset, &options);
-        if (LZ4F_isError(n)) {
-                r = -ENOTRECOVERABLE;
-                goto cleanup;
-        }
+        n = LZ4F_compressEnd(ctx, out_buff + offset, out_allocsize - offset, NULL);
+        if (LZ4F_isError(n))
+                return -ENOTRECOVERABLE;
 
         offset += n;
         total_out += n;
-        r = loop_write(fdt, buf, offset, false);
+        r = loop_write(fdt, out_buff, offset, false);
         if (r < 0)
-                goto cleanup;
+                return r;
 
         log_debug("LZ4 compression finished (%zu -> %zu bytes, %.1f%%)",
                   total_in, total_out,
                   (double) total_out / total_in * 100);
- cleanup:
-        munmap(src, st.st_size);
-        return r;
+
+        return 0;
 #else
         return -EPROTONOSUPPORT;
 #endif
index 3f0341a698a41d690c41150f3c30555b1d5db3c9..c082fdca46843e03fc078df71b254e5854f3b43d 100644 (file)
@@ -28,8 +28,6 @@ int main(int argc, char *argv[]) {
         pthread_t t;
         int r;
 
-        unsetenv("SYSTEMD_MEMPOOL");
-
         loopback = udev_device_new_from_syspath(NULL, "/sys/class/net/lo");
         if (!loopback)
                 return handle_error_errno(errno, "Failed to create loopback device object");
index 5eb3534f530df187d47785d24893e97e97d2b187..d6b9289ea68ca055a7188c601e8790952bf66d6e 100644 (file)
@@ -137,7 +137,7 @@ static int brightness_writer_fork(BrightnessWriter *w) {
         assert(w->child == 0);
         assert(!w->child_event_source);
 
-        r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG, &w->child);
+        r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
         if (r < 0)
                 return r;
         if (r == 0) {
index 800c452a60f6de606ed17bef14f084a28b0f071f..76f529c176be017003b5961b50340e208a69d0a8 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/logind.conf' to display the full config.
+#
 # See logind.conf(5) for details.
 
 [Login]
index 69fb71cdc2d7f837e96f4ddaa1e3c738a8231ab0..9539c39c4e7cf5a7edeae66534e4759be1866186 100644 (file)
@@ -6,20 +6,25 @@
 #include <stdlib.h>
 
 #include "alloc-util.h"
+#include "dissect-image.h"
 #include "id128-util.h"
 #include "log.h"
 #include "machine-id-setup.h"
 #include "main-func.h"
+#include "mount-util.h"
 #include "parse-argument.h"
 #include "path-util.h"
 #include "pretty-print.h"
+#include "terminal-util.h"
 #include "util.h"
 
 static char *arg_root = NULL;
+static char *arg_image = NULL;
 static bool arg_commit = false;
 static bool arg_print = false;
 
 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
 
 static int help(void) {
         _cleanup_free_ char *link = NULL;
@@ -29,15 +34,18 @@ static int help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%s [OPTIONS...]\n\n"
-               "Initialize /etc/machine-id from a random source.\n\n"
+        printf("%s [OPTIONS...]\n"
+               "\n%sInitialize /etc/machine-id from a random source.%s\n\n"
                "  -h --help             Show this help\n"
                "     --version          Show package version\n"
-               "     --root=ROOT        Filesystem root\n"
+               "     --root=PATH        Operate relative to root path\n"
+               "     --image=PATH       Operate relative to image file\n"
                "     --commit           Commit transient ID\n"
                "     --print            Print used machine ID\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
+               ansi_highlight(),
+               ansi_normal(),
                link);
 
         return 0;
@@ -48,6 +56,7 @@ static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_VERSION = 0x100,
                 ARG_ROOT,
+                ARG_IMAGE,
                 ARG_COMMIT,
                 ARG_PRINT,
         };
@@ -56,6 +65,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "help",      no_argument,       NULL, 'h'           },
                 { "version",   no_argument,       NULL, ARG_VERSION   },
                 { "root",      required_argument, NULL, ARG_ROOT      },
+                { "image",     required_argument, NULL, ARG_IMAGE     },
                 { "commit",    no_argument,       NULL, ARG_COMMIT    },
                 { "print",     no_argument,       NULL, ARG_PRINT     },
                 {}
@@ -82,6 +92,12 @@ static int parse_argv(int argc, char *argv[]) {
                                 return r;
                         break;
 
+                case ARG_IMAGE:
+                        r = parse_path_argument(optarg, false, &arg_image);
+                        if (r < 0)
+                                return r;
+                        break;
+
                 case ARG_COMMIT:
                         arg_commit = true;
                         break;
@@ -101,10 +117,16 @@ static int parse_argv(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Extraneous arguments");
 
+        if (arg_image && arg_root)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
+
         return 1;
 }
 
 static int run(int argc, char *argv[]) {
+        _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
+        _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
+        _cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
         char buf[SD_ID128_STRING_MAX];
         sd_id128_t id;
         int r;
@@ -116,6 +138,26 @@ static int run(int argc, char *argv[]) {
         if (r <= 0)
                 return r;
 
+        if (arg_image) {
+                assert(!arg_root);
+
+                r = mount_image_privately_interactively(
+                                arg_image,
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_VALIDATE_OS |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_FSCK,
+                                &unlink_dir,
+                                &loop_device,
+                                &decrypted_image);
+                if (r < 0)
+                        return r;
+
+                arg_root = strdup(unlink_dir);
+                if (!arg_root)
+                        return log_oom();
+        }
+
         if (arg_commit) {
                 const char *etc_machine_id;
 
index 86cd1f19b372713922451e66f0f43ed7cc49acda..1f899e90f67abff9d02873608bb2f59e206b3df4 100644 (file)
@@ -84,11 +84,10 @@ int config_parse_badadv_bandwidth (
                 return 0;
         }
 
-        if (k/1000/100 > UINT32_MAX) {
+        if (k/1000/100 > UINT32_MAX)
                 log_syntax(unit, LOG_WARNING, filename, line, 0,
                            "The value of '%s=', is outside of 0...429496729500000 range: %s",
                            lvalue, rvalue);
-        }
 
         *bandwidth = k/1000/100;
 
index 2fab269397f5ab121ef6fd7b2b425a9da63cb50a..23718081b90bc5c513fae83c6afd44061ec3243a 100644 (file)
@@ -389,7 +389,7 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl
         if (t->allow_localremote >= 0)
                 SET_FLAG(t->flags, IP6_TNL_F_ALLOW_LOCAL_REMOTE, t->allow_localremote);
 
-        if (t->encap_limit != IPV6_DEFAULT_TNL_ENCAP_LIMIT) {
+        if (t->encap_limit != 0) {
                 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_ENCAP_LIMIT, t->encap_limit);
                 if (r < 0)
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_ENCAP_LIMIT attribute: %m");
index a746b3c0c397a1bf71ecc6b976fd2b310958dadc..faaa6a7b6caefec839dfe4e094a2c8fee963c959 100644 (file)
@@ -2510,8 +2510,8 @@ static int link_up_down(int argc, char *argv[], void *userdata) {
                 if (r < 0) {
                         char ifname[IF_NAMESIZE + 1];
 
-                        return log_error_errno(r, "Failed to %s interface %s: %m",
-                                               argv[1], format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX));
+                        return log_error_errno(r, "Failed to bring %s interface %s: %m",
+                                               argv[0], format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX));
                 }
         }
 
index f57828b57da4e5f77649628ad2fef8a257aaf920..4d0e4815db2ce7abf400821800cde6d0286bcb52 100644 (file)
@@ -178,7 +178,7 @@ int bus_link_method_set_dns_servers_ex(sd_bus_message *message, void *userdata,
 }
 
 int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        _cleanup_(ordered_set_freep) OrderedSet *search_domains = NULL, *route_domains = NULL;
+        _cleanup_ordered_set_free_ OrderedSet *search_domains = NULL, *route_domains = NULL;
         Link *l = userdata;
         int r;
 
@@ -218,15 +218,15 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
 
                 domains = route_only ? &route_domains : &search_domains;
-                r = ordered_set_ensure_allocated(domains, &string_hash_ops);
+                r = ordered_set_ensure_allocated(domains, &string_hash_ops_free);
                 if (r < 0)
                         return r;
 
-                r = ordered_set_put(*domains, str);
+                r = ordered_set_consume(*domains, TAKE_PTR(str));
+                if (r == -EEXIST)
+                        continue;
                 if (r < 0)
                         return r;
-
-                TAKE_PTR(str);
         }
 
         r = sd_bus_message_exit_container(message);
@@ -242,8 +242,8 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
         if (r == 0)
                 return 1; /* Polkit will call us back */
 
-        ordered_set_free_free(l->search_domains);
-        ordered_set_free_free(l->route_domains);
+        ordered_set_free(l->search_domains);
+        ordered_set_free(l->route_domains);
         l->search_domains = TAKE_PTR(search_domains);
         l->route_domains = TAKE_PTR(route_domains);
 
index 6868a7ccb2c227c6ff3700fd17c66e71f39713ae..de453fa72e0a7d979d4a58a98d7cb99ff98ca74d 100644 (file)
@@ -478,8 +478,8 @@ void link_dns_settings_clear(Link *link) {
         link->dns = mfree(link->dns);
         link->n_dns = UINT_MAX;
 
-        link->search_domains = ordered_set_free_free(link->search_domains);
-        link->route_domains = ordered_set_free_free(link->route_domains);
+        link->search_domains = ordered_set_free(link->search_domains);
+        link->route_domains = ordered_set_free(link->route_domains);
 
         link->dns_default_route = -1;
         link->llmnr = _RESOLVE_SUPPORT_INVALID;
index e5ffd35b6f9ab4b6a785678acec3622d60357ddd..f532536f1cfed75b5588145c2b05cbd22efa6c0d 100644 (file)
@@ -896,11 +896,9 @@ int config_parse_domains(
                 }
 
                 OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
-                r = ordered_set_ensure_allocated(set, &string_hash_ops_free);
-                if (r < 0)
-                        return log_oom();
-
-                r = ordered_set_put_strdup(*set, domain);
+                r = ordered_set_put_strdup(set, domain);
+                if (r == -EEXIST)
+                        continue;
                 if (r < 0)
                         return log_oom();
         }
index 52f7ce2d9f2beee2d0b73e8850331b23fb9ae866..96232018ddfc559f831a561150be8073f0292bfa 100644 (file)
@@ -19,7 +19,7 @@
 #include "strv.h"
 #include "tmpfile-util.h"
 
-static int ordered_set_put_dns_server(OrderedSet *s, int ifindex, struct in_addr_full *dns) {
+static int ordered_set_put_dns_server(OrderedSet **s, int ifindex, struct in_addr_full *dns) {
         const char *p;
         int r;
 
@@ -40,7 +40,7 @@ static int ordered_set_put_dns_server(OrderedSet *s, int ifindex, struct in_addr
         return r;
 }
 
-static int ordered_set_put_dns_servers(OrderedSet *s, int ifindex, struct in_addr_full **dns, unsigned n) {
+static int ordered_set_put_dns_servers(OrderedSet **s, int ifindex, struct in_addr_full **dns, unsigned n) {
         int r, c = 0;
 
         assert(s);
@@ -57,8 +57,8 @@ static int ordered_set_put_dns_servers(OrderedSet *s, int ifindex, struct in_add
         return c;
 }
 
-static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
-        char *p;
+static int ordered_set_put_in4_addr(OrderedSet **s, const struct in_addr *address) {
+        _cleanup_free_ char *p = NULL;
         int r;
 
         assert(s);
@@ -68,7 +68,11 @@ static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address
         if (r < 0)
                 return r;
 
-        r = ordered_set_consume(s, p);
+        r = ordered_set_ensure_allocated(s, &string_hash_ops_free);
+        if (r < 0)
+                return r;
+
+        r = ordered_set_consume(*s, TAKE_PTR(p));
         if (r == -EEXIST)
                 return 0;
 
@@ -76,7 +80,7 @@ static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address
 }
 
 static int ordered_set_put_in4_addrv(
-                OrderedSet *s,
+                OrderedSet **s,
                 const struct in_addr *addresses,
                 size_t n,
                 bool (*predicate)(const struct in_addr *addr)) {
@@ -100,7 +104,7 @@ static int ordered_set_put_in4_addrv(
 }
 
 int manager_save(Manager *m) {
-        _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
+        _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
         const char *operstate_str, *carrier_state_str, *address_state_str;
         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
         LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
@@ -114,27 +118,6 @@ int manager_save(Manager *m) {
         assert(m);
         assert(m->state_file);
 
-        /* We add all NTP and DNS server to a set, to filter out duplicates */
-        dns = ordered_set_new(&string_hash_ops);
-        if (!dns)
-                return -ENOMEM;
-
-        ntp = ordered_set_new(&string_hash_ops);
-        if (!ntp)
-                return -ENOMEM;
-
-        sip = ordered_set_new(&string_hash_ops);
-        if (!sip)
-                return -ENOMEM;
-
-        search_domains = ordered_set_new(&dns_name_hash_ops);
-        if (!search_domains)
-                return -ENOMEM;
-
-        route_domains = ordered_set_new(&dns_name_hash_ops);
-        if (!route_domains)
-                return -ENOMEM;
-
         HASHMAP_FOREACH(link, m->links) {
                 const struct in_addr *addresses;
 
@@ -155,21 +138,21 @@ int manager_save(Manager *m) {
 
                 /* First add the static configured entries */
                 if (link->n_dns != UINT_MAX)
-                        r = ordered_set_put_dns_servers(dns, link->ifindex, link->dns, link->n_dns);
+                        r = ordered_set_put_dns_servers(&dns, link->ifindex, link->dns, link->n_dns);
                 else
-                        r = ordered_set_put_dns_servers(dns, link->ifindex, link->network->dns, link->network->n_dns);
+                        r = ordered_set_put_dns_servers(&dns, link->ifindex, link->network->dns, link->network->n_dns);
                 if (r < 0)
                         return r;
 
-                r = ordered_set_put_strdupv(ntp, link->ntp ?: link->network->ntp);
+                r = ordered_set_put_strdupv(&ntp, link->ntp ?: link->network->ntp);
                 if (r < 0)
                         return r;
 
-                r = ordered_set_put_string_set(search_domains, link->search_domains ?: link->network->search_domains);
+                r = ordered_set_put_string_set(&search_domains, link->search_domains ?: link->network->search_domains);
                 if (r < 0)
                         return r;
 
-                r = ordered_set_put_string_set(route_domains, link->route_domains ?: link->network->route_domains);
+                r = ordered_set_put_string_set(&route_domains, link->route_domains ?: link->network->route_domains);
                 if (r < 0)
                         return r;
 
@@ -180,7 +163,7 @@ int manager_save(Manager *m) {
                 if (link->network->dhcp_use_dns) {
                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
                         if (r > 0) {
-                                r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
+                                r = ordered_set_put_in4_addrv(&dns, addresses, r, in4_addr_is_non_local);
                                 if (r < 0)
                                         return r;
                         } else if (r < 0 && r != -ENODATA)
@@ -190,7 +173,7 @@ int manager_save(Manager *m) {
                 if (link->network->dhcp_use_ntp) {
                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
                         if (r > 0) {
-                                r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
+                                r = ordered_set_put_in4_addrv(&ntp, addresses, r, in4_addr_is_non_local);
                                 if (r < 0)
                                         return r;
                         } else if (r < 0 && r != -ENODATA)
@@ -200,7 +183,7 @@ int manager_save(Manager *m) {
                 if (link->network->dhcp_use_sip) {
                         r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
                         if (r > 0) {
-                                r = ordered_set_put_in4_addrv(sip, addresses, r, in4_addr_is_non_local);
+                                r = ordered_set_put_in4_addrv(&sip, addresses, r, in4_addr_is_non_local);
                                 if (r < 0)
                                         return r;
                         } else if (r < 0 && r != -ENODATA)
@@ -208,10 +191,11 @@ int manager_save(Manager *m) {
                 }
 
                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
+                        OrderedSet **target_domains;
                         const char *domainname;
                         char **domains = NULL;
 
-                        OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
+                        target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? &search_domains : &route_domains;
                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
                         if (r >= 0) {
                                 r = ordered_set_put_strdup(target_domains, domainname);
index 24b3cb57af9a70c94825aa8f9dd075836e2aa11f..48f6061b1f2c109de0af7656bbcc5b17b076f648 100644 (file)
@@ -93,10 +93,6 @@ static int run(int argc, char *argv[]) {
         if (r < 0)
                 return r;
 
-        r = fw_ctx_new(&m->fw_ctx);
-        if (r < 0)
-                log_warning_errno(r, "Could not initialize firewall, IPMasquerade= option not available: %m");
-
         r = manager_start(m);
         if (r < 0)
                 return log_error_errno(r, "Could not start manager: %m");
index a4ac8ed2bb752e6b478b8281d82aa6cd6e56191e..164a3302072cc5d575ee48beb32eb176533e83d5 100644 (file)
@@ -35,6 +35,7 @@
 #include "cgroup-util.h"
 #include "copy.h"
 #include "cpu-set-util.h"
+#include "creds-util.h"
 #include "dev-setup.h"
 #include "discover-image.h"
 #include "dissect-image.h"
@@ -1592,9 +1593,9 @@ static int parse_argv(int argc, char *argv[]) {
                         else {
                                 const char *e;
 
-                                e = getenv("CREDENTIALS_DIRECTORY");
-                                if (!e)
-                                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential not available (no credentials passed at all): %s", word);
+                                r = get_credentials_dir(&e);
+                                if (r < 0)
+                                        return log_error_errno(r, "Credential not available (no credentials passed at all): %s", word);
 
                                 j = path_join(e, p);
                                 if (!j)
@@ -3581,8 +3582,12 @@ static int outer_child(
                  * makes sure ESP partitions and userns are compatible. */
 
                 r = dissected_image_mount_and_warn(
-                                dissected_image, directory, arg_uid_shift,
-                                DISSECT_IMAGE_MOUNT_ROOT_ONLY|DISSECT_IMAGE_DISCARD_ON_LOOP|
+                                dissected_image,
+                                directory,
+                                arg_uid_shift,
+                                DISSECT_IMAGE_MOUNT_ROOT_ONLY|
+                                DISSECT_IMAGE_DISCARD_ON_LOOP|
+                                DISSECT_IMAGE_USR_NO_ROOT|
                                 (arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK)|
                                 (arg_start_mode == START_BOOT ? DISSECT_IMAGE_VALIDATE_OS : 0));
                 if (r < 0)
@@ -3669,8 +3674,14 @@ static int outer_child(
 
         if (dissected_image) {
                 /* Now we know the uid shift, let's now mount everything else that might be in the image. */
-                r = dissected_image_mount(dissected_image, directory, arg_uid_shift,
-                                          DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY|DISSECT_IMAGE_DISCARD_ON_LOOP|(arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK));
+                r = dissected_image_mount(
+                                dissected_image,
+                                directory,
+                                arg_uid_shift,
+                                DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY|
+                                DISSECT_IMAGE_DISCARD_ON_LOOP|
+                                DISSECT_IMAGE_USR_NO_ROOT|
+                                (arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK));
                 if (r == -EUCLEAN)
                         return log_error_errno(r, "File system check for image failed: %m");
                 if (r < 0)
@@ -5378,7 +5389,11 @@ static int run(int argc, char *argv[]) {
                 }
 
         } else {
-                DissectImageFlags dissect_image_flags = DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK;
+                DissectImageFlags dissect_image_flags =
+                        DISSECT_IMAGE_GENERIC_ROOT |
+                        DISSECT_IMAGE_REQUIRE_ROOT |
+                        DISSECT_IMAGE_RELAX_VAR_CHECK |
+                        DISSECT_IMAGE_USR_NO_ROOT;
                 assert(arg_image);
                 assert(!arg_template);
 
index 085fc6487fd361a8e5353f3cc376365826f124ea..c3e84aadde98183fae6c6b5a9d3658807f25be2b 100644 (file)
@@ -117,6 +117,8 @@ static int process_managed_oom_reply(
                         r = ret;
                         goto finish;
                 }
+                if (ret < 0 && ret != -EEXIST)
+                        log_debug_errno(ret, "Failed to insert reply, ignoring: %m");
 
                 /* Always update the limit in case it was changed. For non-memory pressure detection the value is
                  * ignored so always updating it here is not a problem. */
@@ -156,7 +158,11 @@ static int recursively_get_cgroup_context(Hashmap *new_h, const char *path) {
                 return r;
         else if (r == 0) { /* No subgroups? We're a leaf node */
                 r = oomd_insert_cgroup_context(NULL, new_h, path);
-                return (r == -ENOMEM) ? r : 0;
+                if (r == -ENOMEM)
+                        return r;
+                if (r < 0)
+                        log_debug_errno(r, "Failed to insert context for %s, ignoring: %m", path);
+                return 0;
         }
 
         do {
@@ -171,8 +177,12 @@ static int recursively_get_cgroup_context(Hashmap *new_h, const char *path) {
 
                 r = cg_get_attribute_as_bool("memory", cg_path, "memory.oom.group", &oom_group);
                 /* The cgroup might be gone. Skip it as a candidate since we can't get information on it. */
-                if (r < 0)
-                        return (r == -ENOMEM) ? r : 0;
+                if (r == -ENOMEM)
+                        return r;
+                if (r < 0) {
+                        log_debug_errno(r, "Failed to read memory.oom.group from %s, ignoring: %m", cg_path);
+                        return 0;
+                }
 
                 if (oom_group)
                         r = oomd_insert_cgroup_context(NULL, new_h, cg_path);
@@ -180,6 +190,8 @@ static int recursively_get_cgroup_context(Hashmap *new_h, const char *path) {
                         r = recursively_get_cgroup_context(new_h, cg_path);
                 if (r == -ENOMEM)
                         return r;
+                if (r < 0)
+                        log_debug_errno(r, "Failed to insert or recursively get from %s, ignoring: %m", cg_path);
         } while ((r = cg_read_subgroup(d, &subpath)) > 0);
 
         return 0;
@@ -201,6 +213,8 @@ static int update_monitored_cgroup_contexts(Hashmap **monitored_cgroups) {
                 r = oomd_insert_cgroup_context(*monitored_cgroups, new_base, ctx->path);
                 if (r == -ENOMEM)
                         return r;
+                if (r < 0 && !IN_SET(r, -EEXIST, -ENOENT))
+                        log_debug_errno(r, "Failed to insert context for %s, ignoring: %m", ctx->path);
         }
 
         hashmap_free(*monitored_cgroups);
@@ -225,6 +239,8 @@ static int get_monitored_cgroup_contexts_candidates(Hashmap *monitored_cgroups,
                 r = recursively_get_cgroup_context(candidates, ctx->path);
                 if (r == -ENOMEM)
                         return r;
+                if (r < 0)
+                        log_debug_errno(r, "Failed to recursively get contexts for %s, ignoring: %m", ctx->path);
         }
 
         *ret_candidates = TAKE_PTR(candidates);
@@ -232,6 +248,26 @@ static int get_monitored_cgroup_contexts_candidates(Hashmap *monitored_cgroups,
         return 0;
 }
 
+static int update_monitored_cgroup_contexts_candidates(Hashmap *monitored_cgroups, Hashmap **candidates) {
+        _cleanup_hashmap_free_ Hashmap *new_candidates = NULL;
+        int r;
+
+        assert(monitored_cgroups);
+        assert(candidates);
+        assert(*candidates);
+
+        r = get_monitored_cgroup_contexts_candidates(monitored_cgroups, &new_candidates);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to get candidate contexts: %m");
+
+        oomd_update_cgroup_contexts_between_hashmaps(*candidates, new_candidates);
+
+        hashmap_free(*candidates);
+        *candidates = TAKE_PTR(new_candidates);
+
+        return 0;
+}
+
 static int acquire_managed_oom_connect(Manager *m) {
         _cleanup_(varlink_close_unrefp) Varlink *link = NULL;
         int r;
@@ -275,33 +311,44 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
         /* Reset timer */
         r = sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &usec_now);
         if (r < 0)
-                return log_error_errno(r, "Failed to reset event timer");
+                return log_error_errno(r, "Failed to reset event timer: %m");
 
         r = sd_event_source_set_time_relative(s, INTERVAL_USEC);
         if (r < 0)
-                return log_error_errno(r, "Failed to set relative time for timer");
+                return log_error_errno(r, "Failed to set relative time for timer: %m");
 
         /* Reconnect if our connection dropped */
         if (!m->varlink) {
                 r = acquire_managed_oom_connect(m);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to acquire varlink connection");
+                        return log_error_errno(r, "Failed to acquire varlink connection: %m");
         }
 
         /* Update the cgroups used for detection/action */
         r = update_monitored_cgroup_contexts(&m->monitored_swap_cgroup_contexts);
         if (r == -ENOMEM)
-                return log_error_errno(r, "Failed to update monitored swap cgroup contexts");
+                return log_oom();
+        if (r < 0)
+                log_debug_errno(r, "Failed to update monitored swap cgroup contexts, ignoring: %m");
 
         r = update_monitored_cgroup_contexts(&m->monitored_mem_pressure_cgroup_contexts);
         if (r == -ENOMEM)
-                return log_error_errno(r, "Failed to update monitored memory pressure cgroup contexts");
+                return log_oom();
+        if (r < 0)
+                log_debug_errno(r, "Failed to update monitored memory pressure cgroup contexts, ignoring: %m");
+
+        r = update_monitored_cgroup_contexts_candidates(
+                        m->monitored_mem_pressure_cgroup_contexts, &m->monitored_mem_pressure_cgroup_contexts_candidates);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0)
+                log_debug_errno(r, "Failed to update monitored memory pressure candidate cgroup contexts, ignoring: %m");
 
         r = oomd_system_context_acquire("/proc/swaps", &m->system_context);
         /* If there aren't units depending on swap actions, the only error we exit on is ENOMEM.
          * Allow ENOENT in the event that swap is disabled on the system. */
         if (r == -ENOMEM || (r < 0 && r != -ENOENT && !hashmap_isempty(m->monitored_swap_cgroup_contexts)))
-                return log_error_errno(r, "Failed to acquire system context");
+                return log_error_errno(r, "Failed to acquire system context: %m");
         else if (r == -ENOENT)
                 zero(m->system_context);
 
@@ -318,7 +365,9 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
 
         r = oomd_pressure_above(m->monitored_mem_pressure_cgroup_contexts, m->default_mem_pressure_duration_usec, &targets);
         if (r == -ENOMEM)
-                return log_error_errno(r, "Failed to check if memory pressure exceeded limits");
+                return log_oom();
+        if (r < 0)
+                log_debug_errno(r, "Failed to check if memory pressure exceeded limits, ignoring: %m");
         else if (r == 1) {
                 /* Check if there was reclaim activity in the given interval. The concern is the following case:
                  * Pressure climbed, a lot of high-frequency pages were reclaimed, and we killed the offending
@@ -326,25 +375,37 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
                  * this will cause pressure to remain high. Thus if there isn't any reclaim pressure, no need
                  * to kill something (it won't help anyways). */
                 if ((usec_now - m->last_reclaim_at) <= RECLAIM_DURATION_USEC) {
-                        _cleanup_hashmap_free_ Hashmap *candidates = NULL;
                         OomdCGroupContext *t;
 
-                        r = get_monitored_cgroup_contexts_candidates(m->monitored_mem_pressure_cgroup_contexts, &candidates);
-                        if (r == -ENOMEM)
-                                return log_error_errno(r, "Failed to get monitored memory pressure cgroup candidates");
-
                         SET_FOREACH(t, targets) {
-                                log_notice("Memory pressure for %s is greater than %lu for more than %"PRIu64" seconds and there was reclaim activity",
-                                        t->path, LOAD_INT(t->mem_pressure_limit), m->default_mem_pressure_duration_usec / USEC_PER_SEC);
-
-                                r = oomd_kill_by_pgscan(candidates, t->path, m->dry_run);
+                                _cleanup_free_ char *selected = NULL;
+                                char ts[FORMAT_TIMESPAN_MAX];
+
+                                log_debug("Memory pressure for %s is %lu.%02lu%% > %lu.%02lu%% for > %s with reclaim activity",
+                                          t->path,
+                                          LOAD_INT(t->memory_pressure.avg10), LOAD_FRAC(t->memory_pressure.avg10),
+                                          LOAD_INT(t->mem_pressure_limit), LOAD_FRAC(t->mem_pressure_limit),
+                                          format_timespan(ts, sizeof ts,
+                                                          m->default_mem_pressure_duration_usec,
+                                                          USEC_PER_SEC));
+
+                                r = oomd_kill_by_pgscan_rate(m->monitored_mem_pressure_cgroup_contexts_candidates, t->path, m->dry_run, &selected);
                                 if (r == -ENOMEM)
-                                        return log_error_errno(r, "Failed to kill cgroup processes by pgscan");
+                                        return log_oom();
                                 if (r < 0)
-                                        log_info("Failed to kill any cgroup(s) under %s based on pressure", t->path);
+                                        log_notice_errno(r, "Failed to kill any cgroup(s) under %s based on pressure: %m", t->path);
                                 else {
                                         /* Don't act on all the high pressure cgroups at once; return as soon as we kill one */
                                         m->post_action_delay_start = usec_now;
+                                        if (selected)
+                                                log_notice("Killed %s due to memory pressure for %s being %lu.%02lu%% > %lu.%02lu%%"
+                                                           " for > %s with reclaim activity",
+                                                           selected, t->path,
+                                                           LOAD_INT(t->memory_pressure.avg10), LOAD_FRAC(t->memory_pressure.avg10),
+                                                           LOAD_INT(t->mem_pressure_limit), LOAD_FRAC(t->mem_pressure_limit),
+                                                           format_timespan(ts, sizeof ts,
+                                                                           m->default_mem_pressure_duration_usec,
+                                                                           USEC_PER_SEC));
                                         return 0;
                                 }
                         }
@@ -353,21 +414,30 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
 
         if (oomd_swap_free_below(&m->system_context, 10000 - m->swap_used_limit_permyriad)) {
                 _cleanup_hashmap_free_ Hashmap *candidates = NULL;
+                _cleanup_free_ char *selected = NULL;
 
-                log_notice("Swap used (%"PRIu64") / total (%"PRIu64") is more than " PERMYRIAD_AS_PERCENT_FORMAT_STR,
-                           m->system_context.swap_used, m->system_context.swap_total, PERMYRIAD_AS_PERCENT_FORMAT_VAL(m->swap_used_limit_permyriad));
+                log_debug("Swap used (%"PRIu64") / total (%"PRIu64") is more than " PERMYRIAD_AS_PERCENT_FORMAT_STR,
+                          m->system_context.swap_used, m->system_context.swap_total,
+                          PERMYRIAD_AS_PERCENT_FORMAT_VAL(m->swap_used_limit_permyriad));
 
                 r = get_monitored_cgroup_contexts_candidates(m->monitored_swap_cgroup_contexts, &candidates);
                 if (r == -ENOMEM)
-                        return log_error_errno(r, "Failed to get monitored swap cgroup candidates");
+                        return log_oom();
+                if (r < 0)
+                        log_debug_errno(r, "Failed to get monitored swap cgroup candidates, ignoring: %m");
 
-                r = oomd_kill_by_swap_usage(candidates, m->dry_run);
+                r = oomd_kill_by_swap_usage(candidates, m->dry_run, &selected);
                 if (r == -ENOMEM)
-                        return log_error_errno(r, "Failed to kill cgroup processes by swap usage");
+                        return log_oom();
                 if (r < 0)
-                        log_info("Failed to kill any cgroup(s) based on swap");
+                        log_notice_errno(r, "Failed to kill any cgroup(s) based on swap: %m");
                 else {
                         m->post_action_delay_start = usec_now;
+                        if (selected)
+                                log_notice("Killed %s due to swap used (%"PRIu64") / total (%"PRIu64") being more than "
+                                           PERMYRIAD_AS_PERCENT_FORMAT_STR,
+                                           selected, m->system_context.swap_used, m->system_context.swap_total,
+                                           PERMYRIAD_AS_PERCENT_FORMAT_VAL(m->swap_used_limit_permyriad));
                         return 0;
                 }
         }
@@ -412,6 +482,7 @@ Manager* manager_free(Manager *m) {
 
         hashmap_free(m->monitored_swap_cgroup_contexts);
         hashmap_free(m->monitored_mem_pressure_cgroup_contexts);
+        hashmap_free(m->monitored_mem_pressure_cgroup_contexts_candidates);
 
         return mfree(m);
 }
@@ -448,6 +519,10 @@ int manager_new(Manager **ret) {
         if (!m->monitored_mem_pressure_cgroup_contexts)
                 return -ENOMEM;
 
+        m->monitored_mem_pressure_cgroup_contexts_candidates = hashmap_new(&oomd_cgroup_ctx_hash_ops);
+        if (!m->monitored_mem_pressure_cgroup_contexts_candidates)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(m);
         return 0;
 }
index 9ab8494c6d31e9a981bab64c8ed66a1d2b5b38d0..9c580c8a249c5bd7f1841077ed69d9633fb58a02 100644 (file)
@@ -40,6 +40,7 @@ struct Manager {
          * Used to detect when to take action. */
         Hashmap *monitored_swap_cgroup_contexts;
         Hashmap *monitored_mem_pressure_cgroup_contexts;
+        Hashmap *monitored_mem_pressure_cgroup_contexts_candidates;
 
         OomdSystemContext system_context;
 
index d8dbb750139a762e4e13a98843e7ef4fc4ead973..894d23a83a4a19746efec90d6de105fc622ed9bc 100644 (file)
@@ -208,54 +208,82 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run) {
         return set_size(pids_killed) != 0;
 }
 
-int oomd_kill_by_pgscan(Hashmap *h, const char *prefix, bool dry_run) {
+int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char **ret_selected) {
         _cleanup_free_ OomdCGroupContext **sorted = NULL;
-        int r;
+        int n, r, ret = 0;
 
         assert(h);
+        assert(ret_selected);
 
-        r = oomd_sort_cgroup_contexts(h, compare_pgscan_and_memory_usage, prefix, &sorted);
-        if (r < 0)
-                return r;
+        n = oomd_sort_cgroup_contexts(h, compare_pgscan_rate_and_memory_usage, prefix, &sorted);
+        if (n < 0)
+                return n;
 
-        for (int i = 0; i < r; i++) {
-                /* Skip cgroups with no reclaim and memory usage; it won't alleviate pressure. */
-                /* Don't break since there might be "avoid" cgroups at the end. */
+        for (int i = 0; i < n; i++) {
+                /* Skip cgroups with no reclaim and memory usage; it won't alleviate pressure.
+                 * Continue since there might be "avoid" cgroups at the end. */
                 if (sorted[i]->pgscan == 0 && sorted[i]->current_memory_usage == 0)
                         continue;
 
                 r = oomd_cgroup_kill(sorted[i]->path, true, dry_run);
-                if (r > 0 || r == -ENOMEM)
-                        break;
+                if (r == 0)
+                        continue; /* We didn't find anything to kill */
+                if (r == -ENOMEM)
+                        return r; /* Treat oom as a hard error */
+                if (r < 0) {
+                        if (ret == 0)
+                                ret = r;
+                        continue; /* Try to find something else to kill */
+                }
+
+                char *selected = strdup(sorted[i]->path);
+                if (!selected)
+                        return -ENOMEM;
+                *ret_selected = selected;
+                return 1;
         }
 
-        return r;
+        return ret;
 }
 
-int oomd_kill_by_swap_usage(Hashmap *h, bool dry_run) {
+int oomd_kill_by_swap_usage(Hashmap *h, bool dry_run, char **ret_selected) {
         _cleanup_free_ OomdCGroupContext **sorted = NULL;
-        int r;
+        int n, r, ret = 0;
 
         assert(h);
+        assert(ret_selected);
 
-        r = oomd_sort_cgroup_contexts(h, compare_swap_usage, NULL, &sorted);
-        if (r < 0)
-                return r;
+        n = oomd_sort_cgroup_contexts(h, compare_swap_usage, NULL, &sorted);
+        if (n < 0)
+                return n;
 
         /* Try to kill cgroups with non-zero swap usage until we either succeed in
          * killing or we get to a cgroup with no swap usage. */
-        for (int i = 0; i < r; i++) {
-                /* Skip over cgroups with no resource usage. Don't break since there might be "avoid"
-                 * cgroups at the end. */
+        for (int i = 0; i < n; i++) {
+                /* Skip over cgroups with no resource usage.
+                 * Continue break since there might be "avoid" cgroups at the end. */
                 if (sorted[i]->swap_usage == 0)
                         continue;
 
                 r = oomd_cgroup_kill(sorted[i]->path, true, dry_run);
-                if (r > 0 || r == -ENOMEM)
-                        break;
+                if (r == 0)
+                        continue; /* We didn't find anything to kill */
+                if (r == -ENOMEM)
+                        return r; /* Treat oom as a hard error */
+                if (r < 0) {
+                        if (ret == 0)
+                                ret = r;
+                        continue; /* Try to find something else to kill */
+                }
+
+                char *selected = strdup(sorted[i]->path);
+                if (!selected)
+                        return -ENOMEM;
+                *ret_selected = selected;
+                return 1;
         }
 
-        return r;
+        return ret;
 }
 
 int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
@@ -413,6 +441,25 @@ int oomd_insert_cgroup_context(Hashmap *old_h, Hashmap *new_h, const char *path)
         return 0;
 }
 
+void oomd_update_cgroup_contexts_between_hashmaps(Hashmap *old_h, Hashmap *curr_h) {
+        OomdCGroupContext *ctx;
+
+        assert(old_h);
+        assert(curr_h);
+
+        HASHMAP_FOREACH(ctx, curr_h) {
+                OomdCGroupContext *old_ctx;
+
+                old_ctx = hashmap_get(old_h, ctx->path);
+                if (!old_ctx)
+                        continue;
+
+                ctx->last_pgscan = old_ctx->pgscan;
+                ctx->mem_pressure_limit = old_ctx->mem_pressure_limit;
+                ctx->last_hit_mem_pressure_limit = old_ctx->last_hit_mem_pressure_limit;
+        }
+}
+
 void oomd_dump_swap_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix) {
         char swap[FORMAT_BYTES_MAX];
 
@@ -458,10 +505,12 @@ void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE
                 fprintf(f,
                         "%s\tMemory Min: %s\n"
                         "%s\tMemory Low: %s\n"
-                        "%s\tPgscan: %" PRIu64 "\n",
+                        "%s\tPgscan: %" PRIu64 "\n"
+                        "%s\tLast Pgscan: %" PRIu64 "\n",
                         strempty(prefix), format_bytes_cgroup_protection(mem_min, sizeof(mem_min), ctx->memory_min),
                         strempty(prefix), format_bytes_cgroup_protection(mem_low, sizeof(mem_low), ctx->memory_low),
-                        strempty(prefix), ctx->pgscan);
+                        strempty(prefix), ctx->pgscan,
+                        strempty(prefix), ctx->last_pgscan);
 }
 
 void oomd_dump_system_context(const OomdSystemContext *ctx, FILE *f, const char *prefix) {
index 181443ae7a6f6698e7714dfbadc8ee8b82c91037..51423130d1b8c8c964d3b608f04fa0841e02148c 100644 (file)
@@ -66,7 +66,8 @@ bool oomd_swap_free_below(const OomdSystemContext *ctx, int threshold_permyriad)
 
 /* The compare functions will sort from largest to smallest, putting all the contexts with "avoid" at the end
  * (after the smallest values). */
-static inline int compare_pgscan_and_memory_usage(OomdCGroupContext * const *c1, OomdCGroupContext * const *c2) {
+static inline int compare_pgscan_rate_and_memory_usage(OomdCGroupContext * const *c1, OomdCGroupContext * const *c2) {
+        uint64_t last1, last2;
         int r;
 
         assert(c1);
@@ -76,7 +77,22 @@ static inline int compare_pgscan_and_memory_usage(OomdCGroupContext * const *c1,
         if (r != 0)
                 return r;
 
-        r = CMP((*c2)->pgscan, (*c1)->pgscan);
+        /* If last_pgscan > pgscan, assume the cgroup was recreated and reset last_pgscan to zero. */
+        last2 = (*c2)->last_pgscan;
+        if ((*c2)->last_pgscan > (*c2)->pgscan) {
+                log_info("Last pgscan %" PRIu64 "greater than current pgscan %" PRIu64 "for %s. Using last pgscan of zero.",
+                                (*c2)->last_pgscan, (*c2)->pgscan, (*c2)->path);
+                last2 = 0;
+        }
+
+        last1 = (*c1)->last_pgscan;
+        if ((*c1)->last_pgscan > (*c1)->pgscan) {
+                log_info("Last pgscan %" PRIu64 "greater than current pgscan %" PRIu64 "for %s. Using last pgscan of zero.",
+                                (*c1)->last_pgscan, (*c1)->pgscan, (*c1)->path);
+                last1 = 0;
+        }
+
+        r = CMP((*c2)->pgscan - last2, (*c1)->pgscan - last1);
         if (r != 0)
                 return r;
 
@@ -106,9 +122,10 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run);
 
 /* The following oomd_kill_by_* functions return 1 if processes were killed, or negative otherwise. */
 /* If `prefix` is supplied, only cgroups whose paths start with `prefix` are eligible candidates. Otherwise,
- * everything in `h` is a candidate. */
-int oomd_kill_by_pgscan(Hashmap *h, const char *prefix, bool dry_run);
-int oomd_kill_by_swap_usage(Hashmap *h, bool dry_run);
+ * everything in `h` is a candidate.
+ * Returns the killed cgroup in ret_selected. */
+int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char **ret_selected);
+int oomd_kill_by_swap_usage(Hashmap *h, bool dry_run, char **ret_selected);
 
 int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret);
 int oomd_system_context_acquire(const char *proc_swaps_path, OomdSystemContext *ret);
@@ -119,6 +136,9 @@ int oomd_system_context_acquire(const char *proc_swaps_path, OomdSystemContext *
  * was no prior data to reference. */
 int oomd_insert_cgroup_context(Hashmap *old_h, Hashmap *new_h, const char *path);
 
+/* Update each OomdCGroupContext in `curr_h` with prior interval information from `old_h`. */
+void oomd_update_cgroup_contexts_between_hashmaps(Hashmap *old_h, Hashmap *curr_h);
+
 void oomd_dump_swap_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix);
 void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix);
 void oomd_dump_system_context(const OomdSystemContext *ctx, FILE *f, const char *prefix);
index f1bef9de6fb912795b7c311886bc6e9539d4e232..d1dca0d64d15f60c3f63f54e4ddc6e5d184c9f70 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/oomd.conf' to display the full config.
+#
 # See oomd.conf(5) for details
 
 [OOM]
index 0b1a3adfccf6bdeff8b1412b664f5c7e45ce10d8..bd1c574ca7fa02cabb24d155edcf9f541d190625 100644 (file)
@@ -176,6 +176,53 @@ static void test_oomd_cgroup_context_acquire_and_insert(void) {
         }
 }
 
+static void test_oomd_update_cgroup_contexts_between_hashmaps(void) {
+        _cleanup_hashmap_free_ Hashmap *h_old = NULL, *h_new = NULL;
+        OomdCGroupContext *c_old, *c_new;
+        char **paths = STRV_MAKE("/0.slice",
+                                 "/1.slice");
+
+        OomdCGroupContext ctx_old[3] = {
+                { .path = paths[0],
+                  .mem_pressure_limit = 5,
+                  .last_hit_mem_pressure_limit = 777,
+                  .pgscan = 57 },
+                { .path = paths[1],
+                  .mem_pressure_limit = 6,
+                  .last_hit_mem_pressure_limit = 888,
+                  .pgscan = 42 },
+        };
+
+        OomdCGroupContext ctx_new[3] = {
+                { .path = paths[0],
+                  .pgscan = 100 },
+                { .path = paths[1],
+                  .pgscan = 101 },
+        };
+
+        assert_se(h_old = hashmap_new(&string_hash_ops));
+        assert_se(hashmap_put(h_old, paths[0], &ctx_old[0]) >= 0);
+        assert_se(hashmap_put(h_old, paths[1], &ctx_old[1]) >= 0);
+
+        assert_se(h_new = hashmap_new(&string_hash_ops));
+        assert_se(hashmap_put(h_new, paths[0], &ctx_new[0]) >= 0);
+        assert_se(hashmap_put(h_new, paths[1], &ctx_new[1]) >= 0);
+
+        oomd_update_cgroup_contexts_between_hashmaps(h_old, h_new);
+
+        assert_se(c_old = hashmap_get(h_old, "/0.slice"));
+        assert_se(c_new = hashmap_get(h_new, "/0.slice"));
+        assert_se(c_old->pgscan == c_new->last_pgscan);
+        assert_se(c_old->mem_pressure_limit == c_new->mem_pressure_limit);
+        assert_se(c_old->last_hit_mem_pressure_limit == c_new->last_hit_mem_pressure_limit);
+
+        assert_se(c_old = hashmap_get(h_old, "/1.slice"));
+        assert_se(c_new = hashmap_get(h_new, "/1.slice"));
+        assert_se(c_old->pgscan == c_new->last_pgscan);
+        assert_se(c_old->mem_pressure_limit == c_new->mem_pressure_limit);
+        assert_se(c_old->last_hit_mem_pressure_limit == c_new->last_hit_mem_pressure_limit);
+}
+
 static void test_oomd_system_context_acquire(void) {
         _cleanup_(unlink_tempfilep) char path[] = "/oomdgetsysctxtestXXXXXX";
         OomdSystemContext ctx;
@@ -325,33 +372,45 @@ static void test_oomd_sort_cgroups(void) {
                                  "/herp.slice/derp.scope",
                                  "/herp.slice/derp.scope/sheep.service",
                                  "/zupa.slice",
+                                 "/boop.slice",
                                  "/omitted.slice",
                                  "/avoid.slice");
 
-        OomdCGroupContext ctx[6] = {
+        OomdCGroupContext ctx[7] = {
                 { .path = paths[0],
                   .swap_usage = 20,
-                  .pgscan = 60,
+                  .last_pgscan = 0,
+                  .pgscan = 33,
                   .current_memory_usage = 10 },
                 { .path = paths[1],
                   .swap_usage = 60,
-                  .pgscan = 40,
+                  .last_pgscan = 33,
+                  .pgscan = 1,
                   .current_memory_usage = 20 },
                 { .path = paths[2],
                   .swap_usage = 40,
-                  .pgscan = 40,
+                  .last_pgscan = 1,
+                  .pgscan = 33,
                   .current_memory_usage = 40 },
                 { .path = paths[3],
                   .swap_usage = 10,
-                  .pgscan = 80,
+                  .last_pgscan = 33,
+                  .pgscan = 2,
                   .current_memory_usage = 10 },
                 { .path = paths[4],
+                  .swap_usage = 11,
+                  .last_pgscan = 33,
+                  .pgscan = 33,
+                  .current_memory_usage = 10 },
+                { .path = paths[5],
                   .swap_usage = 90,
-                  .pgscan = 100,
+                  .last_pgscan = 0,
+                  .pgscan = UINT64_MAX,
                   .preference = MANAGED_OOM_PREFERENCE_OMIT },
-                { .path = paths[5],
+                { .path = paths[6],
                   .swap_usage = 99,
-                  .pgscan = 200,
+                  .last_pgscan = 0,
+                  .pgscan = UINT64_MAX,
                   .preference = MANAGED_OOM_PREFERENCE_AVOID },
         };
 
@@ -361,32 +420,36 @@ static void test_oomd_sort_cgroups(void) {
         assert_se(hashmap_put(h, "/herp.slice/derp.scope", &ctx[1]) >= 0);
         assert_se(hashmap_put(h, "/herp.slice/derp.scope/sheep.service", &ctx[2]) >= 0);
         assert_se(hashmap_put(h, "/zupa.slice", &ctx[3]) >= 0);
-        assert_se(hashmap_put(h, "/omitted.slice", &ctx[4]) >= 0);
-        assert_se(hashmap_put(h, "/avoid.slice", &ctx[5]) >= 0);
+        assert_se(hashmap_put(h, "/boop.slice", &ctx[4]) >= 0);
+        assert_se(hashmap_put(h, "/omitted.slice", &ctx[5]) >= 0);
+        assert_se(hashmap_put(h, "/avoid.slice", &ctx[6]) >= 0);
 
-        assert_se(oomd_sort_cgroup_contexts(h, compare_swap_usage, NULL, &sorted_cgroups) == 5);
+        assert_se(oomd_sort_cgroup_contexts(h, compare_swap_usage, NULL, &sorted_cgroups) == 6);
         assert_se(sorted_cgroups[0] == &ctx[1]);
         assert_se(sorted_cgroups[1] == &ctx[2]);
         assert_se(sorted_cgroups[2] == &ctx[0]);
-        assert_se(sorted_cgroups[3] == &ctx[3]);
-        assert_se(sorted_cgroups[4] == &ctx[5]);
+        assert_se(sorted_cgroups[3] == &ctx[4]);
+        assert_se(sorted_cgroups[4] == &ctx[3]);
+        assert_se(sorted_cgroups[5] == &ctx[6]);
         sorted_cgroups = mfree(sorted_cgroups);
 
-        assert_se(oomd_sort_cgroup_contexts(h, compare_pgscan_and_memory_usage, NULL, &sorted_cgroups) == 5);
-        assert_se(sorted_cgroups[0] == &ctx[3]);
-        assert_se(sorted_cgroups[1] == &ctx[0]);
-        assert_se(sorted_cgroups[2] == &ctx[2]);
+        assert_se(oomd_sort_cgroup_contexts(h, compare_pgscan_rate_and_memory_usage, NULL, &sorted_cgroups) == 6);
+        assert_se(sorted_cgroups[0] == &ctx[0]);
+        assert_se(sorted_cgroups[1] == &ctx[2]);
+        assert_se(sorted_cgroups[2] == &ctx[3]);
         assert_se(sorted_cgroups[3] == &ctx[1]);
-        assert_se(sorted_cgroups[4] == &ctx[5]);
+        assert_se(sorted_cgroups[4] == &ctx[4]);
+        assert_se(sorted_cgroups[5] == &ctx[6]);
         sorted_cgroups = mfree(sorted_cgroups);
 
-        assert_se(oomd_sort_cgroup_contexts(h, compare_pgscan_and_memory_usage, "/herp.slice/derp.scope", &sorted_cgroups) == 2);
+        assert_se(oomd_sort_cgroup_contexts(h, compare_pgscan_rate_and_memory_usage, "/herp.slice/derp.scope", &sorted_cgroups) == 2);
         assert_se(sorted_cgroups[0] == &ctx[2]);
         assert_se(sorted_cgroups[1] == &ctx[1]);
         assert_se(sorted_cgroups[2] == 0);
         assert_se(sorted_cgroups[3] == 0);
         assert_se(sorted_cgroups[4] == 0);
         assert_se(sorted_cgroups[5] == 0);
+        assert_se(sorted_cgroups[6] == 0);
         sorted_cgroups = mfree(sorted_cgroups);
 }
 
@@ -395,6 +458,7 @@ int main(void) {
 
         test_setup_logging(LOG_DEBUG);
 
+        test_oomd_update_cgroup_contexts_between_hashmaps();
         test_oomd_system_context_acquire();
         test_oomd_pressure_above();
         test_oomd_memory_reclaim();
index be16f5a067b5ceaab463bf7a7239aa2c1d3363df..195a909bf3899b2899ea791719f72ba923ac4ae8 100644 (file)
@@ -2655,11 +2655,15 @@ static int do_copy_files(Partition *p, const char *fs) {
 
         STRV_FOREACH_PAIR(source, target, p->copy_files) {
                 _cleanup_close_ int sfd = -1, pfd = -1, tfd = -1;
-                _cleanup_free_ char *dn = NULL;
+                _cleanup_free_ char *dn = NULL, *fn = NULL;
 
-                dn = dirname_malloc(*target);
-                if (!dn)
-                        return log_oom();
+                r = path_extract_directory(*target, &dn);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract directory from '%s': %m", *target);
+
+                r = path_extract_filename(*target, &fn);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract filename from '%s': %m", *target);
 
                 sfd = chase_symlinks_and_open(*source, arg_root, CHASE_PREFIX_ROOT|CHASE_WARN, O_CLOEXEC|O_NOCTTY, NULL);
                 if (sfd < 0)
@@ -2686,7 +2690,7 @@ static int do_copy_files(Partition *p, const char *fs) {
 
                                 r = copy_tree_at(
                                                 sfd, ".",
-                                                pfd, basename(*target),
+                                                pfd, fn,
                                                 UID_INVALID, GID_INVALID,
                                                 COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
                         } else
@@ -2994,8 +2998,6 @@ static int partition_acquire_label(Context *context, Partition *p, char **ret) {
                         break;
 
                 label = mfree(label);
-
-
                 if (asprintf(&label, "%s-%u", prefix, ++k) < 0)
                         return log_oom();
         }
@@ -3977,6 +3979,40 @@ static int find_root(char **ret, int *ret_fd) {
         return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device.");
 }
 
+static int resize_pt(int fd) {
+        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+        _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
+        int r;
+
+        /* After resizing the backing file we need to resize the partition table itself too, so that it takes
+         * possession of the enlarged backing file. For this it suffices to open the device with libfdisk and
+         * immediately write it again, with no changes. */
+
+        c = fdisk_new_context();
+        if (!c)
+                return log_oom();
+
+        xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+        r = fdisk_assign_device(c, procfs_path, 0);
+        if (r < 0)
+                return log_error_errno(r, "Failed to open device '%s': %m", procfs_path);
+
+        r = fdisk_has_label(c);
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine whether disk '%s' has a disk label: %m", procfs_path);
+        if (r == 0) {
+                log_debug("Not resizing partition table, as there currently is none.");
+                return 0;
+        }
+
+        r = fdisk_write_disklabel(c);
+        if (r < 0)
+                return log_error_errno(r, "Failed to write resized partition table: %m");
+
+        log_info("Resized partition table.");
+        return 1;
+}
+
 static int resize_backing_fd(const char *node, int *fd) {
         char buf1[FORMAT_BYTES_MAX], buf2[FORMAT_BYTES_MAX];
         _cleanup_close_ int writable_fd = -1;
@@ -4029,6 +4065,10 @@ static int resize_backing_fd(const char *node, int *fd) {
                         /* Fallback to truncation, if fallocate() is not supported. */
                         log_debug("Backing file system does not support fallocate(), falling back to ftruncate().");
                 } else {
+                        r = resize_pt(writable_fd);
+                        if (r < 0)
+                                return r;
+
                         if (st.st_size == 0) /* Likely regular file just created by us */
                                 log_info("Allocated %s for '%s'.", buf2, node);
                         else
@@ -4042,6 +4082,10 @@ static int resize_backing_fd(const char *node, int *fd) {
                 return log_error_errno(errno, "Failed to grow '%s' from %s to %s by truncation: %m",
                                        node, buf1, buf2);
 
+        r = resize_pt(writable_fd);
+        if (r < 0)
+                return r;
+
         if (st.st_size == 0) /* Likely regular file just created by us */
                 log_info("Sized '%s' to %s.", node, buf2);
         else
index 6c09e8bbd4f61eea68e54e69d272bf3434dbe7ad..5651db67227d7d0136136cbed6785ebdcfe4ba0e 100644 (file)
@@ -380,7 +380,16 @@ static int portable_extract_by_path(
                 if (r < 0)
                         return log_debug_errno(r, "Failed to create temporary directory: %m");
 
-                r = dissect_image(d->fd, NULL, NULL, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK, &m);
+                r = dissect_image(
+                                d->fd,
+                                NULL, NULL,
+                                DISSECT_IMAGE_READ_ONLY |
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_DISCARD_ON_LOOP |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_USR_NO_ROOT,
+                                &m);
                 if (r == -ENOPKG)
                         sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Couldn't identify a suitable partition table or file system in '%s'.", path);
                 else if (r == -EADDRNOTAVAIL)
index 9d59c608c1516d98126dc979f00edc3433945bd9..6ce38f10a3e08dcb653a85b59379898be1a372b8 100644 (file)
@@ -342,7 +342,7 @@ static int list_files(PStoreList *list, const char *sourcepath) {
                 size_t buf_size;
 
                 /* Now read contents of pstore file */
-                r = read_full_file(ifd_path, &buf, &buf_size);
+                r = read_full_virtual_file(ifd_path, &buf, &buf_size);
                 if (r < 0) {
                         log_warning_errno(r, "Failed to read file %s, skipping: %m", ifd_path);
                         continue;
index 0392ad98742df9ad233e2389adf051c5ecca5a4e..b1d97736a3f16c278b42402843125a1360938323 100644 (file)
@@ -13,6 +13,8 @@ basic_dns_sources = files('''
         resolved-dns-answer.h
         resolved-dns-question.c
         resolved-dns-question.h
+        resolved-util.c
+        resolved-util.h
         dns-type.c
         dns-type.h
 '''.split())
@@ -210,9 +212,13 @@ tests += [
           libgpg_error,
           libm]],
 
-        [['src/resolve/test-dnssec-complex.c',
-          'src/resolve/dns-type.c'],
-         [], [], resolve_includes, '', 'manual'],
+        [['src/resolve/test-dnssec-complex.c'],
+         [libsystemd_resolve_core,
+          libshared],
+         [libgcrypt,
+          libgpg_error,
+          libm],
+         [], '', 'manual'],
 ]
 
 fuzzers += [
index 2bd18d2c6d3508822ba320ca105ae7145639b4cc..52bbae3293b8283f5e25468e6e7f3dccc4029b45 100644 (file)
@@ -19,6 +19,7 @@
 #include "format-table.h"
 #include "format-util.h"
 #include "gcrypt-util.h"
+#include "hostname-util.h"
 #include "main-func.h"
 #include "missing_network.h"
 #include "netlink-util.h"
@@ -31,6 +32,7 @@
 #include "resolvectl.h"
 #include "resolved-def.h"
 #include "resolved-dns-packet.h"
+#include "resolved-util.h"
 #include "socket-netlink.h"
 #include "sort-util.h"
 #include "stdio-util.h"
@@ -441,6 +443,25 @@ static int idna_candidate(const char *name, char **ret) {
         return false;
 }
 
+static bool single_label_nonsynthetic(const char *name) {
+        _cleanup_free_ char *first_label = NULL;
+        int r;
+
+        if (!dns_name_is_single_label(name))
+                return false;
+
+        if (is_localhost(name) || is_gateway_hostname(name))
+                return false;
+
+        r = resolve_system_hostname(NULL, &first_label);
+        if (r < 0) {
+                log_warning_errno(r, "Failed to determine the hostname: %m");
+                return false;
+        }
+
+        return !streq(name, first_label);
+}
+
 static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_t type, bool warn_missing) {
         _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;
@@ -455,15 +476,15 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
 
         log_debug("Resolving %s %s %s (interface %s).", name, dns_class_to_string(class), dns_type_to_string(type), isempty(arg_ifname) ? "*" : arg_ifname);
 
-        if (dns_name_is_single_label(name))
-                log_notice("(Note that search domains are not appended when resolving raw record types. "
-                           "Please specify fully qualified domain names when resolving raw records, or remove --type= switch from invocation in order to request regular hostname resolution.)");
+        if (dns_name_dot_suffixed(name) == 0 && single_label_nonsynthetic(name))
+                log_notice("(Note that search domains are not appended when --type= is specified. "
+                           "Please specify fully qualified domain names, or remove --type= switch from invocation in order to request regular hostname resolution.)");
 
         r = idna_candidate(name, &idnafied);
         if (r < 0)
                 return r;
         if (r > 0)
-                log_notice("(Note that IDNA translation is not applied when resolving raw record types. "
+                log_notice("(Note that IDNA translation is not applied when --type= is specified. "
                            "Please specify translated domain names — i.e. '%s' — when resolving raw records, or remove --type= switch from invocation in order to request regular hostname resolution.",
                            idnafied);
 
index 032ed0256bf41e9b0886ac2089ea3582360b43f1..c3624669ce18b954fb29890bce42c936ce4005cd 100644 (file)
@@ -195,14 +195,14 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
                 goto finish;
         }
 
-        r = dns_query_process_cname(q);
+        r = dns_query_process_cname_many(q);
         if (r == -ELOOP) {
                 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
                 goto finish;
         }
         if (r < 0)
                 goto finish;
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         r = sd_bus_message_new_method_return(q->bus_request, &reply);
@@ -486,14 +486,14 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
                 goto finish;
         }
 
-        r = dns_query_process_cname(q);
+        r = dns_query_process_cname_many(q);
         if (r == -ELOOP) {
                 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
                 goto finish;
         }
         if (r < 0)
                 goto finish;
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         r = sd_bus_message_new_method_return(q->bus_request, &reply);
@@ -660,14 +660,14 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
                 goto finish;
         }
 
-        r = dns_query_process_cname(q);
+        r = dns_query_process_cname_many(q);
         if (r == -ELOOP) {
                 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
                 goto finish;
         }
         if (r < 0)
                 goto finish;
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         r = sd_bus_message_new_method_return(q->bus_request, &reply);
@@ -1107,8 +1107,8 @@ static void resolve_service_hostname_complete(DnsQuery *q) {
                 return;
         }
 
-        r = dns_query_process_cname(q);
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        r = dns_query_process_cname_many(q);
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
@@ -1180,14 +1180,14 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
                 goto finish;
         }
 
-        r = dns_query_process_cname(q);
+        r = dns_query_process_cname_many(q);
         if (r == -ELOOP) {
                 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
                 goto finish;
         }
         if (r < 0)
                 goto finish;
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         question = dns_query_question_for_protocol(q, q->answer_protocol);
index a667ab5ede431a43e4821c2594727f6f7f4e65ae..a032ac157e067b3dd53061b105caed6444610d73 100644 (file)
@@ -879,9 +879,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
                 }
 
                 fputs(t, f);
-
-                if (item->ifindex != 0 || item->rrsig || item->flags != 0)
-                        fputs("\t;", f);
+                fputs("\t;", f);
+                fprintf(f, " ttl=%" PRIu32, item->rr->ttl);
 
                 if (item->ifindex != 0)
                         fprintf(f, " ifindex=%i", item->ifindex);
@@ -963,3 +962,22 @@ void dns_answer_randomize(DnsAnswer *a) {
                 SWAP_TWO(a->items[i], a->items[k]);
         }
 }
+
+uint32_t dns_answer_min_ttl(DnsAnswer *a) {
+        uint32_t ttl = UINT32_MAX;
+        DnsResourceRecord *rr;
+
+        /* Return the smallest TTL of all RRs in this answer */
+
+        DNS_ANSWER_FOREACH(rr, a) {
+                /* Don't consider OPT (where the TTL field is used for other purposes than an actual TTL) */
+
+                if (dns_type_is_pseudo(rr->key->type) ||
+                    dns_class_is_pseudo(rr->key->class))
+                        continue;
+
+                ttl = MIN(ttl, rr->ttl);
+        }
+
+        return ttl;
+}
index 7d19eee4e2bb5d434726f22fdaaae3b8234c0ab0..447da5d6cc3437e282c6cd7265ab8d78b27a7cad 100644 (file)
@@ -87,6 +87,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f);
 
 void dns_answer_randomize(DnsAnswer *a);
 
+uint32_t dns_answer_min_ttl(DnsAnswer *a);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsAnswer*, dns_answer_unref);
 
 #define _DNS_ANSWER_FOREACH(q, kk, a)                                   \
index 0bf320df8808fba9addef2a93592381e44e89d38..c019dc38c9dd41cce12713158cd7b4f7c5498b98 100644 (file)
@@ -312,19 +312,23 @@ static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
         return NULL;
 }
 
-static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t timestamp, bool use_soa_minimum) {
+static usec_t calculate_until(
+                DnsResourceRecord *rr,
+                uint32_t min_ttl,
+                uint32_t nsec_ttl,
+                usec_t timestamp,
+                bool use_soa_minimum) {
+
         uint32_t ttl;
         usec_t u;
 
         assert(rr);
 
-        ttl = MIN(rr->ttl, nsec_ttl);
+        ttl = MIN(min_ttl, nsec_ttl);
         if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
-                /* If this is a SOA RR, and it is requested, clamp to
-                 * the SOA's minimum field. This is used when we do
-                 * negative caching, to determine the TTL for the
-                 * negative caching entry.  See RFC 2308, Section
-                 * 5. */
+                /* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
+                 * when we do negative caching, to determine the TTL for the negative caching entry. See RFC
+                 * 2308, Section 5. */
 
                 if (ttl > rr->soa.minimum)
                         ttl = rr->soa.minimum;
@@ -337,8 +341,7 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
         if (rr->expiry != USEC_INFINITY) {
                 usec_t left;
 
-                /* Make use of the DNSSEC RRSIG expiry info, if we
-                 * have it */
+                /* Make use of the DNSSEC RRSIG expiry info, if we have it */
 
                 left = LESS_BY(rr->expiry, now(CLOCK_REALTIME));
                 if (u > left)
@@ -354,6 +357,7 @@ static void dns_cache_item_update_positive(
                 DnsResourceRecord *rr,
                 DnsAnswer *answer,
                 DnsPacket *full_packet,
+                uint32_t min_ttl,
                 uint64_t query_flags,
                 bool shared_owner,
                 DnssecResult dnssec_result,
@@ -390,7 +394,7 @@ static void dns_cache_item_update_positive(
         dns_packet_unref(i->full_packet);
         i->full_packet = full_packet;
 
-        i->until = calculate_until(rr, UINT32_MAX, timestamp, false);
+        i->until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false);
         i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS;
         i->shared_owner = shared_owner;
         i->dnssec_result = dnssec_result;
@@ -417,9 +421,10 @@ static int dns_cache_put_positive(
                 const union in_addr_union *owner_address) {
 
         _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
-        DnsCacheItem *existing;
         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
-        int r, k;
+        DnsCacheItem *existing;
+        uint32_t min_ttl;
+        int r;
 
         assert(c);
         assert(rr);
@@ -431,11 +436,16 @@ static int dns_cache_put_positive(
         if (dns_type_is_pseudo(rr->key->type))
                 return 0;
 
+        /* Determine the minimal TTL of all RRs in the answer plus the one by the main RR we are supposed to
+         * cache. Since we cache whole answers to questions we should never return answers where only some
+         * RRs are still valid, hence find the lowest here */
+        min_ttl = MIN(dns_answer_min_ttl(answer), rr->ttl);
+
         /* New TTL is 0? Delete this specific entry... */
-        if (rr->ttl <= 0) {
-                k = dns_cache_remove_by_rr(c, rr);
+        if (min_ttl <= 0) {
+                r = dns_cache_remove_by_rr(c, rr);
                 log_debug("%s: %s",
-                          k > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
+                          r > 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;
         }
@@ -449,6 +459,7 @@ static int dns_cache_put_positive(
                                 rr,
                                 answer,
                                 full_packet,
+                                min_ttl,
                                 query_flags,
                                 shared_owner,
                                 dnssec_result,
@@ -476,7 +487,7 @@ static int dns_cache_put_positive(
                 .rr = dns_resource_record_ref(rr),
                 .answer = dns_answer_ref(answer),
                 .full_packet = dns_packet_ref(full_packet),
-                .until = calculate_until(rr, UINT32_MAX, timestamp, false),
+                .until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false),
                 .query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
                 .shared_owner = shared_owner,
                 .dnssec_result = dnssec_result,
@@ -578,9 +589,12 @@ static int dns_cache_put_negative(
                 .full_packet = dns_packet_ref(full_packet),
         };
 
+        /* Determine how long to cache this entry. In case we have some RRs in the answer use the lowest TTL
+         * of any of them. Typically that's the SOA's TTL, which is OK, but could possibly be lower because
+         * of some other RR. Let's better take the lowest option here than a needlessly high one */
         i->until =
                 i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
-                calculate_until(soa, nsec_ttl, timestamp, true);
+                calculate_until(soa, dns_answer_min_ttl(answer), nsec_ttl, timestamp, true);
 
         if (i->type == DNS_CACHE_NXDOMAIN) {
                 /* NXDOMAIN entries should apply equally to all types, so we use ANY as
@@ -696,7 +710,7 @@ int dns_cache_put(
          * short time.) */
 
         if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
-                if (dns_answer_size(answer) <= 0) {
+                if (dns_answer_isempty(answer)) {
                         if (key) {
                                 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
 
@@ -785,9 +799,8 @@ int dns_cache_put(
         if (r > 0)
                 return 0;
 
-        /* But not if it has a matching CNAME/DNAME (the negative
-         * caching will be done on the canonical name, not on the
-         * alias) */
+        /* But not if it has a matching CNAME/DNAME (the negative caching will be done on the canonical name,
+         * not on the alias) */
         r = dns_answer_find_cname_or_dname(answer, key, NULL, NULL);
         if (r < 0)
                 goto fail;
@@ -803,8 +816,7 @@ int dns_cache_put(
         if (r == 0 && !weird_rcode)
                 return 0;
         if (r > 0) {
-                /* Refuse using the SOA data if it is unsigned, but the key is
-                 * signed */
+                /* Refuse using the SOA data if it is unsigned, but the key is signed */
                 if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) &&
                     (flags & DNS_ANSWER_AUTHENTICATED) == 0)
                         return 0;
@@ -813,7 +825,7 @@ int dns_cache_put(
         if (cache_mode == DNS_CACHE_MODE_NO_NEGATIVE) {
                 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
                 log_debug("Not caching negative entry for: %s, cache mode set to no-negative",
-                        dns_resource_key_to_string(key, key_str, sizeof key_str));
+                          dns_resource_key_to_string(key, key_str, sizeof key_str));
                 return 0;
         }
 
@@ -923,9 +935,18 @@ static int answer_add_clamp_ttl(
         assert(rr);
 
         if (FLAGS_SET(query_flags, SD_RESOLVED_CLAMP_TTL)) {
+                uint32_t left_ttl;
+
+                /* Let's determine how much time is left for this cache entry. Note that we round down, but
+                 * clamp this to be 1s at minimum, since we usually want records to remain cached better too
+                 * short a time than too long a time, but otoh don't want to return 0 ever, since that has
+                 * special semantics in various contexts — in particular in mDNS */
+
+                left_ttl = MAX(1U, LESS_BY(until, current) / USEC_PER_SEC);
+
                 patched = dns_resource_record_ref(rr);
 
-                r = dns_resource_record_clamp_ttl(&patched, LESS_BY(until, current) / USEC_PER_SEC);
+                r = dns_resource_record_clamp_ttl(&patched, left_ttl);
                 if (r < 0)
                         return r;
 
@@ -933,7 +954,7 @@ static int answer_add_clamp_ttl(
 
                 if (rrsig) {
                         patched_rrsig = dns_resource_record_ref(rrsig);
-                        r = dns_resource_record_clamp_ttl(&patched_rrsig, LESS_BY(until, current) / USEC_PER_SEC);
+                        r = dns_resource_record_clamp_ttl(&patched_rrsig, left_ttl);
                         if (r < 0)
                                 return r;
 
@@ -1051,21 +1072,30 @@ int dns_cache_lookup(
                                 DnsAnswerItem *item;
 
                                 DNS_ANSWER_FOREACH_ITEM(item, j->answer) {
-                                        r = answer_add_clamp_ttl(&answer, item->rr, item->ifindex, item->flags, item->rrsig, query_flags, j->until, current);
+                                        r = answer_add_clamp_ttl(
+                                                        &answer,
+                                                        item->rr,
+                                                        item->ifindex,
+                                                        item->flags,
+                                                        item->rrsig,
+                                                        query_flags,
+                                                        j->until,
+                                                        current);
                                         if (r < 0)
                                                 return r;
                                 }
                         }
 
                 } else if (j->rr) {
-                        r = answer_add_clamp_ttl(&answer,
-                                                 j->rr,
-                                                 j->ifindex,
-                                                 FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
-                                                 NULL,
-                                                 query_flags,
-                                                 j->until,
-                                                 current);
+                        r = answer_add_clamp_ttl(
+                                        &answer,
+                                        j->rr,
+                                        j->ifindex,
+                                        FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
+                                        NULL,
+                                        query_flags,
+                                        j->until,
+                                        current);
                         if (r < 0)
                                 return r;
                 }
index abc978ab833c6eeaa81a93d489dcb5b290ed3c1e..8de407d21aed6c243668b7c6e46cb22b23101cf5 100644 (file)
@@ -2271,7 +2271,7 @@ static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
                 bool cache_flush = false;
                 size_t start;
 
-                if (p->rindex == p->size) {
+                if (p->rindex == p->size && p->opt) {
                         /* If we reached the end of the packet already, but there are still more RRs
                          * declared, then that's a corrupt packet. Let's accept the packet anyway, since it's
                          * apparently a common bug in routers. Let's however suppress OPT support in this
index aa9d65d4a827c4ff5c693035ce4961568e2d92d4..e960ac0322730b062d301c11e641c42ea84b952a 100644 (file)
@@ -433,6 +433,14 @@ int dns_query_new(
         } else {
                 bool good = false;
 
+                /* This (primarily) checks two things:
+                 *
+                 * 1. That the question is not empty
+                 * 2. That all RR keys in the question objects are for the same domain
+                 *
+                 * Or in other words, a single DnsQuery object may be used to look up A+AAAA combination for
+                 * the same domain name, or SRV+TXT (for DNS-SD services), but not for unrelated lookups. */
+
                 if (dns_question_size(question_utf8) > 0) {
                         r = dns_question_is_valid_for_query(question_utf8);
                         if (r < 0)
@@ -982,12 +990,12 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
         r = dns_question_cname_redirect(q->question_idna, cname, &nq_idna);
         if (r < 0)
                 return r;
-        else if (r > 0)
+        if (r > 0)
                 log_debug("Following CNAME/DNAME %s → %s.", dns_question_first_name(q->question_idna), dns_question_first_name(nq_idna));
 
         k = dns_question_is_equal(q->question_idna, q->question_utf8);
         if (k < 0)
-                return r;
+                return k;
         if (k > 0) {
                 /* Same question? Shortcut new question generation */
                 nq_utf8 = dns_question_ref(nq_idna);
@@ -996,7 +1004,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
                 k = dns_question_cname_redirect(q->question_utf8, cname, &nq_utf8);
                 if (k < 0)
                         return k;
-                else if (k > 0)
+                if (k > 0)
                         log_debug("Following UTF8 CNAME/DNAME %s → %s.", dns_question_first_name(q->question_utf8), dns_question_first_name(nq_utf8));
         }
 
@@ -1019,33 +1027,84 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
         q->question_utf8 = TAKE_PTR(nq_utf8);
 
         dns_query_unref_candidates(q);
-        dns_query_reset_answer(q);
+
+        /* Note that we do *not* reset the answer here, because the answer we previously got might already
+         * include everything we need, let's check that first */
 
         q->state = DNS_TRANSACTION_NULL;
 
         return 0;
 }
 
-int dns_query_process_cname(DnsQuery *q) {
+int dns_query_process_cname_one(DnsQuery *q) {
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL;
         DnsQuestion *question;
         DnsResourceRecord *rr;
+        bool full_match = true;
+        DnsResourceKey *k;
         int r;
 
         assert(q);
 
+        /* Processes a CNAME redirect if there's one. Returns one of three values:
+         *
+         * CNAME_QUERY_MATCH   → direct RR match, caller should just use the RRs in this answer (and not
+         *                       bother with any CNAME/DNAME stuff)
+         *
+         * CNAME_QUERY_NOMATCH → no match at all, neither direct nor CNAME/DNAME, caller might decide to
+         *                       restart query or take things as NODATA reply.
+         *
+         * CNAME_QUERY_CNAME   → no direct RR match, but a CNAME/DNAME match that we now followed for one step.
+         *
+         * The function might also return a failure, in particular -ELOOP if we encountered too many
+         * CNAMEs/DNAMEs in a chain or if following CNAMEs/DNAMEs was turned off.
+         *
+         * Note that this function doesn't actually restart the query. The caller can decide to do that in
+         * case of CNAME_QUERY_CNAME, though. */
+
         if (!IN_SET(q->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_NULL))
                 return DNS_QUERY_NOMATCH;
 
         question = dns_query_question_for_protocol(q, q->answer_protocol);
 
-        DNS_ANSWER_FOREACH(rr, q->answer) {
-                r = dns_question_matches_rr(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
-                if (r < 0)
-                        return r;
-                if (r > 0)
-                        return DNS_QUERY_MATCH; /* The answer matches directly, no need to follow cnames */
+        /* Small reminder: our question will consist of one or more RR keys that match in name, but not in
+         * record type. Specifically, when we do an address lookup the question will typically consist of one
+         * A and one AAAA key lookup for the same domain name. When we get a response from a server we need
+         * to check if the answer answers all our questions to use it. Note that a response of CNAME/DNAME
+         * can answer both an A and the AAAA question for us, but an A/AAAA response only the relevant
+         * type.
+         *
+         * Hence we first check of the answers we collected are sufficient to answer all our questions
+         * directly. If one question wasn't answered we go on, waiting for more replies. However, if there's
+         * a CNAME/DNAME response we use it, and redirect to it, regardless if it was a response to the A or
+         * the AAAA query.*/
+
+        DNS_QUESTION_FOREACH(k, question) {
+                bool match = false;
+
+                DNS_ANSWER_FOREACH(rr, q->answer) {
+                        r = dns_resource_key_match_rr(k, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
+                        if (r < 0)
+                                return r;
+                        if (r > 0) {
+                                match = true; /* Yay, we found an RR that matches the key we are looking for */
+                                break;
+                        }
+                }
+
+                if (!match) {
+                        /* Hmm. :-( there's no response for this key. This doesn't match. */
+                        full_match = false;
+                        break;
+                }
+        }
+
+        if (full_match)
+                return DNS_QUERY_MATCH; /* The answer can answer our question in full, no need to follow CNAMEs/DNAMEs */
 
+        /* Let's see if there is a CNAME/DNAME to match. This case is simpler: we accept the CNAME/DNAME that
+         * matches any of our questions. */
+        DNS_ANSWER_FOREACH(rr, q->answer) {
                 r = dns_question_matches_cname_or_dname(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
                 if (r < 0)
                         return r;
@@ -1054,7 +1113,7 @@ int dns_query_process_cname(DnsQuery *q) {
         }
 
         if (!cname)
-                return DNS_QUERY_NOMATCH; /* No match and no cname to follow */
+                return DNS_QUERY_NOMATCH; /* No match and no CNAME/DNAME to follow */
 
         if (q->flags & SD_RESOLVED_NO_CNAME)
                 return -ELOOP;
@@ -1063,24 +1122,71 @@ int dns_query_process_cname(DnsQuery *q) {
                 q->previous_redirect_unauthenticated = true;
         if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL))
                 q->previous_redirect_non_confidential = true;
+        if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_SYNTHETIC))
+                q->previous_redirect_non_synthetic = true;
 
         /* OK, let's actually follow the CNAME */
         r = dns_query_cname_redirect(q, cname);
         if (r < 0)
                 return r;
 
-        /* Let's see if the answer can already answer the new
-         * redirected question */
-        r = dns_query_process_cname(q);
-        if (r != DNS_QUERY_NOMATCH)
-                return r;
+        return DNS_QUERY_CNAME; /* Tell caller that we did a single CNAME/DNAME redirection step */
+}
 
-        /* OK, it cannot, let's begin with the new query */
-        r = dns_query_go(q);
-        if (r < 0)
-                return r;
+int dns_query_process_cname_many(DnsQuery *q) {
+        int r;
+
+        assert(q);
+
+        /* Follows CNAMEs through the current packet: as long as the current packet can fulfill our
+         * redirected CNAME queries we keep going, and restart the query once the current packet isn't good
+         * enough anymore. It's a wrapper around dns_query_process_cname_one() and returns the same values,
+         * but with extended semantics. Specifically:
+         *
+         * DNS_QUERY_MATCH   → as above
+         *
+         * DNS_QUERY_CNAME   → we ran into a CNAME/DNAME redirect that we could not answer from the current
+         *                     message, and thus restarted the query to resolve it.
+         *
+         * DNS_QUERY_NOMATCH → we reached the end of CNAME/DNAME chain, and there are no direct matches nor a
+         *                     CNAME/DNAME match. i.e. this is a NODATA case.
+         *
+         * Note that this function will restart the query for the caller if needed, and that's the case
+         * DNS_QUERY_CNAME is returned.
+         */
+
+        r = dns_query_process_cname_one(q);
+        if (r != DNS_QUERY_CNAME)
+                return r; /* The first redirect is special: if it doesn't answer the question that's no
+                           * reason to restart the query, we just accept this as a NODATA answer. */
 
-        return DNS_QUERY_RESTARTED; /* We restarted the query for a new cname */
+        for (;;) {
+                r = dns_query_process_cname_one(q);
+                if (r < 0 || r == DNS_QUERY_MATCH)
+                        return r;
+                if (r == DNS_QUERY_NOMATCH) {
+                        /* OK, so we followed one or more CNAME/DNAME RR but the existing packet can't answer
+                         * this. Let's restart the query hence, with the new question. Why the different
+                         * handling than the first chain element? Because if the server answers a direct
+                         * question with an empty answer then this is a NODATA response. But if it responds
+                         * with a CNAME chain that ultimately is incomplete (i.e. a non-empty but truncated
+                         * CNAME chain) then we better follow up ourselves and ask for the rest of the
+                         * chain. This is particular relevant since our cache will store CNAME/DNAME
+                         * redirects that we learnt about for lookups of certain DNS types, but later on we
+                         * can reuse this data even for other DNS types, but in that case need to follow up
+                         * with the final lookup of the chain ourselves with the RR type we ourselves are
+                         * interested in. */
+                        r = dns_query_go(q);
+                        if (r < 0)
+                                return r;
+
+                        return DNS_QUERY_CNAME;
+                }
+
+                /* So we found a CNAME that the existing packet already answers, again via a CNAME, let's
+                 * continue going then. */
+                assert(r == DNS_QUERY_CNAME);
+        }
 }
 
 DnsQuestion* dns_query_question_for_protocol(DnsQuery *q, DnsProtocol protocol) {
@@ -1140,9 +1246,17 @@ bool dns_query_fully_confidential(DnsQuery *q) {
         return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) && !q->previous_redirect_non_confidential;
 }
 
-bool dns_query_fully_synthetic(DnsQuery *q) {
+bool dns_query_fully_authoritative(DnsQuery *q) {
         assert(q);
 
-        return (q->answer_query_flags & (SD_RESOLVED_SYNTHETIC | SD_RESOLVED_FROM_TRUST_ANCHOR)) &&
-                !(q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~SD_RESOLVED_FROM_TRUST_ANCHOR);
+        /* We are authoritative for everything synthetic (except if a previous CNAME/DNAME) wasn't
+         * synthetic. (Note: SD_RESOLVED_SYNTHETIC is reset on each CNAME/DNAME, hence the explicit check for
+         * previous synthetic DNAME/CNAME redirections.)*/
+        if ((q->answer_query_flags & SD_RESOLVED_SYNTHETIC) && !q->previous_redirect_non_synthetic)
+                return true;
+
+        /* We are also authoritative for everything coming only from the trust anchor and the local
+         * zones. (Note: the SD_RESOLVED_FROM_xyz flags we merge on each redirect, hence no need to
+         * explicitly check previous redirects here.)*/
+        return (q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~(SD_RESOLVED_FROM_TRUST_ANCHOR | SD_RESOLVED_FROM_ZONE)) == 0;
 }
index 5d12171b0a1290b0660287e3ce1127a0732feb8c..fa584fe3de9d884853d3564042476bc1614246fb 100644 (file)
@@ -45,7 +45,14 @@ struct DnsQuery {
          * that even on classic DNS some labels might use UTF8 encoding. Specifically, DNS-SD service names
          * (in contrast to their domain suffixes) use UTF-8 encoding even on DNS. Thus, the difference
          * between these two fields is mostly relevant only for explicit *hostname* lookups as well as the
-         * domain suffixes of service lookups. */
+         * domain suffixes of service lookups.
+         *
+         * Note that questions may consist of multiple RR keys at once, but they must be for the same domain
+         * name. This is used for A+AAAA and TXT+SRV lookups: we'll allocate a single DnsQuery object for
+         * them instead of two separate ones. That allows us minor optimizations with response handling:
+         * CNAME/DNAMEs of the first reply we get can already be used to follow the CNAME/DNAME chain for
+         * both, and we can take benefit of server replies that oftentimes put A responses into AAAA queries
+         * and vice versa (in the additional section). */
         DnsQuestion *question_idna;
         DnsQuestion *question_utf8;
 
@@ -73,6 +80,7 @@ struct DnsQuery {
         int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
         bool previous_redirect_unauthenticated;
         bool previous_redirect_non_confidential;
+        bool previous_redirect_non_synthetic;
         DnsPacket *answer_full_packet;
 
         /* Bus + Varlink client information */
@@ -105,7 +113,7 @@ struct DnsQuery {
 enum {
         DNS_QUERY_MATCH,
         DNS_QUERY_NOMATCH,
-        DNS_QUERY_RESTARTED,
+        DNS_QUERY_CNAME,
 };
 
 DnsQueryCandidate* dns_query_candidate_ref(DnsQueryCandidate*);
@@ -122,7 +130,8 @@ int dns_query_make_auxiliary(DnsQuery *q, DnsQuery *auxiliary_for);
 int dns_query_go(DnsQuery *q);
 void dns_query_ready(DnsQuery *q);
 
-int dns_query_process_cname(DnsQuery *q);
+int dns_query_process_cname_one(DnsQuery *q);
+int dns_query_process_cname_many(DnsQuery *q);
 
 void dns_query_complete(DnsQuery *q, DnsTransactionState state);
 
@@ -134,7 +143,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
 
 bool dns_query_fully_authenticated(DnsQuery *q);
 bool dns_query_fully_confidential(DnsQuery *q);
-bool dns_query_fully_synthetic(DnsQuery *q);
+bool dns_query_fully_authoritative(DnsQuery *q);
 
 static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
         assert(q);
index 047170899db0167d5725b043eaaa1ff947453908..ef40932630407471787b1f5d27802f6a1ad37b73 100644 (file)
@@ -445,3 +445,21 @@ int dns_question_new_service(
 
         return 0;
 }
+
+/*
+ * This function is not used in the code base, but is useful when debugging. Do not delete.
+ */
+void dns_question_dump(DnsQuestion *question, FILE *f) {
+        DnsResourceKey *k;
+
+        if (!f)
+                f = stdout;
+
+        DNS_QUESTION_FOREACH(k, question) {
+                char buf[DNS_RESOURCE_KEY_STRING_MAX];
+
+                fputc('\t', f);
+                fputs(dns_resource_key_to_string(k, buf, sizeof(buf)), f);
+                fputc('\n', f);
+        }
+}
index a6444b0baf9cd629dd556920f497f9a2c5279c9e..8f9a84c82d936d6e088a118febfddca6a4121f04 100644 (file)
@@ -33,6 +33,8 @@ int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b);
 
 int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret);
 
+void dns_question_dump(DnsQuestion *q, FILE *f);
+
 const char *dns_question_first_name(DnsQuestion *q);
 
 static inline size_t dns_question_size(DnsQuestion *q) {
index 7e76e0c6cc08c0f029d4e7dd3d571bcde842eed7..5b0e601e97a8b236795319cc3530b11a89fbabc9 100644 (file)
@@ -820,8 +820,8 @@ static char *format_txt(DnsTxtItem *first) {
 }
 
 const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
-        _cleanup_free_ char *t = NULL;
-        char *s, k[DNS_RESOURCE_KEY_STRING_MAX];
+        _cleanup_free_ char *s = NULL, *t = NULL;
+        char k[DNS_RESOURCE_KEY_STRING_MAX];
         int r;
 
         assert(rr);
@@ -871,18 +871,15 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                         return NULL;
                 break;
 
-        case DNS_TYPE_A: {
-                _cleanup_free_ char *x = NULL;
-
-                r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
+        case DNS_TYPE_A:
+                r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &t);
                 if (r < 0)
                         return NULL;
 
-                s = strjoin(k, " ", x);
+                s = strjoin(k, " ", t);
                 if (!s)
                         return NULL;
                 break;
-        }
 
         case DNS_TYPE_AAAA:
                 r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &t);
@@ -965,7 +962,6 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
 
         case DNS_TYPE_DNSKEY: {
                 _cleanup_free_ char *alg = NULL;
-                char *ss;
                 uint16_t key_tag;
 
                 key_tag = dnssec_keytag(rr, true);
@@ -974,7 +970,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 if (r < 0)
                         return NULL;
 
-                r = asprintf(&s, "%s %u %u %s",
+                r = asprintf(&t, "%s %u %u %s",
                              k,
                              rr->dnskey.flags,
                              rr->dnskey.protocol,
@@ -982,24 +978,22 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 if (r < 0)
                         return NULL;
 
-                r = base64_append(&s, r,
+                r = base64_append(&t, r,
                                   rr->dnskey.key, rr->dnskey.key_size,
                                   8, columns());
                 if (r < 0)
                         return NULL;
 
-                r = asprintf(&ss, "%s\n"
+                r = asprintf(&s, "%s\n"
                              "        -- Flags:%s%s%s\n"
                              "        -- Key tag: %u",
-                             s,
+                             t,
                              rr->dnskey.flags & DNSKEY_FLAG_SEP ? " SEP" : "",
                              rr->dnskey.flags & DNSKEY_FLAG_REVOKE ? " REVOKE" : "",
                              rr->dnskey.flags & DNSKEY_FLAG_ZONE_KEY ? " ZONE_KEY" : "",
                              key_tag);
                 if (r < 0)
                         return NULL;
-                free(s);
-                s = ss;
 
                 break;
         }
@@ -1123,18 +1117,16 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 break;
         }
 
-        case DNS_TYPE_CAA: {
-                _cleanup_free_ char *value;
-
-                value = octescape(rr->caa.value, rr->caa.value_size);
-                if (!value)
+        case DNS_TYPE_CAA:
+                t = octescape(rr->caa.value, rr->caa.value_size);
+                if (!t)
                         return NULL;
 
                 r = asprintf(&s, "%s %u %s \"%s\"%s%s%s%.0u",
                              k,
                              rr->caa.flags,
                              rr->caa.tag,
-                             value,
+                             t,
                              rr->caa.flags ? "\n        -- Flags:" : "",
                              rr->caa.flags & CAA_FLAG_CRITICAL ? " critical" : "",
                              rr->caa.flags & ~CAA_FLAG_CRITICAL ? " " : "",
@@ -1143,9 +1135,8 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                         return NULL;
 
                 break;
-        }
 
-        case DNS_TYPE_OPENPGPKEY: {
+        case DNS_TYPE_OPENPGPKEY:
                 r = asprintf(&s, "%s", k);
                 if (r < 0)
                         return NULL;
@@ -1156,7 +1147,6 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 if (r < 0)
                         return NULL;
                 break;
-        }
 
         default:
                 t = hexmem(rr->generic.data, rr->generic.data_size);
@@ -1171,7 +1161,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
         }
 
         rr->to_string = s;
-        return s;
+        return TAKE_PTR(s);
 }
 
 ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
index 82481563546365e6ae7f8d182d3285607081025b..073489acae03ae0dc4e88ae7a59b81c8c9b83119 100644 (file)
@@ -867,10 +867,11 @@ DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
         if (m->current_dns_server == s)
                 return s;
 
+        /* Let's log about the server switch, at debug level. Except if we switch from a non-fallback server
+         * to a fallback server or back, since that is noteworthy and possibly a configuration issue */
         if (s)
-                log_debug("Switching to %s DNS server %s.",
-                          dns_server_type_to_string(s->type),
-                          strna(dns_server_string_full(s)));
+                log_full((s->type == DNS_SERVER_FALLBACK) != (m->current_dns_server && m->current_dns_server->type == DNS_SERVER_FALLBACK) ? LOG_NOTICE : LOG_DEBUG,
+                         "Switching to %s DNS server %s.", dns_server_type_to_string(s->type), strna(dns_server_string_full(s)));
 
         dns_server_unref(m->current_dns_server);
         m->current_dns_server = dns_server_ref(s);
index 8e781dd7389872a8f7299484b7d8e4d4c215ad7c..602720bf505d6decee5845c2b9953e9cf3076e45 100644 (file)
@@ -161,89 +161,40 @@ static int dns_stub_collect_answer_by_question(
                 DnsQuestion *question,
                 bool with_rrsig) { /* Add RRSIG RR matching each RR */
 
-        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *redirected_key = NULL;
-        unsigned n_cname_redirects = 0;
         DnsAnswerItem *item;
         int r;
 
         assert(reply);
 
-        /* Copies all RRs from 'answer' into 'reply', if they match 'question'. There might be direct and
-         * indirect matches (i.e. via CNAME/DNAME). If they have an indirect one, remember where we need to
-         * go, and restart the loop */
+        /* Copies all RRs from 'answer' into 'reply', if they match 'question'. */
 
-        for (;;) {
-                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *next_redirected_key = NULL;
-
-                DNS_ANSWER_FOREACH_ITEM(item, answer) {
-                        DnsResourceKey *k = NULL;
-
-                        if (redirected_key) {
-                                /* There was a redirect in this packet, let's collect all matching RRs for the redirect */
-                                r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
-                                if (r < 0)
-                                        return r;
-
-                                k = redirected_key;
-                        } else if (question) {
-                                /* We have a question, let's see if this RR matches it */
-                                r = dns_question_matches_rr(question, item->rr, NULL);
-                                if (r < 0)
-                                        return r;
-
-                                k = question->keys[0];
-                        } else
-                                r = 1; /* No question, everything matches */
-
-                        if (r == 0) {
-                                _cleanup_free_ char *target = NULL;
-
-                                /* OK, so the RR doesn't directly match. Let's see if the RR is a matching
-                                 * CNAME or DNAME */
-
-                                assert(k);
-
-                                r = dns_resource_record_get_cname_target(k, item->rr, &target);
-                                if (r == -EUNATCH)
-                                        continue; /* Not a CNAME/DNAME or doesn't match */
-                                if (r < 0)
-                                        return r;
-
-                                /* Oh, wow, this is a redirect. Let's remember where this points, and store
-                                 * it in 'next_redirected_key'. Once we finished iterating through the rest
-                                 * of the RR's we'll start again, with the redirected RR key. */
-
-                                n_cname_redirects++;
-                                if (n_cname_redirects > CNAME_REDIRECT_MAX) /* don't loop forever */
-                                        return -ELOOP;
-
-                                dns_resource_key_unref(next_redirected_key);
-
-                                /* There can only be one CNAME per name, hence no point in storing more than one here */
-                                next_redirected_key = dns_resource_key_new(k->class, k->type, target);
-                                if (!next_redirected_key)
-                                        return -ENOMEM;
-                        }
-
-                        /* Mask the section info, we want the primary answers to always go without section info, so
-                         * that it is added to the answer section when we synthesize a reply. */
+        DNS_ANSWER_FOREACH_ITEM(item, answer) {
 
-                        r = reply_add_with_rrsig(
-                                        reply,
-                                        item->rr,
-                                        item->ifindex,
-                                        item->flags & ~DNS_ANSWER_MASK_SECTIONS,
-                                        item->rrsig,
-                                        with_rrsig);
+                /* We have a question, let's see if this RR matches it */
+                r = dns_question_matches_rr(question, item->rr, NULL);
+                if (r < 0)
+                        return r;
+                if (!r) {
+                        /* Maybe there's a CNAME/DNAME in here? If so, that's an answer too */
+                        r = dns_question_matches_cname_or_dname(question, item->rr, NULL);
                         if (r < 0)
                                 return r;
+                        if (!r)
+                                continue;
                 }
 
-                if (!next_redirected_key)
-                        break;
+                /* Mask the section info, we want the primary answers to always go without section
+                 * info, so that it is added to the answer section when we synthesize a reply. */
 
-                dns_resource_key_unref(redirected_key);
-                redirected_key = TAKE_PTR(next_redirected_key);
+                r = reply_add_with_rrsig(
+                                reply,
+                                item->rr,
+                                item->ifindex,
+                                item->flags & ~DNS_ANSWER_MASK_SECTIONS,
+                                item->rrsig,
+                                with_rrsig);
+                if (r < 0)
+                        return r;
         }
 
         return 0;
@@ -275,7 +226,7 @@ static int dns_stub_collect_answer_by_section(
                     dns_type_is_dnssec(item->rr->key->type))
                         continue;
 
-                if (((item->flags ^ section) & (DNS_ANSWER_SECTION_ANSWER|DNS_ANSWER_SECTION_AUTHORITY|DNS_ANSWER_SECTION_ADDITIONAL)) != 0)
+                if (((item->flags ^ section) & DNS_ANSWER_MASK_SECTIONS) != 0)
                         continue;
 
                 r = reply_add_with_rrsig(
@@ -323,27 +274,27 @@ static int dns_stub_assign_sections(
         if (r < 0)
                 return r;
 
-        /* Include all RRs that originate from the answer or authority sections, and aren't listed in the
+        /* Include all RRs that originate from the authority sections, and aren't already listed in the
          * answer section, in the authority section */
         r = dns_stub_collect_answer_by_section(
                         &q->reply_authoritative,
                         q->answer,
-                        DNS_ANSWER_SECTION_ANSWER,
+                        DNS_ANSWER_SECTION_AUTHORITY,
                         q->reply_answer, NULL,
                         edns0_do);
         if (r < 0)
                 return r;
+
+        /* Include all RRs that originate from the answer or additional sections in the additional section
+         * (except if already listed in the other two sections). Also add all RRs with no section marking. */
         r = dns_stub_collect_answer_by_section(
-                        &q->reply_authoritative,
+                        &q->reply_additional,
                         q->answer,
-                        DNS_ANSWER_SECTION_AUTHORITY,
-                        q->reply_answer, NULL,
+                        DNS_ANSWER_SECTION_ANSWER,
+                        q->reply_answer, q->reply_authoritative,
                         edns0_do);
         if (r < 0)
                 return r;
-
-        /* Include all RRs that originate from the additional sections in the additional section (except if
-         * already listed in the other two sections). Also add all RRs with no section marking. */
         r = dns_stub_collect_answer_by_section(
                         &q->reply_additional,
                         q->answer,
@@ -629,7 +580,7 @@ static int dns_stub_send_reply(
                         DNS_PACKET_ID(q->request_packet),
                         rcode,
                         truncated,
-                        dns_query_fully_synthetic(q),
+                        dns_query_fully_authoritative(q),
                         !!q->request_packet->opt,
                         edns0_do,
                         DNS_PACKET_AD(q->request_packet) && dns_query_fully_authenticated(q),
@@ -761,7 +712,7 @@ static void dns_stub_query_complete(DnsQuery *q) {
          * and keep adding all RRs in the CNAME chain. */
         r = dns_stub_assign_sections(
                         q,
-                        q->request_packet->question,
+                        dns_query_question_for_protocol(q, DNS_PROTOCOL_DNS),
                         dns_stub_reply_with_edns0_do(q));
         if (r < 0) {
                 log_debug_errno(r, "Failed to assign sections: %m");
@@ -771,21 +722,63 @@ static void dns_stub_query_complete(DnsQuery *q) {
 
         switch (q->state) {
 
-        case DNS_TRANSACTION_SUCCESS:
-                r = dns_query_process_cname(q);
-                if (r == -ELOOP) { /* CNAME loop, let's send what we already have */
-                        log_debug_errno(r, "Detected CNAME loop, returning what we already have.");
-                        (void) dns_stub_send_reply(q, q->answer_rcode);
-                        break;
-                }
-                if (r < 0) {
-                        log_debug_errno(r, "Failed to process CNAME: %m");
-                        break;
+        case DNS_TRANSACTION_SUCCESS: {
+                bool first = true;
+
+                for (;;) {
+                        int cname_result;
+
+                        cname_result = dns_query_process_cname_one(q);
+                        if (cname_result == -ELOOP) { /* CNAME loop, let's send what we already have */
+                                log_debug_errno(r, "Detected CNAME loop, returning what we already have.");
+                                (void) dns_stub_send_reply(q, q->answer_rcode);
+                                break;
+                        }
+                        if (cname_result < 0) {
+                                log_debug_errno(cname_result, "Failed to process CNAME: %m");
+                                break;
+                        }
+
+                        if (cname_result == DNS_QUERY_NOMATCH) {
+                                /* This answer doesn't contain any RR that would answer our question
+                                 * positively, i.e. neither directly nor via CNAME. */
+
+                                if (first) /* We never followed a CNAME and the answer doesn't match our
+                                            * question at all? Then this is final, the empty answer is the
+                                            * answer. */
+                                        break;
+
+                                /* Otherwise, we already followed a CNAME once within this packet, and the
+                                 * packet doesn't answer our question. In that case let's restart the query,
+                                 * now with the redirected question. We'll */
+                                r = dns_query_go(q);
+                                if (r < 0)
+                                        log_debug_errno(r, "Failed to restart query: %m");
+
+                                return;
+                        }
+
+                        r = dns_stub_assign_sections(
+                                        q,
+                                        dns_query_question_for_protocol(q, DNS_PROTOCOL_DNS),
+                                        dns_stub_reply_with_edns0_do(q));
+                        if (r < 0) {
+                                log_debug_errno(r, "Failed to assign sections: %m");
+                                dns_query_free(q);
+                                return;
+                        }
+
+                        if (cname_result == DNS_QUERY_MATCH) /* A match? Then we are done, let's return what we got */
+                                break;
+
+                        /* We followed a CNAME. and collected the RRs that answer the redirected question
+                         * successfully. Let's not try to do this again. */
+                        assert(cname_result == DNS_QUERY_CNAME);
+                        first = false;
                 }
-                if (r == DNS_QUERY_RESTARTED)
-                        return;
 
                 _fallthrough_;
+        }
 
         case DNS_TRANSACTION_RCODE_FAILURE:
                 (void) dns_stub_send_reply(q, q->answer_rcode);
index e815dacd7f1e94eed7a83cfdad94665660c52aa8..21154a7f85eb5acb672a85917293a78b6cdf8bdf 100644 (file)
@@ -33,6 +33,7 @@
 #include "resolved-manager.h"
 #include "resolved-mdns.h"
 #include "resolved-resolv-conf.h"
+#include "resolved-util.h"
 #include "resolved-varlink.h"
 #include "socket-util.h"
 #include "string-table.h"
@@ -362,75 +363,17 @@ static int manager_clock_change_listen(Manager *m) {
         return 0;
 }
 
-static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
+static int determine_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
         _cleanup_free_ char *h = NULL, *n = NULL;
-#if HAVE_LIBIDN2
-        _cleanup_free_ char *utf8 = NULL;
-#elif HAVE_LIBIDN
-        int k;
-#endif
-        char label[DNS_LABEL_MAX];
-        const char *p, *decoded;
         int r;
 
         assert(full_hostname);
         assert(llmnr_hostname);
         assert(mdns_hostname);
 
-        /* Extract and normalize the first label of the locally configured hostname, and check it's not "localhost". */
-
-        r = gethostname_strict(&h);
-        if (r < 0)
-                return log_debug_errno(r, "Can't determine system hostname: %m");
-
-        p = h;
-        r = dns_label_unescape(&p, label, sizeof label, 0);
-        if (r < 0)
-                return log_error_errno(r, "Failed to unescape hostname: %m");
-        if (r == 0)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Couldn't find a single label in hostname.");
-
-#if HAVE_LIBIDN || HAVE_LIBIDN2
-        r = dlopen_idn();
-        if (r < 0) {
-                log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m");
-                decoded = label; /* no decoding */
-        } else
-#endif
-        {
-#if HAVE_LIBIDN2
-                r = sym_idn2_to_unicode_8z8z(label, &utf8, 0);
-                if (r != IDN2_OK)
-                        return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN),
-                                               "Failed to undo IDNA: %s", sym_idn2_strerror(r));
-                assert(utf8_is_valid(utf8));
-
-                r = strlen(utf8);
-                decoded = utf8;
-#elif HAVE_LIBIDN
-                k = dns_label_undo_idna(label, r, label, sizeof label);
-                if (k < 0)
-                        return log_error_errno(k, "Failed to undo IDNA: %m");
-                if (k > 0)
-                        r = k;
-
-                if (!utf8_is_valid(label))
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                               "System hostname is not UTF-8 clean.");
-                decoded = label;
-#else
-                decoded = label; /* no decoding */
-#endif
-        }
-
-        r = dns_label_escape_new(decoded, r, &n);
+        r = resolve_system_hostname(&h, &n);
         if (r < 0)
-                return log_error_errno(r, "Failed to escape hostname: %m");
-
-        if (is_localhost(n))
-                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "System hostname is 'localhost', ignoring.");
+                return r;
 
         r = dns_name_concat(n, "local", 0, mdns_hostname);
         if (r < 0)
@@ -501,9 +444,11 @@ static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, voi
 
         assert(m);
 
-        r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname);
-        if (r < 0)
+        r = determine_hostnames(&full_hostname, &llmnr_hostname, &mdns_hostname);
+        if (r < 0) {
+                log_warning_errno(r, "Failed to determine the local hostname and LLMNR/mDNS names, ignoring: %m");
                 return 0; /* ignore invalid hostnames */
+        }
 
         llmnr_hostname_changed = !streq(llmnr_hostname, m->llmnr_hostname);
         if (streq(full_hostname, m->full_hostname) &&
@@ -546,7 +491,7 @@ static int manager_watch_hostname(Manager *m) {
 
         (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
 
-        r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
+        r = determine_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
         if (r < 0) {
                 _cleanup_free_ char *d = NULL;
 
index bfd71575d63e810c8d7215872b10bbf5fccab9ff..2857b58e89e287003b63b99d6f820e601c2ec8a5 100644 (file)
@@ -265,6 +265,7 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
 
         if (dns_packet_validate_reply(p) > 0) {
                 DnsResourceRecord *rr;
+                DnsTransaction *t;
 
                 log_debug("Got mDNS reply packet");
 
@@ -286,8 +287,9 @@ 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);
-                        DnsTransaction *t;
+                        const char *name;
+
+                        name = dns_resource_key_name(rr->key);
 
                         /* If the received reply packet contains ANY record that is not .local
                          * or .in-addr.arpa or .ip6.arpa, we assume someone's playing tricks on
@@ -302,22 +304,13 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
                                 /* See the section 10.1 of RFC6762 */
                                 rr->ttl = 1;
                         }
+                }
 
-                        t = dns_scope_find_transaction(scope, rr->key, SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
-                        if (t)
-                                dns_transaction_process_reply(t, p, false);
-
-                        /* Also look for the various types of ANY transactions */
-                        t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
-                        if (t)
-                                dns_transaction_process_reply(t, p, false);
-
-                        t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, rr->key->type, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
-                        if (t)
-                                dns_transaction_process_reply(t, p, false);
-
-                        t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
-                        if (t)
+                LIST_FOREACH(transactions_by_scope, t, scope->transactions) {
+                        r = dns_answer_match_key(p->answer, t->key, NULL);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to match resource key, ignoring: %m");
+                        else if (r > 0) /* This packet matches the transaction, let's pass it on as reply */
                                 dns_transaction_process_reply(t, p, false);
                 }
 
diff --git a/src/resolve/resolved-util.c b/src/resolve/resolved-util.c
new file mode 100644 (file)
index 0000000..00abada
--- /dev/null
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "dns-def.h"
+#include "dns-domain.h"
+#include "hostname-util.h"
+#include "idn-util.h"
+#include "resolved-util.h"
+#include "utf8.h"
+
+int resolve_system_hostname(char **full_hostname, char **first_label) {
+        _cleanup_free_ char *h = NULL, *n = NULL;
+#if HAVE_LIBIDN2
+        _cleanup_free_ char *utf8 = NULL;
+#elif HAVE_LIBIDN
+        int k;
+#endif
+        char label[DNS_LABEL_MAX];
+        const char *p, *decoded;
+        int r;
+
+        /* Return the full hostname in *full_hostname, if nonnull.
+         *
+         * Extract and normalize the first label of the locally configured hostname, check it's not
+         * "localhost", and return it in *first_label, if nonnull. */
+
+        r = gethostname_strict(&h);
+        if (r < 0)
+                return log_debug_errno(r, "Can't determine system hostname: %m");
+
+        p = h;
+        r = dns_label_unescape(&p, label, sizeof label, 0);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to unescape hostname: %m");
+        if (r == 0)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "Couldn't find a single label in hostname.");
+
+#if HAVE_LIBIDN || HAVE_LIBIDN2
+        r = dlopen_idn();
+        if (r < 0) {
+                log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m");
+                decoded = label; /* no decoding */
+        } else
+#endif
+        {
+#if HAVE_LIBIDN2
+                r = sym_idn2_to_unicode_8z8z(label, &utf8, 0);
+                if (r != IDN2_OK)
+                        return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
+                                               "Failed to undo IDNA: %s", sym_idn2_strerror(r));
+                assert(utf8_is_valid(utf8));
+
+                r = strlen(utf8);
+                decoded = utf8;
+#elif HAVE_LIBIDN
+                k = dns_label_undo_idna(label, r, label, sizeof label);
+                if (k < 0)
+                        return log_debug_errno(k, "Failed to undo IDNA: %m");
+                if (k > 0)
+                        r = k;
+
+                if (!utf8_is_valid(label))
+                        return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "System hostname is not UTF-8 clean.");
+                decoded = label;
+#else
+                decoded = label; /* no decoding */
+#endif
+        }
+
+        r = dns_label_escape_new(decoded, r, &n);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to escape hostname: %m");
+
+        if (is_localhost(n))
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "System hostname is 'localhost', ignoring.");
+
+        if (full_hostname)
+                *full_hostname = TAKE_PTR(h);
+        if (first_label)
+                *first_label = TAKE_PTR(n);
+        return 0;
+}
diff --git a/src/resolve/resolved-util.h b/src/resolve/resolved-util.h
new file mode 100644 (file)
index 0000000..446b7c9
--- /dev/null
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+int resolve_system_hostname(char **full_hostname, char **first_label);
index 77e75b8a8d1770dacf7221cb987422e38101a269..27d8c8967ec4072dd2569a67643905318a97d2c1 100644 (file)
@@ -158,14 +158,14 @@ static void vl_method_resolve_hostname_complete(DnsQuery *q) {
                 goto finish;
         }
 
-        r = dns_query_process_cname(q);
+        r = dns_query_process_cname_many(q);
         if (r == -ELOOP) {
                 r = varlink_error(q->varlink_request, "io.systemd.Resolve.CNAMELoop", NULL);
                 goto finish;
         }
         if (r < 0)
                 goto finish;
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         question = dns_query_question_for_protocol(q, q->answer_protocol);
@@ -395,14 +395,14 @@ static void vl_method_resolve_address_complete(DnsQuery *q) {
                 goto finish;
         }
 
-        r = dns_query_process_cname(q);
+        r = dns_query_process_cname_many(q);
         if (r == -ELOOP) {
                 r = varlink_error(q->varlink_request, "io.systemd.Resolve.CNAMELoop", NULL);
                 goto finish;
         }
         if (r < 0)
                 goto finish;
-        if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+        if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
                 return;
 
         question = dns_query_question_for_protocol(q, q->answer_protocol);
index 33187618e5c6c1ab426fc957921805592bed995e..f88a4e97c0d9b7e4cb74d688e884e2134e917aa0 100644 (file)
@@ -10,6 +10,8 @@
 # the system.conf.d/ subdirectory. The latter is generally recommended.
 # Defaults can be restored by simply deleting this file and all drop-ins.
 #
+# Use 'systemd-analyze cat-config systemd/resolved.conf' to display the full config.
+#
 # See resolved.conf(5) for details.
 
 [Resolve]
index 11244537991e60c57c0eb956a258da6e113a50be..cccea2f72752dd116e2c19b1e90bf367331ee2b2 100644 (file)
@@ -72,7 +72,7 @@ int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) {
         struct acpi_fpdt_boot_header hbrec;
         struct acpi_fpdt_boot brec;
 
-        r = read_full_file("/sys/firmware/acpi/tables/FPDT", &buf, &l);
+        r = read_full_virtual_file("/sys/firmware/acpi/tables/FPDT", &buf, &l);
         if (r < 0)
                 return r;
 
index 729aa1fb00a20ec4ab7c522f87853fa304cd58f2..04c6b5287ed3f1bd9bfe9bf96d8b8e62a31e5d77 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "alloc-util.h"
 #include "ask-password-api.h"
+#include "creds-util.h"
 #include "def.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -971,11 +972,33 @@ finish:
         return r;
 }
 
+static int ask_password_credential(const char *credential_name, AskPasswordFlags flags, char ***ret) {
+        _cleanup_(erase_and_freep) char *buffer = NULL;
+        size_t size;
+        char **l;
+        int r;
+
+        assert(credential_name);
+        assert(ret);
+
+        r = read_credential(credential_name, (void**) &buffer, &size);
+        if (IN_SET(r, -ENXIO, -ENOENT)) /* No credentials passed or this credential not defined? */
+                return -ENOKEY;
+
+        l = strv_parse_nulstr(buffer, size);
+        if (!l)
+                return -ENOMEM;
+
+        *ret = l;
+        return 0;
+}
+
 int ask_password_auto(
                 const char *message,
                 const char *icon,
-                const char *id,
-                const char *keyname,
+                const char *id,                /* id in "ask-password" protocol */
+                const char *key_name,          /* name in kernel keyring */
+                const char *credential_name,   /* name in $CREDENTIALS_DIRECTORY directory */
                 usec_t until,
                 AskPasswordFlags flags,
                 char ***ret) {
@@ -984,20 +1007,26 @@ int ask_password_auto(
 
         assert(ret);
 
+        if (!(flags & ASK_PASSWORD_NO_CREDENTIAL) && credential_name) {
+                r = ask_password_credential(credential_name, flags, ret);
+                if (r != -ENOKEY)
+                        return r;
+        }
+
         if ((flags & ASK_PASSWORD_ACCEPT_CACHED) &&
-            keyname &&
+            key_name &&
             ((flags & ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) &&
             (flags & ASK_PASSWORD_NO_AGENT)) {
-                r = ask_password_keyring(keyname, flags, ret);
+                r = ask_password_keyring(key_name, flags, ret);
                 if (r != -ENOKEY)
                         return r;
         }
 
         if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO))
-                return ask_password_tty(-1, message, keyname, until, flags, NULL, ret);
+                return ask_password_tty(-1, message, key_name, until, flags, NULL, ret);
 
         if (!(flags & ASK_PASSWORD_NO_AGENT))
-                return ask_password_agent(message, icon, id, keyname, until, flags, ret);
+                return ask_password_agent(message, icon, id, key_name, until, flags, ret);
 
         return -EUNATCH;
 }
index 7aac5e597608208bb9923e532125b14c13bedf30..bb507b2e8de0bb8c07dc50b0997b638fad3a468d 100644 (file)
@@ -6,16 +6,17 @@
 #include "time-util.h"
 
 typedef enum AskPasswordFlags {
-        ASK_PASSWORD_ACCEPT_CACHED = 1 << 0,
-        ASK_PASSWORD_PUSH_CACHE    = 1 << 1,
+        ASK_PASSWORD_ACCEPT_CACHED = 1 << 0, /* read from kernel keyring */
+        ASK_PASSWORD_PUSH_CACHE    = 1 << 1, /* write to kernel keyring after getting password from elsewhere */
         ASK_PASSWORD_ECHO          = 1 << 2, /* show the password literally while reading, instead of "*" */
         ASK_PASSWORD_SILENT        = 1 << 3, /* do no show any password at all while reading */
-        ASK_PASSWORD_NO_TTY        = 1 << 4,
-        ASK_PASSWORD_NO_AGENT      = 1 << 5,
+        ASK_PASSWORD_NO_TTY        = 1 << 4, /* never ask for password on tty */
+        ASK_PASSWORD_NO_AGENT      = 1 << 5, /* never ask for password via agent */
         ASK_PASSWORD_CONSOLE_COLOR = 1 << 6, /* Use color if /dev/console points to a console that supports color */
+        ASK_PASSWORD_NO_CREDENTIAL = 1 << 7, /* never use $CREDENTIALS_DIRECTORY data */
 } AskPasswordFlags;
 
-int ask_password_tty(int tty_fd, const char *message, const char *keyname, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
+int ask_password_tty(int tty_fd, const char *message, const char *key_name, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
 int ask_password_plymouth(const char *message, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
-int ask_password_agent(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
-int ask_password_auto(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
+int ask_password_agent(const char *message, const char *icon, const char *id, const char *key_name, usec_t until, AskPasswordFlags flag, char ***ret);
+int ask_password_auto(const char *message, const char *icon, const char *id, const char *key_name, const char *credential_name, usec_t until, AskPasswordFlags flag, char ***ret);
index a75178068b507f661985eaa77f4e6b43792f0545..84d4729334c682d91da077b3b6936a1c79c1fc87 100644 (file)
@@ -1947,6 +1947,7 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
 
         if (STR_IN_SET(field, "PIDFile",
                               "Type",
+                              "ExitType",
                               "Restart",
                               "BusName",
                               "NotifyAccess",
index 4f68a570b52366e1c678c1fe208a1a191568020e..bf24d8d5bbb85d04ae087bf7f0e1d29542f4e01b 100644 (file)
@@ -1101,7 +1101,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
         return 0;
 }
 
-static int find_end_of_month(struct tm *tm, bool utc, int day) {
+static int find_end_of_month(const struct tm *tm, bool utc, int day) {
         struct tm t = *tm;
 
         t.tm_mon++;
@@ -1114,28 +1114,39 @@ static int find_end_of_month(struct tm *tm, bool utc, int day) {
         return t.tm_mday;
 }
 
-static int find_matching_component(const CalendarSpec *spec, const CalendarComponent *c,
-                                   struct tm *tm, int *val) {
-        const CalendarComponent *p = c;
-        int start, stop, d = -1;
+static int find_matching_component(
+                const CalendarSpec *spec,
+                const CalendarComponent *c,
+                const struct tm *tm,           /* tm is only used for end-of-month calculations */
+                int *val) {
+
+        int d = -1, r;
         bool d_set = false;
-        int r;
 
         assert(val);
 
+        /* Finds the *earliest* matching time specified by one of the CalendarCompoment items in chain c.
+         * If no matches can be found, returns -ENOENT.
+         * Otherwise, updates *val to the matching time. 1 is returned if *val was changed, 0 otherwise.
+         */
+
         if (!c)
                 return 0;
 
+        bool end_of_month = spec->end_of_month && c == spec->day;
+
         while (c) {
-                start = c->start;
-                stop = c->stop;
+                int start, stop;
 
-                if (spec->end_of_month && p == spec->day) {
-                        start = find_end_of_month(tm, spec->utc, start);
-                        stop = find_end_of_month(tm, spec->utc, stop);
+                if (end_of_month) {
+                        start = find_end_of_month(tm, spec->utc, c->start);
+                        stop = find_end_of_month(tm, spec->utc, c->stop);
 
                         if (stop > 0)
                                 SWAP_TWO(start, stop);
+                } else {
+                        start = c->start;
+                        stop = c->stop;
                 }
 
                 if (start >= *val) {
@@ -1184,15 +1195,18 @@ static int tm_within_bounds(struct tm *tm, bool utc) {
                 return negative_errno();
 
         /* Did any normalization take place? If so, it was out of bounds before */
-        bool good = t.tm_year == tm->tm_year &&
-                    t.tm_mon  == tm->tm_mon  &&
-                    t.tm_mday == tm->tm_mday &&
-                    t.tm_hour == tm->tm_hour &&
-                    t.tm_min  == tm->tm_min  &&
-                    t.tm_sec  == tm->tm_sec;
-        if (!good)
+        int cmp = CMP(t.tm_year, tm->tm_year) ?:
+                  CMP(t.tm_mon, tm->tm_mon) ?:
+                  CMP(t.tm_mday, tm->tm_mday) ?:
+                  CMP(t.tm_hour, tm->tm_hour) ?:
+                  CMP(t.tm_min, tm->tm_min) ?:
+                  CMP(t.tm_sec, tm->tm_sec);
+
+        if (cmp < 0)
+                return -EDEADLK; /* Refuse to go backward */
+        if (cmp > 0)
                 *tm = t;
-        return good;
+        return cmp == 0;
 }
 
 static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
@@ -1210,6 +1224,10 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
         return (weekdays_bits & (1 << k));
 }
 
+/* A safety valve: if we get stuck in the calculation, return an error.
+ * C.f. https://bugzilla.redhat.com/show_bug.cgi?id=1941335. */
+#define MAX_CALENDAR_ITERATIONS 1000
+
 static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
         struct tm c;
         int tm_usec;
@@ -1223,7 +1241,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
         c = *tm;
         tm_usec = *usec;
 
-        for (;;) {
+        for (unsigned iteration = 0; iteration < MAX_CALENDAR_ITERATIONS; iteration++) {
                 /* Normalize the current date */
                 (void) mktime_or_timegm(&c, spec->utc);
                 c.tm_isdst = spec->dst;
@@ -1320,6 +1338,14 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
                 *usec = tm_usec;
                 return 0;
         }
+
+        /* It seems we entered an infinite loop. Let's gracefully return an error instead of hanging or
+         * aborting. This code is also exercised when timers.target is brought up during early boot, so
+         * aborting here is problematic and hard to diagnose for users. */
+        _cleanup_free_ char *s = NULL;
+        (void) calendar_spec_to_string(spec, &s);
+        return log_warning_errno(SYNTHETIC_ERRNO(EDEADLK),
+                                 "Infinite loop in calendar calculation: %s", strna(s));
 }
 
 static int calendar_spec_next_usec_impl(const CalendarSpec *spec, usec_t usec, usec_t *ret_next) {
index 79c4c70a41cf88028074f3d722e08f803f70ccd2..43138e0a6f600437d1c6c484c2b050b7639f9a26 100644 (file)
@@ -1198,7 +1198,13 @@ int image_read_metadata(Image *i) {
                 if (r < 0)
                         return r;
 
-                r = dissect_image(d->fd, NULL, NULL, DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_RELAX_VAR_CHECK, &m);
+                r = dissect_image(
+                                d->fd,
+                                NULL, NULL,
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_USR_NO_ROOT, &m);
                 if (r < 0)
                         return r;
 
index 6f9a4576144bf5f8697fcb8deb055b9c33c130cb..70739412a2fc8e0fbbef2c5de106ba1e120cc763 100644 (file)
@@ -456,6 +456,22 @@ static int device_wait_for_initialization_harder(
 
 #define DEVICE_TIMEOUT_USEC (45 * USEC_PER_SEC)
 
+static void dissected_partition_done(DissectedPartition *p) {
+        assert(p);
+
+        free(p->fstype);
+        free(p->node);
+        free(p->label);
+        free(p->decrypted_fstype);
+        free(p->decrypted_node);
+        free(p->mount_options);
+
+        *p = (DissectedPartition) {
+                .partno = -1,
+                .architecture = -1
+        };
+}
+
 int dissect_image(
                 int fd,
                 const VeritySettings *verity,
@@ -490,7 +506,9 @@ int dissect_image(
         /* Probes a disk image, and returns information about what it found in *ret.
          *
          * Returns -ENOPKG if no suitable partition table or file system could be found.
-         * Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found. */
+         * Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found.
+         * Returns -ENXIO if we couldn't find any partition suitable as root or /usr partition
+         * Returns -ENOTUNIQ if we only found multiple generic partitions and thus don't know what to do with that */
 
         if (verity && verity->root_hash) {
                 sd_id128_t fsuuid, vuuid;
@@ -612,7 +630,7 @@ int dissect_image(
         }
 
         if ((!(flags & DISSECT_IMAGE_GPT_ONLY) &&
-            (flags & DISSECT_IMAGE_REQUIRE_ROOT)) ||
+            (flags & DISSECT_IMAGE_GENERIC_ROOT)) ||
             (flags & DISSECT_IMAGE_NO_PARTITION_TABLE)) {
                 const char *usage = NULL;
 
@@ -727,7 +745,7 @@ int dissect_image(
                 if (is_gpt) {
                         PartitionDesignator designator = _PARTITION_DESIGNATOR_INVALID;
                         int architecture = _ARCHITECTURE_INVALID;
-                        const char *stype, *sid, *fstype = NULL;
+                        const char *stype, *sid, *fstype = NULL, *label;
                         sd_id128_t type_id, id;
                         bool rw = true;
 
@@ -743,6 +761,8 @@ int dissect_image(
                         if (sd_id128_from_string(stype, &type_id) < 0)
                                 continue;
 
+                        label = blkid_partition_get_name(pp); /* libblkid returns NULL here if empty */
+
                         if (sd_id128_equal(type_id, GPT_HOME)) {
 
                                 check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
@@ -997,12 +1017,21 @@ int dissect_image(
                         }
 
                         if (designator != _PARTITION_DESIGNATOR_INVALID) {
-                                _cleanup_free_ char *t = NULL, *n = NULL, *o = NULL;
+                                _cleanup_free_ char *t = NULL, *n = NULL, *o = NULL, *l = NULL;
                                 const char *options = NULL;
 
-                                /* First one wins */
-                                if (m->partitions[designator].found)
-                                        continue;
+                                if (m->partitions[designator].found) {
+                                        /* For most partition types the first one we see wins. Except for the
+                                         * rootfs and /usr, where we do a version compare of the label, and
+                                         * let the newest version win. This permits a simple A/B versioning
+                                         * scheme in OS images. */
+
+                                        if (!PARTITION_DESIGNATOR_VERSIONED(designator) ||
+                                            strverscmp_improved(m->partitions[designator].label, label) >= 0)
+                                                continue;
+
+                                        dissected_partition_done(m->partitions + designator);
+                                }
 
                                 if (fstype) {
                                         t = strdup(fstype);
@@ -1014,6 +1043,12 @@ int dissect_image(
                                 if (!n)
                                         return -ENOMEM;
 
+                                if (label) {
+                                        l = strdup(label);
+                                        if (!l)
+                                                return -ENOMEM;
+                                }
+
                                 options = mount_options_from_designator(mount_options, designator);
                                 if (options) {
                                         o = strdup(options);
@@ -1028,6 +1063,7 @@ int dissect_image(
                                         .architecture = architecture,
                                         .node = TAKE_PTR(n),
                                         .fstype = TAKE_PTR(t),
+                                        .label = TAKE_PTR(l),
                                         .uuid = id,
                                         .mount_options = TAKE_PTR(o),
                                 };
@@ -1100,46 +1136,64 @@ int dissect_image(
                 m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false;
                 m->partitions[PARTITION_USR_SECONDARY].found = false;
                 m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
-        } else {
-                /* No root partition found? Then let's see if ther's one for the secondary architecture. And if not
-                 * either, then check if there's a single generic one, and use that. */
 
-                if (m->partitions[PARTITION_ROOT_VERITY].found)
-                        return -EADDRNOTAVAIL;
+        } else if (m->partitions[PARTITION_ROOT_VERITY].found)
+                return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */
 
-                /* We didn't find a primary architecture root, but we found a primary architecture /usr? Refuse that for now. */
-                if (m->partitions[PARTITION_USR].found || m->partitions[PARTITION_USR_VERITY].found)
-                        return -EADDRNOTAVAIL;
+        else if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
 
-                if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
-                        /* Upgrade secondary arch to first */
-                        m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
-                        zero(m->partitions[PARTITION_ROOT_SECONDARY]);
-                        m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY];
-                        zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]);
+                /* No root partition found but there's one for the secondary architecture? Then upgrade
+                 * secondary arch to first */
 
-                        m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY];
-                        zero(m->partitions[PARTITION_USR_SECONDARY]);
-                        m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_SECONDARY_VERITY];
-                        zero(m->partitions[PARTITION_USR_SECONDARY_VERITY]);
+                m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
+                zero(m->partitions[PARTITION_ROOT_SECONDARY]);
+                m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY];
+                zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]);
 
-                } else if (flags & DISSECT_IMAGE_REQUIRE_ROOT) {
-                        _cleanup_free_ char *o = NULL;
-                        const char *options = NULL;
+                m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY];
+                zero(m->partitions[PARTITION_USR_SECONDARY]);
+                m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_SECONDARY_VERITY];
+                zero(m->partitions[PARTITION_USR_SECONDARY_VERITY]);
 
-                        /* If the root hash was set, then we won't fall back to a generic node, because the
-                         * root hash decides. */
-                        if (verity && verity->root_hash)
-                                return -EADDRNOTAVAIL;
+        } else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found)
+                return -EADDRNOTAVAIL; /* as above */
+
+        else if (m->partitions[PARTITION_USR].found) {
+
+                /* Invalidate secondary arch /usr/ if we found the primary arch */
+                m->partitions[PARTITION_USR_SECONDARY].found = false;
+                m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
+
+        } else if (m->partitions[PARTITION_USR_VERITY].found)
+                return -EADDRNOTAVAIL; /* as above */
 
-                        /* If we didn't find a generic node, then we can't fix this up either */
-                        if (!generic_node)
-                                return -ENXIO;
+        else if (m->partitions[PARTITION_USR_SECONDARY].found) {
 
-                        /* If we didn't find a properly marked root partition, but we did find a single suitable
-                         * generic Linux partition, then use this as root partition, if the caller asked for it. */
-                        if (multiple_generic)
-                                return -ENOTUNIQ;
+                /* Upgrade secondary arch to primary */
+                m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY];
+                zero(m->partitions[PARTITION_USR_SECONDARY]);
+                m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_SECONDARY_VERITY];
+                zero(m->partitions[PARTITION_USR_SECONDARY_VERITY]);
+
+        } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found)
+                return -EADDRNOTAVAIL; /* as above */
+
+        else if ((flags & DISSECT_IMAGE_GENERIC_ROOT) &&
+                 (!verity || !verity->root_hash)) {
+
+                /* OK, we found nothing usable, then check if there's a single generic one distro, and use
+                 * that. If the root hash was set however, then we won't fall back to a generic node, because
+                 * the root hash decides. */
+
+                /* If we didn't find a properly marked root partition, but we did find a single suitable
+                 * generic Linux partition, then use this as root partition, if the caller asked for it. */
+                if (multiple_generic)
+                        return -ENOTUNIQ;
+
+                /* If we didn't find a generic node, then we can't fix this up either */
+                if (generic_node) {
+                        _cleanup_free_ char *o = NULL;
+                        const char *options;
 
                         options = mount_options_from_designator(mount_options, PARTITION_ROOT);
                         if (options) {
@@ -1160,6 +1214,11 @@ int dissect_image(
                 }
         }
 
+        /* Check if we have a root fs if we are told to do check. /usr alone is fine too, but only if appropriate flag for that is set too */
+        if (FLAGS_SET(flags, DISSECT_IMAGE_REQUIRE_ROOT) &&
+            !(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
+                return -ENXIO;
+
         /* Refuse if we found a verity partition for /usr but no matching file system partition */
         if (!m->partitions[PARTITION_USR].found && m->partitions[PARTITION_USR_VERITY].found)
                 return -EADDRNOTAVAIL;
@@ -1221,13 +1280,8 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
         if (!m)
                 return NULL;
 
-        for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
-                free(m->partitions[i].fstype);
-                free(m->partitions[i].node);
-                free(m->partitions[i].decrypted_fstype);
-                free(m->partitions[i].decrypted_node);
-                free(m->partitions[i].mount_options);
-        }
+        for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++)
+                dissected_partition_done(m->partitions + i);
 
         free(m->image_name);
         free(m->hostname);
@@ -1287,6 +1341,7 @@ static int run_fsck(const char *node, const char *fstype) {
         if (r == 0) {
                 /* Child */
                 execl("/sbin/fsck", "/sbin/fsck", "-aT", node, NULL);
+                log_open();
                 log_debug_errno(errno, "Failed to execl() fsck: %m");
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
@@ -1397,6 +1452,32 @@ static int mount_partition(
         return 1;
 }
 
+static int mount_root_tmpfs(const char *where, uid_t uid_shift, DissectImageFlags flags) {
+        _cleanup_free_ char *options = NULL;
+        int r;
+
+        assert(where);
+
+        /* For images that contain /usr/ but no rootfs, let's mount rootfs as tmpfs */
+
+        if (FLAGS_SET(flags, DISSECT_IMAGE_MKDIR)) {
+                r = mkdir_p(where, 0755);
+                if (r < 0)
+                        return r;
+        }
+
+        if (uid_is_valid(uid_shift)) {
+                if (asprintf(&options, "uid=" UID_FMT ",gid=" GID_FMT, uid_shift, (gid_t) uid_shift) < 0)
+                        return -ENOMEM;
+        }
+
+        r = mount_nofollow_verbose(LOG_DEBUG, "rootfs", where, "tmpfs", MS_NODEV, options);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, DissectImageFlags flags) {
         int r, xbootldr_mounted;
 
@@ -1413,16 +1494,20 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift,
          *  -EAFNOSUPPORT → File system type not supported or not known
          */
 
-        if (!m->partitions[PARTITION_ROOT].found)
-                return -ENXIO;
+        if (!(m->partitions[PARTITION_ROOT].found ||
+              (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
+                return -ENXIO; /* Require a root fs or at least a /usr/ fs (the latter is subject to a flag of its own) */
 
         if ((flags & DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY) == 0) {
-                r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, flags);
+
+                /* First mount the root fs. If there's none we use a tmpfs. */
+                if (m->partitions[PARTITION_ROOT].found)
+                        r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, flags);
+                else
+                        r = mount_root_tmpfs(where, uid_shift, flags);
                 if (r < 0)
                         return r;
-        }
 
-        if ((flags & DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY) == 0) {
                 /* For us mounting root always means mounting /usr as well */
                 r = mount_partition(m->partitions + PARTITION_USR, where, "/usr", uid_shift, flags);
                 if (r < 0)
@@ -1992,7 +2077,7 @@ int dissected_image_decrypt_interactively(
 
                 z = strv_free(z);
 
-                r = ask_password_auto("Please enter image passphrase:", NULL, "dissect", "dissect", USEC_INFINITY, 0, &z);
+                r = ask_password_auto("Please enter image passphrase:", NULL, "dissect", "dissect", "dissect.passphrase", USEC_INFINITY, 0, &z);
                 if (r < 0)
                         return log_error_errno(r, "Failed to query for passphrase: %m");
 
@@ -2305,7 +2390,14 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
         if (r == 0) {
                 error_pipe[0] = safe_close(error_pipe[0]);
 
-                r = dissected_image_mount(m, t, UID_INVALID, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_MOUNT_ROOT_ONLY|DISSECT_IMAGE_VALIDATE_OS);
+                r = dissected_image_mount(
+                                m,
+                                t,
+                                UID_INVALID,
+                                DISSECT_IMAGE_READ_ONLY|
+                                DISSECT_IMAGE_MOUNT_ROOT_ONLY|
+                                DISSECT_IMAGE_VALIDATE_OS|
+                                DISSECT_IMAGE_USR_NO_ROOT);
                 if (r < 0) {
                         /* Let parent know the error */
                         (void) write(error_pipe[1], &r, sizeof(r));
@@ -2537,6 +2629,7 @@ int mount_image_privately_interactively(
                 LoopDevice **ret_loop_device,
                 DecryptedImage **ret_decrypted_image) {
 
+        _cleanup_(verity_settings_done) VeritySettings verity = VERITY_SETTINGS_DEFAULT;
         _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
         _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
         _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
@@ -2553,6 +2646,10 @@ int mount_image_privately_interactively(
         assert(ret_loop_device);
         assert(ret_decrypted_image);
 
+        r = verity_settings_load(&verity, image, NULL, NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to load root hash data: %m");
+
         r = tempfn_random_child(NULL, program_invocation_short_name, &temp);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate temporary mount directory: %m");
@@ -2565,11 +2662,11 @@ int mount_image_privately_interactively(
         if (r < 0)
                 return log_error_errno(r, "Failed to set up loopback device: %m");
 
-        r = dissect_image_and_warn(d->fd, image, NULL, NULL, flags, &dissected_image);
+        r = dissect_image_and_warn(d->fd, image, &verity, NULL, flags, &dissected_image);
         if (r < 0)
                 return r;
 
-        r = dissected_image_decrypt_interactively(dissected_image, NULL, NULL, flags, &decrypted_image);
+        r = dissected_image_decrypt_interactively(dissected_image, NULL, &verity, flags, &decrypted_image);
         if (r < 0)
                 return r;
 
index ddadda1c0cdcbb8177d153b34a6466a1621a4389..f07955230bad8d8cdd58742055b2872557885425 100644 (file)
@@ -23,6 +23,7 @@ struct DissectedPartition {
         sd_id128_t uuid;   /* Partition entry UUID as reported by the GPT */
         char *fstype;
         char *node;
+        char *label;
         char *decrypted_node;
         char *decrypted_fstype;
         char *mount_options;
@@ -48,6 +49,23 @@ typedef enum PartitionDesignator {
         _PARTITION_DESIGNATOR_INVALID = -EINVAL,
 } PartitionDesignator;
 
+static inline bool PARTITION_DESIGNATOR_VERSIONED(PartitionDesignator d) {
+        /* Returns true for all designators where we want to support a concept of "versioning", i.e. which
+         * likely contain software binaries (or hashes thereof) that make sense to be versioned as a
+         * whole. We use this check to automatically pick the newest version of these partitions, by version
+         * comparing the partition labels. */
+
+        return IN_SET(d,
+                      PARTITION_ROOT,
+                      PARTITION_ROOT_SECONDARY,
+                      PARTITION_USR,
+                      PARTITION_USR_SECONDARY,
+                      PARTITION_ROOT_VERITY,
+                      PARTITION_ROOT_SECONDARY_VERITY,
+                      PARTITION_USR_VERITY,
+                      PARTITION_USR_SECONDARY_VERITY);
+}
+
 static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
         switch (p) {
 
@@ -77,7 +95,7 @@ typedef enum DissectImageFlags {
                                     DISSECT_IMAGE_DISCARD |
                                     DISSECT_IMAGE_DISCARD_ON_CRYPTO,
         DISSECT_IMAGE_GPT_ONLY            = 1 << 4,  /* Only recognize images with GPT partition tables */
-        DISSECT_IMAGE_REQUIRE_ROOT        = 1 << 5,  /* Don't accept disks without root partition (and if no partition table or only single generic partition, assume it's root) */
+        DISSECT_IMAGE_GENERIC_ROOT        = 1 << 5,  /* If no partition table or only single generic partition, assume it's the root fs */
         DISSECT_IMAGE_MOUNT_ROOT_ONLY     = 1 << 6,  /* Mount only the root and /usr partitions */
         DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY = 1 << 7,  /* Mount only the non-root and non-/usr partitions */
         DISSECT_IMAGE_VALIDATE_OS         = 1 << 8,  /* Refuse mounting images that aren't identifiable as OS images */
@@ -87,6 +105,8 @@ typedef enum DissectImageFlags {
         DISSECT_IMAGE_NO_PARTITION_TABLE  = 1 << 12, /* Only recognize single file system images */
         DISSECT_IMAGE_VERITY_SHARE        = 1 << 13, /* When activating a verity device, reuse existing one if already open */
         DISSECT_IMAGE_MKDIR               = 1 << 14, /* Make top-level directory to mount right before mounting, if missing */
+        DISSECT_IMAGE_USR_NO_ROOT         = 1 << 15, /* If no root fs is in the image, but /usr is, then allow this (so that we can mount the rootfs as tmpfs or so */
+        DISSECT_IMAGE_REQUIRE_ROOT        = 1 << 16, /* Don't accept disks without root partition (or at least /usr partition if DISSECT_IMAGE_USR_NO_ROOT is set) */
 } DissectImageFlags;
 
 struct DissectedImage {
index 05c322d353cae5a2e8e82651f6e27d9663c97145..ecabc5fc4042b8a8e2084bd4ca1778f40ef623d3 100644 (file)
@@ -756,9 +756,11 @@ int fw_nftables_init(FirewallContext *ctx) {
         if (r < 0)
                 return r;
 
-        r = fw_nftables_init_family(nfnl, AF_INET6);
-        if (r < 0)
-                log_debug_errno(r, "Failed to init ipv6 NAT: %m");
+        if (socket_ipv6_is_supported()) {
+                r = fw_nftables_init_family(nfnl, AF_INET6);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to init ipv6 NAT: %m");
+        }
 
         ctx->nfnl = TAKE_PTR(nfnl);
         return 0;
@@ -810,40 +812,6 @@ static int nft_message_add_setelem_iprange(sd_netlink_message *m,
         return 0;
 }
 
-/* When someone runs 'nft flush ruleset' in the same net namespace
- * this will also tear down the systemd nat table.
- *
- * Unlike iptables -t nat -F (which will remove all rules added by the
- * systemd iptables backend, iptables has builtin chains that cannot be
- * deleted -- the next add operation will 'just work'.
- *
- * In the nftables case, everything gets removed. The next add operation
- * will yield -ENOENT.
- *
- * If we see -ENOENT on add, replay the initial table setup.
- * If that works, re-do the add operation.
- *
- * Note that this doesn't protect against external sabotage such as a
- * 'while true; nft flush ruleset;done'. There is nothing that could be
- * done about that short of extending the kernel to allow tables to be
- * owned by stystemd-networkd and making them non-deleteable except by
- * the 'owning process'.
- */
-static int fw_nftables_recreate_table(sd_netlink *nfnl, int af, sd_netlink_message **old, size_t size) {
-        int r = fw_nftables_init_family(nfnl, af);
-
-        if (r != 0)
-                return r;
-
-        while (size > 0) {
-               size_t i = --size;
-
-               old[i] = sd_netlink_message_unref(old[i]);
-        }
-
-        return 0;
-}
-
 static int nft_message_add_setelem_ip6range(
                 sd_netlink_message *m,
                 const union in_addr_union *source,
@@ -877,14 +845,14 @@ static int nft_message_add_setelem_ip6range(
 
 #define NFT_MASQ_MSGS   3
 
-int fw_nftables_add_masquerade(
+static int fw_nftables_add_masquerade_internal(
                 FirewallContext *ctx,
                 bool add,
                 int af,
                 const union in_addr_union *source,
                 unsigned int source_prefixlen) {
+
         sd_netlink_message *transaction[NFT_MASQ_MSGS] = {};
-        bool retry = true;
         size_t tsize;
         int r;
 
@@ -893,7 +861,7 @@ int fw_nftables_add_masquerade(
 
         if (af == AF_INET6 && source_prefixlen < 8)
                 return -EINVAL;
-again:
+
         r = sd_nfnl_message_batch_begin(ctx->nfnl, &transaction[0]);
         if (r < 0)
                 return r;
@@ -902,7 +870,6 @@ again:
                 r = sd_nfnl_nft_message_new_setelems_begin(ctx->nfnl, &transaction[tsize], af, NFT_SYSTEMD_TABLE_NAME, NFT_SYSTEMD_MASQ_SET_NAME);
         else
                 r = sd_nfnl_nft_message_del_setelems_begin(ctx->nfnl, &transaction[tsize], af, NFT_SYSTEMD_TABLE_NAME, NFT_SYSTEMD_MASQ_SET_NAME);
-
         if (r < 0)
                 goto out_unref;
 
@@ -910,7 +877,6 @@ again:
                  r = nft_message_add_setelem_iprange(transaction[tsize], source, source_prefixlen);
         else
                  r = nft_message_add_setelem_ip6range(transaction[tsize], source, source_prefixlen);
-
         if (r < 0)
                 goto out_unref;
 
@@ -919,26 +885,59 @@ again:
         r = sd_nfnl_message_batch_end(ctx->nfnl, &transaction[tsize]);
         if (r < 0)
                 return r;
+
         ++tsize;
         r = nfnl_netlink_sendv(ctx->nfnl, transaction, tsize);
 
-        if (retry && r == -ENOENT) {
-                int tmp = fw_nftables_recreate_table(ctx->nfnl, af, transaction, tsize);
-                if (tmp == 0) {
-                        retry = false;
-                        goto again;
-                }
-        }
-
 out_unref:
         while (tsize > 0)
                 sd_netlink_message_unref(transaction[--tsize]);
         return r < 0 ? r : 0;
 }
 
+int fw_nftables_add_masquerade(
+                FirewallContext *ctx,
+                bool add,
+                int af,
+                const union in_addr_union *source,
+                unsigned int source_prefixlen) {
+
+        int r;
+
+        if (!socket_ipv6_is_supported() && af == AF_INET6)
+                return -EOPNOTSUPP;
+
+        r = fw_nftables_add_masquerade_internal(ctx, add, af, source, source_prefixlen);
+        if (r != -ENOENT)
+                return r;
+
+        /* When someone runs 'nft flush ruleset' in the same net namespace this will also tear down the
+         * systemd nat table.
+         *
+         * Unlike iptables -t nat -F (which will remove all rules added by the systemd iptables
+         * backend, iptables has builtin chains that cannot be deleted -- the next add operation will
+         * 'just work'.
+         *
+         * In the nftables case, everything gets removed. The next add operation will yield -ENOENT.
+         *
+         * If we see -ENOENT on add, replay the initial table setup. If that works, re-do the add
+         * operation.
+         *
+         * Note that this doesn't protect against external sabotage such as a
+         * 'while true; nft flush ruleset; done'. There is nothing that could be done about that short
+         * of extending the kernel to allow tables to be owned by stystemd-networkd and making them
+         * non-deleteable except by the 'owning process'. */
+
+        r = fw_nftables_init_family(ctx->nfnl, af);
+        if (r < 0)
+                return r;
+
+        return fw_nftables_add_masquerade_internal(ctx, add, af, source, source_prefixlen);
+}
+
 #define NFT_DNAT_MSGS   4
 
-int fw_nftables_add_local_dnat(
+static int fw_nftables_add_local_dnat_internal(
                 FirewallContext *ctx,
                 bool add,
                 int af,
@@ -947,21 +946,24 @@ int fw_nftables_add_local_dnat(
                 const union in_addr_union *remote,
                 uint16_t remote_port,
                 const union in_addr_union *previous_remote) {
-        uint32_t data[5], key[2], dlen;
+
         sd_netlink_message *transaction[NFT_DNAT_MSGS] = {};
-        bool retry = true;
+        static bool ipv6_supported = true;
+        uint32_t data[5], key[2], dlen;
         size_t tsize;
         int r;
 
         assert(add || !previous_remote);
 
+        if (!ipv6_supported && af == AF_INET6)
+                return -EOPNOTSUPP;
+
         if (!IN_SET(protocol, IPPROTO_TCP, IPPROTO_UDP))
                 return -EPROTONOSUPPORT;
 
         if (local_port <= 0)
                 return -EINVAL;
 
-again:
         key[0] = protocol;
         key[1] = htobe16(local_port);
 
@@ -1006,9 +1008,11 @@ again:
 
         assert(tsize < NFT_DNAT_MSGS);
         if (add)
-                nft_add_element(ctx->nfnl, &transaction[tsize], af, NFT_SYSTEMD_DNAT_MAP_NAME, key, sizeof(key), data, dlen);
+                r = nft_add_element(ctx->nfnl, &transaction[tsize], af, NFT_SYSTEMD_DNAT_MAP_NAME, key, sizeof(key), data, dlen);
         else
-                nft_del_element(ctx->nfnl, &transaction[tsize], af, NFT_SYSTEMD_DNAT_MAP_NAME, key, sizeof(key), data, dlen);
+                r = nft_del_element(ctx->nfnl, &transaction[tsize], af, NFT_SYSTEMD_DNAT_MAP_NAME, key, sizeof(key), data, dlen);
+        if (r < 0)
+                goto out_unref;
 
         tsize++;
         assert(tsize < NFT_DNAT_MSGS);
@@ -1019,21 +1023,48 @@ again:
 
         tsize++;
         assert(tsize <= NFT_DNAT_MSGS);
-        r = nfnl_netlink_sendv(ctx->nfnl, transaction, tsize);
-
-        if (retry && r == -ENOENT) {
-                int tmp = fw_nftables_recreate_table(ctx->nfnl, af, transaction, tsize);
 
-                if (tmp == 0) {
-                        /* table created anew; previous address already gone */
-                        previous_remote = NULL;
-                        retry = false;
-                        goto again;
-                }
+        r = nfnl_netlink_sendv(ctx->nfnl, transaction, tsize);
+        if (r == -EOVERFLOW && af == AF_INET6) {
+                /* The current implementation of DNAT in systemd requires kernel's
+                 * fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 (v5.8), and the older kernel returns
+                 * -EOVERFLOW. Let's treat the error as -EOPNOTSUPP. */
+                log_debug_errno(r, "The current implementation of IPv6 DNAT in systemd requires kernel 5.8 or newer, ignoring: %m");
+                ipv6_supported = false;
+                r = -EOPNOTSUPP;
         }
 
 out_unref:
         while (tsize > 0)
                 sd_netlink_message_unref(transaction[--tsize]);
+
         return r < 0 ? r : 0;
 }
+
+int fw_nftables_add_local_dnat(
+                FirewallContext *ctx,
+                bool add,
+                int af,
+                int protocol,
+                uint16_t local_port,
+                const union in_addr_union *remote,
+                uint16_t remote_port,
+                const union in_addr_union *previous_remote) {
+
+        int r;
+
+        if (!socket_ipv6_is_supported() && af == AF_INET6)
+                return -EOPNOTSUPP;
+
+        r = fw_nftables_add_local_dnat_internal(ctx, add, af, protocol, local_port, remote, remote_port, previous_remote);
+        if (r != -ENOENT)
+                return r;
+
+        /* See comment in fw_nftables_add_masquerade(). */
+        r = fw_nftables_init_family(ctx->nfnl, af);
+        if (r < 0)
+                return r;
+
+        /* table created anew; previous address already gone */
+        return fw_nftables_add_local_dnat_internal(ctx, add, af, protocol, local_port, remote, remote_port, NULL);
+}
index 59e1e502fda05697cbbe18b096c05f67405ff840..07e2d0bbd3dc35db035eaf22afd3b393bf6f56f3 100644 (file)
@@ -4,22 +4,27 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-#include "in-addr-util.h"
 #include "sd-netlink.h"
 
-enum FirewallBackend {
+#include "in-addr-util.h"
+
+typedef enum FirewallBackend {
         FW_BACKEND_NONE,
 #if HAVE_LIBIPTC
         FW_BACKEND_IPTABLES,
 #endif
         FW_BACKEND_NFTABLES,
-};
+        _FW_BACKEND_MAX,
+        _FW_BACKEND_INVALID = -EINVAL,
+} FirewallBackend;
 
 struct FirewallContext {
-        enum FirewallBackend firewall_backend;
+        FirewallBackend backend;
         sd_netlink *nfnl;
 };
 
+const char *firewall_backend_to_string(FirewallBackend b) _const_;
+
 int fw_nftables_init(FirewallContext *ctx);
 void fw_nftables_exit(FirewallContext *ctx);
 
index 3bed941127fcbdf7cdb3641b8439b94982814419..afa3e02b45463dfac980975f2642c10fab06d5be 100644 (file)
@@ -7,31 +7,53 @@
 #include "alloc-util.h"
 #include "firewall-util.h"
 #include "firewall-util-private.h"
+#include "log.h"
+#include "string-table.h"
 
-static enum FirewallBackend firewall_backend_probe(FirewallContext *ctx) {
-        if (fw_nftables_init(ctx) == 0)
-               return FW_BACKEND_NFTABLES;
+static const char * const firewall_backend_table[_FW_BACKEND_MAX] = {
+        [FW_BACKEND_NONE] = "none",
 #if HAVE_LIBIPTC
-        return FW_BACKEND_IPTABLES;
+        [FW_BACKEND_IPTABLES] = "iptables",
+#endif
+        [FW_BACKEND_NFTABLES] = "nftables",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(firewall_backend, FirewallBackend);
+
+static void firewall_backend_probe(FirewallContext *ctx) {
+        assert(ctx);
+
+        if (ctx->backend != _FW_BACKEND_INVALID)
+                return;
+
+        if (fw_nftables_init(ctx) >= 0)
+                ctx->backend = FW_BACKEND_NFTABLES;
+        else
+#if HAVE_LIBIPTC
+                ctx->backend = FW_BACKEND_IPTABLES;
 #else
-        return FW_BACKEND_NONE;
+                ctx->backend = FW_BACKEND_NONE;
 #endif
+
+        if (ctx->backend != FW_BACKEND_NONE)
+                log_debug("Using %s as firewall backend.", firewall_backend_to_string(ctx->backend));
+        else
+                log_debug("No firewall backend found.");
 }
 
 int fw_ctx_new(FirewallContext **ret) {
         _cleanup_free_ FirewallContext *ctx = NULL;
 
-        ctx = new0(FirewallContext, 1);
+        ctx = new(FirewallContext, 1);
         if (!ctx)
                 return -ENOMEM;
 
-        /* could probe here.  However, this means that we will load
-         * iptable_nat or nf_tables, both will enable connection tracking.
-         *
-         * Alternative would be to probe here but only call
-         * fw_ctx_new when nspawn/networkd know they will call
-         * fw_add_masquerade/local_dnat later anyway.
-         */
+        *ctx = (FirewallContext) {
+                .backend = _FW_BACKEND_INVALID,
+        };
+
+        firewall_backend_probe(ctx);
+
         *ret = TAKE_PTR(ctx);
         return 0;
 }
@@ -40,47 +62,42 @@ FirewallContext *fw_ctx_free(FirewallContext *ctx) {
         if (!ctx)
                 return NULL;
 
-        if (ctx->firewall_backend == FW_BACKEND_NFTABLES)
-                fw_nftables_exit(ctx);
+        fw_nftables_exit(ctx);
 
         return mfree(ctx);
 }
 
 int fw_add_masquerade(
-                FirewallContext **fw_ctx,
+                FirewallContext **ctx,
                 bool add,
                 int af,
                 const union in_addr_union *source,
                 unsigned source_prefixlen) {
-        FirewallContext *ctx;
+
         int r;
 
-        if (!*fw_ctx) {
-                r = fw_ctx_new(fw_ctx);
+        assert(ctx);
+
+        if (!*ctx) {
+                r = fw_ctx_new(ctx);
                 if (r < 0)
                         return r;
         }
 
-        ctx = *fw_ctx;
-        if (ctx->firewall_backend == FW_BACKEND_NONE)
-                ctx->firewall_backend = firewall_backend_probe(ctx);
-
-        switch (ctx->firewall_backend) {
-        case FW_BACKEND_NONE:
-                return -EOPNOTSUPP;
+        switch ((*ctx)->backend) {
 #if HAVE_LIBIPTC
         case FW_BACKEND_IPTABLES:
                 return fw_iptables_add_masquerade(add, af, source, source_prefixlen);
 #endif
         case FW_BACKEND_NFTABLES:
-                return fw_nftables_add_masquerade(ctx, add, af, source, source_prefixlen);
+                return fw_nftables_add_masquerade(*ctx, add, af, source, source_prefixlen);
+        default:
+                return -EOPNOTSUPP;
         }
-
-        return -EOPNOTSUPP;
 }
 
 int fw_add_local_dnat(
-                FirewallContext **fw_ctx,
+                FirewallContext **ctx,
                 bool add,
                 int af,
                 int protocol,
@@ -88,28 +105,25 @@ int fw_add_local_dnat(
                 const union in_addr_union *remote,
                 uint16_t remote_port,
                 const union in_addr_union *previous_remote) {
-        FirewallContext *ctx;
 
-        if (!*fw_ctx) {
-                int ret = fw_ctx_new(fw_ctx);
-                if (ret < 0)
-                        return ret;
-        }
+        int r;
 
-        ctx = *fw_ctx;
-        if (ctx->firewall_backend == FW_BACKEND_NONE)
-                ctx->firewall_backend = firewall_backend_probe(ctx);
+        assert(ctx);
 
-        switch (ctx->firewall_backend) {
-        case FW_BACKEND_NONE:
-                return -EOPNOTSUPP;
-        case FW_BACKEND_NFTABLES:
-                return fw_nftables_add_local_dnat(ctx, add, af, protocol, local_port, remote, remote_port, previous_remote);
+        if (!*ctx) {
+                r = fw_ctx_new(ctx);
+                if (r < 0)
+                        return r;
+        }
+
+        switch ((*ctx)->backend) {
 #if HAVE_LIBIPTC
         case FW_BACKEND_IPTABLES:
                 return fw_iptables_add_local_dnat(add, af, protocol, local_port, remote, remote_port, previous_remote);
 #endif
+        case FW_BACKEND_NFTABLES:
+                return fw_nftables_add_local_dnat(*ctx, add, af, protocol, local_port, remote, remote_port, previous_remote);
+        default:
+                return -EOPNOTSUPP;
         }
-
-        return -EOPNOTSUPP;
 }
index 5180b429d3d7356ee246448fdbc53cc9a59f748d..7725a5e58dfd31a20ae5de8dc7fee653ab969be3 100644 (file)
@@ -9,19 +9,19 @@
 typedef struct FirewallContext FirewallContext;
 
 int fw_ctx_new(FirewallContext **ret);
-FirewallContext *fw_ctx_free(FirewallContext *fw_ctx);
+FirewallContext *fw_ctx_free(FirewallContext *ctx);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(FirewallContext *, fw_ctx_free);
 
 int fw_add_masquerade(
-                FirewallContext **fw_ctx,
+                FirewallContext **ctx,
                 bool add,
                 int af,
                 const union in_addr_union *source,
                 unsigned source_prefixlen);
 
 int fw_add_local_dnat(
-                FirewallContext **fw_ctx,
+                FirewallContext **ctx,
                 bool add,
                 int af,
                 int protocol,
index 22b8aba07e5028a30d372272b339ee61cb0acdbf..951ed09899c5dce36e0b68fc18dd7daa52724469 100644 (file)
@@ -566,7 +566,7 @@ int fido2_generate_hmac_hash(
                         if (!has_client_pin)
                                 log_warning("Weird, device asked for client PIN, but does not advertise it as feature. Ignoring.");
 
-                        r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", USEC_INFINITY, 0, &pin);
+                        r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", "fido2-pin", USEC_INFINITY, 0, &pin);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to acquire user PIN: %m");
 
index 2c860f76d5d164eb4eddf59a004cda4830bed1e9..1de890f1421fe5416bcd2135e8ab8ebbee3d5ed4 100644 (file)
@@ -204,7 +204,7 @@ int local_gateways(sd_netlink *context, int ifindex, int af, struct local_addres
                 union in_addr_union gateway;
                 uint16_t type;
                 unsigned char dst_len, src_len, table;
-                uint32_t ifi, metric = 0;
+                uint32_t ifi = 0, metric = 0;
                 size_t rta_len;
                 int family;
                 RouteVia via;
index 7c61c334e9008b5dd1914fd0189be84aa087a3ed..706a00c7f0612d6e087f265e965c2d2908a3aceb 100644 (file)
@@ -1396,7 +1396,7 @@ int show_journal(
                         bool noaccess = journal_access_blocked(j);
 
                         if (line == 0 && noaccess)
-                                fprintf(f, "Warning: some journal files were not opened due to insufficient permissions.");
+                                fprintf(f, "Warning: some journal files were not opened due to insufficient permissions.\n");
                         else if (!noaccess)
                                 fprintf(f, "Notice: journal has been rotated since unit was started, output may be incomplete.\n");
                         else
index 576e4054c2944d2e1179761f19d78655e7b46a14..13f202d7e7dfb241fb2eda925b9d2ecc7d289c1c 100644 (file)
@@ -84,9 +84,8 @@ int umount_recursive(const char *prefix, int flags) {
         int n = 0, r;
         bool again;
 
-        /* Try to umount everything recursively below a
-         * directory. Also, take care of stacked mounts, and keep
-         * unmounting them until they are gone. */
+        /* Try to umount everything recursively below a directory. Also, take care of stacked mounts, and
+         * keep unmounting them until they are gone. */
 
         do {
                 _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
@@ -132,68 +131,6 @@ int umount_recursive(const char *prefix, int flags) {
         return n;
 }
 
-static int get_mount_flags(
-                struct libmnt_table *table,
-                const char *path,
-                unsigned long *ret) {
-
-        _cleanup_close_ int fd = -1;
-        struct libmnt_fs *fs;
-        struct statvfs buf;
-        const char *opts;
-        int r;
-
-        /* Get the mount flags for the mountpoint at "path" from "table". We have a fallback using statvfs()
-         * in place (which provides us with mostly the same info), but it's just a fallback, since using it
-         * means triggering autofs or NFS mounts, which we'd rather avoid needlessly.
-         *
-         * This generally doesn't follow symlinks. */
-
-        fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD);
-        if (!fs) {
-                log_debug("Could not find '%s' in mount table, ignoring.", path);
-                goto fallback;
-        }
-
-        opts = mnt_fs_get_vfs_options(fs);
-        if (!opts) {
-                *ret = 0;
-                return 0;
-        }
-
-        r = mnt_optstr_get_flags(opts, ret, mnt_get_builtin_optmap(MNT_LINUX_MAP));
-        if (r != 0) {
-                log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
-                goto fallback;
-        }
-
-        /* MS_RELATIME is default and trying to set it in an unprivileged container causes EPERM */
-        *ret &= ~MS_RELATIME;
-        return 0;
-
-fallback:
-        fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW);
-        if (fd < 0)
-                return -errno;
-
-        if (fstatvfs(fd, &buf) < 0)
-                return -errno;
-
-        /* The statvfs() flags and the mount flags mostly have the same values, but for some cases do
-         * not. Hence map the flags manually. (Strictly speaking, ST_RELATIME/MS_RELATIME is the most
-         * prominent one that doesn't match, but that's the one we mask away anyway, see above.) */
-
-        *ret =
-                FLAGS_SET(buf.f_flag, ST_RDONLY) * MS_RDONLY |
-                FLAGS_SET(buf.f_flag, ST_NODEV) * MS_NODEV |
-                FLAGS_SET(buf.f_flag, ST_NOEXEC) * MS_NOEXEC |
-                FLAGS_SET(buf.f_flag, ST_NOSUID) * MS_NOSUID |
-                FLAGS_SET(buf.f_flag, ST_NOATIME) * MS_NOATIME |
-                FLAGS_SET(buf.f_flag, ST_NODIRATIME) * MS_NODIRATIME;
-
-        return 0;
-}
-
 /* Use this function only if you do not have direct access to /proc/self/mountinfo but the caller can open it
  * for you. This is the case when /proc is masked or not mounted. Otherwise, use bind_remount_recursive. */
 int bind_remount_recursive_with_mountinfo(
@@ -203,8 +140,8 @@ int bind_remount_recursive_with_mountinfo(
                 char **deny_list,
                 FILE *proc_self_mountinfo) {
 
-        _cleanup_set_free_free_ Set *done = NULL;
-        _cleanup_free_ char *simplified = NULL;
+        _cleanup_set_free_ Set *done = NULL;
+        unsigned n_tries = 0;
         int r;
 
         assert(prefix);
@@ -217,32 +154,21 @@ int bind_remount_recursive_with_mountinfo(
          * access, too. When mounts are stacked on the same mount point we only care for each individual
          * "top-level" mount on each point, as we cannot influence/access the underlying mounts anyway. We do
          * not have any effect on future submounts that might get propagated, they might be writable
-         * etc. This includes future submounts that have been triggered via autofs.
+         * etc. This includes future submounts that have been triggered via autofs. Also note that we can't
+         * operate atomically here. Mounts established while we process the tree might or might not get
+         * noticed and thus might or might not be covered.
          *
          * If the "deny_list" parameter is specified it may contain a list of subtrees to exclude from the
          * remount operation. Note that we'll ignore the deny list for the top-level path. */
 
-        simplified = strdup(prefix);
-        if (!simplified)
-                return -ENOMEM;
-
-        path_simplify(simplified, false);
-
-        done = set_new(&path_hash_ops);
-        if (!done)
-                return -ENOMEM;
-
         for (;;) {
-                _cleanup_set_free_free_ Set *todo = NULL;
                 _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
                 _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
+                _cleanup_hashmap_free_ Hashmap *todo = NULL;
                 bool top_autofs = false;
-                char *x;
-                unsigned long orig_flags;
 
-                todo = set_new(&path_hash_ops);
-                if (!todo)
-                        return -ENOMEM;
+                if (n_tries++ >= 32) /* Let's not retry this loop forever */
+                        return -EBUSY;
 
                 rewind(proc_self_mountinfo);
 
@@ -251,130 +177,159 @@ int bind_remount_recursive_with_mountinfo(
                         return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
                 for (;;) {
+                        _cleanup_free_ char *d = NULL;
+                        const char *path, *type, *opts;
+                        unsigned long flags = 0;
                         struct libmnt_fs *fs;
-                        const char *path, *type;
 
                         r = mnt_table_next_fs(table, iter, &fs);
-                        if (r == 1)
+                        if (r == 1) /* EOF */
                                 break;
                         if (r < 0)
                                 return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
 
                         path = mnt_fs_get_target(fs);
+                        if (!path)
+                                continue;
+
+                        if (!path_startswith(path, prefix))
+                                continue;
+
                         type = mnt_fs_get_fstype(fs);
-                        if (!path || !type)
+                        if (!type)
+                                continue;
+
+                        /* Let's ignore autofs mounts. If they aren't triggered yet, we want to avoid
+                         * triggering them, as we don't make any guarantees for future submounts anyway. If
+                         * they are already triggered, then we will find another entry for this. */
+                        if (streq(type, "autofs")) {
+                                top_autofs = top_autofs || path_equal(path, prefix);
                                 continue;
+                        }
 
-                        if (!path_startswith(path, simplified))
+                        if (set_contains(done, path))
                                 continue;
 
                         /* Ignore this mount if it is deny-listed, but only if it isn't the top-level mount
                          * we shall operate on. */
-                        if (!path_equal(path, simplified)) {
+                        if (!path_equal(path, prefix)) {
                                 bool deny_listed = false;
                                 char **i;
 
                                 STRV_FOREACH(i, deny_list) {
-                                        if (path_equal(*i, simplified))
+                                        if (path_equal(*i, prefix))
                                                 continue;
 
-                                        if (!path_startswith(*i, simplified))
+                                        if (!path_startswith(*i, prefix))
                                                 continue;
 
                                         if (path_startswith(path, *i)) {
                                                 deny_listed = true;
-                                                log_debug("Not remounting %s deny-listed by %s, called for %s",
-                                                          path, *i, simplified);
+                                                log_debug("Not remounting %s deny-listed by %s, called for %s", path, *i, prefix);
                                                 break;
                                         }
                                 }
+
                                 if (deny_listed)
                                         continue;
                         }
 
-                        /* Let's ignore autofs mounts.  If they aren't
-                         * triggered yet, we want to avoid triggering
-                         * them, as we don't make any guarantees for
-                         * future submounts anyway.  If they are
-                         * already triggered, then we will find
-                         * another entry for this. */
-                        if (streq(type, "autofs")) {
-                                top_autofs = top_autofs || path_equal(path, simplified);
-                                continue;
-                        }
-
-                        if (!set_contains(done, path)) {
-                                r = set_put_strdup(&todo, path);
+                        opts = mnt_fs_get_vfs_options(fs);
+                        if (opts) {
+                                r = mnt_optstr_get_flags(opts, &flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
                                 if (r < 0)
-                                        return r;
+                                        log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
                         }
-                }
 
-                /* If we have no submounts to process anymore and if
-                 * the root is either already done, or an autofs, we
-                 * are done */
-                if (set_isempty(todo) &&
-                    (top_autofs || set_contains(done, simplified)))
-                        return 0;
+                        d = strdup(path);
+                        if (!d)
+                                return -ENOMEM;
 
-                if (!set_contains(done, simplified) &&
-                    !set_contains(todo, simplified)) {
-                        /* The prefix directory itself is not yet a mount, make it one. */
-                        r = mount_nofollow(simplified, simplified, NULL, MS_BIND|MS_REC, NULL);
+                        r = hashmap_ensure_put(&todo, &path_hash_ops_free, d, ULONG_TO_PTR(flags));
+                        if (r == -EEXIST)
+                                continue;
                         if (r < 0)
                                 return r;
+                        if (r > 0)
+                                TAKE_PTR(d);
+                }
 
-                        orig_flags = 0;
-                        (void) get_mount_flags(table, simplified, &orig_flags);
+                /* Check if the top-level directory was among what we have seen so far. For that check both
+                 * 'done' and 'todo'. Also check 'top_autofs' because if the top-level dir is an autofs we'll
+                 * not include it in either set but will set this bool. */
+                if (!set_contains(done, prefix) &&
+                    !(top_autofs || hashmap_contains(todo, prefix))) {
 
-                        r = mount_nofollow(NULL, simplified, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL);
+                        /* The prefix directory itself is not yet a mount, make it one. */
+                        r = mount_nofollow(prefix, prefix, NULL, MS_BIND|MS_REC, NULL);
                         if (r < 0)
                                 return r;
 
-                        log_debug("Made top-level directory %s a mount point.", prefix);
-
-                        r = set_put_strdup(&done, simplified);
-                        if (r < 0)
-                                return r;
+                        /* Immediately rescan, so that we pick up the new mount's flags */
+                        continue;
                 }
 
-                while ((x = set_steal_first(todo))) {
+                /* If we have no submounts to process anymore, we are done */
+                if (hashmap_isempty(todo))
+                        return 0;
+
+                for (;;) {
+                        unsigned long flags;
+                        char *x = NULL;
+
+                        /* Take the first mount from our list of mounts to still process */
+                        flags = PTR_TO_ULONG(hashmap_steal_first_key_and_value(todo, (void**) &x));
+                        if (!x)
+                                break;
 
-                        r = set_consume(done, x);
+                        r = set_ensure_consume(&done, &path_hash_ops_free, x);
                         if (IN_SET(r, 0, -EEXIST))
-                                continue;
+                                continue; /* Already done */
                         if (r < 0)
                                 return r;
 
-                        /* Deal with mount points that are obstructed by a later mount */
-                        r = path_is_mount_point(x, NULL, 0);
-                        if (IN_SET(r, 0, -ENOENT))
-                                continue;
+                        /* Now, remount this with the new flags set, but exclude MS_RELATIME from it. (It's
+                         * the default anyway, thus redundant, and in userns we'll get an error if we try to
+                         * explicitly enable it) */
+                        r = mount_nofollow(NULL, x, NULL, ((flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags) & ~MS_RELATIME, NULL);
                         if (r < 0) {
-                                if (!ERRNO_IS_PRIVILEGE(r))
+                                int q;
+
+                                /* OK, so the remount of this entry failed. We'll ultimately ignore this in
+                                 * almost all cases (there are simply so many reasons why this can fail,
+                                 * think autofs, NFS, FUSE, …), but let's generate useful debug messages at
+                                 * the very least. */
+
+                                q = path_is_mount_point(x, NULL, 0);
+                                if (IN_SET(q, 0, -ENOENT)) {
+                                        /* Hmm, whaaaa? The mount point is not actually a mount point? Then
+                                         * it is either obstructed by a later mount or somebody has been
+                                         * racing against us and removed it. Either way the mount point
+                                         * doesn't matter to us, let's ignore it hence. */
+                                        log_debug_errno(r, "Mount point '%s' to remount is not a mount point anymore, ignoring remount failure: %m", x);
+                                        continue;
+                                }
+                                if (q < 0) /* Any other error on this? Just log and continue */
+                                        log_debug_errno(q, "Failed to determine whether '%s' is a mount point or not, ignoring: %m", x);
+
+                                if (((flags ^ new_flags) & flags_mask & ~MS_RELATIME) == 0) { /* ignore MS_RELATIME while comparing */
+                                        log_debug_errno(r, "Couldn't remount '%s', but the flags already match what we want, hence ignoring: %m", x);
+                                        continue;
+                                }
+
+                                /* Make this fatal if this is the top-level mount */
+                                if (path_equal(x, prefix))
                                         return r;
 
-                                /* Even if root user invoke this, submounts under private FUSE or NFS mount points
-                                 * may not be acceessed. E.g.,
-                                 *
-                                 * $ bindfs --no-allow-other ~/mnt/mnt ~/mnt/mnt
-                                 * $ bindfs --no-allow-other ~/mnt ~/mnt
-                                 *
-                                 * Then, root user cannot access the mount point ~/mnt/mnt.
-                                 * In such cases, the submounts are ignored, as we have no way to manage them. */
-                                log_debug_errno(r, "Failed to determine '%s' is mount point or not, ignoring: %m", x);
+                                /* If this is not the top-level mount, then handle this gracefully: log but
+                                 * otherwise ignore. With NFS, FUSE, autofs there are just too many reasons
+                                 * this might fail without a chance for us to do anything about it, let's
+                                 * hence be strict on the top-level mount and lenient on the inner ones. */
+                                log_debug_errno(r, "Couldn't remount submount '%s' for unexpected reason, ignoring: %m", x);
                                 continue;
                         }
 
-                        /* Try to reuse the original flag set */
-                        orig_flags = 0;
-                        (void) get_mount_flags(table, x, &orig_flags);
-
-                        r = mount_nofollow(NULL, x, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL);
-                        if (r < 0)
-                                return r;
-
-                        log_debug("Remounted %s read-only.", x);
+                        log_debug("Remounted %s.", x);
                 }
         }
 }
@@ -402,7 +357,9 @@ int bind_remount_one_with_mountinfo(
                 FILE *proc_self_mountinfo) {
 
         _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
-        unsigned long orig_flags = 0;
+        unsigned long flags = 0;
+        struct libmnt_fs *fs;
+        const char *opts;
         int r;
 
         assert(path);
@@ -418,12 +375,32 @@ int bind_remount_one_with_mountinfo(
         if (r < 0)
                 return r;
 
-        /* Try to reuse the original flag set */
-        (void) get_mount_flags(table, path, &orig_flags);
+        fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD);
+        if (!fs) {
+                if (laccess(path, F_OK) < 0) /* Hmm, it's not in the mount table, but does it exist at all? */
+                        return -errno;
+
+                return -EINVAL; /* Not a mount point we recognize */
+        }
 
-        r = mount_nofollow(NULL, path, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL);
-        if (r < 0)
-                return r;
+        opts = mnt_fs_get_vfs_options(fs);
+        if (opts) {
+                r = mnt_optstr_get_flags(opts, &flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
+                if (r < 0)
+                        log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
+        }
+
+        r = mount_nofollow(NULL, path, NULL, ((flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags) & ~MS_RELATIME, NULL);
+        if (r < 0) {
+                if (((flags ^ new_flags) & flags_mask & ~MS_RELATIME) != 0) /* Ignore MS_RELATIME again,
+                                                                             * since kernel adds it in
+                                                                             * everywhere, because it's the
+                                                                             * default. */
+                        return r;
+
+                /* Let's handle redundant remounts gracefully */
+                log_debug_errno(r, "Failed to remount '%s' but flags already match what we want, ignoring: %m", path);
+        }
 
         return 0;
 }
index 27c209cdf8ab6f9afe86f9a8b311da9bdaf5a733..4fa1effb2d3be3878ce56f9fde225757596b1a75 100644 (file)
@@ -181,7 +181,8 @@ int pkcs11_token_login(
                 const CK_TOKEN_INFO *token_info,
                 const char *friendly_name,
                 const char *icon_name,
-                const char *keyname,
+                const char *key_name,
+                const char *credential_name,
                 usec_t until,
                 char **ret_used_pin) {
 
@@ -269,7 +270,7 @@ int pkcs11_token_login(
                                 return log_oom();
 
                         /* We never cache PINs, simply because it's fatal if we use wrong PINs, since usually there are only 3 tries */
-                        r = ask_password_auto(text, icon_name, id, keyname, until, 0, &passwords);
+                        r = ask_password_auto(text, icon_name, id, key_name, credential_name, until, 0, &passwords);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to query PIN for security token '%s': %m", token_label);
                 }
@@ -959,7 +960,7 @@ static int pkcs11_acquire_certificate_callback(
 
         /* Called for every token matching our URI */
 
-        r = pkcs11_token_login(m, session, slot_id, token_info, data->askpw_friendly_name, data->askpw_icon_name, "pkcs11-pin", UINT64_MAX, &pin_used);
+        r = pkcs11_token_login(m, session, slot_id, token_info, data->askpw_friendly_name, data->askpw_icon_name, "pkcs11-pin", "pkcs11-pin", UINT64_MAX, &pin_used);
         if (r < 0)
                 return r;
 
index f32ab304299e458a470825ea5a22639217458cfa..c2c852f0ebe356b8fe965bdf2f3141d80325faba 100644 (file)
@@ -30,7 +30,7 @@ char *pkcs11_token_label(const CK_TOKEN_INFO *token_info);
 char *pkcs11_token_manufacturer_id(const CK_TOKEN_INFO *token_info);
 char *pkcs11_token_model(const CK_TOKEN_INFO *token_info);
 
-int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *keyname, usec_t until, char **ret_used_pin);
+int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *key_name, const char *credential_name, usec_t until, char **ret_used_pin);
 
 int pkcs11_token_find_x509_certificate(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, P11KitUri *search_uri, CK_OBJECT_HANDLE *ret_object);
 #if HAVE_OPENSSL
index 0d07865542e0f04759b7be6be1fb31212a0d5491..29b24906a6fb52452255b78dcd33c771f929fa00 100644 (file)
@@ -322,6 +322,9 @@ int main(int argc, char *argv[]) {
         log_set_prohibit_ipc(true);
         log_parse_environment();
 
+        if (getpid_cached() == 1)
+                log_set_always_reopen_console(true);
+
         r = parse_argv(argc, argv);
         if (r < 0)
                 goto error;
@@ -487,7 +490,7 @@ int main(int argc, char *argv[]) {
                         /* There are things we cannot get rid of. Loop one more time
                          * with LOG_ERR to inform the user. Note that we don't need
                          * to do this if there is a initrd to switch to, because that
-                         * one is likely to get rid of the remounting mounts. If not,
+                         * one is likely to get rid of the remaining mounts. If not,
                          * it will log about them. */
                         umount_log_level = LOG_ERR;
                         continue;
@@ -556,8 +559,10 @@ int main(int argc, char *argv[]) {
                 sync_with_progress();
 
         if (streq(arg_verb, "exit")) {
-                if (in_container)
+                if (in_container) {
+                        log_info("Exiting container.");
                         return arg_exit_code;
+                }
 
                 cmd = RB_POWER_OFF; /* We cannot exit() on the host, fallback on another method. */
         }
index 9b1c4908a40c189e246b0d0a6f7bb6bd7727aa8b..49ec23d93430637033a3b915eb2d8b028a8d7bd4 100644 (file)
@@ -509,7 +509,12 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
                         _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
                         _cleanup_(decrypted_image_unrefp) DecryptedImage *di = NULL;
                         _cleanup_(verity_settings_done) VeritySettings verity_settings = VERITY_SETTINGS_DEFAULT;
-                        DissectImageFlags flags = DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_MOUNT_ROOT_ONLY;
+                        DissectImageFlags flags =
+                                DISSECT_IMAGE_READ_ONLY |
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_MOUNT_ROOT_ONLY |
+                                DISSECT_IMAGE_USR_NO_ROOT;
 
                         r = verity_settings_load(&verity_settings, img->path, NULL, NULL);
                         if (r < 0)
index 4186ec3aea76cd7822d2754c1a07c0d87344b9a5..314962ac69fb87af3e60d625c13407f4dae5408a 100644 (file)
@@ -146,7 +146,6 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
                 _cleanup_free_ char *new_contents = NULL;
                 _cleanup_fclose_ FILE *f = NULL;
                 char **path;
-                size_t size;
 
                 r = mac_selinux_create_file_prepare(new_path, S_IFREG);
                 if (r < 0)
@@ -161,7 +160,7 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
                 if (r < 0)
                         return log_error_errno(errno, "Failed to change mode of \"%s\": %m", t);
 
-                r = read_full_file(new_path, &new_contents, &size);
+                r = read_full_file(new_path, &new_contents, NULL);
                 if (r < 0 && r != -ENOENT)
                         return log_error_errno(r, "Failed to read \"%s\": %m", new_path);
 
@@ -182,16 +181,18 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
                         if (path_equal(*path, new_path))
                                 continue;
 
-                        r = read_full_file(*path, &contents, &size);
+                        r = read_full_file(*path, &contents, NULL);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to read \"%s\": %m", *path);
 
                         fprintf(f, "\n\n### %s", *path);
                         if (!isempty(contents)) {
-                                contents = strreplace(strstrip(contents), "\n", "\n# ");
-                                if (!contents)
+                                _cleanup_free_ char *commented_contents = NULL;
+
+                                commented_contents = strreplace(strstrip(contents), "\n", "\n# ");
+                                if (!commented_contents)
                                         return log_oom();
-                                fprintf(f, "\n# %s", contents);
+                                fprintf(f, "\n# %s", commented_contents);
                         }
                 }
 
@@ -468,10 +469,12 @@ static int trim_edit_markers(const char *path) {
         int r;
 
         /* Trim out the lines between the two markers */
-        r = read_full_file(path, &contents, &size);
+        r = read_full_file(path, &contents, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to read temporary file \"%s\": %m", path);
 
+        size = strlen(contents);
+
         contents_start = strstr(contents, EDIT_MARKER_START);
         if (contents_start)
                 contents_start += strlen(EDIT_MARKER_START);
index 822286919ea9c29657801c62f45062c279da1e29..c784cbcb9acb7ce5541e6605c8da18aafd5a9805 100644 (file)
@@ -125,6 +125,10 @@ int sd_dhcp_client_set_request_broadcast(
 int sd_dhcp_client_set_ifindex(
                 sd_dhcp_client *client,
                 int interface_index);
+int sd_dhcp_client_set_ifname(
+                sd_dhcp_client *client,
+                const char *interface_name);
+const char *sd_dhcp_client_get_ifname(sd_dhcp_client *client);
 int sd_dhcp_client_set_mac(
                 sd_dhcp_client *client,
                 const uint8_t *addr,
index aa49a7434c37a12cb0e7920f9c4f8e0be7f6bd93..e3097ebb312eb3c53fb156dfbc94998fb4b70cfe 100644 (file)
@@ -37,6 +37,9 @@ enum {
 
 int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
 
+int sd_dhcp_server_set_ifname(sd_dhcp_server *server, const char *ifname);
+const char *sd_dhcp_server_get_ifname(sd_dhcp_server *server);
+
 sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
 sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
 
index 84e31701303c39cba454709dc21b43a7b98df03f..e02d67632a102f7f84d9d3cab6103d87a8b3067f 100644 (file)
@@ -91,6 +91,10 @@ int sd_dhcp6_client_set_callback(
 int sd_dhcp6_client_set_ifindex(
                 sd_dhcp6_client *client,
                 int interface_index);
+int sd_dhcp6_client_set_ifname(
+                sd_dhcp6_client *client,
+                const char *interface_name);
+const char * sd_dhcp6_client_get_ifname(sd_dhcp6_client *client);
 int sd_dhcp6_client_set_local_address(
                 sd_dhcp6_client *client,
                 const struct in6_addr *local_address);
index 2809d8748bd7ea1ef154017f5efa488faebab28e..1e89a81b31516e0ca99907b5fdd94d33f4d27aa0 100644 (file)
@@ -44,6 +44,7 @@ int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *use
 int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr);
 int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index);
 int sd_ipv4acd_get_ifindex(sd_ipv4acd *acd);
+int sd_ipv4acd_set_ifname(sd_ipv4acd *acd, const char *interface_name);
 const char *sd_ipv4acd_get_ifname(sd_ipv4acd *acd);
 int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address);
 int sd_ipv4acd_is_running(sd_ipv4acd *acd);
index aa4d174e4b795f877238ffdff3ddc1fb170e61c6..bf5596ab613c8391a701342e2a8445e062a522a9 100644 (file)
@@ -44,6 +44,7 @@ int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdat
 int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr);
 int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index);
 int sd_ipv4ll_get_ifindex(sd_ipv4ll *ll);
+int sd_ipv4ll_set_ifname(sd_ipv4ll *ll, const char *interface_name);
 const char *sd_ipv4ll_get_ifname(sd_ipv4ll *ll);
 int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address);
 int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed);
index e48e29fbc05b0e83c1375e8b95ed1320e8676251..64047ee81716ce1cb96a90e2967b96fa6bf462d4 100644 (file)
@@ -147,6 +147,8 @@ sd_event *sd_lldp_get_event(sd_lldp *lldp);
 
 int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata);
 int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex);
+int sd_lldp_set_ifname(sd_lldp *lldp, const char *ifname);
+const char *sd_lldp_get_ifname(sd_lldp *lldp);
 
 /* Controls how much and what to store in the neighbors database */
 int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t n);
index 49b127c01817af95a257420f6710527a5c4774cd..6088def1b61d257582ca1412a529ef87fe9b48bf 100644 (file)
@@ -78,6 +78,8 @@ sd_event *sd_ndisc_get_event(sd_ndisc *nd);
 
 int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t cb, void *userdata);
 int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index);
+int sd_ndisc_set_ifname(sd_ndisc *nd, const char *interface_name);
+const char *sd_ndisc_get_ifname(sd_ndisc *nd);
 int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr);
 
 int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *ret);
index 3f6c149d5e259daba08b92da1799b184195c9893..be5cf1b94e65d867d87b20f4d7a1ed14ba77b66e 100644 (file)
@@ -53,6 +53,8 @@ int sd_radv_stop(sd_radv *ra);
 int sd_radv_is_running(sd_radv *ra);
 
 int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
+int sd_radv_set_ifname(sd_radv *ra, const char *interface_name);
+const char *sd_radv_get_ifname(sd_radv *ra);
 int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
 int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
 int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
index b098eb27cd46468fbeb711f2433a82d247da7ed5..8d3086e20916bb47d2d60a79f03e7a7fe2195046 100644 (file)
@@ -6,6 +6,7 @@
 #include "alloc-util.h"
 #include "conf-files.h"
 #include "copy.h"
+#include "creds-util.h"
 #include "def.h"
 #include "dissect-image.h"
 #include "fd-util.h"
@@ -13,7 +14,9 @@
 #include "format-util.h"
 #include "fs-util.h"
 #include "hashmap.h"
+#include "libcrypt-util.h"
 #include "main-func.h"
+#include "memory-util.h"
 #include "mount-util.h"
 #include "nscd-flush.h"
 #include "pager.h"
@@ -429,6 +432,8 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
         }
 
         ORDERED_HASHMAP_FOREACH(i, todo_uids) {
+                _cleanup_free_ char *creds_shell = NULL, *cn = NULL;
+
                 struct passwd n = {
                         .pw_name = i->name,
                         .pw_uid = i->uid,
@@ -446,6 +451,17 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
                         .pw_shell = i->shell ?: (char*) default_shell(i->uid),
                 };
 
+                /* Try to pick up the shell for this account via the credentials logic */
+                cn = strjoin("passwd.shell.", i->name);
+                if (!cn)
+                        return -ENOMEM;
+
+                r = read_credential(cn, (void**) &creds_shell, NULL);
+                if (r < 0)
+                        log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+                else
+                        n.pw_shell = creds_shell;
+
                 r = putpwent_sane(&n, passwd);
                 if (r < 0)
                         return r;
@@ -530,6 +546,9 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
         }
 
         ORDERED_HASHMAP_FOREACH(i, todo_uids) {
+                _cleanup_(erase_and_freep) char *creds_password = NULL;
+                _cleanup_free_ char *cn = NULL;
+
                 struct spwd n = {
                         .sp_namp = i->name,
                         .sp_pwdp = (char*) "!*", /* lock this password, and make it invalid */
@@ -542,6 +561,34 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
                         .sp_flag = ULONG_MAX, /* this appears to be what everybody does ... */
                 };
 
+                /* Try to pick up the password for this account via the credentials logic */
+                cn = strjoin("passwd.hashed-password.", i->name);
+                if (!cn)
+                        return -ENOMEM;
+
+                r = read_credential(cn, (void**) &creds_password, NULL);
+                if (r == -ENOENT) {
+                        _cleanup_(erase_and_freep) char *plaintext_password = NULL;
+
+                        free(cn);
+                        cn = strjoin("passwd.plaintext-password.", i->name);
+                        if (!cn)
+                                return -ENOMEM;
+
+                        r = read_credential(cn, (void**) &plaintext_password, NULL);
+                        if (r < 0)
+                                log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+                        else {
+                                r = hash_password(plaintext_password, &creds_password);
+                                if (r < 0)
+                                        return log_debug_errno(r, "Failed to hash password: %m");
+                        }
+                } else if (r < 0)
+                        log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+
+                if (creds_password)
+                        n.sp_pwdp = creds_password;
+
                 r = putspent_sane(&n, shadow);
                 if (r < 0)
                         return r;
@@ -1946,7 +1993,11 @@ static int run(int argc, char *argv[]) {
 
                 r = mount_image_privately_interactively(
                                 arg_image,
-                                DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_VALIDATE_OS |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_FSCK,
                                 &unlink_dir,
                                 &loop_device,
                                 &decrypted_image);
index ff40a8d10ddd0452db642b953d53b2aecc4d0485..0488baba82090e61a798311003f5ad4621f72bb6 100644 (file)
@@ -540,7 +540,16 @@ tests += [
         [['src/test/test-gcrypt-util.c'],
          [], [], [], 'HAVE_GCRYPT'],
 
-        [['src/test/test-nss.c'],
+        [['src/test/test-nss-hosts.c',
+          'src/test/nss-test-util.c',
+          'src/test/nss-test-util.h'],
+         [],
+         [libdl],
+         [], 'ENABLE_NSS', 'manual'],
+
+        [['src/test/test-nss-users.c',
+          'src/test/nss-test-util.c',
+          'src/test/nss-test-util.h'],
          [],
          [libdl],
          [], 'ENABLE_NSS', 'manual'],
diff --git a/src/test/nss-test-util.c b/src/test/nss-test-util.c
new file mode 100644 (file)
index 0000000..fc1d724
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "nss-test-util.h"
+#include "string-util.h"
+
+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;
+        }
+};
+
+void* nss_open_handle(const char *dir, const char *module, int flags) {
+        const char *path = NULL;
+        void *handle;
+
+        if (dir)
+                path = strjoina(dir, "/libnss_", module, ".so.2");
+        if (!path || access(path, F_OK) < 0)
+                path = strjoina("libnss_", module, ".so.2");
+
+        log_debug("Using %s", path);
+        handle = dlopen(path, flags);
+        if (!handle)
+                log_error("Failed to load module %s: %s", module, dlerror());
+        return handle;
+}
diff --git a/src/test/nss-test-util.h b/src/test/nss-test-util.h
new file mode 100644 (file)
index 0000000..f081e64
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <nss.h>
+#include <stdint.h>
+
+const char* nss_status_to_string(enum nss_status status, char *buf, size_t buf_len);
+void* nss_open_handle(const char *dir, const char *module, int flags);
index 01ec7f8770482e5bb5034fcc3cd906a178102a40..4f1d0f64d5772f3353aee98b4a87810f2bab0e5d 100644 (file)
@@ -2,11 +2,11 @@
 
 #include "alloc-util.h"
 #include "calendarspec.h"
+#include "env-util.h"
 #include "errno-util.h"
 #include "string-util.h"
-#include "util.h"
 
-static void test_one(const char *input, const char *output) {
+static void _test_one(int line, const char *input, const char *output) {
         CalendarSpec *c;
         _cleanup_free_ char *p = NULL, *q = NULL;
         usec_t u;
@@ -16,13 +16,13 @@ static void test_one(const char *input, const char *output) {
         assert_se(calendar_spec_from_string(input, &c) >= 0);
 
         assert_se(calendar_spec_to_string(c, &p) >= 0);
-        printf("\"%s\" → \"%s\"\n", input, p);
+        log_info("line %d: \"%s\" → \"%s\"", line, input, p);
 
         assert_se(streq(p, output));
 
         u = now(CLOCK_REALTIME);
         r = calendar_spec_next_usec(c, u, &u);
-        printf("Next: %s\n", r < 0 ? strerror_safe(r) : format_timestamp(buf, sizeof(buf), u));
+        log_info("Next: %s", r < 0 ? strerror_safe(r) : format_timestamp(buf, sizeof buf, u));
         calendar_spec_free(c);
 
         assert_se(calendar_spec_from_string(p, &c) >= 0);
@@ -31,8 +31,9 @@ static void test_one(const char *input, const char *output) {
 
         assert_se(streq(q, p));
 }
+#define test_one(input, output) _test_one(__LINE__, input, output)
 
-static void test_next(const char *input, const char *new_tz, usec_t after, usec_t expect) {
+static void _test_next(int line, const char *input, const char *new_tz, usec_t after, usec_t expect) {
         CalendarSpec *c;
         usec_t u;
         char *old_tz;
@@ -43,22 +44,19 @@ static void test_next(const char *input, const char *new_tz, usec_t after, usec_
         if (old_tz)
                 old_tz = strdupa(old_tz);
 
-        if (new_tz) {
-                char *colon_tz;
+        if (!isempty(new_tz))
+                new_tz = strjoina(":", new_tz);
 
-                colon_tz = strjoina(":", new_tz);
-                assert_se(setenv("TZ", colon_tz, 1) >= 0);
-        } else
-                assert_se(unsetenv("TZ") >= 0);
+        assert_se(set_unset_env("TZ", new_tz, true) == 0);
         tzset();
 
         assert_se(calendar_spec_from_string(input, &c) >= 0);
 
-        printf("\"%s\"\n", input);
+        log_info("line %d: \"%s\" new_tz=%s", line, input, strnull(new_tz));
 
         u = after;
         r = calendar_spec_next_usec(c, after, &u);
-        printf("At: %s\n", r < 0 ? strerror_safe(r) : format_timestamp_style(buf, sizeof buf, u, TIMESTAMP_US));
+        log_info("At: %s", r < 0 ? strerror_safe(r) : format_timestamp_style(buf, sizeof buf, u, TIMESTAMP_US));
         if (expect != USEC_INFINITY)
                 assert_se(r >= 0 && u == expect);
         else
@@ -66,12 +64,10 @@ static void test_next(const char *input, const char *new_tz, usec_t after, usec_
 
         calendar_spec_free(c);
 
-        if (old_tz)
-                assert_se(setenv("TZ", old_tz, 1) >= 0);
-        else
-                assert_se(unsetenv("TZ") >= 0);
+        assert_se(set_unset_env("TZ", old_tz, true) == 0);
         tzset();
 }
+#define test_next(input, new_tz, after, expect) _test_next(__LINE__, input,new_tz,after,expect)
 
 static void test_timestamp(void) {
         char buf[FORMAT_TIMESTAMP_MAX];
@@ -83,12 +79,12 @@ static void test_timestamp(void) {
 
         x = now(CLOCK_REALTIME);
 
-        assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_US));
-        printf("%s\n", buf);
+        assert_se(format_timestamp_style(buf, sizeof buf, x, TIMESTAMP_US));
+        log_info("%s", buf);
         assert_se(calendar_spec_from_string(buf, &c) >= 0);
         assert_se(calendar_spec_to_string(c, &t) >= 0);
         calendar_spec_free(c);
-        printf("%s\n", t);
+        log_info("%s", t);
 
         assert_se(parse_timestamp(t, &y) >= 0);
         assert_se(y == x);
@@ -104,11 +100,11 @@ static void test_hourly_bug_4031(void) {
         n = now(CLOCK_REALTIME);
         assert_se((r = calendar_spec_next_usec(c, n, &u)) >= 0);
 
-        printf("Now: %s (%"PRIu64")\n", format_timestamp_style(buf, sizeof buf, n, TIMESTAMP_US), n);
-        printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror_safe(r) : format_timestamp_style(buf, sizeof buf, u, TIMESTAMP_US), u);
+        log_info("Now: %s (%"PRIu64")", format_timestamp_style(buf, sizeof buf, n, TIMESTAMP_US), n);
+        log_info("Next hourly: %s (%"PRIu64")", r < 0 ? strerror_safe(r) : format_timestamp_style(buf, sizeof buf, u, TIMESTAMP_US), u);
 
         assert_se((r = calendar_spec_next_usec(c, u, &w)) >= 0);
-        printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror_safe(r) : format_timestamp_style(zaf, sizeof zaf, w, TIMESTAMP_US), w);
+        log_info("Next hourly: %s (%"PRIu64")", r < 0 ? strerror_safe(r) : format_timestamp_style(zaf, sizeof zaf, w, TIMESTAMP_US), w);
 
         assert_se(n < u);
         assert_se(u <= n + USEC_PER_HOUR);
@@ -209,15 +205,18 @@ int main(int argc, char* argv[]) {
         test_next("2017-08-06 9..17/2:00 UTC", "", 1502029800000000, 1502031600000000);
         test_next("2016-12-* 3..21/6:00 UTC", "", 1482613200000001, 1482634800000000);
         test_next("2017-09-24 03:30:00 Pacific/Auckland", "", 12345, 1506177000000000);
-        // Due to daylight saving time - 2017-09-24 02:30:00 does not exist
+        /* Due to daylight saving time - 2017-09-24 02:30:00 does not exist */
         test_next("2017-09-24 02:30:00 Pacific/Auckland", "", 12345, -1);
         test_next("2017-04-02 02:30:00 Pacific/Auckland", "", 12345, 1491053400000000);
-        // Confirm that even though it's a time change here (backward) 02:30 happens only once
+        /* Confirm that even though it's a time change here (backward) 02:30 happens only once */
         test_next("2017-04-02 02:30:00 Pacific/Auckland", "", 1491053400000000, -1);
         test_next("2017-04-02 03:30:00 Pacific/Auckland", "", 12345, 1491060600000000);
-        // Confirm that timezones in the Spec work regardless of current timezone
+        /* Confirm that timezones in the Spec work regardless of current timezone */
         test_next("2017-09-09 20:42:00 Pacific/Auckland", "", 12345, 1504946520000000);
         test_next("2017-09-09 20:42:00 Pacific/Auckland", "EET", 12345, 1504946520000000);
+        /* Check that we don't start looping if mktime() moves us backwards */
+        test_next("Sun *-*-* 01:00:00 Europe/Dublin", "", 1616412478000000, 1617494400000000);
+        test_next("Sun *-*-* 01:00:00 Europe/Dublin", "IST", 1616412478000000, 1617494400000000);
 
         assert_se(calendar_spec_from_string("test", &c) < 0);
         assert_se(calendar_spec_from_string(" utc", &c) < 0);
index 43118202b85e9d7f236df503878535b0502ebe25..7b8f8fa1b2babe4c9817ebcf2deefbe34721d062 100644 (file)
@@ -317,7 +317,7 @@ static void test_copy_proc(void) {
         assert_se(read_one_line_file("/proc/version", &a) >= 0);
         assert_se(read_one_line_file(f, &b) >= 0);
         assert_se(streq(a, b));
-        assert_se(strlen(a) > 0);
+        assert_se(!isempty(a));
 }
 
 int main(int argc, char *argv[]) {
index 659b69008203f1d3a1d6e038a7e96308c180e41f..c5c8116e96d3db831925d85b1ff8b3896d66ebfb 100644 (file)
@@ -9,6 +9,7 @@
 #include "ctype.h"
 #include "env-file.h"
 #include "env-util.h"
+#include "errno-util.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
@@ -964,6 +965,24 @@ static void test_read_full_file_offset_size(void) {
         rbuf = mfree(rbuf);
 }
 
+static void test_read_full_virtual_file(void) {
+        const char *filename;
+        int r;
+
+        FOREACH_STRING(filename,
+                       "/proc/1/cmdline",
+                       "/etc/nsswitch.conf",
+                       "/sys/kernel/uevent_seqnum") {
+
+                _cleanup_free_ char *buf = NULL;
+                size_t size = 0;
+
+                r = read_full_virtual_file(filename, &buf, &size);
+                log_info_errno(r, "read_full_virtual_file(\"%s\"): %m (%zu bytes)", filename, size);
+                assert_se(r == 0 || ERRNO_IS_PRIVILEGE(r) || r == -ENOENT);
+        }
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
@@ -991,6 +1010,7 @@ int main(int argc, char *argv[]) {
         test_read_nul_string();
         test_read_full_file_socket();
         test_read_full_file_offset_size();
+        test_read_full_virtual_file();
 
         return 0;
 }
index 8d69f192d81dcacdfa0401a0e15198ef05a2f73e..dfde01a678899a4fc3b22a68afb0c51cce5df99a 100644 (file)
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <unistd.h>
+
 #include "firewall-util.h"
+#include "firewall-util-private.h"
 #include "log.h"
 #include "random-util.h"
+#include "socket-util.h"
 #include "tests.h"
 
-#define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))}
-#define MAKE_IN6_ADDR_UNION(str, u) assert_se(in_addr_from_string(AF_INET6, str, u) >= 0)
-
-static void test_v6(FirewallContext **ctx) {
-        union in_addr_union u = {}, u2 = {};
+static void test_v6(FirewallContext *ctx) {
+        union in_addr_union u1, u2, u3;
         uint8_t prefixlen;
         int r;
 
-        MAKE_IN6_ADDR_UNION("dead::beef", &u);
-
-        r = fw_add_masquerade(ctx, true, AF_INET6, &u, 128);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+        assert_se(ctx);
 
-        r = fw_add_masquerade(ctx, false, AF_INET6, &u, 128);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+        log_info("/* %s(backend=%s) */", __func__, firewall_backend_to_string(ctx->backend));
 
-        r = fw_add_masquerade(ctx, true, AF_INET6, &u, 64);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+        if (!socket_ipv6_is_supported())
+                return log_info("IPv6 is not supported by kernel, skipping tests.");
 
-        r = fw_add_masquerade(ctx, false, AF_INET6, &u, 64);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+        assert_se(in_addr_from_string(AF_INET6, "dead::beef", &u1) >= 0);
+        assert_se(in_addr_from_string(AF_INET6, "1c3::c01d", &u2) >= 0);
 
-        r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u, 815, NULL);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        prefixlen = random_u64_range(128 + 1 - 8) + 8;
+        pseudo_random_bytes(&u3, sizeof(u3));
 
-        MAKE_IN6_ADDR_UNION("1c3::c01d", &u2);
-        r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 128) >= 0);
+        assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 128) >= 0);
+        assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 64) >= 0);
+        assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 64) >= 0);
+        assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u3, prefixlen) >= 0);
+        assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u3, prefixlen) >= 0);
 
-        r = fw_add_local_dnat(ctx, false, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, NULL);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        r = fw_add_local_dnat(&ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u1, 815, NULL);
+        if (r == -EOPNOTSUPP) {
+                log_info("IPv6 DNAT seems not supported, skipping the following tests.");
+                return;
+        }
+        assert_se(r >= 0);
 
-        prefixlen = random_u32() % (128 + 1 - 8);
-        prefixlen += 8;
-        pseudo_random_bytes(&u, sizeof(u));
+        assert_se(fw_add_local_dnat(&ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u1) >= 0);
+        assert_se(fw_add_local_dnat(&ctx, false, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, NULL) >= 0);
 
-        r = fw_add_masquerade(ctx, true, AF_INET6, &u, prefixlen);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+}
 
-        r = fw_add_masquerade(ctx, false, AF_INET6, &u, prefixlen);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+static union in_addr_union *parse_addr(const char *str, union in_addr_union *u) {
+        assert(str);
+        assert(u);
+        assert_se(in_addr_from_string(AF_INET, str, u) >= 0);
+        return u;
 }
 
-int main(int argc, char *argv[]) {
-        _cleanup_(fw_ctx_freep) FirewallContext *ctx;
+static bool test_v4(FirewallContext *ctx) {
+        union in_addr_union u, v;
         int r;
-        test_setup_logging(LOG_DEBUG);
-        uint8_t prefixlen = 32;
 
-        r = fw_ctx_new(&ctx);
-        if (r < 0)
-                return log_error_errno(r, "Failed to init firewall: %m");
+        assert_se(ctx);
 
-        r = fw_add_masquerade(&ctx, true, AF_INET, NULL, 0);
-        if (r == 0)
-                log_error("Expected failure: NULL source");
+        log_info("/* %s(backend=%s) */", __func__, firewall_backend_to_string(ctx->backend));
 
-        r = fw_add_masquerade(&ctx, true, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,0), 0);
-        if (r == 0)
-                log_error("Expected failure: 0 prefixlen");
+        assert_se(fw_add_masquerade(&ctx, true, AF_INET, NULL, 0) == -EINVAL);
+        assert_se(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.1.2.0", &u), 0) == -EINVAL);
 
-        r = fw_add_masquerade(&ctx, true, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,3), prefixlen);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        r = fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.1.2.3", &u), 32);
+        if (r < 0) {
+                bool ignore = IN_SET(r, -EPERM, -EOPNOTSUPP, -ENOPROTOOPT);
 
-        prefixlen = 28;
-        r = fw_add_masquerade(&ctx, true, AF_INET, &MAKE_IN_ADDR_UNION(10,0,2,0), prefixlen);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+                log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
+                               "Failed to add IPv4 masquerade%s: %m",
+                               ignore ? ", skipping following tests" : "");
 
-        r = fw_add_masquerade(&ctx, false, AF_INET, &MAKE_IN_ADDR_UNION(10,0,2,0), prefixlen);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+                if (ignore)
+                        return false;
+        }
+        assert(r >= 0);
 
-        r = fw_add_masquerade(&ctx, false, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,3), 32);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        assert_se(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.0.2.0", &u), 28) >= 0);
+        assert_se(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.0.2.0", &u), 28) >= 0);
+        assert_se(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.1.2.3", &u), 32) >= 0);
+        assert_se(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL) >= 0);
+        assert_se(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL) >= 0);
+        assert_se(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, parse_addr("1.2.3.4", &v)) >= 0);
+        assert_se(fw_add_local_dnat(&ctx, false, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, NULL) >= 0);
+
+        return true;
+}
+
+int main(int argc, char *argv[]) {
+        _cleanup_(fw_ctx_freep) FirewallContext *ctx = NULL;
+
+        test_setup_logging(LOG_DEBUG);
 
-        r = fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 4), 815, NULL);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        if (getuid() != 0)
+                return log_tests_skipped("not root");
 
-        r = fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 4), 815, NULL);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        assert_se(fw_ctx_new(&ctx) >= 0);
+        assert_se(ctx);
 
-        r = fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 5), 815, &MAKE_IN_ADDR_UNION(1, 2, 3, 4));
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        if (ctx->backend == FW_BACKEND_NONE)
+                return EXIT_TEST_SKIP;
 
-        r = fw_add_local_dnat(&ctx, false, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 5), 815, NULL);
-        if (r < 0)
-                log_error_errno(r, "Failed to modify firewall: %m");
+        if (test_v4(ctx) && ctx->backend == FW_BACKEND_NFTABLES)
+                test_v6(ctx);
 
-        test_v6(&ctx);
+#if HAVE_LIBIPTC
+        if (ctx->backend != FW_BACKEND_IPTABLES) {
+                ctx->backend = FW_BACKEND_IPTABLES;
+                test_v4(ctx);
+        }
+#endif
 
         return 0;
 }
index 41df5588d082948a11a15a1951c1fa6a6ba8bcbc..2e9116d359dbeb9306f99a75a844541dd70d5753 100644 (file)
@@ -1,11 +1,20 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <sys/mount.h>
+#include <sys/statvfs.h>
 
 #include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
 #include "mount-util.h"
+#include "namespace-util.h"
+#include "path-util.h"
+#include "process-util.h"
+#include "rm-rf.h"
 #include "string-util.h"
+#include "strv.h"
 #include "tests.h"
+#include "tmpfile-util.h"
 
 static void test_mount_option_mangle(void) {
         char *opts = NULL;
@@ -61,10 +70,98 @@ static void test_mount_option_mangle(void) {
         assert_se(mount_option_mangle("rw,relatime,fmask=0022,dmask=0022,\"hogehoge", MS_RDONLY, &f, &opts) < 0);
 }
 
+static void test_bind_remount_recursive(void) {
+        _cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
+        _cleanup_free_ char *subdir = NULL;
+        const char *p;
+
+        if (geteuid() != 0) {
+                (void) log_tests_skipped("not running as root");
+                return;
+        }
+
+        assert_se(mkdtemp_malloc("/tmp/XXXXXX", &tmp) >= 0);
+        subdir = path_join(tmp, "subdir");
+        assert_se(subdir);
+        assert_se(mkdir(subdir, 0755) >= 0);
+
+        FOREACH_STRING(p, "/usr", "/sys", "/", tmp) {
+                pid_t pid;
+
+                pid = fork();
+                assert_se(pid >= 0);
+
+                if (pid == 0) {
+                        struct statvfs svfs;
+                        /* child */
+                        assert_se(detach_mount_namespace() >= 0);
+
+                        /* Check that the subdir is writable (it must be because it's in /tmp) */
+                        assert_se(statvfs(subdir, &svfs) >= 0);
+                        assert_se(!FLAGS_SET(svfs.f_flag, ST_RDONLY));
+
+                        /* Make the subdir a bind mount */
+                        assert_se(mount_nofollow(subdir, subdir, NULL, MS_BIND|MS_REC, NULL) >= 0);
+
+                        /* Ensure it's still writable */
+                        assert_se(statvfs(subdir, &svfs) >= 0);
+                        assert_se(!FLAGS_SET(svfs.f_flag, ST_RDONLY));
+
+                        /* Now mark the path we currently run for read-only */
+                        assert_se(bind_remount_recursive(p, MS_RDONLY, MS_RDONLY, STRV_MAKE("/sys/kernel")) >= 0);
+
+                        /* Ensure that this worked on the top-level */
+                        assert_se(statvfs(p, &svfs) >= 0);
+                        assert_se(FLAGS_SET(svfs.f_flag, ST_RDONLY));
+
+                        /* And ensure this had an effect on the subdir exactly if we are talking about a path above the subdir */
+                        assert_se(statvfs(subdir, &svfs) >= 0);
+                        assert_se(FLAGS_SET(svfs.f_flag, ST_RDONLY) == !!path_startswith(subdir, p));
+
+                        _exit(EXIT_SUCCESS);
+                }
+
+                assert_se(wait_for_terminate_and_check("test-remount-rec", pid, WAIT_LOG) == EXIT_SUCCESS);
+        }
+}
+
+static void test_bind_remount_one(void) {
+        pid_t pid;
+
+        if (geteuid() != 0) {
+                (void) log_tests_skipped("not running as root");
+                return;
+        }
+
+        pid = fork();
+        assert_se(pid >= 0);
+
+        if (pid == 0) {
+                /* child */
+
+                _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+                assert_se(detach_mount_namespace() >= 0);
+
+                assert_se(fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo) >= 0);
+
+                assert_se(bind_remount_one_with_mountinfo("/run", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) >= 0);
+                assert_se(bind_remount_one_with_mountinfo("/proc/idontexist", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) == -ENOENT);
+                assert_se(bind_remount_one_with_mountinfo("/proc/self", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) == -EINVAL);
+                assert_se(bind_remount_one_with_mountinfo("/", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) >= 0);
+
+                _exit(EXIT_SUCCESS);
+        }
+
+        assert_se(wait_for_terminate_and_check("test-remount-one", pid, WAIT_LOG) == EXIT_SUCCESS);
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
         test_mount_option_mangle();
+        test_bind_remount_recursive();
+        test_bind_remount_one();
 
         return 0;
 }
index bf4b87e8a678d72d4d89826fa18b9155f28c8cf5..cfa46b00b5beff48a4072370740436e6563b49bf 100644 (file)
@@ -147,7 +147,6 @@ static void test_protect_kernel_logs(void) {
                 return;
         }
 
-
         pid = fork();
         assert_se(pid >= 0);
 
@@ -187,7 +186,6 @@ static void test_protect_kernel_logs(void) {
                                     NULL,
                                     NULL,
                                     NULL,
-                                    0,
                                     NULL);
                 assert_se(r == 0);
 
index 761ee5da866d5dc8c9eaa064bd89c5316b5282c0..ae666a3019a9aedd4dff7336719257b62211b75a 100644 (file)
@@ -107,7 +107,6 @@ int main(int argc, char *argv[]) {
                             NULL,
                             NULL,
                             NULL,
-                            0,
                             NULL);
         if (r < 0) {
                 log_error_errno(r, "Failed to set up namespace: %m");
similarity index 87%
rename from src/test/test-nss.c
rename to src/test/test-nss-hosts.c
index 2e9414d16d54eea127f5baf5dd34a743bc3f65f7..e9bc6ecce61b6c01d253fb091b9379e39a09b89d 100644 (file)
@@ -1,12 +1,12 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <dlfcn.h>
 #include <net/if.h>
 #include <stdlib.h>
 #include <unistd.h>
 
 #include "af-list.h"
 #include "alloc-util.h"
+#include "dlfcn-util.h"
 #include "errno-list.h"
 #include "format-util.h"
 #include "hexdecoct.h"
 #include "local-addresses.h"
 #include "log.h"
 #include "main-func.h"
+#include "nss-test-util.h"
 #include "nss-util.h"
+#include "parse-util.h"
 #include "path-util.h"
 #include "stdio-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "tests.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 size_t arg_bufsize = 1024;
 
 static const char* af_to_string(int family, char *buf, size_t buf_len) {
         const char *name;
@@ -54,22 +40,6 @@ static const char* af_to_string(int family, char *buf, size_t buf_len) {
         return buf;
 }
 
-static void* open_handle(const char *dir, const char *module, int flags) {
-        const char *path = NULL;
-        void *handle;
-
-        if (dir)
-                path = strjoina(dir, "/libnss_", module, ".so.2");
-        if (!path || access(path, F_OK) < 0)
-                path = strjoina("libnss_", module, ".so.2");
-
-        log_debug("Using %s", path);
-        handle = dlopen(path, flags);
-        if (!handle)
-                log_error("Failed to load module %s: %s", module, dlerror());
-        return handle;
-}
-
 static int print_gaih_addrtuples(const struct gaih_addrtuple *tuples) {
         int n = 0;
 
@@ -132,7 +102,7 @@ static void print_struct_hostent(struct hostent *host, const char *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];
+        char buffer[arg_bufsize];
         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,
@@ -184,7 +154,7 @@ static void test_gethostbyname4_r(void *handle, const char *module, const char *
 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];
+        char buffer[arg_bufsize];
         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,
@@ -219,7 +189,7 @@ static void test_gethostbyname3_r(void *handle, const char *module, const char *
 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];
+        char buffer[arg_bufsize];
         int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
         enum nss_status status;
         char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
@@ -247,7 +217,7 @@ static void test_gethostbyname2_r(void *handle, const char *module, const char *
 static void test_gethostbyname_r(void *handle, const char *module, const char *name) {
         const char *fname;
         _nss_gethostbyname_r_t f;
-        char buffer[2000];
+        char buffer[arg_bufsize];
         int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
         enum nss_status status;
         char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
@@ -278,7 +248,7 @@ static void test_gethostbyaddr2_r(void *handle,
 
         const char *fname;
         _nss_gethostbyaddr2_r_t f;
-        char buffer[2000];
+        char buffer[arg_bufsize];
         int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
         enum nss_status status;
         char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
@@ -316,7 +286,7 @@ static void test_gethostbyaddr_r(void *handle,
 
         const char *fname;
         _nss_gethostbyaddr_r_t f;
-        char buffer[2000];
+        char buffer[arg_bufsize];
         int errno1 = 999, errno2 = 999; /* nss-dns doesn't set those */
         enum nss_status status;
         char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
@@ -392,8 +362,7 @@ static int make_addresses(struct local_address **addresses) {
                 log_info_errno(n, "Failed to query local addresses: %m");
 
         n_alloc = n; /* we _can_ do that */
-        if (!GREEDY_REALLOC(addrs, n_alloc, n + 3))
-                return log_oom();
+        assert_se(GREEDY_REALLOC(addrs, n_alloc, n + 3));
 
         addrs[n++] = (struct local_address) { .family = AF_INET,
                                               .address.in = { htobe32(0x7F000001) } };
@@ -409,15 +378,14 @@ static int test_one_module(const char *dir,
                            char **names,
                            struct local_address *addresses,
                            int n_addresses) {
-        void *handle;
-        char **name;
 
         log_info("======== %s ========", module);
 
-        handle = open_handle(dir, module, RTLD_LAZY|RTLD_NODELETE);
+        _cleanup_(dlclosep) void *handle = nss_open_handle(dir, module, RTLD_LAZY|RTLD_NODELETE);
         if (!handle)
                 return -EINVAL;
 
+        char **name;
         STRV_FOREACH(name, names)
                 test_byname(handle, module, *name);
 
@@ -428,7 +396,6 @@ static int test_one_module(const char *dir,
                             addresses[i].family);
 
         log_info(" ");
-        dlclose(handle);
         return 0;
 }
 
@@ -437,10 +404,18 @@ static int parse_argv(int argc, char **argv,
                       char ***the_names,
                       struct local_address **the_addresses, int *n_addresses) {
 
-        int r, n = 0;
         _cleanup_strv_free_ char **modules = NULL, **names = NULL;
         _cleanup_free_ struct local_address *addrs = NULL;
         size_t n_allocated = 0;
+        const char *p;
+        int r, n = 0;
+
+        p = getenv("SYSTEMD_TEST_NSS_BUFSIZE");
+        if (p) {
+                r = safe_atozu(p, &arg_bufsize);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse $SYSTEMD_TEST_NSS_BUFSIZE");
+        }
 
         if (argc > 1)
                 modules = strv_new(argv[1]);
@@ -456,8 +431,7 @@ static int parse_argv(int argc, char **argv,
                                 "mymachines",
 #endif
                                 "dns");
-        if (!modules)
-                return -ENOMEM;
+        assert_se(modules);
 
         if (argc > 2) {
                 char **name;
@@ -472,8 +446,7 @@ static int parse_argv(int argc, char **argv,
                                 if (r < 0)
                                         return r;
                         } else {
-                                if (!GREEDY_REALLOC0(addrs, n_allocated, n + 1))
-                                        return -ENOMEM;
+                                assert_se(GREEDY_REALLOC0(addrs, n_allocated, n + 1));
 
                                 addrs[n++] = (struct local_address) { .family = family,
                                                                       .address = address };
@@ -481,26 +454,18 @@ static int parse_argv(int argc, char **argv,
                 }
         } else {
                 _cleanup_free_ char *hostname;
+                assert_se(hostname = gethostname_malloc());
 
-                hostname = gethostname_malloc();
-                if (!hostname)
-                        return -ENOMEM;
-
-                names = strv_new("localhost", "_gateway", "foo_no_such_host", hostname);
-                if (!names)
-                        return -ENOMEM;
+                assert_se(names = strv_new("localhost", "_gateway", "foo_no_such_host", hostname));
 
                 n = make_addresses(&addrs);
-                if (n < 0)
-                        return n;
+                assert_se(n >= 0);
         }
 
-        *the_modules = modules;
-        *the_names = names;
-        modules = names = NULL;
-        *the_addresses = addrs;
+        *the_modules = TAKE_PTR(modules);
+        *the_names = TAKE_PTR(names);
+        *the_addresses = TAKE_PTR(addrs);
         *n_addresses = n;
-        addrs = NULL;
         return 0;
 }
 
@@ -515,14 +480,10 @@ static int run(int argc, char **argv) {
         test_setup_logging(LOG_INFO);
 
         r = parse_argv(argc, argv, &modules, &names, &addresses, &n_addresses);
-        if (r < 0) {
-                log_error_errno(r, "Failed to parse arguments: %m");
-                return EXIT_FAILURE;
-        }
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse arguments: %m");
 
-        dir = dirname_malloc(argv[0]);
-        if (!dir)
-                return log_oom();
+        assert_se(path_extract_directory(argv[0], &dir) >= 0);
 
         STRV_FOREACH(module, modules) {
                 r = test_one_module(dir, *module, names, addresses, n_addresses);
diff --git a/src/test/test-nss-users.c b/src/test/test-nss-users.c
new file mode 100644 (file)
index 0000000..c415c0c
--- /dev/null
@@ -0,0 +1,258 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "dlfcn-util.h"
+#include "errno-list.h"
+#include "format-util.h"
+#include "log.h"
+#include "main-func.h"
+#include "nss-test-util.h"
+#include "nss-util.h"
+#include "path-util.h"
+#include "parse-util.h"
+#include "stdio-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "tests.h"
+#include "user-util.h"
+
+static size_t arg_bufsize = 1024;
+
+static void print_struct_passwd(const struct passwd *pwd) {
+        log_info("        \"%s\" / "UID_FMT":"GID_FMT,
+                 pwd->pw_name, pwd->pw_uid, pwd->pw_gid);
+        log_info("        passwd=\"%s\"", pwd->pw_passwd);
+        log_info("        gecos=\"%s\"", pwd->pw_gecos);
+        log_info("        dir=\"%s\"", pwd->pw_dir);
+        log_info("        shell=\"%s\"", pwd->pw_shell);
+}
+
+static void print_struct_group(const struct group *gr) {
+        _cleanup_free_ char *members = NULL;
+
+        log_info("        \"%s\" / "GID_FMT,
+                 gr->gr_name, gr->gr_gid);
+        log_info("        passwd=\"%s\"", gr->gr_passwd);
+
+        assert_se(members = strv_join(gr->gr_mem, ", "));
+        // FIXME: use shell_maybe_quote(SHELL_ESCAPE_EMPTY) when it becomes available
+        log_info("        members=%s", members);
+}
+
+static void test_getpwnam_r(void *handle, const char *module, const char *name) {
+        const char *fname;
+        _nss_getpwnam_r_t f;
+        char buffer[arg_bufsize];
+        int errno1 = 999; /* nss-dns doesn't set those */
+        enum nss_status status;
+        char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+        struct passwd pwd;
+
+        fname = strjoina("_nss_", module, "_getpwnam_r");
+        f = dlsym(handle, fname);
+        log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+        if (!f) {
+                log_info("%s not defined", fname);
+                return;
+        }
+
+        status = f(name, &pwd, buffer, sizeof buffer, &errno1);
+        log_info("%s(\"%s\") → status=%s%-20serrno=%d/%s",
+                 fname, name,
+                 nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+                 errno1, errno_to_name(errno1) ?: "---");
+        if (status == NSS_STATUS_SUCCESS)
+                print_struct_passwd(&pwd);
+}
+
+static void test_getgrnam_r(void *handle, const char *module, const char *name) {
+        const char *fname;
+        _nss_getgrnam_r_t f;
+        char buffer[arg_bufsize];
+        int errno1 = 999; /* nss-dns doesn't set those */
+        enum nss_status status;
+        char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+        struct group gr;
+
+        fname = strjoina("_nss_", module, "_getgrnam_r");
+        f = dlsym(handle, fname);
+        log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+        if (!f) {
+                log_info("%s not defined", fname);
+                return;
+        }
+
+        status = f(name, &gr, buffer, sizeof buffer, &errno1);
+        log_info("%s(\"%s\") → status=%s%-20serrno=%d/%s",
+                 fname, name,
+                 nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+                 errno1, errno_to_name(errno1) ?: "---");
+        if (status == NSS_STATUS_SUCCESS)
+                print_struct_group(&gr);
+}
+
+static void test_getpwuid_r(void *handle, const char *module, uid_t uid) {
+        const char *fname;
+        _nss_getpwuid_r_t f;
+        char buffer[arg_bufsize];
+        int errno1 = 999; /* nss-dns doesn't set those */
+        enum nss_status status;
+        char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+        struct passwd pwd;
+
+        fname = strjoina("_nss_", module, "_getpwuid_r");
+        f = dlsym(handle, fname);
+        log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+        if (!f) {
+                log_info("%s not defined", fname);
+                return;
+        }
+
+        status = f(uid, &pwd, buffer, sizeof buffer, &errno1);
+        log_info("%s("UID_FMT") → status=%s%-20serrno=%d/%s",
+                 fname, uid,
+                 nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+                 errno1, errno_to_name(errno1) ?: "---");
+        if (status == NSS_STATUS_SUCCESS)
+                print_struct_passwd(&pwd);
+}
+
+static void test_getgrgid_r(void *handle, const char *module, gid_t gid) {
+        const char *fname;
+        _nss_getgrgid_r_t f;
+        char buffer[arg_bufsize];
+        int errno1 = 999; /* nss-dns doesn't set those */
+        enum nss_status status;
+        char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
+        struct group gr;
+
+        fname = strjoina("_nss_", module, "_getgrgid_r");
+        f = dlsym(handle, fname);
+        log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
+        if (!f) {
+                log_info("%s not defined", fname);
+                return;
+        }
+
+        status = f(gid, &gr, buffer, sizeof buffer, &errno1);
+        log_info("%s("GID_FMT") → status=%s%-20serrno=%d/%s",
+                 fname, gid,
+                 nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
+                 errno1, errno_to_name(errno1) ?: "---");
+        if (status == NSS_STATUS_SUCCESS)
+                print_struct_group(&gr);
+}
+
+static void test_byname(void *handle, const char *module, const char *name) {
+        test_getpwnam_r(handle, module, name);
+        test_getgrnam_r(handle, module, name);
+        puts("");
+}
+
+static void test_byuid(void *handle, const char *module, uid_t uid) {
+        test_getpwuid_r(handle, module, uid);
+        test_getgrgid_r(handle, module, uid);
+        puts("");
+}
+
+static int test_one_module(const char *dir,
+                           const char *module,
+                           char **names) {
+
+        log_info("======== %s ========", module);
+
+        _cleanup_(dlclosep) void *handle = nss_open_handle(dir, module, RTLD_LAZY|RTLD_NODELETE);
+        if (!handle)
+                return -EINVAL;
+
+        char **name;
+        STRV_FOREACH(name, names)
+                test_byname(handle, module, *name);
+
+        STRV_FOREACH(name, names) {
+                uid_t uid;
+
+                assert_cc(sizeof(uid_t) == sizeof(uint32_t));
+                /* We use safe_atou32 because we don't want to refuse invalid uids. */
+                if (safe_atou32(*name, &uid) < 0)
+                        continue;
+
+                test_byuid(handle, module, uid);
+        }
+
+        log_info(" ");
+        return 0;
+}
+
+static int parse_argv(int argc, char **argv,
+                      char ***the_modules,
+                      char ***the_names) {
+
+        _cleanup_strv_free_ char **modules = NULL, **names = NULL;
+        const char *p;
+        int r;
+
+        p = getenv("SYSTEMD_TEST_NSS_BUFSIZE");
+        if (p) {
+                r = safe_atozu(p, &arg_bufsize);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse $SYSTEMD_TEST_NSS_BUFSIZE");
+        }
+
+        if (argc > 1)
+                modules = strv_new(argv[1]);
+        else
+                modules = strv_new(
+#if ENABLE_NSS_SYSTEMD
+                                "systemd",
+#endif
+#if ENABLE_NSS_MYMACHINES
+                                "mymachines",
+#endif
+                                "files");
+        assert_se(modules);
+
+        if (argc > 2)
+                names = strv_copy(strv_skip(argv, 2));
+        else
+                names = strv_new("root",
+                                 NOBODY_USER_NAME,
+                                 "foo_no_such_user",
+                                 "0",
+                                 "65534");
+        assert_se(names);
+
+        *the_modules = TAKE_PTR(modules);
+        *the_names = TAKE_PTR(names);
+        return 0;
+}
+
+static int run(int argc, char **argv) {
+        _cleanup_free_ char *dir = NULL;
+        _cleanup_strv_free_ char **modules = NULL, **names = NULL;
+        char **module;
+        int r;
+
+        test_setup_logging(LOG_INFO);
+
+        r = parse_argv(argc, argv, &modules, &names);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse arguments: %m");
+
+        assert_se(path_extract_directory(argv[0], &dir) >= 0);
+
+        STRV_FOREACH(module, modules) {
+                r = test_one_module(dir, *module, names);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+DEFINE_MAIN_FUNCTION(run);
index 0fbdd9706f69590d3e8d9cad74fe38f73d4df28b..8d3c5b0d8c71ecab3b30d0d1c3db0147b572d0f8 100644 (file)
@@ -95,31 +95,20 @@ static void test_set_put(void) {
 }
 
 static void test_set_put_string_set(void) {
-        _cleanup_ordered_set_free_free_ OrderedSet *m = NULL;
-        _cleanup_ordered_set_free_ OrderedSet *q = NULL;
+        _cleanup_ordered_set_free_ OrderedSet *m = NULL, *q = NULL;
         _cleanup_free_ char **final = NULL; /* "just free" because the strings are in the set */
-        void *t;
 
         log_info("/* %s */", __func__);
 
-        m = ordered_set_new(&string_hash_ops);
-        assert_se(m);
-
-        q = ordered_set_new(&string_hash_ops);
-        assert_se(q);
-
-        assert_se(t = strdup("1"));
-        assert_se(ordered_set_put(m, t) == 1);
-        assert_se(t = strdup("22"));
-        assert_se(ordered_set_put(m, t) == 1);
-        assert_se(t = strdup("333"));
-        assert_se(ordered_set_put(m, t) == 1);
+        assert_se(ordered_set_put_strdup(&m, "1") == 1);
+        assert_se(ordered_set_put_strdup(&m, "22") == 1);
+        assert_se(ordered_set_put_strdup(&m, "333") == 1);
 
-        assert_se(ordered_set_put(q, (void*) "11") == 1);
-        assert_se(ordered_set_put(q, (void*) "22") == 1);
-        assert_se(ordered_set_put(q, (void*) "33") == 1);
+        assert_se(ordered_set_put_strdup(&q, "11") == 1);
+        assert_se(ordered_set_put_strdup(&q, "22") == 1);
+        assert_se(ordered_set_put_strdup(&q, "33") == 1);
 
-        assert_se(ordered_set_put_string_set(m, q) == 2);
+        assert_se(ordered_set_put_string_set(&m, q) == 2);
 
         assert_se(final = ordered_set_get_strv(m));
         assert_se(strv_equal(final, STRV_MAKE("1", "22", "333", "11", "33")));
index 0ebef530a032084ddf6ad5985b4cf27640384bab..5ca654e193f9485cbf12ab9385eff3eed51e49da 100644 (file)
@@ -236,6 +236,11 @@ static void test_get_process_cmdline_harder(void) {
                 return;
         }
 
+        /* Set RLIMIT_STACK to infinity to test we don't try to allocate unncessarily large values to read
+         * the cmdline. */
+        if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
+                log_warning("Testing without RLIMIT_STACK=infinity");
+
         assert_se(unlink(path) >= 0);
 
         assert_se(prctl(PR_SET_NAME, "testa") >= 0);
index 02a73ecdb269621be12ebe50a129406078db81cc..44103efa62a24a6fd3eb45486b68bf75b491c037 100644 (file)
@@ -1,17 +1,20 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <math.h>
+
 #include "hexdecoct.h"
-#include "random-util.h"
 #include "log.h"
+#include "memory-util.h"
+#include "random-util.h"
+#include "terminal-util.h"
 #include "tests.h"
 
 static void test_genuine_random_bytes(RandomFlags flags) {
         uint8_t buf[16] = {};
-        unsigned i;
 
         log_info("/* %s */", __func__);
 
-        for (i = 1; i < sizeof buf; i++) {
+        for (size_t i = 1; i < sizeof buf; i++) {
                 assert_se(genuine_random_bytes(buf, i, flags) == 0);
                 if (i + 1 < sizeof buf)
                         assert_se(buf[i] == 0);
@@ -22,11 +25,10 @@ static void test_genuine_random_bytes(RandomFlags flags) {
 
 static void test_pseudo_random_bytes(void) {
         uint8_t buf[16] = {};
-        unsigned i;
 
         log_info("/* %s */", __func__);
 
-        for (i = 1; i < sizeof buf; i++) {
+        for (size_t i = 1; i < sizeof buf; i++) {
                 pseudo_random_bytes(buf, i);
                 if (i + 1 < sizeof buf)
                         assert_se(buf[i] == 0);
@@ -36,9 +38,11 @@ static void test_pseudo_random_bytes(void) {
 }
 
 static void test_rdrand(void) {
-        int r, i;
+        int r;
+
+        log_info("/* %s */", __func__);
 
-        for (i = 0; i < 10; i++) {
+        for (unsigned i = 0; i < 10; i++) {
                 unsigned long x = 0;
 
                 r = rdrand(&x);
@@ -51,6 +55,50 @@ static void test_rdrand(void) {
         }
 }
 
+#define TOTAL 100000
+
+static void test_random_u64_range_one(unsigned mod) {
+        log_info("/* %s(%u) */", __func__, mod);
+
+        unsigned max = 0, count[mod];
+        zero(count);
+
+        for (unsigned i = 0; i < TOTAL; i++) {
+                uint64_t x;
+
+                x = random_u64_range(mod);
+
+                log_trace("%05u: %"PRIu64, i, x);
+                count[x]++;
+                max = MAX(max, count[x]);
+        }
+
+        /* Print histogram: vertical axis — value, horizontal axis — count.
+         *
+         * The expected value is always TOTAL/mod, because the distribution should be flat. The expected
+         * variance is TOTAL×p×(1-p), where p==1/mod, and standard deviation the root of the variance.
+         * Assert that the deviation from the expected value is less than 6 standard deviations.
+         */
+        unsigned scale = 2 * max / (columns() < 20 ? 80 : columns() - 20);
+        double exp = (double) TOTAL / mod;
+
+        for (size_t i = 0; i < mod; i++) {
+                double dev = (count[i] - exp) / sqrt(exp * (mod > 1 ? mod - 1 : 1) / mod);
+                log_debug("%02zu: %5u (%+.3f)%*s",
+                          i, count[i], dev,
+                          count[i] / scale, "x");
+
+                assert_se(fabs(dev) < 6); /* 6 sigma is excessive, but this check should be enough to
+                                           * identify catastrophic failure while minimizing false
+                                           * positives. */
+        }
+}
+
+static void test_random_u64_range(void) {
+        for (unsigned mod = 1; mod < 29; mod++)
+                test_random_u64_range_one(mod);
+}
+
 int main(int argc, char **argv) {
         test_setup_logging(LOG_DEBUG);
 
@@ -61,8 +109,8 @@ int main(int argc, char **argv) {
         test_genuine_random_bytes(RANDOM_ALLOW_INSECURE);
 
         test_pseudo_random_bytes();
-
         test_rdrand();
+        test_random_u64_range();
 
         return 0;
 }
index 846e456551ee66d7e1822f09725e5be2a7669f2a..f11b4eed7cc91135d97bc9427dccdc21790b94db 100644 (file)
@@ -3431,7 +3431,11 @@ static int run(int argc, char *argv[]) {
 
                 r = mount_image_privately_interactively(
                                 arg_image,
-                                DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
+                                DISSECT_IMAGE_GENERIC_ROOT |
+                                DISSECT_IMAGE_REQUIRE_ROOT |
+                                DISSECT_IMAGE_VALIDATE_OS |
+                                DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_FSCK,
                                 &unlink_dir,
                                 &loop_device,
                                 &decrypted_image);
index f06ecd455df534019e86e10ea69f87ecdcd08d82..31e5d0cd673f94baf9cbe02aab333bb8e96aa160 100644 (file)
@@ -441,8 +441,6 @@ static int link_config_apply_rtnl_settings(sd_netlink **rtnl, const link_config
 
 static int link_config_generate_new_name(const link_config_ctx *ctx, const link_config *config, sd_device *device, const char **ret_name) {
         unsigned name_type = NET_NAME_UNKNOWN;
-        const char *new_name = NULL;
-        NamePolicy policy;
         int r;
 
         assert(ctx);
@@ -460,7 +458,8 @@ static int link_config_generate_new_name(const link_config_ctx *ctx, const link_
 
         if (ctx->enable_name_policy && config->name_policy)
                 for (NamePolicy *p = config->name_policy; *p != _NAMEPOLICY_INVALID; p++) {
-                        policy = *p;
+                        const char *new_name = NULL;
+                        NamePolicy policy = *p;
 
                         switch (policy) {
                         case NAMEPOLICY_KERNEL:
@@ -496,16 +495,13 @@ static int link_config_generate_new_name(const link_config_ctx *ctx, const link_
                         default:
                                 assert_not_reached("invalid policy");
                         }
-                        if (ifname_valid(new_name))
-                                break;
+                        if (ifname_valid(new_name)) {
+                                log_device_debug(device, "Policy *%s* yields \"%s\".", name_policy_to_string(policy), new_name);
+                                *ret_name = new_name;
+                                return 0;
+                        }
                 }
 
-        if (new_name) {
-                log_device_debug(device, "Policy *%s* yields \"%s\".", name_policy_to_string(policy), new_name);
-                *ret_name = new_name;
-                return 0;
-        }
-
         if (config->name) {
                 log_device_debug(device, "Policies didn't yield a name, using specified Name=%s.", config->name);
                 *ret_name = config->name;
index d16d7edebd5a3256c4e7bcc68165929cd0792676..fd95e6f304b1527286d729c41baca4980e6835ee 100644 (file)
@@ -86,7 +86,7 @@ static int create_device(void) {
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
-        options_escaped = specifier_escape(arg_options ?: "");
+        options_escaped = specifier_escape(strempty(arg_options));
         if (!options_escaped)
                 return log_oom();
 
index 1528432f43329fa9edeeb59bb1f089e531ba609b..00d8b76539844a0ab218c7e8db454c9acd59192c 100644 (file)
@@ -599,6 +599,7 @@ int xdg_autostart_service_generate_unit(
         fprintf(f,
                 "\n[Service]\n"
                 "Type=exec\n"
+                "ExitType=cgroup\n"
                 "ExecStart=:%s\n"
                 "Restart=no\n"
                 "TimeoutSec=5s\n"
diff --git a/sysctl.d/README b/sysctl.d/README
new file mode 100644 (file)
index 0000000..ab216b1
--- /dev/null
@@ -0,0 +1,8 @@
+Files in this directory contain configuration for systemd-sysctl.service, a
+service to configure sysctl kernel parameters.
+
+See man:sysctl.d(5) for explanation of the configuration file format, and
+man:sysctl(8) and man:systemd-sysctl.service(8) for a description of when and
+how this configuration is applied.
+
+Use 'systemd-analyze cat-config sysctl.d' to display the effective config.
index e8d8fc8c53b2d77a166d42dddd5b31da7a866127..7e3482af62a99589b21f8b2060e1d8980a01a1f4 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
 install_data(
+        'README',
         '50-default.conf',
         install_dir : sysctldir)
 
diff --git a/sysusers.d/README b/sysusers.d/README
new file mode 100644 (file)
index 0000000..df3049c
--- /dev/null
@@ -0,0 +1,8 @@
+Files in this directory contain configuration for systemd-sysusers, a program
+to allocate system users and groups.
+
+See man:sysusers.d(5) for explanation of the configuration file format, and
+man:systemd-sysusers(8) for a description of when and how this configuration is
+applied.
+
+Use 'systemd-analyze cat-config sysusers.d' to display the effective config.
index 93a61f0d9a892606e5f7b23f2dbd95e245d86db5..ef809a4f4486dfbbe6e5833f8197086fe9a6d253 100644 (file)
@@ -1,5 +1,9 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
+if enable_sysusers
+        install_data('README', install_dir : sysusersdir)
+endif
+
 in_files = ['basic.conf']
 
 foreach file : in_files
diff --git a/test/TEST-56-EXIT-TYPE/Makefile b/test/TEST-56-EXIT-TYPE/Makefile
new file mode 120000 (symlink)
index 0000000..e9f93b1
--- /dev/null
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-56-EXIT-TYPE/test.sh b/test/TEST-56-EXIT-TYPE/test.sh
new file mode 100755 (executable)
index 0000000..fc321e4
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+set -e
+TEST_DESCRIPTION="test ExitType=cgroup"
+. $TEST_BASE_DIR/test-functions
+
+do_test "$@" 56
index 55204463c8d31f253f9a7e4e6dd8d81ba5124e12..310dbd6add2be3b09e1e344f122a1b677511bd29 100644 (file)
@@ -94,6 +94,7 @@ ExecStartPre=
 ExecStop=
 ExecStopPost=
 ExecStopPre=
+ExitType=
 FailureAction=
 FileDescriptorName=
 FileDescriptorStoreMax=
index d7f7967e2ffcca4fa77963852e9ed72f2adefffb..6b94058fd366a989544f5acf97b1406d70162389 100644 (file)
@@ -1340,6 +1340,7 @@ install_zoneinfo() {
     inst_any /usr/share/zoneinfo/Asia/Vladivostok
     inst_any /usr/share/zoneinfo/Australia/Sydney
     inst_any /usr/share/zoneinfo/Europe/Berlin
+    inst_any /usr/share/zoneinfo/Europe/Dublin
     inst_any /usr/share/zoneinfo/Europe/Kiev
     inst_any /usr/share/zoneinfo/Pacific/Auckland
     inst_any /usr/share/zoneinfo/Pacific/Honolulu
index b4a5fee842eb0a83efeefd619205660ac4bf6ae9..e2d8ef6da23693b543f702ab7fba4220e5ccafa2 100755 (executable)
@@ -30,13 +30,13 @@ roothash="$(cat ${image}.roothash)"
 
 os_release=$(test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os-release)
 
-systemd-dissect --json=short ${image}.raw | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"fstype":"squashfs","architecture":null,"verity":"external"'
+systemd-dissect --json=short ${image}.raw | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
 systemd-dissect ${image}.raw | grep -q -F "MARKER=1"
 systemd-dissect ${image}.raw | grep -q -F -f $os_release
 
 mv ${image}.verity ${image}.fooverity
 mv ${image}.roothash ${image}.foohash
-systemd-dissect --json=short ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"fstype":"squashfs","architecture":null,"verity":"external"'
+systemd-dissect --json=short ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
 systemd-dissect ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F "MARKER=1"
 systemd-dissect ${image}.raw --root-hash=${roothash} --verity-data=${image}.fooverity | grep -q -F -f $os_release
 mv ${image}.fooverity ${image}.verity
@@ -127,8 +127,8 @@ losetup -d ${loop}
 ROOT_UUID=$(systemd-id128 -u show $(head -c 32 ${image}.roothash) -u | tail -n 1 | cut -b 6-)
 VERITY_UUID=$(systemd-id128 -u show $(tail -c 32 ${image}.roothash) -u | tail -n 1 | cut -b 6-)
 
-systemd-dissect --json=short --root-hash ${roothash} ${image}.gpt | grep -q '{"rw":"ro","designator":"root","partition_uuid":"'$ROOT_UUID'","fstype":"squashfs","architecture":"'$architecture'","verity":"yes","node":'
-systemd-dissect --json=short --root-hash ${roothash} ${image}.gpt | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"'$VERITY_UUID'","fstype":"DM_verity_hash","architecture":"'$architecture'","verity":null,"node":'
+systemd-dissect --json=short --root-hash ${roothash} ${image}.gpt | grep -q '{"rw":"ro","designator":"root","partition_uuid":"'$ROOT_UUID'","partition_label":"Root Partition","fstype":"squashfs","architecture":"'$architecture'","verity":"yes","node":'
+systemd-dissect --json=short --root-hash ${roothash} ${image}.gpt | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"'$VERITY_UUID'","partition_label":"Verity Partition","fstype":"DM_verity_hash","architecture":"'$architecture'","verity":null,"node":'
 systemd-dissect --root-hash ${roothash} ${image}.gpt | grep -q -F "MARKER=1"
 systemd-dissect --root-hash ${roothash} ${image}.gpt | grep -q -F -f $os_release
 
diff --git a/test/units/testsuite-56.service b/test/units/testsuite-56.service
new file mode 100644 (file)
index 0000000..d8ad589
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=TEST-56-EXIT-TYPE
+
+[Service]
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+Type=oneshot
diff --git a/test/units/testsuite-56.sh b/test/units/testsuite-56.sh
new file mode 100755 (executable)
index 0000000..9de03e1
--- /dev/null
@@ -0,0 +1,94 @@
+#!/usr/bin/env bash
+set -ex
+
+systemd-analyze log-level debug
+
+# Multiple level process tree, parent process stays up
+cat >/tmp/test56-exit-cgroup.sh <<EOF
+#!/usr/bin/env bash
+set -eux
+
+# process tree: systemd -> sleep
+sleep infinity &
+disown
+
+# process tree: systemd -> bash -> bash -> sleep
+((sleep infinity); true) &
+
+# process tree: systemd -> bash -> sleep
+sleep infinity
+EOF
+chmod +x /tmp/test56-exit-cgroup.sh
+
+# service should be stopped cleanly
+(sleep 1; systemctl stop one) &
+systemd-run --wait --unit=one -p ExitType=cgroup /tmp/test56-exit-cgroup.sh
+
+# same thing with a truthy exec condition
+(sleep 1; systemctl stop two) &
+systemd-run --wait --unit=two -p ExitType=cgroup -p ExecCondition=true /tmp/test56-exit-cgroup.sh
+
+# false exec condition: systemd-run should exit immediately with status code: 1
+! systemd-run --wait --unit=three -p ExitType=cgroup -p ExecCondition=false /tmp/test56-exit-cgroup.sh
+
+# service should exit uncleanly
+(sleep 1; systemctl kill --signal 9 four) &
+! systemd-run --wait --unit=four -p ExitType=cgroup /tmp/test56-exit-cgroup.sh
+
+
+# Multiple level process tree, parent process exits quickly
+cat >/tmp/test56-exit-cgroup-parentless.sh <<EOF
+#!/usr/bin/env bash
+set -eux
+
+# process tree: systemd -> sleep
+sleep infinity &
+
+# process tree: systemd -> bash -> sleep
+((sleep infinity); true) &
+EOF
+chmod +x /tmp/test56-exit-cgroup-parentless.sh
+
+# service should be stopped cleanly
+(sleep 1; systemctl stop five) &
+systemd-run --wait --unit=five -p ExitType=cgroup /tmp/test56-exit-cgroup-parentless.sh
+
+# service should exit uncleanly
+(sleep 1; systemctl kill --signal 9 six) &
+! systemd-run --wait --unit=six -p ExitType=cgroup /tmp/test56-exit-cgroup-parentless.sh
+
+
+# Multiple level process tree, parent process exits uncleanly but last process exits cleanly
+cat >/tmp/test56-exit-cgroup-clean.sh <<EOF
+#!/usr/bin/env bash
+set -eux
+
+# process tree: systemd -> bash -> sleep
+(sleep 1; true) &
+
+exit 255
+EOF
+chmod +x /tmp/test56-exit-cgroup-clean.sh
+
+# service should exit cleanly and be garbage-collected
+systemd-run --wait --unit=seven -p ExitType=cgroup /tmp/test56-exit-cgroup-clean.sh
+
+
+# Multiple level process tree, parent process exits cleanly but last process exits uncleanly
+cat >/tmp/test56-exit-cgroup-unclean.sh <<EOF
+#!/usr/bin/env bash
+set -eux
+
+# process tree: systemd -> bash -> sleep
+(sleep 1; exit 255) &
+EOF
+chmod +x /tmp/test56-exit-cgroup-unclean.sh
+
+# service should exit uncleanly after 1 second
+! systemd-run --wait --unit=eight -p ExitType=cgroup /tmp/test56-exit-cgroup-unclean.sh
+
+systemd-analyze log-level info
+
+echo OK > /testok
+
+exit 0
diff --git a/tmpfiles.d/README b/tmpfiles.d/README
new file mode 100644 (file)
index 0000000..b42cec2
--- /dev/null
@@ -0,0 +1,8 @@
+Files in this directory contain configuration for systemd-tmpfiles, a program
+to create, delete, and clean up volatile and temporary files and directories.
+
+See man:tmpfiles.d(5) for explanation of the configuration file format, and
+man:systemd-tmpfiles(8) for a description of when and how this configuration is
+applied.
+
+Use 'systemd-analyze cat-config tmpfiles.d' to display the effective config.
index 7322460dbaeea529885fd73edd186049e11b8df3..d5d4bbc9ea4e59471c58861a2f397603d7e3f44e 100644 (file)
@@ -2,19 +2,20 @@
 
 enable_tmpfiles = conf.get('ENABLE_TMPFILES') == 1
 
-tmpfiles = [['home.conf',            ''],
-            ['journal-nocow.conf',   ''],
-            ['systemd-nologin.conf', 'HAVE_PAM'],
-            ['systemd-nspawn.conf',  'ENABLE_MACHINED'],
-            ['systemd-tmp.conf',     ''],
-            ['portables.conf',       'ENABLE_PORTABLED'],
-            ['systemd-pstore.conf',  'ENABLE_PSTORE'],
-            ['tmp.conf',             ''],
-            ['x11.conf',             ''],
-            ['legacy.conf',          'HAVE_SYSV_COMPAT'],
-           ]
-
-foreach pair : tmpfiles
+files = [['README',               ''],
+         ['home.conf',            ''],
+         ['journal-nocow.conf',   ''],
+         ['systemd-nologin.conf', 'HAVE_PAM'],
+         ['systemd-nspawn.conf',  'ENABLE_MACHINED'],
+         ['systemd-tmp.conf',     ''],
+         ['portables.conf',       'ENABLE_PORTABLED'],
+         ['systemd-pstore.conf',  'ENABLE_PSTORE'],
+         ['tmp.conf',             ''],
+         ['x11.conf',             ''],
+         ['legacy.conf',          'HAVE_SYSV_COMPAT'],
+        ]
+
+foreach pair : files
         if not enable_tmpfiles
                 # do nothing
         elif pair[1] == '' or conf.get(pair[1]) == 1
index fdae898551b3ca2298a1f9950db9f38b8a4090b6..4b680d28025837cee36ccdc6bc786017eba0a75d 100755 (executable)
@@ -2,6 +2,7 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 set -eu
 
-git shortlog -s `git describe --abbrev=0 --match 'v[0-9][0-9][0-9]'`.. | \
-    awk '{ $1=""; print $0 "," }' | \
+tag="$(git describe --abbrev=0 --match 'v[0-9][0-9][0-9]')"
+git log --pretty=tformat:%aN --author=noreply@weblate.org --invert-grep -s "${tag}.." | \
+    sed 's/ / /g; s/--/-/g; s/.*/        \0,/' |
     sort -u
index 2fea88384f62ccafb3b3dc9049332055288e7384..2e57b064c183d9a2219fa97829109d458578bd17 100644 (file)
@@ -13,7 +13,7 @@ Documentation=man:systemd-firstboot(1)
 DefaultDependencies=no
 Conflicts=shutdown.target
 After=systemd-remount-fs.service
-Before=systemd-sysusers.service sysinit.target first-boot-complete.target shutdown.target
+Before=systemd-sysusers.service systemd-vconsole-setup.service sysinit.target first-boot-complete.target shutdown.target
 Wants=first-boot-complete.target
 ConditionPathIsReadWrite=/etc
 ConditionFirstBoot=yes
@@ -25,3 +25,14 @@ ExecStart=systemd-firstboot --prompt-locale --prompt-timezone --prompt-root-pass
 StandardOutput=tty
 StandardInput=tty
 StandardError=tty
+
+# Optionally, pick up basic fields from credentials passed to the service
+# manager. This is useful for importing this data from nspawn's
+# --set-credential= switch.
+LoadCredential=passwd.hashed-password.root
+LoadCredential=passwd.plaintext-password.root
+LoadCredential=passwd.shell.root
+LoadCredential=firstboot.locale
+LoadCredential=firstboot.locale-messages
+LoadCredential=firstboot.keymap
+LoadCredential=firstboot.timezone
index 652b956a34095647a5c1b7a206bb9b40c7fe98a9..e60a1735911186b840b9f46e87cb8590c76e950f 100644 (file)
@@ -33,7 +33,7 @@ ProtectKernelLogs=yes
 ProtectKernelModules=yes
 ProtectKernelTunables=yes
 ProtectSystem=strict
-ReadWritePaths=/etc
+ReadWritePaths=/etc@SERVICE_LOCALEGEN_WRITABLE@
 RestrictAddressFamilies=AF_UNIX
 RestrictNamespaces=yes
 RestrictRealtime=yes
index ff5b3db82138f70bd5a2c7d45b3e8dba42603fc2..47373307b32a527bf9cb0caf9232afe11c3a4938 100644 (file)
@@ -21,3 +21,10 @@ Type=oneshot
 RemainAfterExit=yes
 ExecStart=systemd-sysusers
 TimeoutSec=90s
+
+# Optionally, pick up a root password and shell for the root user from a
+# credential passed to the service manager. This is useful for importing this
+# data from nspawn's --set-credential= switch.
+LoadCredential=passwd.hashed-password.root
+LoadCredential=passwd.plaintext-password.root
+LoadCredential=passwd.shell.root