changeset 11243:3a7c9b3f8ef6

6900962 Build dependency is missing for libsun_sas in usr/src/lib/Makefile. 6903244 libsun_sas should not use inquiry-page-83 prop for the LUID attribute. 6903127 sasinfo does not show correct number of PHYs after cable addition to RW2
author Hyon Kim <Hyon.Kim@Sun.COM>
date Thu, 03 Dec 2009 15:59:57 -0800
parents 33c586b163e6
children 36368caa105c
files usr/src/lib/Makefile usr/src/lib/sun_sas/common/devtree_device_disco.c usr/src/lib/sun_sas/common/devtree_hba_disco.c
diffstat 3 files changed, 120 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/Makefile	Thu Dec 03 13:54:10 2009 -0800
+++ b/usr/src/lib/Makefile	Thu Dec 03 15:59:57 2009 -0800
@@ -648,6 +648,9 @@
 libvscan:	libscf
 scsi:		libnvpair
 mpapi:		libpthread libdevinfo libsysevent libnvpair
+sun_fc:		libdevinfo libsysevent libnvpair
+libsun_ima:	libdevinfo libsysevent libnsl
+sun_sas:	libdevinfo libsysevent libnvpair libkstat libdevid
 libgrubmgmt:	libdevinfo libzfs libfstyp
 pyzfs:		libnvpair libsec libidmap libzfs
 libreparse:	libnvpair
--- a/usr/src/lib/sun_sas/common/devtree_device_disco.c	Thu Dec 03 13:54:10 2009 -0800
+++ b/usr/src/lib/sun_sas/common/devtree_device_disco.c	Thu Dec 03 15:59:57 2009 -0800
@@ -78,44 +78,6 @@
 }
 
 /*
- * Get the LUID through libdevid.
- *
- * devpath: /devices path for the devices.
- * luidi: devid string.
- */
-static void
-get_luid(char *devpath, char *luid)
-{
-	const char	ROUTINE[] = "get_luid";
-	int 		fd;
-	ddi_devid_t 	devid = NULL;
-	char 		*devidstr;
-
-	/* reset errno. */
-	errno = 0;
-	if ((fd = open(devpath,  O_RDONLY|O_NDELAY)) >= 0) {
-		if (devid_get(fd, &devid) == 0) {
-			if ((devidstr = devid_to_guid(devid)) != NULL) {
-				(void) strlcpy(luid, devidstr, 256);
-				devid_free_guid(devidstr);
-			} else {
-				log(LOG_DEBUG, ROUTINE,
-				    "failed to get devid guid on (%s) : %s",
-				    devpath, strerror(errno));
-			}
-			devid_free(devid);
-		} else {
-			log(LOG_DEBUG, ROUTINE,
-			    "failed to get devid on (%s)", devpath);
-		}
-		(void) close(fd);
-	} else {
-		log(LOG_DEBUG, ROUTINE, "open failed on (%s) error: %s",
-		    devpath, strerror(errno));
-	}
-}
-
-/*
  * Free the attached port allocation.
  */
 static void
@@ -257,8 +219,9 @@
 	char			    *propStringData = NULL;
 	int			    *propIntData = NULL;
 	int64_t			    *propInt64Data = NULL;
-	uchar_t			    *propByteData = NULL;
 	scsi_lun_t		    samLun;
+	ddi_devid_t		    devid;
+	char			    *guidStr;
 	char			    *unit_address;
 	char			    *charptr;
 	char			    *devpath, link[MAXNAMELEN];
@@ -268,7 +231,7 @@
 	HBA_WWN			    SASAddress, AttachedSASAddress;
 	struct sun_sas_port	    *disco_port_ptr;
 	uint_t			    state = 0;
-	int			    portfound, rval, size, count, i;
+	int			    portfound, rval, size;
 	int			    port_state = HBA_PORTSTATE_ONLINE;
 	uint64_t		    tmpAddr;
 
@@ -616,17 +579,41 @@
 	    sizeof (mapping_ptr->entry.ScsiId.OSDeviceName),
 	    "%s%s%s", DEVICES_DIR, devpath, minorname);
 
