**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**
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>
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>
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
* 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:
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
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.
* 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
* 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
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)
"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)"
@@
+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);
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
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
* `$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
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).
✓ ExecStartPre=
✓ ExecStop=
✓ ExecStopPost=
+✓ ExitType=
✓ FileDescriptorStoreMax=
✓ GuessMainPID=
✓ NonBlocking=
<footer class="site-footer">
- <p>© systemd, 2020</p>
+ <p>© 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>
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.
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
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.
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.
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.
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
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
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
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.
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
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
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.
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
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
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
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
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.
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
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
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
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
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.
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.
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
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
OUI:28DEF6*
ID_OUI_FROM_DATABASE=bioMerieux Inc.
+OUI:28DFEB*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
OUI:28E02C*
ID_OUI_FROM_DATABASE=Apple, Inc.
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
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
OUI:2C6BF5*
ID_OUI_FROM_DATABASE=Juniper Networks
+OUI:2C6DC1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
OUI:2C6E85*
ID_OUI_FROM_DATABASE=Intel Corporate
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
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
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
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
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
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.
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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.
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.
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
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.
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
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
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
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
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
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
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
OUI:6C7660*
ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+OUI:6C79B8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
OUI:6C81FE*
ID_OUI_FROM_DATABASE=Mitsuba Corporation
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
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.
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
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
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
OUI:70B3D51EB*
ID_OUI_FROM_DATABASE=Xavant
+OUI:70B3D51ED*
+ ID_OUI_FROM_DATABASE=SUS Corporation
+
OUI:70B3D51EE*
ID_OUI_FROM_DATABASE=MEGGITT
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
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
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
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
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.
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)
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
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.
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
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
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
OUI:70B3D571E*
ID_OUI_FROM_DATABASE=Motec Pty Ltd
+OUI:70B3D571F*
+ ID_OUI_FROM_DATABASE=Grayshift
+
OUI:70B3D5720*
ID_OUI_FROM_DATABASE=Jeio Tech
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
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
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
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
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
OUI:70B3D5A62*
ID_OUI_FROM_DATABASE=Environexus
+OUI:70B3D5A63*
+ ID_OUI_FROM_DATABASE=DesignA Electronics Limited
+
OUI:70B3D5A64*
ID_OUI_FROM_DATABASE=Newshine
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.
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
OUI:70B3D5AFC*
ID_OUI_FROM_DATABASE=BAE Systems
+OUI:70B3D5AFD*
+ ID_OUI_FROM_DATABASE=dongsheng
+
OUI:70B3D5AFE*
ID_OUI_FROM_DATABASE=MESOTECHNIC
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
OUI:70B3D5C18*
ID_OUI_FROM_DATABASE=Sanmina Israel
+OUI:70B3D5C19*
+ ID_OUI_FROM_DATABASE=Zumbach Electronic AG
+
OUI:70B3D5C1A*
ID_OUI_FROM_DATABASE=Xylon
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
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
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
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
OUI:70B3D5F3F*
ID_OUI_FROM_DATABASE=comtac AG
+OUI:70B3D5F40*
+ ID_OUI_FROM_DATABASE=HORIZON.INC
+
OUI:70B3D5F41*
ID_OUI_FROM_DATABASE=DUEVI SRL
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
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
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.
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
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
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
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.
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
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.
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
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.
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
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
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
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
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
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
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.
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
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.
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.
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
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.
OUI:9843DA*
ID_OUI_FROM_DATABASE=INTERTECH
+OUI:9843FA*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
OUI:9844B6*
ID_OUI_FROM_DATABASE=INFRANOR SAS
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
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.
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
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
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
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
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
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.
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
OUI:A82066*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:A82316*
+ ID_OUI_FROM_DATABASE=Nokia
+
OUI:A823FE*
ID_OUI_FROM_DATABASE=LG Electronics
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.
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
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.
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
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.
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
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
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
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
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
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
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
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.
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
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
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
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
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
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.
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
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.
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.
OUI:D89EF3*
ID_OUI_FROM_DATABASE=Dell Inc.
+OUI:D8A011*
+ ID_OUI_FROM_DATABASE=WiZ
+
OUI:D8A01D*
ID_OUI_FROM_DATABASE=Espressif Inc.
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
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
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
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
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
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
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
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
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
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.
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
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
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
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
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.
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
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
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
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
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
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
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
---- 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
acpi:AMDI*:
ID_VENDOR_FROM_DATABASE=AMD
-@@ -301,6 +300,9 @@
+@@ -310,6 +309,9 @@
acpi:AAA*:
ID_VENDOR_FROM_DATABASE=Avolites Ltd
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
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.
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
acpi:AMX*:
ID_VENDOR_FROM_DATABASE=AMX LLC
-@@ -694,6 +702,9 @@
+@@ -703,6 +711,9 @@
acpi:AOA*:
ID_VENDOR_FROM_DATABASE=AOpen Inc.
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
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
acpi:AUR*:
ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
-@@ -958,6 +972,9 @@
+@@ -967,6 +981,9 @@
acpi:AXE*:
ID_VENDOR_FROM_DATABASE=Axell Corporation
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
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)
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)
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]
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]
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]
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]
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]
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
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]
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
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
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
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
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)
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)
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
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]
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
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
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.
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
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
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
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
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
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)
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)
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
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)
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)
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
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
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
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
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
usb:v06CBp00FC*
usb:v06CBp00C2*
usb:v06CBp00C9*
-usb:v06CBp00E7*
+usb:v06CBp0100*
ID_AUTOSUSPEND=1
# Supported by libfprint driver upeksonly
usb:v138Ap0018*
ID_AUTOSUSPEND=1
+# Supported by libfprint driver vfs7552
+usb:v138Ap0091*
+ ID_AUTOSUSPEND=1
+
# Known unsupported devices
usb:v04F3p036B*
usb:v04F3p0C00*
usb:v138Ap003D*
usb:v138Ap003F*
usb:v138Ap0090*
-usb:v138Ap0091*
usb:v138Ap0092*
usb:v138Ap0094*
usb:v138Ap0097*
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
--- /dev/null
+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.
<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>
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
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
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
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
# 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
#
# 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
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.
<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'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>
@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 = '...';
<!--property Type is not documented!-->
+ <!--property ExitType is not documented!-->
+
<!--property Restart is not documented!-->
<!--property PIDFile is not documented!-->
<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"/>
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
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>
<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>
<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
<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>
<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>
<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
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
<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
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,
<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
<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>
<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>
<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>
</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
<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
)
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
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)
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())
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',
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',
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')
--- /dev/null
+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.
"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"
#: 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"
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"
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"
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"
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
#: 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
#: 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
#: 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
#: 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
#: 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
#: 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
#: 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
#: 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"
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"
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"
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"
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)'."
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)' 서비스 유닛을 강제로 끝내려면 인증이 필요합니다."
--- /dev/null
+# 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."
--- /dev/null
+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.
# SPDX-License-Identifier: LGPL-2.1-or-later
+install_data(
+ 'README',
+ install_dir : udevrulesdir)
+
rules = files('''
60-autosuspend.rules
60-block.rules
_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
-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=
}
_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= \
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'
#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;
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;
}
ARG_KEYNAME,
ARG_NO_OUTPUT,
ARG_VERSION,
+ ARG_CREDENTIAL,
};
static const struct option options[] = {
{ "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 },
{}
};
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;
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");
/* 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;
_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;
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;
* 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)
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;
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)");
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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);
#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);
struct stat st;
size_t n, size;
int n_retries;
- char *p;
assert(ret_contents);
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;
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;
* 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);
#include <sys/types.h>
#include <unistd.h>
+#include "alloc-util.h"
#include "errno-util.h"
#include "time-util.h"
return NULL;
(void) rmdir(p);
- free(p);
- return NULL;
+ return mfree(p);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
return NULL;
(void) unlink_noerrno(p);
- free(p);
- return NULL;
+ return mfree(p);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
/* 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) {
#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)
conf-files.h
copy.c
copy.h
+ creds-util.c
+ creds-util.h
def.h
device-nodes.c
device-nodes.h
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)
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))
} 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 &&
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;
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);
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;
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;
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);
}
}
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) \
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);
-}
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);
}
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);
* 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;
if (r < 0)
return r;
- mfree(t);
+ free(t);
t = strjoin("[", t2, "]");
if (!t)
return -ENOMEM;
/* 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)
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)
#include <sys/stat.h>
+#include "alloc-util.h"
#include "errno-util.h"
typedef enum RemoveFlags {
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);
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);
/* 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 */
/* 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) {
_cleanup_free_ char *abspath = NULL;
int r;
-
assert(path);
if (!label_hnd)
/* 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);
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 = ''
#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"
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 */
#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);
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),
}
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);
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);
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;
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
} 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)
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
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)
#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"
#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"
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");
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));
{ 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" },
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);
#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"
#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"
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;
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;
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;
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) &&
};
}
- 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
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 */
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"
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;
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. */
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);
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",
_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,
Unit meta;
ServiceType type;
+ ServiceExitType exit_type;
ServiceRestart restart;
ExitStatusSet restart_prevent_status;
ExitStatusSet restart_force_status;
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_;
# 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]
j->unit->id,
unit_id == array ? "ordering cycle" : "dependency",
*unit_id, *job_type,
- unit_ids);
+ "%s", unit_ids);
if (delete) {
const char *status;
"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;
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.");
(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)
# 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]
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");
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");
"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)
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");
data->friendly_name,
"drive-harddisk",
"pkcs11-pin",
+ "cryptsetup.pkcs11-pin",
data->until,
NULL);
if (r < 0)
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)
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");
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;
arg_image = argv[optind];
arg_path = argv[optind + 1];
+ arg_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
break;
case ACTION_COPY_FROM:
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:
arg_target = argv[optind + 1];
}
+ arg_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
break;
default:
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();
r = table_add_many(
t,
+ TABLE_STRING, p->label,
TABLE_STRING, p->fstype,
TABLE_STRING, architecture_to_string(p->architecture));
if (r < 0)
#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"
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 = {};
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;
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;
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;
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;
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();
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);
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;
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");
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");
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");
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");
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) {
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) {
# 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]
/* 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) {
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);
}
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);
}
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);
}
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);
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)
} \
} 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,
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)
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';
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,
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;
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;
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;
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;
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;
if (priority) {
int p;
- p = log_level_from_string(priority);
+ p = syslog_parse_priority_and_facility(priority);
if (p >= 0)
stream->priority = p;
}
# 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]
#include "sd-dhcp-client.h"
#include "dhcp-protocol.h"
+#include "log-link.h"
#include "socket-util.h"
typedef struct sd_dhcp_option {
#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__)
#include "dhcp-internal.h"
#include "ordered-set.h"
-#include "log.h"
+#include "log-link.h"
#include "time-util.h"
typedef enum DHCPRawOption {
int fd_raw;
int ifindex;
+ char *ifname;
be32_t address;
be32_t netmask;
be32_t subnet;
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,
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__)
#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"
be32_t id;
} _packed_;
-struct DHCP6IA {
+typedef struct DHCP6IA {
uint16_t type;
union {
struct ia_na ia_na;
};
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);
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);
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__)
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;
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;
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);
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;
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);
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;
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;
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;
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, <_valid);
+ r = dhcp6_option_parse_address(client, option, ia, <_valid);
if (r < 0 && r != -EINVAL)
return r;
if (r >= 0 && lt_valid < lt_min)
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, <_valid);
+ r = dhcp6_option_parse_pdprefix(client, option, ia, <_valid);
if (r < 0 && r != -EINVAL)
return r;
if (r >= 0 && lt_valid < lt_min)
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);
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);
#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;
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__)
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;
assert(p || n == 0);
if (*s) {
- log_lldp("Found duplicate string, ignoring field.");
+ log_lldp(lldp, "Found duplicate string, ignoring field.");
return 0;
}
/* 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;
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));
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) */
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;
}
}
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);
sd-ipv4acd.c
arp-util.h
arp-util.c
+ network-common.c
+ network-common.h
network-internal.c
network-internal.h
sd-ndisc.c
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
unsigned n_ref;
int ifindex;
+ char *ifname;
int fd;
sd_event *event;
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__)
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;
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;
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 */
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;
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 */
}
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 |=
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;
}
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;
}
}
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);
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+const char *get_ifname(int ifindex, char **ifname);
#include "sd-radv.h"
-#include "log.h"
+#include "log-link.h"
#include "list.h"
#include "sparse-endian.h"
RAdvState state;
int ifindex;
+ char *ifname;
sd_event *event;
int event_priority;
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__)
#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"
int event_priority;
sd_event_source *timeout_resend;
int ifindex;
+ char *ifname;
int fd;
uint16_t port;
union sockaddr_union link;
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,
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);
}
#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"
ordered_set_free(server->vendor_options);
free(server->bound_leases);
+
+ free(server->ifname);
return mfree(server);
}
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;
#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"
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];
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) {
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;
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;
ordered_hashmap_free(client->extra_options);
strv_free(client->user_class);
strv_free(client->vendor_class);
+ free(client->ifname);
return mfree(client);
}
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;
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;
#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"
int ifindex;
int fd;
- char ifname[IF_NAMESIZE + 1];
+ char *ifname;
unsigned n_iteration;
unsigned n_conflict;
};
#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__)
ipv4acd_reset(acd);
sd_ipv4acd_detach_event(acd);
-
+ free(acd->ifname);
return mfree(acd);
}
}
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;
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) {
};
#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__)
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;
#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"
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);
}
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;
}
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)
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 */
(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:
if (lldp->fd < 0)
return 0;
- log_lldp("Stopping LLDP client");
+ log_lldp(lldp, "Stopping LLDP client");
lldp_reset(lldp);
lldp_flush_neighbors(lldp);
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);
hashmap_free(lldp->neighbor_by_id);
prioq_free(lldp->neighbor_by_expiry);
+ free(lldp->ifname);
return mfree(lldp);
}
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;
}
#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"
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);
}
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);
ndisc_reset(nd);
sd_ndisc_detach_event(nd);
+ free(nd->ifname);
return mfree(nd);
}
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)
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);
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)
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;
}
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));
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);
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;
if (r < 0)
goto fail;
- log_ndisc("Started IPv6 Router Solicitation client");
+ log_ndisc(nd, "Started IPv6 Router Solicitation client");
return 1;
fail:
#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"
sd_radv_detach_event(ra);
ra->fd = safe_close(ra->fd);
+ free(ra->ifname);
return mfree(ra);
}
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;
}
}
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;
}
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;
}
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) {
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));
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);
ra->state = SD_RADV_STATE_ADVERTISING;
- log_radv("Started IPv6 Router Advertisement daemon");
+ log_radv(ra, "Started IPv6 Router Advertisement daemon");
return 0;
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);
(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);
ra->n_prefixes++;
if (!dynamic) {
- log_radv("Added prefix %s", strna(addr_p));
+ log_radv(ra, "Added prefix %s", strna(addr_p));
return 0;
}
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:
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),
(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);
ra->n_route_prefixes++;
if (!dynamic) {
- log_radv("Added prefix %s", strna(pretty));
+ log_radv(ra, "Added prefix %s", strna(pretty));
return 0;
}
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:
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));
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;
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;
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);
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);
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);
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);
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);
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);
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,
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;
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) {
* 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_
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;
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;
}
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;
}
int device_monitor_get_fd(sd_device_monitor *m) {
- assert_return(m, -EINVAL);
+ assert(m);
return m->sock;
}
_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 &&
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)
(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);
}
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;
bool is_initialized = false;
int r;
+ assert(m);
assert(ret);
buflen = recvmsg(m->sock, &smsg, 0);
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;
}
}
_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;
}
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;
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;
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");
}
}
- return 0;
+ return 1;
}
static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) {
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;
HASHMAP_FOREACH(s, e->child_sources) {
assert(s->type == SOURCE_CHILD);
+ if (s->priority > threshold)
+ continue;
+
if (s->pending)
continue;
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) {
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
n = read(d->fd, &si, sizeof(si));
if (n < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
- return read_one;
+ return 0;
return -errno;
}
assert(SIGNAL_VALID(si.ssi_signo));
- read_one = true;
-
if (e->signal_sources)
s = e->signal_sources[si.ssi_signo];
if (!s)
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);
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))
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;
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;
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))
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;
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++) {
assert(s);
+ if (s->priority > threshold)
+ continue;
+
+ min_priority = MIN(min_priority, s->priority);
+
switch (s->type) {
case SOURCE_IO:
}
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);
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;
}
#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"
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 */
#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,
};
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
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");
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) {
# 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]
#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;
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;
enum {
ARG_VERSION = 0x100,
ARG_ROOT,
+ ARG_IMAGE,
ARG_COMMIT,
ARG_PRINT,
};
{ "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 },
{}
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;
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;
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;
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;
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");
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));
}
}
}
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;
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);
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);
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;
}
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();
}
#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;
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);
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);
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;
}
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)) {
}
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;
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;
/* 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;
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)
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)
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)
}
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);
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");
#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"
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)
* 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)
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)
}
} 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);
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. */
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 {
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);
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;
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);
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);
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;
/* 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);
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
* 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;
}
}
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;
}
}
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);
}
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;
}
* 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;
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) {
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];
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) {
/* 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);
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;
/* 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);
* 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);
# 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]
}
}
+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;
"/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 },
};
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);
}
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();
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)
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
break;
label = mfree(label);
-
-
if (asprintf(&label, "%s-%u", prefix, ++k) < 0)
return log_oom();
}
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;
/* 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
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
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)
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;
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())
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 += [
#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"
#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"
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;
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);
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);
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);
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);
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. */
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);
}
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);
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;
+}
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) \
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;
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)
DnsResourceRecord *rr,
DnsAnswer *answer,
DnsPacket *full_packet,
+ uint32_t min_ttl,
uint64_t query_flags,
bool shared_owner,
DnssecResult dnssec_result,
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;
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);
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;
}
rr,
answer,
full_packet,
+ min_ttl,
query_flags,
shared_owner,
dnssec_result,
.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,
.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
* 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];
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;
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;
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;
}
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;
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;
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;
}
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
} 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)
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);
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));
}
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;
}
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;
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) {
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;
}
* 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;
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 */
enum {
DNS_QUERY_MATCH,
DNS_QUERY_NOMATCH,
- DNS_QUERY_RESTARTED,
+ DNS_QUERY_CNAME,
};
DnsQueryCandidate* dns_query_candidate_ref(DnsQueryCandidate*);
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);
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);
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);
+ }
+}
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) {
}
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);
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);
case DNS_TYPE_DNSKEY: {
_cleanup_free_ char *alg = NULL;
- char *ss;
uint16_t key_tag;
key_tag = dnssec_keytag(rr, true);
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,
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;
}
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 ? " " : "",
return NULL;
break;
- }
- case DNS_TYPE_OPENPGPKEY: {
+ case DNS_TYPE_OPENPGPKEY:
r = asprintf(&s, "%s", k);
if (r < 0)
return NULL;
if (r < 0)
return NULL;
break;
- }
default:
t = hexmem(rr->generic.data, rr->generic.data_size);
}
rr->to_string = s;
- return s;
+ return TAKE_PTR(s);
}
ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
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);
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;
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(
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,
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),
* 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");
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);
#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"
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)
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) &&
(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;
if (dns_packet_validate_reply(p) > 0) {
DnsResourceRecord *rr;
+ DnsTransaction *t;
log_debug("Got mDNS reply packet");
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
/* 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);
}
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+int resolve_system_hostname(char **full_hostname, char **first_label);
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);
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);
# 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]
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;
#include "alloc-util.h"
#include "ask-password-api.h"
+#include "creds-util.h"
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
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) {
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;
}
#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);
if (STR_IN_SET(field, "PIDFile",
"Type",
+ "ExitType",
"Restart",
"BusName",
"NotifyAccess",
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++;
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) {
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) {
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;
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;
*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) {
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;
#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,
/* 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;
}
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;
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;
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);
}
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);
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);
.architecture = architecture,
.node = TAKE_PTR(n),
.fstype = TAKE_PTR(t),
+ .label = TAKE_PTR(l),
.uuid = id,
.mount_options = TAKE_PTR(o),
};
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) {
}
}
+ /* 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;
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);
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);
}
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;
* -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)
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");
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));
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;
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");
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;
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;
_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) {
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 */
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 {
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;
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,
#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;
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;
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;
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;
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,
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);
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);
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);
+}
#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);
#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;
}
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,
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;
}
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,
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");
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;
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
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;
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(
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);
* 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);
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);
}
}
}
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);
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;
}
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) {
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);
}
/* 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;
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
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;
/* 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;
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. */
}
_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)
_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)
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);
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);
}
}
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);
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,
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);
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);
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);
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);
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);
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);
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);
#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"
#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"
}
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,
.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;
}
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 */
.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;
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);
[['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'],
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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);
#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;
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);
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;
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
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];
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);
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);
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);
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[]) {
#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"
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);
test_read_nul_string();
test_read_full_file_socket();
test_read_full_file_offset_size();
+ test_read_full_virtual_file();
return 0;
}
/* 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;
}
/* 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;
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;
}
return;
}
-
pid = fork();
assert_se(pid >= 0);
NULL,
NULL,
NULL,
- 0,
NULL);
assert_se(r == 0);
NULL,
NULL,
NULL,
- 0,
NULL);
if (r < 0) {
log_error_errno(r, "Failed to set up namespace: %m");
/* 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;
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;
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,
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,
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)];
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)];
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)];
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)];
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) } };
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);
addresses[i].family);
log_info(" ");
- dlclose(handle);
return 0;
}
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]);
"mymachines",
#endif
"dns");
- if (!modules)
- return -ENOMEM;
+ assert_se(modules);
if (argc > 2) {
char **name;
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 };
}
} 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;
}
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);
--- /dev/null
+/* 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);
}
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")));
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);
/* 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);
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);
}
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);
}
}
+#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);
test_genuine_random_bytes(RANDOM_ALLOW_INSECURE);
test_pseudo_random_bytes();
-
test_rdrand();
+ test_random_u64_range();
return 0;
}
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);
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);
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:
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;
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();
fprintf(f,
"\n[Service]\n"
"Type=exec\n"
+ "ExitType=cgroup\n"
"ExecStart=:%s\n"
"Restart=no\n"
"TimeoutSec=5s\n"
--- /dev/null
+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.
# SPDX-License-Identifier: LGPL-2.1-or-later
install_data(
+ 'README',
'50-default.conf',
install_dir : sysctldir)
--- /dev/null
+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.
# 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
--- /dev/null
+../TEST-01-BASIC/Makefile
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env bash
+set -e
+TEST_DESCRIPTION="test ExitType=cgroup"
+. $TEST_BASE_DIR/test-functions
+
+do_test "$@" 56
ExecStop=
ExecStopPost=
ExecStopPre=
+ExitType=
FailureAction=
FileDescriptorName=
FileDescriptorStoreMax=
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
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
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
--- /dev/null
+[Unit]
+Description=TEST-56-EXIT-TYPE
+
+[Service]
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+Type=oneshot
--- /dev/null
+#!/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
--- /dev/null
+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.
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
# 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
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
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
ProtectKernelModules=yes
ProtectKernelTunables=yes
ProtectSystem=strict
-ReadWritePaths=/etc
+ReadWritePaths=/etc@SERVICE_LOCALEGEN_WRITABLE@
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=yes
RestrictRealtime=yes
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