diff --git a/man/rules/meson.build b/man/rules/meson.build index 6f9f4c4443..9674cbb30b 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -775,6 +775,7 @@ manpages = [ 'systemd-tmpfiles-setup.service'], ''], ['systemd-tty-ask-password-agent', '1', [], ''], + ['systemd-udev-settle.service', '8', [], ''], ['systemd-udevd.service', '8', ['systemd-udevd', diff --git a/man/systemd-udev-settle.service.xml b/man/systemd-udev-settle.service.xml new file mode 100644 index 0000000000..6fbd99111f --- /dev/null +++ b/man/systemd-udev-settle.service.xml @@ -0,0 +1,51 @@ + + + + + + + + systemd-udev-settle.service + systemd + + + + systemd-udev-settle.service + 8 + + + + systemd-udev-settle.service + Wait for all pending udev events to be handled + + + + systemd-udev-settle.service + + + Description + This service calls udevadm settle to wait until all events that have been queued + by udev7 have been + processed. It is a crude way to wait until "all" hardware has been discovered. Services may pull in this + service and order themselves after it to wait for the udev queue to be empty. + + Using this service is not recommended. There can be no guarantee that hardware + is fully discovered at any specific time, because the kernel does hardware detection asynchronously, and + certain busses and devices take a very long time to become ready, and also additional hardware may be + plugged in at any time. Instead, services should subscribe to udev events and react to any new hardware as + it is discovered. Services that, based on configuration, expect certain devices to appear, may warn or + report failure after a timeout. This timeout should be tailored to the hardware type. Waiting for + systemd-udev-settle.service usually slows boot significantly, because it means waiting + for all unrelated events too. + + + + See Also + + udev7, + udevadm8 + + + diff --git a/man/udevadm.xml b/man/udevadm.xml index 467402ca75..a591ab8c34 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -362,6 +362,10 @@ + + See + systemd-udev-settle.service8 + for more information. udevadm control <replaceable>option</replaceable> diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c index 9cf88b245c..1524808ffe 100644 --- a/src/udev/udevadm-settle.c +++ b/src/udev/udevadm-settle.c @@ -13,10 +13,16 @@ #include #include +#include "sd-bus.h" +#include "sd-login.h" + #include "libudev-util.h" +#include "string-util.h" +#include "strv.h" #include "time-util.h" -#include "udevadm.h" #include "udev-ctrl.h" +#include "udevadm.h" +#include "unit-def.h" #include "util.h" #include "virt.h" @@ -79,6 +85,61 @@ static int parse_argv(int argc, char *argv[]) { return 1; } +static int emit_deprecation_warning(void) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_free_ char *unit = NULL, *unit_path = NULL; + _cleanup_strv_free_ char **a = NULL, **b = NULL; + int r; + + r = sd_pid_get_unit(0, &unit); + if (r < 0 || !streq(unit, "systemd-udev-settle.service")) + return 0; + + log_notice("systemd-udev-settle.service is deprecated."); + + r = sd_bus_open_system(&bus); + if (r < 0) + return log_debug_errno(r, "Failed to open system bus, skipping dependency queries: %m"); + + unit_path = unit_dbus_path_from_name("systemd-udev-settle.service"); + if (!unit_path) + return -ENOMEM; + + (void) sd_bus_get_property_strv( + bus, + "org.freedesktop.systemd1", + unit_path, + "org.freedesktop.systemd1.Unit", + "WantedBy", + NULL, + &a); + + (void) sd_bus_get_property_strv( + bus, + "org.freedesktop.systemd1", + unit_path, + "org.freedesktop.systemd1.Unit", + "RequiredBy", + NULL, + &b); + + r = strv_extend_strv(&a, b, true); + if (r < 0) + return r; + + if (!strv_isempty(a)) { + _cleanup_free_ char *t = NULL; + + t = strv_join(a, ", "); + if (!t) + return -ENOMEM; + + log_notice("Hint: please fix %s not to pull it in.", t); + } + + return 0; +} + int settle_main(int argc, char *argv[], void *userdata) { _cleanup_(udev_queue_unrefp) struct udev_queue *queue = NULL; struct pollfd pfd; @@ -128,6 +189,8 @@ int settle_main(int argc, char *argv[], void *userdata) { .fd = r, }; + (void) emit_deprecation_warning(); + for (;;) { if (arg_exists && access(arg_exists, F_OK) >= 0) return 0; diff --git a/units/systemd-udev-settle.service.in b/units/systemd-udev-settle.service.in index c9e1c91852..22ebf08c51 100644 --- a/units/systemd-udev-settle.service.in +++ b/units/systemd-udev-settle.service.in @@ -13,7 +13,7 @@ [Unit] Description=udev Wait for Complete Device Initialization -Documentation=man:udev(7) man:systemd-udevd.service(8) +Documentation=man:systemd-udev-settle.service(8) DefaultDependencies=no Wants=systemd-udevd.service After=systemd-udev-trigger.service