[multipathd] re-enable disabled PG when at least one path is up
authorroot <root@xa-s05.(none)>
Tue, 21 Jun 2005 10:06:27 +0000 (12:06 +0200)
committerroot <root@xa-s05.(none)>
Tue, 21 Jun 2005 10:06:27 +0000 (12:06 +0200)
Kernel DM is able to disable PG, so userspace daemon should take care of
re-enabling them when appropriate.

Suggested by Ed Goggin, EMC.

libmultipath/devmapper.c
libmultipath/devmapper.h
libmultipath/dmparser.c
libmultipath/structs.h
multipathd/main.c

index d99e24c..580b6c8 100644 (file)
@@ -377,8 +377,8 @@ out:
        return r;
 }
 
-int
-dm_switchgroup(char * mapname, int index)
+static int
+dm_groupmsg (char * msg, char * mapname, int index)
 {
        int r = 0;
        struct dm_task *dmt;
@@ -393,7 +393,7 @@ dm_switchgroup(char * mapname, int index)
        if (!dm_task_set_sector(dmt, 0))
                goto out;
 
-       snprintf(str, 24, "switch_group %i\n", index);
+       snprintf(str, 24, "%s_group %i\n", msg, index);
        condlog(3, "message %s 0 %s", mapname, str);
 
        if (!dm_task_set_message(dmt, str))
@@ -413,6 +413,24 @@ dm_switchgroup(char * mapname, int index)
 }
 
 int
+dm_switchgroup(char * mapname, int index)
+{
+       return dm_groupmsg("switch", mapname,index);
+}
+
+int
+dm_enablegroup(char * mapname, int index)
+{
+       return dm_groupmsg("enable", mapname,index);
+}
+
+int
+dm_disablegroup(char * mapname, int index)
+{
+       return dm_groupmsg("disable", mapname,index);
+}
+
+int
 dm_get_maps (vector mp, char * type)
 {
        struct multipath * mpp;
index 8a2bb55..f0036c6 100644 (file)
@@ -9,6 +9,8 @@ int dm_flush_maps (char *);
 int dm_fail_path(char * mapname, char * path);
 int dm_reinstate(char * mapname, char * path);
 int dm_switchgroup(char * mapname, int index);
+int dm_enablegroup(char * mapname, int index);
+int dm_disablegroup(char * mapname, int index);
 int dm_get_maps (vector mp, char * type);
 int dm_geteventnr (char *name);
 int dm_get_minor (char *name);
index 0d53fb1..fcf144e 100644 (file)
@@ -219,6 +219,8 @@ disassemble_map (vector pathvec, char * params, struct multipath * mpp)
                        if (!strlen(mpp->wwid))
                                strncpy(mpp->wwid, pp->wwid, WWID_SIZE);
 
+                       pp->pgindex = i + 1;
+
                        for (k = 0; k < num_paths_args; k++)
                                p += get_word(p, NULL);
                }
index 01b055f..ae6e54e 100644 (file)
@@ -81,6 +81,7 @@ struct path {
        int failcount;
        int priority;
        int claimed;
+       int pgindex;
        char * getuid;
        char * getprio;
        int (*checkfn) (int, char *, void **);
index c369d1f..753c922 100644 (file)
@@ -862,6 +862,19 @@ reinstate_path (struct path * pp)
        }
 }
 
+static void
+enable_group(struct path * pp)
+{
+       struct pathgroup * pgp;
+
+       pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
+       
+       if (pgp->status == PGSTATE_DISABLED) {
+               condlog(2, "%s: enable group #%i", pp->mpp->alias, pp->pgindex);
+               dm_enablegroup(pp->mpp->alias, pp->pgindex);
+       }
+}
+
 static void *
 checkerloop (void *ap)
 {
@@ -957,6 +970,13 @@ checkerloop (void *ap)
 
                                if (pp->mpp->pgfailback == FAILBACK_IMMEDIATE)
                                        switch_pathgroup(pp->mpp);
+
+                               /*
+                                * if at least one path is up in a group, and
+                                * the group is disabled, re-enable it
+                                */
+                               if (newstate == PATH_UP)
+                                       enable_group(pp);
                        }
                        else if (newstate == PATH_UP || newstate == PATH_GHOST) {
                                /*
@@ -984,6 +1004,7 @@ checkerloop (void *ap)
                                pp->tick = pp->checkint;
                                condlog(4, "%s: delay next check %is",
                                                pp->dev_t, pp->tick);
+
                        }
                        pp->state = newstate;
                }