diff options
author | Adam Kwolek <adam.kwolek@intel.com> | 2011-06-09 13:00:55 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-06-09 13:00:55 +1000 |
commit | 6c3560c0f2e16bafa2899cd1ca4df78ba9512170 (patch) | |
tree | 6b675fc7b057819ecc7098fc9bfec8eb9bd04787 | |
parent | ab724b9862d7a8c4d85ed4b19be87ba9768a2432 (diff) | |
download | mdadm-6c3560c0f2e16bafa2899cd1ca4df78ba9512170.tar.gz |
imsm: FIX: Detect failed devices during recover_backup_imsm()
Detect in recover_backup_imsm() if not opened disks number is smaller
than allowed degradation for given raid level. This allows for reshape restart
on degraded array.
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | super-intel.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/super-intel.c b/super-intel.c index a459fb0..d897900 100644 --- a/super-intel.c +++ b/super-intel.c @@ -7825,6 +7825,8 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) unsigned long num_migr_units = __le32_to_cpu(migr_rec->num_migr_units); int ascending = __le32_to_cpu(migr_rec->ascending_migr); char buffer[20]; + int skipped_disks = 0; + int max_degradation; err = sysfs_get_str(info, NULL, "array_state", (char *)buffer, 20); if (err < 1) @@ -7848,6 +7850,7 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) map_dest = get_imsm_map(id->dev, 0); new_disks = map_dest->num_members; + max_degradation = new_disks - imsm_num_data_members(id->dev, 0); read_offset = (unsigned long long) __le32_to_cpu(migr_rec->ckpt_area_pba) * 512; @@ -7866,6 +7869,10 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) open_backup_targets(info, new_disks, targets); for (i = 0; i < new_disks; i++) { + if (targets[i] < 0) { + skipped_disks++; + continue; + } if (lseek64(targets[i], read_offset, SEEK_SET) < 0) { fprintf(stderr, Name ": Cannot seek to block: %s\n", @@ -7892,6 +7899,13 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) } } + if (skipped_disks > max_degradation) { + fprintf(stderr, + Name ": Cannot restore data from backup." + " Too many failed disks\n"); + goto abort; + } + if (ascending && curr_migr_unit < (num_migr_units-1)) curr_migr_unit++; |