]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevadm: add --wait-daemon option to 'trigger' command
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 12 Jan 2019 23:10:12 +0000 (08:10 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 18 Jan 2019 15:10:01 +0000 (16:10 +0100)
man/udevadm.xml
src/udev/udevadm-trigger.c

index e6d4a1b10818c139716f0a9c229f9ec2e139d7fa..1aed86a164a5c560539f222110d1cf43ffdaafcc 100644 (file)
             the same command to finish.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><option>--wait-daemon[=<replaceable>SECONDS</replaceable>]</option></term>
+          <listitem>
+            <para>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 <command>udevadm control --ping</command> before <command>udevadm trigger</command>.</para>
+          </listitem>
+        </varlistentry>
 
         <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
index b0be6e802a98e764abcdfd48f122486bca1eff10..95329469e3899e0e7eded46de0b278f7ab25c7b9 100644 (file)
 #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;