changeset 11698:5f3c2d3ccd7b

6859995 stmfadm does not return error messages if an online operation fails 6919371 Need error code for failed target port online/offline when target is busy
author Nattuvetty Bhavyan <Nattuvetty.Bhavyan@Sun.COM>
date Thu, 18 Feb 2010 18:57:27 -0800
parents 46111b6bb577
children 7c68095b05ac
files usr/src/cmd/stmfadm/stmfadm.c usr/src/uts/common/io/comstar/stmf/stmf.c usr/src/uts/common/sys/stmf_defines.h
diffstat 3 files changed, 175 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/stmfadm/stmfadm.c	Fri Feb 19 09:52:30 2010 +0800
+++ b/usr/src/cmd/stmfadm/stmfadm.c	Thu Feb 18 18:57:27 2010 -0800
@@ -105,6 +105,8 @@
 #define	VIEW_FORMAT		    "    %-13s: "
 #define	LVL3_FORMAT		    "        %s"
 #define	LVL4_FORMAT		    "            %s"
+#define	DELAYED_EXEC_WAIT_INTERVAL  300 * 1000 * 1000	/* in nano sec */
+#define	DELAYED_EXEC_WAIT_MAX	    30	/* Maximum number of interval times */
 
 /* SCSI Name String length definitions */
 #define	SNS_EUI_16		    16
@@ -129,6 +131,9 @@
 #define	MGMT_URL		    "MGMT-URL"
 #define	HOST_ID			    "HOST-ID"
 
+#define	STMFADM_SUCCESS		    0
+#define	STMFADM_FAILURE		    1
+
 #define	MODIFY_HELP "\n"\
 "Description: Modify properties of a logical unit. \n" \
 "Valid properties for -p, --lu-prop are: \n" \
@@ -2825,7 +2830,8 @@
 	stmfGuid inGuid;
 	unsigned int guid[sizeof (stmfGuid)];
 	int i;
-	int ret = 0;
+	int ret = 0, stmfRet;
+	stmfLogicalUnitProperties luProps;
 
 	if (strlen(lu) != GUID_INPUT) {
 		(void) fprintf(stderr, "%s: %s: %s %d %s\n", cmdName, lu,
@@ -2853,6 +2859,8 @@
 		ret = stmfOnlineLogicalUnit(&inGuid);
 	} else if (state == OFFLINE_LU) {
 		ret = stmfOfflineLogicalUnit(&inGuid);
+	} else {
+		return (STMFADM_FAILURE);
 	}
 	if (ret != STMF_STATUS_SUCCESS) {
 		switch (ret) {
@@ -2864,6 +2872,10 @@
 				(void) fprintf(stderr, "%s: %s\n", cmdName,
 				    gettext("STMF service not found"));
 				break;
+			case STMF_ERROR_BUSY:
+				(void) fprintf(stderr, "%s: %s\n", cmdName,
+				    gettext("resource busy"));
+				break;
 			case STMF_ERROR_NOT_FOUND:
 				(void) fprintf(stderr, "%s: %s: %s\n", cmdName,
 				    lu, gettext("not found"));
@@ -2877,8 +2889,45 @@
 				    gettext("unknown error"));
 				break;
 		}
+	} else {
+		struct timespec	ts = {0};
+		unsigned int	count = 0;
+		uint32_t	ret_state;
+
+		ret_state = (state == ONLINE_LU) ?
+		    STMF_LOGICAL_UNIT_ONLINING : STMF_LOGICAL_UNIT_OFFLINING;
+		ts.tv_nsec = DELAYED_EXEC_WAIT_INTERVAL;
+
+		/* CONSTCOND */
+		while (1) {
+			stmfRet = stmfGetLogicalUnitProperties(&inGuid,
+			    &luProps);
+			if (stmfRet == STMF_STATUS_SUCCESS)
+				ret_state = luProps.status;
+
+			if ((state == ONLINE_LU &&
+			    ret_state == STMF_LOGICAL_UNIT_ONLINE) ||
+			    (state == OFFLINE_LU &&
+			    ret_state == STMF_LOGICAL_UNIT_OFFLINE))
+				return (STMFADM_SUCCESS);
+
+			if ((state == ONLINE_LU &&
+			    ret_state == STMF_LOGICAL_UNIT_OFFLINE) ||
+			    (state == OFFLINE_LU &&
+			    ret_state == STMF_LOGICAL_UNIT_ONLINE))
+				return (STMFADM_FAILURE);
+
+			if (++count ==  DELAYED_EXEC_WAIT_MAX) {
+				(void) fprintf(stderr, "%s: %s\n", cmdName,
+				    gettext("Logical Unit state change request "
+				    "submitted. Waiting for completion "
+				    "timed out"));
+				return (STMFADM_FAILURE);
+			}
+			(void) nanosleep(&ts, NULL);
+		}
 	}
