udevadm trigger: introduce --prioritized-subsystem option

This commit is contained in:
Yu Watanabe 2022-03-05 00:23:13 +09:00
parent 3c5cc23a93
commit 873cf95c2f
4 changed files with 55 additions and 22 deletions

View file

@ -297,6 +297,19 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--prioritized-subsystem=<replaceable>SUBSYSTEM<optional>,<replaceable>SUBSYSTEM</replaceable></optional></replaceable></option></term>
<listitem>
<para>Takes a comma separated list of subsystems. When triggering events for devices, the
devices from the specified subsystems and their parents are triggered first. For example,
if <option>--prioritized-subsystem=block,net</option>, then firstly all block devices and
their parents are triggered, in the next all network devices and their parents are
triggered, and lastly the other devices are triggered. This option can be specified
multiple times, and in that case the lists of the subsystems will be merged. That is,
<option>--prioritized-subsystem=block --prioritized-subsystem=net</option> is equivalent to
<option>--prioritized-subsystem=block,net</option>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-s</option></term>
<term><option>--subsystem-match=<replaceable>SUBSYSTEM</replaceable></option></term>

View file

@ -54,7 +54,8 @@ _udevadm() {
[TRIGGER_STANDALONE]='-v --verbose -n --dry-run -q --quiet -w --settle --wait-daemon --uuid'
[TRIGGER_ARG]='-t --type -c --action -s --subsystem-match -S --subsystem-nomatch
-a --attr-match -A --attr-nomatch -p --property-match
-g --tag-match -y --sysname-match --name-match -b --parent-match'
-g --tag-match -y --sysname-match --name-match -b --parent-match
--prioritized-subsystem'
[SETTLE]='-t --timeout -E --exit-if-exists'
[CONTROL_STANDALONE]='-e --exit -s --stop-exec-queue -S --start-exec-queue -R --reload --ping'
[CONTROL_ARG]='-l --log-priority -p --property -m --children-max -t --timeout'

View file

@ -34,7 +34,8 @@ _udevadm_trigger(){
'--tag-match=property[Trigger events for devices with a matching tag.]' \
'--sysname-match=[Trigger events for devices with a matching sys device name.]' \
'--parent-match=[Trigger events for all children of a given device.]' \
'--uuid[Print synthetic uevent UUID.]'
'--uuid[Print synthetic uevent UUID.]' \
'--prioritized-subsystem=[Trigger events for devices which belong to a matching subsystem earlier.]'
}
(( $+functions[_udevadm_settle] )) ||

View file

@ -229,7 +229,9 @@ static int help(void) {
" -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"
" --uuid Print synthetic uevent UUID\n",
" --uuid Print synthetic uevent UUID\n"
" --prioritized-subsystem=SUBSYSTEM[,SUBSYSTEM…]\n"
" Trigger devices from a matching subsystem first\n",
program_invocation_short_name);
return 0;
@ -240,28 +242,30 @@ int trigger_main(int argc, char *argv[], void *userdata) {
ARG_NAME = 0x100,
ARG_PING,
ARG_UUID,
ARG_PRIORITIZED_SUBSYSTEM,
};
static const struct option options[] = {
{ "verbose", no_argument, NULL, 'v' },
{ "dry-run", no_argument, NULL, 'n' },
{ "quiet", no_argument, NULL, 'q' },
{ "type", required_argument, NULL, 't' },
{ "action", required_argument, NULL, 'c' },
{ "subsystem-match", required_argument, NULL, 's' },
{ "subsystem-nomatch", required_argument, NULL, 'S' },
{ "attr-match", required_argument, NULL, 'a' },
{ "attr-nomatch", required_argument, NULL, 'A' },
{ "property-match", required_argument, NULL, 'p' },
{ "tag-match", required_argument, NULL, 'g' },
{ "sysname-match", required_argument, NULL, 'y' },
{ "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' },
{ "uuid", no_argument, NULL, ARG_UUID },
{ "verbose", no_argument, NULL, 'v' },
{ "dry-run", no_argument, NULL, 'n' },
{ "quiet", no_argument, NULL, 'q' },
{ "type", required_argument, NULL, 't' },
{ "action", required_argument, NULL, 'c' },
{ "subsystem-match", required_argument, NULL, 's' },
{ "subsystem-nomatch", required_argument, NULL, 'S' },
{ "attr-match", required_argument, NULL, 'a' },
{ "attr-nomatch", required_argument, NULL, 'A' },
{ "property-match", required_argument, NULL, 'p' },
{ "tag-match", required_argument, NULL, 'g' },
{ "sysname-match", required_argument, NULL, 'y' },
{ "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' },
{ "uuid", no_argument, NULL, ARG_UUID },
{ "prioritized-subsystem", required_argument, NULL, ARG_PRIORITIZED_SUBSYSTEM },
{}
};
enum {
@ -405,6 +409,20 @@ int trigger_main(int argc, char *argv[], void *userdata) {
arg_uuid = true;
break;
case ARG_PRIORITIZED_SUBSYSTEM: {
_cleanup_strv_free_ char **subsystems = NULL;
subsystems = strv_split(optarg, ",");
if (!subsystems)
return log_error_errno(r, "Failed to parse prioritized subsystem '%s': %m", optarg);
STRV_FOREACH(p, subsystems) {
r = device_enumerator_add_prioritized_subsystem(e, *p);
if (r < 0)
return log_error_errno(r, "Failed to add prioritized subsystem '%s': %m", *p);
}
break;
}
case 'V':
return print_version();
case 'h':