645 lines
20 KiB
Plaintext
645 lines
20 KiB
Plaintext
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
|
|
index 5132081..2640281 100644
|
|
--- a/libmultipath/checkers.c
|
|
+++ b/libmultipath/checkers.c
|
|
@@ -40,6 +40,14 @@ struct checker * alloc_checker (void)
|
|
|
|
void free_checker (struct checker * c)
|
|
{
|
|
+ condlog(3, "unloading %s checker", c->name);
|
|
+ list_del(&c->node);
|
|
+ if (c->handle) {
|
|
+ if (dlclose(c->handle) != 0) {
|
|
+ condlog(0, "Cannot unload checker %s: %s",
|
|
+ c->name, dlerror());
|
|
+ }
|
|
+ }
|
|
free(c);
|
|
}
|
|
|
|
@@ -49,8 +57,7 @@ void cleanup_checkers (void)
|
|
struct checker * checker_temp;
|
|
|
|
list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node) {
|
|
- list_del(&checker_loop->node);
|
|
- free(checker_loop);
|
|
+ free_checker(checker_loop);
|
|
}
|
|
}
|
|
|
|
@@ -68,7 +75,6 @@ struct checker * checker_lookup (char * name)
|
|
struct checker * add_checker (char * name)
|
|
{
|
|
char libname[LIB_CHECKER_NAMELEN];
|
|
- void * handle;
|
|
struct checker * c;
|
|
char *errstr;
|
|
|
|
@@ -78,31 +84,31 @@ struct checker * add_checker (char * name)
|
|
snprintf(libname, LIB_CHECKER_NAMELEN, "%s/libcheck%s.so",
|
|
conf->multipath_dir, name);
|
|
condlog(3, "loading %s checker", libname);
|
|
- handle = dlopen(libname, RTLD_NOW);
|
|
+ c->handle = dlopen(libname, RTLD_NOW);
|
|
errstr = dlerror();
|
|
if (errstr != NULL)
|
|
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
- if (!handle)
|
|
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
+ if (!c->handle)
|
|
goto out;
|
|
|
|
- c->check = (int (*)(struct checker *)) dlsym(handle, "libcheck_check");
|
|
+ c->check = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_check");
|
|
errstr = dlerror();
|
|
if (errstr != NULL)
|
|
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
if (!c->check)
|
|
goto out;
|
|
|
|
- c->init = (int (*)(struct checker *)) dlsym(handle, "libcheck_init");
|
|
+ c->init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_init");
|
|
errstr = dlerror();
|
|
if (errstr != NULL)
|
|
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
if (!c->init)
|
|
goto out;
|
|
|
|
- c->free = (void (*)(struct checker *)) dlsym(handle, "libcheck_free");
|
|
+ c->free = (void (*)(struct checker *)) dlsym(c->handle, "libcheck_free");
|
|
errstr = dlerror();
|
|
if (errstr != NULL)
|
|
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
if (!c->free)
|
|
goto out;
|
|
|
|
@@ -199,4 +205,5 @@ void checker_get (struct checker * dst, char * name)
|
|
dst->check = src->check;
|
|
dst->init = src->init;
|
|
dst->free = src->free;
|
|
+ dst->handle = NULL;
|
|
}
|
|
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
|
|
index e735250..da09d6c 100644
|
|
--- a/libmultipath/checkers.h
|
|
+++ b/libmultipath/checkers.h
|
|
@@ -94,6 +94,7 @@ enum path_check_state {
|
|
|
|
struct checker {
|
|
struct list_head node;
|
|
+ void *handle;
|
|
int fd;
|
|
int sync;
|
|
int disable;
|
|
@@ -111,6 +112,7 @@ struct checker {
|
|
|
|
char * checker_state_name (int);
|
|
int init_checkers (void);
|
|
+void cleanup_checkers (void);
|
|
struct checker * add_checker (char *);
|
|
struct checker * checker_lookup (char *);
|
|
int checker_init (struct checker *, void **);
|
|
diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c
|
|
index 9eac31d..03c1354 100644
|
|
--- a/libmultipath/checkers/emc_clariion.c
|
|
+++ b/libmultipath/checkers/emc_clariion.c
|
|
@@ -102,6 +102,8 @@ int libcheck_check (struct checker * c)
|
|
int ret;
|
|
|
|
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ memset(sense_buffer, 0, 128);
|
|
+ memset(sb, 0, SENSE_BUFF_LEN);
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
io_hdr.mx_sb_len = sizeof (sb);
|
|
@@ -128,7 +130,7 @@ int libcheck_check (struct checker * c)
|
|
}
|
|
|
|
if ( /* Effective initiator type */
|
|
- sense_buffer[27] != 0x03
|
|
+ sense_buffer[27] != 0x03
|
|
/*
|
|
* Failover mode should be set to 1 (PNR failover mode)
|
|
* or 4 (ALUA failover mode).
|
|
@@ -155,7 +157,7 @@ int libcheck_check (struct checker * c)
|
|
"or LUNZ");
|
|
return PATH_DOWN;
|
|
}
|
|
-
|
|
+
|
|
/*
|
|
* store the LUN WWN there and compare that it indeed did not
|
|
* change in between, to protect against the path suddenly
|
|
@@ -171,28 +173,29 @@ int libcheck_check (struct checker * c)
|
|
memcpy(ct->wwn, &sense_buffer[10], 16);
|
|
ct->wwn_set = 1;
|
|
}
|
|
-
|
|
+
|
|
/*
|
|
* Issue read on active path to determine if inactive snapshot.
|
|
*/
|
|
if (sense_buffer[4] == 2) {/* if active path */
|
|
unsigned char buf[4096];
|
|
|
|
+ memset(buf, 0, 4096);
|
|
ret = sg_read(c->fd, &buf[0], sbb = &sb[0]);
|
|
if (ret == PATH_DOWN) {
|
|
hexadecimal_to_ascii(ct->wwn, wwnstr);
|
|
|
|
/*
|
|
- * Check for inactive snapshot LU this way. Must
|
|
+ * Check for inactive snapshot LU this way. Must
|
|
* fail these.
|
|
- */
|
|
+ */
|
|
if (((sbb[2]&0xf) == 5) && (sbb[12] == 0x25) &&
|
|
(sbb[13]==1)) {
|
|
/*
|
|
- * Do this so that we can fail even the
|
|
- * passive paths which will return
|
|
+ * Do this so that we can fail even the
|
|
+ * passive paths which will return
|
|
* 02/04/03 not 05/25/01 on read.
|
|
- */
|
|
+ */
|
|
SET_INACTIVE_SNAP(c);
|
|
MSG(c, "emc_clariion_checker: Active "
|
|
"path to inactive snapshot WWN %s.",
|
|
@@ -206,10 +209,10 @@ int libcheck_check (struct checker * c)
|
|
MSG(c, "emc_clariion_checker: Active path is "
|
|
"healthy.");
|
|
/*
|
|
- * Remove the path from the set of paths to inactive
|
|
- * snapshot LUs if it was in this list since the
|
|
- * snapshot is no longer inactive.
|
|
- */
|
|
+ * Remove the path from the set of paths to inactive
|
|
+ * snapshot LUs if it was in this list since the
|
|
+ * snapshot is no longer inactive.
|
|
+ */
|
|
CLR_INACTIVE_SNAP(c);
|
|
}
|
|
} else {
|
|
@@ -221,7 +224,7 @@ int libcheck_check (struct checker * c)
|
|
ret = PATH_DOWN;
|
|
} else {
|
|
MSG(c,
|
|
- "emc_clariion_checker: Passive path is healthy.");
|
|
+ "emc_clariion_checker: Passive path is healthy.");
|
|
ret = PATH_UP; /* not ghost */
|
|
}
|
|
}
|
|
diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c
|
|
index 7509307..3f28d85 100644
|
|
--- a/libmultipath/checkers/hp_sw.c
|
|
+++ b/libmultipath/checkers/hp_sw.c
|
|
@@ -48,75 +48,76 @@ static int
|
|
do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
|
|
void *resp, int mx_resp_len, int noisy)
|
|
{
|
|
- unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
|
|
- { INQUIRY_CMD, 0, 0, 0, 0, 0 };
|
|
- unsigned char sense_b[SENSE_BUFF_LEN];
|
|
- struct sg_io_hdr io_hdr;
|
|
-
|
|
- if (cmddt)
|
|
- inqCmdBlk[1] |= 2;
|
|
- if (evpd)
|
|
- inqCmdBlk[1] |= 1;
|
|
- inqCmdBlk[2] = (unsigned char) pg_op;
|
|
+ unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
|
|
+ { INQUIRY_CMD, 0, 0, 0, 0, 0 };
|
|
+ unsigned char sense_b[SENSE_BUFF_LEN];
|
|
+ struct sg_io_hdr io_hdr;
|
|
+
|
|
+ if (cmddt)
|
|
+ inqCmdBlk[1] |= 2;
|
|
+ if (evpd)
|
|
+ inqCmdBlk[1] |= 1;
|
|
+ inqCmdBlk[2] = (unsigned char) pg_op;
|
|
inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
|
|
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
|
|
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
- io_hdr.interface_id = 'S';
|
|
- io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
- io_hdr.mx_sb_len = sizeof (sense_b);
|
|
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
- io_hdr.dxfer_len = mx_resp_len;
|
|
- io_hdr.dxferp = resp;
|
|
- io_hdr.cmdp = inqCmdBlk;
|
|
- io_hdr.sbp = sense_b;
|
|
- io_hdr.timeout = DEF_TIMEOUT;
|
|
-
|
|
- if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
|
|
- return 1;
|
|
-
|
|
- /* treat SG_ERR here to get rid of sg_err.[ch] */
|
|
- io_hdr.status &= 0x7e;
|
|
- if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
|
|
- (0 == io_hdr.driver_status))
|
|
- return 0;
|
|
- if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
|
|
- (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
|
|
- (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
|
|
- if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
|
|
- int sense_key;
|
|
- unsigned char * sense_buffer = io_hdr.sbp;
|
|
- if (sense_buffer[0] & 0x2)
|
|
- sense_key = sense_buffer[1] & 0xf;
|
|
- else
|
|
- sense_key = sense_buffer[2] & 0xf;
|
|
- if(RECOVERED_ERROR == sense_key)
|
|
- return 0;
|
|
- }
|
|
- }
|
|
- return 1;
|
|
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ memset(sense_b, 0, SENSE_BUFF_LEN);
|
|
+ io_hdr.interface_id = 'S';
|
|
+ io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
+ io_hdr.mx_sb_len = sizeof (sense_b);
|
|
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
+ io_hdr.dxfer_len = mx_resp_len;
|
|
+ io_hdr.dxferp = resp;
|
|
+ io_hdr.cmdp = inqCmdBlk;
|
|
+ io_hdr.sbp = sense_b;
|
|
+ io_hdr.timeout = DEF_TIMEOUT;
|
|
+
|
|
+ if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
|
|
+ return 1;
|
|
+
|
|
+ /* treat SG_ERR here to get rid of sg_err.[ch] */
|
|
+ io_hdr.status &= 0x7e;
|
|
+ if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
|
|
+ (0 == io_hdr.driver_status))
|
|
+ return 0;
|
|
+ if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
|
|
+ (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
|
|
+ (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
|
|
+ if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
|
|
+ int sense_key;
|
|
+ unsigned char * sense_buffer = io_hdr.sbp;
|
|
+ if (sense_buffer[0] & 0x2)
|
|
+ sense_key = sense_buffer[1] & 0xf;
|
|
+ else
|
|
+ sense_key = sense_buffer[2] & 0xf;
|
|
+ if(RECOVERED_ERROR == sense_key)
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ return 1;
|
|
}
|
|
|
|
static int
|
|
do_tur (int fd)
|
|
{
|
|
- unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
|
|
- struct sg_io_hdr io_hdr;
|
|
- unsigned char sense_buffer[32];
|
|
-
|
|
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
- io_hdr.interface_id = 'S';
|
|
- io_hdr.cmd_len = sizeof (turCmdBlk);
|
|
- io_hdr.mx_sb_len = sizeof (sense_buffer);
|
|
- io_hdr.dxfer_direction = SG_DXFER_NONE;
|
|
- io_hdr.cmdp = turCmdBlk;
|
|
- io_hdr.sbp = sense_buffer;
|
|
- io_hdr.timeout = DEF_TIMEOUT;
|
|
- io_hdr.pack_id = 0;
|
|
-
|
|
- if (ioctl(fd, SG_IO, &io_hdr) < 0)
|
|
+ unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
|
|
+ struct sg_io_hdr io_hdr;
|
|
+ unsigned char sense_buffer[32];
|
|
+
|
|
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ io_hdr.interface_id = 'S';
|
|
+ io_hdr.cmd_len = sizeof (turCmdBlk);
|
|
+ io_hdr.mx_sb_len = sizeof (sense_buffer);
|
|
+ io_hdr.dxfer_direction = SG_DXFER_NONE;
|
|
+ io_hdr.cmdp = turCmdBlk;
|
|
+ io_hdr.sbp = sense_buffer;
|
|
+ io_hdr.timeout = DEF_TIMEOUT;
|
|
+ io_hdr.pack_id = 0;
|
|
+
|
|
+ if (ioctl(fd, SG_IO, &io_hdr) < 0)
|
|
return 1;
|
|
|
|
- if (io_hdr.info & SG_INFO_OK_MASK)
|
|
+ if (io_hdr.info & SG_INFO_OK_MASK)
|
|
return 1;
|
|
|
|
return 0;
|
|
@@ -134,8 +135,8 @@ libcheck_check (struct checker * c)
|
|
|
|
if (do_tur(c->fd)) {
|
|
MSG(c, MSG_HP_SW_GHOST);
|
|
- return PATH_GHOST;
|
|
- }
|
|
+ return PATH_GHOST;
|
|
+ }
|
|
MSG(c, MSG_HP_SW_UP);
|
|
return PATH_UP;
|
|
}
|
|
diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c
|
|
index 0086125..c4c7b8f 100644
|
|
--- a/libmultipath/checkers/rdac.c
|
|
+++ b/libmultipath/checkers/rdac.c
|
|
@@ -52,6 +52,7 @@ do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len)
|
|
inqCmdBlk[2] = (unsigned char) pg_op;
|
|
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
|
|
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ memset(sense_b, 0, SENSE_BUFF_LEN);
|
|
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
@@ -100,6 +101,7 @@ libcheck_check (struct checker * c)
|
|
{
|
|
struct volume_access_inq inq;
|
|
|
|
+ memset(&inq, 0, sizeof(struct volume_access_inq));
|
|
if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq))) {
|
|
MSG(c, MSG_RDAC_DOWN);
|
|
return PATH_DOWN;
|
|
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
|
|
index 43b846d..820a2e3 100644
|
|
--- a/libmultipath/checkers/tur.c
|
|
+++ b/libmultipath/checkers/tur.c
|
|
@@ -47,6 +47,7 @@ libcheck_check (struct checker * c)
|
|
|
|
retry:
|
|
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ memset(&sense_buffer, 0, 32);
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (turCmdBlk);
|
|
io_hdr.mx_sb_len = sizeof (sense_buffer);
|
|
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
|
index cf134e4..908156d 100644
|
|
--- a/libmultipath/config.c
|
|
+++ b/libmultipath/config.c
|
|
@@ -150,9 +150,6 @@ free_hwe (struct hwentry * hwe)
|
|
if (hwe->revision)
|
|
FREE(hwe->revision);
|
|
|
|
- if (hwe->selector)
|
|
- FREE(hwe->selector);
|
|
-
|
|
if (hwe->getuid)
|
|
FREE(hwe->getuid);
|
|
|
|
@@ -162,6 +159,15 @@ free_hwe (struct hwentry * hwe)
|
|
if (hwe->hwhandler)
|
|
FREE(hwe->hwhandler);
|
|
|
|
+ if (hwe->selector)
|
|
+ FREE(hwe->selector);
|
|
+
|
|
+ if (hwe->checker_name)
|
|
+ FREE(hwe->checker_name);
|
|
+
|
|
+ if (hwe->prio_name)
|
|
+ FREE(hwe->prio_name);
|
|
+
|
|
if (hwe->bl_product)
|
|
FREE(hwe->bl_product);
|
|
|
|
@@ -409,6 +415,12 @@ free_config (struct config * conf)
|
|
if (conf->bindings_file)
|
|
FREE(conf->bindings_file);
|
|
|
|
+ if (conf->prio_name)
|
|
+ FREE(conf->prio_name);
|
|
+
|
|
+ if (conf->checker_name)
|
|
+ FREE(conf->checker_name);
|
|
+
|
|
free_blacklist(conf->blist_devnode);
|
|
free_blacklist(conf->blist_wwid);
|
|
free_blacklist_device(conf->blist_device);
|
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
|
index 9929e19..20d0684 100644
|
|
--- a/libmultipath/discovery.c
|
|
+++ b/libmultipath/discovery.c
|
|
@@ -232,6 +232,7 @@ devt2devname (char *devname, char *devt)
|
|
char block_path[FILE_NAME_SIZE];
|
|
struct stat statbuf;
|
|
|
|
+ memset(block_path, 0, FILE_NAME_SIZE);
|
|
if (sscanf(devt, "%u:%u", &major, &minor) != 2) {
|
|
condlog(0, "Invalid device number %s", devt);
|
|
return 1;
|
|
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
|
index 46ae2ec..7467411 100644
|
|
--- a/libmultipath/print.c
|
|
+++ b/libmultipath/print.c
|
|
@@ -111,19 +111,22 @@ snprint_ro (char * buff, size_t len, struct multipath * mpp)
|
|
static int
|
|
snprint_progress (char * buff, size_t len, int cur, int total)
|
|
{
|
|
- int i = PROGRESS_LEN * cur / total;
|
|
- int j = PROGRESS_LEN - i;
|
|
char * c = buff;
|
|
char * end = buff + len;
|
|
|
|
- while (i-- > 0) {
|
|
- c += snprintf(c, len, "X");
|
|
- if ((len = (end - c)) <= 1) goto out;
|
|
- }
|
|
+ if (total > 0) {
|
|
+ int i = PROGRESS_LEN * cur / total;
|
|
+ int j = PROGRESS_LEN - i;
|
|
+
|
|
+ while (i-- > 0) {
|
|
+ c += snprintf(c, len, "X");
|
|
+ if ((len = (end - c)) <= 1) goto out;
|
|
+ }
|
|
|
|
- while (j-- > 0) {
|
|
- c += snprintf(c, len, ".");
|
|
- if ((len = (end - c)) <= 1) goto out;
|
|
+ while (j-- > 0) {
|
|
+ c += snprintf(c, len, ".");
|
|
+ if ((len = (end - c)) <= 1) goto out;
|
|
+ }
|
|
}
|
|
|
|
c += snprintf(c, len, " %i/%i", cur, total);
|
|
@@ -705,6 +708,7 @@ print_multipath_topology (struct multipath * mpp, int verbosity)
|
|
{
|
|
char buff[MAX_LINE_LEN * MAX_LINES] = {};
|
|
|
|
+ memset(&buff[0], 0, MAX_LINE_LEN * MAX_LINES);
|
|
snprint_multipath_topology(&buff[0], MAX_LINE_LEN * MAX_LINES,
|
|
mpp, verbosity);
|
|
printf("%s", buff);
|
|
diff --git a/libmultipath/prio.c b/libmultipath/prio.c
|
|
index c9d2873..352e9ca 100644
|
|
--- a/libmultipath/prio.c
|
|
+++ b/libmultipath/prio.c
|
|
@@ -24,6 +24,14 @@ struct prio * alloc_prio (void)
|
|
|
|
void free_prio (struct prio * p)
|
|
{
|
|
+ condlog(3, "unloading %s prioritizer", p->name);
|
|
+ list_del(&p->node);
|
|
+ if (p->handle) {
|
|
+ if (dlclose(p->handle) != 0) {
|
|
+ condlog(0, "Cannot unload prioritizer %s: %s",
|
|
+ p->name, dlerror());
|
|
+ }
|
|
+ }
|
|
free(p);
|
|
}
|
|
|
|
@@ -33,8 +41,7 @@ void cleanup_prio(void)
|
|
struct prio * prio_temp;
|
|
|
|
list_for_each_entry_safe(prio_loop, prio_temp, &prioritizers, node) {
|
|
- list_del(&prio_loop->node);
|
|
- free(prio_loop);
|
|
+ free_prio(prio_loop);
|
|
}
|
|
}
|
|
|
|
@@ -52,7 +59,6 @@ struct prio * prio_lookup (char * name)
|
|
struct prio * add_prio (char * name)
|
|
{
|
|
char libname[LIB_PRIO_NAMELEN];
|
|
- void * handle;
|
|
struct prio * p;
|
|
char *errstr;
|
|
|
|
@@ -62,16 +68,16 @@ struct prio * add_prio (char * name)
|
|
snprintf(libname, LIB_PRIO_NAMELEN, "%s/libprio%s.so",
|
|
conf->multipath_dir, name);
|
|
condlog(3, "loading %s prioritizer", libname);
|
|
- handle = dlopen(libname, RTLD_NOW);
|
|
+ p->handle = dlopen(libname, RTLD_NOW);
|
|
errstr = dlerror();
|
|
if (errstr != NULL)
|
|
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
- if (!handle)
|
|
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
|
+ if (!p->handle)
|
|
goto out;
|
|
- p->getprio = (int (*)(struct path *)) dlsym(handle, "getprio");
|
|
+ p->getprio = (int (*)(struct path *)) 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: (%s)", errstr);
|
|
if (!p->getprio)
|
|
goto out;
|
|
snprintf(p->name, PRIO_NAME_LEN, "%s", name);
|
|
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
|
|
index 4eea703..deef02d 100644
|
|
--- a/libmultipath/prio.h
|
|
+++ b/libmultipath/prio.h
|
|
@@ -37,12 +37,14 @@
|
|
#define PRIO_NAME_LEN 16
|
|
|
|
struct prio {
|
|
+ void *handle;
|
|
struct list_head node;
|
|
char name[PRIO_NAME_LEN];
|
|
int (*getprio)(struct path *);
|
|
};
|
|
|
|
int init_prio (void);
|
|
+void cleanup_prio(void);
|
|
struct prio * add_prio (char *);
|
|
struct prio * prio_lookup (char *);
|
|
int prio_getprio (struct prio *, struct path *);
|
|
diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c
|
|
index 59df788..498de62 100644
|
|
--- a/libmultipath/prioritizers/alua_rtpg.c
|
|
+++ b/libmultipath/prioritizers/alua_rtpg.c
|
|
@@ -265,8 +265,10 @@ get_asymmetric_access_state(int fd, unsigned int tpg)
|
|
}
|
|
memset(buf, 0, buflen);
|
|
rc = do_rtpg(fd, buf, buflen);
|
|
- if (rc < 0)
|
|
+ if (rc < 0) {
|
|
+ free(buf);
|
|
return rc;
|
|
+ }
|
|
scsi_buflen = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
|
|
if (buflen < (scsi_buflen + 4)) {
|
|
free(buf);
|
|
diff --git a/libmultipath/prioritizers/emc.c b/libmultipath/prioritizers/emc.c
|
|
index 61d7a77..c3301b2 100644
|
|
--- a/libmultipath/prioritizers/emc.c
|
|
+++ b/libmultipath/prioritizers/emc.c
|
|
@@ -18,8 +18,9 @@ int emc_clariion_prio(const char *dev, int fd)
|
|
unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0,
|
|
sizeof(sb), 0};
|
|
struct sg_io_hdr io_hdr;
|
|
- int ret = 0;
|
|
+ int ret = PRIO_UNDEF;
|
|
|
|
+ memset(&sense_buffer, 0, 256);
|
|
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
@@ -45,9 +46,9 @@ int emc_clariion_prio(const char *dev, int fd)
|
|
pp_emc_log(0, "path unit report page in unknown format");
|
|
goto out;
|
|
}
|
|
-
|
|
+
|
|
if ( /* Effective initiator type */
|
|
- sense_buffer[27] != 0x03
|
|
+ sense_buffer[27] != 0x03
|
|
/*
|
|
* Failover mode should be set to 1 (PNR failover mode)
|
|
* or 4 (ALUA failover mode).
|
|
@@ -68,7 +69,7 @@ int emc_clariion_prio(const char *dev, int fd)
|
|
/* Note this will switch to the default priority group, even if
|
|
* it is not the currently active one. */
|
|
ret = (sense_buffer[5] == sense_buffer[8]) ? 1 : 0;
|
|
-
|
|
+
|
|
out:
|
|
return(ret);
|
|
}
|
|
diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c
|
|
index f3d4cb3..d56a46a 100644
|
|
--- a/libmultipath/prioritizers/hds.c
|
|
+++ b/libmultipath/prioritizers/hds.c
|
|
@@ -104,6 +104,7 @@ int hds_modular_prio (const char *dev, int fd)
|
|
}
|
|
|
|
memset (&io_hdr, 0, sizeof (sg_io_hdr_t));
|
|
+ memset (inqBuff, 0, INQ_REPLY_LEN);
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
io_hdr.mx_sb_len = sizeof (sense_buffer);
|
|
diff --git a/libmultipath/prioritizers/ontap.c b/libmultipath/prioritizers/ontap.c
|
|
index 1200114..4d7c128 100644
|
|
--- a/libmultipath/prioritizers/ontap.c
|
|
+++ b/libmultipath/prioritizers/ontap.c
|
|
@@ -79,6 +79,7 @@ static int send_gva(const char *dev, int fd, unsigned char pg,
|
|
int ret = -1;
|
|
|
|
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ memset(results, 0, *results_size);
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (cdb);
|
|
io_hdr.mx_sb_len = sizeof (sb);
|
|
diff --git a/libmultipath/prioritizers/rdac.c b/libmultipath/prioritizers/rdac.c
|
|
index 7eafc31..b514bdd 100644
|
|
--- a/libmultipath/prioritizers/rdac.c
|
|
+++ b/libmultipath/prioritizers/rdac.c
|
|
@@ -21,6 +21,7 @@ int rdac_prio(const char *dev, int fd)
|
|
int ret = 0;
|
|
|
|
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
|
+ memset(sense_buffer, 0, 256);
|
|
io_hdr.interface_id = 'S';
|
|
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
|
io_hdr.mx_sb_len = sizeof (sb);
|