>From 92f0a71f94a4568647e137f8f0d857be7fd482df Mon Sep 17 00:00:00 2001 From: Marcin Labun <marcin.labun@xxxxxxxxx> Date: Wed, 29 Sep 2010 05:32:29 +0200 Subject: [AUTOREBUILD 7/8] Monitor: Respect policy in auto-rebuild in mdadm monitoring. Respect policy definition from mdadm.conf. For each degraded volume/container, its policy is retrieved. In next steps potential donor container/volume is searched for a spare disk, For each spare disk we check if the domain matches and verify is the action token allows for spare sharing. *spare* action is minimum to let spare sharing in the same policy domain. Signed-off-by: Marcin Labun <marcin.labun@xxxxxxxxx> --- Monitor.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 85 insertions(+), 12 deletions(-) diff --git a/Monitor.c b/Monitor.c index 62cbe98..dd9e707 100644 --- a/Monitor.c +++ b/Monitor.c @@ -724,6 +724,33 @@ static int dev_suitable(unsigned devid, int devstate, unsigned long long size) return 0; } +struct state *get_parent(struct state *st) +{ + if (is_external(st->metadata_version)) + return st->parent; + else + return st; +} + +static struct supertype *get_super(struct state *st) +{ + struct supertype *super = NULL; + char *metadata = NULL; + int i; + + if (is_external(st->metadata_version)) { + st = st->parent; + if (!st) + return NULL; + metadata = st->metadata_version + strlen("external:"); + } else { + metadata = st->metadata_version; + } + for (i = 0; !super && superlist[i]; i++) + super = superlist[i]->match_metadata_desc(metadata); + return super; +} + /* If an array has active < raid && spare == 0 * Look for another array/container with unused, unfailed spare @@ -736,40 +763,51 @@ static void spare_sharing(struct state *statelist, char *mailaddr, struct state *st, *stp, *vol, *st2 = NULL; int i, ext, found; struct mdinfo *sra = NULL; + struct domainlist *dl = NULL; + struct supertype *super = NULL; for (st = statelist; st; st = st->next) { if (st->err || st->active == st->raid || st->spare > 0) continue; - found = 0; ext = is_external(st->metadata_version); /* * for exernal metadata spare will be moved to parent container */ - if (ext) { - stp = st->parent; - if (!stp) - continue; - } else { - stp = st; - } - /* get member device state updated */ + stp = get_parent(st); + if (!stp) + continue; + super = get_super(st); + if (!super) + continue; + /* get the disk state updated */ sra = get_raid_disk_info(stp); if (!sra) { dprintf("no sra for device: %s\n", stp->devname); continue; } - sysfs_free(sra); for (i = 0; i < stp->total; i++) if (dev_suitable(stp->devid[i], stp->devstate[i], st->min_size)) break; - if (i < stp->total) + if (i < stp->total) { /* there is a spare in array/parent container, * it was probably just added * but mdmon has not started recovery yet * we will not add any more spares for now */ + sysfs_free(sra); + continue; + } + + /* get the array/volume domain */ + dl = domain_from_array(sra, super->ss->name); + sysfs_free(sra); + if (!dl) { + dprintf("domain: %p name: %s dev: %s meta: %s\n", + dl, (dl) ? dl->dom : "NULL", stp->devname, + super->ss->name); continue; + } /* search for an array/container with unused spare */ for (st2 = statelist; st2; st2 = st2->next) { @@ -791,12 +829,47 @@ static void spare_sharing(struct state *statelist, char *mailaddr, if (st2->active < st2->raid) continue; } - /* support for domain comparision needed */ + + /* update the disk info in st2 state */ + sra = get_raid_disk_info(st2); + if (!sra) { + fprintf(stderr, "no sra for device: %s\n", + st2->devname); + continue; + } + sysfs_free(sra); for (i = 0; i < st2->total; i++) { + struct dev_policy *policy = NULL; + struct mdinfo dinfo; + enum policy_action action; if (!dev_suitable(st2->devid[i], st2->devstate[i], st->min_size)) continue; + + dinfo.disk.major = major(st2->devid[i]); + dinfo.disk.minor = minor(st2->devid[i]); + + policy = disk_policy(&dinfo); + /* Can only add a spare if device has at least + one domains */ + if (pol_find(policy, pol_domain) == NULL) + continue; + + if (!domain_test(dl, policy, super->ss->name)) { + /* domain test fails */ + dprintf("domain test fails: %s" + "(name: %s value: %s metadata: %s)\n", + dl->dom, + (policy) ? policy->name : "NULL", + (policy) ? policy->value : "NULL", + super->ss->name); + continue; + } + /* check if spare sharing alowed */ + action = policy_action(policy, super->ss->name); + if (action < act_spare) + continue; if (move_spare(st2, stp, &st2->devid[i], mailaddr, mailfrom, alert_cmd, dosyslog)) { -- 1.6.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html