]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevadm: use varlink connection to send ping
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 21 Dec 2024 21:53:43 +0000 (06:53 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 7 Jan 2025 11:31:15 +0000 (20:31 +0900)
src/udev/udevadm-settle.c
src/udev/udevadm-trigger.c
src/udev/udevadm-util.c
src/udev/udevadm-util.h

index d47a9c3a07f2367758ba0964cbce6df2a4d9a272..72e09e0fc567d2e989084483e5028b0f1b789624 100644 (file)
@@ -16,8 +16,8 @@
 #include "path-util.h"
 #include "strv.h"
 #include "time-util.h"
-#include "udev-ctrl.h"
 #include "udev-util.h"
+#include "udevadm-util.h"
 #include "udevadm.h"
 #include "unit-def.h"
 #include "virt.h"
@@ -198,23 +198,9 @@ int settle_main(int argc, char *argv[], void *userdata) {
         (void) emit_deprecation_warning();
 
         if (getuid() == 0) {
-                _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL;
-
-                /* guarantee that the udev daemon isn't pre-processing */
-
-                r = udev_ctrl_new(&uctrl);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to create control socket for udev daemon: %m");
-
-                r = udev_ctrl_send_ping(uctrl);
-                if (r < 0) {
-                        log_debug_errno(r, "Failed to connect to udev daemon, ignoring: %m");
-                        return 0;
-                }
-
-                r = udev_ctrl_wait(uctrl, MAX(5 * USEC_PER_SEC, arg_timeout_usec));
-                if (r < 0)
-                        return log_error_errno(r, "Failed to wait for daemon to reply: %m");
+                r = udev_ping(MAX(5 * USEC_PER_SEC, arg_timeout_usec), /* ignore_connection_failure = */ true);
+                if (r <= 0)
+                        return r;
         } else {
                 /* For non-privileged users, at least check if udevd is running. */
                 if (access("/run/udev/control", F_OK) < 0)
index 695f440b8f3267e59ca8f836cbac5a5f0c901608..808c383e21d7080ac71f627637a35dd01799212b 100644 (file)
@@ -21,7 +21,6 @@
 #include "strv.h"
 #include "udevadm.h"
 #include "udevadm-util.h"
-#include "udev-ctrl.h"
 #include "virt.h"
 
 static bool arg_verbose = false;
@@ -498,19 +497,10 @@ int trigger_main(int argc, char *argv[], void *userdata) {
         }
 
         if (ping) {
-                _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL;
-
-                r = udev_ctrl_new(&uctrl);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to initialize udev control: %m");
-
-                r = udev_ctrl_send_ping(uctrl);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to connect to udev daemon: %m");
-
-                r = udev_ctrl_wait(uctrl, ping_timeout_usec);
+                r = udev_ping(ping_timeout_usec, /* ignore_connection_failure = */ false);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to wait for daemon to reply: %m");
+                        return r;
+                assert(r > 0);
         }
 
         for (; optind < argc; optind++) {
index 2447edad1929b68949a86b8d5a05eab397290150..2a3e974d0484970028af6a76f30a3cc2ee5c9d71 100644 (file)
@@ -7,8 +7,11 @@
 #include "bus-util.h"
 #include "device-private.h"
 #include "path-util.h"
+#include "udev-ctrl.h"
+#include "udev-varlink.h"
 #include "udevadm-util.h"
 #include "unit-name.h"
+#include "varlink-util.h"
 
 static int find_device_from_unit(const char *unit_name, sd_device **ret) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -122,3 +125,46 @@ int parse_device_action(const char *str, sd_device_action_t *action) {
         *action = a;
         return 1;
 }
+
+static int udev_ping_via_ctrl(usec_t timeout_usec, bool ignore_connection_failure) {
+        _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL;
+        int r;
+
+        r = udev_ctrl_new(&uctrl);
+        if (r < 0)
+                return log_error_errno(r, "Failed to initialize udev control: %m");
+
+        r = udev_ctrl_send_ping(uctrl);
+        if (r < 0) {
+                bool ignore = ignore_connection_failure && (ERRNO_IS_NEG_DISCONNECT(r) || r == -ENOENT);
+                log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
+                               "Failed to connect to udev daemon%s: %m",
+                               ignore ? ", ignoring" : "");
+                return ignore ? 0 : r;
+        }
+
+        r = udev_ctrl_wait(uctrl, timeout_usec);
+        if (r < 0)
+                return log_error_errno(r, "Failed to wait for daemon to reply: %m");
+
+        return 1; /* received reply */
+}
+
+int udev_ping(usec_t timeout_usec, bool ignore_connection_failure) {
+        _cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *link = NULL;
+        int r;
+
+        r = udev_varlink_connect(&link, timeout_usec);
+        if (ERRNO_IS_NEG_DISCONNECT(r) || r == -ENOENT) {
+                log_debug_errno(r, "Failed to connect to udev via varlink, falling back to use legacy control socket, ignoring: %m");
+                return udev_ping_via_ctrl(timeout_usec, ignore_connection_failure);
+        }
+        if (r < 0)
+                return log_error_errno(r, "Failed to connect to udev via varlink: %m");
+
+        r = varlink_call_and_log(link, "io.systemd.service.Ping", /* parameters = */ NULL, /* reply = */ NULL);
+        if (r < 0)
+                return r;
+
+        return 1; /* received reply */
+}
index 7fb4556413475b2b7ed44a203a35f72d522bebcf..4b58efbe97a39e8d3ad9b0c78df625551b01c545 100644 (file)
@@ -6,3 +6,4 @@
 int find_device(const char *id, const char *prefix, sd_device **ret);
 int find_device_with_action(const char *id, sd_device_action_t action, sd_device **ret);
 int parse_device_action(const char *str, sd_device_action_t *action);
+int udev_ping(usec_t timeout, bool ignore_connection_failure);