xref: /onnv-gate/usr/src/lib/libstmf/common/stmf.c (revision 10765)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
229585STim.Szeto@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include <stdlib.h>
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <wchar.h>
297836SJohn.Forte@Sun.COM #include <strings.h>
307836SJohn.Forte@Sun.COM #include <sys/types.h>
317836SJohn.Forte@Sun.COM #include <sys/stat.h>
327836SJohn.Forte@Sun.COM #include <fcntl.h>
337836SJohn.Forte@Sun.COM #include <unistd.h>
347836SJohn.Forte@Sun.COM #include <libintl.h>
357836SJohn.Forte@Sun.COM #include <errno.h>
367836SJohn.Forte@Sun.COM #include <string.h>
377836SJohn.Forte@Sun.COM #include <assert.h>
387836SJohn.Forte@Sun.COM #include <libnvpair.h>
397836SJohn.Forte@Sun.COM #include <pthread.h>
407836SJohn.Forte@Sun.COM #include <syslog.h>
417836SJohn.Forte@Sun.COM #include <libstmf.h>
427836SJohn.Forte@Sun.COM #include <netinet/in.h>
437836SJohn.Forte@Sun.COM #include <inttypes.h>
447836SJohn.Forte@Sun.COM #include <store.h>
457836SJohn.Forte@Sun.COM #include <locale.h>
469585STim.Szeto@Sun.COM #include <math.h>
479585STim.Szeto@Sun.COM #include <libstmf_impl.h>
487836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h>
499585STim.Szeto@Sun.COM #include <sys/stmf_sbd_ioctl.h>
5010725SJohn.Forte@Sun.COM #include <sys/pppt_ioctl.h>
517836SJohn.Forte@Sun.COM 
527836SJohn.Forte@Sun.COM #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
539585STim.Szeto@Sun.COM #define	SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
5410725SJohn.Forte@Sun.COM #define	PPPT_PATH    "/devices/pseudo/pppt@0:pppt"
557836SJohn.Forte@Sun.COM 
567836SJohn.Forte@Sun.COM #define	EUI "eui."
577836SJohn.Forte@Sun.COM #define	WWN "wwn."
587836SJohn.Forte@Sun.COM #define	IQN "iqn."
599585STim.Szeto@Sun.COM #define	LU_ASCII_GUID_SIZE 32
609585STim.Szeto@Sun.COM #define	LU_GUID_SIZE 16
619585STim.Szeto@Sun.COM #define	OUI_ASCII_SIZE 6
62*10765SJohn.Forte@Sun.COM #define	HOST_ID_ASCII_SIZE 8
639585STim.Szeto@Sun.COM #define	OUI_SIZE 3
64*10765SJohn.Forte@Sun.COM #define	HOST_ID_SIZE 4
657836SJohn.Forte@Sun.COM #define	IDENT_LENGTH_BYTE 3
667836SJohn.Forte@Sun.COM 
679585STim.Szeto@Sun.COM /* various initial allocation values */
689585STim.Szeto@Sun.COM #define	ALLOC_LU		8192
699585STim.Szeto@Sun.COM #define	ALLOC_TARGET_PORT	2048
709585STim.Szeto@Sun.COM #define	ALLOC_PROVIDER		64
719585STim.Szeto@Sun.COM #define	ALLOC_GROUP		2048
729585STim.Szeto@Sun.COM #define	ALLOC_SESSION		2048
739585STim.Szeto@Sun.COM #define	ALLOC_VE		256
749585STim.Szeto@Sun.COM #define	ALLOC_PP_DATA_SIZE	128*1024
759585STim.Szeto@Sun.COM #define	ALLOC_GRP_MEMBER	256
769585STim.Szeto@Sun.COM 
777836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME	223
789585STim.Szeto@Sun.COM #define	MAX_SERIAL_SIZE 252 + 1
799585STim.Szeto@Sun.COM #define	MAX_LU_ALIAS_SIZE 256
809585STim.Szeto@Sun.COM #define	MAX_SBD_PROPS	MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
817836SJohn.Forte@Sun.COM 
827836SJohn.Forte@Sun.COM #define	OPEN_STMF 0
837836SJohn.Forte@Sun.COM #define	OPEN_EXCL_STMF O_EXCL
847836SJohn.Forte@Sun.COM 
859585STim.Szeto@Sun.COM #define	OPEN_SBD 0
869585STim.Szeto@Sun.COM #define	OPEN_EXCL_SBD O_EXCL
879585STim.Szeto@Sun.COM 
8810725SJohn.Forte@Sun.COM #define	OPEN_PPPT 0
8910725SJohn.Forte@Sun.COM #define	OPEN_EXCL_PPPT O_EXCL
9010725SJohn.Forte@Sun.COM 
917836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_TYPE 0
927836SJohn.Forte@Sun.COM #define	TARGET_TYPE 1
937836SJohn.Forte@Sun.COM #define	STMF_SERVICE_TYPE 2
947836SJohn.Forte@Sun.COM 
959585STim.Szeto@Sun.COM #define	HOST_GROUP   1
969585STim.Szeto@Sun.COM #define	TARGET_GROUP 2
979585STim.Szeto@Sun.COM 
989585STim.Szeto@Sun.COM /* set default persistence here */
999585STim.Szeto@Sun.COM #define	STMF_DEFAULT_PERSIST	STMF_PERSIST_SMF
1009585STim.Szeto@Sun.COM 
1019585STim.Szeto@Sun.COM #define	MAX_PROVIDER_RETRY 30
1029585STim.Szeto@Sun.COM 
1037836SJohn.Forte@Sun.COM static int openStmf(int, int *fd);
1049585STim.Szeto@Sun.COM static int openSbd(int, int *fd);
10510725SJohn.Forte@Sun.COM static int openPppt(int, int *fd);
1067836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *);
1077836SJohn.Forte@Sun.COM static int loadStore(int fd);
1087836SJohn.Forte@Sun.COM static int initializeConfig();
1097836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
1107836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *);
1117836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
1127836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *);
1137836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *);
1147836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *);
1157836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int);
1169585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
1179585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *);
1189585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *);
1199585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid);
1209585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
1219585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
1229585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
1239585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *);
1249585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *);
1259585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t);
1269585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *);
1279585STim.Szeto@Sun.COM static int checkHexUpper(char *);
1289585STim.Szeto@Sun.COM static int strToShift(const char *);
1299585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *);
1309585STim.Szeto@Sun.COM static void diskError(uint32_t, int *);
1319585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *);
1329585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
1339585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
1349585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t);
1359585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod();
1369585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int);
1379585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int);
1389585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
1399585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *);
14010725SJohn.Forte@Sun.COM static int setDiskStandby(stmfGuid *luGuid);
1419585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *);
14210725SJohn.Forte@Sun.COM static void deleteNonActiveLus();
1439585STim.Szeto@Sun.COM 
1449585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER;
1459585STim.Szeto@Sun.COM static int iPersistType = 0;
1469585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
1479585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE;
1487836SJohn.Forte@Sun.COM 
1497836SJohn.Forte@Sun.COM /*
1507836SJohn.Forte@Sun.COM  * Open for stmf module
1517836SJohn.Forte@Sun.COM  *
1527836SJohn.Forte@Sun.COM  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
1537836SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
1547836SJohn.Forte@Sun.COM  */
1557836SJohn.Forte@Sun.COM static int
1567836SJohn.Forte@Sun.COM openStmf(int flag, int *fd)
1577836SJohn.Forte@Sun.COM {
1587836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
1597836SJohn.Forte@Sun.COM 
1607836SJohn.Forte@Sun.COM 	if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
1617836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
1627836SJohn.Forte@Sun.COM 	} else {
1637836SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
1647836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1659585STim.Szeto@Sun.COM 		} else if (errno == EACCES) {
1669585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERM;
1677836SJohn.Forte@Sun.COM 		} else {
1687836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1697836SJohn.Forte@Sun.COM 		}
1707836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
1717836SJohn.Forte@Sun.COM 		    STMF_PATH, errno);
1727836SJohn.Forte@Sun.COM 	}
1737836SJohn.Forte@Sun.COM 
1747836SJohn.Forte@Sun.COM 	return (ret);
1757836SJohn.Forte@Sun.COM }
1767836SJohn.Forte@Sun.COM 
1777836SJohn.Forte@Sun.COM /*
1789585STim.Szeto@Sun.COM  * Open for sbd module
1799585STim.Szeto@Sun.COM  *
18010725SJohn.Forte@Sun.COM  * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD)
1819585STim.Szeto@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
1829585STim.Szeto@Sun.COM  */
1839585STim.Szeto@Sun.COM static int
1849585STim.Szeto@Sun.COM openSbd(int flag, int *fd)
1859585STim.Szeto@Sun.COM {
1869585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
1879585STim.Szeto@Sun.COM 
1889585STim.Szeto@Sun.COM 	if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
1899585STim.Szeto@Sun.COM 		ret = STMF_STATUS_SUCCESS;
1909585STim.Szeto@Sun.COM 	} else {
1919585STim.Szeto@Sun.COM 		if (errno == EBUSY) {
1929585STim.Szeto@Sun.COM 			ret = STMF_ERROR_BUSY;
1939585STim.Szeto@Sun.COM 		} else if (errno == EACCES) {
1949585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERM;
1959585STim.Szeto@Sun.COM 		} else {
1969585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
1979585STim.Szeto@Sun.COM 		}
1989585STim.Szeto@Sun.COM 		syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)",
1999585STim.Szeto@Sun.COM 		    SBD_PATH, errno);
2009585STim.Szeto@Sun.COM 	}
2019585STim.Szeto@Sun.COM 
2029585STim.Szeto@Sun.COM 	return (ret);
2039585STim.Szeto@Sun.COM }
2049585STim.Szeto@Sun.COM 
2059585STim.Szeto@Sun.COM /*
20610725SJohn.Forte@Sun.COM  * Open for pppt module
20710725SJohn.Forte@Sun.COM  *
20810725SJohn.Forte@Sun.COM  * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT)
20910725SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
21010725SJohn.Forte@Sun.COM  */
21110725SJohn.Forte@Sun.COM static int
21210725SJohn.Forte@Sun.COM openPppt(int flag, int *fd)
21310725SJohn.Forte@Sun.COM {
21410725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
21510725SJohn.Forte@Sun.COM 
21610725SJohn.Forte@Sun.COM 	if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) {
21710725SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
21810725SJohn.Forte@Sun.COM 	} else {
21910725SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
22010725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
22110725SJohn.Forte@Sun.COM 		} else if (errno == EACCES) {
22210725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PERM;
22310725SJohn.Forte@Sun.COM 		} else {
22410725SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
22510725SJohn.Forte@Sun.COM 		}
22610725SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)",
22710725SJohn.Forte@Sun.COM 		    PPPT_PATH, errno);
22810725SJohn.Forte@Sun.COM 	}
22910725SJohn.Forte@Sun.COM 
23010725SJohn.Forte@Sun.COM 	return (ret);
23110725SJohn.Forte@Sun.COM }
23210725SJohn.Forte@Sun.COM 
23310725SJohn.Forte@Sun.COM /*
2347836SJohn.Forte@Sun.COM  * initializeConfig
2357836SJohn.Forte@Sun.COM  *
2367836SJohn.Forte@Sun.COM  * This routine should be called before any ioctl requiring initialization
2377836SJohn.Forte@Sun.COM  * which is basically everything except stmfGetState(), setStmfState() and
2387836SJohn.Forte@Sun.COM  * stmfLoadConfig().
2397836SJohn.Forte@Sun.COM  */
2407836SJohn.Forte@Sun.COM static int
2417836SJohn.Forte@Sun.COM initializeConfig()
2427836SJohn.Forte@Sun.COM {
2437836SJohn.Forte@Sun.COM 	int ret;
2447836SJohn.Forte@Sun.COM 	stmfState state;
2457836SJohn.Forte@Sun.COM 
2467836SJohn.Forte@Sun.COM 
2477836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2487836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2497836SJohn.Forte@Sun.COM 		return (ret);
2507836SJohn.Forte@Sun.COM 	}
2517836SJohn.Forte@Sun.COM 
2527836SJohn.Forte@Sun.COM 	/* if we've already initialized or in the process, return success */
2537836SJohn.Forte@Sun.COM 	if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
2547836SJohn.Forte@Sun.COM 	    state.configState == STMF_CONFIG_STATE_INIT) {
2557836SJohn.Forte@Sun.COM 		return (STMF_STATUS_SUCCESS);
2567836SJohn.Forte@Sun.COM 	}
2577836SJohn.Forte@Sun.COM 
2587836SJohn.Forte@Sun.COM 	ret = stmfLoadConfig();
2597836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2607836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
2617836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfLoadConfig:error(%d)", ret);
2627836SJohn.Forte@Sun.COM 		return (ret);
2637836SJohn.Forte@Sun.COM 	}
2647836SJohn.Forte@Sun.COM 
2657836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2667836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2677836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
2687836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfGetState:error(%d)", ret);
2697836SJohn.Forte@Sun.COM 		return (ret);
2707836SJohn.Forte@Sun.COM 	}
2717836SJohn.Forte@Sun.COM 
2727836SJohn.Forte@Sun.COM 	if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
2737836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
2747836SJohn.Forte@Sun.COM 		    state.configState);
2757836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_ERROR;
2767836SJohn.Forte@Sun.COM 	}
2777836SJohn.Forte@Sun.COM 
2787836SJohn.Forte@Sun.COM 	return (ret);
2797836SJohn.Forte@Sun.COM }
2807836SJohn.Forte@Sun.COM 
2817836SJohn.Forte@Sun.COM 
2827836SJohn.Forte@Sun.COM /*
2837836SJohn.Forte@Sun.COM  * groupIoctl
2847836SJohn.Forte@Sun.COM  *
2857836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for create/delete on group
2867836SJohn.Forte@Sun.COM  *
2877836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group cmd
2887836SJohn.Forte@Sun.COM  * groupName - groupName to create or delete
2897836SJohn.Forte@Sun.COM  */
2907836SJohn.Forte@Sun.COM static int
2917836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName)
2927836SJohn.Forte@Sun.COM {
2937836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2947836SJohn.Forte@Sun.COM 	int ioctlRet;
2957836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2967836SJohn.Forte@Sun.COM 	stmf_group_name_t iGroupName;
2977836SJohn.Forte@Sun.COM 
2987836SJohn.Forte@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
2997836SJohn.Forte@Sun.COM 
3007836SJohn.Forte@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
3017836SJohn.Forte@Sun.COM 
3027836SJohn.Forte@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
3037836SJohn.Forte@Sun.COM 
3047836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3057836SJohn.Forte@Sun.COM 	/*
3067836SJohn.Forte@Sun.COM 	 * Issue ioctl to create the host group
3077836SJohn.Forte@Sun.COM 	 */
3087836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3097836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
3107836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3117836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3127836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3137836SJohn.Forte@Sun.COM 		switch (errno) {
3149585STim.Szeto@Sun.COM 			case EPERM:
3157836SJohn.Forte@Sun.COM 			case EACCES:
3167836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3177836SJohn.Forte@Sun.COM 				break;
3187836SJohn.Forte@Sun.COM 			default:
3197836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
3207836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_EXISTS:
3217836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_EXISTS:
3227836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
3237836SJohn.Forte@Sun.COM 						break;
3247836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_IN_USE:
3257836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_IN_USE:
3267836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_GROUP_IN_USE;
3277836SJohn.Forte@Sun.COM 						break;
3287836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
3297836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
3307836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
3317836SJohn.Forte@Sun.COM 						break;
3327836SJohn.Forte@Sun.COM 					default:
3337836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
3347836SJohn.Forte@Sun.COM 						    "groupIoctl:error(%d)",
3357836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
3367836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
3377836SJohn.Forte@Sun.COM 						break;
3387836SJohn.Forte@Sun.COM 				}
3397836SJohn.Forte@Sun.COM 				break;
3407836SJohn.Forte@Sun.COM 		}
3417836SJohn.Forte@Sun.COM 	}
3427836SJohn.Forte@Sun.COM done:
3437836SJohn.Forte@Sun.COM 	return (ret);
3447836SJohn.Forte@Sun.COM }
3457836SJohn.Forte@Sun.COM 
3467836SJohn.Forte@Sun.COM /*
3479585STim.Szeto@Sun.COM  * groupMemberIoctl
3487836SJohn.Forte@Sun.COM  *
3497836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for add/remove member on group
3507836SJohn.Forte@Sun.COM  *
3517836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group member cmd
3527836SJohn.Forte@Sun.COM  * groupName - groupName to add to or remove from
3537836SJohn.Forte@Sun.COM  * devid - group member to add or remove
3547836SJohn.Forte@Sun.COM  */
3557836SJohn.Forte@Sun.COM static int
3567836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
3577836SJohn.Forte@Sun.COM {
3587836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
3597836SJohn.Forte@Sun.COM 	int ioctlRet;
3607836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
3617836SJohn.Forte@Sun.COM 	stmf_group_op_data_t stmfGroupData;
3627836SJohn.Forte@Sun.COM 
3637836SJohn.Forte@Sun.COM 	bzero(&stmfGroupData, sizeof (stmfGroupData));
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
3667836SJohn.Forte@Sun.COM 
3677836SJohn.Forte@Sun.COM 	stmfGroupData.group.name_size = strlen((char *)groupName);
3687836SJohn.Forte@Sun.COM 	stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
3697836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
3707836SJohn.Forte@Sun.COM 	    devid->identLength);
3717836SJohn.Forte@Sun.COM 
3727836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3737836SJohn.Forte@Sun.COM 	/*
3747836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
3757836SJohn.Forte@Sun.COM 	 */
3767836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3777836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
3787836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
3797836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3807836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3817836SJohn.Forte@Sun.COM 		switch (errno) {
3827836SJohn.Forte@Sun.COM 			case EBUSY:
3839884STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
3849884STim.Szeto@Sun.COM 					case STMF_IOCERR_TG_NEED_TG_OFFLINE:
3859884STim.Szeto@Sun.COM 						ret = STMF_ERROR_TG_ONLINE;
3869884STim.Szeto@Sun.COM 						break;
3879884STim.Szeto@Sun.COM 					default:
3889884STim.Szeto@Sun.COM 						ret = STMF_ERROR_BUSY;
3899884STim.Szeto@Sun.COM 						break;
3909884STim.Szeto@Sun.COM 				}
3917836SJohn.Forte@Sun.COM 				break;
3929585STim.Szeto@Sun.COM 			case EPERM:
3937836SJohn.Forte@Sun.COM 			case EACCES:
3947836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3957836SJohn.Forte@Sun.COM 				break;
3967836SJohn.Forte@Sun.COM 			default:
3977836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
3987836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_ENTRY_EXISTS:
3997836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_ENTRY_EXISTS:
4007836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
4017836SJohn.Forte@Sun.COM 						break;
4027836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG_ENTRY:
4037836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG_ENTRY:
4047836SJohn.Forte@Sun.COM 						ret =
4057836SJohn.Forte@Sun.COM 						    STMF_ERROR_MEMBER_NOT_FOUND;
4067836SJohn.Forte@Sun.COM 						break;
4077836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
4087836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
4097836SJohn.Forte@Sun.COM 						ret =
4107836SJohn.Forte@Sun.COM 						    STMF_ERROR_GROUP_NOT_FOUND;
4117836SJohn.Forte@Sun.COM 						break;
4127836SJohn.Forte@Sun.COM 					default:
4137836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
4147836SJohn.Forte@Sun.COM 						    "groupMemberIoctl:error"
4157836SJohn.Forte@Sun.COM 						    "(%d)",
4167836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
4177836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
4187836SJohn.Forte@Sun.COM 						break;
4197836SJohn.Forte@Sun.COM 				}
4207836SJohn.Forte@Sun.COM 				break;
4217836SJohn.Forte@Sun.COM 		}
4227836SJohn.Forte@Sun.COM 	}
4237836SJohn.Forte@Sun.COM done:
4247836SJohn.Forte@Sun.COM 	return (ret);
4257836SJohn.Forte@Sun.COM }
4267836SJohn.Forte@Sun.COM 
4277836SJohn.Forte@Sun.COM /*
4289585STim.Szeto@Sun.COM  * qsort function
4299585STim.Szeto@Sun.COM  * sort on veIndex
4309585STim.Szeto@Sun.COM  */
4319585STim.Szeto@Sun.COM static int
4329585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2)
4339585STim.Szeto@Sun.COM {
4349585STim.Szeto@Sun.COM 
4359585STim.Szeto@Sun.COM 	stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
4369585STim.Szeto@Sun.COM 	if (v1->veIndex > v2->veIndex)
4379585STim.Szeto@Sun.COM 		return (1);
4389585STim.Szeto@Sun.COM 	if (v1->veIndex < v2->veIndex)
4399585STim.Szeto@Sun.COM 		return (-1);
4409585STim.Szeto@Sun.COM 	return (0);
4419585STim.Szeto@Sun.COM }
4429585STim.Szeto@Sun.COM 
4439585STim.Szeto@Sun.COM /*
4447836SJohn.Forte@Sun.COM  * guidCompare
4457836SJohn.Forte@Sun.COM  *
4467836SJohn.Forte@Sun.COM  * qsort function
4477836SJohn.Forte@Sun.COM  * sort on guid
4487836SJohn.Forte@Sun.COM  */
4497836SJohn.Forte@Sun.COM static int
4507836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2)
4517836SJohn.Forte@Sun.COM {
4527836SJohn.Forte@Sun.COM 
4537836SJohn.Forte@Sun.COM 	stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
4547836SJohn.Forte@Sun.COM 	int i;
4557836SJohn.Forte@Sun.COM 
4567836SJohn.Forte@Sun.COM 	for (i = 0; i < sizeof (stmfGuid); i++) {
4577836SJohn.Forte@Sun.COM 		if (g1->guid[i] > g2->guid[i])
4587836SJohn.Forte@Sun.COM 			return (1);
4597836SJohn.Forte@Sun.COM 		if (g1->guid[i] < g2->guid[i])
4607836SJohn.Forte@Sun.COM 			return (-1);
4617836SJohn.Forte@Sun.COM 	}
4627836SJohn.Forte@Sun.COM 
4637836SJohn.Forte@Sun.COM 	return (0);
4647836SJohn.Forte@Sun.COM }
4657836SJohn.Forte@Sun.COM 
4667836SJohn.Forte@Sun.COM /*
4677836SJohn.Forte@Sun.COM  * stmfAddToHostGroup
4687836SJohn.Forte@Sun.COM  *
4697836SJohn.Forte@Sun.COM  * Purpose: Adds an initiator to an existing host group
4707836SJohn.Forte@Sun.COM  *
4717836SJohn.Forte@Sun.COM  * hostGroupName - name of an existing host group
4727836SJohn.Forte@Sun.COM  * hostName - name of initiator to add
4737836SJohn.Forte@Sun.COM  */
4747836SJohn.Forte@Sun.COM int
4757836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
4767836SJohn.Forte@Sun.COM {
4777836SJohn.Forte@Sun.COM 	int ret;
4787836SJohn.Forte@Sun.COM 	int fd;
4797836SJohn.Forte@Sun.COM 
4807836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
4817836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
4827836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
4837836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
4847836SJohn.Forte@Sun.COM 	}
4857836SJohn.Forte@Sun.COM 
4867836SJohn.Forte@Sun.COM 	/* call init */
4877836SJohn.Forte@Sun.COM 	ret = initializeConfig();
4887836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
4897836SJohn.Forte@Sun.COM 		return (ret);
4907836SJohn.Forte@Sun.COM 	}
4917836SJohn.Forte@Sun.COM 
4927836SJohn.Forte@Sun.COM 	/*
4937836SJohn.Forte@Sun.COM 	 * Open control node for stmf
4947836SJohn.Forte@Sun.COM 	 */
4957836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4967836SJohn.Forte@Sun.COM 		return (ret);
4977836SJohn.Forte@Sun.COM 
4987836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
4997836SJohn.Forte@Sun.COM 	    hostName)) != STMF_STATUS_SUCCESS) {
5007836SJohn.Forte@Sun.COM 		goto done;
5017836SJohn.Forte@Sun.COM 	}
5027836SJohn.Forte@Sun.COM 
5039585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5049585STim.Szeto@Sun.COM 		goto done;
5059585STim.Szeto@Sun.COM 	}
5069585STim.Szeto@Sun.COM 
5077836SJohn.Forte@Sun.COM 	ret = psAddHostGroupMember((char *)hostGroupName,
5087836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
5097836SJohn.Forte@Sun.COM 	switch (ret) {
5107836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
5117836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
5127836SJohn.Forte@Sun.COM 			break;
5137836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
5147836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
5157836SJohn.Forte@Sun.COM 			break;
5167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5187836SJohn.Forte@Sun.COM 			break;
5197836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
5207836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
5217836SJohn.Forte@Sun.COM 			break;
5227836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5237836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5247836SJohn.Forte@Sun.COM 			break;
5257836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
5267836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5277836SJohn.Forte@Sun.COM 			break;
5287836SJohn.Forte@Sun.COM 		default:
5297836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
5307836SJohn.Forte@Sun.COM 			    "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
5317836SJohn.Forte@Sun.COM 			    ret);
5327836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
5337836SJohn.Forte@Sun.COM 			break;
5347836SJohn.Forte@Sun.COM 	}
5357836SJohn.Forte@Sun.COM 
5367836SJohn.Forte@Sun.COM done:
5377836SJohn.Forte@Sun.COM 	(void) close(fd);
5387836SJohn.Forte@Sun.COM 	return (ret);
5397836SJohn.Forte@Sun.COM }
5407836SJohn.Forte@Sun.COM 
5417836SJohn.Forte@Sun.COM /*
5427836SJohn.Forte@Sun.COM  * stmfAddToTargetGroup
5437836SJohn.Forte@Sun.COM  *
5447836SJohn.Forte@Sun.COM  * Purpose: Adds a local port to an existing target group
5457836SJohn.Forte@Sun.COM  *
5467836SJohn.Forte@Sun.COM  * targetGroupName - name of an existing target group
5477836SJohn.Forte@Sun.COM  * targetName - name of target to add
5487836SJohn.Forte@Sun.COM  */
5497836SJohn.Forte@Sun.COM int
5507836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
5517836SJohn.Forte@Sun.COM {
5527836SJohn.Forte@Sun.COM 	int ret;
5537836SJohn.Forte@Sun.COM 	int fd;
5547836SJohn.Forte@Sun.COM 
5557836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
5567836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
5577836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
5587836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
5597836SJohn.Forte@Sun.COM 	}
5607836SJohn.Forte@Sun.COM 
5617836SJohn.Forte@Sun.COM 	/* call init */
5627836SJohn.Forte@Sun.COM 	ret = initializeConfig();
5637836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
5647836SJohn.Forte@Sun.COM 		return (ret);
5657836SJohn.Forte@Sun.COM 	}
5667836SJohn.Forte@Sun.COM 
5677836SJohn.Forte@Sun.COM 	/*
5687836SJohn.Forte@Sun.COM 	 * Open control node for stmf
5697836SJohn.Forte@Sun.COM 	 */
5707836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5717836SJohn.Forte@Sun.COM 		return (ret);
5727836SJohn.Forte@Sun.COM 
5737836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
5747836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
5757836SJohn.Forte@Sun.COM 		goto done;
5767836SJohn.Forte@Sun.COM 	}
5777836SJohn.Forte@Sun.COM 
5789585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5799585STim.Szeto@Sun.COM 		goto done;
5809585STim.Szeto@Sun.COM 	}
5819585STim.Szeto@Sun.COM 
5827836SJohn.Forte@Sun.COM 	ret = psAddTargetGroupMember((char *)targetGroupName,
5837836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
5847836SJohn.Forte@Sun.COM 	switch (ret) {
5857836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
5867836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
5877836SJohn.Forte@Sun.COM 			break;
5887836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
5897836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
5907836SJohn.Forte@Sun.COM 			break;
5917836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5927836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5937836SJohn.Forte@Sun.COM 			break;
5947836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
5957836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
5967836SJohn.Forte@Sun.COM 			break;
5977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5997836SJohn.Forte@Sun.COM 			break;
6007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
6017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
6027836SJohn.Forte@Sun.COM 			break;
6037836SJohn.Forte@Sun.COM 		default:
6047836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
6057836SJohn.Forte@Sun.COM 			    "stmfAddToTargetGroup:psAddTargetGroupMember:"
6067836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
6077836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
6087836SJohn.Forte@Sun.COM 			break;
6097836SJohn.Forte@Sun.COM 	}
6107836SJohn.Forte@Sun.COM 
6117836SJohn.Forte@Sun.COM done:
6127836SJohn.Forte@Sun.COM 	(void) close(fd);
6137836SJohn.Forte@Sun.COM 	return (ret);
6147836SJohn.Forte@Sun.COM }
6157836SJohn.Forte@Sun.COM 
6167836SJohn.Forte@Sun.COM /*
6177836SJohn.Forte@Sun.COM  * addViewEntryIoctl
6187836SJohn.Forte@Sun.COM  *
6197836SJohn.Forte@Sun.COM  * Purpose: Issues ioctl to add a view entry
6207836SJohn.Forte@Sun.COM  *
6217836SJohn.Forte@Sun.COM  * lu - Logical Unit identifier to which the view entry is added
6227836SJohn.Forte@Sun.COM  * viewEntry - view entry to add
6237836SJohn.Forte@Sun.COM  * init - When set to B_TRUE, we are in the init state, i.e. don't call open
6247836SJohn.Forte@Sun.COM  */
6257836SJohn.Forte@Sun.COM static int
6267836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
6277836SJohn.Forte@Sun.COM {
6287836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
6297836SJohn.Forte@Sun.COM 	int ioctlRet;
6307836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
6317836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6347836SJohn.Forte@Sun.COM 	/*
6357836SJohn.Forte@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
6367836SJohn.Forte@Sun.COM 	 * false on input
6377836SJohn.Forte@Sun.COM 	 */
6387836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
6397836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
6407836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
6417836SJohn.Forte@Sun.COM 
6427836SJohn.Forte@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
6437836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
6447836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
6457836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
6467836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
6477836SJohn.Forte@Sun.COM 	}
6487836SJohn.Forte@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
6497836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup,
6507836SJohn.Forte@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
6517836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
6527836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
6537836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
6547836SJohn.Forte@Sun.COM 	}
6557836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
6567836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
6577836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
6587836SJohn.Forte@Sun.COM 	}
6597836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
6607836SJohn.Forte@Sun.COM 
6617836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
6627836SJohn.Forte@Sun.COM 	/*
6637836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
6647836SJohn.Forte@Sun.COM 	 */
6657836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
6667836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6677836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6687836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
6697836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6707836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
6717836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
6727836SJohn.Forte@Sun.COM 		switch (errno) {
6737836SJohn.Forte@Sun.COM 			case EBUSY:
6747836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
6757836SJohn.Forte@Sun.COM 				break;
6769585STim.Szeto@Sun.COM 			case EPERM:
6779585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
6789585STim.Szeto@Sun.COM 				break;
6797836SJohn.Forte@Sun.COM 			case EACCES:
6807836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
6817836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6827836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
6837836SJohn.Forte@Sun.COM 						break;
6847836SJohn.Forte@Sun.COM 					default:
6857836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
6867836SJohn.Forte@Sun.COM 						break;
6877836SJohn.Forte@Sun.COM 				}
6887836SJohn.Forte@Sun.COM 				break;
6897836SJohn.Forte@Sun.COM 			default:
6907836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
6917836SJohn.Forte@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
6927836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
6937836SJohn.Forte@Sun.COM 						break;
6947836SJohn.Forte@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
6957836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
6967836SJohn.Forte@Sun.COM 						break;
6977836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6987836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
6997836SJohn.Forte@Sun.COM 						break;
7007836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
7017836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
7027836SJohn.Forte@Sun.COM 						break;
7037836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
7047836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
7057836SJohn.Forte@Sun.COM 						break;
7067836SJohn.Forte@Sun.COM 					default:
7077836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
7087836SJohn.Forte@Sun.COM 						    "addViewEntryIoctl"
7097836SJohn.Forte@Sun.COM 						    ":error(%d)",
7107836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
7117836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
7127836SJohn.Forte@Sun.COM 						break;
7137836SJohn.Forte@Sun.COM 				}
7147836SJohn.Forte@Sun.COM 				break;
7157836SJohn.Forte@Sun.COM 		}
7167836SJohn.Forte@Sun.COM 		goto done;
7177836SJohn.Forte@Sun.COM 	}
7187836SJohn.Forte@Sun.COM 
7197836SJohn.Forte@Sun.COM 	/* copy lu nbr back to caller's view entry on success */
7207836SJohn.Forte@Sun.COM 	viewEntry->veIndex = ioctlViewEntry.ve_ndx;
7217836SJohn.Forte@Sun.COM 	if (ioctlViewEntry.ve_lu_number_valid) {
7227836SJohn.Forte@Sun.COM 		bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
7237836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
7247836SJohn.Forte@Sun.COM 	}
7257836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
7267836SJohn.Forte@Sun.COM 
7277836SJohn.Forte@Sun.COM done:
7287836SJohn.Forte@Sun.COM 	return (ret);
7297836SJohn.Forte@Sun.COM }
7307836SJohn.Forte@Sun.COM 
7317836SJohn.Forte@Sun.COM /*
7327836SJohn.Forte@Sun.COM  * stmfAddViewEntry
7337836SJohn.Forte@Sun.COM  *
7347836SJohn.Forte@Sun.COM  * Purpose: Adds a view entry to a logical unit
7357836SJohn.Forte@Sun.COM  *
7367836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to which the view entry is added
7377836SJohn.Forte@Sun.COM  * viewEntry - view entry structure to add
7387836SJohn.Forte@Sun.COM  */
7397836SJohn.Forte@Sun.COM int
7407836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
7417836SJohn.Forte@Sun.COM {
7427836SJohn.Forte@Sun.COM 	int ret;
7437836SJohn.Forte@Sun.COM 	int fd;
7447836SJohn.Forte@Sun.COM 	stmfViewEntry iViewEntry;
7457836SJohn.Forte@Sun.COM 
7467836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntry == NULL) {
7477836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
7487836SJohn.Forte@Sun.COM 	}
7497836SJohn.Forte@Sun.COM 
7507836SJohn.Forte@Sun.COM 	/* initialize and set internal view entry */
7517836SJohn.Forte@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
7527836SJohn.Forte@Sun.COM 
7537836SJohn.Forte@Sun.COM 	if (!viewEntry->allHosts) {
7547836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
7557836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.hostGroup));
7567836SJohn.Forte@Sun.COM 	} else {
7577836SJohn.Forte@Sun.COM 		iViewEntry.allHosts = B_TRUE;
7587836SJohn.Forte@Sun.COM 	}
7597836SJohn.Forte@Sun.COM 
7607836SJohn.Forte@Sun.COM 	if (!viewEntry->allTargets) {
7617836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
7627836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.targetGroup));
7637836SJohn.Forte@Sun.COM 	} else {
7647836SJohn.Forte@Sun.COM 		iViewEntry.allTargets = B_TRUE;
7657836SJohn.Forte@Sun.COM 	}
7667836SJohn.Forte@Sun.COM 
7677836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
7687836SJohn.Forte@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
7697836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
7707836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
7717836SJohn.Forte@Sun.COM 	}
7727836SJohn.Forte@Sun.COM 
7737836SJohn.Forte@Sun.COM 	/*
7747836SJohn.Forte@Sun.COM 	 * set users return view entry index valid flag to false
7757836SJohn.Forte@Sun.COM 	 * in case of failure
7767836SJohn.Forte@Sun.COM 	 */
7777836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
7787836SJohn.Forte@Sun.COM 
7797836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
7807836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
7817836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
7827836SJohn.Forte@Sun.COM 	}
7837836SJohn.Forte@Sun.COM 
7847836SJohn.Forte@Sun.COM 	/* call init */
7857836SJohn.Forte@Sun.COM 	ret = initializeConfig();
7867836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
7877836SJohn.Forte@Sun.COM 		return (ret);
7887836SJohn.Forte@Sun.COM 	}
7897836SJohn.Forte@Sun.COM 
7907836SJohn.Forte@Sun.COM 	/*
7917836SJohn.Forte@Sun.COM 	 * Open control node for stmf
7927836SJohn.Forte@Sun.COM 	 */
7937836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
7947836SJohn.Forte@Sun.COM 		return (ret);
7957836SJohn.Forte@Sun.COM 
7967836SJohn.Forte@Sun.COM 	/*
7977836SJohn.Forte@Sun.COM 	 * First add the view entry to the driver
7987836SJohn.Forte@Sun.COM 	 */
7997836SJohn.Forte@Sun.COM 	ret = addViewEntryIoctl(fd, lu, &iViewEntry);
8007836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
8017836SJohn.Forte@Sun.COM 		goto done;
8027836SJohn.Forte@Sun.COM 	}
8037836SJohn.Forte@Sun.COM 
8049585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
8059585STim.Szeto@Sun.COM 		goto done;
8069585STim.Szeto@Sun.COM 	}
8079585STim.Szeto@Sun.COM 
8087836SJohn.Forte@Sun.COM 	/*
8097836SJohn.Forte@Sun.COM 	 * If the add to driver was successful, add it to the persistent
8107836SJohn.Forte@Sun.COM 	 * store.
8117836SJohn.Forte@Sun.COM 	 */
8127836SJohn.Forte@Sun.COM 	ret = psAddViewEntry(lu, &iViewEntry);
8137836SJohn.Forte@Sun.COM 	switch (ret) {
8147836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
8157836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
8167836SJohn.Forte@Sun.COM 			break;
8177836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
8187836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
8197836SJohn.Forte@Sun.COM 			break;
8207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
8217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
8227836SJohn.Forte@Sun.COM 			break;
8237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
8247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
8257836SJohn.Forte@Sun.COM 			break;
8267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
8277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
8287836SJohn.Forte@Sun.COM 			break;
8297836SJohn.Forte@Sun.COM 		default:
8307836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
8317836SJohn.Forte@Sun.COM 			    "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
8327836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
8337836SJohn.Forte@Sun.COM 			break;
8347836SJohn.Forte@Sun.COM 	}
8357836SJohn.Forte@Sun.COM 
8367836SJohn.Forte@Sun.COM done:
8377836SJohn.Forte@Sun.COM 	(void) close(fd);
8387836SJohn.Forte@Sun.COM 
8397836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
8407836SJohn.Forte@Sun.COM 		/* set caller's view entry on success */
8417836SJohn.Forte@Sun.COM 		viewEntry->veIndexValid = iViewEntry.veIndexValid;
8427836SJohn.Forte@Sun.COM 		viewEntry->veIndex = iViewEntry.veIndex;
8437836SJohn.Forte@Sun.COM 		viewEntry->luNbrValid = B_TRUE;
8447836SJohn.Forte@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
8457836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
8467836SJohn.Forte@Sun.COM 	}
8477836SJohn.Forte@Sun.COM 	return (ret);
8487836SJohn.Forte@Sun.COM }
8497836SJohn.Forte@Sun.COM 
8507836SJohn.Forte@Sun.COM /*
8517836SJohn.Forte@Sun.COM  * stmfClearProviderData
8527836SJohn.Forte@Sun.COM  *
8537836SJohn.Forte@Sun.COM  * Purpose: delete all provider data for specified provider
8547836SJohn.Forte@Sun.COM  *
8557836SJohn.Forte@Sun.COM  * providerName - name of provider for which data should be deleted
8567836SJohn.Forte@Sun.COM  */
8577836SJohn.Forte@Sun.COM int
8587836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType)
8597836SJohn.Forte@Sun.COM {
8607836SJohn.Forte@Sun.COM 	int ret;
8617836SJohn.Forte@Sun.COM 	int fd;
8627836SJohn.Forte@Sun.COM 	int ioctlRet;
8637836SJohn.Forte@Sun.COM 	int savedErrno;
8647836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
8657836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t ppi;
8667836SJohn.Forte@Sun.COM 
8677836SJohn.Forte@Sun.COM 	/* call init */
8687836SJohn.Forte@Sun.COM 	ret = initializeConfig();
8697836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
8707836SJohn.Forte@Sun.COM 		return (ret);
8717836SJohn.Forte@Sun.COM 	}
8727836SJohn.Forte@Sun.COM 
8737836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
8747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8757836SJohn.Forte@Sun.COM 	}
8767836SJohn.Forte@Sun.COM 
8777836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
8787836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
8797836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8807836SJohn.Forte@Sun.COM 	}
8817836SJohn.Forte@Sun.COM 
8827836SJohn.Forte@Sun.COM 	/*
8837836SJohn.Forte@Sun.COM 	 * Open control node for stmf
8847836SJohn.Forte@Sun.COM 	 */
8857836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
8867836SJohn.Forte@Sun.COM 		return (ret);
8877836SJohn.Forte@Sun.COM 
8887836SJohn.Forte@Sun.COM 	bzero(&ppi, sizeof (ppi));
8897836SJohn.Forte@Sun.COM 
8907836SJohn.Forte@Sun.COM 	(void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
8917836SJohn.Forte@Sun.COM 
8927836SJohn.Forte@Sun.COM 	switch (providerType) {
8937836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
8947836SJohn.Forte@Sun.COM 			ppi.ppi_lu_provider = 1;
8957836SJohn.Forte@Sun.COM 			break;
8967836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
8977836SJohn.Forte@Sun.COM 			ppi.ppi_port_provider = 1;
8987836SJohn.Forte@Sun.COM 			break;
8997836SJohn.Forte@Sun.COM 		default:
9007836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
9017836SJohn.Forte@Sun.COM 			goto done;
9027836SJohn.Forte@Sun.COM 	}
9037836SJohn.Forte@Sun.COM 
9047836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
9057836SJohn.Forte@Sun.COM 
9067836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
9077836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
9087836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
9097836SJohn.Forte@Sun.COM 
9107836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
9117836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
9127836SJohn.Forte@Sun.COM 		savedErrno = errno;
9137836SJohn.Forte@Sun.COM 		switch (savedErrno) {
9147836SJohn.Forte@Sun.COM 			case EBUSY:
9157836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
9167836SJohn.Forte@Sun.COM 				break;
9179585STim.Szeto@Sun.COM 			case EPERM:
9187836SJohn.Forte@Sun.COM 			case EACCES:
9197836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
9207836SJohn.Forte@Sun.COM 				break;
9217836SJohn.Forte@Sun.COM 			default:
9227836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
9237836SJohn.Forte@Sun.COM 				    "stmfClearProviderData:ioctl error(%d)",
9247836SJohn.Forte@Sun.COM 				    ioctlRet);
9257836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
9267836SJohn.Forte@Sun.COM 				break;
9277836SJohn.Forte@Sun.COM 		}
9287836SJohn.Forte@Sun.COM 		if (savedErrno != ENOENT) {
9297836SJohn.Forte@Sun.COM 			goto done;
9307836SJohn.Forte@Sun.COM 		}
9317836SJohn.Forte@Sun.COM 	}
9327836SJohn.Forte@Sun.COM 
9339585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
9349585STim.Szeto@Sun.COM 		goto done;
9359585STim.Szeto@Sun.COM 	}
9369585STim.Szeto@Sun.COM 
9377836SJohn.Forte@Sun.COM 	ret = psClearProviderData(providerName, providerType);
9387836SJohn.Forte@Sun.COM 	switch (ret) {
9397836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
9407836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
9417836SJohn.Forte@Sun.COM 			break;
9427836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
9437836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
9447836SJohn.Forte@Sun.COM 			break;
9457836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
9467836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
9477836SJohn.Forte@Sun.COM 			break;
9487836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
9497836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
9507836SJohn.Forte@Sun.COM 			break;
9517836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
9527836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
9537836SJohn.Forte@Sun.COM 			break;
9547836SJohn.Forte@Sun.COM 		default:
9557836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
9567836SJohn.Forte@Sun.COM 			    "stmfClearProviderData:psClearProviderData"
9577836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
9587836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
9597836SJohn.Forte@Sun.COM 			break;
9607836SJohn.Forte@Sun.COM 	}
9617836SJohn.Forte@Sun.COM 
9627836SJohn.Forte@Sun.COM done:
9637836SJohn.Forte@Sun.COM 	(void) close(fd);
9647836SJohn.Forte@Sun.COM 	return (ret);
9657836SJohn.Forte@Sun.COM }
9667836SJohn.Forte@Sun.COM 
9677836SJohn.Forte@Sun.COM /*
9687836SJohn.Forte@Sun.COM  * stmfCreateHostGroup
9697836SJohn.Forte@Sun.COM  *
9707836SJohn.Forte@Sun.COM  * Purpose: Create a new initiator group
9717836SJohn.Forte@Sun.COM  *
9727836SJohn.Forte@Sun.COM  * hostGroupName - name of host group to create
9737836SJohn.Forte@Sun.COM  */
9747836SJohn.Forte@Sun.COM int
9757836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName)
9767836SJohn.Forte@Sun.COM {
9777836SJohn.Forte@Sun.COM 	int ret;
9787836SJohn.Forte@Sun.COM 	int fd;
9797836SJohn.Forte@Sun.COM 
9807836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
9817836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
9827836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
9837836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
9847836SJohn.Forte@Sun.COM 	}
9857836SJohn.Forte@Sun.COM 
9867836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
9877836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
9887836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
9897836SJohn.Forte@Sun.COM 	}
9907836SJohn.Forte@Sun.COM 
9917836SJohn.Forte@Sun.COM 	/* call init */
9927836SJohn.Forte@Sun.COM 	ret = initializeConfig();
9937836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
9947836SJohn.Forte@Sun.COM 		return (ret);
9957836SJohn.Forte@Sun.COM 	}
9967836SJohn.Forte@Sun.COM 
9977836SJohn.Forte@Sun.COM 	/*
9987836SJohn.Forte@Sun.COM 	 * Open control node for stmf
9997836SJohn.Forte@Sun.COM 	 */
10007836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
10017836SJohn.Forte@Sun.COM 		return (ret);
10027836SJohn.Forte@Sun.COM 
10037836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
10047836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
10057836SJohn.Forte@Sun.COM 		goto done;
10067836SJohn.Forte@Sun.COM 	}
10077836SJohn.Forte@Sun.COM 
10089585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
10099585STim.Szeto@Sun.COM 		goto done;
10109585STim.Szeto@Sun.COM 	}
10119585STim.Szeto@Sun.COM 
10127836SJohn.Forte@Sun.COM 	ret = psCreateHostGroup((char *)hostGroupName);
10137836SJohn.Forte@Sun.COM 	switch (ret) {
10147836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
10157836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
10167836SJohn.Forte@Sun.COM 			break;
10177836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
10187836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
10197836SJohn.Forte@Sun.COM 			break;
10207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
10217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
10227836SJohn.Forte@Sun.COM 			break;
10237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
10247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
10257836SJohn.Forte@Sun.COM 			break;
10267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
10277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
10287836SJohn.Forte@Sun.COM 			break;
10297836SJohn.Forte@Sun.COM 		default:
10307836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
10317836SJohn.Forte@Sun.COM 			    "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
10327836SJohn.Forte@Sun.COM 			    ret);
10337836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
10347836SJohn.Forte@Sun.COM 			break;
10357836SJohn.Forte@Sun.COM 	}
10367836SJohn.Forte@Sun.COM 
10377836SJohn.Forte@Sun.COM done:
10387836SJohn.Forte@Sun.COM 	(void) close(fd);
10397836SJohn.Forte@Sun.COM 	return (ret);
10407836SJohn.Forte@Sun.COM }
10417836SJohn.Forte@Sun.COM 
10427836SJohn.Forte@Sun.COM /*
10439585STim.Szeto@Sun.COM  * stmfCreateLu
10449585STim.Szeto@Sun.COM  *
10459585STim.Szeto@Sun.COM  * Purpose: Create a logical unit
10469585STim.Szeto@Sun.COM  *
10479585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
10489585STim.Szeto@Sun.COM  *
10499585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
10509585STim.Szeto@Sun.COM  *	    unit
10519585STim.Szeto@Sun.COM  */
10529585STim.Szeto@Sun.COM int
10539585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid)
10549585STim.Szeto@Sun.COM {
10559585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10569585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
10579585STim.Szeto@Sun.COM 
10589585STim.Szeto@Sun.COM 	if (hdl == NULL) {
10599585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10609585STim.Szeto@Sun.COM 	}
10619585STim.Szeto@Sun.COM 
10629585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
10639585STim.Szeto@Sun.COM 		ret = createDiskLu((diskResource *)luPropsHdl->resource,
10649585STim.Szeto@Sun.COM 		    luGuid);
10659585STim.Szeto@Sun.COM 	} else {
10669585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10679585STim.Szeto@Sun.COM 	}
10689585STim.Szeto@Sun.COM 
10699585STim.Szeto@Sun.COM 	return (ret);
10709585STim.Szeto@Sun.COM }
10719585STim.Szeto@Sun.COM 
10729585STim.Szeto@Sun.COM /*
10739585STim.Szeto@Sun.COM  * stmfCreateLuResource
10749585STim.Szeto@Sun.COM  *
10759585STim.Szeto@Sun.COM  * Purpose: Create resource handle for a logical unit
10769585STim.Szeto@Sun.COM  *
10779585STim.Szeto@Sun.COM  * dType - Type of logical unit resource to create
10789585STim.Szeto@Sun.COM  *	   Can be: STMF_DISK
10799585STim.Szeto@Sun.COM  *
10809585STim.Szeto@Sun.COM  * hdl - pointer to luResource
10819585STim.Szeto@Sun.COM  */
10829585STim.Szeto@Sun.COM int
10839585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl)
10849585STim.Szeto@Sun.COM {
10859585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10869585STim.Szeto@Sun.COM 
10879585STim.Szeto@Sun.COM 	if (dType != STMF_DISK || hdl == NULL) {
10889585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10899585STim.Szeto@Sun.COM 	}
10909585STim.Szeto@Sun.COM 
10919585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
10929585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
10939585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
10949585STim.Szeto@Sun.COM 	}
10959585STim.Szeto@Sun.COM 
10969585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
10979585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
10989585STim.Szeto@Sun.COM 		free(*hdl);
10999585STim.Szeto@Sun.COM 		return (ret);
11009585STim.Szeto@Sun.COM 	}
11019585STim.Szeto@Sun.COM 
11029585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
11039585STim.Szeto@Sun.COM }
11049585STim.Szeto@Sun.COM 
11059585STim.Szeto@Sun.COM /*
11069585STim.Szeto@Sun.COM  * Creates a disk logical unit
11079585STim.Szeto@Sun.COM  *
11089585STim.Szeto@Sun.COM  * disk - pointer to diskResource structure that represents the properties
11099585STim.Szeto@Sun.COM  *        for the disk logical unit to be created.
11109585STim.Szeto@Sun.COM  */
11119585STim.Szeto@Sun.COM static int
11129585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid)
11139585STim.Szeto@Sun.COM {
11149585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
11159585STim.Szeto@Sun.COM 	int dataFileNameLen = 0;
11169585STim.Szeto@Sun.COM 	int metaFileNameLen = 0;
11179585STim.Szeto@Sun.COM 	int serialNumLen = 0;
11189585STim.Szeto@Sun.COM 	int luAliasLen = 0;
111910113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
11209585STim.Szeto@Sun.COM 	int sluBufSize = 0;
11219585STim.Szeto@Sun.COM 	int bufOffset = 0;
11229585STim.Szeto@Sun.COM 	int fd = 0;
11239585STim.Szeto@Sun.COM 	int ioctlRet;
11249585STim.Szeto@Sun.COM 	int savedErrno;
11259585STim.Szeto@Sun.COM 	stmfGuid guid;
11269585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
11279585STim.Szeto@Sun.COM 
11289585STim.Szeto@Sun.COM 	sbd_create_and_reg_lu_t *sbdLu = NULL;
11299585STim.Szeto@Sun.COM 
11309585STim.Szeto@Sun.COM 	/*
11319585STim.Szeto@Sun.COM 	 * Open control node for sbd
11329585STim.Szeto@Sun.COM 	 */
11339585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
11349585STim.Szeto@Sun.COM 		return (ret);
11359585STim.Szeto@Sun.COM 
11369585STim.Szeto@Sun.COM 	/* data file name must be specified */
11379585STim.Szeto@Sun.COM 	if (disk->luDataFileNameValid) {
11389585STim.Szeto@Sun.COM 		dataFileNameLen = strlen(disk->luDataFileName);
11399585STim.Szeto@Sun.COM 	} else {
11409585STim.Szeto@Sun.COM 		(void) close(fd);
11419585STim.Szeto@Sun.COM 		return (STMF_ERROR_MISSING_PROP_VAL);
11429585STim.Szeto@Sun.COM 	}
11439585STim.Szeto@Sun.COM 
11449585STim.Szeto@Sun.COM 	sluBufSize += dataFileNameLen + 1;
11459585STim.Szeto@Sun.COM 
11469585STim.Szeto@Sun.COM 	if (disk->luMetaFileNameValid) {
11479585STim.Szeto@Sun.COM 		metaFileNameLen = strlen(disk->luMetaFileName);
11489585STim.Szeto@Sun.COM 		sluBufSize += metaFileNameLen + 1;
11499585STim.Szeto@Sun.COM 	}
11509585STim.Szeto@Sun.COM 
11519585STim.Szeto@Sun.COM 	serialNumLen = strlen(disk->serialNum);
11529585STim.Szeto@Sun.COM 	sluBufSize += serialNumLen;
11539585STim.Szeto@Sun.COM 
11549585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
11559585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
11569585STim.Szeto@Sun.COM 		sluBufSize += luAliasLen + 1;
11579585STim.Szeto@Sun.COM 	}
11589585STim.Szeto@Sun.COM 
115910113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
116010113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
116110113SNattuvetty.Bhavyan@Sun.COM 		sluBufSize += luMgmtUrlLen + 1;
116210113SNattuvetty.Bhavyan@Sun.COM 	}
116310113SNattuvetty.Bhavyan@Sun.COM 
11649585STim.Szeto@Sun.COM 	/*
11659585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
11669585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
11679585STim.Szeto@Sun.COM 	 */
11689585STim.Szeto@Sun.COM 	sbdLu = (sbd_create_and_reg_lu_t *)calloc(1,
11699585STim.Szeto@Sun.COM 	    sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8);
11709585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
11719585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
11729585STim.Szeto@Sun.COM 	}
11739585STim.Szeto@Sun.COM 
11749585STim.Szeto@Sun.COM 	sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) +
11759585STim.Szeto@Sun.COM 	    sluBufSize - 8;
11769585STim.Szeto@Sun.COM 
11779585STim.Szeto@Sun.COM 	if (metaFileNameLen) {
11789585STim.Szeto@Sun.COM 		sbdLu->slu_meta_fname_valid = 1;
11799585STim.Szeto@Sun.COM 		sbdLu->slu_meta_fname_off = bufOffset;
11809585STim.Szeto@Sun.COM 		bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]),
11819585STim.Szeto@Sun.COM 		    metaFileNameLen + 1);
11829585STim.Szeto@Sun.COM 		bufOffset += metaFileNameLen + 1;
11839585STim.Szeto@Sun.COM 	}
11849585STim.Szeto@Sun.COM 
11859585STim.Szeto@Sun.COM 	bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]),
11869585STim.Szeto@Sun.COM 	    dataFileNameLen + 1);
11879585STim.Szeto@Sun.COM 	sbdLu->slu_data_fname_off = bufOffset;
11889585STim.Szeto@Sun.COM 	bufOffset += dataFileNameLen + 1;
11899585STim.Szeto@Sun.COM 
11909585STim.Szeto@Sun.COM 	/* currently, serial # is not passed null terminated to the driver */
11919585STim.Szeto@Sun.COM 	if (disk->serialNumValid) {
11929585STim.Szeto@Sun.COM 		sbdLu->slu_serial_valid = 1;
11939585STim.Szeto@Sun.COM 		sbdLu->slu_serial_off = bufOffset;
11949585STim.Szeto@Sun.COM 		sbdLu->slu_serial_size = serialNumLen;
11959585STim.Szeto@Sun.COM 		bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]),
11969585STim.Szeto@Sun.COM 		    serialNumLen);
11979585STim.Szeto@Sun.COM 		bufOffset += serialNumLen;
11989585STim.Szeto@Sun.COM 	}
11999585STim.Szeto@Sun.COM 
12009585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
12019585STim.Szeto@Sun.COM 		sbdLu->slu_alias_valid = 1;
12029585STim.Szeto@Sun.COM 		sbdLu->slu_alias_off = bufOffset;
12039585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]),
12049585STim.Szeto@Sun.COM 		    luAliasLen + 1);
12059585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
12069585STim.Szeto@Sun.COM 	}
12079585STim.Szeto@Sun.COM 
120810113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
120910113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->slu_mgmt_url_valid = 1;
121010113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->slu_mgmt_url_off = bufOffset;
121110113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]),
121210113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
121310113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
121410113SNattuvetty.Bhavyan@Sun.COM 	}
121510113SNattuvetty.Bhavyan@Sun.COM 
12169585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
12179585STim.Szeto@Sun.COM 		sbdLu->slu_lu_size_valid = 1;
12189585STim.Szeto@Sun.COM 		sbdLu->slu_lu_size = disk->luSize;
12199585STim.Szeto@Sun.COM 	}
12209585STim.Szeto@Sun.COM 
12219585STim.Szeto@Sun.COM 	if (disk->luGuidValid) {
12229585STim.Szeto@Sun.COM 		sbdLu->slu_guid_valid = 1;
12239585STim.Szeto@Sun.COM 		bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid));
12249585STim.Szeto@Sun.COM 	}
12259585STim.Szeto@Sun.COM 
12269585STim.Szeto@Sun.COM 	if (disk->vidValid) {
12279585STim.Szeto@Sun.COM 		sbdLu->slu_vid_valid = 1;
12289585STim.Szeto@Sun.COM 		bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid));
12299585STim.Szeto@Sun.COM 	}
12309585STim.Szeto@Sun.COM 
12319585STim.Szeto@Sun.COM 	if (disk->pidValid) {
12329585STim.Szeto@Sun.COM 		sbdLu->slu_pid_valid = 1;
12339585STim.Szeto@Sun.COM 		bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid));
12349585STim.Szeto@Sun.COM 	}
12359585STim.Szeto@Sun.COM 
12369585STim.Szeto@Sun.COM 	if (disk->revValid) {
12379585STim.Szeto@Sun.COM 		sbdLu->slu_rev_valid = 1;
12389585STim.Szeto@Sun.COM 		bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev));
12399585STim.Szeto@Sun.COM 	}
12409585STim.Szeto@Sun.COM 
12419585STim.Szeto@Sun.COM 	if (disk->companyIdValid) {
12429585STim.Szeto@Sun.COM 		sbdLu->slu_company_id_valid = 1;
12439585STim.Szeto@Sun.COM 		sbdLu->slu_company_id = disk->companyId;
12449585STim.Szeto@Sun.COM 	}
12459585STim.Szeto@Sun.COM 
1246*10765SJohn.Forte@Sun.COM 	if (disk->hostIdValid) {
1247*10765SJohn.Forte@Sun.COM 		sbdLu->slu_host_id_valid = 1;
1248*10765SJohn.Forte@Sun.COM 		sbdLu->slu_host_id = disk->hostId;
1249*10765SJohn.Forte@Sun.COM 	}
1250*10765SJohn.Forte@Sun.COM 
12519585STim.Szeto@Sun.COM 	if (disk->blkSizeValid) {
12529585STim.Szeto@Sun.COM 		sbdLu->slu_blksize_valid = 1;
12539585STim.Szeto@Sun.COM 		sbdLu->slu_blksize = disk->blkSize;
12549585STim.Szeto@Sun.COM 	}
12559585STim.Szeto@Sun.COM 
12569585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
12579585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
12589585STim.Szeto@Sun.COM 			sbdLu->slu_write_protected = 1;
12599585STim.Szeto@Sun.COM 		}
12609585STim.Szeto@Sun.COM 	}
12619585STim.Szeto@Sun.COM 
12629585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
12639585STim.Szeto@Sun.COM 		sbdLu->slu_writeback_cache_disable_valid = 1;
12649585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
12659585STim.Szeto@Sun.COM 			sbdLu->slu_writeback_cache_disable = 1;
12669585STim.Szeto@Sun.COM 		}
12679585STim.Szeto@Sun.COM 	}
12689585STim.Szeto@Sun.COM 
12699585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
12709585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size;
12719585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
12729585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size;
12739585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
12749585STim.Szeto@Sun.COM 
12759585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl);
12769585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
12779585STim.Szeto@Sun.COM 		savedErrno = errno;
12789585STim.Szeto@Sun.COM 		switch (savedErrno) {
12799585STim.Szeto@Sun.COM 			case EBUSY:
12809585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
12819585STim.Szeto@Sun.COM 				break;
12829585STim.Szeto@Sun.COM 			case EPERM:
12839585STim.Szeto@Sun.COM 			case EACCES:
12849585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
12859585STim.Szeto@Sun.COM 				break;
12869585STim.Szeto@Sun.COM 			default:
12879585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
12889585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
12899585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
12909585STim.Szeto@Sun.COM 					"createDiskLu:ioctl "
12919585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
12929585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
12939585STim.Szeto@Sun.COM 				}
12949585STim.Szeto@Sun.COM 				break;
12959585STim.Szeto@Sun.COM 		}
12969585STim.Szeto@Sun.COM 	}
12979585STim.Szeto@Sun.COM 
12989585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
12999585STim.Szeto@Sun.COM 		goto done;
13009585STim.Szeto@Sun.COM 	}
13019585STim.Szeto@Sun.COM 
13029585STim.Szeto@Sun.COM 	/*
13039585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
13049585STim.Szeto@Sun.COM 	 * NULL
13059585STim.Szeto@Sun.COM 	 */
13069585STim.Szeto@Sun.COM 	if (createdGuid) {
13079585STim.Szeto@Sun.COM 		bcopy(sbdLu->slu_guid, createdGuid->guid,
13089585STim.Szeto@Sun.COM 		    sizeof (sbdLu->slu_guid));
13099585STim.Szeto@Sun.COM 	}
13109585STim.Szeto@Sun.COM 
13119585STim.Szeto@Sun.COM 	bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid));
13129585STim.Szeto@Sun.COM 	if (disk->luMetaFileNameValid) {
13139585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&guid, disk->luMetaFileName);
13149585STim.Szeto@Sun.COM 	} else {
13159585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&guid, disk->luDataFileName);
13169585STim.Szeto@Sun.COM 	}
13179585STim.Szeto@Sun.COM done:
13189585STim.Szeto@Sun.COM 	free(sbdLu);
13199585STim.Szeto@Sun.COM 	(void) close(fd);
13209585STim.Szeto@Sun.COM 	return (ret);
13219585STim.Szeto@Sun.COM }
13229585STim.Szeto@Sun.COM 
13239585STim.Szeto@Sun.COM 
13249585STim.Szeto@Sun.COM /*
13259585STim.Szeto@Sun.COM  * stmfImportLu
13269585STim.Szeto@Sun.COM  *
13279585STim.Szeto@Sun.COM  * Purpose: Import a previously created logical unit
13289585STim.Szeto@Sun.COM  *
13299585STim.Szeto@Sun.COM  * dType - Type of logical unit
13309585STim.Szeto@Sun.COM  *         Can be: STMF_DISK
13319585STim.Szeto@Sun.COM  *
13329585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the imported logical
13339585STim.Szeto@Sun.COM  *	    unit
13349585STim.Szeto@Sun.COM  *
13359585STim.Szeto@Sun.COM  * fname - A file name where the metadata resides
13369585STim.Szeto@Sun.COM  *
13379585STim.Szeto@Sun.COM  */
13389585STim.Szeto@Sun.COM int
13399585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid)
13409585STim.Szeto@Sun.COM {
13419585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
13429585STim.Szeto@Sun.COM 
13439585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
13449585STim.Szeto@Sun.COM 		ret = importDiskLu(fname, luGuid);
13459585STim.Szeto@Sun.COM 	} else {
13469585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13479585STim.Szeto@Sun.COM 	}
13489585STim.Szeto@Sun.COM 
13499585STim.Szeto@Sun.COM 	return (ret);
13509585STim.Szeto@Sun.COM }
13519585STim.Szeto@Sun.COM 
13529585STim.Szeto@Sun.COM /*
13539585STim.Szeto@Sun.COM  * importDiskLu
13549585STim.Szeto@Sun.COM  *
13559585STim.Szeto@Sun.COM  * filename - filename to import
13569585STim.Szeto@Sun.COM  * createdGuid - if not NULL, on success contains the imported guid
13579585STim.Szeto@Sun.COM  *
13589585STim.Szeto@Sun.COM  */
13599585STim.Szeto@Sun.COM static int
13609585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid)
13619585STim.Szeto@Sun.COM {
13629585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
13639585STim.Szeto@Sun.COM 	int fd = 0;
13649585STim.Szeto@Sun.COM 	int ioctlRet;
13659585STim.Szeto@Sun.COM 	int savedErrno;
13669585STim.Szeto@Sun.COM 	int metaFileNameLen;
13679585STim.Szeto@Sun.COM 	stmfGuid iGuid;
13689585STim.Szeto@Sun.COM 	int iluBufSize = 0;
13699585STim.Szeto@Sun.COM 	sbd_import_lu_t *sbdLu = NULL;
13709585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
13719585STim.Szeto@Sun.COM 
13729585STim.Szeto@Sun.COM 	if (fname == NULL) {
13739585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13749585STim.Szeto@Sun.COM 	}
13759585STim.Szeto@Sun.COM 
13769585STim.Szeto@Sun.COM 	/*
13779585STim.Szeto@Sun.COM 	 * Open control node for sbd
13789585STim.Szeto@Sun.COM 	 */
13799585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
13809585STim.Szeto@Sun.COM 		return (ret);
13819585STim.Szeto@Sun.COM 
13829585STim.Szeto@Sun.COM 	metaFileNameLen = strlen(fname);
13839585STim.Szeto@Sun.COM 	iluBufSize += metaFileNameLen + 1;
13849585STim.Szeto@Sun.COM 
13859585STim.Szeto@Sun.COM 	/*
13869585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
13879585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
13889585STim.Szeto@Sun.COM 	 */
13899585STim.Szeto@Sun.COM 	sbdLu = (sbd_import_lu_t *)calloc(1,
13909585STim.Szeto@Sun.COM 	    sizeof (sbd_import_lu_t) + iluBufSize - 8);
13919585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
13929585STim.Szeto@Sun.COM 		(void) close(fd);
13939585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
13949585STim.Szeto@Sun.COM 	}
13959585STim.Szeto@Sun.COM 
13969585STim.Szeto@Sun.COM 	/*
13979585STim.Szeto@Sun.COM 	 * Accept either a data file or meta data file.
13989585STim.Szeto@Sun.COM 	 * sbd will do the right thing here either way.
13999585STim.Szeto@Sun.COM 	 * i.e. if it's a data file, it assumes that the
14009585STim.Szeto@Sun.COM 	 * meta data is shared with the data.
14019585STim.Szeto@Sun.COM 	 */
14029585STim.Szeto@Sun.COM 	(void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen);
14039585STim.Szeto@Sun.COM 
14049585STim.Szeto@Sun.COM 	sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8;
14059585STim.Szeto@Sun.COM 
14069585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
14079585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size;
14089585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
14099585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size;
14109585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
14119585STim.Szeto@Sun.COM 
14129585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl);
14139585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
14149585STim.Szeto@Sun.COM 		savedErrno = errno;
14159585STim.Szeto@Sun.COM 		switch (savedErrno) {
14169585STim.Szeto@Sun.COM 			case EBUSY:
14179585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
14189585STim.Szeto@Sun.COM 				break;
14199585STim.Szeto@Sun.COM 			case EPERM:
14209585STim.Szeto@Sun.COM 			case EACCES:
14219585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
14229585STim.Szeto@Sun.COM 				break;
14239585STim.Szeto@Sun.COM 			default:
14249585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
14259585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
14269585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
14279585STim.Szeto@Sun.COM 					"importDiskLu:ioctl "
14289585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
14299585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
14309585STim.Szeto@Sun.COM 				}
14319585STim.Szeto@Sun.COM 				break;
14329585STim.Szeto@Sun.COM 		}
14339585STim.Szeto@Sun.COM 	}
14349585STim.Szeto@Sun.COM 
14359585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
14369585STim.Szeto@Sun.COM 		goto done;
14379585STim.Szeto@Sun.COM 	}
14389585STim.Szeto@Sun.COM 
14399585STim.Szeto@Sun.COM 	/*
14409585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
14419585STim.Szeto@Sun.COM 	 * NULL and add it to the persistent store for sbd
14429585STim.Szeto@Sun.COM 	 */
14439585STim.Szeto@Sun.COM 	if (createdGuid) {
14449585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
14459585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14469585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(createdGuid, fname);
14479585STim.Szeto@Sun.COM 	} else {
14489585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
14499585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14509585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&iGuid, fname);
14519585STim.Szeto@Sun.COM 	}
14529585STim.Szeto@Sun.COM done:
14539585STim.Szeto@Sun.COM 	free(sbdLu);
14549585STim.Szeto@Sun.COM 	(void) close(fd);
14559585STim.Szeto@Sun.COM 	return (ret);
14569585STim.Szeto@Sun.COM }
14579585STim.Szeto@Sun.COM 
14589585STim.Szeto@Sun.COM /*
14599585STim.Szeto@Sun.COM  * diskError
14609585STim.Szeto@Sun.COM  *
14619585STim.Szeto@Sun.COM  * Purpose: Translate sbd driver error
14629585STim.Szeto@Sun.COM  */
14639585STim.Szeto@Sun.COM static void
14649585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret)
14659585STim.Szeto@Sun.COM {
14669585STim.Szeto@Sun.COM 	switch (stmfError) {
14679585STim.Szeto@Sun.COM 		case SBD_RET_META_CREATION_FAILED:
14689585STim.Szeto@Sun.COM 		case SBD_RET_ZFS_META_CREATE_FAILED:
14699585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_CREATION;
14709585STim.Szeto@Sun.COM 			break;
14719585STim.Szeto@Sun.COM 		case SBD_RET_INVALID_BLKSIZE:
14729585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_INVALID_BLKSIZE;
14739585STim.Szeto@Sun.COM 			break;
14749585STim.Szeto@Sun.COM 		case SBD_RET_FILE_ALREADY_REGISTERED:
14759585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_IN_USE;
14769585STim.Szeto@Sun.COM 			break;
14779585STim.Szeto@Sun.COM 		case SBD_RET_GUID_ALREADY_REGISTERED:
14789585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_GUID_IN_USE;
14799585STim.Szeto@Sun.COM 			break;
14809585STim.Szeto@Sun.COM 		case SBD_RET_META_PATH_NOT_ABSOLUTE:
14819585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_LOOKUP_FAILED:
14829585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_OPEN_FAILED:
14839585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_GETATTR_FAILED:
14849585STim.Szeto@Sun.COM 		case SBD_RET_NO_META:
14859585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_FILE_NAME;
14869585STim.Szeto@Sun.COM 			break;
14879585STim.Szeto@Sun.COM 		case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
14889585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_LOOKUP_FAILED:
14899585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_OPEN_FAILED:
14909585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_GETATTR_FAILED:
14919585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_DATA_FILE_NAME;
14929585STim.Szeto@Sun.COM 			break;
14939585STim.Szeto@Sun.COM 		case SBD_RET_FILE_SIZE_ERROR:
14949585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_SIZE_INVALID;
14959585STim.Szeto@Sun.COM 			break;
14969585STim.Szeto@Sun.COM 		case SBD_RET_SIZE_OUT_OF_RANGE:
14979585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
14989585STim.Szeto@Sun.COM 			break;
14999585STim.Szeto@Sun.COM 		case SBD_RET_LU_BUSY:
15009585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_LU_BUSY;
15019585STim.Szeto@Sun.COM 			break;
15029585STim.Szeto@Sun.COM 		case SBD_RET_WRITE_CACHE_SET_FAILED:
15039585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_WRITE_CACHE_SET;
15049585STim.Szeto@Sun.COM 			break;
150510725SJohn.Forte@Sun.COM 		case SBD_RET_ACCESS_STATE_FAILED:
150610725SJohn.Forte@Sun.COM 			*ret = STMF_ERROR_ACCESS_STATE_SET;
150710725SJohn.Forte@Sun.COM 			break;
15089585STim.Szeto@Sun.COM 		default:
15099585STim.Szeto@Sun.COM 			*ret = STMF_STATUS_ERROR;
15109585STim.Szeto@Sun.COM 			break;
15119585STim.Szeto@Sun.COM 	}
15129585STim.Szeto@Sun.COM }
15139585STim.Szeto@Sun.COM 
15149585STim.Szeto@Sun.COM /*
15159585STim.Szeto@Sun.COM  * Creates a logical unit resource of type STMF_DISK.
15169585STim.Szeto@Sun.COM  *
15179585STim.Szeto@Sun.COM  * No defaults should be set here as all defaults are derived from the
15189585STim.Szeto@Sun.COM  * driver's default settings.
15199585STim.Szeto@Sun.COM  */
15209585STim.Szeto@Sun.COM static int
15219585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl)
15229585STim.Szeto@Sun.COM {
15239585STim.Szeto@Sun.COM 	hdl->type = STMF_DISK;
15249585STim.Szeto@Sun.COM 
15259585STim.Szeto@Sun.COM 	hdl->resource = calloc(1, sizeof (diskResource));
15269585STim.Szeto@Sun.COM 	if (hdl->resource == NULL) {
15279585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
15289585STim.Szeto@Sun.COM 	}
15299585STim.Szeto@Sun.COM 
15309585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
15319585STim.Szeto@Sun.COM }
15329585STim.Szeto@Sun.COM 
15339585STim.Szeto@Sun.COM /*
15349585STim.Szeto@Sun.COM  * stmfDeleteLu
15359585STim.Szeto@Sun.COM  *
15369585STim.Szeto@Sun.COM  * Purpose: Delete a logical unit
15379585STim.Szeto@Sun.COM  *
15389585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
15399585STim.Szeto@Sun.COM  *
15409585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
15419585STim.Szeto@Sun.COM  *	    unit
15429585STim.Szeto@Sun.COM  */
15439585STim.Szeto@Sun.COM int
15449585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid)
15459585STim.Szeto@Sun.COM {
15469585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15479585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
15489585STim.Szeto@Sun.COM 
15499585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
15509585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
15519585STim.Szeto@Sun.COM 	}
15529585STim.Szeto@Sun.COM 
15539585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
15549585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
15559585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
15569585STim.Szeto@Sun.COM 		return (ret);
15579585STim.Szeto@Sun.COM 	} else {
15589585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
15599585STim.Szeto@Sun.COM 			ret = deleteDiskLu(luGuid);
15609585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
15619585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
15629585STim.Szeto@Sun.COM 		} else {
15639585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
15649585STim.Szeto@Sun.COM 		}
15659585STim.Szeto@Sun.COM 	}
15669585STim.Szeto@Sun.COM 
15679585STim.Szeto@Sun.COM 	return (ret);
15689585STim.Szeto@Sun.COM }
15699585STim.Szeto@Sun.COM 
15709585STim.Szeto@Sun.COM static int
15719585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid)
15729585STim.Szeto@Sun.COM {
15739585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15749585STim.Szeto@Sun.COM 	int fd;
15759585STim.Szeto@Sun.COM 	int savedErrno;
15769585STim.Szeto@Sun.COM 	int ioctlRet;
15779585STim.Szeto@Sun.COM 	sbd_delete_lu_t deleteLu = {0};
15789585STim.Szeto@Sun.COM 
15799585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
15809585STim.Szeto@Sun.COM 
15819585STim.Szeto@Sun.COM 	/*
15829585STim.Szeto@Sun.COM 	 * Open control node for sbd
15839585STim.Szeto@Sun.COM 	 */
15849585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
15859585STim.Szeto@Sun.COM 		return (ret);
15869585STim.Szeto@Sun.COM 
15879585STim.Szeto@Sun.COM 	ret = removeGuidFromDiskStore(luGuid);
15889585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
15899585STim.Szeto@Sun.COM 		goto done;
15909585STim.Szeto@Sun.COM 	}
15919585STim.Szeto@Sun.COM 
15929585STim.Szeto@Sun.COM 	bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
15939585STim.Szeto@Sun.COM 	deleteLu.dlu_by_guid = 1;
15949585STim.Szeto@Sun.COM 
15959585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
15969585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
15979585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
15989585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
15999585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
16009585STim.Szeto@Sun.COM 		savedErrno = errno;
16019585STim.Szeto@Sun.COM 		switch (savedErrno) {
16029585STim.Szeto@Sun.COM 			case EBUSY:
16039585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
16049585STim.Szeto@Sun.COM 				break;
16059585STim.Szeto@Sun.COM 			case EPERM:
16069585STim.Szeto@Sun.COM 			case EACCES:
16079585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
16089585STim.Szeto@Sun.COM 				break;
16099585STim.Szeto@Sun.COM 			case ENOENT:
16109585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
16119585STim.Szeto@Sun.COM 				break;
16129585STim.Szeto@Sun.COM 			default:
16139585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
16149585STim.Szeto@Sun.COM 				    "deleteDiskLu:ioctl error(%d) (%d) (%d)",
16159585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
16169585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
16179585STim.Szeto@Sun.COM 				break;
16189585STim.Szeto@Sun.COM 		}
16199585STim.Szeto@Sun.COM 	}
16209585STim.Szeto@Sun.COM 
16219585STim.Szeto@Sun.COM done:
16229585STim.Szeto@Sun.COM 	(void) close(fd);
16239585STim.Szeto@Sun.COM 	return (ret);
16249585STim.Szeto@Sun.COM }
16259585STim.Szeto@Sun.COM 
16269585STim.Szeto@Sun.COM /*
162710725SJohn.Forte@Sun.COM  * stmfLuStandby
162810725SJohn.Forte@Sun.COM  *
162910725SJohn.Forte@Sun.COM  * Purpose: Sets access state to standby
163010725SJohn.Forte@Sun.COM  *
163110725SJohn.Forte@Sun.COM  * luGuid - guid of registered logical unit
163210725SJohn.Forte@Sun.COM  *
163310725SJohn.Forte@Sun.COM  */
163410725SJohn.Forte@Sun.COM int
163510725SJohn.Forte@Sun.COM stmfLuStandby(stmfGuid *luGuid)
163610725SJohn.Forte@Sun.COM {
163710725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
163810725SJohn.Forte@Sun.COM 	stmfLogicalUnitProperties luProps;
163910725SJohn.Forte@Sun.COM 
164010725SJohn.Forte@Sun.COM 	if (luGuid == NULL) {
164110725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
164210725SJohn.Forte@Sun.COM 	}
164310725SJohn.Forte@Sun.COM 
164410725SJohn.Forte@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
164510725SJohn.Forte@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
164610725SJohn.Forte@Sun.COM 	    != STMF_STATUS_SUCCESS) {
164710725SJohn.Forte@Sun.COM 		return (ret);
164810725SJohn.Forte@Sun.COM 	} else {
164910725SJohn.Forte@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
165010725SJohn.Forte@Sun.COM 			ret = setDiskStandby(luGuid);
165110725SJohn.Forte@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
165210725SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
165310725SJohn.Forte@Sun.COM 		} else {
165410725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
165510725SJohn.Forte@Sun.COM 		}
165610725SJohn.Forte@Sun.COM 	}
165710725SJohn.Forte@Sun.COM 
165810725SJohn.Forte@Sun.COM 	return (ret);
165910725SJohn.Forte@Sun.COM }
166010725SJohn.Forte@Sun.COM 
166110725SJohn.Forte@Sun.COM static int
166210725SJohn.Forte@Sun.COM setDiskStandby(stmfGuid *luGuid)
166310725SJohn.Forte@Sun.COM {
166410725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
166510725SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
166610725SJohn.Forte@Sun.COM 	sbd_set_lu_standby_t sbdLu = {0};
166710725SJohn.Forte@Sun.COM 	int ioctlRet;
166810725SJohn.Forte@Sun.COM 	int savedErrno;
166910725SJohn.Forte@Sun.COM 	int fd = 0;
167010725SJohn.Forte@Sun.COM 
167110725SJohn.Forte@Sun.COM 	/*
167210725SJohn.Forte@Sun.COM 	 * Open control node for sbd
167310725SJohn.Forte@Sun.COM 	 */
167410725SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
167510725SJohn.Forte@Sun.COM 		return (ret);
167610725SJohn.Forte@Sun.COM 
167710725SJohn.Forte@Sun.COM 	bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid));
167810725SJohn.Forte@Sun.COM 
167910725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
168010725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t);
168110725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu;
168210725SJohn.Forte@Sun.COM 
168310725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl);
168410725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
168510725SJohn.Forte@Sun.COM 		savedErrno = errno;
168610725SJohn.Forte@Sun.COM 		switch (savedErrno) {
168710725SJohn.Forte@Sun.COM 			case EBUSY:
168810725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
168910725SJohn.Forte@Sun.COM 				break;
169010725SJohn.Forte@Sun.COM 			case EPERM:
169110725SJohn.Forte@Sun.COM 			case EACCES:
169210725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
169310725SJohn.Forte@Sun.COM 				break;
169410725SJohn.Forte@Sun.COM 			default:
169510725SJohn.Forte@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
169610725SJohn.Forte@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
169710725SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
169810725SJohn.Forte@Sun.COM 					"setDiskStandby:ioctl "
169910725SJohn.Forte@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
170010725SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
170110725SJohn.Forte@Sun.COM 				}
170210725SJohn.Forte@Sun.COM 				break;
170310725SJohn.Forte@Sun.COM 		}
170410725SJohn.Forte@Sun.COM 	}
170510725SJohn.Forte@Sun.COM 	return (ret);
170610725SJohn.Forte@Sun.COM }
170710725SJohn.Forte@Sun.COM 
170810725SJohn.Forte@Sun.COM /*
17099585STim.Szeto@Sun.COM  * stmfModifyLu
17109585STim.Szeto@Sun.COM  *
17119585STim.Szeto@Sun.COM  * Purpose: Modify properties of a logical unit
17129585STim.Szeto@Sun.COM  *
17139585STim.Szeto@Sun.COM  * luGuid - guid of registered logical unit
17149585STim.Szeto@Sun.COM  * prop - property to modify
17159585STim.Szeto@Sun.COM  * propVal - property value to set
17169585STim.Szeto@Sun.COM  *
17179585STim.Szeto@Sun.COM  */
17189585STim.Szeto@Sun.COM int
17199585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
17209585STim.Szeto@Sun.COM {
17219585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17229585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
17239585STim.Szeto@Sun.COM 
17249585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
17259585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17269585STim.Szeto@Sun.COM 	}
17279585STim.Szeto@Sun.COM 
17289585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
17299585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
17309585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
17319585STim.Szeto@Sun.COM 		return (ret);
17329585STim.Szeto@Sun.COM 	} else {
17339585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
17349585STim.Szeto@Sun.COM 			ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
17359585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
17369585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
17379585STim.Szeto@Sun.COM 		} else {
17389585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
17399585STim.Szeto@Sun.COM 		}
17409585STim.Szeto@Sun.COM 	}
17419585STim.Szeto@Sun.COM 
17429585STim.Szeto@Sun.COM 	return (ret);
17439585STim.Szeto@Sun.COM }
17449585STim.Szeto@Sun.COM 
17459585STim.Szeto@Sun.COM /*
17469585STim.Szeto@Sun.COM  * stmfModifyLuByFname
17479585STim.Szeto@Sun.COM  *
17489585STim.Szeto@Sun.COM  * Purpose: Modify a device by filename. Device does not need to be registered.
17499585STim.Szeto@Sun.COM  *
17509585STim.Szeto@Sun.COM  * dType - type of device to modify
17519585STim.Szeto@Sun.COM  *         STMF_DISK
17529585STim.Szeto@Sun.COM  *
17539585STim.Szeto@Sun.COM  * fname - filename or meta filename
17549585STim.Szeto@Sun.COM  * prop - valid property identifier
17559585STim.Szeto@Sun.COM  * propVal - property value
17569585STim.Szeto@Sun.COM  *
17579585STim.Szeto@Sun.COM  */
17589585STim.Szeto@Sun.COM int
17599585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
17609585STim.Szeto@Sun.COM     const char *propVal)
17619585STim.Szeto@Sun.COM {
17629585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17639585STim.Szeto@Sun.COM 	if (fname == NULL) {
17649585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17659585STim.Szeto@Sun.COM 	}
17669585STim.Szeto@Sun.COM 
17679585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
17689585STim.Szeto@Sun.COM 		ret = modifyDiskLuProp(NULL, fname, prop, propVal);
17699585STim.Szeto@Sun.COM 	} else {
17709585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17719585STim.Szeto@Sun.COM 	}
17729585STim.Szeto@Sun.COM 
17739585STim.Szeto@Sun.COM 	return (ret);
17749585STim.Szeto@Sun.COM }
17759585STim.Szeto@Sun.COM 
17769585STim.Szeto@Sun.COM static int
17779585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
17789585STim.Szeto@Sun.COM     const char *propVal)
17799585STim.Szeto@Sun.COM {
17809585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17819585STim.Szeto@Sun.COM 	luResource hdl = NULL;
17829585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl;
17839585STim.Szeto@Sun.COM 
17849585STim.Szeto@Sun.COM 	ret = stmfCreateLuResource(STMF_DISK, &hdl);
17859585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17869585STim.Szeto@Sun.COM 		return (ret);
17879585STim.Szeto@Sun.COM 	}
17889585STim.Szeto@Sun.COM 	ret = validateModifyDiskProp(prop);
17899585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17909585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
17919585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_PROP);
17929585STim.Szeto@Sun.COM 	}
17939585STim.Szeto@Sun.COM 	ret = stmfSetLuProp(hdl, prop, propVal);
17949585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17959585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
17969585STim.Szeto@Sun.COM 		return (ret);
17979585STim.Szeto@Sun.COM 	}
17989585STim.Szeto@Sun.COM 	luPropsHdl = hdl;
17999585STim.Szeto@Sun.COM 	ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
18009585STim.Szeto@Sun.COM 	(void) stmfFreeLuResource(hdl);
18019585STim.Szeto@Sun.COM 	return (ret);
18029585STim.Szeto@Sun.COM }
18039585STim.Szeto@Sun.COM 
18049585STim.Szeto@Sun.COM static int
18059585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop)
18069585STim.Szeto@Sun.COM {
18079585STim.Szeto@Sun.COM 	switch (prop) {
18089585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
18099585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
181010113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
18119585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
18129585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
18139585STim.Szeto@Sun.COM 			return (STMF_STATUS_SUCCESS);
18149585STim.Szeto@Sun.COM 			break;
18159585STim.Szeto@Sun.COM 		default:
18169585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
18179585STim.Szeto@Sun.COM 			break;
18189585STim.Szeto@Sun.COM 	}
18199585STim.Szeto@Sun.COM }
18209585STim.Szeto@Sun.COM 
18219585STim.Szeto@Sun.COM static int
18229585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
18239585STim.Szeto@Sun.COM {
18249585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
18259585STim.Szeto@Sun.COM 	int luAliasLen = 0;
182610113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
18279585STim.Szeto@Sun.COM 	int mluBufSize = 0;
18289585STim.Szeto@Sun.COM 	int bufOffset = 0;
18299585STim.Szeto@Sun.COM 	int fd = 0;
18309585STim.Szeto@Sun.COM 	int ioctlRet;
18319585STim.Szeto@Sun.COM 	int savedErrno;
18329585STim.Szeto@Sun.COM 	int fnameSize = 0;
18339585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
18349585STim.Szeto@Sun.COM 
18359585STim.Szeto@Sun.COM 	sbd_modify_lu_t *sbdLu = NULL;
18369585STim.Szeto@Sun.COM 
18379585STim.Szeto@Sun.COM 	if (luGuid == NULL && fname == NULL) {
18389585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
18399585STim.Szeto@Sun.COM 	}
18409585STim.Szeto@Sun.COM 
18419585STim.Szeto@Sun.COM 	if (fname) {
18429585STim.Szeto@Sun.COM 		fnameSize = strlen(fname) + 1;
18439585STim.Szeto@Sun.COM 		mluBufSize += fnameSize;
18449585STim.Szeto@Sun.COM 	}
18459585STim.Szeto@Sun.COM 
18469585STim.Szeto@Sun.COM 	/*
18479585STim.Szeto@Sun.COM 	 * Open control node for sbd
18489585STim.Szeto@Sun.COM 	 */
18499585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
18509585STim.Szeto@Sun.COM 		return (ret);
18519585STim.Szeto@Sun.COM 
18529585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18539585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
18549585STim.Szeto@Sun.COM 		mluBufSize += luAliasLen + 1;
18559585STim.Szeto@Sun.COM 	}
18569585STim.Szeto@Sun.COM 
185710113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
185810113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
185910113SNattuvetty.Bhavyan@Sun.COM 		mluBufSize += luMgmtUrlLen + 1;
186010113SNattuvetty.Bhavyan@Sun.COM 	}
186110113SNattuvetty.Bhavyan@Sun.COM 
18629585STim.Szeto@Sun.COM 	/*
18639585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
18649585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
18659585STim.Szeto@Sun.COM 	 */
18669585STim.Szeto@Sun.COM 	sbdLu = (sbd_modify_lu_t *)calloc(1,
18679585STim.Szeto@Sun.COM 	    sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
18689585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
18699585STim.Szeto@Sun.COM 		(void) close(fd);
18709585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
18719585STim.Szeto@Sun.COM 	}
18729585STim.Szeto@Sun.COM 
18739585STim.Szeto@Sun.COM 	sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
18749585STim.Szeto@Sun.COM 	    mluBufSize - 8 + fnameSize;
18759585STim.Szeto@Sun.COM 
18769585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18779585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_valid = 1;
18789585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_off = bufOffset;
18799585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
18809585STim.Szeto@Sun.COM 		    luAliasLen + 1);
18819585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
18829585STim.Szeto@Sun.COM 	}
18839585STim.Szeto@Sun.COM 
188410113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
188510113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_valid = 1;
188610113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_off = bufOffset;
188710113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
188810113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
188910113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
189010113SNattuvetty.Bhavyan@Sun.COM 	}
189110113SNattuvetty.Bhavyan@Sun.COM 
18929585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
18939585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size_valid = 1;
18949585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size = disk->luSize;
18959585STim.Szeto@Sun.COM 	}
18969585STim.Szeto@Sun.COM 
18979585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
18989585STim.Szeto@Sun.COM 		sbdLu->mlu_write_protected_valid = 1;
18999585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
19009585STim.Szeto@Sun.COM 			sbdLu->mlu_write_protected = 1;
19019585STim.Szeto@Sun.COM 		}
19029585STim.Szeto@Sun.COM 	}
19039585STim.Szeto@Sun.COM 
19049585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
19059585STim.Szeto@Sun.COM 		sbdLu->mlu_writeback_cache_disable_valid = 1;
19069585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
19079585STim.Szeto@Sun.COM 			sbdLu->mlu_writeback_cache_disable = 1;
19089585STim.Szeto@Sun.COM 		}
19099585STim.Szeto@Sun.COM 	}
19109585STim.Szeto@Sun.COM 
19119585STim.Szeto@Sun.COM 	if (luGuid) {
19129585STim.Szeto@Sun.COM 		bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
19139585STim.Szeto@Sun.COM 		sbdLu->mlu_by_guid = 1;
19149585STim.Szeto@Sun.COM 	} else {
19159585STim.Szeto@Sun.COM 		sbdLu->mlu_fname_off = bufOffset;
19169585STim.Szeto@Sun.COM 		bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
19179585STim.Szeto@Sun.COM 		sbdLu->mlu_by_fname = 1;
19189585STim.Szeto@Sun.COM 	}
19199585STim.Szeto@Sun.COM 
19209585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
19219585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
19229585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
19239585STim.Szeto@Sun.COM 
19249585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
19259585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
19269585STim.Szeto@Sun.COM 		savedErrno = errno;
19279585STim.Szeto@Sun.COM 		switch (savedErrno) {
19289585STim.Szeto@Sun.COM 			case EBUSY:
19299585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
19309585STim.Szeto@Sun.COM 				break;
19319585STim.Szeto@Sun.COM 			case EPERM:
19329585STim.Szeto@Sun.COM 			case EACCES:
19339585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
19349585STim.Szeto@Sun.COM 				break;
19359585STim.Szeto@Sun.COM 			default:
19369585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
19379585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
19389585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
19399585STim.Szeto@Sun.COM 					"modifyDiskLu:ioctl "
19409585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
19419585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
19429585STim.Szeto@Sun.COM 				}
19439585STim.Szeto@Sun.COM 				break;
19449585STim.Szeto@Sun.COM 		}
19459585STim.Szeto@Sun.COM 	}
19469585STim.Szeto@Sun.COM 
19479585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
19489585STim.Szeto@Sun.COM 		goto done;
19499585STim.Szeto@Sun.COM 	}
19509585STim.Szeto@Sun.COM 
19519585STim.Szeto@Sun.COM done:
19529585STim.Szeto@Sun.COM 	free(sbdLu);
19539585STim.Szeto@Sun.COM 	(void) close(fd);
19549585STim.Szeto@Sun.COM 	return (ret);
19559585STim.Szeto@Sun.COM }
19569585STim.Szeto@Sun.COM 
19579585STim.Szeto@Sun.COM /*
19589585STim.Szeto@Sun.COM  * removeGuidFromDiskStore
19599585STim.Szeto@Sun.COM  *
19609585STim.Szeto@Sun.COM  * Purpose: delete a logical unit from the sbd provider data
19619585STim.Szeto@Sun.COM  */
19629585STim.Szeto@Sun.COM static int
19639585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid)
19649585STim.Szeto@Sun.COM {
19659585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, NULL, B_FALSE));
19669585STim.Szeto@Sun.COM }
19679585STim.Szeto@Sun.COM 
19689585STim.Szeto@Sun.COM 
19699585STim.Szeto@Sun.COM /*
19709585STim.Szeto@Sun.COM  * addGuidToDiskStore
19719585STim.Szeto@Sun.COM  *
19729585STim.Szeto@Sun.COM  * Purpose: add a logical unit to the sbd provider data
19739585STim.Szeto@Sun.COM  */
19749585STim.Szeto@Sun.COM static int
19759585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename)
19769585STim.Szeto@Sun.COM {
19779585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, filename, B_TRUE));
19789585STim.Szeto@Sun.COM }
19799585STim.Szeto@Sun.COM 
19809585STim.Szeto@Sun.COM 
19819585STim.Szeto@Sun.COM /*
19829585STim.Szeto@Sun.COM  * persistDiskGuid
19839585STim.Szeto@Sun.COM  *
19849585STim.Szeto@Sun.COM  * Purpose: Persist or unpersist a guid for the sbd provider data
19859585STim.Szeto@Sun.COM  *
19869585STim.Szeto@Sun.COM  */
19879585STim.Szeto@Sun.COM static int
19889585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
19899585STim.Szeto@Sun.COM {
19909585STim.Szeto@Sun.COM 	char	    guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
19919585STim.Szeto@Sun.COM 	nvlist_t    *nvl = NULL;
19929585STim.Szeto@Sun.COM 
19939585STim.Szeto@Sun.COM 	uint64_t    setToken;
19949585STim.Szeto@Sun.COM 	boolean_t   retryGetProviderData = B_FALSE;
19959585STim.Szeto@Sun.COM 	boolean_t   newData = B_FALSE;
19969585STim.Szeto@Sun.COM 	int	    ret = STMF_STATUS_SUCCESS;
19979585STim.Szeto@Sun.COM 	int	    retryCnt = 0;
19989585STim.Szeto@Sun.COM 	int	    stmfRet;
19999585STim.Szeto@Sun.COM 
20009585STim.Szeto@Sun.COM 	/* if we're persisting a guid, there must be a filename */
20019585STim.Szeto@Sun.COM 	if (persist && !filename) {
20029585STim.Szeto@Sun.COM 		return (1);
20039585STim.Szeto@Sun.COM 	}
20049585STim.Szeto@Sun.COM 
20059585STim.Szeto@Sun.COM 	/* guid is stored in lowercase ascii hex */
20069585STim.Szeto@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
20079585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
20089585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x",
20099585STim.Szeto@Sun.COM 	    guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
20109585STim.Szeto@Sun.COM 	    guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
20119585STim.Szeto@Sun.COM 	    guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
20129585STim.Szeto@Sun.COM 	    guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
20139585STim.Szeto@Sun.COM 
20149585STim.Szeto@Sun.COM 
20159585STim.Szeto@Sun.COM 	do {
20169585STim.Szeto@Sun.COM 		retryGetProviderData = B_FALSE;
20179585STim.Szeto@Sun.COM 		stmfRet = stmfGetProviderDataProt("sbd", &nvl,
20189585STim.Szeto@Sun.COM 		    STMF_LU_PROVIDER_TYPE, &setToken);
20199585STim.Szeto@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
20209585STim.Szeto@Sun.COM 			if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
20219585STim.Szeto@Sun.COM 				ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
20229585STim.Szeto@Sun.COM 				if (ret != 0) {
20239585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20249585STim.Szeto@Sun.COM 					    "unpersistGuid:nvlist_alloc(%d)",
20259585STim.Szeto@Sun.COM 					    ret);
20269585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
20279585STim.Szeto@Sun.COM 					goto done;
20289585STim.Szeto@Sun.COM 				}
20299585STim.Szeto@Sun.COM 				newData = B_TRUE;
20309585STim.Szeto@Sun.COM 			} else {
203110725SJohn.Forte@Sun.COM 				/*
203210725SJohn.Forte@Sun.COM 				 * if we're persisting the data, it's
203310725SJohn.Forte@Sun.COM 				 * an error. Otherwise, just return
203410725SJohn.Forte@Sun.COM 				 */
203510725SJohn.Forte@Sun.COM 				if (persist) {
203610725SJohn.Forte@Sun.COM 					ret = stmfRet;
203710725SJohn.Forte@Sun.COM 				}
20389585STim.Szeto@Sun.COM 				goto done;
20399585STim.Szeto@Sun.COM 			}
20409585STim.Szeto@Sun.COM 		}
20419585STim.Szeto@Sun.COM 		if (persist) {
20429585STim.Szeto@Sun.COM 			ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
20439585STim.Szeto@Sun.COM 		} else {
20449585STim.Szeto@Sun.COM 			ret = nvlist_remove(nvl, guidAsciiBuf,
20459585STim.Szeto@Sun.COM 			    DATA_TYPE_STRING);
20469585STim.Szeto@Sun.COM 			if (ret == ENOENT) {
20479585STim.Szeto@Sun.COM 				ret = 0;
20489585STim.Szeto@Sun.COM 			}
20499585STim.Szeto@Sun.COM 		}
20509585STim.Szeto@Sun.COM 		if (ret == 0) {
20519585STim.Szeto@Sun.COM 			if (newData) {
20529585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20539585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, NULL);
20549585STim.Szeto@Sun.COM 			} else {
20559585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20569585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, &setToken);
20579585STim.Szeto@Sun.COM 			}
20589585STim.Szeto@Sun.COM 			if (stmfRet != STMF_STATUS_SUCCESS) {
20599585STim.Szeto@Sun.COM 				if (stmfRet == STMF_ERROR_BUSY) {
20609585STim.Szeto@Sun.COM 					/* get/set failed, try again */
20619585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20629585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20639585STim.Szeto@Sun.COM 						ret = stmfRet;
20649585STim.Szeto@Sun.COM 						break;
20659585STim.Szeto@Sun.COM 					}
20669585STim.Szeto@Sun.COM 					continue;
20679585STim.Szeto@Sun.COM 				} else if (stmfRet ==
20689585STim.Szeto@Sun.COM 				    STMF_ERROR_PROV_DATA_STALE) {
20699585STim.Szeto@Sun.COM 					/* update failed, try again */
20709585STim.Szeto@Sun.COM 					nvlist_free(nvl);
20719585STim.Szeto@Sun.COM 					nvl = NULL;
20729585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20739585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20749585STim.Szeto@Sun.COM 						ret = stmfRet;
20759585STim.Szeto@Sun.COM 						break;
20769585STim.Szeto@Sun.COM 					}
20779585STim.Szeto@Sun.COM 					continue;
20789585STim.Szeto@Sun.COM 				} else {
20799585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20809585STim.Szeto@Sun.COM 					    "unpersistGuid:error(%x)", stmfRet);
20819585STim.Szeto@Sun.COM 					ret = stmfRet;
20829585STim.Szeto@Sun.COM 				}
20839585STim.Szeto@Sun.COM 				break;
20849585STim.Szeto@Sun.COM 			}
20859585STim.Szeto@Sun.COM 		} else {
20869585STim.Szeto@Sun.COM 			syslog(LOG_DEBUG,
20879585STim.Szeto@Sun.COM 			    "unpersistGuid:error nvlist_add/remove(%d)",
20889585STim.Szeto@Sun.COM 			    ret);
20899585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
20909585STim.Szeto@Sun.COM 		}
20919585STim.Szeto@Sun.COM 	} while (retryGetProviderData);
20929585STim.Szeto@Sun.COM 
20939585STim.Szeto@Sun.COM done:
20949585STim.Szeto@Sun.COM 	nvlist_free(nvl);
20959585STim.Szeto@Sun.COM 	return (ret);
20969585STim.Szeto@Sun.COM }
20979585STim.Szeto@Sun.COM 
20989585STim.Szeto@Sun.COM 
20999585STim.Szeto@Sun.COM /*
21009585STim.Szeto@Sun.COM  * stmfGetLuProp
21019585STim.Szeto@Sun.COM  *
21029585STim.Szeto@Sun.COM  * Purpose: Get current value for a resource property
21039585STim.Szeto@Sun.COM  *
21049585STim.Szeto@Sun.COM  * hdl - luResource from a previous call to stmfCreateLuResource
21059585STim.Szeto@Sun.COM  *
21069585STim.Szeto@Sun.COM  * resourceProp - a valid resource property type
21079585STim.Szeto@Sun.COM  *
21089585STim.Szeto@Sun.COM  * propVal - void pointer to a pointer of the value to be retrieved
21099585STim.Szeto@Sun.COM  */
21109585STim.Szeto@Sun.COM int
21119585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
21129585STim.Szeto@Sun.COM {
21139585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21149585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
21159585STim.Szeto@Sun.COM 	if (hdl == NULL || propLen == NULL || propVal == NULL) {
21169585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21179585STim.Szeto@Sun.COM 	}
21189585STim.Szeto@Sun.COM 
21199585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
21209585STim.Szeto@Sun.COM 		ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
21219585STim.Szeto@Sun.COM 	} else {
21229585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21239585STim.Szeto@Sun.COM 	}
21249585STim.Szeto@Sun.COM 
21259585STim.Szeto@Sun.COM 	return (ret);
21269585STim.Szeto@Sun.COM }
21279585STim.Szeto@Sun.COM 
21289585STim.Szeto@Sun.COM /*
21299585STim.Szeto@Sun.COM  * stmfGetLuResource
21309585STim.Szeto@Sun.COM  *
21319585STim.Szeto@Sun.COM  * Purpose: Get a logical unit resource handle for a given logical unit.
21329585STim.Szeto@Sun.COM  *
21339585STim.Szeto@Sun.COM  * hdl - pointer to luResource
21349585STim.Szeto@Sun.COM  */
21359585STim.Szeto@Sun.COM int
21369585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
21379585STim.Szeto@Sun.COM {
21389585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21399585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
21409585STim.Szeto@Sun.COM 
21419585STim.Szeto@Sun.COM 
21429585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
21439585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
21449585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
21459585STim.Szeto@Sun.COM 		return (ret);
21469585STim.Szeto@Sun.COM 	} else {
21479585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
21489585STim.Szeto@Sun.COM 			ret = getDiskAllProps(luGuid, hdl);
21499585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
21509585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
21519585STim.Szeto@Sun.COM 		} else {
21529585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
21539585STim.Szeto@Sun.COM 		}
21549585STim.Szeto@Sun.COM 	}
21559585STim.Szeto@Sun.COM 
21569585STim.Szeto@Sun.COM 	return (ret);
21579585STim.Szeto@Sun.COM }
21589585STim.Szeto@Sun.COM 
21599585STim.Szeto@Sun.COM /*
21609585STim.Szeto@Sun.COM  * getDiskAllProps
21619585STim.Szeto@Sun.COM  *
21629585STim.Szeto@Sun.COM  * Purpose: load all disk properties from sbd driver
21639585STim.Szeto@Sun.COM  *
21649585STim.Szeto@Sun.COM  * luGuid - guid of disk device for which properties are to be retrieved
21659585STim.Szeto@Sun.COM  * hdl - allocated luResource into which properties are to be copied
21669585STim.Szeto@Sun.COM  *
21679585STim.Szeto@Sun.COM  */
21689585STim.Szeto@Sun.COM static int
21699585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
21709585STim.Szeto@Sun.COM {
21719585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21729585STim.Szeto@Sun.COM 	int fd;
21739585STim.Szeto@Sun.COM 	sbd_lu_props_t *sbdProps;
21749585STim.Szeto@Sun.COM 	int ioctlRet;
21759585STim.Szeto@Sun.COM 	int savedErrno;
21769585STim.Szeto@Sun.COM 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
21779585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
21789585STim.Szeto@Sun.COM 
21799585STim.Szeto@Sun.COM 	/*
21809585STim.Szeto@Sun.COM 	 * Open control node for sbd
21819585STim.Szeto@Sun.COM 	 */
21829585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
21839585STim.Szeto@Sun.COM 		return (ret);
21849585STim.Szeto@Sun.COM 
21859585STim.Szeto@Sun.COM 
21869585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
21879585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
21889585STim.Szeto@Sun.COM 		(void) close(fd);
21899585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
21909585STim.Szeto@Sun.COM 	}
21919585STim.Szeto@Sun.COM 
21929585STim.Szeto@Sun.COM 	sbdProps = calloc(1, sbdPropsSize);
21939585STim.Szeto@Sun.COM 	if (sbdProps == NULL) {
21949585STim.Szeto@Sun.COM 		free(*hdl);
21959585STim.Szeto@Sun.COM 		(void) close(fd);
21969585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
21979585STim.Szeto@Sun.COM 	}
21989585STim.Szeto@Sun.COM 
21999585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
22009585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
22019585STim.Szeto@Sun.COM 		free(*hdl);
220210725SJohn.Forte@Sun.COM 		free(sbdProps);
22039585STim.Szeto@Sun.COM 		(void) close(fd);
22049585STim.Szeto@Sun.COM 		return (ret);
22059585STim.Szeto@Sun.COM 	}
22069585STim.Szeto@Sun.COM 
22079585STim.Szeto@Sun.COM 	sbdProps->slp_input_guid = 1;
22089585STim.Szeto@Sun.COM 	bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
22099585STim.Szeto@Sun.COM 
22109585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
22119585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdPropsSize;
22129585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
22139585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdPropsSize;
22149585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
22159585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
22169585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
22179585STim.Szeto@Sun.COM 		savedErrno = errno;
22189585STim.Szeto@Sun.COM 		switch (savedErrno) {
22199585STim.Szeto@Sun.COM 			case EBUSY:
22209585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
22219585STim.Szeto@Sun.COM 				break;
22229585STim.Szeto@Sun.COM 			case EPERM:
22239585STim.Szeto@Sun.COM 			case EACCES:
22249585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
22259585STim.Szeto@Sun.COM 				break;
22269585STim.Szeto@Sun.COM 			case ENOENT:
22279585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
22289585STim.Szeto@Sun.COM 				break;
22299585STim.Szeto@Sun.COM 			default:
22309585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
22319585STim.Szeto@Sun.COM 				    "getDiskAllProps:ioctl error(%d) (%d) (%d)",
22329585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
22339585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
22349585STim.Szeto@Sun.COM 				break;
22359585STim.Szeto@Sun.COM 		}
22369585STim.Szeto@Sun.COM 	}
22379585STim.Szeto@Sun.COM 
22389585STim.Szeto@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
22399585STim.Szeto@Sun.COM 		ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
22409585STim.Szeto@Sun.COM 	}
22419585STim.Szeto@Sun.COM 
224210725SJohn.Forte@Sun.COM 	free(sbdProps);
22439585STim.Szeto@Sun.COM 	(void) close(fd);
22449585STim.Szeto@Sun.COM 	return (ret);
22459585STim.Szeto@Sun.COM }
22469585STim.Szeto@Sun.COM 
22479585STim.Szeto@Sun.COM /*
22489585STim.Szeto@Sun.COM  * loadDiskPropsFromDriver
22499585STim.Szeto@Sun.COM  *
22509585STim.Szeto@Sun.COM  * Purpose: Retrieve all disk type properties from sbd driver
22519585STim.Szeto@Sun.COM  *
22529585STim.Szeto@Sun.COM  * hdl - Allocated luResourceImpl
22539585STim.Szeto@Sun.COM  * sbdProps - sbd_lu_props_t structure returned from sbd driver
22549585STim.Szeto@Sun.COM  *
22559585STim.Szeto@Sun.COM  */
22569585STim.Szeto@Sun.COM static int
22579585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
22589585STim.Szeto@Sun.COM {
22599585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
22609585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
22619585STim.Szeto@Sun.COM 	/* copy guid */
22629585STim.Szeto@Sun.COM 	diskLu->luGuidValid = B_TRUE;
22639585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
22649585STim.Szeto@Sun.COM 
22659585STim.Szeto@Sun.COM 	if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
22669585STim.Szeto@Sun.COM 		diskLu->luMetaFileNameValid = B_TRUE;
22679585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luMetaFileName,
22689585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
22699585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) >=
22709585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) {
22719585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22729585STim.Szeto@Sun.COM 		}
22739585STim.Szeto@Sun.COM 	}
22749585STim.Szeto@Sun.COM 
22759585STim.Szeto@Sun.COM 	if (sbdProps->slp_data_fname_valid) {
22769585STim.Szeto@Sun.COM 		diskLu->luDataFileNameValid = B_TRUE;
22779585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luDataFileName,
22789585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
22799585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) >=
22809585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) {
22819585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22829585STim.Szeto@Sun.COM 		}
22839585STim.Szeto@Sun.COM 	}
22849585STim.Szeto@Sun.COM 
22859585STim.Szeto@Sun.COM 	if (sbdProps->slp_serial_valid) {
22869585STim.Szeto@Sun.COM 		diskLu->serialNumValid = B_TRUE;
22879585STim.Szeto@Sun.COM 		bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
22889585STim.Szeto@Sun.COM 		    diskLu->serialNum, sbdProps->slp_serial_size);
22899585STim.Szeto@Sun.COM 	}
22909585STim.Szeto@Sun.COM 
229110113SNattuvetty.Bhavyan@Sun.COM 	if (sbdProps->slp_mgmt_url_valid) {
229210113SNattuvetty.Bhavyan@Sun.COM 		diskLu->luMgmtUrlValid = B_TRUE;
229310113SNattuvetty.Bhavyan@Sun.COM 		if (strlcpy(diskLu->luMgmtUrl,
229410113SNattuvetty.Bhavyan@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
229510113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) >=
229610113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) {
229710113SNattuvetty.Bhavyan@Sun.COM 			return (STMF_STATUS_ERROR);
229810113SNattuvetty.Bhavyan@Sun.COM 		}
229910113SNattuvetty.Bhavyan@Sun.COM 	}
230010113SNattuvetty.Bhavyan@Sun.COM 
23019585STim.Szeto@Sun.COM 	if (sbdProps->slp_alias_valid) {
23029585STim.Szeto@Sun.COM 		diskLu->luAliasValid = B_TRUE;
23039585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luAlias,
23049585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]),
23059585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) >=
23069585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) {
23079585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
23089585STim.Szeto@Sun.COM 		}
23099585STim.Szeto@Sun.COM 	} else { /* set alias to data filename if not set */
23109585STim.Szeto@Sun.COM 		if (sbdProps->slp_data_fname_valid) {
23119585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
23129585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias,
23139585STim.Szeto@Sun.COM 			    (char *)&(sbdProps->slp_buf[
23149585STim.Szeto@Sun.COM 			    sbdProps->slp_data_fname_off]),
23159585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
23169585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
23179585STim.Szeto@Sun.COM 				return (STMF_STATUS_ERROR);
23189585STim.Szeto@Sun.COM 			}
23199585STim.Szeto@Sun.COM 		}
23209585STim.Szeto@Sun.COM 	}
23219585STim.Szeto@Sun.COM 
23229585STim.Szeto@Sun.COM 	diskLu->vidValid = B_TRUE;
23239585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
23249585STim.Szeto@Sun.COM 
23259585STim.Szeto@Sun.COM 	diskLu->pidValid = B_TRUE;
23269585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
23279585STim.Szeto@Sun.COM 
23289585STim.Szeto@Sun.COM 	diskLu->revValid = B_TRUE;
23299585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
23309585STim.Szeto@Sun.COM 
23319585STim.Szeto@Sun.COM 	diskLu->writeProtectEnableValid = B_TRUE;
23329585STim.Szeto@Sun.COM 	if (sbdProps->slp_write_protected) {
23339585STim.Szeto@Sun.COM 		diskLu->writeProtectEnable = B_TRUE;
23349585STim.Szeto@Sun.COM 	}
23359585STim.Szeto@Sun.COM 
23369585STim.Szeto@Sun.COM 	diskLu->writebackCacheDisableValid = B_TRUE;
23379585STim.Szeto@Sun.COM 	if (sbdProps->slp_writeback_cache_disable_cur) {
23389585STim.Szeto@Sun.COM 		diskLu->writebackCacheDisable = B_TRUE;
23399585STim.Szeto@Sun.COM 	}
23409585STim.Szeto@Sun.COM 
23419585STim.Szeto@Sun.COM 	diskLu->blkSizeValid = B_TRUE;
23429585STim.Szeto@Sun.COM 	diskLu->blkSize = sbdProps->slp_blksize;
23439585STim.Szeto@Sun.COM 
23449585STim.Szeto@Sun.COM 	diskLu->luSizeValid = B_TRUE;
23459585STim.Szeto@Sun.COM 	diskLu->luSize = sbdProps->slp_lu_size;
23469585STim.Szeto@Sun.COM 
234710725SJohn.Forte@Sun.COM 	diskLu->accessState = sbdProps->slp_access_state;
234810725SJohn.Forte@Sun.COM 
23499585STim.Szeto@Sun.COM 	return (ret);
23509585STim.Szeto@Sun.COM }
23519585STim.Szeto@Sun.COM 
23529585STim.Szeto@Sun.COM 
23539585STim.Szeto@Sun.COM /*
23549585STim.Szeto@Sun.COM  * stmfSetLuProp
23559585STim.Szeto@Sun.COM  *
23569585STim.Szeto@Sun.COM  * Purpose: set a property on an luResource
23579585STim.Szeto@Sun.COM  *
23589585STim.Szeto@Sun.COM  * hdl - allocated luResource
23599585STim.Szeto@Sun.COM  * prop - property identifier
23609585STim.Szeto@Sun.COM  * propVal - property value to be set
23619585STim.Szeto@Sun.COM  */
23629585STim.Szeto@Sun.COM int
23639585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
23649585STim.Szeto@Sun.COM {
23659585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
23669585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
23679585STim.Szeto@Sun.COM 	if (hdl == NULL) {
23689585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
23699585STim.Szeto@Sun.COM 	}
23709585STim.Szeto@Sun.COM 
23719585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
23729585STim.Szeto@Sun.COM 		ret = setDiskProp(luPropsHdl, prop, propVal);
23739585STim.Szeto@Sun.COM 	} else {
23749585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
23759585STim.Szeto@Sun.COM 	}
23769585STim.Szeto@Sun.COM 
23779585STim.Szeto@Sun.COM 	return (ret);
23789585STim.Szeto@Sun.COM }
23799585STim.Szeto@Sun.COM 
23809585STim.Szeto@Sun.COM /*
23819585STim.Szeto@Sun.COM  * getDiskProp
23829585STim.Szeto@Sun.COM  *
23839585STim.Szeto@Sun.COM  * Purpose: retrieve a given property from a logical unit resource of type disk
23849585STim.Szeto@Sun.COM  *
23859585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
23869585STim.Szeto@Sun.COM  * prop - property identifier
23879585STim.Szeto@Sun.COM  * propVal - pointer to character to contain the retrieved property value
23889585STim.Szeto@Sun.COM  * propLen - On input this is the length of propVal. On failure, it contains the
23899585STim.Szeto@Sun.COM  *           number of bytes required for propVal
23909585STim.Szeto@Sun.COM  */
23919585STim.Szeto@Sun.COM static int
23929585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
23939585STim.Szeto@Sun.COM {
23949585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
23959585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
239610725SJohn.Forte@Sun.COM 	char accessState[20];
23979585STim.Szeto@Sun.COM 	size_t reqLen;
23989585STim.Szeto@Sun.COM 
239910725SJohn.Forte@Sun.COM 	if (prop == STMF_LU_PROP_ACCESS_STATE) {
240010725SJohn.Forte@Sun.COM 		if (diskLu->accessState == SBD_LU_ACTIVE) {
240110725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_ACTIVE,
240210725SJohn.Forte@Sun.COM 			    sizeof (accessState));
240310725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) {
240410725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
240510725SJohn.Forte@Sun.COM 			    STMF_ACCESS_STANDBY_TO_ACTIVE,
240610725SJohn.Forte@Sun.COM 			    sizeof (accessState));
240710725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_STANDBY) {
240810725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_STANDBY,
240910725SJohn.Forte@Sun.COM 			    sizeof (accessState));
241010725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState ==
241110725SJohn.Forte@Sun.COM 		    SBD_LU_TRANSITION_TO_STANDBY) {
241210725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
241310725SJohn.Forte@Sun.COM 			    STMF_ACCESS_ACTIVE_TO_STANDBY,
241410725SJohn.Forte@Sun.COM 			    sizeof (accessState));
241510725SJohn.Forte@Sun.COM 		}
241610725SJohn.Forte@Sun.COM 		if ((reqLen = strlcpy(propVal, accessState,
241710725SJohn.Forte@Sun.COM 		    *propLen)) >= *propLen) {
241810725SJohn.Forte@Sun.COM 			*propLen = reqLen + 1;
241910725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
242010725SJohn.Forte@Sun.COM 		}
242110725SJohn.Forte@Sun.COM 		return (0);
242210725SJohn.Forte@Sun.COM 	}
242310725SJohn.Forte@Sun.COM 
242410725SJohn.Forte@Sun.COM 	if (diskLu->accessState != SBD_LU_ACTIVE) {
242510725SJohn.Forte@Sun.COM 		return (STMF_ERROR_NO_PROP_STANDBY);
242610725SJohn.Forte@Sun.COM 	}
242710725SJohn.Forte@Sun.COM 
24289585STim.Szeto@Sun.COM 	switch (prop) {
24299585STim.Szeto@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE:
24309585STim.Szeto@Sun.COM 			if (diskLu->blkSizeValid == B_FALSE) {
24319585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24329585STim.Szeto@Sun.COM 			}
24339585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen, "%llu",
24349585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->blkSize);
24359585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
24369585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24379585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24389585STim.Szeto@Sun.COM 			}
24399585STim.Szeto@Sun.COM 			break;
24409585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
24419585STim.Szeto@Sun.COM 			if (diskLu->luDataFileNameValid == B_FALSE) {
24429585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24439585STim.Szeto@Sun.COM 			}
24449585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
24459585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
24469585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24479585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24489585STim.Szeto@Sun.COM 			}
24499585STim.Szeto@Sun.COM 			break;
24509585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
24519585STim.Szeto@Sun.COM 			if (diskLu->luMetaFileNameValid == B_FALSE) {
24529585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24539585STim.Szeto@Sun.COM 			}
24549585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
24559585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
24569585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24579585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24589585STim.Szeto@Sun.COM 			}
24599585STim.Szeto@Sun.COM 			break;
246010113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
246110113SNattuvetty.Bhavyan@Sun.COM 			if (diskLu->luMgmtUrlValid == B_FALSE) {
246210113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_NO_PROP);
246310113SNattuvetty.Bhavyan@Sun.COM 			}
246410113SNattuvetty.Bhavyan@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
246510113SNattuvetty.Bhavyan@Sun.COM 			    *propLen)) >= *propLen) {
246610113SNattuvetty.Bhavyan@Sun.COM 				*propLen = reqLen + 1;
246710113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
246810113SNattuvetty.Bhavyan@Sun.COM 			}
246910113SNattuvetty.Bhavyan@Sun.COM 			break;
24709585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
24719585STim.Szeto@Sun.COM 			if (diskLu->luGuidValid == B_FALSE) {
24729585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24739585STim.Szeto@Sun.COM 			}
24749585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen,
24759585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
24769585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X",
24779585STim.Szeto@Sun.COM 			    diskLu->luGuid[0], diskLu->luGuid[1],
24789585STim.Szeto@Sun.COM 			    diskLu->luGuid[2], diskLu->luGuid[3],
24799585STim.Szeto@Sun.COM 			    diskLu->luGuid[4], diskLu->luGuid[5],
24809585STim.Szeto@Sun.COM 			    diskLu->luGuid[6], diskLu->luGuid[7],
24819585STim.Szeto@Sun.COM 			    diskLu->luGuid[8], diskLu->luGuid[9],
24829585STim.Szeto@Sun.COM 			    diskLu->luGuid[10], diskLu->luGuid[11],
24839585STim.Szeto@Sun.COM 			    diskLu->luGuid[12], diskLu->luGuid[13],
24849585STim.Szeto@Sun.COM 			    diskLu->luGuid[14], diskLu->luGuid[15]);
24859585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
24869585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24879585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24889585STim.Szeto@Sun.COM 			}
24899585STim.Szeto@Sun.COM 			break;
24909585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
24919585STim.Szeto@Sun.COM 			if (diskLu->serialNumValid == B_FALSE) {
24929585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24939585STim.Szeto@Sun.COM 			}
24949585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->serialNum,
24959585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
24969585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24979585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24989585STim.Szeto@Sun.COM 			}
24999585STim.Szeto@Sun.COM 			break;
25009585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
25019585STim.Szeto@Sun.COM 			if (diskLu->luSizeValid == B_FALSE) {
25029585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25039585STim.Szeto@Sun.COM 			}
25049585STim.Szeto@Sun.COM 			(void) snprintf(propVal, *propLen, "%llu",
25059585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->luSize);
25069585STim.Szeto@Sun.COM 			break;
25079585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
25089585STim.Szeto@Sun.COM 			if (diskLu->luAliasValid == B_FALSE) {
25099585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25109585STim.Szeto@Sun.COM 			}
25119585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luAlias,
25129585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
25139585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
25149585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
25159585STim.Szeto@Sun.COM 			}
25169585STim.Szeto@Sun.COM 			break;
25179585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
25189585STim.Szeto@Sun.COM 			if (diskLu->vidValid == B_FALSE) {
25199585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25209585STim.Szeto@Sun.COM 			}
25219585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->vid)) {
25229585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
25239585STim.Szeto@Sun.COM 			}
25249585STim.Szeto@Sun.COM 			bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
25259585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->vid)] = 0;
25269585STim.Szeto@Sun.COM 			break;
25279585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
25289585STim.Szeto@Sun.COM 			if (diskLu->pidValid == B_FALSE) {
25299585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25309585STim.Szeto@Sun.COM 			}
25319585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->pid)) {
25329585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
25339585STim.Szeto@Sun.COM 			}
25349585STim.Szeto@Sun.COM 			bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
25359585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->pid)] = 0;
25369585STim.Szeto@Sun.COM 			break;
25379585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
25389585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnableValid == B_FALSE) {
25399585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25409585STim.Szeto@Sun.COM 			}
25419585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnable) {
25429585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
25439585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25449585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25459585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25469585STim.Szeto@Sun.COM 				}
25479585STim.Szeto@Sun.COM 			} else {
25489585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
25499585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25509585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25519585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25529585STim.Szeto@Sun.COM 				}
25539585STim.Szeto@Sun.COM 			}
25549585STim.Szeto@Sun.COM 			break;
25559585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
25569585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisableValid == B_FALSE) {
25579585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25589585STim.Szeto@Sun.COM 			}
25599585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisable) {
25609585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
25619585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25629585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25639585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25649585STim.Szeto@Sun.COM 				}
25659585STim.Szeto@Sun.COM 			} else {
25669585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
25679585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25689585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25699585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25709585STim.Szeto@Sun.COM 				}
25719585STim.Szeto@Sun.COM 			}
25729585STim.Szeto@Sun.COM 			break;
25739585STim.Szeto@Sun.COM 		default:
25749585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NO_PROP;
25759585STim.Szeto@Sun.COM 			break;
25769585STim.Szeto@Sun.COM 	}
25779585STim.Szeto@Sun.COM 
25789585STim.Szeto@Sun.COM 	return (ret);
25799585STim.Szeto@Sun.COM }
25809585STim.Szeto@Sun.COM 
25819585STim.Szeto@Sun.COM /*
25829585STim.Szeto@Sun.COM  * setDiskProp
25839585STim.Szeto@Sun.COM  *
25849585STim.Szeto@Sun.COM  * Purpose: set properties for resource of type disk
25859585STim.Szeto@Sun.COM  *
25869585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
25879585STim.Szeto@Sun.COM  * resourceProp - valid resource identifier
25889585STim.Szeto@Sun.COM  * propVal - valid resource value
25899585STim.Szeto@Sun.COM  */
25909585STim.Szeto@Sun.COM static int
25919585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
25929585STim.Szeto@Sun.COM {
25939585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
25949585STim.Szeto@Sun.COM 	int i;
25959585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
25969585STim.Szeto@Sun.COM 	unsigned long long numericProp = 0;
25979585STim.Szeto@Sun.COM 	char guidProp[LU_ASCII_GUID_SIZE + 1];
25989585STim.Szeto@Sun.COM 	char ouiProp[OUI_ASCII_SIZE + 1];
2599*10765SJohn.Forte@Sun.COM 	char hostIdProp[HOST_ID_ASCII_SIZE + 1];
26009585STim.Szeto@Sun.COM 	unsigned int oui[OUI_SIZE];
2601*10765SJohn.Forte@Sun.COM 	unsigned int hostId[HOST_ID_SIZE];
26029585STim.Szeto@Sun.COM 	unsigned int guid[LU_GUID_SIZE];
26039585STim.Szeto@Sun.COM 	int propSize;
26049585STim.Szeto@Sun.COM 
26059585STim.Szeto@Sun.COM 
26069585STim.Szeto@Sun.COM 	if (propVal == NULL) {
26079585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
26089585STim.Szeto@Sun.COM 	}
26099585STim.Szeto@Sun.COM 
26109585STim.Szeto@Sun.COM 	switch (resourceProp) {
26119585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
26129585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias, propVal,
26139585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
26149585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
26159585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26169585STim.Szeto@Sun.COM 			}
26179585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
26189585STim.Szeto@Sun.COM 			break;
26199585STim.Szeto@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE:
26209585STim.Szeto@Sun.COM 			(void) sscanf(propVal, "%llu", &numericProp);
26219585STim.Szeto@Sun.COM 			if (numericProp > UINT16_MAX) {
26229585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26239585STim.Szeto@Sun.COM 			}
26249585STim.Szeto@Sun.COM 			diskLu->blkSize = numericProp;
26259585STim.Szeto@Sun.COM 			diskLu->blkSizeValid = B_TRUE;
26269585STim.Szeto@Sun.COM 			break;
26279585STim.Szeto@Sun.COM 		case STMF_LU_PROP_COMPANY_ID:
26289585STim.Szeto@Sun.COM 			if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
26299585STim.Szeto@Sun.COM 			    sizeof (ouiProp)) {
26309585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26319585STim.Szeto@Sun.COM 			}
26329585STim.Szeto@Sun.COM 			if (checkHexUpper(ouiProp) != 0) {
26339585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26349585STim.Szeto@Sun.COM 			}
26359585STim.Szeto@Sun.COM 			(void) sscanf(ouiProp, "%2X%2X%2X",
26369585STim.Szeto@Sun.COM 			    &oui[0], &oui[1], &oui[2]);
26379585STim.Szeto@Sun.COM 
26389585STim.Szeto@Sun.COM 			diskLu->companyId = 0;
26399585STim.Szeto@Sun.COM 			diskLu->companyId += oui[0] << 16;
26409585STim.Szeto@Sun.COM 			diskLu->companyId += oui[1] << 8;
26419585STim.Szeto@Sun.COM 			diskLu->companyId += oui[2];
2642*10765SJohn.Forte@Sun.COM 			if (diskLu->companyId == 0) {
2643*10765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
2644*10765SJohn.Forte@Sun.COM 			}
26459585STim.Szeto@Sun.COM 			diskLu->companyIdValid = B_TRUE;
26469585STim.Szeto@Sun.COM 			break;
2647*10765SJohn.Forte@Sun.COM 		case STMF_LU_PROP_HOST_ID:
2648*10765SJohn.Forte@Sun.COM 			if ((strlcpy(hostIdProp, propVal,
2649*10765SJohn.Forte@Sun.COM 			    sizeof (hostIdProp))) >= sizeof (hostIdProp)) {
2650*10765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
2651*10765SJohn.Forte@Sun.COM 			}
2652*10765SJohn.Forte@Sun.COM 			if (checkHexUpper(hostIdProp) != 0) {
2653*10765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
2654*10765SJohn.Forte@Sun.COM 			}
2655*10765SJohn.Forte@Sun.COM 			(void) sscanf(hostIdProp, "%2X%2X%2X%2X",
2656*10765SJohn.Forte@Sun.COM 			    &hostId[0], &hostId[1], &hostId[2], &hostId[3]);
2657*10765SJohn.Forte@Sun.COM 
2658*10765SJohn.Forte@Sun.COM 			diskLu->hostId = 0;
2659*10765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[0] << 24;
2660*10765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[1] << 16;
2661*10765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[2] << 8;
2662*10765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[3];
2663*10765SJohn.Forte@Sun.COM 			if (diskLu->hostId == 0) {
2664*10765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
2665*10765SJohn.Forte@Sun.COM 			}
2666*10765SJohn.Forte@Sun.COM 			diskLu->hostIdValid = B_TRUE;
2667*10765SJohn.Forte@Sun.COM 			break;
26689585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
26699585STim.Szeto@Sun.COM 			if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
26709585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26719585STim.Szeto@Sun.COM 			}
26729585STim.Szeto@Sun.COM 
26739585STim.Szeto@Sun.COM 			if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
26749585STim.Szeto@Sun.COM 			    sizeof (guidProp)) {
26759585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26769585STim.Szeto@Sun.COM 			}
26779585STim.Szeto@Sun.COM 
26789585STim.Szeto@Sun.COM 			if (checkHexUpper(guidProp) != 0) {
26799585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26809585STim.Szeto@Sun.COM 			}
26819585STim.Szeto@Sun.COM 
26829585STim.Szeto@Sun.COM 			(void) sscanf(guidProp,
26839585STim.Szeto@Sun.COM 			    "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
26849585STim.Szeto@Sun.COM 			    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
26859585STim.Szeto@Sun.COM 			    &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
26869585STim.Szeto@Sun.COM 			    &guid[10], &guid[11], &guid[12], &guid[13],
26879585STim.Szeto@Sun.COM 			    &guid[14], &guid[15]);
26889585STim.Szeto@Sun.COM 			for (i = 0; i < sizeof (diskLu->luGuid); i++) {
26899585STim.Szeto@Sun.COM 				diskLu->luGuid[i] = guid[i];
26909585STim.Szeto@Sun.COM 			}
26919585STim.Szeto@Sun.COM 			diskLu->luGuidValid = B_TRUE;
26929585STim.Szeto@Sun.COM 			break;
26939585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
26949585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luDataFileName, propVal,
26959585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName))) >=
26969585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName)) {
26979585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26989585STim.Szeto@Sun.COM 			}
26999585STim.Szeto@Sun.COM 			diskLu->luDataFileNameValid = B_TRUE;
27009585STim.Szeto@Sun.COM 			break;
27019585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
27029585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luMetaFileName, propVal,
27039585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName))) >=
27049585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName)) {
27059585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
27069585STim.Szeto@Sun.COM 			}
27079585STim.Szeto@Sun.COM 			diskLu->luMetaFileNameValid = B_TRUE;
27089585STim.Szeto@Sun.COM 			break;
270910113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
271010113SNattuvetty.Bhavyan@Sun.COM 			if ((strlcpy(diskLu->luMgmtUrl, propVal,
271110113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl))) >=
271210113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl)) {
271310113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
271410113SNattuvetty.Bhavyan@Sun.COM 			}
271510113SNattuvetty.Bhavyan@Sun.COM 			diskLu->luMgmtUrlValid = B_TRUE;
271610113SNattuvetty.Bhavyan@Sun.COM 			break;
27179585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
27189585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
27199585STim.Szeto@Sun.COM 			    sizeof (diskLu->pid)) {
27209585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
27219585STim.Szeto@Sun.COM 			}
27229585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->pid, propVal, propSize);
27239585STim.Szeto@Sun.COM 			diskLu->pidValid = B_TRUE;
27249585STim.Szeto@Sun.COM 			break;
27259585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
27269585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
27279585STim.Szeto@Sun.COM 			    (sizeof (diskLu->serialNum) - 1)) {
27289585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
27299585STim.Szeto@Sun.COM 			}
27309585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->serialNum, propVal, propSize);
27319585STim.Szeto@Sun.COM 			diskLu->serialNumValid = B_TRUE;
27329585STim.Szeto@Sun.COM 			break;
27339585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
27349585STim.Szeto@Sun.COM 			if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
27359585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27369585STim.Szeto@Sun.COM 			}
27379585STim.Szeto@Sun.COM 			diskLu->luSizeValid = B_TRUE;
27389585STim.Szeto@Sun.COM 			break;
27399585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
27409585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
27419585STim.Szeto@Sun.COM 			    sizeof (diskLu->vid)) {
27429585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
27439585STim.Szeto@Sun.COM 			}
27449585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->vid, propVal, propSize);
27459585STim.Szeto@Sun.COM 			diskLu->vidValid = B_TRUE;
27469585STim.Szeto@Sun.COM 			break;
27479585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
27489585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
27499585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_TRUE;
27509585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
27519585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_FALSE;
27529585STim.Szeto@Sun.COM 			} else {
27539585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27549585STim.Szeto@Sun.COM 			}
27559585STim.Szeto@Sun.COM 			diskLu->writeProtectEnableValid = B_TRUE;
27569585STim.Szeto@Sun.COM 			break;
27579585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
27589585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
27599585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_TRUE;
27609585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
27619585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_FALSE;
27629585STim.Szeto@Sun.COM 			} else {
27639585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27649585STim.Szeto@Sun.COM 			}
27659585STim.Szeto@Sun.COM 			diskLu->writebackCacheDisableValid = B_TRUE;
27669585STim.Szeto@Sun.COM 			break;
276710725SJohn.Forte@Sun.COM 		case STMF_LU_PROP_ACCESS_STATE:
276810725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
276910725SJohn.Forte@Sun.COM 			break;
27709585STim.Szeto@Sun.COM 		default:
27719585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NO_PROP;
27729585STim.Szeto@Sun.COM 			break;
27739585STim.Szeto@Sun.COM 	}
27749585STim.Szeto@Sun.COM 	return (ret);
27759585STim.Szeto@Sun.COM }
27769585STim.Szeto@Sun.COM 
27779585STim.Szeto@Sun.COM static int
27789585STim.Szeto@Sun.COM checkHexUpper(char *buf)
27799585STim.Szeto@Sun.COM {
27809585STim.Szeto@Sun.COM 	int i;
27819585STim.Szeto@Sun.COM 
27829585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(buf); i++) {
27839585STim.Szeto@Sun.COM 		if (isxdigit(buf[i])) {
27849585STim.Szeto@Sun.COM 			buf[i] = toupper(buf[i]);
27859585STim.Szeto@Sun.COM 			continue;
27869585STim.Szeto@Sun.COM 		}
27879585STim.Szeto@Sun.COM 		return (-1);
27889585STim.Szeto@Sun.COM 	}
27899585STim.Szeto@Sun.COM 
27909585STim.Szeto@Sun.COM 	return (0);
27919585STim.Szeto@Sun.COM }
27929585STim.Szeto@Sun.COM 
27939585STim.Szeto@Sun.COM /*
27949585STim.Szeto@Sun.COM  * Given a numeric suffix, convert the value into a number of bits that the
27959585STim.Szeto@Sun.COM  * resulting value must be shifted.
27969585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
27979585STim.Szeto@Sun.COM  */
27989585STim.Szeto@Sun.COM static int
27999585STim.Szeto@Sun.COM strToShift(const char *buf)
28009585STim.Szeto@Sun.COM {
28019585STim.Szeto@Sun.COM 	const char *ends = "BKMGTPE";
28029585STim.Szeto@Sun.COM 	int i;
28039585STim.Szeto@Sun.COM 
28049585STim.Szeto@Sun.COM 	if (buf[0] == '\0')
28059585STim.Szeto@Sun.COM 		return (0);
28069585STim.Szeto@Sun.COM 
28079585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(ends); i++) {
28089585STim.Szeto@Sun.COM 		if (toupper(buf[0]) == ends[i])
28099585STim.Szeto@Sun.COM 			return (10*i);
28109585STim.Szeto@Sun.COM 	}
28119585STim.Szeto@Sun.COM 
28129585STim.Szeto@Sun.COM 	return (-1);
28139585STim.Szeto@Sun.COM }
28149585STim.Szeto@Sun.COM 
28159585STim.Szeto@Sun.COM int
28169585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl)
28179585STim.Szeto@Sun.COM {
28189585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
28199585STim.Szeto@Sun.COM 	if (hdl == NULL) {
28209585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28219585STim.Szeto@Sun.COM 	}
28229585STim.Szeto@Sun.COM 
28239585STim.Szeto@Sun.COM 	luResourceImpl *hdlImpl = hdl;
28249585STim.Szeto@Sun.COM 	free(hdlImpl->resource);
28259585STim.Szeto@Sun.COM 	free(hdlImpl);
28269585STim.Szeto@Sun.COM 	return (ret);
28279585STim.Szeto@Sun.COM }
28289585STim.Szeto@Sun.COM 
28299585STim.Szeto@Sun.COM /*
28309585STim.Szeto@Sun.COM  * Convert a string of the form '100G' into a real number. Used when setting
28319585STim.Szeto@Sun.COM  * the size of a logical unit.
28329585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
28339585STim.Szeto@Sun.COM  */
28349585STim.Szeto@Sun.COM static int
28359585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num)
28369585STim.Szeto@Sun.COM {
28379585STim.Szeto@Sun.COM 	char *end;
28389585STim.Szeto@Sun.COM 	int shift;
28399585STim.Szeto@Sun.COM 
28409585STim.Szeto@Sun.COM 	*num = 0;
28419585STim.Szeto@Sun.COM 
28429585STim.Szeto@Sun.COM 	/* Check to see if this looks like a number.  */
28439585STim.Szeto@Sun.COM 	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
28449585STim.Szeto@Sun.COM 		return (-1);
28459585STim.Szeto@Sun.COM 	}
28469585STim.Szeto@Sun.COM 
28479585STim.Szeto@Sun.COM 	/* Rely on stroull() to process the numeric portion.  */
28489585STim.Szeto@Sun.COM 	errno = 0;
28499585STim.Szeto@Sun.COM 	*num = strtoull(value, &end, 10);
28509585STim.Szeto@Sun.COM 
28519585STim.Szeto@Sun.COM 	/*
28529585STim.Szeto@Sun.COM 	 * Check for ERANGE, which indicates that the value is too large to fit
28539585STim.Szeto@Sun.COM 	 * in a 64-bit value.
28549585STim.Szeto@Sun.COM 	 */
28559585STim.Szeto@Sun.COM 	if (errno == ERANGE) {
28569585STim.Szeto@Sun.COM 		return (-1);
28579585STim.Szeto@Sun.COM 	}
28589585STim.Szeto@Sun.COM 
28599585STim.Szeto@Sun.COM 	/*
28609585STim.Szeto@Sun.COM 	 * If we have a decimal value, then do the computation with floating
28619585STim.Szeto@Sun.COM 	 * point arithmetic.  Otherwise, use standard arithmetic.
28629585STim.Szeto@Sun.COM 	 */
28639585STim.Szeto@Sun.COM 	if (*end == '.') {
28649585STim.Szeto@Sun.COM 		double fval = strtod(value, &end);
28659585STim.Szeto@Sun.COM 
28669585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
28679585STim.Szeto@Sun.COM 			return (-1);
28689585STim.Szeto@Sun.COM 		}
28699585STim.Szeto@Sun.COM 
28709585STim.Szeto@Sun.COM 		fval *= pow(2, shift);
28719585STim.Szeto@Sun.COM 
28729585STim.Szeto@Sun.COM 		if (fval > UINT64_MAX) {
28739585STim.Szeto@Sun.COM 			return (-1);
28749585STim.Szeto@Sun.COM 		}
28759585STim.Szeto@Sun.COM 
28769585STim.Szeto@Sun.COM 		*num = (uint64_t)fval;
28779585STim.Szeto@Sun.COM 	} else {
28789585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
28799585STim.Szeto@Sun.COM 			return (-1);
28809585STim.Szeto@Sun.COM 		}
28819585STim.Szeto@Sun.COM 
28829585STim.Szeto@Sun.COM 		/* Check for overflow */
28839585STim.Szeto@Sun.COM 		if (shift >= 64 || (*num << shift) >> shift != *num) {
28849585STim.Szeto@Sun.COM 			return (-1);
28859585STim.Szeto@Sun.COM 		}
28869585STim.Szeto@Sun.COM 
28879585STim.Szeto@Sun.COM 		*num <<= shift;
28889585STim.Szeto@Sun.COM 	}
28899585STim.Szeto@Sun.COM 
28909585STim.Szeto@Sun.COM 	return (0);
28919585STim.Szeto@Sun.COM }
28929585STim.Szeto@Sun.COM 
28939585STim.Szeto@Sun.COM /*
28947836SJohn.Forte@Sun.COM  * stmfCreateTargetGroup
28957836SJohn.Forte@Sun.COM  *
28967836SJohn.Forte@Sun.COM  * Purpose: Create a local port group
28977836SJohn.Forte@Sun.COM  *
28987836SJohn.Forte@Sun.COM  * targetGroupName - name of local port group to create
28997836SJohn.Forte@Sun.COM  */
29007836SJohn.Forte@Sun.COM int
29017836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName)
29027836SJohn.Forte@Sun.COM {
29037836SJohn.Forte@Sun.COM 	int ret;
29047836SJohn.Forte@Sun.COM 	int fd;
29057836SJohn.Forte@Sun.COM 
29067836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
29077836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
29087836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
29097836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
29107836SJohn.Forte@Sun.COM 	}
29117836SJohn.Forte@Sun.COM 
29127836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
29137836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
29147836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
29157836SJohn.Forte@Sun.COM 	}
29167836SJohn.Forte@Sun.COM 
29177836SJohn.Forte@Sun.COM 	/* call init */
29187836SJohn.Forte@Sun.COM 	ret = initializeConfig();
29197836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
29207836SJohn.Forte@Sun.COM 		return (ret);
29217836SJohn.Forte@Sun.COM 	}
29227836SJohn.Forte@Sun.COM 
29237836SJohn.Forte@Sun.COM 	/*
29247836SJohn.Forte@Sun.COM 	 * Open control node for stmf
29257836SJohn.Forte@Sun.COM 	 */
29267836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
29277836SJohn.Forte@Sun.COM 		return (ret);
29287836SJohn.Forte@Sun.COM 
29297836SJohn.Forte@Sun.COM 	/*
29307836SJohn.Forte@Sun.COM 	 * Add the group to the driver
29317836SJohn.Forte@Sun.COM 	 */
29327836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
29337836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
29347836SJohn.Forte@Sun.COM 		goto done;
29357836SJohn.Forte@Sun.COM 	}
29367836SJohn.Forte@Sun.COM 
29379585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
29389585STim.Szeto@Sun.COM 		goto done;
29399585STim.Szeto@Sun.COM 	}
29409585STim.Szeto@Sun.COM 
29417836SJohn.Forte@Sun.COM 	/*
29427836SJohn.Forte@Sun.COM 	 * If the add to the driver was successful, add it to the persistent
29437836SJohn.Forte@Sun.COM 	 * store.
29447836SJohn.Forte@Sun.COM 	 */
29457836SJohn.Forte@Sun.COM 	ret = psCreateTargetGroup((char *)targetGroupName);
29467836SJohn.Forte@Sun.COM 	switch (ret) {
29477836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
29487836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
29497836SJohn.Forte@Sun.COM 			break;
29507836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
29517836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
29527836SJohn.Forte@Sun.COM 			break;
29537836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
29547836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
29557836SJohn.Forte@Sun.COM 			break;
29567836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
29577836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
29587836SJohn.Forte@Sun.COM 			break;
29597836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
29607836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
29617836SJohn.Forte@Sun.COM 			break;
29627836SJohn.Forte@Sun.COM 		default:
29637836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
29647836SJohn.Forte@Sun.COM 			    "stmfCreateTargetGroup:psCreateTargetGroup"
29657836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
29667836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
29677836SJohn.Forte@Sun.COM 			break;
29687836SJohn.Forte@Sun.COM 	}
29697836SJohn.Forte@Sun.COM 
29707836SJohn.Forte@Sun.COM done:
29717836SJohn.Forte@Sun.COM 	(void) close(fd);
29727836SJohn.Forte@Sun.COM 	return (ret);
29737836SJohn.Forte@Sun.COM }
29747836SJohn.Forte@Sun.COM 
29757836SJohn.Forte@Sun.COM /*
29767836SJohn.Forte@Sun.COM  * stmfDeleteHostGroup
29777836SJohn.Forte@Sun.COM  *
29787836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
29797836SJohn.Forte@Sun.COM  *
29807836SJohn.Forte@Sun.COM  * hostGroupName - group to delete
29817836SJohn.Forte@Sun.COM  */
29827836SJohn.Forte@Sun.COM int
29837836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName)
29847836SJohn.Forte@Sun.COM {
29857836SJohn.Forte@Sun.COM 	int ret;
29867836SJohn.Forte@Sun.COM 	int fd;
29877836SJohn.Forte@Sun.COM 
29887836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL) {
29897836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
29907836SJohn.Forte@Sun.COM 	}
29917836SJohn.Forte@Sun.COM 
29927836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
29937836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
29947836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
29957836SJohn.Forte@Sun.COM 	}
29967836SJohn.Forte@Sun.COM 
29977836SJohn.Forte@Sun.COM 	/* call init */
29987836SJohn.Forte@Sun.COM 	ret = initializeConfig();
29997836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
30007836SJohn.Forte@Sun.COM 		return (ret);
30017836SJohn.Forte@Sun.COM 	}
30027836SJohn.Forte@Sun.COM 
30037836SJohn.Forte@Sun.COM 	/*
30047836SJohn.Forte@Sun.COM 	 * Open control node for stmf
30057836SJohn.Forte@Sun.COM 	 */
30067836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
30077836SJohn.Forte@Sun.COM 		return (ret);
30087836SJohn.Forte@Sun.COM 
30097836SJohn.Forte@Sun.COM 	/*
30107836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
30117836SJohn.Forte@Sun.COM 	 */
30127836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
30137836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
30147836SJohn.Forte@Sun.COM 		goto done;
30157836SJohn.Forte@Sun.COM 	}
30167836SJohn.Forte@Sun.COM 
30179585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
30189585STim.Szeto@Sun.COM 		goto done;
30199585STim.Szeto@Sun.COM 	}
30209585STim.Szeto@Sun.COM 
30217836SJohn.Forte@Sun.COM 	/*
30227836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
30237836SJohn.Forte@Sun.COM 	 * persistent store.
30247836SJohn.Forte@Sun.COM 	 */
30257836SJohn.Forte@Sun.COM 	ret = psDeleteHostGroup((char *)hostGroupName);
30267836SJohn.Forte@Sun.COM 	switch (ret) {
30277836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
30287836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
30297836SJohn.Forte@Sun.COM 			break;
30307836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
30317836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
30327836SJohn.Forte@Sun.COM 			break;
30337836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
30347836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
30357836SJohn.Forte@Sun.COM 			break;
30367836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
30377836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
30387836SJohn.Forte@Sun.COM 			break;
30397836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
30407836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
30417836SJohn.Forte@Sun.COM 			break;
30427836SJohn.Forte@Sun.COM 		default:
30437836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
30447836SJohn.Forte@Sun.COM 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
30457836SJohn.Forte@Sun.COM 			    ret);
30467836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
30477836SJohn.Forte@Sun.COM 			break;
30487836SJohn.Forte@Sun.COM 	}
30497836SJohn.Forte@Sun.COM 
30507836SJohn.Forte@Sun.COM done:
30517836SJohn.Forte@Sun.COM 	(void) close(fd);
30527836SJohn.Forte@Sun.COM 	return (ret);
30537836SJohn.Forte@Sun.COM }
30547836SJohn.Forte@Sun.COM 
30557836SJohn.Forte@Sun.COM /*
30567836SJohn.Forte@Sun.COM  * stmfDeleteTargetGroup
30577836SJohn.Forte@Sun.COM  *
30587836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
30597836SJohn.Forte@Sun.COM  *
30607836SJohn.Forte@Sun.COM  * targetGroupName - group to delete
30617836SJohn.Forte@Sun.COM  */
30627836SJohn.Forte@Sun.COM int
30637836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
30647836SJohn.Forte@Sun.COM {
30657836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
30667836SJohn.Forte@Sun.COM 	int fd;
30677836SJohn.Forte@Sun.COM 
30687836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL) {
30697836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
30707836SJohn.Forte@Sun.COM 	}
30717836SJohn.Forte@Sun.COM 
30727836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
30737836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
30747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
30757836SJohn.Forte@Sun.COM 	}
30767836SJohn.Forte@Sun.COM 
30777836SJohn.Forte@Sun.COM 	/* call init */
30787836SJohn.Forte@Sun.COM 	ret = initializeConfig();
30797836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
30807836SJohn.Forte@Sun.COM 		return (ret);
30817836SJohn.Forte@Sun.COM 	}
30827836SJohn.Forte@Sun.COM 
30837836SJohn.Forte@Sun.COM 	/*
30847836SJohn.Forte@Sun.COM 	 * Open control node for stmf
30857836SJohn.Forte@Sun.COM 	 */
30867836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
30877836SJohn.Forte@Sun.COM 		return (ret);
30887836SJohn.Forte@Sun.COM 
30897836SJohn.Forte@Sun.COM 	/*
30907836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
30917836SJohn.Forte@Sun.COM 	 */
30927836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
30937836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
30947836SJohn.Forte@Sun.COM 		goto done;
30957836SJohn.Forte@Sun.COM 	}
30967836SJohn.Forte@Sun.COM 
30979585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
30989585STim.Szeto@Sun.COM 		goto done;
30999585STim.Szeto@Sun.COM 	}
31009585STim.Szeto@Sun.COM 
31017836SJohn.Forte@Sun.COM 	/*
31027836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
31037836SJohn.Forte@Sun.COM 	 * persistent store.
31047836SJohn.Forte@Sun.COM 	 */
31057836SJohn.Forte@Sun.COM 	ret = psDeleteTargetGroup((char *)targetGroupName);
31067836SJohn.Forte@Sun.COM 	switch (ret) {
31077836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
31087836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
31097836SJohn.Forte@Sun.COM 			break;
31107836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
31117836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
31127836SJohn.Forte@Sun.COM 			break;
31137836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
31147836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
31157836SJohn.Forte@Sun.COM 			break;
31167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
31177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
31187836SJohn.Forte@Sun.COM 			break;
31197836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
31207836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
31217836SJohn.Forte@Sun.COM 			break;
31227836SJohn.Forte@Sun.COM 		default:
31237836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
31247836SJohn.Forte@Sun.COM 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
31257836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
31267836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
31277836SJohn.Forte@Sun.COM 			break;
31287836SJohn.Forte@Sun.COM 	}
31297836SJohn.Forte@Sun.COM 
31307836SJohn.Forte@Sun.COM done:
31317836SJohn.Forte@Sun.COM 	(void) close(fd);
31327836SJohn.Forte@Sun.COM 	return (ret);
31337836SJohn.Forte@Sun.COM }
31347836SJohn.Forte@Sun.COM 
31357836SJohn.Forte@Sun.COM /*
31367836SJohn.Forte@Sun.COM  * stmfDevidFromIscsiName
31377836SJohn.Forte@Sun.COM  *
31387836SJohn.Forte@Sun.COM  * Purpose: convert an iSCSI name to an stmf devid
31397836SJohn.Forte@Sun.COM  *
31407836SJohn.Forte@Sun.COM  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
31417836SJohn.Forte@Sun.COM  * devid - on success, contains the converted iscsi name
31427836SJohn.Forte@Sun.COM  */
31437836SJohn.Forte@Sun.COM int
31447836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
31457836SJohn.Forte@Sun.COM {
31467836SJohn.Forte@Sun.COM 	if (devid == NULL || iscsiName == NULL)
31477836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31487836SJohn.Forte@Sun.COM 
31497836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
31507836SJohn.Forte@Sun.COM 
31517836SJohn.Forte@Sun.COM 	/* Validate size of target */
31527836SJohn.Forte@Sun.COM 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
31537836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(EUI) ||
31547836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(IQN)) {
31557836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31567836SJohn.Forte@Sun.COM 	}
31577836SJohn.Forte@Sun.COM 
31587836SJohn.Forte@Sun.COM 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
31597836SJohn.Forte@Sun.COM 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
31607836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31617836SJohn.Forte@Sun.COM 	}
31627836SJohn.Forte@Sun.COM 
31637836SJohn.Forte@Sun.COM 	/* copy UTF-8 bytes to ident */
31647836SJohn.Forte@Sun.COM 	bcopy(iscsiName, devid->ident, devid->identLength);
31657836SJohn.Forte@Sun.COM 
31667836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
31677836SJohn.Forte@Sun.COM }
31687836SJohn.Forte@Sun.COM 
31697836SJohn.Forte@Sun.COM /*
31707836SJohn.Forte@Sun.COM  * stmfDevidFromWwn
31717836SJohn.Forte@Sun.COM  *
31727836SJohn.Forte@Sun.COM  * Purpose: convert a WWN to an stmf devid
31737836SJohn.Forte@Sun.COM  *
31747836SJohn.Forte@Sun.COM  * wwn - 8-byte wwn identifier
31757836SJohn.Forte@Sun.COM  * devid - on success, contains the converted wwn
31767836SJohn.Forte@Sun.COM  */
31777836SJohn.Forte@Sun.COM int
31787836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
31797836SJohn.Forte@Sun.COM {
31807836SJohn.Forte@Sun.COM 	if (wwn == NULL || devid == NULL)
31817836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31827836SJohn.Forte@Sun.COM 
31837836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
31847836SJohn.Forte@Sun.COM 
31857836SJohn.Forte@Sun.COM 	/* Copy eui prefix */
31867836SJohn.Forte@Sun.COM 	(void) bcopy(WWN, devid->ident, strlen(WWN));
31877836SJohn.Forte@Sun.COM 
31887836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
31897836SJohn.Forte@Sun.COM 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
31907836SJohn.Forte@Sun.COM 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
31917836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
31927836SJohn.Forte@Sun.COM 
31937836SJohn.Forte@Sun.COM 	devid->identLength = strlen((char *)devid->ident);
31947836SJohn.Forte@Sun.COM 
31957836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
31967836SJohn.Forte@Sun.COM }
31977836SJohn.Forte@Sun.COM 
31987836SJohn.Forte@Sun.COM /*
31997836SJohn.Forte@Sun.COM  * stmfFreeMemory
32007836SJohn.Forte@Sun.COM  *
32017836SJohn.Forte@Sun.COM  * Purpose: Free memory allocated by this library
32027836SJohn.Forte@Sun.COM  *
32037836SJohn.Forte@Sun.COM  * memory - previously allocated pointer of memory managed by library
32047836SJohn.Forte@Sun.COM  */
32057836SJohn.Forte@Sun.COM void
32067836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory)
32077836SJohn.Forte@Sun.COM {
32087836SJohn.Forte@Sun.COM 	free(memory);
32097836SJohn.Forte@Sun.COM }
32107836SJohn.Forte@Sun.COM 
32117836SJohn.Forte@Sun.COM /*
32129585STim.Szeto@Sun.COM  * get host group, target group list from stmf
32137836SJohn.Forte@Sun.COM  *
32149585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
32157836SJohn.Forte@Sun.COM  */
32169585STim.Szeto@Sun.COM static int
32179585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType)
32189585STim.Szeto@Sun.COM {
32199585STim.Szeto@Sun.COM 	int ret;
32209585STim.Szeto@Sun.COM 	int fd;
32219585STim.Szeto@Sun.COM 	int ioctlRet;
32229585STim.Szeto@Sun.COM 	int i;
32239585STim.Szeto@Sun.COM 	int cmd;
32249585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
32259585STim.Szeto@Sun.COM 	/* framework group list */
32269585STim.Szeto@Sun.COM 	stmf_group_name_t *iGroupList = NULL;
32279585STim.Szeto@Sun.COM 	uint32_t groupListSize;
32289585STim.Szeto@Sun.COM 
32299585STim.Szeto@Sun.COM 	if (groupList == NULL) {
32309585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32319585STim.Szeto@Sun.COM 	}
32329585STim.Szeto@Sun.COM 
32339585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
32349585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_LIST;
32359585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
32369585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_LIST;
32379585STim.Szeto@Sun.COM 	} else {
32389585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32399585STim.Szeto@Sun.COM 	}
32409585STim.Szeto@Sun.COM 
32419585STim.Szeto@Sun.COM 	/* call init */
32429585STim.Szeto@Sun.COM 	ret = initializeConfig();
32439585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
32449585STim.Szeto@Sun.COM 		return (ret);
32459585STim.Szeto@Sun.COM 	}
32469585STim.Szeto@Sun.COM 
32479585STim.Szeto@Sun.COM 	/*
32489585STim.Szeto@Sun.COM 	 * Open control node for stmf
32499585STim.Szeto@Sun.COM 	 */
32509585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
32519585STim.Szeto@Sun.COM 		return (ret);
32529585STim.Szeto@Sun.COM 
32539585STim.Szeto@Sun.COM 	/*
32549585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
32559585STim.Szeto@Sun.COM 	 */
32569585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GROUP;
32579585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_group_name_t));
32589585STim.Szeto@Sun.COM 	iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
32599585STim.Szeto@Sun.COM 	if (iGroupList == NULL) {
32609585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
32619585STim.Szeto@Sun.COM 		goto done;
32629585STim.Szeto@Sun.COM 	}
32639585STim.Szeto@Sun.COM 
32649585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
32659585STim.Szeto@Sun.COM 	/*
32669585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
32679585STim.Szeto@Sun.COM 	 */
32689585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
32699585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
32709585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
32719585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
32729585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
32739585STim.Szeto@Sun.COM 		switch (errno) {
32749585STim.Szeto@Sun.COM 			case EBUSY:
32759585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
32769585STim.Szeto@Sun.COM 				break;
32779585STim.Szeto@Sun.COM 			case EPERM:
32789585STim.Szeto@Sun.COM 			case EACCES:
32799585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
32809585STim.Szeto@Sun.COM 				break;
32819585STim.Szeto@Sun.COM 			default:
32829585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
32839585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
32849585STim.Szeto@Sun.COM 				    errno);
32859585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
32869585STim.Szeto@Sun.COM 				break;
32879585STim.Szeto@Sun.COM 		}
32889585STim.Szeto@Sun.COM 		goto done;
32899585STim.Szeto@Sun.COM 	}
32909585STim.Szeto@Sun.COM 	/*
32919585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
32929585STim.Szeto@Sun.COM 	 */
32939585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
32949585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
32959585STim.Szeto@Sun.COM 		    sizeof (stmf_group_name_t);
32969585STim.Szeto@Sun.COM 		iGroupList = realloc(iGroupList, groupListSize);
32979585STim.Szeto@Sun.COM 		if (iGroupList == NULL) {
32989585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
32999585STim.Szeto@Sun.COM 			goto done;
33009585STim.Szeto@Sun.COM 		}
33019585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
33029585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
33039585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
33049585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
33059585STim.Szeto@Sun.COM 			switch (errno) {
33069585STim.Szeto@Sun.COM 				case EBUSY:
33079585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
33089585STim.Szeto@Sun.COM 					break;
33099585STim.Szeto@Sun.COM 				case EPERM:
33109585STim.Szeto@Sun.COM 				case EACCES:
33119585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
33129585STim.Szeto@Sun.COM 					break;
33139585STim.Szeto@Sun.COM 				default:
33149585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
33159585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
33169585STim.Szeto@Sun.COM 					    errno);
33179585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
33189585STim.Szeto@Sun.COM 					break;
33199585STim.Szeto@Sun.COM 			}
33209585STim.Szeto@Sun.COM 			goto done;
33219585STim.Szeto@Sun.COM 		}
33229585STim.Szeto@Sun.COM 	}
33239585STim.Szeto@Sun.COM 
33249585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
332510236SSrivijitha.Dugganapalli@Sun.COM 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
332610236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries);
33279585STim.Szeto@Sun.COM 	if (*groupList == NULL) {
33289585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
33299585STim.Szeto@Sun.COM 		goto done;
33309585STim.Szeto@Sun.COM 	}
33319585STim.Szeto@Sun.COM 	(*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
33329585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
333310113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupList[i].name, (*groupList)->name[i],
33349585STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
33359585STim.Szeto@Sun.COM 	}
33369585STim.Szeto@Sun.COM 
33379585STim.Szeto@Sun.COM done:
33389585STim.Szeto@Sun.COM 	free(iGroupList);
33399585STim.Szeto@Sun.COM 	(void) close(fd);
33409585STim.Szeto@Sun.COM 	return (ret);
33419585STim.Szeto@Sun.COM }
33429585STim.Szeto@Sun.COM 
33439585STim.Szeto@Sun.COM /*
33449585STim.Szeto@Sun.COM  * get host group members, target group members from stmf
33459585STim.Szeto@Sun.COM  *
33469585STim.Szeto@Sun.COM  * groupProps - allocated on success
33479585STim.Szeto@Sun.COM  *
33489585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
33499585STim.Szeto@Sun.COM  */
33509585STim.Szeto@Sun.COM static int
33519585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
33529585STim.Szeto@Sun.COM     int groupType)
33537836SJohn.Forte@Sun.COM {
33547836SJohn.Forte@Sun.COM 	int ret;
33559585STim.Szeto@Sun.COM 	int fd;
33569585STim.Szeto@Sun.COM 	int ioctlRet;
33579585STim.Szeto@Sun.COM 	int i;
33589585STim.Szeto@Sun.COM 	int cmd;
33599585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
33609585STim.Szeto@Sun.COM 	/* framework group list */
33619585STim.Szeto@Sun.COM 	stmf_group_name_t iGroupName;
33629585STim.Szeto@Sun.COM 	stmf_ge_ident_t *iGroupMembers;
33639585STim.Szeto@Sun.COM 	uint32_t groupListSize;
33649585STim.Szeto@Sun.COM 
33659585STim.Szeto@Sun.COM 	if (groupName == NULL) {
33669585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33679585STim.Szeto@Sun.COM 	}
33689585STim.Szeto@Sun.COM 
33699585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
33709585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_ENTRIES;
33719585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
33729585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_ENTRIES;
33739585STim.Szeto@Sun.COM 	} else {
33747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33757836SJohn.Forte@Sun.COM 	}
33767836SJohn.Forte@Sun.COM 
33779585STim.Szeto@Sun.COM 	/* call init */
33789585STim.Szeto@Sun.COM 	ret = initializeConfig();
33799585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
33809585STim.Szeto@Sun.COM 		return (ret);
33819585STim.Szeto@Sun.COM 	}
33829585STim.Szeto@Sun.COM 
33839585STim.Szeto@Sun.COM 	/*
33849585STim.Szeto@Sun.COM 	 * Open control node for stmf
33859585STim.Szeto@Sun.COM 	 */
33869585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
33879585STim.Szeto@Sun.COM 		return (ret);
33889585STim.Szeto@Sun.COM 
33899585STim.Szeto@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
33909585STim.Szeto@Sun.COM 
33919585STim.Szeto@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
33929585STim.Szeto@Sun.COM 
33939585STim.Szeto@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
33949585STim.Szeto@Sun.COM 
33959585STim.Szeto@Sun.COM 	/*
33969585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
33979585STim.Szeto@Sun.COM 	 */
33989585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GRP_MEMBER;
33999585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
34009585STim.Szeto@Sun.COM 	iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
34019585STim.Szeto@Sun.COM 	if (iGroupMembers == NULL) {
34029585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
34039585STim.Szeto@Sun.COM 		goto done;
34049585STim.Szeto@Sun.COM 	}
34059585STim.Szeto@Sun.COM 
34069585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
34079585STim.Szeto@Sun.COM 	/*
34089585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
34099585STim.Szeto@Sun.COM 	 */
34109585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
34119585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
34129585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
34139585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
34149585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
34159585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
34169585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
34179585STim.Szeto@Sun.COM 		switch (errno) {
34189585STim.Szeto@Sun.COM 			case EBUSY:
34199585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
34209585STim.Szeto@Sun.COM 				break;
34219585STim.Szeto@Sun.COM 			case EPERM:
34229585STim.Szeto@Sun.COM 			case EACCES:
34239585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
34249585STim.Szeto@Sun.COM 				break;
34259585STim.Szeto@Sun.COM 			default:
34269585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
34279585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
34289585STim.Szeto@Sun.COM 				    errno);
34299585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
34309585STim.Szeto@Sun.COM 				break;
34319585STim.Szeto@Sun.COM 		}
34329585STim.Szeto@Sun.COM 		goto done;
34339585STim.Szeto@Sun.COM 	}
34349585STim.Szeto@Sun.COM 	/*
34359585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
34369585STim.Szeto@Sun.COM 	 */
34379585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
34389585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
34399585STim.Szeto@Sun.COM 		    sizeof (stmf_ge_ident_t);
34409585STim.Szeto@Sun.COM 		iGroupMembers = realloc(iGroupMembers, groupListSize);
34419585STim.Szeto@Sun.COM 		if (iGroupMembers == NULL) {
34429585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
34439585STim.Szeto@Sun.COM 			goto done;
34449585STim.Szeto@Sun.COM 		}
34459585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
34469585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
34479585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
34489585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
34499585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
34509585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
34519585STim.Szeto@Sun.COM 			switch (errno) {
34529585STim.Szeto@Sun.COM 				case EBUSY:
34539585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
34549585STim.Szeto@Sun.COM 					break;
34559585STim.Szeto@Sun.COM 				case EPERM:
34569585STim.Szeto@Sun.COM 				case EACCES:
34579585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
34589585STim.Szeto@Sun.COM 					break;
34599585STim.Szeto@Sun.COM 				default:
34609585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
34619585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
34629585STim.Szeto@Sun.COM 					    errno);
34639585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
34649585STim.Szeto@Sun.COM 					break;
34659585STim.Szeto@Sun.COM 			}
34669585STim.Szeto@Sun.COM 			goto done;
34679585STim.Szeto@Sun.COM 		}
34689585STim.Szeto@Sun.COM 	}
34699585STim.Szeto@Sun.COM 
34709585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
34719585STim.Szeto@Sun.COM 	*groupProps = (stmfGroupProperties *)calloc(1,
347210236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupProperties) +
347310236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries);
34749585STim.Szeto@Sun.COM 	if (*groupProps == NULL) {
34759585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
34769585STim.Szeto@Sun.COM 		goto done;
34779585STim.Szeto@Sun.COM 	}
34789585STim.Szeto@Sun.COM 	(*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
34799585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
34809585STim.Szeto@Sun.COM 		(*groupProps)->name[i].identLength =
348110113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size;
348210113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
348310113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size);
34849585STim.Szeto@Sun.COM 	}
34859585STim.Szeto@Sun.COM 
34869585STim.Szeto@Sun.COM done:
34879585STim.Szeto@Sun.COM 	free(iGroupMembers);
34889585STim.Szeto@Sun.COM 	(void) close(fd);
34899585STim.Szeto@Sun.COM 	return (ret);
34909585STim.Szeto@Sun.COM }
34919585STim.Szeto@Sun.COM 
34929585STim.Szeto@Sun.COM /*
34939585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
34949585STim.Szeto@Sun.COM  */
34959585STim.Szeto@Sun.COM static int
34969585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type)
34979585STim.Szeto@Sun.COM {
34989585STim.Szeto@Sun.COM 	int ret;
34999585STim.Szeto@Sun.COM 
35009585STim.Szeto@Sun.COM 	if (groupList == NULL) {
35019585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35029585STim.Szeto@Sun.COM 	}
35039585STim.Szeto@Sun.COM 
35049585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
35059585STim.Szeto@Sun.COM 		ret = psGetHostGroupList(groupList);
35069585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
35079585STim.Szeto@Sun.COM 		ret = psGetTargetGroupList(groupList);
35089585STim.Szeto@Sun.COM 	} else {
35099585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35109585STim.Szeto@Sun.COM 	}
35117836SJohn.Forte@Sun.COM 	switch (ret) {
35127836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
35137836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
35147836SJohn.Forte@Sun.COM 			break;
35157836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
35167836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
35177836SJohn.Forte@Sun.COM 			break;
35187836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
35197836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
35207836SJohn.Forte@Sun.COM 			break;
35217836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
35227836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
35237836SJohn.Forte@Sun.COM 			break;
35247836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
35257836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
35267836SJohn.Forte@Sun.COM 			break;
35277836SJohn.Forte@Sun.COM 		default:
35287836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
35297836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
35307836SJohn.Forte@Sun.COM 			    ret);
35317836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
35327836SJohn.Forte@Sun.COM 			break;
35337836SJohn.Forte@Sun.COM 	}
35347836SJohn.Forte@Sun.COM 
35357836SJohn.Forte@Sun.COM 	return (ret);
35367836SJohn.Forte@Sun.COM }
35377836SJohn.Forte@Sun.COM 
35387836SJohn.Forte@Sun.COM /*
35399585STim.Szeto@Sun.COM  * stmfGetHostGroupList
35407836SJohn.Forte@Sun.COM  *
35419585STim.Szeto@Sun.COM  * Purpose: Retrieves the list of initiator group oids
35429585STim.Szeto@Sun.COM  *
35439585STim.Szeto@Sun.COM  * hostGroupList - pointer to pointer to hostGroupList structure
35449585STim.Szeto@Sun.COM  *                 on success, this contains the host group list.
35457836SJohn.Forte@Sun.COM  */
35467836SJohn.Forte@Sun.COM int
35479585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList)
35489585STim.Szeto@Sun.COM {
35499585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
35509585STim.Szeto@Sun.COM 
35519585STim.Szeto@Sun.COM 	if (hostGroupList == NULL) {
35529585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35539585STim.Szeto@Sun.COM 	}
35549585STim.Szeto@Sun.COM 
35559585STim.Szeto@Sun.COM 	ret = groupListIoctl(hostGroupList, HOST_GROUP);
35569585STim.Szeto@Sun.COM 	return (ret);
35579585STim.Szeto@Sun.COM }
35589585STim.Szeto@Sun.COM 
35599585STim.Szeto@Sun.COM 
35609585STim.Szeto@Sun.COM /*
35619585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
35629585STim.Szeto@Sun.COM  */
35639585STim.Szeto@Sun.COM static int
35649585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName,
35659585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp, int type)
35667836SJohn.Forte@Sun.COM {
35677836SJohn.Forte@Sun.COM 	int ret;
35687836SJohn.Forte@Sun.COM 
35699585STim.Szeto@Sun.COM 	if (groupName == NULL) {
35707836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35717836SJohn.Forte@Sun.COM 	}
35727836SJohn.Forte@Sun.COM 
35739585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
35749585STim.Szeto@Sun.COM 		ret = psGetHostGroupMemberList((char *)groupName, groupProp);
35759585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
35769585STim.Szeto@Sun.COM 		ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
35779585STim.Szeto@Sun.COM 	} else {
35789585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35799585STim.Szeto@Sun.COM 	}
35807836SJohn.Forte@Sun.COM 	switch (ret) {
35817836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
35827836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
35837836SJohn.Forte@Sun.COM 			break;
35847836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
35857836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
35867836SJohn.Forte@Sun.COM 			break;
35877836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
35887836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
35897836SJohn.Forte@Sun.COM 			break;
35907836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
35917836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
35927836SJohn.Forte@Sun.COM 			break;
35937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
35947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
35957836SJohn.Forte@Sun.COM 			break;
35967836SJohn.Forte@Sun.COM 		default:
35977836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
35989585STim.Szeto@Sun.COM 			    "iLoadGroupMembersFromPs:psGetHostGroupList:"
35999585STim.Szeto@Sun.COM 			    "error(%d)", ret);
36007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
36017836SJohn.Forte@Sun.COM 			break;
36027836SJohn.Forte@Sun.COM 	}
36037836SJohn.Forte@Sun.COM 
36047836SJohn.Forte@Sun.COM 	return (ret);
36057836SJohn.Forte@Sun.COM }
36067836SJohn.Forte@Sun.COM 
36077836SJohn.Forte@Sun.COM /*
36089585STim.Szeto@Sun.COM  * stmfGetHostGroupMembers
36099585STim.Szeto@Sun.COM  *
36109585STim.Szeto@Sun.COM  * Purpose: Retrieves the group properties for a host group
36119585STim.Szeto@Sun.COM  *
36129585STim.Szeto@Sun.COM  * groupName - name of group for which to retrieve host group members.
36139585STim.Szeto@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
36149585STim.Szeto@Sun.COM  *             on success, this contains the list of group members.
36159585STim.Szeto@Sun.COM  */
36169585STim.Szeto@Sun.COM int
36179585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName,
36189585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp)
36199585STim.Szeto@Sun.COM {
36209585STim.Szeto@Sun.COM 	int ret;
36219585STim.Szeto@Sun.COM 
36229585STim.Szeto@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
36239585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36249585STim.Szeto@Sun.COM 	}
36259585STim.Szeto@Sun.COM 
36269585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
36279585STim.Szeto@Sun.COM 
36289585STim.Szeto@Sun.COM 	return (ret);
36299585STim.Szeto@Sun.COM }
36309585STim.Szeto@Sun.COM 
36319585STim.Szeto@Sun.COM /*
36327836SJohn.Forte@Sun.COM  * stmfGetProviderData
36337836SJohn.Forte@Sun.COM  *
36347836SJohn.Forte@Sun.COM  * Purpose: Get provider data list
36357836SJohn.Forte@Sun.COM  *
36367836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
36377836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
36387836SJohn.Forte@Sun.COM  *       retrieved.
36397836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
36407836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
36417836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
36427836SJohn.Forte@Sun.COM  */
36437836SJohn.Forte@Sun.COM int
36447836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
36457836SJohn.Forte@Sun.COM {
36467836SJohn.Forte@Sun.COM 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
36477836SJohn.Forte@Sun.COM 	    NULL));
36487836SJohn.Forte@Sun.COM }
36497836SJohn.Forte@Sun.COM 
36507836SJohn.Forte@Sun.COM /*
36517836SJohn.Forte@Sun.COM  * stmfGetProviderDataProt
36527836SJohn.Forte@Sun.COM  *
36537836SJohn.Forte@Sun.COM  * Purpose: Get provider data list with token
36547836SJohn.Forte@Sun.COM  *
36557836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
36567836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
36577836SJohn.Forte@Sun.COM  *       retrieved.
36587836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
36597836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
36607836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
36617836SJohn.Forte@Sun.COM  * setToken - Returns the stale data token
36627836SJohn.Forte@Sun.COM  */
36637836SJohn.Forte@Sun.COM int
36647836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
36657836SJohn.Forte@Sun.COM     uint64_t *setToken)
36667836SJohn.Forte@Sun.COM {
36677836SJohn.Forte@Sun.COM 	int ret;
36687836SJohn.Forte@Sun.COM 
36697836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
36707836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36717836SJohn.Forte@Sun.COM 	}
36727836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
36737836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
36747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36757836SJohn.Forte@Sun.COM 	}
36767836SJohn.Forte@Sun.COM 	/* call init */
36777836SJohn.Forte@Sun.COM 	ret = initializeConfig();
36787836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
36797836SJohn.Forte@Sun.COM 		return (ret);
36807836SJohn.Forte@Sun.COM 	}
36819585STim.Szeto@Sun.COM 	return (getProviderData(providerName, nvl, providerType, setToken));
36827836SJohn.Forte@Sun.COM }
36837836SJohn.Forte@Sun.COM 
36847836SJohn.Forte@Sun.COM /*
36857836SJohn.Forte@Sun.COM  * stmfGetProviderDataList
36867836SJohn.Forte@Sun.COM  *
36877836SJohn.Forte@Sun.COM  * Purpose: Get the list of providers currently persisting data
36887836SJohn.Forte@Sun.COM  *
36897836SJohn.Forte@Sun.COM  * providerList - pointer to pointer to an stmfProviderList structure allocated
36907836SJohn.Forte@Sun.COM  *                by the caller. Will contain the list of providers on success.
36917836SJohn.Forte@Sun.COM  */
36927836SJohn.Forte@Sun.COM int
36937836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList)
36947836SJohn.Forte@Sun.COM {
36957836SJohn.Forte@Sun.COM 	int ret;
36967836SJohn.Forte@Sun.COM 
36977836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(providerList);
36987836SJohn.Forte@Sun.COM 	switch (ret) {
36997836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
37007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
37017836SJohn.Forte@Sun.COM 			break;
37027836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
37037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
37047836SJohn.Forte@Sun.COM 			break;
37057836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
37067836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
37077836SJohn.Forte@Sun.COM 			break;
37087836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
37097836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
37107836SJohn.Forte@Sun.COM 			break;
37117836SJohn.Forte@Sun.COM 		default:
37127836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
37137836SJohn.Forte@Sun.COM 			    "stmfGetProviderDataList:psGetProviderDataList"
37147836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
37157836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
37167836SJohn.Forte@Sun.COM 			break;
37177836SJohn.Forte@Sun.COM 	}
37187836SJohn.Forte@Sun.COM 
37197836SJohn.Forte@Sun.COM 	return (ret);
37207836SJohn.Forte@Sun.COM }
37217836SJohn.Forte@Sun.COM 
37227836SJohn.Forte@Sun.COM 
37237836SJohn.Forte@Sun.COM /*
37247836SJohn.Forte@Sun.COM  * stmfGetSessionList
37257836SJohn.Forte@Sun.COM  *
37267836SJohn.Forte@Sun.COM  * Purpose: Retrieves the session list for a target (devid)
37277836SJohn.Forte@Sun.COM  *
37287836SJohn.Forte@Sun.COM  * devid - devid of target for which to retrieve session information.
37297836SJohn.Forte@Sun.COM  * sessionList - pointer to pointer to stmfSessionList structure
37307836SJohn.Forte@Sun.COM  *             on success, this contains the list of initiator sessions.
37317836SJohn.Forte@Sun.COM  */
37327836SJohn.Forte@Sun.COM int
37337836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
37347836SJohn.Forte@Sun.COM {
37357836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
37367836SJohn.Forte@Sun.COM 	int fd;
37377836SJohn.Forte@Sun.COM 	int ioctlRet;
37387836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_SESSION_LIST;
37397836SJohn.Forte@Sun.COM 	int i;
37407836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
374110261SCharles.Ting@Sun.COM 	slist_scsi_session_t *fSessionList, *fSessionListP = NULL;
37427836SJohn.Forte@Sun.COM 	uint8_t ident[260];
37437836SJohn.Forte@Sun.COM 	uint32_t fSessionListSize;
37447836SJohn.Forte@Sun.COM 
37457836SJohn.Forte@Sun.COM 	if (sessionList == NULL || devid == NULL) {
37467836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
37477836SJohn.Forte@Sun.COM 	}
37487836SJohn.Forte@Sun.COM 
37497836SJohn.Forte@Sun.COM 	/* call init */
37507836SJohn.Forte@Sun.COM 	ret = initializeConfig();
37517836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
37527836SJohn.Forte@Sun.COM 		return (ret);
37537836SJohn.Forte@Sun.COM 	}
37547836SJohn.Forte@Sun.COM 
37557836SJohn.Forte@Sun.COM 	/*
37567836SJohn.Forte@Sun.COM 	 * Open control node for stmf
37577836SJohn.Forte@Sun.COM 	 */
37587836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
37597836SJohn.Forte@Sun.COM 		return (ret);
37607836SJohn.Forte@Sun.COM 
37617836SJohn.Forte@Sun.COM 	/*
37627836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
37637836SJohn.Forte@Sun.COM 	 */
37649585STim.Szeto@Sun.COM 	fSessionListSize = ALLOC_SESSION;
37657836SJohn.Forte@Sun.COM 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
37667836SJohn.Forte@Sun.COM 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
376710261SCharles.Ting@Sun.COM 	fSessionListP = fSessionList;
37687836SJohn.Forte@Sun.COM 	if (fSessionList == NULL) {
376910261SCharles.Ting@Sun.COM 		ret = STMF_ERROR_NOMEM;
377010261SCharles.Ting@Sun.COM 		goto done;
37717836SJohn.Forte@Sun.COM 	}
37727836SJohn.Forte@Sun.COM 
37737836SJohn.Forte@Sun.COM 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
37747836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
37757836SJohn.Forte@Sun.COM 	    devid->identLength);
37767836SJohn.Forte@Sun.COM 
37777836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
37787836SJohn.Forte@Sun.COM 	/*
37797836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the session list
37807836SJohn.Forte@Sun.COM 	 */
37817836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
37827836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
37837836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
37847836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fSessionListSize;
37857836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
37867836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
37877836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
37887836SJohn.Forte@Sun.COM 		switch (errno) {
37897836SJohn.Forte@Sun.COM 			case EBUSY:
37907836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
37917836SJohn.Forte@Sun.COM 				break;
37929585STim.Szeto@Sun.COM 			case EPERM:
37937836SJohn.Forte@Sun.COM 			case EACCES:
37947836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
37957836SJohn.Forte@Sun.COM 				break;
37967836SJohn.Forte@Sun.COM 			default:
37977836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
37987836SJohn.Forte@Sun.COM 				    "stmfGetSessionList:ioctl errno(%d)",
37997836SJohn.Forte@Sun.COM 				    errno);
38007836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
38017836SJohn.Forte@Sun.COM 				break;
38027836SJohn.Forte@Sun.COM 		}
38037836SJohn.Forte@Sun.COM 		goto done;
38047836SJohn.Forte@Sun.COM 	}
38057836SJohn.Forte@Sun.COM 	/*
38067836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
38077836SJohn.Forte@Sun.COM 	 */
38089585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
38097836SJohn.Forte@Sun.COM 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
38107836SJohn.Forte@Sun.COM 		    sizeof (slist_scsi_session_t);
38117836SJohn.Forte@Sun.COM 		fSessionList = realloc(fSessionList, fSessionListSize);
38127836SJohn.Forte@Sun.COM 		if (fSessionList == NULL) {
381310261SCharles.Ting@Sun.COM 			ret = STMF_ERROR_NOMEM;
381410261SCharles.Ting@Sun.COM 			goto done;
38157836SJohn.Forte@Sun.COM 		}
381610261SCharles.Ting@Sun.COM 		fSessionListP = fSessionList;
38177836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fSessionListSize;
38187836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
38197836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
38207836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
38217836SJohn.Forte@Sun.COM 			switch (errno) {
38227836SJohn.Forte@Sun.COM 				case EBUSY:
38237836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
38247836SJohn.Forte@Sun.COM 					break;
38259585STim.Szeto@Sun.COM 				case EPERM:
38267836SJohn.Forte@Sun.COM 				case EACCES:
38277836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
38287836SJohn.Forte@Sun.COM 					break;
38297836SJohn.Forte@Sun.COM 				default:
38307836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
38317836SJohn.Forte@Sun.COM 					    "stmfGetSessionList:ioctl "
38327836SJohn.Forte@Sun.COM 					    "errno(%d)", errno);
38337836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
38347836SJohn.Forte@Sun.COM 					break;
38357836SJohn.Forte@Sun.COM 			}
38367836SJohn.Forte@Sun.COM 			goto done;
38377836SJohn.Forte@Sun.COM 		}
38387836SJohn.Forte@Sun.COM 	}
38397836SJohn.Forte@Sun.COM 
38407836SJohn.Forte@Sun.COM 	/*
38417836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
38427836SJohn.Forte@Sun.COM 	 */
38437836SJohn.Forte@Sun.COM 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
38447836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
38457836SJohn.Forte@Sun.COM 	if (*sessionList == NULL) {
38467836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
38477836SJohn.Forte@Sun.COM 		free(sessionList);
38487836SJohn.Forte@Sun.COM 		goto done;
38497836SJohn.Forte@Sun.COM 	}
38507836SJohn.Forte@Sun.COM 
38517836SJohn.Forte@Sun.COM 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
38527836SJohn.Forte@Sun.COM 
38537836SJohn.Forte@Sun.COM 	/*
38547836SJohn.Forte@Sun.COM 	 * copy session info to caller's buffer
38557836SJohn.Forte@Sun.COM 	 */
38567836SJohn.Forte@Sun.COM 	for (i = 0; i < (*sessionList)->cnt; i++) {
38577836SJohn.Forte@Sun.COM 		(*sessionList)->session[i].initiator.identLength =
38587836SJohn.Forte@Sun.COM 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
38597836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
38607836SJohn.Forte@Sun.COM 		    (*sessionList)->session[i].initiator.ident,
38617836SJohn.Forte@Sun.COM 		    STMF_IDENT_LENGTH);
38627836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->alias),
38637836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].alias),
38647836SJohn.Forte@Sun.COM 		    sizeof ((*sessionList)->session[i].alias));
38657836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList++->creation_time),
38667836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].creationTime),
38677836SJohn.Forte@Sun.COM 		    sizeof (time_t));
38687836SJohn.Forte@Sun.COM 	}
38697836SJohn.Forte@Sun.COM done:
38707836SJohn.Forte@Sun.COM 	(void) close(fd);
387110261SCharles.Ting@Sun.COM 	free(fSessionListP);
38727836SJohn.Forte@Sun.COM 	return (ret);
38737836SJohn.Forte@Sun.COM }
38747836SJohn.Forte@Sun.COM 
38757836SJohn.Forte@Sun.COM /*
38767836SJohn.Forte@Sun.COM  * stmfGetTargetGroupList
38777836SJohn.Forte@Sun.COM  *
38787836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target groups
38797836SJohn.Forte@Sun.COM  *
38807836SJohn.Forte@Sun.COM  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
38817836SJohn.Forte@Sun.COM  *		     success, it contains the list of target groups.
38827836SJohn.Forte@Sun.COM  */
38837836SJohn.Forte@Sun.COM int
38847836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList)
38857836SJohn.Forte@Sun.COM {
38867836SJohn.Forte@Sun.COM 	int ret;
38877836SJohn.Forte@Sun.COM 
38887836SJohn.Forte@Sun.COM 	if (targetGroupList == NULL) {
38897836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38907836SJohn.Forte@Sun.COM 	}
38917836SJohn.Forte@Sun.COM 
38929585STim.Szeto@Sun.COM 	ret = groupListIoctl(targetGroupList, TARGET_GROUP);
38937836SJohn.Forte@Sun.COM 	return (ret);
38947836SJohn.Forte@Sun.COM }
38957836SJohn.Forte@Sun.COM 
38967836SJohn.Forte@Sun.COM /*
38977836SJohn.Forte@Sun.COM  * stmfGetTargetGroupMembers
38987836SJohn.Forte@Sun.COM  *
38997836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group members for a target group
39007836SJohn.Forte@Sun.COM  *
39017836SJohn.Forte@Sun.COM  * groupName - name of target group for which to retrieve members.
39027836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
39037836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
39047836SJohn.Forte@Sun.COM  */
39057836SJohn.Forte@Sun.COM int
39067836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName,
39077836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
39087836SJohn.Forte@Sun.COM {
39097836SJohn.Forte@Sun.COM 	int ret;
39107836SJohn.Forte@Sun.COM 
39117836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
39127836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39137836SJohn.Forte@Sun.COM 	}
39147836SJohn.Forte@Sun.COM 
39159585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
39167836SJohn.Forte@Sun.COM 
39177836SJohn.Forte@Sun.COM 	return (ret);
39187836SJohn.Forte@Sun.COM }
39197836SJohn.Forte@Sun.COM 
39207836SJohn.Forte@Sun.COM /*
39217836SJohn.Forte@Sun.COM  * stmfGetTargetList
39227836SJohn.Forte@Sun.COM  *
39237836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target ports
39247836SJohn.Forte@Sun.COM  *
39257836SJohn.Forte@Sun.COM  * targetList - pointer to a pointer to an stmfDevidList structure.
39267836SJohn.Forte@Sun.COM  *		    On success, it contains the list of local ports (target).
39277836SJohn.Forte@Sun.COM  */
39287836SJohn.Forte@Sun.COM int
39297836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList)
39307836SJohn.Forte@Sun.COM {
39317836SJohn.Forte@Sun.COM 	int ret;
39327836SJohn.Forte@Sun.COM 	int fd;
39337836SJohn.Forte@Sun.COM 	int ioctlRet;
39347836SJohn.Forte@Sun.COM 	int i;
39357836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
39367836SJohn.Forte@Sun.COM 	/* framework target port list */
39379585STim.Szeto@Sun.COM 	slist_target_port_t *fTargetList, *fTargetListP = NULL;
39387836SJohn.Forte@Sun.COM 	uint32_t fTargetListSize;
39397836SJohn.Forte@Sun.COM 
39407836SJohn.Forte@Sun.COM 	if (targetList == NULL) {
39417836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39427836SJohn.Forte@Sun.COM 	}
39437836SJohn.Forte@Sun.COM 
39447836SJohn.Forte@Sun.COM 	/* call init */
39457836SJohn.Forte@Sun.COM 	ret = initializeConfig();
39467836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
39477836SJohn.Forte@Sun.COM 		return (ret);
39487836SJohn.Forte@Sun.COM 	}
39497836SJohn.Forte@Sun.COM 
39507836SJohn.Forte@Sun.COM 	/*
39517836SJohn.Forte@Sun.COM 	 * Open control node for stmf
39527836SJohn.Forte@Sun.COM 	 */
39537836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
39547836SJohn.Forte@Sun.COM 		return (ret);
39557836SJohn.Forte@Sun.COM 
39567836SJohn.Forte@Sun.COM 	/*
39577836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
39587836SJohn.Forte@Sun.COM 	 */
39599585STim.Szeto@Sun.COM 	fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
39608252SJohn.Forte@Sun.COM 	fTargetListP = fTargetList =
39618252SJohn.Forte@Sun.COM 	    (slist_target_port_t *)calloc(1, fTargetListSize);
39627836SJohn.Forte@Sun.COM 	if (fTargetList == NULL) {
39639585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
39647836SJohn.Forte@Sun.COM 		goto done;
39657836SJohn.Forte@Sun.COM 	}
39667836SJohn.Forte@Sun.COM 
39677836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
39687836SJohn.Forte@Sun.COM 	/*
39698252SJohn.Forte@Sun.COM 	 * Issue ioctl to retrieve target list
39707836SJohn.Forte@Sun.COM 	 */
39717836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
39727836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fTargetListSize;
39737836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
39747836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
39757836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
39767836SJohn.Forte@Sun.COM 		switch (errno) {
39777836SJohn.Forte@Sun.COM 			case EBUSY:
39787836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
39797836SJohn.Forte@Sun.COM 				break;
39809585STim.Szeto@Sun.COM 			case EPERM:
39817836SJohn.Forte@Sun.COM 			case EACCES:
39827836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
39837836SJohn.Forte@Sun.COM 				break;
39847836SJohn.Forte@Sun.COM 			default:
39857836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
39867836SJohn.Forte@Sun.COM 				    "stmfGetTargetList:ioctl errno(%d)", errno);
39877836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
39887836SJohn.Forte@Sun.COM 				break;
39897836SJohn.Forte@Sun.COM 		}
39907836SJohn.Forte@Sun.COM 		goto done;
39917836SJohn.Forte@Sun.COM 	}
39927836SJohn.Forte@Sun.COM 	/*
39937836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
39947836SJohn.Forte@Sun.COM 	 */
39959585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
39967836SJohn.Forte@Sun.COM 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
39978116SJohn.Forte@Sun.COM 		    sizeof (slist_target_port_t);
39988252SJohn.Forte@Sun.COM 		fTargetListP = fTargetList =
39998252SJohn.Forte@Sun.COM 		    realloc(fTargetList, fTargetListSize);
40007836SJohn.Forte@Sun.COM 		if (fTargetList == NULL) {
40019585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
40029585STim.Szeto@Sun.COM 			goto done;
40037836SJohn.Forte@Sun.COM 		}
40047836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fTargetListSize;
40057836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
40067836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
40077836SJohn.Forte@Sun.COM 		    &stmfIoctl);
40087836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
40097836SJohn.Forte@Sun.COM 			switch (errno) {
40107836SJohn.Forte@Sun.COM 				case EBUSY:
40117836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
40127836SJohn.Forte@Sun.COM 					break;
40139585STim.Szeto@Sun.COM 				case EPERM:
40147836SJohn.Forte@Sun.COM 				case EACCES:
40157836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
40167836SJohn.Forte@Sun.COM 					break;
40177836SJohn.Forte@Sun.COM 				default:
40187836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
40197836SJohn.Forte@Sun.COM 					    "stmfGetTargetList:ioctl errno(%d)",
40207836SJohn.Forte@Sun.COM 					    errno);
40217836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
40227836SJohn.Forte@Sun.COM 					break;
40237836SJohn.Forte@Sun.COM 			}
40247836SJohn.Forte@Sun.COM 			goto done;
40257836SJohn.Forte@Sun.COM 		}
40267836SJohn.Forte@Sun.COM 	}
40277836SJohn.Forte@Sun.COM 
40287836SJohn.Forte@Sun.COM 	*targetList = (stmfDevidList *)calloc(1,
40297836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
40307836SJohn.Forte@Sun.COM 	    sizeof (stmfDevidList));
40319585STim.Szeto@Sun.COM 	if (*targetList == NULL) {
40329585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
40339585STim.Szeto@Sun.COM 		goto done;
40349585STim.Szeto@Sun.COM 	}
40357836SJohn.Forte@Sun.COM 
40367836SJohn.Forte@Sun.COM 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
40377836SJohn.Forte@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
40387836SJohn.Forte@Sun.COM 		(*targetList)->devid[i].identLength =
40397836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE];
40407836SJohn.Forte@Sun.COM 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
40417836SJohn.Forte@Sun.COM 		    &(*targetList)->devid[i].ident,
40427836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE]);
40437836SJohn.Forte@Sun.COM 	}
40447836SJohn.Forte@Sun.COM 
40457836SJohn.Forte@Sun.COM done:
40467836SJohn.Forte@Sun.COM 	(void) close(fd);
40478252SJohn.Forte@Sun.COM 	free(fTargetListP);
40487836SJohn.Forte@Sun.COM 	return (ret);
40497836SJohn.Forte@Sun.COM }
40507836SJohn.Forte@Sun.COM 
40517836SJohn.Forte@Sun.COM /*
40527836SJohn.Forte@Sun.COM  * stmfGetTargetProperties
40537836SJohn.Forte@Sun.COM  *
40547836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
40557836SJohn.Forte@Sun.COM  *
40567836SJohn.Forte@Sun.COM  * devid - devid of the target for which to retrieve properties
40577836SJohn.Forte@Sun.COM  * targetProps - pointer to an stmfTargetProperties structure.
40587836SJohn.Forte@Sun.COM  *		On success, it contains the target properties for
40597836SJohn.Forte@Sun.COM  *		the specified devid.
40607836SJohn.Forte@Sun.COM  */
40617836SJohn.Forte@Sun.COM int
40627836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
40637836SJohn.Forte@Sun.COM {
40647836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
40657836SJohn.Forte@Sun.COM 	int fd;
40667836SJohn.Forte@Sun.COM 	int ioctlRet;
40677836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
40687836SJohn.Forte@Sun.COM 	sioc_target_port_props_t targetProperties;
406910725SJohn.Forte@Sun.COM 	scsi_devid_desc_t *scsiDevid;
40707836SJohn.Forte@Sun.COM 
40717836SJohn.Forte@Sun.COM 	if (devid == NULL || targetProps == NULL) {
40727836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
40737836SJohn.Forte@Sun.COM 	}
40747836SJohn.Forte@Sun.COM 
40757836SJohn.Forte@Sun.COM 	/* call init */
40767836SJohn.Forte@Sun.COM 	ret = initializeConfig();
40777836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
40787836SJohn.Forte@Sun.COM 		return (ret);
40797836SJohn.Forte@Sun.COM 	}
40807836SJohn.Forte@Sun.COM 
40817836SJohn.Forte@Sun.COM 	/*
40827836SJohn.Forte@Sun.COM 	 * Open control node for stmf
40837836SJohn.Forte@Sun.COM 	 */
40847836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
40857836SJohn.Forte@Sun.COM 		return (ret);
40867836SJohn.Forte@Sun.COM 
40877836SJohn.Forte@Sun.COM 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
40887836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
40897836SJohn.Forte@Sun.COM 	    devid->identLength);
40907836SJohn.Forte@Sun.COM 
40917836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
40927836SJohn.Forte@Sun.COM 	/*
40937836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
40947836SJohn.Forte@Sun.COM 	 */
40957836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
40967836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
40977836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
40987836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
40997836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
41007836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
41017836SJohn.Forte@Sun.COM 	    &stmfIoctl);
41027836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
41037836SJohn.Forte@Sun.COM 		switch (errno) {
41047836SJohn.Forte@Sun.COM 			case EBUSY:
41057836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
41067836SJohn.Forte@Sun.COM 				break;
41079585STim.Szeto@Sun.COM 			case EPERM:
41087836SJohn.Forte@Sun.COM 			case EACCES:
41097836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
41107836SJohn.Forte@Sun.COM 				break;
41117836SJohn.Forte@Sun.COM 			case ENOENT:
41127836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
41137836SJohn.Forte@Sun.COM 				break;
41147836SJohn.Forte@Sun.COM 			default:
41157836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
41167836SJohn.Forte@Sun.COM 				    "stmfGetTargetProperties:ioctl errno(%d)",
41177836SJohn.Forte@Sun.COM 				    errno);
41187836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
41197836SJohn.Forte@Sun.COM 				break;
41207836SJohn.Forte@Sun.COM 		}
41217836SJohn.Forte@Sun.COM 		goto done;
41227836SJohn.Forte@Sun.COM 	}
41237836SJohn.Forte@Sun.COM 
41247836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
41257836SJohn.Forte@Sun.COM 	    sizeof (targetProperties.tgt_provider_name));
41267836SJohn.Forte@Sun.COM 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
41277836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINE;
41287836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
41297836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
41307836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
41317836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINING;
41327836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
41337836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
41347836SJohn.Forte@Sun.COM 	}
41357836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_alias, targetProps->alias,
41367836SJohn.Forte@Sun.COM 	    sizeof (targetProps->alias));
413710725SJohn.Forte@Sun.COM 
413810725SJohn.Forte@Sun.COM 	scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id;
413910725SJohn.Forte@Sun.COM 	targetProps->protocol = scsiDevid->protocol_id;
414010725SJohn.Forte@Sun.COM 
41417836SJohn.Forte@Sun.COM done:
41427836SJohn.Forte@Sun.COM 	(void) close(fd);
41437836SJohn.Forte@Sun.COM 	return (ret);
41447836SJohn.Forte@Sun.COM }
41457836SJohn.Forte@Sun.COM 
41467836SJohn.Forte@Sun.COM /*
41477836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitList
41487836SJohn.Forte@Sun.COM  *
41497836SJohn.Forte@Sun.COM  * Purpose: Retrieves list of logical unit Object IDs
41507836SJohn.Forte@Sun.COM  *
41517836SJohn.Forte@Sun.COM  * luList - pointer to a pointer to a stmfGuidList structure. On success,
41527836SJohn.Forte@Sun.COM  *          it contains the list of logical unit guids.
41537836SJohn.Forte@Sun.COM  *
41547836SJohn.Forte@Sun.COM  */
41557836SJohn.Forte@Sun.COM int
41567836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList)
41577836SJohn.Forte@Sun.COM {
41587836SJohn.Forte@Sun.COM 	int ret;
41597836SJohn.Forte@Sun.COM 	int fd;
41607836SJohn.Forte@Sun.COM 	int ioctlRet;
41617836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_LU_LIST;
41629585STim.Szeto@Sun.COM 	int i;
41637836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
41647836SJohn.Forte@Sun.COM 	slist_lu_t *fLuList;
41657836SJohn.Forte@Sun.COM 	uint32_t fLuListSize;
41669585STim.Szeto@Sun.COM 	uint32_t listCnt;
41677836SJohn.Forte@Sun.COM 
41687836SJohn.Forte@Sun.COM 	if (luList == NULL) {
41697836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
41707836SJohn.Forte@Sun.COM 	}
41717836SJohn.Forte@Sun.COM 
41727836SJohn.Forte@Sun.COM 	/* call init */
41737836SJohn.Forte@Sun.COM 	ret = initializeConfig();
41747836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
41757836SJohn.Forte@Sun.COM 		return (ret);
41767836SJohn.Forte@Sun.COM 	}
41777836SJohn.Forte@Sun.COM 
41787836SJohn.Forte@Sun.COM 	/*
41797836SJohn.Forte@Sun.COM 	 * Open control node for stmf
41807836SJohn.Forte@Sun.COM 	 */
41817836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
41827836SJohn.Forte@Sun.COM 		return (ret);
41837836SJohn.Forte@Sun.COM 
41847836SJohn.Forte@Sun.COM 	/*
41857836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
41867836SJohn.Forte@Sun.COM 	 */
41879585STim.Szeto@Sun.COM 	fLuListSize = ALLOC_LU;
41887836SJohn.Forte@Sun.COM 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
41897836SJohn.Forte@Sun.COM 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
41907836SJohn.Forte@Sun.COM 	if (fLuList == NULL) {
41919585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
41929585STim.Szeto@Sun.COM 		goto done;
41937836SJohn.Forte@Sun.COM 	}
41947836SJohn.Forte@Sun.COM 
41957836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
41967836SJohn.Forte@Sun.COM 	/*
41977836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the LU list
41987836SJohn.Forte@Sun.COM 	 */
41997836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
42007836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fLuListSize;
42017836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
42027836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
42037836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
42047836SJohn.Forte@Sun.COM 		switch (errno) {
42057836SJohn.Forte@Sun.COM 			case EBUSY:
42067836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
42077836SJohn.Forte@Sun.COM 				break;
42089585STim.Szeto@Sun.COM 			case EPERM:
42097836SJohn.Forte@Sun.COM 			case EACCES:
42107836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
42117836SJohn.Forte@Sun.COM 				break;
42127836SJohn.Forte@Sun.COM 			default:
42137836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
42147836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
42157836SJohn.Forte@Sun.COM 				    errno);
42167836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
42177836SJohn.Forte@Sun.COM 				break;
42187836SJohn.Forte@Sun.COM 		}
42197836SJohn.Forte@Sun.COM 		goto done;
42207836SJohn.Forte@Sun.COM 	}
42217836SJohn.Forte@Sun.COM 	/*
42227836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
42237836SJohn.Forte@Sun.COM 	 */
42249585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
42257836SJohn.Forte@Sun.COM 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
42267836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
42279585STim.Szeto@Sun.COM 		free(fLuList);
42289585STim.Szeto@Sun.COM 		fLuList = (slist_lu_t *)calloc(1, fLuListSize);
42297836SJohn.Forte@Sun.COM 		if (fLuList == NULL) {
42309585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
42319585STim.Szeto@Sun.COM 			goto done;
42327836SJohn.Forte@Sun.COM 		}
42337836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fLuListSize;
42347836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
42357836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
42367836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
42377836SJohn.Forte@Sun.COM 			switch (errno) {
42387836SJohn.Forte@Sun.COM 				case EBUSY:
42397836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
42407836SJohn.Forte@Sun.COM 					break;
42419585STim.Szeto@Sun.COM 				case EPERM:
42427836SJohn.Forte@Sun.COM 				case EACCES:
42437836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
42447836SJohn.Forte@Sun.COM 					break;
42457836SJohn.Forte@Sun.COM 				default:
42467836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
42477836SJohn.Forte@Sun.COM 					    "stmfGetLogicalUnitList:"
42487836SJohn.Forte@Sun.COM 					    "ioctl errno(%d)", errno);
42497836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
42507836SJohn.Forte@Sun.COM 					break;
42517836SJohn.Forte@Sun.COM 			}
42527836SJohn.Forte@Sun.COM 			goto done;
42537836SJohn.Forte@Sun.COM 		}
42547836SJohn.Forte@Sun.COM 	}
42557836SJohn.Forte@Sun.COM 
42567836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
42577836SJohn.Forte@Sun.COM 		goto done;
42587836SJohn.Forte@Sun.COM 	}
42597836SJohn.Forte@Sun.COM 
42609585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
42617836SJohn.Forte@Sun.COM 
42627836SJohn.Forte@Sun.COM 	/*
42637836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
42647836SJohn.Forte@Sun.COM 	 */
42657836SJohn.Forte@Sun.COM 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
42669585STim.Szeto@Sun.COM 	    listCnt * sizeof (stmfGuid));
42677836SJohn.Forte@Sun.COM 	if (*luList == NULL) {
42687836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
42697836SJohn.Forte@Sun.COM 		goto done;
42707836SJohn.Forte@Sun.COM 	}
42717836SJohn.Forte@Sun.COM 
42729585STim.Szeto@Sun.COM 	(*luList)->cnt = listCnt;
42739585STim.Szeto@Sun.COM 
42749585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
42759585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
42769585STim.Szeto@Sun.COM 		bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
42779585STim.Szeto@Sun.COM 		    sizeof (stmfGuid));
42789585STim.Szeto@Sun.COM 	}
42799585STim.Szeto@Sun.COM 
42807836SJohn.Forte@Sun.COM 	/*
42819585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
42827836SJohn.Forte@Sun.COM 	 */
42839585STim.Szeto@Sun.COM 	qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
42849585STim.Szeto@Sun.COM 	    sizeof (stmfGuid), guidCompare);
42857836SJohn.Forte@Sun.COM 
42867836SJohn.Forte@Sun.COM done:
42877836SJohn.Forte@Sun.COM 	(void) close(fd);
42887836SJohn.Forte@Sun.COM 	/*
42897836SJohn.Forte@Sun.COM 	 * free internal buffers
42907836SJohn.Forte@Sun.COM 	 */
42917836SJohn.Forte@Sun.COM 	free(fLuList);
42927836SJohn.Forte@Sun.COM 	return (ret);
42937836SJohn.Forte@Sun.COM }
42947836SJohn.Forte@Sun.COM 
42957836SJohn.Forte@Sun.COM /*
42967836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitProperties
42977836SJohn.Forte@Sun.COM  *
42987836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
42997836SJohn.Forte@Sun.COM  *
43007836SJohn.Forte@Sun.COM  * lu - guid of the logical unit for which to retrieve properties
43017836SJohn.Forte@Sun.COM  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
43027836SJohn.Forte@Sun.COM  *               it contains the logical unit properties for the specified guid.
43037836SJohn.Forte@Sun.COM  */
43047836SJohn.Forte@Sun.COM int
43057836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
43067836SJohn.Forte@Sun.COM {
43077836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
43087836SJohn.Forte@Sun.COM 	int stmfRet;
43097836SJohn.Forte@Sun.COM 	int fd;
43107836SJohn.Forte@Sun.COM 	int ioctlRet;
43117836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
43127836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
43137836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
43147836SJohn.Forte@Sun.COM 	sioc_lu_props_t fLuProps;
43157836SJohn.Forte@Sun.COM 
43169585STim.Szeto@Sun.COM 	if (lu == NULL || luProps == NULL) {
43179585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
43187836SJohn.Forte@Sun.COM 	}
43197836SJohn.Forte@Sun.COM 
43207836SJohn.Forte@Sun.COM 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
43217836SJohn.Forte@Sun.COM 
43227836SJohn.Forte@Sun.COM 	/* call init */
43237836SJohn.Forte@Sun.COM 	ret = initializeConfig();
43247836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
43257836SJohn.Forte@Sun.COM 		return (ret);
43267836SJohn.Forte@Sun.COM 	}
43277836SJohn.Forte@Sun.COM 
43287836SJohn.Forte@Sun.COM 	/*
43297836SJohn.Forte@Sun.COM 	 * Open control node for stmf
43307836SJohn.Forte@Sun.COM 	 */
43317836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
43327836SJohn.Forte@Sun.COM 		return (ret);
43337836SJohn.Forte@Sun.COM 
43347836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
43357836SJohn.Forte@Sun.COM 	/*
43367836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
43377836SJohn.Forte@Sun.COM 	 */
43387836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
43397836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
43407836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
43417836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
43427836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
43437836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
43447836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
43457836SJohn.Forte@Sun.COM 		switch (errno) {
43467836SJohn.Forte@Sun.COM 			case EBUSY:
43477836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
43487836SJohn.Forte@Sun.COM 				break;
43499585STim.Szeto@Sun.COM 			case EPERM:
43507836SJohn.Forte@Sun.COM 			case EACCES:
43517836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
43527836SJohn.Forte@Sun.COM 				break;
43537836SJohn.Forte@Sun.COM 			case ENOENT:
43547836SJohn.Forte@Sun.COM 				stmfRet = stmfGetViewEntryList(lu,
43557836SJohn.Forte@Sun.COM 				    &viewEntryList);
43567836SJohn.Forte@Sun.COM 				if (stmfRet == STMF_STATUS_SUCCESS) {
43577836SJohn.Forte@Sun.COM 					luProps->status =
43587836SJohn.Forte@Sun.COM 					    STMF_LOGICAL_UNIT_UNREGISTERED;
43597836SJohn.Forte@Sun.COM 					if (viewEntryList->cnt > 0) {
43607836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_SUCCESS;
43617836SJohn.Forte@Sun.COM 					} else {
43627836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
43637836SJohn.Forte@Sun.COM 					}
43647836SJohn.Forte@Sun.COM 				} else {
43657836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
43667836SJohn.Forte@Sun.COM 				}
43677836SJohn.Forte@Sun.COM 				stmfFreeMemory(viewEntryList);
43687836SJohn.Forte@Sun.COM 				break;
43697836SJohn.Forte@Sun.COM 			default:
43707836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
43717836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnit:ioctl errno(%d)",
43727836SJohn.Forte@Sun.COM 				    errno);
43737836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
43747836SJohn.Forte@Sun.COM 				break;
43757836SJohn.Forte@Sun.COM 		}
43767836SJohn.Forte@Sun.COM 		goto done;
43777836SJohn.Forte@Sun.COM 	}
43787836SJohn.Forte@Sun.COM 
43797836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
43807836SJohn.Forte@Sun.COM 	    sizeof (fLuProps.lu_provider_name));
43817836SJohn.Forte@Sun.COM 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
43827836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
43837836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
43847836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
43857836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
43867836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
43877836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
43887836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
43897836SJohn.Forte@Sun.COM 	}
43907836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
43917836SJohn.Forte@Sun.COM done:
43927836SJohn.Forte@Sun.COM 	(void) close(fd);
43937836SJohn.Forte@Sun.COM 	return (ret);
43947836SJohn.Forte@Sun.COM }
43957836SJohn.Forte@Sun.COM 
43967836SJohn.Forte@Sun.COM /*
43977836SJohn.Forte@Sun.COM  * stmfGetState
43987836SJohn.Forte@Sun.COM  *
43997836SJohn.Forte@Sun.COM  * Purpose: retrieve the current state of the stmf module
44007836SJohn.Forte@Sun.COM  *
44017836SJohn.Forte@Sun.COM  * state - pointer to stmfState structure allocated by the caller
44027836SJohn.Forte@Sun.COM  *         On success, contains the state of stmf
44037836SJohn.Forte@Sun.COM  */
44047836SJohn.Forte@Sun.COM int
44057836SJohn.Forte@Sun.COM stmfGetState(stmfState *state)
44067836SJohn.Forte@Sun.COM {
44077836SJohn.Forte@Sun.COM 	int ret;
44087836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
44097836SJohn.Forte@Sun.COM 
44107836SJohn.Forte@Sun.COM 	if (state == NULL) {
44117836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
44127836SJohn.Forte@Sun.COM 	}
44137836SJohn.Forte@Sun.COM 
44147836SJohn.Forte@Sun.COM 	ret = getStmfState(&iState);
44157836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
44167836SJohn.Forte@Sun.COM 		return (ret);
44177836SJohn.Forte@Sun.COM 	}
44187836SJohn.Forte@Sun.COM 	switch (iState.state) {
44197836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINE:
44207836SJohn.Forte@Sun.COM 			state->operationalState =
44217836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINE;
44227836SJohn.Forte@Sun.COM 			break;
44237836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINE:
44247836SJohn.Forte@Sun.COM 			state->operationalState =
44257836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINE;
44267836SJohn.Forte@Sun.COM 			break;
44277836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINING:
44287836SJohn.Forte@Sun.COM 			state->operationalState =
44297836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINING;
44307836SJohn.Forte@Sun.COM 			break;
44317836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINING:
44327836SJohn.Forte@Sun.COM 			state->operationalState =
44337836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINING;
44347836SJohn.Forte@Sun.COM 			break;
44357836SJohn.Forte@Sun.COM 		default:
44367836SJohn.Forte@Sun.COM 			state->operationalState =
44377836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_UNKNOWN;
44387836SJohn.Forte@Sun.COM 			break;
44397836SJohn.Forte@Sun.COM 	}
44407836SJohn.Forte@Sun.COM 	switch (iState.config_state) {
44417836SJohn.Forte@Sun.COM 		case STMF_CONFIG_NONE:
44427836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_NONE;
44437836SJohn.Forte@Sun.COM 			break;
44447836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT:
44457836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_INIT;
44467836SJohn.Forte@Sun.COM 			break;
44477836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT_DONE:
44487836SJohn.Forte@Sun.COM 			state->configState =
44497836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_INIT_DONE;
44507836SJohn.Forte@Sun.COM 			break;
44517836SJohn.Forte@Sun.COM 		default:
44527836SJohn.Forte@Sun.COM 			state->configState =
44537836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_UNKNOWN;
44547836SJohn.Forte@Sun.COM 			break;
44557836SJohn.Forte@Sun.COM 	}
44567836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
44577836SJohn.Forte@Sun.COM }
44587836SJohn.Forte@Sun.COM 
44597836SJohn.Forte@Sun.COM /*
44607836SJohn.Forte@Sun.COM  * stmfGetViewEntryList
44617836SJohn.Forte@Sun.COM  *
44627836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of view entries for the specified
44637836SJohn.Forte@Sun.COM  *          logical unit.
44647836SJohn.Forte@Sun.COM  *
44657836SJohn.Forte@Sun.COM  * lu - the guid of the logical unit for which to retrieve the view entry list
44667836SJohn.Forte@Sun.COM  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
44677836SJohn.Forte@Sun.COM  *                 success, contains the list of view entries.
44687836SJohn.Forte@Sun.COM  */
44697836SJohn.Forte@Sun.COM int
44707836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
44717836SJohn.Forte@Sun.COM {
44727836SJohn.Forte@Sun.COM 	int ret;
44739585STim.Szeto@Sun.COM 	int fd;
44749585STim.Szeto@Sun.COM 	int ioctlRet;
44759585STim.Szeto@Sun.COM 	int cmd = STMF_IOCTL_LU_VE_LIST;
44769585STim.Szeto@Sun.COM 	int i;
44779585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
44789585STim.Szeto@Sun.COM 	stmf_view_op_entry_t *fVeList;
44799585STim.Szeto@Sun.COM 	uint32_t fVeListSize;
44809585STim.Szeto@Sun.COM 	uint32_t listCnt;
44817836SJohn.Forte@Sun.COM 
44827836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntryList == NULL) {
44837836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
44847836SJohn.Forte@Sun.COM 	}
44857836SJohn.Forte@Sun.COM 
44869585STim.Szeto@Sun.COM 	/* call init */
44879585STim.Szeto@Sun.COM 	ret = initializeConfig();
44889585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
44899585STim.Szeto@Sun.COM 		return (ret);
44909585STim.Szeto@Sun.COM 	}
44919585STim.Szeto@Sun.COM 
44929585STim.Szeto@Sun.COM 	/*
44939585STim.Szeto@Sun.COM 	 * Open control node for stmf
44949585STim.Szeto@Sun.COM 	 */
44959585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
44969585STim.Szeto@Sun.COM 		return (ret);
44979585STim.Szeto@Sun.COM 
44989585STim.Szeto@Sun.COM 	/*
44999585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
45009585STim.Szeto@Sun.COM 	 */
45019585STim.Szeto@Sun.COM 	fVeListSize = ALLOC_VE;
45029585STim.Szeto@Sun.COM 	fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
45039585STim.Szeto@Sun.COM 	fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
45049585STim.Szeto@Sun.COM 	if (fVeList == NULL) {
45059585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
45069585STim.Szeto@Sun.COM 		goto done;
45079585STim.Szeto@Sun.COM 	}
45089585STim.Szeto@Sun.COM 
45099585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
45109585STim.Szeto@Sun.COM 	/*
45119585STim.Szeto@Sun.COM 	 * Issue ioctl to get the LU list
45129585STim.Szeto@Sun.COM 	 */
45139585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
45149585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
45159585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
45169585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = fVeListSize;
45179585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
45189585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
45199585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
45209585STim.Szeto@Sun.COM 		switch (errno) {
45219585STim.Szeto@Sun.COM 			case EBUSY:
45229585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
45239585STim.Szeto@Sun.COM 				break;
45249585STim.Szeto@Sun.COM 			case EPERM:
45259585STim.Szeto@Sun.COM 			case EACCES:
45269585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
45279585STim.Szeto@Sun.COM 				break;
45289585STim.Szeto@Sun.COM 			default:
45299585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
45309585STim.Szeto@Sun.COM 				    "stmfGetViewEntryList:ioctl errno(%d)",
45319585STim.Szeto@Sun.COM 				    errno);
45329585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
45339585STim.Szeto@Sun.COM 				break;
45349585STim.Szeto@Sun.COM 		}
45359585STim.Szeto@Sun.COM 		goto done;
45369585STim.Szeto@Sun.COM 	}
45379585STim.Szeto@Sun.COM 	/*
45389585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
45399585STim.Szeto@Sun.COM 	 */
45409585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
45419585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
45429585STim.Szeto@Sun.COM 		fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
45439585STim.Szeto@Sun.COM 		    sizeof (stmf_view_op_entry_t);
45449585STim.Szeto@Sun.COM 		free(fVeList);
45459585STim.Szeto@Sun.COM 		fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
45469585STim.Szeto@Sun.COM 		if (fVeList == NULL) {
45479585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOMEM);
45489585STim.Szeto@Sun.COM 		}
45499585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = fVeListSize;
45509585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
45519585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
45529585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
45539585STim.Szeto@Sun.COM 			switch (errno) {
45549585STim.Szeto@Sun.COM 				case EBUSY:
45559585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
45569585STim.Szeto@Sun.COM 					break;
45579585STim.Szeto@Sun.COM 				case EPERM:
45589585STim.Szeto@Sun.COM 				case EACCES:
45599585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
45609585STim.Szeto@Sun.COM 					break;
45619585STim.Szeto@Sun.COM 				default:
45629585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
45639585STim.Szeto@Sun.COM 					    "stmfGetLogicalUnitList:"
45649585STim.Szeto@Sun.COM 					    "ioctl errno(%d)", errno);
45659585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
45669585STim.Szeto@Sun.COM 					break;
45679585STim.Szeto@Sun.COM 			}
45689585STim.Szeto@Sun.COM 			goto done;
45699585STim.Szeto@Sun.COM 		}
45709585STim.Szeto@Sun.COM 	}
45719585STim.Szeto@Sun.COM 
45729585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
45739585STim.Szeto@Sun.COM 		goto done;
45749585STim.Szeto@Sun.COM 	}
45759585STim.Szeto@Sun.COM 
45769585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_nentries == 0) {
45779585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOT_FOUND;
45789585STim.Szeto@Sun.COM 		goto done;
45799585STim.Szeto@Sun.COM 	}
45809585STim.Szeto@Sun.COM 
45819585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
45829585STim.Szeto@Sun.COM 
45839585STim.Szeto@Sun.COM 	/*
45849585STim.Szeto@Sun.COM 	 * allocate caller's buffer with the final size
45859585STim.Szeto@Sun.COM 	 */
45869585STim.Szeto@Sun.COM 	*viewEntryList = (stmfViewEntryList *)calloc(1,
45879585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
45889585STim.Szeto@Sun.COM 	if (*viewEntryList == NULL) {
45899585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
45909585STim.Szeto@Sun.COM 		goto done;
45919585STim.Szeto@Sun.COM 	}
45929585STim.Szeto@Sun.COM 
45939585STim.Szeto@Sun.COM 	(*viewEntryList)->cnt = listCnt;
45949585STim.Szeto@Sun.COM 
45959585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
45969585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
45979585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndexValid = B_TRUE;
45989585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
45999585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_hosts == 1) {
46009585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allHosts = B_TRUE;
46019585STim.Szeto@Sun.COM 		} else {
46029585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_host_group.name,
46039585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].hostGroup,
46049585STim.Szeto@Sun.COM 			    fVeList[i].ve_host_group.name_size);
46059585STim.Szeto@Sun.COM 		}
46069585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_targets == 1) {
46079585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allTargets = B_TRUE;
46089585STim.Szeto@Sun.COM 		} else {
46099585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_target_group.name,
46109585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].targetGroup,
46119585STim.Szeto@Sun.COM 			    fVeList[i].ve_target_group.name_size);
46129585STim.Szeto@Sun.COM 		}
46139585STim.Szeto@Sun.COM 		bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
46149585STim.Szeto@Sun.COM 		    sizeof ((*viewEntryList)->ve[i].luNbr));
46159585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].luNbrValid = B_TRUE;
46169585STim.Szeto@Sun.COM 	}
46179585STim.Szeto@Sun.COM 
46189585STim.Szeto@Sun.COM 	/*
46199585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
46209585STim.Szeto@Sun.COM 	 */
46219585STim.Szeto@Sun.COM 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
46229585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntry), viewEntryCompare);
46239585STim.Szeto@Sun.COM 
46249585STim.Szeto@Sun.COM done:
46259585STim.Szeto@Sun.COM 	(void) close(fd);
46269585STim.Szeto@Sun.COM 	/*
46279585STim.Szeto@Sun.COM 	 * free internal buffers
46289585STim.Szeto@Sun.COM 	 */
46299585STim.Szeto@Sun.COM 	free(fVeList);
46307836SJohn.Forte@Sun.COM 	return (ret);
46317836SJohn.Forte@Sun.COM }
46327836SJohn.Forte@Sun.COM 
46339585STim.Szeto@Sun.COM 
46347836SJohn.Forte@Sun.COM /*
46357836SJohn.Forte@Sun.COM  * loadHostGroups
46367836SJohn.Forte@Sun.COM  *
46377836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the host groups into stmf
46387836SJohn.Forte@Sun.COM  *
46397836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
46407836SJohn.Forte@Sun.COM  * groupList - populated host group list
46417836SJohn.Forte@Sun.COM  */
46427836SJohn.Forte@Sun.COM static int
46437836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList)
46447836SJohn.Forte@Sun.COM {
46457836SJohn.Forte@Sun.COM 	int i, j;
46467836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
46477836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
46487836SJohn.Forte@Sun.COM 
46497836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
46507836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
46517836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
46527836SJohn.Forte@Sun.COM 			goto out;
46537836SJohn.Forte@Sun.COM 		}
46549585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
46559585STim.Szeto@Sun.COM 		    &groupProps, HOST_GROUP);
46567836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
46577836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
46587836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
46597836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
46607836SJohn.Forte@Sun.COM 				goto out;
46617836SJohn.Forte@Sun.COM 			}
46627836SJohn.Forte@Sun.COM 		}
46637836SJohn.Forte@Sun.COM 	}
46647836SJohn.Forte@Sun.COM 
46657836SJohn.Forte@Sun.COM 
46667836SJohn.Forte@Sun.COM out:
46677836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
46687836SJohn.Forte@Sun.COM 	return (ret);
46697836SJohn.Forte@Sun.COM }
46707836SJohn.Forte@Sun.COM 
46717836SJohn.Forte@Sun.COM /*
46727836SJohn.Forte@Sun.COM  * loadTargetGroups
46737836SJohn.Forte@Sun.COM  *
46747836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the target groups into stmf
46757836SJohn.Forte@Sun.COM  *
46767836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
46777836SJohn.Forte@Sun.COM  * groupList - populated target group list.
46787836SJohn.Forte@Sun.COM  */
46797836SJohn.Forte@Sun.COM static int
46807836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList)
46817836SJohn.Forte@Sun.COM {
46827836SJohn.Forte@Sun.COM 	int i, j;
46837836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
46847836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
46857836SJohn.Forte@Sun.COM 
46867836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
46877836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
46887836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
46897836SJohn.Forte@Sun.COM 			goto out;
46907836SJohn.Forte@Sun.COM 		}
46919585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
46929585STim.Szeto@Sun.COM 		    &groupProps, TARGET_GROUP);
46937836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
46947836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
46957836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
46967836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
46977836SJohn.Forte@Sun.COM 				goto out;
46987836SJohn.Forte@Sun.COM 			}
46997836SJohn.Forte@Sun.COM 		}
47007836SJohn.Forte@Sun.COM 	}
47017836SJohn.Forte@Sun.COM 
47027836SJohn.Forte@Sun.COM 
47037836SJohn.Forte@Sun.COM out:
47047836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
47057836SJohn.Forte@Sun.COM 	return (ret);
47067836SJohn.Forte@Sun.COM }
47077836SJohn.Forte@Sun.COM 
47087836SJohn.Forte@Sun.COM 
47097836SJohn.Forte@Sun.COM /*
47107836SJohn.Forte@Sun.COM  * loadStore
47117836SJohn.Forte@Sun.COM  *
47127836SJohn.Forte@Sun.COM  * Purpose: Load the configuration data from the store
47137836SJohn.Forte@Sun.COM  *
47147836SJohn.Forte@Sun.COM  * First load the host groups and target groups, then the view entries
47157836SJohn.Forte@Sun.COM  * and finally the provider data
47167836SJohn.Forte@Sun.COM  *
47177836SJohn.Forte@Sun.COM  * fd - file descriptor of control node for stmf.
47187836SJohn.Forte@Sun.COM  */
47197836SJohn.Forte@Sun.COM static int
47207836SJohn.Forte@Sun.COM loadStore(int fd)
47217836SJohn.Forte@Sun.COM {
47227836SJohn.Forte@Sun.COM 	int ret;
47237836SJohn.Forte@Sun.COM 	int i, j;
47247836SJohn.Forte@Sun.COM 	stmfGroupList *groupList = NULL;
47257836SJohn.Forte@Sun.COM 	stmfGuidList *guidList = NULL;
47267836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
47277836SJohn.Forte@Sun.COM 	stmfProviderList *providerList = NULL;
47287836SJohn.Forte@Sun.COM 	int providerType;
47297836SJohn.Forte@Sun.COM 	nvlist_t *nvl = NULL;
47307836SJohn.Forte@Sun.COM 
47317836SJohn.Forte@Sun.COM 
47327836SJohn.Forte@Sun.COM 
47337836SJohn.Forte@Sun.COM 	/* load host groups */
47349585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
47357836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47367836SJohn.Forte@Sun.COM 		return (ret);
47377836SJohn.Forte@Sun.COM 	}
47387836SJohn.Forte@Sun.COM 	ret = loadHostGroups(fd, groupList);
47397836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47407836SJohn.Forte@Sun.COM 		goto out;
47417836SJohn.Forte@Sun.COM 	}
47427836SJohn.Forte@Sun.COM 
47437836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
47447836SJohn.Forte@Sun.COM 	groupList = NULL;
47457836SJohn.Forte@Sun.COM 
47467836SJohn.Forte@Sun.COM 	/* load target groups */
47479585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
47487836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47497836SJohn.Forte@Sun.COM 		goto out;
47507836SJohn.Forte@Sun.COM 	}
47517836SJohn.Forte@Sun.COM 	ret = loadTargetGroups(fd, groupList);
47527836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47537836SJohn.Forte@Sun.COM 		goto out;
47547836SJohn.Forte@Sun.COM 	}
47557836SJohn.Forte@Sun.COM 
47567836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
47577836SJohn.Forte@Sun.COM 	groupList = NULL;
47587836SJohn.Forte@Sun.COM 
47597836SJohn.Forte@Sun.COM 	/* Get the guid list */
47607836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&guidList);
47617836SJohn.Forte@Sun.COM 	switch (ret) {
47627836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
47637836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
47647836SJohn.Forte@Sun.COM 			break;
47657836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
47667836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
47677836SJohn.Forte@Sun.COM 			break;
47687836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
47697836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
47707836SJohn.Forte@Sun.COM 			break;
47717836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
47727836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
47737836SJohn.Forte@Sun.COM 			break;
47747836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
47757836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
47767836SJohn.Forte@Sun.COM 			break;
47777836SJohn.Forte@Sun.COM 		default:
47787836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
47797836SJohn.Forte@Sun.COM 			break;
47807836SJohn.Forte@Sun.COM 	}
47817836SJohn.Forte@Sun.COM 
47827836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47837836SJohn.Forte@Sun.COM 		goto out;
47847836SJohn.Forte@Sun.COM 	}
47857836SJohn.Forte@Sun.COM 
47867836SJohn.Forte@Sun.COM 	/*
47877836SJohn.Forte@Sun.COM 	 * We have the guid list, now get the corresponding
47887836SJohn.Forte@Sun.COM 	 * view entries for each guid
47897836SJohn.Forte@Sun.COM 	 */
47907836SJohn.Forte@Sun.COM 	for (i = 0; i < guidList->cnt; i++) {
47917836SJohn.Forte@Sun.COM 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
47927836SJohn.Forte@Sun.COM 		switch (ret) {
47937836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
47947836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
47957836SJohn.Forte@Sun.COM 				break;
47967836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
47977836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
47987836SJohn.Forte@Sun.COM 				break;
47997836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
48007836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
48017836SJohn.Forte@Sun.COM 				break;
48027836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48037836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
48047836SJohn.Forte@Sun.COM 				break;
48057836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
48067836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
48077836SJohn.Forte@Sun.COM 				break;
48087836SJohn.Forte@Sun.COM 			default:
48097836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
48107836SJohn.Forte@Sun.COM 				break;
48117836SJohn.Forte@Sun.COM 		}
48127836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
48137836SJohn.Forte@Sun.COM 			goto out;
48147836SJohn.Forte@Sun.COM 		}
48157836SJohn.Forte@Sun.COM 		for (j = 0; j < viewEntryList->cnt; j++) {
48167836SJohn.Forte@Sun.COM 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
48177836SJohn.Forte@Sun.COM 			    &viewEntryList->ve[j]);
48187836SJohn.Forte@Sun.COM 			if (ret != STMF_STATUS_SUCCESS) {
48197836SJohn.Forte@Sun.COM 				goto out;
48207836SJohn.Forte@Sun.COM 			}
48217836SJohn.Forte@Sun.COM 		}
48227836SJohn.Forte@Sun.COM 	}
48237836SJohn.Forte@Sun.COM 
48247836SJohn.Forte@Sun.COM 	/* get the list of providers that have data */
48257836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(&providerList);
48267836SJohn.Forte@Sun.COM 	switch (ret) {
48277836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
48287836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
48297836SJohn.Forte@Sun.COM 			break;
48307836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
48317836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
48327836SJohn.Forte@Sun.COM 			break;
48337836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
48347836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
48357836SJohn.Forte@Sun.COM 			break;
48367836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48377836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
48387836SJohn.Forte@Sun.COM 			break;
48397836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
48407836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
48417836SJohn.Forte@Sun.COM 			break;
48427836SJohn.Forte@Sun.COM 		default:
48437836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
48447836SJohn.Forte@Sun.COM 			break;
48457836SJohn.Forte@Sun.COM 	}
48467836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
48477836SJohn.Forte@Sun.COM 		goto out;
48487836SJohn.Forte@Sun.COM 	}
48497836SJohn.Forte@Sun.COM 
48507836SJohn.Forte@Sun.COM 	for (i = 0; i < providerList->cnt; i++) {
48517836SJohn.Forte@Sun.COM 		providerType = providerList->provider[i].providerType;
48527836SJohn.Forte@Sun.COM 		ret = psGetProviderData(providerList->provider[i].name,
48537836SJohn.Forte@Sun.COM 		    &nvl, providerType, NULL);
48547836SJohn.Forte@Sun.COM 		switch (ret) {
48557836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
48567836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
48577836SJohn.Forte@Sun.COM 				break;
48587836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
48597836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
48607836SJohn.Forte@Sun.COM 				break;
48617836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
48627836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
48637836SJohn.Forte@Sun.COM 				break;
48647836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48657836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
48667836SJohn.Forte@Sun.COM 				break;
48677836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
48687836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
48697836SJohn.Forte@Sun.COM 				break;
48707836SJohn.Forte@Sun.COM 			default:
48717836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
48727836SJohn.Forte@Sun.COM 				break;
48737836SJohn.Forte@Sun.COM 		}
48747836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
48757836SJohn.Forte@Sun.COM 			goto out;
48767836SJohn.Forte@Sun.COM 		}
48777836SJohn.Forte@Sun.COM 
48787836SJohn.Forte@Sun.COM 		/* call setProviderData */
48797836SJohn.Forte@Sun.COM 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
48809585STim.Szeto@Sun.COM 		    providerType, NULL);
48817836SJohn.Forte@Sun.COM 		switch (ret) {
48827836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
48837836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
48847836SJohn.Forte@Sun.COM 				break;
48857836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
48867836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
48877836SJohn.Forte@Sun.COM 				break;
48887836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
48897836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
48907836SJohn.Forte@Sun.COM 				break;
48917836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48927836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
48937836SJohn.Forte@Sun.COM 				break;
48947836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
48957836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
48967836SJohn.Forte@Sun.COM 				break;
48977836SJohn.Forte@Sun.COM 			default:
48987836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
48997836SJohn.Forte@Sun.COM 				break;
49007836SJohn.Forte@Sun.COM 		}
49017836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
49027836SJohn.Forte@Sun.COM 			goto out;
49037836SJohn.Forte@Sun.COM 		}
49047836SJohn.Forte@Sun.COM 
49057836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
49067836SJohn.Forte@Sun.COM 		nvl = NULL;
49077836SJohn.Forte@Sun.COM 	}
49087836SJohn.Forte@Sun.COM out:
49097836SJohn.Forte@Sun.COM 	if (groupList != NULL) {
49107836SJohn.Forte@Sun.COM 		free(groupList);
49117836SJohn.Forte@Sun.COM 	}
49127836SJohn.Forte@Sun.COM 	if (guidList != NULL) {
49137836SJohn.Forte@Sun.COM 		free(guidList);
49147836SJohn.Forte@Sun.COM 	}
49157836SJohn.Forte@Sun.COM 	if (viewEntryList != NULL) {
49167836SJohn.Forte@Sun.COM 		free(viewEntryList);
49177836SJohn.Forte@Sun.COM 	}
49187836SJohn.Forte@Sun.COM 	if (nvl != NULL) {
49197836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
49207836SJohn.Forte@Sun.COM 	}
49217836SJohn.Forte@Sun.COM 	return (ret);
49227836SJohn.Forte@Sun.COM }
49237836SJohn.Forte@Sun.COM 
49247836SJohn.Forte@Sun.COM /*
492510725SJohn.Forte@Sun.COM  * stmfGetAluaState
492610725SJohn.Forte@Sun.COM  *
492710725SJohn.Forte@Sun.COM  * Purpose - Get the alua state
492810725SJohn.Forte@Sun.COM  *
492910725SJohn.Forte@Sun.COM  */
493010725SJohn.Forte@Sun.COM int
493110725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node)
493210725SJohn.Forte@Sun.COM {
493310725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
493410725SJohn.Forte@Sun.COM 	int fd;
493510725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
493610725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
493710725SJohn.Forte@Sun.COM 	int ioctlRet;
493810725SJohn.Forte@Sun.COM 
493910725SJohn.Forte@Sun.COM 	if (enabled == NULL || node == NULL) {
494010725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
494110725SJohn.Forte@Sun.COM 	}
494210725SJohn.Forte@Sun.COM 
494310725SJohn.Forte@Sun.COM 	/*
494410725SJohn.Forte@Sun.COM 	 * Open control node for stmf
494510725SJohn.Forte@Sun.COM 	 */
494610725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
494710725SJohn.Forte@Sun.COM 		return (ret);
494810725SJohn.Forte@Sun.COM 
494910725SJohn.Forte@Sun.COM 	/*
495010725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
495110725SJohn.Forte@Sun.COM 	 */
495210725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
495310725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (alua_state);
495410725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state;
495510725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl);
495610725SJohn.Forte@Sun.COM 
495710725SJohn.Forte@Sun.COM 	(void) close(fd);
495810725SJohn.Forte@Sun.COM 
495910725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
496010725SJohn.Forte@Sun.COM 		switch (errno) {
496110725SJohn.Forte@Sun.COM 			case EBUSY:
496210725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
496310725SJohn.Forte@Sun.COM 				break;
496410725SJohn.Forte@Sun.COM 			case EPERM:
496510725SJohn.Forte@Sun.COM 			case EACCES:
496610725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
496710725SJohn.Forte@Sun.COM 				break;
496810725SJohn.Forte@Sun.COM 			default:
496910725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
497010725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
497110725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
497210725SJohn.Forte@Sun.COM 				break;
497310725SJohn.Forte@Sun.COM 		}
497410725SJohn.Forte@Sun.COM 	} else {
497510725SJohn.Forte@Sun.COM 		if (alua_state.alua_state == 1) {
497610725SJohn.Forte@Sun.COM 			*enabled = B_TRUE;
497710725SJohn.Forte@Sun.COM 		} else {
497810725SJohn.Forte@Sun.COM 			*enabled = B_FALSE;
497910725SJohn.Forte@Sun.COM 		}
498010725SJohn.Forte@Sun.COM 		*node = alua_state.alua_node;
498110725SJohn.Forte@Sun.COM 	}
498210725SJohn.Forte@Sun.COM 
498310725SJohn.Forte@Sun.COM 	return (ret);
498410725SJohn.Forte@Sun.COM }
498510725SJohn.Forte@Sun.COM 
498610725SJohn.Forte@Sun.COM /*
498710725SJohn.Forte@Sun.COM  * stmfSetAluaState
498810725SJohn.Forte@Sun.COM  *
498910725SJohn.Forte@Sun.COM  * Purpose - set the alua state to enabled/disabled
499010725SJohn.Forte@Sun.COM  *
499110725SJohn.Forte@Sun.COM  */
499210725SJohn.Forte@Sun.COM int
499310725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node)
499410725SJohn.Forte@Sun.COM {
499510725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
499610725SJohn.Forte@Sun.COM 	int fd;
499710725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
499810725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
499910725SJohn.Forte@Sun.COM 	int ioctlRet;
500010725SJohn.Forte@Sun.COM 
500110725SJohn.Forte@Sun.COM 	if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) {
500210725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
500310725SJohn.Forte@Sun.COM 	}
500410725SJohn.Forte@Sun.COM 
500510725SJohn.Forte@Sun.COM 	if (enabled) {
500610725SJohn.Forte@Sun.COM 		alua_state.alua_state = 1;
500710725SJohn.Forte@Sun.COM 	}
500810725SJohn.Forte@Sun.COM 
500910725SJohn.Forte@Sun.COM 	alua_state.alua_node = node;
501010725SJohn.Forte@Sun.COM 
501110725SJohn.Forte@Sun.COM 	/*
501210725SJohn.Forte@Sun.COM 	 * Open control node for stmf
501310725SJohn.Forte@Sun.COM 	 */
501410725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
501510725SJohn.Forte@Sun.COM 		return (ret);
501610725SJohn.Forte@Sun.COM 
501710725SJohn.Forte@Sun.COM 	/*
501810725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
501910725SJohn.Forte@Sun.COM 	 */
502010725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
502110725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (alua_state);
502210725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state;
502310725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl);
502410725SJohn.Forte@Sun.COM 
502510725SJohn.Forte@Sun.COM 	(void) close(fd);
502610725SJohn.Forte@Sun.COM 
502710725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
502810725SJohn.Forte@Sun.COM 		switch (errno) {
502910725SJohn.Forte@Sun.COM 			case EBUSY:
503010725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
503110725SJohn.Forte@Sun.COM 				break;
503210725SJohn.Forte@Sun.COM 			case EPERM:
503310725SJohn.Forte@Sun.COM 			case EACCES:
503410725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
503510725SJohn.Forte@Sun.COM 				break;
503610725SJohn.Forte@Sun.COM 			default:
503710725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
503810725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
503910725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
504010725SJohn.Forte@Sun.COM 				break;
504110725SJohn.Forte@Sun.COM 		}
504210725SJohn.Forte@Sun.COM 	}
504310725SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
504410725SJohn.Forte@Sun.COM 		deleteNonActiveLus();
504510725SJohn.Forte@Sun.COM 	}
504610725SJohn.Forte@Sun.COM 
504710725SJohn.Forte@Sun.COM 	return (ret);
504810725SJohn.Forte@Sun.COM }
504910725SJohn.Forte@Sun.COM 
505010725SJohn.Forte@Sun.COM static void
505110725SJohn.Forte@Sun.COM deleteNonActiveLus()
505210725SJohn.Forte@Sun.COM {
505310725SJohn.Forte@Sun.COM 	int stmfRet;
505410725SJohn.Forte@Sun.COM 	int i;
505510725SJohn.Forte@Sun.COM 	stmfGuidList *luList;
505610725SJohn.Forte@Sun.COM 	luResource hdl = NULL;
505710725SJohn.Forte@Sun.COM 	char propVal[10];
505810725SJohn.Forte@Sun.COM 	size_t propValSize = sizeof (propVal);
505910725SJohn.Forte@Sun.COM 
506010725SJohn.Forte@Sun.COM 	stmfRet = stmfGetLogicalUnitList(&luList);
506110725SJohn.Forte@Sun.COM 	if (stmfRet != STMF_STATUS_SUCCESS) {
506210725SJohn.Forte@Sun.COM 		return;
506310725SJohn.Forte@Sun.COM 	}
506410725SJohn.Forte@Sun.COM 
506510725SJohn.Forte@Sun.COM 	for (i = 0; i < luList->cnt; i++) {
506610725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuResource(&luList->guid[i], &hdl);
506710725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
506810725SJohn.Forte@Sun.COM 			goto err;
506910725SJohn.Forte@Sun.COM 		}
507010725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
507110725SJohn.Forte@Sun.COM 		    &propValSize);
507210725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
507310725SJohn.Forte@Sun.COM 			goto err;
507410725SJohn.Forte@Sun.COM 		}
507510725SJohn.Forte@Sun.COM 		if (propVal[0] == '0') {
507610725SJohn.Forte@Sun.COM 			(void) stmfFreeLuResource(hdl);
507710725SJohn.Forte@Sun.COM 			hdl = NULL;
507810725SJohn.Forte@Sun.COM 			continue;
507910725SJohn.Forte@Sun.COM 		}
508010725SJohn.Forte@Sun.COM 		(void) stmfDeleteLu(&luList->guid[i]);
508110725SJohn.Forte@Sun.COM 		(void) stmfFreeLuResource(hdl);
508210725SJohn.Forte@Sun.COM 		hdl = NULL;
508310725SJohn.Forte@Sun.COM 	}
508410725SJohn.Forte@Sun.COM 
508510725SJohn.Forte@Sun.COM err:
508610725SJohn.Forte@Sun.COM 	stmfFreeMemory(luList);
508710725SJohn.Forte@Sun.COM 	(void) stmfFreeLuResource(hdl);
508810725SJohn.Forte@Sun.COM }
508910725SJohn.Forte@Sun.COM 
509010725SJohn.Forte@Sun.COM /*
50917836SJohn.Forte@Sun.COM  * stmfLoadConfig
50927836SJohn.Forte@Sun.COM  *
50937836SJohn.Forte@Sun.COM  * Purpose - load the configuration data from smf into stmf
50947836SJohn.Forte@Sun.COM  *
50957836SJohn.Forte@Sun.COM  */
50967836SJohn.Forte@Sun.COM int
50977836SJohn.Forte@Sun.COM stmfLoadConfig(void)
50987836SJohn.Forte@Sun.COM {
50999585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
51007836SJohn.Forte@Sun.COM 	int fd;
51017836SJohn.Forte@Sun.COM 	stmf_state_desc_t stmfStateSet;
51027836SJohn.Forte@Sun.COM 	stmfState state;
51037836SJohn.Forte@Sun.COM 
51049585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
51059585STim.Szeto@Sun.COM 		stmfStateSet.state = STMF_STATE_OFFLINE;
510610560SSusan.Gleeson@Sun.COM 
51079585STim.Szeto@Sun.COM 		if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
51089585STim.Szeto@Sun.COM 		    != STMF_STATUS_SUCCESS) {
51099585STim.Szeto@Sun.COM 			return (ret);
51109585STim.Szeto@Sun.COM 		}
511110560SSusan.Gleeson@Sun.COM 		/*
511210560SSusan.Gleeson@Sun.COM 		 * Configuration not stored persistently; nothing to
511310560SSusan.Gleeson@Sun.COM 		 * initialize so do not set to STMF_CONFIG_INIT.
511410560SSusan.Gleeson@Sun.COM 		 */
51159585STim.Szeto@Sun.COM 		stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
51169585STim.Szeto@Sun.COM 		goto done;
51179585STim.Szeto@Sun.COM 	}
51187836SJohn.Forte@Sun.COM 
51197836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
51207836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
51217836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
51227836SJohn.Forte@Sun.COM 	}
51237836SJohn.Forte@Sun.COM 
51247836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
51257836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
51267836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
51277836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
51287836SJohn.Forte@Sun.COM 		}
51297836SJohn.Forte@Sun.COM 	} else {
51307836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
51317836SJohn.Forte@Sun.COM 	}
51327836SJohn.Forte@Sun.COM 
51337836SJohn.Forte@Sun.COM 
51347836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
51357836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT;
51367836SJohn.Forte@Sun.COM 
51377836SJohn.Forte@Sun.COM 	/*
51387836SJohn.Forte@Sun.COM 	 * Open control node for stmf
51397836SJohn.Forte@Sun.COM 	 */
51407836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
51417836SJohn.Forte@Sun.COM 		return (ret);
51427836SJohn.Forte@Sun.COM 
51437836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
51447836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
51457836SJohn.Forte@Sun.COM 		goto done;
51467836SJohn.Forte@Sun.COM 	}
51477836SJohn.Forte@Sun.COM 
51487836SJohn.Forte@Sun.COM 	/* Load the persistent configuration data */
51497836SJohn.Forte@Sun.COM 	ret = loadStore(fd);
51507836SJohn.Forte@Sun.COM 	if (ret != 0) {
51517836SJohn.Forte@Sun.COM 		goto done;
51527836SJohn.Forte@Sun.COM 	}
51537836SJohn.Forte@Sun.COM 
51547836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
51557836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
51567836SJohn.Forte@Sun.COM 
51577836SJohn.Forte@Sun.COM done:
51587836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
51597836SJohn.Forte@Sun.COM 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
51607836SJohn.Forte@Sun.COM 	}
51617836SJohn.Forte@Sun.COM 	(void) close(fd);
51627836SJohn.Forte@Sun.COM 	return (ret);
51637836SJohn.Forte@Sun.COM }
51647836SJohn.Forte@Sun.COM 
51659585STim.Szeto@Sun.COM 
51667836SJohn.Forte@Sun.COM /*
51677836SJohn.Forte@Sun.COM  * getStmfState
51687836SJohn.Forte@Sun.COM  *
51697836SJohn.Forte@Sun.COM  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
51707836SJohn.Forte@Sun.COM  *             information of the stmf service on success.
51717836SJohn.Forte@Sun.COM  */
51727836SJohn.Forte@Sun.COM static int
51737836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState)
51747836SJohn.Forte@Sun.COM {
51757836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
51767836SJohn.Forte@Sun.COM 	int fd;
51777836SJohn.Forte@Sun.COM 	int ioctlRet;
51787836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
51797836SJohn.Forte@Sun.COM 
51807836SJohn.Forte@Sun.COM 	/*
51817836SJohn.Forte@Sun.COM 	 * Open control node for stmf
51827836SJohn.Forte@Sun.COM 	 */
51837836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
51847836SJohn.Forte@Sun.COM 		return (ret);
51857836SJohn.Forte@Sun.COM 
51867836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
51877836SJohn.Forte@Sun.COM 	/*
51887836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
51897836SJohn.Forte@Sun.COM 	 */
51907836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
51917836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
51927836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
51937836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
51947836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
51957836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
51967836SJohn.Forte@Sun.COM 
51977836SJohn.Forte@Sun.COM 	(void) close(fd);
51987836SJohn.Forte@Sun.COM 
51997836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
52007836SJohn.Forte@Sun.COM 		switch (errno) {
52017836SJohn.Forte@Sun.COM 			case EBUSY:
52027836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
52037836SJohn.Forte@Sun.COM 				break;
52047836SJohn.Forte@Sun.COM 			case EPERM:
52057836SJohn.Forte@Sun.COM 			case EACCES:
52067836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
52077836SJohn.Forte@Sun.COM 				break;
52087836SJohn.Forte@Sun.COM 			default:
52097836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
52107836SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
52117836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
52127836SJohn.Forte@Sun.COM 				break;
52137836SJohn.Forte@Sun.COM 		}
52147836SJohn.Forte@Sun.COM 	}
52157836SJohn.Forte@Sun.COM 	return (ret);
52167836SJohn.Forte@Sun.COM }
52177836SJohn.Forte@Sun.COM 
52187836SJohn.Forte@Sun.COM 
52197836SJohn.Forte@Sun.COM /*
52207836SJohn.Forte@Sun.COM  * setStmfState
52217836SJohn.Forte@Sun.COM  *
52227836SJohn.Forte@Sun.COM  * stmfState - pointer to caller set state structure
52237836SJohn.Forte@Sun.COM  * objectType - one of:
52247836SJohn.Forte@Sun.COM  *		LOGICAL_UNIT_TYPE
52257836SJohn.Forte@Sun.COM  *		TARGET_TYPE
52267836SJohn.Forte@Sun.COM  *		STMF_SERVICE_TYPE
52277836SJohn.Forte@Sun.COM  */
52287836SJohn.Forte@Sun.COM static int
52297836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
52307836SJohn.Forte@Sun.COM {
52317836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
52327836SJohn.Forte@Sun.COM 	int ioctlRet;
52337836SJohn.Forte@Sun.COM 	int cmd;
52347836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
52357836SJohn.Forte@Sun.COM 
52367836SJohn.Forte@Sun.COM 	switch (objectType) {
52377836SJohn.Forte@Sun.COM 		case LOGICAL_UNIT_TYPE:
52387836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_LU_STATE;
52397836SJohn.Forte@Sun.COM 			break;
52407836SJohn.Forte@Sun.COM 		case TARGET_TYPE:
52417836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
52427836SJohn.Forte@Sun.COM 			break;
52437836SJohn.Forte@Sun.COM 		case STMF_SERVICE_TYPE:
52447836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_STMF_STATE;
52457836SJohn.Forte@Sun.COM 			break;
52467836SJohn.Forte@Sun.COM 		default:
52477836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
52487836SJohn.Forte@Sun.COM 			goto done;
52497836SJohn.Forte@Sun.COM 	}
52507836SJohn.Forte@Sun.COM 
52517836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
52527836SJohn.Forte@Sun.COM 	/*
52537836SJohn.Forte@Sun.COM 	 * Issue ioctl to set the stmf state
52547836SJohn.Forte@Sun.COM 	 */
52557836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
52567836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
52577836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
52587836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
52597836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
52607836SJohn.Forte@Sun.COM 		switch (errno) {
52617836SJohn.Forte@Sun.COM 			case EBUSY:
52627836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
52637836SJohn.Forte@Sun.COM 				break;
52649585STim.Szeto@Sun.COM 			case EPERM:
52657836SJohn.Forte@Sun.COM 			case EACCES:
52667836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
52677836SJohn.Forte@Sun.COM 				break;
52687836SJohn.Forte@Sun.COM 			case ENOENT:
52697836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
52707836SJohn.Forte@Sun.COM 				break;
52717836SJohn.Forte@Sun.COM 			default:
52727836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
52737836SJohn.Forte@Sun.COM 				    "setStmfState:ioctl errno(%d)", errno);
52747836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
52757836SJohn.Forte@Sun.COM 				break;
52767836SJohn.Forte@Sun.COM 		}
52777836SJohn.Forte@Sun.COM 	}
52787836SJohn.Forte@Sun.COM done:
52797836SJohn.Forte@Sun.COM 	return (ret);
52807836SJohn.Forte@Sun.COM }
52817836SJohn.Forte@Sun.COM 
52827836SJohn.Forte@Sun.COM /*
52837836SJohn.Forte@Sun.COM  * stmfOnline
52847836SJohn.Forte@Sun.COM  *
52857836SJohn.Forte@Sun.COM  * Purpose: Online stmf service
52867836SJohn.Forte@Sun.COM  *
52877836SJohn.Forte@Sun.COM  */
52887836SJohn.Forte@Sun.COM int
52897836SJohn.Forte@Sun.COM stmfOnline(void)
52907836SJohn.Forte@Sun.COM {
52917836SJohn.Forte@Sun.COM 	int ret;
52927836SJohn.Forte@Sun.COM 	int fd;
52937836SJohn.Forte@Sun.COM 	stmfState state;
52947836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
52957836SJohn.Forte@Sun.COM 
52967836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
52977836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
52987836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
52997836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
53007836SJohn.Forte@Sun.COM 		}
53017836SJohn.Forte@Sun.COM 	} else {
53027836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
53037836SJohn.Forte@Sun.COM 	}
53047836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_ONLINE;
53057836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
53067836SJohn.Forte@Sun.COM 	/*
53077836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53087836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
53097836SJohn.Forte@Sun.COM 	 */
53107836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53117836SJohn.Forte@Sun.COM 		return (ret);
53127836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
53137836SJohn.Forte@Sun.COM 	(void) close(fd);
53147836SJohn.Forte@Sun.COM 	return (ret);
53157836SJohn.Forte@Sun.COM }
53167836SJohn.Forte@Sun.COM 
53177836SJohn.Forte@Sun.COM /*
53187836SJohn.Forte@Sun.COM  * stmfOffline
53197836SJohn.Forte@Sun.COM  *
53207836SJohn.Forte@Sun.COM  * Purpose: Offline stmf service
53217836SJohn.Forte@Sun.COM  *
53227836SJohn.Forte@Sun.COM  */
53237836SJohn.Forte@Sun.COM int
53247836SJohn.Forte@Sun.COM stmfOffline(void)
53257836SJohn.Forte@Sun.COM {
53267836SJohn.Forte@Sun.COM 	int ret;
53277836SJohn.Forte@Sun.COM 	int fd;
53287836SJohn.Forte@Sun.COM 	stmfState state;
53297836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
53307836SJohn.Forte@Sun.COM 
53317836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
53327836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
53337836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
53347836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_OFFLINE);
53357836SJohn.Forte@Sun.COM 		}
53367836SJohn.Forte@Sun.COM 	} else {
53377836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
53387836SJohn.Forte@Sun.COM 	}
53397836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_OFFLINE;
53407836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
53417836SJohn.Forte@Sun.COM 
53427836SJohn.Forte@Sun.COM 	/*
53437836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53447836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
53457836SJohn.Forte@Sun.COM 	 */
53467836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53477836SJohn.Forte@Sun.COM 		return (ret);
53487836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
53497836SJohn.Forte@Sun.COM 	(void) close(fd);
53507836SJohn.Forte@Sun.COM 	return (ret);
53517836SJohn.Forte@Sun.COM }
53527836SJohn.Forte@Sun.COM 
53537836SJohn.Forte@Sun.COM 
53547836SJohn.Forte@Sun.COM /*
53557836SJohn.Forte@Sun.COM  * stmfOfflineTarget
53567836SJohn.Forte@Sun.COM  *
53577836SJohn.Forte@Sun.COM  * Purpose: Change state of target to offline
53587836SJohn.Forte@Sun.COM  *
53597836SJohn.Forte@Sun.COM  * devid - devid of the target to offline
53607836SJohn.Forte@Sun.COM  */
53617836SJohn.Forte@Sun.COM int
53627836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid)
53637836SJohn.Forte@Sun.COM {
53647836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
53657836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
53667836SJohn.Forte@Sun.COM 	int fd;
53677836SJohn.Forte@Sun.COM 
53687836SJohn.Forte@Sun.COM 	if (devid == NULL) {
53697836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
53707836SJohn.Forte@Sun.COM 	}
53717836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
53727836SJohn.Forte@Sun.COM 
53737836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_OFFLINE;
53747836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
53757836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
53767836SJohn.Forte@Sun.COM 	    devid->identLength);
53777836SJohn.Forte@Sun.COM 	/*
53787836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53797836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
53807836SJohn.Forte@Sun.COM 	 */
53817836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53827836SJohn.Forte@Sun.COM 		return (ret);
53837836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
53847836SJohn.Forte@Sun.COM 	(void) close(fd);
53857836SJohn.Forte@Sun.COM 	return (ret);
53867836SJohn.Forte@Sun.COM }
53877836SJohn.Forte@Sun.COM 
53887836SJohn.Forte@Sun.COM /*
53897836SJohn.Forte@Sun.COM  * stmfOfflineLogicalUnit
53907836SJohn.Forte@Sun.COM  *
53917836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to offline
53927836SJohn.Forte@Sun.COM  *
53937836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to offline
53947836SJohn.Forte@Sun.COM  */
53957836SJohn.Forte@Sun.COM int
53967836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu)
53977836SJohn.Forte@Sun.COM {
53987836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
53997836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54007836SJohn.Forte@Sun.COM 	int fd;
54017836SJohn.Forte@Sun.COM 
54027836SJohn.Forte@Sun.COM 	if (lu == NULL) {
54037836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
54047836SJohn.Forte@Sun.COM 	}
54057836SJohn.Forte@Sun.COM 
54067836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
54077836SJohn.Forte@Sun.COM 
54087836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_OFFLINE;
54097836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
54107836SJohn.Forte@Sun.COM 	/*
54117836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54127836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
54137836SJohn.Forte@Sun.COM 	 */
54147836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
54157836SJohn.Forte@Sun.COM 		return (ret);
54167836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
54177836SJohn.Forte@Sun.COM 	(void) close(fd);
54187836SJohn.Forte@Sun.COM 	return (ret);
54197836SJohn.Forte@Sun.COM }
54207836SJohn.Forte@Sun.COM 
54217836SJohn.Forte@Sun.COM /*
54227836SJohn.Forte@Sun.COM  * stmfOnlineTarget
54237836SJohn.Forte@Sun.COM  *
54247836SJohn.Forte@Sun.COM  * Purpose: Change state of target to online
54257836SJohn.Forte@Sun.COM  *
54267836SJohn.Forte@Sun.COM  * devid - devid of the target to online
54277836SJohn.Forte@Sun.COM  */
54287836SJohn.Forte@Sun.COM int
54297836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid)
54307836SJohn.Forte@Sun.COM {
54317836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
54327836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54337836SJohn.Forte@Sun.COM 	int fd;
54347836SJohn.Forte@Sun.COM 
54357836SJohn.Forte@Sun.COM 	if (devid == NULL) {
54367836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
54377836SJohn.Forte@Sun.COM 	}
54387836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
54397836SJohn.Forte@Sun.COM 
54407836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_ONLINE;
54417836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
54427836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
54437836SJohn.Forte@Sun.COM 	    devid->identLength);
54447836SJohn.Forte@Sun.COM 	/*
54457836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54467836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
54477836SJohn.Forte@Sun.COM 	 */
54487836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
54497836SJohn.Forte@Sun.COM 		return (ret);
54507836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
54517836SJohn.Forte@Sun.COM 	(void) close(fd);
54527836SJohn.Forte@Sun.COM 	return (ret);
54537836SJohn.Forte@Sun.COM }
54547836SJohn.Forte@Sun.COM 
54557836SJohn.Forte@Sun.COM /*
54567836SJohn.Forte@Sun.COM  * stmfOnlineLogicalUnit
54577836SJohn.Forte@Sun.COM  *
54587836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to online
54597836SJohn.Forte@Sun.COM  *
54607836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to online
54617836SJohn.Forte@Sun.COM  */
54627836SJohn.Forte@Sun.COM int
54637836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu)
54647836SJohn.Forte@Sun.COM {
54657836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
54667836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54677836SJohn.Forte@Sun.COM 	int fd;
54687836SJohn.Forte@Sun.COM 
54697836SJohn.Forte@Sun.COM 	if (lu == NULL) {
54707836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
54717836SJohn.Forte@Sun.COM 	}
54727836SJohn.Forte@Sun.COM 
54737836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
54747836SJohn.Forte@Sun.COM 
54757836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_ONLINE;
54767836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
54777836SJohn.Forte@Sun.COM 	/*
54787836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54797836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
54807836SJohn.Forte@Sun.COM 	 */
54817836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
54827836SJohn.Forte@Sun.COM 		return (ret);
54837836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
54847836SJohn.Forte@Sun.COM 	(void) close(fd);
54857836SJohn.Forte@Sun.COM 	return (ret);
54867836SJohn.Forte@Sun.COM }
54877836SJohn.Forte@Sun.COM 
54887836SJohn.Forte@Sun.COM /*
54897836SJohn.Forte@Sun.COM  * stmfRemoveFromHostGroup
54907836SJohn.Forte@Sun.COM  *
54917836SJohn.Forte@Sun.COM  * Purpose: Removes an initiator from an initiator group
54927836SJohn.Forte@Sun.COM  *
54937836SJohn.Forte@Sun.COM  * hostGroupName - name of an initiator group
54947836SJohn.Forte@Sun.COM  * hostName - name of host group member to remove
54957836SJohn.Forte@Sun.COM  */
54967836SJohn.Forte@Sun.COM int
54977836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
54987836SJohn.Forte@Sun.COM {
54997836SJohn.Forte@Sun.COM 	int ret;
55007836SJohn.Forte@Sun.COM 	int fd;
55017836SJohn.Forte@Sun.COM 
55027836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
55037836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
55047836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
55057836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
55067836SJohn.Forte@Sun.COM 	}
55077836SJohn.Forte@Sun.COM 
55087836SJohn.Forte@Sun.COM 	/* call init */
55097836SJohn.Forte@Sun.COM 	ret = initializeConfig();
55107836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
55117836SJohn.Forte@Sun.COM 		return (ret);
55127836SJohn.Forte@Sun.COM 	}
55137836SJohn.Forte@Sun.COM 
55147836SJohn.Forte@Sun.COM 	/*
55157836SJohn.Forte@Sun.COM 	 * Open control node for stmf
55167836SJohn.Forte@Sun.COM 	 */
55177836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
55187836SJohn.Forte@Sun.COM 		return (ret);
55197836SJohn.Forte@Sun.COM 
55207836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
55217836SJohn.Forte@Sun.COM 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
55227836SJohn.Forte@Sun.COM 		goto done;
55237836SJohn.Forte@Sun.COM 	}
55247836SJohn.Forte@Sun.COM 
55259585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
55269585STim.Szeto@Sun.COM 		goto done;
55279585STim.Szeto@Sun.COM 	}
55289585STim.Szeto@Sun.COM 
55297836SJohn.Forte@Sun.COM 	ret = psRemoveHostGroupMember((char *)hostGroupName,
55307836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
55317836SJohn.Forte@Sun.COM 	switch (ret) {
55327836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
55337836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
55347836SJohn.Forte@Sun.COM 			break;
55357836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
55367836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
55377836SJohn.Forte@Sun.COM 			break;
55387836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
55397836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
55407836SJohn.Forte@Sun.COM 			break;
55417836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
55427836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
55437836SJohn.Forte@Sun.COM 			break;
55447836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
55457836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
55467836SJohn.Forte@Sun.COM 			break;
55477836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
55487836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
55497836SJohn.Forte@Sun.COM 			break;
55507836SJohn.Forte@Sun.COM 		default:
55517836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
55527836SJohn.Forte@Sun.COM 			    "stmfRemoveFromHostGroup"
55537836SJohn.Forte@Sun.COM 			    "psRemoveHostGroupMember:error(%d)", ret);
55547836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
55557836SJohn.Forte@Sun.COM 			break;
55567836SJohn.Forte@Sun.COM 	}
55577836SJohn.Forte@Sun.COM 
55587836SJohn.Forte@Sun.COM done:
55597836SJohn.Forte@Sun.COM 	(void) close(fd);
55607836SJohn.Forte@Sun.COM 	return (ret);
55617836SJohn.Forte@Sun.COM }
55627836SJohn.Forte@Sun.COM 
55637836SJohn.Forte@Sun.COM /*
55647836SJohn.Forte@Sun.COM  * stmfRemoveFromTargetGroup
55657836SJohn.Forte@Sun.COM  *
55667836SJohn.Forte@Sun.COM  * Purpose: Removes a local port from a local port group
55677836SJohn.Forte@Sun.COM  *
55687836SJohn.Forte@Sun.COM  * targetGroupName - name of a target group
55697836SJohn.Forte@Sun.COM  * targetName - name of target to remove
55707836SJohn.Forte@Sun.COM  */
55717836SJohn.Forte@Sun.COM int
55727836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
55737836SJohn.Forte@Sun.COM {
55747836SJohn.Forte@Sun.COM 	int ret;
55757836SJohn.Forte@Sun.COM 	int fd;
55767836SJohn.Forte@Sun.COM 
55777836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
55787836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
55797836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
55807836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
55817836SJohn.Forte@Sun.COM 	}
55827836SJohn.Forte@Sun.COM 
55837836SJohn.Forte@Sun.COM 	/* call init */
55847836SJohn.Forte@Sun.COM 	ret = initializeConfig();
55857836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
55867836SJohn.Forte@Sun.COM 		return (ret);
55877836SJohn.Forte@Sun.COM 	}
55887836SJohn.Forte@Sun.COM 
55897836SJohn.Forte@Sun.COM 	/*
55907836SJohn.Forte@Sun.COM 	 * Open control node for stmf
55917836SJohn.Forte@Sun.COM 	 */
55927836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
55937836SJohn.Forte@Sun.COM 		return (ret);
55947836SJohn.Forte@Sun.COM 
55957836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
55967836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
55977836SJohn.Forte@Sun.COM 		goto done;
55987836SJohn.Forte@Sun.COM 	}
55997836SJohn.Forte@Sun.COM 
56009585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
56019585STim.Szeto@Sun.COM 		goto done;
56029585STim.Szeto@Sun.COM 	}
56039585STim.Szeto@Sun.COM 
56047836SJohn.Forte@Sun.COM 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
56057836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
56067836SJohn.Forte@Sun.COM 	switch (ret) {
56077836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
56087836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
56097836SJohn.Forte@Sun.COM 			break;
56107836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
56117836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
56127836SJohn.Forte@Sun.COM 			break;
56137836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
56147836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
56157836SJohn.Forte@Sun.COM 			break;
56167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
56177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
56187836SJohn.Forte@Sun.COM 			break;
56197836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
56207836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
56217836SJohn.Forte@Sun.COM 			break;
56227836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
56237836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
56247836SJohn.Forte@Sun.COM 			break;
56257836SJohn.Forte@Sun.COM 		default:
56267836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
56277836SJohn.Forte@Sun.COM 			    "stmfRemoveFromTargetGroup"
56287836SJohn.Forte@Sun.COM 			    "psRemoveTargetGroupMember:error(%d)", ret);
56297836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
56307836SJohn.Forte@Sun.COM 			break;
56317836SJohn.Forte@Sun.COM 	}
56327836SJohn.Forte@Sun.COM 
56337836SJohn.Forte@Sun.COM done:
56347836SJohn.Forte@Sun.COM 	(void) close(fd);
56357836SJohn.Forte@Sun.COM 	return (ret);
56367836SJohn.Forte@Sun.COM }
56377836SJohn.Forte@Sun.COM 
56387836SJohn.Forte@Sun.COM /*
56397836SJohn.Forte@Sun.COM  * stmfRemoveViewEntry
56407836SJohn.Forte@Sun.COM  *
56417836SJohn.Forte@Sun.COM  * Purpose: Removes a view entry from a logical unit
56427836SJohn.Forte@Sun.COM  *
56437836SJohn.Forte@Sun.COM  * lu - guid of lu for which view entry is being removed
56447836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry to remove
56457836SJohn.Forte@Sun.COM  *
56467836SJohn.Forte@Sun.COM  */
56477836SJohn.Forte@Sun.COM int
56487836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
56497836SJohn.Forte@Sun.COM {
56507836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
56517836SJohn.Forte@Sun.COM 	int fd;
56527836SJohn.Forte@Sun.COM 	int ioctlRet;
56537836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
56547836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
56557836SJohn.Forte@Sun.COM 
56567836SJohn.Forte@Sun.COM 	if (lu == NULL) {
56577836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
56587836SJohn.Forte@Sun.COM 	}
56597836SJohn.Forte@Sun.COM 
56607836SJohn.Forte@Sun.COM 	/* call init */
56617836SJohn.Forte@Sun.COM 	ret = initializeConfig();
56627836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
56637836SJohn.Forte@Sun.COM 		return (ret);
56647836SJohn.Forte@Sun.COM 	}
56657836SJohn.Forte@Sun.COM 
56667836SJohn.Forte@Sun.COM 	/*
56677836SJohn.Forte@Sun.COM 	 * Open control node for stmf
56687836SJohn.Forte@Sun.COM 	 */
56697836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
56707836SJohn.Forte@Sun.COM 		return (ret);
56717836SJohn.Forte@Sun.COM 
56727836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
56737836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
56747836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx = viewEntryIndex;
56757836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
56767836SJohn.Forte@Sun.COM 
56777836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
56787836SJohn.Forte@Sun.COM 	/*
56797836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
56807836SJohn.Forte@Sun.COM 	 */
56817836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
56827836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
56837836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
56847836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
56857836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
56867836SJohn.Forte@Sun.COM 		switch (errno) {
56877836SJohn.Forte@Sun.COM 			case EBUSY:
56887836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
56897836SJohn.Forte@Sun.COM 				break;
56909585STim.Szeto@Sun.COM 			case EPERM:
56919585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
56929585STim.Szeto@Sun.COM 				break;
56937836SJohn.Forte@Sun.COM 			case EACCES:
56947836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
56957836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
56967836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
56977836SJohn.Forte@Sun.COM 						break;
56987836SJohn.Forte@Sun.COM 					default:
56997836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
57007836SJohn.Forte@Sun.COM 						break;
57017836SJohn.Forte@Sun.COM 				}
57027836SJohn.Forte@Sun.COM 				break;
57037836SJohn.Forte@Sun.COM 			case ENODEV:
57047836SJohn.Forte@Sun.COM 			case ENOENT:
57057836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
57067836SJohn.Forte@Sun.COM 				break;
57077836SJohn.Forte@Sun.COM 			default:
57087836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
57097836SJohn.Forte@Sun.COM 				    "stmfRemoveViewEntry:ioctl errno(%d)",
57107836SJohn.Forte@Sun.COM 				    errno);
57117836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
57127836SJohn.Forte@Sun.COM 				break;
57137836SJohn.Forte@Sun.COM 		}
57147836SJohn.Forte@Sun.COM 		goto done;
57157836SJohn.Forte@Sun.COM 	}
57167836SJohn.Forte@Sun.COM 
57179585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
57189585STim.Szeto@Sun.COM 		goto done;
57199585STim.Szeto@Sun.COM 	}
57209585STim.Szeto@Sun.COM 
57217836SJohn.Forte@Sun.COM 	ret = psRemoveViewEntry(lu, viewEntryIndex);
57227836SJohn.Forte@Sun.COM 	switch (ret) {
57237836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
57247836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
57257836SJohn.Forte@Sun.COM 			break;
57267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
57277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
57287836SJohn.Forte@Sun.COM 			break;
57297836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
57307836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
57317836SJohn.Forte@Sun.COM 			break;
57327836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
57337836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
57347836SJohn.Forte@Sun.COM 			break;
57357836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
57367836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
57377836SJohn.Forte@Sun.COM 			break;
57387836SJohn.Forte@Sun.COM 		default:
57397836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
57407836SJohn.Forte@Sun.COM 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
57417836SJohn.Forte@Sun.COM 			    ret);
57427836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
57437836SJohn.Forte@Sun.COM 			break;
57447836SJohn.Forte@Sun.COM 	}
57457836SJohn.Forte@Sun.COM 
57467836SJohn.Forte@Sun.COM done:
57477836SJohn.Forte@Sun.COM 	(void) close(fd);
57487836SJohn.Forte@Sun.COM 	return (ret);
57497836SJohn.Forte@Sun.COM }
57507836SJohn.Forte@Sun.COM 
57517836SJohn.Forte@Sun.COM /*
57527836SJohn.Forte@Sun.COM  * stmfSetProviderData
57537836SJohn.Forte@Sun.COM  *
57547836SJohn.Forte@Sun.COM  * Purpose: set the provider data
57557836SJohn.Forte@Sun.COM  *
57567836SJohn.Forte@Sun.COM  * providerName - unique name of provider
57577836SJohn.Forte@Sun.COM  * nvl - nvlist to set
57587836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
57597836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
57607836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
57617836SJohn.Forte@Sun.COM  */
57627836SJohn.Forte@Sun.COM int
57637836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
57647836SJohn.Forte@Sun.COM {
57657836SJohn.Forte@Sun.COM 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
57667836SJohn.Forte@Sun.COM 	    NULL));
57677836SJohn.Forte@Sun.COM }
57687836SJohn.Forte@Sun.COM 
57697836SJohn.Forte@Sun.COM /*
57707836SJohn.Forte@Sun.COM  * stmfSetProviderDataProt
57717836SJohn.Forte@Sun.COM  *
57727836SJohn.Forte@Sun.COM  * Purpose: set the provider data
57737836SJohn.Forte@Sun.COM  *
57747836SJohn.Forte@Sun.COM  * providerName - unique name of provider
57757836SJohn.Forte@Sun.COM  * nvl - nvlist to set
57767836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
57777836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
57787836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
57797836SJohn.Forte@Sun.COM  * setToken - Stale data token returned in the stmfGetProviderDataProt()
57807836SJohn.Forte@Sun.COM  *	      call or NULL.
57817836SJohn.Forte@Sun.COM  */
57827836SJohn.Forte@Sun.COM int
57837836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
57847836SJohn.Forte@Sun.COM     uint64_t *setToken)
57857836SJohn.Forte@Sun.COM {
57867836SJohn.Forte@Sun.COM 	int ret;
57877836SJohn.Forte@Sun.COM 	int fd;
57887836SJohn.Forte@Sun.COM 
57897836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
57907836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
57917836SJohn.Forte@Sun.COM 	}
57927836SJohn.Forte@Sun.COM 
57937836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
57947836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
57957836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
57967836SJohn.Forte@Sun.COM 	}
57977836SJohn.Forte@Sun.COM 
57987836SJohn.Forte@Sun.COM 	/* call init */
57997836SJohn.Forte@Sun.COM 	ret = initializeConfig();
58007836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
58017836SJohn.Forte@Sun.COM 		return (ret);
58027836SJohn.Forte@Sun.COM 	}
58037836SJohn.Forte@Sun.COM 
58047836SJohn.Forte@Sun.COM 	/*
58057836SJohn.Forte@Sun.COM 	 * Open control node for stmf
58067836SJohn.Forte@Sun.COM 	 */
58077836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
58087836SJohn.Forte@Sun.COM 		return (ret);
58097836SJohn.Forte@Sun.COM 
58109585STim.Szeto@Sun.COM 	ret = setProviderData(fd, providerName, nvl, providerType, setToken);
58117836SJohn.Forte@Sun.COM 
58127836SJohn.Forte@Sun.COM 	(void) close(fd);
58137836SJohn.Forte@Sun.COM 
58147836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
58157836SJohn.Forte@Sun.COM 		goto done;
58167836SJohn.Forte@Sun.COM 	}
58177836SJohn.Forte@Sun.COM 
58189585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
58199585STim.Szeto@Sun.COM 		goto done;
58209585STim.Szeto@Sun.COM 	}
58219585STim.Szeto@Sun.COM 
58227836SJohn.Forte@Sun.COM 	/* setting driver provider data successful. Now persist it */
58239585STim.Szeto@Sun.COM 	ret = psSetProviderData(providerName, nvl, providerType, NULL);
58247836SJohn.Forte@Sun.COM 	switch (ret) {
58257836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
58267836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
58277836SJohn.Forte@Sun.COM 			break;
58287836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
58297836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
58307836SJohn.Forte@Sun.COM 			break;
58317836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
58327836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
58337836SJohn.Forte@Sun.COM 			break;
58347836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
58357836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
58367836SJohn.Forte@Sun.COM 			break;
58377836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
58387836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
58397836SJohn.Forte@Sun.COM 			break;
58407836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_PROV_DATA_STALE:
58417836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PROV_DATA_STALE;
58427836SJohn.Forte@Sun.COM 			break;
58437836SJohn.Forte@Sun.COM 		default:
58447836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
58457836SJohn.Forte@Sun.COM 			    "stmfSetProviderData"
58467836SJohn.Forte@Sun.COM 			    "psSetProviderData:error(%d)", ret);
58477836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
58487836SJohn.Forte@Sun.COM 			break;
58497836SJohn.Forte@Sun.COM 	}
58507836SJohn.Forte@Sun.COM 
58517836SJohn.Forte@Sun.COM done:
58527836SJohn.Forte@Sun.COM 	return (ret);
58537836SJohn.Forte@Sun.COM }
58547836SJohn.Forte@Sun.COM 
58557836SJohn.Forte@Sun.COM /*
58569585STim.Szeto@Sun.COM  * getProviderData
58579585STim.Szeto@Sun.COM  *
58589585STim.Szeto@Sun.COM  * Purpose: set the provider data from stmf
58599585STim.Szeto@Sun.COM  *
58609585STim.Szeto@Sun.COM  * providerName - unique name of provider
58619585STim.Szeto@Sun.COM  * nvl - nvlist to load/retrieve
58629585STim.Szeto@Sun.COM  * providerType - logical unit or port provider
58639585STim.Szeto@Sun.COM  * setToken - returned stale data token
58649585STim.Szeto@Sun.COM  */
58659585STim.Szeto@Sun.COM int
58669585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType,
58679585STim.Szeto@Sun.COM     uint64_t *setToken)
58689585STim.Szeto@Sun.COM {
58699585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
58709585STim.Szeto@Sun.COM 	int fd;
58719585STim.Szeto@Sun.COM 	int ioctlRet;
58729585STim.Szeto@Sun.COM 	size_t nvlistSize = ALLOC_PP_DATA_SIZE;
58739585STim.Szeto@Sun.COM 	int retryCnt = 0;
58749585STim.Szeto@Sun.COM 	int retryCntMax = MAX_PROVIDER_RETRY;
58759585STim.Szeto@Sun.COM 	stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
58769585STim.Szeto@Sun.COM 	boolean_t retry = B_TRUE;
58779585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
58789585STim.Szeto@Sun.COM 
58799585STim.Szeto@Sun.COM 	if (providerName == NULL) {
58809585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
58819585STim.Szeto@Sun.COM 	}
58829585STim.Szeto@Sun.COM 
58839585STim.Szeto@Sun.COM 	/*
58849585STim.Szeto@Sun.COM 	 * Open control node for stmf
58859585STim.Szeto@Sun.COM 	 */
58869585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
58879585STim.Szeto@Sun.COM 		return (ret);
58889585STim.Szeto@Sun.COM 
58899585STim.Szeto@Sun.COM 	/* set provider name and provider type */
58909585STim.Szeto@Sun.COM 	if (strlcpy(ppi.ppi_name, providerName,
58919585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) >=
58929585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) {
58939585STim.Szeto@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
58949585STim.Szeto@Sun.COM 		goto done;
58959585STim.Szeto@Sun.COM 	}
58969585STim.Szeto@Sun.COM 	switch (providerType) {
58979585STim.Szeto@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
58989585STim.Szeto@Sun.COM 			ppi.ppi_lu_provider = 1;
58999585STim.Szeto@Sun.COM 			break;
59009585STim.Szeto@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
59019585STim.Szeto@Sun.COM 			ppi.ppi_port_provider = 1;
59029585STim.Szeto@Sun.COM 			break;
59039585STim.Szeto@Sun.COM 		default:
59049585STim.Szeto@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
59059585STim.Szeto@Sun.COM 			goto done;
59069585STim.Szeto@Sun.COM 	}
59079585STim.Szeto@Sun.COM 
59089585STim.Szeto@Sun.COM 	do {
59099585STim.Szeto@Sun.COM 		/* allocate memory for ioctl */
59109585STim.Szeto@Sun.COM 		ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
59119585STim.Szeto@Sun.COM 		    sizeof (stmf_ppioctl_data_t));
59129585STim.Szeto@Sun.COM 		if (ppi_out == NULL) {
59139585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
59149585STim.Szeto@Sun.COM 			goto done;
59159585STim.Szeto@Sun.COM 
59169585STim.Szeto@Sun.COM 		}
59179585STim.Szeto@Sun.COM 
59189585STim.Szeto@Sun.COM 		/* set the size of the ioctl data to allocated buffer */
59199585STim.Szeto@Sun.COM 		ppi.ppi_data_size = nvlistSize;
59209585STim.Szeto@Sun.COM 
59219585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
59229585STim.Szeto@Sun.COM 
59239585STim.Szeto@Sun.COM 		stmfIoctl.stmf_version = STMF_VERSION_1;
59249585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
59259585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
59269585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
59279585STim.Szeto@Sun.COM 		    nvlistSize;
59289585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
59299585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
59309585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
59319585STim.Szeto@Sun.COM 			switch (errno) {
59329585STim.Szeto@Sun.COM 				case EBUSY:
59339585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
59349585STim.Szeto@Sun.COM 					break;
59359585STim.Szeto@Sun.COM 				case EPERM:
59369585STim.Szeto@Sun.COM 				case EACCES:
59379585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
59389585STim.Szeto@Sun.COM 					break;
59399585STim.Szeto@Sun.COM 				case EINVAL:
59409585STim.Szeto@Sun.COM 					if (stmfIoctl.stmf_error ==
59419585STim.Szeto@Sun.COM 					    STMF_IOCERR_INSUFFICIENT_BUF) {
59429585STim.Szeto@Sun.COM 						nvlistSize =
59439585STim.Szeto@Sun.COM 						    ppi_out->ppi_data_size;
59449585STim.Szeto@Sun.COM 						free(ppi_out);
59459585STim.Szeto@Sun.COM 						ppi_out = NULL;
59469585STim.Szeto@Sun.COM 						if (retryCnt++ > retryCntMax) {
59479585STim.Szeto@Sun.COM 							retry = B_FALSE;
59489585STim.Szeto@Sun.COM 							ret = STMF_ERROR_BUSY;
59499585STim.Szeto@Sun.COM 						} else {
59509585STim.Szeto@Sun.COM 							ret =
59519585STim.Szeto@Sun.COM 							    STMF_STATUS_SUCCESS;
59529585STim.Szeto@Sun.COM 						}
59539585STim.Szeto@Sun.COM 					} else {
59549585STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
59559585STim.Szeto@Sun.COM 						    "getProviderData:ioctl"
59569585STim.Szeto@Sun.COM 						    "unable to retrieve "
59579585STim.Szeto@Sun.COM 						    "nvlist");
59589585STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
59599585STim.Szeto@Sun.COM 					}
59609585STim.Szeto@Sun.COM 					break;
59619585STim.Szeto@Sun.COM 				case ENOENT:
59629585STim.Szeto@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
59639585STim.Szeto@Sun.COM 					break;
59649585STim.Szeto@Sun.COM 				default:
59659585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
59669585STim.Szeto@Sun.COM 					    "getProviderData:ioctl errno(%d)",
59679585STim.Szeto@Sun.COM 					    errno);
59689585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
59699585STim.Szeto@Sun.COM 					break;
59709585STim.Szeto@Sun.COM 			}
59719585STim.Szeto@Sun.COM 			if (ret != STMF_STATUS_SUCCESS)
59729585STim.Szeto@Sun.COM 				goto done;
59739585STim.Szeto@Sun.COM 		}
59749585STim.Szeto@Sun.COM 	} while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
59759585STim.Szeto@Sun.COM 
59769585STim.Szeto@Sun.COM 	if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
59779585STim.Szeto@Sun.COM 	    ppi_out->ppi_data_size, nvl, 0)) != 0) {
59789585STim.Szeto@Sun.COM 		ret = STMF_STATUS_ERROR;
59799585STim.Szeto@Sun.COM 		goto done;
59809585STim.Szeto@Sun.COM 	}
59819585STim.Szeto@Sun.COM 
59829585STim.Szeto@Sun.COM 	/* caller has asked for new token */
59839585STim.Szeto@Sun.COM 	if (setToken) {
59849585STim.Szeto@Sun.COM 		*setToken = ppi_out->ppi_token;
59859585STim.Szeto@Sun.COM 	}
59869585STim.Szeto@Sun.COM done:
59879585STim.Szeto@Sun.COM 	free(ppi_out);
59889585STim.Szeto@Sun.COM 	(void) close(fd);
59899585STim.Szeto@Sun.COM 	return (ret);
59909585STim.Szeto@Sun.COM }
59919585STim.Szeto@Sun.COM 
59929585STim.Szeto@Sun.COM /*
59937836SJohn.Forte@Sun.COM  * setProviderData
59947836SJohn.Forte@Sun.COM  *
59959585STim.Szeto@Sun.COM  * Purpose: set the provider data in stmf
59967836SJohn.Forte@Sun.COM  *
59977836SJohn.Forte@Sun.COM  * providerName - unique name of provider
59987836SJohn.Forte@Sun.COM  * nvl - nvlist to set
59997836SJohn.Forte@Sun.COM  * providerType - logical unit or port provider
60009585STim.Szeto@Sun.COM  * setToken - stale data token to check if not NULL
60017836SJohn.Forte@Sun.COM  */
60027836SJohn.Forte@Sun.COM static int
60039585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
60049585STim.Szeto@Sun.COM     uint64_t *setToken)
60057836SJohn.Forte@Sun.COM {
60067836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
60077836SJohn.Forte@Sun.COM 	int ioctlRet;
60087836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
60097836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t *ppi = NULL;
60109585STim.Szeto@Sun.COM 	uint64_t outToken;
60117836SJohn.Forte@Sun.COM 	char *allocatedNvBuffer;
60127836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
60137836SJohn.Forte@Sun.COM 
60147836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
60157836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
60167836SJohn.Forte@Sun.COM 	}
60177836SJohn.Forte@Sun.COM 
60187836SJohn.Forte@Sun.COM 	/* get size of encoded nvlist */
60197836SJohn.Forte@Sun.COM 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
60207836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
60217836SJohn.Forte@Sun.COM 	}
60227836SJohn.Forte@Sun.COM 
60237836SJohn.Forte@Sun.COM 	/* allocate memory for ioctl */
60247836SJohn.Forte@Sun.COM 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
60257836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t));
60267836SJohn.Forte@Sun.COM 	if (ppi == NULL) {
60277836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
60287836SJohn.Forte@Sun.COM 	}
60297836SJohn.Forte@Sun.COM 
60309585STim.Szeto@Sun.COM 	if (setToken) {
60319585STim.Szeto@Sun.COM 		ppi->ppi_token_valid = 1;
60329585STim.Szeto@Sun.COM 		ppi->ppi_token = *setToken;
60339585STim.Szeto@Sun.COM 	}
60349585STim.Szeto@Sun.COM 
60357836SJohn.Forte@Sun.COM 	allocatedNvBuffer = (char *)&ppi->ppi_data;
60367836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
60377836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
60387836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
60397836SJohn.Forte@Sun.COM 	}
60407836SJohn.Forte@Sun.COM 
60417836SJohn.Forte@Sun.COM 	/* set provider name and provider type */
60427836SJohn.Forte@Sun.COM 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
60437836SJohn.Forte@Sun.COM 	switch (providerType) {
60447836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
60457836SJohn.Forte@Sun.COM 			ppi->ppi_lu_provider = 1;
60467836SJohn.Forte@Sun.COM 			break;
60477836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
60487836SJohn.Forte@Sun.COM 			ppi->ppi_port_provider = 1;
60497836SJohn.Forte@Sun.COM 			break;
60507836SJohn.Forte@Sun.COM 		default:
60517836SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
60527836SJohn.Forte@Sun.COM 	}
60537836SJohn.Forte@Sun.COM 
60547836SJohn.Forte@Sun.COM 	/* set the size of the ioctl data to packed data size */
60557836SJohn.Forte@Sun.COM 	ppi->ppi_data_size = nvlistEncodedSize;
60567836SJohn.Forte@Sun.COM 
60577836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
60587836SJohn.Forte@Sun.COM 
60597836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
60607836SJohn.Forte@Sun.COM 	/*
60617836SJohn.Forte@Sun.COM 	 * Subtracting 8 from the size as that is the size of the last member
60627836SJohn.Forte@Sun.COM 	 * of the structure where the packed data resides
60637836SJohn.Forte@Sun.COM 	 */
60647836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
60657836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t) - 8;
60667836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
60679585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
60689585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
60697836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
60707836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
60717836SJohn.Forte@Sun.COM 		switch (errno) {
60727836SJohn.Forte@Sun.COM 			case EBUSY:
60737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
60747836SJohn.Forte@Sun.COM 				break;
60759585STim.Szeto@Sun.COM 			case EPERM:
60767836SJohn.Forte@Sun.COM 			case EACCES:
60777836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
60787836SJohn.Forte@Sun.COM 				break;
60799585STim.Szeto@Sun.COM 			case EINVAL:
60809585STim.Szeto@Sun.COM 				if (stmfIoctl.stmf_error ==
60819585STim.Szeto@Sun.COM 				    STMF_IOCERR_PPD_UPDATED) {
60829585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PROV_DATA_STALE;
60839585STim.Szeto@Sun.COM 				} else {
60849585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
60859585STim.Szeto@Sun.COM 				}
60869585STim.Szeto@Sun.COM 				break;
60877836SJohn.Forte@Sun.COM 			default:
60887836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
60897836SJohn.Forte@Sun.COM 				    "setProviderData:ioctl errno(%d)", errno);
60907836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
60917836SJohn.Forte@Sun.COM 				break;
60927836SJohn.Forte@Sun.COM 		}
60937836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS)
60947836SJohn.Forte@Sun.COM 			goto done;
60957836SJohn.Forte@Sun.COM 	}
60967836SJohn.Forte@Sun.COM 
60979585STim.Szeto@Sun.COM 	/* caller has asked for new token */
60989585STim.Szeto@Sun.COM 	if (setToken) {
60999585STim.Szeto@Sun.COM 		*setToken = outToken;
61009585STim.Szeto@Sun.COM 	}
61017836SJohn.Forte@Sun.COM done:
61027836SJohn.Forte@Sun.COM 	free(ppi);
61037836SJohn.Forte@Sun.COM 	return (ret);
61047836SJohn.Forte@Sun.COM }
61059585STim.Szeto@Sun.COM 
61069585STim.Szeto@Sun.COM /*
61079585STim.Szeto@Sun.COM  * set the persistence method in the library only or library and service
61089585STim.Szeto@Sun.COM  */
61099585STim.Szeto@Sun.COM int
61109585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
61119585STim.Szeto@Sun.COM {
61129585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
61139585STim.Szeto@Sun.COM 	int oldPersist;
61149585STim.Szeto@Sun.COM 
61159585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
61169585STim.Szeto@Sun.COM 	oldPersist = iPersistType;
61179585STim.Szeto@Sun.COM 	if (persistType == STMF_PERSIST_NONE ||
61189585STim.Szeto@Sun.COM 	    persistType == STMF_PERSIST_SMF) {
61199585STim.Szeto@Sun.COM 		iLibSetPersist = B_TRUE;
61209585STim.Szeto@Sun.COM 		iPersistType = persistType;
61219585STim.Szeto@Sun.COM 	} else {
61229585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
61239585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
61249585STim.Szeto@Sun.COM 	}
61259585STim.Szeto@Sun.COM 	/* Is this for this library open or in SMF */
61269585STim.Szeto@Sun.COM 	if (serviceSet == B_TRUE) {
61279585STim.Szeto@Sun.COM 		ret = psSetServicePersist(persistType);
61289585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
61299585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
61309585STim.Szeto@Sun.COM 			/* Set to old value */
61319585STim.Szeto@Sun.COM 			iPersistType = oldPersist;
61329585STim.Szeto@Sun.COM 		}
61339585STim.Szeto@Sun.COM 	}
61349585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
61359585STim.Szeto@Sun.COM 
61369585STim.Szeto@Sun.COM 	return (ret);
61379585STim.Szeto@Sun.COM }
61389585STim.Szeto@Sun.COM 
61399585STim.Szeto@Sun.COM /*
61409585STim.Szeto@Sun.COM  * Only returns internal state for persist. If unset, goes to ps. If that
61419585STim.Szeto@Sun.COM  * fails, returns default setting
61429585STim.Szeto@Sun.COM  */
61439585STim.Szeto@Sun.COM static uint8_t
61449585STim.Szeto@Sun.COM iGetPersistMethod()
61459585STim.Szeto@Sun.COM {
61469585STim.Szeto@Sun.COM 
61479585STim.Szeto@Sun.COM 	uint8_t persistType = 0;
61489585STim.Szeto@Sun.COM 
61499585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
61509585STim.Szeto@Sun.COM 	if (iLibSetPersist) {
61519585STim.Szeto@Sun.COM 		persistType = iPersistType;
61529585STim.Szeto@Sun.COM 	} else {
61539585STim.Szeto@Sun.COM 		int ret;
61549585STim.Szeto@Sun.COM 		ret = psGetServicePersist(&persistType);
61559585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
61569585STim.Szeto@Sun.COM 			/* set to default */
61579585STim.Szeto@Sun.COM 			persistType = STMF_DEFAULT_PERSIST;
61589585STim.Szeto@Sun.COM 		}
61599585STim.Szeto@Sun.COM 	}
61609585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
61619585STim.Szeto@Sun.COM 	return (persistType);
61629585STim.Szeto@Sun.COM }
61639585STim.Szeto@Sun.COM 
61649585STim.Szeto@Sun.COM /*
61659585STim.Szeto@Sun.COM  * Returns either library state or persistent config state depending on
61669585STim.Szeto@Sun.COM  * serviceState
61679585STim.Szeto@Sun.COM  */
61689585STim.Szeto@Sun.COM int
61699585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
61709585STim.Szeto@Sun.COM {
61719585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
61729585STim.Szeto@Sun.COM 
61739585STim.Szeto@Sun.COM 	if (persistType == NULL) {
61749585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
61759585STim.Szeto@Sun.COM 	}
61769585STim.Szeto@Sun.COM 	if (serviceState) {
61779585STim.Szeto@Sun.COM 		ret = psGetServicePersist(persistType);
61789585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
61799585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
61809585STim.Szeto@Sun.COM 		}
61819585STim.Szeto@Sun.COM 	} else {
61829585STim.Szeto@Sun.COM 		(void) pthread_mutex_lock(&persistenceTypeLock);
61839585STim.Szeto@Sun.COM 		if (iLibSetPersist) {
61849585STim.Szeto@Sun.COM 			*persistType = iPersistType;
61859585STim.Szeto@Sun.COM 		} else {
61869585STim.Szeto@Sun.COM 			*persistType = STMF_DEFAULT_PERSIST;
61879585STim.Szeto@Sun.COM 		}
61889585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
61899585STim.Szeto@Sun.COM 	}
61909585STim.Szeto@Sun.COM 
61919585STim.Szeto@Sun.COM 	return (ret);
61929585STim.Szeto@Sun.COM }
619310691STim.Szeto@Sun.COM 
619410691STim.Szeto@Sun.COM /*
619510725SJohn.Forte@Sun.COM  * stmfPostProxyMsg
619610725SJohn.Forte@Sun.COM  *
619710725SJohn.Forte@Sun.COM  * Purpose: Post a message to the proxy port provider
619810725SJohn.Forte@Sun.COM  *
619910725SJohn.Forte@Sun.COM  * buf - buffer containing message to post
620010725SJohn.Forte@Sun.COM  * buflen - buffer length
620110725SJohn.Forte@Sun.COM  */
620210725SJohn.Forte@Sun.COM int
620310725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen)
620410725SJohn.Forte@Sun.COM {
620510725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
620610725SJohn.Forte@Sun.COM 	int ioctlRet;
620710725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
620810725SJohn.Forte@Sun.COM 
620910725SJohn.Forte@Sun.COM 	if (buf == NULL) {
621010725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
621110725SJohn.Forte@Sun.COM 	}
621210725SJohn.Forte@Sun.COM 
621310725SJohn.Forte@Sun.COM 	/*
621410725SJohn.Forte@Sun.COM 	 * Issue ioctl to post the message
621510725SJohn.Forte@Sun.COM 	 */
621610725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
621710725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf_size = buflen;
621810725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf;
621910725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl);
622010725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
622110725SJohn.Forte@Sun.COM 		switch (errno) {
622210725SJohn.Forte@Sun.COM 			case EPERM:
622310725SJohn.Forte@Sun.COM 			case EACCES:
622410725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
622510725SJohn.Forte@Sun.COM 				break;
622610725SJohn.Forte@Sun.COM 			default:
622710725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_POST_MSG_FAILED;
622810725SJohn.Forte@Sun.COM 				break;
622910725SJohn.Forte@Sun.COM 		}
623010725SJohn.Forte@Sun.COM 	}
623110725SJohn.Forte@Sun.COM 
623210725SJohn.Forte@Sun.COM 	return (ret);
623310725SJohn.Forte@Sun.COM }
623410725SJohn.Forte@Sun.COM 
623510725SJohn.Forte@Sun.COM /*
623610725SJohn.Forte@Sun.COM  * stmfInitProxyDoor
623710725SJohn.Forte@Sun.COM  *
623810725SJohn.Forte@Sun.COM  * Purpose: Install door in proxy
623910725SJohn.Forte@Sun.COM  *
624010725SJohn.Forte@Sun.COM  * hdl - pointer to returned handle
624110725SJohn.Forte@Sun.COM  * fd - door from door_create()
624210725SJohn.Forte@Sun.COM  */
624310725SJohn.Forte@Sun.COM int
624410725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door)
624510725SJohn.Forte@Sun.COM {
624610725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
624710725SJohn.Forte@Sun.COM 	int ioctlRet;
624810725SJohn.Forte@Sun.COM 	int fd;
624910725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
625010725SJohn.Forte@Sun.COM 
625110725SJohn.Forte@Sun.COM 	if (hdl == NULL) {
625210725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
625310725SJohn.Forte@Sun.COM 	}
625410725SJohn.Forte@Sun.COM 
625510725SJohn.Forte@Sun.COM 	/*
625610725SJohn.Forte@Sun.COM 	 * Open control node for pppt
625710725SJohn.Forte@Sun.COM 	 */
625810725SJohn.Forte@Sun.COM 	if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) {
625910725SJohn.Forte@Sun.COM 		return (ret);
626010725SJohn.Forte@Sun.COM 	}
626110725SJohn.Forte@Sun.COM 
626210725SJohn.Forte@Sun.COM 	/*
626310725SJohn.Forte@Sun.COM 	 * Issue ioctl to install the door
626410725SJohn.Forte@Sun.COM 	 */
626510725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
626610725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_door_fd = (uint32_t)door;
626710725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl);
626810725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
626910725SJohn.Forte@Sun.COM 		switch (errno) {
627010725SJohn.Forte@Sun.COM 			case EPERM:
627110725SJohn.Forte@Sun.COM 			case EACCES:
627210725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
627310725SJohn.Forte@Sun.COM 				break;
627410725SJohn.Forte@Sun.COM 			case EINVAL:
627510725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_INVALID_ARG;
627610725SJohn.Forte@Sun.COM 				break;
627710725SJohn.Forte@Sun.COM 			case EBUSY:
627810725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_DOOR_INSTALLED;
627910725SJohn.Forte@Sun.COM 				break;
628010725SJohn.Forte@Sun.COM 			default:
628110725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
628210725SJohn.Forte@Sun.COM 				break;
628310725SJohn.Forte@Sun.COM 		}
628410725SJohn.Forte@Sun.COM 	}
628510725SJohn.Forte@Sun.COM 
628610725SJohn.Forte@Sun.COM 	/* return driver fd to caller */
628710725SJohn.Forte@Sun.COM 	*hdl = fd;
628810725SJohn.Forte@Sun.COM 	return (ret);
628910725SJohn.Forte@Sun.COM }
629010725SJohn.Forte@Sun.COM 
629110725SJohn.Forte@Sun.COM void
629210725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl)
629310725SJohn.Forte@Sun.COM {
629410725SJohn.Forte@Sun.COM 	(void) close(hdl);
629510725SJohn.Forte@Sun.COM }
629610725SJohn.Forte@Sun.COM 
629710725SJohn.Forte@Sun.COM /*
629810691STim.Szeto@Sun.COM  * validateLunNumIoctl
629910691STim.Szeto@Sun.COM  *
630010691STim.Szeto@Sun.COM  * Purpose: Issues ioctl to check and get available lun# in view entry
630110691STim.Szeto@Sun.COM  *
630210691STim.Szeto@Sun.COM  * viewEntry - view entry to use
630310691STim.Szeto@Sun.COM  */
630410691STim.Szeto@Sun.COM static int
630510691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry)
630610691STim.Szeto@Sun.COM {
630710691STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
630810691STim.Szeto@Sun.COM 	int ioctlRet;
630910691STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
631010691STim.Szeto@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
631110691STim.Szeto@Sun.COM 
631210691STim.Szeto@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
631310691STim.Szeto@Sun.COM 	/*
631410691STim.Szeto@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
631510691STim.Szeto@Sun.COM 	 * false on input
631610691STim.Szeto@Sun.COM 	 */
631710691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
631810691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
631910691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
632010691STim.Szeto@Sun.COM 
632110691STim.Szeto@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
632210691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
632310691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
632410691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
632510691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
632610691STim.Szeto@Sun.COM 	}
632710691STim.Szeto@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
632810691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup,
632910691STim.Szeto@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
633010691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
633110691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
633210691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
633310691STim.Szeto@Sun.COM 	}
633410691STim.Szeto@Sun.COM 	/* Validating the lun number */
633510691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
633610691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
633710691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
633810691STim.Szeto@Sun.COM 	}
633910691STim.Szeto@Sun.COM 
634010691STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
634110691STim.Szeto@Sun.COM 	/*
634210691STim.Szeto@Sun.COM 	 * Issue ioctl to validate lun# in the view entry
634310691STim.Szeto@Sun.COM 	 */
634410691STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
634510691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
634610691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
634710691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
634810691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
634910691STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl);
635010691STim.Szeto@Sun.COM 
635110691STim.Szeto@Sun.COM 	/* save available lun number */
635210691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
635310691STim.Szeto@Sun.COM 		bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
635410691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
635510691STim.Szeto@Sun.COM 	}
635610691STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
635710691STim.Szeto@Sun.COM 		switch (errno) {
635810691STim.Szeto@Sun.COM 			case EBUSY:
635910691STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
636010691STim.Szeto@Sun.COM 				break;
636110691STim.Szeto@Sun.COM 			case EPERM:
636210691STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
636310691STim.Szeto@Sun.COM 				break;
636410691STim.Szeto@Sun.COM 			case EACCES:
636510691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
636610691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
636710691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
636810691STim.Szeto@Sun.COM 						break;
636910691STim.Szeto@Sun.COM 					default:
637010691STim.Szeto@Sun.COM 						ret = STMF_ERROR_PERM;
637110691STim.Szeto@Sun.COM 						break;
637210691STim.Szeto@Sun.COM 				}
637310691STim.Szeto@Sun.COM 				break;
637410691STim.Szeto@Sun.COM 			default:
637510691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
637610691STim.Szeto@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
637710691STim.Szeto@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
637810691STim.Szeto@Sun.COM 						break;
637910691STim.Szeto@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
638010691STim.Szeto@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
638110691STim.Szeto@Sun.COM 						break;
638210691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
638310691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
638410691STim.Szeto@Sun.COM 						break;
638510691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_HG:
638610691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
638710691STim.Szeto@Sun.COM 						break;
638810691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_TG:
638910691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
639010691STim.Szeto@Sun.COM 						break;
639110691STim.Szeto@Sun.COM 					default:
639210691STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
639310691STim.Szeto@Sun.COM 						    "addViewEntryIoctl"
639410691STim.Szeto@Sun.COM 						    ":error(%d)",
639510691STim.Szeto@Sun.COM 						    stmfIoctl.stmf_error);
639610691STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
639710691STim.Szeto@Sun.COM 						break;
639810691STim.Szeto@Sun.COM 				}
639910691STim.Szeto@Sun.COM 				break;
640010691STim.Szeto@Sun.COM 		}
640110691STim.Szeto@Sun.COM 	}
640210691STim.Szeto@Sun.COM 	return (ret);
640310691STim.Szeto@Sun.COM }
640410691STim.Szeto@Sun.COM 
640510691STim.Szeto@Sun.COM /*
640610691STim.Szeto@Sun.COM  * stmfValidateView
640710691STim.Szeto@Sun.COM  *
640810691STim.Szeto@Sun.COM  * Purpose: Validate or get lun # base on TG, HG of view entry
640910691STim.Szeto@Sun.COM  *
641010691STim.Szeto@Sun.COM  * viewEntry - view entry structure to use
641110691STim.Szeto@Sun.COM  */
641210691STim.Szeto@Sun.COM int
641310691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry)
641410691STim.Szeto@Sun.COM {
641510691STim.Szeto@Sun.COM 	int ret;
641610691STim.Szeto@Sun.COM 	int fd;
641710691STim.Szeto@Sun.COM 	stmfViewEntry iViewEntry;
641810691STim.Szeto@Sun.COM 
641910691STim.Szeto@Sun.COM 	if (viewEntry == NULL) {
642010691STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
642110691STim.Szeto@Sun.COM 	}
642210691STim.Szeto@Sun.COM 
642310691STim.Szeto@Sun.COM 	/* initialize and set internal view entry */
642410691STim.Szeto@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
642510691STim.Szeto@Sun.COM 
642610691STim.Szeto@Sun.COM 	if (!viewEntry->allHosts) {
642710691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
642810691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.hostGroup));
642910691STim.Szeto@Sun.COM 	} else {
643010691STim.Szeto@Sun.COM 		iViewEntry.allHosts = B_TRUE;
643110691STim.Szeto@Sun.COM 	}
643210691STim.Szeto@Sun.COM 
643310691STim.Szeto@Sun.COM 	if (!viewEntry->allTargets) {
643410691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
643510691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.targetGroup));
643610691STim.Szeto@Sun.COM 	} else {
643710691STim.Szeto@Sun.COM 		iViewEntry.allTargets = B_TRUE;
643810691STim.Szeto@Sun.COM 	}
643910691STim.Szeto@Sun.COM 
644010691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
644110691STim.Szeto@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
644210691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
644310691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
644410691STim.Szeto@Sun.COM 	}
644510691STim.Szeto@Sun.COM 
644610691STim.Szeto@Sun.COM 	/*
644710691STim.Szeto@Sun.COM 	 * set users return view entry index valid flag to false
644810691STim.Szeto@Sun.COM 	 * in case of failure
644910691STim.Szeto@Sun.COM 	 */
645010691STim.Szeto@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
645110691STim.Szeto@Sun.COM 
645210691STim.Szeto@Sun.COM 	/* Check to ensure service exists */
645310691STim.Szeto@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
645410691STim.Szeto@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
645510691STim.Szeto@Sun.COM 	}
645610691STim.Szeto@Sun.COM 
645710691STim.Szeto@Sun.COM 	/* call init */
645810691STim.Szeto@Sun.COM 	ret = initializeConfig();
645910691STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
646010691STim.Szeto@Sun.COM 		return (ret);
646110691STim.Szeto@Sun.COM 	}
646210691STim.Szeto@Sun.COM 
646310691STim.Szeto@Sun.COM 	/*
646410691STim.Szeto@Sun.COM 	 * Open control node for stmf
646510691STim.Szeto@Sun.COM 	 */
646610691STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
646710691STim.Szeto@Sun.COM 		return (ret);
646810691STim.Szeto@Sun.COM 
646910691STim.Szeto@Sun.COM 	/*
647010691STim.Szeto@Sun.COM 	 * Validate lun# in the view entry from the driver
647110691STim.Szeto@Sun.COM 	 */
647210691STim.Szeto@Sun.COM 	ret = validateLunNumIoctl(fd, &iViewEntry);
647310691STim.Szeto@Sun.COM 	(void) close(fd);
647410691STim.Szeto@Sun.COM 
647510691STim.Szeto@Sun.COM 	/* save available lun number */
647610691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
647710691STim.Szeto@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
647810691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
647910691STim.Szeto@Sun.COM 	}
648010691STim.Szeto@Sun.COM 
648110691STim.Szeto@Sun.COM 	return (ret);
648210691STim.Szeto@Sun.COM }
6483