diff options
author | Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com> | 2010-12-26 22:31:25 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-12-26 22:31:25 +1100 |
commit | 5be68a0762f479724da5e579c2b8fbf9f6a28d6a (patch) | |
tree | 070b1776f531342557dd29a43073af573570bc1e /Incremental.c | |
parent | cbeeb0e5f016044190c4bcc61393048536608770 (diff) |
external: get number of failed disks for container
Container degradation here is defined as the number of failed disks in
mostly degraded sub-array. This number is used as value for
array.failed_disks and used in comparison to find best match.
Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Incremental.c')
-rw-r--r-- | Incremental.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/Incremental.c b/Incremental.c index 944ed661..6ff64f3a 100644 --- a/Incremental.c +++ b/Incremental.c @@ -820,6 +820,32 @@ static int count_active(struct supertype *st, struct mdinfo *sra, return cnt; } +/* test if container has degraded member(s) */ +static int container_members_max_degradation(struct map_ent *map, struct map_ent *me) +{ + mdu_array_info_t array; + int afd; + int max_degraded = 0; + + for(; map; map = map->next) { + if (!is_subarray(map->metadata) || + devname2devnum(map->metadata+1) != me->devnum) + continue; + afd = open_dev(map->devnum); + if (afd < 0) + continue; + /* most accurate information regarding array degradation */ + if (ioctl(afd, GET_ARRAY_INFO, &array) >= 0) { + int degraded = array.raid_disks - array.active_disks - + array.spare_disks; + if (degraded > max_degraded) + max_degraded = degraded; + } + close(afd); + } + return (max_degraded); +} + static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, struct map_ent *target, int bare, struct supertype *st, int verbose) @@ -887,7 +913,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE| GET_COMPONENT|GET_VERSION); if (sra) - sra->array.failed_disks = 0; + sra->array.failed_disks = -1; } if (!sra) continue; @@ -914,6 +940,11 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, goto next; } else st2 = st; + /* update number of failed disks for mostly degraded + * container member */ + if (sra->array.failed_disks == -1) + sra->array.failed_disks = container_members_max_degradation(map, mp); + get_dev_size(dfd, NULL, &devsize); if (st2->ss->avail_size(st2, devsize) < sra->component_size) { if (verbose > 1) |