summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@strace.io>2023-03-09 08:00:00 +0000
committerDmitry V. Levin <ldv@strace.io>2023-03-10 17:10:41 +0000
commit0a7eda348ccf2e4591ac5db039482785fdd40021 (patch)
treeaca9746d8554b77b339e3adf2b255705f9744c17
parente8c53080c41e0e651bc33185148925b7f6be4441 (diff)
downloadsystemd-0a7eda348ccf2e4591ac5db039482785fdd40021.tar.gz
udevadm verify: introduce --root option
When udevadm verify is invoked without positional arguments and loads all rules files from the system like the udev daemon does, this option can be used to operate on files underneath the specified root path.
-rw-r--r--man/udevadm.xml5
-rw-r--r--shell-completion/bash/udevadm6
-rw-r--r--shell-completion/zsh/_udevadm1
-rw-r--r--src/udev/udevadm-verify.c33
4 files changed, 39 insertions, 6 deletions
diff --git a/man/udevadm.xml b/man/udevadm.xml
index bafd5af0fb..503ec81091 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -769,6 +769,11 @@
parsed. When set to <constant>never</constant>, names will
never be resolved.</para>
</listitem>
+ <term><option>--root=<replaceable>PATH</replaceable></option></term>
+ <listitem>
+ <para>When looking for udev rules files located in udev/rules.d directories,
+ operate on files underneath the specified root path <replaceable>PATH</replaceable>.</para>
+ </listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm
index b6e14e1d36..3c3c403153 100644
--- a/shell-completion/bash/udevadm
+++ b/shell-completion/bash/udevadm
@@ -64,7 +64,7 @@ _udevadm() {
[MONITOR_ARG]='-s --subsystem-match -t --tag-match'
[TEST]='-a --action -N --resolve-names'
[TEST_BUILTIN]='-a --action'
- [VERIFY]='-N --resolve-names'
+ [VERIFY]='-N --resolve-names --root'
[WAIT]='-t --timeout --initialized=no --removed --settle'
[LOCK]='-t --timeout -d --device -b --backing -p --print'
)
@@ -254,6 +254,10 @@ _udevadm() {
-N|--resolve-names)
comps='early never'
;;
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o dirnames
+ ;;
*)
comps=''
;;
diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm
index 074d367a9d..e8414eef67 100644
--- a/shell-completion/zsh/_udevadm
+++ b/shell-completion/zsh/_udevadm
@@ -108,6 +108,7 @@ _udevadm_test-builtin(){
_udevadm_verify(){
_arguments \
{-N+,--resolve-names=}'[When to resolve names.]:resolve:(early never)' \
+ '--root=[Operate on catalog hierarchy under specified directory]:directories:_directories' \
{-h,--help}'[Print help text.]' \
'*::files:_files'
}
diff --git a/src/udev/udevadm-verify.c b/src/udev/udevadm-verify.c
index f472892731..26f317711e 100644
--- a/src/udev/udevadm-verify.c
+++ b/src/udev/udevadm-verify.c
@@ -10,12 +10,17 @@
#include "conf-files.h"
#include "constants.h"
#include "log.h"
+#include "parse-argument.h"
#include "pretty-print.h"
+#include "static-destruct.h"
#include "strv.h"
#include "udev-rules.h"
#include "udevadm.h"
static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY;
+static char *arg_root = NULL;
+
+STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
static int help(void) {
_cleanup_free_ char *link = NULL;
@@ -30,6 +35,7 @@ static int help(void) {
" -h --help Show this help\n"
" -V --version Show package version\n"
" -N --resolve-names=early|never When to resolve names\n"
+ " --root=PATH Operate on an alternate filesystem root\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
@@ -40,14 +46,18 @@ static int help(void) {
}
static int parse_argv(int argc, char *argv[]) {
+ enum {
+ ARG_ROOT = 0x100,
+ };
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'V' },
- { "resolve-names", required_argument, NULL, 'N' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "resolve-names", required_argument, NULL, 'N' },
+ { "root", required_argument, NULL, ARG_ROOT },
{}
};
- int c;
+ int r, c;
assert(argc >= 0);
assert(argv);
@@ -71,12 +81,22 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_resolve_name_timing == RESOLVE_NAME_NEVER)
arg_resolve_name_timing = RESOLVE_NAME_LATE;
break;
+ case ARG_ROOT:
+ r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
+ if (r < 0)
+ return r;
+ break;
+
case '?':
return -EINVAL;
default:
assert_not_reached();
}
+ if (arg_root && optind < argc)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Combination of --root= and FILEs is not supported.");
+
return 1;
}
@@ -124,9 +144,12 @@ int verify_main(int argc, char *argv[], void *userdata) {
const char* const* rules_dirs = STRV_MAKE_CONST(CONF_PATHS("udev/rules.d"));
_cleanup_strv_free_ char **files = NULL;
- r = conf_files_list_strv(&files, ".rules", NULL, 0, rules_dirs);
+ r = conf_files_list_strv(&files, ".rules", arg_root, 0, rules_dirs);
if (r < 0)
return log_error_errno(r, "Failed to enumerate rules files: %m");
+ if (arg_root && strv_isempty(files))
+ return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
+ "No rules files found in %s", arg_root);
return verify_rules(rules, files);
}