xref: /onnv-gate/usr/src/lib/libstmf/common/stmf.c (revision 11865)
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 /*
2211691SSrivijitha.Dugganapalli@Sun.COM  * Copyright 2010 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>
5111103SJohn.Forte@Sun.COM #include <macros.h>
527836SJohn.Forte@Sun.COM 
537836SJohn.Forte@Sun.COM #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
549585STim.Szeto@Sun.COM #define	SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
5510725SJohn.Forte@Sun.COM #define	PPPT_PATH    "/devices/pseudo/pppt@0:pppt"
567836SJohn.Forte@Sun.COM 
577836SJohn.Forte@Sun.COM #define	EUI "eui."
587836SJohn.Forte@Sun.COM #define	WWN "wwn."
597836SJohn.Forte@Sun.COM #define	IQN "iqn."
609585STim.Szeto@Sun.COM #define	LU_ASCII_GUID_SIZE 32
619585STim.Szeto@Sun.COM #define	LU_GUID_SIZE 16
629585STim.Szeto@Sun.COM #define	OUI_ASCII_SIZE 6
6310765SJohn.Forte@Sun.COM #define	HOST_ID_ASCII_SIZE 8
649585STim.Szeto@Sun.COM #define	OUI_SIZE 3
6510765SJohn.Forte@Sun.COM #define	HOST_ID_SIZE 4
667836SJohn.Forte@Sun.COM #define	IDENT_LENGTH_BYTE 3
677836SJohn.Forte@Sun.COM 
689585STim.Szeto@Sun.COM /* various initial allocation values */
699585STim.Szeto@Sun.COM #define	ALLOC_LU		8192
709585STim.Szeto@Sun.COM #define	ALLOC_TARGET_PORT	2048
719585STim.Szeto@Sun.COM #define	ALLOC_PROVIDER		64
729585STim.Szeto@Sun.COM #define	ALLOC_GROUP		2048
739585STim.Szeto@Sun.COM #define	ALLOC_SESSION		2048
749585STim.Szeto@Sun.COM #define	ALLOC_VE		256
759585STim.Szeto@Sun.COM #define	ALLOC_PP_DATA_SIZE	128*1024
769585STim.Szeto@Sun.COM #define	ALLOC_GRP_MEMBER	256
779585STim.Szeto@Sun.COM 
787836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME	223
799585STim.Szeto@Sun.COM #define	MAX_SERIAL_SIZE 252 + 1
809585STim.Szeto@Sun.COM #define	MAX_LU_ALIAS_SIZE 256
819585STim.Szeto@Sun.COM #define	MAX_SBD_PROPS	MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
827836SJohn.Forte@Sun.COM 
837836SJohn.Forte@Sun.COM #define	OPEN_STMF 0
847836SJohn.Forte@Sun.COM #define	OPEN_EXCL_STMF O_EXCL
857836SJohn.Forte@Sun.COM 
869585STim.Szeto@Sun.COM #define	OPEN_SBD 0
879585STim.Szeto@Sun.COM #define	OPEN_EXCL_SBD O_EXCL
889585STim.Szeto@Sun.COM 
8910725SJohn.Forte@Sun.COM #define	OPEN_PPPT 0
9010725SJohn.Forte@Sun.COM #define	OPEN_EXCL_PPPT O_EXCL
9110725SJohn.Forte@Sun.COM 
927836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_TYPE 0
937836SJohn.Forte@Sun.COM #define	TARGET_TYPE 1
947836SJohn.Forte@Sun.COM #define	STMF_SERVICE_TYPE 2
957836SJohn.Forte@Sun.COM 
969585STim.Szeto@Sun.COM #define	HOST_GROUP   1
979585STim.Szeto@Sun.COM #define	TARGET_GROUP 2
989585STim.Szeto@Sun.COM 
999585STim.Szeto@Sun.COM /* set default persistence here */
1009585STim.Szeto@Sun.COM #define	STMF_DEFAULT_PERSIST	STMF_PERSIST_SMF
1019585STim.Szeto@Sun.COM 
1029585STim.Szeto@Sun.COM #define	MAX_PROVIDER_RETRY 30
1039585STim.Szeto@Sun.COM 
1047836SJohn.Forte@Sun.COM static int openStmf(int, int *fd);
1059585STim.Szeto@Sun.COM static int openSbd(int, int *fd);
10610725SJohn.Forte@Sun.COM static int openPppt(int, int *fd);
1077836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *);
1087836SJohn.Forte@Sun.COM static int loadStore(int fd);
1097836SJohn.Forte@Sun.COM static int initializeConfig();
1107836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
1117836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *);
1127836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
1137836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *);
1147836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *);
1157836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *);
1167836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int);
1179585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
1189585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *);
1199585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *);
1209585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid);
1219585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
1229585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
1239585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
1249585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *);
1259585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *);
1269585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t);
1279585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *);
12811103SJohn.Forte@Sun.COM static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen);
1299585STim.Szeto@Sun.COM static int checkHexUpper(char *);
1309585STim.Szeto@Sun.COM static int strToShift(const char *);
1319585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *);
1329585STim.Szeto@Sun.COM static void diskError(uint32_t, int *);
1339585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *);
1349585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
1359585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
1369585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t);
1379585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod();
1389585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int);
1399585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int);
1409585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
1419585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *);
14210725SJohn.Forte@Sun.COM static int setDiskStandby(stmfGuid *luGuid);
14311103SJohn.Forte@Sun.COM static int setDiskGlobalProp(uint32_t, const char *);
1449585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *);
14510725SJohn.Forte@Sun.COM static void deleteNonActiveLus();
1469585STim.Szeto@Sun.COM 
1479585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER;
1489585STim.Szeto@Sun.COM static int iPersistType = 0;
1499585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
1509585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE;
1517836SJohn.Forte@Sun.COM 
1527836SJohn.Forte@Sun.COM /*
1537836SJohn.Forte@Sun.COM  * Open for stmf module
1547836SJohn.Forte@Sun.COM  *
1557836SJohn.Forte@Sun.COM  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
1567836SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
1577836SJohn.Forte@Sun.COM  */
1587836SJohn.Forte@Sun.COM static int
1597836SJohn.Forte@Sun.COM openStmf(int flag, int *fd)
1607836SJohn.Forte@Sun.COM {
1617836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
1627836SJohn.Forte@Sun.COM 
1637836SJohn.Forte@Sun.COM 	if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
1647836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
1657836SJohn.Forte@Sun.COM 	} else {
1667836SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
1677836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1689585STim.Szeto@Sun.COM 		} else if (errno == EACCES) {
1699585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERM;
1707836SJohn.Forte@Sun.COM 		} else {
1717836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1727836SJohn.Forte@Sun.COM 		}
1737836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
1747836SJohn.Forte@Sun.COM 		    STMF_PATH, errno);
1757836SJohn.Forte@Sun.COM 	}
1767836SJohn.Forte@Sun.COM 
1777836SJohn.Forte@Sun.COM 	return (ret);
1787836SJohn.Forte@Sun.COM }
1797836SJohn.Forte@Sun.COM 
1807836SJohn.Forte@Sun.COM /*
1819585STim.Szeto@Sun.COM  * Open for sbd module
1829585STim.Szeto@Sun.COM  *
18310725SJohn.Forte@Sun.COM  * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD)
1849585STim.Szeto@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
1859585STim.Szeto@Sun.COM  */
1869585STim.Szeto@Sun.COM static int
1879585STim.Szeto@Sun.COM openSbd(int flag, int *fd)
1889585STim.Szeto@Sun.COM {
1899585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
1909585STim.Szeto@Sun.COM 
1919585STim.Szeto@Sun.COM 	if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
1929585STim.Szeto@Sun.COM 		ret = STMF_STATUS_SUCCESS;
1939585STim.Szeto@Sun.COM 	} else {
1949585STim.Szeto@Sun.COM 		if (errno == EBUSY) {
1959585STim.Szeto@Sun.COM 			ret = STMF_ERROR_BUSY;
1969585STim.Szeto@Sun.COM 		} else if (errno == EACCES) {
1979585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERM;
1989585STim.Szeto@Sun.COM 		} else {
1999585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
2009585STim.Szeto@Sun.COM 		}
2019585STim.Szeto@Sun.COM 		syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)",
2029585STim.Szeto@Sun.COM 		    SBD_PATH, errno);
2039585STim.Szeto@Sun.COM 	}
2049585STim.Szeto@Sun.COM 
2059585STim.Szeto@Sun.COM 	return (ret);
2069585STim.Szeto@Sun.COM }
2079585STim.Szeto@Sun.COM 
2089585STim.Szeto@Sun.COM /*
20910725SJohn.Forte@Sun.COM  * Open for pppt module
21010725SJohn.Forte@Sun.COM  *
21110725SJohn.Forte@Sun.COM  * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT)
21210725SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
21310725SJohn.Forte@Sun.COM  */
21410725SJohn.Forte@Sun.COM static int
21510725SJohn.Forte@Sun.COM openPppt(int flag, int *fd)
21610725SJohn.Forte@Sun.COM {
21710725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
21810725SJohn.Forte@Sun.COM 
21910725SJohn.Forte@Sun.COM 	if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) {
22010725SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
22110725SJohn.Forte@Sun.COM 	} else {
22210725SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
22310725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
22410725SJohn.Forte@Sun.COM 		} else if (errno == EACCES) {
22510725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PERM;
22610725SJohn.Forte@Sun.COM 		} else {
22710725SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
22810725SJohn.Forte@Sun.COM 		}
22910725SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)",
23010725SJohn.Forte@Sun.COM 		    PPPT_PATH, errno);
23110725SJohn.Forte@Sun.COM 	}
23210725SJohn.Forte@Sun.COM 
23310725SJohn.Forte@Sun.COM 	return (ret);
23410725SJohn.Forte@Sun.COM }
23510725SJohn.Forte@Sun.COM 
23610725SJohn.Forte@Sun.COM /*
2377836SJohn.Forte@Sun.COM  * initializeConfig
2387836SJohn.Forte@Sun.COM  *
2397836SJohn.Forte@Sun.COM  * This routine should be called before any ioctl requiring initialization
2407836SJohn.Forte@Sun.COM  * which is basically everything except stmfGetState(), setStmfState() and
2417836SJohn.Forte@Sun.COM  * stmfLoadConfig().
2427836SJohn.Forte@Sun.COM  */
2437836SJohn.Forte@Sun.COM static int
2447836SJohn.Forte@Sun.COM initializeConfig()
2457836SJohn.Forte@Sun.COM {
2467836SJohn.Forte@Sun.COM 	int ret;
2477836SJohn.Forte@Sun.COM 	stmfState state;
2487836SJohn.Forte@Sun.COM 
2497836SJohn.Forte@Sun.COM 
2507836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2517836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2527836SJohn.Forte@Sun.COM 		return (ret);
2537836SJohn.Forte@Sun.COM 	}
2547836SJohn.Forte@Sun.COM 
2557836SJohn.Forte@Sun.COM 	/* if we've already initialized or in the process, return success */
2567836SJohn.Forte@Sun.COM 	if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
2577836SJohn.Forte@Sun.COM 	    state.configState == STMF_CONFIG_STATE_INIT) {
2587836SJohn.Forte@Sun.COM 		return (STMF_STATUS_SUCCESS);
2597836SJohn.Forte@Sun.COM 	}
2607836SJohn.Forte@Sun.COM 
2617836SJohn.Forte@Sun.COM 	ret = stmfLoadConfig();
2627836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2637836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
2647836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfLoadConfig:error(%d)", ret);
2657836SJohn.Forte@Sun.COM 		return (ret);
2667836SJohn.Forte@Sun.COM 	}
2677836SJohn.Forte@Sun.COM 
2687836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2697836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2707836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
2717836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfGetState:error(%d)", ret);
2727836SJohn.Forte@Sun.COM 		return (ret);
2737836SJohn.Forte@Sun.COM 	}
2747836SJohn.Forte@Sun.COM 
2757836SJohn.Forte@Sun.COM 	if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
2767836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
2777836SJohn.Forte@Sun.COM 		    state.configState);
2787836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_ERROR;
2797836SJohn.Forte@Sun.COM 	}
2807836SJohn.Forte@Sun.COM 
2817836SJohn.Forte@Sun.COM 	return (ret);
2827836SJohn.Forte@Sun.COM }
2837836SJohn.Forte@Sun.COM 
2847836SJohn.Forte@Sun.COM 
2857836SJohn.Forte@Sun.COM /*
2867836SJohn.Forte@Sun.COM  * groupIoctl
2877836SJohn.Forte@Sun.COM  *
2887836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for create/delete on group
2897836SJohn.Forte@Sun.COM  *
2907836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group cmd
2917836SJohn.Forte@Sun.COM  * groupName - groupName to create or delete
2927836SJohn.Forte@Sun.COM  */
2937836SJohn.Forte@Sun.COM static int
2947836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName)
2957836SJohn.Forte@Sun.COM {
2967836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2977836SJohn.Forte@Sun.COM 	int ioctlRet;
2987836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2997836SJohn.Forte@Sun.COM 	stmf_group_name_t iGroupName;
3007836SJohn.Forte@Sun.COM 
3017836SJohn.Forte@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
3027836SJohn.Forte@Sun.COM 
3037836SJohn.Forte@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
3047836SJohn.Forte@Sun.COM 
3057836SJohn.Forte@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3087836SJohn.Forte@Sun.COM 	/*
3097836SJohn.Forte@Sun.COM 	 * Issue ioctl to create the host group
3107836SJohn.Forte@Sun.COM 	 */
3117836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3127836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
3137836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3147836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3157836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3167836SJohn.Forte@Sun.COM 		switch (errno) {
3179585STim.Szeto@Sun.COM 			case EPERM:
3187836SJohn.Forte@Sun.COM 			case EACCES:
3197836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3207836SJohn.Forte@Sun.COM 				break;
3217836SJohn.Forte@Sun.COM 			default:
3227836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
3237836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_EXISTS:
3247836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_EXISTS:
3257836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
3267836SJohn.Forte@Sun.COM 						break;
3277836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_IN_USE:
3287836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_IN_USE:
3297836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_GROUP_IN_USE;
3307836SJohn.Forte@Sun.COM 						break;
3317836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
3327836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
3337836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
3347836SJohn.Forte@Sun.COM 						break;
3357836SJohn.Forte@Sun.COM 					default:
3367836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
3377836SJohn.Forte@Sun.COM 						    "groupIoctl:error(%d)",
3387836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
3397836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
3407836SJohn.Forte@Sun.COM 						break;
3417836SJohn.Forte@Sun.COM 				}
3427836SJohn.Forte@Sun.COM 				break;
3437836SJohn.Forte@Sun.COM 		}
3447836SJohn.Forte@Sun.COM 	}
3457836SJohn.Forte@Sun.COM done:
3467836SJohn.Forte@Sun.COM 	return (ret);
3477836SJohn.Forte@Sun.COM }
3487836SJohn.Forte@Sun.COM 
3497836SJohn.Forte@Sun.COM /*
3509585STim.Szeto@Sun.COM  * groupMemberIoctl
3517836SJohn.Forte@Sun.COM  *
3527836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for add/remove member on group
3537836SJohn.Forte@Sun.COM  *
3547836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group member cmd
3557836SJohn.Forte@Sun.COM  * groupName - groupName to add to or remove from
3567836SJohn.Forte@Sun.COM  * devid - group member to add or remove
3577836SJohn.Forte@Sun.COM  */
3587836SJohn.Forte@Sun.COM static int
3597836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
3607836SJohn.Forte@Sun.COM {
3617836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
3627836SJohn.Forte@Sun.COM 	int ioctlRet;
3637836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
3647836SJohn.Forte@Sun.COM 	stmf_group_op_data_t stmfGroupData;
3657836SJohn.Forte@Sun.COM 
3667836SJohn.Forte@Sun.COM 	bzero(&stmfGroupData, sizeof (stmfGroupData));
3677836SJohn.Forte@Sun.COM 
3687836SJohn.Forte@Sun.COM 	bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
3697836SJohn.Forte@Sun.COM 
3707836SJohn.Forte@Sun.COM 	stmfGroupData.group.name_size = strlen((char *)groupName);
3717836SJohn.Forte@Sun.COM 	stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
3727836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
3737836SJohn.Forte@Sun.COM 	    devid->identLength);
3747836SJohn.Forte@Sun.COM 
3757836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3767836SJohn.Forte@Sun.COM 	/*
3777836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
3787836SJohn.Forte@Sun.COM 	 */
3797836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3807836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
3817836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
3827836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3837836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3847836SJohn.Forte@Sun.COM 		switch (errno) {
3857836SJohn.Forte@Sun.COM 			case EBUSY:
3869884STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
3879884STim.Szeto@Sun.COM 					case STMF_IOCERR_TG_NEED_TG_OFFLINE:
3889884STim.Szeto@Sun.COM 						ret = STMF_ERROR_TG_ONLINE;
3899884STim.Szeto@Sun.COM 						break;
3909884STim.Szeto@Sun.COM 					default:
3919884STim.Szeto@Sun.COM 						ret = STMF_ERROR_BUSY;
3929884STim.Szeto@Sun.COM 						break;
3939884STim.Szeto@Sun.COM 				}
3947836SJohn.Forte@Sun.COM 				break;
3959585STim.Szeto@Sun.COM 			case EPERM:
3967836SJohn.Forte@Sun.COM 			case EACCES:
3977836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3987836SJohn.Forte@Sun.COM 				break;
3997836SJohn.Forte@Sun.COM 			default:
4007836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
4017836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_ENTRY_EXISTS:
4027836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_ENTRY_EXISTS:
4037836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
4047836SJohn.Forte@Sun.COM 						break;
4057836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG_ENTRY:
4067836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG_ENTRY:
4077836SJohn.Forte@Sun.COM 						ret =
4087836SJohn.Forte@Sun.COM 						    STMF_ERROR_MEMBER_NOT_FOUND;
4097836SJohn.Forte@Sun.COM 						break;
4107836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
4117836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
4127836SJohn.Forte@Sun.COM 						ret =
4137836SJohn.Forte@Sun.COM 						    STMF_ERROR_GROUP_NOT_FOUND;
4147836SJohn.Forte@Sun.COM 						break;
4157836SJohn.Forte@Sun.COM 					default:
4167836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
4177836SJohn.Forte@Sun.COM 						    "groupMemberIoctl:error"
4187836SJohn.Forte@Sun.COM 						    "(%d)",
4197836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
4207836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
4217836SJohn.Forte@Sun.COM 						break;
4227836SJohn.Forte@Sun.COM 				}
4237836SJohn.Forte@Sun.COM 				break;
4247836SJohn.Forte@Sun.COM 		}
4257836SJohn.Forte@Sun.COM 	}
4267836SJohn.Forte@Sun.COM done:
4277836SJohn.Forte@Sun.COM 	return (ret);
4287836SJohn.Forte@Sun.COM }
4297836SJohn.Forte@Sun.COM 
4307836SJohn.Forte@Sun.COM /*
4319585STim.Szeto@Sun.COM  * qsort function
4329585STim.Szeto@Sun.COM  * sort on veIndex
4339585STim.Szeto@Sun.COM  */
4349585STim.Szeto@Sun.COM static int
4359585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2)
4369585STim.Szeto@Sun.COM {
4379585STim.Szeto@Sun.COM 
4389585STim.Szeto@Sun.COM 	stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
4399585STim.Szeto@Sun.COM 	if (v1->veIndex > v2->veIndex)
4409585STim.Szeto@Sun.COM 		return (1);
4419585STim.Szeto@Sun.COM 	if (v1->veIndex < v2->veIndex)
4429585STim.Szeto@Sun.COM 		return (-1);
4439585STim.Szeto@Sun.COM 	return (0);
4449585STim.Szeto@Sun.COM }
4459585STim.Szeto@Sun.COM 
4469585STim.Szeto@Sun.COM /*
4477836SJohn.Forte@Sun.COM  * guidCompare
4487836SJohn.Forte@Sun.COM  *
4497836SJohn.Forte@Sun.COM  * qsort function
4507836SJohn.Forte@Sun.COM  * sort on guid
4517836SJohn.Forte@Sun.COM  */
4527836SJohn.Forte@Sun.COM static int
4537836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2)
4547836SJohn.Forte@Sun.COM {
4557836SJohn.Forte@Sun.COM 
4567836SJohn.Forte@Sun.COM 	stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
4577836SJohn.Forte@Sun.COM 	int i;
4587836SJohn.Forte@Sun.COM 
4597836SJohn.Forte@Sun.COM 	for (i = 0; i < sizeof (stmfGuid); i++) {
4607836SJohn.Forte@Sun.COM 		if (g1->guid[i] > g2->guid[i])
4617836SJohn.Forte@Sun.COM 			return (1);
4627836SJohn.Forte@Sun.COM 		if (g1->guid[i] < g2->guid[i])
4637836SJohn.Forte@Sun.COM 			return (-1);
4647836SJohn.Forte@Sun.COM 	}
4657836SJohn.Forte@Sun.COM 
4667836SJohn.Forte@Sun.COM 	return (0);
4677836SJohn.Forte@Sun.COM }
4687836SJohn.Forte@Sun.COM 
4697836SJohn.Forte@Sun.COM /*
4707836SJohn.Forte@Sun.COM  * stmfAddToHostGroup
4717836SJohn.Forte@Sun.COM  *
4727836SJohn.Forte@Sun.COM  * Purpose: Adds an initiator to an existing host group
4737836SJohn.Forte@Sun.COM  *
4747836SJohn.Forte@Sun.COM  * hostGroupName - name of an existing host group
4757836SJohn.Forte@Sun.COM  * hostName - name of initiator to add
4767836SJohn.Forte@Sun.COM  */
4777836SJohn.Forte@Sun.COM int
4787836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
4797836SJohn.Forte@Sun.COM {
4807836SJohn.Forte@Sun.COM 	int ret;
4817836SJohn.Forte@Sun.COM 	int fd;
4827836SJohn.Forte@Sun.COM 
4837836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
4847836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
4857836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
4867836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
4877836SJohn.Forte@Sun.COM 	}
4887836SJohn.Forte@Sun.COM 
4897836SJohn.Forte@Sun.COM 	/* call init */
4907836SJohn.Forte@Sun.COM 	ret = initializeConfig();
4917836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
4927836SJohn.Forte@Sun.COM 		return (ret);
4937836SJohn.Forte@Sun.COM 	}
4947836SJohn.Forte@Sun.COM 
4957836SJohn.Forte@Sun.COM 	/*
4967836SJohn.Forte@Sun.COM 	 * Open control node for stmf
4977836SJohn.Forte@Sun.COM 	 */
4987836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4997836SJohn.Forte@Sun.COM 		return (ret);
5007836SJohn.Forte@Sun.COM 
5017836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
5027836SJohn.Forte@Sun.COM 	    hostName)) != STMF_STATUS_SUCCESS) {
5037836SJohn.Forte@Sun.COM 		goto done;
5047836SJohn.Forte@Sun.COM 	}
5057836SJohn.Forte@Sun.COM 
5069585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5079585STim.Szeto@Sun.COM 		goto done;
5089585STim.Szeto@Sun.COM 	}
5099585STim.Szeto@Sun.COM 
5107836SJohn.Forte@Sun.COM 	ret = psAddHostGroupMember((char *)hostGroupName,
5117836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
5127836SJohn.Forte@Sun.COM 	switch (ret) {
5137836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
5147836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
5157836SJohn.Forte@Sun.COM 			break;
5167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
5177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
5187836SJohn.Forte@Sun.COM 			break;
5197836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5207836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5217836SJohn.Forte@Sun.COM 			break;
5227836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
5237836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
5247836SJohn.Forte@Sun.COM 			break;
5257836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5267836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5277836SJohn.Forte@Sun.COM 			break;
5287836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
5297836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5307836SJohn.Forte@Sun.COM 			break;
5317836SJohn.Forte@Sun.COM 		default:
5327836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
5337836SJohn.Forte@Sun.COM 			    "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
5347836SJohn.Forte@Sun.COM 			    ret);
5357836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
5367836SJohn.Forte@Sun.COM 			break;
5377836SJohn.Forte@Sun.COM 	}
5387836SJohn.Forte@Sun.COM 
5397836SJohn.Forte@Sun.COM done:
5407836SJohn.Forte@Sun.COM 	(void) close(fd);
5417836SJohn.Forte@Sun.COM 	return (ret);
5427836SJohn.Forte@Sun.COM }
5437836SJohn.Forte@Sun.COM 
5447836SJohn.Forte@Sun.COM /*
5457836SJohn.Forte@Sun.COM  * stmfAddToTargetGroup
5467836SJohn.Forte@Sun.COM  *
5477836SJohn.Forte@Sun.COM  * Purpose: Adds a local port to an existing target group
5487836SJohn.Forte@Sun.COM  *
5497836SJohn.Forte@Sun.COM  * targetGroupName - name of an existing target group
5507836SJohn.Forte@Sun.COM  * targetName - name of target to add
5517836SJohn.Forte@Sun.COM  */
5527836SJohn.Forte@Sun.COM int
5537836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
5547836SJohn.Forte@Sun.COM {
5557836SJohn.Forte@Sun.COM 	int ret;
5567836SJohn.Forte@Sun.COM 	int fd;
5577836SJohn.Forte@Sun.COM 
5587836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
5597836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
5607836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
5617836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
5627836SJohn.Forte@Sun.COM 	}
5637836SJohn.Forte@Sun.COM 
5647836SJohn.Forte@Sun.COM 	/* call init */
5657836SJohn.Forte@Sun.COM 	ret = initializeConfig();
5667836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
5677836SJohn.Forte@Sun.COM 		return (ret);
5687836SJohn.Forte@Sun.COM 	}
5697836SJohn.Forte@Sun.COM 
5707836SJohn.Forte@Sun.COM 	/*
5717836SJohn.Forte@Sun.COM 	 * Open control node for stmf
5727836SJohn.Forte@Sun.COM 	 */
5737836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5747836SJohn.Forte@Sun.COM 		return (ret);
5757836SJohn.Forte@Sun.COM 
5767836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
5777836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
5787836SJohn.Forte@Sun.COM 		goto done;
5797836SJohn.Forte@Sun.COM 	}
5807836SJohn.Forte@Sun.COM 
5819585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5829585STim.Szeto@Sun.COM 		goto done;
5839585STim.Szeto@Sun.COM 	}
5849585STim.Szeto@Sun.COM 
5857836SJohn.Forte@Sun.COM 	ret = psAddTargetGroupMember((char *)targetGroupName,
5867836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
5877836SJohn.Forte@Sun.COM 	switch (ret) {
5887836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
5897836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
5907836SJohn.Forte@Sun.COM 			break;
5917836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
5927836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
5937836SJohn.Forte@Sun.COM 			break;
5947836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5957836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5967836SJohn.Forte@Sun.COM 			break;
5977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
5987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
5997836SJohn.Forte@Sun.COM 			break;
6007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
6027836SJohn.Forte@Sun.COM 			break;
6037836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
6047836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
6057836SJohn.Forte@Sun.COM 			break;
6067836SJohn.Forte@Sun.COM 		default:
6077836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
6087836SJohn.Forte@Sun.COM 			    "stmfAddToTargetGroup:psAddTargetGroupMember:"
6097836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
6107836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
6117836SJohn.Forte@Sun.COM 			break;
6127836SJohn.Forte@Sun.COM 	}
6137836SJohn.Forte@Sun.COM 
6147836SJohn.Forte@Sun.COM done:
6157836SJohn.Forte@Sun.COM 	(void) close(fd);
6167836SJohn.Forte@Sun.COM 	return (ret);
6177836SJohn.Forte@Sun.COM }
6187836SJohn.Forte@Sun.COM 
6197836SJohn.Forte@Sun.COM /*
6207836SJohn.Forte@Sun.COM  * addViewEntryIoctl
6217836SJohn.Forte@Sun.COM  *
6227836SJohn.Forte@Sun.COM  * Purpose: Issues ioctl to add a view entry
6237836SJohn.Forte@Sun.COM  *
6247836SJohn.Forte@Sun.COM  * lu - Logical Unit identifier to which the view entry is added
6257836SJohn.Forte@Sun.COM  * viewEntry - view entry to add
6267836SJohn.Forte@Sun.COM  * init - When set to B_TRUE, we are in the init state, i.e. don't call open
6277836SJohn.Forte@Sun.COM  */
6287836SJohn.Forte@Sun.COM static int
6297836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
6307836SJohn.Forte@Sun.COM {
6317836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
6327836SJohn.Forte@Sun.COM 	int ioctlRet;
6337836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
6347836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
6357836SJohn.Forte@Sun.COM 
6367836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6377836SJohn.Forte@Sun.COM 	/*
6387836SJohn.Forte@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
6397836SJohn.Forte@Sun.COM 	 * false on input
6407836SJohn.Forte@Sun.COM 	 */
6417836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
6427836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
6437836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
6447836SJohn.Forte@Sun.COM 
6457836SJohn.Forte@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
6467836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
6477836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
6487836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
6497836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
6507836SJohn.Forte@Sun.COM 	}
6517836SJohn.Forte@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
6527836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup,
6537836SJohn.Forte@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
6547836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
6557836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
6567836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
6577836SJohn.Forte@Sun.COM 	}
6587836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
6597836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
6607836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
6617836SJohn.Forte@Sun.COM 	}
6627836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
6637836SJohn.Forte@Sun.COM 
6647836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
6657836SJohn.Forte@Sun.COM 	/*
6667836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
6677836SJohn.Forte@Sun.COM 	 */
6687836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
6697836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6707836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6717836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
6727836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6737836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
6747836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
6757836SJohn.Forte@Sun.COM 		switch (errno) {
6767836SJohn.Forte@Sun.COM 			case EBUSY:
6777836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
6787836SJohn.Forte@Sun.COM 				break;
6799585STim.Szeto@Sun.COM 			case EPERM:
6809585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
6819585STim.Szeto@Sun.COM 				break;
6827836SJohn.Forte@Sun.COM 			case EACCES:
6837836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
6847836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6857836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
6867836SJohn.Forte@Sun.COM 						break;
6877836SJohn.Forte@Sun.COM 					default:
6887836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
6897836SJohn.Forte@Sun.COM 						break;
6907836SJohn.Forte@Sun.COM 				}
6917836SJohn.Forte@Sun.COM 				break;
6927836SJohn.Forte@Sun.COM 			default:
6937836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
6947836SJohn.Forte@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
6957836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
6967836SJohn.Forte@Sun.COM 						break;
6977836SJohn.Forte@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
6987836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
6997836SJohn.Forte@Sun.COM 						break;
7007836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
7017836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
7027836SJohn.Forte@Sun.COM 						break;
7037836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
7047836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
7057836SJohn.Forte@Sun.COM 						break;
7067836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
7077836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
7087836SJohn.Forte@Sun.COM 						break;
7097836SJohn.Forte@Sun.COM 					default:
7107836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
7117836SJohn.Forte@Sun.COM 						    "addViewEntryIoctl"
7127836SJohn.Forte@Sun.COM 						    ":error(%d)",
7137836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
7147836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
7157836SJohn.Forte@Sun.COM 						break;
7167836SJohn.Forte@Sun.COM 				}
7177836SJohn.Forte@Sun.COM 				break;
7187836SJohn.Forte@Sun.COM 		}
7197836SJohn.Forte@Sun.COM 		goto done;
7207836SJohn.Forte@Sun.COM 	}
7217836SJohn.Forte@Sun.COM 
7227836SJohn.Forte@Sun.COM 	/* copy lu nbr back to caller's view entry on success */
7237836SJohn.Forte@Sun.COM 	viewEntry->veIndex = ioctlViewEntry.ve_ndx;
7247836SJohn.Forte@Sun.COM 	if (ioctlViewEntry.ve_lu_number_valid) {
7257836SJohn.Forte@Sun.COM 		bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
7267836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
7277836SJohn.Forte@Sun.COM 	}
7287836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
7297836SJohn.Forte@Sun.COM 
7307836SJohn.Forte@Sun.COM done:
7317836SJohn.Forte@Sun.COM 	return (ret);
7327836SJohn.Forte@Sun.COM }
7337836SJohn.Forte@Sun.COM 
7347836SJohn.Forte@Sun.COM /*
7357836SJohn.Forte@Sun.COM  * stmfAddViewEntry
7367836SJohn.Forte@Sun.COM  *
7377836SJohn.Forte@Sun.COM  * Purpose: Adds a view entry to a logical unit
7387836SJohn.Forte@Sun.COM  *
7397836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to which the view entry is added
7407836SJohn.Forte@Sun.COM  * viewEntry - view entry structure to add
7417836SJohn.Forte@Sun.COM  */
7427836SJohn.Forte@Sun.COM int
7437836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
7447836SJohn.Forte@Sun.COM {
7457836SJohn.Forte@Sun.COM 	int ret;
7467836SJohn.Forte@Sun.COM 	int fd;
7477836SJohn.Forte@Sun.COM 	stmfViewEntry iViewEntry;
7487836SJohn.Forte@Sun.COM 
7497836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntry == NULL) {
7507836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
7517836SJohn.Forte@Sun.COM 	}
7527836SJohn.Forte@Sun.COM 
7537836SJohn.Forte@Sun.COM 	/* initialize and set internal view entry */
7547836SJohn.Forte@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
7557836SJohn.Forte@Sun.COM 
7567836SJohn.Forte@Sun.COM 	if (!viewEntry->allHosts) {
7577836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
7587836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.hostGroup));
7597836SJohn.Forte@Sun.COM 	} else {
7607836SJohn.Forte@Sun.COM 		iViewEntry.allHosts = B_TRUE;
7617836SJohn.Forte@Sun.COM 	}
7627836SJohn.Forte@Sun.COM 
7637836SJohn.Forte@Sun.COM 	if (!viewEntry->allTargets) {
7647836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
7657836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.targetGroup));
7667836SJohn.Forte@Sun.COM 	} else {
7677836SJohn.Forte@Sun.COM 		iViewEntry.allTargets = B_TRUE;
7687836SJohn.Forte@Sun.COM 	}
7697836SJohn.Forte@Sun.COM 
7707836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
7717836SJohn.Forte@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
7727836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
7737836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
7747836SJohn.Forte@Sun.COM 	}
7757836SJohn.Forte@Sun.COM 
7767836SJohn.Forte@Sun.COM 	/*
7777836SJohn.Forte@Sun.COM 	 * set users return view entry index valid flag to false
7787836SJohn.Forte@Sun.COM 	 * in case of failure
7797836SJohn.Forte@Sun.COM 	 */
7807836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
7817836SJohn.Forte@Sun.COM 
7827836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
7837836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
7847836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
7857836SJohn.Forte@Sun.COM 	}
7867836SJohn.Forte@Sun.COM 
7877836SJohn.Forte@Sun.COM 	/* call init */
7887836SJohn.Forte@Sun.COM 	ret = initializeConfig();
7897836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
7907836SJohn.Forte@Sun.COM 		return (ret);
7917836SJohn.Forte@Sun.COM 	}
7927836SJohn.Forte@Sun.COM 
7937836SJohn.Forte@Sun.COM 	/*
7947836SJohn.Forte@Sun.COM 	 * Open control node for stmf
7957836SJohn.Forte@Sun.COM 	 */
7967836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
7977836SJohn.Forte@Sun.COM 		return (ret);
7987836SJohn.Forte@Sun.COM 
7997836SJohn.Forte@Sun.COM 	/*
8007836SJohn.Forte@Sun.COM 	 * First add the view entry to the driver
8017836SJohn.Forte@Sun.COM 	 */
8027836SJohn.Forte@Sun.COM 	ret = addViewEntryIoctl(fd, lu, &iViewEntry);
8037836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
8047836SJohn.Forte@Sun.COM 		goto done;
8057836SJohn.Forte@Sun.COM 	}
8067836SJohn.Forte@Sun.COM 
8079585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
8089585STim.Szeto@Sun.COM 		goto done;
8099585STim.Szeto@Sun.COM 	}
8109585STim.Szeto@Sun.COM 
8117836SJohn.Forte@Sun.COM 	/*
8127836SJohn.Forte@Sun.COM 	 * If the add to driver was successful, add it to the persistent
8137836SJohn.Forte@Sun.COM 	 * store.
8147836SJohn.Forte@Sun.COM 	 */
8157836SJohn.Forte@Sun.COM 	ret = psAddViewEntry(lu, &iViewEntry);
8167836SJohn.Forte@Sun.COM 	switch (ret) {
8177836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
8187836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
8197836SJohn.Forte@Sun.COM 			break;
8207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
8217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
8227836SJohn.Forte@Sun.COM 			break;
8237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
8247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
8257836SJohn.Forte@Sun.COM 			break;
8267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
8277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
8287836SJohn.Forte@Sun.COM 			break;
8297836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
8307836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
8317836SJohn.Forte@Sun.COM 			break;
8327836SJohn.Forte@Sun.COM 		default:
8337836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
8347836SJohn.Forte@Sun.COM 			    "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
8357836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
8367836SJohn.Forte@Sun.COM 			break;
8377836SJohn.Forte@Sun.COM 	}
8387836SJohn.Forte@Sun.COM 
8397836SJohn.Forte@Sun.COM done:
8407836SJohn.Forte@Sun.COM 	(void) close(fd);
8417836SJohn.Forte@Sun.COM 
8427836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
8437836SJohn.Forte@Sun.COM 		/* set caller's view entry on success */
8447836SJohn.Forte@Sun.COM 		viewEntry->veIndexValid = iViewEntry.veIndexValid;
8457836SJohn.Forte@Sun.COM 		viewEntry->veIndex = iViewEntry.veIndex;
8467836SJohn.Forte@Sun.COM 		viewEntry->luNbrValid = B_TRUE;
8477836SJohn.Forte@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
8487836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
8497836SJohn.Forte@Sun.COM 	}
8507836SJohn.Forte@Sun.COM 	return (ret);
8517836SJohn.Forte@Sun.COM }
8527836SJohn.Forte@Sun.COM 
8537836SJohn.Forte@Sun.COM /*
8547836SJohn.Forte@Sun.COM  * stmfClearProviderData
8557836SJohn.Forte@Sun.COM  *
8567836SJohn.Forte@Sun.COM  * Purpose: delete all provider data for specified provider
8577836SJohn.Forte@Sun.COM  *
8587836SJohn.Forte@Sun.COM  * providerName - name of provider for which data should be deleted
8597836SJohn.Forte@Sun.COM  */
8607836SJohn.Forte@Sun.COM int
8617836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType)
8627836SJohn.Forte@Sun.COM {
8637836SJohn.Forte@Sun.COM 	int ret;
8647836SJohn.Forte@Sun.COM 	int fd;
8657836SJohn.Forte@Sun.COM 	int ioctlRet;
8667836SJohn.Forte@Sun.COM 	int savedErrno;
8677836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
8687836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t ppi;
8697836SJohn.Forte@Sun.COM 
8707836SJohn.Forte@Sun.COM 	/* call init */
8717836SJohn.Forte@Sun.COM 	ret = initializeConfig();
8727836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
8737836SJohn.Forte@Sun.COM 		return (ret);
8747836SJohn.Forte@Sun.COM 	}
8757836SJohn.Forte@Sun.COM 
8767836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
8777836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8787836SJohn.Forte@Sun.COM 	}
8797836SJohn.Forte@Sun.COM 
8807836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
8817836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
8827836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8837836SJohn.Forte@Sun.COM 	}
8847836SJohn.Forte@Sun.COM 
8857836SJohn.Forte@Sun.COM 	/*
8867836SJohn.Forte@Sun.COM 	 * Open control node for stmf
8877836SJohn.Forte@Sun.COM 	 */
8887836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
8897836SJohn.Forte@Sun.COM 		return (ret);
8907836SJohn.Forte@Sun.COM 
8917836SJohn.Forte@Sun.COM 	bzero(&ppi, sizeof (ppi));
8927836SJohn.Forte@Sun.COM 
8937836SJohn.Forte@Sun.COM 	(void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
8947836SJohn.Forte@Sun.COM 
8957836SJohn.Forte@Sun.COM 	switch (providerType) {
8967836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
8977836SJohn.Forte@Sun.COM 			ppi.ppi_lu_provider = 1;
8987836SJohn.Forte@Sun.COM 			break;
8997836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
9007836SJohn.Forte@Sun.COM 			ppi.ppi_port_provider = 1;
9017836SJohn.Forte@Sun.COM 			break;
9027836SJohn.Forte@Sun.COM 		default:
9037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
9047836SJohn.Forte@Sun.COM 			goto done;
9057836SJohn.Forte@Sun.COM 	}
9067836SJohn.Forte@Sun.COM 
9077836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
9087836SJohn.Forte@Sun.COM 
9097836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
9107836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
9117836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
9127836SJohn.Forte@Sun.COM 
9137836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
9147836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
9157836SJohn.Forte@Sun.COM 		savedErrno = errno;
9167836SJohn.Forte@Sun.COM 		switch (savedErrno) {
9177836SJohn.Forte@Sun.COM 			case EBUSY:
9187836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
9197836SJohn.Forte@Sun.COM 				break;
9209585STim.Szeto@Sun.COM 			case EPERM:
9217836SJohn.Forte@Sun.COM 			case EACCES:
9227836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
9237836SJohn.Forte@Sun.COM 				break;
9247836SJohn.Forte@Sun.COM 			default:
9257836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
9267836SJohn.Forte@Sun.COM 				    "stmfClearProviderData:ioctl error(%d)",
9277836SJohn.Forte@Sun.COM 				    ioctlRet);
9287836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
9297836SJohn.Forte@Sun.COM 				break;
9307836SJohn.Forte@Sun.COM 		}
9317836SJohn.Forte@Sun.COM 		if (savedErrno != ENOENT) {
9327836SJohn.Forte@Sun.COM 			goto done;
9337836SJohn.Forte@Sun.COM 		}
9347836SJohn.Forte@Sun.COM 	}
9357836SJohn.Forte@Sun.COM 
9369585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
9379585STim.Szeto@Sun.COM 		goto done;
9389585STim.Szeto@Sun.COM 	}
9399585STim.Szeto@Sun.COM 
9407836SJohn.Forte@Sun.COM 	ret = psClearProviderData(providerName, providerType);
9417836SJohn.Forte@Sun.COM 	switch (ret) {
9427836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
9437836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
9447836SJohn.Forte@Sun.COM 			break;
9457836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
9467836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
9477836SJohn.Forte@Sun.COM 			break;
9487836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
9497836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
9507836SJohn.Forte@Sun.COM 			break;
9517836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
9527836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
9537836SJohn.Forte@Sun.COM 			break;
9547836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
9557836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
9567836SJohn.Forte@Sun.COM 			break;
9577836SJohn.Forte@Sun.COM 		default:
9587836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
9597836SJohn.Forte@Sun.COM 			    "stmfClearProviderData:psClearProviderData"
9607836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
9617836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
9627836SJohn.Forte@Sun.COM 			break;
9637836SJohn.Forte@Sun.COM 	}
9647836SJohn.Forte@Sun.COM 
9657836SJohn.Forte@Sun.COM done:
9667836SJohn.Forte@Sun.COM 	(void) close(fd);
9677836SJohn.Forte@Sun.COM 	return (ret);
9687836SJohn.Forte@Sun.COM }
9697836SJohn.Forte@Sun.COM 
9707836SJohn.Forte@Sun.COM /*
9717836SJohn.Forte@Sun.COM  * stmfCreateHostGroup
9727836SJohn.Forte@Sun.COM  *
9737836SJohn.Forte@Sun.COM  * Purpose: Create a new initiator group
9747836SJohn.Forte@Sun.COM  *
9757836SJohn.Forte@Sun.COM  * hostGroupName - name of host group to create
9767836SJohn.Forte@Sun.COM  */
9777836SJohn.Forte@Sun.COM int
9787836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName)
9797836SJohn.Forte@Sun.COM {
9807836SJohn.Forte@Sun.COM 	int ret;
9817836SJohn.Forte@Sun.COM 	int fd;
9827836SJohn.Forte@Sun.COM 
9837836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
9847836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
9857836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
9867836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
9877836SJohn.Forte@Sun.COM 	}
9887836SJohn.Forte@Sun.COM 
9897836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
9907836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
9917836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
9927836SJohn.Forte@Sun.COM 	}
9937836SJohn.Forte@Sun.COM 
9947836SJohn.Forte@Sun.COM 	/* call init */
9957836SJohn.Forte@Sun.COM 	ret = initializeConfig();
9967836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
9977836SJohn.Forte@Sun.COM 		return (ret);
9987836SJohn.Forte@Sun.COM 	}
9997836SJohn.Forte@Sun.COM 
10007836SJohn.Forte@Sun.COM 	/*
10017836SJohn.Forte@Sun.COM 	 * Open control node for stmf
10027836SJohn.Forte@Sun.COM 	 */
10037836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
10047836SJohn.Forte@Sun.COM 		return (ret);
10057836SJohn.Forte@Sun.COM 
10067836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
10077836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
10087836SJohn.Forte@Sun.COM 		goto done;
10097836SJohn.Forte@Sun.COM 	}
10107836SJohn.Forte@Sun.COM 
10119585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
10129585STim.Szeto@Sun.COM 		goto done;
10139585STim.Szeto@Sun.COM 	}
10149585STim.Szeto@Sun.COM 
10157836SJohn.Forte@Sun.COM 	ret = psCreateHostGroup((char *)hostGroupName);
10167836SJohn.Forte@Sun.COM 	switch (ret) {
10177836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
10187836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
10197836SJohn.Forte@Sun.COM 			break;
10207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
10217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
10227836SJohn.Forte@Sun.COM 			break;
10237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
10247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
10257836SJohn.Forte@Sun.COM 			break;
10267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
10277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
10287836SJohn.Forte@Sun.COM 			break;
10297836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
10307836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
10317836SJohn.Forte@Sun.COM 			break;
10327836SJohn.Forte@Sun.COM 		default:
10337836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
10347836SJohn.Forte@Sun.COM 			    "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
10357836SJohn.Forte@Sun.COM 			    ret);
10367836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
10377836SJohn.Forte@Sun.COM 			break;
10387836SJohn.Forte@Sun.COM 	}
10397836SJohn.Forte@Sun.COM 
10407836SJohn.Forte@Sun.COM done:
10417836SJohn.Forte@Sun.COM 	(void) close(fd);
10427836SJohn.Forte@Sun.COM 	return (ret);
10437836SJohn.Forte@Sun.COM }
10447836SJohn.Forte@Sun.COM 
10457836SJohn.Forte@Sun.COM /*
10469585STim.Szeto@Sun.COM  * stmfCreateLu
10479585STim.Szeto@Sun.COM  *
10489585STim.Szeto@Sun.COM  * Purpose: Create a logical unit
10499585STim.Szeto@Sun.COM  *
10509585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
10519585STim.Szeto@Sun.COM  *
10529585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
10539585STim.Szeto@Sun.COM  *	    unit
10549585STim.Szeto@Sun.COM  */
10559585STim.Szeto@Sun.COM int
10569585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid)
10579585STim.Szeto@Sun.COM {
10589585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10599585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
10609585STim.Szeto@Sun.COM 
10619585STim.Szeto@Sun.COM 	if (hdl == NULL) {
10629585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10639585STim.Szeto@Sun.COM 	}
10649585STim.Szeto@Sun.COM 
10659585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
10669585STim.Szeto@Sun.COM 		ret = createDiskLu((diskResource *)luPropsHdl->resource,
10679585STim.Szeto@Sun.COM 		    luGuid);
10689585STim.Szeto@Sun.COM 	} else {
10699585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10709585STim.Szeto@Sun.COM 	}
10719585STim.Szeto@Sun.COM 
10729585STim.Szeto@Sun.COM 	return (ret);
10739585STim.Szeto@Sun.COM }
10749585STim.Szeto@Sun.COM 
10759585STim.Szeto@Sun.COM /*
10769585STim.Szeto@Sun.COM  * stmfCreateLuResource
10779585STim.Szeto@Sun.COM  *
10789585STim.Szeto@Sun.COM  * Purpose: Create resource handle for a logical unit
10799585STim.Szeto@Sun.COM  *
10809585STim.Szeto@Sun.COM  * dType - Type of logical unit resource to create
10819585STim.Szeto@Sun.COM  *	   Can be: STMF_DISK
10829585STim.Szeto@Sun.COM  *
10839585STim.Szeto@Sun.COM  * hdl - pointer to luResource
10849585STim.Szeto@Sun.COM  */
10859585STim.Szeto@Sun.COM int
10869585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl)
10879585STim.Szeto@Sun.COM {
10889585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10899585STim.Szeto@Sun.COM 
10909585STim.Szeto@Sun.COM 	if (dType != STMF_DISK || hdl == NULL) {
10919585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10929585STim.Szeto@Sun.COM 	}
10939585STim.Szeto@Sun.COM 
10949585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
10959585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
10969585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
10979585STim.Szeto@Sun.COM 	}
10989585STim.Szeto@Sun.COM 
10999585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
11009585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
11019585STim.Szeto@Sun.COM 		free(*hdl);
11029585STim.Szeto@Sun.COM 		return (ret);
11039585STim.Szeto@Sun.COM 	}
11049585STim.Szeto@Sun.COM 
11059585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
11069585STim.Szeto@Sun.COM }
11079585STim.Szeto@Sun.COM 
11089585STim.Szeto@Sun.COM /*
11099585STim.Szeto@Sun.COM  * Creates a disk logical unit
11109585STim.Szeto@Sun.COM  *
11119585STim.Szeto@Sun.COM  * disk - pointer to diskResource structure that represents the properties
11129585STim.Szeto@Sun.COM  *        for the disk logical unit to be created.
11139585STim.Szeto@Sun.COM  */
11149585STim.Szeto@Sun.COM static int
11159585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid)
11169585STim.Szeto@Sun.COM {
11179585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
11189585STim.Szeto@Sun.COM 	int dataFileNameLen = 0;
11199585STim.Szeto@Sun.COM 	int metaFileNameLen = 0;
11209585STim.Szeto@Sun.COM 	int serialNumLen = 0;
11219585STim.Szeto@Sun.COM 	int luAliasLen = 0;
112210113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
11239585STim.Szeto@Sun.COM 	int sluBufSize = 0;
11249585STim.Szeto@Sun.COM 	int bufOffset = 0;
11259585STim.Szeto@Sun.COM 	int fd = 0;
11269585STim.Szeto@Sun.COM 	int ioctlRet;
11279585STim.Szeto@Sun.COM 	int savedErrno;
11289585STim.Szeto@Sun.COM 	stmfGuid guid;
11299585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
11309585STim.Szeto@Sun.COM 
11319585STim.Szeto@Sun.COM 	sbd_create_and_reg_lu_t *sbdLu = NULL;
11329585STim.Szeto@Sun.COM 
11339585STim.Szeto@Sun.COM 	/*
11349585STim.Szeto@Sun.COM 	 * Open control node for sbd
11359585STim.Szeto@Sun.COM 	 */
11369585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
11379585STim.Szeto@Sun.COM 		return (ret);
11389585STim.Szeto@Sun.COM 
11399585STim.Szeto@Sun.COM 	/* data file name must be specified */
11409585STim.Szeto@Sun.COM 	if (disk->luDataFileNameValid) {
11419585STim.Szeto@Sun.COM 		dataFileNameLen = strlen(disk->luDataFileName);
11429585STim.Szeto@Sun.COM 	} else {
11439585STim.Szeto@Sun.COM 		(void) close(fd);
11449585STim.Szeto@Sun.COM 		return (STMF_ERROR_MISSING_PROP_VAL);
11459585STim.Szeto@Sun.COM 	}
11469585STim.Szeto@Sun.COM 
11479585STim.Szeto@Sun.COM 	sluBufSize += dataFileNameLen + 1;
11489585STim.Szeto@Sun.COM 
11499585STim.Szeto@Sun.COM 	if (disk->luMetaFileNameValid) {
11509585STim.Szeto@Sun.COM 		metaFileNameLen = strlen(disk->luMetaFileName);
11519585STim.Szeto@Sun.COM 		sluBufSize += metaFileNameLen + 1;
11529585STim.Szeto@Sun.COM 	}
11539585STim.Szeto@Sun.COM 
11549585STim.Szeto@Sun.COM 	serialNumLen = strlen(disk->serialNum);
11559585STim.Szeto@Sun.COM 	sluBufSize += serialNumLen;
11569585STim.Szeto@Sun.COM 
11579585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
11589585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
11599585STim.Szeto@Sun.COM 		sluBufSize += luAliasLen + 1;
11609585STim.Szeto@Sun.COM 	}
11619585STim.Szeto@Sun.COM 
116210113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
116310113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
116410113SNattuvetty.Bhavyan@Sun.COM 		sluBufSize += luMgmtUrlLen + 1;
116510113SNattuvetty.Bhavyan@Sun.COM 	}
116610113SNattuvetty.Bhavyan@Sun.COM 
11679585STim.Szeto@Sun.COM 	/*
11689585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
11699585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
11709585STim.Szeto@Sun.COM 	 */
11719585STim.Szeto@Sun.COM 	sbdLu = (sbd_create_and_reg_lu_t *)calloc(1,
11729585STim.Szeto@Sun.COM 	    sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8);
11739585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
11749585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
11759585STim.Szeto@Sun.COM 	}
11769585STim.Szeto@Sun.COM 
11779585STim.Szeto@Sun.COM 	sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) +
11789585STim.Szeto@Sun.COM 	    sluBufSize - 8;
11799585STim.Szeto@Sun.COM 
11809585STim.Szeto@Sun.COM 	if (metaFileNameLen) {
11819585STim.Szeto@Sun.COM 		sbdLu->slu_meta_fname_valid = 1;
11829585STim.Szeto@Sun.COM 		sbdLu->slu_meta_fname_off = bufOffset;
11839585STim.Szeto@Sun.COM 		bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]),
11849585STim.Szeto@Sun.COM 		    metaFileNameLen + 1);
11859585STim.Szeto@Sun.COM 		bufOffset += metaFileNameLen + 1;
11869585STim.Szeto@Sun.COM 	}
11879585STim.Szeto@Sun.COM 
11889585STim.Szeto@Sun.COM 	bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]),
11899585STim.Szeto@Sun.COM 	    dataFileNameLen + 1);
11909585STim.Szeto@Sun.COM 	sbdLu->slu_data_fname_off = bufOffset;
11919585STim.Szeto@Sun.COM 	bufOffset += dataFileNameLen + 1;
11929585STim.Szeto@Sun.COM 
11939585STim.Szeto@Sun.COM 	/* currently, serial # is not passed null terminated to the driver */
11949585STim.Szeto@Sun.COM 	if (disk->serialNumValid) {
11959585STim.Szeto@Sun.COM 		sbdLu->slu_serial_valid = 1;
11969585STim.Szeto@Sun.COM 		sbdLu->slu_serial_off = bufOffset;
11979585STim.Szeto@Sun.COM 		sbdLu->slu_serial_size = serialNumLen;
11989585STim.Szeto@Sun.COM 		bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]),
11999585STim.Szeto@Sun.COM 		    serialNumLen);
12009585STim.Szeto@Sun.COM 		bufOffset += serialNumLen;
12019585STim.Szeto@Sun.COM 	}
12029585STim.Szeto@Sun.COM 
12039585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
12049585STim.Szeto@Sun.COM 		sbdLu->slu_alias_valid = 1;
12059585STim.Szeto@Sun.COM 		sbdLu->slu_alias_off = bufOffset;
12069585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]),
12079585STim.Szeto@Sun.COM 		    luAliasLen + 1);
12089585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
12099585STim.Szeto@Sun.COM 	}
12109585STim.Szeto@Sun.COM 
121110113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
121210113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->slu_mgmt_url_valid = 1;
121310113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->slu_mgmt_url_off = bufOffset;
121410113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]),
121510113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
121610113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
121710113SNattuvetty.Bhavyan@Sun.COM 	}
121810113SNattuvetty.Bhavyan@Sun.COM 
12199585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
12209585STim.Szeto@Sun.COM 		sbdLu->slu_lu_size_valid = 1;
12219585STim.Szeto@Sun.COM 		sbdLu->slu_lu_size = disk->luSize;
12229585STim.Szeto@Sun.COM 	}
12239585STim.Szeto@Sun.COM 
12249585STim.Szeto@Sun.COM 	if (disk->luGuidValid) {
12259585STim.Szeto@Sun.COM 		sbdLu->slu_guid_valid = 1;
12269585STim.Szeto@Sun.COM 		bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid));
12279585STim.Szeto@Sun.COM 	}
12289585STim.Szeto@Sun.COM 
12299585STim.Szeto@Sun.COM 	if (disk->vidValid) {
12309585STim.Szeto@Sun.COM 		sbdLu->slu_vid_valid = 1;
12319585STim.Szeto@Sun.COM 		bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid));
12329585STim.Szeto@Sun.COM 	}
12339585STim.Szeto@Sun.COM 
12349585STim.Szeto@Sun.COM 	if (disk->pidValid) {
12359585STim.Szeto@Sun.COM 		sbdLu->slu_pid_valid = 1;
12369585STim.Szeto@Sun.COM 		bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid));
12379585STim.Szeto@Sun.COM 	}
12389585STim.Szeto@Sun.COM 
12399585STim.Szeto@Sun.COM 	if (disk->revValid) {
12409585STim.Szeto@Sun.COM 		sbdLu->slu_rev_valid = 1;
12419585STim.Szeto@Sun.COM 		bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev));
12429585STim.Szeto@Sun.COM 	}
12439585STim.Szeto@Sun.COM 
12449585STim.Szeto@Sun.COM 	if (disk->companyIdValid) {
12459585STim.Szeto@Sun.COM 		sbdLu->slu_company_id_valid = 1;
12469585STim.Szeto@Sun.COM 		sbdLu->slu_company_id = disk->companyId;
12479585STim.Szeto@Sun.COM 	}
12489585STim.Szeto@Sun.COM 
124910765SJohn.Forte@Sun.COM 	if (disk->hostIdValid) {
125010765SJohn.Forte@Sun.COM 		sbdLu->slu_host_id_valid = 1;
125110765SJohn.Forte@Sun.COM 		sbdLu->slu_host_id = disk->hostId;
125210765SJohn.Forte@Sun.COM 	}
125310765SJohn.Forte@Sun.COM 
12549585STim.Szeto@Sun.COM 	if (disk->blkSizeValid) {
12559585STim.Szeto@Sun.COM 		sbdLu->slu_blksize_valid = 1;
12569585STim.Szeto@Sun.COM 		sbdLu->slu_blksize = disk->blkSize;
12579585STim.Szeto@Sun.COM 	}
12589585STim.Szeto@Sun.COM 
12599585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
12609585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
12619585STim.Szeto@Sun.COM 			sbdLu->slu_write_protected = 1;
12629585STim.Szeto@Sun.COM 		}
12639585STim.Szeto@Sun.COM 	}
12649585STim.Szeto@Sun.COM 
12659585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
12669585STim.Szeto@Sun.COM 		sbdLu->slu_writeback_cache_disable_valid = 1;
12679585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
12689585STim.Szeto@Sun.COM 			sbdLu->slu_writeback_cache_disable = 1;
12699585STim.Szeto@Sun.COM 		}
12709585STim.Szeto@Sun.COM 	}
12719585STim.Szeto@Sun.COM 
12729585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
12739585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size;
12749585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
12759585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size;
12769585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
12779585STim.Szeto@Sun.COM 
12789585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl);
12799585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
12809585STim.Szeto@Sun.COM 		savedErrno = errno;
12819585STim.Szeto@Sun.COM 		switch (savedErrno) {
12829585STim.Szeto@Sun.COM 			case EBUSY:
12839585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
12849585STim.Szeto@Sun.COM 				break;
12859585STim.Szeto@Sun.COM 			case EPERM:
12869585STim.Szeto@Sun.COM 			case EACCES:
12879585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
12889585STim.Szeto@Sun.COM 				break;
12899585STim.Szeto@Sun.COM 			default:
12909585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
12919585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
12929585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
12939585STim.Szeto@Sun.COM 					"createDiskLu:ioctl "
12949585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
12959585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
12969585STim.Szeto@Sun.COM 				}
12979585STim.Szeto@Sun.COM 				break;
12989585STim.Szeto@Sun.COM 		}
12999585STim.Szeto@Sun.COM 	}
13009585STim.Szeto@Sun.COM 
13019585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
13029585STim.Szeto@Sun.COM 		goto done;
13039585STim.Szeto@Sun.COM 	}
13049585STim.Szeto@Sun.COM 
13059585STim.Szeto@Sun.COM 	/*
13069585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
13079585STim.Szeto@Sun.COM 	 * NULL
13089585STim.Szeto@Sun.COM 	 */
13099585STim.Szeto@Sun.COM 	if (createdGuid) {
13109585STim.Szeto@Sun.COM 		bcopy(sbdLu->slu_guid, createdGuid->guid,
13119585STim.Szeto@Sun.COM 		    sizeof (sbdLu->slu_guid));
13129585STim.Szeto@Sun.COM 	}
13139585STim.Szeto@Sun.COM 
13149585STim.Szeto@Sun.COM 	bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid));
13159585STim.Szeto@Sun.COM 	if (disk->luMetaFileNameValid) {
13169585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&guid, disk->luMetaFileName);
13179585STim.Szeto@Sun.COM 	} else {
13189585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&guid, disk->luDataFileName);
13199585STim.Szeto@Sun.COM 	}
13209585STim.Szeto@Sun.COM done:
13219585STim.Szeto@Sun.COM 	free(sbdLu);
13229585STim.Szeto@Sun.COM 	(void) close(fd);
13239585STim.Szeto@Sun.COM 	return (ret);
13249585STim.Szeto@Sun.COM }
13259585STim.Szeto@Sun.COM 
13269585STim.Szeto@Sun.COM 
13279585STim.Szeto@Sun.COM /*
13289585STim.Szeto@Sun.COM  * stmfImportLu
13299585STim.Szeto@Sun.COM  *
13309585STim.Szeto@Sun.COM  * Purpose: Import a previously created logical unit
13319585STim.Szeto@Sun.COM  *
13329585STim.Szeto@Sun.COM  * dType - Type of logical unit
13339585STim.Szeto@Sun.COM  *         Can be: STMF_DISK
13349585STim.Szeto@Sun.COM  *
13359585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the imported logical
13369585STim.Szeto@Sun.COM  *	    unit
13379585STim.Szeto@Sun.COM  *
13389585STim.Szeto@Sun.COM  * fname - A file name where the metadata resides
13399585STim.Szeto@Sun.COM  *
13409585STim.Szeto@Sun.COM  */
13419585STim.Szeto@Sun.COM int
13429585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid)
13439585STim.Szeto@Sun.COM {
13449585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
13459585STim.Szeto@Sun.COM 
13469585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
13479585STim.Szeto@Sun.COM 		ret = importDiskLu(fname, luGuid);
13489585STim.Szeto@Sun.COM 	} else {
13499585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13509585STim.Szeto@Sun.COM 	}
13519585STim.Szeto@Sun.COM 
13529585STim.Szeto@Sun.COM 	return (ret);
13539585STim.Szeto@Sun.COM }
13549585STim.Szeto@Sun.COM 
13559585STim.Szeto@Sun.COM /*
13569585STim.Szeto@Sun.COM  * importDiskLu
13579585STim.Szeto@Sun.COM  *
13589585STim.Szeto@Sun.COM  * filename - filename to import
13599585STim.Szeto@Sun.COM  * createdGuid - if not NULL, on success contains the imported guid
13609585STim.Szeto@Sun.COM  *
13619585STim.Szeto@Sun.COM  */
13629585STim.Szeto@Sun.COM static int
13639585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid)
13649585STim.Szeto@Sun.COM {
13659585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
13669585STim.Szeto@Sun.COM 	int fd = 0;
13679585STim.Szeto@Sun.COM 	int ioctlRet;
13689585STim.Szeto@Sun.COM 	int savedErrno;
13699585STim.Szeto@Sun.COM 	int metaFileNameLen;
13709585STim.Szeto@Sun.COM 	stmfGuid iGuid;
13719585STim.Szeto@Sun.COM 	int iluBufSize = 0;
13729585STim.Szeto@Sun.COM 	sbd_import_lu_t *sbdLu = NULL;
13739585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
13749585STim.Szeto@Sun.COM 
13759585STim.Szeto@Sun.COM 	if (fname == NULL) {
13769585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13779585STim.Szeto@Sun.COM 	}
13789585STim.Szeto@Sun.COM 
13799585STim.Szeto@Sun.COM 	/*
13809585STim.Szeto@Sun.COM 	 * Open control node for sbd
13819585STim.Szeto@Sun.COM 	 */
13829585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
13839585STim.Szeto@Sun.COM 		return (ret);
13849585STim.Szeto@Sun.COM 
13859585STim.Szeto@Sun.COM 	metaFileNameLen = strlen(fname);
13869585STim.Szeto@Sun.COM 	iluBufSize += metaFileNameLen + 1;
13879585STim.Szeto@Sun.COM 
13889585STim.Szeto@Sun.COM 	/*
13899585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
13909585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
13919585STim.Szeto@Sun.COM 	 */
13929585STim.Szeto@Sun.COM 	sbdLu = (sbd_import_lu_t *)calloc(1,
13939585STim.Szeto@Sun.COM 	    sizeof (sbd_import_lu_t) + iluBufSize - 8);
13949585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
13959585STim.Szeto@Sun.COM 		(void) close(fd);
13969585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
13979585STim.Szeto@Sun.COM 	}
13989585STim.Szeto@Sun.COM 
13999585STim.Szeto@Sun.COM 	/*
14009585STim.Szeto@Sun.COM 	 * Accept either a data file or meta data file.
14019585STim.Szeto@Sun.COM 	 * sbd will do the right thing here either way.
14029585STim.Szeto@Sun.COM 	 * i.e. if it's a data file, it assumes that the
14039585STim.Szeto@Sun.COM 	 * meta data is shared with the data.
14049585STim.Szeto@Sun.COM 	 */
14059585STim.Szeto@Sun.COM 	(void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen);
14069585STim.Szeto@Sun.COM 
14079585STim.Szeto@Sun.COM 	sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8;
14089585STim.Szeto@Sun.COM 
14099585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
14109585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size;
14119585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
14129585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size;
14139585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
14149585STim.Szeto@Sun.COM 
14159585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl);
14169585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
14179585STim.Szeto@Sun.COM 		savedErrno = errno;
14189585STim.Szeto@Sun.COM 		switch (savedErrno) {
14199585STim.Szeto@Sun.COM 			case EBUSY:
14209585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
14219585STim.Szeto@Sun.COM 				break;
14229585STim.Szeto@Sun.COM 			case EPERM:
14239585STim.Szeto@Sun.COM 			case EACCES:
14249585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
14259585STim.Szeto@Sun.COM 				break;
14269585STim.Szeto@Sun.COM 			default:
14279585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
14289585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
14299585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
14309585STim.Szeto@Sun.COM 					"importDiskLu:ioctl "
14319585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
14329585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
14339585STim.Szeto@Sun.COM 				}
14349585STim.Szeto@Sun.COM 				break;
14359585STim.Szeto@Sun.COM 		}
14369585STim.Szeto@Sun.COM 	}
14379585STim.Szeto@Sun.COM 
14389585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
14399585STim.Szeto@Sun.COM 		goto done;
14409585STim.Szeto@Sun.COM 	}
14419585STim.Szeto@Sun.COM 
14429585STim.Szeto@Sun.COM 	/*
14439585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
14449585STim.Szeto@Sun.COM 	 * NULL and add it to the persistent store for sbd
14459585STim.Szeto@Sun.COM 	 */
14469585STim.Szeto@Sun.COM 	if (createdGuid) {
14479585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
14489585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14499585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(createdGuid, fname);
14509585STim.Szeto@Sun.COM 	} else {
14519585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
14529585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14539585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&iGuid, fname);
14549585STim.Szeto@Sun.COM 	}
14559585STim.Szeto@Sun.COM done:
14569585STim.Szeto@Sun.COM 	free(sbdLu);
14579585STim.Szeto@Sun.COM 	(void) close(fd);
14589585STim.Szeto@Sun.COM 	return (ret);
14599585STim.Szeto@Sun.COM }
14609585STim.Szeto@Sun.COM 
14619585STim.Szeto@Sun.COM /*
14629585STim.Szeto@Sun.COM  * diskError
14639585STim.Szeto@Sun.COM  *
14649585STim.Szeto@Sun.COM  * Purpose: Translate sbd driver error
14659585STim.Szeto@Sun.COM  */
14669585STim.Szeto@Sun.COM static void
14679585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret)
14689585STim.Szeto@Sun.COM {
14699585STim.Szeto@Sun.COM 	switch (stmfError) {
14709585STim.Szeto@Sun.COM 		case SBD_RET_META_CREATION_FAILED:
14719585STim.Szeto@Sun.COM 		case SBD_RET_ZFS_META_CREATE_FAILED:
14729585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_CREATION;
14739585STim.Szeto@Sun.COM 			break;
14749585STim.Szeto@Sun.COM 		case SBD_RET_INVALID_BLKSIZE:
14759585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_INVALID_BLKSIZE;
14769585STim.Szeto@Sun.COM 			break;
14779585STim.Szeto@Sun.COM 		case SBD_RET_FILE_ALREADY_REGISTERED:
14789585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_IN_USE;
14799585STim.Szeto@Sun.COM 			break;
14809585STim.Szeto@Sun.COM 		case SBD_RET_GUID_ALREADY_REGISTERED:
14819585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_GUID_IN_USE;
14829585STim.Szeto@Sun.COM 			break;
14839585STim.Szeto@Sun.COM 		case SBD_RET_META_PATH_NOT_ABSOLUTE:
14849585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_LOOKUP_FAILED:
14859585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_OPEN_FAILED:
14869585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_GETATTR_FAILED:
14879585STim.Szeto@Sun.COM 		case SBD_RET_NO_META:
14889585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_FILE_NAME;
14899585STim.Szeto@Sun.COM 			break;
14909585STim.Szeto@Sun.COM 		case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
14919585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_LOOKUP_FAILED:
14929585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_OPEN_FAILED:
14939585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_GETATTR_FAILED:
14949585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_DATA_FILE_NAME;
14959585STim.Szeto@Sun.COM 			break;
14969585STim.Szeto@Sun.COM 		case SBD_RET_FILE_SIZE_ERROR:
14979585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_SIZE_INVALID;
14989585STim.Szeto@Sun.COM 			break;
14999585STim.Szeto@Sun.COM 		case SBD_RET_SIZE_OUT_OF_RANGE:
15009585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
15019585STim.Szeto@Sun.COM 			break;
15029585STim.Szeto@Sun.COM 		case SBD_RET_LU_BUSY:
15039585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_LU_BUSY;
15049585STim.Szeto@Sun.COM 			break;
15059585STim.Szeto@Sun.COM 		case SBD_RET_WRITE_CACHE_SET_FAILED:
15069585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_WRITE_CACHE_SET;
15079585STim.Szeto@Sun.COM 			break;
150810725SJohn.Forte@Sun.COM 		case SBD_RET_ACCESS_STATE_FAILED:
150910725SJohn.Forte@Sun.COM 			*ret = STMF_ERROR_ACCESS_STATE_SET;
151010725SJohn.Forte@Sun.COM 			break;
15119585STim.Szeto@Sun.COM 		default:
15129585STim.Szeto@Sun.COM 			*ret = STMF_STATUS_ERROR;
15139585STim.Szeto@Sun.COM 			break;
15149585STim.Szeto@Sun.COM 	}
15159585STim.Szeto@Sun.COM }
15169585STim.Szeto@Sun.COM 
15179585STim.Szeto@Sun.COM /*
15189585STim.Szeto@Sun.COM  * Creates a logical unit resource of type STMF_DISK.
15199585STim.Szeto@Sun.COM  *
15209585STim.Szeto@Sun.COM  * No defaults should be set here as all defaults are derived from the
15219585STim.Szeto@Sun.COM  * driver's default settings.
15229585STim.Szeto@Sun.COM  */
15239585STim.Szeto@Sun.COM static int
15249585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl)
15259585STim.Szeto@Sun.COM {
15269585STim.Szeto@Sun.COM 	hdl->type = STMF_DISK;
15279585STim.Szeto@Sun.COM 
15289585STim.Szeto@Sun.COM 	hdl->resource = calloc(1, sizeof (diskResource));
15299585STim.Szeto@Sun.COM 	if (hdl->resource == NULL) {
15309585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
15319585STim.Szeto@Sun.COM 	}
15329585STim.Szeto@Sun.COM 
15339585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
15349585STim.Szeto@Sun.COM }
15359585STim.Szeto@Sun.COM 
15369585STim.Szeto@Sun.COM /*
15379585STim.Szeto@Sun.COM  * stmfDeleteLu
15389585STim.Szeto@Sun.COM  *
15399585STim.Szeto@Sun.COM  * Purpose: Delete a logical unit
15409585STim.Szeto@Sun.COM  *
15419585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
15429585STim.Szeto@Sun.COM  *
15439585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
15449585STim.Szeto@Sun.COM  *	    unit
15459585STim.Szeto@Sun.COM  */
15469585STim.Szeto@Sun.COM int
15479585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid)
15489585STim.Szeto@Sun.COM {
15499585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15509585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
15519585STim.Szeto@Sun.COM 
15529585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
15539585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
15549585STim.Szeto@Sun.COM 	}
15559585STim.Szeto@Sun.COM 
15569585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
15579585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
15589585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
15599585STim.Szeto@Sun.COM 		return (ret);
15609585STim.Szeto@Sun.COM 	} else {
15619585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
15629585STim.Szeto@Sun.COM 			ret = deleteDiskLu(luGuid);
15639585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
15649585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
15659585STim.Szeto@Sun.COM 		} else {
15669585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
15679585STim.Szeto@Sun.COM 		}
15689585STim.Szeto@Sun.COM 	}
15699585STim.Szeto@Sun.COM 
15709585STim.Szeto@Sun.COM 	return (ret);
15719585STim.Szeto@Sun.COM }
15729585STim.Szeto@Sun.COM 
15739585STim.Szeto@Sun.COM static int
15749585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid)
15759585STim.Szeto@Sun.COM {
15769585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15779585STim.Szeto@Sun.COM 	int fd;
15789585STim.Szeto@Sun.COM 	int savedErrno;
15799585STim.Szeto@Sun.COM 	int ioctlRet;
15809585STim.Szeto@Sun.COM 	sbd_delete_lu_t deleteLu = {0};
15819585STim.Szeto@Sun.COM 
15829585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
15839585STim.Szeto@Sun.COM 
15849585STim.Szeto@Sun.COM 	/*
15859585STim.Szeto@Sun.COM 	 * Open control node for sbd
15869585STim.Szeto@Sun.COM 	 */
15879585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
15889585STim.Szeto@Sun.COM 		return (ret);
15899585STim.Szeto@Sun.COM 
15909585STim.Szeto@Sun.COM 	ret = removeGuidFromDiskStore(luGuid);
15919585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
15929585STim.Szeto@Sun.COM 		goto done;
15939585STim.Szeto@Sun.COM 	}
15949585STim.Szeto@Sun.COM 
15959585STim.Szeto@Sun.COM 	bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
15969585STim.Szeto@Sun.COM 	deleteLu.dlu_by_guid = 1;
15979585STim.Szeto@Sun.COM 
15989585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
15999585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
16009585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
16019585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
16029585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
16039585STim.Szeto@Sun.COM 		savedErrno = errno;
16049585STim.Szeto@Sun.COM 		switch (savedErrno) {
16059585STim.Szeto@Sun.COM 			case EBUSY:
16069585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
16079585STim.Szeto@Sun.COM 				break;
16089585STim.Szeto@Sun.COM 			case EPERM:
16099585STim.Szeto@Sun.COM 			case EACCES:
16109585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
16119585STim.Szeto@Sun.COM 				break;
16129585STim.Szeto@Sun.COM 			case ENOENT:
16139585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
16149585STim.Szeto@Sun.COM 				break;
16159585STim.Szeto@Sun.COM 			default:
16169585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
16179585STim.Szeto@Sun.COM 				    "deleteDiskLu:ioctl error(%d) (%d) (%d)",
16189585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
16199585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
16209585STim.Szeto@Sun.COM 				break;
16219585STim.Szeto@Sun.COM 		}
16229585STim.Szeto@Sun.COM 	}
16239585STim.Szeto@Sun.COM 
16249585STim.Szeto@Sun.COM done:
16259585STim.Szeto@Sun.COM 	(void) close(fd);
16269585STim.Szeto@Sun.COM 	return (ret);
16279585STim.Szeto@Sun.COM }
16289585STim.Szeto@Sun.COM 
16299585STim.Szeto@Sun.COM /*
163010725SJohn.Forte@Sun.COM  * stmfLuStandby
163110725SJohn.Forte@Sun.COM  *
163210725SJohn.Forte@Sun.COM  * Purpose: Sets access state to standby
163310725SJohn.Forte@Sun.COM  *
163410725SJohn.Forte@Sun.COM  * luGuid - guid of registered logical unit
163510725SJohn.Forte@Sun.COM  *
163610725SJohn.Forte@Sun.COM  */
163710725SJohn.Forte@Sun.COM int
163810725SJohn.Forte@Sun.COM stmfLuStandby(stmfGuid *luGuid)
163910725SJohn.Forte@Sun.COM {
164010725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
164110725SJohn.Forte@Sun.COM 	stmfLogicalUnitProperties luProps;
164210725SJohn.Forte@Sun.COM 
164310725SJohn.Forte@Sun.COM 	if (luGuid == NULL) {
164410725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
164510725SJohn.Forte@Sun.COM 	}
164610725SJohn.Forte@Sun.COM 
164710725SJohn.Forte@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
164810725SJohn.Forte@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
164910725SJohn.Forte@Sun.COM 	    != STMF_STATUS_SUCCESS) {
165010725SJohn.Forte@Sun.COM 		return (ret);
165110725SJohn.Forte@Sun.COM 	} else {
165210725SJohn.Forte@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
165310725SJohn.Forte@Sun.COM 			ret = setDiskStandby(luGuid);
165410725SJohn.Forte@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
165510725SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
165610725SJohn.Forte@Sun.COM 		} else {
165710725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
165810725SJohn.Forte@Sun.COM 		}
165910725SJohn.Forte@Sun.COM 	}
166010725SJohn.Forte@Sun.COM 
166110725SJohn.Forte@Sun.COM 	return (ret);
166210725SJohn.Forte@Sun.COM }
166310725SJohn.Forte@Sun.COM 
166410725SJohn.Forte@Sun.COM static int
166510725SJohn.Forte@Sun.COM setDiskStandby(stmfGuid *luGuid)
166610725SJohn.Forte@Sun.COM {
166710725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
166810725SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
166910725SJohn.Forte@Sun.COM 	sbd_set_lu_standby_t sbdLu = {0};
167010725SJohn.Forte@Sun.COM 	int ioctlRet;
167110725SJohn.Forte@Sun.COM 	int savedErrno;
167210725SJohn.Forte@Sun.COM 	int fd = 0;
167310725SJohn.Forte@Sun.COM 
167410725SJohn.Forte@Sun.COM 	/*
167510725SJohn.Forte@Sun.COM 	 * Open control node for sbd
167610725SJohn.Forte@Sun.COM 	 */
167710725SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
167810725SJohn.Forte@Sun.COM 		return (ret);
167910725SJohn.Forte@Sun.COM 
168010725SJohn.Forte@Sun.COM 	bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid));
168110725SJohn.Forte@Sun.COM 
168210725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
168310725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t);
168410725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu;
168510725SJohn.Forte@Sun.COM 
168610725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl);
168710725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
168810725SJohn.Forte@Sun.COM 		savedErrno = errno;
168910725SJohn.Forte@Sun.COM 		switch (savedErrno) {
169010725SJohn.Forte@Sun.COM 			case EBUSY:
169110725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
169210725SJohn.Forte@Sun.COM 				break;
169310725SJohn.Forte@Sun.COM 			case EPERM:
169410725SJohn.Forte@Sun.COM 			case EACCES:
169510725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
169610725SJohn.Forte@Sun.COM 				break;
169710725SJohn.Forte@Sun.COM 			default:
169810725SJohn.Forte@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
169910725SJohn.Forte@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
170010725SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
170110725SJohn.Forte@Sun.COM 					"setDiskStandby:ioctl "
170210725SJohn.Forte@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
170310725SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
170410725SJohn.Forte@Sun.COM 				}
170510725SJohn.Forte@Sun.COM 				break;
170610725SJohn.Forte@Sun.COM 		}
170710725SJohn.Forte@Sun.COM 	}
170810725SJohn.Forte@Sun.COM 	return (ret);
170910725SJohn.Forte@Sun.COM }
171010725SJohn.Forte@Sun.COM 
171110725SJohn.Forte@Sun.COM /*
17129585STim.Szeto@Sun.COM  * stmfModifyLu
17139585STim.Szeto@Sun.COM  *
17149585STim.Szeto@Sun.COM  * Purpose: Modify properties of a logical unit
17159585STim.Szeto@Sun.COM  *
17169585STim.Szeto@Sun.COM  * luGuid - guid of registered logical unit
17179585STim.Szeto@Sun.COM  * prop - property to modify
17189585STim.Szeto@Sun.COM  * propVal - property value to set
17199585STim.Szeto@Sun.COM  *
17209585STim.Szeto@Sun.COM  */
17219585STim.Szeto@Sun.COM int
17229585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
17239585STim.Szeto@Sun.COM {
17249585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17259585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
17269585STim.Szeto@Sun.COM 
17279585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
17289585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17299585STim.Szeto@Sun.COM 	}
17309585STim.Szeto@Sun.COM 
17319585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
17329585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
17339585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
17349585STim.Szeto@Sun.COM 		return (ret);
17359585STim.Szeto@Sun.COM 	} else {
17369585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
17379585STim.Szeto@Sun.COM 			ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
17389585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
17399585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
17409585STim.Szeto@Sun.COM 		} else {
17419585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
17429585STim.Szeto@Sun.COM 		}
17439585STim.Szeto@Sun.COM 	}
17449585STim.Szeto@Sun.COM 
17459585STim.Szeto@Sun.COM 	return (ret);
17469585STim.Szeto@Sun.COM }
17479585STim.Szeto@Sun.COM 
17489585STim.Szeto@Sun.COM /*
17499585STim.Szeto@Sun.COM  * stmfModifyLuByFname
17509585STim.Szeto@Sun.COM  *
17519585STim.Szeto@Sun.COM  * Purpose: Modify a device by filename. Device does not need to be registered.
17529585STim.Szeto@Sun.COM  *
17539585STim.Szeto@Sun.COM  * dType - type of device to modify
17549585STim.Szeto@Sun.COM  *         STMF_DISK
17559585STim.Szeto@Sun.COM  *
17569585STim.Szeto@Sun.COM  * fname - filename or meta filename
17579585STim.Szeto@Sun.COM  * prop - valid property identifier
17589585STim.Szeto@Sun.COM  * propVal - property value
17599585STim.Szeto@Sun.COM  *
17609585STim.Szeto@Sun.COM  */
17619585STim.Szeto@Sun.COM int
17629585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
17639585STim.Szeto@Sun.COM     const char *propVal)
17649585STim.Szeto@Sun.COM {
17659585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17669585STim.Szeto@Sun.COM 	if (fname == NULL) {
17679585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17689585STim.Szeto@Sun.COM 	}
17699585STim.Szeto@Sun.COM 
17709585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
17719585STim.Szeto@Sun.COM 		ret = modifyDiskLuProp(NULL, fname, prop, propVal);
17729585STim.Szeto@Sun.COM 	} else {
17739585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17749585STim.Szeto@Sun.COM 	}
17759585STim.Szeto@Sun.COM 
17769585STim.Szeto@Sun.COM 	return (ret);
17779585STim.Szeto@Sun.COM }
17789585STim.Szeto@Sun.COM 
17799585STim.Szeto@Sun.COM static int
17809585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
17819585STim.Szeto@Sun.COM     const char *propVal)
17829585STim.Szeto@Sun.COM {
17839585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17849585STim.Szeto@Sun.COM 	luResource hdl = NULL;
17859585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl;
17869585STim.Szeto@Sun.COM 
17879585STim.Szeto@Sun.COM 	ret = stmfCreateLuResource(STMF_DISK, &hdl);
17889585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17899585STim.Szeto@Sun.COM 		return (ret);
17909585STim.Szeto@Sun.COM 	}
17919585STim.Szeto@Sun.COM 	ret = validateModifyDiskProp(prop);
17929585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17939585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
17949585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_PROP);
17959585STim.Szeto@Sun.COM 	}
17969585STim.Szeto@Sun.COM 	ret = stmfSetLuProp(hdl, prop, propVal);
17979585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17989585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
17999585STim.Szeto@Sun.COM 		return (ret);
18009585STim.Szeto@Sun.COM 	}
18019585STim.Szeto@Sun.COM 	luPropsHdl = hdl;
18029585STim.Szeto@Sun.COM 	ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
18039585STim.Szeto@Sun.COM 	(void) stmfFreeLuResource(hdl);
18049585STim.Szeto@Sun.COM 	return (ret);
18059585STim.Szeto@Sun.COM }
18069585STim.Szeto@Sun.COM 
18079585STim.Szeto@Sun.COM static int
18089585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop)
18099585STim.Szeto@Sun.COM {
18109585STim.Szeto@Sun.COM 	switch (prop) {
18119585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
18129585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
181310113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
18149585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
18159585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
18169585STim.Szeto@Sun.COM 			return (STMF_STATUS_SUCCESS);
18179585STim.Szeto@Sun.COM 			break;
18189585STim.Szeto@Sun.COM 		default:
18199585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
18209585STim.Szeto@Sun.COM 			break;
18219585STim.Szeto@Sun.COM 	}
18229585STim.Szeto@Sun.COM }
18239585STim.Szeto@Sun.COM 
18249585STim.Szeto@Sun.COM static int
18259585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
18269585STim.Szeto@Sun.COM {
18279585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
18289585STim.Szeto@Sun.COM 	int luAliasLen = 0;
182910113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
18309585STim.Szeto@Sun.COM 	int mluBufSize = 0;
18319585STim.Szeto@Sun.COM 	int bufOffset = 0;
18329585STim.Szeto@Sun.COM 	int fd = 0;
18339585STim.Szeto@Sun.COM 	int ioctlRet;
18349585STim.Szeto@Sun.COM 	int savedErrno;
18359585STim.Szeto@Sun.COM 	int fnameSize = 0;
18369585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
18379585STim.Szeto@Sun.COM 
18389585STim.Szeto@Sun.COM 	sbd_modify_lu_t *sbdLu = NULL;
18399585STim.Szeto@Sun.COM 
18409585STim.Szeto@Sun.COM 	if (luGuid == NULL && fname == NULL) {
18419585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
18429585STim.Szeto@Sun.COM 	}
18439585STim.Szeto@Sun.COM 
18449585STim.Szeto@Sun.COM 	if (fname) {
18459585STim.Szeto@Sun.COM 		fnameSize = strlen(fname) + 1;
18469585STim.Szeto@Sun.COM 		mluBufSize += fnameSize;
18479585STim.Szeto@Sun.COM 	}
18489585STim.Szeto@Sun.COM 
18499585STim.Szeto@Sun.COM 	/*
18509585STim.Szeto@Sun.COM 	 * Open control node for sbd
18519585STim.Szeto@Sun.COM 	 */
18529585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
18539585STim.Szeto@Sun.COM 		return (ret);
18549585STim.Szeto@Sun.COM 
18559585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18569585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
18579585STim.Szeto@Sun.COM 		mluBufSize += luAliasLen + 1;
18589585STim.Szeto@Sun.COM 	}
18599585STim.Szeto@Sun.COM 
186010113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
186110113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
186210113SNattuvetty.Bhavyan@Sun.COM 		mluBufSize += luMgmtUrlLen + 1;
186310113SNattuvetty.Bhavyan@Sun.COM 	}
186410113SNattuvetty.Bhavyan@Sun.COM 
18659585STim.Szeto@Sun.COM 	/*
18669585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
18679585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
18689585STim.Szeto@Sun.COM 	 */
18699585STim.Szeto@Sun.COM 	sbdLu = (sbd_modify_lu_t *)calloc(1,
18709585STim.Szeto@Sun.COM 	    sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
18719585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
18729585STim.Szeto@Sun.COM 		(void) close(fd);
18739585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
18749585STim.Szeto@Sun.COM 	}
18759585STim.Szeto@Sun.COM 
18769585STim.Szeto@Sun.COM 	sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
18779585STim.Szeto@Sun.COM 	    mluBufSize - 8 + fnameSize;
18789585STim.Szeto@Sun.COM 
18799585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18809585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_valid = 1;
18819585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_off = bufOffset;
18829585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
18839585STim.Szeto@Sun.COM 		    luAliasLen + 1);
18849585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
18859585STim.Szeto@Sun.COM 	}
18869585STim.Szeto@Sun.COM 
188710113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
188810113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_valid = 1;
188910113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_off = bufOffset;
189010113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
189110113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
189210113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
189310113SNattuvetty.Bhavyan@Sun.COM 	}
189410113SNattuvetty.Bhavyan@Sun.COM 
18959585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
18969585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size_valid = 1;
18979585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size = disk->luSize;
18989585STim.Szeto@Sun.COM 	}
18999585STim.Szeto@Sun.COM 
19009585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
19019585STim.Szeto@Sun.COM 		sbdLu->mlu_write_protected_valid = 1;
19029585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
19039585STim.Szeto@Sun.COM 			sbdLu->mlu_write_protected = 1;
19049585STim.Szeto@Sun.COM 		}
19059585STim.Szeto@Sun.COM 	}
19069585STim.Szeto@Sun.COM 
19079585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
19089585STim.Szeto@Sun.COM 		sbdLu->mlu_writeback_cache_disable_valid = 1;
19099585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
19109585STim.Szeto@Sun.COM 			sbdLu->mlu_writeback_cache_disable = 1;
19119585STim.Szeto@Sun.COM 		}
19129585STim.Szeto@Sun.COM 	}
19139585STim.Szeto@Sun.COM 
19149585STim.Szeto@Sun.COM 	if (luGuid) {
19159585STim.Szeto@Sun.COM 		bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
19169585STim.Szeto@Sun.COM 		sbdLu->mlu_by_guid = 1;
19179585STim.Szeto@Sun.COM 	} else {
19189585STim.Szeto@Sun.COM 		sbdLu->mlu_fname_off = bufOffset;
19199585STim.Szeto@Sun.COM 		bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
19209585STim.Szeto@Sun.COM 		sbdLu->mlu_by_fname = 1;
19219585STim.Szeto@Sun.COM 	}
19229585STim.Szeto@Sun.COM 
19239585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
19249585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
19259585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
19269585STim.Szeto@Sun.COM 
19279585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
19289585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
19299585STim.Szeto@Sun.COM 		savedErrno = errno;
19309585STim.Szeto@Sun.COM 		switch (savedErrno) {
19319585STim.Szeto@Sun.COM 			case EBUSY:
19329585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
19339585STim.Szeto@Sun.COM 				break;
19349585STim.Szeto@Sun.COM 			case EPERM:
19359585STim.Szeto@Sun.COM 			case EACCES:
19369585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
19379585STim.Szeto@Sun.COM 				break;
19389585STim.Szeto@Sun.COM 			default:
19399585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
19409585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
19419585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
19429585STim.Szeto@Sun.COM 					"modifyDiskLu:ioctl "
19439585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
19449585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
19459585STim.Szeto@Sun.COM 				}
19469585STim.Szeto@Sun.COM 				break;
19479585STim.Szeto@Sun.COM 		}
19489585STim.Szeto@Sun.COM 	}
19499585STim.Szeto@Sun.COM 
19509585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
19519585STim.Szeto@Sun.COM 		goto done;
19529585STim.Szeto@Sun.COM 	}
19539585STim.Szeto@Sun.COM 
19549585STim.Szeto@Sun.COM done:
19559585STim.Szeto@Sun.COM 	free(sbdLu);
19569585STim.Szeto@Sun.COM 	(void) close(fd);
19579585STim.Szeto@Sun.COM 	return (ret);
19589585STim.Szeto@Sun.COM }
19599585STim.Szeto@Sun.COM 
19609585STim.Szeto@Sun.COM /*
19619585STim.Szeto@Sun.COM  * removeGuidFromDiskStore
19629585STim.Szeto@Sun.COM  *
19639585STim.Szeto@Sun.COM  * Purpose: delete a logical unit from the sbd provider data
19649585STim.Szeto@Sun.COM  */
19659585STim.Szeto@Sun.COM static int
19669585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid)
19679585STim.Szeto@Sun.COM {
19689585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, NULL, B_FALSE));
19699585STim.Szeto@Sun.COM }
19709585STim.Szeto@Sun.COM 
19719585STim.Szeto@Sun.COM 
19729585STim.Szeto@Sun.COM /*
19739585STim.Szeto@Sun.COM  * addGuidToDiskStore
19749585STim.Szeto@Sun.COM  *
19759585STim.Szeto@Sun.COM  * Purpose: add a logical unit to the sbd provider data
19769585STim.Szeto@Sun.COM  */
19779585STim.Szeto@Sun.COM static int
19789585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename)
19799585STim.Szeto@Sun.COM {
19809585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, filename, B_TRUE));
19819585STim.Szeto@Sun.COM }
19829585STim.Szeto@Sun.COM 
19839585STim.Szeto@Sun.COM 
19849585STim.Szeto@Sun.COM /*
19859585STim.Szeto@Sun.COM  * persistDiskGuid
19869585STim.Szeto@Sun.COM  *
19879585STim.Szeto@Sun.COM  * Purpose: Persist or unpersist a guid for the sbd provider data
19889585STim.Szeto@Sun.COM  *
19899585STim.Szeto@Sun.COM  */
19909585STim.Szeto@Sun.COM static int
19919585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
19929585STim.Szeto@Sun.COM {
19939585STim.Szeto@Sun.COM 	char	    guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
19949585STim.Szeto@Sun.COM 	nvlist_t    *nvl = NULL;
19959585STim.Szeto@Sun.COM 
19969585STim.Szeto@Sun.COM 	uint64_t    setToken;
19979585STim.Szeto@Sun.COM 	boolean_t   retryGetProviderData = B_FALSE;
19989585STim.Szeto@Sun.COM 	boolean_t   newData = B_FALSE;
19999585STim.Szeto@Sun.COM 	int	    ret = STMF_STATUS_SUCCESS;
20009585STim.Szeto@Sun.COM 	int	    retryCnt = 0;
20019585STim.Szeto@Sun.COM 	int	    stmfRet;
20029585STim.Szeto@Sun.COM 
20039585STim.Szeto@Sun.COM 	/* if we're persisting a guid, there must be a filename */
20049585STim.Szeto@Sun.COM 	if (persist && !filename) {
20059585STim.Szeto@Sun.COM 		return (1);
20069585STim.Szeto@Sun.COM 	}
20079585STim.Szeto@Sun.COM 
20089585STim.Szeto@Sun.COM 	/* guid is stored in lowercase ascii hex */
20099585STim.Szeto@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
20109585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
20119585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x",
20129585STim.Szeto@Sun.COM 	    guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
20139585STim.Szeto@Sun.COM 	    guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
20149585STim.Szeto@Sun.COM 	    guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
20159585STim.Szeto@Sun.COM 	    guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
20169585STim.Szeto@Sun.COM 
20179585STim.Szeto@Sun.COM 
20189585STim.Szeto@Sun.COM 	do {
20199585STim.Szeto@Sun.COM 		retryGetProviderData = B_FALSE;
20209585STim.Szeto@Sun.COM 		stmfRet = stmfGetProviderDataProt("sbd", &nvl,
20219585STim.Szeto@Sun.COM 		    STMF_LU_PROVIDER_TYPE, &setToken);
20229585STim.Szeto@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
20239585STim.Szeto@Sun.COM 			if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
20249585STim.Szeto@Sun.COM 				ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
20259585STim.Szeto@Sun.COM 				if (ret != 0) {
20269585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20279585STim.Szeto@Sun.COM 					    "unpersistGuid:nvlist_alloc(%d)",
20289585STim.Szeto@Sun.COM 					    ret);
20299585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
20309585STim.Szeto@Sun.COM 					goto done;
20319585STim.Szeto@Sun.COM 				}
20329585STim.Szeto@Sun.COM 				newData = B_TRUE;
20339585STim.Szeto@Sun.COM 			} else {
203410725SJohn.Forte@Sun.COM 				/*
203510725SJohn.Forte@Sun.COM 				 * if we're persisting the data, it's
203610725SJohn.Forte@Sun.COM 				 * an error. Otherwise, just return
203710725SJohn.Forte@Sun.COM 				 */
203810725SJohn.Forte@Sun.COM 				if (persist) {
203910725SJohn.Forte@Sun.COM 					ret = stmfRet;
204010725SJohn.Forte@Sun.COM 				}
20419585STim.Szeto@Sun.COM 				goto done;
20429585STim.Szeto@Sun.COM 			}
20439585STim.Szeto@Sun.COM 		}
20449585STim.Szeto@Sun.COM 		if (persist) {
20459585STim.Szeto@Sun.COM 			ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
20469585STim.Szeto@Sun.COM 		} else {
20479585STim.Szeto@Sun.COM 			ret = nvlist_remove(nvl, guidAsciiBuf,
20489585STim.Szeto@Sun.COM 			    DATA_TYPE_STRING);
20499585STim.Szeto@Sun.COM 			if (ret == ENOENT) {
20509585STim.Szeto@Sun.COM 				ret = 0;
20519585STim.Szeto@Sun.COM 			}
20529585STim.Szeto@Sun.COM 		}
20539585STim.Szeto@Sun.COM 		if (ret == 0) {
20549585STim.Szeto@Sun.COM 			if (newData) {
20559585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20569585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, NULL);
20579585STim.Szeto@Sun.COM 			} else {
20589585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20599585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, &setToken);
20609585STim.Szeto@Sun.COM 			}
20619585STim.Szeto@Sun.COM 			if (stmfRet != STMF_STATUS_SUCCESS) {
20629585STim.Szeto@Sun.COM 				if (stmfRet == STMF_ERROR_BUSY) {
20639585STim.Szeto@Sun.COM 					/* get/set failed, try again */
20649585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20659585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20669585STim.Szeto@Sun.COM 						ret = stmfRet;
20679585STim.Szeto@Sun.COM 						break;
20689585STim.Szeto@Sun.COM 					}
20699585STim.Szeto@Sun.COM 					continue;
20709585STim.Szeto@Sun.COM 				} else if (stmfRet ==
20719585STim.Szeto@Sun.COM 				    STMF_ERROR_PROV_DATA_STALE) {
20729585STim.Szeto@Sun.COM 					/* update failed, try again */
20739585STim.Szeto@Sun.COM 					nvlist_free(nvl);
20749585STim.Szeto@Sun.COM 					nvl = NULL;
20759585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20769585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20779585STim.Szeto@Sun.COM 						ret = stmfRet;
20789585STim.Szeto@Sun.COM 						break;
20799585STim.Szeto@Sun.COM 					}
20809585STim.Szeto@Sun.COM 					continue;
20819585STim.Szeto@Sun.COM 				} else {
20829585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20839585STim.Szeto@Sun.COM 					    "unpersistGuid:error(%x)", stmfRet);
20849585STim.Szeto@Sun.COM 					ret = stmfRet;
20859585STim.Szeto@Sun.COM 				}
20869585STim.Szeto@Sun.COM 				break;
20879585STim.Szeto@Sun.COM 			}
20889585STim.Szeto@Sun.COM 		} else {
20899585STim.Szeto@Sun.COM 			syslog(LOG_DEBUG,
20909585STim.Szeto@Sun.COM 			    "unpersistGuid:error nvlist_add/remove(%d)",
20919585STim.Szeto@Sun.COM 			    ret);
20929585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
20939585STim.Szeto@Sun.COM 		}
20949585STim.Szeto@Sun.COM 	} while (retryGetProviderData);
20959585STim.Szeto@Sun.COM 
20969585STim.Szeto@Sun.COM done:
20979585STim.Szeto@Sun.COM 	nvlist_free(nvl);
20989585STim.Szeto@Sun.COM 	return (ret);
20999585STim.Szeto@Sun.COM }
21009585STim.Szeto@Sun.COM 
21019585STim.Szeto@Sun.COM 
21029585STim.Szeto@Sun.COM /*
21039585STim.Szeto@Sun.COM  * stmfGetLuProp
21049585STim.Szeto@Sun.COM  *
21059585STim.Szeto@Sun.COM  * Purpose: Get current value for a resource property
21069585STim.Szeto@Sun.COM  *
21079585STim.Szeto@Sun.COM  * hdl - luResource from a previous call to stmfCreateLuResource
21089585STim.Szeto@Sun.COM  *
21099585STim.Szeto@Sun.COM  * resourceProp - a valid resource property type
21109585STim.Szeto@Sun.COM  *
21119585STim.Szeto@Sun.COM  * propVal - void pointer to a pointer of the value to be retrieved
21129585STim.Szeto@Sun.COM  */
21139585STim.Szeto@Sun.COM int
21149585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
21159585STim.Szeto@Sun.COM {
21169585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21179585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
21189585STim.Szeto@Sun.COM 	if (hdl == NULL || propLen == NULL || propVal == NULL) {
21199585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21209585STim.Szeto@Sun.COM 	}
21219585STim.Szeto@Sun.COM 
21229585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
21239585STim.Szeto@Sun.COM 		ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
21249585STim.Szeto@Sun.COM 	} else {
21259585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21269585STim.Szeto@Sun.COM 	}
21279585STim.Szeto@Sun.COM 
21289585STim.Szeto@Sun.COM 	return (ret);
21299585STim.Szeto@Sun.COM }
21309585STim.Szeto@Sun.COM 
21319585STim.Szeto@Sun.COM /*
21329585STim.Szeto@Sun.COM  * stmfGetLuResource
21339585STim.Szeto@Sun.COM  *
21349585STim.Szeto@Sun.COM  * Purpose: Get a logical unit resource handle for a given logical unit.
21359585STim.Szeto@Sun.COM  *
21369585STim.Szeto@Sun.COM  * hdl - pointer to luResource
21379585STim.Szeto@Sun.COM  */
21389585STim.Szeto@Sun.COM int
21399585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
21409585STim.Szeto@Sun.COM {
21419585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21429585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
21439585STim.Szeto@Sun.COM 
214411691SSrivijitha.Dugganapalli@Sun.COM 	if (hdl == NULL) {
214511691SSrivijitha.Dugganapalli@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
214611691SSrivijitha.Dugganapalli@Sun.COM 	}
21479585STim.Szeto@Sun.COM 
21489585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
21499585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
21509585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
21519585STim.Szeto@Sun.COM 		return (ret);
21529585STim.Szeto@Sun.COM 	} else {
21539585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
21549585STim.Szeto@Sun.COM 			ret = getDiskAllProps(luGuid, hdl);
21559585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
21569585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
21579585STim.Szeto@Sun.COM 		} else {
21589585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
21599585STim.Szeto@Sun.COM 		}
21609585STim.Szeto@Sun.COM 	}
21619585STim.Szeto@Sun.COM 
21629585STim.Szeto@Sun.COM 	return (ret);
21639585STim.Szeto@Sun.COM }
21649585STim.Szeto@Sun.COM 
21659585STim.Szeto@Sun.COM /*
21669585STim.Szeto@Sun.COM  * getDiskAllProps
21679585STim.Szeto@Sun.COM  *
21689585STim.Szeto@Sun.COM  * Purpose: load all disk properties from sbd driver
21699585STim.Szeto@Sun.COM  *
21709585STim.Szeto@Sun.COM  * luGuid - guid of disk device for which properties are to be retrieved
21719585STim.Szeto@Sun.COM  * hdl - allocated luResource into which properties are to be copied
21729585STim.Szeto@Sun.COM  *
21739585STim.Szeto@Sun.COM  */
21749585STim.Szeto@Sun.COM static int
21759585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
21769585STim.Szeto@Sun.COM {
21779585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21789585STim.Szeto@Sun.COM 	int fd;
21799585STim.Szeto@Sun.COM 	sbd_lu_props_t *sbdProps;
21809585STim.Szeto@Sun.COM 	int ioctlRet;
21819585STim.Szeto@Sun.COM 	int savedErrno;
21829585STim.Szeto@Sun.COM 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
21839585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
21849585STim.Szeto@Sun.COM 
21859585STim.Szeto@Sun.COM 	/*
21869585STim.Szeto@Sun.COM 	 * Open control node for sbd
21879585STim.Szeto@Sun.COM 	 */
21889585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
21899585STim.Szeto@Sun.COM 		return (ret);
21909585STim.Szeto@Sun.COM 
21919585STim.Szeto@Sun.COM 
21929585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
21939585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
21949585STim.Szeto@Sun.COM 		(void) close(fd);
21959585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
21969585STim.Szeto@Sun.COM 	}
21979585STim.Szeto@Sun.COM 
21989585STim.Szeto@Sun.COM 	sbdProps = calloc(1, sbdPropsSize);
21999585STim.Szeto@Sun.COM 	if (sbdProps == NULL) {
22009585STim.Szeto@Sun.COM 		free(*hdl);
22019585STim.Szeto@Sun.COM 		(void) close(fd);
22029585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
22039585STim.Szeto@Sun.COM 	}
22049585STim.Szeto@Sun.COM 
22059585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
22069585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
22079585STim.Szeto@Sun.COM 		free(*hdl);
220810725SJohn.Forte@Sun.COM 		free(sbdProps);
22099585STim.Szeto@Sun.COM 		(void) close(fd);
22109585STim.Szeto@Sun.COM 		return (ret);
22119585STim.Szeto@Sun.COM 	}
22129585STim.Szeto@Sun.COM 
22139585STim.Szeto@Sun.COM 	sbdProps->slp_input_guid = 1;
22149585STim.Szeto@Sun.COM 	bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
22159585STim.Szeto@Sun.COM 
22169585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
22179585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdPropsSize;
22189585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
22199585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdPropsSize;
22209585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
22219585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
22229585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
22239585STim.Szeto@Sun.COM 		savedErrno = errno;
22249585STim.Szeto@Sun.COM 		switch (savedErrno) {
22259585STim.Szeto@Sun.COM 			case EBUSY:
22269585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
22279585STim.Szeto@Sun.COM 				break;
22289585STim.Szeto@Sun.COM 			case EPERM:
22299585STim.Szeto@Sun.COM 			case EACCES:
22309585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
22319585STim.Szeto@Sun.COM 				break;
22329585STim.Szeto@Sun.COM 			case ENOENT:
22339585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
22349585STim.Szeto@Sun.COM 				break;
22359585STim.Szeto@Sun.COM 			default:
22369585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
22379585STim.Szeto@Sun.COM 				    "getDiskAllProps:ioctl error(%d) (%d) (%d)",
22389585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
22399585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
22409585STim.Szeto@Sun.COM 				break;
22419585STim.Szeto@Sun.COM 		}
22429585STim.Szeto@Sun.COM 	}
22439585STim.Szeto@Sun.COM 
22449585STim.Szeto@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
22459585STim.Szeto@Sun.COM 		ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
22469585STim.Szeto@Sun.COM 	}
22479585STim.Szeto@Sun.COM 
224810725SJohn.Forte@Sun.COM 	free(sbdProps);
22499585STim.Szeto@Sun.COM 	(void) close(fd);
22509585STim.Szeto@Sun.COM 	return (ret);
22519585STim.Szeto@Sun.COM }
22529585STim.Szeto@Sun.COM 
22539585STim.Szeto@Sun.COM /*
22549585STim.Szeto@Sun.COM  * loadDiskPropsFromDriver
22559585STim.Szeto@Sun.COM  *
22569585STim.Szeto@Sun.COM  * Purpose: Retrieve all disk type properties from sbd driver
22579585STim.Szeto@Sun.COM  *
22589585STim.Szeto@Sun.COM  * hdl - Allocated luResourceImpl
22599585STim.Szeto@Sun.COM  * sbdProps - sbd_lu_props_t structure returned from sbd driver
22609585STim.Szeto@Sun.COM  *
22619585STim.Szeto@Sun.COM  */
22629585STim.Szeto@Sun.COM static int
22639585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
22649585STim.Szeto@Sun.COM {
22659585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
22669585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
22679585STim.Szeto@Sun.COM 	/* copy guid */
22689585STim.Szeto@Sun.COM 	diskLu->luGuidValid = B_TRUE;
22699585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
22709585STim.Szeto@Sun.COM 
22719585STim.Szeto@Sun.COM 	if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
22729585STim.Szeto@Sun.COM 		diskLu->luMetaFileNameValid = B_TRUE;
22739585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luMetaFileName,
22749585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
22759585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) >=
22769585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) {
22779585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22789585STim.Szeto@Sun.COM 		}
22799585STim.Szeto@Sun.COM 	}
22809585STim.Szeto@Sun.COM 
22819585STim.Szeto@Sun.COM 	if (sbdProps->slp_data_fname_valid) {
22829585STim.Szeto@Sun.COM 		diskLu->luDataFileNameValid = B_TRUE;
22839585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luDataFileName,
22849585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
22859585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) >=
22869585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) {
22879585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22889585STim.Szeto@Sun.COM 		}
22899585STim.Szeto@Sun.COM 	}
22909585STim.Szeto@Sun.COM 
22919585STim.Szeto@Sun.COM 	if (sbdProps->slp_serial_valid) {
22929585STim.Szeto@Sun.COM 		diskLu->serialNumValid = B_TRUE;
22939585STim.Szeto@Sun.COM 		bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
22949585STim.Szeto@Sun.COM 		    diskLu->serialNum, sbdProps->slp_serial_size);
22959585STim.Szeto@Sun.COM 	}
22969585STim.Szeto@Sun.COM 
229710113SNattuvetty.Bhavyan@Sun.COM 	if (sbdProps->slp_mgmt_url_valid) {
229810113SNattuvetty.Bhavyan@Sun.COM 		diskLu->luMgmtUrlValid = B_TRUE;
229910113SNattuvetty.Bhavyan@Sun.COM 		if (strlcpy(diskLu->luMgmtUrl,
230010113SNattuvetty.Bhavyan@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
230110113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) >=
230210113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) {
230310113SNattuvetty.Bhavyan@Sun.COM 			return (STMF_STATUS_ERROR);
230410113SNattuvetty.Bhavyan@Sun.COM 		}
230510113SNattuvetty.Bhavyan@Sun.COM 	}
230610113SNattuvetty.Bhavyan@Sun.COM 
23079585STim.Szeto@Sun.COM 	if (sbdProps->slp_alias_valid) {
23089585STim.Szeto@Sun.COM 		diskLu->luAliasValid = B_TRUE;
23099585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luAlias,
23109585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]),
23119585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) >=
23129585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) {
23139585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
23149585STim.Szeto@Sun.COM 		}
23159585STim.Szeto@Sun.COM 	} else { /* set alias to data filename if not set */
23169585STim.Szeto@Sun.COM 		if (sbdProps->slp_data_fname_valid) {
23179585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
23189585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias,
23199585STim.Szeto@Sun.COM 			    (char *)&(sbdProps->slp_buf[
23209585STim.Szeto@Sun.COM 			    sbdProps->slp_data_fname_off]),
23219585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
23229585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
23239585STim.Szeto@Sun.COM 				return (STMF_STATUS_ERROR);
23249585STim.Szeto@Sun.COM 			}
23259585STim.Szeto@Sun.COM 		}
23269585STim.Szeto@Sun.COM 	}
23279585STim.Szeto@Sun.COM 
23289585STim.Szeto@Sun.COM 	diskLu->vidValid = B_TRUE;
23299585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
23309585STim.Szeto@Sun.COM 
23319585STim.Szeto@Sun.COM 	diskLu->pidValid = B_TRUE;
23329585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
23339585STim.Szeto@Sun.COM 
23349585STim.Szeto@Sun.COM 	diskLu->revValid = B_TRUE;
23359585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
23369585STim.Szeto@Sun.COM 
23379585STim.Szeto@Sun.COM 	diskLu->writeProtectEnableValid = B_TRUE;
23389585STim.Szeto@Sun.COM 	if (sbdProps->slp_write_protected) {
23399585STim.Szeto@Sun.COM 		diskLu->writeProtectEnable = B_TRUE;
23409585STim.Szeto@Sun.COM 	}
23419585STim.Szeto@Sun.COM 
23429585STim.Szeto@Sun.COM 	diskLu->writebackCacheDisableValid = B_TRUE;
23439585STim.Szeto@Sun.COM 	if (sbdProps->slp_writeback_cache_disable_cur) {
23449585STim.Szeto@Sun.COM 		diskLu->writebackCacheDisable = B_TRUE;
23459585STim.Szeto@Sun.COM 	}
23469585STim.Szeto@Sun.COM 
23479585STim.Szeto@Sun.COM 	diskLu->blkSizeValid = B_TRUE;
23489585STim.Szeto@Sun.COM 	diskLu->blkSize = sbdProps->slp_blksize;
23499585STim.Szeto@Sun.COM 
23509585STim.Szeto@Sun.COM 	diskLu->luSizeValid = B_TRUE;
23519585STim.Szeto@Sun.COM 	diskLu->luSize = sbdProps->slp_lu_size;
23529585STim.Szeto@Sun.COM 
235310725SJohn.Forte@Sun.COM 	diskLu->accessState = sbdProps->slp_access_state;
235410725SJohn.Forte@Sun.COM 
23559585STim.Szeto@Sun.COM 	return (ret);
23569585STim.Szeto@Sun.COM }
23579585STim.Szeto@Sun.COM 
235811103SJohn.Forte@Sun.COM /*
235911103SJohn.Forte@Sun.COM  * stmfGetGlobalLuProp
236011103SJohn.Forte@Sun.COM  *
236111103SJohn.Forte@Sun.COM  * Purpose: get a global property for a device type
236211103SJohn.Forte@Sun.COM  *
236311103SJohn.Forte@Sun.COM  */
236411103SJohn.Forte@Sun.COM int
236511103SJohn.Forte@Sun.COM stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal,
236611103SJohn.Forte@Sun.COM     size_t *propLen)
236711103SJohn.Forte@Sun.COM {
236811103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
236911103SJohn.Forte@Sun.COM 	if (dType != STMF_DISK || propVal == NULL) {
237011103SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
237111103SJohn.Forte@Sun.COM 	}
237211103SJohn.Forte@Sun.COM 
237311103SJohn.Forte@Sun.COM 	ret = getDiskGlobalProp(prop, propVal, propLen);
237411103SJohn.Forte@Sun.COM 
237511103SJohn.Forte@Sun.COM 	return (ret);
237611103SJohn.Forte@Sun.COM }
237711103SJohn.Forte@Sun.COM 
237811103SJohn.Forte@Sun.COM /*
237911103SJohn.Forte@Sun.COM  * getDiskGlobalProp
238011103SJohn.Forte@Sun.COM  *
238111103SJohn.Forte@Sun.COM  * Purpose: get global property from sbd driver
238211103SJohn.Forte@Sun.COM  *
238311103SJohn.Forte@Sun.COM  */
238411103SJohn.Forte@Sun.COM static int
238511103SJohn.Forte@Sun.COM getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen)
238611103SJohn.Forte@Sun.COM {
238711103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
238811103SJohn.Forte@Sun.COM 	int fd;
238911103SJohn.Forte@Sun.COM 	sbd_global_props_t *sbdProps;
239011103SJohn.Forte@Sun.COM 	void *sbd_realloc;
239111103SJohn.Forte@Sun.COM 	int retryCnt = 0;
239211103SJohn.Forte@Sun.COM 	boolean_t retry;
239311103SJohn.Forte@Sun.COM 	int ioctlRet;
239411103SJohn.Forte@Sun.COM 	int savedErrno;
239511103SJohn.Forte@Sun.COM 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
239611103SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
239711103SJohn.Forte@Sun.COM 	size_t reqLen;
239811103SJohn.Forte@Sun.COM 
239911103SJohn.Forte@Sun.COM 	switch (prop) {
240011103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
240111103SJohn.Forte@Sun.COM 			break;
240211103SJohn.Forte@Sun.COM 		default:
240311103SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_PROP);
240411103SJohn.Forte@Sun.COM 	}
240511103SJohn.Forte@Sun.COM 
240611103SJohn.Forte@Sun.COM 	/*
240711103SJohn.Forte@Sun.COM 	 * Open control node for sbd
240811103SJohn.Forte@Sun.COM 	 */
240911103SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
241011103SJohn.Forte@Sun.COM 		return (ret);
241111103SJohn.Forte@Sun.COM 
241211103SJohn.Forte@Sun.COM 	sbdProps = calloc(1, sbdPropsSize);
241311103SJohn.Forte@Sun.COM 	if (sbdProps == NULL) {
241411103SJohn.Forte@Sun.COM 		(void) close(fd);
241511103SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
241611103SJohn.Forte@Sun.COM 	}
241711103SJohn.Forte@Sun.COM 
241811103SJohn.Forte@Sun.COM 	do {
241911103SJohn.Forte@Sun.COM 		retry = B_FALSE;
242011103SJohn.Forte@Sun.COM 		sbdIoctl.stmf_version = STMF_VERSION_1;
242111103SJohn.Forte@Sun.COM 		sbdIoctl.stmf_obuf_size = sbdPropsSize;
242211103SJohn.Forte@Sun.COM 		sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
242311103SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl);
242411103SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
242511103SJohn.Forte@Sun.COM 			savedErrno = errno;
242611103SJohn.Forte@Sun.COM 			switch (savedErrno) {
242711103SJohn.Forte@Sun.COM 				case EBUSY:
242811103SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
242911103SJohn.Forte@Sun.COM 					break;
243011103SJohn.Forte@Sun.COM 				case EPERM:
243111103SJohn.Forte@Sun.COM 				case EACCES:
243211103SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
243311103SJohn.Forte@Sun.COM 					break;
243411103SJohn.Forte@Sun.COM 				case ENOMEM:
243511103SJohn.Forte@Sun.COM 					if (sbdIoctl.stmf_error ==
243611103SJohn.Forte@Sun.COM 					    SBD_RET_INSUFFICIENT_BUF_SPACE &&
243711103SJohn.Forte@Sun.COM 					    retryCnt++ < 3) {
243811103SJohn.Forte@Sun.COM 						sbdPropsSize =
243911103SJohn.Forte@Sun.COM 						    sizeof (*sbdProps) +
244011103SJohn.Forte@Sun.COM 						    sbdProps->
244111103SJohn.Forte@Sun.COM 						    mlu_buf_size_needed;
244211103SJohn.Forte@Sun.COM 
244311103SJohn.Forte@Sun.COM 						sbd_realloc = sbdProps;
244411103SJohn.Forte@Sun.COM 						sbdProps = realloc(sbdProps,
244511103SJohn.Forte@Sun.COM 						    sbdPropsSize);
244611103SJohn.Forte@Sun.COM 						if (sbdProps == NULL) {
244711103SJohn.Forte@Sun.COM 							free(sbd_realloc);
244811103SJohn.Forte@Sun.COM 							ret = STMF_ERROR_NOMEM;
244911103SJohn.Forte@Sun.COM 							break;
245011103SJohn.Forte@Sun.COM 						}
245111103SJohn.Forte@Sun.COM 						retry = B_TRUE;
245211103SJohn.Forte@Sun.COM 					} else {
245311103SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOMEM;
245411103SJohn.Forte@Sun.COM 					}
245511103SJohn.Forte@Sun.COM 					break;
245611103SJohn.Forte@Sun.COM 				default:
245711103SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
245811103SJohn.Forte@Sun.COM 					    "getDiskGlobalProp:ioctl error(%d)"
245911103SJohn.Forte@Sun.COM 					    "(%d)(%d)", ioctlRet,
246011103SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
246111103SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
246211103SJohn.Forte@Sun.COM 					break;
246311103SJohn.Forte@Sun.COM 			}
246411103SJohn.Forte@Sun.COM 
246511103SJohn.Forte@Sun.COM 		}
246611103SJohn.Forte@Sun.COM 	} while (retry);
246711103SJohn.Forte@Sun.COM 
246811103SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
246911103SJohn.Forte@Sun.COM 		goto done;
247011103SJohn.Forte@Sun.COM 	}
247111103SJohn.Forte@Sun.COM 
247211103SJohn.Forte@Sun.COM 	switch (prop) {
247311103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
247411103SJohn.Forte@Sun.COM 			if (sbdProps->mlu_mgmt_url_valid == 0) {
247511103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NO_PROP;
247611103SJohn.Forte@Sun.COM 				goto done;
247711103SJohn.Forte@Sun.COM 			}
247811103SJohn.Forte@Sun.COM 			if ((reqLen = strlcpy(propVal, (char *)&(
247911103SJohn.Forte@Sun.COM 			    sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]),
248011103SJohn.Forte@Sun.COM 			    *propLen)) >= *propLen) {
248111103SJohn.Forte@Sun.COM 				*propLen = reqLen + 1;
248211103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_INVALID_ARG;
248311103SJohn.Forte@Sun.COM 				goto done;
248411103SJohn.Forte@Sun.COM 			}
248511103SJohn.Forte@Sun.COM 			break;
248611103SJohn.Forte@Sun.COM 	}
248711103SJohn.Forte@Sun.COM 
248811103SJohn.Forte@Sun.COM done:
248911103SJohn.Forte@Sun.COM 	free(sbdProps);
249011103SJohn.Forte@Sun.COM 	(void) close(fd);
249111103SJohn.Forte@Sun.COM 	return (ret);
249211103SJohn.Forte@Sun.COM }
249311103SJohn.Forte@Sun.COM 
249411103SJohn.Forte@Sun.COM /*
249511103SJohn.Forte@Sun.COM  * stmfSetGlobalLuProp
249611103SJohn.Forte@Sun.COM  *
249711103SJohn.Forte@Sun.COM  * Purpose: set a global property for a device type
249811103SJohn.Forte@Sun.COM  *
249911103SJohn.Forte@Sun.COM  */
250011103SJohn.Forte@Sun.COM int
250111103SJohn.Forte@Sun.COM stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal)
250211103SJohn.Forte@Sun.COM {
250311103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
250411103SJohn.Forte@Sun.COM 	if (dType != STMF_DISK || propVal == NULL) {
250511103SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
250611103SJohn.Forte@Sun.COM 	}
250711103SJohn.Forte@Sun.COM 
250811103SJohn.Forte@Sun.COM 	ret = setDiskGlobalProp(prop, propVal);
250911103SJohn.Forte@Sun.COM 
251011103SJohn.Forte@Sun.COM 	return (ret);
251111103SJohn.Forte@Sun.COM }
251211103SJohn.Forte@Sun.COM 
251311103SJohn.Forte@Sun.COM /*
251411103SJohn.Forte@Sun.COM  * setDiskGlobalProp
251511103SJohn.Forte@Sun.COM  *
251611103SJohn.Forte@Sun.COM  * Purpose: set properties for resource of type disk
251711103SJohn.Forte@Sun.COM  *
251811103SJohn.Forte@Sun.COM  * resourceProp - valid resource identifier
251911103SJohn.Forte@Sun.COM  * propVal - valid resource value
252011103SJohn.Forte@Sun.COM  */
252111103SJohn.Forte@Sun.COM static int
252211103SJohn.Forte@Sun.COM setDiskGlobalProp(uint32_t resourceProp, const char *propVal)
252311103SJohn.Forte@Sun.COM {
252411103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
252511103SJohn.Forte@Sun.COM 	sbd_global_props_t *sbdGlobalProps = NULL;
252611103SJohn.Forte@Sun.COM 	int sbdGlobalPropsSize = 0;
252711103SJohn.Forte@Sun.COM 	int propLen;
252811103SJohn.Forte@Sun.COM 	int mluBufSize = 0;
252911103SJohn.Forte@Sun.COM 	int fd;
253011103SJohn.Forte@Sun.COM 	int savedErrno;
253111103SJohn.Forte@Sun.COM 	int ioctlRet;
253211103SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
253311103SJohn.Forte@Sun.COM 
253411103SJohn.Forte@Sun.COM 	switch (resourceProp) {
253511103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
253611103SJohn.Forte@Sun.COM 			break;
253711103SJohn.Forte@Sun.COM 		default:
253811103SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_PROP);
253911103SJohn.Forte@Sun.COM 			break;
254011103SJohn.Forte@Sun.COM 	}
254111103SJohn.Forte@Sun.COM 
254211103SJohn.Forte@Sun.COM 	/*
254311103SJohn.Forte@Sun.COM 	 * Open control node for sbd
254411103SJohn.Forte@Sun.COM 	 */
254511103SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
254611103SJohn.Forte@Sun.COM 		return (ret);
254711103SJohn.Forte@Sun.COM 
254811103SJohn.Forte@Sun.COM 	propLen = strlen(propVal);
254911103SJohn.Forte@Sun.COM 	mluBufSize += propLen + 1;
255011103SJohn.Forte@Sun.COM 	sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 +
255111103SJohn.Forte@Sun.COM 	    max(8, mluBufSize);
255211103SJohn.Forte@Sun.COM 	/*
255311103SJohn.Forte@Sun.COM 	 * 8 is the size of the buffer set aside for
255411103SJohn.Forte@Sun.COM 	 * concatenation of variable length fields
255511103SJohn.Forte@Sun.COM 	 */
255611103SJohn.Forte@Sun.COM 	sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize);
255711103SJohn.Forte@Sun.COM 	if (sbdGlobalProps == NULL) {
255811103SJohn.Forte@Sun.COM 		(void) close(fd);
255911103SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
256011103SJohn.Forte@Sun.COM 	}
256111103SJohn.Forte@Sun.COM 
256211103SJohn.Forte@Sun.COM 	sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize;
256311103SJohn.Forte@Sun.COM 
256411103SJohn.Forte@Sun.COM 	switch (resourceProp) {
256511103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
256611103SJohn.Forte@Sun.COM 			sbdGlobalProps->mlu_mgmt_url_valid = 1;
256711103SJohn.Forte@Sun.COM 			bcopy(propVal, &(sbdGlobalProps->mlu_buf),
256811103SJohn.Forte@Sun.COM 			    propLen + 1);
256911103SJohn.Forte@Sun.COM 			break;
257011103SJohn.Forte@Sun.COM 		default:
257111103SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NO_PROP;
257211103SJohn.Forte@Sun.COM 			goto done;
257311103SJohn.Forte@Sun.COM 	}
257411103SJohn.Forte@Sun.COM 
257511103SJohn.Forte@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
257611103SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size;
257711103SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps;
257811103SJohn.Forte@Sun.COM 
257911103SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl);
258011103SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
258111103SJohn.Forte@Sun.COM 		savedErrno = errno;
258211103SJohn.Forte@Sun.COM 		switch (savedErrno) {
258311103SJohn.Forte@Sun.COM 			case EBUSY:
258411103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
258511103SJohn.Forte@Sun.COM 				break;
258611103SJohn.Forte@Sun.COM 			case EPERM:
258711103SJohn.Forte@Sun.COM 			case EACCES:
258811103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
258911103SJohn.Forte@Sun.COM 				break;
259011103SJohn.Forte@Sun.COM 			default:
259111103SJohn.Forte@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
259211103SJohn.Forte@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
259311103SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
259411103SJohn.Forte@Sun.COM 					"modifyDiskLu:ioctl "
259511103SJohn.Forte@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
259611103SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
259711103SJohn.Forte@Sun.COM 				}
259811103SJohn.Forte@Sun.COM 				break;
259911103SJohn.Forte@Sun.COM 		}
260011103SJohn.Forte@Sun.COM 	}
260111103SJohn.Forte@Sun.COM 
260211103SJohn.Forte@Sun.COM done:
260311103SJohn.Forte@Sun.COM 	free(sbdGlobalProps);
260411103SJohn.Forte@Sun.COM 	(void) close(fd);
260511103SJohn.Forte@Sun.COM 	return (ret);
260611103SJohn.Forte@Sun.COM }
260711103SJohn.Forte@Sun.COM 
26089585STim.Szeto@Sun.COM 
26099585STim.Szeto@Sun.COM /*
26109585STim.Szeto@Sun.COM  * stmfSetLuProp
26119585STim.Szeto@Sun.COM  *
26129585STim.Szeto@Sun.COM  * Purpose: set a property on an luResource
26139585STim.Szeto@Sun.COM  *
26149585STim.Szeto@Sun.COM  * hdl - allocated luResource
26159585STim.Szeto@Sun.COM  * prop - property identifier
26169585STim.Szeto@Sun.COM  * propVal - property value to be set
26179585STim.Szeto@Sun.COM  */
26189585STim.Szeto@Sun.COM int
26199585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
26209585STim.Szeto@Sun.COM {
26219585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
26229585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
26239585STim.Szeto@Sun.COM 	if (hdl == NULL) {
26249585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
26259585STim.Szeto@Sun.COM 	}
26269585STim.Szeto@Sun.COM 
26279585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
26289585STim.Szeto@Sun.COM 		ret = setDiskProp(luPropsHdl, prop, propVal);
26299585STim.Szeto@Sun.COM 	} else {
26309585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
26319585STim.Szeto@Sun.COM 	}
26329585STim.Szeto@Sun.COM 
26339585STim.Szeto@Sun.COM 	return (ret);
26349585STim.Szeto@Sun.COM }
26359585STim.Szeto@Sun.COM 
26369585STim.Szeto@Sun.COM /*
26379585STim.Szeto@Sun.COM  * getDiskProp
26389585STim.Szeto@Sun.COM  *
26399585STim.Szeto@Sun.COM  * Purpose: retrieve a given property from a logical unit resource of type disk
26409585STim.Szeto@Sun.COM  *
26419585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
26429585STim.Szeto@Sun.COM  * prop - property identifier
26439585STim.Szeto@Sun.COM  * propVal - pointer to character to contain the retrieved property value
26449585STim.Szeto@Sun.COM  * propLen - On input this is the length of propVal. On failure, it contains the
26459585STim.Szeto@Sun.COM  *           number of bytes required for propVal
26469585STim.Szeto@Sun.COM  */
26479585STim.Szeto@Sun.COM static int
26489585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
26499585STim.Szeto@Sun.COM {
26509585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
26519585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
265210725SJohn.Forte@Sun.COM 	char accessState[20];
26539585STim.Szeto@Sun.COM 	size_t reqLen;
26549585STim.Szeto@Sun.COM 
265510725SJohn.Forte@Sun.COM 	if (prop == STMF_LU_PROP_ACCESS_STATE) {
265610725SJohn.Forte@Sun.COM 		if (diskLu->accessState == SBD_LU_ACTIVE) {
265710725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_ACTIVE,
265810725SJohn.Forte@Sun.COM 			    sizeof (accessState));
265910725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) {
266010725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
266110725SJohn.Forte@Sun.COM 			    STMF_ACCESS_STANDBY_TO_ACTIVE,
266210725SJohn.Forte@Sun.COM 			    sizeof (accessState));
266310725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_STANDBY) {
266410725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_STANDBY,
266510725SJohn.Forte@Sun.COM 			    sizeof (accessState));
266610725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState ==
266710725SJohn.Forte@Sun.COM 		    SBD_LU_TRANSITION_TO_STANDBY) {
266810725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
266910725SJohn.Forte@Sun.COM 			    STMF_ACCESS_ACTIVE_TO_STANDBY,
267010725SJohn.Forte@Sun.COM 			    sizeof (accessState));
267110725SJohn.Forte@Sun.COM 		}
267210725SJohn.Forte@Sun.COM 		if ((reqLen = strlcpy(propVal, accessState,
267310725SJohn.Forte@Sun.COM 		    *propLen)) >= *propLen) {
267410725SJohn.Forte@Sun.COM 			*propLen = reqLen + 1;
267510725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
267610725SJohn.Forte@Sun.COM 		}
267710725SJohn.Forte@Sun.COM 		return (0);
267810725SJohn.Forte@Sun.COM 	}
267910725SJohn.Forte@Sun.COM 
268010725SJohn.Forte@Sun.COM 	if (diskLu->accessState != SBD_LU_ACTIVE) {
268110725SJohn.Forte@Sun.COM 		return (STMF_ERROR_NO_PROP_STANDBY);
268210725SJohn.Forte@Sun.COM 	}
268310725SJohn.Forte@Sun.COM 
26849585STim.Szeto@Sun.COM 	switch (prop) {
26859585STim.Szeto@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE:
26869585STim.Szeto@Sun.COM 			if (diskLu->blkSizeValid == B_FALSE) {
26879585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
26889585STim.Szeto@Sun.COM 			}
26899585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen, "%llu",
26909585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->blkSize);
26919585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
26929585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
26939585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26949585STim.Szeto@Sun.COM 			}
26959585STim.Szeto@Sun.COM 			break;
26969585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
26979585STim.Szeto@Sun.COM 			if (diskLu->luDataFileNameValid == B_FALSE) {
26989585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
26999585STim.Szeto@Sun.COM 			}
27009585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
27019585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27029585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27039585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27049585STim.Szeto@Sun.COM 			}
27059585STim.Szeto@Sun.COM 			break;
27069585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
27079585STim.Szeto@Sun.COM 			if (diskLu->luMetaFileNameValid == B_FALSE) {
27089585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27099585STim.Szeto@Sun.COM 			}
27109585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
27119585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27129585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27139585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27149585STim.Szeto@Sun.COM 			}
27159585STim.Szeto@Sun.COM 			break;
271610113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
271710113SNattuvetty.Bhavyan@Sun.COM 			if (diskLu->luMgmtUrlValid == B_FALSE) {
271810113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_NO_PROP);
271910113SNattuvetty.Bhavyan@Sun.COM 			}
272010113SNattuvetty.Bhavyan@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
272110113SNattuvetty.Bhavyan@Sun.COM 			    *propLen)) >= *propLen) {
272210113SNattuvetty.Bhavyan@Sun.COM 				*propLen = reqLen + 1;
272310113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
272410113SNattuvetty.Bhavyan@Sun.COM 			}
272510113SNattuvetty.Bhavyan@Sun.COM 			break;
27269585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
27279585STim.Szeto@Sun.COM 			if (diskLu->luGuidValid == B_FALSE) {
27289585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27299585STim.Szeto@Sun.COM 			}
27309585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen,
27319585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
27329585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X",
27339585STim.Szeto@Sun.COM 			    diskLu->luGuid[0], diskLu->luGuid[1],
27349585STim.Szeto@Sun.COM 			    diskLu->luGuid[2], diskLu->luGuid[3],
27359585STim.Szeto@Sun.COM 			    diskLu->luGuid[4], diskLu->luGuid[5],
27369585STim.Szeto@Sun.COM 			    diskLu->luGuid[6], diskLu->luGuid[7],
27379585STim.Szeto@Sun.COM 			    diskLu->luGuid[8], diskLu->luGuid[9],
27389585STim.Szeto@Sun.COM 			    diskLu->luGuid[10], diskLu->luGuid[11],
27399585STim.Szeto@Sun.COM 			    diskLu->luGuid[12], diskLu->luGuid[13],
27409585STim.Szeto@Sun.COM 			    diskLu->luGuid[14], diskLu->luGuid[15]);
27419585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
27429585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27439585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27449585STim.Szeto@Sun.COM 			}
27459585STim.Szeto@Sun.COM 			break;
27469585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
27479585STim.Szeto@Sun.COM 			if (diskLu->serialNumValid == B_FALSE) {
27489585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27499585STim.Szeto@Sun.COM 			}
27509585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->serialNum,
27519585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27529585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27539585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27549585STim.Szeto@Sun.COM 			}
27559585STim.Szeto@Sun.COM 			break;
27569585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
27579585STim.Szeto@Sun.COM 			if (diskLu->luSizeValid == B_FALSE) {
27589585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27599585STim.Szeto@Sun.COM 			}
27609585STim.Szeto@Sun.COM 			(void) snprintf(propVal, *propLen, "%llu",
27619585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->luSize);
27629585STim.Szeto@Sun.COM 			break;
27639585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
27649585STim.Szeto@Sun.COM 			if (diskLu->luAliasValid == B_FALSE) {
27659585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27669585STim.Szeto@Sun.COM 			}
27679585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luAlias,
27689585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27699585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27709585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27719585STim.Szeto@Sun.COM 			}
27729585STim.Szeto@Sun.COM 			break;
27739585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
27749585STim.Szeto@Sun.COM 			if (diskLu->vidValid == B_FALSE) {
27759585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27769585STim.Szeto@Sun.COM 			}
27779585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->vid)) {
27789585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27799585STim.Szeto@Sun.COM 			}
27809585STim.Szeto@Sun.COM 			bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
27819585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->vid)] = 0;
27829585STim.Szeto@Sun.COM 			break;
27839585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
27849585STim.Szeto@Sun.COM 			if (diskLu->pidValid == B_FALSE) {
27859585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27869585STim.Szeto@Sun.COM 			}
27879585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->pid)) {
27889585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27899585STim.Szeto@Sun.COM 			}
27909585STim.Szeto@Sun.COM 			bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
27919585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->pid)] = 0;
27929585STim.Szeto@Sun.COM 			break;
27939585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
27949585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnableValid == B_FALSE) {
27959585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27969585STim.Szeto@Sun.COM 			}
27979585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnable) {
27989585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
27999585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28009585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28019585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28029585STim.Szeto@Sun.COM 				}
28039585STim.Szeto@Sun.COM 			} else {
28049585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
28059585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28069585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28079585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28089585STim.Szeto@Sun.COM 				}
28099585STim.Szeto@Sun.COM 			}
28109585STim.Szeto@Sun.COM 			break;
28119585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
28129585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisableValid == B_FALSE) {
28139585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
28149585STim.Szeto@Sun.COM 			}
28159585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisable) {
28169585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
28179585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28189585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28199585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28209585STim.Szeto@Sun.COM 				}
28219585STim.Szeto@Sun.COM 			} else {
28229585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
28239585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28249585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28259585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28269585STim.Szeto@Sun.COM 				}
28279585STim.Szeto@Sun.COM 			}
28289585STim.Szeto@Sun.COM 			break;
28299585STim.Szeto@Sun.COM 		default:
283011691SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
28319585STim.Szeto@Sun.COM 			break;
28329585STim.Szeto@Sun.COM 	}
28339585STim.Szeto@Sun.COM 
28349585STim.Szeto@Sun.COM 	return (ret);
28359585STim.Szeto@Sun.COM }
28369585STim.Szeto@Sun.COM 
28379585STim.Szeto@Sun.COM /*
28389585STim.Szeto@Sun.COM  * setDiskProp
28399585STim.Szeto@Sun.COM  *
28409585STim.Szeto@Sun.COM  * Purpose: set properties for resource of type disk
28419585STim.Szeto@Sun.COM  *
28429585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
28439585STim.Szeto@Sun.COM  * resourceProp - valid resource identifier
28449585STim.Szeto@Sun.COM  * propVal - valid resource value
28459585STim.Szeto@Sun.COM  */
28469585STim.Szeto@Sun.COM static int
28479585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
28489585STim.Szeto@Sun.COM {
28499585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
28509585STim.Szeto@Sun.COM 	int i;
28519585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
28529585STim.Szeto@Sun.COM 	unsigned long long numericProp = 0;
28539585STim.Szeto@Sun.COM 	char guidProp[LU_ASCII_GUID_SIZE + 1];
28549585STim.Szeto@Sun.COM 	char ouiProp[OUI_ASCII_SIZE + 1];
285510765SJohn.Forte@Sun.COM 	char hostIdProp[HOST_ID_ASCII_SIZE + 1];
28569585STim.Szeto@Sun.COM 	unsigned int oui[OUI_SIZE];
285710765SJohn.Forte@Sun.COM 	unsigned int hostId[HOST_ID_SIZE];
28589585STim.Szeto@Sun.COM 	unsigned int guid[LU_GUID_SIZE];
28599585STim.Szeto@Sun.COM 	int propSize;
28609585STim.Szeto@Sun.COM 
28619585STim.Szeto@Sun.COM 
28629585STim.Szeto@Sun.COM 	if (propVal == NULL) {
28639585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28649585STim.Szeto@Sun.COM 	}
28659585STim.Szeto@Sun.COM 
28669585STim.Szeto@Sun.COM 	switch (resourceProp) {
28679585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
28689585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias, propVal,
28699585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
28709585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
28719585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
28729585STim.Szeto@Sun.COM 			}
28739585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
28749585STim.Szeto@Sun.COM 			break;
2875*11865SSrivijitha.Dugganapalli@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE: {
2876*11865SSrivijitha.Dugganapalli@Sun.COM 			const char *tmp = propVal;
2877*11865SSrivijitha.Dugganapalli@Sun.COM 			while (*tmp) {
2878*11865SSrivijitha.Dugganapalli@Sun.COM 				if (!isdigit(*tmp++)) {
2879*11865SSrivijitha.Dugganapalli@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
2880*11865SSrivijitha.Dugganapalli@Sun.COM 				}
2881*11865SSrivijitha.Dugganapalli@Sun.COM 			}
28829585STim.Szeto@Sun.COM 			(void) sscanf(propVal, "%llu", &numericProp);
28839585STim.Szeto@Sun.COM 			if (numericProp > UINT16_MAX) {
28849585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
28859585STim.Szeto@Sun.COM 			}
28869585STim.Szeto@Sun.COM 			diskLu->blkSize = numericProp;
28879585STim.Szeto@Sun.COM 			diskLu->blkSizeValid = B_TRUE;
28889585STim.Szeto@Sun.COM 			break;
2889*11865SSrivijitha.Dugganapalli@Sun.COM 		}
28909585STim.Szeto@Sun.COM 		case STMF_LU_PROP_COMPANY_ID:
28919585STim.Szeto@Sun.COM 			if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
28929585STim.Szeto@Sun.COM 			    sizeof (ouiProp)) {
28939585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
28949585STim.Szeto@Sun.COM 			}
28959585STim.Szeto@Sun.COM 			if (checkHexUpper(ouiProp) != 0) {
28969585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
28979585STim.Szeto@Sun.COM 			}
28989585STim.Szeto@Sun.COM 			(void) sscanf(ouiProp, "%2X%2X%2X",
28999585STim.Szeto@Sun.COM 			    &oui[0], &oui[1], &oui[2]);
29009585STim.Szeto@Sun.COM 
29019585STim.Szeto@Sun.COM 			diskLu->companyId = 0;
29029585STim.Szeto@Sun.COM 			diskLu->companyId += oui[0] << 16;
29039585STim.Szeto@Sun.COM 			diskLu->companyId += oui[1] << 8;
29049585STim.Szeto@Sun.COM 			diskLu->companyId += oui[2];
290510765SJohn.Forte@Sun.COM 			if (diskLu->companyId == 0) {
290610765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
290710765SJohn.Forte@Sun.COM 			}
29089585STim.Szeto@Sun.COM 			diskLu->companyIdValid = B_TRUE;
29099585STim.Szeto@Sun.COM 			break;
291010765SJohn.Forte@Sun.COM 		case STMF_LU_PROP_HOST_ID:
291110765SJohn.Forte@Sun.COM 			if ((strlcpy(hostIdProp, propVal,
291210765SJohn.Forte@Sun.COM 			    sizeof (hostIdProp))) >= sizeof (hostIdProp)) {
291310765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
291410765SJohn.Forte@Sun.COM 			}
291510765SJohn.Forte@Sun.COM 			if (checkHexUpper(hostIdProp) != 0) {
291610765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
291710765SJohn.Forte@Sun.COM 			}
291810765SJohn.Forte@Sun.COM 			(void) sscanf(hostIdProp, "%2X%2X%2X%2X",
291910765SJohn.Forte@Sun.COM 			    &hostId[0], &hostId[1], &hostId[2], &hostId[3]);
292010765SJohn.Forte@Sun.COM 
292110765SJohn.Forte@Sun.COM 			diskLu->hostId = 0;
292210765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[0] << 24;
292310765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[1] << 16;
292410765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[2] << 8;
292510765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[3];
292610765SJohn.Forte@Sun.COM 			if (diskLu->hostId == 0) {
292710765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
292810765SJohn.Forte@Sun.COM 			}
292910765SJohn.Forte@Sun.COM 			diskLu->hostIdValid = B_TRUE;
293010765SJohn.Forte@Sun.COM 			break;
29319585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
29329585STim.Szeto@Sun.COM 			if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
29339585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29349585STim.Szeto@Sun.COM 			}
29359585STim.Szeto@Sun.COM 
29369585STim.Szeto@Sun.COM 			if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
29379585STim.Szeto@Sun.COM 			    sizeof (guidProp)) {
29389585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29399585STim.Szeto@Sun.COM 			}
29409585STim.Szeto@Sun.COM 
29419585STim.Szeto@Sun.COM 			if (checkHexUpper(guidProp) != 0) {
29429585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29439585STim.Szeto@Sun.COM 			}
29449585STim.Szeto@Sun.COM 
29459585STim.Szeto@Sun.COM 			(void) sscanf(guidProp,
29469585STim.Szeto@Sun.COM 			    "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
29479585STim.Szeto@Sun.COM 			    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
29489585STim.Szeto@Sun.COM 			    &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
29499585STim.Szeto@Sun.COM 			    &guid[10], &guid[11], &guid[12], &guid[13],
29509585STim.Szeto@Sun.COM 			    &guid[14], &guid[15]);
29519585STim.Szeto@Sun.COM 			for (i = 0; i < sizeof (diskLu->luGuid); i++) {
29529585STim.Szeto@Sun.COM 				diskLu->luGuid[i] = guid[i];
29539585STim.Szeto@Sun.COM 			}
29549585STim.Szeto@Sun.COM 			diskLu->luGuidValid = B_TRUE;
29559585STim.Szeto@Sun.COM 			break;
29569585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
29579585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luDataFileName, propVal,
29589585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName))) >=
29599585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName)) {
29609585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29619585STim.Szeto@Sun.COM 			}
29629585STim.Szeto@Sun.COM 			diskLu->luDataFileNameValid = B_TRUE;
29639585STim.Szeto@Sun.COM 			break;
29649585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
29659585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luMetaFileName, propVal,
29669585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName))) >=
29679585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName)) {
29689585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29699585STim.Szeto@Sun.COM 			}
29709585STim.Szeto@Sun.COM 			diskLu->luMetaFileNameValid = B_TRUE;
29719585STim.Szeto@Sun.COM 			break;
297210113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
297310113SNattuvetty.Bhavyan@Sun.COM 			if ((strlcpy(diskLu->luMgmtUrl, propVal,
297410113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl))) >=
297510113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl)) {
297610113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
297710113SNattuvetty.Bhavyan@Sun.COM 			}
297810113SNattuvetty.Bhavyan@Sun.COM 			diskLu->luMgmtUrlValid = B_TRUE;
297910113SNattuvetty.Bhavyan@Sun.COM 			break;
29809585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
29819585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
29829585STim.Szeto@Sun.COM 			    sizeof (diskLu->pid)) {
29839585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29849585STim.Szeto@Sun.COM 			}
29859585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->pid, propVal, propSize);
29869585STim.Szeto@Sun.COM 			diskLu->pidValid = B_TRUE;
29879585STim.Szeto@Sun.COM 			break;
29889585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
29899585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
29909585STim.Szeto@Sun.COM 			    (sizeof (diskLu->serialNum) - 1)) {
29919585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29929585STim.Szeto@Sun.COM 			}
29939585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->serialNum, propVal, propSize);
29949585STim.Szeto@Sun.COM 			diskLu->serialNumValid = B_TRUE;
29959585STim.Szeto@Sun.COM 			break;
29969585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
29979585STim.Szeto@Sun.COM 			if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
29989585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29999585STim.Szeto@Sun.COM 			}
30009585STim.Szeto@Sun.COM 			diskLu->luSizeValid = B_TRUE;
30019585STim.Szeto@Sun.COM 			break;
30029585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
30039585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
30049585STim.Szeto@Sun.COM 			    sizeof (diskLu->vid)) {
30059585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
30069585STim.Szeto@Sun.COM 			}
30079585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->vid, propVal, propSize);
30089585STim.Szeto@Sun.COM 			diskLu->vidValid = B_TRUE;
30099585STim.Szeto@Sun.COM 			break;
30109585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
30119585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
30129585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_TRUE;
30139585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
30149585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_FALSE;
30159585STim.Szeto@Sun.COM 			} else {
30169585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
30179585STim.Szeto@Sun.COM 			}
30189585STim.Szeto@Sun.COM 			diskLu->writeProtectEnableValid = B_TRUE;
30199585STim.Szeto@Sun.COM 			break;
30209585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
30219585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
30229585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_TRUE;
30239585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
30249585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_FALSE;
30259585STim.Szeto@Sun.COM 			} else {
30269585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
30279585STim.Szeto@Sun.COM 			}
30289585STim.Szeto@Sun.COM 			diskLu->writebackCacheDisableValid = B_TRUE;
30299585STim.Szeto@Sun.COM 			break;
303010725SJohn.Forte@Sun.COM 		case STMF_LU_PROP_ACCESS_STATE:
303110725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
303210725SJohn.Forte@Sun.COM 			break;
30339585STim.Szeto@Sun.COM 		default:
303411691SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
30359585STim.Szeto@Sun.COM 			break;
30369585STim.Szeto@Sun.COM 	}
30379585STim.Szeto@Sun.COM 	return (ret);
30389585STim.Szeto@Sun.COM }
30399585STim.Szeto@Sun.COM 
30409585STim.Szeto@Sun.COM static int
30419585STim.Szeto@Sun.COM checkHexUpper(char *buf)
30429585STim.Szeto@Sun.COM {
30439585STim.Szeto@Sun.COM 	int i;
30449585STim.Szeto@Sun.COM 
30459585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(buf); i++) {
30469585STim.Szeto@Sun.COM 		if (isxdigit(buf[i])) {
30479585STim.Szeto@Sun.COM 			buf[i] = toupper(buf[i]);
30489585STim.Szeto@Sun.COM 			continue;
30499585STim.Szeto@Sun.COM 		}
30509585STim.Szeto@Sun.COM 		return (-1);
30519585STim.Szeto@Sun.COM 	}
30529585STim.Szeto@Sun.COM 
30539585STim.Szeto@Sun.COM 	return (0);
30549585STim.Szeto@Sun.COM }
30559585STim.Szeto@Sun.COM 
30569585STim.Szeto@Sun.COM /*
30579585STim.Szeto@Sun.COM  * Given a numeric suffix, convert the value into a number of bits that the
30589585STim.Szeto@Sun.COM  * resulting value must be shifted.
30599585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
30609585STim.Szeto@Sun.COM  */
30619585STim.Szeto@Sun.COM static int
30629585STim.Szeto@Sun.COM strToShift(const char *buf)
30639585STim.Szeto@Sun.COM {
30649585STim.Szeto@Sun.COM 	const char *ends = "BKMGTPE";
30659585STim.Szeto@Sun.COM 	int i;
30669585STim.Szeto@Sun.COM 
30679585STim.Szeto@Sun.COM 	if (buf[0] == '\0')
30689585STim.Szeto@Sun.COM 		return (0);
30699585STim.Szeto@Sun.COM 
30709585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(ends); i++) {
30719585STim.Szeto@Sun.COM 		if (toupper(buf[0]) == ends[i])
30729585STim.Szeto@Sun.COM 			return (10*i);
30739585STim.Szeto@Sun.COM 	}
30749585STim.Szeto@Sun.COM 
30759585STim.Szeto@Sun.COM 	return (-1);
30769585STim.Szeto@Sun.COM }
30779585STim.Szeto@Sun.COM 
30789585STim.Szeto@Sun.COM int
30799585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl)
30809585STim.Szeto@Sun.COM {
30819585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
30829585STim.Szeto@Sun.COM 	if (hdl == NULL) {
30839585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
30849585STim.Szeto@Sun.COM 	}
30859585STim.Szeto@Sun.COM 
30869585STim.Szeto@Sun.COM 	luResourceImpl *hdlImpl = hdl;
30879585STim.Szeto@Sun.COM 	free(hdlImpl->resource);
30889585STim.Szeto@Sun.COM 	free(hdlImpl);
30899585STim.Szeto@Sun.COM 	return (ret);
30909585STim.Szeto@Sun.COM }
30919585STim.Szeto@Sun.COM 
30929585STim.Szeto@Sun.COM /*
30939585STim.Szeto@Sun.COM  * Convert a string of the form '100G' into a real number. Used when setting
30949585STim.Szeto@Sun.COM  * the size of a logical unit.
30959585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
30969585STim.Szeto@Sun.COM  */
30979585STim.Szeto@Sun.COM static int
30989585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num)
30999585STim.Szeto@Sun.COM {
31009585STim.Szeto@Sun.COM 	char *end;
31019585STim.Szeto@Sun.COM 	int shift;
31029585STim.Szeto@Sun.COM 
31039585STim.Szeto@Sun.COM 	*num = 0;
31049585STim.Szeto@Sun.COM 
31059585STim.Szeto@Sun.COM 	/* Check to see if this looks like a number.  */
31069585STim.Szeto@Sun.COM 	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
31079585STim.Szeto@Sun.COM 		return (-1);
31089585STim.Szeto@Sun.COM 	}
31099585STim.Szeto@Sun.COM 
31109585STim.Szeto@Sun.COM 	/* Rely on stroull() to process the numeric portion.  */
31119585STim.Szeto@Sun.COM 	errno = 0;
31129585STim.Szeto@Sun.COM 	*num = strtoull(value, &end, 10);
31139585STim.Szeto@Sun.COM 
31149585STim.Szeto@Sun.COM 	/*
31159585STim.Szeto@Sun.COM 	 * Check for ERANGE, which indicates that the value is too large to fit
31169585STim.Szeto@Sun.COM 	 * in a 64-bit value.
31179585STim.Szeto@Sun.COM 	 */
31189585STim.Szeto@Sun.COM 	if (errno == ERANGE) {
31199585STim.Szeto@Sun.COM 		return (-1);
31209585STim.Szeto@Sun.COM 	}
31219585STim.Szeto@Sun.COM 
31229585STim.Szeto@Sun.COM 	/*
31239585STim.Szeto@Sun.COM 	 * If we have a decimal value, then do the computation with floating
31249585STim.Szeto@Sun.COM 	 * point arithmetic.  Otherwise, use standard arithmetic.
31259585STim.Szeto@Sun.COM 	 */
31269585STim.Szeto@Sun.COM 	if (*end == '.') {
31279585STim.Szeto@Sun.COM 		double fval = strtod(value, &end);
31289585STim.Szeto@Sun.COM 
31299585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
31309585STim.Szeto@Sun.COM 			return (-1);
31319585STim.Szeto@Sun.COM 		}
31329585STim.Szeto@Sun.COM 
31339585STim.Szeto@Sun.COM 		fval *= pow(2, shift);
31349585STim.Szeto@Sun.COM 
31359585STim.Szeto@Sun.COM 		if (fval > UINT64_MAX) {
31369585STim.Szeto@Sun.COM 			return (-1);
31379585STim.Szeto@Sun.COM 		}
31389585STim.Szeto@Sun.COM 
31399585STim.Szeto@Sun.COM 		*num = (uint64_t)fval;
31409585STim.Szeto@Sun.COM 	} else {
31419585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
31429585STim.Szeto@Sun.COM 			return (-1);
31439585STim.Szeto@Sun.COM 		}
31449585STim.Szeto@Sun.COM 
31459585STim.Szeto@Sun.COM 		/* Check for overflow */
31469585STim.Szeto@Sun.COM 		if (shift >= 64 || (*num << shift) >> shift != *num) {
31479585STim.Szeto@Sun.COM 			return (-1);
31489585STim.Szeto@Sun.COM 		}
31499585STim.Szeto@Sun.COM 
31509585STim.Szeto@Sun.COM 		*num <<= shift;
31519585STim.Szeto@Sun.COM 	}
31529585STim.Szeto@Sun.COM 
31539585STim.Szeto@Sun.COM 	return (0);
31549585STim.Szeto@Sun.COM }
31559585STim.Szeto@Sun.COM 
31569585STim.Szeto@Sun.COM /*
31577836SJohn.Forte@Sun.COM  * stmfCreateTargetGroup
31587836SJohn.Forte@Sun.COM  *
31597836SJohn.Forte@Sun.COM  * Purpose: Create a local port group
31607836SJohn.Forte@Sun.COM  *
31617836SJohn.Forte@Sun.COM  * targetGroupName - name of local port group to create
31627836SJohn.Forte@Sun.COM  */
31637836SJohn.Forte@Sun.COM int
31647836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName)
31657836SJohn.Forte@Sun.COM {
31667836SJohn.Forte@Sun.COM 	int ret;
31677836SJohn.Forte@Sun.COM 	int fd;
31687836SJohn.Forte@Sun.COM 
31697836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
31707836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
31717836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
31727836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31737836SJohn.Forte@Sun.COM 	}
31747836SJohn.Forte@Sun.COM 
31757836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
31767836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
31777836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
31787836SJohn.Forte@Sun.COM 	}
31797836SJohn.Forte@Sun.COM 
31807836SJohn.Forte@Sun.COM 	/* call init */
31817836SJohn.Forte@Sun.COM 	ret = initializeConfig();
31827836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
31837836SJohn.Forte@Sun.COM 		return (ret);
31847836SJohn.Forte@Sun.COM 	}
31857836SJohn.Forte@Sun.COM 
31867836SJohn.Forte@Sun.COM 	/*
31877836SJohn.Forte@Sun.COM 	 * Open control node for stmf
31887836SJohn.Forte@Sun.COM 	 */
31897836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
31907836SJohn.Forte@Sun.COM 		return (ret);
31917836SJohn.Forte@Sun.COM 
31927836SJohn.Forte@Sun.COM 	/*
31937836SJohn.Forte@Sun.COM 	 * Add the group to the driver
31947836SJohn.Forte@Sun.COM 	 */
31957836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
31967836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
31977836SJohn.Forte@Sun.COM 		goto done;
31987836SJohn.Forte@Sun.COM 	}
31997836SJohn.Forte@Sun.COM 
32009585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
32019585STim.Szeto@Sun.COM 		goto done;
32029585STim.Szeto@Sun.COM 	}
32039585STim.Szeto@Sun.COM 
32047836SJohn.Forte@Sun.COM 	/*
32057836SJohn.Forte@Sun.COM 	 * If the add to the driver was successful, add it to the persistent
32067836SJohn.Forte@Sun.COM 	 * store.
32077836SJohn.Forte@Sun.COM 	 */
32087836SJohn.Forte@Sun.COM 	ret = psCreateTargetGroup((char *)targetGroupName);
32097836SJohn.Forte@Sun.COM 	switch (ret) {
32107836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
32117836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
32127836SJohn.Forte@Sun.COM 			break;
32137836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
32147836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
32157836SJohn.Forte@Sun.COM 			break;
32167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
32177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
32187836SJohn.Forte@Sun.COM 			break;
32197836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
32207836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
32217836SJohn.Forte@Sun.COM 			break;
32227836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
32237836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
32247836SJohn.Forte@Sun.COM 			break;
32257836SJohn.Forte@Sun.COM 		default:
32267836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
32277836SJohn.Forte@Sun.COM 			    "stmfCreateTargetGroup:psCreateTargetGroup"
32287836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
32297836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
32307836SJohn.Forte@Sun.COM 			break;
32317836SJohn.Forte@Sun.COM 	}
32327836SJohn.Forte@Sun.COM 
32337836SJohn.Forte@Sun.COM done:
32347836SJohn.Forte@Sun.COM 	(void) close(fd);
32357836SJohn.Forte@Sun.COM 	return (ret);
32367836SJohn.Forte@Sun.COM }
32377836SJohn.Forte@Sun.COM 
32387836SJohn.Forte@Sun.COM /*
32397836SJohn.Forte@Sun.COM  * stmfDeleteHostGroup
32407836SJohn.Forte@Sun.COM  *
32417836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
32427836SJohn.Forte@Sun.COM  *
32437836SJohn.Forte@Sun.COM  * hostGroupName - group to delete
32447836SJohn.Forte@Sun.COM  */
32457836SJohn.Forte@Sun.COM int
32467836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName)
32477836SJohn.Forte@Sun.COM {
32487836SJohn.Forte@Sun.COM 	int ret;
32497836SJohn.Forte@Sun.COM 	int fd;
32507836SJohn.Forte@Sun.COM 
32517836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL) {
32527836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32537836SJohn.Forte@Sun.COM 	}
32547836SJohn.Forte@Sun.COM 
32557836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
32567836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
32577836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
32587836SJohn.Forte@Sun.COM 	}
32597836SJohn.Forte@Sun.COM 
32607836SJohn.Forte@Sun.COM 	/* call init */
32617836SJohn.Forte@Sun.COM 	ret = initializeConfig();
32627836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
32637836SJohn.Forte@Sun.COM 		return (ret);
32647836SJohn.Forte@Sun.COM 	}
32657836SJohn.Forte@Sun.COM 
32667836SJohn.Forte@Sun.COM 	/*
32677836SJohn.Forte@Sun.COM 	 * Open control node for stmf
32687836SJohn.Forte@Sun.COM 	 */
32697836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
32707836SJohn.Forte@Sun.COM 		return (ret);
32717836SJohn.Forte@Sun.COM 
32727836SJohn.Forte@Sun.COM 	/*
32737836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
32747836SJohn.Forte@Sun.COM 	 */
32757836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
32767836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
32777836SJohn.Forte@Sun.COM 		goto done;
32787836SJohn.Forte@Sun.COM 	}
32797836SJohn.Forte@Sun.COM 
32809585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
32819585STim.Szeto@Sun.COM 		goto done;
32829585STim.Szeto@Sun.COM 	}
32839585STim.Szeto@Sun.COM 
32847836SJohn.Forte@Sun.COM 	/*
32857836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
32867836SJohn.Forte@Sun.COM 	 * persistent store.
32877836SJohn.Forte@Sun.COM 	 */
32887836SJohn.Forte@Sun.COM 	ret = psDeleteHostGroup((char *)hostGroupName);
32897836SJohn.Forte@Sun.COM 	switch (ret) {
32907836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
32917836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
32927836SJohn.Forte@Sun.COM 			break;
32937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
32947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
32957836SJohn.Forte@Sun.COM 			break;
32967836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
32977836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
32987836SJohn.Forte@Sun.COM 			break;
32997836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
33007836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
33017836SJohn.Forte@Sun.COM 			break;
33027836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
33037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
33047836SJohn.Forte@Sun.COM 			break;
33057836SJohn.Forte@Sun.COM 		default:
33067836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
33077836SJohn.Forte@Sun.COM 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
33087836SJohn.Forte@Sun.COM 			    ret);
33097836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
33107836SJohn.Forte@Sun.COM 			break;
33117836SJohn.Forte@Sun.COM 	}
33127836SJohn.Forte@Sun.COM 
33137836SJohn.Forte@Sun.COM done:
33147836SJohn.Forte@Sun.COM 	(void) close(fd);
33157836SJohn.Forte@Sun.COM 	return (ret);
33167836SJohn.Forte@Sun.COM }
33177836SJohn.Forte@Sun.COM 
33187836SJohn.Forte@Sun.COM /*
33197836SJohn.Forte@Sun.COM  * stmfDeleteTargetGroup
33207836SJohn.Forte@Sun.COM  *
33217836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
33227836SJohn.Forte@Sun.COM  *
33237836SJohn.Forte@Sun.COM  * targetGroupName - group to delete
33247836SJohn.Forte@Sun.COM  */
33257836SJohn.Forte@Sun.COM int
33267836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
33277836SJohn.Forte@Sun.COM {
33287836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
33297836SJohn.Forte@Sun.COM 	int fd;
33307836SJohn.Forte@Sun.COM 
33317836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL) {
33327836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33337836SJohn.Forte@Sun.COM 	}
33347836SJohn.Forte@Sun.COM 
33357836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
33367836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
33377836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
33387836SJohn.Forte@Sun.COM 	}
33397836SJohn.Forte@Sun.COM 
33407836SJohn.Forte@Sun.COM 	/* call init */
33417836SJohn.Forte@Sun.COM 	ret = initializeConfig();
33427836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
33437836SJohn.Forte@Sun.COM 		return (ret);
33447836SJohn.Forte@Sun.COM 	}
33457836SJohn.Forte@Sun.COM 
33467836SJohn.Forte@Sun.COM 	/*
33477836SJohn.Forte@Sun.COM 	 * Open control node for stmf
33487836SJohn.Forte@Sun.COM 	 */
33497836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
33507836SJohn.Forte@Sun.COM 		return (ret);
33517836SJohn.Forte@Sun.COM 
33527836SJohn.Forte@Sun.COM 	/*
33537836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
33547836SJohn.Forte@Sun.COM 	 */
33557836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
33567836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
33577836SJohn.Forte@Sun.COM 		goto done;
33587836SJohn.Forte@Sun.COM 	}
33597836SJohn.Forte@Sun.COM 
33609585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
33619585STim.Szeto@Sun.COM 		goto done;
33629585STim.Szeto@Sun.COM 	}
33639585STim.Szeto@Sun.COM 
33647836SJohn.Forte@Sun.COM 	/*
33657836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
33667836SJohn.Forte@Sun.COM 	 * persistent store.
33677836SJohn.Forte@Sun.COM 	 */
33687836SJohn.Forte@Sun.COM 	ret = psDeleteTargetGroup((char *)targetGroupName);
33697836SJohn.Forte@Sun.COM 	switch (ret) {
33707836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
33717836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
33727836SJohn.Forte@Sun.COM 			break;
33737836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
33747836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
33757836SJohn.Forte@Sun.COM 			break;
33767836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
33777836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
33787836SJohn.Forte@Sun.COM 			break;
33797836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
33807836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
33817836SJohn.Forte@Sun.COM 			break;
33827836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
33837836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
33847836SJohn.Forte@Sun.COM 			break;
33857836SJohn.Forte@Sun.COM 		default:
33867836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
33877836SJohn.Forte@Sun.COM 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
33887836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
33897836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
33907836SJohn.Forte@Sun.COM 			break;
33917836SJohn.Forte@Sun.COM 	}
33927836SJohn.Forte@Sun.COM 
33937836SJohn.Forte@Sun.COM done:
33947836SJohn.Forte@Sun.COM 	(void) close(fd);
33957836SJohn.Forte@Sun.COM 	return (ret);
33967836SJohn.Forte@Sun.COM }
33977836SJohn.Forte@Sun.COM 
33987836SJohn.Forte@Sun.COM /*
33997836SJohn.Forte@Sun.COM  * stmfDevidFromIscsiName
34007836SJohn.Forte@Sun.COM  *
34017836SJohn.Forte@Sun.COM  * Purpose: convert an iSCSI name to an stmf devid
34027836SJohn.Forte@Sun.COM  *
34037836SJohn.Forte@Sun.COM  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
34047836SJohn.Forte@Sun.COM  * devid - on success, contains the converted iscsi name
34057836SJohn.Forte@Sun.COM  */
34067836SJohn.Forte@Sun.COM int
34077836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
34087836SJohn.Forte@Sun.COM {
34097836SJohn.Forte@Sun.COM 	if (devid == NULL || iscsiName == NULL)
34107836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34117836SJohn.Forte@Sun.COM 
34127836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
34137836SJohn.Forte@Sun.COM 
34147836SJohn.Forte@Sun.COM 	/* Validate size of target */
34157836SJohn.Forte@Sun.COM 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
34167836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(EUI) ||
34177836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(IQN)) {
34187836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34197836SJohn.Forte@Sun.COM 	}
34207836SJohn.Forte@Sun.COM 
34217836SJohn.Forte@Sun.COM 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
34227836SJohn.Forte@Sun.COM 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
34237836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34247836SJohn.Forte@Sun.COM 	}
34257836SJohn.Forte@Sun.COM 
34267836SJohn.Forte@Sun.COM 	/* copy UTF-8 bytes to ident */
34277836SJohn.Forte@Sun.COM 	bcopy(iscsiName, devid->ident, devid->identLength);
34287836SJohn.Forte@Sun.COM 
34297836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
34307836SJohn.Forte@Sun.COM }
34317836SJohn.Forte@Sun.COM 
34327836SJohn.Forte@Sun.COM /*
34337836SJohn.Forte@Sun.COM  * stmfDevidFromWwn
34347836SJohn.Forte@Sun.COM  *
34357836SJohn.Forte@Sun.COM  * Purpose: convert a WWN to an stmf devid
34367836SJohn.Forte@Sun.COM  *
34377836SJohn.Forte@Sun.COM  * wwn - 8-byte wwn identifier
34387836SJohn.Forte@Sun.COM  * devid - on success, contains the converted wwn
34397836SJohn.Forte@Sun.COM  */
34407836SJohn.Forte@Sun.COM int
34417836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
34427836SJohn.Forte@Sun.COM {
34437836SJohn.Forte@Sun.COM 	if (wwn == NULL || devid == NULL)
34447836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34457836SJohn.Forte@Sun.COM 
34467836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
34477836SJohn.Forte@Sun.COM 
34487836SJohn.Forte@Sun.COM 	/* Copy eui prefix */
34497836SJohn.Forte@Sun.COM 	(void) bcopy(WWN, devid->ident, strlen(WWN));
34507836SJohn.Forte@Sun.COM 
34517836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
34527836SJohn.Forte@Sun.COM 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
34537836SJohn.Forte@Sun.COM 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
34547836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
34557836SJohn.Forte@Sun.COM 
34567836SJohn.Forte@Sun.COM 	devid->identLength = strlen((char *)devid->ident);
34577836SJohn.Forte@Sun.COM 
34587836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
34597836SJohn.Forte@Sun.COM }
34607836SJohn.Forte@Sun.COM 
34617836SJohn.Forte@Sun.COM /*
34627836SJohn.Forte@Sun.COM  * stmfFreeMemory
34637836SJohn.Forte@Sun.COM  *
34647836SJohn.Forte@Sun.COM  * Purpose: Free memory allocated by this library
34657836SJohn.Forte@Sun.COM  *
34667836SJohn.Forte@Sun.COM  * memory - previously allocated pointer of memory managed by library
34677836SJohn.Forte@Sun.COM  */
34687836SJohn.Forte@Sun.COM void
34697836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory)
34707836SJohn.Forte@Sun.COM {
34717836SJohn.Forte@Sun.COM 	free(memory);
34727836SJohn.Forte@Sun.COM }
34737836SJohn.Forte@Sun.COM 
34747836SJohn.Forte@Sun.COM /*
34759585STim.Szeto@Sun.COM  * get host group, target group list from stmf
34767836SJohn.Forte@Sun.COM  *
34779585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
34787836SJohn.Forte@Sun.COM  */
34799585STim.Szeto@Sun.COM static int
34809585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType)
34819585STim.Szeto@Sun.COM {
34829585STim.Szeto@Sun.COM 	int ret;
34839585STim.Szeto@Sun.COM 	int fd;
34849585STim.Szeto@Sun.COM 	int ioctlRet;
34859585STim.Szeto@Sun.COM 	int i;
34869585STim.Szeto@Sun.COM 	int cmd;
34879585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
34889585STim.Szeto@Sun.COM 	/* framework group list */
34899585STim.Szeto@Sun.COM 	stmf_group_name_t *iGroupList = NULL;
34909585STim.Szeto@Sun.COM 	uint32_t groupListSize;
34919585STim.Szeto@Sun.COM 
34929585STim.Szeto@Sun.COM 	if (groupList == NULL) {
34939585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34949585STim.Szeto@Sun.COM 	}
34959585STim.Szeto@Sun.COM 
34969585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
34979585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_LIST;
34989585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
34999585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_LIST;
35009585STim.Szeto@Sun.COM 	} else {
35019585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35029585STim.Szeto@Sun.COM 	}
35039585STim.Szeto@Sun.COM 
35049585STim.Szeto@Sun.COM 	/* call init */
35059585STim.Szeto@Sun.COM 	ret = initializeConfig();
35069585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
35079585STim.Szeto@Sun.COM 		return (ret);
35089585STim.Szeto@Sun.COM 	}
35099585STim.Szeto@Sun.COM 
35109585STim.Szeto@Sun.COM 	/*
35119585STim.Szeto@Sun.COM 	 * Open control node for stmf
35129585STim.Szeto@Sun.COM 	 */
35139585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
35149585STim.Szeto@Sun.COM 		return (ret);
35159585STim.Szeto@Sun.COM 
35169585STim.Szeto@Sun.COM 	/*
35179585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
35189585STim.Szeto@Sun.COM 	 */
35199585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GROUP;
35209585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_group_name_t));
35219585STim.Szeto@Sun.COM 	iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
35229585STim.Szeto@Sun.COM 	if (iGroupList == NULL) {
35239585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
35249585STim.Szeto@Sun.COM 		goto done;
35259585STim.Szeto@Sun.COM 	}
35269585STim.Szeto@Sun.COM 
35279585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
35289585STim.Szeto@Sun.COM 	/*
35299585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
35309585STim.Szeto@Sun.COM 	 */
35319585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
35329585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
35339585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
35349585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
35359585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
35369585STim.Szeto@Sun.COM 		switch (errno) {
35379585STim.Szeto@Sun.COM 			case EBUSY:
35389585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
35399585STim.Szeto@Sun.COM 				break;
35409585STim.Szeto@Sun.COM 			case EPERM:
35419585STim.Szeto@Sun.COM 			case EACCES:
35429585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
35439585STim.Szeto@Sun.COM 				break;
35449585STim.Szeto@Sun.COM 			default:
35459585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
35469585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
35479585STim.Szeto@Sun.COM 				    errno);
35489585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
35499585STim.Szeto@Sun.COM 				break;
35509585STim.Szeto@Sun.COM 		}
35519585STim.Szeto@Sun.COM 		goto done;
35529585STim.Szeto@Sun.COM 	}
35539585STim.Szeto@Sun.COM 	/*
35549585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
35559585STim.Szeto@Sun.COM 	 */
35569585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
35579585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
35589585STim.Szeto@Sun.COM 		    sizeof (stmf_group_name_t);
35599585STim.Szeto@Sun.COM 		iGroupList = realloc(iGroupList, groupListSize);
35609585STim.Szeto@Sun.COM 		if (iGroupList == NULL) {
35619585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
35629585STim.Szeto@Sun.COM 			goto done;
35639585STim.Szeto@Sun.COM 		}
35649585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
35659585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
35669585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
35679585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
35689585STim.Szeto@Sun.COM 			switch (errno) {
35699585STim.Szeto@Sun.COM 				case EBUSY:
35709585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
35719585STim.Szeto@Sun.COM 					break;
35729585STim.Szeto@Sun.COM 				case EPERM:
35739585STim.Szeto@Sun.COM 				case EACCES:
35749585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
35759585STim.Szeto@Sun.COM 					break;
35769585STim.Szeto@Sun.COM 				default:
35779585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
35789585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
35799585STim.Szeto@Sun.COM 					    errno);
35809585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
35819585STim.Szeto@Sun.COM 					break;
35829585STim.Szeto@Sun.COM 			}
35839585STim.Szeto@Sun.COM 			goto done;
35849585STim.Szeto@Sun.COM 		}
35859585STim.Szeto@Sun.COM 	}
35869585STim.Szeto@Sun.COM 
35879585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
358810236SSrivijitha.Dugganapalli@Sun.COM 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
358910236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries);
35909585STim.Szeto@Sun.COM 	if (*groupList == NULL) {
35919585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
35929585STim.Szeto@Sun.COM 		goto done;
35939585STim.Szeto@Sun.COM 	}
35949585STim.Szeto@Sun.COM 	(*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
35959585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
359610113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupList[i].name, (*groupList)->name[i],
35979585STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
35989585STim.Szeto@Sun.COM 	}
35999585STim.Szeto@Sun.COM 
36009585STim.Szeto@Sun.COM done:
36019585STim.Szeto@Sun.COM 	free(iGroupList);
36029585STim.Szeto@Sun.COM 	(void) close(fd);
36039585STim.Szeto@Sun.COM 	return (ret);
36049585STim.Szeto@Sun.COM }
36059585STim.Szeto@Sun.COM 
36069585STim.Szeto@Sun.COM /*
36079585STim.Szeto@Sun.COM  * get host group members, target group members from stmf
36089585STim.Szeto@Sun.COM  *
36099585STim.Szeto@Sun.COM  * groupProps - allocated on success
36109585STim.Szeto@Sun.COM  *
36119585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
36129585STim.Szeto@Sun.COM  */
36139585STim.Szeto@Sun.COM static int
36149585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
36159585STim.Szeto@Sun.COM     int groupType)
36167836SJohn.Forte@Sun.COM {
36177836SJohn.Forte@Sun.COM 	int ret;
36189585STim.Szeto@Sun.COM 	int fd;
36199585STim.Szeto@Sun.COM 	int ioctlRet;
36209585STim.Szeto@Sun.COM 	int i;
36219585STim.Szeto@Sun.COM 	int cmd;
36229585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
36239585STim.Szeto@Sun.COM 	/* framework group list */
36249585STim.Szeto@Sun.COM 	stmf_group_name_t iGroupName;
36259585STim.Szeto@Sun.COM 	stmf_ge_ident_t *iGroupMembers;
36269585STim.Szeto@Sun.COM 	uint32_t groupListSize;
36279585STim.Szeto@Sun.COM 
36289585STim.Szeto@Sun.COM 	if (groupName == NULL) {
36299585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36309585STim.Szeto@Sun.COM 	}
36319585STim.Szeto@Sun.COM 
36329585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
36339585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_ENTRIES;
36349585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
36359585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_ENTRIES;
36369585STim.Szeto@Sun.COM 	} else {
36377836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36387836SJohn.Forte@Sun.COM 	}
36397836SJohn.Forte@Sun.COM 
36409585STim.Szeto@Sun.COM 	/* call init */
36419585STim.Szeto@Sun.COM 	ret = initializeConfig();
36429585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
36439585STim.Szeto@Sun.COM 		return (ret);
36449585STim.Szeto@Sun.COM 	}
36459585STim.Szeto@Sun.COM 
36469585STim.Szeto@Sun.COM 	/*
36479585STim.Szeto@Sun.COM 	 * Open control node for stmf
36489585STim.Szeto@Sun.COM 	 */
36499585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
36509585STim.Szeto@Sun.COM 		return (ret);
36519585STim.Szeto@Sun.COM 
36529585STim.Szeto@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
36539585STim.Szeto@Sun.COM 
36549585STim.Szeto@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
36559585STim.Szeto@Sun.COM 
36569585STim.Szeto@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
36579585STim.Szeto@Sun.COM 
36589585STim.Szeto@Sun.COM 	/*
36599585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
36609585STim.Szeto@Sun.COM 	 */
36619585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GRP_MEMBER;
36629585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
36639585STim.Szeto@Sun.COM 	iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
36649585STim.Szeto@Sun.COM 	if (iGroupMembers == NULL) {
36659585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
36669585STim.Szeto@Sun.COM 		goto done;
36679585STim.Szeto@Sun.COM 	}
36689585STim.Szeto@Sun.COM 
36699585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
36709585STim.Szeto@Sun.COM 	/*
36719585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
36729585STim.Szeto@Sun.COM 	 */
36739585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
36749585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
36759585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
36769585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
36779585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
36789585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
36799585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
36809585STim.Szeto@Sun.COM 		switch (errno) {
36819585STim.Szeto@Sun.COM 			case EBUSY:
36829585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
36839585STim.Szeto@Sun.COM 				break;
36849585STim.Szeto@Sun.COM 			case EPERM:
36859585STim.Szeto@Sun.COM 			case EACCES:
36869585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
36879585STim.Szeto@Sun.COM 				break;
36889585STim.Szeto@Sun.COM 			default:
36899585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
36909585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
36919585STim.Szeto@Sun.COM 				    errno);
36929585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
36939585STim.Szeto@Sun.COM 				break;
36949585STim.Szeto@Sun.COM 		}
36959585STim.Szeto@Sun.COM 		goto done;
36969585STim.Szeto@Sun.COM 	}
36979585STim.Szeto@Sun.COM 	/*
36989585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
36999585STim.Szeto@Sun.COM 	 */
37009585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
37019585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
37029585STim.Szeto@Sun.COM 		    sizeof (stmf_ge_ident_t);
37039585STim.Szeto@Sun.COM 		iGroupMembers = realloc(iGroupMembers, groupListSize);
37049585STim.Szeto@Sun.COM 		if (iGroupMembers == NULL) {
37059585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
37069585STim.Szeto@Sun.COM 			goto done;
37079585STim.Szeto@Sun.COM 		}
37089585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
37099585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
37109585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
37119585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
37129585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
37139585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
37149585STim.Szeto@Sun.COM 			switch (errno) {
37159585STim.Szeto@Sun.COM 				case EBUSY:
37169585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
37179585STim.Szeto@Sun.COM 					break;
37189585STim.Szeto@Sun.COM 				case EPERM:
37199585STim.Szeto@Sun.COM 				case EACCES:
37209585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
37219585STim.Szeto@Sun.COM 					break;
37229585STim.Szeto@Sun.COM 				default:
37239585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
37249585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
37259585STim.Szeto@Sun.COM 					    errno);
37269585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
37279585STim.Szeto@Sun.COM 					break;
37289585STim.Szeto@Sun.COM 			}
37299585STim.Szeto@Sun.COM 			goto done;
37309585STim.Szeto@Sun.COM 		}
37319585STim.Szeto@Sun.COM 	}
37329585STim.Szeto@Sun.COM 
37339585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
37349585STim.Szeto@Sun.COM 	*groupProps = (stmfGroupProperties *)calloc(1,
373510236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupProperties) +
373610236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries);
37379585STim.Szeto@Sun.COM 	if (*groupProps == NULL) {
37389585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
37399585STim.Szeto@Sun.COM 		goto done;
37409585STim.Szeto@Sun.COM 	}
37419585STim.Szeto@Sun.COM 	(*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
37429585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
37439585STim.Szeto@Sun.COM 		(*groupProps)->name[i].identLength =
374410113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size;
374510113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
374610113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size);
37479585STim.Szeto@Sun.COM 	}
37489585STim.Szeto@Sun.COM 
37499585STim.Szeto@Sun.COM done:
37509585STim.Szeto@Sun.COM 	free(iGroupMembers);
37519585STim.Szeto@Sun.COM 	(void) close(fd);
37529585STim.Szeto@Sun.COM 	return (ret);
37539585STim.Szeto@Sun.COM }
37549585STim.Szeto@Sun.COM 
37559585STim.Szeto@Sun.COM /*
37569585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
37579585STim.Szeto@Sun.COM  */
37589585STim.Szeto@Sun.COM static int
37599585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type)
37609585STim.Szeto@Sun.COM {
37619585STim.Szeto@Sun.COM 	int ret;
37629585STim.Szeto@Sun.COM 
37639585STim.Szeto@Sun.COM 	if (groupList == NULL) {
37649585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
37659585STim.Szeto@Sun.COM 	}
37669585STim.Szeto@Sun.COM 
37679585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
37689585STim.Szeto@Sun.COM 		ret = psGetHostGroupList(groupList);
37699585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
37709585STim.Szeto@Sun.COM 		ret = psGetTargetGroupList(groupList);
37719585STim.Szeto@Sun.COM 	} else {
37729585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
37739585STim.Szeto@Sun.COM 	}
37747836SJohn.Forte@Sun.COM 	switch (ret) {
37757836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
37767836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
37777836SJohn.Forte@Sun.COM 			break;
37787836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
37797836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
37807836SJohn.Forte@Sun.COM 			break;
37817836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
37827836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
37837836SJohn.Forte@Sun.COM 			break;
37847836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
37857836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
37867836SJohn.Forte@Sun.COM 			break;
37877836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
37887836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
37897836SJohn.Forte@Sun.COM 			break;
37907836SJohn.Forte@Sun.COM 		default:
37917836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
37927836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
37937836SJohn.Forte@Sun.COM 			    ret);
37947836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
37957836SJohn.Forte@Sun.COM 			break;
37967836SJohn.Forte@Sun.COM 	}
37977836SJohn.Forte@Sun.COM 
37987836SJohn.Forte@Sun.COM 	return (ret);
37997836SJohn.Forte@Sun.COM }
38007836SJohn.Forte@Sun.COM 
38017836SJohn.Forte@Sun.COM /*
38029585STim.Szeto@Sun.COM  * stmfGetHostGroupList
38037836SJohn.Forte@Sun.COM  *
38049585STim.Szeto@Sun.COM  * Purpose: Retrieves the list of initiator group oids
38059585STim.Szeto@Sun.COM  *
38069585STim.Szeto@Sun.COM  * hostGroupList - pointer to pointer to hostGroupList structure
38079585STim.Szeto@Sun.COM  *                 on success, this contains the host group list.
38087836SJohn.Forte@Sun.COM  */
38097836SJohn.Forte@Sun.COM int
38109585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList)
38119585STim.Szeto@Sun.COM {
38129585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
38139585STim.Szeto@Sun.COM 
38149585STim.Szeto@Sun.COM 	if (hostGroupList == NULL) {
38159585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38169585STim.Szeto@Sun.COM 	}
38179585STim.Szeto@Sun.COM 
38189585STim.Szeto@Sun.COM 	ret = groupListIoctl(hostGroupList, HOST_GROUP);
38199585STim.Szeto@Sun.COM 	return (ret);
38209585STim.Szeto@Sun.COM }
38219585STim.Szeto@Sun.COM 
38229585STim.Szeto@Sun.COM 
38239585STim.Szeto@Sun.COM /*
38249585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
38259585STim.Szeto@Sun.COM  */
38269585STim.Szeto@Sun.COM static int
38279585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName,
38289585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp, int type)
38297836SJohn.Forte@Sun.COM {
38307836SJohn.Forte@Sun.COM 	int ret;
38317836SJohn.Forte@Sun.COM 
38329585STim.Szeto@Sun.COM 	if (groupName == NULL) {
38337836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38347836SJohn.Forte@Sun.COM 	}
38357836SJohn.Forte@Sun.COM 
38369585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
38379585STim.Szeto@Sun.COM 		ret = psGetHostGroupMemberList((char *)groupName, groupProp);
38389585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
38399585STim.Szeto@Sun.COM 		ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
38409585STim.Szeto@Sun.COM 	} else {
38419585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38429585STim.Szeto@Sun.COM 	}
38437836SJohn.Forte@Sun.COM 	switch (ret) {
38447836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
38457836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
38467836SJohn.Forte@Sun.COM 			break;
38477836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
38487836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
38497836SJohn.Forte@Sun.COM 			break;
38507836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
38517836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
38527836SJohn.Forte@Sun.COM 			break;
38537836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
38547836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
38557836SJohn.Forte@Sun.COM 			break;
38567836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
38577836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
38587836SJohn.Forte@Sun.COM 			break;
38597836SJohn.Forte@Sun.COM 		default:
38607836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
38619585STim.Szeto@Sun.COM 			    "iLoadGroupMembersFromPs:psGetHostGroupList:"
38629585STim.Szeto@Sun.COM 			    "error(%d)", ret);
38637836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
38647836SJohn.Forte@Sun.COM 			break;
38657836SJohn.Forte@Sun.COM 	}
38667836SJohn.Forte@Sun.COM 
38677836SJohn.Forte@Sun.COM 	return (ret);
38687836SJohn.Forte@Sun.COM }
38697836SJohn.Forte@Sun.COM 
38707836SJohn.Forte@Sun.COM /*
38719585STim.Szeto@Sun.COM  * stmfGetHostGroupMembers
38729585STim.Szeto@Sun.COM  *
38739585STim.Szeto@Sun.COM  * Purpose: Retrieves the group properties for a host group
38749585STim.Szeto@Sun.COM  *
38759585STim.Szeto@Sun.COM  * groupName - name of group for which to retrieve host group members.
38769585STim.Szeto@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
38779585STim.Szeto@Sun.COM  *             on success, this contains the list of group members.
38789585STim.Szeto@Sun.COM  */
38799585STim.Szeto@Sun.COM int
38809585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName,
38819585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp)
38829585STim.Szeto@Sun.COM {
38839585STim.Szeto@Sun.COM 	int ret;
38849585STim.Szeto@Sun.COM 
38859585STim.Szeto@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
38869585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38879585STim.Szeto@Sun.COM 	}
38889585STim.Szeto@Sun.COM 
38899585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
38909585STim.Szeto@Sun.COM 
38919585STim.Szeto@Sun.COM 	return (ret);
38929585STim.Szeto@Sun.COM }
38939585STim.Szeto@Sun.COM 
38949585STim.Szeto@Sun.COM /*
38957836SJohn.Forte@Sun.COM  * stmfGetProviderData
38967836SJohn.Forte@Sun.COM  *
38977836SJohn.Forte@Sun.COM  * Purpose: Get provider data list
38987836SJohn.Forte@Sun.COM  *
38997836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
39007836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
39017836SJohn.Forte@Sun.COM  *       retrieved.
39027836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
39037836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
39047836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
39057836SJohn.Forte@Sun.COM  */
39067836SJohn.Forte@Sun.COM int
39077836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
39087836SJohn.Forte@Sun.COM {
39097836SJohn.Forte@Sun.COM 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
39107836SJohn.Forte@Sun.COM 	    NULL));
39117836SJohn.Forte@Sun.COM }
39127836SJohn.Forte@Sun.COM 
39137836SJohn.Forte@Sun.COM /*
39147836SJohn.Forte@Sun.COM  * stmfGetProviderDataProt
39157836SJohn.Forte@Sun.COM  *
39167836SJohn.Forte@Sun.COM  * Purpose: Get provider data list with token
39177836SJohn.Forte@Sun.COM  *
39187836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
39197836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
39207836SJohn.Forte@Sun.COM  *       retrieved.
39217836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
39227836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
39237836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
39247836SJohn.Forte@Sun.COM  * setToken - Returns the stale data token
39257836SJohn.Forte@Sun.COM  */
39267836SJohn.Forte@Sun.COM int
39277836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
39287836SJohn.Forte@Sun.COM     uint64_t *setToken)
39297836SJohn.Forte@Sun.COM {
39307836SJohn.Forte@Sun.COM 	int ret;
39317836SJohn.Forte@Sun.COM 
39327836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
39337836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39347836SJohn.Forte@Sun.COM 	}
39357836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
39367836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
39377836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39387836SJohn.Forte@Sun.COM 	}
39397836SJohn.Forte@Sun.COM 	/* call init */
39407836SJohn.Forte@Sun.COM 	ret = initializeConfig();
39417836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
39427836SJohn.Forte@Sun.COM 		return (ret);
39437836SJohn.Forte@Sun.COM 	}
39449585STim.Szeto@Sun.COM 	return (getProviderData(providerName, nvl, providerType, setToken));
39457836SJohn.Forte@Sun.COM }
39467836SJohn.Forte@Sun.COM 
39477836SJohn.Forte@Sun.COM /*
39487836SJohn.Forte@Sun.COM  * stmfGetProviderDataList
39497836SJohn.Forte@Sun.COM  *
39507836SJohn.Forte@Sun.COM  * Purpose: Get the list of providers currently persisting data
39517836SJohn.Forte@Sun.COM  *
39527836SJohn.Forte@Sun.COM  * providerList - pointer to pointer to an stmfProviderList structure allocated
39537836SJohn.Forte@Sun.COM  *                by the caller. Will contain the list of providers on success.
39547836SJohn.Forte@Sun.COM  */
39557836SJohn.Forte@Sun.COM int
39567836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList)
39577836SJohn.Forte@Sun.COM {
39587836SJohn.Forte@Sun.COM 	int ret;
39597836SJohn.Forte@Sun.COM 
39607836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(providerList);
39617836SJohn.Forte@Sun.COM 	switch (ret) {
39627836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
39637836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
39647836SJohn.Forte@Sun.COM 			break;
39657836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
39667836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
39677836SJohn.Forte@Sun.COM 			break;
39687836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
39697836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
39707836SJohn.Forte@Sun.COM 			break;
39717836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
39727836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
39737836SJohn.Forte@Sun.COM 			break;
39747836SJohn.Forte@Sun.COM 		default:
39757836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
39767836SJohn.Forte@Sun.COM 			    "stmfGetProviderDataList:psGetProviderDataList"
39777836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
39787836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
39797836SJohn.Forte@Sun.COM 			break;
39807836SJohn.Forte@Sun.COM 	}
39817836SJohn.Forte@Sun.COM 
39827836SJohn.Forte@Sun.COM 	return (ret);
39837836SJohn.Forte@Sun.COM }
39847836SJohn.Forte@Sun.COM 
39857836SJohn.Forte@Sun.COM 
39867836SJohn.Forte@Sun.COM /*
39877836SJohn.Forte@Sun.COM  * stmfGetSessionList
39887836SJohn.Forte@Sun.COM  *
39897836SJohn.Forte@Sun.COM  * Purpose: Retrieves the session list for a target (devid)
39907836SJohn.Forte@Sun.COM  *
39917836SJohn.Forte@Sun.COM  * devid - devid of target for which to retrieve session information.
39927836SJohn.Forte@Sun.COM  * sessionList - pointer to pointer to stmfSessionList structure
39937836SJohn.Forte@Sun.COM  *             on success, this contains the list of initiator sessions.
39947836SJohn.Forte@Sun.COM  */
39957836SJohn.Forte@Sun.COM int
39967836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
39977836SJohn.Forte@Sun.COM {
39987836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
39997836SJohn.Forte@Sun.COM 	int fd;
40007836SJohn.Forte@Sun.COM 	int ioctlRet;
40017836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_SESSION_LIST;
40027836SJohn.Forte@Sun.COM 	int i;
40037836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
400410261SCharles.Ting@Sun.COM 	slist_scsi_session_t *fSessionList, *fSessionListP = NULL;
40057836SJohn.Forte@Sun.COM 	uint8_t ident[260];
40067836SJohn.Forte@Sun.COM 	uint32_t fSessionListSize;
40077836SJohn.Forte@Sun.COM 
40087836SJohn.Forte@Sun.COM 	if (sessionList == NULL || devid == NULL) {
40097836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
40107836SJohn.Forte@Sun.COM 	}
40117836SJohn.Forte@Sun.COM 
40127836SJohn.Forte@Sun.COM 	/* call init */
40137836SJohn.Forte@Sun.COM 	ret = initializeConfig();
40147836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
40157836SJohn.Forte@Sun.COM 		return (ret);
40167836SJohn.Forte@Sun.COM 	}
40177836SJohn.Forte@Sun.COM 
40187836SJohn.Forte@Sun.COM 	/*
40197836SJohn.Forte@Sun.COM 	 * Open control node for stmf
40207836SJohn.Forte@Sun.COM 	 */
40217836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
40227836SJohn.Forte@Sun.COM 		return (ret);
40237836SJohn.Forte@Sun.COM 
40247836SJohn.Forte@Sun.COM 	/*
40257836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
40267836SJohn.Forte@Sun.COM 	 */
40279585STim.Szeto@Sun.COM 	fSessionListSize = ALLOC_SESSION;
40287836SJohn.Forte@Sun.COM 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
40297836SJohn.Forte@Sun.COM 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
403010261SCharles.Ting@Sun.COM 	fSessionListP = fSessionList;
40317836SJohn.Forte@Sun.COM 	if (fSessionList == NULL) {
403210261SCharles.Ting@Sun.COM 		ret = STMF_ERROR_NOMEM;
403310261SCharles.Ting@Sun.COM 		goto done;
40347836SJohn.Forte@Sun.COM 	}
40357836SJohn.Forte@Sun.COM 
40367836SJohn.Forte@Sun.COM 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
40377836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
40387836SJohn.Forte@Sun.COM 	    devid->identLength);
40397836SJohn.Forte@Sun.COM 
40407836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
40417836SJohn.Forte@Sun.COM 	/*
40427836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the session list
40437836SJohn.Forte@Sun.COM 	 */
40447836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
40457836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
40467836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
40477836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fSessionListSize;
40487836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
40497836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
40507836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
40517836SJohn.Forte@Sun.COM 		switch (errno) {
40527836SJohn.Forte@Sun.COM 			case EBUSY:
40537836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
40547836SJohn.Forte@Sun.COM 				break;
40559585STim.Szeto@Sun.COM 			case EPERM:
40567836SJohn.Forte@Sun.COM 			case EACCES:
40577836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
40587836SJohn.Forte@Sun.COM 				break;
40597836SJohn.Forte@Sun.COM 			default:
40607836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
40617836SJohn.Forte@Sun.COM 				    "stmfGetSessionList:ioctl errno(%d)",
40627836SJohn.Forte@Sun.COM 				    errno);
40637836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
40647836SJohn.Forte@Sun.COM 				break;
40657836SJohn.Forte@Sun.COM 		}
40667836SJohn.Forte@Sun.COM 		goto done;
40677836SJohn.Forte@Sun.COM 	}
40687836SJohn.Forte@Sun.COM 	/*
40697836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
40707836SJohn.Forte@Sun.COM 	 */
40719585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
40727836SJohn.Forte@Sun.COM 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
40737836SJohn.Forte@Sun.COM 		    sizeof (slist_scsi_session_t);
40747836SJohn.Forte@Sun.COM 		fSessionList = realloc(fSessionList, fSessionListSize);
40757836SJohn.Forte@Sun.COM 		if (fSessionList == NULL) {
407610261SCharles.Ting@Sun.COM 			ret = STMF_ERROR_NOMEM;
407710261SCharles.Ting@Sun.COM 			goto done;
40787836SJohn.Forte@Sun.COM 		}
407910261SCharles.Ting@Sun.COM 		fSessionListP = fSessionList;
40807836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fSessionListSize;
40817836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
40827836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
40837836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
40847836SJohn.Forte@Sun.COM 			switch (errno) {
40857836SJohn.Forte@Sun.COM 				case EBUSY:
40867836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
40877836SJohn.Forte@Sun.COM 					break;
40889585STim.Szeto@Sun.COM 				case EPERM:
40897836SJohn.Forte@Sun.COM 				case EACCES:
40907836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
40917836SJohn.Forte@Sun.COM 					break;
40927836SJohn.Forte@Sun.COM 				default:
40937836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
40947836SJohn.Forte@Sun.COM 					    "stmfGetSessionList:ioctl "
40957836SJohn.Forte@Sun.COM 					    "errno(%d)", errno);
40967836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
40977836SJohn.Forte@Sun.COM 					break;
40987836SJohn.Forte@Sun.COM 			}
40997836SJohn.Forte@Sun.COM 			goto done;
41007836SJohn.Forte@Sun.COM 		}
41017836SJohn.Forte@Sun.COM 	}
41027836SJohn.Forte@Sun.COM 
41037836SJohn.Forte@Sun.COM 	/*
41047836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
41057836SJohn.Forte@Sun.COM 	 */
41067836SJohn.Forte@Sun.COM 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
41077836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
41087836SJohn.Forte@Sun.COM 	if (*sessionList == NULL) {
41097836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
41107836SJohn.Forte@Sun.COM 		free(sessionList);
41117836SJohn.Forte@Sun.COM 		goto done;
41127836SJohn.Forte@Sun.COM 	}
41137836SJohn.Forte@Sun.COM 
41147836SJohn.Forte@Sun.COM 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
41157836SJohn.Forte@Sun.COM 
41167836SJohn.Forte@Sun.COM 	/*
41177836SJohn.Forte@Sun.COM 	 * copy session info to caller's buffer
41187836SJohn.Forte@Sun.COM 	 */
41197836SJohn.Forte@Sun.COM 	for (i = 0; i < (*sessionList)->cnt; i++) {
41207836SJohn.Forte@Sun.COM 		(*sessionList)->session[i].initiator.identLength =
41217836SJohn.Forte@Sun.COM 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
41227836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
41237836SJohn.Forte@Sun.COM 		    (*sessionList)->session[i].initiator.ident,
41247836SJohn.Forte@Sun.COM 		    STMF_IDENT_LENGTH);
41257836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->alias),
41267836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].alias),
41277836SJohn.Forte@Sun.COM 		    sizeof ((*sessionList)->session[i].alias));
41287836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList++->creation_time),
41297836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].creationTime),
41307836SJohn.Forte@Sun.COM 		    sizeof (time_t));
41317836SJohn.Forte@Sun.COM 	}
41327836SJohn.Forte@Sun.COM done:
41337836SJohn.Forte@Sun.COM 	(void) close(fd);
413410261SCharles.Ting@Sun.COM 	free(fSessionListP);
41357836SJohn.Forte@Sun.COM 	return (ret);
41367836SJohn.Forte@Sun.COM }
41377836SJohn.Forte@Sun.COM 
41387836SJohn.Forte@Sun.COM /*
41397836SJohn.Forte@Sun.COM  * stmfGetTargetGroupList
41407836SJohn.Forte@Sun.COM  *
41417836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target groups
41427836SJohn.Forte@Sun.COM  *
41437836SJohn.Forte@Sun.COM  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
41447836SJohn.Forte@Sun.COM  *		     success, it contains the list of target groups.
41457836SJohn.Forte@Sun.COM  */
41467836SJohn.Forte@Sun.COM int
41477836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList)
41487836SJohn.Forte@Sun.COM {
41497836SJohn.Forte@Sun.COM 	int ret;
41507836SJohn.Forte@Sun.COM 
41517836SJohn.Forte@Sun.COM 	if (targetGroupList == NULL) {
41527836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
41537836SJohn.Forte@Sun.COM 	}
41547836SJohn.Forte@Sun.COM 
41559585STim.Szeto@Sun.COM 	ret = groupListIoctl(targetGroupList, TARGET_GROUP);
41567836SJohn.Forte@Sun.COM 	return (ret);
41577836SJohn.Forte@Sun.COM }
41587836SJohn.Forte@Sun.COM 
41597836SJohn.Forte@Sun.COM /*
41607836SJohn.Forte@Sun.COM  * stmfGetTargetGroupMembers
41617836SJohn.Forte@Sun.COM  *
41627836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group members for a target group
41637836SJohn.Forte@Sun.COM  *
41647836SJohn.Forte@Sun.COM  * groupName - name of target group for which to retrieve members.
41657836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
41667836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
41677836SJohn.Forte@Sun.COM  */
41687836SJohn.Forte@Sun.COM int
41697836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName,
41707836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
41717836SJohn.Forte@Sun.COM {
41727836SJohn.Forte@Sun.COM 	int ret;
41737836SJohn.Forte@Sun.COM 
41747836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
41757836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
41767836SJohn.Forte@Sun.COM 	}
41777836SJohn.Forte@Sun.COM 
41789585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
41797836SJohn.Forte@Sun.COM 
41807836SJohn.Forte@Sun.COM 	return (ret);
41817836SJohn.Forte@Sun.COM }
41827836SJohn.Forte@Sun.COM 
41837836SJohn.Forte@Sun.COM /*
41847836SJohn.Forte@Sun.COM  * stmfGetTargetList
41857836SJohn.Forte@Sun.COM  *
41867836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target ports
41877836SJohn.Forte@Sun.COM  *
41887836SJohn.Forte@Sun.COM  * targetList - pointer to a pointer to an stmfDevidList structure.
41897836SJohn.Forte@Sun.COM  *		    On success, it contains the list of local ports (target).
41907836SJohn.Forte@Sun.COM  */
41917836SJohn.Forte@Sun.COM int
41927836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList)
41937836SJohn.Forte@Sun.COM {
41947836SJohn.Forte@Sun.COM 	int ret;
41957836SJohn.Forte@Sun.COM 	int fd;
41967836SJohn.Forte@Sun.COM 	int ioctlRet;
41977836SJohn.Forte@Sun.COM 	int i;
41987836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
41997836SJohn.Forte@Sun.COM 	/* framework target port list */
42009585STim.Szeto@Sun.COM 	slist_target_port_t *fTargetList, *fTargetListP = NULL;
42017836SJohn.Forte@Sun.COM 	uint32_t fTargetListSize;
42027836SJohn.Forte@Sun.COM 
42037836SJohn.Forte@Sun.COM 	if (targetList == NULL) {
42047836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
42057836SJohn.Forte@Sun.COM 	}
42067836SJohn.Forte@Sun.COM 
42077836SJohn.Forte@Sun.COM 	/* call init */
42087836SJohn.Forte@Sun.COM 	ret = initializeConfig();
42097836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
42107836SJohn.Forte@Sun.COM 		return (ret);
42117836SJohn.Forte@Sun.COM 	}
42127836SJohn.Forte@Sun.COM 
42137836SJohn.Forte@Sun.COM 	/*
42147836SJohn.Forte@Sun.COM 	 * Open control node for stmf
42157836SJohn.Forte@Sun.COM 	 */
42167836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
42177836SJohn.Forte@Sun.COM 		return (ret);
42187836SJohn.Forte@Sun.COM 
42197836SJohn.Forte@Sun.COM 	/*
42207836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
42217836SJohn.Forte@Sun.COM 	 */
42229585STim.Szeto@Sun.COM 	fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
42238252SJohn.Forte@Sun.COM 	fTargetListP = fTargetList =
42248252SJohn.Forte@Sun.COM 	    (slist_target_port_t *)calloc(1, fTargetListSize);
42257836SJohn.Forte@Sun.COM 	if (fTargetList == NULL) {
42269585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
42277836SJohn.Forte@Sun.COM 		goto done;
42287836SJohn.Forte@Sun.COM 	}
42297836SJohn.Forte@Sun.COM 
42307836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
42317836SJohn.Forte@Sun.COM 	/*
42328252SJohn.Forte@Sun.COM 	 * Issue ioctl to retrieve target list
42337836SJohn.Forte@Sun.COM 	 */
42347836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
42357836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fTargetListSize;
42367836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
42377836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
42387836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
42397836SJohn.Forte@Sun.COM 		switch (errno) {
42407836SJohn.Forte@Sun.COM 			case EBUSY:
42417836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
42427836SJohn.Forte@Sun.COM 				break;
42439585STim.Szeto@Sun.COM 			case EPERM:
42447836SJohn.Forte@Sun.COM 			case EACCES:
42457836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
42467836SJohn.Forte@Sun.COM 				break;
42477836SJohn.Forte@Sun.COM 			default:
42487836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
42497836SJohn.Forte@Sun.COM 				    "stmfGetTargetList:ioctl errno(%d)", errno);
42507836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
42517836SJohn.Forte@Sun.COM 				break;
42527836SJohn.Forte@Sun.COM 		}
42537836SJohn.Forte@Sun.COM 		goto done;
42547836SJohn.Forte@Sun.COM 	}
42557836SJohn.Forte@Sun.COM 	/*
42567836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
42577836SJohn.Forte@Sun.COM 	 */
42589585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
42597836SJohn.Forte@Sun.COM 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
42608116SJohn.Forte@Sun.COM 		    sizeof (slist_target_port_t);
42618252SJohn.Forte@Sun.COM 		fTargetListP = fTargetList =
42628252SJohn.Forte@Sun.COM 		    realloc(fTargetList, fTargetListSize);
42637836SJohn.Forte@Sun.COM 		if (fTargetList == NULL) {
42649585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
42659585STim.Szeto@Sun.COM 			goto done;
42667836SJohn.Forte@Sun.COM 		}
42677836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fTargetListSize;
42687836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
42697836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
42707836SJohn.Forte@Sun.COM 		    &stmfIoctl);
42717836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
42727836SJohn.Forte@Sun.COM 			switch (errno) {
42737836SJohn.Forte@Sun.COM 				case EBUSY:
42747836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
42757836SJohn.Forte@Sun.COM 					break;
42769585STim.Szeto@Sun.COM 				case EPERM:
42777836SJohn.Forte@Sun.COM 				case EACCES:
42787836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
42797836SJohn.Forte@Sun.COM 					break;
42807836SJohn.Forte@Sun.COM 				default:
42817836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
42827836SJohn.Forte@Sun.COM 					    "stmfGetTargetList:ioctl errno(%d)",
42837836SJohn.Forte@Sun.COM 					    errno);
42847836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
42857836SJohn.Forte@Sun.COM 					break;
42867836SJohn.Forte@Sun.COM 			}
42877836SJohn.Forte@Sun.COM 			goto done;
42887836SJohn.Forte@Sun.COM 		}
42897836SJohn.Forte@Sun.COM 	}
42907836SJohn.Forte@Sun.COM 
42917836SJohn.Forte@Sun.COM 	*targetList = (stmfDevidList *)calloc(1,
42927836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
42937836SJohn.Forte@Sun.COM 	    sizeof (stmfDevidList));
42949585STim.Szeto@Sun.COM 	if (*targetList == NULL) {
42959585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
42969585STim.Szeto@Sun.COM 		goto done;
42979585STim.Szeto@Sun.COM 	}
42987836SJohn.Forte@Sun.COM 
42997836SJohn.Forte@Sun.COM 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
43007836SJohn.Forte@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
43017836SJohn.Forte@Sun.COM 		(*targetList)->devid[i].identLength =
43027836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE];
43037836SJohn.Forte@Sun.COM 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
43047836SJohn.Forte@Sun.COM 		    &(*targetList)->devid[i].ident,
43057836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE]);
43067836SJohn.Forte@Sun.COM 	}
43077836SJohn.Forte@Sun.COM 
43087836SJohn.Forte@Sun.COM done:
43097836SJohn.Forte@Sun.COM 	(void) close(fd);
43108252SJohn.Forte@Sun.COM 	free(fTargetListP);
43117836SJohn.Forte@Sun.COM 	return (ret);
43127836SJohn.Forte@Sun.COM }
43137836SJohn.Forte@Sun.COM 
43147836SJohn.Forte@Sun.COM /*
43157836SJohn.Forte@Sun.COM  * stmfGetTargetProperties
43167836SJohn.Forte@Sun.COM  *
43177836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
43187836SJohn.Forte@Sun.COM  *
43197836SJohn.Forte@Sun.COM  * devid - devid of the target for which to retrieve properties
43207836SJohn.Forte@Sun.COM  * targetProps - pointer to an stmfTargetProperties structure.
43217836SJohn.Forte@Sun.COM  *		On success, it contains the target properties for
43227836SJohn.Forte@Sun.COM  *		the specified devid.
43237836SJohn.Forte@Sun.COM  */
43247836SJohn.Forte@Sun.COM int
43257836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
43267836SJohn.Forte@Sun.COM {
43277836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
43287836SJohn.Forte@Sun.COM 	int fd;
43297836SJohn.Forte@Sun.COM 	int ioctlRet;
43307836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
43317836SJohn.Forte@Sun.COM 	sioc_target_port_props_t targetProperties;
433210725SJohn.Forte@Sun.COM 	scsi_devid_desc_t *scsiDevid;
43337836SJohn.Forte@Sun.COM 
43347836SJohn.Forte@Sun.COM 	if (devid == NULL || targetProps == NULL) {
43357836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
43367836SJohn.Forte@Sun.COM 	}
43377836SJohn.Forte@Sun.COM 
43387836SJohn.Forte@Sun.COM 	/* call init */
43397836SJohn.Forte@Sun.COM 	ret = initializeConfig();
43407836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
43417836SJohn.Forte@Sun.COM 		return (ret);
43427836SJohn.Forte@Sun.COM 	}
43437836SJohn.Forte@Sun.COM 
43447836SJohn.Forte@Sun.COM 	/*
43457836SJohn.Forte@Sun.COM 	 * Open control node for stmf
43467836SJohn.Forte@Sun.COM 	 */
43477836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
43487836SJohn.Forte@Sun.COM 		return (ret);
43497836SJohn.Forte@Sun.COM 
43507836SJohn.Forte@Sun.COM 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
43517836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
43527836SJohn.Forte@Sun.COM 	    devid->identLength);
43537836SJohn.Forte@Sun.COM 
43547836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
43557836SJohn.Forte@Sun.COM 	/*
43567836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
43577836SJohn.Forte@Sun.COM 	 */
43587836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
43597836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
43607836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
43617836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
43627836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
43637836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
43647836SJohn.Forte@Sun.COM 	    &stmfIoctl);
43657836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
43667836SJohn.Forte@Sun.COM 		switch (errno) {
43677836SJohn.Forte@Sun.COM 			case EBUSY:
43687836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
43697836SJohn.Forte@Sun.COM 				break;
43709585STim.Szeto@Sun.COM 			case EPERM:
43717836SJohn.Forte@Sun.COM 			case EACCES:
43727836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
43737836SJohn.Forte@Sun.COM 				break;
43747836SJohn.Forte@Sun.COM 			case ENOENT:
43757836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
43767836SJohn.Forte@Sun.COM 				break;
43777836SJohn.Forte@Sun.COM 			default:
43787836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
43797836SJohn.Forte@Sun.COM 				    "stmfGetTargetProperties:ioctl errno(%d)",
43807836SJohn.Forte@Sun.COM 				    errno);
43817836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
43827836SJohn.Forte@Sun.COM 				break;
43837836SJohn.Forte@Sun.COM 		}
43847836SJohn.Forte@Sun.COM 		goto done;
43857836SJohn.Forte@Sun.COM 	}
43867836SJohn.Forte@Sun.COM 
43877836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
43887836SJohn.Forte@Sun.COM 	    sizeof (targetProperties.tgt_provider_name));
43897836SJohn.Forte@Sun.COM 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
43907836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINE;
43917836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
43927836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
43937836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
43947836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINING;
43957836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
43967836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
43977836SJohn.Forte@Sun.COM 	}
43987836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_alias, targetProps->alias,
43997836SJohn.Forte@Sun.COM 	    sizeof (targetProps->alias));
440010725SJohn.Forte@Sun.COM 
440110725SJohn.Forte@Sun.COM 	scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id;
440210725SJohn.Forte@Sun.COM 	targetProps->protocol = scsiDevid->protocol_id;
440310725SJohn.Forte@Sun.COM 
44047836SJohn.Forte@Sun.COM done:
44057836SJohn.Forte@Sun.COM 	(void) close(fd);
44067836SJohn.Forte@Sun.COM 	return (ret);
44077836SJohn.Forte@Sun.COM }
44087836SJohn.Forte@Sun.COM 
44097836SJohn.Forte@Sun.COM /*
44107836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitList
44117836SJohn.Forte@Sun.COM  *
44127836SJohn.Forte@Sun.COM  * Purpose: Retrieves list of logical unit Object IDs
44137836SJohn.Forte@Sun.COM  *
44147836SJohn.Forte@Sun.COM  * luList - pointer to a pointer to a stmfGuidList structure. On success,
44157836SJohn.Forte@Sun.COM  *          it contains the list of logical unit guids.
44167836SJohn.Forte@Sun.COM  *
44177836SJohn.Forte@Sun.COM  */
44187836SJohn.Forte@Sun.COM int
44197836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList)
44207836SJohn.Forte@Sun.COM {
44217836SJohn.Forte@Sun.COM 	int ret;
44227836SJohn.Forte@Sun.COM 	int fd;
44237836SJohn.Forte@Sun.COM 	int ioctlRet;
44247836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_LU_LIST;
44259585STim.Szeto@Sun.COM 	int i;
44267836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
44277836SJohn.Forte@Sun.COM 	slist_lu_t *fLuList;
44287836SJohn.Forte@Sun.COM 	uint32_t fLuListSize;
44299585STim.Szeto@Sun.COM 	uint32_t listCnt;
44307836SJohn.Forte@Sun.COM 
44317836SJohn.Forte@Sun.COM 	if (luList == NULL) {
44327836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
44337836SJohn.Forte@Sun.COM 	}
44347836SJohn.Forte@Sun.COM 
44357836SJohn.Forte@Sun.COM 	/* call init */
44367836SJohn.Forte@Sun.COM 	ret = initializeConfig();
44377836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
44387836SJohn.Forte@Sun.COM 		return (ret);
44397836SJohn.Forte@Sun.COM 	}
44407836SJohn.Forte@Sun.COM 
44417836SJohn.Forte@Sun.COM 	/*
44427836SJohn.Forte@Sun.COM 	 * Open control node for stmf
44437836SJohn.Forte@Sun.COM 	 */
44447836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
44457836SJohn.Forte@Sun.COM 		return (ret);
44467836SJohn.Forte@Sun.COM 
44477836SJohn.Forte@Sun.COM 	/*
44487836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
44497836SJohn.Forte@Sun.COM 	 */
44509585STim.Szeto@Sun.COM 	fLuListSize = ALLOC_LU;
44517836SJohn.Forte@Sun.COM 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
44527836SJohn.Forte@Sun.COM 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
44537836SJohn.Forte@Sun.COM 	if (fLuList == NULL) {
44549585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
44559585STim.Szeto@Sun.COM 		goto done;
44567836SJohn.Forte@Sun.COM 	}
44577836SJohn.Forte@Sun.COM 
44587836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
44597836SJohn.Forte@Sun.COM 	/*
44607836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the LU list
44617836SJohn.Forte@Sun.COM 	 */
44627836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
44637836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fLuListSize;
44647836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
44657836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
44667836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
44677836SJohn.Forte@Sun.COM 		switch (errno) {
44687836SJohn.Forte@Sun.COM 			case EBUSY:
44697836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
44707836SJohn.Forte@Sun.COM 				break;
44719585STim.Szeto@Sun.COM 			case EPERM:
44727836SJohn.Forte@Sun.COM 			case EACCES:
44737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
44747836SJohn.Forte@Sun.COM 				break;
44757836SJohn.Forte@Sun.COM 			default:
44767836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
44777836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
44787836SJohn.Forte@Sun.COM 				    errno);
44797836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
44807836SJohn.Forte@Sun.COM 				break;
44817836SJohn.Forte@Sun.COM 		}
44827836SJohn.Forte@Sun.COM 		goto done;
44837836SJohn.Forte@Sun.COM 	}
44847836SJohn.Forte@Sun.COM 	/*
44857836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
44867836SJohn.Forte@Sun.COM 	 */
44879585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
44887836SJohn.Forte@Sun.COM 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
44897836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
44909585STim.Szeto@Sun.COM 		free(fLuList);
44919585STim.Szeto@Sun.COM 		fLuList = (slist_lu_t *)calloc(1, fLuListSize);
44927836SJohn.Forte@Sun.COM 		if (fLuList == NULL) {
44939585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
44949585STim.Szeto@Sun.COM 			goto done;
44957836SJohn.Forte@Sun.COM 		}
44967836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fLuListSize;
44977836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
44987836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
44997836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
45007836SJohn.Forte@Sun.COM 			switch (errno) {
45017836SJohn.Forte@Sun.COM 				case EBUSY:
45027836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
45037836SJohn.Forte@Sun.COM 					break;
45049585STim.Szeto@Sun.COM 				case EPERM:
45057836SJohn.Forte@Sun.COM 				case EACCES:
45067836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
45077836SJohn.Forte@Sun.COM 					break;
45087836SJohn.Forte@Sun.COM 				default:
45097836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
45107836SJohn.Forte@Sun.COM 					    "stmfGetLogicalUnitList:"
45117836SJohn.Forte@Sun.COM 					    "ioctl errno(%d)", errno);
45127836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
45137836SJohn.Forte@Sun.COM 					break;
45147836SJohn.Forte@Sun.COM 			}
45157836SJohn.Forte@Sun.COM 			goto done;
45167836SJohn.Forte@Sun.COM 		}
45177836SJohn.Forte@Sun.COM 	}
45187836SJohn.Forte@Sun.COM 
45197836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
45207836SJohn.Forte@Sun.COM 		goto done;
45217836SJohn.Forte@Sun.COM 	}
45227836SJohn.Forte@Sun.COM 
45239585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
45247836SJohn.Forte@Sun.COM 
45257836SJohn.Forte@Sun.COM 	/*
45267836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
45277836SJohn.Forte@Sun.COM 	 */
45287836SJohn.Forte@Sun.COM 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
45299585STim.Szeto@Sun.COM 	    listCnt * sizeof (stmfGuid));
45307836SJohn.Forte@Sun.COM 	if (*luList == NULL) {
45317836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
45327836SJohn.Forte@Sun.COM 		goto done;
45337836SJohn.Forte@Sun.COM 	}
45347836SJohn.Forte@Sun.COM 
45359585STim.Szeto@Sun.COM 	(*luList)->cnt = listCnt;
45369585STim.Szeto@Sun.COM 
45379585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
45389585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
45399585STim.Szeto@Sun.COM 		bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
45409585STim.Szeto@Sun.COM 		    sizeof (stmfGuid));
45419585STim.Szeto@Sun.COM 	}
45429585STim.Szeto@Sun.COM 
45437836SJohn.Forte@Sun.COM 	/*
45449585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
45457836SJohn.Forte@Sun.COM 	 */
45469585STim.Szeto@Sun.COM 	qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
45479585STim.Szeto@Sun.COM 	    sizeof (stmfGuid), guidCompare);
45487836SJohn.Forte@Sun.COM 
45497836SJohn.Forte@Sun.COM done:
45507836SJohn.Forte@Sun.COM 	(void) close(fd);
45517836SJohn.Forte@Sun.COM 	/*
45527836SJohn.Forte@Sun.COM 	 * free internal buffers
45537836SJohn.Forte@Sun.COM 	 */
45547836SJohn.Forte@Sun.COM 	free(fLuList);
45557836SJohn.Forte@Sun.COM 	return (ret);
45567836SJohn.Forte@Sun.COM }
45577836SJohn.Forte@Sun.COM 
45587836SJohn.Forte@Sun.COM /*
45597836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitProperties
45607836SJohn.Forte@Sun.COM  *
45617836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
45627836SJohn.Forte@Sun.COM  *
45637836SJohn.Forte@Sun.COM  * lu - guid of the logical unit for which to retrieve properties
45647836SJohn.Forte@Sun.COM  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
45657836SJohn.Forte@Sun.COM  *               it contains the logical unit properties for the specified guid.
45667836SJohn.Forte@Sun.COM  */
45677836SJohn.Forte@Sun.COM int
45687836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
45697836SJohn.Forte@Sun.COM {
45707836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
45717836SJohn.Forte@Sun.COM 	int stmfRet;
45727836SJohn.Forte@Sun.COM 	int fd;
45737836SJohn.Forte@Sun.COM 	int ioctlRet;
45747836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
45757836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
45767836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
45777836SJohn.Forte@Sun.COM 	sioc_lu_props_t fLuProps;
45787836SJohn.Forte@Sun.COM 
45799585STim.Szeto@Sun.COM 	if (lu == NULL || luProps == NULL) {
45809585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
45817836SJohn.Forte@Sun.COM 	}
45827836SJohn.Forte@Sun.COM 
45837836SJohn.Forte@Sun.COM 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
45847836SJohn.Forte@Sun.COM 
45857836SJohn.Forte@Sun.COM 	/* call init */
45867836SJohn.Forte@Sun.COM 	ret = initializeConfig();
45877836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
45887836SJohn.Forte@Sun.COM 		return (ret);
45897836SJohn.Forte@Sun.COM 	}
45907836SJohn.Forte@Sun.COM 
45917836SJohn.Forte@Sun.COM 	/*
45927836SJohn.Forte@Sun.COM 	 * Open control node for stmf
45937836SJohn.Forte@Sun.COM 	 */
45947836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
45957836SJohn.Forte@Sun.COM 		return (ret);
45967836SJohn.Forte@Sun.COM 
45977836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
45987836SJohn.Forte@Sun.COM 	/*
45997836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
46007836SJohn.Forte@Sun.COM 	 */
46017836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
46027836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
46037836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
46047836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
46057836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
46067836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
46077836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
46087836SJohn.Forte@Sun.COM 		switch (errno) {
46097836SJohn.Forte@Sun.COM 			case EBUSY:
46107836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
46117836SJohn.Forte@Sun.COM 				break;
46129585STim.Szeto@Sun.COM 			case EPERM:
46137836SJohn.Forte@Sun.COM 			case EACCES:
46147836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
46157836SJohn.Forte@Sun.COM 				break;
46167836SJohn.Forte@Sun.COM 			case ENOENT:
46177836SJohn.Forte@Sun.COM 				stmfRet = stmfGetViewEntryList(lu,
46187836SJohn.Forte@Sun.COM 				    &viewEntryList);
46197836SJohn.Forte@Sun.COM 				if (stmfRet == STMF_STATUS_SUCCESS) {
46207836SJohn.Forte@Sun.COM 					luProps->status =
46217836SJohn.Forte@Sun.COM 					    STMF_LOGICAL_UNIT_UNREGISTERED;
46227836SJohn.Forte@Sun.COM 					if (viewEntryList->cnt > 0) {
46237836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_SUCCESS;
46247836SJohn.Forte@Sun.COM 					} else {
46257836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
46267836SJohn.Forte@Sun.COM 					}
46277836SJohn.Forte@Sun.COM 				} else {
46287836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
46297836SJohn.Forte@Sun.COM 				}
46307836SJohn.Forte@Sun.COM 				stmfFreeMemory(viewEntryList);
46317836SJohn.Forte@Sun.COM 				break;
46327836SJohn.Forte@Sun.COM 			default:
46337836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
46347836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnit:ioctl errno(%d)",
46357836SJohn.Forte@Sun.COM 				    errno);
46367836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
46377836SJohn.Forte@Sun.COM 				break;
46387836SJohn.Forte@Sun.COM 		}
46397836SJohn.Forte@Sun.COM 		goto done;
46407836SJohn.Forte@Sun.COM 	}
46417836SJohn.Forte@Sun.COM 
46427836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
46437836SJohn.Forte@Sun.COM 	    sizeof (fLuProps.lu_provider_name));
46447836SJohn.Forte@Sun.COM 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
46457836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
46467836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
46477836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
46487836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
46497836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
46507836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
46517836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
46527836SJohn.Forte@Sun.COM 	}
46537836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
46547836SJohn.Forte@Sun.COM done:
46557836SJohn.Forte@Sun.COM 	(void) close(fd);
46567836SJohn.Forte@Sun.COM 	return (ret);
46577836SJohn.Forte@Sun.COM }
46587836SJohn.Forte@Sun.COM 
46597836SJohn.Forte@Sun.COM /*
46607836SJohn.Forte@Sun.COM  * stmfGetState
46617836SJohn.Forte@Sun.COM  *
46627836SJohn.Forte@Sun.COM  * Purpose: retrieve the current state of the stmf module
46637836SJohn.Forte@Sun.COM  *
46647836SJohn.Forte@Sun.COM  * state - pointer to stmfState structure allocated by the caller
46657836SJohn.Forte@Sun.COM  *         On success, contains the state of stmf
46667836SJohn.Forte@Sun.COM  */
46677836SJohn.Forte@Sun.COM int
46687836SJohn.Forte@Sun.COM stmfGetState(stmfState *state)
46697836SJohn.Forte@Sun.COM {
46707836SJohn.Forte@Sun.COM 	int ret;
46717836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
46727836SJohn.Forte@Sun.COM 
46737836SJohn.Forte@Sun.COM 	if (state == NULL) {
46747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
46757836SJohn.Forte@Sun.COM 	}
46767836SJohn.Forte@Sun.COM 
46777836SJohn.Forte@Sun.COM 	ret = getStmfState(&iState);
46787836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
46797836SJohn.Forte@Sun.COM 		return (ret);
46807836SJohn.Forte@Sun.COM 	}
46817836SJohn.Forte@Sun.COM 	switch (iState.state) {
46827836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINE:
46837836SJohn.Forte@Sun.COM 			state->operationalState =
46847836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINE;
46857836SJohn.Forte@Sun.COM 			break;
46867836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINE:
46877836SJohn.Forte@Sun.COM 			state->operationalState =
46887836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINE;
46897836SJohn.Forte@Sun.COM 			break;
46907836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINING:
46917836SJohn.Forte@Sun.COM 			state->operationalState =
46927836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINING;
46937836SJohn.Forte@Sun.COM 			break;
46947836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINING:
46957836SJohn.Forte@Sun.COM 			state->operationalState =
46967836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINING;
46977836SJohn.Forte@Sun.COM 			break;
46987836SJohn.Forte@Sun.COM 		default:
46997836SJohn.Forte@Sun.COM 			state->operationalState =
47007836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_UNKNOWN;
47017836SJohn.Forte@Sun.COM 			break;
47027836SJohn.Forte@Sun.COM 	}
47037836SJohn.Forte@Sun.COM 	switch (iState.config_state) {
47047836SJohn.Forte@Sun.COM 		case STMF_CONFIG_NONE:
47057836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_NONE;
47067836SJohn.Forte@Sun.COM 			break;
47077836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT:
47087836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_INIT;
47097836SJohn.Forte@Sun.COM 			break;
47107836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT_DONE:
47117836SJohn.Forte@Sun.COM 			state->configState =
47127836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_INIT_DONE;
47137836SJohn.Forte@Sun.COM 			break;
47147836SJohn.Forte@Sun.COM 		default:
47157836SJohn.Forte@Sun.COM 			state->configState =
47167836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_UNKNOWN;
47177836SJohn.Forte@Sun.COM 			break;
47187836SJohn.Forte@Sun.COM 	}
47197836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
47207836SJohn.Forte@Sun.COM }
47217836SJohn.Forte@Sun.COM 
47227836SJohn.Forte@Sun.COM /*
47237836SJohn.Forte@Sun.COM  * stmfGetViewEntryList
47247836SJohn.Forte@Sun.COM  *
47257836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of view entries for the specified
47267836SJohn.Forte@Sun.COM  *          logical unit.
47277836SJohn.Forte@Sun.COM  *
47287836SJohn.Forte@Sun.COM  * lu - the guid of the logical unit for which to retrieve the view entry list
47297836SJohn.Forte@Sun.COM  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
47307836SJohn.Forte@Sun.COM  *                 success, contains the list of view entries.
47317836SJohn.Forte@Sun.COM  */
47327836SJohn.Forte@Sun.COM int
47337836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
47347836SJohn.Forte@Sun.COM {
47357836SJohn.Forte@Sun.COM 	int ret;
47369585STim.Szeto@Sun.COM 	int fd;
47379585STim.Szeto@Sun.COM 	int ioctlRet;
47389585STim.Szeto@Sun.COM 	int cmd = STMF_IOCTL_LU_VE_LIST;
47399585STim.Szeto@Sun.COM 	int i;
47409585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
47419585STim.Szeto@Sun.COM 	stmf_view_op_entry_t *fVeList;
47429585STim.Szeto@Sun.COM 	uint32_t fVeListSize;
47439585STim.Szeto@Sun.COM 	uint32_t listCnt;
47447836SJohn.Forte@Sun.COM 
47457836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntryList == NULL) {
47467836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
47477836SJohn.Forte@Sun.COM 	}
47487836SJohn.Forte@Sun.COM 
47499585STim.Szeto@Sun.COM 	/* call init */
47509585STim.Szeto@Sun.COM 	ret = initializeConfig();
47519585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47529585STim.Szeto@Sun.COM 		return (ret);
47539585STim.Szeto@Sun.COM 	}
47549585STim.Szeto@Sun.COM 
47559585STim.Szeto@Sun.COM 	/*
47569585STim.Szeto@Sun.COM 	 * Open control node for stmf
47579585STim.Szeto@Sun.COM 	 */
47589585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
47599585STim.Szeto@Sun.COM 		return (ret);
47609585STim.Szeto@Sun.COM 
47619585STim.Szeto@Sun.COM 	/*
47629585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
47639585STim.Szeto@Sun.COM 	 */
47649585STim.Szeto@Sun.COM 	fVeListSize = ALLOC_VE;
47659585STim.Szeto@Sun.COM 	fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
47669585STim.Szeto@Sun.COM 	fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
47679585STim.Szeto@Sun.COM 	if (fVeList == NULL) {
47689585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
47699585STim.Szeto@Sun.COM 		goto done;
47709585STim.Szeto@Sun.COM 	}
47719585STim.Szeto@Sun.COM 
47729585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
47739585STim.Szeto@Sun.COM 	/*
47749585STim.Szeto@Sun.COM 	 * Issue ioctl to get the LU list
47759585STim.Szeto@Sun.COM 	 */
47769585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
47779585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
47789585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
47799585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = fVeListSize;
47809585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
47819585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
47829585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
47839585STim.Szeto@Sun.COM 		switch (errno) {
47849585STim.Szeto@Sun.COM 			case EBUSY:
47859585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
47869585STim.Szeto@Sun.COM 				break;
47879585STim.Szeto@Sun.COM 			case EPERM:
47889585STim.Szeto@Sun.COM 			case EACCES:
47899585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
47909585STim.Szeto@Sun.COM 				break;
47919585STim.Szeto@Sun.COM 			default:
47929585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
47939585STim.Szeto@Sun.COM 				    "stmfGetViewEntryList:ioctl errno(%d)",
47949585STim.Szeto@Sun.COM 				    errno);
47959585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
47969585STim.Szeto@Sun.COM 				break;
47979585STim.Szeto@Sun.COM 		}
47989585STim.Szeto@Sun.COM 		goto done;
47999585STim.Szeto@Sun.COM 	}
48009585STim.Szeto@Sun.COM 	/*
48019585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
48029585STim.Szeto@Sun.COM 	 */
48039585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
48049585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
48059585STim.Szeto@Sun.COM 		fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
48069585STim.Szeto@Sun.COM 		    sizeof (stmf_view_op_entry_t);
48079585STim.Szeto@Sun.COM 		free(fVeList);
48089585STim.Szeto@Sun.COM 		fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
48099585STim.Szeto@Sun.COM 		if (fVeList == NULL) {
48109585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOMEM);
48119585STim.Szeto@Sun.COM 		}
48129585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = fVeListSize;
48139585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
48149585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
48159585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
48169585STim.Szeto@Sun.COM 			switch (errno) {
48179585STim.Szeto@Sun.COM 				case EBUSY:
48189585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
48199585STim.Szeto@Sun.COM 					break;
48209585STim.Szeto@Sun.COM 				case EPERM:
48219585STim.Szeto@Sun.COM 				case EACCES:
48229585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
48239585STim.Szeto@Sun.COM 					break;
48249585STim.Szeto@Sun.COM 				default:
48259585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
48269585STim.Szeto@Sun.COM 					    "stmfGetLogicalUnitList:"
48279585STim.Szeto@Sun.COM 					    "ioctl errno(%d)", errno);
48289585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
48299585STim.Szeto@Sun.COM 					break;
48309585STim.Szeto@Sun.COM 			}
48319585STim.Szeto@Sun.COM 			goto done;
48329585STim.Szeto@Sun.COM 		}
48339585STim.Szeto@Sun.COM 	}
48349585STim.Szeto@Sun.COM 
48359585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
48369585STim.Szeto@Sun.COM 		goto done;
48379585STim.Szeto@Sun.COM 	}
48389585STim.Szeto@Sun.COM 
48399585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
48409585STim.Szeto@Sun.COM 
48419585STim.Szeto@Sun.COM 	/*
48429585STim.Szeto@Sun.COM 	 * allocate caller's buffer with the final size
48439585STim.Szeto@Sun.COM 	 */
48449585STim.Szeto@Sun.COM 	*viewEntryList = (stmfViewEntryList *)calloc(1,
48459585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
48469585STim.Szeto@Sun.COM 	if (*viewEntryList == NULL) {
48479585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
48489585STim.Szeto@Sun.COM 		goto done;
48499585STim.Szeto@Sun.COM 	}
48509585STim.Szeto@Sun.COM 
48519585STim.Szeto@Sun.COM 	(*viewEntryList)->cnt = listCnt;
48529585STim.Szeto@Sun.COM 
48539585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
48549585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
48559585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndexValid = B_TRUE;
48569585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
48579585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_hosts == 1) {
48589585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allHosts = B_TRUE;
48599585STim.Szeto@Sun.COM 		} else {
48609585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_host_group.name,
48619585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].hostGroup,
48629585STim.Szeto@Sun.COM 			    fVeList[i].ve_host_group.name_size);
48639585STim.Szeto@Sun.COM 		}
48649585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_targets == 1) {
48659585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allTargets = B_TRUE;
48669585STim.Szeto@Sun.COM 		} else {
48679585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_target_group.name,
48689585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].targetGroup,
48699585STim.Szeto@Sun.COM 			    fVeList[i].ve_target_group.name_size);
48709585STim.Szeto@Sun.COM 		}
48719585STim.Szeto@Sun.COM 		bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
48729585STim.Szeto@Sun.COM 		    sizeof ((*viewEntryList)->ve[i].luNbr));
48739585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].luNbrValid = B_TRUE;
48749585STim.Szeto@Sun.COM 	}
48759585STim.Szeto@Sun.COM 
48769585STim.Szeto@Sun.COM 	/*
48779585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
48789585STim.Szeto@Sun.COM 	 */
48799585STim.Szeto@Sun.COM 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
48809585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntry), viewEntryCompare);
48819585STim.Szeto@Sun.COM 
48829585STim.Szeto@Sun.COM done:
48839585STim.Szeto@Sun.COM 	(void) close(fd);
48849585STim.Szeto@Sun.COM 	/*
48859585STim.Szeto@Sun.COM 	 * free internal buffers
48869585STim.Szeto@Sun.COM 	 */
48879585STim.Szeto@Sun.COM 	free(fVeList);
48887836SJohn.Forte@Sun.COM 	return (ret);
48897836SJohn.Forte@Sun.COM }
48907836SJohn.Forte@Sun.COM 
48919585STim.Szeto@Sun.COM 
48927836SJohn.Forte@Sun.COM /*
48937836SJohn.Forte@Sun.COM  * loadHostGroups
48947836SJohn.Forte@Sun.COM  *
48957836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the host groups into stmf
48967836SJohn.Forte@Sun.COM  *
48977836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
48987836SJohn.Forte@Sun.COM  * groupList - populated host group list
48997836SJohn.Forte@Sun.COM  */
49007836SJohn.Forte@Sun.COM static int
49017836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList)
49027836SJohn.Forte@Sun.COM {
49037836SJohn.Forte@Sun.COM 	int i, j;
49047836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
49057836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
49067836SJohn.Forte@Sun.COM 
49077836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
49087836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
49097836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
49107836SJohn.Forte@Sun.COM 			goto out;
49117836SJohn.Forte@Sun.COM 		}
49129585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
49139585STim.Szeto@Sun.COM 		    &groupProps, HOST_GROUP);
49147836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
49157836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
49167836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
49177836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
49187836SJohn.Forte@Sun.COM 				goto out;
49197836SJohn.Forte@Sun.COM 			}
49207836SJohn.Forte@Sun.COM 		}
49217836SJohn.Forte@Sun.COM 	}
49227836SJohn.Forte@Sun.COM 
49237836SJohn.Forte@Sun.COM 
49247836SJohn.Forte@Sun.COM out:
49257836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
49267836SJohn.Forte@Sun.COM 	return (ret);
49277836SJohn.Forte@Sun.COM }
49287836SJohn.Forte@Sun.COM 
49297836SJohn.Forte@Sun.COM /*
49307836SJohn.Forte@Sun.COM  * loadTargetGroups
49317836SJohn.Forte@Sun.COM  *
49327836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the target groups into stmf
49337836SJohn.Forte@Sun.COM  *
49347836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
49357836SJohn.Forte@Sun.COM  * groupList - populated target group list.
49367836SJohn.Forte@Sun.COM  */
49377836SJohn.Forte@Sun.COM static int
49387836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList)
49397836SJohn.Forte@Sun.COM {
49407836SJohn.Forte@Sun.COM 	int i, j;
49417836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
49427836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
49437836SJohn.Forte@Sun.COM 
49447836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
49457836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
49467836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
49477836SJohn.Forte@Sun.COM 			goto out;
49487836SJohn.Forte@Sun.COM 		}
49499585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
49509585STim.Szeto@Sun.COM 		    &groupProps, TARGET_GROUP);
49517836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
49527836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
49537836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
49547836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
49557836SJohn.Forte@Sun.COM 				goto out;
49567836SJohn.Forte@Sun.COM 			}
49577836SJohn.Forte@Sun.COM 		}
49587836SJohn.Forte@Sun.COM 	}
49597836SJohn.Forte@Sun.COM 
49607836SJohn.Forte@Sun.COM 
49617836SJohn.Forte@Sun.COM out:
49627836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
49637836SJohn.Forte@Sun.COM 	return (ret);
49647836SJohn.Forte@Sun.COM }
49657836SJohn.Forte@Sun.COM 
49667836SJohn.Forte@Sun.COM 
49677836SJohn.Forte@Sun.COM /*
49687836SJohn.Forte@Sun.COM  * loadStore
49697836SJohn.Forte@Sun.COM  *
49707836SJohn.Forte@Sun.COM  * Purpose: Load the configuration data from the store
49717836SJohn.Forte@Sun.COM  *
49727836SJohn.Forte@Sun.COM  * First load the host groups and target groups, then the view entries
49737836SJohn.Forte@Sun.COM  * and finally the provider data
49747836SJohn.Forte@Sun.COM  *
49757836SJohn.Forte@Sun.COM  * fd - file descriptor of control node for stmf.
49767836SJohn.Forte@Sun.COM  */
49777836SJohn.Forte@Sun.COM static int
49787836SJohn.Forte@Sun.COM loadStore(int fd)
49797836SJohn.Forte@Sun.COM {
49807836SJohn.Forte@Sun.COM 	int ret;
49817836SJohn.Forte@Sun.COM 	int i, j;
49827836SJohn.Forte@Sun.COM 	stmfGroupList *groupList = NULL;
49837836SJohn.Forte@Sun.COM 	stmfGuidList *guidList = NULL;
49847836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
49857836SJohn.Forte@Sun.COM 	stmfProviderList *providerList = NULL;
49867836SJohn.Forte@Sun.COM 	int providerType;
49877836SJohn.Forte@Sun.COM 	nvlist_t *nvl = NULL;
49887836SJohn.Forte@Sun.COM 
49897836SJohn.Forte@Sun.COM 
49907836SJohn.Forte@Sun.COM 
49917836SJohn.Forte@Sun.COM 	/* load host groups */
49929585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
49937836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
49947836SJohn.Forte@Sun.COM 		return (ret);
49957836SJohn.Forte@Sun.COM 	}
49967836SJohn.Forte@Sun.COM 	ret = loadHostGroups(fd, groupList);
49977836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
49987836SJohn.Forte@Sun.COM 		goto out;
49997836SJohn.Forte@Sun.COM 	}
50007836SJohn.Forte@Sun.COM 
50017836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
50027836SJohn.Forte@Sun.COM 	groupList = NULL;
50037836SJohn.Forte@Sun.COM 
50047836SJohn.Forte@Sun.COM 	/* load target groups */
50059585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
50067836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50077836SJohn.Forte@Sun.COM 		goto out;
50087836SJohn.Forte@Sun.COM 	}
50097836SJohn.Forte@Sun.COM 	ret = loadTargetGroups(fd, groupList);
50107836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50117836SJohn.Forte@Sun.COM 		goto out;
50127836SJohn.Forte@Sun.COM 	}
50137836SJohn.Forte@Sun.COM 
50147836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
50157836SJohn.Forte@Sun.COM 	groupList = NULL;
50167836SJohn.Forte@Sun.COM 
50177836SJohn.Forte@Sun.COM 	/* Get the guid list */
50187836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&guidList);
50197836SJohn.Forte@Sun.COM 	switch (ret) {
50207836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
50217836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
50227836SJohn.Forte@Sun.COM 			break;
50237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
50247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
50257836SJohn.Forte@Sun.COM 			break;
50267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
50277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
50287836SJohn.Forte@Sun.COM 			break;
50297836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
50307836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
50317836SJohn.Forte@Sun.COM 			break;
50327836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
50337836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
50347836SJohn.Forte@Sun.COM 			break;
50357836SJohn.Forte@Sun.COM 		default:
50367836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
50377836SJohn.Forte@Sun.COM 			break;
50387836SJohn.Forte@Sun.COM 	}
50397836SJohn.Forte@Sun.COM 
50407836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50417836SJohn.Forte@Sun.COM 		goto out;
50427836SJohn.Forte@Sun.COM 	}
50437836SJohn.Forte@Sun.COM 
50447836SJohn.Forte@Sun.COM 	/*
50457836SJohn.Forte@Sun.COM 	 * We have the guid list, now get the corresponding
50467836SJohn.Forte@Sun.COM 	 * view entries for each guid
50477836SJohn.Forte@Sun.COM 	 */
50487836SJohn.Forte@Sun.COM 	for (i = 0; i < guidList->cnt; i++) {
50497836SJohn.Forte@Sun.COM 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
50507836SJohn.Forte@Sun.COM 		switch (ret) {
50517836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
50527836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
50537836SJohn.Forte@Sun.COM 				break;
50547836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
50557836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
50567836SJohn.Forte@Sun.COM 				break;
50577836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
50587836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
50597836SJohn.Forte@Sun.COM 				break;
50607836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
50617836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
50627836SJohn.Forte@Sun.COM 				break;
50637836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
50647836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
50657836SJohn.Forte@Sun.COM 				break;
50667836SJohn.Forte@Sun.COM 			default:
50677836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
50687836SJohn.Forte@Sun.COM 				break;
50697836SJohn.Forte@Sun.COM 		}
50707836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
50717836SJohn.Forte@Sun.COM 			goto out;
50727836SJohn.Forte@Sun.COM 		}
50737836SJohn.Forte@Sun.COM 		for (j = 0; j < viewEntryList->cnt; j++) {
50747836SJohn.Forte@Sun.COM 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
50757836SJohn.Forte@Sun.COM 			    &viewEntryList->ve[j]);
50767836SJohn.Forte@Sun.COM 			if (ret != STMF_STATUS_SUCCESS) {
50777836SJohn.Forte@Sun.COM 				goto out;
50787836SJohn.Forte@Sun.COM 			}
50797836SJohn.Forte@Sun.COM 		}
50807836SJohn.Forte@Sun.COM 	}
50817836SJohn.Forte@Sun.COM 
50827836SJohn.Forte@Sun.COM 	/* get the list of providers that have data */
50837836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(&providerList);
50847836SJohn.Forte@Sun.COM 	switch (ret) {
50857836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
50867836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
50877836SJohn.Forte@Sun.COM 			break;
50887836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
50897836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
50907836SJohn.Forte@Sun.COM 			break;
50917836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
50927836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
50937836SJohn.Forte@Sun.COM 			break;
50947836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
50957836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
50967836SJohn.Forte@Sun.COM 			break;
50977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
50987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
50997836SJohn.Forte@Sun.COM 			break;
51007836SJohn.Forte@Sun.COM 		default:
51017836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
51027836SJohn.Forte@Sun.COM 			break;
51037836SJohn.Forte@Sun.COM 	}
51047836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
51057836SJohn.Forte@Sun.COM 		goto out;
51067836SJohn.Forte@Sun.COM 	}
51077836SJohn.Forte@Sun.COM 
51087836SJohn.Forte@Sun.COM 	for (i = 0; i < providerList->cnt; i++) {
51097836SJohn.Forte@Sun.COM 		providerType = providerList->provider[i].providerType;
51107836SJohn.Forte@Sun.COM 		ret = psGetProviderData(providerList->provider[i].name,
51117836SJohn.Forte@Sun.COM 		    &nvl, providerType, NULL);
51127836SJohn.Forte@Sun.COM 		switch (ret) {
51137836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
51147836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
51157836SJohn.Forte@Sun.COM 				break;
51167836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
51177836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
51187836SJohn.Forte@Sun.COM 				break;
51197836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
51207836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
51217836SJohn.Forte@Sun.COM 				break;
51227836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
51237836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
51247836SJohn.Forte@Sun.COM 				break;
51257836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
51267836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
51277836SJohn.Forte@Sun.COM 				break;
51287836SJohn.Forte@Sun.COM 			default:
51297836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
51307836SJohn.Forte@Sun.COM 				break;
51317836SJohn.Forte@Sun.COM 		}
51327836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
51337836SJohn.Forte@Sun.COM 			goto out;
51347836SJohn.Forte@Sun.COM 		}
51357836SJohn.Forte@Sun.COM 
51367836SJohn.Forte@Sun.COM 		/* call setProviderData */
51377836SJohn.Forte@Sun.COM 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
51389585STim.Szeto@Sun.COM 		    providerType, NULL);
51397836SJohn.Forte@Sun.COM 		switch (ret) {
51407836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
51417836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
51427836SJohn.Forte@Sun.COM 				break;
51437836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
51447836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
51457836SJohn.Forte@Sun.COM 				break;
51467836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
51477836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
51487836SJohn.Forte@Sun.COM 				break;
51497836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
51507836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
51517836SJohn.Forte@Sun.COM 				break;
51527836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
51537836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
51547836SJohn.Forte@Sun.COM 				break;
51557836SJohn.Forte@Sun.COM 			default:
51567836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
51577836SJohn.Forte@Sun.COM 				break;
51587836SJohn.Forte@Sun.COM 		}
51597836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
51607836SJohn.Forte@Sun.COM 			goto out;
51617836SJohn.Forte@Sun.COM 		}
51627836SJohn.Forte@Sun.COM 
51637836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
51647836SJohn.Forte@Sun.COM 		nvl = NULL;
51657836SJohn.Forte@Sun.COM 	}
51667836SJohn.Forte@Sun.COM out:
51677836SJohn.Forte@Sun.COM 	if (groupList != NULL) {
51687836SJohn.Forte@Sun.COM 		free(groupList);
51697836SJohn.Forte@Sun.COM 	}
51707836SJohn.Forte@Sun.COM 	if (guidList != NULL) {
51717836SJohn.Forte@Sun.COM 		free(guidList);
51727836SJohn.Forte@Sun.COM 	}
51737836SJohn.Forte@Sun.COM 	if (viewEntryList != NULL) {
51747836SJohn.Forte@Sun.COM 		free(viewEntryList);
51757836SJohn.Forte@Sun.COM 	}
51767836SJohn.Forte@Sun.COM 	if (nvl != NULL) {
51777836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
51787836SJohn.Forte@Sun.COM 	}
51797836SJohn.Forte@Sun.COM 	return (ret);
51807836SJohn.Forte@Sun.COM }
51817836SJohn.Forte@Sun.COM 
51827836SJohn.Forte@Sun.COM /*
518310725SJohn.Forte@Sun.COM  * stmfGetAluaState
518410725SJohn.Forte@Sun.COM  *
518510725SJohn.Forte@Sun.COM  * Purpose - Get the alua state
518610725SJohn.Forte@Sun.COM  *
518710725SJohn.Forte@Sun.COM  */
518810725SJohn.Forte@Sun.COM int
518910725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node)
519010725SJohn.Forte@Sun.COM {
519110725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
519210725SJohn.Forte@Sun.COM 	int fd;
519310725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
519410725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
519510725SJohn.Forte@Sun.COM 	int ioctlRet;
519610725SJohn.Forte@Sun.COM 
519710725SJohn.Forte@Sun.COM 	if (enabled == NULL || node == NULL) {
519810725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
519910725SJohn.Forte@Sun.COM 	}
520010725SJohn.Forte@Sun.COM 
520110725SJohn.Forte@Sun.COM 	/*
520210725SJohn.Forte@Sun.COM 	 * Open control node for stmf
520310725SJohn.Forte@Sun.COM 	 */
520410725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
520510725SJohn.Forte@Sun.COM 		return (ret);
520610725SJohn.Forte@Sun.COM 
520710725SJohn.Forte@Sun.COM 	/*
520810725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
520910725SJohn.Forte@Sun.COM 	 */
521010725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
521110725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (alua_state);
521210725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state;
521310725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl);
521410725SJohn.Forte@Sun.COM 
521510725SJohn.Forte@Sun.COM 	(void) close(fd);
521610725SJohn.Forte@Sun.COM 
521710725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
521810725SJohn.Forte@Sun.COM 		switch (errno) {
521910725SJohn.Forte@Sun.COM 			case EBUSY:
522010725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
522110725SJohn.Forte@Sun.COM 				break;
522210725SJohn.Forte@Sun.COM 			case EPERM:
522310725SJohn.Forte@Sun.COM 			case EACCES:
522410725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
522510725SJohn.Forte@Sun.COM 				break;
522610725SJohn.Forte@Sun.COM 			default:
522710725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
522810725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
522910725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
523010725SJohn.Forte@Sun.COM 				break;
523110725SJohn.Forte@Sun.COM 		}
523210725SJohn.Forte@Sun.COM 	} else {
523310725SJohn.Forte@Sun.COM 		if (alua_state.alua_state == 1) {
523410725SJohn.Forte@Sun.COM 			*enabled = B_TRUE;
523510725SJohn.Forte@Sun.COM 		} else {
523610725SJohn.Forte@Sun.COM 			*enabled = B_FALSE;
523710725SJohn.Forte@Sun.COM 		}
523810725SJohn.Forte@Sun.COM 		*node = alua_state.alua_node;
523910725SJohn.Forte@Sun.COM 	}
524010725SJohn.Forte@Sun.COM 
524110725SJohn.Forte@Sun.COM 	return (ret);
524210725SJohn.Forte@Sun.COM }
524310725SJohn.Forte@Sun.COM 
524410725SJohn.Forte@Sun.COM /*
524510725SJohn.Forte@Sun.COM  * stmfSetAluaState
524610725SJohn.Forte@Sun.COM  *
524710725SJohn.Forte@Sun.COM  * Purpose - set the alua state to enabled/disabled
524810725SJohn.Forte@Sun.COM  *
524910725SJohn.Forte@Sun.COM  */
525010725SJohn.Forte@Sun.COM int
525110725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node)
525210725SJohn.Forte@Sun.COM {
525310725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
525410725SJohn.Forte@Sun.COM 	int fd;
525510725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
525610725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
525710725SJohn.Forte@Sun.COM 	int ioctlRet;
525810725SJohn.Forte@Sun.COM 
525910725SJohn.Forte@Sun.COM 	if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) {
526010725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
526110725SJohn.Forte@Sun.COM 	}
526210725SJohn.Forte@Sun.COM 
526310725SJohn.Forte@Sun.COM 	if (enabled) {
526410725SJohn.Forte@Sun.COM 		alua_state.alua_state = 1;
526510725SJohn.Forte@Sun.COM 	}
526610725SJohn.Forte@Sun.COM 
526710725SJohn.Forte@Sun.COM 	alua_state.alua_node = node;
526810725SJohn.Forte@Sun.COM 
526910725SJohn.Forte@Sun.COM 	/*
527010725SJohn.Forte@Sun.COM 	 * Open control node for stmf
527110725SJohn.Forte@Sun.COM 	 */
527210725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
527310725SJohn.Forte@Sun.COM 		return (ret);
527410725SJohn.Forte@Sun.COM 
527510725SJohn.Forte@Sun.COM 	/*
527610725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
527710725SJohn.Forte@Sun.COM 	 */
527810725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
527910725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (alua_state);
528010725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state;
528110725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl);
528210725SJohn.Forte@Sun.COM 
528310725SJohn.Forte@Sun.COM 	(void) close(fd);
528410725SJohn.Forte@Sun.COM 
528510725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
528610725SJohn.Forte@Sun.COM 		switch (errno) {
528710725SJohn.Forte@Sun.COM 			case EBUSY:
528810725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
528910725SJohn.Forte@Sun.COM 				break;
529010725SJohn.Forte@Sun.COM 			case EPERM:
529110725SJohn.Forte@Sun.COM 			case EACCES:
529210725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
529310725SJohn.Forte@Sun.COM 				break;
529410725SJohn.Forte@Sun.COM 			default:
529510725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
529610725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
529710725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
529810725SJohn.Forte@Sun.COM 				break;
529910725SJohn.Forte@Sun.COM 		}
530010725SJohn.Forte@Sun.COM 	}
530111116SJohn.Forte@Sun.COM 	if (!enabled && ret == STMF_STATUS_SUCCESS) {
530210725SJohn.Forte@Sun.COM 		deleteNonActiveLus();
530310725SJohn.Forte@Sun.COM 	}
530410725SJohn.Forte@Sun.COM 
530510725SJohn.Forte@Sun.COM 	return (ret);
530610725SJohn.Forte@Sun.COM }
530710725SJohn.Forte@Sun.COM 
530810725SJohn.Forte@Sun.COM static void
530910725SJohn.Forte@Sun.COM deleteNonActiveLus()
531010725SJohn.Forte@Sun.COM {
531110725SJohn.Forte@Sun.COM 	int stmfRet;
531210725SJohn.Forte@Sun.COM 	int i;
531310725SJohn.Forte@Sun.COM 	stmfGuidList *luList;
531410725SJohn.Forte@Sun.COM 	luResource hdl = NULL;
531510725SJohn.Forte@Sun.COM 	char propVal[10];
531610725SJohn.Forte@Sun.COM 	size_t propValSize = sizeof (propVal);
531710725SJohn.Forte@Sun.COM 
531810725SJohn.Forte@Sun.COM 	stmfRet = stmfGetLogicalUnitList(&luList);
531910725SJohn.Forte@Sun.COM 	if (stmfRet != STMF_STATUS_SUCCESS) {
532010725SJohn.Forte@Sun.COM 		return;
532110725SJohn.Forte@Sun.COM 	}
532210725SJohn.Forte@Sun.COM 
532310725SJohn.Forte@Sun.COM 	for (i = 0; i < luList->cnt; i++) {
532410725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuResource(&luList->guid[i], &hdl);
532510725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
532610725SJohn.Forte@Sun.COM 			goto err;
532710725SJohn.Forte@Sun.COM 		}
532810725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
532910725SJohn.Forte@Sun.COM 		    &propValSize);
533010725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
533110725SJohn.Forte@Sun.COM 			goto err;
533210725SJohn.Forte@Sun.COM 		}
533310725SJohn.Forte@Sun.COM 		if (propVal[0] == '0') {
533410725SJohn.Forte@Sun.COM 			(void) stmfFreeLuResource(hdl);
533510725SJohn.Forte@Sun.COM 			hdl = NULL;
533610725SJohn.Forte@Sun.COM 			continue;
533710725SJohn.Forte@Sun.COM 		}
533810725SJohn.Forte@Sun.COM 		(void) stmfDeleteLu(&luList->guid[i]);
533910725SJohn.Forte@Sun.COM 		(void) stmfFreeLuResource(hdl);
534010725SJohn.Forte@Sun.COM 		hdl = NULL;
534110725SJohn.Forte@Sun.COM 	}
534210725SJohn.Forte@Sun.COM 
534310725SJohn.Forte@Sun.COM err:
534410725SJohn.Forte@Sun.COM 	stmfFreeMemory(luList);
534510725SJohn.Forte@Sun.COM 	(void) stmfFreeLuResource(hdl);
534610725SJohn.Forte@Sun.COM }
534710725SJohn.Forte@Sun.COM 
534810725SJohn.Forte@Sun.COM /*
53497836SJohn.Forte@Sun.COM  * stmfLoadConfig
53507836SJohn.Forte@Sun.COM  *
53517836SJohn.Forte@Sun.COM  * Purpose - load the configuration data from smf into stmf
53527836SJohn.Forte@Sun.COM  *
53537836SJohn.Forte@Sun.COM  */
53547836SJohn.Forte@Sun.COM int
53557836SJohn.Forte@Sun.COM stmfLoadConfig(void)
53567836SJohn.Forte@Sun.COM {
53579585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
53587836SJohn.Forte@Sun.COM 	int fd;
53597836SJohn.Forte@Sun.COM 	stmf_state_desc_t stmfStateSet;
53607836SJohn.Forte@Sun.COM 	stmfState state;
53617836SJohn.Forte@Sun.COM 
53629585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
53639585STim.Szeto@Sun.COM 		stmfStateSet.state = STMF_STATE_OFFLINE;
536410560SSusan.Gleeson@Sun.COM 
53659585STim.Szeto@Sun.COM 		if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
53669585STim.Szeto@Sun.COM 		    != STMF_STATUS_SUCCESS) {
53679585STim.Szeto@Sun.COM 			return (ret);
53689585STim.Szeto@Sun.COM 		}
536910560SSusan.Gleeson@Sun.COM 		/*
537010560SSusan.Gleeson@Sun.COM 		 * Configuration not stored persistently; nothing to
537110560SSusan.Gleeson@Sun.COM 		 * initialize so do not set to STMF_CONFIG_INIT.
537210560SSusan.Gleeson@Sun.COM 		 */
53739585STim.Szeto@Sun.COM 		stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
53749585STim.Szeto@Sun.COM 		goto done;
53759585STim.Szeto@Sun.COM 	}
53767836SJohn.Forte@Sun.COM 
53777836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
53787836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
53797836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
53807836SJohn.Forte@Sun.COM 	}
53817836SJohn.Forte@Sun.COM 
53827836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
53837836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
53847836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
53857836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
53867836SJohn.Forte@Sun.COM 		}
53877836SJohn.Forte@Sun.COM 	} else {
53887836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
53897836SJohn.Forte@Sun.COM 	}
53907836SJohn.Forte@Sun.COM 
53917836SJohn.Forte@Sun.COM 
53927836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
53937836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT;
53947836SJohn.Forte@Sun.COM 
53957836SJohn.Forte@Sun.COM 	/*
53967836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53977836SJohn.Forte@Sun.COM 	 */
53987836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53997836SJohn.Forte@Sun.COM 		return (ret);
54007836SJohn.Forte@Sun.COM 
54017836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
54027836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
54037836SJohn.Forte@Sun.COM 		goto done;
54047836SJohn.Forte@Sun.COM 	}
54057836SJohn.Forte@Sun.COM 
54067836SJohn.Forte@Sun.COM 	/* Load the persistent configuration data */
54077836SJohn.Forte@Sun.COM 	ret = loadStore(fd);
54087836SJohn.Forte@Sun.COM 	if (ret != 0) {
54097836SJohn.Forte@Sun.COM 		goto done;
54107836SJohn.Forte@Sun.COM 	}
54117836SJohn.Forte@Sun.COM 
54127836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
54137836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
54147836SJohn.Forte@Sun.COM 
54157836SJohn.Forte@Sun.COM done:
54167836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
54177836SJohn.Forte@Sun.COM 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
54187836SJohn.Forte@Sun.COM 	}
54197836SJohn.Forte@Sun.COM 	(void) close(fd);
54207836SJohn.Forte@Sun.COM 	return (ret);
54217836SJohn.Forte@Sun.COM }
54227836SJohn.Forte@Sun.COM 
54239585STim.Szeto@Sun.COM 
54247836SJohn.Forte@Sun.COM /*
54257836SJohn.Forte@Sun.COM  * getStmfState
54267836SJohn.Forte@Sun.COM  *
54277836SJohn.Forte@Sun.COM  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
54287836SJohn.Forte@Sun.COM  *             information of the stmf service on success.
54297836SJohn.Forte@Sun.COM  */
54307836SJohn.Forte@Sun.COM static int
54317836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState)
54327836SJohn.Forte@Sun.COM {
54337836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54347836SJohn.Forte@Sun.COM 	int fd;
54357836SJohn.Forte@Sun.COM 	int ioctlRet;
54367836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
54377836SJohn.Forte@Sun.COM 
54387836SJohn.Forte@Sun.COM 	/*
54397836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54407836SJohn.Forte@Sun.COM 	 */
54417836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
54427836SJohn.Forte@Sun.COM 		return (ret);
54437836SJohn.Forte@Sun.COM 
54447836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
54457836SJohn.Forte@Sun.COM 	/*
54467836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
54477836SJohn.Forte@Sun.COM 	 */
54487836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
54497836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
54507836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
54517836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
54527836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
54537836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
54547836SJohn.Forte@Sun.COM 
54557836SJohn.Forte@Sun.COM 	(void) close(fd);
54567836SJohn.Forte@Sun.COM 
54577836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
54587836SJohn.Forte@Sun.COM 		switch (errno) {
54597836SJohn.Forte@Sun.COM 			case EBUSY:
54607836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
54617836SJohn.Forte@Sun.COM 				break;
54627836SJohn.Forte@Sun.COM 			case EPERM:
54637836SJohn.Forte@Sun.COM 			case EACCES:
54647836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
54657836SJohn.Forte@Sun.COM 				break;
54667836SJohn.Forte@Sun.COM 			default:
54677836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
54687836SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
54697836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
54707836SJohn.Forte@Sun.COM 				break;
54717836SJohn.Forte@Sun.COM 		}
54727836SJohn.Forte@Sun.COM 	}
54737836SJohn.Forte@Sun.COM 	return (ret);
54747836SJohn.Forte@Sun.COM }
54757836SJohn.Forte@Sun.COM 
54767836SJohn.Forte@Sun.COM 
54777836SJohn.Forte@Sun.COM /*
54787836SJohn.Forte@Sun.COM  * setStmfState
54797836SJohn.Forte@Sun.COM  *
54807836SJohn.Forte@Sun.COM  * stmfState - pointer to caller set state structure
54817836SJohn.Forte@Sun.COM  * objectType - one of:
54827836SJohn.Forte@Sun.COM  *		LOGICAL_UNIT_TYPE
54837836SJohn.Forte@Sun.COM  *		TARGET_TYPE
54847836SJohn.Forte@Sun.COM  *		STMF_SERVICE_TYPE
54857836SJohn.Forte@Sun.COM  */
54867836SJohn.Forte@Sun.COM static int
54877836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
54887836SJohn.Forte@Sun.COM {
54897836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54907836SJohn.Forte@Sun.COM 	int ioctlRet;
54917836SJohn.Forte@Sun.COM 	int cmd;
54927836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
54937836SJohn.Forte@Sun.COM 
54947836SJohn.Forte@Sun.COM 	switch (objectType) {
54957836SJohn.Forte@Sun.COM 		case LOGICAL_UNIT_TYPE:
54967836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_LU_STATE;
54977836SJohn.Forte@Sun.COM 			break;
54987836SJohn.Forte@Sun.COM 		case TARGET_TYPE:
54997836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
55007836SJohn.Forte@Sun.COM 			break;
55017836SJohn.Forte@Sun.COM 		case STMF_SERVICE_TYPE:
55027836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_STMF_STATE;
55037836SJohn.Forte@Sun.COM 			break;
55047836SJohn.Forte@Sun.COM 		default:
55057836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
55067836SJohn.Forte@Sun.COM 			goto done;
55077836SJohn.Forte@Sun.COM 	}
55087836SJohn.Forte@Sun.COM 
55097836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
55107836SJohn.Forte@Sun.COM 	/*
55117836SJohn.Forte@Sun.COM 	 * Issue ioctl to set the stmf state
55127836SJohn.Forte@Sun.COM 	 */
55137836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
55147836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
55157836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
55167836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
55177836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
55187836SJohn.Forte@Sun.COM 		switch (errno) {
55197836SJohn.Forte@Sun.COM 			case EBUSY:
55207836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
55217836SJohn.Forte@Sun.COM 				break;
55229585STim.Szeto@Sun.COM 			case EPERM:
55237836SJohn.Forte@Sun.COM 			case EACCES:
55247836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
55257836SJohn.Forte@Sun.COM 				break;
55267836SJohn.Forte@Sun.COM 			case ENOENT:
55277836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
55287836SJohn.Forte@Sun.COM 				break;
55297836SJohn.Forte@Sun.COM 			default:
55307836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
55317836SJohn.Forte@Sun.COM 				    "setStmfState:ioctl errno(%d)", errno);
55327836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
55337836SJohn.Forte@Sun.COM 				break;
55347836SJohn.Forte@Sun.COM 		}
55357836SJohn.Forte@Sun.COM 	}
55367836SJohn.Forte@Sun.COM done:
55377836SJohn.Forte@Sun.COM 	return (ret);
55387836SJohn.Forte@Sun.COM }
55397836SJohn.Forte@Sun.COM 
55407836SJohn.Forte@Sun.COM /*
55417836SJohn.Forte@Sun.COM  * stmfOnline
55427836SJohn.Forte@Sun.COM  *
55437836SJohn.Forte@Sun.COM  * Purpose: Online stmf service
55447836SJohn.Forte@Sun.COM  *
55457836SJohn.Forte@Sun.COM  */
55467836SJohn.Forte@Sun.COM int
55477836SJohn.Forte@Sun.COM stmfOnline(void)
55487836SJohn.Forte@Sun.COM {
55497836SJohn.Forte@Sun.COM 	int ret;
55507836SJohn.Forte@Sun.COM 	int fd;
55517836SJohn.Forte@Sun.COM 	stmfState state;
55527836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
55537836SJohn.Forte@Sun.COM 
55547836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
55557836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
55567836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
55577836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
55587836SJohn.Forte@Sun.COM 		}
55597836SJohn.Forte@Sun.COM 	} else {
55607836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
55617836SJohn.Forte@Sun.COM 	}
55627836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_ONLINE;
55637836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
55647836SJohn.Forte@Sun.COM 	/*
55657836SJohn.Forte@Sun.COM 	 * Open control node for stmf
55667836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
55677836SJohn.Forte@Sun.COM 	 */
55687836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
55697836SJohn.Forte@Sun.COM 		return (ret);
55707836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
55717836SJohn.Forte@Sun.COM 	(void) close(fd);
55727836SJohn.Forte@Sun.COM 	return (ret);
55737836SJohn.Forte@Sun.COM }
55747836SJohn.Forte@Sun.COM 
55757836SJohn.Forte@Sun.COM /*
55767836SJohn.Forte@Sun.COM  * stmfOffline
55777836SJohn.Forte@Sun.COM  *
55787836SJohn.Forte@Sun.COM  * Purpose: Offline stmf service
55797836SJohn.Forte@Sun.COM  *
55807836SJohn.Forte@Sun.COM  */
55817836SJohn.Forte@Sun.COM int
55827836SJohn.Forte@Sun.COM stmfOffline(void)
55837836SJohn.Forte@Sun.COM {
55847836SJohn.Forte@Sun.COM 	int ret;
55857836SJohn.Forte@Sun.COM 	int fd;
55867836SJohn.Forte@Sun.COM 	stmfState state;
55877836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
55887836SJohn.Forte@Sun.COM 
55897836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
55907836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
55917836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
55927836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_OFFLINE);
55937836SJohn.Forte@Sun.COM 		}
55947836SJohn.Forte@Sun.COM 	} else {
55957836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
55967836SJohn.Forte@Sun.COM 	}
55977836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_OFFLINE;
55987836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
55997836SJohn.Forte@Sun.COM 
56007836SJohn.Forte@Sun.COM 	/*
56017836SJohn.Forte@Sun.COM 	 * Open control node for stmf
56027836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
56037836SJohn.Forte@Sun.COM 	 */
56047836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
56057836SJohn.Forte@Sun.COM 		return (ret);
56067836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
56077836SJohn.Forte@Sun.COM 	(void) close(fd);
56087836SJohn.Forte@Sun.COM 	return (ret);
56097836SJohn.Forte@Sun.COM }
56107836SJohn.Forte@Sun.COM 
56117836SJohn.Forte@Sun.COM 
56127836SJohn.Forte@Sun.COM /*
56137836SJohn.Forte@Sun.COM  * stmfOfflineTarget
56147836SJohn.Forte@Sun.COM  *
56157836SJohn.Forte@Sun.COM  * Purpose: Change state of target to offline
56167836SJohn.Forte@Sun.COM  *
56177836SJohn.Forte@Sun.COM  * devid - devid of the target to offline
56187836SJohn.Forte@Sun.COM  */
56197836SJohn.Forte@Sun.COM int
56207836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid)
56217836SJohn.Forte@Sun.COM {
56227836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
56237836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
56247836SJohn.Forte@Sun.COM 	int fd;
56257836SJohn.Forte@Sun.COM 
56267836SJohn.Forte@Sun.COM 	if (devid == NULL) {
56277836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
56287836SJohn.Forte@Sun.COM 	}
56297836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
56307836SJohn.Forte@Sun.COM 
56317836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_OFFLINE;
56327836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
56337836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
56347836SJohn.Forte@Sun.COM 	    devid->identLength);
56357836SJohn.Forte@Sun.COM 	/*
56367836SJohn.Forte@Sun.COM 	 * Open control node for stmf
56377836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
56387836SJohn.Forte@Sun.COM 	 */
56397836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
56407836SJohn.Forte@Sun.COM 		return (ret);
56417836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
56427836SJohn.Forte@Sun.COM 	(void) close(fd);
56437836SJohn.Forte@Sun.COM 	return (ret);
56447836SJohn.Forte@Sun.COM }
56457836SJohn.Forte@Sun.COM 
56467836SJohn.Forte@Sun.COM /*
56477836SJohn.Forte@Sun.COM  * stmfOfflineLogicalUnit
56487836SJohn.Forte@Sun.COM  *
56497836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to offline
56507836SJohn.Forte@Sun.COM  *
56517836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to offline
56527836SJohn.Forte@Sun.COM  */
56537836SJohn.Forte@Sun.COM int
56547836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu)
56557836SJohn.Forte@Sun.COM {
56567836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
56577836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
56587836SJohn.Forte@Sun.COM 	int fd;
56597836SJohn.Forte@Sun.COM 
56607836SJohn.Forte@Sun.COM 	if (lu == NULL) {
56617836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
56627836SJohn.Forte@Sun.COM 	}
56637836SJohn.Forte@Sun.COM 
56647836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
56657836SJohn.Forte@Sun.COM 
56667836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_OFFLINE;
56677836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
56687836SJohn.Forte@Sun.COM 	/*
56697836SJohn.Forte@Sun.COM 	 * Open control node for stmf
56707836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
56717836SJohn.Forte@Sun.COM 	 */
56727836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
56737836SJohn.Forte@Sun.COM 		return (ret);
56747836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
56757836SJohn.Forte@Sun.COM 	(void) close(fd);
56767836SJohn.Forte@Sun.COM 	return (ret);
56777836SJohn.Forte@Sun.COM }
56787836SJohn.Forte@Sun.COM 
56797836SJohn.Forte@Sun.COM /*
56807836SJohn.Forte@Sun.COM  * stmfOnlineTarget
56817836SJohn.Forte@Sun.COM  *
56827836SJohn.Forte@Sun.COM  * Purpose: Change state of target to online
56837836SJohn.Forte@Sun.COM  *
56847836SJohn.Forte@Sun.COM  * devid - devid of the target to online
56857836SJohn.Forte@Sun.COM  */
56867836SJohn.Forte@Sun.COM int
56877836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid)
56887836SJohn.Forte@Sun.COM {
56897836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
56907836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
56917836SJohn.Forte@Sun.COM 	int fd;
56927836SJohn.Forte@Sun.COM 
56937836SJohn.Forte@Sun.COM 	if (devid == NULL) {
56947836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
56957836SJohn.Forte@Sun.COM 	}
56967836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
56977836SJohn.Forte@Sun.COM 
56987836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_ONLINE;
56997836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
57007836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
57017836SJohn.Forte@Sun.COM 	    devid->identLength);
57027836SJohn.Forte@Sun.COM 	/*
57037836SJohn.Forte@Sun.COM 	 * Open control node for stmf
57047836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
57057836SJohn.Forte@Sun.COM 	 */
57067836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
57077836SJohn.Forte@Sun.COM 		return (ret);
57087836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
57097836SJohn.Forte@Sun.COM 	(void) close(fd);
57107836SJohn.Forte@Sun.COM 	return (ret);
57117836SJohn.Forte@Sun.COM }
57127836SJohn.Forte@Sun.COM 
57137836SJohn.Forte@Sun.COM /*
57147836SJohn.Forte@Sun.COM  * stmfOnlineLogicalUnit
57157836SJohn.Forte@Sun.COM  *
57167836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to online
57177836SJohn.Forte@Sun.COM  *
57187836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to online
57197836SJohn.Forte@Sun.COM  */
57207836SJohn.Forte@Sun.COM int
57217836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu)
57227836SJohn.Forte@Sun.COM {
57237836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
57247836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
57257836SJohn.Forte@Sun.COM 	int fd;
57267836SJohn.Forte@Sun.COM 
57277836SJohn.Forte@Sun.COM 	if (lu == NULL) {
57287836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
57297836SJohn.Forte@Sun.COM 	}
57307836SJohn.Forte@Sun.COM 
57317836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
57327836SJohn.Forte@Sun.COM 
57337836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_ONLINE;
57347836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
57357836SJohn.Forte@Sun.COM 	/*
57367836SJohn.Forte@Sun.COM 	 * Open control node for stmf
57377836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
57387836SJohn.Forte@Sun.COM 	 */
57397836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
57407836SJohn.Forte@Sun.COM 		return (ret);
57417836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
57427836SJohn.Forte@Sun.COM 	(void) close(fd);
57437836SJohn.Forte@Sun.COM 	return (ret);
57447836SJohn.Forte@Sun.COM }
57457836SJohn.Forte@Sun.COM 
57467836SJohn.Forte@Sun.COM /*
57477836SJohn.Forte@Sun.COM  * stmfRemoveFromHostGroup
57487836SJohn.Forte@Sun.COM  *
57497836SJohn.Forte@Sun.COM  * Purpose: Removes an initiator from an initiator group
57507836SJohn.Forte@Sun.COM  *
57517836SJohn.Forte@Sun.COM  * hostGroupName - name of an initiator group
57527836SJohn.Forte@Sun.COM  * hostName - name of host group member to remove
57537836SJohn.Forte@Sun.COM  */
57547836SJohn.Forte@Sun.COM int
57557836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
57567836SJohn.Forte@Sun.COM {
57577836SJohn.Forte@Sun.COM 	int ret;
57587836SJohn.Forte@Sun.COM 	int fd;
57597836SJohn.Forte@Sun.COM 
57607836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
57617836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
57627836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
57637836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
57647836SJohn.Forte@Sun.COM 	}
57657836SJohn.Forte@Sun.COM 
57667836SJohn.Forte@Sun.COM 	/* call init */
57677836SJohn.Forte@Sun.COM 	ret = initializeConfig();
57687836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
57697836SJohn.Forte@Sun.COM 		return (ret);
57707836SJohn.Forte@Sun.COM 	}
57717836SJohn.Forte@Sun.COM 
57727836SJohn.Forte@Sun.COM 	/*
57737836SJohn.Forte@Sun.COM 	 * Open control node for stmf
57747836SJohn.Forte@Sun.COM 	 */
57757836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
57767836SJohn.Forte@Sun.COM 		return (ret);
57777836SJohn.Forte@Sun.COM 
57787836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
57797836SJohn.Forte@Sun.COM 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
57807836SJohn.Forte@Sun.COM 		goto done;
57817836SJohn.Forte@Sun.COM 	}
57827836SJohn.Forte@Sun.COM 
57839585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
57849585STim.Szeto@Sun.COM 		goto done;
57859585STim.Szeto@Sun.COM 	}
57869585STim.Szeto@Sun.COM 
57877836SJohn.Forte@Sun.COM 	ret = psRemoveHostGroupMember((char *)hostGroupName,
57887836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
57897836SJohn.Forte@Sun.COM 	switch (ret) {
57907836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
57917836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
57927836SJohn.Forte@Sun.COM 			break;
57937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
57947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
57957836SJohn.Forte@Sun.COM 			break;
57967836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
57977836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
57987836SJohn.Forte@Sun.COM 			break;
57997836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
58007836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
58017836SJohn.Forte@Sun.COM 			break;
58027836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
58037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
58047836SJohn.Forte@Sun.COM 			break;
58057836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
58067836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
58077836SJohn.Forte@Sun.COM 			break;
58087836SJohn.Forte@Sun.COM 		default:
58097836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
58107836SJohn.Forte@Sun.COM 			    "stmfRemoveFromHostGroup"
58117836SJohn.Forte@Sun.COM 			    "psRemoveHostGroupMember:error(%d)", ret);
58127836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
58137836SJohn.Forte@Sun.COM 			break;
58147836SJohn.Forte@Sun.COM 	}
58157836SJohn.Forte@Sun.COM 
58167836SJohn.Forte@Sun.COM done:
58177836SJohn.Forte@Sun.COM 	(void) close(fd);
58187836SJohn.Forte@Sun.COM 	return (ret);
58197836SJohn.Forte@Sun.COM }
58207836SJohn.Forte@Sun.COM 
58217836SJohn.Forte@Sun.COM /*
58227836SJohn.Forte@Sun.COM  * stmfRemoveFromTargetGroup
58237836SJohn.Forte@Sun.COM  *
58247836SJohn.Forte@Sun.COM  * Purpose: Removes a local port from a local port group
58257836SJohn.Forte@Sun.COM  *
58267836SJohn.Forte@Sun.COM  * targetGroupName - name of a target group
58277836SJohn.Forte@Sun.COM  * targetName - name of target to remove
58287836SJohn.Forte@Sun.COM  */
58297836SJohn.Forte@Sun.COM int
58307836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
58317836SJohn.Forte@Sun.COM {
58327836SJohn.Forte@Sun.COM 	int ret;
58337836SJohn.Forte@Sun.COM 	int fd;
58347836SJohn.Forte@Sun.COM 
58357836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
58367836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
58377836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
58387836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
58397836SJohn.Forte@Sun.COM 	}
58407836SJohn.Forte@Sun.COM 
58417836SJohn.Forte@Sun.COM 	/* call init */
58427836SJohn.Forte@Sun.COM 	ret = initializeConfig();
58437836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
58447836SJohn.Forte@Sun.COM 		return (ret);
58457836SJohn.Forte@Sun.COM 	}
58467836SJohn.Forte@Sun.COM 
58477836SJohn.Forte@Sun.COM 	/*
58487836SJohn.Forte@Sun.COM 	 * Open control node for stmf
58497836SJohn.Forte@Sun.COM 	 */
58507836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
58517836SJohn.Forte@Sun.COM 		return (ret);
58527836SJohn.Forte@Sun.COM 
58537836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
58547836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
58557836SJohn.Forte@Sun.COM 		goto done;
58567836SJohn.Forte@Sun.COM 	}
58577836SJohn.Forte@Sun.COM 
58589585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
58599585STim.Szeto@Sun.COM 		goto done;
58609585STim.Szeto@Sun.COM 	}
58619585STim.Szeto@Sun.COM 
58627836SJohn.Forte@Sun.COM 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
58637836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
58647836SJohn.Forte@Sun.COM 	switch (ret) {
58657836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
58667836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
58677836SJohn.Forte@Sun.COM 			break;
58687836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
58697836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
58707836SJohn.Forte@Sun.COM 			break;
58717836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
58727836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
58737836SJohn.Forte@Sun.COM 			break;
58747836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
58757836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
58767836SJohn.Forte@Sun.COM 			break;
58777836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
58787836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
58797836SJohn.Forte@Sun.COM 			break;
58807836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
58817836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
58827836SJohn.Forte@Sun.COM 			break;
58837836SJohn.Forte@Sun.COM 		default:
58847836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
58857836SJohn.Forte@Sun.COM 			    "stmfRemoveFromTargetGroup"
58867836SJohn.Forte@Sun.COM 			    "psRemoveTargetGroupMember:error(%d)", ret);
58877836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
58887836SJohn.Forte@Sun.COM 			break;
58897836SJohn.Forte@Sun.COM 	}
58907836SJohn.Forte@Sun.COM 
58917836SJohn.Forte@Sun.COM done:
58927836SJohn.Forte@Sun.COM 	(void) close(fd);
58937836SJohn.Forte@Sun.COM 	return (ret);
58947836SJohn.Forte@Sun.COM }
58957836SJohn.Forte@Sun.COM 
58967836SJohn.Forte@Sun.COM /*
58977836SJohn.Forte@Sun.COM  * stmfRemoveViewEntry
58987836SJohn.Forte@Sun.COM  *
58997836SJohn.Forte@Sun.COM  * Purpose: Removes a view entry from a logical unit
59007836SJohn.Forte@Sun.COM  *
59017836SJohn.Forte@Sun.COM  * lu - guid of lu for which view entry is being removed
59027836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry to remove
59037836SJohn.Forte@Sun.COM  *
59047836SJohn.Forte@Sun.COM  */
59057836SJohn.Forte@Sun.COM int
59067836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
59077836SJohn.Forte@Sun.COM {
59087836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
59097836SJohn.Forte@Sun.COM 	int fd;
59107836SJohn.Forte@Sun.COM 	int ioctlRet;
59117836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
59127836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
59137836SJohn.Forte@Sun.COM 
59147836SJohn.Forte@Sun.COM 	if (lu == NULL) {
59157836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
59167836SJohn.Forte@Sun.COM 	}
59177836SJohn.Forte@Sun.COM 
59187836SJohn.Forte@Sun.COM 	/* call init */
59197836SJohn.Forte@Sun.COM 	ret = initializeConfig();
59207836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
59217836SJohn.Forte@Sun.COM 		return (ret);
59227836SJohn.Forte@Sun.COM 	}
59237836SJohn.Forte@Sun.COM 
59247836SJohn.Forte@Sun.COM 	/*
59257836SJohn.Forte@Sun.COM 	 * Open control node for stmf
59267836SJohn.Forte@Sun.COM 	 */
59277836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
59287836SJohn.Forte@Sun.COM 		return (ret);
59297836SJohn.Forte@Sun.COM 
59307836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
59317836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
59327836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx = viewEntryIndex;
59337836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
59347836SJohn.Forte@Sun.COM 
59357836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
59367836SJohn.Forte@Sun.COM 	/*
59377836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
59387836SJohn.Forte@Sun.COM 	 */
59397836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
59407836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
59417836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
59427836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
59437836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
59447836SJohn.Forte@Sun.COM 		switch (errno) {
59457836SJohn.Forte@Sun.COM 			case EBUSY:
59467836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
59477836SJohn.Forte@Sun.COM 				break;
59489585STim.Szeto@Sun.COM 			case EPERM:
59499585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
59509585STim.Szeto@Sun.COM 				break;
59517836SJohn.Forte@Sun.COM 			case EACCES:
59527836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
59537836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
59547836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
59557836SJohn.Forte@Sun.COM 						break;
59567836SJohn.Forte@Sun.COM 					default:
59577836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
59587836SJohn.Forte@Sun.COM 						break;
59597836SJohn.Forte@Sun.COM 				}
59607836SJohn.Forte@Sun.COM 				break;
59617836SJohn.Forte@Sun.COM 			case ENODEV:
59627836SJohn.Forte@Sun.COM 			case ENOENT:
59637836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
59647836SJohn.Forte@Sun.COM 				break;
59657836SJohn.Forte@Sun.COM 			default:
59667836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
59677836SJohn.Forte@Sun.COM 				    "stmfRemoveViewEntry:ioctl errno(%d)",
59687836SJohn.Forte@Sun.COM 				    errno);
59697836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
59707836SJohn.Forte@Sun.COM 				break;
59717836SJohn.Forte@Sun.COM 		}
59727836SJohn.Forte@Sun.COM 		goto done;
59737836SJohn.Forte@Sun.COM 	}
59747836SJohn.Forte@Sun.COM 
59759585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
59769585STim.Szeto@Sun.COM 		goto done;
59779585STim.Szeto@Sun.COM 	}
59789585STim.Szeto@Sun.COM 
59797836SJohn.Forte@Sun.COM 	ret = psRemoveViewEntry(lu, viewEntryIndex);
59807836SJohn.Forte@Sun.COM 	switch (ret) {
59817836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
59827836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
59837836SJohn.Forte@Sun.COM 			break;
59847836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
59857836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
59867836SJohn.Forte@Sun.COM 			break;
59877836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
59887836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
59897836SJohn.Forte@Sun.COM 			break;
59907836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
59917836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
59927836SJohn.Forte@Sun.COM 			break;
59937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
59947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
59957836SJohn.Forte@Sun.COM 			break;
59967836SJohn.Forte@Sun.COM 		default:
59977836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
59987836SJohn.Forte@Sun.COM 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
59997836SJohn.Forte@Sun.COM 			    ret);
60007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
60017836SJohn.Forte@Sun.COM 			break;
60027836SJohn.Forte@Sun.COM 	}
60037836SJohn.Forte@Sun.COM 
60047836SJohn.Forte@Sun.COM done:
60057836SJohn.Forte@Sun.COM 	(void) close(fd);
60067836SJohn.Forte@Sun.COM 	return (ret);
60077836SJohn.Forte@Sun.COM }
60087836SJohn.Forte@Sun.COM 
60097836SJohn.Forte@Sun.COM /*
60107836SJohn.Forte@Sun.COM  * stmfSetProviderData
60117836SJohn.Forte@Sun.COM  *
60127836SJohn.Forte@Sun.COM  * Purpose: set the provider data
60137836SJohn.Forte@Sun.COM  *
60147836SJohn.Forte@Sun.COM  * providerName - unique name of provider
60157836SJohn.Forte@Sun.COM  * nvl - nvlist to set
60167836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
60177836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
60187836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
60197836SJohn.Forte@Sun.COM  */
60207836SJohn.Forte@Sun.COM int
60217836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
60227836SJohn.Forte@Sun.COM {
60237836SJohn.Forte@Sun.COM 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
60247836SJohn.Forte@Sun.COM 	    NULL));
60257836SJohn.Forte@Sun.COM }
60267836SJohn.Forte@Sun.COM 
60277836SJohn.Forte@Sun.COM /*
60287836SJohn.Forte@Sun.COM  * stmfSetProviderDataProt
60297836SJohn.Forte@Sun.COM  *
60307836SJohn.Forte@Sun.COM  * Purpose: set the provider data
60317836SJohn.Forte@Sun.COM  *
60327836SJohn.Forte@Sun.COM  * providerName - unique name of provider
60337836SJohn.Forte@Sun.COM  * nvl - nvlist to set
60347836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
60357836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
60367836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
60377836SJohn.Forte@Sun.COM  * setToken - Stale data token returned in the stmfGetProviderDataProt()
60387836SJohn.Forte@Sun.COM  *	      call or NULL.
60397836SJohn.Forte@Sun.COM  */
60407836SJohn.Forte@Sun.COM int
60417836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
60427836SJohn.Forte@Sun.COM     uint64_t *setToken)
60437836SJohn.Forte@Sun.COM {
60447836SJohn.Forte@Sun.COM 	int ret;
60457836SJohn.Forte@Sun.COM 	int fd;
60467836SJohn.Forte@Sun.COM 
60477836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
60487836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
60497836SJohn.Forte@Sun.COM 	}
60507836SJohn.Forte@Sun.COM 
60517836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
60527836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
60537836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
60547836SJohn.Forte@Sun.COM 	}
60557836SJohn.Forte@Sun.COM 
60567836SJohn.Forte@Sun.COM 	/* call init */
60577836SJohn.Forte@Sun.COM 	ret = initializeConfig();
60587836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
60597836SJohn.Forte@Sun.COM 		return (ret);
60607836SJohn.Forte@Sun.COM 	}
60617836SJohn.Forte@Sun.COM 
60627836SJohn.Forte@Sun.COM 	/*
60637836SJohn.Forte@Sun.COM 	 * Open control node for stmf
60647836SJohn.Forte@Sun.COM 	 */
60657836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
60667836SJohn.Forte@Sun.COM 		return (ret);
60677836SJohn.Forte@Sun.COM 
60689585STim.Szeto@Sun.COM 	ret = setProviderData(fd, providerName, nvl, providerType, setToken);
60697836SJohn.Forte@Sun.COM 
60707836SJohn.Forte@Sun.COM 	(void) close(fd);
60717836SJohn.Forte@Sun.COM 
60727836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
60737836SJohn.Forte@Sun.COM 		goto done;
60747836SJohn.Forte@Sun.COM 	}
60757836SJohn.Forte@Sun.COM 
60769585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
60779585STim.Szeto@Sun.COM 		goto done;
60789585STim.Szeto@Sun.COM 	}
60799585STim.Szeto@Sun.COM 
60807836SJohn.Forte@Sun.COM 	/* setting driver provider data successful. Now persist it */
60819585STim.Szeto@Sun.COM 	ret = psSetProviderData(providerName, nvl, providerType, NULL);
60827836SJohn.Forte@Sun.COM 	switch (ret) {
60837836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
60847836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
60857836SJohn.Forte@Sun.COM 			break;
60867836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
60877836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
60887836SJohn.Forte@Sun.COM 			break;
60897836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
60907836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
60917836SJohn.Forte@Sun.COM 			break;
60927836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
60937836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
60947836SJohn.Forte@Sun.COM 			break;
60957836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
60967836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
60977836SJohn.Forte@Sun.COM 			break;
60987836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_PROV_DATA_STALE:
60997836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PROV_DATA_STALE;
61007836SJohn.Forte@Sun.COM 			break;
61017836SJohn.Forte@Sun.COM 		default:
61027836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
61037836SJohn.Forte@Sun.COM 			    "stmfSetProviderData"
61047836SJohn.Forte@Sun.COM 			    "psSetProviderData:error(%d)", ret);
61057836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
61067836SJohn.Forte@Sun.COM 			break;
61077836SJohn.Forte@Sun.COM 	}
61087836SJohn.Forte@Sun.COM 
61097836SJohn.Forte@Sun.COM done:
61107836SJohn.Forte@Sun.COM 	return (ret);
61117836SJohn.Forte@Sun.COM }
61127836SJohn.Forte@Sun.COM 
61137836SJohn.Forte@Sun.COM /*
61149585STim.Szeto@Sun.COM  * getProviderData
61159585STim.Szeto@Sun.COM  *
61169585STim.Szeto@Sun.COM  * Purpose: set the provider data from stmf
61179585STim.Szeto@Sun.COM  *
61189585STim.Szeto@Sun.COM  * providerName - unique name of provider
61199585STim.Szeto@Sun.COM  * nvl - nvlist to load/retrieve
61209585STim.Szeto@Sun.COM  * providerType - logical unit or port provider
61219585STim.Szeto@Sun.COM  * setToken - returned stale data token
61229585STim.Szeto@Sun.COM  */
61239585STim.Szeto@Sun.COM int
61249585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType,
61259585STim.Szeto@Sun.COM     uint64_t *setToken)
61269585STim.Szeto@Sun.COM {
61279585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
61289585STim.Szeto@Sun.COM 	int fd;
61299585STim.Szeto@Sun.COM 	int ioctlRet;
61309585STim.Szeto@Sun.COM 	size_t nvlistSize = ALLOC_PP_DATA_SIZE;
61319585STim.Szeto@Sun.COM 	int retryCnt = 0;
61329585STim.Szeto@Sun.COM 	int retryCntMax = MAX_PROVIDER_RETRY;
61339585STim.Szeto@Sun.COM 	stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
61349585STim.Szeto@Sun.COM 	boolean_t retry = B_TRUE;
61359585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
61369585STim.Szeto@Sun.COM 
61379585STim.Szeto@Sun.COM 	if (providerName == NULL) {
61389585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
61399585STim.Szeto@Sun.COM 	}
61409585STim.Szeto@Sun.COM 
61419585STim.Szeto@Sun.COM 	/*
61429585STim.Szeto@Sun.COM 	 * Open control node for stmf
61439585STim.Szeto@Sun.COM 	 */
61449585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
61459585STim.Szeto@Sun.COM 		return (ret);
61469585STim.Szeto@Sun.COM 
61479585STim.Szeto@Sun.COM 	/* set provider name and provider type */
61489585STim.Szeto@Sun.COM 	if (strlcpy(ppi.ppi_name, providerName,
61499585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) >=
61509585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) {
61519585STim.Szeto@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
61529585STim.Szeto@Sun.COM 		goto done;
61539585STim.Szeto@Sun.COM 	}
61549585STim.Szeto@Sun.COM 	switch (providerType) {
61559585STim.Szeto@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
61569585STim.Szeto@Sun.COM 			ppi.ppi_lu_provider = 1;
61579585STim.Szeto@Sun.COM 			break;
61589585STim.Szeto@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
61599585STim.Szeto@Sun.COM 			ppi.ppi_port_provider = 1;
61609585STim.Szeto@Sun.COM 			break;
61619585STim.Szeto@Sun.COM 		default:
61629585STim.Szeto@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
61639585STim.Szeto@Sun.COM 			goto done;
61649585STim.Szeto@Sun.COM 	}
61659585STim.Szeto@Sun.COM 
61669585STim.Szeto@Sun.COM 	do {
61679585STim.Szeto@Sun.COM 		/* allocate memory for ioctl */
61689585STim.Szeto@Sun.COM 		ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
61699585STim.Szeto@Sun.COM 		    sizeof (stmf_ppioctl_data_t));
61709585STim.Szeto@Sun.COM 		if (ppi_out == NULL) {
61719585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
61729585STim.Szeto@Sun.COM 			goto done;
61739585STim.Szeto@Sun.COM 
61749585STim.Szeto@Sun.COM 		}
61759585STim.Szeto@Sun.COM 
61769585STim.Szeto@Sun.COM 		/* set the size of the ioctl data to allocated buffer */
61779585STim.Szeto@Sun.COM 		ppi.ppi_data_size = nvlistSize;
61789585STim.Szeto@Sun.COM 
61799585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
61809585STim.Szeto@Sun.COM 
61819585STim.Szeto@Sun.COM 		stmfIoctl.stmf_version = STMF_VERSION_1;
61829585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
61839585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
61849585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
61859585STim.Szeto@Sun.COM 		    nvlistSize;
61869585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
61879585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
61889585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
61899585STim.Szeto@Sun.COM 			switch (errno) {
61909585STim.Szeto@Sun.COM 				case EBUSY:
61919585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
61929585STim.Szeto@Sun.COM 					break;
61939585STim.Szeto@Sun.COM 				case EPERM:
61949585STim.Szeto@Sun.COM 				case EACCES:
61959585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
61969585STim.Szeto@Sun.COM 					break;
61979585STim.Szeto@Sun.COM 				case EINVAL:
61989585STim.Szeto@Sun.COM 					if (stmfIoctl.stmf_error ==
61999585STim.Szeto@Sun.COM 					    STMF_IOCERR_INSUFFICIENT_BUF) {
62009585STim.Szeto@Sun.COM 						nvlistSize =
62019585STim.Szeto@Sun.COM 						    ppi_out->ppi_data_size;
62029585STim.Szeto@Sun.COM 						free(ppi_out);
62039585STim.Szeto@Sun.COM 						ppi_out = NULL;
62049585STim.Szeto@Sun.COM 						if (retryCnt++ > retryCntMax) {
62059585STim.Szeto@Sun.COM 							retry = B_FALSE;
62069585STim.Szeto@Sun.COM 							ret = STMF_ERROR_BUSY;
62079585STim.Szeto@Sun.COM 						} else {
62089585STim.Szeto@Sun.COM 							ret =
62099585STim.Szeto@Sun.COM 							    STMF_STATUS_SUCCESS;
62109585STim.Szeto@Sun.COM 						}
62119585STim.Szeto@Sun.COM 					} else {
62129585STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
62139585STim.Szeto@Sun.COM 						    "getProviderData:ioctl"
62149585STim.Szeto@Sun.COM 						    "unable to retrieve "
62159585STim.Szeto@Sun.COM 						    "nvlist");
62169585STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
62179585STim.Szeto@Sun.COM 					}
62189585STim.Szeto@Sun.COM 					break;
62199585STim.Szeto@Sun.COM 				case ENOENT:
62209585STim.Szeto@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
62219585STim.Szeto@Sun.COM 					break;
62229585STim.Szeto@Sun.COM 				default:
62239585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
62249585STim.Szeto@Sun.COM 					    "getProviderData:ioctl errno(%d)",
62259585STim.Szeto@Sun.COM 					    errno);
62269585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
62279585STim.Szeto@Sun.COM 					break;
62289585STim.Szeto@Sun.COM 			}
62299585STim.Szeto@Sun.COM 			if (ret != STMF_STATUS_SUCCESS)
62309585STim.Szeto@Sun.COM 				goto done;
62319585STim.Szeto@Sun.COM 		}
62329585STim.Szeto@Sun.COM 	} while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
62339585STim.Szeto@Sun.COM 
62349585STim.Szeto@Sun.COM 	if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
62359585STim.Szeto@Sun.COM 	    ppi_out->ppi_data_size, nvl, 0)) != 0) {
62369585STim.Szeto@Sun.COM 		ret = STMF_STATUS_ERROR;
62379585STim.Szeto@Sun.COM 		goto done;
62389585STim.Szeto@Sun.COM 	}
62399585STim.Szeto@Sun.COM 
62409585STim.Szeto@Sun.COM 	/* caller has asked for new token */
62419585STim.Szeto@Sun.COM 	if (setToken) {
62429585STim.Szeto@Sun.COM 		*setToken = ppi_out->ppi_token;
62439585STim.Szeto@Sun.COM 	}
62449585STim.Szeto@Sun.COM done:
62459585STim.Szeto@Sun.COM 	free(ppi_out);
62469585STim.Szeto@Sun.COM 	(void) close(fd);
62479585STim.Szeto@Sun.COM 	return (ret);
62489585STim.Szeto@Sun.COM }
62499585STim.Szeto@Sun.COM 
62509585STim.Szeto@Sun.COM /*
62517836SJohn.Forte@Sun.COM  * setProviderData
62527836SJohn.Forte@Sun.COM  *
62539585STim.Szeto@Sun.COM  * Purpose: set the provider data in stmf
62547836SJohn.Forte@Sun.COM  *
62557836SJohn.Forte@Sun.COM  * providerName - unique name of provider
62567836SJohn.Forte@Sun.COM  * nvl - nvlist to set
62577836SJohn.Forte@Sun.COM  * providerType - logical unit or port provider
62589585STim.Szeto@Sun.COM  * setToken - stale data token to check if not NULL
62597836SJohn.Forte@Sun.COM  */
62607836SJohn.Forte@Sun.COM static int
62619585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
62629585STim.Szeto@Sun.COM     uint64_t *setToken)
62637836SJohn.Forte@Sun.COM {
62647836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
62657836SJohn.Forte@Sun.COM 	int ioctlRet;
62667836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
62677836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t *ppi = NULL;
62689585STim.Szeto@Sun.COM 	uint64_t outToken;
62697836SJohn.Forte@Sun.COM 	char *allocatedNvBuffer;
62707836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
62717836SJohn.Forte@Sun.COM 
62727836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
62737836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
62747836SJohn.Forte@Sun.COM 	}
62757836SJohn.Forte@Sun.COM 
62767836SJohn.Forte@Sun.COM 	/* get size of encoded nvlist */
62777836SJohn.Forte@Sun.COM 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
62787836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
62797836SJohn.Forte@Sun.COM 	}
62807836SJohn.Forte@Sun.COM 
62817836SJohn.Forte@Sun.COM 	/* allocate memory for ioctl */
62827836SJohn.Forte@Sun.COM 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
62837836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t));
62847836SJohn.Forte@Sun.COM 	if (ppi == NULL) {
62857836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
62867836SJohn.Forte@Sun.COM 	}
62877836SJohn.Forte@Sun.COM 
62889585STim.Szeto@Sun.COM 	if (setToken) {
62899585STim.Szeto@Sun.COM 		ppi->ppi_token_valid = 1;
62909585STim.Szeto@Sun.COM 		ppi->ppi_token = *setToken;
62919585STim.Szeto@Sun.COM 	}
62929585STim.Szeto@Sun.COM 
62937836SJohn.Forte@Sun.COM 	allocatedNvBuffer = (char *)&ppi->ppi_data;
62947836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
62957836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
62967836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
62977836SJohn.Forte@Sun.COM 	}
62987836SJohn.Forte@Sun.COM 
62997836SJohn.Forte@Sun.COM 	/* set provider name and provider type */
63007836SJohn.Forte@Sun.COM 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
63017836SJohn.Forte@Sun.COM 	switch (providerType) {
63027836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
63037836SJohn.Forte@Sun.COM 			ppi->ppi_lu_provider = 1;
63047836SJohn.Forte@Sun.COM 			break;
63057836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
63067836SJohn.Forte@Sun.COM 			ppi->ppi_port_provider = 1;
63077836SJohn.Forte@Sun.COM 			break;
63087836SJohn.Forte@Sun.COM 		default:
63097836SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
63107836SJohn.Forte@Sun.COM 	}
63117836SJohn.Forte@Sun.COM 
63127836SJohn.Forte@Sun.COM 	/* set the size of the ioctl data to packed data size */
63137836SJohn.Forte@Sun.COM 	ppi->ppi_data_size = nvlistEncodedSize;
63147836SJohn.Forte@Sun.COM 
63157836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
63167836SJohn.Forte@Sun.COM 
63177836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
63187836SJohn.Forte@Sun.COM 	/*
63197836SJohn.Forte@Sun.COM 	 * Subtracting 8 from the size as that is the size of the last member
63207836SJohn.Forte@Sun.COM 	 * of the structure where the packed data resides
63217836SJohn.Forte@Sun.COM 	 */
63227836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
63237836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t) - 8;
63247836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
63259585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
63269585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
63277836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
63287836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
63297836SJohn.Forte@Sun.COM 		switch (errno) {
63307836SJohn.Forte@Sun.COM 			case EBUSY:
63317836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
63327836SJohn.Forte@Sun.COM 				break;
63339585STim.Szeto@Sun.COM 			case EPERM:
63347836SJohn.Forte@Sun.COM 			case EACCES:
63357836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
63367836SJohn.Forte@Sun.COM 				break;
63379585STim.Szeto@Sun.COM 			case EINVAL:
63389585STim.Szeto@Sun.COM 				if (stmfIoctl.stmf_error ==
63399585STim.Szeto@Sun.COM 				    STMF_IOCERR_PPD_UPDATED) {
63409585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PROV_DATA_STALE;
63419585STim.Szeto@Sun.COM 				} else {
63429585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
63439585STim.Szeto@Sun.COM 				}
63449585STim.Szeto@Sun.COM 				break;
63457836SJohn.Forte@Sun.COM 			default:
63467836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
63477836SJohn.Forte@Sun.COM 				    "setProviderData:ioctl errno(%d)", errno);
63487836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
63497836SJohn.Forte@Sun.COM 				break;
63507836SJohn.Forte@Sun.COM 		}
63517836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS)
63527836SJohn.Forte@Sun.COM 			goto done;
63537836SJohn.Forte@Sun.COM 	}
63547836SJohn.Forte@Sun.COM 
63559585STim.Szeto@Sun.COM 	/* caller has asked for new token */
63569585STim.Szeto@Sun.COM 	if (setToken) {
63579585STim.Szeto@Sun.COM 		*setToken = outToken;
63589585STim.Szeto@Sun.COM 	}
63597836SJohn.Forte@Sun.COM done:
63607836SJohn.Forte@Sun.COM 	free(ppi);
63617836SJohn.Forte@Sun.COM 	return (ret);
63627836SJohn.Forte@Sun.COM }
63639585STim.Szeto@Sun.COM 
63649585STim.Szeto@Sun.COM /*
63659585STim.Szeto@Sun.COM  * set the persistence method in the library only or library and service
63669585STim.Szeto@Sun.COM  */
63679585STim.Szeto@Sun.COM int
63689585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
63699585STim.Szeto@Sun.COM {
63709585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
63719585STim.Szeto@Sun.COM 	int oldPersist;
63729585STim.Szeto@Sun.COM 
63739585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
63749585STim.Szeto@Sun.COM 	oldPersist = iPersistType;
63759585STim.Szeto@Sun.COM 	if (persistType == STMF_PERSIST_NONE ||
63769585STim.Szeto@Sun.COM 	    persistType == STMF_PERSIST_SMF) {
63779585STim.Szeto@Sun.COM 		iLibSetPersist = B_TRUE;
63789585STim.Szeto@Sun.COM 		iPersistType = persistType;
63799585STim.Szeto@Sun.COM 	} else {
63809585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
63819585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
63829585STim.Szeto@Sun.COM 	}
63839585STim.Szeto@Sun.COM 	/* Is this for this library open or in SMF */
63849585STim.Szeto@Sun.COM 	if (serviceSet == B_TRUE) {
63859585STim.Szeto@Sun.COM 		ret = psSetServicePersist(persistType);
63869585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
63879585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
63889585STim.Szeto@Sun.COM 			/* Set to old value */
63899585STim.Szeto@Sun.COM 			iPersistType = oldPersist;
63909585STim.Szeto@Sun.COM 		}
63919585STim.Szeto@Sun.COM 	}
63929585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
63939585STim.Szeto@Sun.COM 
63949585STim.Szeto@Sun.COM 	return (ret);
63959585STim.Szeto@Sun.COM }
63969585STim.Szeto@Sun.COM 
63979585STim.Szeto@Sun.COM /*
63989585STim.Szeto@Sun.COM  * Only returns internal state for persist. If unset, goes to ps. If that
63999585STim.Szeto@Sun.COM  * fails, returns default setting
64009585STim.Szeto@Sun.COM  */
64019585STim.Szeto@Sun.COM static uint8_t
64029585STim.Szeto@Sun.COM iGetPersistMethod()
64039585STim.Szeto@Sun.COM {
64049585STim.Szeto@Sun.COM 
64059585STim.Szeto@Sun.COM 	uint8_t persistType = 0;
64069585STim.Szeto@Sun.COM 
64079585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
64089585STim.Szeto@Sun.COM 	if (iLibSetPersist) {
64099585STim.Szeto@Sun.COM 		persistType = iPersistType;
64109585STim.Szeto@Sun.COM 	} else {
64119585STim.Szeto@Sun.COM 		int ret;
64129585STim.Szeto@Sun.COM 		ret = psGetServicePersist(&persistType);
64139585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
64149585STim.Szeto@Sun.COM 			/* set to default */
64159585STim.Szeto@Sun.COM 			persistType = STMF_DEFAULT_PERSIST;
64169585STim.Szeto@Sun.COM 		}
64179585STim.Szeto@Sun.COM 	}
64189585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
64199585STim.Szeto@Sun.COM 	return (persistType);
64209585STim.Szeto@Sun.COM }
64219585STim.Szeto@Sun.COM 
64229585STim.Szeto@Sun.COM /*
64239585STim.Szeto@Sun.COM  * Returns either library state or persistent config state depending on
64249585STim.Szeto@Sun.COM  * serviceState
64259585STim.Szeto@Sun.COM  */
64269585STim.Szeto@Sun.COM int
64279585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
64289585STim.Szeto@Sun.COM {
64299585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
64309585STim.Szeto@Sun.COM 
64319585STim.Szeto@Sun.COM 	if (persistType == NULL) {
64329585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
64339585STim.Szeto@Sun.COM 	}
64349585STim.Szeto@Sun.COM 	if (serviceState) {
64359585STim.Szeto@Sun.COM 		ret = psGetServicePersist(persistType);
64369585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
64379585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
64389585STim.Szeto@Sun.COM 		}
64399585STim.Szeto@Sun.COM 	} else {
64409585STim.Szeto@Sun.COM 		(void) pthread_mutex_lock(&persistenceTypeLock);
64419585STim.Szeto@Sun.COM 		if (iLibSetPersist) {
64429585STim.Szeto@Sun.COM 			*persistType = iPersistType;
64439585STim.Szeto@Sun.COM 		} else {
64449585STim.Szeto@Sun.COM 			*persistType = STMF_DEFAULT_PERSIST;
64459585STim.Szeto@Sun.COM 		}
64469585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
64479585STim.Szeto@Sun.COM 	}
64489585STim.Szeto@Sun.COM 
64499585STim.Szeto@Sun.COM 	return (ret);
64509585STim.Szeto@Sun.COM }
645110691STim.Szeto@Sun.COM 
645210691STim.Szeto@Sun.COM /*
645310725SJohn.Forte@Sun.COM  * stmfPostProxyMsg
645410725SJohn.Forte@Sun.COM  *
645510725SJohn.Forte@Sun.COM  * Purpose: Post a message to the proxy port provider
645610725SJohn.Forte@Sun.COM  *
645710725SJohn.Forte@Sun.COM  * buf - buffer containing message to post
645810725SJohn.Forte@Sun.COM  * buflen - buffer length
645910725SJohn.Forte@Sun.COM  */
646010725SJohn.Forte@Sun.COM int
646110725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen)
646210725SJohn.Forte@Sun.COM {
646310725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
646410725SJohn.Forte@Sun.COM 	int ioctlRet;
646510725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
646610725SJohn.Forte@Sun.COM 
646710725SJohn.Forte@Sun.COM 	if (buf == NULL) {
646810725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
646910725SJohn.Forte@Sun.COM 	}
647010725SJohn.Forte@Sun.COM 
647110725SJohn.Forte@Sun.COM 	/*
647210725SJohn.Forte@Sun.COM 	 * Issue ioctl to post the message
647310725SJohn.Forte@Sun.COM 	 */
647410725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
647510725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf_size = buflen;
647610725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf;
647710725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl);
647810725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
647910725SJohn.Forte@Sun.COM 		switch (errno) {
648010725SJohn.Forte@Sun.COM 			case EPERM:
648110725SJohn.Forte@Sun.COM 			case EACCES:
648210725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
648310725SJohn.Forte@Sun.COM 				break;
648410725SJohn.Forte@Sun.COM 			default:
648510725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_POST_MSG_FAILED;
648610725SJohn.Forte@Sun.COM 				break;
648710725SJohn.Forte@Sun.COM 		}
648810725SJohn.Forte@Sun.COM 	}
648910725SJohn.Forte@Sun.COM 
649010725SJohn.Forte@Sun.COM 	return (ret);
649110725SJohn.Forte@Sun.COM }
649210725SJohn.Forte@Sun.COM 
649310725SJohn.Forte@Sun.COM /*
649410725SJohn.Forte@Sun.COM  * stmfInitProxyDoor
649510725SJohn.Forte@Sun.COM  *
649610725SJohn.Forte@Sun.COM  * Purpose: Install door in proxy
649710725SJohn.Forte@Sun.COM  *
649810725SJohn.Forte@Sun.COM  * hdl - pointer to returned handle
649910725SJohn.Forte@Sun.COM  * fd - door from door_create()
650010725SJohn.Forte@Sun.COM  */
650110725SJohn.Forte@Sun.COM int
650210725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door)
650310725SJohn.Forte@Sun.COM {
650410725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
650510725SJohn.Forte@Sun.COM 	int ioctlRet;
650610725SJohn.Forte@Sun.COM 	int fd;
650710725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
650810725SJohn.Forte@Sun.COM 
650910725SJohn.Forte@Sun.COM 	if (hdl == NULL) {
651010725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
651110725SJohn.Forte@Sun.COM 	}
651210725SJohn.Forte@Sun.COM 
651310725SJohn.Forte@Sun.COM 	/*
651410725SJohn.Forte@Sun.COM 	 * Open control node for pppt
651510725SJohn.Forte@Sun.COM 	 */
651610725SJohn.Forte@Sun.COM 	if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) {
651710725SJohn.Forte@Sun.COM 		return (ret);
651810725SJohn.Forte@Sun.COM 	}
651910725SJohn.Forte@Sun.COM 
652010725SJohn.Forte@Sun.COM 	/*
652110725SJohn.Forte@Sun.COM 	 * Issue ioctl to install the door
652210725SJohn.Forte@Sun.COM 	 */
652310725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
652410725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_door_fd = (uint32_t)door;
652510725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl);
652610725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
652710725SJohn.Forte@Sun.COM 		switch (errno) {
652810725SJohn.Forte@Sun.COM 			case EPERM:
652910725SJohn.Forte@Sun.COM 			case EACCES:
653010725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
653110725SJohn.Forte@Sun.COM 				break;
653210725SJohn.Forte@Sun.COM 			case EINVAL:
653310725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_INVALID_ARG;
653410725SJohn.Forte@Sun.COM 				break;
653510725SJohn.Forte@Sun.COM 			case EBUSY:
653610725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_DOOR_INSTALLED;
653710725SJohn.Forte@Sun.COM 				break;
653810725SJohn.Forte@Sun.COM 			default:
653910725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
654010725SJohn.Forte@Sun.COM 				break;
654110725SJohn.Forte@Sun.COM 		}
654210725SJohn.Forte@Sun.COM 	}
654310725SJohn.Forte@Sun.COM 
654410725SJohn.Forte@Sun.COM 	/* return driver fd to caller */
654510725SJohn.Forte@Sun.COM 	*hdl = fd;
654610725SJohn.Forte@Sun.COM 	return (ret);
654710725SJohn.Forte@Sun.COM }
654810725SJohn.Forte@Sun.COM 
654910725SJohn.Forte@Sun.COM void
655010725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl)
655110725SJohn.Forte@Sun.COM {
655210725SJohn.Forte@Sun.COM 	(void) close(hdl);
655310725SJohn.Forte@Sun.COM }
655410725SJohn.Forte@Sun.COM 
655510725SJohn.Forte@Sun.COM /*
655610691STim.Szeto@Sun.COM  * validateLunNumIoctl
655710691STim.Szeto@Sun.COM  *
655810691STim.Szeto@Sun.COM  * Purpose: Issues ioctl to check and get available lun# in view entry
655910691STim.Szeto@Sun.COM  *
656010691STim.Szeto@Sun.COM  * viewEntry - view entry to use
656110691STim.Szeto@Sun.COM  */
656210691STim.Szeto@Sun.COM static int
656310691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry)
656410691STim.Szeto@Sun.COM {
656510691STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
656610691STim.Szeto@Sun.COM 	int ioctlRet;
656710691STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
656810691STim.Szeto@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
656910691STim.Szeto@Sun.COM 
657010691STim.Szeto@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
657110691STim.Szeto@Sun.COM 	/*
657210691STim.Szeto@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
657310691STim.Szeto@Sun.COM 	 * false on input
657410691STim.Szeto@Sun.COM 	 */
657510691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
657610691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
657710691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
657810691STim.Szeto@Sun.COM 
657910691STim.Szeto@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
658010691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
658110691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
658210691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
658310691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
658410691STim.Szeto@Sun.COM 	}
658510691STim.Szeto@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
658610691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup,
658710691STim.Szeto@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
658810691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
658910691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
659010691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
659110691STim.Szeto@Sun.COM 	}
659210691STim.Szeto@Sun.COM 	/* Validating the lun number */
659310691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
659410691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
659510691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
659610691STim.Szeto@Sun.COM 	}
659710691STim.Szeto@Sun.COM 
659810691STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
659910691STim.Szeto@Sun.COM 	/*
660010691STim.Szeto@Sun.COM 	 * Issue ioctl to validate lun# in the view entry
660110691STim.Szeto@Sun.COM 	 */
660210691STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
660310691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
660410691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
660510691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
660610691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
660710691STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl);
660810691STim.Szeto@Sun.COM 
660910691STim.Szeto@Sun.COM 	/* save available lun number */
661010691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
661110691STim.Szeto@Sun.COM 		bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
661210691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
661310691STim.Szeto@Sun.COM 	}
661410691STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
661510691STim.Szeto@Sun.COM 		switch (errno) {
661610691STim.Szeto@Sun.COM 			case EBUSY:
661710691STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
661810691STim.Szeto@Sun.COM 				break;
661910691STim.Szeto@Sun.COM 			case EPERM:
662010691STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
662110691STim.Szeto@Sun.COM 				break;
662210691STim.Szeto@Sun.COM 			case EACCES:
662310691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
662410691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
662510691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
662610691STim.Szeto@Sun.COM 						break;
662710691STim.Szeto@Sun.COM 					default:
662810691STim.Szeto@Sun.COM 						ret = STMF_ERROR_PERM;
662910691STim.Szeto@Sun.COM 						break;
663010691STim.Szeto@Sun.COM 				}
663110691STim.Szeto@Sun.COM 				break;
663210691STim.Szeto@Sun.COM 			default:
663310691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
663410691STim.Szeto@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
663510691STim.Szeto@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
663610691STim.Szeto@Sun.COM 						break;
663710691STim.Szeto@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
663810691STim.Szeto@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
663910691STim.Szeto@Sun.COM 						break;
664010691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
664110691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
664210691STim.Szeto@Sun.COM 						break;
664310691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_HG:
664410691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
664510691STim.Szeto@Sun.COM 						break;
664610691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_TG:
664710691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
664810691STim.Szeto@Sun.COM 						break;
664910691STim.Szeto@Sun.COM 					default:
665010691STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
665110691STim.Szeto@Sun.COM 						    "addViewEntryIoctl"
665210691STim.Szeto@Sun.COM 						    ":error(%d)",
665310691STim.Szeto@Sun.COM 						    stmfIoctl.stmf_error);
665410691STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
665510691STim.Szeto@Sun.COM 						break;
665610691STim.Szeto@Sun.COM 				}
665710691STim.Szeto@Sun.COM 				break;
665810691STim.Szeto@Sun.COM 		}
665910691STim.Szeto@Sun.COM 	}
666010691STim.Szeto@Sun.COM 	return (ret);
666110691STim.Szeto@Sun.COM }
666210691STim.Szeto@Sun.COM 
666310691STim.Szeto@Sun.COM /*
666410691STim.Szeto@Sun.COM  * stmfValidateView
666510691STim.Szeto@Sun.COM  *
666610691STim.Szeto@Sun.COM  * Purpose: Validate or get lun # base on TG, HG of view entry
666710691STim.Szeto@Sun.COM  *
666810691STim.Szeto@Sun.COM  * viewEntry - view entry structure to use
666910691STim.Szeto@Sun.COM  */
667010691STim.Szeto@Sun.COM int
667110691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry)
667210691STim.Szeto@Sun.COM {
667310691STim.Szeto@Sun.COM 	int ret;
667410691STim.Szeto@Sun.COM 	int fd;
667510691STim.Szeto@Sun.COM 	stmfViewEntry iViewEntry;
667610691STim.Szeto@Sun.COM 
667710691STim.Szeto@Sun.COM 	if (viewEntry == NULL) {
667810691STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
667910691STim.Szeto@Sun.COM 	}
668010691STim.Szeto@Sun.COM 
668110691STim.Szeto@Sun.COM 	/* initialize and set internal view entry */
668210691STim.Szeto@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
668310691STim.Szeto@Sun.COM 
668410691STim.Szeto@Sun.COM 	if (!viewEntry->allHosts) {
668510691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
668610691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.hostGroup));
668710691STim.Szeto@Sun.COM 	} else {
668810691STim.Szeto@Sun.COM 		iViewEntry.allHosts = B_TRUE;
668910691STim.Szeto@Sun.COM 	}
669010691STim.Szeto@Sun.COM 
669110691STim.Szeto@Sun.COM 	if (!viewEntry->allTargets) {
669210691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
669310691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.targetGroup));
669410691STim.Szeto@Sun.COM 	} else {
669510691STim.Szeto@Sun.COM 		iViewEntry.allTargets = B_TRUE;
669610691STim.Szeto@Sun.COM 	}
669710691STim.Szeto@Sun.COM 
669810691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
669910691STim.Szeto@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
670010691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
670110691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
670210691STim.Szeto@Sun.COM 	}
670310691STim.Szeto@Sun.COM 
670410691STim.Szeto@Sun.COM 	/*
670510691STim.Szeto@Sun.COM 	 * set users return view entry index valid flag to false
670610691STim.Szeto@Sun.COM 	 * in case of failure
670710691STim.Szeto@Sun.COM 	 */
670810691STim.Szeto@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
670910691STim.Szeto@Sun.COM 
671010691STim.Szeto@Sun.COM 	/* Check to ensure service exists */
671110691STim.Szeto@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
671210691STim.Szeto@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
671310691STim.Szeto@Sun.COM 	}
671410691STim.Szeto@Sun.COM 
671510691STim.Szeto@Sun.COM 	/* call init */
671610691STim.Szeto@Sun.COM 	ret = initializeConfig();
671710691STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
671810691STim.Szeto@Sun.COM 		return (ret);
671910691STim.Szeto@Sun.COM 	}
672010691STim.Szeto@Sun.COM 
672110691STim.Szeto@Sun.COM 	/*
672210691STim.Szeto@Sun.COM 	 * Open control node for stmf
672310691STim.Szeto@Sun.COM 	 */
672410691STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
672510691STim.Szeto@Sun.COM 		return (ret);
672610691STim.Szeto@Sun.COM 
672710691STim.Szeto@Sun.COM 	/*
672810691STim.Szeto@Sun.COM 	 * Validate lun# in the view entry from the driver
672910691STim.Szeto@Sun.COM 	 */
673010691STim.Szeto@Sun.COM 	ret = validateLunNumIoctl(fd, &iViewEntry);
673110691STim.Szeto@Sun.COM 	(void) close(fd);
673210691STim.Szeto@Sun.COM 
673310691STim.Szeto@Sun.COM 	/* save available lun number */
673410691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
673510691STim.Szeto@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
673610691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
673710691STim.Szeto@Sun.COM 	}
673810691STim.Szeto@Sun.COM 
673910691STim.Szeto@Sun.COM 	return (ret);
674010691STim.Szeto@Sun.COM }
6741