diff --git a/disk/lvm.c b/disk/lvm.c index 6707a40..126b494 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -271,15 +271,9 @@ grub_lvm_scan_device (const char *name) dlocn++; mda_offset = grub_le_to_cpu64 (dlocn->offset); mda_size = grub_le_to_cpu64 (dlocn->size); - dlocn++; - if (dlocn->offset) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "We don't support multiple LVM metadata areas"); - - goto fail; - } + /* It's possible to have multiple copies of metadata areas, we just use the + first one. */ /* Allocate buffer space for the circular worst-case scenario. */ metadatabuf = grub_malloc (2 * mda_size); @@ -564,7 +558,10 @@ grub_lvm_scan_device (const char *name) { if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN)) { - pv->disk = grub_disk_open (name); + /* This could happen to LVM on RAID, pv->disk points to the + raid device, we shouldn't change it. */ + if (! pv->disk) + pv->disk = grub_disk_open (name); break; } } diff --git a/disk/raid.c b/disk/raid.c index c4d0857..23b69ad 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -590,56 +590,6 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, static grub_raid_t grub_raid_list; static void -grub_raid_scan_device (int head_only) -{ - auto int hook (const char *name); - int hook (const char *name) - { - grub_disk_t disk; - struct grub_raid_array array; - struct grub_raid *p; - - grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name); - - disk = grub_disk_open (name); - if (!disk) - return 0; - - if (disk->total_sectors == GRUB_ULONG_MAX) - { - grub_disk_close (disk); - return 0; - } - - for (p = grub_raid_list; p; p = p->next) - { - if (! p->detect (disk, &array)) - { - if (! insert_array (disk, &array, p->name)) - return 0; - - break; - } - - /* This error usually means it's not raid, no need to display - it. */ - if (grub_errno != GRUB_ERR_OUT_OF_RANGE) - grub_print_error (); - - grub_errno = GRUB_ERR_NONE; - if (head_only) - break; - } - - grub_disk_close (disk); - - return 0; - } - - grub_device_iterate (&hook); -} - -static void free_array (void) { struct grub_raid_array *array; @@ -668,9 +618,38 @@ free_array (void) void grub_raid_register (grub_raid_t raid) { + auto int hook (const char *name); + int hook (const char *name) + { + grub_disk_t disk; + struct grub_raid_array array; + + grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name); + + disk = grub_disk_open (name); + if (!disk) + return 0; + + if ((disk->total_sectors != GRUB_ULONG_MAX) && + (! grub_raid_list->detect (disk, &array)) && + (! insert_array (disk, &array, grub_raid_list->name))) + return 0; + + /* This error usually means it's not raid, no need to display + it. */ + if (grub_errno != GRUB_ERR_OUT_OF_RANGE) + grub_print_error (); + + grub_errno = GRUB_ERR_NONE; + + grub_disk_close (disk); + + return 0; + } + raid->next = grub_raid_list; grub_raid_list = raid; - grub_raid_scan_device (1); + grub_device_iterate (&hook); } void @@ -686,13 +665,6 @@ grub_raid_unregister (grub_raid_t raid) } } -void -grub_raid_rescan (void) -{ - free_array (); - grub_raid_scan_device (0); -} - static struct grub_disk_dev grub_raid_dev = { .name = "raid", diff --git a/include/grub/raid.h b/include/grub/raid.h index 595ced1..8fa4c38 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -67,7 +67,6 @@ typedef struct grub_raid *grub_raid_t; void grub_raid_register (grub_raid_t raid); void grub_raid_unregister (grub_raid_t raid); -void grub_raid_rescan (void); void grub_raid_block_xor (char *buf1, const char *buf2, int size); typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array, diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 4722269..a4de2ae 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -293,7 +292,13 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) grub_util_error ("loopback command fails."); } - grub_raid_rescan (); + grub_lvm_fini (); + grub_mdraid_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid_init (); + grub_lvm_init (); + switch (cmd) { case CMD_LS: diff --git a/util/grub-probe.c b/util/grub-probe.c index 97d3860..df920af 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -106,7 +106,6 @@ probe (const char *path, char *device_name) char *drive_name = NULL; char *grub_path = NULL; char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL; - int abstraction_type; grub_device_t dev = NULL; grub_fs_t fs; @@ -132,28 +131,6 @@ probe (const char *path, char *device_name) goto end; } - abstraction_type = grub_util_get_dev_abstraction (device_name); - /* No need to check for errors; lack of abstraction is permissible. */ - - if (print == PRINT_ABSTRACTION) - { - char *abstraction_name; - switch (abstraction_type) - { - case GRUB_DEV_ABSTRACTION_LVM: - abstraction_name = "lvm"; - break; - case GRUB_DEV_ABSTRACTION_RAID: - abstraction_name = "raid mdraid"; - break; - default: - grub_util_info ("did not find LVM/RAID in %s, assuming raw device", device_name); - goto end; - } - printf ("%s\n", abstraction_name); - goto end; - } - drive_name = grub_util_get_grub_dev (device_name); if (! drive_name) grub_util_error ("Cannot find a GRUB drive for %s. Check your device.map.\n", device_name); @@ -169,6 +146,33 @@ probe (const char *path, char *device_name) if (! dev) grub_util_error ("%s", grub_errmsg); + if (print == PRINT_ABSTRACTION) + { + grub_disk_memberlist_t list = NULL, tmp; + const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID); + int is_raid = (dev->disk->dev->id == GRUB_DISK_DEVICE_RAID_ID); + + if ((is_lvm) && (dev->disk->dev->memberlist)) + list = dev->disk->dev->memberlist (dev->disk); + while (list) + { + is_raid |= (list->disk->dev->id == GRUB_DISK_DEVICE_RAID_ID); + tmp = list->next; + free (list); + list = tmp; + } + + if (is_raid) + printf ("raid mdraid"); + + if (is_lvm) + printf ((is_raid) ? " lvm" : "lvm"); + + printf ("\n"); + + goto end; + } + if (print == PRINT_PARTMAP) { grub_disk_memberlist_t list = NULL, tmp;