#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
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);
}
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);
}
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);
}
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);
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
* 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;