[multipath] option to use priorities as weights in the round-robin scheduler
authorroot <root@xa-s05.(none)>
Wed, 24 Aug 2005 14:48:40 +0000 (16:48 +0200)
committerroot <root@xa-s05.(none)>
Wed, 24 Aug 2005 14:48:40 +0000 (16:48 +0200)
Disabled by default.

Synthax is "rr_weight = priorities", and is valid in the default{},
device{} and multipath{} blocks.

This is an interim solution before a cleaner "least queued scheduler".

To make this complete, the daemon should be able to "message" DM to
change the path weights when their prio changes. Probably not worth the
effort and spend time on another scheduler.

The core of this patch is in the multipath table setup :

if (mp->rr_weight && pp->priority)
minio = conf->rr_minio * pp->priority;

The rest is the config switch handling, and printing.

libmultipath/config.h
libmultipath/dict.c
libmultipath/print.c
libmultipath/print.h
libmultipath/propsel.c
libmultipath/propsel.h
libmultipath/structs.c
libmultipath/structs.h
multipath/main.c

index aa695fd..6d8369c 100644 (file)
@@ -17,6 +17,7 @@ struct hwentry {
        int pgpolicy;
        int checker_index;
        int pgfailback;
+       int rr_weight;
 
        char * vendor;
        char * product;
@@ -31,6 +32,7 @@ struct mpentry {
        int selector_args;
        int pgpolicy;
        int pgfailback;
+       int rr_weight;
 
        char * wwid;
        char * selector;
@@ -52,6 +54,7 @@ struct config {
        int max_checkint;
        int pgfailback;
        int remove;
+       int rr_weight;
 
        char * dev;
        char * multipath;
index 2280a00..8e74b5b 100644 (file)
@@ -129,6 +129,25 @@ def_minio_handler(vector strvec)
 }
 
 static int
+def_weight_handler(vector strvec)
+{
+       char * buff;
+
+       buff = set_value(strvec);
+
+       if (!buff)
+               return 1;
+
+       if (strlen(buff) == 10 &&
+           !strcmp(buff, "priorities"))
+               conf->rr_weight = RR_WEIGHT_PRIO;
+
+       FREE(buff);
+
+       return 0;
+}
+
+static int
 default_failback_handler(vector strvec)
 {
        char * buff;
@@ -385,6 +404,29 @@ hw_failback_handler(vector strvec)
        return 0;
 }
 
+static int
+hw_weight_handler(vector strvec)
+{
+       struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+       char * buff;
+
+       if (!hwe)
+               return 1;
+
+       buff = set_value(strvec);
+
+       if (!buff)
+               return 1;
+
+       if (strlen(buff) == 10 &&
+           !strcmp(buff, "priorities"))
+               hwe->rr_weight = RR_WEIGHT_PRIO;
+
+       FREE(buff);
+
+       return 0;
+}
+
 /*
  * multipaths block handlers
  */
@@ -509,6 +551,29 @@ mp_failback_handler(vector strvec)
        return 0;
 }
 
+static int
+mp_weight_handler(vector strvec)
+{
+       struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
+       char * buff;
+
+       if (!mpe)
+               return 1;
+
+       buff = set_value(strvec);
+
+       if (!buff)
+               return 1;
+
+       if (strlen(buff) == 10 &&
+           !strcmp(buff, "priorities"))
+               mpe->rr_weight = RR_WEIGHT_PRIO;
+
+       FREE(buff);
+
+       return 0;
+}
+
 vector
 init_keywords(void)
 {
@@ -525,6 +590,7 @@ init_keywords(void)
        install_keyword("default_features", &def_features_handler);
        install_keyword("failback", &default_failback_handler);
        install_keyword("rr_min_io", &def_minio_handler);
+       install_keyword("rr_weight", &def_weight_handler);
        
        install_keyword_root("devnode_blacklist", &blacklist_handler);
        install_keyword("devnode", &ble_handler);
@@ -543,6 +609,7 @@ init_keywords(void)
        install_keyword("hardware_handler", &hw_handler_handler);
        install_keyword("prio_callout", &prio_callout_handler);
        install_keyword("failback", &hw_failback_handler);
+       install_keyword("rr_weight", &hw_weight_handler);
        install_sublevel_end();
 
        install_keyword_root("multipaths", &multipaths_handler);
@@ -553,6 +620,7 @@ init_keywords(void)
        install_keyword("path_grouping_policy", &mp_pgpolicy_handler);
        install_keyword("path_selector", &mp_selector_handler);
        install_keyword("failback", &mp_failback_handler);
+       install_keyword("rr_weight", &mp_weight_handler);
        install_sublevel_end();
 
        return keywords;
index 0ad4857..de12526 100644 (file)
@@ -242,6 +242,12 @@ snprint_path (char * line, int len, char * format, struct path * pp,
                                      pp->tick, pp->checkint);
                        NOPAD;
                        break;
+               case 'p':
+                       if (pp->priority) {
+                               PRINT(c, TAIL, "%i", pp->priority);
+                       }
+                       NOPAD;
+                       break;
                default:
                        break;
                }
index f9b8f1c..c77956f 100644 (file)
@@ -9,6 +9,7 @@
  * %T : checker path status
  * %s : scsi strings
  * %c : claimed
+ * %p : priority
  * 
  * map format magics :
  * 
@@ -17,9 +18,9 @@
  * %F : failback countdown
  * %C : checker countdown
  */
-#define PRINT_PATH_LONG      "%w %i %d %D %t%T%c %s"
+#define PRINT_PATH_LONG      "%w %i %d %D %p %t%T%c %s"
 #define PRINT_PATH_INDENT    " \\_ %i %d %D %t%T%c"
-#define PRINT_PATH_CHECKER   "%i %d %D %t%T %C"
+#define PRINT_PATH_CHECKER   "%i %d %D %p %t%T %C"
 #define PRINT_MAP_FAILBACK   "%w %d %F"
 
 #define MAX_LINE_LEN 80
index baac293..e73309e 100644 (file)
  * stop at first explicit setting found
  */
 extern int
+select_rr_weight (struct multipath * mp)
+{
+       if (mp->mpe && mp->mpe->rr_weight) {
+               mp->rr_weight = mp->mpe->rr_weight;
+               condlog(3, "rr_weight = %i (LUN setting)",
+                       mp->rr_weight);
+               return 0;
+       }
+       if (mp->hwe && mp->hwe->rr_weight) {
+               mp->rr_weight = mp->hwe->rr_weight;
+               condlog(3, "rr_weight = %i (controler setting)",
+                       mp->rr_weight);
+               return 0;
+       }
+       if (conf->rr_weight) {
+               mp->rr_weight = conf->rr_weight;
+               condlog(3, "rr_weight = %i (config file default)",
+                       mp->rr_weight);
+               return 0;
+       }
+       mp->rr_weight = RR_WEIGHT_NONE;
+       condlog(3, "rr_weight = %i (internal default)",
+               mp->rr_weight);
+       return 0;
+}
+
+extern int
 select_pgfailback (struct multipath * mp)
 {
        if (mp->mpe && mp->mpe->pgfailback != FAILBACK_UNDEF) {
index 11d585b..5e57a32 100644 (file)
@@ -1,3 +1,4 @@
+int select_rr_weight (struct multipath * mp);
 int select_pgfailback (struct multipath * mp);
 int select_pgpolicy (struct multipath * mp);
 int select_selector (struct multipath * mp);
index 2c1c38b..4c26986 100644 (file)
@@ -105,9 +105,9 @@ alloc_multipath (void)
 
        mpp = (struct multipath *)MALLOC(sizeof(struct multipath));
 
-       if (mpp) {
+       if (mpp)
                mpp->nextpg = 1;
-       }
+
        return mpp;
 }
 
index 08a2a5e..0aac789 100644 (file)
@@ -19,6 +19,12 @@ enum free_path_switch {
        FREE_PATHS
 };
 
+enum rr_weight_mode {
+       RR_WEIGHT_UNDEF,
+       RR_WEIGHT_NONE,
+       RR_WEIGHT_PRIO
+};
+
 enum failback_mode {
        FAILBACK_UNDEF,
        FAILBACK_MANUAL,
@@ -108,6 +114,7 @@ struct multipath {
        int action;
        int pgfailback;
        int failback_tick;
+       int rr_weight;
        unsigned long long size;
        vector paths;
        vector pg;
index 9f6a561..b4cda89 100644 (file)
@@ -301,6 +301,7 @@ assemble_map (struct multipath * mp)
 {
        int i, j;
        int shift, freechar;
+       int minio;
        char * p;
        struct pathgroup * pgp;
        struct path * pp;
@@ -331,8 +332,13 @@ assemble_map (struct multipath * mp)
                freechar -= shift;
 
                vector_foreach_slot (pgp->paths, pp, j) {
+                       minio = conf->minio;
+                       
+                       if (mp->rr_weight == RR_WEIGHT_PRIO && pp->priority)
+                               minio *= pp->priority;
+
                        shift = snprintf(p, freechar, " %s %d",
-                                        pp->dev_t, conf->minio);
+                                        pp->dev_t, minio);
                        if (shift >= freechar) {
                                fprintf(stderr, "mp->params too small\n");
                                return 1;
@@ -385,6 +391,7 @@ setup_map (struct multipath * mpp)
        select_selector(mpp);
        select_features(mpp);
        select_hwhandler(mpp);
+       select_rr_weight(mpp);
 
        /*
         * apply selected grouping policy to valid paths
@@ -759,19 +766,27 @@ usage (char * progname)
 }
 
 static int
-update_pathvec (vector pathvec)
+update_paths (struct multipath * mpp)
 {
-       int i;
+       int i, j;
+       struct pathgroup * pgp;
        struct path * pp;
 
-       vector_foreach_slot (pathvec, pp, i) {
-               if (pp->dev && pp->dev_t && strlen(pp->dev) == 0) {
-                       devt2devname(pp->dev, pp->dev_t);
-                       pathinfo(pp, conf->hwtable,
-                               DI_SYSFS | DI_CHECKER | DI_SERIAL | DI_PRIO);
+       vector_foreach_slot (mpp->pg, pgp, i) {
+               vector_foreach_slot (pgp->paths, pp, j) {
+                       if (!strlen(pp->dev)) {
+                               devt2devname(pp->dev, pp->dev_t);
+                               pathinfo(pp, conf->hwtable,
+                                        DI_SYSFS | DI_CHECKER | \
+                                        DI_SERIAL | DI_PRIO);
+                               continue;
+                       }
+                       if (pp->state == PATH_UNCHECKED)
+                               pathinfo(pp, conf->hwtable, DI_CHECKER);
+
+                       if (!pp->priority)
+                               pathinfo(pp, conf->hwtable, DI_PRIO);
                }
-               if (pp->checkfn && pp->state == PATH_UNCHECKED)
-                       pp->state = pp->checkfn(pp->fd, NULL, NULL);
        }
        return 0;
 }
@@ -807,10 +822,12 @@ get_dm_mpvec (vector curmp, vector pathvec, char * refwwid)
                 * If not in "fast list mode", we need to fetch information
                 * about them
                 */
-               if (conf->list != 1) {
-                       update_pathvec(pathvec);
+               if (conf->list != 1)
+                       update_paths(mpp);
+
+               if (conf->list > 1)
                        select_path_group(mpp);
-               }
+
                disassemble_status(mpp->status, mpp);
 
                if (conf->list)