RE: [AUTOREBUILD 7/8] Monitor: Respect policy in auto-rebuild inmdadm monitoring.

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