From: NeilBrown Date: Mon, 22 Nov 2010 09:58:07 +0000 (+1100) Subject: Monitor: teach spare migration about containers X-Git-Tag: mdadm-3.2~251 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66f5c4b66562cfbe0f0fb65a9bfabb17441ae23e;p=thirdparty%2Fmdadm.git 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 --- diff --git a/Monitor.c b/Monitor.c index ba6735c4..793087e0 100644 --- a/Monitor.c +++ b/Monitor.c @@ -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])