diff options
Diffstat (limited to 'src/udev/udevadm-trigger.c')
-rw-r--r-- | src/udev/udevadm-trigger.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index f13a08f3f9..95329469e3 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -10,11 +10,14 @@ #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; static bool arg_dry_run = false; @@ -117,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; @@ -125,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[] = { @@ -142,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' }, {} @@ -155,9 +162,15 @@ 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) { + log_info("Running in chroot, ignoring request."); + return 0; + } + r = sd_device_enumerator_new(&e); if (r < 0) return r; @@ -182,18 +195,14 @@ int trigger_main(int argc, char *argv[], void *userdata) { device_type = TYPE_DEVICES; else if (streq(optarg, "subsystems")) device_type = TYPE_SUBSYSTEMS; - else { - log_error("Unknown type --type=%s", optarg); - return -EINVAL; - } + else + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown type --type=%s", optarg); break; case 'c': if (STR_IN_SET(optarg, "add", "remove", "change")) action = optarg; - else { - log_error("Unknown action '%s'", optarg); - return -EINVAL; - } + else + log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown action '%s'", optarg); break; case 's': @@ -269,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': @@ -280,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; |