summaryrefslogtreecommitdiff
path: root/super-intel.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2010-04-19 15:28:07 +1000
committerNeilBrown <neilb@suse.de>2010-04-19 15:28:07 +1000
commit4eb269706f403d2424166683688f0a41d893c1c3 (patch)
treeeff7209c10aa9810ba7cbe4eca325357388aab5c /super-intel.c
parentc824e918980e46aa8dba5d806304877444837054 (diff)
Create: cleanup after failed create in duplicated array member case
mdadm prevents creation when device names are duplicated on the command line, but leaves the partially created array intact. Detect this case in the error code from add_to_super() and cleanup the partially created array. The imsm handler is updated to report this conflict in add_to_super_imsm_volume(). Note that since neither mdmon, nor userspace for that matter, ever saw an active array we only need to perform a subset of the cleanup actions. So call ioctl(STOP_ARRAY) directly and arrange for Create() to cleanup the map file rather than calling Manage_runstop(). Reported-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'super-intel.c')
-rw-r--r--super-intel.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/super-intel.c b/super-intel.c
index 999b9707..677396c6 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -3035,7 +3035,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
map->num_members = info->raid_disks;
for (i = 0; i < map->num_members; i++) {
/* initialized in add_to_super */
- set_imsm_ord_tbl_ent(map, i, 0);
+ set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD);
}
mpb->num_raid_devs++;
@@ -3113,6 +3113,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
struct dl *dl;
struct imsm_dev *dev;
struct imsm_map *map;
+ int slot;
dev = get_imsm_dev(super, super->current_vol);
map = get_imsm_map(dev, 0);
@@ -3147,6 +3148,14 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
dl->index = super->anchor->num_disks;
super->anchor->num_disks++;
}
+ /* Check the device has not already been added */
+ slot = get_imsm_disk_slot(map, dl->index);
+ if (slot >= 0 &&
+ (get_imsm_ord_tbl_ent(dev, slot) & IMSM_ORD_REBUILD) == 0) {
+ fprintf(stderr, Name ": %s has been included in this array twice\n",
+ devname);
+ return 1;
+ }
set_imsm_ord_tbl_ent(map, dk->number, dl->index);
dl->disk.status = CONFIGURED_DISK;