-	return (ret);
+	return (STMFADM_FAILURE);
 }
 
 /*
@@ -2934,8 +2983,9 @@
 static int
 onlineOfflineTarget(char *target, int state)
 {
-	int ret = 0;
+	int ret = 0, stmfRet = 0;
 	stmfDevid devid;
+	stmfTargetProperties targetProps;
 
 	if (parseDevid(target, &devid) != 0) {
 		(void) fprintf(stderr, "%s: %s: %s\n",
@@ -2946,6 +2996,8 @@
 		ret = stmfOnlineTarget(&devid);
 	} else if (state == OFFLINE_TARGET) {
 		ret = stmfOfflineTarget(&devid);
+	} else {
+		return (STMFADM_FAILURE);
 	}
 	if (ret != STMF_STATUS_SUCCESS) {
 		switch (ret) {
@@ -2957,6 +3009,10 @@
 				(void) fprintf(stderr, "%s: %s\n", cmdName,
 				    gettext("STMF service not found"));
 				break;
+			case STMF_ERROR_BUSY:
+				(void) fprintf(stderr, "%s: %s\n", cmdName,
+				    gettext("resource busy"));
+				break;
 			case STMF_ERROR_NOT_FOUND:
 				(void) fprintf(stderr, "%s: %s: %s\n", cmdName,
 				    target, gettext("not found"));
@@ -2970,8 +3026,46 @@
 				    gettext("unknown error"));
 				break;
 		}
+	} else {
+		struct timespec  ts = {0};
+		unsigned int count = 0;
+		uint32_t	ret_state;
+
+		ret_state = (state == ONLINE_TARGET) ?
+		    STMF_TARGET_PORT_ONLINING : STMF_TARGET_PORT_OFFLINING;
+		ts.tv_nsec = DELAYED_EXEC_WAIT_INTERVAL;
+
+		/* CONSTCOND */
+		while (1) {
+			stmfRet = stmfGetTargetProperties(&devid, &targetProps);
+			if (stmfRet == STMF_STATUS_SUCCESS)
+				ret_state = targetProps.status;
+
+			if ((state == ONLINE_TARGET &&
+			    ret_state == STMF_TARGET_PORT_ONLINE) ||
+			    (state == OFFLINE_TARGET &&
+			    ret_state == STMF_TARGET_PORT_OFFLINE)) {
+				return (STMFADM_SUCCESS);
+			}
+
+			if ((state == ONLINE_TARGET &&
+			    ret_state == STMF_TARGET_PORT_OFFLINE) ||
+			    (state == OFFLINE_TARGET &&
+			    ret_state == STMF_TARGET_PORT_ONLINE)) {
+				return (STMFADM_FAILURE);
+			}
+
+			if (++count ==  DELAYED_EXEC_WAIT_MAX) {
+				(void) fprintf(stderr, "%s: %s\n", cmdName,
+				    gettext("Target state change request "
+				    "submitted. Waiting for completion "
+				    "timed out."));
+				return (STMFADM_FAILURE);
+			}
+			(void) nanosleep(&ts, NULL);
+		}
 	}
