1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Copyright © 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
12 #include <sys/signalfd.h>
15 #include "sd-device.h"
17 #include "device-private.h"
18 #include "device-util.h"
19 #include "format-util.h"
20 #include "path-util.h"
21 #include "string-util.h"
24 #include "terminal-util.h"
25 #include "udev-builtin.h"
26 #include "udev-event.h"
27 #include "udev-format.h"
28 #include "udevadm-util.h"
30 #include "user-util.h"
32 static sd_device_action_t arg_action
= SD_DEVICE_ADD
;
33 static ResolveNameTiming arg_resolve_name_timing
= RESOLVE_NAME_EARLY
;
34 static const char *arg_syspath
= NULL
;
36 static int help(void) {
38 printf("%s test [OPTIONS] DEVPATH\n\n"
39 "Test an event run.\n\n"
40 " -h --help Show this help\n"
41 " -V --version Show package version\n"
42 " -a --action=ACTION|help Set action string\n"
43 " -N --resolve-names=early|late|never When to resolve names\n",
44 program_invocation_short_name
);
49 static int parse_argv(int argc
, char *argv
[]) {
50 static const struct option options
[] = {
51 { "action", required_argument
, NULL
, 'a' },
52 { "resolve-names", required_argument
, NULL
, 'N' },
53 { "version", no_argument
, NULL
, 'V' },
54 { "help", no_argument
, NULL
, 'h' },
60 while ((c
= getopt_long(argc
, argv
, "a:N:Vh", options
, NULL
)) >= 0)
63 r
= parse_device_action(optarg
, &arg_action
);
65 return log_error_errno(r
, "Invalid action '%s'", optarg
);
70 arg_resolve_name_timing
= resolve_name_timing_from_string(optarg
);
71 if (arg_resolve_name_timing
< 0)
72 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
73 "--resolve-names= must be early, late or never");
76 return print_version();
85 arg_syspath
= argv
[optind
];
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "syspath parameter missing.");
92 int test_main(int argc
, char *argv
[], void *userdata
) {
93 _cleanup_(udev_rules_freep
) UdevRules
*rules
= NULL
;
94 _cleanup_(udev_event_freep
) UdevEvent
*event
= NULL
;
95 _cleanup_(sd_device_unrefp
) sd_device
*dev
= NULL
;
96 sigset_t mask
, sigmask_orig
;
101 r
= parse_argv(argc
, argv
);
105 printf("This program is for debugging only, it does not run any program\n"
106 "specified by a RUN key. It may show incorrect results, because\n"
107 "some values may be different, or not available at a simulation run.\n"
110 assert_se(sigprocmask(SIG_SETMASK
, NULL
, &sigmask_orig
) >= 0);
114 r
= udev_rules_load(&rules
, arg_resolve_name_timing
);
116 log_error_errno(r
, "Failed to read udev rules: %m");
120 r
= find_device_with_action(arg_syspath
, arg_action
, &dev
);
122 log_error_errno(r
, "Failed to open device '%s': %m", arg_syspath
);
126 /* don't read info from the db */
129 event
= udev_event_new(dev
, NULL
, EVENT_UDEVADM_TEST
);
131 assert_se(sigfillset(&mask
) >= 0);
132 assert_se(sigprocmask(SIG_SETMASK
, &mask
, &sigmask_orig
) >= 0);
134 udev_event_execute_rules(event
, rules
);
136 printf("%sProperties:%s\n", ansi_highlight(), ansi_normal());
137 FOREACH_DEVICE_PROPERTY(dev
, key
, value
)
138 printf(" %s=%s\n", key
, value
);
140 if (sd_device_get_tag_first(dev
)) {
141 printf("%sTags:%s\n", ansi_highlight(), ansi_normal());
142 FOREACH_DEVICE_TAG(dev
, tag
)
143 printf(" %s\n", tag
);
146 if (sd_device_get_devnum(dev
, NULL
) >= 0) {
148 if (sd_device_get_devlink_first(dev
)) {
150 device_get_devlink_priority(dev
, &prio
);
151 printf("%sDevice node symlinks:%s (priority=%i)\n", ansi_highlight(), ansi_normal(), prio
);
152 FOREACH_DEVICE_DEVLINK(dev
, devlink
)
153 printf(" %s\n", devlink
);
156 printf("%sInotify watch:%s\n %s\n", ansi_highlight(), ansi_normal(), enabled_disabled(event
->inotify_watch
));
158 uid_t uid
= event
->uid
;
159 if (!uid_is_valid(uid
))
160 (void) device_get_devnode_uid(dev
, &uid
);
161 if (uid_is_valid(uid
)) {
162 _cleanup_free_
char *user
= uid_to_name(uid
);
163 printf("%sDevice node owner:%s\n %s (uid="UID_FMT
")\n", ansi_highlight(), ansi_normal(), strna(user
), uid
);
166 gid_t gid
= event
->gid
;
167 if (!gid_is_valid(uid
))
168 (void) device_get_devnode_gid(dev
, &gid
);
169 if (gid_is_valid(gid
)) {
170 _cleanup_free_
char *group
= gid_to_name(gid
);
171 printf("%sDevice node group:%s\n %s (gid="GID_FMT
")\n", ansi_highlight(), ansi_normal(), strna(group
), gid
);
174 mode_t mode
= event
->mode
;
175 if (mode
== MODE_INVALID
)
176 (void) device_get_devnode_mode(dev
, &mode
);
177 if (mode
!= MODE_INVALID
)
178 printf("%sDevice node permission:%s\n %04o\n", ansi_highlight(), ansi_normal(), mode
);
180 if (!ordered_hashmap_isempty(event
->seclabel_list
)) {
181 const char *name
, *label
;
182 printf("%sDevice node security label:%s\n", ansi_highlight(), ansi_normal());
183 ORDERED_HASHMAP_FOREACH_KEY(label
, name
, event
->seclabel_list
)
184 printf(" %s : %s\n", name
, label
);
188 if (sd_device_get_ifindex(dev
, NULL
) >= 0) {
189 if (!isempty(event
->name
))
190 printf("%sNetwork interface name:%s\n %s\n", ansi_highlight(), ansi_normal(), event
->name
);
192 if (!strv_isempty(event
->altnames
)) {
194 printf("%sAlternative interface names:%s", ansi_highlight(), ansi_normal());
195 fputstrv(stdout
, event
->altnames
, "\n ", &space
);
200 if (!ordered_hashmap_isempty(event
->run_list
)) {
203 printf("%sQueued commands:%s\n", ansi_highlight(), ansi_normal());
204 ORDERED_HASHMAP_FOREACH_KEY(val
, command
, event
->run_list
) {
205 UdevBuiltinCommand builtin_cmd
= PTR_TO_UDEV_BUILTIN_CMD(val
);
207 if (builtin_cmd
!= _UDEV_BUILTIN_INVALID
)
208 printf(" RUN{builtin} : %s\n", command
);
210 printf(" RUN{program} : %s\n", command
);