[libmultipath] store the pgpolicy function pointer in struct multipath
authorChristophe Varoqui <root@xa-s05.(none)>
Thu, 17 Nov 2005 10:51:15 +0000 (11:51 +0100)
committerChristophe Varoqui <root@xa-s05.(none)>
Thu, 17 Nov 2005 10:51:15 +0000 (11:51 +0100)
- setup the pointer in libmultipath/propsel.c:select_pgpolicy
- use in multipath/main.c:setup_map()

Edward Goggin, EMC, patch-chest

libmultipath/propsel.c
libmultipath/structs.h
multipath/main.c

index 1c7b12b..5817617 100644 (file)
 
 #include "../libcheckers/checkers.h"
 
+pgpolicyfn *pgpolicies[] = {
+       NULL,
+       one_path_per_group,
+       one_group,
+       group_by_serial,
+       group_by_prio,
+       group_by_node_name
+};
+
 /*
  * selectors :
  * traverse the configuration layers from most specific to most generic
@@ -74,13 +83,11 @@ select_pgfailback (struct multipath * mp)
 extern int
 select_pgpolicy (struct multipath * mp)
 {
-       struct path * pp;
        char pgpolicy_name[POLICY_NAME_SIZE];
 
-       pp = VECTOR_SLOT(mp->paths, 0);
-
        if (conf->pgpolicy_flag > 0) {
                mp->pgpolicy = conf->pgpolicy_flag;
+               mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
                if (get_pgpolicy_name(pgpolicy_name, mp->pgpolicy))
                        return 1;
                condlog(3, "pgpolicy = %s (cmd line flag)", pgpolicy_name);
@@ -88,6 +95,7 @@ select_pgpolicy (struct multipath * mp)
        }
        if (mp->mpe && mp->mpe->pgpolicy > 0) {
                mp->pgpolicy = mp->mpe->pgpolicy;
+               mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
                if (get_pgpolicy_name(pgpolicy_name, mp->pgpolicy))
                        return 1;
                condlog(3, "pgpolicy = %s (LUN setting)", pgpolicy_name);
@@ -95,6 +103,7 @@ select_pgpolicy (struct multipath * mp)
        }
        if (mp->hwe && mp->hwe->pgpolicy > 0) {
                mp->pgpolicy = mp->hwe->pgpolicy;
+               mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
                if (get_pgpolicy_name(pgpolicy_name, mp->pgpolicy))
                        return 1;
                condlog(3, "pgpolicy = %s (controler setting)", pgpolicy_name);
@@ -102,12 +111,14 @@ select_pgpolicy (struct multipath * mp)
        }
        if (conf->default_pgpolicy > 0) {
                mp->pgpolicy = conf->default_pgpolicy;
+               mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
                if (get_pgpolicy_name(pgpolicy_name, mp->pgpolicy))
                        return 1;
                condlog(3, "pgpolicy = %s (config file default)", pgpolicy_name);
                return 0;
        }
        mp->pgpolicy = FAILOVER;
+       mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
        if (get_pgpolicy_name(pgpolicy_name, mp->pgpolicy))
                return 1;
        condlog(3, "pgpolicy = %s (internal default)", pgpolicy_name);
index d53f04e..2ba1053 100644 (file)
@@ -109,9 +109,12 @@ struct path {
        struct hwentry * hwe;
 };
 
+typedef int (pgpolicyfn) (struct multipath *);
+
 struct multipath {
        char wwid[WWID_SIZE];
        int pgpolicy;
+       pgpolicyfn *pgpolicyfn;
        int nextpg;
        int bestpg;
        int queuedio;
index 1efe53e..8b14ca1 100644 (file)
@@ -308,52 +308,42 @@ filter_pathvec (vector pathvec, char * refwwid)
 static int
 setup_map (struct multipath * mpp)
 {
+       struct pathgroup * pgp;
+       int i;
+       
        /*
         * don't bother if devmap size is unknown
         */
        if (mpp->size <= 0) {
-               condlog(3, "%s devmap size is unknown", mpp->alias);
+               condlog(3, "%s: devmap size is unknown", mpp->alias);
                return 1;
        }
 
        /*
         * properties selectors
         */
+       select_pgfailback(mpp);
        select_pgpolicy(mpp);
        select_selector(mpp);
        select_features(mpp);
        select_hwhandler(mpp);
        select_rr_weight(mpp);
-       select_no_path_retry(mpp);
        select_minio(mpp);
+       select_no_path_retry(mpp);
 
        /*
-        * apply selected grouping policy to valid paths
+        * assign paths to path groups -- start with no groups and all paths
+        * in mpp->paths
         */
-       switch (mpp->pgpolicy) {
-       case MULTIBUS:
-               one_group(mpp);
-               break;
-       case FAILOVER:
-               one_path_per_group(mpp);
-               break;
-       case GROUP_BY_SERIAL:
-               group_by_serial(mpp);
-               break;
-       case GROUP_BY_PRIO:
-               group_by_prio(mpp);
-               break;
-       case GROUP_BY_NODE_NAME:
-               group_by_node_name(mpp);
-               break;
-       default:
-               break;
-       }
+       if (mpp->pg) {
+               vector_foreach_slot (mpp->pg, pgp, i)
+                       free_pathgroup(pgp, KEEP_PATHS);
 
-       if (mpp->pg == NULL) {
-               condlog(3, "pgpolicy failed to produce a pg vector");
-               return 1;
+               vector_free(mpp->pg);
+               mpp->pg = NULL;
        }
+       if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
+               return 1;
 
        /*
         * ponders each path group and determine highest prio pg
@@ -366,7 +356,7 @@ setup_map (struct multipath * mpp)
         * into a mp->params strings to feed the device-mapper
         */
        if (assemble_map(mpp)) {
-               condlog(3, "problem assembing map");
+               condlog(0, "%s: problem assembing map", mpp->alias);
                return 1;
        }
        return 0;