RE: [AUTOREBUILD 7/8] Monitor: Respect policy in auto-rebuild inmdadm monitoring.
am 01.10.2010 14:58:13 von Marcin.Labun=46rom 92f0a71f94a4568647e137f8f0d857be7fd482df Mon Sep 17 00:00:00 200=
1
=46rom: Marcin Labun
Date: Wed, 29 Sep 2010 05:32:29 +0200
Subject: [AUTOREBUILD 7/8] Monitor: Respect policy in auto-rebuild in m=
dadm monitoring.
Respect policy definition from mdadm.conf.
=46or each degraded volume/container, its policy is retrieved. In next =
steps
potential donor container/volume is searched for a spare disk,
=46or 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=20
in the same policy domain.
Signed-off-by: Marcin Labun
---
=A0Monitor.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++=
++++++-------
=A01 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 devsta=
te, unsigned long long size)
=A0 return 0;
=A0}
=A0
+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 =3D NULL;
+ char *metadata =3D NULL;
+ int i;
+
+ if (is_external(st->metadata_version)) {
+ st =3D st->parent;
+ if (!st)
+ return NULL;
+ metadata =3D st->metadata_version + str=
len("external:");
+ } else {
+ metadata =3D st->metadata_version;
+ }
+ for (i =3D 0; !super && superlist[i]; i++)
+ super =3D superlist[i]->match_metadata_=
desc(metadata);
+ return super;
+}
+
=A0
=A0/* If an array has active < raid && spare == 0
=A0 * Look for another array/container with unused, unfailed spare
@@ -736,40 +763,51 @@ static void spare_sharing(struct state *statelist=
, char *mailaddr,
=A0 struct state *st, *stp, *vol, *st2 =3D NULL;
=A0 int i, ext, found;
=A0 struct mdinfo *sra =3D NULL;
+ struct domainlist *dl =3D NULL;
+ struct supertype *super =3D NULL;
=A0
=A0 for (st =3D statelist; st; st =3D st->next) {
=A0 if (st->err || st->active == st->=
raid || st->spare > 0)
=A0 continue;
-
=A0 found =3D 0;
=A0 ext =3D is_external(st->metadata_vers=
ion);
=A0 /*
=A0 =A0* for exernal metadata spare will =
be moved to parent container
=A0 =A0*/
- if (ext) {
- stp =3D st->parent;
- if (!stp)
- =A0=A 0 con=
tinue;
- } else {
- stp =3D st;
- }
- /* get member device state updated */
+ stp =3D get_parent(st);
+ if (!stp)
+ continue;
+ super =3D get_super(st);
+ if (!super)
+ continue;
+ /* get the disk state updated */
=A0 sra =3D get_raid_disk_info(stp);
=A0 if (!sra) {
=A0 dprintf("no sra for=
device: %s\n", stp->devname);
=A0 continue;
=A0 }
- sysfs_free(sra);
=A0 for (i =3D 0; i < stp->total; i++)
=A0 if (dev_suitable(st=
p->devid[i], stp->devstate[i],
=
=A0 =A0st->min_size))
=A0 b=
reak;
- if (i < stp->total)
+ if (i < stp->total) {
=A0 /* there is a spare=
in array/parent container,
=A0 =A0* it was probabl=
y just added
=A0 =A0* but mdmon has =
not started recovery yet
=A0 =A0* we will not ad=
d any more spares for now */
+ sysfs_free(sra);
+ continue;
+ }
+
+ /* get the array/volume domain */
+ dl =3D domain_from_array(sra, super->ss=
->name);
+ sysfs_free(sra);
+ if (!dl) {
+ dprintf("domain: %p n=
ame: %s dev: %s meta: %s\n",
+ =A0=A 0 dl,=
(dl) ? dl->dom : "NULL", stp->devname,
+ =A0=A 0 sup=
er->ss->name);
=A0 continue;
+ }
=A0
=A0 /* search for an array/container with=
unused spare */
=A0 for (st2 =3D statelist; st2; st2 =3D =
st2->next) {
@@ -791,12 +829,47 @@ static void spare_sharing(struct state *statelist=
, char *mailaddr,
=A0 i=
f (st2->active < st2->raid)
=
=A0 continue;
=A0 }
- /* support for domain=
comparision needed */
+
+ /* update the disk in=
fo in st2 state */
+ sra =3D get_raid_disk=
_info(st2);
+ if (!sra) {
+ =A0=A 0 fpr=
intf(stderr, "no sra for device: %s\n",
+ =A0=A 0 =
st2->devname);
+ =A0=A 0 con=
tinue;
+ }
+ sysfs_free(sra);
=A0 for (i =3D 0; i < s=
t2->total; i++) {
+ =A0=A 0 str=
uct dev_policy *policy =3D NULL;
+ =A0=A 0 str=
uct mdinfo dinfo;
+ =A0=A 0 enu=
m policy_action action;
=A0 i=
f (!dev_suitable(st2->devid[i],
=
=A0 st2->devstate[i],
=
=A0 =A0 st->min_size))
=
=A0 continue;
+
+ =A0=A 0 din=
fo.disk.major =3D major(st2->devid[i]);
+ =A0=A 0 din=
fo.disk.minor =3D minor(st2->devid[i]);
+
+ =A0=A 0 pol=
icy =3D disk_policy(&dinfo);
+ =A0=A 0 /* =
Can only add a spare if device has at least
+ =A0=A 0 =A0=
=A0 one domains */
+ =A0=A 0 if =
(pol_find(policy, pol_domain) == NULL)
+ =A0=A 0 =
continue;
+
+ =A0=A 0 if =
(!domain_test(dl, policy, super->ss->name)) {
+ =A0=A 0 =
/* domain test fails */
+ =A0=A 0 =
dprintf("domain test fails: %s"
+ =A0=A 0 =
"(name: %s value: %s metadata: %s)\n",
+ =A0=A 0 =
dl->dom,
+ =A0=A 0 =
(policy) ? policy->name : "NULL",
+ =A0=A 0 =
(policy) ? policy->value : "NULL",
+ =A0=A 0 =
super->ss->name);
+ =A0=A 0 =
continue;
+ =A0=A 0 }
+ =A0=A 0 /* =
check if spare sharing alowed */
+ =A0=A 0 act=
ion =3D policy_action(policy, super->ss->name);
+ =A0=A 0 if =
(action < act_spare)
+ =A0=A 0 =
continue;
=A0 i=
f (move_spare(st2, stp, &st2->devid[i],
=
=A0 mailaddr, mailfrom, alert_cmd,
=
=A0 dosyslog)) {
--=20
1.6.4.2
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" i=
n
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html