]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-libudev.c
build-sys: ignore Python 2 bytecode files
[thirdparty/systemd.git] / src / test / test-libudev.c
CommitLineData
1298001e
KS
1/***
2 This file is part of systemd.
3
4 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
33a5cc29 19
b2d9e4f2 20#include <getopt.h>
07630cea 21#include <stdio.h>
f2fd4d27 22#include <sys/epoll.h>
07630cea 23#include <unistd.h>
ba6929f6 24
33a5cc29 25#include "libudev.h"
b4bbcaa9 26
d054f0a4 27#include "stdio-util.h"
07630cea 28#include "string-util.h"
1ca208fb 29#include "udev-util.h"
33502ffe 30#include "util.h"
33a5cc29 31
f2fd4d27
KS
32#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
33
f168c273 34static void print_device(struct udev_device *device) {
912541b0
KS
35 const char *str;
36 dev_t devnum;
37 int count;
38 struct udev_list_entry *list_entry;
39
40 printf("*** device: %p ***\n", device);
41 str = udev_device_get_action(device);
42 if (str != NULL)
43 printf("action: '%s'\n", str);
44
45 str = udev_device_get_syspath(device);
46 printf("syspath: '%s'\n", str);
47
48 str = udev_device_get_sysname(device);
49 printf("sysname: '%s'\n", str);
50
51 str = udev_device_get_sysnum(device);
52 if (str != NULL)
53 printf("sysnum: '%s'\n", str);
54
55 str = udev_device_get_devpath(device);
56 printf("devpath: '%s'\n", str);
57
58 str = udev_device_get_subsystem(device);
59 if (str != NULL)
60 printf("subsystem: '%s'\n", str);
61
62 str = udev_device_get_devtype(device);
63 if (str != NULL)
64 printf("devtype: '%s'\n", str);
65
66 str = udev_device_get_driver(device);
67 if (str != NULL)
68 printf("driver: '%s'\n", str);
69
70 str = udev_device_get_devnode(device);
71 if (str != NULL)
72 printf("devname: '%s'\n", str);
73
74 devnum = udev_device_get_devnum(device);
75 if (major(devnum) > 0)
76 printf("devnum: %u:%u\n", major(devnum), minor(devnum));
77
78 count = 0;
79 udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
80 printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
81 count++;
82 }
83 if (count > 0)
84 printf("found %i links\n", count);
85
86 count = 0;
87 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
88 printf("property: '%s=%s'\n",
89 udev_list_entry_get_name(list_entry),
90 udev_list_entry_get_value(list_entry));
91 count++;
92 }
93 if (count > 0)
94 printf("found %i properties\n", count);
95
96 str = udev_device_get_property_value(device, "MAJOR");
97 if (str != NULL)
98 printf("MAJOR: '%s'\n", str);
99
100 str = udev_device_get_sysattr_value(device, "dev");
101 if (str != NULL)
102 printf("attr{dev}: '%s'\n", str);
103
104 printf("\n");
ba6929f6
KS
105}
106
f168c273 107static int test_device(struct udev *udev, const char *syspath) {
1ca208fb 108 _cleanup_udev_device_unref_ struct udev_device *device;
912541b0
KS
109
110 printf("looking at device: %s\n", syspath);
111 device = udev_device_new_from_syspath(udev, syspath);
112 if (device == NULL) {
113 printf("no device found\n");
114 return -1;
115 }
116 print_device(device);
1ca208fb 117
912541b0 118 return 0;
33a5cc29
KS
119}
120
f168c273 121static int test_device_parents(struct udev *udev, const char *syspath) {
1ca208fb 122 _cleanup_udev_device_unref_ struct udev_device *device;
912541b0
KS
123 struct udev_device *device_parent;
124
125 printf("looking at device: %s\n", syspath);
126 device = udev_device_new_from_syspath(udev, syspath);
127 if (device == NULL)
128 return -1;
129
130 printf("looking at parents\n");
131 device_parent = device;
132 do {
133 print_device(device_parent);
134 device_parent = udev_device_get_parent(device_parent);
135 } while (device_parent != NULL);
136
137 printf("looking at parents again\n");
138 device_parent = device;
139 do {
140 print_device(device_parent);
141 device_parent = udev_device_get_parent(device_parent);
142 } while (device_parent != NULL);
912541b0
KS
143
144 return 0;
4ad3a37f
KS
145}
146
f168c273 147static int test_device_devnum(struct udev *udev) {
912541b0
KS
148 dev_t devnum = makedev(1, 3);
149 struct udev_device *device;
150
151 printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
152 device = udev_device_new_from_devnum(udev, 'c', devnum);
153 if (device == NULL)
154 return -1;
155 print_device(device);
156 udev_device_unref(device);
157 return 0;
4c9dff47
KS
158}
159
f168c273 160static int test_device_subsys_name(struct udev *udev) {
912541b0
KS
161 struct udev_device *device;
162
163 printf("looking up device: 'block':'sda'\n");
164 device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
165 if (device == NULL)
166 return -1;
167 print_device(device);
168 udev_device_unref(device);
169
170 printf("looking up device: 'subsystem':'pci'\n");
171 device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
172 if (device == NULL)
173 return -1;
174 print_device(device);
175 udev_device_unref(device);
176
177 printf("looking up device: 'drivers':'scsi:sd'\n");
178 device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
179 if (device == NULL)
180 return -1;
181 print_device(device);
182 udev_device_unref(device);
183
184 printf("looking up device: 'module':'printk'\n");
185 device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
186 if (device == NULL)
187 return -1;
188 print_device(device);
189 udev_device_unref(device);
190 return 0;
90d80c2e
KS
191}
192
f168c273 193static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
912541b0
KS
194 struct udev_list_entry *list_entry;
195 int count = 0;
196
197 udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
198 struct udev_device *device;
199
200 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
201 udev_list_entry_get_name(list_entry));
202 if (device != NULL) {
203 printf("device: '%s' (%s)\n",
204 udev_device_get_syspath(device),
205 udev_device_get_subsystem(device));
206 udev_device_unref(device);
207 count++;
208 }
209 }
210 printf("found %i devices\n\n", count);
211 return count;
ba6929f6
KS
212}
213
f168c273 214static int test_monitor(struct udev *udev) {
912541b0
KS
215 struct udev_monitor *udev_monitor = NULL;
216 int fd_ep;
217 int fd_udev = -1;
218 struct epoll_event ep_udev, ep_stdin;
219
220 fd_ep = epoll_create1(EPOLL_CLOEXEC);
221 if (fd_ep < 0) {
222 printf("error creating epoll fd: %m\n");
223 goto out;
224 }
225
226 udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
227 if (udev_monitor == NULL) {
228 printf("no socket\n");
229 goto out;
230 }
231 fd_udev = udev_monitor_get_fd(udev_monitor);
232
233 if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
234 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
235 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
236 printf("filter failed\n");
237 goto out;
238 }
239
240 if (udev_monitor_enable_receiving(udev_monitor) < 0) {
241 printf("bind failed\n");
242 goto out;
243 }
244
29804cc1 245 memzero(&ep_udev, sizeof(struct epoll_event));
912541b0
KS
246 ep_udev.events = EPOLLIN;
247 ep_udev.data.fd = fd_udev;
248 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
249 printf("fail to add fd to epoll: %m\n");
250 goto out;
251 }
252
29804cc1 253 memzero(&ep_stdin, sizeof(struct epoll_event));
912541b0
KS
254 ep_stdin.events = EPOLLIN;
255 ep_stdin.data.fd = STDIN_FILENO;
256 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
257 printf("fail to add fd to epoll: %m\n");
258 goto out;
259 }
260
261 for (;;) {
262 int fdcount;
263 struct epoll_event ev[4];
264 struct udev_device *device;
265 int i;
266
267 printf("waiting for events from udev, press ENTER to exit\n");
268 fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
269 printf("epoll fd count: %i\n", fdcount);
270
271 for (i = 0; i < fdcount; i++) {
272 if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
273 device = udev_monitor_receive_device(udev_monitor);
274 if (device == NULL) {
275 printf("no device from socket\n");
276 continue;
277 }
278 print_device(device);
279 udev_device_unref(device);
280 } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
281 printf("exiting loop\n");
282 goto out;
283 }
284 }
285 }
f2fd4d27 286out:
912541b0
KS
287 if (fd_ep >= 0)
288 close(fd_ep);
289 udev_monitor_unref(udev_monitor);
290 return 0;
33a5cc29
KS
291}
292
f168c273 293static int test_queue(struct udev *udev) {
912541b0 294 struct udev_queue *udev_queue;
912541b0
KS
295
296 udev_queue = udev_queue_new(udev);
297 if (udev_queue == NULL)
298 return -1;
912541b0
KS
299
300 if (udev_queue_get_queue_is_empty(udev_queue))
301 printf("queue is empty\n");
912541b0 302
912541b0
KS
303 udev_queue_unref(udev_queue);
304 return 0;
64ccdf82
KS
305}
306
f168c273 307static int test_enumerate(struct udev *udev, const char *subsystem) {
912541b0 308 struct udev_enumerate *udev_enumerate;
c0c6a4fc 309 int r;
912541b0
KS
310
311 printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
312 udev_enumerate = udev_enumerate_new(udev);
313 if (udev_enumerate == NULL)
314 return -1;
315 udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
316 udev_enumerate_scan_devices(udev_enumerate);
317 test_enumerate_print_list(udev_enumerate);
318 udev_enumerate_unref(udev_enumerate);
319
320 printf("enumerate 'net' + duplicated scan + null + zero\n");
321 udev_enumerate = udev_enumerate_new(udev);
322 if (udev_enumerate == NULL)
323 return -1;
324 udev_enumerate_add_match_subsystem(udev_enumerate, "net");
325 udev_enumerate_scan_devices(udev_enumerate);
326 udev_enumerate_scan_devices(udev_enumerate);
327 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
328 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
329 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
330 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
331 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
332 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
333 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
334 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
335 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
336 udev_enumerate_scan_devices(udev_enumerate);
337 test_enumerate_print_list(udev_enumerate);
338 udev_enumerate_unref(udev_enumerate);
339
340 printf("enumerate 'block'\n");
341 udev_enumerate = udev_enumerate_new(udev);
342 if (udev_enumerate == NULL)
343 return -1;
344 udev_enumerate_add_match_subsystem(udev_enumerate,"block");
c0c6a4fc 345 r = udev_enumerate_add_match_is_initialized(udev_enumerate);
86ff9f11
TA
346 if (r < 0) {
347 udev_enumerate_unref(udev_enumerate);
c0c6a4fc 348 return r;
86ff9f11 349 }
912541b0
KS
350 udev_enumerate_scan_devices(udev_enumerate);
351 test_enumerate_print_list(udev_enumerate);
352 udev_enumerate_unref(udev_enumerate);
353
354 printf("enumerate 'not block'\n");
355 udev_enumerate = udev_enumerate_new(udev);
356 if (udev_enumerate == NULL)
357 return -1;
358 udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
359 udev_enumerate_scan_devices(udev_enumerate);
360 test_enumerate_print_list(udev_enumerate);
361 udev_enumerate_unref(udev_enumerate);
362
363 printf("enumerate 'pci, mem, vc'\n");
364 udev_enumerate = udev_enumerate_new(udev);
365 if (udev_enumerate == NULL)
366 return -1;
367 udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
368 udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
369 udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
370 udev_enumerate_scan_devices(udev_enumerate);
371 test_enumerate_print_list(udev_enumerate);
372 udev_enumerate_unref(udev_enumerate);
373
374 printf("enumerate 'subsystem'\n");
375 udev_enumerate = udev_enumerate_new(udev);
376 if (udev_enumerate == NULL)
377 return -1;
378 udev_enumerate_scan_subsystems(udev_enumerate);
379 test_enumerate_print_list(udev_enumerate);
380 udev_enumerate_unref(udev_enumerate);
381
382 printf("enumerate 'property IF_FS_*=filesystem'\n");
383 udev_enumerate = udev_enumerate_new(udev);
384 if (udev_enumerate == NULL)
385 return -1;
386 udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
387 udev_enumerate_scan_devices(udev_enumerate);
388 test_enumerate_print_list(udev_enumerate);
389 udev_enumerate_unref(udev_enumerate);
390 return 0;
90d80c2e
KS
391}
392
872c8faa 393static void test_hwdb(struct udev *udev, const char *modalias) {
960787ae 394 struct udev_hwdb *hwdb;
2001208c
KS
395 struct udev_list_entry *entry;
396
397 hwdb = udev_hwdb_new(udev);
398
399 udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
400 printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
401 printf("\n");
402
403 hwdb = udev_hwdb_unref(hwdb);
bdf7026e 404 assert_se(hwdb == NULL);
2001208c
KS
405}
406
f168c273 407int main(int argc, char *argv[]) {
912541b0
KS
408 struct udev *udev = NULL;
409 static const struct option options[] = {
410 { "syspath", required_argument, NULL, 'p' },
411 { "subsystem", required_argument, NULL, 's' },
412 { "debug", no_argument, NULL, 'd' },
413 { "help", no_argument, NULL, 'h' },
414 { "version", no_argument, NULL, 'V' },
415 {}
416 };
417 const char *syspath = "/devices/virtual/mem/null";
418 const char *subsystem = NULL;
419 char path[1024];
601185b4 420 int c;
912541b0
KS
421
422 udev = udev_new();
423 printf("context: %p\n", udev);
424 if (udev == NULL) {
425 printf("no context\n");
426 return 1;
427 }
912541b0 428
601185b4
ZJS
429 while ((c = getopt_long(argc, argv, "p:s:dhV", options, NULL)) >= 0)
430 switch (c) {
912541b0 431
912541b0
KS
432 case 'p':
433 syspath = optarg;
434 break;
601185b4 435
912541b0
KS
436 case 's':
437 subsystem = optarg;
438 break;
601185b4 439
912541b0 440 case 'd':
25e773ee
KS
441 if (log_get_max_level() < LOG_INFO)
442 log_set_max_level(LOG_INFO);
912541b0 443 break;
601185b4 444
912541b0
KS
445 case 'h':
446 printf("--debug --syspath= --subsystem= --help\n");
447 goto out;
601185b4 448
912541b0
KS
449 case 'V':
450 printf("%s\n", VERSION);
451 goto out;
601185b4
ZJS
452
453 case '?':
912541b0 454 goto out;
601185b4
ZJS
455
456 default:
457 assert_not_reached("Unhandled option code.");
912541b0 458 }
601185b4 459
912541b0 460
912541b0 461 /* add sys path if needed */
33502ffe 462 if (!startswith(syspath, "/sys")) {
d054f0a4 463 xsprintf(path, "/sys/%s", syspath);
912541b0
KS
464 syspath = path;
465 }
466
467 test_device(udev, syspath);
468 test_device_devnum(udev);
469 test_device_subsys_name(udev);
470 test_device_parents(udev, syspath);
471
472 test_enumerate(udev, subsystem);
473
474 test_queue(udev);
475
2001208c
KS
476 test_hwdb(udev, "usb:v0D50p0011*");
477
912541b0 478 test_monitor(udev);
b2d9e4f2 479out:
912541b0
KS
480 udev_unref(udev);
481 return 0;
33a5cc29 482}