diff options
author | NeilBrown <neilb@suse.de> | 2010-11-22 10:58:07 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-11-22 10:58:07 +0100 |
commit | 66f5c4b66562cfbe0f0fb65a9bfabb17441ae23e (patch) | |
tree | 02d7f76f5606894b39a3e40d29372f833ea66f68 /Monitor.c | |
parent | Monitor: policy based spare migration. (diff) | |
download | mdadm-66f5c4b66562cfbe0f0fb65a9bfabb17441ae23e.tar.xz mdadm-66f5c4b66562cfbe0f0fb65a9bfabb17441ae23e.zip |
Monitor: teach spare migration about containers
When trying to move a spare, move to the container of a degraded
array, not to the array itself.
And don't try to move from a subarray, only from a native or container
array.
And don't move from a container which contains degraded subarrays.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Monitor.c')
-rw-r--r-- | Monitor.c | 28 |
1 files changed, 23 insertions, 5 deletions
@@ -740,10 +740,22 @@ static int move_spare(struct state *from, struct state *to, static int check_donor(struct state *from, struct state *to, struct domainlist *domlist) { + struct state *sub; + if (from == to) return 0; - if (from->active < from->raid) + if (from->parent) + /* Cannot move from a member */ return 0; + for (sub = from->subarray; sub; sub = sub->subarray) + /* If source array has degraded subarrays, don't + * remove anything + */ + if (sub->active < sub->raid) + return 0; + if (from->metadata->ss->external == 0) + if (from->active < from->raid) + return 0; if (from->spare <= 0) return 0; if (domlist == NULL) @@ -753,14 +765,20 @@ static int check_donor(struct state *from, struct state *to, static void try_spare_migration(struct state *statelist, struct alert_info *info) { - struct state *from, *to; + struct state *from; + struct state *st; link_containers_with_subarrays(statelist); - for (to = statelist; to; to = to->next) - if (to->active < to->raid && - to->spare == 0) { + for (st = statelist; st; st = st->next) + if (st->active < st->raid && + st->spare == 0) { struct domainlist *domlist = NULL; int d; + struct state *to = st; + + if (to->parent) + /* member of a container */ + to = to->parent; for (d = 0; d < MaxDisks; d++) if (to->devid[d]) |