>From f423b226f10cfe3b416c5e0580dde45cd8ca887d Mon Sep 17 00:00:00 2001 From: Marcin Labun <marcin.labun@xxxxxxxxx> Date: Wed, 29 Sep 2010 05:39:53 +0200 Subject: [AUTOREBUILD 8/8] Monitor: Helper functions added for spare_sharing in monitor Helper functions added: check_domain_match - checks domain policy matching of potential spare disk check_donor - checks if container/volume is eligible to give a spare disk Signed-off-by: Marcin Labun <marcin.labun@xxxxxxxxx> --- Monitor.c | 122 +++++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 75 insertions(+), 47 deletions(-) diff --git a/Monitor.c b/Monitor.c index dd9e707..c6f9565 100644 --- a/Monitor.c +++ b/Monitor.c @@ -751,6 +751,70 @@ static struct supertype *get_super(struct state *st) return super; } +/* checks if domains of potential spare disk and + * a volume/container domain under rebuild match + */ +static int check_domain_match(struct domainlist *dl, + unsigned devid, + struct supertype *super) +{ + struct dev_policy *policy = NULL; + struct mdinfo dinfo; + enum policy_action action; + + dinfo.disk.major = major(devid); + dinfo.disk.minor = minor(devid); + + policy = disk_policy(&dinfo); + /* Can only add a spare if device has at least one domains */ + if (pol_find(policy, pol_domain) == NULL) + return 0; + + if (!domain_test(dl, policy, super->ss->name)) { + 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); + /* domain test fails */ + return 0; + } + /* check if spare sharing allowed */ + action = policy_action(policy, super->ss->name); + if (action < act_spare) + return 0; + return 1; +} + +/* check if donoring volume/container: + * - has the same metadata + * - has not error reported + * - has not degraded volume + * Returns: + * 0 - do not use the volume/container + * 1 - volume/container can be potetial spare disk donor + */ +static int check_donor(struct state *st2, struct state *stp) +{ + struct state *vol; + int ext = (stp->volumes != NULL); + + if (st2->err || st2 == stp) + return 0; + if ((ext && st2->parent != NULL) || + (strcmp(stp->metadata_version, st2->metadata_version) != 0)) + return 0; + if (ext) { + /* if container has degraded volume + * we can't remove spares */ + for (vol = st2->volumes; vol; vol = vol->volumes) + if (vol->active < vol->raid) + return 0; + } else if (st2->active < st2->raid) + return 0; + return 1; +} /* If an array has active < raid && spare == 0 * Look for another array/container with unused, unfailed spare @@ -760,8 +824,8 @@ static struct supertype *get_super(struct state *st) static void spare_sharing(struct state *statelist, char *mailaddr, char *mailfrom, char *alert_cmd, int dosyslog) { - struct state *st, *stp, *vol, *st2 = NULL; - int i, ext, found; + struct state *st, *stp, *st2 = NULL; + int i, found; struct mdinfo *sra = NULL; struct domainlist *dl = NULL; struct supertype *super = NULL; @@ -770,7 +834,7 @@ static void spare_sharing(struct state *statelist, char *mailaddr, 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 */ @@ -811,65 +875,29 @@ static void spare_sharing(struct state *statelist, char *mailaddr, /* search for an array/container with unused spare */ for (st2 = statelist; st2; st2 = st2->next) { - if (st2->err || st2 == stp) - continue; - if ((ext && st2->parent != NULL) || - (strcmp(stp->metadata_version, - st2->metadata_version) != 0)) + /* check if donor container/volume */ + if (!check_donor(st2, stp)) continue; - if (ext) { - /* if container has degraded volume - * we can't remove spares */ - for (vol = st2->volumes; vol; vol = vol->volumes) - if (vol->active < vol->raid) - break; - if (vol) - continue; - } else { - if (st2->active < st2->raid) - continue; - } /* 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); + fprintf(stderr, + "Cannot retrive the disk states " + "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) + if (!check_domain_match(dl, + st2->devid[i], + super)) 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