changeset 11103:3b3f33a37cab

6894418 set interface for global logical unit property 6895461 'stmf: WARNING: proxy port not registered' appears occasionally on COMSTAR target
author John Forte <John.Forte@Sun.COM>
date Thu, 19 Nov 2009 05:07:17 -0800
parents b91faef0c984
children 166a083c78c5
files usr/src/lib/libstmf/common/libstmf.h usr/src/lib/libstmf/common/mapfile-vers usr/src/lib/libstmf/common/stmf.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h usr/src/uts/common/io/comstar/stmf/stmf.c usr/src/uts/common/sys/stmf_sbd_ioctl.h
diffstat 8 files changed, 451 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libstmf/common/libstmf.h	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/lib/libstmf/common/libstmf.h	Thu Nov 19 05:07:17 2009 -0800
@@ -323,6 +323,8 @@
 int stmfFreeLuResource(luResource hdl);
 void stmfFreeMemory(void *);
 int stmfGetAluaState(boolean_t *enabled, uint32_t *node);
+int stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal,
+    size_t *propLen);
 int stmfGetHostGroupList(stmfGroupList **initiatorGroupList);
 int stmfGetHostGroupMembers(stmfGroupName *hostGroupName,
     stmfGroupProperties **groupProperties);
@@ -371,6 +373,7 @@
     stmfDevid *targetName);
 int stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex);
 int stmfSetAluaState(boolean_t enabled, uint32_t node);
+int stmfSetGlobalLuProp(uint16_t dType, uint32_t propType, const char *propVal);
 int stmfSetLuProp(luResource hdl, uint32_t propType, const char *propVal);
 int stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet);
 int stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType);
--- a/usr/src/lib/libstmf/common/mapfile-vers	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/lib/libstmf/common/mapfile-vers	Thu Nov 19 05:07:17 2009 -0800
@@ -53,6 +53,7 @@
 	    stmfDevidFromWwn;
 	    stmfFreeLuResource;
 	    stmfFreeMemory;
+	    stmfGetGlobalLuProp;
 	    stmfGetHostGroupList;
 	    stmfGetHostGroupMembers;
 	    stmfGetLuProp;
@@ -85,6 +86,7 @@
 	    stmfRemoveViewEntry;
 	    stmfSetAluaState;
 	    stmfGetAluaState;
+	    stmfSetGlobalLuProp;
 	    stmfSetPersistMethod;
 	    stmfSetProviderData;
 	    stmfSetProviderDataProt;
--- a/usr/src/lib/libstmf/common/stmf.c	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/lib/libstmf/common/stmf.c	Thu Nov 19 05:07:17 2009 -0800
@@ -48,6 +48,7 @@
 #include <sys/stmf_ioctl.h>
 #include <sys/stmf_sbd_ioctl.h>
 #include <sys/pppt_ioctl.h>
+#include <macros.h>
 
 #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
 #define	SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
@@ -124,6 +125,7 @@
 static int addGuidToDiskStore(stmfGuid *, char *);
 static int persistDiskGuid(stmfGuid *, char *, boolean_t);
 static int setDiskProp(luResourceImpl *, uint32_t, const char *);
+static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen);
 static int checkHexUpper(char *);
 static int strToShift(const char *);
 static int niceStrToNum(const char *, uint64_t *);
@@ -138,6 +140,7 @@
 static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
 static int getProviderData(char *, nvlist_t **, int, uint64_t *);
 static int setDiskStandby(stmfGuid *luGuid);
+static int setDiskGlobalProp(uint32_t, const char *);
 static int viewEntryCompare(const void *, const void *);
 static void deleteNonActiveLus();
 
@@ -2349,6 +2352,256 @@
 	return (ret);
 }
 
