summaryrefslogtreecommitdiff
path: root/src/udev/udevadm-trigger.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev/udevadm-trigger.c')
-rw-r--r--src/udev/udevadm-trigger.c55
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;