From: Moger, Babu Date: Wed, 22 Feb 2012 18:09:10 +0000 (+0000) Subject: multipath-tools: Generalizing the vpd 0x83 processing with correct buffer length X-Git-Tag: upstream/0.5.0~44 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad83502eddaca2770745fb15cf664e2ebb990df6;p=platform%2Fupstream%2Fmultipath-tools.git multipath-tools: Generalizing the vpd 0x83 processing with correct buffer length Right now the buffer length for inquiry vpd 0x83 is hardcoded to 128 bytes. This can cause problems if the length of all the designation descriptors exceed 128 bytes. This was causing me issues while configuring my storage with alua. I have generalized the processing with correct buffer length. Patch has been tested with NetApp E-series storage. Signed-off-by: Babu Moger --- diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c index b76db72..981ba06 100644 --- a/libmultipath/prioritizers/alua_rtpg.c +++ b/libmultipath/prioritizers/alua_rtpg.c @@ -172,38 +172,62 @@ get_target_port_group_support(int fd) int get_target_port_group(int fd) { - unsigned char buf[128]; + unsigned char *buf; struct vpd83_data * vpd83; struct vpd83_dscr * dscr; int rc; + int buflen, scsi_buflen; - memset(buf, 0, sizeof(buf)); - rc = do_inquiry(fd, 1, 0x83, buf, sizeof(buf)); - if (!rc) { - vpd83 = (struct vpd83_data *) buf; - - rc = -RTPG_NO_TPG_IDENTIFIER; - FOR_EACH_VPD83_DSCR(vpd83, dscr) { - if (vpd83_dscr_istype(dscr, IDTYPE_TARGET_PORT_GROUP)) { - struct vpd83_tpg_dscr * p; - - if (rc != -RTPG_NO_TPG_IDENTIFIER) { - PRINT_DEBUG("get_target_port_group: " - "more than one TPG identifier " - "found!\n"); - continue; - } - - p = (struct vpd83_tpg_dscr *) dscr->data; - rc = get_uint16(p->tpg); - } + buflen = 128; /* Lets start from 128 */ + buf = (unsigned char *)malloc(buflen); + if (!buf) { + PRINT_DEBUG("malloc failed: could not allocate" + "%u bytes\n", buflen); + return -RTPG_RTPG_FAILED; + } + + memset(buf, 0, buflen); + rc = do_inquiry(fd, 1, 0x83, buf, buflen); + if (rc < 0) + goto out; + + scsi_buflen = (buf[2] << 8 | buf[3]) + 4; + if (buflen < scsi_buflen) { + free(buf); + buf = (unsigned char *)malloc(scsi_buflen); + if (!buf) { + PRINT_DEBUG("malloc failed: could not allocate" + "%u bytes\n", scsi_buflen); + return -RTPG_RTPG_FAILED; } - if (rc == -RTPG_NO_TPG_IDENTIFIER) { - PRINT_DEBUG("get_target_port_group: " - "no TPG identifier found!\n"); + buflen = scsi_buflen; + memset(buf, 0, buflen); + rc = do_inquiry(fd, 1, 0x83, buf, buflen); + if (rc < 0) + goto out; + } + + vpd83 = (struct vpd83_data *) buf; + rc = -RTPG_NO_TPG_IDENTIFIER; + FOR_EACH_VPD83_DSCR(vpd83, dscr) { + if (vpd83_dscr_istype(dscr, IDTYPE_TARGET_PORT_GROUP)) { + struct vpd83_tpg_dscr *p; + if (rc != -RTPG_NO_TPG_IDENTIFIER) { + PRINT_DEBUG("get_target_port_group: more " + "than one TPG identifier found!\n"); + continue; + } + p = (struct vpd83_tpg_dscr *)dscr->data; + rc = get_uint16(p->tpg); } } + if (rc == -RTPG_NO_TPG_IDENTIFIER) { + PRINT_DEBUG("get_target_port_group: " + "no TPG identifier found!\n"); + } +out: + free(buf); return rc; }