You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
385 lines
13 KiB
385 lines
13 KiB
--- |
|
libmpathpersist/mpath_persist.c | 28 +++++++++++--- |
|
libmultipath/config.c | 3 + |
|
libmultipath/config.h | 2 + |
|
libmultipath/defaults.h | 1 |
|
libmultipath/dict.c | 77 ++++++++++++++++++++++++++++++++++++++++ |
|
libmultipath/propsel.c | 20 ++++++++++ |
|
libmultipath/propsel.h | 1 |
|
libmultipath/structs.h | 7 +++ |
|
multipath/multipath.conf.5 | 7 +++ |
|
9 files changed, 140 insertions(+), 6 deletions(-) |
|
|
|
Index: multipath-tools-130222-patched/libmpathpersist/mpath_persist.c |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmpathpersist/mpath_persist.c |
|
+++ multipath-tools-130222-patched/libmpathpersist/mpath_persist.c |
|
@@ -287,6 +287,7 @@ int mpath_persistent_reserve_out ( int f |
|
} |
|
|
|
select_reservation_key(mpp); |
|
+ select_all_tg_pt(mpp); |
|
|
|
memcpy(&prkey, paramp->sa_key, 8); |
|
if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && |
|
@@ -419,7 +420,7 @@ int mpath_prout_reg(struct multipath *mp |
|
unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy) |
|
{ |
|
|
|
- int i, j; |
|
+ int i, j, k; |
|
struct pathgroup *pgp = NULL; |
|
struct path *pp = NULL; |
|
int rollback = 0; |
|
@@ -444,11 +445,13 @@ int mpath_prout_reg(struct multipath *mp |
|
} |
|
|
|
struct threadinfo thread[active_pathcount]; |
|
+ int hosts[active_pathcount]; |
|
|
|
memset(thread, 0, sizeof(thread)); |
|
|
|
/* init thread parameter */ |
|
for (i =0; i< active_pathcount; i++){ |
|
+ hosts[i] = -1; |
|
thread[i].param.rq_servact = rq_servact; |
|
thread[i].param.rq_scope = rq_scope; |
|
thread[i].param.rq_type = rq_type; |
|
@@ -476,6 +479,17 @@ int mpath_prout_reg(struct multipath *mp |
|
condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev); |
|
continue; |
|
} |
|
+ if (mpp->all_tg_pt == ALL_TG_PT_ON && |
|
+ pp->sg_id.host_no != -1) { |
|
+ for (k = 0; k < count; k++) { |
|
+ if (pp->sg_id.host_no == hosts[k]) { |
|
+ condlog(3, "%s: %s host %d matches skip.", pp->wwid, pp->dev, pp->sg_id.host_no); |
|
+ break; |
|
+ } |
|
+ } |
|
+ if (k < count) |
|
+ continue; |
|
+ } |
|
strncpy(thread[count].param.dev, pp->dev, FILE_NAME_SIZE); |
|
|
|
if (count && (thread[count].param.paramp->sa_flags & MPATH_F_SPEC_I_PT_MASK)){ |
|
@@ -492,10 +506,12 @@ int mpath_prout_reg(struct multipath *mp |
|
condlog (0, "%s: failed to create thread %d", mpp->wwid, rc); |
|
thread[count].param.status = MPATH_PR_THREAD_ERROR; |
|
} |
|
+ else |
|
+ hosts[count] = pp->sg_id.host_no; |
|
count = count +1; |
|
} |
|
} |
|
- for( i=0; i < active_pathcount ; i++){ |
|
+ for( i=0; i < count ; i++){ |
|
if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { |
|
rc = pthread_join(thread[i].id, NULL); |
|
if (rc){ |
|
@@ -518,7 +534,7 @@ int mpath_prout_reg(struct multipath *mp |
|
} |
|
if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){ |
|
condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid); |
|
- for( i=0 ; i < active_pathcount ; i++){ |
|
+ for( i=0 ; i < count ; i++){ |
|
if (thread[i].param.status == MPATH_PR_SUCCESS) { |
|
memcpy(&thread[i].param.paramp->key, &thread[i].param.paramp->sa_key, 8); |
|
memset(&thread[i].param.paramp->sa_key, 0, 8); |
|
@@ -532,7 +548,7 @@ int mpath_prout_reg(struct multipath *mp |
|
} else |
|
thread[i].param.status = MPATH_PR_SKIP; |
|
} |
|
- for(i=0; i < active_pathcount ; i++){ |
|
+ for(i=0; i < count ; i++){ |
|
if (thread[i].param.status != MPATH_PR_SKIP && |
|
thread[i].param.status != MPATH_PR_THREAD_ERROR) { |
|
rc = pthread_join(thread[i].id, NULL); |
|
@@ -678,7 +694,7 @@ int mpath_prout_rel(struct multipath *mp |
|
} |
|
} |
|
pthread_attr_destroy (&attr); |
|
- for (i = 0; i < active_pathcount; i++){ |
|
+ for (i = 0; i < count; i++){ |
|
if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { |
|
rc = pthread_join (thread[i].id, NULL); |
|
if (rc){ |
|
@@ -687,7 +703,7 @@ int mpath_prout_rel(struct multipath *mp |
|
} |
|
} |
|
|
|
- for (i = 0; i < active_pathcount; i++){ |
|
+ for (i = 0; i < count; i++){ |
|
/* check thread status here and return the status */ |
|
|
|
if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT) |
|
Index: multipath-tools-130222-patched/libmultipath/config.c |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/config.c |
|
+++ multipath-tools-130222-patched/libmultipath/config.c |
|
@@ -349,6 +349,7 @@ merge_hwe (struct hwentry * dst, struct |
|
merge_num(max_sectors_kb); |
|
merge_num(unpriv_sgio); |
|
merge_num(ghost_delay); |
|
+ merge_num(all_tg_pt); |
|
|
|
/* |
|
* Make sure features is consistent with |
|
@@ -414,6 +415,7 @@ overwrite_hwe (struct hwentry * dst, str |
|
overwrite_num(max_sectors_kb); |
|
overwrite_num(unpriv_sgio); |
|
overwrite_num(ghost_delay); |
|
+ overwrite_num(all_tg_pt); |
|
|
|
/* |
|
* Make sure features is consistent with |
|
@@ -700,6 +702,7 @@ load_config (char * file, struct udev *u |
|
conf->max_sectors_kb = DEFAULT_MAX_SECTORS_KB; |
|
conf->unpriv_sgio = DEFAULT_UNPRIV_SGIO; |
|
conf->ghost_delay = DEFAULT_GHOST_DELAY; |
|
+ conf->all_tg_pt = DEFAULT_ALL_TG_PT; |
|
|
|
/* |
|
* preload default hwtable |
|
Index: multipath-tools-130222-patched/libmultipath/config.h |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/config.h |
|
+++ multipath-tools-130222-patched/libmultipath/config.h |
|
@@ -71,6 +71,7 @@ struct hwentry { |
|
int max_sectors_kb; |
|
int unpriv_sgio; |
|
int ghost_delay; |
|
+ int all_tg_pt; |
|
char * bl_product; |
|
}; |
|
|
|
@@ -162,6 +163,7 @@ struct config { |
|
int max_sectors_kb; |
|
int unpriv_sgio; |
|
int ghost_delay; |
|
+ int all_tg_pt; |
|
unsigned int version[3]; |
|
|
|
char * dev; |
|
Index: multipath-tools-130222-patched/libmultipath/dict.c |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/dict.c |
|
+++ multipath-tools-130222-patched/libmultipath/dict.c |
|
@@ -1051,6 +1051,29 @@ def_ghost_delay_handler(vector strvec) |
|
return 0; |
|
} |
|
|
|
+static int |
|
+def_all_tg_pt_handler(vector strvec) |
|
+{ |
|
+ char * buff; |
|
+ |
|
+ buff = set_value(strvec); |
|
+ if (!buff) |
|
+ return 1; |
|
+ |
|
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || |
|
+ (strlen(buff) == 1 && !strcmp(buff, "0"))) |
|
+ conf->all_tg_pt = ALL_TG_PT_OFF; |
|
+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || |
|
+ (strlen(buff) == 1 && !strcmp(buff, "1"))) |
|
+ conf->all_tg_pt = ALL_TG_PT_ON; |
|
+ else |
|
+ conf->all_tg_pt = DEFAULT_ALL_TG_PT; |
|
+ |
|
+ FREE(buff); |
|
+ return 0; |
|
+} |
|
+ |
|
+ |
|
/* |
|
* blacklist block handlers |
|
*/ |
|
@@ -1969,6 +1992,33 @@ hw_ghost_delay_handler(vector strvec) |
|
return 0; |
|
} |
|
|
|
+static int |
|
+hw_all_tg_pt_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) == 2 && !strcmp(buff, "no")) || |
|
+ (strlen(buff) == 1 && !strcmp(buff, "0"))) |
|
+ hwe->all_tg_pt = ALL_TG_PT_OFF; |
|
+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || |
|
+ (strlen(buff) == 1 && !strcmp(buff, "1"))) |
|
+ hwe->all_tg_pt = ALL_TG_PT_ON; |
|
+ else |
|
+ hwe->all_tg_pt = ALL_TG_PT_UNDEF; |
|
+ |
|
+ FREE(buff); |
|
+ return 0; |
|
+} |
|
+ |
|
/* |
|
* multipaths block handlers |
|
*/ |
|
@@ -3325,6 +3375,19 @@ snprint_hw_ghost_delay (char * buff, int |
|
} |
|
|
|
static int |
|
+snprint_hw_all_tg_pt(char * buff, int len, void * data) |
|
+{ |
|
+ struct hwentry * hwe = (struct hwentry *)data; |
|
+ |
|
+ if (hwe->all_tg_pt == ALL_TG_PT_ON) |
|
+ return snprintf(buff, len, "yes"); |
|
+ else if (hwe->all_tg_pt == ALL_TG_PT_OFF) |
|
+ return snprintf(buff, len, "no"); |
|
+ else |
|
+ return 0; |
|
+} |
|
+ |
|
+static int |
|
snprint_def_polling_interval (char * buff, int len, void * data) |
|
{ |
|
return snprintf(buff, len, "%i", conf->checkint); |
|
@@ -3829,6 +3892,15 @@ snprint_def_ghost_delay (char * buff, in |
|
} |
|
|
|
static int |
|
+snprint_def_all_tg_pt(char * buff, int len, void * data) |
|
+{ |
|
+ if (conf->all_tg_pt == ALL_TG_PT_ON) |
|
+ return snprintf(buff, len, "yes"); |
|
+ else |
|
+ return snprintf(buff, len, "no"); |
|
+} |
|
+ |
|
+static int |
|
snprint_ble_simple (char * buff, int len, void * data) |
|
{ |
|
struct blentry * ble = (struct blentry *)data; |
|
@@ -3926,6 +3998,7 @@ init_keywords(void) |
|
install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb); |
|
install_keyword("unpriv_sgio", &def_unpriv_sgio_handler, &snprint_def_unpriv_sgio); |
|
install_keyword("ghost_delay", &def_ghost_delay_handler, &snprint_def_ghost_delay); |
|
+ install_keyword("all_tg_pt", &def_all_tg_pt_handler, &snprint_def_all_tg_pt); |
|
__deprecated install_keyword("default_selector", &def_selector_handler, NULL); |
|
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); |
|
__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); |
|
@@ -4000,6 +4073,7 @@ init_keywords(void) |
|
install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb); |
|
install_keyword("unpriv_sgio", &hw_unpriv_sgio_handler, &snprint_hw_unpriv_sgio); |
|
install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay); |
|
+ install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt); |
|
install_sublevel_end(); |
|
|
|
install_keyword_root("overrides", &nop_handler); |
|
@@ -4031,6 +4105,9 @@ init_keywords(void) |
|
install_keyword("delay_wait_checks", &nop_handler, &snprint_nop); |
|
install_keyword("skip_kpartx", &nop_handler, &snprint_nop); |
|
install_keyword("max_sectors_kb", &nop_handler, &snprint_nop); |
|
+ install_keyword("unpriv_sgio", &nop_handler, &snprint_nop); |
|
+ install_keyword("ghost_delay", &nop_handler, &snprint_nop); |
|
+ install_keyword("all_tg_pt", &nop_handler, &snprint_nop); |
|
|
|
install_keyword_root("multipaths", &multipaths_handler); |
|
install_keyword_multi("multipath", &multipath_handler, NULL); |
|
Index: multipath-tools-130222-patched/libmultipath/propsel.c |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/propsel.c |
|
+++ multipath-tools-130222-patched/libmultipath/propsel.c |
|
@@ -992,3 +992,23 @@ select_ghost_delay (struct multipath * m |
|
condlog(3, "ghost_delay = DISABLED (internal default)"); |
|
return 0; |
|
} |
|
+ |
|
+extern int |
|
+select_all_tg_pt (struct multipath *mp) |
|
+{ |
|
+ if (mp->hwe && mp->hwe->all_tg_pt != ALL_TG_PT_UNDEF) { |
|
+ mp->all_tg_pt = mp->hwe->all_tg_pt; |
|
+ condlog(3, "all_tg_pt = %i (controller setting)", |
|
+ mp->all_tg_pt); |
|
+ return 0; |
|
+ } |
|
+ if (conf->all_tg_pt != GHOST_DELAY_UNDEF) { |
|
+ mp->all_tg_pt = conf->all_tg_pt; |
|
+ condlog(3, "all_tg_pt = %i (config file default)", |
|
+ mp->all_tg_pt); |
|
+ return 0; |
|
+ } |
|
+ mp->all_tg_pt = DEFAULT_ALL_TG_PT; |
|
+ condlog(3, "all_tg_pt = %i (internal default)", mp->all_tg_pt); |
|
+ return 0; |
|
+} |
|
Index: multipath-tools-130222-patched/libmultipath/structs.h |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/structs.h |
|
+++ multipath-tools-130222-patched/libmultipath/structs.h |
|
@@ -154,6 +154,12 @@ enum unpriv_sgio_states { |
|
UNPRIV_SGIO_ON, |
|
}; |
|
|
|
+enum all_tg_pt_states { |
|
+ ALL_TG_PT_UNDEF, |
|
+ ALL_TG_PT_OFF, |
|
+ ALL_TG_PT_ON, |
|
+}; |
|
+ |
|
enum scsi_protocol { |
|
SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ |
|
SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ |
|
@@ -324,6 +330,7 @@ struct multipath { |
|
int prkey_source; |
|
struct be64 reservation_key; |
|
unsigned char prflag; |
|
+ int all_tg_pt; |
|
}; |
|
|
|
struct pathgroup { |
|
Index: multipath-tools-130222-patched/libmultipath/propsel.h |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/propsel.h |
|
+++ multipath-tools-130222-patched/libmultipath/propsel.h |
|
@@ -28,3 +28,4 @@ int select_skip_kpartx (struct multipath |
|
int select_max_sectors_kb (struct multipath * mp); |
|
int select_unpriv_sgio (struct multipath * mp); |
|
int select_ghost_delay (struct multipath * mp); |
|
+int select_all_tg_pt (struct multipath *mp); |
|
Index: multipath-tools-130222-patched/libmultipath/defaults.h |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/libmultipath/defaults.h |
|
+++ multipath-tools-130222-patched/libmultipath/defaults.h |
|
@@ -29,6 +29,7 @@ |
|
#define DEFAULT_MAX_SECTORS_KB MAX_SECTORS_KB_UNDEF |
|
#define DEFAULT_UNPRIV_SGIO UNPRIV_SGIO_OFF |
|
#define DEFAULT_GHOST_DELAY GHOST_DELAY_OFF |
|
+#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF |
|
|
|
#define DEFAULT_CHECKINT 5 |
|
#define MAX_CHECKINT(a) (a << 2) |
|
Index: multipath-tools-130222-patched/multipath/multipath.conf.5 |
|
=================================================================== |
|
--- multipath-tools-130222-patched.orig/multipath/multipath.conf.5 |
|
+++ multipath-tools-130222-patched/multipath/multipath.conf.5 |
|
@@ -449,6 +449,13 @@ registration is removed, the RESERVATION |
|
It is unset by default. |
|
.RE |
|
.TP |
|
+.B all_tg_pt |
|
+This must be set to \fIyes\fR to successfully use mpathpersist on arrays that |
|
+automatically set and clear registration keys on all target ports from a |
|
+host, instead of per target port per host. |
|
+Default is |
|
+.I no |
|
+.TP |
|
.B retain_attached_hw_handler |
|
If set to |
|
.I yes
|
|
|