diff options
author | Kay Sievers <kay@vrfy.org> | 2012-06-10 22:53:07 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2012-06-10 22:53:07 +0200 |
commit | 4f5d327a49e1a40ae0a3b8f1855dc90f3c0d953f (patch) | |
tree | 2ec8c673cc428ad1f40c2dde5379b1b17198fe05 | |
parent | 94f7a71442bda7c43191979ea13cc97112745ce4 (diff) |
udev: support "udevadm info /dev/sda; udevadm info /sys/class/block/sda"
-rw-r--r-- | man/udevadm.xml | 11 | ||||
-rw-r--r-- | src/udev/udevadm-info.c | 161 |
2 files changed, 85 insertions, 87 deletions
diff --git a/man/udevadm.xml b/man/udevadm.xml index cbf22b4b5..d0cd9220f 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml | |||
@@ -116,15 +116,8 @@ | |||
116 | <varlistentry> | 116 | <varlistentry> |
117 | <term><option>--root</option></term> | 117 | <term><option>--root</option></term> |
118 | <listitem> | 118 | <listitem> |
119 | <para>The udev root directory: <filename>/dev</filename>. If used in conjunction | 119 | <para>Print absolute paths in <command>name</command> or <command>symlink</command> |
120 | with a <command>name</command> or <command>symlink</command> query, the | 120 | query.</para> |
121 | query returns the absolute path including the root directory.</para> | ||
122 | </listitem> | ||
123 | </varlistentry> | ||
124 | <varlistentry> | ||
125 | <term><option>--run</option></term> | ||
126 | <listitem> | ||
127 | <para>The udev runtime directory: <filename>/run/udev</filename>.</para> | ||
128 | </listitem> | 121 | </listitem> |
129 | </varlistentry> | 122 | </varlistentry> |
130 | <varlistentry> | 123 | <varlistentry> |
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index 229c0a284..907e961f4 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c | |||
@@ -264,13 +264,42 @@ static void cleanup_db(struct udev *udev) | |||
264 | } | 264 | } |
265 | } | 265 | } |
266 | 266 | ||
267 | static struct udev_device *find_device(struct udev *udev, const char *id, const char *prefix) | ||
268 | { | ||
269 | char name[UTIL_PATH_SIZE]; | ||
270 | |||
271 | if (prefix && !startswith(id, prefix)) { | ||
272 | util_strscpyl(name, sizeof(name), prefix, id, NULL); | ||
273 | id = name; | ||
274 | } | ||
275 | |||
276 | if (startswith(id, "/dev/")) { | ||
277 | struct stat statbuf; | ||
278 | char type; | ||
279 | |||
280 | if (stat(id, &statbuf) < 0) | ||
281 | return NULL; | ||
282 | |||
283 | if (S_ISBLK(statbuf.st_mode)) | ||
284 | type = 'b'; | ||
285 | else if (S_ISCHR(statbuf.st_mode)) | ||
286 | type = 'c'; | ||
287 | else | ||
288 | return NULL; | ||
289 | |||
290 | return udev_device_new_from_devnum(udev, type, statbuf.st_rdev); | ||
291 | } else if (startswith(id, "/sys/")) | ||
292 | return udev_device_new_from_syspath(udev, id); | ||
293 | else | ||
294 | return NULL; | ||
295 | } | ||
296 | |||
267 | static int uinfo(struct udev *udev, int argc, char *argv[]) | 297 | static int uinfo(struct udev *udev, int argc, char *argv[]) |
268 | { | 298 | { |
269 | struct udev_device *device = NULL; | 299 | struct udev_device *device = NULL; |
270 | bool root = 0; | 300 | bool root = 0; |
271 | bool export = 0; | 301 | bool export = 0; |
272 | const char *export_prefix = NULL; | 302 | const char *export_prefix = NULL; |
273 | char path[UTIL_PATH_SIZE]; | ||
274 | char name[UTIL_PATH_SIZE]; | 303 | char name[UTIL_PATH_SIZE]; |
275 | struct udev_list_entry *list_entry; | 304 | struct udev_list_entry *list_entry; |
276 | int rc = 0; | 305 | int rc = 0; |
@@ -283,7 +312,6 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
283 | { "cleanup-db", no_argument, NULL, 'c' }, | 312 | { "cleanup-db", no_argument, NULL, 'c' }, |
284 | { "export-db", no_argument, NULL, 'e' }, | 313 | { "export-db", no_argument, NULL, 'e' }, |
285 | { "root", no_argument, NULL, 'r' }, | 314 | { "root", no_argument, NULL, 'r' }, |
286 | { "run", no_argument, NULL, 'R' }, | ||
287 | { "device-id-of-file", required_argument, NULL, 'd' }, | 315 | { "device-id-of-file", required_argument, NULL, 'd' }, |
288 | { "export", no_argument, NULL, 'x' }, | 316 | { "export", no_argument, NULL, 'x' }, |
289 | { "export-prefix", required_argument, NULL, 'P' }, | 317 | { "export-prefix", required_argument, NULL, 'P' }, |
@@ -292,83 +320,73 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
292 | {} | 320 | {} |
293 | }; | 321 | }; |
294 | 322 | ||
323 | static const char *usage = | ||
324 | "Usage: udevadm info OPTIONS\n" | ||
325 | " --query=<type> query device information:\n" | ||
326 | " name name of device node\n" | ||
327 | " symlink pointing to node\n" | ||
328 | " path sys device path\n" | ||
329 | " property the device properties\n" | ||
330 | " all all values\n" | ||
331 | " --path=<syspath> sys device path used for query or attribute walk\n" | ||
332 | " --name=<name> node or symlink name used for query or attribute walk\n" | ||
333 | " --root prepend dev directory to path names\n" | ||
334 | " --attribute-walk print all key matches while walking along the chain\n" | ||
335 | " of parent devices\n" | ||
336 | " --device-id-of-file=<file> print major:minor of device containing this file\n" | ||
337 | " --export export key/value pairs\n" | ||
338 | " --export-prefix export the key name with a prefix\n" | ||
339 | " --export-db export the content of the udev database\n" | ||
340 | " --cleanup-db cleanup the udev database\n" | ||
341 | " --help\n"; | ||
342 | |||
295 | enum action_type { | 343 | enum action_type { |
296 | ACTION_NONE, | ||
297 | ACTION_QUERY, | 344 | ACTION_QUERY, |
298 | ACTION_ATTRIBUTE_WALK, | 345 | ACTION_ATTRIBUTE_WALK, |
299 | ACTION_ROOT, | ||
300 | ACTION_DEVICE_ID_FILE, | 346 | ACTION_DEVICE_ID_FILE, |
301 | } action = ACTION_NONE; | 347 | } action = ACTION_QUERY; |
302 | 348 | ||
303 | enum query_type { | 349 | enum query_type { |
304 | QUERY_NONE, | ||
305 | QUERY_NAME, | 350 | QUERY_NAME, |
306 | QUERY_PATH, | 351 | QUERY_PATH, |
307 | QUERY_SYMLINK, | 352 | QUERY_SYMLINK, |
308 | QUERY_PROPERTY, | 353 | QUERY_PROPERTY, |
309 | QUERY_ALL, | 354 | QUERY_ALL, |
310 | } query = QUERY_NONE; | 355 | } query = QUERY_ALL; |
311 | 356 | ||
312 | for (;;) { | 357 | for (;;) { |
313 | int option; | 358 | int option; |
314 | struct stat statbuf; | ||
315 | 359 | ||
316 | option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL); | 360 | option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL); |
317 | if (option == -1) | 361 | if (option == -1) |
318 | break; | 362 | break; |
319 | 363 | ||
320 | switch (option) { | 364 | switch (option) { |
321 | case 'n': | 365 | case 'n': { |
322 | if (device != NULL) { | 366 | if (device != NULL) { |
323 | fprintf(stderr, "device already specified\n"); | 367 | fprintf(stderr, "device already specified\n"); |
324 | rc = 2; | 368 | rc = 2; |
325 | goto exit; | 369 | goto exit; |
326 | } | 370 | } |
327 | /* add /dev if not given */ | 371 | |
328 | if (!startswith(optarg, "/dev")) | 372 | device = find_device(udev, optarg, "/dev/"); |
329 | util_strscpyl(name, sizeof(name), "/dev/", optarg, NULL); | 373 | if (device == NULL) { |
330 | else | ||
331 | util_strscpy(name, sizeof(name), optarg); | ||
332 | util_remove_trailing_chars(name, '/'); | ||
333 | if (stat(name, &statbuf) < 0) { | ||
334 | fprintf(stderr, "device node not found\n"); | 374 | fprintf(stderr, "device node not found\n"); |
335 | rc = 2; | 375 | rc = 2; |
336 | goto exit; | 376 | goto exit; |
337 | } else { | ||
338 | char type; | ||
339 | |||
340 | if (S_ISBLK(statbuf.st_mode)) { | ||
341 | type = 'b'; | ||
342 | } else if (S_ISCHR(statbuf.st_mode)) { | ||
343 | type = 'c'; | ||
344 | } else { | ||
345 | fprintf(stderr, "device node has wrong file type\n"); | ||
346 | rc = 2; | ||
347 | goto exit; | ||
348 | } | ||
349 | device = udev_device_new_from_devnum(udev, type, statbuf.st_rdev); | ||
350 | if (device == NULL) { | ||
351 | fprintf(stderr, "device node not found\n"); | ||
352 | rc = 2; | ||
353 | goto exit; | ||
354 | } | ||
355 | } | 377 | } |
356 | break; | 378 | break; |
379 | } | ||
357 | case 'p': | 380 | case 'p': |
358 | if (device != NULL) { | 381 | if (device != NULL) { |
359 | fprintf(stderr, "device already specified\n"); | 382 | fprintf(stderr, "device already specified\n"); |
360 | rc = 2; | 383 | rc = 2; |
361 | goto exit; | 384 | goto exit; |
362 | } | 385 | } |
363 | /* add sys dir if needed */ | 386 | |
364 | if (!startswith(optarg, "/sys")) | 387 | device = find_device(udev, optarg, "/sys"); |
365 | util_strscpyl(path, sizeof(path), "/sys", optarg, NULL); | ||
366 | else | ||
367 | util_strscpy(path, sizeof(path), optarg); | ||
368 | util_remove_trailing_chars(path, '/'); | ||
369 | device = udev_device_new_from_syspath(udev, path); | ||
370 | if (device == NULL) { | 388 | if (device == NULL) { |
371 | fprintf(stderr, "device path not found\n"); | 389 | fprintf(stderr, "syspath not found\n"); |
372 | rc = 2; | 390 | rc = 2; |
373 | goto exit; | 391 | goto exit; |
374 | } | 392 | } |
@@ -392,13 +410,8 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
392 | } | 410 | } |
393 | break; | 411 | break; |
394 | case 'r': | 412 | case 'r': |
395 | if (action == ACTION_NONE) | ||
396 | action = ACTION_ROOT; | ||
397 | root = true; | 413 | root = true; |
398 | break; | 414 | break; |
399 | case 'R': | ||
400 | printf("/run/udev\n"); | ||
401 | goto exit; | ||
402 | case 'd': | 415 | case 'd': |
403 | action = ACTION_DEVICE_ID_FILE; | 416 | action = ACTION_DEVICE_ID_FILE; |
404 | util_strscpy(name, sizeof(name), optarg); | 417 | util_strscpy(name, sizeof(name), optarg); |
@@ -422,24 +435,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
422 | printf("%s\n", VERSION); | 435 | printf("%s\n", VERSION); |
423 | goto exit; | 436 | goto exit; |
424 | case 'h': | 437 | case 'h': |
425 | printf("Usage: udevadm info OPTIONS\n" | 438 | printf("%s\n", usage); |
426 | " --query=<type> query device information:\n" | ||
427 | " name name of device node\n" | ||
428 | " symlink pointing to node\n" | ||
429 | " path sys device path\n" | ||
430 | " property the device properties\n" | ||
431 | " all all values\n" | ||
432 | " --path=<syspath> sys device path used for query or attribute walk\n" | ||
433 | " --name=<name> node or symlink name used for query or attribute walk\n" | ||
434 | " --root prepend dev directory to path names\n" | ||
435 | " --attribute-walk print all key matches while walking along the chain\n" | ||
436 | " of parent devices\n" | ||
437 | " --device-id-of-file=<file> print major:minor of device containing this file\n" | ||
438 | " --export export key/value pairs\n" | ||
439 | " --export-prefix export the key name with a prefix\n" | ||
440 | " --export-db export the content of the udev database\n" | ||
441 | " --cleanup-db cleanup the udev database\n" | ||
442 | " --help\n\n"); | ||
443 | goto exit; | 439 | goto exit; |
444 | default: | 440 | default: |
445 | rc = 1; | 441 | rc = 1; |
@@ -449,10 +445,18 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
449 | 445 | ||
450 | switch (action) { | 446 | switch (action) { |
451 | case ACTION_QUERY: | 447 | case ACTION_QUERY: |
452 | if (device == NULL) { | 448 | if (!device) { |
453 | fprintf(stderr, "query needs a valid device specified by --path= or --name=\n"); | 449 | if (!argv[optind]) { |
454 | rc = 4; | 450 | fprintf(stderr, "%s\n", usage); |
455 | goto exit; | 451 | rc = 2; |
452 | goto exit; | ||
453 | } | ||
454 | device = find_device(udev, argv[optind], NULL); | ||
455 | if (!device) { | ||
456 | fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); | ||
457 | rc = 4; | ||
458 | goto exit; | ||
459 | } | ||
456 | } | 460 | } |
457 | 461 | ||
458 | switch(query) { | 462 | switch(query) { |
@@ -513,8 +517,16 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
513 | } | 517 | } |
514 | break; | 518 | break; |
515 | case ACTION_ATTRIBUTE_WALK: | 519 | case ACTION_ATTRIBUTE_WALK: |
516 | if (device == NULL) { | 520 | if (!device && argv[optind]) { |
517 | fprintf(stderr, "query needs a valid device specified by --path= or --name=\n"); | 521 | device = find_device(udev, argv[optind], NULL); |
522 | if (!device) { | ||
523 | fprintf(stderr, "Unknown device, absolute path in /dev/ or /sys expected.\n"); | ||
524 | rc = 4; | ||
525 | goto exit; | ||
526 | } | ||
527 | } | ||
528 | if (!device) { | ||
529 | fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); | ||
518 | rc = 4; | 530 | rc = 4; |
519 | goto exit; | 531 | goto exit; |
520 | } | 532 | } |
@@ -524,13 +536,6 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) | |||
524 | if (stat_device(name, export, export_prefix) != 0) | 536 | if (stat_device(name, export, export_prefix) != 0) |
525 | rc = 1; | 537 | rc = 1; |
526 | break; | 538 | break; |
527 | case ACTION_ROOT: | ||
528 | printf("/dev\n"); | ||
529 | break; | ||
530 | default: | ||
531 | fprintf(stderr, "missing option\n"); | ||
532 | rc = 1; | ||
533 | break; | ||
534 | } | 539 | } |
535 | 540 | ||
536 | exit: | 541 | exit: |