+/*
+ * stmfGetGlobalLuProp
+ *
+ * Purpose: get a global property for a device type
+ *
+ */
+int
+stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal,
+    size_t *propLen)
+{
+	int ret = STMF_STATUS_SUCCESS;
+	if (dType != STMF_DISK || propVal == NULL) {
+		return (STMF_ERROR_INVALID_ARG);
+	}
+
+	ret = getDiskGlobalProp(prop, propVal, propLen);
+
+	return (ret);
+}
+
+/*
+ * getDiskGlobalProp
+ *
+ * Purpose: get global property from sbd driver
+ *
+ */
+static int
+getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen)
+{
+	int ret = STMF_STATUS_SUCCESS;
+	int fd;
+	sbd_global_props_t *sbdProps;
+	void *sbd_realloc;
+	int retryCnt = 0;
+	boolean_t retry;
+	int ioctlRet;
+	int savedErrno;
+	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
+	stmf_iocdata_t sbdIoctl = {0};
+	size_t reqLen;
+
+	switch (prop) {
+		case STMF_LU_PROP_MGMT_URL:
+			break;
+		default:
+			return (STMF_ERROR_INVALID_PROP);
+	}
+
+	/*
+	 * Open control node for sbd
+	 */
+	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
+		return (ret);
+
+	sbdProps = calloc(1, sbdPropsSize);
+	if (sbdProps == NULL) {
+		(void) close(fd);
+		return (STMF_ERROR_NOMEM);
+	}
+
+	do {
+		retry = B_FALSE;
+		sbdIoctl.stmf_version = STMF_VERSION_1;
+		sbdIoctl.stmf_obuf_size = sbdPropsSize;
+		sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
+		ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl);
+		if (ioctlRet != 0) {
+			savedErrno = errno;
+			switch (savedErrno) {
+				case EBUSY:
+					ret = STMF_ERROR_BUSY;
+					break;
+				case EPERM:
+				case EACCES:
+					ret = STMF_ERROR_PERM;
+					break;
+				case ENOMEM:
+					if (sbdIoctl.stmf_error ==
+					    SBD_RET_INSUFFICIENT_BUF_SPACE &&
+					    retryCnt++ < 3) {
+						sbdPropsSize =
+						    sizeof (*sbdProps) +
+						    sbdProps->
+						    mlu_buf_size_needed;
+
+						sbd_realloc = sbdProps;
+						sbdProps = realloc(sbdProps,
+						    sbdPropsSize);
+						if (sbdProps == NULL) {
+							free(sbd_realloc);
+							ret = STMF_ERROR_NOMEM;
+							break;
+						}
+						retry = B_TRUE;
+					} else {
+						ret = STMF_ERROR_NOMEM;
+					}
+					break;
+				default:
+					syslog(LOG_DEBUG,
+					    "getDiskGlobalProp:ioctl error(%d)"
+					    "(%d)(%d)", ioctlRet,
+					    sbdIoctl.stmf_error, savedErrno);
+					ret = STMF_STATUS_ERROR;
+					break;
+			}
+
+		}
+	} while (retry);
+
+	if (ret != STMF_STATUS_SUCCESS) {
+		goto done;
+	}
+
+	switch (prop) {
+		case STMF_LU_PROP_MGMT_URL:
+			if (sbdProps->mlu_mgmt_url_valid == 0) {
+				ret = STMF_ERROR_NO_PROP;
+				goto done;
+			}
+			if ((reqLen = strlcpy(propVal, (char *)&(
+			    sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]),
+			    *propLen)) >= *propLen) {
+				*propLen = reqLen + 1;
+				ret = STMF_ERROR_INVALID_ARG;
+				goto done;
+			}
+			break;
+	}
+
+done:
+	free(sbdProps);
+	(void) close(fd);
+	return (ret);
+}
+
+/*
+ * stmfSetGlobalLuProp
+ *
+ * Purpose: set a global property for a device type
+ *
+ */
+int
+stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal)
+{
+	int ret = STMF_STATUS_SUCCESS;
+	if (dType != STMF_DISK || propVal == NULL) {
+		return (STMF_ERROR_INVALID_ARG);
+	}
+
+	ret = setDiskGlobalProp(prop, propVal);
+
+	return (ret);
+}
+
+/*
+ * setDiskGlobalProp
+ *
+ * Purpose: set properties for resource of type disk
+ *
+ * resourceProp - valid resource identifier
+ * propVal - valid resource value
+ */
+static int
+setDiskGlobalProp(uint32_t resourceProp, const char *propVal)
+{
+	int ret = STMF_STATUS_SUCCESS;
+	sbd_global_props_t *sbdGlobalProps = NULL;
+	int sbdGlobalPropsSize = 0;
+	int propLen;
+	int mluBufSize = 0;
+	int fd;
+	int savedErrno;
+	int ioctlRet;
+	stmf_iocdata_t sbdIoctl = {0};
+
+	switch (resourceProp) {
+		case STMF_LU_PROP_MGMT_URL:
+			break;
+		default:
+			return (STMF_ERROR_INVALID_PROP);
+			break;
+	}
+
+	/*
+	 * Open control node for sbd
+	 */
+	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
+		return (ret);
+
+	propLen = strlen(propVal);
+	mluBufSize += propLen + 1;
+	sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 +
+	    max(8, mluBufSize);
+	/*
+	 * 8 is the size of the buffer set aside for
+	 * concatenation of variable length fields
+	 */
+	sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize);
+	if (sbdGlobalProps == NULL) {
+		(void) close(fd);
+		return (STMF_ERROR_NOMEM);
+	}
+
+	sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize;
+
+	switch (resourceProp) {
+		case STMF_LU_PROP_MGMT_URL:
+			sbdGlobalProps->mlu_mgmt_url_valid = 1;
+			bcopy(propVal, &(sbdGlobalProps->mlu_buf),
+			    propLen + 1);
+			break;
+		default:
+			ret = STMF_ERROR_NO_PROP;
+			goto done;
+	}
+
+	sbdIoctl.stmf_version = STMF_VERSION_1;
+	sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size;
+	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps;
+
+	ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl);
+	if (ioctlRet != 0) {
+		savedErrno = errno;
+		switch (savedErrno) {
+			case EBUSY:
+				ret = STMF_ERROR_BUSY;
+				break;
+			case EPERM:
+			case EACCES:
+				ret = STMF_ERROR_PERM;
+				break;
+			default:
+				diskError(sbdIoctl.stmf_error, &ret);
+				if (ret == STMF_STATUS_ERROR) {
+					syslog(LOG_DEBUG,
+					"modifyDiskLu:ioctl "
+					"error(%d) (%d) (%d)", ioctlRet,
+					    sbdIoctl.stmf_error, savedErrno);
+				}
+				break;
+		}
+	}
+
+done:
+	free(sbdGlobalProps);
+	(void) close(fd);
+	return (ret);
+}
+
 
 /*
  * stmfSetLuProp
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c	Thu Nov 19 05:07:17 2009 -0800
@@ -77,6 +77,10 @@
 int sbd_import_active_lu(sbd_import_lu_t *ilu, sbd_lu_t *sl, uint32_t *err_ret);
 int sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret);
 int sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret);
+int sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz,
+    uint32_t *err_ret);
+int sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz,
+    uint32_t *err_ret);
 int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
     sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret);
 char *sbd_get_zvol_name(sbd_lu_t *sl);
@@ -98,9 +102,15 @@
 static kmutex_t		sbd_lock;
 static dev_info_t	*sbd_dip;
 static uint32_t		sbd_lu_count = 0;
+
+/* Global property settings for the logical unit */
 char sbd_vendor_id[]	= "SUN     ";
 char sbd_product_id[]	= "COMSTAR         ";
 char sbd_revision[]	= "1.0 ";