-	count = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, "inquiry-page-83",
-	    (uchar_t **)&propByteData);
-	if (count < 0) {
-		get_luid(mapping_ptr->entry.ScsiId.OSDeviceName,
-		    mapping_ptr->entry.LUID.buffer);
+	/* reset errno to 0 */
+	errno = 0;
+	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "devid",
+	    &propStringData) != -1) {
+		if (devid_str_decode(propStringData, &devid, NULL) != -1) {
+			guidStr = devid_to_guid(devid);
+			if (guidStr != NULL) {
+				(void) strlcpy(mapping_ptr->entry.LUID.buffer,
+				    guidStr, 256);
+				devid_free_guid(guidStr);
+			} else {
+				/*
+				 * Note:
+				 * if logical unit associated page 83 id
+				 * descriptor is not avaialble for the device
+				 * devid_to_guid returns NULl with errno 0.
+				 */
+				log(LOG_DEBUG, ROUTINE,
+				    "failed to get devid guid on (%s) : %s",
+				    devpath, strerror(errno));
+			}
+		} else {
+			/*
+			 * device may not support proper page 83 id descriptor.
+			 * leave LUID attribute to NULL and continue.
+			 */
+			log(LOG_DEBUG, ROUTINE,
+			    "failed to decode devid prop on (%s) : %s",
+			    devpath, strerror(errno));
+		}
 	} else {
-		for (i = 0, charptr = mapping_ptr->entry.LUID.buffer; i < count;
-		    i++, charptr += 2) {
-			(void) sprintf(charptr, "%02x", propByteData[i]);
-		}
-		*charptr = '\0';
+		/* leave LUID attribute to NULL and continue. */
+		log(LOG_DEBUG, ROUTINE,
+		    "failed to get devid prop on (%s) : %s",
+		    devpath, strerror(errno));
 	}
 
 	if (disco_port_ptr->scsiInfo == NULL) {
@@ -652,6 +639,8 @@
 	int			    *propIntData = NULL;
 	int64_t			    *propInt64Data = NULL;
 	scsi_lun_t		    samLun;
+	ddi_devid_t		    devid;
+	char			    *guidStr;
 	char			    *unit_address;
 	char			    *charptr;
 	char			    *clientdevpath = NULL;
@@ -1001,18 +990,50 @@
 	    "%s%s%s", DEVICES_DIR, clientdevpath, minorname);
 
 	/* get luid. */
