diff --git a/ChangeLog b/ChangeLog index 6aec4618a..a68720fc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2008-02-09 Robert Millan + + * 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(). + 2008-02-09 Robert Millan * util/grub-probe.c (main): When `verbosity > 1', set `debug' diff --git a/disk/lvm.c b/disk/lvm.c index 43c5af8ba..eb5840624 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -52,6 +52,26 @@ grub_lvm_iterate (int (*hook) (const char *name)) 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 --git a/disk/raid.c b/disk/raid.c index 8b92b3477..0d3177fd1 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -67,6 +67,26 @@ grub_raid_iterate (int (*hook) (const char *name)) 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_dev = .close = grub_raid_close, .read = grub_raid_read, .write = grub_raid_write, +#ifdef GRUB_UTIL + .memberlist = grub_raid_memberlist, +#endif .next = 0 }; diff --git a/include/grub/disk.h b/include/grub/disk.h index 9891a9cfc..2a79a0bff 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -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 --git a/util/grub-probe.c b/util/grub-probe.c index a0d38fba4..3635d74a4 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -74,6 +74,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) { @@ -133,23 +158,21 @@ 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); + grub_disk_memberlist_t list = NULL, tmp; - name = strdup (dev->disk->partition->partmap->name); - if (! name) - grub_util_error ("not enough memory"); + /* Check if dev->disk itself is contained in a partmap. */ + probe_partmap (dev->disk); - underscore = strchr (name, '_'); - if (! underscore) - grub_util_error ("Invalid partition map %s", name); - - *underscore = '\0'; - printf ("%s\n", name); - free (name); + /* 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; }