+char *sbd_mgmt_url = NULL;
+uint16_t sbd_mgmt_url_alloc_size = 0;
+krwlock_t sbd_global_prop_lock;
+
 static char sbd_name[] = "sbd";
 
 static struct cb_ops sbd_cb_ops = {
@@ -176,6 +186,7 @@
 		return (EINVAL);
 	}
 	mutex_init(&sbd_lock, NULL, MUTEX_DRIVER, NULL);
+	rw_init(&sbd_global_prop_lock, NULL, RW_DRIVER, NULL);
 	return (0);
 }
 
@@ -222,6 +233,7 @@
 	}
 	stmf_free(sbd_lp);
 	mutex_destroy(&sbd_lock);
+	rw_destroy(&sbd_global_prop_lock);
 	ldi_ident_release(sbd_zfs_ident);
 	return (0);
 }
@@ -384,6 +396,30 @@
 		ret = sbd_modify_lu((sbd_modify_lu_t *)ibuf,
 		    iocd->stmf_ibuf_size, &iocd->stmf_error);
 		break;
+	case SBD_IOCTL_SET_GLOBAL_LU:
+		if (iocd->stmf_ibuf_size < (sizeof (sbd_global_props_t) - 8)) {
+			ret = EFAULT;
+			break;
+		}
+		if (iocd->stmf_obuf_size) {
+			ret = EINVAL;
+			break;
+		}
+		ret = sbd_set_global_props((sbd_global_props_t *)ibuf,
+		    iocd->stmf_ibuf_size, &iocd->stmf_error);
+		break;
+	case SBD_IOCTL_GET_GLOBAL_LU:
+		if (iocd->stmf_ibuf_size) {
+			ret = EINVAL;
+			break;
+		}
+		if (iocd->stmf_obuf_size < sizeof (sbd_global_props_t)) {
+			ret = EINVAL;
+			break;
+		}
+		ret = sbd_get_global_props((sbd_global_props_t *)obuf,
+		    iocd->stmf_obuf_size, &iocd->stmf_error);
+		break;
 	case SBD_IOCTL_GET_LU_PROPS:
 		if (iocd->stmf_ibuf_size < (sizeof (sbd_lu_props_t) - 8)) {
 			ret = EFAULT;
@@ -2743,6 +2779,74 @@
 	return (ret);
 }
 
