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.
int pgpolicy;
int checker_index;
int pgfailback;
+ int rr_weight;
char * vendor;
char * product;
int selector_args;
int pgpolicy;
int pgfailback;
+ int rr_weight;
char * wwid;
char * selector;
int max_checkint;
int pgfailback;
int remove;
+ int rr_weight;
char * dev;
char * multipath;
return 0;
}
+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)
{
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
*/
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)
{
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);
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);
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;
pp->tick, pp->checkint);
NOPAD;
break;
+ case 'p':
+ if (pp->priority) {
+ PRINT(c, TAIL, "%i", pp->priority);
+ }
+ NOPAD;
+ break;
default:
break;
}
* %T : checker path status
* %s : scsi strings
* %c : claimed
+ * %p : priority
*
* map format magics :
*
* %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
* traverse the configuration layers from most specific to most generic
* 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)
{
+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);
mpp = (struct multipath *)MALLOC(sizeof(struct multipath));
- if (mpp) {
+ if (mpp)
mpp->nextpg = 1;
- }
+
return mpp;
}
FREE_PATHS
};
+enum rr_weight_mode {
+ RR_WEIGHT_UNDEF,
+ RR_WEIGHT_NONE,
+ RR_WEIGHT_PRIO
+};
+
enum failback_mode {
FAILBACK_UNDEF,
FAILBACK_MANUAL,
int action;
int pgfailback;
int failback_tick;
+ int rr_weight;
unsigned long long size;
vector paths;
vector pg;
{
int i, j;
int shift, freechar;
+ int minio;
char * p;
struct pathgroup * pgp;
struct path * pp;
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;
select_selector(mpp);
select_features(mpp);
select_hwhandler(mpp);
+ select_rr_weight(mpp);
/*
* apply selected grouping policy to valid paths
}
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;
}
* 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)