]> git.proxmox.com Git - grub2.git/blob - util/grub-probe.c
2a987b58b43b1c18e04d33395244ff5301d18f5a
[grub2.git] / util / grub-probe.c
1 /* grub-probe.c - probe device information for a given path */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <config.h>
21 #include <grub/types.h>
22 #include <grub/emu/misc.h>
23 #include <grub/util/misc.h>
24 #include <grub/device.h>
25 #include <grub/disk.h>
26 #include <grub/file.h>
27 #include <grub/fs.h>
28 #include <grub/partition.h>
29 #include <grub/msdos_partition.h>
30 #include <grub/emu/hostdisk.h>
31 #include <grub/emu/getroot.h>
32 #include <grub/term.h>
33 #include <grub/env.h>
34 #include <grub/diskfilter.h>
35 #include <grub/i18n.h>
36 #include <grub/emu/misc.h>
37 #include <grub/util/ofpath.h>
38 #include <grub/crypto.h>
39 #include <grub/cryptodisk.h>
40
41 #include <stdio.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <sys/stat.h>
46 #include <assert.h>
47
48 #define _GNU_SOURCE 1
49 #include <argp.h>
50
51 #include "progname.h"
52
53 enum {
54 PRINT_FS,
55 PRINT_FS_UUID,
56 PRINT_FS_LABEL,
57 PRINT_DRIVE,
58 PRINT_DEVICE,
59 PRINT_PARTMAP,
60 PRINT_ABSTRACTION,
61 PRINT_CRYPTODISK_UUID,
62 PRINT_HINT_STR,
63 PRINT_BIOS_HINT,
64 PRINT_IEEE1275_HINT,
65 PRINT_BAREMETAL_HINT,
66 PRINT_EFI_HINT,
67 PRINT_ARC_HINT,
68 PRINT_COMPATIBILITY_HINT,
69 PRINT_MSDOS_PARTTYPE,
70 PRINT_DISK
71 };
72
73 static int print = PRINT_FS;
74 static unsigned int argument_is_device = 0;
75
76 static void
77 probe_partmap (grub_disk_t disk)
78 {
79 grub_partition_t part;
80 grub_disk_memberlist_t list = NULL, tmp;
81
82 if (disk->partition == NULL)
83 {
84 grub_util_info ("no partition map found for %s", disk->name);
85 }
86
87 for (part = disk->partition; part; part = part->parent)
88 printf ("%s ", part->partmap->name);
89
90 /* In case of LVM/RAID, check the member devices as well. */
91 if (disk->dev->memberlist)
92 {
93 list = disk->dev->memberlist (disk);
94 }
95 while (list)
96 {
97 probe_partmap (list->disk);
98 tmp = list->next;
99 free (list);
100 list = tmp;
101 }
102 }
103
104 static void
105 probe_cryptodisk_uuid (grub_disk_t disk)
106 {
107 grub_disk_memberlist_t list = NULL, tmp;
108
109 /* In case of LVM/RAID, check the member devices as well. */
110 if (disk->dev->memberlist)
111 {
112 list = disk->dev->memberlist (disk);
113 }
114 while (list)
115 {
116 probe_cryptodisk_uuid (list->disk);
117 tmp = list->next;
118 free (list);
119 list = tmp;
120 }
121 if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
122 grub_util_cryptodisk_print_uuid (disk);
123 }
124
125 static int
126 probe_raid_level (grub_disk_t disk)
127 {
128 /* disk might be NULL in the case of a LVM physical volume with no LVM
129 signature. Ignore such cases here. */
130 if (!disk)
131 return -1;
132
133 if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
134 return -1;
135
136 if (disk->name[0] != 'm' || disk->name[1] != 'd')
137 return -1;
138
139 if (!((struct grub_diskfilter_lv *) disk->data)->segments)
140 return -1;
141 return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
142 }
143
144 /* Since OF path names can have "," characters in them, and GRUB
145 internally uses "," to indicate partitions (unlike OF which uses
146 ":" for this purpose) we escape such commas. */
147 static char *
148 escape_of_path (const char *orig_path)
149 {
150 char *new_path, *d, c;
151 const char *p;
152
153 if (!strchr (orig_path, ','))
154 return (char *) xstrdup (orig_path);
155
156 new_path = xmalloc (strlen (orig_path) * 2 + sizeof ("ieee1275/"));
157
158 p = orig_path;
159 grub_strcpy (new_path, "ieee1275/");
160 d = new_path + sizeof ("ieee1275/") - 1;
161 while ((c = *p++) != '\0')
162 {
163 if (c == ',')
164 *d++ = '\\';
165 *d++ = c;
166 }
167 *d = 0;
168
169 free ((char *) orig_path);
170
171 return new_path;
172 }
173
174 static char *
175 guess_bios_drive (const char *orig_path)
176 {
177 char *canon;
178 char *ptr;
179 canon = canonicalize_file_name (orig_path);
180 if (!canon)
181 return NULL;
182 ptr = strrchr (orig_path, '/');
183 if (ptr)
184 ptr++;
185 else
186 ptr = canon;
187 if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
188 {
189 int num = ptr[2] - 'a';
190 free (canon);
191 return xasprintf ("hd%d", num);
192 }
193 if (ptr[0] == 'f' && ptr[1] == 'd')
194 {
195 int num = atoi (ptr + 2);
196 free (canon);
197 return xasprintf ("fd%d", num);
198 }
199 free (canon);
200 return NULL;
201 }
202
203 static char *
204 guess_efi_drive (const char *orig_path)
205 {
206 char *canon;
207 char *ptr;
208 canon = canonicalize_file_name (orig_path);
209 if (!canon)
210 return NULL;
211 ptr = strrchr (orig_path, '/');
212 if (ptr)
213 ptr++;
214 else
215 ptr = canon;
216 if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
217 {
218 int num = ptr[2] - 'a';
219 free (canon);
220 return xasprintf ("hd%d", num);
221 }
222 if (ptr[0] == 'f' && ptr[1] == 'd')
223 {
224 int num = atoi (ptr + 2);
225 free (canon);
226 return xasprintf ("fd%d", num);
227 }
228 free (canon);
229 return NULL;
230 }
231
232 static char *
233 guess_baremetal_drive (const char *orig_path)
234 {
235 char *canon;
236 char *ptr;
237 canon = canonicalize_file_name (orig_path);
238 if (!canon)
239 return NULL;
240 ptr = strrchr (orig_path, '/');
241 if (ptr)
242 ptr++;
243 else
244 ptr = canon;
245 if (ptr[0] == 'h' && ptr[1] == 'd')
246 {
247 int num = ptr[2] - 'a';
248 free (canon);
249 return xasprintf ("ata%d", num);
250 }
251 if (ptr[0] == 's' && ptr[1] == 'd')
252 {
253 int num = ptr[2] - 'a';
254 free (canon);
255 return xasprintf ("ahci%d", num);
256 }
257 free (canon);
258 return NULL;
259 }
260
261 static void
262 print_full_name (const char *drive, grub_device_t dev)
263 {
264 char *dname = escape_of_path (drive);
265 if (dev->disk->partition)
266 {
267 char *pname = grub_partition_get_name (dev->disk->partition);
268 printf ("%s,%s", dname, pname);
269 free (pname);
270 }
271 else
272 printf ("%s", dname);
273 free (dname);
274 }
275
276 static void
277 probe_abstraction (grub_disk_t disk)
278 {
279 grub_disk_memberlist_t list = NULL, tmp;
280 int raid_level;
281
282 if (disk->dev->memberlist)
283 list = disk->dev->memberlist (disk);
284 while (list)
285 {
286 probe_abstraction (list->disk);
287
288 tmp = list->next;
289 free (list);
290 list = tmp;
291 }
292
293 if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
294 && grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0)
295 printf ("lvm ");
296
297 if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
298 && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0)
299 printf ("ldm ");
300
301 if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
302 grub_util_cryptodisk_print_abstraction (disk);
303
304 raid_level = probe_raid_level (disk);
305 if (raid_level >= 0)
306 {
307 printf ("raid ");
308 if (disk->dev->raidname)
309 printf ("%s ", disk->dev->raidname (disk));
310 }
311 if (raid_level == 5)
312 printf ("raid5rec ");
313 if (raid_level == 6)
314 printf ("raid6rec ");
315 }
316
317 static void
318 probe (const char *path, char **device_names, char delim)
319 {
320 char **drives_names = NULL;
321 char **curdev, **curdrive;
322 char *grub_path = NULL;
323 int ndev = 0;
324
325 if (path != NULL)
326 {
327 grub_path = canonicalize_file_name (path);
328 if (! grub_path)
329 grub_util_error (_("failed to get canonical path of %s"), path);
330 device_names = grub_guess_root_devices (grub_path);
331 free (grub_path);
332 }
333
334 if (! device_names)
335 grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
336
337 if (print == PRINT_DEVICE)
338 {
339 for (curdev = device_names; *curdev; curdev++)
340 {
341 printf ("%s", *curdev);
342 putchar (delim);
343 }
344 return;
345 }
346
347 if (print == PRINT_DISK)
348 {
349 for (curdev = device_names; *curdev; curdev++)
350 {
351 char *disk;
352 disk = grub_util_get_os_disk (*curdev);
353 if (!disk)
354 {
355 grub_print_error ();
356 continue;
357 }
358 printf ("%s", disk);
359 putchar (delim);
360 }
361 return;
362 }
363
364 for (curdev = device_names; *curdev; curdev++)
365 {
366 grub_util_pull_device (*curdev);
367 ndev++;
368 }
369
370 drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1));
371
372 for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
373 curdrive++)
374 {
375 *curdrive = grub_util_get_grub_dev (*curdev);
376 if (! *curdrive)
377 grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
378 *curdev);
379 }
380 *curdrive = 0;
381
382 if (print == PRINT_DRIVE)
383 {
384 for (curdrive = drives_names; *curdrive; curdrive++)
385 {
386 printf ("(%s)", *curdrive);
387 putchar (delim);
388 }
389 goto end;
390 }
391
392 if (print == PRINT_FS || print == PRINT_FS_UUID
393 || print == PRINT_FS_LABEL)
394 {
395 grub_device_t dev = NULL;
396 grub_fs_t fs;
397
398 grub_util_info ("opening %s", drives_names[0]);
399 dev = grub_device_open (drives_names[0]);
400 if (! dev)
401 grub_util_error ("%s", _(grub_errmsg));
402
403 fs = grub_fs_probe (dev);
404 if (! fs)
405 grub_util_error ("%s", _(grub_errmsg));
406
407 if (print == PRINT_FS)
408 {
409 printf ("%s", fs->name);
410 putchar (delim);
411 }
412 else if (print == PRINT_FS_UUID)
413 {
414 char *uuid;
415 if (! fs->uuid)
416 grub_util_error (_("%s does not support UUIDs"), fs->name);
417
418 if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
419 grub_util_error ("%s", grub_errmsg);
420
421 printf ("%s", uuid);
422 putchar (delim);
423 }
424 else if (print == PRINT_FS_LABEL)
425 {
426 char *label;
427 if (! fs->label)
428 grub_util_error (_("%s does not support labels"), fs->name);
429
430 if (fs->label (dev, &label) != GRUB_ERR_NONE)
431 grub_util_error ("%s", _(grub_errmsg));
432
433 printf ("%s", label);
434 putchar (delim);
435 }
436 goto end;
437 }
438
439 for (curdrive = drives_names, curdev = device_names; *curdrive;
440 curdrive++, curdev++)
441 {
442 grub_device_t dev = NULL;
443
444 grub_util_info ("opening %s", *curdrive);
445 dev = grub_device_open (*curdrive);
446 if (! dev)
447 grub_util_error ("%s", _(grub_errmsg));
448
449 if (print == PRINT_HINT_STR)
450 {
451 const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
452 const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
453 char *biosname, *bare, *efi;
454 const char *map;
455
456 if (ofpath)
457 {
458 printf ("--hint-ieee1275='");
459 print_full_name (ofpath, dev);
460 printf ("' ");
461 }
462
463 biosname = guess_bios_drive (*curdev);
464 if (biosname)
465 {
466 printf ("--hint-bios=");
467 print_full_name (biosname, dev);
468 printf (" ");
469 }
470 free (biosname);
471
472 efi = guess_efi_drive (*curdev);
473 if (efi)
474 {
475 printf ("--hint-efi=");
476 print_full_name (efi, dev);
477 printf (" ");
478 }
479 free (efi);
480
481 bare = guess_baremetal_drive (*curdev);
482 if (bare)
483 {
484 printf ("--hint-baremetal=");
485 print_full_name (bare, dev);
486 printf (" ");
487 }
488 free (bare);
489
490 /* FIXME: Add ARC hint. */
491
492 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
493 if (map)
494 {
495 printf ("--hint='");
496 print_full_name (map, dev);
497 printf ("' ");
498 }
499 printf ("\n");
500
501 grub_device_close (dev);
502 continue;
503 }
504
505 if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
506 || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
507 || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
508 && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
509 {
510 print_full_name (dev->disk->name, dev);
511 putchar (delim);
512 continue;
513 }
514
515 if (print == PRINT_COMPATIBILITY_HINT)
516 {
517 const char *map;
518 char *biosname;
519 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
520 if (map)
521 {
522 print_full_name (map, dev);
523 putchar (delim);
524 grub_device_close (dev);
525 /* Compatibility hint is one device only. */
526 break;
527 }
528 biosname = guess_bios_drive (*curdev);
529 if (biosname)
530 {
531 print_full_name (biosname, dev);
532 putchar (delim);
533 }
534 free (biosname);
535 grub_device_close (dev);
536 /* Compatibility hint is one device only. */
537 if (biosname)
538 break;
539 continue;
540 }
541
542 if (print == PRINT_BIOS_HINT)
543 {
544 char *biosname;
545 biosname = guess_bios_drive (*curdev);
546 if (biosname)
547 {
548 print_full_name (biosname, dev);
549 putchar (delim);
550 }
551 free (biosname);
552 grub_device_close (dev);
553 continue;
554 }
555 if (print == PRINT_IEEE1275_HINT)
556 {
557 const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
558 const char *ofpath = grub_util_devname_to_ofpath (osdev);
559 const char *map;
560
561 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
562 if (map)
563 {
564 print_full_name (map, dev);
565 putchar (delim);
566 }
567
568 if (ofpath)
569 {
570 print_full_name (ofpath, dev);
571 putchar (delim);
572 }
573
574 grub_device_close (dev);
575 continue;
576 }
577 if (print == PRINT_EFI_HINT)
578 {
579 char *biosname;
580 char *name;
581 const char *map;
582 biosname = guess_efi_drive (*curdev);
583
584 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
585 if (map)
586 {
587 print_full_name (map, dev);
588 putchar (delim);
589 }
590 if (biosname)
591 {
592 print_full_name (biosname, dev);
593 putchar (delim);
594 }
595
596 free (biosname);
597 grub_device_close (dev);
598 continue;
599 }
600
601 if (print == PRINT_BAREMETAL_HINT)
602 {
603 char *biosname;
604 char *name;
605 const char *map;
606
607 biosname = guess_baremetal_drive (*curdev);
608
609 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
610 if (map)
611 {
612 print_full_name (map, dev);
613 putchar (delim);
614 }
615 if (biosname)
616 {
617 print_full_name (biosname, dev);
618 putchar (delim);
619 }
620
621 free (biosname);
622 grub_device_close (dev);
623 continue;
624 }
625
626 if (print == PRINT_ARC_HINT)
627 {
628 const char *map;
629
630 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
631 if (map)
632 {
633 print_full_name (map, dev);
634 putchar (delim);
635 }
636
637 /* FIXME */
638 grub_device_close (dev);
639 continue;
640 }
641
642 if (print == PRINT_ABSTRACTION)
643 {
644 probe_abstraction (dev->disk);
645 putchar (delim);
646 grub_device_close (dev);
647 continue;
648 }
649
650 if (print == PRINT_CRYPTODISK_UUID)
651 {
652 probe_cryptodisk_uuid (dev->disk);
653 putchar (delim);
654 grub_device_close (dev);
655 continue;
656 }
657
658 if (print == PRINT_PARTMAP)
659 {
660 /* Check if dev->disk itself is contained in a partmap. */
661 probe_partmap (dev->disk);
662 putchar (delim);
663 grub_device_close (dev);
664 continue;
665 }
666
667 if (print == PRINT_MSDOS_PARTTYPE)
668 {
669 if (dev->disk->partition
670 && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
671 printf ("%02x", dev->disk->partition->msdostype);
672
673 putchar (delim);
674 grub_device_close (dev);
675 continue;
676 }
677 }
678
679 end:
680 for (curdrive = drives_names; *curdrive; curdrive++)
681 free (*curdrive);
682 free (drives_names);
683 }
684
685 static struct argp_option options[] = {
686 {"device", 'd', 0, 0,
687 N_("given argument is a system device, not a path"), 0},
688 {"device-map", 'm', N_("FILE"), 0,
689 N_("use FILE as the device map [default=%s]"), 0},
690 {"target", 't', "(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|cryptodisk_uuid|msdos_parttype)", 0,
691 N_("print filesystem module, GRUB drive, system device, partition map module, abstraction module or CRYPTO UUID [default=fs]"), 0},
692 {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0},
693 { 0, 0, 0, 0, 0, 0 }
694 };
695
696
697 static char *
698 help_filter (int key, const char *text, void *input __attribute__ ((unused)))
699 {
700 switch (key)
701 {
702 case 'm':
703 return xasprintf (text, DEFAULT_DEVICE_MAP);
704
705 default:
706 return (char *) text;
707 }
708 }
709
710 struct arguments
711 {
712 char **devices;
713 size_t device_max;
714 size_t ndevices;
715 char *dev_map;
716 int zero_delim;
717 };
718
719 static error_t
720 argp_parser (int key, char *arg, struct argp_state *state)
721 {
722 /* Get the input argument from argp_parse, which we
723 know is a pointer to our arguments structure. */
724 struct arguments *arguments = state->input;
725
726 char *p;
727
728 switch (key)
729 {
730 case 'd':
731 argument_is_device = 1;
732 break;
733
734 case 'm':
735 if (arguments->dev_map)
736 free (arguments->dev_map);
737
738 arguments->dev_map = xstrdup (arg);
739 break;
740
741 case 't':
742 if (!strcmp (arg, "fs"))
743 print = PRINT_FS;
744 else if (!strcmp (arg, "fs_uuid"))
745 print = PRINT_FS_UUID;
746 else if (!strcmp (arg, "fs_label"))
747 print = PRINT_FS_LABEL;
748 else if (!strcmp (arg, "drive"))
749 print = PRINT_DRIVE;
750 else if (!strcmp (arg, "device"))
751 print = PRINT_DEVICE;
752 else if (!strcmp (arg, "partmap"))
753 print = PRINT_PARTMAP;
754 else if (!strcmp (arg, "abstraction"))
755 print = PRINT_ABSTRACTION;
756 else if (!strcmp (arg, "cryptodisk_uuid"))
757 print = PRINT_CRYPTODISK_UUID;
758 else if (!strcmp (arg, "msdos_parttype"))
759 print = PRINT_MSDOS_PARTTYPE;
760 else if (!strcmp (arg, "hints_string"))
761 print = PRINT_HINT_STR;
762 else if (!strcmp (arg, "bios_hints"))
763 print = PRINT_BIOS_HINT;
764 else if (!strcmp (arg, "ieee1275_hints"))
765 print = PRINT_IEEE1275_HINT;
766 else if (!strcmp (arg, "baremetal_hints"))
767 print = PRINT_BAREMETAL_HINT;
768 else if (!strcmp (arg, "efi_hints"))
769 print = PRINT_EFI_HINT;
770 else if (!strcmp (arg, "arc_hints"))
771 print = PRINT_ARC_HINT;
772 else if (!strcmp (arg, "compatibility_hint"))
773 print = PRINT_COMPATIBILITY_HINT;
774 else if (!strcmp (arg, "disk"))
775 print = PRINT_DISK;
776 else
777 argp_usage (state);
778 break;
779
780 case '0':
781 arguments->zero_delim = 1;
782 break;
783
784 case 'v':
785 verbosity++;
786 break;
787
788 case ARGP_KEY_NO_ARGS:
789 fprintf (stderr, "%s", _("No path or device is specified.\n"));
790 argp_usage (state);
791 break;
792
793 case ARGP_KEY_ARG:
794 assert (arguments->ndevices < arguments->device_max);
795 arguments->devices[arguments->ndevices++] = xstrdup(arg);
796 break;
797
798 default:
799 return ARGP_ERR_UNKNOWN;
800 }
801 return 0;
802 }
803
804 static struct argp argp = {
805 options, argp_parser, N_("[OPTION]... [PATH|DEVICE]"),
806 N_("\
807 Probe device information for a given path (or device, if the -d option is given)."),
808 NULL, help_filter, NULL
809 };
810
811 int
812 main (int argc, char *argv[])
813 {
814 char delim;
815 struct arguments arguments;
816
817 set_program_name (argv[0]);
818
819 grub_util_init_nls ();
820
821 memset (&arguments, 0, sizeof (struct arguments));
822 arguments.device_max = argc + 1;
823 arguments.devices = xmalloc ((arguments.device_max + 1)
824 * sizeof (arguments.devices[0]));
825 memset (arguments.devices, 0, (arguments.device_max + 1)
826 * sizeof (arguments.devices[0]));
827
828 /* Parse our arguments */
829 if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
830 {
831 fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
832 exit(1);
833 }
834
835 if (verbosity > 1)
836 grub_env_set ("debug", "all");
837
838 /* Obtain ARGUMENT. */
839 if (arguments.ndevices != 1 && !argument_is_device)
840 {
841 char *program = xstrdup(program_name);
842 fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
843 argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
844 free (program);
845 exit(1);
846 }
847
848 /* Initialize the emulated biosdisk driver. */
849 grub_util_biosdisk_init (arguments.dev_map ? : DEFAULT_DEVICE_MAP);
850
851 /* Initialize all modules. */
852 grub_init_all ();
853 grub_gcry_init_all ();
854
855 grub_lvm_fini ();
856 grub_mdraid09_fini ();
857 grub_mdraid1x_fini ();
858 grub_diskfilter_fini ();
859 grub_diskfilter_init ();
860 grub_mdraid09_init ();
861 grub_mdraid1x_init ();
862 grub_lvm_init ();
863
864 if (print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
865 || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
866 || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
867 delim = ' ';
868 else
869 delim = '\n';
870
871 if (arguments.zero_delim)
872 delim = '\0';
873
874 /* Do it. */
875 if (argument_is_device)
876 probe (NULL, arguments.devices, delim);
877 else
878 probe (arguments.devices[0], NULL, delim);
879
880 if (!arguments.zero_delim && (print == PRINT_COMPATIBILITY_HINT
881 || print == PRINT_BIOS_HINT
882 || print == PRINT_IEEE1275_HINT
883 || print == PRINT_BAREMETAL_HINT
884 || print == PRINT_EFI_HINT
885 || print == PRINT_ARC_HINT))
886 putchar ('\n');
887
888 /* Free resources. */
889 grub_gcry_fini_all ();
890 grub_fini_all ();
891 grub_util_biosdisk_fini ();
892
893 {
894 size_t i;
895 for (i = 0; i < arguments.ndevices; i++)
896 free (arguments.devices[i]);
897 }
898 free (arguments.devices);
899
900 free (arguments.dev_map);
901
902 return 0;
903 }