-	return (ret);
+	return (STMFADM_FAILURE);
 }
 
 /*
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c	Fri Feb 19 09:52:30 2010 +0800
+++ b/usr/src/uts/common/io/comstar/stmf/stmf.c	Thu Feb 18 18:57:27 2010 -0800
@@ -770,6 +770,8 @@
 		ctl_ret = stmf_ctl(cmd, (void *)ilu->ilu_lu, &ssi);
 		if (ctl_ret == STMF_ALREADY)
 			ret = 0;
+		else if (ctl_ret == STMF_BUSY)
+			ret = EBUSY;
 		else if (ctl_ret != STMF_SUCCESS)
 			ret = EIO;
 		mutex_enter(&stmf_state.stmf_lock);
@@ -814,6 +816,8 @@
 		ctl_ret = stmf_ctl(cmd, (void *)ilport->ilport_lport, &ssi);
 		if (ctl_ret == STMF_ALREADY)
 			ret = 0;
+		else if (ctl_ret == STMF_BUSY)
+			ret = EBUSY;
 		else if (ctl_ret != STMF_SUCCESS)
 			ret = EIO;
 		mutex_enter(&stmf_state.stmf_lock);
@@ -4874,15 +4878,24 @@
 
 	switch (cmd) {
 	case STMF_CMD_LU_ONLINE:
-		if ((ilu->ilu_state == STMF_STATE_ONLINE) ||
-		    (ilu->ilu_state == STMF_STATE_ONLINING)) {
-			ret = STMF_ALREADY;
+		switch (ilu->ilu_state) {
+			case STMF_STATE_OFFLINE:
+				ret = STMF_SUCCESS;
+				break;
+			case STMF_STATE_ONLINE:
+			case STMF_STATE_ONLINING:
+				ret = STMF_ALREADY;
+				break;
+			case STMF_STATE_OFFLINING:
+				ret = STMF_BUSY;
+				break;
+			default:
+				ret = STMF_BADSTATE;
+				break;
+		}
+		if (ret != STMF_SUCCESS)
 			goto stmf_ctl_lock_exit;
-		}
-		if (ilu->ilu_state != STMF_STATE_OFFLINE) {
-			ret = STMF_INVALID_ARG;
-			goto stmf_ctl_lock_exit;
-		}
+
 		ilu->ilu_state = STMF_STATE_ONLINING;
 		mutex_exit(&stmf_state.stmf_lock);
 		stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
@@ -4890,7 +4903,7 @@
 
 	case STMF_CMD_LU_ONLINE_COMPLETE:
 		if (ilu->ilu_state != STMF_STATE_ONLINING) {
-			ret = STMF_INVALID_ARG;
+			ret = STMF_BADSTATE;
 			goto stmf_ctl_lock_exit;
 		}
 		if (((stmf_change_status_t *)arg)->st_completion_status ==
@@ -4909,15 +4922,23 @@
 		goto stmf_ctl_lock_exit;
 
 	case STMF_CMD_LU_OFFLINE:
-		if ((ilu->ilu_state == STMF_STATE_OFFLINE) ||
-		    (ilu->ilu_state == STMF_STATE_OFFLINING)) {
-			ret = STMF_ALREADY;
+		switch (ilu->ilu_state) {
+			case STMF_STATE_ONLINE:
+				ret = STMF_SUCCESS;
+				break;
+			case STMF_STATE_OFFLINE:
+			case STMF_STATE_OFFLINING:
+				ret = STMF_ALREADY;
+				break;
+			case STMF_STATE_ONLINING:
+				ret = STMF_BUSY;
+				break;
+			default:
+				ret = STMF_BADSTATE;
+				break;
+		}
+		if (ret != STMF_SUCCESS)
 			goto stmf_ctl_lock_exit;
-		}
-		if (ilu->ilu_state != STMF_STATE_ONLINE) {
-			ret = STMF_INVALID_ARG;
-			goto stmf_ctl_lock_exit;
-		}
 		ilu->ilu_state = STMF_STATE_OFFLINING;
 		mutex_exit(&stmf_state.stmf_lock);
 		stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
@@ -4925,7 +4946,7 @@
 
 	case STMF_CMD_LU_OFFLINE_COMPLETE:
 		if (ilu->ilu_state != STMF_STATE_OFFLINING) {
-			ret = STMF_INVALID_ARG;
+			ret = STMF_BADSTATE;
 			goto stmf_ctl_lock_exit;
 		}
 		if (((stmf_change_status_t *)arg)->st_completion_status ==
@@ -4947,14 +4968,23 @@
 	 * It's related with hardware disable/enable.
 	 */
 	case STMF_CMD_LPORT_ONLINE:
