Mercurial > illumos > illumos-gate
changeset 10691:36de6b202f7e
6870543 stmfAddViewEntry() could use a validate-only mode
author | tim szeto <Tim.Szeto@Sun.COM> |
---|---|
date | Wed, 30 Sep 2009 10:02:47 -0600 |
parents | c9e94c239e8c |
children | ab0b8119c0e1 |
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/stmf/lun_map.c usr/src/uts/common/io/comstar/stmf/lun_map.h usr/src/uts/common/io/comstar/stmf/stmf.c usr/src/uts/common/sys/stmf_ioctl.h |
diffstat | 7 files changed, 298 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libstmf/common/libstmf.h Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/lib/libstmf/common/libstmf.h Wed Sep 30 10:02:47 2009 -0600 @@ -355,6 +355,7 @@ int stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType); int stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, uint64_t *setToken); +int stmfValidateView(stmfViewEntry *viewEntry); #ifdef __cplusplus }
--- a/usr/src/lib/libstmf/common/mapfile-vers Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/lib/libstmf/common/mapfile-vers Wed Sep 30 10:02:47 2009 -0600 @@ -83,6 +83,7 @@ stmfSetProviderData; stmfSetProviderDataProt; stmfSetLuProp; + stmfValidateView; local: *; };
--- a/usr/src/lib/libstmf/common/stmf.c Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/lib/libstmf/common/stmf.c Wed Sep 30 10:02:47 2009 -0600 @@ -5822,3 +5822,190 @@ return (ret); } + +/* + * validateLunNumIoctl + * + * Purpose: Issues ioctl to check and get available lun# in view entry + * + * viewEntry - view entry to use + */ +static int +validateLunNumIoctl(int fd, stmfViewEntry *viewEntry) +{ + int ret = STMF_STATUS_SUCCESS; + int ioctlRet; + stmf_iocdata_t stmfIoctl; + stmf_view_op_entry_t ioctlViewEntry; + + bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); + /* + * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be + * false on input + */ + ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; + ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; + ioctlViewEntry.ve_all_targets = viewEntry->allTargets; + + if (viewEntry->allHosts == B_FALSE) { + bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, + sizeof (stmfGroupName)); + ioctlViewEntry.ve_host_group.name_size = + strlen((char *)viewEntry->hostGroup); + } + if (viewEntry->allTargets == B_FALSE) { + bcopy(viewEntry->targetGroup, + &ioctlViewEntry.ve_target_group.name, + sizeof (stmfGroupName)); + ioctlViewEntry.ve_target_group.name_size = + strlen((char *)viewEntry->targetGroup); + } + /* Validating the lun number */ + if (viewEntry->luNbrValid) { + bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, + sizeof (ioctlViewEntry.ve_lu_nbr)); + } + + bzero(&stmfIoctl, sizeof (stmfIoctl)); + /* + * Issue ioctl to validate lun# in the view entry + */ + stmfIoctl.stmf_version = STMF_VERSION_1; + stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); + stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; + stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); + stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; + ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl); + + /* save available lun number */ + if (!viewEntry->luNbrValid) { + bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, + sizeof (ioctlViewEntry.ve_lu_nbr)); + } + if (ioctlRet != 0) { + switch (errno) { + case EBUSY: + ret = STMF_ERROR_BUSY; + break; + case EPERM: + ret = STMF_ERROR_PERM; + break; + case EACCES: + switch (stmfIoctl.stmf_error) { + case STMF_IOCERR_UPDATE_NEED_CFG_INIT: + ret = STMF_ERROR_CONFIG_NONE; + break; + default: + ret = STMF_ERROR_PERM; + break; + } + break; + default: + switch (stmfIoctl.stmf_error) { + case STMF_IOCERR_LU_NUMBER_IN_USE: + ret = STMF_ERROR_LUN_IN_USE; + break; + case STMF_IOCERR_VIEW_ENTRY_CONFLICT: + ret = STMF_ERROR_VE_CONFLICT; + break; + case STMF_IOCERR_UPDATE_NEED_CFG_INIT: + ret = STMF_ERROR_CONFIG_NONE; + break; + case STMF_IOCERR_INVALID_HG: + ret = STMF_ERROR_INVALID_HG; + break; + case STMF_IOCERR_INVALID_TG: + ret = STMF_ERROR_INVALID_TG; + break; + default: + syslog(LOG_DEBUG, + "addViewEntryIoctl" + ":error(%d)", + stmfIoctl.stmf_error); + ret = STMF_STATUS_ERROR; + break; + } + break; + } + } + return (ret); +} + +/* + * stmfValidateView + * + * Purpose: Validate or get lun # base on TG, HG of view entry + * + * viewEntry - view entry structure to use + */ +int +stmfValidateView(stmfViewEntry *viewEntry) +{ + int ret; + int fd; + stmfViewEntry iViewEntry; + + if (viewEntry == NULL) { + return (STMF_ERROR_INVALID_ARG); + } + + /* initialize and set internal view entry */ + bzero(&iViewEntry, sizeof (iViewEntry)); + + if (!viewEntry->allHosts) { + bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, + sizeof (iViewEntry.hostGroup)); + } else { + iViewEntry.allHosts = B_TRUE; + } + + if (!viewEntry->allTargets) { + bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, + sizeof (iViewEntry.targetGroup)); + } else { + iViewEntry.allTargets = B_TRUE; + } + + if (viewEntry->luNbrValid) { + iViewEntry.luNbrValid = B_TRUE; + bcopy(viewEntry->luNbr, iViewEntry.luNbr, + sizeof (iViewEntry.luNbr)); + } + + /* + * set users return view entry index valid flag to false + * in case of failure + */ + viewEntry->veIndexValid = B_FALSE; + + /* Check to ensure service exists */ + if (psCheckService() != STMF_STATUS_SUCCESS) { + return (STMF_ERROR_SERVICE_NOT_FOUND); + } + + /* call init */ + ret = initializeConfig(); + if (ret != STMF_STATUS_SUCCESS) { + return (ret); + } + + /* + * Open control node for stmf + */ + if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) + return (ret); + + /* + * Validate lun# in the view entry from the driver + */ + ret = validateLunNumIoctl(fd, &iViewEntry); + (void) close(fd); + + /* save available lun number */ + if (!viewEntry->luNbrValid) { + bcopy(iViewEntry.luNbr, viewEntry->luNbr, + sizeof (iViewEntry.luNbr)); + } + + return (ret); +}
--- a/usr/src/uts/common/io/comstar/stmf/lun_map.c Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/uts/common/io/comstar/stmf/lun_map.c Wed Sep 30 10:02:47 2009 -0600 @@ -1668,3 +1668,90 @@ } return (NULL); } + +stmf_status_t +stmf_validate_lun_view_entry(stmf_id_data_t *hg, stmf_id_data_t *tg, + uint8_t *lun, uint32_t *err_detail) +{ + char *phg, *ptg; + stmf_lun_map_t *ve_map = NULL; + stmf_ver_hg_t *verhg = NULL; + stmf_ver_tg_t *vertg = NULL; + uint16_t lun_num; + stmf_status_t ret = STMF_SUCCESS; + + ASSERT(mutex_owned(&stmf_state.stmf_lock)); + + ve_map = stmf_duplicate_ve_map(0); + for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL; + vertg = vertg->vert_next) { + ptg = (char *)vertg->vert_tg_ref->id_data; + if ((ptg[0] != '*') && (tg->id_data[0] != '*') && + (vertg->vert_tg_ref != tg)) { + continue; + } + for (verhg = vertg->vert_verh_list; verhg != NULL; + verhg = verhg->verh_next) { + phg = (char *)verhg->verh_hg_ref->id_data; + if ((phg[0] != '*') && (hg->id_data[0] != '*') && + (verhg->verh_hg_ref != hg)) { + continue; + } + (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map, + &ve_map, 0); + } + } + + ret = STMF_SUCCESS; + /* Return an available lun number */ + if (lun[2] == 0xFF) { + /* Pick a LUN number */ + lun_num = stmf_get_next_free_lun(ve_map, lun); + if (lun_num > 0x3FFF) + ret = STMF_NOT_SUPPORTED; + } else { + lun_num = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8); + if (stmf_get_ent_from_map(ve_map, lun_num) != NULL) { + *err_detail = STMF_IOCERR_LU_NUMBER_IN_USE; + ret = STMF_LUN_TAKEN; + } + } + stmf_destroy_ve_map(ve_map); + + return (ret); +} + +int +stmf_validate_lun_ve(uint8_t *hgname, uint16_t hgname_size, + uint8_t *tgname, uint16_t tgname_size, + uint8_t *luNbr, uint32_t *err_detail) +{ + stmf_id_data_t *hg; + stmf_id_data_t *tg; + stmf_status_t ret; + + ASSERT(mutex_owned(&stmf_state.stmf_lock)); + + hg = stmf_lookup_id(&stmf_state.stmf_hg_list, hgname_size, + (uint8_t *)hgname); + if (!hg) { + *err_detail = STMF_IOCERR_INVALID_HG; + return (ENOENT); /* could not find group */ + } + tg = stmf_lookup_id(&stmf_state.stmf_tg_list, tgname_size, + (uint8_t *)tgname); + if (!tg) { + *err_detail = STMF_IOCERR_INVALID_TG; + return (ENOENT); /* could not find group */ + } + ret = stmf_validate_lun_view_entry(hg, tg, luNbr, err_detail); + + if (ret == STMF_LUN_TAKEN) { + return (EEXIST); + } else if (ret == STMF_NOT_SUPPORTED) { + return (E2BIG); + } else if (ret != STMF_SUCCESS) { + return (EINVAL); + } + return (0); +}
--- a/usr/src/uts/common/io/comstar/stmf/lun_map.h Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/uts/common/io/comstar/stmf/lun_map.h Wed Sep 30 10:02:47 2009 -0600 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LUN_MAP_H @@ -153,6 +153,8 @@ int stmf_add_ve(uint8_t *hgname, uint16_t hgname_size, uint8_t *tgname, uint16_t tgname_size, uint8_t *lu_guid, uint32_t *ve_id, uint8_t *luNbr, uint32_t *err_detail); +int stmf_validate_lun_ve(uint8_t *hgname, uint16_t hgname_size, uint8_t *tgname, + uint16_t tgname_size, uint8_t *luNbr, uint32_t *err_detail); int stmf_remove_ve_by_id(uint8_t *guid, uint32_t veid, uint32_t *err_detail); stmf_id_data_t *stmf_lookup_id(stmf_id_list_t *idlist, uint16_t id_size, uint8_t *data);
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/uts/common/io/comstar/stmf/stmf.c Wed Sep 30 10:02:47 2009 -0600 @@ -887,6 +887,7 @@ grpname->name_size, idtype, &iocd->stmf_error); mutex_exit(&stmf_state.stmf_lock); break; + case STMF_IOCTL_VALIDATE_VIEW: case STMF_IOCTL_ADD_VIEW_ENTRY: if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) { ret = EACCES; @@ -914,14 +915,23 @@ else veid = 0xffffffff; mutex_enter(&stmf_state.stmf_lock); - ret = stmf_add_ve(ve->ve_host_group.name, - ve->ve_host_group.name_size, - ve->ve_target_group.name, - ve->ve_target_group.name_size, - ve->ve_guid, - &veid, - ve->ve_lu_nbr, - &iocd->stmf_error); + if (cmd == STMF_IOCTL_ADD_VIEW_ENTRY) { + ret = stmf_add_ve(ve->ve_host_group.name, + ve->ve_host_group.name_size, + ve->ve_target_group.name, + ve->ve_target_group.name_size, + ve->ve_guid, + &veid, + ve->ve_lu_nbr, + &iocd->stmf_error); + } else { /* STMF_IOCTL_VALIDATE_VIEW */ + ret = stmf_validate_lun_ve(ve->ve_host_group.name, + ve->ve_host_group.name_size, + ve->ve_target_group.name, + ve->ve_target_group.name_size, + ve->ve_lu_nbr, + &iocd->stmf_error); + } mutex_exit(&stmf_state.stmf_lock); if (ret == 0 && (!ve->ve_ndx_valid || !ve->ve_lu_number_valid) &&
--- a/usr/src/uts/common/sys/stmf_ioctl.h Wed Sep 30 13:07:19 2009 +0200 +++ b/usr/src/uts/common/sys/stmf_ioctl.h Wed Sep 30 10:02:47 2009 -0600 @@ -66,6 +66,7 @@ #define STMF_IOCTL_REG_LU_LIST (STMF_IOCTL | 32) #define STMF_IOCTL_VE_LU_LIST (STMF_IOCTL | 33) #define STMF_IOCTL_LU_VE_LIST (STMF_IOCTL | 34) +#define STMF_IOCTL_VALIDATE_VIEW (STMF_IOCTL | 35) typedef struct stmf_iocdata { uint32_t stmf_version;