udevadm-lock: use common verb help and add --introspect-cli

The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-control" option namespace. The synopsis
makes use of the new nulstr-argspec functionality:
  > udevadm [OPTION…] lock [OPTION…] COMMAND
  > udevadm [OPTION…] lock [OPTION…] --print
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-08-28 09:58:36 +02:00
parent e939427d5d
commit d8b733d6dd
3 changed files with 23 additions and 35 deletions
+8 -24
View File
@@ -4,14 +4,14 @@
#include <sys/stat.h>
#include <unistd.h>
#include "sd-json.h"
#include "blockdev-util.h"
#include "device-util.h"
#include "fd-util.h"
#include "fdset.h"
#include "format-table.h"
#include "glyph-util.h"
#include "hash-funcs.h"
#include "help-util.h"
#include "lock-util.h"
#include "options.h"
#include "path-util.h"
@@ -23,6 +23,7 @@
#include "strv.h"
#include "time-util.h"
#include "udevadm.h"
#include "verbs.h"
static usec_t arg_timeout_usec = USEC_INFINITY;
static char **arg_devices = NULL;
@@ -34,26 +35,6 @@ STATIC_DESTRUCTOR_REGISTER(arg_devices, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_backing, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_cmdline, strv_freep);
static int help(void) {
_cleanup_(table_unrefp) Table *options = NULL;
int r;
r = option_parser_get_help_table_ns("udevadm-lock", &options);
if (r < 0)
return r;
help_cmdline("lock [OPTIONS...] COMMAND");
help_cmdline("lock [OPTIONS...] --print");
help_abstract("Lock a block device and run a command.");
help_section("Options");
r = table_print_or_warn(options);
if (r < 0)
return r;
help_man_page_reference("udevadm", "8");
return 0;
}
static int parse_argv(int argc, char *argv[]) {
int r;
@@ -68,7 +49,7 @@ static int parse_argv(int argc, char *argv[]) {
OPTION_NAMESPACE("udevadm-lock"): {}
OPTION_COMMON_HELP:
return help();
return command_print_verb_help("lock");
OPTION('V', "version", NULL, "Show package version"):
return print_version();
@@ -97,9 +78,12 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(r, "Failed to parse --timeout= parameter: %s", opts.arg);
break;
OPTION('p', "print", NULL, "Only show which block device the lock would be taken on"):
OPTION('p', "print", NULL, "Only show which device would be locked, without running the command"):
arg_print = true;
break;
OPTION_COMMON_INTROSPECT_CLI:
return introspect_cli(SD_JSON_FORMAT_OFF);
}
char **args = option_parser_get_args(&opts);
+11 -11
View File
@@ -33,17 +33,17 @@ VERB_COMMON_HELP_AUTO_PROGRAM("udevadm");
#define UDEVADM_VERB(fn, name, args, flags, help, footer) \
VERB_SCOPE_NS_FULL(, fn, name, "udevadm-" name, args, VERB_ANY, VERB_ANY, flags, /* dat= */ 0, help, footer)
UDEVADM_VERB(verb_info_main, "info", "[DEVPATH|FILE]\0", 0, "Query sysfs or the udev database", NULL);
UDEVADM_VERB(verb_trigger_main, "trigger", "DEVPATH\0", 0, "Request events from the kernel", NULL);
UDEVADM_VERB(verb_settle_main, "settle", NULL, 0, "Wait for pending udev events", NULL);
UDEVADM_VERB(verb_control_main, "control", NULL, VERB_OPTION_REQUIRED, "Control the udev daemon", NULL);
UDEVADM_VERB(verb_monitor_main, "monitor", NULL, 0, "Listen to kernel and udev events", NULL);
UDEVADM_VERB(verb_test_main, "test", "DEVPATH\0", 0, "Test an event run", NULL);
UDEVADM_VERB(verb_builtin_main, "test-builtin", "COMMAND DEVPATH\0", 0, "Test a built-in command", NULL);
UDEVADM_VERB(verb_verify_main, "verify", "[FILE…]\0", 0, "Verify udev rules files", NULL);
UDEVADM_VERB(verb_cat_main, "cat", "[FILE…]\0", 0, "Show udev rules files", NULL);
UDEVADM_VERB(verb_wait_main, "wait", "DEVICE [DEVICE…]\0", 0, "Wait for device or device symlink", NULL);
UDEVADM_VERB(verb_lock_main, "lock", "COMMAND", 0, "Lock a block device", NULL);
UDEVADM_VERB(verb_info_main, "info", "[DEVPATH|FILE]\0", 0, "Query sysfs or the udev database", NULL);
UDEVADM_VERB(verb_trigger_main, "trigger", "DEVPATH\0", 0, "Request events from the kernel", NULL);
UDEVADM_VERB(verb_settle_main, "settle", NULL, 0, "Wait for pending udev events", NULL);
UDEVADM_VERB(verb_control_main, "control", NULL, VERB_OPTION_REQUIRED, "Control the udev daemon", NULL);
UDEVADM_VERB(verb_monitor_main, "monitor", NULL, 0, "Listen to kernel and udev events", NULL);
UDEVADM_VERB(verb_test_main, "test", "DEVPATH\0", 0, "Test an event run", NULL);
UDEVADM_VERB(verb_builtin_main, "test-builtin", "COMMAND DEVPATH\0", 0, "Test a built-in command", NULL);
UDEVADM_VERB(verb_verify_main, "verify", "[FILE…]\0", 0, "Verify udev rules files", NULL);
UDEVADM_VERB(verb_cat_main, "cat", "[FILE…]\0", 0, "Show udev rules files", NULL);
UDEVADM_VERB(verb_wait_main, "wait", "DEVICE [DEVICE…]\0", 0, "Wait for device or device symlink", NULL);
UDEVADM_VERB(verb_lock_main, "lock", "COMMAND\0--print\0", 0, "Lock a block device and run a command", NULL);
UDEVADM_VERB(verb_hwdb_main, "hwdb", NULL, VERB_DEPRECATED, "Update or query the hardware database",
"Verb 'hwdb' is deprecated. Use systemd-hwdb instead.");
@@ -218,6 +218,10 @@ udevadm --introspect-cli | jq -e \
'.commands[] | select(.names[0] == "udevadm") | .verbs[] |
select(.names[0] == "hwdb") | .isDeprecated == true'
# udevadm print has multiple argspecs. Check that we print them.
udevadm lock -h | grep -E '^> udevadm .* lock .* COMMAND$'
udevadm lock -h | grep -E '^> udevadm .* lock .* --print$'
# systemd is optionally a multicall binary that also provides systemd-executor
if [[ "$(readlink "$(command -v systemd-executor)" 2>/dev/null)" == systemd ]]; then
systemd --introspect-cli | jq -e \