]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-libudev.c
hwdb: add support for Alienware graphics amplifier
[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 21#include <stdio.h>
ba6929f6 22#include <unistd.h>
b2d9e4f2 23#include <getopt.h>
f2fd4d27 24#include <sys/epoll.h>
ba6929f6 25
33a5cc29 26#include "libudev.h"
1ca208fb 27#include "udev-util.h"
33502ffe 28#include "util.h"
33a5cc29 29
f2fd4d27
KS
30#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
31
f168c273 32static void print_device(struct udev_device *device) {
912541b0
KS
33 const char *str;
34 dev_t devnum;
35 int count;
36 struct udev_list_entry *list_entry;
37
38 printf("*** device: %p ***\n", device);
39 str = udev_device_get_action(device);
40 if (str != NULL)
41 printf("action: '%s'\n", str);
42
43 str = udev_device_get_syspath(device);
44 printf("syspath: '%s'\n", str);
45
46 str = udev_device_get_sysname(device);
47 printf("sysname: '%s'\n", str);
48
49 str = udev_device_get_sysnum(device);
50 if (str != NULL)
51 printf("sysnum: '%s'\n", str);
52
53 str = udev_device_get_devpath(device);
54 printf("devpath: '%s'\n", str);
55
56 str = udev_device_get_subsystem(device);
57 if (str != NULL)
58 printf("subsystem: '%s'\n", str);
59
60 str = udev_device_get_devtype(device);
61 if (str != NULL)
62 printf("devtype: '%s'\n", str);
63
64 str = udev_device_get_driver(device);
65 if (str != NULL)
66 printf("driver: '%s'\n", str);
67
68 str = udev_device_get_devnode(device);
69 if (str != NULL)
70 printf("devname: '%s'\n", str);
71
72 devnum = udev_device_get_devnum(device);
73 if (major(devnum) > 0)
74 printf("devnum: %u:%u\n", major(devnum), minor(devnum));
75
76 count = 0;
77 udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
78 printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
79 count++;
80 }
81 if (count > 0)
82 printf("found %i links\n", count);
83
84 count = 0;
85 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
86 printf("property: '%s=%s'\n",
87 udev_list_entry_get_name(list_entry),
88 udev_list_entry_get_value(list_entry));
89 count++;
90 }
91 if (count > 0)
92 printf("found %i properties\n", count);
93
94 str = udev_device_get_property_value(device, "MAJOR");
95 if (str != NULL)
96 printf("MAJOR: '%s'\n", str);
97
98 str = udev_device_get_sysattr_value(device, "dev");
99 if (str != NULL)
100 printf("attr{dev}: '%s'\n", str);
101
102 printf("\n");
ba6929f6
KS
103}
104
f168c273 105static int test_device(struct udev *udev, const char *syspath) {
1ca208fb 106 _cleanup_udev_device_unref_ struct udev_device *device;
912541b0
KS
107
108 printf("looking at device: %s\n", syspath);
109 device = udev_device_new_from_syspath(udev, syspath);
110 if (device == NULL) {
111 printf("no device found\n");
112 return -1;
113 }
114 print_device(device);
1ca208fb 115
912541b0 116 return 0;
33a5cc29
KS
117}
118
f168c273 119static int test_device_parents(struct udev *udev, const char *syspath) {
1ca208fb 120 _cleanup_udev_device_unref_ struct udev_device *device;
912541b0
KS
121 struct udev_device *device_parent;
122
123 printf("looking at device: %s\n", syspath);
124 device = udev_device_new_from_syspath(udev, syspath);
125 if (device == NULL)
126 return -1;
127
128 printf("looking at parents\n");
129 device_parent = device;
130 do {
131 print_device(device_parent);
132 device_parent = udev_device_get_parent(device_parent);
133 } while (device_parent != NULL);
134
135 printf("looking at parents again\n");
136 device_parent = device;
137 do {
138 print_device(device_parent);
139 device_parent = udev_device_get_parent(device_parent);
140 } while (device_parent != NULL);
912541b0
KS
141
142 return 0;
4ad3a37f
KS
143}
144
f168c273 145static int test_device_devnum(struct udev *udev) {
912541b0
KS
146 dev_t devnum = makedev(1, 3);
147 struct udev_device *device;
148
149 printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
150 device = udev_device_new_from_devnum(udev, 'c', devnum);
151 if (device == NULL)
152 return -1;
153 print_device(device);
154 udev_device_unref(device);
155 return 0;
4c9dff47
KS
156}
157
f168c273 158static int test_device_subsys_name(struct udev *udev) {
912541b0
KS
159 struct udev_device *device;
160
161 printf("looking up device: 'block':'sda'\n");
162 device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
163 if (device == NULL)
164 return -1;
165 print_device(device);
166 udev_device_unref(device);
167
168 printf("looking up device: 'subsystem':'pci'\n");
169 device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
170 if (device == NULL)
171 return -1;
172 print_device(device);
173 udev_device_unref(device);
174
175 printf("looking up device: 'drivers':'scsi:sd'\n");
176 device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
177 if (device == NULL)
178 return -1;
179 print_device(device);
180 udev_device_unref(device);
181
182 printf("looking up device: 'module':'printk'\n");
183 device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
184 if (device == NULL)
185 return -1;
186 print_device(device);
187 udev_device_unref(device);
188 return 0;
90d80c2e
KS
189}
190
f168c273 191static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
912541b0
KS
192 struct udev_list_entry *list_entry;
193 int count = 0;
194
195 udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
196 struct udev_device *device;
197
198 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
199 udev_list_entry_get_name(list_entry));
200 if (device != NULL) {
201 printf("device: '%s' (%s)\n",
202 udev_device_get_syspath(device),
203 udev_device_get_subsystem(device));
204 udev_device_unref(device);
205 count++;
206 }
207 }
208 printf("found %i devices\n\n", count);
209 return count;
ba6929f6
KS
210}
211
f168c273 212static int test_monitor(struct udev *udev) {
912541b0
KS
213 struct udev_monitor *udev_monitor = NULL;
214 int fd_ep;
215 int fd_udev = -1;
216 struct epoll_event ep_udev, ep_stdin;
217
218 fd_ep = epoll_create1(EPOLL_CLOEXEC);
219 if (fd_ep < 0) {
220 printf("error creating epoll fd: %m\n");
221 goto out;
222 }
223
224 udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
225 if (udev_monitor == NULL) {
226 printf("no socket\n");
227 goto out;
228 }
229 fd_udev = udev_monitor_get_fd(udev_monitor);
230
231 if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
232 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
233 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
234 printf("filter failed\n");
235 goto out;
236 }
237
238 if (udev_monitor_enable_receiving(udev_monitor) < 0) {
239 printf("bind failed\n");
240 goto out;
241 }
242
29804cc1 243 memzero(&ep_udev, sizeof(struct epoll_event));
912541b0
KS
244 ep_udev.events = EPOLLIN;
245 ep_udev.data.fd = fd_udev;
246 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
247 printf("fail to add fd to epoll: %m\n");
248 goto out;
249 }
250
29804cc1 251 memzero(&ep_stdin, sizeof(struct epoll_event));
912541b0
KS
252 ep_stdin.events = EPOLLIN;
253 ep_stdin.data.fd = STDIN_FILENO;
254 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
255 printf("fail to add fd to epoll: %m\n");
256 goto out;
257 }
258
259 for (;;) {
260 int fdcount;
261 struct epoll_event ev[4];
262 struct udev_device *device;
263 int i;
264
265 printf("waiting for events from udev, press ENTER to exit\n");
266 fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
267 printf("epoll fd count: %i\n", fdcount);
268
269 for (i = 0; i < fdcount; i++) {
270 if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
271 device = udev_monitor_receive_device(udev_monitor);
272 if (device == NULL) {
273 printf("no device from socket\n");
274 continue;
275 }
276 print_device(device);
277 udev_device_unref(device);
278 } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
279 printf("exiting loop\n");
280 goto out;
281 }
282 }
283 }
f2fd4d27 284out:
912541b0
KS
285 if (fd_ep >= 0)
286 close(fd_ep);
287 udev_monitor_unref(udev_monitor);
288 return 0;
33a5cc29
KS
289}
290
f168c273 291static int test_queue(struct udev *udev) {
912541b0 292 struct udev_queue *udev_queue;
912541b0
KS
293
294 udev_queue = udev_queue_new(udev);
295 if (udev_queue == NULL)
296 return -1;
912541b0
KS
297
298 if (udev_queue_get_queue_is_empty(udev_queue))
299 printf("queue is empty\n");
912541b0 300
912541b0
KS
301 udev_queue_unref(udev_queue);
302 return 0;
64ccdf82
KS
303}
304
f168c273 305static int test_enumerate(struct udev *udev, const char *subsystem) {
912541b0 306 struct udev_enumerate *udev_enumerate;
c0c6a4fc 307 int r;
912541b0
KS
308
309 printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
310 udev_enumerate = udev_enumerate_new(udev);
311 if (udev_enumerate == NULL)
312 return -1;
313 udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
314 udev_enumerate_scan_devices(udev_enumerate);
315 test_enumerate_print_list(udev_enumerate);
316 udev_enumerate_unref(udev_enumerate);
317
318 printf("enumerate 'net' + duplicated scan + null + zero\n");
319 udev_enumerate = udev_enumerate_new(udev);
320 if (udev_enumerate == NULL)
321 return -1;
322 udev_enumerate_add_match_subsystem(udev_enumerate, "net");
323 udev_enumerate_scan_devices(udev_enumerate);
324 udev_enumerate_scan_devices(udev_enumerate);
325 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
326 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
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/null");
332 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
333 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
334 udev_enumerate_scan_devices(udev_enumerate);
335 test_enumerate_print_list(udev_enumerate);
336 udev_enumerate_unref(udev_enumerate);
337
338 printf("enumerate 'block'\n");
339 udev_enumerate = udev_enumerate_new(udev);
340 if (udev_enumerate == NULL)
341 return -1;
342 udev_enumerate_add_match_subsystem(udev_enumerate,"block");
c0c6a4fc 343 r = udev_enumerate_add_match_is_initialized(udev_enumerate);
86ff9f11
TA
344 if (r < 0) {
345 udev_enumerate_unref(udev_enumerate);
c0c6a4fc 346 return r;
86ff9f11 347 }
912541b0
KS
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}