+int
+sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz,
+    uint32_t *err_ret)
+{
+	sbd_lu_t *sl = NULL;
+	int ret = 0;
+	sbd_it_data_t *it;
+	uint32_t sz;
+
+	sz = struct_sz - sizeof (*mlu) + 8 + 1;
+
+	/* if there is data in the buf, null terminate it */
+	if (struct_sz > sizeof (*mlu)) {
+		mlu->mlu_buf[struct_sz - sizeof (*mlu) + 8 - 1] = 0;
+	}
+
+	*err_ret = 0;
+
+	/* Lets validate offsets */
+	if (((mlu->mlu_mgmt_url_valid) &&
+	    (mlu->mlu_mgmt_url_off >= sz))) {
+		return (EINVAL);
+	}
+
+	if (mlu->mlu_mgmt_url_valid) {
+		uint16_t url_sz;
+
+		url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off);
+		if (url_sz > 0)
+			url_sz++;
+
+		rw_enter(&sbd_global_prop_lock, RW_WRITER);
+		if (sbd_mgmt_url_alloc_size > 0 &&
+		    (url_sz == 0 || sbd_mgmt_url_alloc_size < url_sz)) {
+			kmem_free(sbd_mgmt_url, sbd_mgmt_url_alloc_size);
+			sbd_mgmt_url = NULL;
+			sbd_mgmt_url_alloc_size = 0;
+		}
+		if (url_sz > 0) {
+			if (sbd_mgmt_url_alloc_size == 0) {
+				sbd_mgmt_url = kmem_alloc(url_sz, KM_SLEEP);
+				sbd_mgmt_url_alloc_size = url_sz;
+			}
+			(void) strcpy(sbd_mgmt_url, (char *)mlu->mlu_buf +
+			    mlu->mlu_mgmt_url_off);
+		}
+		/*
+		 * check each lu to determine whether a UA is needed.
+		 */
+		mutex_enter(&sbd_lock);
+		for (sl = sbd_lu_list; sl; sl = sl->sl_next) {
+			if (sl->sl_mgmt_url) {
+				continue;
+			}
+			mutex_enter(&sl->sl_lock);
+			for (it = sl->sl_it_list; it != NULL;
+			    it = it->sbd_it_next) {
+				it->sbd_it_ua_conditions |=
+				    SBD_UA_MODE_PARAMETERS_CHANGED;
+			}
+			mutex_exit(&sl->sl_lock);
+		}
+		mutex_exit(&sbd_lock);
+		rw_exit(&sbd_global_prop_lock);
+	}
+	return (ret);
+}
+
 /* ARGSUSED */
 int
 sbd_delete_locked_lu(sbd_lu_t *sl, uint32_t *err_ret,
@@ -2946,6 +3050,38 @@
 }
 
 int
+sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz,
+    uint32_t *err_ret)
+{
+	uint32_t sz = 0;
+	uint16_t off;
+
+	rw_enter(&sbd_global_prop_lock, RW_READER);
+	if (sbd_mgmt_url) {
+		sz += strlen(sbd_mgmt_url) + 1;
+	}
+	bzero(oslp, sizeof (*oslp) - 8);
+	oslp->mlu_buf_size_needed = sz;
+
+	if (sz > (oslp_sz - sizeof (*oslp) + 8)) {
+		*err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE;
+		rw_exit(&sbd_global_prop_lock);
+		return (ENOMEM);
+	}
+
+	off = 0;
+	if (sbd_mgmt_url) {
+		oslp->mlu_mgmt_url_valid = 1;
+		oslp->mlu_mgmt_url_off = off;
+		(void) strcpy((char *)&oslp->mlu_buf[off], sbd_mgmt_url);
+		off += strlen(sbd_mgmt_url) + 1;
+	}
+
+	rw_exit(&sbd_global_prop_lock);
+	return (0);
+}
+
+int
 sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
     sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret)
 {
@@ -2984,8 +3120,11 @@
 		sz += strlen(sl->sl_alias) + 1;
 	}
 
+	rw_enter(&sbd_global_prop_lock, RW_READER);
 	if (sl->sl_mgmt_url) {
 		sz += strlen(sl->sl_mgmt_url) + 1;
+	} else if (sbd_mgmt_url) {
+		sz += strlen(sbd_mgmt_url) + 1;
 	}
 	bzero(oslp, sizeof (*oslp) - 8);
 	oslp->slp_buf_size_needed = sz;
@@ -2993,6 +3132,7 @@
 	if (sz > (oslp_sz - sizeof (*oslp) + 8)) {
 		sl->sl_trans_op = SL_OP_NONE;
 		*err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE;
+		rw_exit(&sbd_global_prop_lock);
 		return (ENOMEM);
 	}
 
@@ -3028,6 +3168,11 @@
 		oslp->slp_mgmt_url_off = off;
 		(void) strcpy((char *)&oslp->slp_buf[off], sl->sl_mgmt_url);
 		off += strlen(sl->sl_mgmt_url) + 1;
+	} else if (sbd_mgmt_url) {
+		oslp->slp_mgmt_url_valid = 1;
+		oslp->slp_mgmt_url_off = off;
+		(void) strcpy((char *)&oslp->slp_buf[off], sbd_mgmt_url);
+		off += strlen(sbd_mgmt_url) + 1;
 	}
 	if (sl->sl_serial_no_size) {
 		oslp->slp_serial_off = off;
@@ -3072,6 +3217,7 @@
 
 	sl->sl_trans_op = SL_OP_NONE;
 
+	rw_exit(&sbd_global_prop_lock);
 	return (0);
 }
 
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c	Thu Nov 19 05:07:17 2009 -0800
@@ -1138,6 +1138,7 @@
 	uint16_t cmd_size;
 	uint32_t xfer_size = 4;
 	uint32_t mgmt_url_size = 0;
+	char *mgmt_url = NULL;
 
 
 	byte0 = DTYPE_DIRECT;
@@ -1168,10 +1169,6 @@
 		return;
 	}
 
-	if (sl->sl_mgmt_url) {
-		mgmt_url_size = strlen(sl->sl_mgmt_url);
-	}
-
 	/*
 	 * Standard inquiry
 	 */
@@ -1270,6 +1267,15 @@
 		return;
 	}
 
+	rw_enter(&sbd_global_prop_lock, RW_READER);
+	if (sl->sl_mgmt_url) {
+		mgmt_url_size = strlen(sl->sl_mgmt_url);
+		mgmt_url = sl->sl_mgmt_url;
+	} else if (sbd_mgmt_url) {
+		mgmt_url_size = strlen(sbd_mgmt_url);
+		mgmt_url = sbd_mgmt_url;
+	}
+
 	/*
 	 * EVPD handling
 	 */
