From 5c4cd5da70b4ed1a5518caa234c38eab502a37e4 Mon Sep 17 00:00:00 2001 From: Anna Czarnowska Date: Mon, 22 Nov 2010 20:58:07 +1100 Subject: [PATCH] imsm: create mdinfo list of disks in a container from supertype If getinfo_super is called on a container supertype we only get information on first disk. As a parameter it uses reference to preallocated mdinfo structure. Amending getinfo_super to return full list of disks would require ammending all previous calls and subsequently freeing memory allocated for mdinfo list. Function container_content that returns a mdinfo list is written specifically for assembly, performing actions not needed to just fill mdinfo. It also does not include spares so is unsuitable. As an alternative a new function getinfo_super_disks is created to obtain information about all disks states in array. Existing function sysfs_free is used to free memory allocated by getinfo_super_disks. Signed-off-by: Anna Czarnowska Signed-off-by: Marcin Labun Signed-off-by: NeilBrown --- mdadm.h | 2 +- super-intel.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/mdadm.h b/mdadm.h index daaf628..3b0cad1 100644 --- a/mdadm.h +++ b/mdadm.h @@ -548,7 +548,7 @@ extern struct superswitch { * appear to be failed/missing. */ void (*getinfo_super)(struct supertype *st, struct mdinfo *info, char *map); - + struct mdinfo *(*getinfo_super_disks)(struct supertype *st); /* Check if the given metadata is flagged as belonging to "this" * host. 0 for 'no', 1 for 'yes', -1 for "Don't record homehost" */ diff --git a/super-intel.c b/super-intel.c index 58d0fa7..b736e4f 100644 --- a/super-intel.c +++ b/super-intel.c @@ -1690,6 +1690,51 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * } +/* allocates memory and fills disk in mdinfo structure + * for each disk in array */ +struct mdinfo *getinfo_super_disks_imsm(struct supertype *st) +{ + struct mdinfo *mddev = NULL; + struct intel_super *super = st->sb; + struct imsm_disk *disk; + int count = 0; + struct dl *dl; + if (!super || !super->disks) + return NULL; + dl = super->disks; + mddev = malloc(sizeof(*mddev)); + if (!mddev) { + fprintf(stderr, Name ": Failed to allocate memory.\n"); + return NULL; + } + memset(mddev, 0, sizeof(*mddev)); + while (dl) { + struct mdinfo *tmp; + disk = &dl->disk; + tmp = malloc(sizeof(*tmp)); + if (!tmp) { + fprintf(stderr, Name ": Failed to allocate memory.\n"); + if (mddev) + sysfs_free(mddev); + return NULL; + } + memset(tmp, 0, sizeof(*tmp)); + if (mddev->devs) + tmp->next = mddev->devs; + mddev->devs = tmp; + tmp->disk.number = count++; + tmp->disk.major = dl->major; + tmp->disk.minor = dl->minor; + tmp->disk.state = is_configured(disk) ? + (1 << MD_DISK_ACTIVE) : 0; + tmp->disk.state |= is_failed(disk) ? (1 << MD_DISK_FAULTY) : 0; + tmp->disk.state |= is_spare(disk) ? 0 : (1 << MD_DISK_SYNC); + tmp->disk.raid_disk = -1; + dl = dl->next; + } + return mddev; +} + static int update_super_imsm(struct supertype *st, struct mdinfo *info, char *update, char *devname, int verbose, int uuid_set, char *homehost) @@ -5579,6 +5624,7 @@ struct superswitch super_imsm = { .match_home = match_home_imsm, .uuid_from_super= uuid_from_super_imsm, .getinfo_super = getinfo_super_imsm, + .getinfo_super_disks = getinfo_super_disks_imsm, .update_super = update_super_imsm, .avail_size = avail_size_imsm,