-		if (ilport->ilport_state == STMF_STATE_ONLINE) {
-			ret = STMF_ALREADY;
+		switch (ilport->ilport_state) {
+			case STMF_STATE_OFFLINE:
+				ret = STMF_SUCCESS;
+				break;
+			case STMF_STATE_ONLINE:
+			case STMF_STATE_ONLINING:
+				ret = STMF_ALREADY;
+				break;
+			case STMF_STATE_OFFLINING:
+				ret = STMF_BUSY;
+				break;
+			default:
+				ret = STMF_BADSTATE;
+				break;
+		}
+		if (ret != STMF_SUCCESS)
 			goto stmf_ctl_lock_exit;
-		}
-		if (ilport->ilport_state != STMF_STATE_OFFLINE) {
-			ret = STMF_INVALID_ARG;
-			goto stmf_ctl_lock_exit;
-		}
 
 		/*
 		 * Only user request can recover the port from the
@@ -5009,7 +5039,7 @@
 
 	case STMF_CMD_LPORT_ONLINE_COMPLETE:
 		if (ilport->ilport_state != STMF_STATE_ONLINING) {
-			ret = STMF_INVALID_ARG;
+			ret = STMF_BADSTATE;
 			goto stmf_ctl_lock_exit;
 		}
 		if (((stmf_change_status_t *)arg)->st_completion_status ==
@@ -5027,14 +5057,24 @@
 		goto stmf_ctl_lock_exit;
 
 	case STMF_CMD_LPORT_OFFLINE:
-		if (ilport->ilport_state == STMF_STATE_OFFLINE) {
-			ret = STMF_ALREADY;
+		switch (ilport->ilport_state) {
+			case STMF_STATE_ONLINE:
+				ret = STMF_SUCCESS;
+				break;
+			case STMF_STATE_OFFLINE:
+			case STMF_STATE_OFFLINING:
+				ret = STMF_ALREADY;
+				break;
+			case STMF_STATE_ONLINING:
+				ret = STMF_BUSY;
+				break;
+			default:
+				ret = STMF_BADSTATE;
+				break;
+		}
+		if (ret != STMF_SUCCESS)
 			goto stmf_ctl_lock_exit;
-		}
-		if (ilport->ilport_state != STMF_STATE_ONLINE) {
-			ret = STMF_INVALID_ARG;
-			goto stmf_ctl_lock_exit;
-		}
+
 		ilport->ilport_state = STMF_STATE_OFFLINING;
 		mutex_exit(&stmf_state.stmf_lock);
 		stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
@@ -5042,7 +5082,7 @@
 
 	case STMF_CMD_LPORT_OFFLINE_COMPLETE:
 		if (ilport->ilport_state != STMF_STATE_OFFLINING) {
-			ret = STMF_INVALID_ARG;
+			ret = STMF_BADSTATE;
 			goto stmf_ctl_lock_exit;
 		}
 		if (((stmf_change_status_t *)arg)->st_completion_status ==
@@ -6808,6 +6848,7 @@
 	for (preq = &stmf_state.stmf_svc_waiting; (*preq) != NULL; ) {
 		req = *preq;
 		deq = 0;
+
 		switch (req->svc_cmd) {
 		case STMF_CMD_LU_ONLINE:
 			lu = (stmf_lu_t *)req->svc_obj;
--- a/usr/src/uts/common/sys/stmf_defines.h	Fri Feb 19 09:52:30 2010 +0800
+++ b/usr/src/uts/common/sys/stmf_defines.h	Thu Feb 18 18:57:27 2010 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #ifndef	_STMF_DEFINES_H
@@ -83,6 +83,7 @@
 #define	STMF_ALREADY		(STMF_FAILURE | STMF_FSC(8))
 #define	STMF_TIMEOUT		(STMF_FAILURE | STMF_FSC(9))
 #define	STMF_NOT_SUPPORTED	(STMF_FAILURE | STMF_FSC(10))
+#define	STMF_BADSTATE		(STMF_FAILURE | STMF_FSC(11))
 
 #define	GET_BYTE_OFFSET(ptr, off)	(((uint8_t *)(ptr)) + (off))
 #define	GET_STRUCT_SIZE(s)		((sizeof (s) + 7) & 0xfffffff8)