Mercurial > illumos > illumos-gate
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)