@@ -1325,8 +1331,7 @@
 		if (mgmt_url_size == 0) {
 			stmf_scsilib_send_status(task, STATUS_CHECK,
 			    STMF_SAA_INVALID_FIELD_IN_CDB);
-			kmem_free(p, bsize);
-			return;
+			goto err_done;
 		}
 		{
 			uint16_t idx, newidx, sz, url_size;
@@ -1336,7 +1341,7 @@
 			p[1] = 0x85;
 
 			idx = 4;
-			url = sl->sl_mgmt_url;
+			url = mgmt_url;
 			url_size = sbd_parse_mgmt_url(&url);
 			/* Creating Network Service Descriptors */
 			while (url_size != 0) {
@@ -1390,13 +1395,14 @@
 	default:
 		stmf_scsilib_send_status(task, STATUS_CHECK,
 		    STMF_SAA_INVALID_FIELD_IN_CDB);
-		kmem_free(p, bsize);
-		return;
+		goto err_done;
 	}
 
 	sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
 	    min(cmd_size, xfer_size));
+err_done:
 	kmem_free(p, bsize);
+	rw_exit(&sbd_global_prop_lock);
 }
 
 stmf_status_t
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h	Thu Nov 19 05:07:17 2009 -0800
@@ -34,6 +34,10 @@
 extern char sbd_vendor_id[];
 extern char sbd_product_id[];
 extern char sbd_revision[];
+extern char *sbd_mgmt_url;
+extern uint16_t sbd_mgmt_url_alloc_size;
+extern krwlock_t sbd_global_prop_lock;
+
 /*
  * Error codes
  */
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/uts/common/io/comstar/stmf/stmf.c	Thu Nov 19 05:07:17 2009 -0800
@@ -5481,7 +5481,9 @@
 	case TM_LUN_RESET:
 		stmf_handle_lun_reset(task);
 		/* issue the reset to the proxy node as well */
-		(void) stmf_proxy_scsi_cmd(task, NULL);
+		if (stmf_state.stmf_alua_state == 1) {
+			(void) stmf_proxy_scsi_cmd(task, NULL);
+		}
 		return;
 	case TM_TARGET_RESET:
 	case TM_TARGET_COLD_RESET:
--- a/usr/src/uts/common/sys/stmf_sbd_ioctl.h	Thu Nov 19 15:28:11 2009 +1100
+++ b/usr/src/uts/common/sys/stmf_sbd_ioctl.h	Thu Nov 19 05:07:17 2009 -0800
@@ -74,6 +74,8 @@
 #define	SBD_IOCTL_GET_LU_PROPS				SBD_IOCTL_DEF(5)
 #define	SBD_IOCTL_GET_LU_LIST				SBD_IOCTL_DEF(6)
 #define	SBD_IOCTL_SET_LU_STANDBY			SBD_IOCTL_DEF(7)
+#define	SBD_IOCTL_SET_GLOBAL_LU				SBD_IOCTL_DEF(8)
+#define	SBD_IOCTL_GET_GLOBAL_LU				SBD_IOCTL_DEF(9)
 
 typedef struct sbd_create_and_reg_lu {
 	uint32_t	slu_struct_size;
@@ -110,6 +112,29 @@
 	char		slu_buf[8];	/* likely more than 8 */
 } sbd_create_and_reg_lu_t;
 
+typedef struct sbd_global_props {
+	uint32_t	mlu_struct_size;
+	uint32_t	mlu_vid_valid:1,
+			mlu_pid_valid:1,
+			mlu_rev_valid:1,
+			mlu_serial_valid:1,
+			mlu_mgmt_url_valid:1,
+			mlu_company_id_valid:1,
+			mlu_host_id_valid:1;
+	uint16_t	mlu_serial_off;
+	uint8_t		mlu_serial_size;
+	uint8_t		mlu_rsvd1;
+	uint32_t	mlu_company_id;
+	uint16_t	mlu_mgmt_url_off;
+	uint16_t	rsvd1;
+	uint32_t	mlu_host_id;
+	uint32_t	mlu_buf_size_needed;
+	char		mlu_rev[4];
+	char		mlu_vid[8];
+	char		mlu_pid[16];
+	char		mlu_buf[8];	/* likely more than 8 */
+} sbd_global_props_t;
+
 typedef struct sbd_set_lu_standby {
 	uint8_t		stlu_guid[16];
 } sbd_set_lu_standby_t;