]>
Commit | Line | Data |
---|---|---|
e7145211 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
bb051f66 | 2 | /* |
810adae9 | 3 | * Copyright © 2003-2004 Greg Kroah-Hartman <greg@kroah.com> |
bb051f66 GKH |
4 | */ |
5 | ||
bb051f66 | 6 | #include <errno.h> |
eff4a673 | 7 | #include <getopt.h> |
07630cea LP |
8 | #include <signal.h> |
9 | #include <stddef.h> | |
10 | #include <stdio.h> | |
11 | #include <stdlib.h> | |
2181d30a | 12 | #include <sys/signalfd.h> |
07630cea | 13 | #include <unistd.h> |
bb051f66 | 14 | |
77ad202c YW |
15 | #include "sd-device.h" |
16 | ||
17 | #include "device-private.h" | |
18 | #include "device-util.h" | |
5ea78a39 | 19 | #include "libudev-util.h" |
07630cea | 20 | #include "string-util.h" |
5ea78a39 | 21 | #include "strxcpyx.h" |
07a26e42 | 22 | #include "udev-builtin.h" |
25de7aa7 | 23 | #include "udev-event.h" |
3d05193e | 24 | #include "udevadm.h" |
bb051f66 | 25 | |
89e94ad3 | 26 | static const char *arg_action = "add"; |
c4d44cba | 27 | static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; |
89e94ad3 YW |
28 | static char arg_syspath[UTIL_PATH_SIZE] = {}; |
29 | ||
30 | static int help(void) { | |
5ac0162c | 31 | |
5639df9a YW |
32 | printf("%s test [OPTIONS] DEVPATH\n\n" |
33 | "Test an event run.\n\n" | |
5ac0162c | 34 | " -h --help Show this help\n" |
5639df9a | 35 | " -V --version Show package version\n" |
6d22bd87 | 36 | " -a --action=ACTION|help Set action string\n" |
5ac0162c LP |
37 | " -N --resolve-names=early|late|never When to resolve names\n" |
38 | , program_invocation_short_name); | |
5ac0162c | 39 | |
89e94ad3 YW |
40 | return 0; |
41 | } | |
912541b0 | 42 | |
89e94ad3 | 43 | static int parse_argv(int argc, char *argv[]) { |
912541b0 | 44 | static const struct option options[] = { |
5639df9a | 45 | { "action", required_argument, NULL, 'a' }, |
912541b0 | 46 | { "resolve-names", required_argument, NULL, 'N' }, |
5639df9a YW |
47 | { "version", no_argument, NULL, 'V' }, |
48 | { "help", no_argument, NULL, 'h' }, | |
912541b0 KS |
49 | {} |
50 | }; | |
51 | ||
89e94ad3 | 52 | int c; |
912541b0 | 53 | |
5639df9a | 54 | while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0) |
7643ac9a | 55 | switch (c) { |
a12b87f5 YW |
56 | case 'a': { |
57 | DeviceAction a; | |
58 | ||
6d22bd87 YW |
59 | if (streq(optarg, "help")) { |
60 | dump_device_action_table(); | |
61 | return 0; | |
62 | } | |
63 | ||
a12b87f5 YW |
64 | a = device_action_from_string(optarg); |
65 | if (a < 0) | |
66 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), | |
67 | "Invalid action '%s'", optarg); | |
68 | ||
89e94ad3 | 69 | arg_action = optarg; |
912541b0 | 70 | break; |
a12b87f5 | 71 | } |
912541b0 | 72 | case 'N': |
c4d44cba | 73 | arg_resolve_name_timing = resolve_name_timing_from_string(optarg); |
baaa35ad ZJS |
74 | if (arg_resolve_name_timing < 0) |
75 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), | |
76 | "--resolve-names= must be early, late or never"); | |
912541b0 | 77 | break; |
5639df9a | 78 | case 'V': |
51b006e1 | 79 | return print_version(); |
912541b0 | 80 | case 'h': |
89e94ad3 | 81 | return help(); |
7643ac9a | 82 | case '?': |
89e94ad3 | 83 | return -EINVAL; |
7643ac9a ZJS |
84 | default: |
85 | assert_not_reached("Unknown option"); | |
912541b0 | 86 | } |
912541b0 | 87 | |
baaa35ad ZJS |
88 | if (!argv[optind]) |
89 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), | |
90 | "syspath parameter missing."); | |
912541b0 | 91 | |
89e94ad3 YW |
92 | /* add /sys if needed */ |
93 | if (!startswith(argv[optind], "/sys")) | |
94 | strscpyl(arg_syspath, sizeof(arg_syspath), "/sys", argv[optind], NULL); | |
95 | else | |
96 | strscpy(arg_syspath, sizeof(arg_syspath), argv[optind]); | |
97 | ||
98 | return 1; | |
99 | } | |
100 | ||
101 | int test_main(int argc, char *argv[], void *userdata) { | |
9a07157d | 102 | _cleanup_(udev_rules_freep) UdevRules *rules = NULL; |
2e088715 | 103 | _cleanup_(udev_event_freep) UdevEvent *event = NULL; |
77ad202c YW |
104 | _cleanup_(sd_device_unrefp) sd_device *dev = NULL; |
105 | const char *cmd, *key, *value; | |
89e94ad3 | 106 | sigset_t mask, sigmask_orig; |
29448498 YW |
107 | Iterator i; |
108 | void *val; | |
89e94ad3 YW |
109 | int r; |
110 | ||
111 | log_set_max_level(LOG_DEBUG); | |
112 | ||
113 | r = parse_argv(argc, argv); | |
114 | if (r <= 0) | |
115 | return r; | |
116 | ||
baa30fbc | 117 | printf("This program is for debugging only, it does not run any program\n" |
912541b0 KS |
118 | "specified by a RUN key. It may show incorrect results, because\n" |
119 | "some values may be different, or not available at a simulation run.\n" | |
120 | "\n"); | |
121 | ||
babdf0d3 | 122 | assert_se(sigprocmask(SIG_SETMASK, NULL, &sigmask_orig) >= 0); |
912541b0 | 123 | |
2024ed61 | 124 | udev_builtin_init(); |
912541b0 | 125 | |
c238a1f5 | 126 | r = udev_rules_load(&rules, arg_resolve_name_timing); |
1d791281 ZJS |
127 | if (r < 0) { |
128 | log_error_errno(r, "Failed to read udev rules: %m"); | |
912541b0 KS |
129 | goto out; |
130 | } | |
131 | ||
77ad202c YW |
132 | r = device_new_from_synthetic_event(&dev, arg_syspath, arg_action); |
133 | if (r < 0) { | |
134 | log_error_errno(r, "Failed to open device '%s': %m", arg_syspath); | |
912541b0 KS |
135 | goto out; |
136 | } | |
137 | ||
bf0e00ec | 138 | /* don't read info from the db */ |
77ad202c | 139 | device_seal(dev); |
912541b0 | 140 | |
77ad202c | 141 | event = udev_event_new(dev, 0, NULL); |
912541b0 | 142 | |
a3ebe5eb YW |
143 | assert_se(sigfillset(&mask) >= 0); |
144 | assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0); | |
912541b0 | 145 | |
e2099267 | 146 | udev_event_execute_rules(event, 60 * USEC_PER_SEC, SIGKILL, NULL, rules); |
912541b0 | 147 | |
77ad202c YW |
148 | FOREACH_DEVICE_PROPERTY(dev, key, value) |
149 | printf("%s=%s\n", key, value); | |
912541b0 | 150 | |
39a15c8a | 151 | ORDERED_HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) { |
1ea97217 | 152 | char program[UTIL_PATH_SIZE]; |
912541b0 | 153 | |
5eb6ef8b | 154 | (void) udev_event_apply_format(event, cmd, program, sizeof(program), false); |
1ea97217 | 155 | printf("run: '%s'\n", program); |
912541b0 | 156 | } |
89e94ad3 YW |
157 | |
158 | r = 0; | |
2181d30a | 159 | out: |
2024ed61 | 160 | udev_builtin_exit(); |
89e94ad3 | 161 | return r; |
bb051f66 | 162 | } |