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/util/grub-fstest.c b/util/grub-fstest.c index 4722269..c39529a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -294,6 +294,8 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) } grub_raid_rescan (); + grub_lvm_fini (); + grub_lvm_init (); switch (cmd) { case CMD_LS: diff --git a/util/grub-probe.c b/util/grub-probe.c index 97d3860..a187859 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; @@ -114,10 +113,10 @@ probe (const char *path, char *device_name) { #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (! grub_util_check_char_device (device_name)) - grub_util_error ("%s is not a character device.\n", device_name); + grub_util_error ("%s is not a character device.\n", device_name); #else if (! grub_util_check_block_device (device_name)) - grub_util_error ("%s is not a block device.\n", device_name); + grub_util_error ("%s is not a block device.\n", device_name); #endif } else @@ -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,38 @@ probe (const char *path, char *device_name) if (! dev) grub_util_error ("%s", grub_errmsg); + if (print == PRINT_ABSTRACTION) + { + char buf[30]; + grub_disk_memberlist_t list = NULL, tmp; + int is_lvm = 0; + int is_raid = 0; + + is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID); + 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; + } + + buf[0] = buf[1] = 0; + if (is_raid) + strcat (buf, " raid mdraid"); + + if (is_lvm) + strcat (buf, " lvm"); + + printf ("%s\n", &buf[1]); + + goto end; + } + if (print == PRINT_PARTMAP) { grub_disk_memberlist_t list = NULL, tmp;