diff options
author | Adam Kwolek <adam.kwolek@intel.com> | 2011-06-08 17:09:09 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-06-08 17:09:09 +1000 |
commit | b915c95fd3c37698b7e240b00830dbc0d576c16c (patch) | |
tree | 2217b4507d42b589f81fbf8e1ca706ee8259c359 | |
parent | 10f228541c9ab498301cdbc7b4773819191e5168 (diff) | |
download | mdadm-b915c95fd3c37698b7e240b00830dbc0d576c16c.tar.gz |
imsm: Check if array degradation has been changed
Before reshaping every "migration unit", check if array is still usable.
In failed disks number is greater than allowed degradation level, reshape
has to be aborted.
Signed-off-by: Maciej Trela <maciej.trela@intel.com>
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | super-intel.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/super-intel.c b/super-intel.c index ca97bcc..4b30024 100644 --- a/super-intel.c +++ b/super-intel.c @@ -8305,6 +8305,53 @@ int wait_for_reshape_imsm(struct mdinfo *sra, unsigned long long to_complete, } /******************************************************************************* + * Function: check_degradation_change + * Description: Check that array hasn't become failed. + * Parameters: + * info : for sysfs access + * sources : source disks descriptors + * degraded: previous degradation level + * Returns: + * degradation level + ******************************************************************************/ +int check_degradation_change(struct mdinfo *info, + int *sources, + int degraded) +{ + unsigned long long new_degraded; + sysfs_get_ll(info, NULL, "degraded", &new_degraded); + if (new_degraded != (unsigned long long)degraded) { + /* check each device to ensure it is still working */ + struct mdinfo *sd; + new_degraded = 0; + for (sd = info->devs ; sd ; sd = sd->next) { + if (sd->disk.state & (1<<MD_DISK_FAULTY)) + continue; + if (sd->disk.state & (1<<MD_DISK_SYNC)) { + char sbuf[20]; + if (sysfs_get_str(info, + sd, "state", sbuf, 20) < 0 || + strstr(sbuf, "faulty") || + strstr(sbuf, "in_sync") == NULL) { + /* this device is dead */ + sd->disk.state = (1<<MD_DISK_FAULTY); + if (sd->disk.raid_disk >= 0 && + sources[sd->disk.raid_disk] >= 0) { + close(sources[ + sd->disk.raid_disk]); + sources[sd->disk.raid_disk] = + -1; + } + new_degraded++; + } + } + } + } + + return new_degraded; +} + +/******************************************************************************* * Function: imsm_manage_reshape * Description: Function finds array under reshape and it manages reshape * process. It creates stripes backups (if required) and sets @@ -8348,6 +8395,7 @@ static int imsm_manage_reshape( unsigned long long start_src; /* [bytes] */ unsigned long long start; /* [bytes] */ unsigned long long start_buf_shift; /* [bytes] */ + int degraded = 0; if (!fds || !offsets || !destfd || !destoffsets || !sra) goto abort; @@ -8414,6 +8462,15 @@ static int imsm_manage_reshape( * __le32_to_cpu(migr_rec->curr_migr_unit); unsigned long long border; + /* Check that array hasn't become failed. + */ + degraded = check_degradation_change(sra, fds, degraded); + if (degraded > 1) { + dprintf("imsm: Abort reshape due to degradation" + " level (%i)\n", degraded); + goto abort; + } + next_step = __le32_to_cpu(migr_rec->blocks_per_unit); if ((current_position + next_step) > max_position) |