changeset 10522:c355ff626865

6867300 COMSTAR: panic[cpu1]/thread=ffffff415d18e760: assertion failed: tgt->target_state == TS_DELETING
author Peter Cudhea - Sun Microsystems - Burlington, MA United States <Peter.Cudhea@Sun.COM>
date Mon, 14 Sep 2009 15:04:57 -0400
parents 1eaab2a76b85
children c595f961c3f7
files usr/src/uts/common/io/comstar/port/iscsit/iscsit.c usr/src/uts/common/io/comstar/port/iscsit/iscsit_tgt.c
diffstat 2 files changed, 46 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit.c	Mon Sep 14 12:46:21 2009 -0600
+++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit.c	Mon Sep 14 15:04:57 2009 -0400
@@ -373,10 +373,9 @@
 {
 	iscsit_ioc_set_config_t		setcfg;
 	iscsit_ioc_set_config32_t	setcfg32;
-	/* iscsit_ioc_get_config_t	getcfg; */
-	char				*cfg_pnvlist;
-	nvlist_t			*cfg_nvlist;
-	it_config_t			*cfg;
+	char				*cfg_pnvlist = NULL;
+	nvlist_t			*cfg_nvlist = NULL;
+	it_config_t			*cfg = NULL;
 	idm_status_t			idmrc;
 	int				rc = 0;
 
@@ -429,11 +428,14 @@
 	/* Handle ioctl request (enable/disable have already been handled) */
 	switch (cmd) {
 	case ISCSIT_IOC_SET_CONFIG:
+		/* Any errors must set state back to ISE_ENABLED */
 		switch (ddi_model_convert_from(flag & FMODELS)) {
 		case DDI_MODEL_ILP32:
 			if (ddi_copyin((void *)argp, &setcfg32,
-			    sizeof (iscsit_ioc_set_config32_t), flag) != 0)
-				return (EFAULT);
+			    sizeof (iscsit_ioc_set_config32_t), flag) != 0) {
+				rc = EFAULT;
+				goto cleanup;
+			}
 
 			setcfg.set_cfg_pnvlist =
 			    (char *)((uintptr_t)setcfg32.set_cfg_pnvlist);
@@ -443,14 +445,17 @@
 			break;
 		case DDI_MODEL_NONE:
 			if (ddi_copyin((void *)argp, &setcfg,
-			    sizeof (iscsit_ioc_set_config_t), flag) != 0)
-				return (EFAULT);
+			    sizeof (iscsit_ioc_set_config_t), flag) != 0) {
+				rc = EFAULT;
+				goto cleanup;
+			}
 			break;
 		}
 
 		/* Check API version */
 		if (setcfg.set_cfg_vers != ISCSIT_API_VERS0) {
-			return (EINVAL);
+			rc = EINVAL;
+			goto cleanup;
 		}
 
 		/* Config is in packed nvlist format so unpack it */
@@ -460,34 +465,34 @@
 
 		if (ddi_copyin(setcfg.set_cfg_pnvlist, cfg_pnvlist,
 		    setcfg.set_cfg_pnvlist_len, flag) != 0) {
-			kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
-			return (EFAULT);
+			rc = EFAULT;
+			goto cleanup;
 		}
 
-		if (nvlist_unpack(cfg_pnvlist, setcfg.set_cfg_pnvlist_len,
-		    &cfg_nvlist, KM_SLEEP) != 0) {
-			kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
-			return (EINVAL);
+		rc = nvlist_unpack(cfg_pnvlist, setcfg.set_cfg_pnvlist_len,
+		    &cfg_nvlist, KM_SLEEP);
+		if (rc != 0) {
+			goto cleanup;
 		}
 
 		/* Translate nvlist */
-		if (it_nv_to_config(cfg_nvlist, &cfg) != 0) {
+		rc = it_nv_to_config(cfg_nvlist, &cfg);
+		if (rc != 0) {
 			cmn_err(CE_WARN, "Configuration is invalid");
-			kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
-			nvlist_free(cfg_nvlist);
-			return (EINVAL);
+			goto cleanup;
 		}
 
 		/* Update config */
-		if (iscsit_config_merge(cfg) != 0) {
+		rc = iscsit_config_merge(cfg);
+		/* FALLTHROUGH */
+
+cleanup:
+		if (cfg)
+			it_config_free_cmn(cfg);
+		if (cfg_pnvlist)
 			kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
+		if (cfg_nvlist)
 			nvlist_free(cfg_nvlist);
-			return (EIO);
-		}
-
-		it_config_free_cmn(cfg);
-		kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
-		nvlist_free(cfg_nvlist);
 
 		/*
 		 * Now that the reconfig is complete set our state back to
@@ -533,13 +538,14 @@
 		iscsit_global.global_svc_state = ISE_DISABLED;
 		ISCSIT_GLOBAL_UNLOCK();
 		break;
+
 	default:
 		rc = EINVAL;
+		ISCSIT_GLOBAL_LOCK(RW_WRITER);
+		iscsit_global.global_svc_state = ISE_ENABLED;
+		ISCSIT_GLOBAL_UNLOCK();
 	}
 
-	/* Don't forget to clear ISE_BUSY state */
-	ASSERT(iscsit_global.global_svc_state != ISE_BUSY);
-
 	return (rc);
 }
 
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_tgt.c	Mon Sep 14 12:46:21 2009 -0600
+++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_tgt.c	Mon Sep 14 15:04:57 2009 -0400
@@ -904,6 +904,13 @@
 	result->target_stmf_lport = lport;
 
 	/*
+	 * We need a global hold until the STMF-ONLINE state machine
+	 * completes.  Acquire that hold now, in case we need to call
+	 * iscsit_tgt_destroy, which will also release the hold.
+	 */
+	iscsit_global_hold();
+
+	/*
 	 * Additional target modifications from config
 	 */
 	if (iscsit_tgt_modify(result, cfg_tgt) != IDM_STATUS_SUCCESS) {
@@ -922,8 +929,6 @@
 	}
 	result->target_stmf_lport_registered = 1;
 
-	iscsit_global_hold();
-
 	return (result);
 }
 
@@ -1009,7 +1014,9 @@
 {
 	iscsit_tpgt_t *tpgt, *next_tpgt;
 
-	ASSERT(tgt->target_state == TS_DELETING);
+	ASSERT(tgt->target_state == TS_DELETING ||
+	    (tgt->target_state == TS_CREATED &&
+	    tgt->target_stmf_lport_registered == 0));
 
 	/*
 	 * Destroy all target portal group tags
@@ -1912,7 +1919,7 @@
 idm_status_t
 iscsit_portal_online(iscsit_portal_t *portal)
 {
-	idm_status_t rc;
+	idm_status_t rc = 0;
 	idm_svc_t	*svc;
 	idm_svc_req_t	sr;
 	uint16_t	port;