#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"
(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)
#include "strv.h"
#include "udevadm.h"
#include "udevadm-util.h"
-#include "udev-ctrl.h"
#include "virt.h"
static bool arg_verbose = false;
}
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++) {
#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;
*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 */
+}
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);