From 2001622c58c1989f386086d11bd2a00d5fe00a30 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jan 2019 08:10:12 +0900 Subject: [PATCH] udevadm: add --wait-daemon option to 'trigger' command --- man/udevadm.xml | 8 ++++++++ src/udev/udevadm-trigger.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/man/udevadm.xml b/man/udevadm.xml index e6d4a1b108..1aed86a164 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -319,6 +319,14 @@ the same command to finish. + + + + Before triggering uevents, wait for systemd-udevd daemon to be initialized. + Optionally takes timeout value. Default timeout is 5 seconds. This is equivalent to invoke + invoking udevadm control --ping before udevadm trigger. + + diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index b0be6e802a..95329469e3 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -10,11 +10,13 @@ #include "fd-util.h" #include "fileio.h" #include "path-util.h" +#include "process-util.h" #include "set.h" #include "string-util.h" #include "strv.h" #include "udevadm.h" #include "udevadm-util.h" +#include "udev-ctrl.h" #include "virt.h" static bool arg_verbose = false; @@ -118,6 +120,8 @@ static int help(void) { " --name-match=NAME Trigger devices with this /dev name\n" " -b --parent-match=NAME Trigger devices with that parent device\n" " -w --settle Wait for the triggered events to complete\n" + " --wait-daemon[=SECONDS] Wait for udevd daemon to be initialized\n" + " before triggering uevents\n" , program_invocation_short_name); return 0; @@ -126,6 +130,7 @@ static int help(void) { int trigger_main(int argc, char *argv[], void *userdata) { enum { ARG_NAME = 0x100, + ARG_PING, }; static const struct option options[] = { @@ -143,6 +148,7 @@ int trigger_main(int argc, char *argv[], void *userdata) { { "name-match", required_argument, NULL, ARG_NAME }, { "parent-match", required_argument, NULL, 'b' }, { "settle", no_argument, NULL, 'w' }, + { "wait-daemon", optional_argument, NULL, ARG_PING }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, {} @@ -156,7 +162,8 @@ int trigger_main(int argc, char *argv[], void *userdata) { _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; _cleanup_set_free_free_ Set *settle_set = NULL; - bool settle = false; + usec_t ping_timeout_usec = 5 * USEC_PER_SEC; + bool settle = false, ping = false; int c, r; if (running_in_chroot() > 0) { @@ -271,6 +278,16 @@ int trigger_main(int argc, char *argv[], void *userdata) { break; } + case ARG_PING: { + ping = true; + if (optarg) { + r = parse_sec(optarg, &ping_timeout_usec); + if (r < 0) + log_error_errno(r, "Failed to parse timeout value '%s', ignoring: %m", optarg); + } + break; + } + case 'V': return print_version(); case 'h': @@ -282,6 +299,24 @@ int trigger_main(int argc, char *argv[], void *userdata) { } } + if (!arg_dry_run || ping) { + r = must_be_root(); + if (r < 0) + return r; + } + + if (ping) { + _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *uctrl = NULL; + + uctrl = udev_ctrl_new(); + if (!uctrl) + return log_oom(); + + r = udev_ctrl_send_ping(uctrl, ping_timeout_usec); + if (r < 0) + return log_error_errno(r, "Failed to connect to udev daemon: %m"); + } + for (; optind < argc; optind++) { _cleanup_(sd_device_unrefp) sd_device *dev = NULL;