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);