udevadm: use varlink connection to send ping

This commit is contained in:
Yu Watanabe
2025-01-07 20:31:15 +09:00
parent 4e4c2fcfb6
commit 3fed28b8cb
4 changed files with 54 additions and 31 deletions
+4 -18
View 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)
+3 -13
View 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);
r = udev_ping(ping_timeout_usec, /* ignore_connection_failure = */ false);
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);
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++) {
+46
View 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 */
}
+1
View 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);