]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/udev/udevadm-test.c
tree-wide: Use log_setup() everywhere
[thirdparty/systemd.git] / src / udev / udevadm-test.c
CommitLineData
f13467ec 1/* SPDX-License-Identifier: GPL-2.0-or-later */
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"
03b6879f 19#include "format-util.h"
25f3b272 20#include "path-util.h"
07630cea 21#include "string-util.h"
03b6879f 22#include "strv.h"
5ea78a39 23#include "strxcpyx.h"
03b6879f 24#include "terminal-util.h"
07a26e42 25#include "udev-builtin.h"
25de7aa7 26#include "udev-event.h"
0b76cc2f 27#include "udev-format.h"
d1429d8f 28#include "udevadm-util.h"
3d05193e 29#include "udevadm.h"
03b6879f 30#include "user-util.h"
bb051f66 31
d1429d8f 32static sd_device_action_t arg_action = SD_DEVICE_ADD;
c4d44cba 33static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY;
d1429d8f 34static const char *arg_syspath = NULL;
89e94ad3
YW
35
36static int help(void) {
5ac0162c 37
5639df9a
YW
38 printf("%s test [OPTIONS] DEVPATH\n\n"
39 "Test an event run.\n\n"
5ac0162c 40 " -h --help Show this help\n"
5639df9a 41 " -V --version Show package version\n"
6d22bd87 42 " -a --action=ACTION|help Set action string\n"
bc556335
DDM
43 " -N --resolve-names=early|late|never When to resolve names\n",
44 program_invocation_short_name);
5ac0162c 45
89e94ad3
YW
46 return 0;
47}
912541b0 48
89e94ad3 49static int parse_argv(int argc, char *argv[]) {
912541b0 50 static const struct option options[] = {
5639df9a 51 { "action", required_argument, NULL, 'a' },
912541b0 52 { "resolve-names", required_argument, NULL, 'N' },
5639df9a
YW
53 { "version", no_argument, NULL, 'V' },
54 { "help", no_argument, NULL, 'h' },
912541b0
KS
55 {}
56 };
57
6de7fa87 58 int r, c;
912541b0 59
5639df9a 60 while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0)
7643ac9a 61 switch (c) {
6de7fa87
YW
62 case 'a':
63 r = parse_device_action(optarg, &arg_action);
64 if (r < 0)
65 return log_error_errno(r, "Invalid action '%s'", optarg);
66 if (r == 0)
6d22bd87 67 return 0;
912541b0
KS
68 break;
69 case 'N':
c4d44cba 70 arg_resolve_name_timing = resolve_name_timing_from_string(optarg);
baaa35ad
ZJS
71 if (arg_resolve_name_timing < 0)
72 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
73 "--resolve-names= must be early, late or never");
912541b0 74 break;
5639df9a 75 case 'V':
51b006e1 76 return print_version();
912541b0 77 case 'h':
89e94ad3 78 return help();
7643ac9a 79 case '?':
89e94ad3 80 return -EINVAL;
7643ac9a 81 default:
04499a70 82 assert_not_reached();
912541b0 83 }
912541b0 84
d1429d8f
YW
85 arg_syspath = argv[optind];
86 if (!arg_syspath)
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "syspath parameter missing.");
89e94ad3
YW
88
89 return 1;
90}
91
92int test_main(int argc, char *argv[], void *userdata) {
9a07157d 93 _cleanup_(udev_rules_freep) UdevRules *rules = NULL;
2e088715 94 _cleanup_(udev_event_freep) UdevEvent *event = NULL;
77ad202c 95 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
89e94ad3
YW
96 sigset_t mask, sigmask_orig;
97 int r;
98
aa976d87 99 log_setup();
89e94ad3
YW
100
101 r = parse_argv(argc, argv);
102 if (r <= 0)
103 return r;
104
baa30fbc 105 printf("This program is for debugging only, it does not run any program\n"
912541b0
KS
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"
108 "\n");
109
babdf0d3 110 assert_se(sigprocmask(SIG_SETMASK, NULL, &sigmask_orig) >= 0);
912541b0 111
2024ed61 112 udev_builtin_init();
912541b0 113
c238a1f5 114 r = udev_rules_load(&rules, arg_resolve_name_timing);
1d791281
ZJS
115 if (r < 0) {
116 log_error_errno(r, "Failed to read udev rules: %m");
912541b0
KS
117 goto out;
118 }
119
d1429d8f 120 r = find_device_with_action(arg_syspath, arg_action, &dev);
77ad202c
YW
121 if (r < 0) {
122 log_error_errno(r, "Failed to open device '%s': %m", arg_syspath);
912541b0
KS
123 goto out;
124 }
125
bf0e00ec 126 /* don't read info from the db */
77ad202c 127 device_seal(dev);
912541b0 128
089bef66 129 event = udev_event_new(dev, NULL, EVENT_UDEVADM_TEST);
912541b0 130
a3ebe5eb
YW
131 assert_se(sigfillset(&mask) >= 0);
132 assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0);
912541b0 133
eb1a51b8 134 udev_event_execute_rules(event, rules);
912541b0 135
03b6879f 136 printf("%sProperties:%s\n", ansi_highlight(), ansi_normal());
77ad202c 137 FOREACH_DEVICE_PROPERTY(dev, key, value)
03b6879f 138 printf(" %s=%s\n", key, value);
912541b0 139
03b6879f
YW
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);
144 }
145
146 if (sd_device_get_devnum(dev, NULL) >= 0) {
147
148 if (sd_device_get_devlink_first(dev)) {
149 int prio;
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);
154 }
155
156 printf("%sInotify watch:%s\n %s\n", ansi_highlight(), ansi_normal(), enabled_disabled(event->inotify_watch));
157
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);
164 }
165
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);
172 }
173
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);
e17e438e
YW
179
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);
185 }
03b6879f
YW
186 }
187
188 if (sd_device_get_ifindex(dev, NULL) >= 0) {
189 if (!isempty(event->name))
6a363a83 190 printf("%sNetwork interface name:%s\n %s\n", ansi_highlight(), ansi_normal(), event->name);
912541b0 191
03b6879f
YW
192 if (!strv_isempty(event->altnames)) {
193 bool space = true;
194 printf("%sAlternative interface names:%s", ansi_highlight(), ansi_normal());
195 fputstrv(stdout, event->altnames, "\n ", &space);
196 puts("");
197 }
198 }
199
200 if (!ordered_hashmap_isempty(event->run_list)) {
201 void *val;
202 const char *command;
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);
206
207 if (builtin_cmd != _UDEV_BUILTIN_INVALID)
208 printf(" RUN{builtin} : %s\n", command);
209 else
210 printf(" RUN{program} : %s\n", command);
211 }
912541b0 212 }
89e94ad3
YW
213
214 r = 0;
2181d30a 215out:
2024ed61 216 udev_builtin_exit();
89e94ad3 217 return r;
bb051f66 218}