summaryrefslogtreecommitdiffstats
path: root/Monitor.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-11-22 10:58:07 +0100
committerNeilBrown <neilb@suse.de>2010-11-22 10:58:07 +0100
commit66f5c4b66562cfbe0f0fb65a9bfabb17441ae23e (patch)
tree02d7f76f5606894b39a3e40d29372f833ea66f68 /Monitor.c
parentMonitor: policy based spare migration. (diff)
downloadmdadm-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.c28
1 files changed, 23 insertions, 5 deletions
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])