summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-06-10 22:53:07 +0200
committerKay Sievers <kay@vrfy.org>2012-06-10 22:53:07 +0200
commit4f5d327a49e1a40ae0a3b8f1855dc90f3c0d953f (patch)
tree2ec8c673cc428ad1f40c2dde5379b1b17198fe05
parent94f7a71442bda7c43191979ea13cc97112745ce4 (diff)
udev: support "udevadm info /dev/sda; udevadm info /sys/class/block/sda"
-rw-r--r--man/udevadm.xml11
-rw-r--r--src/udev/udevadm-info.c161
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
267static 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
267static int uinfo(struct udev *udev, int argc, char *argv[]) 297static 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
536exit: 541exit: