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