* disk/lvm.c [GRUB_UTIL] (grub_lvm_memberlist): New function. Construct and return a grub_diskmemberlist_t composed of LVM physical volumes. [GRUB_UTIL] (grub_lvm_dev): Add `memberlist' member. * disk/raid.c [GRUB_UTIL] (grub_raid_memberlist): New function. Construct and return a grub_diskmemberlist_t composed of physical array members. [GRUB_UTIL] (grub_raid_dev): Add `memberlist' member. * include/grub/disk.h [GRUB_UTIL] (grub_disk_memberlist): New struct prototype. [GRUB_UTIL] (struct grub_disk_dev): Add `memberlist' function pointer. [GRUB_UTIL] (struct grub_disk_memberlist): New struct declaration. [GRUB_UTIL] (grub_disk_memberlist_t): New typedef. * util/grub-probe.c (probe): Move partmap probing code from here ... (probe_partmap): ... to here. (probe): Use probe_partmap() once for the disk we're probing, and additionally, when such disk contains a memberlist() struct member, once for each disk that is contained in the structure returned by memberlist(). diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/disk/lvm.c ./disk/lvm.c --- ../grub2/disk/lvm.c 2007-07-22 01:32:20.000000000 +0200 +++ ./disk/lvm.c 2008-02-08 15:37:27.000000000 +0100 @@ -52,6 +52,26 @@ grub_lvm_iterate (int (*hook) (const cha return 0; } +#ifdef GRUB_UTIL +static grub_disk_memberlist_t +grub_lvm_memberlist (grub_disk_t disk) +{ + struct grub_lvm_lv *lv = disk->data; + grub_disk_memberlist_t list = NULL, tmp; + struct grub_lvm_pv *pv; + + for (pv = lv->vg->pvs; pv; pv = pv->next) + { + tmp = grub_malloc (sizeof (*tmp)); + tmp->disk = pv->disk; + tmp->next = list; + list = tmp; + } + + return list; +} +#endif + static grub_err_t grub_lvm_open (const char *name, grub_disk_t disk) { @@ -479,6 +499,9 @@ static struct grub_disk_dev grub_lvm_dev .close = grub_lvm_close, .read = grub_lvm_read, .write = grub_lvm_write, +#ifdef GRUB_UTIL + .memberlist = grub_lvm_memberlist, +#endif .next = 0 }; diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/disk/raid.c ./disk/raid.c --- ../grub2/disk/raid.c 2008-02-08 13:35:05.000000000 +0100 +++ ./disk/raid.c 2008-02-08 15:37:05.000000000 +0100 @@ -67,6 +67,26 @@ grub_raid_iterate (int (*hook) (const ch return 0; } +#ifdef GRUB_UTIL +static grub_disk_memberlist_t +grub_raid_memberlist (grub_disk_t disk) +{ + struct grub_raid_array *array = disk->data; + grub_disk_memberlist_t list = NULL, tmp; + int i; + + for (i = 0; i < array->total_devs; i++) + { + tmp = grub_malloc (sizeof (*tmp)); + tmp->disk = array->device[i]; + tmp->next = list; + list = tmp; + } + + return list; +} +#endif + static grub_err_t grub_raid_open (const char *name, grub_disk_t disk) { @@ -531,6 +551,9 @@ static struct grub_disk_dev grub_raid_de .close = grub_raid_close, .read = grub_raid_read, .write = grub_raid_write, +#ifdef GRUB_UTIL + .memberlist = grub_raid_memberlist, +#endif .next = 0 }; diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/include/grub/disk.h ./include/grub/disk.h --- ../grub2/include/grub/disk.h 2008-01-21 00:20:36.000000000 +0100 +++ ./include/grub/disk.h 2008-02-08 15:37:05.000000000 +0100 @@ -40,6 +40,9 @@ enum grub_disk_dev_id }; struct grub_disk; +#ifdef GRUB_UTIL +struct grub_disk_memberlist; +#endif /* Disk device. */ struct grub_disk_dev @@ -67,6 +70,10 @@ struct grub_disk_dev grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector, grub_size_t size, const char *buf); +#ifdef GRUB_UTIL + struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk); +#endif + /* The next disk device. */ struct grub_disk_dev *next; }; @@ -105,6 +112,15 @@ struct grub_disk }; typedef struct grub_disk *grub_disk_t; +#ifdef GRUB_UTIL +struct grub_disk_memberlist +{ + grub_disk_t disk; + struct grub_disk_memberlist *next; +}; +typedef struct grub_disk_memberlist *grub_disk_memberlist_t; +#endif + /* The sector size. */ #define GRUB_DISK_SECTOR_SIZE 0x200 #define GRUB_DISK_SECTOR_BITS 9 diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/util/grub-probe.c ./util/grub-probe.c --- ../grub2/util/grub-probe.c 2008-02-06 22:07:49.000000000 +0100 +++ ./util/grub-probe.c 2008-02-08 15:37:05.000000000 +0100 @@ -75,6 +75,31 @@ grub_refresh (void) } static void +probe_partmap (grub_disk_t disk) +{ + char *name; + char *underscore; + + if (disk->partition == NULL) + { + grub_util_info ("No partition map found for %s", disk->name); + return; + } + + name = strdup (disk->partition->partmap->name); + if (! name) + grub_util_error ("Not enough memory"); + + underscore = strchr (name, '_'); + if (! underscore) + grub_util_error ("Invalid partition map %s", name); + + *underscore = '\0'; + printf ("%s\n", name); + free (name); +} + +static void probe (const char *path) { char *device_name; @@ -133,23 +158,19 @@ probe (const char *path) if (print == PRINT_PARTMAP) { - char *name; - char *underscore; - - if (dev->disk->partition == NULL) - grub_util_error ("Cannot detect partition map for %s", drive_name); - - name = strdup (dev->disk->partition->partmap->name); - if (! name) - grub_util_error ("not enough memory"); - - underscore = strchr (name, '_'); - if (! underscore) - grub_util_error ("Invalid partition map %s", name); - - *underscore = '\0'; - printf ("%s\n", name); - free (name); + grub_disk_memberlist_t list = NULL, tmp; + /* Check if dev->disk itself is contained in a partmap. */ + probe_partmap (dev->disk); + /* In case of LVM/RAID, check the member devices as well. */ + if (dev->disk->dev->memberlist) + list = dev->disk->dev->memberlist (dev->disk); + while (list) + { + probe_partmap (list->disk); + tmp = list->next; + free (list); + list = tmp; + } goto end; }