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.
565 lines
17 KiB
565 lines
17 KiB
--- |
|
libmultipath/prio.c | 34 ++++++++++++++++- |
|
libmultipath/prio.h | 7 +++ |
|
libmultipath/prioritizers/alua.c | 62 +++++++++++++++++++++++-------- |
|
libmultipath/prioritizers/alua_rtpg.c | 22 +++++++++-- |
|
libmultipath/prioritizers/alua_rtpg.h | 4 +- |
|
libmultipath/prioritizers/const.c | 4 ++ |
|
libmultipath/prioritizers/datacore.c | 3 + |
|
libmultipath/prioritizers/def_func.h | 11 +++++ |
|
libmultipath/prioritizers/emc.c | 4 ++ |
|
libmultipath/prioritizers/hds.c | 4 ++ |
|
libmultipath/prioritizers/hp_sw.c | 4 ++ |
|
libmultipath/prioritizers/iet.c | 4 ++ |
|
libmultipath/prioritizers/ontap.c | 4 ++ |
|
libmultipath/prioritizers/random.c | 4 ++ |
|
libmultipath/prioritizers/rdac.c | 4 ++ |
|
libmultipath/prioritizers/weightedpath.c | 3 + |
|
libmultipath/propsel.c | 4 +- |
|
multipathd/main.c | 24 ++++++++---- |
|
18 files changed, 174 insertions(+), 32 deletions(-) |
|
|
|
Index: multipath-tools-130222/libmultipath/prio.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prio.c |
|
+++ multipath-tools-130222/libmultipath/prio.c |
|
@@ -112,9 +112,24 @@ struct prio * add_prio (char * name) |
|
p->getprio = (int (*)(struct path *, char *)) dlsym(p->handle, "getprio"); |
|
errstr = dlerror(); |
|
if (errstr != NULL) |
|
- condlog(0, "A dynamic linking error occurred: (%s)", errstr); |
|
+ condlog(0, "A dynamic linking error occurred with getprio: (%s)", errstr); |
|
if (!p->getprio) |
|
goto out; |
|
+ |
|
+ p->initprio = (int (*)(struct prio *)) dlsym(p->handle, "initprio"); |
|
+ errstr = dlerror(); |
|
+ if (errstr != NULL) |
|
+ condlog(0, "A dynamic linking error occurred with initprio: (%s)", errstr); |
|
+ if (!p->initprio) |
|
+ goto out; |
|
+ |
|
+ p->freeprio = (int (*)(struct prio *)) dlsym(p->handle, "freeprio"); |
|
+ errstr = dlerror(); |
|
+ if (errstr != NULL) |
|
+ condlog(0, "A dynamic linking error occurred with freeprio: (%s)", errstr); |
|
+ if (!p->freeprio) |
|
+ goto out; |
|
+ |
|
list_add(&p->node, &prioritizers); |
|
return p; |
|
out: |
|
@@ -122,6 +137,13 @@ out: |
|
return NULL; |
|
} |
|
|
|
+int prio_init (struct prio * p) |
|
+{ |
|
+ if (!p || !p->initprio) |
|
+ return 1; |
|
+ return p->initprio(p); |
|
+} |
|
+ |
|
int prio_getprio (struct prio * p, struct path * pp) |
|
{ |
|
return p->getprio(pp, p->args); |
|
@@ -156,8 +178,16 @@ void prio_get (struct prio * dst, char * |
|
strncpy(dst->name, src->name, PRIO_NAME_LEN); |
|
if (args) |
|
strncpy(dst->args, args, PRIO_ARGS_LEN); |
|
+ dst->initprio = src->initprio; |
|
dst->getprio = src->getprio; |
|
+ dst->freeprio = src->freeprio; |
|
dst->handle = NULL; |
|
+ dst->context = NULL; |
|
+ |
|
+ if (dst->initprio(dst) != 0){ |
|
+ memset(dst, 0x0, sizeof(struct prio)); |
|
+ return; |
|
+ } |
|
|
|
src->refcount++; |
|
} |
|
@@ -173,6 +203,8 @@ void prio_put (struct prio * dst) |
|
src = NULL; |
|
else |
|
src = prio_lookup(dst->name); |
|
+ if (dst->freeprio) |
|
+ dst->freeprio(dst); |
|
memset(dst, 0x0, sizeof(struct prio)); |
|
free_prio(src); |
|
} |
|
Index: multipath-tools-130222/libmultipath/prio.h |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prio.h |
|
+++ multipath-tools-130222/libmultipath/prio.h |
|
@@ -46,9 +46,15 @@ struct prio { |
|
void *handle; |
|
int refcount; |
|
struct list_head node; |
|
+ void * context; |
|
char name[PRIO_NAME_LEN]; |
|
char args[PRIO_ARGS_LEN]; |
|
+ int (*initprio)(struct prio * p); |
|
+ /* You are allowed to call initprio multiple times without calling |
|
+ * freeprio. Doing so will reinitialize it (possibly skipping |
|
+ * allocations) */ |
|
int (*getprio)(struct path *, char *); |
|
+ int (*freeprio)(struct prio * p); |
|
}; |
|
|
|
unsigned int get_prio_timeout(unsigned int default_timeout); |
|
@@ -57,6 +63,7 @@ void cleanup_prio (void); |
|
struct prio * add_prio (char *); |
|
struct prio * prio_lookup (char *); |
|
int prio_getprio (struct prio *, struct path *); |
|
+int prio_init (struct prio *); |
|
void prio_get (struct prio *, char *, char *); |
|
void prio_put (struct prio *); |
|
int prio_selected (struct prio *); |
|
Index: multipath-tools-130222/libmultipath/prioritizers/alua.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/alua.c |
|
@@ -37,6 +37,12 @@ static const char * aas_string[] = { |
|
[AAS_TRANSITIONING] = "transitioning between states", |
|
}; |
|
|
|
+struct alua_context { |
|
+ int tpg_support; |
|
+ int tpg; |
|
+ int buflen; |
|
+}; |
|
+ |
|
static const char *aas_print_string(int rc) |
|
{ |
|
rc &= 0x7f; |
|
@@ -51,25 +57,26 @@ static const char *aas_print_string(int |
|
} |
|
|
|
int |
|
-get_alua_info(int fd) |
|
+get_alua_info(int fd, struct alua_context *ct) |
|
{ |
|
int rc; |
|
- int tpg; |
|
int aas; |
|
|
|
- rc = get_target_port_group_support(fd); |
|
- if (rc < 0) |
|
- return -ALUA_PRIO_TPGS_FAILED; |
|
- |
|
- if (rc == TPGS_NONE) |
|
- return -ALUA_PRIO_NOT_SUPPORTED; |
|
- |
|
- tpg = get_target_port_group(fd); |
|
- if (tpg < 0) |
|
- return -ALUA_PRIO_RTPG_FAILED; |
|
+ if (ct->tpg_support <= 0 || ct->tpg < 0) { |
|
+ ct->tpg_support = get_target_port_group_support(fd); |
|
+ if (ct->tpg_support < 0) |
|
+ return -ALUA_PRIO_TPGS_FAILED; |
|
+ |
|
+ if (ct->tpg_support == TPGS_NONE) |
|
+ return -ALUA_PRIO_NOT_SUPPORTED; |
|
+ |
|
+ ct->tpg = get_target_port_group(fd, &ct->buflen); |
|
+ if (ct->tpg < 0) |
|
+ return -ALUA_PRIO_RTPG_FAILED; |
|
+ } |
|
|
|
- condlog(3, "reported target port group is %i", tpg); |
|
- rc = get_asymmetric_access_state(fd, tpg); |
|
+ condlog(3, "reported target port group is %i", ct->tpg); |
|
+ rc = get_asymmetric_access_state(fd, ct->tpg, &ct->buflen); |
|
if (rc < 0) |
|
return -ALUA_PRIO_GETAAS_FAILED; |
|
aas = (rc & 0x0f); |
|
@@ -88,7 +95,7 @@ int getprio (struct path * pp, char * ar |
|
if (pp->fd < 0) |
|
return -ALUA_PRIO_NO_INFORMATION; |
|
|
|
- rc = get_alua_info(pp->fd); |
|
+ rc = get_alua_info(pp->fd, pp->prio.context); |
|
if (rc >= 0) { |
|
aas = (rc & 0x0f); |
|
priopath = (rc & 0x80); |
|
@@ -128,3 +135,28 @@ int getprio (struct path * pp, char * ar |
|
} |
|
return rc; |
|
} |
|
+ |
|
+int initprio(struct prio *p) |
|
+{ |
|
+ if (!p->context) { |
|
+ struct alua_context *ct; |
|
+ |
|
+ ct = malloc(sizeof(struct alua_context)); |
|
+ if (!ct) |
|
+ return 1; |
|
+ p->context = ct; |
|
+ } |
|
+ memset(p->context, 0, sizeof(struct alua_context)); |
|
+ return 0; |
|
+} |
|
+ |
|
+ |
|
+int freeprio(struct prio *p) |
|
+{ |
|
+ if (p->context) { |
|
+ free(p->context); |
|
+ p->context = NULL; |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c |
|
@@ -171,7 +171,7 @@ get_target_port_group_support(int fd) |
|
} |
|
|
|
int |
|
-get_target_port_group(int fd) |
|
+get_target_port_group(int fd, int *buflen_ptr) |
|
{ |
|
unsigned char *buf; |
|
struct vpd83_data * vpd83; |
|
@@ -179,7 +179,12 @@ get_target_port_group(int fd) |
|
int rc; |
|
int buflen, scsi_buflen; |
|
|
|
- buflen = 128; /* Lets start from 128 */ |
|
+ if (!buflen_ptr || *buflen_ptr == 0) { |
|
+ buflen = 128; /* Lets start from 128 */ |
|
+ if (buflen_ptr) |
|
+ *buflen_ptr = 128; |
|
+ } else |
|
+ buflen = *buflen_ptr; |
|
buf = (unsigned char *)malloc(buflen); |
|
if (!buf) { |
|
PRINT_DEBUG("malloc failed: could not allocate" |
|
@@ -202,6 +207,8 @@ get_target_port_group(int fd) |
|
return -RTPG_RTPG_FAILED; |
|
} |
|
buflen = scsi_buflen; |
|
+ if (buflen_ptr) |
|
+ *buflen_ptr = buflen; |
|
memset(buf, 0, buflen); |
|
rc = do_inquiry(fd, 1, 0x83, buf, buflen); |
|
if (rc < 0) |
|
@@ -269,7 +276,7 @@ do_rtpg(int fd, void* resp, long resplen |
|
} |
|
|
|
int |
|
-get_asymmetric_access_state(int fd, unsigned int tpg) |
|
+get_asymmetric_access_state(int fd, unsigned int tpg, int *buflen_ptr) |
|
{ |
|
unsigned char *buf; |
|
struct rtpg_data * tpgd; |
|
@@ -278,7 +285,12 @@ get_asymmetric_access_state(int fd, unsi |
|
int buflen; |
|
uint32_t scsi_buflen; |
|
|
|
- buflen = 128; /* Initial value from old code */ |
|
+ if (!buflen_ptr || *buflen_ptr == 0) { |
|
+ buflen = 128; /* Initial value from old code */ |
|
+ if (buflen_ptr) |
|
+ *buflen_ptr = 128; |
|
+ } else |
|
+ buflen = *buflen_ptr; |
|
buf = (unsigned char *)malloc(buflen); |
|
if (!buf) { |
|
PRINT_DEBUG ("malloc failed: could not allocate" |
|
@@ -299,6 +311,8 @@ get_asymmetric_access_state(int fd, unsi |
|
return -RTPG_RTPG_FAILED; |
|
} |
|
buflen = scsi_buflen; |
|
+ if (buflen_ptr) |
|
+ *buflen_ptr = buflen; |
|
memset(buf, 0, buflen); |
|
rc = do_rtpg(fd, buf, buflen); |
|
if (rc < 0) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.h |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.h |
|
+++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.h |
|
@@ -23,8 +23,8 @@ |
|
#define RTPG_TPG_NOT_FOUND 4 |
|
|
|
int get_target_port_group_support(int fd); |
|
-int get_target_port_group(int fd); |
|
-int get_asymmetric_access_state(int fd, unsigned int tpg); |
|
+int get_target_port_group(int fd, int *buflen_ptr); |
|
+int get_asymmetric_access_state(int fd, unsigned int tpg, int *buflen_ptr); |
|
|
|
#endif /* __RTPG_H__ */ |
|
|
|
Index: multipath-tools-130222/libmultipath/prioritizers/const.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/const.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/const.c |
|
@@ -1,8 +1,12 @@ |
|
#include <stdio.h> |
|
|
|
#include <prio.h> |
|
+#include "def_func.h" |
|
|
|
int getprio (struct path * pp, char * args) |
|
{ |
|
return 1; |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/datacore.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/datacore.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/datacore.c |
|
@@ -25,6 +25,7 @@ |
|
#include <debug.h> |
|
#include <prio.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
#define INQ_REPLY_LEN 255 |
|
#define INQ_CMD_CODE 0x12 |
|
@@ -111,3 +112,5 @@ int getprio (struct path * pp, char * ar |
|
return datacore_prio(pp->dev, pp->fd, args); |
|
} |
|
|
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/def_func.h |
|
=================================================================== |
|
--- /dev/null |
|
+++ multipath-tools-130222/libmultipath/prioritizers/def_func.h |
|
@@ -0,0 +1,11 @@ |
|
+#ifndef _DEF_FUNC_H |
|
+#define _DEF_FUNC_H |
|
+ |
|
+#include "prio.h" |
|
+ |
|
+#define declare_nop_prio(name) \ |
|
+int name (struct prio *p) \ |
|
+{ \ |
|
+ return 0; \ |
|
+} |
|
+#endif /* _DEF_FUNC_H */ |
|
Index: multipath-tools-130222/libmultipath/prioritizers/emc.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/emc.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/emc.c |
|
@@ -6,6 +6,7 @@ |
|
#include <debug.h> |
|
#include <prio.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
#define INQUIRY_CMD 0x12 |
|
#define INQUIRY_CMDLEN 6 |
|
@@ -85,3 +86,6 @@ int getprio (struct path * pp, char * ar |
|
{ |
|
return emc_clariion_prio(pp->dev, pp->fd); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/hds.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/hds.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/hds.c |
|
@@ -76,6 +76,7 @@ |
|
#include <debug.h> |
|
#include <prio.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
#define INQ_REPLY_LEN 255 |
|
#define INQ_CMD_CODE 0x12 |
|
@@ -170,3 +171,6 @@ int getprio (struct path * pp, char * ar |
|
{ |
|
return hds_modular_prio(pp->dev, pp->fd); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/hp_sw.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/hp_sw.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/hp_sw.c |
|
@@ -16,6 +16,7 @@ |
|
#include <debug.h> |
|
#include <prio.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
#define TUR_CMD_LEN 6 |
|
#define SCSI_CHECK_CONDITION 0x2 |
|
@@ -99,3 +100,6 @@ int getprio (struct path * pp, char * ar |
|
{ |
|
return hp_sw_prio(pp->dev, pp->fd); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/iet.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/iet.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/iet.c |
|
@@ -9,6 +9,7 @@ |
|
#include <debug.h> |
|
#include <unistd.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
// |
|
// This prioritizer suits iSCSI needs, makes it possible to prefer one path. |
|
@@ -141,3 +142,6 @@ int getprio(struct path * pp, char * arg |
|
{ |
|
return iet_prio(pp->dev, args); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/ontap.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/ontap.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/ontap.c |
|
@@ -23,6 +23,7 @@ |
|
#include <debug.h> |
|
#include <prio.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
#define INQUIRY_CMD 0x12 |
|
#define INQUIRY_CMDLEN 6 |
|
@@ -245,3 +246,6 @@ int getprio (struct path * pp, char * ar |
|
{ |
|
return ontap_prio(pp->dev, pp->fd); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/random.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/random.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/random.c |
|
@@ -4,6 +4,7 @@ |
|
#include <time.h> |
|
|
|
#include <prio.h> |
|
+#include "def_func.h" |
|
|
|
int getprio (struct path * pp, char * args) |
|
{ |
|
@@ -13,3 +14,6 @@ int getprio (struct path * pp, char * ar |
|
srand((unsigned int)tv.tv_usec); |
|
return 1+(int) (10.0*rand()/(RAND_MAX+1.0)); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/rdac.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/rdac.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/rdac.c |
|
@@ -6,6 +6,7 @@ |
|
#include <debug.h> |
|
#include <prio.h> |
|
#include <structs.h> |
|
+#include "def_func.h" |
|
|
|
#define INQUIRY_CMD 0x12 |
|
#define INQUIRY_CMDLEN 6 |
|
@@ -95,3 +96,6 @@ int getprio (struct path * pp, char * ar |
|
{ |
|
return rdac_prio(pp->dev, pp->fd); |
|
} |
|
+ |
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.c |
|
+++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.c |
|
@@ -32,6 +32,7 @@ |
|
#include <memory.h> |
|
#include <debug.h> |
|
#include <regex.h> |
|
+#include "def_func.h" |
|
|
|
char *get_next_string(char **temp, char *split_char) |
|
{ |
|
@@ -104,3 +105,5 @@ int getprio(struct path *pp, char *args) |
|
return prio_path_weight(pp, args); |
|
} |
|
|
|
+declare_nop_prio(initprio) |
|
+declare_nop_prio(freeprio) |
|
Index: multipath-tools-130222/libmultipath/propsel.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmultipath/propsel.c |
|
+++ multipath-tools-130222/libmultipath/propsel.c |
|
@@ -401,10 +401,10 @@ detect_prio(struct path * pp) |
|
|
|
if (get_target_port_group_support(pp->fd) <= 0) |
|
return; |
|
- ret = get_target_port_group(pp->fd); |
|
+ ret = get_target_port_group(pp->fd, NULL); |
|
if (ret < 0) |
|
return; |
|
- if (get_asymmetric_access_state(pp->fd, ret) < 0) |
|
+ if (get_asymmetric_access_state(pp->fd, ret, NULL) < 0) |
|
return; |
|
prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); |
|
} |
|
Index: multipath-tools-130222/multipathd/main.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/multipathd/main.c |
|
+++ multipath-tools-130222/multipathd/main.c |
|
@@ -700,20 +700,23 @@ static int |
|
uev_update_path (struct uevent *uev, struct vectors * vecs) |
|
{ |
|
int ro, retval = 0; |
|
+ struct path * pp; |
|
+ |
|
+ pp = find_path_by_dev(vecs->pathvec, uev->kernel); |
|
+ if (!pp) { |
|
+ condlog(0, "%s: spurious uevent, path not found", |
|
+ uev->kernel); |
|
+ return 1; |
|
+ } |
|
+ /* reinit the prio values on change event, in case something is |
|
+ * different */ |
|
+ prio_init(&pp->prio); |
|
|
|
ro = uevent_get_disk_ro(uev); |
|
|
|
if (ro >= 0) { |
|
- struct path * pp; |
|
- |
|
condlog(2, "%s: update path write_protect to '%d' (uevent)", |
|
uev->kernel, ro); |
|
- pp = find_path_by_dev(vecs->pathvec, uev->kernel); |
|
- if (!pp) { |
|
- condlog(0, "%s: spurious uevent, path not found", |
|
- uev->kernel); |
|
- return 1; |
|
- } |
|
if (pp->mpp) { |
|
retval = reload_map(vecs, pp->mpp, 0); |
|
|
|
@@ -1218,6 +1221,11 @@ check_path (struct vectors * vecs, struc |
|
} |
|
|
|
if(newstate == PATH_UP || newstate == PATH_GHOST){ |
|
+ /* |
|
+ * Reinitialize the prioritizer, in case something |
|
+ * changed. |
|
+ */ |
|
+ prio_init(&pp->prio); |
|
if ( pp->mpp && pp->mpp->prflag ){ |
|
/* |
|
* Check Persistent Reservation.
|
|
|