-	if (di_prop_lookup_strings(DDI_DEV_T_ANY, clientnode,
-	    "client-guid", &propStringData) != -1) {
-		(void) strlcpy(mapping_ptr->entry.LUID.buffer, propStringData,
-		    sizeof (mapping_ptr->entry.LUID.buffer));
+	errno = 0; /* reset errno to 0 */
+	if (di_prop_lookup_strings(DDI_DEV_T_ANY, clientnode, "devid",
+	    &propStringData) != -1) {
+		if (devid_str_decode(propStringData, &devid, NULL) != -1) {
+			guidStr = devid_to_guid(devid);
+			if (guidStr != NULL) {
+				(void) strlcpy(mapping_ptr->entry.LUID.buffer,
+				    guidStr,
+				    sizeof (mapping_ptr->entry.LUID.buffer));
+				devid_free_guid(guidStr);
+			} else {
+				/*
+				 * Note:
+				 * if logical unit associated page 83 id
+				 * descriptor is not avaialble for the device
+				 * devid_to_guid returns NULl with errno 0.
+				 */
+				log(LOG_DEBUG, ROUTINE,
+				    "failed to get devid guid on (%s)",
+				    " associated with path(%s) : %s",
+				    clientdevpath,
+				    pathdevpath ?  pathdevpath :
+				    "(missing device path)",
+				    strerror(errno));
+			}
+		} else {
+			/*
+			 * device may not support proper page 83 id descriptor.
+			 * leave LUID attribute to NULL and continue.
+			 */
+			log(LOG_DEBUG, ROUTINE,
+			    "failed to decode devid prop on (%s)",
+			    " associated with path(%s) : %s",
+			    clientdevpath,
+			    pathdevpath ?  pathdevpath :
+			    "(missing device path)",
+			    strerror(errno));
+		}
 	} else {
-		log(LOG_DEBUG, ROUTINE, "No client-guid prop found on path(%s)",
-		    pathdevpath ?  pathdevpath :
-		    "(missing device path)");
-		if (pathdevpath) di_devfs_path_free(pathdevpath);
-		di_devfs_path_free(clientdevpath);
-		free_attached_port(port_ptr);
-		return (HBA_STATUS_ERROR);
+		/* leave LUID attribute to NULL and continue. */
+		log(LOG_DEBUG, ROUTINE, "Failed to get devid on %s"
+		    " associated with path(%s) : %s", clientdevpath,
+		    pathdevpath ?  pathdevpath : "(missing device path)",
+		    strerror(errno));
 	}
 
 	if (disco_port_ptr->scsiInfo == NULL) {
--- a/usr/src/lib/sun_sas/common/devtree_hba_disco.c	Thu Dec 03 13:54:10 2009 -0800
+++ b/usr/src/lib/sun_sas/common/devtree_hba_disco.c	Thu Dec 03 15:59:57 2009 -0800
@@ -98,6 +98,7 @@
 	uint64_t		    tmpAddr;
 	char			    *charptr, cntlLink[MAXPATHLEN] = {'\0'};
 	int			    rval;
+	di_node_t		    branchNode;
 	uint_t			    state = HBA_PORTSTATE_UNKNOWN;
 
 	if (hba_ptr == NULL) {
@@ -127,6 +128,26 @@
 		return (HBA_STATUS_ERROR);
 	}
 
+	/*
+	 * Let's take a branch snap shot for pulling attributes.
+	 * The attribute change doesn't invalidate devinfo cache snapshot.
+	 * Phy info prop and num-phys can be obsolate when the same hba
+	 * connected to the same expander(SIM) thus phy numbers are increased.
+	 * Also the phy number may get decreased when a connection is removed
+	 * while the iport still exist through another connection.
+	 */
+	branchNode = di_init(portDevpath, DINFOPROP);
+	if (branchNode == DI_NODE_NIL) {
+		/* something is wrong here. */
+		di_fini(branchNode);
+		log(LOG_DEBUG, ROUTINE,
+		    "Unable to take devinfoi branch snapshot on HBA port \"%s\""
+		    " due to %s", portDevpath, strerror(errno));
+		S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
+		S_FREE(port_ptr);
+		return (HBA_STATUS_ERROR);
+	}
+
 	state = di_state(portNode);
 	if (((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) ||
 	    ((state & DI_DEVICE_OFFLINE) == DI_DEVICE_OFFLINE)) {
@@ -165,12 +186,13 @@
 	port_ptr->port_attributes.PortSpecificAttribute.
 	    SASPort->PortProtocol = protocol;
 
-	rval = di_prop_lookup_strings(DDI_DEV_T_ANY, portNode,
+	rval = di_prop_lookup_strings(DDI_DEV_T_ANY, branchNode,
 	    "initiator-port", &propStringData);
 	if (rval < 0) {
 		log(LOG_DEBUG, ROUTINE,
 		    "Unable to get initiator-port from HBA port node %s.",
 		    port_ptr->port_attributes.OSDeviceName);
+		di_fini(branchNode);
 		S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
 		S_FREE(port_ptr);
 		return (HBA_STATUS_ERROR);
@@ -192,12 +214,13 @@
 		}
 	}
 
-	rval = di_prop_lookup_strings(DDI_DEV_T_ANY, portNode,
+	rval = di_prop_lookup_strings(DDI_DEV_T_ANY, branchNode,
 	    "attached-port", &propStringData);
 	if (rval < 0) {
 		log(LOG_DEBUG, ROUTINE,
 		    "Unable to get attached-port from HBA port node %s.",
 		    port_ptr->port_attributes.OSDeviceName);
+		di_fini(branchNode);
 		S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
 		S_FREE(port_ptr);
 		return (HBA_STATUS_ERROR);
@@ -223,12 +246,13 @@
 		}
 	}
 
-	rval = di_prop_lookup_ints(DDI_DEV_T_ANY, portNode,
+	rval = di_prop_lookup_ints(DDI_DEV_T_ANY, branchNode,
 	    "num-phys", &propIntData);
 	if (rval < 0) {
 		log(LOG_DEBUG, ROUTINE,
 		    "Unable to get NumberofPhys from HBA port %s.",
 		    port_ptr->port_attributes.OSDeviceName);
+		di_fini(branchNode);
 		S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
 		S_FREE(port_ptr);
 		return (HBA_STATUS_ERROR);
@@ -239,23 +263,29 @@
 
 	if (port_ptr->port_attributes.PortSpecificAttribute.\
 	    SASPort->NumberofPhys > 0) {
-		if (get_phy_info(portNode, port_ptr) != HBA_STATUS_OK) {
+		if (get_phy_info(branchNode, port_ptr) != HBA_STATUS_OK) {
 			log(LOG_DEBUG, ROUTINE,
 			    "Failed to get phy info on HBA port %s.",
 			    port_ptr->port_attributes.OSDeviceName);
+			di_fini(branchNode);
 			S_FREE(port_ptr->port_attributes.
 			    PortSpecificAttribute.SASPort);
 			S_FREE(port_ptr);
+			return (HBA_STATUS_ERROR);
 		}
 	}
 
-	/* devtree_attached_devices(portSubtreenode, port_ptr); */
+	/* now done with prop checking. remove branchNode. */
+	di_fini(branchNode);
+
+	/* Construct discovered target port. */
 	if (devtree_attached_devices(portNode, port_ptr) != HBA_STATUS_OK) {
 		log(LOG_DEBUG, ROUTINE,
 		    "Failed to get attached device info HBA port %s.",
 		    port_ptr->port_attributes.OSDeviceName);
 		S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
 		S_FREE(port_ptr);
+		return (HBA_STATUS_ERROR);
 	}
 
 	fillDomainPortWWN(port_ptr);