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.

566 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.