2 This file is part of systemd.
4 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
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.
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.
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/>.
29 #include <sys/epoll.h>
32 #include "udev-util.h"
35 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
37 static void log_fn(struct udev *udev,
38 int priority, const char *file, int line, const char *fn,
39 const char *format, va_list args) {
40 printf("test-libudev: %s %s:%d ", fn, file, line);
41 vprintf(format, args);
44 static void print_device(struct udev_device *device) {
48 struct udev_list_entry *list_entry;
50 printf("*** device: %p ***\n", device);
51 str = udev_device_get_action(device);
53 printf("action: '%s'\n", str);
55 str = udev_device_get_syspath(device);
56 printf("syspath: '%s'\n", str);
58 str = udev_device_get_sysname(device);
59 printf("sysname: '%s'\n", str);
61 str = udev_device_get_sysnum(device);
63 printf("sysnum: '%s'\n", str);
65 str = udev_device_get_devpath(device);
66 printf("devpath: '%s'\n", str);
68 str = udev_device_get_subsystem(device);
70 printf("subsystem: '%s'\n", str);
72 str = udev_device_get_devtype(device);
74 printf("devtype: '%s'\n", str);
76 str = udev_device_get_driver(device);
78 printf("driver: '%s'\n", str);
80 str = udev_device_get_devnode(device);
82 printf("devname: '%s'\n", str);
84 devnum = udev_device_get_devnum(device);
85 if (major(devnum) > 0)
86 printf("devnum: %u:%u\n", major(devnum), minor(devnum));
89 udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
90 printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
94 printf("found %i links\n", count);
97 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
98 printf("property: '%s=%s'\n",
99 udev_list_entry_get_name(list_entry),
100 udev_list_entry_get_value(list_entry));
104 printf("found %i properties\n", count);
106 str = udev_device_get_property_value(device, "MAJOR");
108 printf("MAJOR: '%s'\n", str);
110 str = udev_device_get_sysattr_value(device, "dev");
112 printf("attr{dev}: '%s'\n", str);
117 static int test_device(struct udev *udev, const char *syspath) {
118 _cleanup_udev_device_unref_ struct udev_device *device;
120 printf("looking at device: %s\n", syspath);
121 device = udev_device_new_from_syspath(udev, syspath);
122 if (device == NULL) {
123 printf("no device found\n");
126 print_device(device);
131 static int test_device_parents(struct udev *udev, const char *syspath) {
132 _cleanup_udev_device_unref_ struct udev_device *device;
133 struct udev_device *device_parent;
135 printf("looking at device: %s\n", syspath);
136 device = udev_device_new_from_syspath(udev, syspath);
140 printf("looking at parents\n");
141 device_parent = device;
143 print_device(device_parent);
144 device_parent = udev_device_get_parent(device_parent);
145 } while (device_parent != NULL);
147 printf("looking at parents again\n");
148 device_parent = device;
150 print_device(device_parent);
151 device_parent = udev_device_get_parent(device_parent);
152 } while (device_parent != NULL);
157 static int test_device_devnum(struct udev *udev) {
158 dev_t devnum = makedev(1, 3);
159 struct udev_device *device;
161 printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
162 device = udev_device_new_from_devnum(udev, 'c', devnum);
165 print_device(device);
166 udev_device_unref(device);
170 static int test_device_subsys_name(struct udev *udev) {
171 struct udev_device *device;
173 printf("looking up device: 'block':'sda'\n");
174 device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
177 print_device(device);
178 udev_device_unref(device);
180 printf("looking up device: 'subsystem':'pci'\n");
181 device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
184 print_device(device);
185 udev_device_unref(device);
187 printf("looking up device: 'drivers':'scsi:sd'\n");
188 device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
191 print_device(device);
192 udev_device_unref(device);
194 printf("looking up device: 'module':'printk'\n");
195 device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
198 print_device(device);
199 udev_device_unref(device);
203 static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
204 struct udev_list_entry *list_entry;
207 udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
208 struct udev_device *device;
210 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
211 udev_list_entry_get_name(list_entry));
212 if (device != NULL) {
213 printf("device: '%s' (%s)\n",
214 udev_device_get_syspath(device),
215 udev_device_get_subsystem(device));
216 udev_device_unref(device);
220 printf("found %i devices\n\n", count);
224 static int test_monitor(struct udev *udev) {
225 struct udev_monitor *udev_monitor = NULL;
228 struct epoll_event ep_udev, ep_stdin;
230 fd_ep = epoll_create1(EPOLL_CLOEXEC);
232 printf("error creating epoll fd: %m\n");
236 udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
237 if (udev_monitor == NULL) {
238 printf("no socket\n");
241 fd_udev = udev_monitor_get_fd(udev_monitor);
243 if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
244 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
245 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
246 printf("filter failed\n");
250 if (udev_monitor_enable_receiving(udev_monitor) < 0) {
251 printf("bind failed\n");
255 memset(&ep_udev, 0, sizeof(struct epoll_event));
256 ep_udev.events = EPOLLIN;
257 ep_udev.data.fd = fd_udev;
258 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
259 printf("fail to add fd to epoll: %m\n");
263 memset(&ep_stdin, 0, sizeof(struct epoll_event));
264 ep_stdin.events = EPOLLIN;
265 ep_stdin.data.fd = STDIN_FILENO;
266 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
267 printf("fail to add fd to epoll: %m\n");
273 struct epoll_event ev[4];
274 struct udev_device *device;
277 printf("waiting for events from udev, press ENTER to exit\n");
278 fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
279 printf("epoll fd count: %i\n", fdcount);
281 for (i = 0; i < fdcount; i++) {
282 if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
283 device = udev_monitor_receive_device(udev_monitor);
284 if (device == NULL) {
285 printf("no device from socket\n");
288 print_device(device);
289 udev_device_unref(device);
290 } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
291 printf("exiting loop\n");
299 udev_monitor_unref(udev_monitor);
303 static int test_queue(struct udev *udev) {
304 struct udev_queue *udev_queue;
305 unsigned long long int seqnum;
306 struct udev_list_entry *list_entry;
308 udev_queue = udev_queue_new(udev);
309 if (udev_queue == NULL)
311 seqnum = udev_queue_get_kernel_seqnum(udev_queue);
312 printf("seqnum kernel: %llu\n", seqnum);
313 seqnum = udev_queue_get_udev_seqnum(udev_queue);
314 printf("seqnum udev : %llu\n", seqnum);
316 if (udev_queue_get_queue_is_empty(udev_queue))
317 printf("queue is empty\n");
318 printf("get queue list\n");
319 udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
320 printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
322 printf("get queue list again\n");
323 udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
324 printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
327 list_entry = udev_queue_get_queued_list_entry(udev_queue);
328 if (list_entry != NULL) {
329 printf("event [%llu] is queued\n", seqnum);
330 seqnum = strtoull(udev_list_entry_get_value(list_entry), NULL, 10);
331 if (udev_queue_get_seqnum_is_finished(udev_queue, seqnum))
332 printf("event [%llu] is not finished\n", seqnum);
334 printf("event [%llu] is finished\n", seqnum);
337 udev_queue_unref(udev_queue);
341 static int test_enumerate(struct udev *udev, const char *subsystem) {
342 struct udev_enumerate *udev_enumerate;
344 printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
345 udev_enumerate = udev_enumerate_new(udev);
346 if (udev_enumerate == NULL)
348 udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
349 udev_enumerate_scan_devices(udev_enumerate);
350 test_enumerate_print_list(udev_enumerate);
351 udev_enumerate_unref(udev_enumerate);
353 printf("enumerate 'net' + duplicated scan + null + zero\n");
354 udev_enumerate = udev_enumerate_new(udev);
355 if (udev_enumerate == NULL)
357 udev_enumerate_add_match_subsystem(udev_enumerate, "net");
358 udev_enumerate_scan_devices(udev_enumerate);
359 udev_enumerate_scan_devices(udev_enumerate);
360 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
361 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
362 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
363 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
364 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
365 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
366 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
367 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
368 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
369 udev_enumerate_scan_devices(udev_enumerate);
370 test_enumerate_print_list(udev_enumerate);
371 udev_enumerate_unref(udev_enumerate);
373 printf("enumerate 'block'\n");
374 udev_enumerate = udev_enumerate_new(udev);
375 if (udev_enumerate == NULL)
377 udev_enumerate_add_match_subsystem(udev_enumerate,"block");
378 udev_enumerate_add_match_is_initialized(udev_enumerate);
379 udev_enumerate_scan_devices(udev_enumerate);
380 test_enumerate_print_list(udev_enumerate);
381 udev_enumerate_unref(udev_enumerate);
383 printf("enumerate 'not block'\n");
384 udev_enumerate = udev_enumerate_new(udev);
385 if (udev_enumerate == NULL)
387 udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
388 udev_enumerate_scan_devices(udev_enumerate);
389 test_enumerate_print_list(udev_enumerate);
390 udev_enumerate_unref(udev_enumerate);
392 printf("enumerate 'pci, mem, vc'\n");
393 udev_enumerate = udev_enumerate_new(udev);
394 if (udev_enumerate == NULL)
396 udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
397 udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
398 udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
399 udev_enumerate_scan_devices(udev_enumerate);
400 test_enumerate_print_list(udev_enumerate);
401 udev_enumerate_unref(udev_enumerate);
403 printf("enumerate 'subsystem'\n");
404 udev_enumerate = udev_enumerate_new(udev);
405 if (udev_enumerate == NULL)
407 udev_enumerate_scan_subsystems(udev_enumerate);
408 test_enumerate_print_list(udev_enumerate);
409 udev_enumerate_unref(udev_enumerate);
411 printf("enumerate 'property IF_FS_*=filesystem'\n");
412 udev_enumerate = udev_enumerate_new(udev);
413 if (udev_enumerate == NULL)
415 udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
416 udev_enumerate_scan_devices(udev_enumerate);
417 test_enumerate_print_list(udev_enumerate);
418 udev_enumerate_unref(udev_enumerate);
422 static void test_hwdb(struct udev *udev, const char *modalias) {
423 struct udev_hwdb *hwdb;
424 struct udev_list_entry *entry;
426 hwdb = udev_hwdb_new(udev);
428 udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
429 printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
432 hwdb = udev_hwdb_unref(hwdb);
433 assert(hwdb == NULL);
436 int main(int argc, char *argv[]) {
437 struct udev *udev = NULL;
438 static const struct option options[] = {
439 { "syspath", required_argument, NULL, 'p' },
440 { "subsystem", required_argument, NULL, 's' },
441 { "debug", no_argument, NULL, 'd' },
442 { "help", no_argument, NULL, 'h' },
443 { "version", no_argument, NULL, 'V' },
446 const char *syspath = "/devices/virtual/mem/null";
447 const char *subsystem = NULL;
451 printf("context: %p\n", udev);
453 printf("no context\n");
456 udev_set_log_fn(udev, log_fn);
457 printf("set log: %p\n", log_fn);
462 option = getopt_long(argc, argv, "+p:s:dhV", options, NULL);
474 if (udev_get_log_priority(udev) < LOG_INFO)
475 udev_set_log_priority(udev, LOG_INFO);
478 printf("--debug --syspath= --subsystem= --help\n");
481 printf("%s\n", VERSION);
488 /* add sys path if needed */
489 if (!startswith(syspath, "/sys")) {
490 snprintf(path, sizeof(path), "/sys/%s", syspath);
494 test_device(udev, syspath);
495 test_device_devnum(udev);
496 test_device_subsys_name(udev);
497 test_device_parents(udev, syspath);
499 test_enumerate(udev, subsystem);
503 test_hwdb(udev, "usb:v0D50p0011*");