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