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;