]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevadm: beef up deprecation log warning
authorLennart Poettering <lennart@poettering.net>
Wed, 8 Jul 2020 15:51:55 +0000 (17:51 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 14 Jul 2020 12:57:19 +0000 (14:57 +0200)
Let's add a catalog entry explaining further details.

Most importantly though: talk to PID 1 directly, via the private D-Bus
socket, so that this actually works correctly during early boot, where
D-Bus is not around.

catalog/systemd.catalog.in
src/systemd/sd-messages.h
src/udev/udevadm-settle.c

index 1d3b62a2f49a43f4e2933aac956240a385e9805c..056df00de8fb8e938de7bb674521c8f33abea625 100644 (file)
@@ -484,3 +484,36 @@ It is strongly recommended to avoid running services under this user identity,
 in particular on systems using NFS or running containers. Allocate a user ID
 specific to this service, either statically via systemd-sysusers or dynamically
 via the DynamicUser= service setting.
+
+-- 1c0454c1bd2241e0ac6fefb4bc631433
+Subject: systemd-udev-settle.service is deprecated.
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Usage of the systemd service unit systemd-udev-settle.service is deprecated. It
+inserts artificial delays into the boot process without providing the
+guarantees other subsystems traditionally assumed it provides. Relying on this
+service is racy, and it is generally a bug to make use of it and depend on it.
+
+Traditionally, this service's job was to wait until all devices a system
+possesses have been fully probed and initialized, delaying boot until this
+phase is completed. However, today's systems and hardware generally don't work
+this way anymore, hardware today may show up any time and take any time to be
+probed and initialized. Thus, in the general case, it's no longer possible to
+correctly delay boot until "all devices" have been processed, as it is not
+clear what "all devices" means and when they have been found. This is in
+particular the case if USB hardware or network-attached hardware is used.
+
+Modern software that requires some specific hardware (such as a network device
+or block device) to operate should only wait for the specific devices it needs
+to show up, and otherwise operate asynchronously initializing devices as they
+appear during boot and during runtime without delaying the boot process.
+
+It is a defect of the software in question if it doesn't work this way, and
+still pulls systemd-udev-settle.service into the boot process.
+
+Please file a bug report against the following units, with a request for it to
+be updated to operate in a hotplug fashion without depending on
+systemd-udev-settle.service:
+
+    @OFFENDING_UNITS@
index 00846ea00bb8f59876d24fa579c3b3f9040b9053..a4e9680dc11ce4c8cf493a022878bd308edfda9e 100644 (file)
@@ -170,6 +170,11 @@ _SD_BEGIN_DECLARATIONS;
 #define SD_MESSAGE_NOBODY_USER_UNSUITABLE_STR \
                                           SD_ID128_MAKE_STR(b4,80,32,5f,9c,39,4a,7b,80,2c,23,1e,51,a2,75,2c)
 
+#define SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED \
+                                          SD_ID128_MAKE(1c,04,54,c1,bd,22,41,e0,ac,6f,ef,b4,bc,63,14,33)
+#define SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED_STR \
+                                          SD_ID128_MAKE_STR(1c,04,54,c1,bd,22,41,e0,ac,6f,ef,b4,bc,63,14,33)
+
 _SD_END_DECLARATIONS;
 
 #endif
index 5730349ba5df78ad28057831131402016b80d40d..66c7103d783ac729756319fa251518d3b06e8ec9 100644 (file)
@@ -14,7 +14,9 @@
 
 #include "sd-bus.h"
 #include "sd-login.h"
+#include "sd-messages.h"
 
+#include "bus-util.h"
 #include "io-util.h"
 #include "libudev-util.h"
 #include "string-util.h"
@@ -87,54 +89,69 @@ static int parse_argv(int argc, char *argv[]) {
 
 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;
+        _cleanup_strv_free_ char **a = NULL;
+        _cleanup_free_ char *unit = NULL;
         int r;
 
         r = sd_pid_get_unit(0, &unit);
-        if (r < 0 || !streq(unit, "systemd-udev-settle.service"))
+        if (r < 0) {
+                log_debug_errno(r, "Failed to determine unit we run in, ignoring: %m");
                 return 0;
+        }
 
-        log_notice("systemd-udev-settle.service is deprecated.");
+        if (!streq(unit, "systemd-udev-settle.service"))
+                return 0;
 
-        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);
+        r = bus_connect_system_systemd(&bus);
         if (r < 0)
-                return r;
+                log_debug_errno(r, "Failed to open connection to systemd, skipping dependency queries: %m");
+        else {
+                _cleanup_strv_free_ char **b = NULL;
+                _cleanup_free_ char *unit_path = NULL;
+
+                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)) {
+        if (strv_isempty(a))
+                /* Print a simple message if we cannot determine the dependencies */
+                log_notice("systemd-udev-settle.service is deprecated.");
+        else {
+                /* Print a longer, structured message if we can acquire the dependencies (this should be the
+                 * common case). This is hooked up with a catalog entry and everything. */
                 _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);
+                log_struct(LOG_NOTICE,
+                           "MESSAGE=systemd-udev-settle.service is deprecated. Please fix %s not to pull it in.", t,
+                           "OFFENDING_UNITS=%s", t,
+                           "MESSAGE_ID=" SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED_STR);
         }
 
         return 0;