xref: /onnv-gate/usr/src/lib/libstmf/common/stmf.c (revision 12730:cb9032e66478)
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 /*
2212591SSrivijitha.Dugganapalli@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
237836SJohn.Forte@Sun.COM  */
247836SJohn.Forte@Sun.COM 
257836SJohn.Forte@Sun.COM #include <stdlib.h>
267836SJohn.Forte@Sun.COM #include <stdio.h>
277836SJohn.Forte@Sun.COM #include <wchar.h>
287836SJohn.Forte@Sun.COM #include <strings.h>
297836SJohn.Forte@Sun.COM #include <sys/types.h>
307836SJohn.Forte@Sun.COM #include <sys/stat.h>
317836SJohn.Forte@Sun.COM #include <fcntl.h>
327836SJohn.Forte@Sun.COM #include <unistd.h>
337836SJohn.Forte@Sun.COM #include <libintl.h>
347836SJohn.Forte@Sun.COM #include <errno.h>
357836SJohn.Forte@Sun.COM #include <string.h>
367836SJohn.Forte@Sun.COM #include <assert.h>
377836SJohn.Forte@Sun.COM #include <libnvpair.h>
387836SJohn.Forte@Sun.COM #include <pthread.h>
397836SJohn.Forte@Sun.COM #include <syslog.h>
407836SJohn.Forte@Sun.COM #include <libstmf.h>
417836SJohn.Forte@Sun.COM #include <netinet/in.h>
427836SJohn.Forte@Sun.COM #include <inttypes.h>
437836SJohn.Forte@Sun.COM #include <store.h>
447836SJohn.Forte@Sun.COM #include <locale.h>
459585STim.Szeto@Sun.COM #include <math.h>
469585STim.Szeto@Sun.COM #include <libstmf_impl.h>
477836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h>
489585STim.Szeto@Sun.COM #include <sys/stmf_sbd_ioctl.h>
4910725SJohn.Forte@Sun.COM #include <sys/pppt_ioctl.h>
5011103SJohn.Forte@Sun.COM #include <macros.h>
517836SJohn.Forte@Sun.COM 
527836SJohn.Forte@Sun.COM #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
539585STim.Szeto@Sun.COM #define	SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
5410725SJohn.Forte@Sun.COM #define	PPPT_PATH    "/devices/pseudo/pppt@0:pppt"
557836SJohn.Forte@Sun.COM 
567836SJohn.Forte@Sun.COM #define	EUI "eui."
577836SJohn.Forte@Sun.COM #define	WWN "wwn."
587836SJohn.Forte@Sun.COM #define	IQN "iqn."
599585STim.Szeto@Sun.COM #define	LU_ASCII_GUID_SIZE 32
609585STim.Szeto@Sun.COM #define	LU_GUID_SIZE 16
619585STim.Szeto@Sun.COM #define	OUI_ASCII_SIZE 6
6210765SJohn.Forte@Sun.COM #define	HOST_ID_ASCII_SIZE 8
639585STim.Szeto@Sun.COM #define	OUI_SIZE 3
6410765SJohn.Forte@Sun.COM #define	HOST_ID_SIZE 4
657836SJohn.Forte@Sun.COM #define	IDENT_LENGTH_BYTE 3
667836SJohn.Forte@Sun.COM 
679585STim.Szeto@Sun.COM /* various initial allocation values */
689585STim.Szeto@Sun.COM #define	ALLOC_LU		8192
699585STim.Szeto@Sun.COM #define	ALLOC_TARGET_PORT	2048
709585STim.Szeto@Sun.COM #define	ALLOC_PROVIDER		64
719585STim.Szeto@Sun.COM #define	ALLOC_GROUP		2048
729585STim.Szeto@Sun.COM #define	ALLOC_SESSION		2048
739585STim.Szeto@Sun.COM #define	ALLOC_VE		256
749585STim.Szeto@Sun.COM #define	ALLOC_PP_DATA_SIZE	128*1024
759585STim.Szeto@Sun.COM #define	ALLOC_GRP_MEMBER	256
769585STim.Szeto@Sun.COM 
777836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME	223
789585STim.Szeto@Sun.COM #define	MAX_SERIAL_SIZE 252 + 1
799585STim.Szeto@Sun.COM #define	MAX_LU_ALIAS_SIZE 256
809585STim.Szeto@Sun.COM #define	MAX_SBD_PROPS	MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
817836SJohn.Forte@Sun.COM 
827836SJohn.Forte@Sun.COM #define	OPEN_STMF 0
837836SJohn.Forte@Sun.COM #define	OPEN_EXCL_STMF O_EXCL
847836SJohn.Forte@Sun.COM 
859585STim.Szeto@Sun.COM #define	OPEN_SBD 0
869585STim.Szeto@Sun.COM #define	OPEN_EXCL_SBD O_EXCL
879585STim.Szeto@Sun.COM 
8810725SJohn.Forte@Sun.COM #define	OPEN_PPPT 0
8910725SJohn.Forte@Sun.COM #define	OPEN_EXCL_PPPT O_EXCL
9010725SJohn.Forte@Sun.COM 
917836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_TYPE 0
927836SJohn.Forte@Sun.COM #define	TARGET_TYPE 1
937836SJohn.Forte@Sun.COM #define	STMF_SERVICE_TYPE 2
947836SJohn.Forte@Sun.COM 
959585STim.Szeto@Sun.COM #define	HOST_GROUP   1
969585STim.Szeto@Sun.COM #define	TARGET_GROUP 2
979585STim.Szeto@Sun.COM 
989585STim.Szeto@Sun.COM /* set default persistence here */
999585STim.Szeto@Sun.COM #define	STMF_DEFAULT_PERSIST	STMF_PERSIST_SMF
1009585STim.Szeto@Sun.COM 
1019585STim.Szeto@Sun.COM #define	MAX_PROVIDER_RETRY 30
1029585STim.Szeto@Sun.COM 
1037836SJohn.Forte@Sun.COM static int openStmf(int, int *fd);
1049585STim.Szeto@Sun.COM static int openSbd(int, int *fd);
10510725SJohn.Forte@Sun.COM static int openPppt(int, int *fd);
1067836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *);
1077836SJohn.Forte@Sun.COM static int loadStore(int fd);
1087836SJohn.Forte@Sun.COM static int initializeConfig();
1097836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
1107836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *);
1117836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
1127836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *);
1137836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *);
1147836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *);
1157836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int);
1169585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
1179585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *);
1189585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *);
1199585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid);
1209585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
1219585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
1229585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
1239585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *);
1249585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *);
1259585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t);
1269585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *);
12711103SJohn.Forte@Sun.COM static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen);
1289585STim.Szeto@Sun.COM static int checkHexUpper(char *);
1299585STim.Szeto@Sun.COM static int strToShift(const char *);
1309585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *);
1319585STim.Szeto@Sun.COM static void diskError(uint32_t, int *);
1329585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *);
1339585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
1349585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
1359585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t);
1369585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod();
1379585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int);
1389585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int);
1399585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
1409585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *);
14110725SJohn.Forte@Sun.COM static int setDiskStandby(stmfGuid *luGuid);
14211103SJohn.Forte@Sun.COM static int setDiskGlobalProp(uint32_t, const char *);
1439585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *);
14410725SJohn.Forte@Sun.COM static void deleteNonActiveLus();
14512682SSrivijitha.Dugganapalli@Sun.COM static int loadStmfProp(int fd);
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
openStmf(int flag,int * fd)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
openSbd(int flag,int * fd)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
openPppt(int flag,int * fd)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
initializeConfig()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
groupIoctl(int fd,int cmd,stmfGroupName * groupName)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
groupMemberIoctl(int fd,int cmd,stmfGroupName * groupName,stmfDevid * devid)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
viewEntryCompare(const void * p1,const void * p2)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
guidCompare(const void * p1,const void * p2)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
stmfAddToHostGroup(stmfGroupName * hostGroupName,stmfDevid * hostName)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
stmfAddToTargetGroup(stmfGroupName * targetGroupName,stmfDevid * targetName)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
addViewEntryIoctl(int fd,stmfGuid * lu,stmfViewEntry * viewEntry)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
stmfAddViewEntry(stmfGuid * lu,stmfViewEntry * viewEntry)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
stmfClearProviderData(char * providerName,int providerType)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
stmfCreateHostGroup(stmfGroupName * hostGroupName)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
stmfCreateLu(luResource hdl,stmfGuid * luGuid)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
stmfCreateLuResource(uint16_t dType,luResource * hdl)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
createDiskLu(diskResource * disk,stmfGuid * createdGuid)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
stmfImportLu(uint16_t dType,char * fname,stmfGuid * luGuid)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
importDiskLu(char * fname,stmfGuid * createdGuid)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) {
141712591SSrivijitha.Dugganapalli@Sun.COM 
141812591SSrivijitha.Dugganapalli@Sun.COM 		if (createdGuid && sbdIoctl.stmf_error ==
141912591SSrivijitha.Dugganapalli@Sun.COM 		    SBD_RET_FILE_ALREADY_REGISTERED) {
142012591SSrivijitha.Dugganapalli@Sun.COM 			bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
142112591SSrivijitha.Dugganapalli@Sun.COM 			    sizeof (sbdLu->ilu_ret_guid));
142212591SSrivijitha.Dugganapalli@Sun.COM 		}
142312591SSrivijitha.Dugganapalli@Sun.COM 
14249585STim.Szeto@Sun.COM 		savedErrno = errno;
14259585STim.Szeto@Sun.COM 		switch (savedErrno) {
14269585STim.Szeto@Sun.COM 			case EBUSY:
14279585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
14289585STim.Szeto@Sun.COM 				break;
14299585STim.Szeto@Sun.COM 			case EPERM:
14309585STim.Szeto@Sun.COM 			case EACCES:
14319585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
14329585STim.Szeto@Sun.COM 				break;
14339585STim.Szeto@Sun.COM 			default:
14349585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
14359585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
14369585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
14379585STim.Szeto@Sun.COM 					"importDiskLu:ioctl "
14389585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
14399585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
14409585STim.Szeto@Sun.COM 				}
14419585STim.Szeto@Sun.COM 				break;
14429585STim.Szeto@Sun.COM 		}
14439585STim.Szeto@Sun.COM 	}
14449585STim.Szeto@Sun.COM 
144512591SSrivijitha.Dugganapalli@Sun.COM 
14469585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
14479585STim.Szeto@Sun.COM 		goto done;
14489585STim.Szeto@Sun.COM 	}
14499585STim.Szeto@Sun.COM 
14509585STim.Szeto@Sun.COM 	/*
14519585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
14529585STim.Szeto@Sun.COM 	 * NULL and add it to the persistent store for sbd
14539585STim.Szeto@Sun.COM 	 */
14549585STim.Szeto@Sun.COM 	if (createdGuid) {
14559585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
14569585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14579585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(createdGuid, fname);
14589585STim.Szeto@Sun.COM 	} else {
14599585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
14609585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14619585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&iGuid, fname);
14629585STim.Szeto@Sun.COM 	}
14639585STim.Szeto@Sun.COM done:
14649585STim.Szeto@Sun.COM 	free(sbdLu);
14659585STim.Szeto@Sun.COM 	(void) close(fd);
14669585STim.Szeto@Sun.COM 	return (ret);
14679585STim.Szeto@Sun.COM }
14689585STim.Szeto@Sun.COM 
14699585STim.Szeto@Sun.COM /*
14709585STim.Szeto@Sun.COM  * diskError
14719585STim.Szeto@Sun.COM  *
14729585STim.Szeto@Sun.COM  * Purpose: Translate sbd driver error
14739585STim.Szeto@Sun.COM  */
14749585STim.Szeto@Sun.COM static void
diskError(uint32_t stmfError,int * ret)14759585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret)
14769585STim.Szeto@Sun.COM {
14779585STim.Szeto@Sun.COM 	switch (stmfError) {
14789585STim.Szeto@Sun.COM 		case SBD_RET_META_CREATION_FAILED:
14799585STim.Szeto@Sun.COM 		case SBD_RET_ZFS_META_CREATE_FAILED:
14809585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_CREATION;
14819585STim.Szeto@Sun.COM 			break;
14829585STim.Szeto@Sun.COM 		case SBD_RET_INVALID_BLKSIZE:
14839585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_INVALID_BLKSIZE;
14849585STim.Szeto@Sun.COM 			break;
14859585STim.Szeto@Sun.COM 		case SBD_RET_FILE_ALREADY_REGISTERED:
14869585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_IN_USE;
14879585STim.Szeto@Sun.COM 			break;
14889585STim.Szeto@Sun.COM 		case SBD_RET_GUID_ALREADY_REGISTERED:
14899585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_GUID_IN_USE;
14909585STim.Szeto@Sun.COM 			break;
14919585STim.Szeto@Sun.COM 		case SBD_RET_META_PATH_NOT_ABSOLUTE:
14929585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_LOOKUP_FAILED:
14939585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_OPEN_FAILED:
14949585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_GETATTR_FAILED:
14959585STim.Szeto@Sun.COM 		case SBD_RET_NO_META:
14969585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_FILE_NAME;
14979585STim.Szeto@Sun.COM 			break;
14989585STim.Szeto@Sun.COM 		case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
14999585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_LOOKUP_FAILED:
15009585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_OPEN_FAILED:
15019585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_GETATTR_FAILED:
15029585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_DATA_FILE_NAME;
15039585STim.Szeto@Sun.COM 			break;
15049585STim.Szeto@Sun.COM 		case SBD_RET_FILE_SIZE_ERROR:
15059585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_SIZE_INVALID;
15069585STim.Szeto@Sun.COM 			break;
15079585STim.Szeto@Sun.COM 		case SBD_RET_SIZE_OUT_OF_RANGE:
15089585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
15099585STim.Szeto@Sun.COM 			break;
15109585STim.Szeto@Sun.COM 		case SBD_RET_LU_BUSY:
15119585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_LU_BUSY;
15129585STim.Szeto@Sun.COM 			break;
15139585STim.Szeto@Sun.COM 		case SBD_RET_WRITE_CACHE_SET_FAILED:
15149585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_WRITE_CACHE_SET;
15159585STim.Szeto@Sun.COM 			break;
151610725SJohn.Forte@Sun.COM 		case SBD_RET_ACCESS_STATE_FAILED:
151710725SJohn.Forte@Sun.COM 			*ret = STMF_ERROR_ACCESS_STATE_SET;
151810725SJohn.Forte@Sun.COM 			break;
15199585STim.Szeto@Sun.COM 		default:
15209585STim.Szeto@Sun.COM 			*ret = STMF_STATUS_ERROR;
15219585STim.Szeto@Sun.COM 			break;
15229585STim.Szeto@Sun.COM 	}
15239585STim.Szeto@Sun.COM }
15249585STim.Szeto@Sun.COM 
15259585STim.Szeto@Sun.COM /*
15269585STim.Szeto@Sun.COM  * Creates a logical unit resource of type STMF_DISK.
15279585STim.Szeto@Sun.COM  *
15289585STim.Szeto@Sun.COM  * No defaults should be set here as all defaults are derived from the
15299585STim.Szeto@Sun.COM  * driver's default settings.
15309585STim.Szeto@Sun.COM  */
15319585STim.Szeto@Sun.COM static int
createDiskResource(luResourceImpl * hdl)15329585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl)
15339585STim.Szeto@Sun.COM {
15349585STim.Szeto@Sun.COM 	hdl->type = STMF_DISK;
15359585STim.Szeto@Sun.COM 
15369585STim.Szeto@Sun.COM 	hdl->resource = calloc(1, sizeof (diskResource));
15379585STim.Szeto@Sun.COM 	if (hdl->resource == NULL) {
15389585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
15399585STim.Szeto@Sun.COM 	}
15409585STim.Szeto@Sun.COM 
15419585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
15429585STim.Szeto@Sun.COM }
15439585STim.Szeto@Sun.COM 
15449585STim.Szeto@Sun.COM /*
15459585STim.Szeto@Sun.COM  * stmfDeleteLu
15469585STim.Szeto@Sun.COM  *
15479585STim.Szeto@Sun.COM  * Purpose: Delete a logical unit
15489585STim.Szeto@Sun.COM  *
15499585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
15509585STim.Szeto@Sun.COM  *
15519585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
15529585STim.Szeto@Sun.COM  *	    unit
15539585STim.Szeto@Sun.COM  */
15549585STim.Szeto@Sun.COM int
stmfDeleteLu(stmfGuid * luGuid)15559585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid)
15569585STim.Szeto@Sun.COM {
15579585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15589585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
15599585STim.Szeto@Sun.COM 
15609585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
15619585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
15629585STim.Szeto@Sun.COM 	}
15639585STim.Szeto@Sun.COM 
15649585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
15659585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
15669585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
15679585STim.Szeto@Sun.COM 		return (ret);
15689585STim.Szeto@Sun.COM 	} else {
15699585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
15709585STim.Szeto@Sun.COM 			ret = deleteDiskLu(luGuid);
15719585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
15729585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
15739585STim.Szeto@Sun.COM 		} else {
15749585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
15759585STim.Szeto@Sun.COM 		}
15769585STim.Szeto@Sun.COM 	}
15779585STim.Szeto@Sun.COM 
15789585STim.Szeto@Sun.COM 	return (ret);
15799585STim.Szeto@Sun.COM }
15809585STim.Szeto@Sun.COM 
15819585STim.Szeto@Sun.COM static int
deleteDiskLu(stmfGuid * luGuid)15829585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid)
15839585STim.Szeto@Sun.COM {
15849585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15859585STim.Szeto@Sun.COM 	int fd;
15869585STim.Szeto@Sun.COM 	int savedErrno;
15879585STim.Szeto@Sun.COM 	int ioctlRet;
15889585STim.Szeto@Sun.COM 	sbd_delete_lu_t deleteLu = {0};
15899585STim.Szeto@Sun.COM 
15909585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
15919585STim.Szeto@Sun.COM 
15929585STim.Szeto@Sun.COM 	/*
15939585STim.Szeto@Sun.COM 	 * Open control node for sbd
15949585STim.Szeto@Sun.COM 	 */
15959585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
15969585STim.Szeto@Sun.COM 		return (ret);
15979585STim.Szeto@Sun.COM 
15989585STim.Szeto@Sun.COM 	ret = removeGuidFromDiskStore(luGuid);
15999585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
16009585STim.Szeto@Sun.COM 		goto done;
16019585STim.Szeto@Sun.COM 	}
16029585STim.Szeto@Sun.COM 
16039585STim.Szeto@Sun.COM 	bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
16049585STim.Szeto@Sun.COM 	deleteLu.dlu_by_guid = 1;
16059585STim.Szeto@Sun.COM 
16069585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
16079585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
16089585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
16099585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
16109585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
16119585STim.Szeto@Sun.COM 		savedErrno = errno;
16129585STim.Szeto@Sun.COM 		switch (savedErrno) {
16139585STim.Szeto@Sun.COM 			case EBUSY:
16149585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
16159585STim.Szeto@Sun.COM 				break;
16169585STim.Szeto@Sun.COM 			case EPERM:
16179585STim.Szeto@Sun.COM 			case EACCES:
16189585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
16199585STim.Szeto@Sun.COM 				break;
16209585STim.Szeto@Sun.COM 			case ENOENT:
16219585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
16229585STim.Szeto@Sun.COM 				break;
16239585STim.Szeto@Sun.COM 			default:
16249585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
16259585STim.Szeto@Sun.COM 				    "deleteDiskLu:ioctl error(%d) (%d) (%d)",
16269585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
16279585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
16289585STim.Szeto@Sun.COM 				break;
16299585STim.Szeto@Sun.COM 		}
16309585STim.Szeto@Sun.COM 	}
16319585STim.Szeto@Sun.COM 
16329585STim.Szeto@Sun.COM done:
16339585STim.Szeto@Sun.COM 	(void) close(fd);
16349585STim.Szeto@Sun.COM 	return (ret);
16359585STim.Szeto@Sun.COM }
16369585STim.Szeto@Sun.COM 
16379585STim.Szeto@Sun.COM /*
163810725SJohn.Forte@Sun.COM  * stmfLuStandby
163910725SJohn.Forte@Sun.COM  *
164010725SJohn.Forte@Sun.COM  * Purpose: Sets access state to standby
164110725SJohn.Forte@Sun.COM  *
164210725SJohn.Forte@Sun.COM  * luGuid - guid of registered logical unit
164310725SJohn.Forte@Sun.COM  *
164410725SJohn.Forte@Sun.COM  */
164510725SJohn.Forte@Sun.COM int
stmfLuStandby(stmfGuid * luGuid)164610725SJohn.Forte@Sun.COM stmfLuStandby(stmfGuid *luGuid)
164710725SJohn.Forte@Sun.COM {
164810725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
164910725SJohn.Forte@Sun.COM 	stmfLogicalUnitProperties luProps;
165010725SJohn.Forte@Sun.COM 
165110725SJohn.Forte@Sun.COM 	if (luGuid == NULL) {
165210725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
165310725SJohn.Forte@Sun.COM 	}
165410725SJohn.Forte@Sun.COM 
165510725SJohn.Forte@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
165610725SJohn.Forte@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
165710725SJohn.Forte@Sun.COM 	    != STMF_STATUS_SUCCESS) {
165810725SJohn.Forte@Sun.COM 		return (ret);
165910725SJohn.Forte@Sun.COM 	} else {
166010725SJohn.Forte@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
166110725SJohn.Forte@Sun.COM 			ret = setDiskStandby(luGuid);
166210725SJohn.Forte@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
166310725SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
166410725SJohn.Forte@Sun.COM 		} else {
166510725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
166610725SJohn.Forte@Sun.COM 		}
166710725SJohn.Forte@Sun.COM 	}
166810725SJohn.Forte@Sun.COM 
166910725SJohn.Forte@Sun.COM 	return (ret);
167010725SJohn.Forte@Sun.COM }
167110725SJohn.Forte@Sun.COM 
167210725SJohn.Forte@Sun.COM static int
setDiskStandby(stmfGuid * luGuid)167310725SJohn.Forte@Sun.COM setDiskStandby(stmfGuid *luGuid)
167410725SJohn.Forte@Sun.COM {
167510725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
167610725SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
167710725SJohn.Forte@Sun.COM 	sbd_set_lu_standby_t sbdLu = {0};
167810725SJohn.Forte@Sun.COM 	int ioctlRet;
167910725SJohn.Forte@Sun.COM 	int savedErrno;
168010725SJohn.Forte@Sun.COM 	int fd = 0;
168110725SJohn.Forte@Sun.COM 
168210725SJohn.Forte@Sun.COM 	/*
168310725SJohn.Forte@Sun.COM 	 * Open control node for sbd
168410725SJohn.Forte@Sun.COM 	 */
168510725SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
168610725SJohn.Forte@Sun.COM 		return (ret);
168710725SJohn.Forte@Sun.COM 
168810725SJohn.Forte@Sun.COM 	bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid));
168910725SJohn.Forte@Sun.COM 
169010725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
169110725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t);
169210725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu;
169310725SJohn.Forte@Sun.COM 
169410725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl);
169510725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
169610725SJohn.Forte@Sun.COM 		savedErrno = errno;
169710725SJohn.Forte@Sun.COM 		switch (savedErrno) {
169810725SJohn.Forte@Sun.COM 			case EBUSY:
169910725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
170010725SJohn.Forte@Sun.COM 				break;
170110725SJohn.Forte@Sun.COM 			case EPERM:
170210725SJohn.Forte@Sun.COM 			case EACCES:
170310725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
170410725SJohn.Forte@Sun.COM 				break;
170510725SJohn.Forte@Sun.COM 			default:
170610725SJohn.Forte@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
170710725SJohn.Forte@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
170810725SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
170910725SJohn.Forte@Sun.COM 					"setDiskStandby:ioctl "
171010725SJohn.Forte@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
171110725SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
171210725SJohn.Forte@Sun.COM 				}
171310725SJohn.Forte@Sun.COM 				break;
171410725SJohn.Forte@Sun.COM 		}
171510725SJohn.Forte@Sun.COM 	}
1716*12730SJohn.Forte@Sun.COM 	(void) close(fd);
171710725SJohn.Forte@Sun.COM 	return (ret);
171810725SJohn.Forte@Sun.COM }
171910725SJohn.Forte@Sun.COM 
172010725SJohn.Forte@Sun.COM /*
17219585STim.Szeto@Sun.COM  * stmfModifyLu
17229585STim.Szeto@Sun.COM  *
17239585STim.Szeto@Sun.COM  * Purpose: Modify properties of a logical unit
17249585STim.Szeto@Sun.COM  *
17259585STim.Szeto@Sun.COM  * luGuid - guid of registered logical unit
17269585STim.Szeto@Sun.COM  * prop - property to modify
17279585STim.Szeto@Sun.COM  * propVal - property value to set
17289585STim.Szeto@Sun.COM  *
17299585STim.Szeto@Sun.COM  */
17309585STim.Szeto@Sun.COM int
stmfModifyLu(stmfGuid * luGuid,uint32_t prop,const char * propVal)17319585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
17329585STim.Szeto@Sun.COM {
17339585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17349585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
17359585STim.Szeto@Sun.COM 
17369585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
17379585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17389585STim.Szeto@Sun.COM 	}
17399585STim.Szeto@Sun.COM 
17409585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
17419585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
17429585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
17439585STim.Szeto@Sun.COM 		return (ret);
17449585STim.Szeto@Sun.COM 	} else {
17459585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
17469585STim.Szeto@Sun.COM 			ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
17479585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
17489585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
17499585STim.Szeto@Sun.COM 		} else {
17509585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
17519585STim.Szeto@Sun.COM 		}
17529585STim.Szeto@Sun.COM 	}
17539585STim.Szeto@Sun.COM 
17549585STim.Szeto@Sun.COM 	return (ret);
17559585STim.Szeto@Sun.COM }
17569585STim.Szeto@Sun.COM 
17579585STim.Szeto@Sun.COM /*
17589585STim.Szeto@Sun.COM  * stmfModifyLuByFname
17599585STim.Szeto@Sun.COM  *
17609585STim.Szeto@Sun.COM  * Purpose: Modify a device by filename. Device does not need to be registered.
17619585STim.Szeto@Sun.COM  *
17629585STim.Szeto@Sun.COM  * dType - type of device to modify
17639585STim.Szeto@Sun.COM  *         STMF_DISK
17649585STim.Szeto@Sun.COM  *
17659585STim.Szeto@Sun.COM  * fname - filename or meta filename
17669585STim.Szeto@Sun.COM  * prop - valid property identifier
17679585STim.Szeto@Sun.COM  * propVal - property value
17689585STim.Szeto@Sun.COM  *
17699585STim.Szeto@Sun.COM  */
17709585STim.Szeto@Sun.COM int
stmfModifyLuByFname(uint16_t dType,const char * fname,uint32_t prop,const char * propVal)17719585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
17729585STim.Szeto@Sun.COM     const char *propVal)
17739585STim.Szeto@Sun.COM {
17749585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17759585STim.Szeto@Sun.COM 	if (fname == NULL) {
17769585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17779585STim.Szeto@Sun.COM 	}
17789585STim.Szeto@Sun.COM 
17799585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
17809585STim.Szeto@Sun.COM 		ret = modifyDiskLuProp(NULL, fname, prop, propVal);
17819585STim.Szeto@Sun.COM 	} else {
17829585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17839585STim.Szeto@Sun.COM 	}
17849585STim.Szeto@Sun.COM 
17859585STim.Szeto@Sun.COM 	return (ret);
17869585STim.Szeto@Sun.COM }
17879585STim.Szeto@Sun.COM 
17889585STim.Szeto@Sun.COM static int
modifyDiskLuProp(stmfGuid * luGuid,const char * fname,uint32_t prop,const char * propVal)17899585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
17909585STim.Szeto@Sun.COM     const char *propVal)
17919585STim.Szeto@Sun.COM {
17929585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17939585STim.Szeto@Sun.COM 	luResource hdl = NULL;
17949585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl;
17959585STim.Szeto@Sun.COM 
17969585STim.Szeto@Sun.COM 	ret = stmfCreateLuResource(STMF_DISK, &hdl);
17979585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17989585STim.Szeto@Sun.COM 		return (ret);
17999585STim.Szeto@Sun.COM 	}
18009585STim.Szeto@Sun.COM 	ret = validateModifyDiskProp(prop);
18019585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
18029585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
18039585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_PROP);
18049585STim.Szeto@Sun.COM 	}
18059585STim.Szeto@Sun.COM 	ret = stmfSetLuProp(hdl, prop, propVal);
18069585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
18079585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
18089585STim.Szeto@Sun.COM 		return (ret);
18099585STim.Szeto@Sun.COM 	}
18109585STim.Szeto@Sun.COM 	luPropsHdl = hdl;
18119585STim.Szeto@Sun.COM 	ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
18129585STim.Szeto@Sun.COM 	(void) stmfFreeLuResource(hdl);
18139585STim.Szeto@Sun.COM 	return (ret);
18149585STim.Szeto@Sun.COM }
18159585STim.Szeto@Sun.COM 
18169585STim.Szeto@Sun.COM static int
validateModifyDiskProp(uint32_t prop)18179585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop)
18189585STim.Szeto@Sun.COM {
18199585STim.Szeto@Sun.COM 	switch (prop) {
18209585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
18219585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
182210113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
18239585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
18249585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
18259585STim.Szeto@Sun.COM 			return (STMF_STATUS_SUCCESS);
18269585STim.Szeto@Sun.COM 			break;
18279585STim.Szeto@Sun.COM 		default:
18289585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
18299585STim.Szeto@Sun.COM 			break;
18309585STim.Szeto@Sun.COM 	}
18319585STim.Szeto@Sun.COM }
18329585STim.Szeto@Sun.COM 
18339585STim.Szeto@Sun.COM static int
modifyDiskLu(diskResource * disk,stmfGuid * luGuid,const char * fname)18349585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
18359585STim.Szeto@Sun.COM {
18369585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
18379585STim.Szeto@Sun.COM 	int luAliasLen = 0;
183810113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
18399585STim.Szeto@Sun.COM 	int mluBufSize = 0;
18409585STim.Szeto@Sun.COM 	int bufOffset = 0;
18419585STim.Szeto@Sun.COM 	int fd = 0;
18429585STim.Szeto@Sun.COM 	int ioctlRet;
18439585STim.Szeto@Sun.COM 	int savedErrno;
18449585STim.Szeto@Sun.COM 	int fnameSize = 0;
18459585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
18469585STim.Szeto@Sun.COM 
18479585STim.Szeto@Sun.COM 	sbd_modify_lu_t *sbdLu = NULL;
18489585STim.Szeto@Sun.COM 
18499585STim.Szeto@Sun.COM 	if (luGuid == NULL && fname == NULL) {
18509585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
18519585STim.Szeto@Sun.COM 	}
18529585STim.Szeto@Sun.COM 
18539585STim.Szeto@Sun.COM 	if (fname) {
18549585STim.Szeto@Sun.COM 		fnameSize = strlen(fname) + 1;
18559585STim.Szeto@Sun.COM 		mluBufSize += fnameSize;
18569585STim.Szeto@Sun.COM 	}
18579585STim.Szeto@Sun.COM 
18589585STim.Szeto@Sun.COM 	/*
18599585STim.Szeto@Sun.COM 	 * Open control node for sbd
18609585STim.Szeto@Sun.COM 	 */
18619585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
18629585STim.Szeto@Sun.COM 		return (ret);
18639585STim.Szeto@Sun.COM 
18649585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18659585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
18669585STim.Szeto@Sun.COM 		mluBufSize += luAliasLen + 1;
18679585STim.Szeto@Sun.COM 	}
18689585STim.Szeto@Sun.COM 
186910113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
187010113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
187110113SNattuvetty.Bhavyan@Sun.COM 		mluBufSize += luMgmtUrlLen + 1;
187210113SNattuvetty.Bhavyan@Sun.COM 	}
187310113SNattuvetty.Bhavyan@Sun.COM 
18749585STim.Szeto@Sun.COM 	/*
18759585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
18769585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
18779585STim.Szeto@Sun.COM 	 */
18789585STim.Szeto@Sun.COM 	sbdLu = (sbd_modify_lu_t *)calloc(1,
18799585STim.Szeto@Sun.COM 	    sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
18809585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
18819585STim.Szeto@Sun.COM 		(void) close(fd);
18829585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
18839585STim.Szeto@Sun.COM 	}
18849585STim.Szeto@Sun.COM 
18859585STim.Szeto@Sun.COM 	sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
18869585STim.Szeto@Sun.COM 	    mluBufSize - 8 + fnameSize;
18879585STim.Szeto@Sun.COM 
18889585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18899585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_valid = 1;
18909585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_off = bufOffset;
18919585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
18929585STim.Szeto@Sun.COM 		    luAliasLen + 1);
18939585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
18949585STim.Szeto@Sun.COM 	}
18959585STim.Szeto@Sun.COM 
189610113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
189710113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_valid = 1;
189810113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_off = bufOffset;
189910113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
190010113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
190110113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
190210113SNattuvetty.Bhavyan@Sun.COM 	}
190310113SNattuvetty.Bhavyan@Sun.COM 
19049585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
19059585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size_valid = 1;
19069585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size = disk->luSize;
19079585STim.Szeto@Sun.COM 	}
19089585STim.Szeto@Sun.COM 
19099585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
19109585STim.Szeto@Sun.COM 		sbdLu->mlu_write_protected_valid = 1;
19119585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
19129585STim.Szeto@Sun.COM 			sbdLu->mlu_write_protected = 1;
19139585STim.Szeto@Sun.COM 		}
19149585STim.Szeto@Sun.COM 	}
19159585STim.Szeto@Sun.COM 
19169585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
19179585STim.Szeto@Sun.COM 		sbdLu->mlu_writeback_cache_disable_valid = 1;
19189585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
19199585STim.Szeto@Sun.COM 			sbdLu->mlu_writeback_cache_disable = 1;
19209585STim.Szeto@Sun.COM 		}
19219585STim.Szeto@Sun.COM 	}
19229585STim.Szeto@Sun.COM 
19239585STim.Szeto@Sun.COM 	if (luGuid) {
19249585STim.Szeto@Sun.COM 		bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
19259585STim.Szeto@Sun.COM 		sbdLu->mlu_by_guid = 1;
19269585STim.Szeto@Sun.COM 	} else {
19279585STim.Szeto@Sun.COM 		sbdLu->mlu_fname_off = bufOffset;
19289585STim.Szeto@Sun.COM 		bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
19299585STim.Szeto@Sun.COM 		sbdLu->mlu_by_fname = 1;
19309585STim.Szeto@Sun.COM 	}
19319585STim.Szeto@Sun.COM 
19329585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
19339585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
19349585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
19359585STim.Szeto@Sun.COM 
19369585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
19379585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
19389585STim.Szeto@Sun.COM 		savedErrno = errno;
19399585STim.Szeto@Sun.COM 		switch (savedErrno) {
19409585STim.Szeto@Sun.COM 			case EBUSY:
19419585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
19429585STim.Szeto@Sun.COM 				break;
19439585STim.Szeto@Sun.COM 			case EPERM:
19449585STim.Szeto@Sun.COM 			case EACCES:
19459585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
19469585STim.Szeto@Sun.COM 				break;
19479585STim.Szeto@Sun.COM 			default:
19489585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
19499585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
19509585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
19519585STim.Szeto@Sun.COM 					"modifyDiskLu:ioctl "
19529585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
19539585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
19549585STim.Szeto@Sun.COM 				}
19559585STim.Szeto@Sun.COM 				break;
19569585STim.Szeto@Sun.COM 		}
19579585STim.Szeto@Sun.COM 	}
19589585STim.Szeto@Sun.COM 
19599585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
19609585STim.Szeto@Sun.COM 		goto done;
19619585STim.Szeto@Sun.COM 	}
19629585STim.Szeto@Sun.COM 
19639585STim.Szeto@Sun.COM done:
19649585STim.Szeto@Sun.COM 	free(sbdLu);
19659585STim.Szeto@Sun.COM 	(void) close(fd);
19669585STim.Szeto@Sun.COM 	return (ret);
19679585STim.Szeto@Sun.COM }
19689585STim.Szeto@Sun.COM 
19699585STim.Szeto@Sun.COM /*
19709585STim.Szeto@Sun.COM  * removeGuidFromDiskStore
19719585STim.Szeto@Sun.COM  *
19729585STim.Szeto@Sun.COM  * Purpose: delete a logical unit from the sbd provider data
19739585STim.Szeto@Sun.COM  */
19749585STim.Szeto@Sun.COM static int
removeGuidFromDiskStore(stmfGuid * guid)19759585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid)
19769585STim.Szeto@Sun.COM {
19779585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, NULL, B_FALSE));
19789585STim.Szeto@Sun.COM }
19799585STim.Szeto@Sun.COM 
19809585STim.Szeto@Sun.COM 
19819585STim.Szeto@Sun.COM /*
19829585STim.Szeto@Sun.COM  * addGuidToDiskStore
19839585STim.Szeto@Sun.COM  *
19849585STim.Szeto@Sun.COM  * Purpose: add a logical unit to the sbd provider data
19859585STim.Szeto@Sun.COM  */
19869585STim.Szeto@Sun.COM static int
addGuidToDiskStore(stmfGuid * guid,char * filename)19879585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename)
19889585STim.Szeto@Sun.COM {
19899585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, filename, B_TRUE));
19909585STim.Szeto@Sun.COM }
19919585STim.Szeto@Sun.COM 
19929585STim.Szeto@Sun.COM 
19939585STim.Szeto@Sun.COM /*
19949585STim.Szeto@Sun.COM  * persistDiskGuid
19959585STim.Szeto@Sun.COM  *
19969585STim.Szeto@Sun.COM  * Purpose: Persist or unpersist a guid for the sbd provider data
19979585STim.Szeto@Sun.COM  *
19989585STim.Szeto@Sun.COM  */
19999585STim.Szeto@Sun.COM static int
persistDiskGuid(stmfGuid * guid,char * filename,boolean_t persist)20009585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
20019585STim.Szeto@Sun.COM {
20029585STim.Szeto@Sun.COM 	char	    guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
20039585STim.Szeto@Sun.COM 	nvlist_t    *nvl = NULL;
20049585STim.Szeto@Sun.COM 
20059585STim.Szeto@Sun.COM 	uint64_t    setToken;
20069585STim.Szeto@Sun.COM 	boolean_t   retryGetProviderData = B_FALSE;
20079585STim.Szeto@Sun.COM 	boolean_t   newData = B_FALSE;
20089585STim.Szeto@Sun.COM 	int	    ret = STMF_STATUS_SUCCESS;
20099585STim.Szeto@Sun.COM 	int	    retryCnt = 0;
20109585STim.Szeto@Sun.COM 	int	    stmfRet;
20119585STim.Szeto@Sun.COM 
20129585STim.Szeto@Sun.COM 	/* if we're persisting a guid, there must be a filename */
20139585STim.Szeto@Sun.COM 	if (persist && !filename) {
20149585STim.Szeto@Sun.COM 		return (1);
20159585STim.Szeto@Sun.COM 	}
20169585STim.Szeto@Sun.COM 
20179585STim.Szeto@Sun.COM 	/* guid is stored in lowercase ascii hex */
20189585STim.Szeto@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
20199585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
20209585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x",
20219585STim.Szeto@Sun.COM 	    guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
20229585STim.Szeto@Sun.COM 	    guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
20239585STim.Szeto@Sun.COM 	    guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
20249585STim.Szeto@Sun.COM 	    guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
20259585STim.Szeto@Sun.COM 
20269585STim.Szeto@Sun.COM 
20279585STim.Szeto@Sun.COM 	do {
20289585STim.Szeto@Sun.COM 		retryGetProviderData = B_FALSE;
20299585STim.Szeto@Sun.COM 		stmfRet = stmfGetProviderDataProt("sbd", &nvl,
20309585STim.Szeto@Sun.COM 		    STMF_LU_PROVIDER_TYPE, &setToken);
20319585STim.Szeto@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
20329585STim.Szeto@Sun.COM 			if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
20339585STim.Szeto@Sun.COM 				ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
20349585STim.Szeto@Sun.COM 				if (ret != 0) {
20359585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20369585STim.Szeto@Sun.COM 					    "unpersistGuid:nvlist_alloc(%d)",
20379585STim.Szeto@Sun.COM 					    ret);
20389585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
20399585STim.Szeto@Sun.COM 					goto done;
20409585STim.Szeto@Sun.COM 				}
20419585STim.Szeto@Sun.COM 				newData = B_TRUE;
20429585STim.Szeto@Sun.COM 			} else {
204310725SJohn.Forte@Sun.COM 				/*
204410725SJohn.Forte@Sun.COM 				 * if we're persisting the data, it's
204510725SJohn.Forte@Sun.COM 				 * an error. Otherwise, just return
204610725SJohn.Forte@Sun.COM 				 */
204710725SJohn.Forte@Sun.COM 				if (persist) {
204810725SJohn.Forte@Sun.COM 					ret = stmfRet;
204910725SJohn.Forte@Sun.COM 				}
20509585STim.Szeto@Sun.COM 				goto done;
20519585STim.Szeto@Sun.COM 			}
20529585STim.Szeto@Sun.COM 		}
20539585STim.Szeto@Sun.COM 		if (persist) {
20549585STim.Szeto@Sun.COM 			ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
20559585STim.Szeto@Sun.COM 		} else {
20569585STim.Szeto@Sun.COM 			ret = nvlist_remove(nvl, guidAsciiBuf,
20579585STim.Szeto@Sun.COM 			    DATA_TYPE_STRING);
20589585STim.Szeto@Sun.COM 			if (ret == ENOENT) {
20599585STim.Szeto@Sun.COM 				ret = 0;
20609585STim.Szeto@Sun.COM 			}
20619585STim.Szeto@Sun.COM 		}
20629585STim.Szeto@Sun.COM 		if (ret == 0) {
20639585STim.Szeto@Sun.COM 			if (newData) {
20649585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20659585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, NULL);
20669585STim.Szeto@Sun.COM 			} else {
20679585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20689585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, &setToken);
20699585STim.Szeto@Sun.COM 			}
20709585STim.Szeto@Sun.COM 			if (stmfRet != STMF_STATUS_SUCCESS) {
20719585STim.Szeto@Sun.COM 				if (stmfRet == STMF_ERROR_BUSY) {
20729585STim.Szeto@Sun.COM 					/* get/set failed, try again */
20739585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20749585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20759585STim.Szeto@Sun.COM 						ret = stmfRet;
20769585STim.Szeto@Sun.COM 						break;
20779585STim.Szeto@Sun.COM 					}
20789585STim.Szeto@Sun.COM 					continue;
20799585STim.Szeto@Sun.COM 				} else if (stmfRet ==
20809585STim.Szeto@Sun.COM 				    STMF_ERROR_PROV_DATA_STALE) {
20819585STim.Szeto@Sun.COM 					/* update failed, try again */
20829585STim.Szeto@Sun.COM 					nvlist_free(nvl);
20839585STim.Szeto@Sun.COM 					nvl = NULL;
20849585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20859585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20869585STim.Szeto@Sun.COM 						ret = stmfRet;
20879585STim.Szeto@Sun.COM 						break;
20889585STim.Szeto@Sun.COM 					}
20899585STim.Szeto@Sun.COM 					continue;
20909585STim.Szeto@Sun.COM 				} else {
20919585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20929585STim.Szeto@Sun.COM 					    "unpersistGuid:error(%x)", stmfRet);
20939585STim.Szeto@Sun.COM 					ret = stmfRet;
20949585STim.Szeto@Sun.COM 				}
20959585STim.Szeto@Sun.COM 				break;
20969585STim.Szeto@Sun.COM 			}
20979585STim.Szeto@Sun.COM 		} else {
20989585STim.Szeto@Sun.COM 			syslog(LOG_DEBUG,
20999585STim.Szeto@Sun.COM 			    "unpersistGuid:error nvlist_add/remove(%d)",
21009585STim.Szeto@Sun.COM 			    ret);
21019585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
21029585STim.Szeto@Sun.COM 		}
21039585STim.Szeto@Sun.COM 	} while (retryGetProviderData);
21049585STim.Szeto@Sun.COM 
21059585STim.Szeto@Sun.COM done:
21069585STim.Szeto@Sun.COM 	nvlist_free(nvl);
21079585STim.Szeto@Sun.COM 	return (ret);
21089585STim.Szeto@Sun.COM }
21099585STim.Szeto@Sun.COM 
21109585STim.Szeto@Sun.COM 
21119585STim.Szeto@Sun.COM /*
21129585STim.Szeto@Sun.COM  * stmfGetLuProp
21139585STim.Szeto@Sun.COM  *
21149585STim.Szeto@Sun.COM  * Purpose: Get current value for a resource property
21159585STim.Szeto@Sun.COM  *
21169585STim.Szeto@Sun.COM  * hdl - luResource from a previous call to stmfCreateLuResource
21179585STim.Szeto@Sun.COM  *
21189585STim.Szeto@Sun.COM  * resourceProp - a valid resource property type
21199585STim.Szeto@Sun.COM  *
21209585STim.Szeto@Sun.COM  * propVal - void pointer to a pointer of the value to be retrieved
21219585STim.Szeto@Sun.COM  */
21229585STim.Szeto@Sun.COM int
stmfGetLuProp(luResource hdl,uint32_t prop,char * propVal,size_t * propLen)21239585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
21249585STim.Szeto@Sun.COM {
21259585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21269585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
21279585STim.Szeto@Sun.COM 	if (hdl == NULL || propLen == NULL || propVal == NULL) {
21289585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21299585STim.Szeto@Sun.COM 	}
21309585STim.Szeto@Sun.COM 
21319585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
21329585STim.Szeto@Sun.COM 		ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
21339585STim.Szeto@Sun.COM 	} else {
21349585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21359585STim.Szeto@Sun.COM 	}
21369585STim.Szeto@Sun.COM 
21379585STim.Szeto@Sun.COM 	return (ret);
21389585STim.Szeto@Sun.COM }
21399585STim.Szeto@Sun.COM 
21409585STim.Szeto@Sun.COM /*
21419585STim.Szeto@Sun.COM  * stmfGetLuResource
21429585STim.Szeto@Sun.COM  *
21439585STim.Szeto@Sun.COM  * Purpose: Get a logical unit resource handle for a given logical unit.
21449585STim.Szeto@Sun.COM  *
21459585STim.Szeto@Sun.COM  * hdl - pointer to luResource
21469585STim.Szeto@Sun.COM  */
21479585STim.Szeto@Sun.COM int
stmfGetLuResource(stmfGuid * luGuid,luResource * hdl)21489585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
21499585STim.Szeto@Sun.COM {
21509585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21519585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
21529585STim.Szeto@Sun.COM 
215311691SSrivijitha.Dugganapalli@Sun.COM 	if (hdl == NULL) {
215411691SSrivijitha.Dugganapalli@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
215511691SSrivijitha.Dugganapalli@Sun.COM 	}
21569585STim.Szeto@Sun.COM 
21579585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
21589585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
21599585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
21609585STim.Szeto@Sun.COM 		return (ret);
21619585STim.Szeto@Sun.COM 	} else {
21629585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
21639585STim.Szeto@Sun.COM 			ret = getDiskAllProps(luGuid, hdl);
21649585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
21659585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
21669585STim.Szeto@Sun.COM 		} else {
21679585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
21689585STim.Szeto@Sun.COM 		}
21699585STim.Szeto@Sun.COM 	}
21709585STim.Szeto@Sun.COM 
21719585STim.Szeto@Sun.COM 	return (ret);
21729585STim.Szeto@Sun.COM }
21739585STim.Szeto@Sun.COM 
21749585STim.Szeto@Sun.COM /*
21759585STim.Szeto@Sun.COM  * getDiskAllProps
21769585STim.Szeto@Sun.COM  *
21779585STim.Szeto@Sun.COM  * Purpose: load all disk properties from sbd driver
21789585STim.Szeto@Sun.COM  *
21799585STim.Szeto@Sun.COM  * luGuid - guid of disk device for which properties are to be retrieved
21809585STim.Szeto@Sun.COM  * hdl - allocated luResource into which properties are to be copied
21819585STim.Szeto@Sun.COM  *
21829585STim.Szeto@Sun.COM  */
21839585STim.Szeto@Sun.COM static int
getDiskAllProps(stmfGuid * luGuid,luResource * hdl)21849585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
21859585STim.Szeto@Sun.COM {
21869585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21879585STim.Szeto@Sun.COM 	int fd;
21889585STim.Szeto@Sun.COM 	sbd_lu_props_t *sbdProps;
21899585STim.Szeto@Sun.COM 	int ioctlRet;
21909585STim.Szeto@Sun.COM 	int savedErrno;
21919585STim.Szeto@Sun.COM 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
21929585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
21939585STim.Szeto@Sun.COM 
21949585STim.Szeto@Sun.COM 	/*
21959585STim.Szeto@Sun.COM 	 * Open control node for sbd
21969585STim.Szeto@Sun.COM 	 */
21979585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
21989585STim.Szeto@Sun.COM 		return (ret);
21999585STim.Szeto@Sun.COM 
22009585STim.Szeto@Sun.COM 
22019585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
22029585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
22039585STim.Szeto@Sun.COM 		(void) close(fd);
22049585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
22059585STim.Szeto@Sun.COM 	}
22069585STim.Szeto@Sun.COM 
22079585STim.Szeto@Sun.COM 	sbdProps = calloc(1, sbdPropsSize);
22089585STim.Szeto@Sun.COM 	if (sbdProps == NULL) {
22099585STim.Szeto@Sun.COM 		free(*hdl);
22109585STim.Szeto@Sun.COM 		(void) close(fd);
22119585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
22129585STim.Szeto@Sun.COM 	}
22139585STim.Szeto@Sun.COM 
22149585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
22159585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
22169585STim.Szeto@Sun.COM 		free(*hdl);
221710725SJohn.Forte@Sun.COM 		free(sbdProps);
22189585STim.Szeto@Sun.COM 		(void) close(fd);
22199585STim.Szeto@Sun.COM 		return (ret);
22209585STim.Szeto@Sun.COM 	}
22219585STim.Szeto@Sun.COM 
22229585STim.Szeto@Sun.COM 	sbdProps->slp_input_guid = 1;
22239585STim.Szeto@Sun.COM 	bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
22249585STim.Szeto@Sun.COM 
22259585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
22269585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdPropsSize;
22279585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
22289585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdPropsSize;
22299585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
22309585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
22319585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
22329585STim.Szeto@Sun.COM 		savedErrno = errno;
22339585STim.Szeto@Sun.COM 		switch (savedErrno) {
22349585STim.Szeto@Sun.COM 			case EBUSY:
22359585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
22369585STim.Szeto@Sun.COM 				break;
22379585STim.Szeto@Sun.COM 			case EPERM:
22389585STim.Szeto@Sun.COM 			case EACCES:
22399585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
22409585STim.Szeto@Sun.COM 				break;
22419585STim.Szeto@Sun.COM 			case ENOENT:
22429585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
22439585STim.Szeto@Sun.COM 				break;
22449585STim.Szeto@Sun.COM 			default:
22459585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
22469585STim.Szeto@Sun.COM 				    "getDiskAllProps:ioctl error(%d) (%d) (%d)",
22479585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
22489585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
22499585STim.Szeto@Sun.COM 				break;
22509585STim.Szeto@Sun.COM 		}
22519585STim.Szeto@Sun.COM 	}
22529585STim.Szeto@Sun.COM 
22539585STim.Szeto@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
22549585STim.Szeto@Sun.COM 		ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
22559585STim.Szeto@Sun.COM 	}
22569585STim.Szeto@Sun.COM 
225710725SJohn.Forte@Sun.COM 	free(sbdProps);
22589585STim.Szeto@Sun.COM 	(void) close(fd);
22599585STim.Szeto@Sun.COM 	return (ret);
22609585STim.Szeto@Sun.COM }
22619585STim.Szeto@Sun.COM 
22629585STim.Szeto@Sun.COM /*
22639585STim.Szeto@Sun.COM  * loadDiskPropsFromDriver
22649585STim.Szeto@Sun.COM  *
22659585STim.Szeto@Sun.COM  * Purpose: Retrieve all disk type properties from sbd driver
22669585STim.Szeto@Sun.COM  *
22679585STim.Szeto@Sun.COM  * hdl - Allocated luResourceImpl
22689585STim.Szeto@Sun.COM  * sbdProps - sbd_lu_props_t structure returned from sbd driver
22699585STim.Szeto@Sun.COM  *
22709585STim.Szeto@Sun.COM  */
22719585STim.Szeto@Sun.COM static int
loadDiskPropsFromDriver(luResourceImpl * hdl,sbd_lu_props_t * sbdProps)22729585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
22739585STim.Szeto@Sun.COM {
22749585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
22759585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
22769585STim.Szeto@Sun.COM 	/* copy guid */
22779585STim.Szeto@Sun.COM 	diskLu->luGuidValid = B_TRUE;
22789585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
22799585STim.Szeto@Sun.COM 
22809585STim.Szeto@Sun.COM 	if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
22819585STim.Szeto@Sun.COM 		diskLu->luMetaFileNameValid = B_TRUE;
22829585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luMetaFileName,
22839585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
22849585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) >=
22859585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) {
22869585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22879585STim.Szeto@Sun.COM 		}
22889585STim.Szeto@Sun.COM 	}
22899585STim.Szeto@Sun.COM 
22909585STim.Szeto@Sun.COM 	if (sbdProps->slp_data_fname_valid) {
22919585STim.Szeto@Sun.COM 		diskLu->luDataFileNameValid = B_TRUE;
22929585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luDataFileName,
22939585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
22949585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) >=
22959585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) {
22969585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22979585STim.Szeto@Sun.COM 		}
22989585STim.Szeto@Sun.COM 	}
22999585STim.Szeto@Sun.COM 
23009585STim.Szeto@Sun.COM 	if (sbdProps->slp_serial_valid) {
23019585STim.Szeto@Sun.COM 		diskLu->serialNumValid = B_TRUE;
23029585STim.Szeto@Sun.COM 		bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
23039585STim.Szeto@Sun.COM 		    diskLu->serialNum, sbdProps->slp_serial_size);
23049585STim.Szeto@Sun.COM 	}
23059585STim.Szeto@Sun.COM 
230610113SNattuvetty.Bhavyan@Sun.COM 	if (sbdProps->slp_mgmt_url_valid) {
230710113SNattuvetty.Bhavyan@Sun.COM 		diskLu->luMgmtUrlValid = B_TRUE;
230810113SNattuvetty.Bhavyan@Sun.COM 		if (strlcpy(diskLu->luMgmtUrl,
230910113SNattuvetty.Bhavyan@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
231010113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) >=
231110113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) {
231210113SNattuvetty.Bhavyan@Sun.COM 			return (STMF_STATUS_ERROR);
231310113SNattuvetty.Bhavyan@Sun.COM 		}
231410113SNattuvetty.Bhavyan@Sun.COM 	}
231510113SNattuvetty.Bhavyan@Sun.COM 
23169585STim.Szeto@Sun.COM 	if (sbdProps->slp_alias_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[sbdProps->slp_alias_off]),
23209585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) >=
23219585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) {
23229585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
23239585STim.Szeto@Sun.COM 		}
23249585STim.Szeto@Sun.COM 	} else { /* set alias to data filename if not set */
23259585STim.Szeto@Sun.COM 		if (sbdProps->slp_data_fname_valid) {
23269585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
23279585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias,
23289585STim.Szeto@Sun.COM 			    (char *)&(sbdProps->slp_buf[
23299585STim.Szeto@Sun.COM 			    sbdProps->slp_data_fname_off]),
23309585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
23319585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
23329585STim.Szeto@Sun.COM 				return (STMF_STATUS_ERROR);
23339585STim.Szeto@Sun.COM 			}
23349585STim.Szeto@Sun.COM 		}
23359585STim.Szeto@Sun.COM 	}
23369585STim.Szeto@Sun.COM 
23379585STim.Szeto@Sun.COM 	diskLu->vidValid = B_TRUE;
23389585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
23399585STim.Szeto@Sun.COM 
23409585STim.Szeto@Sun.COM 	diskLu->pidValid = B_TRUE;
23419585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
23429585STim.Szeto@Sun.COM 
23439585STim.Szeto@Sun.COM 	diskLu->revValid = B_TRUE;
23449585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
23459585STim.Szeto@Sun.COM 
23469585STim.Szeto@Sun.COM 	diskLu->writeProtectEnableValid = B_TRUE;
23479585STim.Szeto@Sun.COM 	if (sbdProps->slp_write_protected) {
23489585STim.Szeto@Sun.COM 		diskLu->writeProtectEnable = B_TRUE;
23499585STim.Szeto@Sun.COM 	}
23509585STim.Szeto@Sun.COM 
23519585STim.Szeto@Sun.COM 	diskLu->writebackCacheDisableValid = B_TRUE;
23529585STim.Szeto@Sun.COM 	if (sbdProps->slp_writeback_cache_disable_cur) {
23539585STim.Szeto@Sun.COM 		diskLu->writebackCacheDisable = B_TRUE;
23549585STim.Szeto@Sun.COM 	}
23559585STim.Szeto@Sun.COM 
23569585STim.Szeto@Sun.COM 	diskLu->blkSizeValid = B_TRUE;
23579585STim.Szeto@Sun.COM 	diskLu->blkSize = sbdProps->slp_blksize;
23589585STim.Szeto@Sun.COM 
23599585STim.Szeto@Sun.COM 	diskLu->luSizeValid = B_TRUE;
23609585STim.Szeto@Sun.COM 	diskLu->luSize = sbdProps->slp_lu_size;
23619585STim.Szeto@Sun.COM 
236210725SJohn.Forte@Sun.COM 	diskLu->accessState = sbdProps->slp_access_state;
236310725SJohn.Forte@Sun.COM 
23649585STim.Szeto@Sun.COM 	return (ret);
23659585STim.Szeto@Sun.COM }
23669585STim.Szeto@Sun.COM 
236711103SJohn.Forte@Sun.COM /*
236811103SJohn.Forte@Sun.COM  * stmfGetGlobalLuProp
236911103SJohn.Forte@Sun.COM  *
237011103SJohn.Forte@Sun.COM  * Purpose: get a global property for a device type
237111103SJohn.Forte@Sun.COM  *
237211103SJohn.Forte@Sun.COM  */
237311103SJohn.Forte@Sun.COM int
stmfGetGlobalLuProp(uint16_t dType,uint32_t prop,char * propVal,size_t * propLen)237411103SJohn.Forte@Sun.COM stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal,
237511103SJohn.Forte@Sun.COM     size_t *propLen)
237611103SJohn.Forte@Sun.COM {
237711103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
237811103SJohn.Forte@Sun.COM 	if (dType != STMF_DISK || propVal == NULL) {
237911103SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
238011103SJohn.Forte@Sun.COM 	}
238111103SJohn.Forte@Sun.COM 
238211103SJohn.Forte@Sun.COM 	ret = getDiskGlobalProp(prop, propVal, propLen);
238311103SJohn.Forte@Sun.COM 
238411103SJohn.Forte@Sun.COM 	return (ret);
238511103SJohn.Forte@Sun.COM }
238611103SJohn.Forte@Sun.COM 
238711103SJohn.Forte@Sun.COM /*
238811103SJohn.Forte@Sun.COM  * getDiskGlobalProp
238911103SJohn.Forte@Sun.COM  *
239011103SJohn.Forte@Sun.COM  * Purpose: get global property from sbd driver
239111103SJohn.Forte@Sun.COM  *
239211103SJohn.Forte@Sun.COM  */
239311103SJohn.Forte@Sun.COM static int
getDiskGlobalProp(uint32_t prop,char * propVal,size_t * propLen)239411103SJohn.Forte@Sun.COM getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen)
239511103SJohn.Forte@Sun.COM {
239611103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
239711103SJohn.Forte@Sun.COM 	int fd;
239811103SJohn.Forte@Sun.COM 	sbd_global_props_t *sbdProps;
239911103SJohn.Forte@Sun.COM 	void *sbd_realloc;
240011103SJohn.Forte@Sun.COM 	int retryCnt = 0;
240111103SJohn.Forte@Sun.COM 	boolean_t retry;
240211103SJohn.Forte@Sun.COM 	int ioctlRet;
240311103SJohn.Forte@Sun.COM 	int savedErrno;
240411103SJohn.Forte@Sun.COM 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
240511103SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
240611103SJohn.Forte@Sun.COM 	size_t reqLen;
240711103SJohn.Forte@Sun.COM 
240811103SJohn.Forte@Sun.COM 	switch (prop) {
240911103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
241011103SJohn.Forte@Sun.COM 			break;
241111103SJohn.Forte@Sun.COM 		default:
241211103SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_PROP);
241311103SJohn.Forte@Sun.COM 	}
241411103SJohn.Forte@Sun.COM 
241511103SJohn.Forte@Sun.COM 	/*
241611103SJohn.Forte@Sun.COM 	 * Open control node for sbd
241711103SJohn.Forte@Sun.COM 	 */
241811103SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
241911103SJohn.Forte@Sun.COM 		return (ret);
242011103SJohn.Forte@Sun.COM 
242111103SJohn.Forte@Sun.COM 	sbdProps = calloc(1, sbdPropsSize);
242211103SJohn.Forte@Sun.COM 	if (sbdProps == NULL) {
242311103SJohn.Forte@Sun.COM 		(void) close(fd);
242411103SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
242511103SJohn.Forte@Sun.COM 	}
242611103SJohn.Forte@Sun.COM 
242711103SJohn.Forte@Sun.COM 	do {
242811103SJohn.Forte@Sun.COM 		retry = B_FALSE;
242911103SJohn.Forte@Sun.COM 		sbdIoctl.stmf_version = STMF_VERSION_1;
243011103SJohn.Forte@Sun.COM 		sbdIoctl.stmf_obuf_size = sbdPropsSize;
243111103SJohn.Forte@Sun.COM 		sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
243211103SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl);
243311103SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
243411103SJohn.Forte@Sun.COM 			savedErrno = errno;
243511103SJohn.Forte@Sun.COM 			switch (savedErrno) {
243611103SJohn.Forte@Sun.COM 				case EBUSY:
243711103SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
243811103SJohn.Forte@Sun.COM 					break;
243911103SJohn.Forte@Sun.COM 				case EPERM:
244011103SJohn.Forte@Sun.COM 				case EACCES:
244111103SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
244211103SJohn.Forte@Sun.COM 					break;
244311103SJohn.Forte@Sun.COM 				case ENOMEM:
244411103SJohn.Forte@Sun.COM 					if (sbdIoctl.stmf_error ==
244511103SJohn.Forte@Sun.COM 					    SBD_RET_INSUFFICIENT_BUF_SPACE &&
244611103SJohn.Forte@Sun.COM 					    retryCnt++ < 3) {
244711103SJohn.Forte@Sun.COM 						sbdPropsSize =
244811103SJohn.Forte@Sun.COM 						    sizeof (*sbdProps) +
244911103SJohn.Forte@Sun.COM 						    sbdProps->
245011103SJohn.Forte@Sun.COM 						    mlu_buf_size_needed;
245111103SJohn.Forte@Sun.COM 
245211103SJohn.Forte@Sun.COM 						sbd_realloc = sbdProps;
245311103SJohn.Forte@Sun.COM 						sbdProps = realloc(sbdProps,
245411103SJohn.Forte@Sun.COM 						    sbdPropsSize);
245511103SJohn.Forte@Sun.COM 						if (sbdProps == NULL) {
245611103SJohn.Forte@Sun.COM 							free(sbd_realloc);
245711103SJohn.Forte@Sun.COM 							ret = STMF_ERROR_NOMEM;
245811103SJohn.Forte@Sun.COM 							break;
245911103SJohn.Forte@Sun.COM 						}
246011103SJohn.Forte@Sun.COM 						retry = B_TRUE;
246111103SJohn.Forte@Sun.COM 					} else {
246211103SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOMEM;
246311103SJohn.Forte@Sun.COM 					}
246411103SJohn.Forte@Sun.COM 					break;
246511103SJohn.Forte@Sun.COM 				default:
246611103SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
246711103SJohn.Forte@Sun.COM 					    "getDiskGlobalProp:ioctl error(%d)"
246811103SJohn.Forte@Sun.COM 					    "(%d)(%d)", ioctlRet,
246911103SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
247011103SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
247111103SJohn.Forte@Sun.COM 					break;
247211103SJohn.Forte@Sun.COM 			}
247311103SJohn.Forte@Sun.COM 
247411103SJohn.Forte@Sun.COM 		}
247511103SJohn.Forte@Sun.COM 	} while (retry);
247611103SJohn.Forte@Sun.COM 
247711103SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
247811103SJohn.Forte@Sun.COM 		goto done;
247911103SJohn.Forte@Sun.COM 	}
248011103SJohn.Forte@Sun.COM 
248111103SJohn.Forte@Sun.COM 	switch (prop) {
248211103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
248311103SJohn.Forte@Sun.COM 			if (sbdProps->mlu_mgmt_url_valid == 0) {
248411103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NO_PROP;
248511103SJohn.Forte@Sun.COM 				goto done;
248611103SJohn.Forte@Sun.COM 			}
248711103SJohn.Forte@Sun.COM 			if ((reqLen = strlcpy(propVal, (char *)&(
248811103SJohn.Forte@Sun.COM 			    sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]),
248911103SJohn.Forte@Sun.COM 			    *propLen)) >= *propLen) {
249011103SJohn.Forte@Sun.COM 				*propLen = reqLen + 1;
249111103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_INVALID_ARG;
249211103SJohn.Forte@Sun.COM 				goto done;
249311103SJohn.Forte@Sun.COM 			}
249411103SJohn.Forte@Sun.COM 			break;
249511103SJohn.Forte@Sun.COM 	}
249611103SJohn.Forte@Sun.COM 
249711103SJohn.Forte@Sun.COM done:
249811103SJohn.Forte@Sun.COM 	free(sbdProps);
249911103SJohn.Forte@Sun.COM 	(void) close(fd);
250011103SJohn.Forte@Sun.COM 	return (ret);
250111103SJohn.Forte@Sun.COM }
250211103SJohn.Forte@Sun.COM 
250311103SJohn.Forte@Sun.COM /*
250411103SJohn.Forte@Sun.COM  * stmfSetGlobalLuProp
250511103SJohn.Forte@Sun.COM  *
250611103SJohn.Forte@Sun.COM  * Purpose: set a global property for a device type
250711103SJohn.Forte@Sun.COM  *
250811103SJohn.Forte@Sun.COM  */
250911103SJohn.Forte@Sun.COM int
stmfSetGlobalLuProp(uint16_t dType,uint32_t prop,const char * propVal)251011103SJohn.Forte@Sun.COM stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal)
251111103SJohn.Forte@Sun.COM {
251211103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
251311103SJohn.Forte@Sun.COM 	if (dType != STMF_DISK || propVal == NULL) {
251411103SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
251511103SJohn.Forte@Sun.COM 	}
251611103SJohn.Forte@Sun.COM 
251711103SJohn.Forte@Sun.COM 	ret = setDiskGlobalProp(prop, propVal);
251811103SJohn.Forte@Sun.COM 
251911103SJohn.Forte@Sun.COM 	return (ret);
252011103SJohn.Forte@Sun.COM }
252111103SJohn.Forte@Sun.COM 
252211103SJohn.Forte@Sun.COM /*
252311103SJohn.Forte@Sun.COM  * setDiskGlobalProp
252411103SJohn.Forte@Sun.COM  *
252511103SJohn.Forte@Sun.COM  * Purpose: set properties for resource of type disk
252611103SJohn.Forte@Sun.COM  *
252711103SJohn.Forte@Sun.COM  * resourceProp - valid resource identifier
252811103SJohn.Forte@Sun.COM  * propVal - valid resource value
252911103SJohn.Forte@Sun.COM  */
253011103SJohn.Forte@Sun.COM static int
setDiskGlobalProp(uint32_t resourceProp,const char * propVal)253111103SJohn.Forte@Sun.COM setDiskGlobalProp(uint32_t resourceProp, const char *propVal)
253211103SJohn.Forte@Sun.COM {
253311103SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
253411103SJohn.Forte@Sun.COM 	sbd_global_props_t *sbdGlobalProps = NULL;
253511103SJohn.Forte@Sun.COM 	int sbdGlobalPropsSize = 0;
253611103SJohn.Forte@Sun.COM 	int propLen;
253711103SJohn.Forte@Sun.COM 	int mluBufSize = 0;
253811103SJohn.Forte@Sun.COM 	int fd;
253911103SJohn.Forte@Sun.COM 	int savedErrno;
254011103SJohn.Forte@Sun.COM 	int ioctlRet;
254111103SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
254211103SJohn.Forte@Sun.COM 
254311103SJohn.Forte@Sun.COM 	switch (resourceProp) {
254411103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
254511103SJohn.Forte@Sun.COM 			break;
254611103SJohn.Forte@Sun.COM 		default:
254711103SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_PROP);
254811103SJohn.Forte@Sun.COM 			break;
254911103SJohn.Forte@Sun.COM 	}
255011103SJohn.Forte@Sun.COM 
255111103SJohn.Forte@Sun.COM 	/*
255211103SJohn.Forte@Sun.COM 	 * Open control node for sbd
255311103SJohn.Forte@Sun.COM 	 */
255411103SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
255511103SJohn.Forte@Sun.COM 		return (ret);
255611103SJohn.Forte@Sun.COM 
255711103SJohn.Forte@Sun.COM 	propLen = strlen(propVal);
255811103SJohn.Forte@Sun.COM 	mluBufSize += propLen + 1;
255911103SJohn.Forte@Sun.COM 	sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 +
256011103SJohn.Forte@Sun.COM 	    max(8, mluBufSize);
256111103SJohn.Forte@Sun.COM 	/*
256211103SJohn.Forte@Sun.COM 	 * 8 is the size of the buffer set aside for
256311103SJohn.Forte@Sun.COM 	 * concatenation of variable length fields
256411103SJohn.Forte@Sun.COM 	 */
256511103SJohn.Forte@Sun.COM 	sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize);
256611103SJohn.Forte@Sun.COM 	if (sbdGlobalProps == NULL) {
256711103SJohn.Forte@Sun.COM 		(void) close(fd);
256811103SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
256911103SJohn.Forte@Sun.COM 	}
257011103SJohn.Forte@Sun.COM 
257111103SJohn.Forte@Sun.COM 	sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize;
257211103SJohn.Forte@Sun.COM 
257311103SJohn.Forte@Sun.COM 	switch (resourceProp) {
257411103SJohn.Forte@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
257511103SJohn.Forte@Sun.COM 			sbdGlobalProps->mlu_mgmt_url_valid = 1;
257611103SJohn.Forte@Sun.COM 			bcopy(propVal, &(sbdGlobalProps->mlu_buf),
257711103SJohn.Forte@Sun.COM 			    propLen + 1);
257811103SJohn.Forte@Sun.COM 			break;
257911103SJohn.Forte@Sun.COM 		default:
258011103SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NO_PROP;
258111103SJohn.Forte@Sun.COM 			goto done;
258211103SJohn.Forte@Sun.COM 	}
258311103SJohn.Forte@Sun.COM 
258411103SJohn.Forte@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
258511103SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size;
258611103SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps;
258711103SJohn.Forte@Sun.COM 
258811103SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl);
258911103SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
259011103SJohn.Forte@Sun.COM 		savedErrno = errno;
259111103SJohn.Forte@Sun.COM 		switch (savedErrno) {
259211103SJohn.Forte@Sun.COM 			case EBUSY:
259311103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
259411103SJohn.Forte@Sun.COM 				break;
259511103SJohn.Forte@Sun.COM 			case EPERM:
259611103SJohn.Forte@Sun.COM 			case EACCES:
259711103SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
259811103SJohn.Forte@Sun.COM 				break;
259911103SJohn.Forte@Sun.COM 			default:
260011103SJohn.Forte@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
260111103SJohn.Forte@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
260211103SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
260311103SJohn.Forte@Sun.COM 					"modifyDiskLu:ioctl "
260411103SJohn.Forte@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
260511103SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
260611103SJohn.Forte@Sun.COM 				}
260711103SJohn.Forte@Sun.COM 				break;
260811103SJohn.Forte@Sun.COM 		}
260911103SJohn.Forte@Sun.COM 	}
261011103SJohn.Forte@Sun.COM 
261111103SJohn.Forte@Sun.COM done:
261211103SJohn.Forte@Sun.COM 	free(sbdGlobalProps);
261311103SJohn.Forte@Sun.COM 	(void) close(fd);
261411103SJohn.Forte@Sun.COM 	return (ret);
261511103SJohn.Forte@Sun.COM }
261611103SJohn.Forte@Sun.COM 
26179585STim.Szeto@Sun.COM 
26189585STim.Szeto@Sun.COM /*
26199585STim.Szeto@Sun.COM  * stmfSetLuProp
26209585STim.Szeto@Sun.COM  *
26219585STim.Szeto@Sun.COM  * Purpose: set a property on an luResource
26229585STim.Szeto@Sun.COM  *
26239585STim.Szeto@Sun.COM  * hdl - allocated luResource
26249585STim.Szeto@Sun.COM  * prop - property identifier
26259585STim.Szeto@Sun.COM  * propVal - property value to be set
26269585STim.Szeto@Sun.COM  */
26279585STim.Szeto@Sun.COM int
stmfSetLuProp(luResource hdl,uint32_t prop,const char * propVal)26289585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
26299585STim.Szeto@Sun.COM {
26309585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
26319585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
26329585STim.Szeto@Sun.COM 	if (hdl == NULL) {
26339585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
26349585STim.Szeto@Sun.COM 	}
26359585STim.Szeto@Sun.COM 
26369585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
26379585STim.Szeto@Sun.COM 		ret = setDiskProp(luPropsHdl, prop, propVal);
26389585STim.Szeto@Sun.COM 	} else {
26399585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
26409585STim.Szeto@Sun.COM 	}
26419585STim.Szeto@Sun.COM 
26429585STim.Szeto@Sun.COM 	return (ret);
26439585STim.Szeto@Sun.COM }
26449585STim.Szeto@Sun.COM 
26459585STim.Szeto@Sun.COM /*
26469585STim.Szeto@Sun.COM  * getDiskProp
26479585STim.Szeto@Sun.COM  *
26489585STim.Szeto@Sun.COM  * Purpose: retrieve a given property from a logical unit resource of type disk
26499585STim.Szeto@Sun.COM  *
26509585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
26519585STim.Szeto@Sun.COM  * prop - property identifier
26529585STim.Szeto@Sun.COM  * propVal - pointer to character to contain the retrieved property value
26539585STim.Szeto@Sun.COM  * propLen - On input this is the length of propVal. On failure, it contains the
26549585STim.Szeto@Sun.COM  *           number of bytes required for propVal
26559585STim.Szeto@Sun.COM  */
26569585STim.Szeto@Sun.COM static int
getDiskProp(luResourceImpl * hdl,uint32_t prop,char * propVal,size_t * propLen)26579585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
26589585STim.Szeto@Sun.COM {
26599585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
26609585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
266110725SJohn.Forte@Sun.COM 	char accessState[20];
26629585STim.Szeto@Sun.COM 	size_t reqLen;
26639585STim.Szeto@Sun.COM 
266410725SJohn.Forte@Sun.COM 	if (prop == STMF_LU_PROP_ACCESS_STATE) {
266510725SJohn.Forte@Sun.COM 		if (diskLu->accessState == SBD_LU_ACTIVE) {
266610725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_ACTIVE,
266710725SJohn.Forte@Sun.COM 			    sizeof (accessState));
266810725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) {
266910725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
267010725SJohn.Forte@Sun.COM 			    STMF_ACCESS_STANDBY_TO_ACTIVE,
267110725SJohn.Forte@Sun.COM 			    sizeof (accessState));
267210725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_STANDBY) {
267310725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_STANDBY,
267410725SJohn.Forte@Sun.COM 			    sizeof (accessState));
267510725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState ==
267610725SJohn.Forte@Sun.COM 		    SBD_LU_TRANSITION_TO_STANDBY) {
267710725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
267810725SJohn.Forte@Sun.COM 			    STMF_ACCESS_ACTIVE_TO_STANDBY,
267910725SJohn.Forte@Sun.COM 			    sizeof (accessState));
268010725SJohn.Forte@Sun.COM 		}
268110725SJohn.Forte@Sun.COM 		if ((reqLen = strlcpy(propVal, accessState,
268210725SJohn.Forte@Sun.COM 		    *propLen)) >= *propLen) {
268310725SJohn.Forte@Sun.COM 			*propLen = reqLen + 1;
268410725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
268510725SJohn.Forte@Sun.COM 		}
268610725SJohn.Forte@Sun.COM 		return (0);
268710725SJohn.Forte@Sun.COM 	}
268810725SJohn.Forte@Sun.COM 
268910725SJohn.Forte@Sun.COM 	if (diskLu->accessState != SBD_LU_ACTIVE) {
269010725SJohn.Forte@Sun.COM 		return (STMF_ERROR_NO_PROP_STANDBY);
269110725SJohn.Forte@Sun.COM 	}
269210725SJohn.Forte@Sun.COM 
26939585STim.Szeto@Sun.COM 	switch (prop) {
26949585STim.Szeto@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE:
26959585STim.Szeto@Sun.COM 			if (diskLu->blkSizeValid == B_FALSE) {
26969585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
26979585STim.Szeto@Sun.COM 			}
26989585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen, "%llu",
26999585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->blkSize);
27009585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
27019585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27029585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27039585STim.Szeto@Sun.COM 			}
27049585STim.Szeto@Sun.COM 			break;
27059585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
27069585STim.Szeto@Sun.COM 			if (diskLu->luDataFileNameValid == B_FALSE) {
27079585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27089585STim.Szeto@Sun.COM 			}
27099585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
27109585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27119585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27129585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27139585STim.Szeto@Sun.COM 			}
27149585STim.Szeto@Sun.COM 			break;
27159585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
27169585STim.Szeto@Sun.COM 			if (diskLu->luMetaFileNameValid == B_FALSE) {
27179585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27189585STim.Szeto@Sun.COM 			}
27199585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
27209585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27219585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27229585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27239585STim.Szeto@Sun.COM 			}
27249585STim.Szeto@Sun.COM 			break;
272510113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
272610113SNattuvetty.Bhavyan@Sun.COM 			if (diskLu->luMgmtUrlValid == B_FALSE) {
272710113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_NO_PROP);
272810113SNattuvetty.Bhavyan@Sun.COM 			}
272910113SNattuvetty.Bhavyan@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
273010113SNattuvetty.Bhavyan@Sun.COM 			    *propLen)) >= *propLen) {
273110113SNattuvetty.Bhavyan@Sun.COM 				*propLen = reqLen + 1;
273210113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
273310113SNattuvetty.Bhavyan@Sun.COM 			}
273410113SNattuvetty.Bhavyan@Sun.COM 			break;
27359585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
27369585STim.Szeto@Sun.COM 			if (diskLu->luGuidValid == B_FALSE) {
27379585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27389585STim.Szeto@Sun.COM 			}
27399585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen,
27409585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
27419585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X",
27429585STim.Szeto@Sun.COM 			    diskLu->luGuid[0], diskLu->luGuid[1],
27439585STim.Szeto@Sun.COM 			    diskLu->luGuid[2], diskLu->luGuid[3],
27449585STim.Szeto@Sun.COM 			    diskLu->luGuid[4], diskLu->luGuid[5],
27459585STim.Szeto@Sun.COM 			    diskLu->luGuid[6], diskLu->luGuid[7],
27469585STim.Szeto@Sun.COM 			    diskLu->luGuid[8], diskLu->luGuid[9],
27479585STim.Szeto@Sun.COM 			    diskLu->luGuid[10], diskLu->luGuid[11],
27489585STim.Szeto@Sun.COM 			    diskLu->luGuid[12], diskLu->luGuid[13],
27499585STim.Szeto@Sun.COM 			    diskLu->luGuid[14], diskLu->luGuid[15]);
27509585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
27519585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27529585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27539585STim.Szeto@Sun.COM 			}
27549585STim.Szeto@Sun.COM 			break;
27559585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
27569585STim.Szeto@Sun.COM 			if (diskLu->serialNumValid == B_FALSE) {
27579585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27589585STim.Szeto@Sun.COM 			}
27599585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->serialNum,
27609585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27619585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27629585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27639585STim.Szeto@Sun.COM 			}
27649585STim.Szeto@Sun.COM 			break;
27659585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
27669585STim.Szeto@Sun.COM 			if (diskLu->luSizeValid == B_FALSE) {
27679585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27689585STim.Szeto@Sun.COM 			}
27699585STim.Szeto@Sun.COM 			(void) snprintf(propVal, *propLen, "%llu",
27709585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->luSize);
27719585STim.Szeto@Sun.COM 			break;
27729585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
27739585STim.Szeto@Sun.COM 			if (diskLu->luAliasValid == B_FALSE) {
27749585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27759585STim.Szeto@Sun.COM 			}
27769585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luAlias,
27779585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
27789585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
27799585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27809585STim.Szeto@Sun.COM 			}
27819585STim.Szeto@Sun.COM 			break;
27829585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
27839585STim.Szeto@Sun.COM 			if (diskLu->vidValid == B_FALSE) {
27849585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27859585STim.Szeto@Sun.COM 			}
27869585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->vid)) {
27879585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27889585STim.Szeto@Sun.COM 			}
27899585STim.Szeto@Sun.COM 			bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
27909585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->vid)] = 0;
27919585STim.Szeto@Sun.COM 			break;
27929585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
27939585STim.Szeto@Sun.COM 			if (diskLu->pidValid == B_FALSE) {
27949585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
27959585STim.Szeto@Sun.COM 			}
27969585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->pid)) {
27979585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27989585STim.Szeto@Sun.COM 			}
27999585STim.Szeto@Sun.COM 			bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
28009585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->pid)] = 0;
28019585STim.Szeto@Sun.COM 			break;
28029585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
28039585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnableValid == B_FALSE) {
28049585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
28059585STim.Szeto@Sun.COM 			}
28069585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnable) {
28079585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
28089585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28099585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28109585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28119585STim.Szeto@Sun.COM 				}
28129585STim.Szeto@Sun.COM 			} else {
28139585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
28149585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28159585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28169585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28179585STim.Szeto@Sun.COM 				}
28189585STim.Szeto@Sun.COM 			}
28199585STim.Szeto@Sun.COM 			break;
28209585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
28219585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisableValid == B_FALSE) {
28229585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
28239585STim.Szeto@Sun.COM 			}
28249585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisable) {
28259585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
28269585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28279585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28289585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28299585STim.Szeto@Sun.COM 				}
28309585STim.Szeto@Sun.COM 			} else {
28319585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
28329585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
28339585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
28349585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
28359585STim.Szeto@Sun.COM 				}
28369585STim.Szeto@Sun.COM 			}
28379585STim.Szeto@Sun.COM 			break;
28389585STim.Szeto@Sun.COM 		default:
283911691SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
28409585STim.Szeto@Sun.COM 			break;
28419585STim.Szeto@Sun.COM 	}
28429585STim.Szeto@Sun.COM 
28439585STim.Szeto@Sun.COM 	return (ret);
28449585STim.Szeto@Sun.COM }
28459585STim.Szeto@Sun.COM 
28469585STim.Szeto@Sun.COM /*
28479585STim.Szeto@Sun.COM  * setDiskProp
28489585STim.Szeto@Sun.COM  *
28499585STim.Szeto@Sun.COM  * Purpose: set properties for resource of type disk
28509585STim.Szeto@Sun.COM  *
28519585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
28529585STim.Szeto@Sun.COM  * resourceProp - valid resource identifier
28539585STim.Szeto@Sun.COM  * propVal - valid resource value
28549585STim.Szeto@Sun.COM  */
28559585STim.Szeto@Sun.COM static int
setDiskProp(luResourceImpl * hdl,uint32_t resourceProp,const char * propVal)28569585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
28579585STim.Szeto@Sun.COM {
28589585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
28599585STim.Szeto@Sun.COM 	int i;
28609585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
28619585STim.Szeto@Sun.COM 	unsigned long long numericProp = 0;
28629585STim.Szeto@Sun.COM 	char guidProp[LU_ASCII_GUID_SIZE + 1];
28639585STim.Szeto@Sun.COM 	char ouiProp[OUI_ASCII_SIZE + 1];
286410765SJohn.Forte@Sun.COM 	char hostIdProp[HOST_ID_ASCII_SIZE + 1];
28659585STim.Szeto@Sun.COM 	unsigned int oui[OUI_SIZE];
286610765SJohn.Forte@Sun.COM 	unsigned int hostId[HOST_ID_SIZE];
28679585STim.Szeto@Sun.COM 	unsigned int guid[LU_GUID_SIZE];
28689585STim.Szeto@Sun.COM 	int propSize;
28699585STim.Szeto@Sun.COM 
28709585STim.Szeto@Sun.COM 
28719585STim.Szeto@Sun.COM 	if (propVal == NULL) {
28729585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28739585STim.Szeto@Sun.COM 	}
28749585STim.Szeto@Sun.COM 
28759585STim.Szeto@Sun.COM 	switch (resourceProp) {
28769585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
28779585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias, propVal,
28789585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
28799585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
28809585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
28819585STim.Szeto@Sun.COM 			}
28829585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
28839585STim.Szeto@Sun.COM 			break;
288411865SSrivijitha.Dugganapalli@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE: {
288511865SSrivijitha.Dugganapalli@Sun.COM 			const char *tmp = propVal;
288611865SSrivijitha.Dugganapalli@Sun.COM 			while (*tmp) {
288711865SSrivijitha.Dugganapalli@Sun.COM 				if (!isdigit(*tmp++)) {
288811865SSrivijitha.Dugganapalli@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
288911865SSrivijitha.Dugganapalli@Sun.COM 				}
289011865SSrivijitha.Dugganapalli@Sun.COM 			}
28919585STim.Szeto@Sun.COM 			(void) sscanf(propVal, "%llu", &numericProp);
28929585STim.Szeto@Sun.COM 			if (numericProp > UINT16_MAX) {
28939585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
28949585STim.Szeto@Sun.COM 			}
28959585STim.Szeto@Sun.COM 			diskLu->blkSize = numericProp;
28969585STim.Szeto@Sun.COM 			diskLu->blkSizeValid = B_TRUE;
28979585STim.Szeto@Sun.COM 			break;
289811865SSrivijitha.Dugganapalli@Sun.COM 		}
28999585STim.Szeto@Sun.COM 		case STMF_LU_PROP_COMPANY_ID:
29009585STim.Szeto@Sun.COM 			if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
29019585STim.Szeto@Sun.COM 			    sizeof (ouiProp)) {
29029585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29039585STim.Szeto@Sun.COM 			}
29049585STim.Szeto@Sun.COM 			if (checkHexUpper(ouiProp) != 0) {
29059585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29069585STim.Szeto@Sun.COM 			}
29079585STim.Szeto@Sun.COM 			(void) sscanf(ouiProp, "%2X%2X%2X",
29089585STim.Szeto@Sun.COM 			    &oui[0], &oui[1], &oui[2]);
29099585STim.Szeto@Sun.COM 
29109585STim.Szeto@Sun.COM 			diskLu->companyId = 0;
29119585STim.Szeto@Sun.COM 			diskLu->companyId += oui[0] << 16;
29129585STim.Szeto@Sun.COM 			diskLu->companyId += oui[1] << 8;
29139585STim.Szeto@Sun.COM 			diskLu->companyId += oui[2];
291410765SJohn.Forte@Sun.COM 			if (diskLu->companyId == 0) {
291510765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
291610765SJohn.Forte@Sun.COM 			}
29179585STim.Szeto@Sun.COM 			diskLu->companyIdValid = B_TRUE;
29189585STim.Szeto@Sun.COM 			break;
291910765SJohn.Forte@Sun.COM 		case STMF_LU_PROP_HOST_ID:
292010765SJohn.Forte@Sun.COM 			if ((strlcpy(hostIdProp, propVal,
292110765SJohn.Forte@Sun.COM 			    sizeof (hostIdProp))) >= sizeof (hostIdProp)) {
292210765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
292310765SJohn.Forte@Sun.COM 			}
292410765SJohn.Forte@Sun.COM 			if (checkHexUpper(hostIdProp) != 0) {
292510765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
292610765SJohn.Forte@Sun.COM 			}
292710765SJohn.Forte@Sun.COM 			(void) sscanf(hostIdProp, "%2X%2X%2X%2X",
292810765SJohn.Forte@Sun.COM 			    &hostId[0], &hostId[1], &hostId[2], &hostId[3]);
292910765SJohn.Forte@Sun.COM 
293010765SJohn.Forte@Sun.COM 			diskLu->hostId = 0;
293110765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[0] << 24;
293210765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[1] << 16;
293310765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[2] << 8;
293410765SJohn.Forte@Sun.COM 			diskLu->hostId += hostId[3];
293510765SJohn.Forte@Sun.COM 			if (diskLu->hostId == 0) {
293610765SJohn.Forte@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
293710765SJohn.Forte@Sun.COM 			}
293810765SJohn.Forte@Sun.COM 			diskLu->hostIdValid = B_TRUE;
293910765SJohn.Forte@Sun.COM 			break;
29409585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
29419585STim.Szeto@Sun.COM 			if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
29429585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29439585STim.Szeto@Sun.COM 			}
29449585STim.Szeto@Sun.COM 
29459585STim.Szeto@Sun.COM 			if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
29469585STim.Szeto@Sun.COM 			    sizeof (guidProp)) {
29479585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29489585STim.Szeto@Sun.COM 			}
29499585STim.Szeto@Sun.COM 
29509585STim.Szeto@Sun.COM 			if (checkHexUpper(guidProp) != 0) {
29519585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
29529585STim.Szeto@Sun.COM 			}
29539585STim.Szeto@Sun.COM 
29549585STim.Szeto@Sun.COM 			(void) sscanf(guidProp,
29559585STim.Szeto@Sun.COM 			    "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
29569585STim.Szeto@Sun.COM 			    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
29579585STim.Szeto@Sun.COM 			    &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
29589585STim.Szeto@Sun.COM 			    &guid[10], &guid[11], &guid[12], &guid[13],
29599585STim.Szeto@Sun.COM 			    &guid[14], &guid[15]);
29609585STim.Szeto@Sun.COM 			for (i = 0; i < sizeof (diskLu->luGuid); i++) {
29619585STim.Szeto@Sun.COM 				diskLu->luGuid[i] = guid[i];
29629585STim.Szeto@Sun.COM 			}
29639585STim.Szeto@Sun.COM 			diskLu->luGuidValid = B_TRUE;
29649585STim.Szeto@Sun.COM 			break;
29659585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
29669585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luDataFileName, propVal,
29679585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName))) >=
29689585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName)) {
29699585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29709585STim.Szeto@Sun.COM 			}
29719585STim.Szeto@Sun.COM 			diskLu->luDataFileNameValid = B_TRUE;
29729585STim.Szeto@Sun.COM 			break;
29739585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
29749585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luMetaFileName, propVal,
29759585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName))) >=
29769585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName)) {
29779585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29789585STim.Szeto@Sun.COM 			}
29799585STim.Szeto@Sun.COM 			diskLu->luMetaFileNameValid = B_TRUE;
29809585STim.Szeto@Sun.COM 			break;
298110113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
298210113SNattuvetty.Bhavyan@Sun.COM 			if ((strlcpy(diskLu->luMgmtUrl, propVal,
298310113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl))) >=
298410113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl)) {
298510113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
298610113SNattuvetty.Bhavyan@Sun.COM 			}
298710113SNattuvetty.Bhavyan@Sun.COM 			diskLu->luMgmtUrlValid = B_TRUE;
298810113SNattuvetty.Bhavyan@Sun.COM 			break;
29899585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
29909585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
29919585STim.Szeto@Sun.COM 			    sizeof (diskLu->pid)) {
29929585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
29939585STim.Szeto@Sun.COM 			}
29949585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->pid, propVal, propSize);
29959585STim.Szeto@Sun.COM 			diskLu->pidValid = B_TRUE;
29969585STim.Szeto@Sun.COM 			break;
29979585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
29989585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
29999585STim.Szeto@Sun.COM 			    (sizeof (diskLu->serialNum) - 1)) {
30009585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
30019585STim.Szeto@Sun.COM 			}
30029585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->serialNum, propVal, propSize);
30039585STim.Szeto@Sun.COM 			diskLu->serialNumValid = B_TRUE;
30049585STim.Szeto@Sun.COM 			break;
30059585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
30069585STim.Szeto@Sun.COM 			if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
30079585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
30089585STim.Szeto@Sun.COM 			}
30099585STim.Szeto@Sun.COM 			diskLu->luSizeValid = B_TRUE;
30109585STim.Szeto@Sun.COM 			break;
30119585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
30129585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
30139585STim.Szeto@Sun.COM 			    sizeof (diskLu->vid)) {
30149585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
30159585STim.Szeto@Sun.COM 			}
30169585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->vid, propVal, propSize);
30179585STim.Szeto@Sun.COM 			diskLu->vidValid = B_TRUE;
30189585STim.Szeto@Sun.COM 			break;
30199585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
30209585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
30219585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_TRUE;
30229585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
30239585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_FALSE;
30249585STim.Szeto@Sun.COM 			} else {
30259585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
30269585STim.Szeto@Sun.COM 			}
30279585STim.Szeto@Sun.COM 			diskLu->writeProtectEnableValid = B_TRUE;
30289585STim.Szeto@Sun.COM 			break;
30299585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
30309585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
30319585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_TRUE;
30329585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
30339585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_FALSE;
30349585STim.Szeto@Sun.COM 			} else {
30359585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
30369585STim.Szeto@Sun.COM 			}
30379585STim.Szeto@Sun.COM 			diskLu->writebackCacheDisableValid = B_TRUE;
30389585STim.Szeto@Sun.COM 			break;
303910725SJohn.Forte@Sun.COM 		case STMF_LU_PROP_ACCESS_STATE:
304010725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
304110725SJohn.Forte@Sun.COM 			break;
30429585STim.Szeto@Sun.COM 		default:
304311691SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
30449585STim.Szeto@Sun.COM 			break;
30459585STim.Szeto@Sun.COM 	}
30469585STim.Szeto@Sun.COM 	return (ret);
30479585STim.Szeto@Sun.COM }
30489585STim.Szeto@Sun.COM 
30499585STim.Szeto@Sun.COM static int
checkHexUpper(char * buf)30509585STim.Szeto@Sun.COM checkHexUpper(char *buf)
30519585STim.Szeto@Sun.COM {
30529585STim.Szeto@Sun.COM 	int i;
30539585STim.Szeto@Sun.COM 
30549585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(buf); i++) {
30559585STim.Szeto@Sun.COM 		if (isxdigit(buf[i])) {
30569585STim.Szeto@Sun.COM 			buf[i] = toupper(buf[i]);
30579585STim.Szeto@Sun.COM 			continue;
30589585STim.Szeto@Sun.COM 		}
30599585STim.Szeto@Sun.COM 		return (-1);
30609585STim.Szeto@Sun.COM 	}
30619585STim.Szeto@Sun.COM 
30629585STim.Szeto@Sun.COM 	return (0);
30639585STim.Szeto@Sun.COM }
30649585STim.Szeto@Sun.COM 
30659585STim.Szeto@Sun.COM /*
30669585STim.Szeto@Sun.COM  * Given a numeric suffix, convert the value into a number of bits that the
30679585STim.Szeto@Sun.COM  * resulting value must be shifted.
30689585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
30699585STim.Szeto@Sun.COM  */
30709585STim.Szeto@Sun.COM static int
strToShift(const char * buf)30719585STim.Szeto@Sun.COM strToShift(const char *buf)
30729585STim.Szeto@Sun.COM {
30739585STim.Szeto@Sun.COM 	const char *ends = "BKMGTPE";
30749585STim.Szeto@Sun.COM 	int i;
30759585STim.Szeto@Sun.COM 
30769585STim.Szeto@Sun.COM 	if (buf[0] == '\0')
30779585STim.Szeto@Sun.COM 		return (0);
30789585STim.Szeto@Sun.COM 
30799585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(ends); i++) {
30809585STim.Szeto@Sun.COM 		if (toupper(buf[0]) == ends[i])
30819585STim.Szeto@Sun.COM 			return (10*i);
30829585STim.Szeto@Sun.COM 	}
30839585STim.Szeto@Sun.COM 
30849585STim.Szeto@Sun.COM 	return (-1);
30859585STim.Szeto@Sun.COM }
30869585STim.Szeto@Sun.COM 
30879585STim.Szeto@Sun.COM int
stmfFreeLuResource(luResource hdl)30889585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl)
30899585STim.Szeto@Sun.COM {
30909585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
30919585STim.Szeto@Sun.COM 	if (hdl == NULL) {
30929585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
30939585STim.Szeto@Sun.COM 	}
30949585STim.Szeto@Sun.COM 
30959585STim.Szeto@Sun.COM 	luResourceImpl *hdlImpl = hdl;
30969585STim.Szeto@Sun.COM 	free(hdlImpl->resource);
30979585STim.Szeto@Sun.COM 	free(hdlImpl);
30989585STim.Szeto@Sun.COM 	return (ret);
30999585STim.Szeto@Sun.COM }
31009585STim.Szeto@Sun.COM 
31019585STim.Szeto@Sun.COM /*
31029585STim.Szeto@Sun.COM  * Convert a string of the form '100G' into a real number. Used when setting
31039585STim.Szeto@Sun.COM  * the size of a logical unit.
31049585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
31059585STim.Szeto@Sun.COM  */
31069585STim.Szeto@Sun.COM static int
niceStrToNum(const char * value,uint64_t * num)31079585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num)
31089585STim.Szeto@Sun.COM {
31099585STim.Szeto@Sun.COM 	char *end;
31109585STim.Szeto@Sun.COM 	int shift;
31119585STim.Szeto@Sun.COM 
31129585STim.Szeto@Sun.COM 	*num = 0;
31139585STim.Szeto@Sun.COM 
31149585STim.Szeto@Sun.COM 	/* Check to see if this looks like a number.  */
31159585STim.Szeto@Sun.COM 	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
31169585STim.Szeto@Sun.COM 		return (-1);
31179585STim.Szeto@Sun.COM 	}
31189585STim.Szeto@Sun.COM 
31199585STim.Szeto@Sun.COM 	/* Rely on stroull() to process the numeric portion.  */
31209585STim.Szeto@Sun.COM 	errno = 0;
31219585STim.Szeto@Sun.COM 	*num = strtoull(value, &end, 10);
31229585STim.Szeto@Sun.COM 
31239585STim.Szeto@Sun.COM 	/*
31249585STim.Szeto@Sun.COM 	 * Check for ERANGE, which indicates that the value is too large to fit
31259585STim.Szeto@Sun.COM 	 * in a 64-bit value.
31269585STim.Szeto@Sun.COM 	 */
31279585STim.Szeto@Sun.COM 	if (errno == ERANGE) {
31289585STim.Szeto@Sun.COM 		return (-1);
31299585STim.Szeto@Sun.COM 	}
31309585STim.Szeto@Sun.COM 
31319585STim.Szeto@Sun.COM 	/*
31329585STim.Szeto@Sun.COM 	 * If we have a decimal value, then do the computation with floating
31339585STim.Szeto@Sun.COM 	 * point arithmetic.  Otherwise, use standard arithmetic.
31349585STim.Szeto@Sun.COM 	 */
31359585STim.Szeto@Sun.COM 	if (*end == '.') {
31369585STim.Szeto@Sun.COM 		double fval = strtod(value, &end);
31379585STim.Szeto@Sun.COM 
31389585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
31399585STim.Szeto@Sun.COM 			return (-1);
31409585STim.Szeto@Sun.COM 		}
31419585STim.Szeto@Sun.COM 
31429585STim.Szeto@Sun.COM 		fval *= pow(2, shift);
31439585STim.Szeto@Sun.COM 
31449585STim.Szeto@Sun.COM 		if (fval > UINT64_MAX) {
31459585STim.Szeto@Sun.COM 			return (-1);
31469585STim.Szeto@Sun.COM 		}
31479585STim.Szeto@Sun.COM 
31489585STim.Szeto@Sun.COM 		*num = (uint64_t)fval;
31499585STim.Szeto@Sun.COM 	} else {
31509585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
31519585STim.Szeto@Sun.COM 			return (-1);
31529585STim.Szeto@Sun.COM 		}
31539585STim.Szeto@Sun.COM 
31549585STim.Szeto@Sun.COM 		/* Check for overflow */
31559585STim.Szeto@Sun.COM 		if (shift >= 64 || (*num << shift) >> shift != *num) {
31569585STim.Szeto@Sun.COM 			return (-1);
31579585STim.Szeto@Sun.COM 		}
31589585STim.Szeto@Sun.COM 
31599585STim.Szeto@Sun.COM 		*num <<= shift;
31609585STim.Szeto@Sun.COM 	}
31619585STim.Szeto@Sun.COM 
31629585STim.Szeto@Sun.COM 	return (0);
31639585STim.Szeto@Sun.COM }
31649585STim.Szeto@Sun.COM 
31659585STim.Szeto@Sun.COM /*
31667836SJohn.Forte@Sun.COM  * stmfCreateTargetGroup
31677836SJohn.Forte@Sun.COM  *
31687836SJohn.Forte@Sun.COM  * Purpose: Create a local port group
31697836SJohn.Forte@Sun.COM  *
31707836SJohn.Forte@Sun.COM  * targetGroupName - name of local port group to create
31717836SJohn.Forte@Sun.COM  */
31727836SJohn.Forte@Sun.COM int
stmfCreateTargetGroup(stmfGroupName * targetGroupName)31737836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName)
31747836SJohn.Forte@Sun.COM {
31757836SJohn.Forte@Sun.COM 	int ret;
31767836SJohn.Forte@Sun.COM 	int fd;
31777836SJohn.Forte@Sun.COM 
31787836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
31797836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
31807836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
31817836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31827836SJohn.Forte@Sun.COM 	}
31837836SJohn.Forte@Sun.COM 
31847836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
31857836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
31867836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
31877836SJohn.Forte@Sun.COM 	}
31887836SJohn.Forte@Sun.COM 
31897836SJohn.Forte@Sun.COM 	/* call init */
31907836SJohn.Forte@Sun.COM 	ret = initializeConfig();
31917836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
31927836SJohn.Forte@Sun.COM 		return (ret);
31937836SJohn.Forte@Sun.COM 	}
31947836SJohn.Forte@Sun.COM 
31957836SJohn.Forte@Sun.COM 	/*
31967836SJohn.Forte@Sun.COM 	 * Open control node for stmf
31977836SJohn.Forte@Sun.COM 	 */
31987836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
31997836SJohn.Forte@Sun.COM 		return (ret);
32007836SJohn.Forte@Sun.COM 
32017836SJohn.Forte@Sun.COM 	/*
32027836SJohn.Forte@Sun.COM 	 * Add the group to the driver
32037836SJohn.Forte@Sun.COM 	 */
32047836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
32057836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
32067836SJohn.Forte@Sun.COM 		goto done;
32077836SJohn.Forte@Sun.COM 	}
32087836SJohn.Forte@Sun.COM 
32099585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
32109585STim.Szeto@Sun.COM 		goto done;
32119585STim.Szeto@Sun.COM 	}
32129585STim.Szeto@Sun.COM 
32137836SJohn.Forte@Sun.COM 	/*
32147836SJohn.Forte@Sun.COM 	 * If the add to the driver was successful, add it to the persistent
32157836SJohn.Forte@Sun.COM 	 * store.
32167836SJohn.Forte@Sun.COM 	 */
32177836SJohn.Forte@Sun.COM 	ret = psCreateTargetGroup((char *)targetGroupName);
32187836SJohn.Forte@Sun.COM 	switch (ret) {
32197836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
32207836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
32217836SJohn.Forte@Sun.COM 			break;
32227836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
32237836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
32247836SJohn.Forte@Sun.COM 			break;
32257836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
32267836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
32277836SJohn.Forte@Sun.COM 			break;
32287836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
32297836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
32307836SJohn.Forte@Sun.COM 			break;
32317836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
32327836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
32337836SJohn.Forte@Sun.COM 			break;
32347836SJohn.Forte@Sun.COM 		default:
32357836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
32367836SJohn.Forte@Sun.COM 			    "stmfCreateTargetGroup:psCreateTargetGroup"
32377836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
32387836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
32397836SJohn.Forte@Sun.COM 			break;
32407836SJohn.Forte@Sun.COM 	}
32417836SJohn.Forte@Sun.COM 
32427836SJohn.Forte@Sun.COM done:
32437836SJohn.Forte@Sun.COM 	(void) close(fd);
32447836SJohn.Forte@Sun.COM 	return (ret);
32457836SJohn.Forte@Sun.COM }
32467836SJohn.Forte@Sun.COM 
32477836SJohn.Forte@Sun.COM /*
32487836SJohn.Forte@Sun.COM  * stmfDeleteHostGroup
32497836SJohn.Forte@Sun.COM  *
32507836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
32517836SJohn.Forte@Sun.COM  *
32527836SJohn.Forte@Sun.COM  * hostGroupName - group to delete
32537836SJohn.Forte@Sun.COM  */
32547836SJohn.Forte@Sun.COM int
stmfDeleteHostGroup(stmfGroupName * hostGroupName)32557836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName)
32567836SJohn.Forte@Sun.COM {
32577836SJohn.Forte@Sun.COM 	int ret;
32587836SJohn.Forte@Sun.COM 	int fd;
32597836SJohn.Forte@Sun.COM 
32607836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL) {
32617836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32627836SJohn.Forte@Sun.COM 	}
32637836SJohn.Forte@Sun.COM 
32647836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
32657836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
32667836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
32677836SJohn.Forte@Sun.COM 	}
32687836SJohn.Forte@Sun.COM 
32697836SJohn.Forte@Sun.COM 	/* call init */
32707836SJohn.Forte@Sun.COM 	ret = initializeConfig();
32717836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
32727836SJohn.Forte@Sun.COM 		return (ret);
32737836SJohn.Forte@Sun.COM 	}
32747836SJohn.Forte@Sun.COM 
32757836SJohn.Forte@Sun.COM 	/*
32767836SJohn.Forte@Sun.COM 	 * Open control node for stmf
32777836SJohn.Forte@Sun.COM 	 */
32787836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
32797836SJohn.Forte@Sun.COM 		return (ret);
32807836SJohn.Forte@Sun.COM 
32817836SJohn.Forte@Sun.COM 	/*
32827836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
32837836SJohn.Forte@Sun.COM 	 */
32847836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
32857836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
32867836SJohn.Forte@Sun.COM 		goto done;
32877836SJohn.Forte@Sun.COM 	}
32887836SJohn.Forte@Sun.COM 
32899585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
32909585STim.Szeto@Sun.COM 		goto done;
32919585STim.Szeto@Sun.COM 	}
32929585STim.Szeto@Sun.COM 
32937836SJohn.Forte@Sun.COM 	/*
32947836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
32957836SJohn.Forte@Sun.COM 	 * persistent store.
32967836SJohn.Forte@Sun.COM 	 */
32977836SJohn.Forte@Sun.COM 	ret = psDeleteHostGroup((char *)hostGroupName);
32987836SJohn.Forte@Sun.COM 	switch (ret) {
32997836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
33007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
33017836SJohn.Forte@Sun.COM 			break;
33027836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
33037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
33047836SJohn.Forte@Sun.COM 			break;
33057836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
33067836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
33077836SJohn.Forte@Sun.COM 			break;
33087836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
33097836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
33107836SJohn.Forte@Sun.COM 			break;
33117836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
33127836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
33137836SJohn.Forte@Sun.COM 			break;
33147836SJohn.Forte@Sun.COM 		default:
33157836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
33167836SJohn.Forte@Sun.COM 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
33177836SJohn.Forte@Sun.COM 			    ret);
33187836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
33197836SJohn.Forte@Sun.COM 			break;
33207836SJohn.Forte@Sun.COM 	}
33217836SJohn.Forte@Sun.COM 
33227836SJohn.Forte@Sun.COM done:
33237836SJohn.Forte@Sun.COM 	(void) close(fd);
33247836SJohn.Forte@Sun.COM 	return (ret);
33257836SJohn.Forte@Sun.COM }
33267836SJohn.Forte@Sun.COM 
33277836SJohn.Forte@Sun.COM /*
33287836SJohn.Forte@Sun.COM  * stmfDeleteTargetGroup
33297836SJohn.Forte@Sun.COM  *
33307836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
33317836SJohn.Forte@Sun.COM  *
33327836SJohn.Forte@Sun.COM  * targetGroupName - group to delete
33337836SJohn.Forte@Sun.COM  */
33347836SJohn.Forte@Sun.COM int
stmfDeleteTargetGroup(stmfGroupName * targetGroupName)33357836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
33367836SJohn.Forte@Sun.COM {
33377836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
33387836SJohn.Forte@Sun.COM 	int fd;
33397836SJohn.Forte@Sun.COM 
33407836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL) {
33417836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33427836SJohn.Forte@Sun.COM 	}
33437836SJohn.Forte@Sun.COM 
33447836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
33457836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
33467836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
33477836SJohn.Forte@Sun.COM 	}
33487836SJohn.Forte@Sun.COM 
33497836SJohn.Forte@Sun.COM 	/* call init */
33507836SJohn.Forte@Sun.COM 	ret = initializeConfig();
33517836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
33527836SJohn.Forte@Sun.COM 		return (ret);
33537836SJohn.Forte@Sun.COM 	}
33547836SJohn.Forte@Sun.COM 
33557836SJohn.Forte@Sun.COM 	/*
33567836SJohn.Forte@Sun.COM 	 * Open control node for stmf
33577836SJohn.Forte@Sun.COM 	 */
33587836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
33597836SJohn.Forte@Sun.COM 		return (ret);
33607836SJohn.Forte@Sun.COM 
33617836SJohn.Forte@Sun.COM 	/*
33627836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
33637836SJohn.Forte@Sun.COM 	 */
33647836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
33657836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
33667836SJohn.Forte@Sun.COM 		goto done;
33677836SJohn.Forte@Sun.COM 	}
33687836SJohn.Forte@Sun.COM 
33699585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
33709585STim.Szeto@Sun.COM 		goto done;
33719585STim.Szeto@Sun.COM 	}
33729585STim.Szeto@Sun.COM 
33737836SJohn.Forte@Sun.COM 	/*
33747836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
33757836SJohn.Forte@Sun.COM 	 * persistent store.
33767836SJohn.Forte@Sun.COM 	 */
33777836SJohn.Forte@Sun.COM 	ret = psDeleteTargetGroup((char *)targetGroupName);
33787836SJohn.Forte@Sun.COM 	switch (ret) {
33797836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
33807836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
33817836SJohn.Forte@Sun.COM 			break;
33827836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
33837836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
33847836SJohn.Forte@Sun.COM 			break;
33857836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
33867836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
33877836SJohn.Forte@Sun.COM 			break;
33887836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
33897836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
33907836SJohn.Forte@Sun.COM 			break;
33917836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
33927836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
33937836SJohn.Forte@Sun.COM 			break;
33947836SJohn.Forte@Sun.COM 		default:
33957836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
33967836SJohn.Forte@Sun.COM 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
33977836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
33987836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
33997836SJohn.Forte@Sun.COM 			break;
34007836SJohn.Forte@Sun.COM 	}
34017836SJohn.Forte@Sun.COM 
34027836SJohn.Forte@Sun.COM done:
34037836SJohn.Forte@Sun.COM 	(void) close(fd);
34047836SJohn.Forte@Sun.COM 	return (ret);
34057836SJohn.Forte@Sun.COM }
34067836SJohn.Forte@Sun.COM 
34077836SJohn.Forte@Sun.COM /*
34087836SJohn.Forte@Sun.COM  * stmfDevidFromIscsiName
34097836SJohn.Forte@Sun.COM  *
34107836SJohn.Forte@Sun.COM  * Purpose: convert an iSCSI name to an stmf devid
34117836SJohn.Forte@Sun.COM  *
34127836SJohn.Forte@Sun.COM  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
34137836SJohn.Forte@Sun.COM  * devid - on success, contains the converted iscsi name
34147836SJohn.Forte@Sun.COM  */
34157836SJohn.Forte@Sun.COM int
stmfDevidFromIscsiName(char * iscsiName,stmfDevid * devid)34167836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
34177836SJohn.Forte@Sun.COM {
34187836SJohn.Forte@Sun.COM 	if (devid == NULL || iscsiName == NULL)
34197836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34207836SJohn.Forte@Sun.COM 
34217836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
34227836SJohn.Forte@Sun.COM 
34237836SJohn.Forte@Sun.COM 	/* Validate size of target */
34247836SJohn.Forte@Sun.COM 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
34257836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(EUI) ||
34267836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(IQN)) {
34277836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34287836SJohn.Forte@Sun.COM 	}
34297836SJohn.Forte@Sun.COM 
34307836SJohn.Forte@Sun.COM 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
34317836SJohn.Forte@Sun.COM 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
34327836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34337836SJohn.Forte@Sun.COM 	}
34347836SJohn.Forte@Sun.COM 
34357836SJohn.Forte@Sun.COM 	/* copy UTF-8 bytes to ident */
34367836SJohn.Forte@Sun.COM 	bcopy(iscsiName, devid->ident, devid->identLength);
34377836SJohn.Forte@Sun.COM 
34387836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
34397836SJohn.Forte@Sun.COM }
34407836SJohn.Forte@Sun.COM 
34417836SJohn.Forte@Sun.COM /*
34427836SJohn.Forte@Sun.COM  * stmfDevidFromWwn
34437836SJohn.Forte@Sun.COM  *
34447836SJohn.Forte@Sun.COM  * Purpose: convert a WWN to an stmf devid
34457836SJohn.Forte@Sun.COM  *
34467836SJohn.Forte@Sun.COM  * wwn - 8-byte wwn identifier
34477836SJohn.Forte@Sun.COM  * devid - on success, contains the converted wwn
34487836SJohn.Forte@Sun.COM  */
34497836SJohn.Forte@Sun.COM int
stmfDevidFromWwn(uchar_t * wwn,stmfDevid * devid)34507836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
34517836SJohn.Forte@Sun.COM {
34527836SJohn.Forte@Sun.COM 	if (wwn == NULL || devid == NULL)
34537836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34547836SJohn.Forte@Sun.COM 
34557836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
34567836SJohn.Forte@Sun.COM 
34577836SJohn.Forte@Sun.COM 	/* Copy eui prefix */
34587836SJohn.Forte@Sun.COM 	(void) bcopy(WWN, devid->ident, strlen(WWN));
34597836SJohn.Forte@Sun.COM 
34607836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
34617836SJohn.Forte@Sun.COM 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
34627836SJohn.Forte@Sun.COM 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
34637836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
34647836SJohn.Forte@Sun.COM 
34657836SJohn.Forte@Sun.COM 	devid->identLength = strlen((char *)devid->ident);
34667836SJohn.Forte@Sun.COM 
34677836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
34687836SJohn.Forte@Sun.COM }
34697836SJohn.Forte@Sun.COM 
34707836SJohn.Forte@Sun.COM /*
34717836SJohn.Forte@Sun.COM  * stmfFreeMemory
34727836SJohn.Forte@Sun.COM  *
34737836SJohn.Forte@Sun.COM  * Purpose: Free memory allocated by this library
34747836SJohn.Forte@Sun.COM  *
34757836SJohn.Forte@Sun.COM  * memory - previously allocated pointer of memory managed by library
34767836SJohn.Forte@Sun.COM  */
34777836SJohn.Forte@Sun.COM void
stmfFreeMemory(void * memory)34787836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory)
34797836SJohn.Forte@Sun.COM {
34807836SJohn.Forte@Sun.COM 	free(memory);
34817836SJohn.Forte@Sun.COM }
34827836SJohn.Forte@Sun.COM 
34837836SJohn.Forte@Sun.COM /*
34849585STim.Szeto@Sun.COM  * get host group, target group list from stmf
34857836SJohn.Forte@Sun.COM  *
34869585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
34877836SJohn.Forte@Sun.COM  */
34889585STim.Szeto@Sun.COM static int
groupListIoctl(stmfGroupList ** groupList,int groupType)34899585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType)
34909585STim.Szeto@Sun.COM {
34919585STim.Szeto@Sun.COM 	int ret;
34929585STim.Szeto@Sun.COM 	int fd;
34939585STim.Szeto@Sun.COM 	int ioctlRet;
34949585STim.Szeto@Sun.COM 	int i;
34959585STim.Szeto@Sun.COM 	int cmd;
34969585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
34979585STim.Szeto@Sun.COM 	/* framework group list */
34989585STim.Szeto@Sun.COM 	stmf_group_name_t *iGroupList = NULL;
34999585STim.Szeto@Sun.COM 	uint32_t groupListSize;
35009585STim.Szeto@Sun.COM 
35019585STim.Szeto@Sun.COM 	if (groupList == NULL) {
35029585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35039585STim.Szeto@Sun.COM 	}
35049585STim.Szeto@Sun.COM 
35059585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
35069585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_LIST;
35079585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
35089585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_LIST;
35099585STim.Szeto@Sun.COM 	} else {
35109585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35119585STim.Szeto@Sun.COM 	}
35129585STim.Szeto@Sun.COM 
35139585STim.Szeto@Sun.COM 	/* call init */
35149585STim.Szeto@Sun.COM 	ret = initializeConfig();
35159585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
35169585STim.Szeto@Sun.COM 		return (ret);
35179585STim.Szeto@Sun.COM 	}
35189585STim.Szeto@Sun.COM 
35199585STim.Szeto@Sun.COM 	/*
35209585STim.Szeto@Sun.COM 	 * Open control node for stmf
35219585STim.Szeto@Sun.COM 	 */
35229585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
35239585STim.Szeto@Sun.COM 		return (ret);
35249585STim.Szeto@Sun.COM 
35259585STim.Szeto@Sun.COM 	/*
35269585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
35279585STim.Szeto@Sun.COM 	 */
35289585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GROUP;
35299585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_group_name_t));
35309585STim.Szeto@Sun.COM 	iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
35319585STim.Szeto@Sun.COM 	if (iGroupList == NULL) {
35329585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
35339585STim.Szeto@Sun.COM 		goto done;
35349585STim.Szeto@Sun.COM 	}
35359585STim.Szeto@Sun.COM 
35369585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
35379585STim.Szeto@Sun.COM 	/*
35389585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
35399585STim.Szeto@Sun.COM 	 */
35409585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
35419585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
35429585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
35439585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
35449585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
35459585STim.Szeto@Sun.COM 		switch (errno) {
35469585STim.Szeto@Sun.COM 			case EBUSY:
35479585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
35489585STim.Szeto@Sun.COM 				break;
35499585STim.Szeto@Sun.COM 			case EPERM:
35509585STim.Szeto@Sun.COM 			case EACCES:
35519585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
35529585STim.Szeto@Sun.COM 				break;
35539585STim.Szeto@Sun.COM 			default:
35549585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
35559585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
35569585STim.Szeto@Sun.COM 				    errno);
35579585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
35589585STim.Szeto@Sun.COM 				break;
35599585STim.Szeto@Sun.COM 		}
35609585STim.Szeto@Sun.COM 		goto done;
35619585STim.Szeto@Sun.COM 	}
35629585STim.Szeto@Sun.COM 	/*
35639585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
35649585STim.Szeto@Sun.COM 	 */
35659585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
35669585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
35679585STim.Szeto@Sun.COM 		    sizeof (stmf_group_name_t);
35689585STim.Szeto@Sun.COM 		iGroupList = realloc(iGroupList, groupListSize);
35699585STim.Szeto@Sun.COM 		if (iGroupList == NULL) {
35709585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
35719585STim.Szeto@Sun.COM 			goto done;
35729585STim.Szeto@Sun.COM 		}
35739585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
35749585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
35759585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
35769585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
35779585STim.Szeto@Sun.COM 			switch (errno) {
35789585STim.Szeto@Sun.COM 				case EBUSY:
35799585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
35809585STim.Szeto@Sun.COM 					break;
35819585STim.Szeto@Sun.COM 				case EPERM:
35829585STim.Szeto@Sun.COM 				case EACCES:
35839585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
35849585STim.Szeto@Sun.COM 					break;
35859585STim.Szeto@Sun.COM 				default:
35869585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
35879585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
35889585STim.Szeto@Sun.COM 					    errno);
35899585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
35909585STim.Szeto@Sun.COM 					break;
35919585STim.Szeto@Sun.COM 			}
35929585STim.Szeto@Sun.COM 			goto done;
35939585STim.Szeto@Sun.COM 		}
35949585STim.Szeto@Sun.COM 	}
35959585STim.Szeto@Sun.COM 
35969585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
359710236SSrivijitha.Dugganapalli@Sun.COM 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
359810236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries);
35999585STim.Szeto@Sun.COM 	if (*groupList == NULL) {
36009585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
36019585STim.Szeto@Sun.COM 		goto done;
36029585STim.Szeto@Sun.COM 	}
36039585STim.Szeto@Sun.COM 	(*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
36049585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
360510113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupList[i].name, (*groupList)->name[i],
36069585STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
36079585STim.Szeto@Sun.COM 	}
36089585STim.Szeto@Sun.COM 
36099585STim.Szeto@Sun.COM done:
36109585STim.Szeto@Sun.COM 	free(iGroupList);
36119585STim.Szeto@Sun.COM 	(void) close(fd);
36129585STim.Szeto@Sun.COM 	return (ret);
36139585STim.Szeto@Sun.COM }
36149585STim.Szeto@Sun.COM 
36159585STim.Szeto@Sun.COM /*
36169585STim.Szeto@Sun.COM  * get host group members, target group members from stmf
36179585STim.Szeto@Sun.COM  *
36189585STim.Szeto@Sun.COM  * groupProps - allocated on success
36199585STim.Szeto@Sun.COM  *
36209585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
36219585STim.Szeto@Sun.COM  */
36229585STim.Szeto@Sun.COM static int
groupMemberListIoctl(stmfGroupName * groupName,stmfGroupProperties ** groupProps,int groupType)36239585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
36249585STim.Szeto@Sun.COM     int groupType)
36257836SJohn.Forte@Sun.COM {
36267836SJohn.Forte@Sun.COM 	int ret;
36279585STim.Szeto@Sun.COM 	int fd;
36289585STim.Szeto@Sun.COM 	int ioctlRet;
36299585STim.Szeto@Sun.COM 	int i;
36309585STim.Szeto@Sun.COM 	int cmd;
36319585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
36329585STim.Szeto@Sun.COM 	/* framework group list */
36339585STim.Szeto@Sun.COM 	stmf_group_name_t iGroupName;
36349585STim.Szeto@Sun.COM 	stmf_ge_ident_t *iGroupMembers;
36359585STim.Szeto@Sun.COM 	uint32_t groupListSize;
36369585STim.Szeto@Sun.COM 
36379585STim.Szeto@Sun.COM 	if (groupName == NULL) {
36389585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36399585STim.Szeto@Sun.COM 	}
36409585STim.Szeto@Sun.COM 
36419585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
36429585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_ENTRIES;
36439585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
36449585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_ENTRIES;
36459585STim.Szeto@Sun.COM 	} else {
36467836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36477836SJohn.Forte@Sun.COM 	}
36487836SJohn.Forte@Sun.COM 
36499585STim.Szeto@Sun.COM 	/* call init */
36509585STim.Szeto@Sun.COM 	ret = initializeConfig();
36519585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
36529585STim.Szeto@Sun.COM 		return (ret);
36539585STim.Szeto@Sun.COM 	}
36549585STim.Szeto@Sun.COM 
36559585STim.Szeto@Sun.COM 	/*
36569585STim.Szeto@Sun.COM 	 * Open control node for stmf
36579585STim.Szeto@Sun.COM 	 */
36589585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
36599585STim.Szeto@Sun.COM 		return (ret);
36609585STim.Szeto@Sun.COM 
36619585STim.Szeto@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
36629585STim.Szeto@Sun.COM 
36639585STim.Szeto@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
36649585STim.Szeto@Sun.COM 
36659585STim.Szeto@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
36669585STim.Szeto@Sun.COM 
36679585STim.Szeto@Sun.COM 	/*
36689585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
36699585STim.Szeto@Sun.COM 	 */
36709585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GRP_MEMBER;
36719585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
36729585STim.Szeto@Sun.COM 	iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
36739585STim.Szeto@Sun.COM 	if (iGroupMembers == NULL) {
36749585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
36759585STim.Szeto@Sun.COM 		goto done;
36769585STim.Szeto@Sun.COM 	}
36779585STim.Szeto@Sun.COM 
36789585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
36799585STim.Szeto@Sun.COM 	/*
36809585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
36819585STim.Szeto@Sun.COM 	 */
36829585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
36839585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
36849585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
36859585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
36869585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
36879585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
36889585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
36899585STim.Szeto@Sun.COM 		switch (errno) {
36909585STim.Szeto@Sun.COM 			case EBUSY:
36919585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
36929585STim.Szeto@Sun.COM 				break;
36939585STim.Szeto@Sun.COM 			case EPERM:
36949585STim.Szeto@Sun.COM 			case EACCES:
36959585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
36969585STim.Szeto@Sun.COM 				break;
36979585STim.Szeto@Sun.COM 			default:
36989585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
36999585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
37009585STim.Szeto@Sun.COM 				    errno);
37019585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
37029585STim.Szeto@Sun.COM 				break;
37039585STim.Szeto@Sun.COM 		}
37049585STim.Szeto@Sun.COM 		goto done;
37059585STim.Szeto@Sun.COM 	}
37069585STim.Szeto@Sun.COM 	/*
37079585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
37089585STim.Szeto@Sun.COM 	 */
37099585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
37109585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
37119585STim.Szeto@Sun.COM 		    sizeof (stmf_ge_ident_t);
37129585STim.Szeto@Sun.COM 		iGroupMembers = realloc(iGroupMembers, groupListSize);
37139585STim.Szeto@Sun.COM 		if (iGroupMembers == NULL) {
37149585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
37159585STim.Szeto@Sun.COM 			goto done;
37169585STim.Szeto@Sun.COM 		}
37179585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
37189585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
37199585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
37209585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
37219585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
37229585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
37239585STim.Szeto@Sun.COM 			switch (errno) {
37249585STim.Szeto@Sun.COM 				case EBUSY:
37259585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
37269585STim.Szeto@Sun.COM 					break;
37279585STim.Szeto@Sun.COM 				case EPERM:
37289585STim.Szeto@Sun.COM 				case EACCES:
37299585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
37309585STim.Szeto@Sun.COM 					break;
37319585STim.Szeto@Sun.COM 				default:
37329585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
37339585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
37349585STim.Szeto@Sun.COM 					    errno);
37359585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
37369585STim.Szeto@Sun.COM 					break;
37379585STim.Szeto@Sun.COM 			}
37389585STim.Szeto@Sun.COM 			goto done;
37399585STim.Szeto@Sun.COM 		}
37409585STim.Szeto@Sun.COM 	}
37419585STim.Szeto@Sun.COM 
37429585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
37439585STim.Szeto@Sun.COM 	*groupProps = (stmfGroupProperties *)calloc(1,
374410236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupProperties) +
374510236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries);
37469585STim.Szeto@Sun.COM 	if (*groupProps == NULL) {
37479585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
37489585STim.Szeto@Sun.COM 		goto done;
37499585STim.Szeto@Sun.COM 	}
37509585STim.Szeto@Sun.COM 	(*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
37519585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
37529585STim.Szeto@Sun.COM 		(*groupProps)->name[i].identLength =
375310113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size;
375410113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
375510113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size);
37569585STim.Szeto@Sun.COM 	}
37579585STim.Szeto@Sun.COM 
37589585STim.Szeto@Sun.COM done:
37599585STim.Szeto@Sun.COM 	free(iGroupMembers);
37609585STim.Szeto@Sun.COM 	(void) close(fd);
37619585STim.Szeto@Sun.COM 	return (ret);
37629585STim.Szeto@Sun.COM }
37639585STim.Szeto@Sun.COM 
37649585STim.Szeto@Sun.COM /*
37659585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
37669585STim.Szeto@Sun.COM  */
37679585STim.Szeto@Sun.COM static int
iLoadGroupFromPs(stmfGroupList ** groupList,int type)37689585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type)
37699585STim.Szeto@Sun.COM {
37709585STim.Szeto@Sun.COM 	int ret;
37719585STim.Szeto@Sun.COM 
37729585STim.Szeto@Sun.COM 	if (groupList == NULL) {
37739585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
37749585STim.Szeto@Sun.COM 	}
37759585STim.Szeto@Sun.COM 
37769585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
37779585STim.Szeto@Sun.COM 		ret = psGetHostGroupList(groupList);
37789585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
37799585STim.Szeto@Sun.COM 		ret = psGetTargetGroupList(groupList);
37809585STim.Szeto@Sun.COM 	} else {
37819585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
37829585STim.Szeto@Sun.COM 	}
37837836SJohn.Forte@Sun.COM 	switch (ret) {
37847836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
37857836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
37867836SJohn.Forte@Sun.COM 			break;
37877836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
37887836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
37897836SJohn.Forte@Sun.COM 			break;
37907836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
37917836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
37927836SJohn.Forte@Sun.COM 			break;
37937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
37947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
37957836SJohn.Forte@Sun.COM 			break;
37967836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
37977836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
37987836SJohn.Forte@Sun.COM 			break;
37997836SJohn.Forte@Sun.COM 		default:
38007836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
38017836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
38027836SJohn.Forte@Sun.COM 			    ret);
38037836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
38047836SJohn.Forte@Sun.COM 			break;
38057836SJohn.Forte@Sun.COM 	}
38067836SJohn.Forte@Sun.COM 
38077836SJohn.Forte@Sun.COM 	return (ret);
38087836SJohn.Forte@Sun.COM }
38097836SJohn.Forte@Sun.COM 
38107836SJohn.Forte@Sun.COM /*
38119585STim.Szeto@Sun.COM  * stmfGetHostGroupList
38127836SJohn.Forte@Sun.COM  *
38139585STim.Szeto@Sun.COM  * Purpose: Retrieves the list of initiator group oids
38149585STim.Szeto@Sun.COM  *
38159585STim.Szeto@Sun.COM  * hostGroupList - pointer to pointer to hostGroupList structure
38169585STim.Szeto@Sun.COM  *                 on success, this contains the host group list.
38177836SJohn.Forte@Sun.COM  */
38187836SJohn.Forte@Sun.COM int
stmfGetHostGroupList(stmfGroupList ** hostGroupList)38199585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList)
38209585STim.Szeto@Sun.COM {
38219585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
38229585STim.Szeto@Sun.COM 
38239585STim.Szeto@Sun.COM 	if (hostGroupList == NULL) {
38249585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38259585STim.Szeto@Sun.COM 	}
38269585STim.Szeto@Sun.COM 
38279585STim.Szeto@Sun.COM 	ret = groupListIoctl(hostGroupList, HOST_GROUP);
38289585STim.Szeto@Sun.COM 	return (ret);
38299585STim.Szeto@Sun.COM }
38309585STim.Szeto@Sun.COM 
38319585STim.Szeto@Sun.COM 
38329585STim.Szeto@Sun.COM /*
38339585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
38349585STim.Szeto@Sun.COM  */
38359585STim.Szeto@Sun.COM static int
iLoadGroupMembersFromPs(stmfGroupName * groupName,stmfGroupProperties ** groupProp,int type)38369585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName,
38379585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp, int type)
38387836SJohn.Forte@Sun.COM {
38397836SJohn.Forte@Sun.COM 	int ret;
38407836SJohn.Forte@Sun.COM 
38419585STim.Szeto@Sun.COM 	if (groupName == NULL) {
38427836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38437836SJohn.Forte@Sun.COM 	}
38447836SJohn.Forte@Sun.COM 
38459585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
38469585STim.Szeto@Sun.COM 		ret = psGetHostGroupMemberList((char *)groupName, groupProp);
38479585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
38489585STim.Szeto@Sun.COM 		ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
38499585STim.Szeto@Sun.COM 	} else {
38509585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38519585STim.Szeto@Sun.COM 	}
38527836SJohn.Forte@Sun.COM 	switch (ret) {
38537836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
38547836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
38557836SJohn.Forte@Sun.COM 			break;
38567836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
38577836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
38587836SJohn.Forte@Sun.COM 			break;
38597836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
38607836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
38617836SJohn.Forte@Sun.COM 			break;
38627836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
38637836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
38647836SJohn.Forte@Sun.COM 			break;
38657836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
38667836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
38677836SJohn.Forte@Sun.COM 			break;
38687836SJohn.Forte@Sun.COM 		default:
38697836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
38709585STim.Szeto@Sun.COM 			    "iLoadGroupMembersFromPs:psGetHostGroupList:"
38719585STim.Szeto@Sun.COM 			    "error(%d)", ret);
38727836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
38737836SJohn.Forte@Sun.COM 			break;
38747836SJohn.Forte@Sun.COM 	}
38757836SJohn.Forte@Sun.COM 
38767836SJohn.Forte@Sun.COM 	return (ret);
38777836SJohn.Forte@Sun.COM }
38787836SJohn.Forte@Sun.COM 
38797836SJohn.Forte@Sun.COM /*
38809585STim.Szeto@Sun.COM  * stmfGetHostGroupMembers
38819585STim.Szeto@Sun.COM  *
38829585STim.Szeto@Sun.COM  * Purpose: Retrieves the group properties for a host group
38839585STim.Szeto@Sun.COM  *
38849585STim.Szeto@Sun.COM  * groupName - name of group for which to retrieve host group members.
38859585STim.Szeto@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
38869585STim.Szeto@Sun.COM  *             on success, this contains the list of group members.
38879585STim.Szeto@Sun.COM  */
38889585STim.Szeto@Sun.COM int
stmfGetHostGroupMembers(stmfGroupName * groupName,stmfGroupProperties ** groupProp)38899585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName,
38909585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp)
38919585STim.Szeto@Sun.COM {
38929585STim.Szeto@Sun.COM 	int ret;
38939585STim.Szeto@Sun.COM 
38949585STim.Szeto@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
38959585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38969585STim.Szeto@Sun.COM 	}
38979585STim.Szeto@Sun.COM 
38989585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
38999585STim.Szeto@Sun.COM 
39009585STim.Szeto@Sun.COM 	return (ret);
39019585STim.Szeto@Sun.COM }
39029585STim.Szeto@Sun.COM 
39039585STim.Szeto@Sun.COM /*
39047836SJohn.Forte@Sun.COM  * stmfGetProviderData
39057836SJohn.Forte@Sun.COM  *
39067836SJohn.Forte@Sun.COM  * Purpose: Get provider data list
39077836SJohn.Forte@Sun.COM  *
39087836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
39097836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
39107836SJohn.Forte@Sun.COM  *       retrieved.
39117836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
39127836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
39137836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
39147836SJohn.Forte@Sun.COM  */
39157836SJohn.Forte@Sun.COM int
stmfGetProviderData(char * providerName,nvlist_t ** nvl,int providerType)39167836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
39177836SJohn.Forte@Sun.COM {
39187836SJohn.Forte@Sun.COM 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
39197836SJohn.Forte@Sun.COM 	    NULL));
39207836SJohn.Forte@Sun.COM }
39217836SJohn.Forte@Sun.COM 
39227836SJohn.Forte@Sun.COM /*
39237836SJohn.Forte@Sun.COM  * stmfGetProviderDataProt
39247836SJohn.Forte@Sun.COM  *
39257836SJohn.Forte@Sun.COM  * Purpose: Get provider data list with token
39267836SJohn.Forte@Sun.COM  *
39277836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
39287836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
39297836SJohn.Forte@Sun.COM  *       retrieved.
39307836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
39317836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
39327836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
39337836SJohn.Forte@Sun.COM  * setToken - Returns the stale data token
39347836SJohn.Forte@Sun.COM  */
39357836SJohn.Forte@Sun.COM int
stmfGetProviderDataProt(char * providerName,nvlist_t ** nvl,int providerType,uint64_t * setToken)39367836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
39377836SJohn.Forte@Sun.COM     uint64_t *setToken)
39387836SJohn.Forte@Sun.COM {
39397836SJohn.Forte@Sun.COM 	int ret;
39407836SJohn.Forte@Sun.COM 
39417836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
39427836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39437836SJohn.Forte@Sun.COM 	}
39447836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
39457836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
39467836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39477836SJohn.Forte@Sun.COM 	}
39487836SJohn.Forte@Sun.COM 	/* call init */
39497836SJohn.Forte@Sun.COM 	ret = initializeConfig();
39507836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
39517836SJohn.Forte@Sun.COM 		return (ret);
39527836SJohn.Forte@Sun.COM 	}
39539585STim.Szeto@Sun.COM 	return (getProviderData(providerName, nvl, providerType, setToken));
39547836SJohn.Forte@Sun.COM }
39557836SJohn.Forte@Sun.COM 
39567836SJohn.Forte@Sun.COM /*
39577836SJohn.Forte@Sun.COM  * stmfGetProviderDataList
39587836SJohn.Forte@Sun.COM  *
39597836SJohn.Forte@Sun.COM  * Purpose: Get the list of providers currently persisting data
39607836SJohn.Forte@Sun.COM  *
39617836SJohn.Forte@Sun.COM  * providerList - pointer to pointer to an stmfProviderList structure allocated
39627836SJohn.Forte@Sun.COM  *                by the caller. Will contain the list of providers on success.
39637836SJohn.Forte@Sun.COM  */
39647836SJohn.Forte@Sun.COM int
stmfGetProviderDataList(stmfProviderList ** providerList)39657836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList)
39667836SJohn.Forte@Sun.COM {
39677836SJohn.Forte@Sun.COM 	int ret;
39687836SJohn.Forte@Sun.COM 
39697836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(providerList);
39707836SJohn.Forte@Sun.COM 	switch (ret) {
39717836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
39727836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
39737836SJohn.Forte@Sun.COM 			break;
39747836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
39757836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
39767836SJohn.Forte@Sun.COM 			break;
39777836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
39787836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
39797836SJohn.Forte@Sun.COM 			break;
39807836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
39817836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
39827836SJohn.Forte@Sun.COM 			break;
39837836SJohn.Forte@Sun.COM 		default:
39847836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
39857836SJohn.Forte@Sun.COM 			    "stmfGetProviderDataList:psGetProviderDataList"
39867836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
39877836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
39887836SJohn.Forte@Sun.COM 			break;
39897836SJohn.Forte@Sun.COM 	}
39907836SJohn.Forte@Sun.COM 
39917836SJohn.Forte@Sun.COM 	return (ret);
39927836SJohn.Forte@Sun.COM }
39937836SJohn.Forte@Sun.COM 
39947836SJohn.Forte@Sun.COM 
39957836SJohn.Forte@Sun.COM /*
39967836SJohn.Forte@Sun.COM  * stmfGetSessionList
39977836SJohn.Forte@Sun.COM  *
39987836SJohn.Forte@Sun.COM  * Purpose: Retrieves the session list for a target (devid)
39997836SJohn.Forte@Sun.COM  *
40007836SJohn.Forte@Sun.COM  * devid - devid of target for which to retrieve session information.
40017836SJohn.Forte@Sun.COM  * sessionList - pointer to pointer to stmfSessionList structure
40027836SJohn.Forte@Sun.COM  *             on success, this contains the list of initiator sessions.
40037836SJohn.Forte@Sun.COM  */
40047836SJohn.Forte@Sun.COM int
stmfGetSessionList(stmfDevid * devid,stmfSessionList ** sessionList)40057836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
40067836SJohn.Forte@Sun.COM {
40077836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
40087836SJohn.Forte@Sun.COM 	int fd;
40097836SJohn.Forte@Sun.COM 	int ioctlRet;
40107836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_SESSION_LIST;
40117836SJohn.Forte@Sun.COM 	int i;
40127836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
401310261SCharles.Ting@Sun.COM 	slist_scsi_session_t *fSessionList, *fSessionListP = NULL;
40147836SJohn.Forte@Sun.COM 	uint8_t ident[260];
40157836SJohn.Forte@Sun.COM 	uint32_t fSessionListSize;
40167836SJohn.Forte@Sun.COM 
40177836SJohn.Forte@Sun.COM 	if (sessionList == NULL || devid == NULL) {
40187836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
40197836SJohn.Forte@Sun.COM 	}
40207836SJohn.Forte@Sun.COM 
40217836SJohn.Forte@Sun.COM 	/* call init */
40227836SJohn.Forte@Sun.COM 	ret = initializeConfig();
40237836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
40247836SJohn.Forte@Sun.COM 		return (ret);
40257836SJohn.Forte@Sun.COM 	}
40267836SJohn.Forte@Sun.COM 
40277836SJohn.Forte@Sun.COM 	/*
40287836SJohn.Forte@Sun.COM 	 * Open control node for stmf
40297836SJohn.Forte@Sun.COM 	 */
40307836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
40317836SJohn.Forte@Sun.COM 		return (ret);
40327836SJohn.Forte@Sun.COM 
40337836SJohn.Forte@Sun.COM 	/*
40347836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
40357836SJohn.Forte@Sun.COM 	 */
40369585STim.Szeto@Sun.COM 	fSessionListSize = ALLOC_SESSION;
40377836SJohn.Forte@Sun.COM 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
40387836SJohn.Forte@Sun.COM 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
403910261SCharles.Ting@Sun.COM 	fSessionListP = fSessionList;
40407836SJohn.Forte@Sun.COM 	if (fSessionList == NULL) {
404110261SCharles.Ting@Sun.COM 		ret = STMF_ERROR_NOMEM;
404210261SCharles.Ting@Sun.COM 		goto done;
40437836SJohn.Forte@Sun.COM 	}
40447836SJohn.Forte@Sun.COM 
40457836SJohn.Forte@Sun.COM 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
40467836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
40477836SJohn.Forte@Sun.COM 	    devid->identLength);
40487836SJohn.Forte@Sun.COM 
40497836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
40507836SJohn.Forte@Sun.COM 	/*
40517836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the session list
40527836SJohn.Forte@Sun.COM 	 */
40537836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
40547836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
40557836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
40567836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fSessionListSize;
40577836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
40587836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
40597836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
40607836SJohn.Forte@Sun.COM 		switch (errno) {
40617836SJohn.Forte@Sun.COM 			case EBUSY:
40627836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
40637836SJohn.Forte@Sun.COM 				break;
40649585STim.Szeto@Sun.COM 			case EPERM:
40657836SJohn.Forte@Sun.COM 			case EACCES:
40667836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
40677836SJohn.Forte@Sun.COM 				break;
40687836SJohn.Forte@Sun.COM 			default:
40697836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
40707836SJohn.Forte@Sun.COM 				    "stmfGetSessionList:ioctl errno(%d)",
40717836SJohn.Forte@Sun.COM 				    errno);
40727836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
40737836SJohn.Forte@Sun.COM 				break;
40747836SJohn.Forte@Sun.COM 		}
40757836SJohn.Forte@Sun.COM 		goto done;
40767836SJohn.Forte@Sun.COM 	}
40777836SJohn.Forte@Sun.COM 	/*
40787836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
40797836SJohn.Forte@Sun.COM 	 */
40809585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
40817836SJohn.Forte@Sun.COM 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
40827836SJohn.Forte@Sun.COM 		    sizeof (slist_scsi_session_t);
40837836SJohn.Forte@Sun.COM 		fSessionList = realloc(fSessionList, fSessionListSize);
40847836SJohn.Forte@Sun.COM 		if (fSessionList == NULL) {
408510261SCharles.Ting@Sun.COM 			ret = STMF_ERROR_NOMEM;
408610261SCharles.Ting@Sun.COM 			goto done;
40877836SJohn.Forte@Sun.COM 		}
408810261SCharles.Ting@Sun.COM 		fSessionListP = fSessionList;
40897836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fSessionListSize;
40907836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
40917836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
40927836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
40937836SJohn.Forte@Sun.COM 			switch (errno) {
40947836SJohn.Forte@Sun.COM 				case EBUSY:
40957836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
40967836SJohn.Forte@Sun.COM 					break;
40979585STim.Szeto@Sun.COM 				case EPERM:
40987836SJohn.Forte@Sun.COM 				case EACCES:
40997836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
41007836SJohn.Forte@Sun.COM 					break;
41017836SJohn.Forte@Sun.COM 				default:
41027836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
41037836SJohn.Forte@Sun.COM 					    "stmfGetSessionList:ioctl "
41047836SJohn.Forte@Sun.COM 					    "errno(%d)", errno);
41057836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
41067836SJohn.Forte@Sun.COM 					break;
41077836SJohn.Forte@Sun.COM 			}
41087836SJohn.Forte@Sun.COM 			goto done;
41097836SJohn.Forte@Sun.COM 		}
41107836SJohn.Forte@Sun.COM 	}
41117836SJohn.Forte@Sun.COM 
41127836SJohn.Forte@Sun.COM 	/*
41137836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
41147836SJohn.Forte@Sun.COM 	 */
41157836SJohn.Forte@Sun.COM 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
41167836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
41177836SJohn.Forte@Sun.COM 	if (*sessionList == NULL) {
41187836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
41197836SJohn.Forte@Sun.COM 		free(sessionList);
41207836SJohn.Forte@Sun.COM 		goto done;
41217836SJohn.Forte@Sun.COM 	}
41227836SJohn.Forte@Sun.COM 
41237836SJohn.Forte@Sun.COM 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
41247836SJohn.Forte@Sun.COM 
41257836SJohn.Forte@Sun.COM 	/*
41267836SJohn.Forte@Sun.COM 	 * copy session info to caller's buffer
41277836SJohn.Forte@Sun.COM 	 */
41287836SJohn.Forte@Sun.COM 	for (i = 0; i < (*sessionList)->cnt; i++) {
41297836SJohn.Forte@Sun.COM 		(*sessionList)->session[i].initiator.identLength =
41307836SJohn.Forte@Sun.COM 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
41317836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
41327836SJohn.Forte@Sun.COM 		    (*sessionList)->session[i].initiator.ident,
41337836SJohn.Forte@Sun.COM 		    STMF_IDENT_LENGTH);
41347836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->alias),
41357836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].alias),
41367836SJohn.Forte@Sun.COM 		    sizeof ((*sessionList)->session[i].alias));
41377836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList++->creation_time),
41387836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].creationTime),
41397836SJohn.Forte@Sun.COM 		    sizeof (time_t));
41407836SJohn.Forte@Sun.COM 	}
41417836SJohn.Forte@Sun.COM done:
41427836SJohn.Forte@Sun.COM 	(void) close(fd);
414310261SCharles.Ting@Sun.COM 	free(fSessionListP);
41447836SJohn.Forte@Sun.COM 	return (ret);
41457836SJohn.Forte@Sun.COM }
41467836SJohn.Forte@Sun.COM 
41477836SJohn.Forte@Sun.COM /*
41487836SJohn.Forte@Sun.COM  * stmfGetTargetGroupList
41497836SJohn.Forte@Sun.COM  *
41507836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target groups
41517836SJohn.Forte@Sun.COM  *
41527836SJohn.Forte@Sun.COM  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
41537836SJohn.Forte@Sun.COM  *		     success, it contains the list of target groups.
41547836SJohn.Forte@Sun.COM  */
41557836SJohn.Forte@Sun.COM int
stmfGetTargetGroupList(stmfGroupList ** targetGroupList)41567836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList)
41577836SJohn.Forte@Sun.COM {
41587836SJohn.Forte@Sun.COM 	int ret;
41597836SJohn.Forte@Sun.COM 
41607836SJohn.Forte@Sun.COM 	if (targetGroupList == NULL) {
41617836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
41627836SJohn.Forte@Sun.COM 	}
41637836SJohn.Forte@Sun.COM 
41649585STim.Szeto@Sun.COM 	ret = groupListIoctl(targetGroupList, TARGET_GROUP);
41657836SJohn.Forte@Sun.COM 	return (ret);
41667836SJohn.Forte@Sun.COM }
41677836SJohn.Forte@Sun.COM 
41687836SJohn.Forte@Sun.COM /*
41697836SJohn.Forte@Sun.COM  * stmfGetTargetGroupMembers
41707836SJohn.Forte@Sun.COM  *
41717836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group members for a target group
41727836SJohn.Forte@Sun.COM  *
41737836SJohn.Forte@Sun.COM  * groupName - name of target group for which to retrieve members.
41747836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
41757836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
41767836SJohn.Forte@Sun.COM  */
41777836SJohn.Forte@Sun.COM int
stmfGetTargetGroupMembers(stmfGroupName * groupName,stmfGroupProperties ** groupProp)41787836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName,
41797836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
41807836SJohn.Forte@Sun.COM {
41817836SJohn.Forte@Sun.COM 	int ret;
41827836SJohn.Forte@Sun.COM 
41837836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
41847836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
41857836SJohn.Forte@Sun.COM 	}
41867836SJohn.Forte@Sun.COM 
41879585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
41887836SJohn.Forte@Sun.COM 
41897836SJohn.Forte@Sun.COM 	return (ret);
41907836SJohn.Forte@Sun.COM }
41917836SJohn.Forte@Sun.COM 
41927836SJohn.Forte@Sun.COM /*
41937836SJohn.Forte@Sun.COM  * stmfGetTargetList
41947836SJohn.Forte@Sun.COM  *
41957836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target ports
41967836SJohn.Forte@Sun.COM  *
41977836SJohn.Forte@Sun.COM  * targetList - pointer to a pointer to an stmfDevidList structure.
41987836SJohn.Forte@Sun.COM  *		    On success, it contains the list of local ports (target).
41997836SJohn.Forte@Sun.COM  */
42007836SJohn.Forte@Sun.COM int
stmfGetTargetList(stmfDevidList ** targetList)42017836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList)
42027836SJohn.Forte@Sun.COM {
42037836SJohn.Forte@Sun.COM 	int ret;
42047836SJohn.Forte@Sun.COM 	int fd;
42057836SJohn.Forte@Sun.COM 	int ioctlRet;
42067836SJohn.Forte@Sun.COM 	int i;
42077836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
42087836SJohn.Forte@Sun.COM 	/* framework target port list */
42099585STim.Szeto@Sun.COM 	slist_target_port_t *fTargetList, *fTargetListP = NULL;
42107836SJohn.Forte@Sun.COM 	uint32_t fTargetListSize;
42117836SJohn.Forte@Sun.COM 
42127836SJohn.Forte@Sun.COM 	if (targetList == NULL) {
42137836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
42147836SJohn.Forte@Sun.COM 	}
42157836SJohn.Forte@Sun.COM 
42167836SJohn.Forte@Sun.COM 	/* call init */
42177836SJohn.Forte@Sun.COM 	ret = initializeConfig();
42187836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
42197836SJohn.Forte@Sun.COM 		return (ret);
42207836SJohn.Forte@Sun.COM 	}
42217836SJohn.Forte@Sun.COM 
42227836SJohn.Forte@Sun.COM 	/*
42237836SJohn.Forte@Sun.COM 	 * Open control node for stmf
42247836SJohn.Forte@Sun.COM 	 */
42257836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
42267836SJohn.Forte@Sun.COM 		return (ret);
42277836SJohn.Forte@Sun.COM 
42287836SJohn.Forte@Sun.COM 	/*
42297836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
42307836SJohn.Forte@Sun.COM 	 */
42319585STim.Szeto@Sun.COM 	fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
42328252SJohn.Forte@Sun.COM 	fTargetListP = fTargetList =
42338252SJohn.Forte@Sun.COM 	    (slist_target_port_t *)calloc(1, fTargetListSize);
42347836SJohn.Forte@Sun.COM 	if (fTargetList == NULL) {
42359585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
42367836SJohn.Forte@Sun.COM 		goto done;
42377836SJohn.Forte@Sun.COM 	}
42387836SJohn.Forte@Sun.COM 
42397836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
42407836SJohn.Forte@Sun.COM 	/*
42418252SJohn.Forte@Sun.COM 	 * Issue ioctl to retrieve target list
42427836SJohn.Forte@Sun.COM 	 */
42437836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
42447836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fTargetListSize;
42457836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
42467836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
42477836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
42487836SJohn.Forte@Sun.COM 		switch (errno) {
42497836SJohn.Forte@Sun.COM 			case EBUSY:
42507836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
42517836SJohn.Forte@Sun.COM 				break;
42529585STim.Szeto@Sun.COM 			case EPERM:
42537836SJohn.Forte@Sun.COM 			case EACCES:
42547836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
42557836SJohn.Forte@Sun.COM 				break;
42567836SJohn.Forte@Sun.COM 			default:
42577836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
42587836SJohn.Forte@Sun.COM 				    "stmfGetTargetList:ioctl errno(%d)", errno);
42597836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
42607836SJohn.Forte@Sun.COM 				break;
42617836SJohn.Forte@Sun.COM 		}
42627836SJohn.Forte@Sun.COM 		goto done;
42637836SJohn.Forte@Sun.COM 	}
42647836SJohn.Forte@Sun.COM 	/*
42657836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
42667836SJohn.Forte@Sun.COM 	 */
42679585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
42687836SJohn.Forte@Sun.COM 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
42698116SJohn.Forte@Sun.COM 		    sizeof (slist_target_port_t);
42708252SJohn.Forte@Sun.COM 		fTargetListP = fTargetList =
42718252SJohn.Forte@Sun.COM 		    realloc(fTargetList, fTargetListSize);
42727836SJohn.Forte@Sun.COM 		if (fTargetList == NULL) {
42739585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
42749585STim.Szeto@Sun.COM 			goto done;
42757836SJohn.Forte@Sun.COM 		}
42767836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fTargetListSize;
42777836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
42787836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
42797836SJohn.Forte@Sun.COM 		    &stmfIoctl);
42807836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
42817836SJohn.Forte@Sun.COM 			switch (errno) {
42827836SJohn.Forte@Sun.COM 				case EBUSY:
42837836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
42847836SJohn.Forte@Sun.COM 					break;
42859585STim.Szeto@Sun.COM 				case EPERM:
42867836SJohn.Forte@Sun.COM 				case EACCES:
42877836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
42887836SJohn.Forte@Sun.COM 					break;
42897836SJohn.Forte@Sun.COM 				default:
42907836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
42917836SJohn.Forte@Sun.COM 					    "stmfGetTargetList:ioctl errno(%d)",
42927836SJohn.Forte@Sun.COM 					    errno);
42937836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
42947836SJohn.Forte@Sun.COM 					break;
42957836SJohn.Forte@Sun.COM 			}
42967836SJohn.Forte@Sun.COM 			goto done;
42977836SJohn.Forte@Sun.COM 		}
42987836SJohn.Forte@Sun.COM 	}
42997836SJohn.Forte@Sun.COM 
43007836SJohn.Forte@Sun.COM 	*targetList = (stmfDevidList *)calloc(1,
43017836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
43027836SJohn.Forte@Sun.COM 	    sizeof (stmfDevidList));
43039585STim.Szeto@Sun.COM 	if (*targetList == NULL) {
43049585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
43059585STim.Szeto@Sun.COM 		goto done;
43069585STim.Szeto@Sun.COM 	}
43077836SJohn.Forte@Sun.COM 
43087836SJohn.Forte@Sun.COM 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
43097836SJohn.Forte@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
43107836SJohn.Forte@Sun.COM 		(*targetList)->devid[i].identLength =
43117836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE];
43127836SJohn.Forte@Sun.COM 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
43137836SJohn.Forte@Sun.COM 		    &(*targetList)->devid[i].ident,
43147836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE]);
43157836SJohn.Forte@Sun.COM 	}
43167836SJohn.Forte@Sun.COM 
43177836SJohn.Forte@Sun.COM done:
43187836SJohn.Forte@Sun.COM 	(void) close(fd);
43198252SJohn.Forte@Sun.COM 	free(fTargetListP);
43207836SJohn.Forte@Sun.COM 	return (ret);
43217836SJohn.Forte@Sun.COM }
43227836SJohn.Forte@Sun.COM 
43237836SJohn.Forte@Sun.COM /*
43247836SJohn.Forte@Sun.COM  * stmfGetTargetProperties
43257836SJohn.Forte@Sun.COM  *
43267836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
43277836SJohn.Forte@Sun.COM  *
43287836SJohn.Forte@Sun.COM  * devid - devid of the target for which to retrieve properties
43297836SJohn.Forte@Sun.COM  * targetProps - pointer to an stmfTargetProperties structure.
43307836SJohn.Forte@Sun.COM  *		On success, it contains the target properties for
43317836SJohn.Forte@Sun.COM  *		the specified devid.
43327836SJohn.Forte@Sun.COM  */
43337836SJohn.Forte@Sun.COM int
stmfGetTargetProperties(stmfDevid * devid,stmfTargetProperties * targetProps)43347836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
43357836SJohn.Forte@Sun.COM {
43367836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
43377836SJohn.Forte@Sun.COM 	int fd;
43387836SJohn.Forte@Sun.COM 	int ioctlRet;
43397836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
43407836SJohn.Forte@Sun.COM 	sioc_target_port_props_t targetProperties;
434110725SJohn.Forte@Sun.COM 	scsi_devid_desc_t *scsiDevid;
43427836SJohn.Forte@Sun.COM 
43437836SJohn.Forte@Sun.COM 	if (devid == NULL || targetProps == NULL) {
43447836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
43457836SJohn.Forte@Sun.COM 	}
43467836SJohn.Forte@Sun.COM 
43477836SJohn.Forte@Sun.COM 	/* call init */
43487836SJohn.Forte@Sun.COM 	ret = initializeConfig();
43497836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
43507836SJohn.Forte@Sun.COM 		return (ret);
43517836SJohn.Forte@Sun.COM 	}
43527836SJohn.Forte@Sun.COM 
43537836SJohn.Forte@Sun.COM 	/*
43547836SJohn.Forte@Sun.COM 	 * Open control node for stmf
43557836SJohn.Forte@Sun.COM 	 */
43567836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
43577836SJohn.Forte@Sun.COM 		return (ret);
43587836SJohn.Forte@Sun.COM 
43597836SJohn.Forte@Sun.COM 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
43607836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
43617836SJohn.Forte@Sun.COM 	    devid->identLength);
43627836SJohn.Forte@Sun.COM 
43637836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
43647836SJohn.Forte@Sun.COM 	/*
43657836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
43667836SJohn.Forte@Sun.COM 	 */
43677836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
43687836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
43697836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
43707836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
43717836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
43727836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
43737836SJohn.Forte@Sun.COM 	    &stmfIoctl);
43747836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
43757836SJohn.Forte@Sun.COM 		switch (errno) {
43767836SJohn.Forte@Sun.COM 			case EBUSY:
43777836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
43787836SJohn.Forte@Sun.COM 				break;
43799585STim.Szeto@Sun.COM 			case EPERM:
43807836SJohn.Forte@Sun.COM 			case EACCES:
43817836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
43827836SJohn.Forte@Sun.COM 				break;
43837836SJohn.Forte@Sun.COM 			case ENOENT:
43847836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
43857836SJohn.Forte@Sun.COM 				break;
43867836SJohn.Forte@Sun.COM 			default:
43877836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
43887836SJohn.Forte@Sun.COM 				    "stmfGetTargetProperties:ioctl errno(%d)",
43897836SJohn.Forte@Sun.COM 				    errno);
43907836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
43917836SJohn.Forte@Sun.COM 				break;
43927836SJohn.Forte@Sun.COM 		}
43937836SJohn.Forte@Sun.COM 		goto done;
43947836SJohn.Forte@Sun.COM 	}
43957836SJohn.Forte@Sun.COM 
43967836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
43977836SJohn.Forte@Sun.COM 	    sizeof (targetProperties.tgt_provider_name));
43987836SJohn.Forte@Sun.COM 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
43997836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINE;
44007836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
44017836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
44027836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
44037836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINING;
44047836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
44057836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
44067836SJohn.Forte@Sun.COM 	}
44077836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_alias, targetProps->alias,
44087836SJohn.Forte@Sun.COM 	    sizeof (targetProps->alias));
440910725SJohn.Forte@Sun.COM 
441010725SJohn.Forte@Sun.COM 	scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id;
441110725SJohn.Forte@Sun.COM 	targetProps->protocol = scsiDevid->protocol_id;
441210725SJohn.Forte@Sun.COM 
44137836SJohn.Forte@Sun.COM done:
44147836SJohn.Forte@Sun.COM 	(void) close(fd);
44157836SJohn.Forte@Sun.COM 	return (ret);
44167836SJohn.Forte@Sun.COM }
44177836SJohn.Forte@Sun.COM 
44187836SJohn.Forte@Sun.COM /*
44197836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitList
44207836SJohn.Forte@Sun.COM  *
44217836SJohn.Forte@Sun.COM  * Purpose: Retrieves list of logical unit Object IDs
44227836SJohn.Forte@Sun.COM  *
44237836SJohn.Forte@Sun.COM  * luList - pointer to a pointer to a stmfGuidList structure. On success,
44247836SJohn.Forte@Sun.COM  *          it contains the list of logical unit guids.
44257836SJohn.Forte@Sun.COM  *
44267836SJohn.Forte@Sun.COM  */
44277836SJohn.Forte@Sun.COM int
stmfGetLogicalUnitList(stmfGuidList ** luList)44287836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList)
44297836SJohn.Forte@Sun.COM {
44307836SJohn.Forte@Sun.COM 	int ret;
44317836SJohn.Forte@Sun.COM 	int fd;
44327836SJohn.Forte@Sun.COM 	int ioctlRet;
44337836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_LU_LIST;
44349585STim.Szeto@Sun.COM 	int i;
44357836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
44367836SJohn.Forte@Sun.COM 	slist_lu_t *fLuList;
44377836SJohn.Forte@Sun.COM 	uint32_t fLuListSize;
44389585STim.Szeto@Sun.COM 	uint32_t listCnt;
44397836SJohn.Forte@Sun.COM 
44407836SJohn.Forte@Sun.COM 	if (luList == NULL) {
44417836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
44427836SJohn.Forte@Sun.COM 	}
44437836SJohn.Forte@Sun.COM 
44447836SJohn.Forte@Sun.COM 	/* call init */
44457836SJohn.Forte@Sun.COM 	ret = initializeConfig();
44467836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
44477836SJohn.Forte@Sun.COM 		return (ret);
44487836SJohn.Forte@Sun.COM 	}
44497836SJohn.Forte@Sun.COM 
44507836SJohn.Forte@Sun.COM 	/*
44517836SJohn.Forte@Sun.COM 	 * Open control node for stmf
44527836SJohn.Forte@Sun.COM 	 */
44537836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
44547836SJohn.Forte@Sun.COM 		return (ret);
44557836SJohn.Forte@Sun.COM 
44567836SJohn.Forte@Sun.COM 	/*
44577836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
44587836SJohn.Forte@Sun.COM 	 */
44599585STim.Szeto@Sun.COM 	fLuListSize = ALLOC_LU;
44607836SJohn.Forte@Sun.COM 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
44617836SJohn.Forte@Sun.COM 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
44627836SJohn.Forte@Sun.COM 	if (fLuList == NULL) {
44639585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
44649585STim.Szeto@Sun.COM 		goto done;
44657836SJohn.Forte@Sun.COM 	}
44667836SJohn.Forte@Sun.COM 
44677836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
44687836SJohn.Forte@Sun.COM 	/*
44697836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the LU list
44707836SJohn.Forte@Sun.COM 	 */
44717836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
44727836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fLuListSize;
44737836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
44747836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
44757836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
44767836SJohn.Forte@Sun.COM 		switch (errno) {
44777836SJohn.Forte@Sun.COM 			case EBUSY:
44787836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
44797836SJohn.Forte@Sun.COM 				break;
44809585STim.Szeto@Sun.COM 			case EPERM:
44817836SJohn.Forte@Sun.COM 			case EACCES:
44827836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
44837836SJohn.Forte@Sun.COM 				break;
44847836SJohn.Forte@Sun.COM 			default:
44857836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
44867836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
44877836SJohn.Forte@Sun.COM 				    errno);
44887836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
44897836SJohn.Forte@Sun.COM 				break;
44907836SJohn.Forte@Sun.COM 		}
44917836SJohn.Forte@Sun.COM 		goto done;
44927836SJohn.Forte@Sun.COM 	}
44937836SJohn.Forte@Sun.COM 	/*
44947836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
44957836SJohn.Forte@Sun.COM 	 */
44969585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
44977836SJohn.Forte@Sun.COM 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
44987836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
44999585STim.Szeto@Sun.COM 		free(fLuList);
45009585STim.Szeto@Sun.COM 		fLuList = (slist_lu_t *)calloc(1, fLuListSize);
45017836SJohn.Forte@Sun.COM 		if (fLuList == NULL) {
45029585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
45039585STim.Szeto@Sun.COM 			goto done;
45047836SJohn.Forte@Sun.COM 		}
45057836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fLuListSize;
45067836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
45077836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
45087836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
45097836SJohn.Forte@Sun.COM 			switch (errno) {
45107836SJohn.Forte@Sun.COM 				case EBUSY:
45117836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
45127836SJohn.Forte@Sun.COM 					break;
45139585STim.Szeto@Sun.COM 				case EPERM:
45147836SJohn.Forte@Sun.COM 				case EACCES:
45157836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
45167836SJohn.Forte@Sun.COM 					break;
45177836SJohn.Forte@Sun.COM 				default:
45187836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
45197836SJohn.Forte@Sun.COM 					    "stmfGetLogicalUnitList:"
45207836SJohn.Forte@Sun.COM 					    "ioctl errno(%d)", errno);
45217836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
45227836SJohn.Forte@Sun.COM 					break;
45237836SJohn.Forte@Sun.COM 			}
45247836SJohn.Forte@Sun.COM 			goto done;
45257836SJohn.Forte@Sun.COM 		}
45267836SJohn.Forte@Sun.COM 	}
45277836SJohn.Forte@Sun.COM 
45287836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
45297836SJohn.Forte@Sun.COM 		goto done;
45307836SJohn.Forte@Sun.COM 	}
45317836SJohn.Forte@Sun.COM 
45329585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
45337836SJohn.Forte@Sun.COM 
45347836SJohn.Forte@Sun.COM 	/*
45357836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
45367836SJohn.Forte@Sun.COM 	 */
45377836SJohn.Forte@Sun.COM 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
45389585STim.Szeto@Sun.COM 	    listCnt * sizeof (stmfGuid));
45397836SJohn.Forte@Sun.COM 	if (*luList == NULL) {
45407836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
45417836SJohn.Forte@Sun.COM 		goto done;
45427836SJohn.Forte@Sun.COM 	}
45437836SJohn.Forte@Sun.COM 
45449585STim.Szeto@Sun.COM 	(*luList)->cnt = listCnt;
45459585STim.Szeto@Sun.COM 
45469585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
45479585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
45489585STim.Szeto@Sun.COM 		bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
45499585STim.Szeto@Sun.COM 		    sizeof (stmfGuid));
45509585STim.Szeto@Sun.COM 	}
45519585STim.Szeto@Sun.COM 
45527836SJohn.Forte@Sun.COM 	/*
45539585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
45547836SJohn.Forte@Sun.COM 	 */
45559585STim.Szeto@Sun.COM 	qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
45569585STim.Szeto@Sun.COM 	    sizeof (stmfGuid), guidCompare);
45577836SJohn.Forte@Sun.COM 
45587836SJohn.Forte@Sun.COM done:
45597836SJohn.Forte@Sun.COM 	(void) close(fd);
45607836SJohn.Forte@Sun.COM 	/*
45617836SJohn.Forte@Sun.COM 	 * free internal buffers
45627836SJohn.Forte@Sun.COM 	 */
45637836SJohn.Forte@Sun.COM 	free(fLuList);
45647836SJohn.Forte@Sun.COM 	return (ret);
45657836SJohn.Forte@Sun.COM }
45667836SJohn.Forte@Sun.COM 
45677836SJohn.Forte@Sun.COM /*
45687836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitProperties
45697836SJohn.Forte@Sun.COM  *
45707836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
45717836SJohn.Forte@Sun.COM  *
45727836SJohn.Forte@Sun.COM  * lu - guid of the logical unit for which to retrieve properties
45737836SJohn.Forte@Sun.COM  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
45747836SJohn.Forte@Sun.COM  *               it contains the logical unit properties for the specified guid.
45757836SJohn.Forte@Sun.COM  */
45767836SJohn.Forte@Sun.COM int
stmfGetLogicalUnitProperties(stmfGuid * lu,stmfLogicalUnitProperties * luProps)45777836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
45787836SJohn.Forte@Sun.COM {
45797836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
45807836SJohn.Forte@Sun.COM 	int stmfRet;
45817836SJohn.Forte@Sun.COM 	int fd;
45827836SJohn.Forte@Sun.COM 	int ioctlRet;
45837836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
45847836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
45857836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
45867836SJohn.Forte@Sun.COM 	sioc_lu_props_t fLuProps;
45877836SJohn.Forte@Sun.COM 
45889585STim.Szeto@Sun.COM 	if (lu == NULL || luProps == NULL) {
45899585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
45907836SJohn.Forte@Sun.COM 	}
45917836SJohn.Forte@Sun.COM 
45927836SJohn.Forte@Sun.COM 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
45937836SJohn.Forte@Sun.COM 
45947836SJohn.Forte@Sun.COM 	/* call init */
45957836SJohn.Forte@Sun.COM 	ret = initializeConfig();
45967836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
45977836SJohn.Forte@Sun.COM 		return (ret);
45987836SJohn.Forte@Sun.COM 	}
45997836SJohn.Forte@Sun.COM 
46007836SJohn.Forte@Sun.COM 	/*
46017836SJohn.Forte@Sun.COM 	 * Open control node for stmf
46027836SJohn.Forte@Sun.COM 	 */
46037836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
46047836SJohn.Forte@Sun.COM 		return (ret);
46057836SJohn.Forte@Sun.COM 
46067836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
46077836SJohn.Forte@Sun.COM 	/*
46087836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
46097836SJohn.Forte@Sun.COM 	 */
46107836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
46117836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
46127836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
46137836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
46147836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
46157836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
46167836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
46177836SJohn.Forte@Sun.COM 		switch (errno) {
46187836SJohn.Forte@Sun.COM 			case EBUSY:
46197836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
46207836SJohn.Forte@Sun.COM 				break;
46219585STim.Szeto@Sun.COM 			case EPERM:
46227836SJohn.Forte@Sun.COM 			case EACCES:
46237836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
46247836SJohn.Forte@Sun.COM 				break;
46257836SJohn.Forte@Sun.COM 			case ENOENT:
46267836SJohn.Forte@Sun.COM 				stmfRet = stmfGetViewEntryList(lu,
46277836SJohn.Forte@Sun.COM 				    &viewEntryList);
46287836SJohn.Forte@Sun.COM 				if (stmfRet == STMF_STATUS_SUCCESS) {
46297836SJohn.Forte@Sun.COM 					luProps->status =
46307836SJohn.Forte@Sun.COM 					    STMF_LOGICAL_UNIT_UNREGISTERED;
46317836SJohn.Forte@Sun.COM 					if (viewEntryList->cnt > 0) {
46327836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_SUCCESS;
46337836SJohn.Forte@Sun.COM 					} else {
46347836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
46357836SJohn.Forte@Sun.COM 					}
46367836SJohn.Forte@Sun.COM 				} else {
46377836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
46387836SJohn.Forte@Sun.COM 				}
46397836SJohn.Forte@Sun.COM 				stmfFreeMemory(viewEntryList);
46407836SJohn.Forte@Sun.COM 				break;
46417836SJohn.Forte@Sun.COM 			default:
46427836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
46437836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnit:ioctl errno(%d)",
46447836SJohn.Forte@Sun.COM 				    errno);
46457836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
46467836SJohn.Forte@Sun.COM 				break;
46477836SJohn.Forte@Sun.COM 		}
46487836SJohn.Forte@Sun.COM 		goto done;
46497836SJohn.Forte@Sun.COM 	}
46507836SJohn.Forte@Sun.COM 
46517836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
46527836SJohn.Forte@Sun.COM 	    sizeof (fLuProps.lu_provider_name));
46537836SJohn.Forte@Sun.COM 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
46547836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
46557836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
46567836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
46577836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
46587836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
46597836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
46607836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
46617836SJohn.Forte@Sun.COM 	}
46627836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
46637836SJohn.Forte@Sun.COM done:
46647836SJohn.Forte@Sun.COM 	(void) close(fd);
46657836SJohn.Forte@Sun.COM 	return (ret);
46667836SJohn.Forte@Sun.COM }
46677836SJohn.Forte@Sun.COM 
46687836SJohn.Forte@Sun.COM /*
46697836SJohn.Forte@Sun.COM  * stmfGetState
46707836SJohn.Forte@Sun.COM  *
46717836SJohn.Forte@Sun.COM  * Purpose: retrieve the current state of the stmf module
46727836SJohn.Forte@Sun.COM  *
46737836SJohn.Forte@Sun.COM  * state - pointer to stmfState structure allocated by the caller
46747836SJohn.Forte@Sun.COM  *         On success, contains the state of stmf
46757836SJohn.Forte@Sun.COM  */
46767836SJohn.Forte@Sun.COM int
stmfGetState(stmfState * state)46777836SJohn.Forte@Sun.COM stmfGetState(stmfState *state)
46787836SJohn.Forte@Sun.COM {
46797836SJohn.Forte@Sun.COM 	int ret;
46807836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
46817836SJohn.Forte@Sun.COM 
46827836SJohn.Forte@Sun.COM 	if (state == NULL) {
46837836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
46847836SJohn.Forte@Sun.COM 	}
46857836SJohn.Forte@Sun.COM 
46867836SJohn.Forte@Sun.COM 	ret = getStmfState(&iState);
46877836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
46887836SJohn.Forte@Sun.COM 		return (ret);
46897836SJohn.Forte@Sun.COM 	}
46907836SJohn.Forte@Sun.COM 	switch (iState.state) {
46917836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINE:
46927836SJohn.Forte@Sun.COM 			state->operationalState =
46937836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINE;
46947836SJohn.Forte@Sun.COM 			break;
46957836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINE:
46967836SJohn.Forte@Sun.COM 			state->operationalState =
46977836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINE;
46987836SJohn.Forte@Sun.COM 			break;
46997836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINING:
47007836SJohn.Forte@Sun.COM 			state->operationalState =
47017836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINING;
47027836SJohn.Forte@Sun.COM 			break;
47037836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINING:
47047836SJohn.Forte@Sun.COM 			state->operationalState =
47057836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINING;
47067836SJohn.Forte@Sun.COM 			break;
47077836SJohn.Forte@Sun.COM 		default:
47087836SJohn.Forte@Sun.COM 			state->operationalState =
47097836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_UNKNOWN;
47107836SJohn.Forte@Sun.COM 			break;
47117836SJohn.Forte@Sun.COM 	}
47127836SJohn.Forte@Sun.COM 	switch (iState.config_state) {
47137836SJohn.Forte@Sun.COM 		case STMF_CONFIG_NONE:
47147836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_NONE;
47157836SJohn.Forte@Sun.COM 			break;
47167836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT:
47177836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_INIT;
47187836SJohn.Forte@Sun.COM 			break;
47197836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT_DONE:
47207836SJohn.Forte@Sun.COM 			state->configState =
47217836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_INIT_DONE;
47227836SJohn.Forte@Sun.COM 			break;
47237836SJohn.Forte@Sun.COM 		default:
47247836SJohn.Forte@Sun.COM 			state->configState =
47257836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_UNKNOWN;
47267836SJohn.Forte@Sun.COM 			break;
47277836SJohn.Forte@Sun.COM 	}
47287836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
47297836SJohn.Forte@Sun.COM }
47307836SJohn.Forte@Sun.COM 
47317836SJohn.Forte@Sun.COM /*
47327836SJohn.Forte@Sun.COM  * stmfGetViewEntryList
47337836SJohn.Forte@Sun.COM  *
47347836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of view entries for the specified
47357836SJohn.Forte@Sun.COM  *          logical unit.
47367836SJohn.Forte@Sun.COM  *
47377836SJohn.Forte@Sun.COM  * lu - the guid of the logical unit for which to retrieve the view entry list
47387836SJohn.Forte@Sun.COM  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
47397836SJohn.Forte@Sun.COM  *                 success, contains the list of view entries.
47407836SJohn.Forte@Sun.COM  */
47417836SJohn.Forte@Sun.COM int
stmfGetViewEntryList(stmfGuid * lu,stmfViewEntryList ** viewEntryList)47427836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
47437836SJohn.Forte@Sun.COM {
47447836SJohn.Forte@Sun.COM 	int ret;
47459585STim.Szeto@Sun.COM 	int fd;
47469585STim.Szeto@Sun.COM 	int ioctlRet;
47479585STim.Szeto@Sun.COM 	int cmd = STMF_IOCTL_LU_VE_LIST;
47489585STim.Szeto@Sun.COM 	int i;
47499585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
47509585STim.Szeto@Sun.COM 	stmf_view_op_entry_t *fVeList;
47519585STim.Szeto@Sun.COM 	uint32_t fVeListSize;
47529585STim.Szeto@Sun.COM 	uint32_t listCnt;
47537836SJohn.Forte@Sun.COM 
47547836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntryList == NULL) {
47557836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
47567836SJohn.Forte@Sun.COM 	}
47577836SJohn.Forte@Sun.COM 
47589585STim.Szeto@Sun.COM 	/* call init */
47599585STim.Szeto@Sun.COM 	ret = initializeConfig();
47609585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47619585STim.Szeto@Sun.COM 		return (ret);
47629585STim.Szeto@Sun.COM 	}
47639585STim.Szeto@Sun.COM 
47649585STim.Szeto@Sun.COM 	/*
47659585STim.Szeto@Sun.COM 	 * Open control node for stmf
47669585STim.Szeto@Sun.COM 	 */
47679585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
47689585STim.Szeto@Sun.COM 		return (ret);
47699585STim.Szeto@Sun.COM 
47709585STim.Szeto@Sun.COM 	/*
47719585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
47729585STim.Szeto@Sun.COM 	 */
47739585STim.Szeto@Sun.COM 	fVeListSize = ALLOC_VE;
47749585STim.Szeto@Sun.COM 	fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
47759585STim.Szeto@Sun.COM 	fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
47769585STim.Szeto@Sun.COM 	if (fVeList == NULL) {
47779585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
47789585STim.Szeto@Sun.COM 		goto done;
47799585STim.Szeto@Sun.COM 	}
47809585STim.Szeto@Sun.COM 
47819585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
47829585STim.Szeto@Sun.COM 	/*
47839585STim.Szeto@Sun.COM 	 * Issue ioctl to get the LU list
47849585STim.Szeto@Sun.COM 	 */
47859585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
47869585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
47879585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
47889585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = fVeListSize;
47899585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
47909585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
47919585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
47929585STim.Szeto@Sun.COM 		switch (errno) {
47939585STim.Szeto@Sun.COM 			case EBUSY:
47949585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
47959585STim.Szeto@Sun.COM 				break;
47969585STim.Szeto@Sun.COM 			case EPERM:
47979585STim.Szeto@Sun.COM 			case EACCES:
47989585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
47999585STim.Szeto@Sun.COM 				break;
48009585STim.Szeto@Sun.COM 			default:
48019585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
48029585STim.Szeto@Sun.COM 				    "stmfGetViewEntryList:ioctl errno(%d)",
48039585STim.Szeto@Sun.COM 				    errno);
48049585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
48059585STim.Szeto@Sun.COM 				break;
48069585STim.Szeto@Sun.COM 		}
48079585STim.Szeto@Sun.COM 		goto done;
48089585STim.Szeto@Sun.COM 	}
48099585STim.Szeto@Sun.COM 	/*
48109585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
48119585STim.Szeto@Sun.COM 	 */
48129585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
48139585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
48149585STim.Szeto@Sun.COM 		fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
48159585STim.Szeto@Sun.COM 		    sizeof (stmf_view_op_entry_t);
48169585STim.Szeto@Sun.COM 		free(fVeList);
48179585STim.Szeto@Sun.COM 		fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
48189585STim.Szeto@Sun.COM 		if (fVeList == NULL) {
48199585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOMEM);
48209585STim.Szeto@Sun.COM 		}
48219585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = fVeListSize;
48229585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
48239585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
48249585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
48259585STim.Szeto@Sun.COM 			switch (errno) {
48269585STim.Szeto@Sun.COM 				case EBUSY:
48279585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
48289585STim.Szeto@Sun.COM 					break;
48299585STim.Szeto@Sun.COM 				case EPERM:
48309585STim.Szeto@Sun.COM 				case EACCES:
48319585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
48329585STim.Szeto@Sun.COM 					break;
48339585STim.Szeto@Sun.COM 				default:
48349585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
48359585STim.Szeto@Sun.COM 					    "stmfGetLogicalUnitList:"
48369585STim.Szeto@Sun.COM 					    "ioctl errno(%d)", errno);
48379585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
48389585STim.Szeto@Sun.COM 					break;
48399585STim.Szeto@Sun.COM 			}
48409585STim.Szeto@Sun.COM 			goto done;
48419585STim.Szeto@Sun.COM 		}
48429585STim.Szeto@Sun.COM 	}
48439585STim.Szeto@Sun.COM 
48449585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
48459585STim.Szeto@Sun.COM 		goto done;
48469585STim.Szeto@Sun.COM 	}
48479585STim.Szeto@Sun.COM 
48489585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
48499585STim.Szeto@Sun.COM 
48509585STim.Szeto@Sun.COM 	/*
48519585STim.Szeto@Sun.COM 	 * allocate caller's buffer with the final size
48529585STim.Szeto@Sun.COM 	 */
48539585STim.Szeto@Sun.COM 	*viewEntryList = (stmfViewEntryList *)calloc(1,
48549585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
48559585STim.Szeto@Sun.COM 	if (*viewEntryList == NULL) {
48569585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
48579585STim.Szeto@Sun.COM 		goto done;
48589585STim.Szeto@Sun.COM 	}
48599585STim.Szeto@Sun.COM 
48609585STim.Szeto@Sun.COM 	(*viewEntryList)->cnt = listCnt;
48619585STim.Szeto@Sun.COM 
48629585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
48639585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
48649585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndexValid = B_TRUE;
48659585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
48669585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_hosts == 1) {
48679585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allHosts = B_TRUE;
48689585STim.Szeto@Sun.COM 		} else {
48699585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_host_group.name,
48709585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].hostGroup,
48719585STim.Szeto@Sun.COM 			    fVeList[i].ve_host_group.name_size);
48729585STim.Szeto@Sun.COM 		}
48739585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_targets == 1) {
48749585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allTargets = B_TRUE;
48759585STim.Szeto@Sun.COM 		} else {
48769585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_target_group.name,
48779585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].targetGroup,
48789585STim.Szeto@Sun.COM 			    fVeList[i].ve_target_group.name_size);
48799585STim.Szeto@Sun.COM 		}
48809585STim.Szeto@Sun.COM 		bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
48819585STim.Szeto@Sun.COM 		    sizeof ((*viewEntryList)->ve[i].luNbr));
48829585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].luNbrValid = B_TRUE;
48839585STim.Szeto@Sun.COM 	}
48849585STim.Szeto@Sun.COM 
48859585STim.Szeto@Sun.COM 	/*
48869585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
48879585STim.Szeto@Sun.COM 	 */
48889585STim.Szeto@Sun.COM 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
48899585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntry), viewEntryCompare);
48909585STim.Szeto@Sun.COM 
48919585STim.Szeto@Sun.COM done:
48929585STim.Szeto@Sun.COM 	(void) close(fd);
48939585STim.Szeto@Sun.COM 	/*
48949585STim.Szeto@Sun.COM 	 * free internal buffers
48959585STim.Szeto@Sun.COM 	 */
48969585STim.Szeto@Sun.COM 	free(fVeList);
48977836SJohn.Forte@Sun.COM 	return (ret);
48987836SJohn.Forte@Sun.COM }
48997836SJohn.Forte@Sun.COM 
49009585STim.Szeto@Sun.COM 
49017836SJohn.Forte@Sun.COM /*
49027836SJohn.Forte@Sun.COM  * loadHostGroups
49037836SJohn.Forte@Sun.COM  *
49047836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the host groups into stmf
49057836SJohn.Forte@Sun.COM  *
49067836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
49077836SJohn.Forte@Sun.COM  * groupList - populated host group list
49087836SJohn.Forte@Sun.COM  */
49097836SJohn.Forte@Sun.COM static int
loadHostGroups(int fd,stmfGroupList * groupList)49107836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList)
49117836SJohn.Forte@Sun.COM {
49127836SJohn.Forte@Sun.COM 	int i, j;
49137836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
49147836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
49157836SJohn.Forte@Sun.COM 
49167836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
49177836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
49187836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
49197836SJohn.Forte@Sun.COM 			goto out;
49207836SJohn.Forte@Sun.COM 		}
49219585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
49229585STim.Szeto@Sun.COM 		    &groupProps, HOST_GROUP);
49237836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
49247836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
49257836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
49267836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
49277836SJohn.Forte@Sun.COM 				goto out;
49287836SJohn.Forte@Sun.COM 			}
49297836SJohn.Forte@Sun.COM 		}
49307836SJohn.Forte@Sun.COM 	}
49317836SJohn.Forte@Sun.COM 
49327836SJohn.Forte@Sun.COM 
49337836SJohn.Forte@Sun.COM out:
49347836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
49357836SJohn.Forte@Sun.COM 	return (ret);
49367836SJohn.Forte@Sun.COM }
49377836SJohn.Forte@Sun.COM 
49387836SJohn.Forte@Sun.COM /*
49397836SJohn.Forte@Sun.COM  * loadTargetGroups
49407836SJohn.Forte@Sun.COM  *
49417836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the target groups into stmf
49427836SJohn.Forte@Sun.COM  *
49437836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
49447836SJohn.Forte@Sun.COM  * groupList - populated target group list.
49457836SJohn.Forte@Sun.COM  */
49467836SJohn.Forte@Sun.COM static int
loadTargetGroups(int fd,stmfGroupList * groupList)49477836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList)
49487836SJohn.Forte@Sun.COM {
49497836SJohn.Forte@Sun.COM 	int i, j;
49507836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
49517836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
49527836SJohn.Forte@Sun.COM 
49537836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
49547836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
49557836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
49567836SJohn.Forte@Sun.COM 			goto out;
49577836SJohn.Forte@Sun.COM 		}
49589585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
49599585STim.Szeto@Sun.COM 		    &groupProps, TARGET_GROUP);
49607836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
49617836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
49627836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
49637836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
49647836SJohn.Forte@Sun.COM 				goto out;
49657836SJohn.Forte@Sun.COM 			}
49667836SJohn.Forte@Sun.COM 		}
49677836SJohn.Forte@Sun.COM 	}
49687836SJohn.Forte@Sun.COM 
49697836SJohn.Forte@Sun.COM 
49707836SJohn.Forte@Sun.COM out:
49717836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
49727836SJohn.Forte@Sun.COM 	return (ret);
49737836SJohn.Forte@Sun.COM }
49747836SJohn.Forte@Sun.COM 
49757836SJohn.Forte@Sun.COM 
49767836SJohn.Forte@Sun.COM /*
49777836SJohn.Forte@Sun.COM  * loadStore
49787836SJohn.Forte@Sun.COM  *
49797836SJohn.Forte@Sun.COM  * Purpose: Load the configuration data from the store
49807836SJohn.Forte@Sun.COM  *
49817836SJohn.Forte@Sun.COM  * First load the host groups and target groups, then the view entries
49827836SJohn.Forte@Sun.COM  * and finally the provider data
49837836SJohn.Forte@Sun.COM  *
49847836SJohn.Forte@Sun.COM  * fd - file descriptor of control node for stmf.
49857836SJohn.Forte@Sun.COM  */
49867836SJohn.Forte@Sun.COM static int
loadStore(int fd)49877836SJohn.Forte@Sun.COM loadStore(int fd)
49887836SJohn.Forte@Sun.COM {
49897836SJohn.Forte@Sun.COM 	int ret;
49907836SJohn.Forte@Sun.COM 	int i, j;
49917836SJohn.Forte@Sun.COM 	stmfGroupList *groupList = NULL;
49927836SJohn.Forte@Sun.COM 	stmfGuidList *guidList = NULL;
49937836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
49947836SJohn.Forte@Sun.COM 	stmfProviderList *providerList = NULL;
49957836SJohn.Forte@Sun.COM 	int providerType;
49967836SJohn.Forte@Sun.COM 	nvlist_t *nvl = NULL;
49977836SJohn.Forte@Sun.COM 
49987836SJohn.Forte@Sun.COM 
49997836SJohn.Forte@Sun.COM 
50007836SJohn.Forte@Sun.COM 	/* load host groups */
50019585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
50027836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50037836SJohn.Forte@Sun.COM 		return (ret);
50047836SJohn.Forte@Sun.COM 	}
50057836SJohn.Forte@Sun.COM 	ret = loadHostGroups(fd, groupList);
50067836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50077836SJohn.Forte@Sun.COM 		goto out;
50087836SJohn.Forte@Sun.COM 	}
50097836SJohn.Forte@Sun.COM 
50107836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
50117836SJohn.Forte@Sun.COM 	groupList = NULL;
50127836SJohn.Forte@Sun.COM 
50137836SJohn.Forte@Sun.COM 	/* load target groups */
50149585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
50157836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50167836SJohn.Forte@Sun.COM 		goto out;
50177836SJohn.Forte@Sun.COM 	}
50187836SJohn.Forte@Sun.COM 	ret = loadTargetGroups(fd, groupList);
50197836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50207836SJohn.Forte@Sun.COM 		goto out;
50217836SJohn.Forte@Sun.COM 	}
50227836SJohn.Forte@Sun.COM 
50237836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
50247836SJohn.Forte@Sun.COM 	groupList = NULL;
50257836SJohn.Forte@Sun.COM 
50267836SJohn.Forte@Sun.COM 	/* Get the guid list */
50277836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&guidList);
50287836SJohn.Forte@Sun.COM 	switch (ret) {
50297836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
50307836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
50317836SJohn.Forte@Sun.COM 			break;
50327836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
50337836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
50347836SJohn.Forte@Sun.COM 			break;
50357836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
50367836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
50377836SJohn.Forte@Sun.COM 			break;
50387836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
50397836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
50407836SJohn.Forte@Sun.COM 			break;
50417836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
50427836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
50437836SJohn.Forte@Sun.COM 			break;
50447836SJohn.Forte@Sun.COM 		default:
50457836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
50467836SJohn.Forte@Sun.COM 			break;
50477836SJohn.Forte@Sun.COM 	}
50487836SJohn.Forte@Sun.COM 
50497836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
50507836SJohn.Forte@Sun.COM 		goto out;
50517836SJohn.Forte@Sun.COM 	}
50527836SJohn.Forte@Sun.COM 
50537836SJohn.Forte@Sun.COM 	/*
50547836SJohn.Forte@Sun.COM 	 * We have the guid list, now get the corresponding
50557836SJohn.Forte@Sun.COM 	 * view entries for each guid
50567836SJohn.Forte@Sun.COM 	 */
50577836SJohn.Forte@Sun.COM 	for (i = 0; i < guidList->cnt; i++) {
50587836SJohn.Forte@Sun.COM 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
50597836SJohn.Forte@Sun.COM 		switch (ret) {
50607836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
50617836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
50627836SJohn.Forte@Sun.COM 				break;
50637836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
50647836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
50657836SJohn.Forte@Sun.COM 				break;
50667836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
50677836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
50687836SJohn.Forte@Sun.COM 				break;
50697836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
50707836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
50717836SJohn.Forte@Sun.COM 				break;
50727836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
50737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
50747836SJohn.Forte@Sun.COM 				break;
50757836SJohn.Forte@Sun.COM 			default:
50767836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
50777836SJohn.Forte@Sun.COM 				break;
50787836SJohn.Forte@Sun.COM 		}
50797836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
50807836SJohn.Forte@Sun.COM 			goto out;
50817836SJohn.Forte@Sun.COM 		}
50827836SJohn.Forte@Sun.COM 		for (j = 0; j < viewEntryList->cnt; j++) {
50837836SJohn.Forte@Sun.COM 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
50847836SJohn.Forte@Sun.COM 			    &viewEntryList->ve[j]);
50857836SJohn.Forte@Sun.COM 			if (ret != STMF_STATUS_SUCCESS) {
50867836SJohn.Forte@Sun.COM 				goto out;
50877836SJohn.Forte@Sun.COM 			}
50887836SJohn.Forte@Sun.COM 		}
50897836SJohn.Forte@Sun.COM 	}
50907836SJohn.Forte@Sun.COM 
50917836SJohn.Forte@Sun.COM 	/* get the list of providers that have data */
50927836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(&providerList);
50937836SJohn.Forte@Sun.COM 	switch (ret) {
50947836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
50957836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
50967836SJohn.Forte@Sun.COM 			break;
50977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
50987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
50997836SJohn.Forte@Sun.COM 			break;
51007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
51017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
51027836SJohn.Forte@Sun.COM 			break;
51037836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
51047836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
51057836SJohn.Forte@Sun.COM 			break;
51067836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
51077836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
51087836SJohn.Forte@Sun.COM 			break;
51097836SJohn.Forte@Sun.COM 		default:
51107836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
51117836SJohn.Forte@Sun.COM 			break;
51127836SJohn.Forte@Sun.COM 	}
51137836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
51147836SJohn.Forte@Sun.COM 		goto out;
51157836SJohn.Forte@Sun.COM 	}
51167836SJohn.Forte@Sun.COM 
51177836SJohn.Forte@Sun.COM 	for (i = 0; i < providerList->cnt; i++) {
51187836SJohn.Forte@Sun.COM 		providerType = providerList->provider[i].providerType;
51197836SJohn.Forte@Sun.COM 		ret = psGetProviderData(providerList->provider[i].name,
51207836SJohn.Forte@Sun.COM 		    &nvl, providerType, NULL);
51217836SJohn.Forte@Sun.COM 		switch (ret) {
51227836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
51237836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
51247836SJohn.Forte@Sun.COM 				break;
51257836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
51267836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
51277836SJohn.Forte@Sun.COM 				break;
51287836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
51297836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
51307836SJohn.Forte@Sun.COM 				break;
51317836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
51327836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
51337836SJohn.Forte@Sun.COM 				break;
51347836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
51357836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
51367836SJohn.Forte@Sun.COM 				break;
51377836SJohn.Forte@Sun.COM 			default:
51387836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
51397836SJohn.Forte@Sun.COM 				break;
51407836SJohn.Forte@Sun.COM 		}
51417836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
51427836SJohn.Forte@Sun.COM 			goto out;
51437836SJohn.Forte@Sun.COM 		}
51447836SJohn.Forte@Sun.COM 
51457836SJohn.Forte@Sun.COM 		/* call setProviderData */
51467836SJohn.Forte@Sun.COM 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
51479585STim.Szeto@Sun.COM 		    providerType, NULL);
51487836SJohn.Forte@Sun.COM 		switch (ret) {
51497836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
51507836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
51517836SJohn.Forte@Sun.COM 				break;
51527836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
51537836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
51547836SJohn.Forte@Sun.COM 				break;
51557836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
51567836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
51577836SJohn.Forte@Sun.COM 				break;
51587836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
51597836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
51607836SJohn.Forte@Sun.COM 				break;
51617836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
51627836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
51637836SJohn.Forte@Sun.COM 				break;
51647836SJohn.Forte@Sun.COM 			default:
51657836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
51667836SJohn.Forte@Sun.COM 				break;
51677836SJohn.Forte@Sun.COM 		}
51687836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
51697836SJohn.Forte@Sun.COM 			goto out;
51707836SJohn.Forte@Sun.COM 		}
51717836SJohn.Forte@Sun.COM 
51727836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
51737836SJohn.Forte@Sun.COM 		nvl = NULL;
51747836SJohn.Forte@Sun.COM 	}
51757836SJohn.Forte@Sun.COM out:
51767836SJohn.Forte@Sun.COM 	if (groupList != NULL) {
51777836SJohn.Forte@Sun.COM 		free(groupList);
51787836SJohn.Forte@Sun.COM 	}
51797836SJohn.Forte@Sun.COM 	if (guidList != NULL) {
51807836SJohn.Forte@Sun.COM 		free(guidList);
51817836SJohn.Forte@Sun.COM 	}
51827836SJohn.Forte@Sun.COM 	if (viewEntryList != NULL) {
51837836SJohn.Forte@Sun.COM 		free(viewEntryList);
51847836SJohn.Forte@Sun.COM 	}
51857836SJohn.Forte@Sun.COM 	if (nvl != NULL) {
51867836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
51877836SJohn.Forte@Sun.COM 	}
51887836SJohn.Forte@Sun.COM 	return (ret);
51897836SJohn.Forte@Sun.COM }
51907836SJohn.Forte@Sun.COM 
51917836SJohn.Forte@Sun.COM /*
519210725SJohn.Forte@Sun.COM  * stmfGetAluaState
519310725SJohn.Forte@Sun.COM  *
519410725SJohn.Forte@Sun.COM  * Purpose - Get the alua state
519510725SJohn.Forte@Sun.COM  *
519610725SJohn.Forte@Sun.COM  */
519710725SJohn.Forte@Sun.COM int
stmfGetAluaState(boolean_t * enabled,uint32_t * node)519810725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node)
519910725SJohn.Forte@Sun.COM {
520010725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
520110725SJohn.Forte@Sun.COM 	int fd;
520210725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
520310725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
520410725SJohn.Forte@Sun.COM 	int ioctlRet;
520510725SJohn.Forte@Sun.COM 
520610725SJohn.Forte@Sun.COM 	if (enabled == NULL || node == NULL) {
520710725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
520810725SJohn.Forte@Sun.COM 	}
520910725SJohn.Forte@Sun.COM 
521010725SJohn.Forte@Sun.COM 	/*
521110725SJohn.Forte@Sun.COM 	 * Open control node for stmf
521210725SJohn.Forte@Sun.COM 	 */
521310725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
521410725SJohn.Forte@Sun.COM 		return (ret);
521510725SJohn.Forte@Sun.COM 
521610725SJohn.Forte@Sun.COM 	/*
521710725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
521810725SJohn.Forte@Sun.COM 	 */
521910725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
522010725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (alua_state);
522110725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state;
522210725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl);
522310725SJohn.Forte@Sun.COM 
522410725SJohn.Forte@Sun.COM 	(void) close(fd);
522510725SJohn.Forte@Sun.COM 
522610725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
522710725SJohn.Forte@Sun.COM 		switch (errno) {
522810725SJohn.Forte@Sun.COM 			case EBUSY:
522910725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
523010725SJohn.Forte@Sun.COM 				break;
523110725SJohn.Forte@Sun.COM 			case EPERM:
523210725SJohn.Forte@Sun.COM 			case EACCES:
523310725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
523410725SJohn.Forte@Sun.COM 				break;
523510725SJohn.Forte@Sun.COM 			default:
523610725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
523710725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
523810725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
523910725SJohn.Forte@Sun.COM 				break;
524010725SJohn.Forte@Sun.COM 		}
524110725SJohn.Forte@Sun.COM 	} else {
524210725SJohn.Forte@Sun.COM 		if (alua_state.alua_state == 1) {
524310725SJohn.Forte@Sun.COM 			*enabled = B_TRUE;
524410725SJohn.Forte@Sun.COM 		} else {
524510725SJohn.Forte@Sun.COM 			*enabled = B_FALSE;
524610725SJohn.Forte@Sun.COM 		}
524710725SJohn.Forte@Sun.COM 		*node = alua_state.alua_node;
524810725SJohn.Forte@Sun.COM 	}
524910725SJohn.Forte@Sun.COM 
525010725SJohn.Forte@Sun.COM 	return (ret);
525110725SJohn.Forte@Sun.COM }
525210725SJohn.Forte@Sun.COM 
525310725SJohn.Forte@Sun.COM /*
525410725SJohn.Forte@Sun.COM  * stmfSetAluaState
525510725SJohn.Forte@Sun.COM  *
525610725SJohn.Forte@Sun.COM  * Purpose - set the alua state to enabled/disabled
525710725SJohn.Forte@Sun.COM  *
525810725SJohn.Forte@Sun.COM  */
525910725SJohn.Forte@Sun.COM int
stmfSetAluaState(boolean_t enabled,uint32_t node)526010725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node)
526110725SJohn.Forte@Sun.COM {
526210725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
526310725SJohn.Forte@Sun.COM 	int fd;
526410725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
526510725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
526610725SJohn.Forte@Sun.COM 	int ioctlRet;
526710725SJohn.Forte@Sun.COM 
526810725SJohn.Forte@Sun.COM 	if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) {
526910725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
527010725SJohn.Forte@Sun.COM 	}
527110725SJohn.Forte@Sun.COM 
527210725SJohn.Forte@Sun.COM 	if (enabled) {
527310725SJohn.Forte@Sun.COM 		alua_state.alua_state = 1;
527410725SJohn.Forte@Sun.COM 	}
527510725SJohn.Forte@Sun.COM 
527610725SJohn.Forte@Sun.COM 	alua_state.alua_node = node;
527710725SJohn.Forte@Sun.COM 
527810725SJohn.Forte@Sun.COM 	/*
527910725SJohn.Forte@Sun.COM 	 * Open control node for stmf
528010725SJohn.Forte@Sun.COM 	 */
528110725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
528210725SJohn.Forte@Sun.COM 		return (ret);
528310725SJohn.Forte@Sun.COM 
528410725SJohn.Forte@Sun.COM 	/*
528510725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
528610725SJohn.Forte@Sun.COM 	 */
528710725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
528810725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (alua_state);
528910725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state;
529010725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl);
529110725SJohn.Forte@Sun.COM 
529210725SJohn.Forte@Sun.COM 	(void) close(fd);
529310725SJohn.Forte@Sun.COM 
529410725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
529510725SJohn.Forte@Sun.COM 		switch (errno) {
529610725SJohn.Forte@Sun.COM 			case EBUSY:
529710725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
529810725SJohn.Forte@Sun.COM 				break;
529910725SJohn.Forte@Sun.COM 			case EPERM:
530010725SJohn.Forte@Sun.COM 			case EACCES:
530110725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
530210725SJohn.Forte@Sun.COM 				break;
530310725SJohn.Forte@Sun.COM 			default:
530410725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
530510725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
530610725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
530710725SJohn.Forte@Sun.COM 				break;
530810725SJohn.Forte@Sun.COM 		}
530910725SJohn.Forte@Sun.COM 	}
531011116SJohn.Forte@Sun.COM 	if (!enabled && ret == STMF_STATUS_SUCCESS) {
531110725SJohn.Forte@Sun.COM 		deleteNonActiveLus();
531210725SJohn.Forte@Sun.COM 	}
531310725SJohn.Forte@Sun.COM 
531410725SJohn.Forte@Sun.COM 	return (ret);
531510725SJohn.Forte@Sun.COM }
531610725SJohn.Forte@Sun.COM 
531710725SJohn.Forte@Sun.COM static void
deleteNonActiveLus()531810725SJohn.Forte@Sun.COM deleteNonActiveLus()
531910725SJohn.Forte@Sun.COM {
532010725SJohn.Forte@Sun.COM 	int stmfRet;
532110725SJohn.Forte@Sun.COM 	int i;
532210725SJohn.Forte@Sun.COM 	stmfGuidList *luList;
532310725SJohn.Forte@Sun.COM 	luResource hdl = NULL;
532410725SJohn.Forte@Sun.COM 	char propVal[10];
532510725SJohn.Forte@Sun.COM 	size_t propValSize = sizeof (propVal);
532610725SJohn.Forte@Sun.COM 
532710725SJohn.Forte@Sun.COM 	stmfRet = stmfGetLogicalUnitList(&luList);
532810725SJohn.Forte@Sun.COM 	if (stmfRet != STMF_STATUS_SUCCESS) {
532910725SJohn.Forte@Sun.COM 		return;
533010725SJohn.Forte@Sun.COM 	}
533110725SJohn.Forte@Sun.COM 
533210725SJohn.Forte@Sun.COM 	for (i = 0; i < luList->cnt; i++) {
533310725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuResource(&luList->guid[i], &hdl);
533410725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
533510725SJohn.Forte@Sun.COM 			goto err;
533610725SJohn.Forte@Sun.COM 		}
533710725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
533810725SJohn.Forte@Sun.COM 		    &propValSize);
533910725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
534010725SJohn.Forte@Sun.COM 			goto err;
534110725SJohn.Forte@Sun.COM 		}
534210725SJohn.Forte@Sun.COM 		if (propVal[0] == '0') {
534310725SJohn.Forte@Sun.COM 			(void) stmfFreeLuResource(hdl);
534410725SJohn.Forte@Sun.COM 			hdl = NULL;
534510725SJohn.Forte@Sun.COM 			continue;
534610725SJohn.Forte@Sun.COM 		}
534710725SJohn.Forte@Sun.COM 		(void) stmfDeleteLu(&luList->guid[i]);
534810725SJohn.Forte@Sun.COM 		(void) stmfFreeLuResource(hdl);
534910725SJohn.Forte@Sun.COM 		hdl = NULL;
535010725SJohn.Forte@Sun.COM 	}
535110725SJohn.Forte@Sun.COM 
535210725SJohn.Forte@Sun.COM err:
535310725SJohn.Forte@Sun.COM 	stmfFreeMemory(luList);
535410725SJohn.Forte@Sun.COM 	(void) stmfFreeLuResource(hdl);
535510725SJohn.Forte@Sun.COM }
535610725SJohn.Forte@Sun.COM 
535710725SJohn.Forte@Sun.COM /*
53587836SJohn.Forte@Sun.COM  * stmfLoadConfig
53597836SJohn.Forte@Sun.COM  *
53607836SJohn.Forte@Sun.COM  * Purpose - load the configuration data from smf into stmf
53617836SJohn.Forte@Sun.COM  *
53627836SJohn.Forte@Sun.COM  */
53637836SJohn.Forte@Sun.COM int
stmfLoadConfig(void)53647836SJohn.Forte@Sun.COM stmfLoadConfig(void)
53657836SJohn.Forte@Sun.COM {
53669585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
53677836SJohn.Forte@Sun.COM 	int fd;
53687836SJohn.Forte@Sun.COM 	stmf_state_desc_t stmfStateSet;
53697836SJohn.Forte@Sun.COM 	stmfState state;
53707836SJohn.Forte@Sun.COM 
53719585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
53729585STim.Szeto@Sun.COM 		stmfStateSet.state = STMF_STATE_OFFLINE;
537310560SSusan.Gleeson@Sun.COM 
53749585STim.Szeto@Sun.COM 		if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
53759585STim.Szeto@Sun.COM 		    != STMF_STATUS_SUCCESS) {
53769585STim.Szeto@Sun.COM 			return (ret);
53779585STim.Szeto@Sun.COM 		}
537810560SSusan.Gleeson@Sun.COM 		/*
537910560SSusan.Gleeson@Sun.COM 		 * Configuration not stored persistently; nothing to
538010560SSusan.Gleeson@Sun.COM 		 * initialize so do not set to STMF_CONFIG_INIT.
538110560SSusan.Gleeson@Sun.COM 		 */
53829585STim.Szeto@Sun.COM 		stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
53839585STim.Szeto@Sun.COM 		goto done;
53849585STim.Szeto@Sun.COM 	}
53857836SJohn.Forte@Sun.COM 
53867836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
53877836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
53887836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
53897836SJohn.Forte@Sun.COM 	}
53907836SJohn.Forte@Sun.COM 
53917836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
53927836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
53937836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
53947836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
53957836SJohn.Forte@Sun.COM 		}
53967836SJohn.Forte@Sun.COM 	} else {
53977836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
53987836SJohn.Forte@Sun.COM 	}
53997836SJohn.Forte@Sun.COM 
54007836SJohn.Forte@Sun.COM 
54017836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
54027836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT;
54037836SJohn.Forte@Sun.COM 
54047836SJohn.Forte@Sun.COM 	/*
54057836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54067836SJohn.Forte@Sun.COM 	 */
54077836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
54087836SJohn.Forte@Sun.COM 		return (ret);
54097836SJohn.Forte@Sun.COM 
54107836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
54117836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
54127836SJohn.Forte@Sun.COM 		goto done;
54137836SJohn.Forte@Sun.COM 	}
54147836SJohn.Forte@Sun.COM 
54157836SJohn.Forte@Sun.COM 	/* Load the persistent configuration data */
54167836SJohn.Forte@Sun.COM 	ret = loadStore(fd);
54177836SJohn.Forte@Sun.COM 	if (ret != 0) {
54187836SJohn.Forte@Sun.COM 		goto done;
54197836SJohn.Forte@Sun.COM 	}
54207836SJohn.Forte@Sun.COM 
54217836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
54227836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
54237836SJohn.Forte@Sun.COM 
54247836SJohn.Forte@Sun.COM done:
54257836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
54267836SJohn.Forte@Sun.COM 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
54277836SJohn.Forte@Sun.COM 	}
54287836SJohn.Forte@Sun.COM 	(void) close(fd);
54297836SJohn.Forte@Sun.COM 	return (ret);
54307836SJohn.Forte@Sun.COM }
54317836SJohn.Forte@Sun.COM 
54329585STim.Szeto@Sun.COM 
54337836SJohn.Forte@Sun.COM /*
54347836SJohn.Forte@Sun.COM  * getStmfState
54357836SJohn.Forte@Sun.COM  *
54367836SJohn.Forte@Sun.COM  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
54377836SJohn.Forte@Sun.COM  *             information of the stmf service on success.
54387836SJohn.Forte@Sun.COM  */
54397836SJohn.Forte@Sun.COM static int
getStmfState(stmf_state_desc_t * stmfState)54407836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState)
54417836SJohn.Forte@Sun.COM {
54427836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54437836SJohn.Forte@Sun.COM 	int fd;
54447836SJohn.Forte@Sun.COM 	int ioctlRet;
54457836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
54467836SJohn.Forte@Sun.COM 
54477836SJohn.Forte@Sun.COM 	/*
54487836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54497836SJohn.Forte@Sun.COM 	 */
54507836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
54517836SJohn.Forte@Sun.COM 		return (ret);
54527836SJohn.Forte@Sun.COM 
54537836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
54547836SJohn.Forte@Sun.COM 	/*
54557836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
54567836SJohn.Forte@Sun.COM 	 */
54577836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
54587836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
54597836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
54607836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
54617836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
54627836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
54637836SJohn.Forte@Sun.COM 
54647836SJohn.Forte@Sun.COM 	(void) close(fd);
54657836SJohn.Forte@Sun.COM 
54667836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
54677836SJohn.Forte@Sun.COM 		switch (errno) {
54687836SJohn.Forte@Sun.COM 			case EBUSY:
54697836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
54707836SJohn.Forte@Sun.COM 				break;
54717836SJohn.Forte@Sun.COM 			case EPERM:
54727836SJohn.Forte@Sun.COM 			case EACCES:
54737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
54747836SJohn.Forte@Sun.COM 				break;
54757836SJohn.Forte@Sun.COM 			default:
54767836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
54777836SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
54787836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
54797836SJohn.Forte@Sun.COM 				break;
54807836SJohn.Forte@Sun.COM 		}
54817836SJohn.Forte@Sun.COM 	}
54827836SJohn.Forte@Sun.COM 	return (ret);
54837836SJohn.Forte@Sun.COM }
54847836SJohn.Forte@Sun.COM 
54857836SJohn.Forte@Sun.COM 
54867836SJohn.Forte@Sun.COM /*
54877836SJohn.Forte@Sun.COM  * setStmfState
54887836SJohn.Forte@Sun.COM  *
54897836SJohn.Forte@Sun.COM  * stmfState - pointer to caller set state structure
54907836SJohn.Forte@Sun.COM  * objectType - one of:
54917836SJohn.Forte@Sun.COM  *		LOGICAL_UNIT_TYPE
54927836SJohn.Forte@Sun.COM  *		TARGET_TYPE
54937836SJohn.Forte@Sun.COM  *		STMF_SERVICE_TYPE
54947836SJohn.Forte@Sun.COM  */
54957836SJohn.Forte@Sun.COM static int
setStmfState(int fd,stmf_state_desc_t * stmfState,int objectType)54967836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
54977836SJohn.Forte@Sun.COM {
54987836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54997836SJohn.Forte@Sun.COM 	int ioctlRet;
55007836SJohn.Forte@Sun.COM 	int cmd;
55017836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
55027836SJohn.Forte@Sun.COM 
55037836SJohn.Forte@Sun.COM 	switch (objectType) {
55047836SJohn.Forte@Sun.COM 		case LOGICAL_UNIT_TYPE:
55057836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_LU_STATE;
55067836SJohn.Forte@Sun.COM 			break;
55077836SJohn.Forte@Sun.COM 		case TARGET_TYPE:
55087836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
55097836SJohn.Forte@Sun.COM 			break;
55107836SJohn.Forte@Sun.COM 		case STMF_SERVICE_TYPE:
55117836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_STMF_STATE;
55127836SJohn.Forte@Sun.COM 			break;
55137836SJohn.Forte@Sun.COM 		default:
55147836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
55157836SJohn.Forte@Sun.COM 			goto done;
55167836SJohn.Forte@Sun.COM 	}
55177836SJohn.Forte@Sun.COM 
55187836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
55197836SJohn.Forte@Sun.COM 	/*
55207836SJohn.Forte@Sun.COM 	 * Issue ioctl to set the stmf state
55217836SJohn.Forte@Sun.COM 	 */
55227836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
55237836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
55247836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
55257836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
55267836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
55277836SJohn.Forte@Sun.COM 		switch (errno) {
55287836SJohn.Forte@Sun.COM 			case EBUSY:
55297836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
55307836SJohn.Forte@Sun.COM 				break;
55319585STim.Szeto@Sun.COM 			case EPERM:
55327836SJohn.Forte@Sun.COM 			case EACCES:
55337836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
55347836SJohn.Forte@Sun.COM 				break;
55357836SJohn.Forte@Sun.COM 			case ENOENT:
55367836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
55377836SJohn.Forte@Sun.COM 				break;
55387836SJohn.Forte@Sun.COM 			default:
55397836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
55407836SJohn.Forte@Sun.COM 				    "setStmfState:ioctl errno(%d)", errno);
55417836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
55427836SJohn.Forte@Sun.COM 				break;
55437836SJohn.Forte@Sun.COM 		}
55447836SJohn.Forte@Sun.COM 	}
55457836SJohn.Forte@Sun.COM done:
55467836SJohn.Forte@Sun.COM 	return (ret);
55477836SJohn.Forte@Sun.COM }
554812682SSrivijitha.Dugganapalli@Sun.COM int
stmfSetStmfProp(uint8_t propType,char * propVal)554912682SSrivijitha.Dugganapalli@Sun.COM stmfSetStmfProp(uint8_t propType, char *propVal)
555012682SSrivijitha.Dugganapalli@Sun.COM {
555112682SSrivijitha.Dugganapalli@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
555212682SSrivijitha.Dugganapalli@Sun.COM 	switch (propType) {
555312682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_DEFAULT_LU_STATE:
555412682SSrivijitha.Dugganapalli@Sun.COM 			break;
555512682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_DEFAULT_TARGET_PORT_STATE:
555612682SSrivijitha.Dugganapalli@Sun.COM 			break;
555712682SSrivijitha.Dugganapalli@Sun.COM 		default:
555812682SSrivijitha.Dugganapalli@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
555912682SSrivijitha.Dugganapalli@Sun.COM 	}
556012682SSrivijitha.Dugganapalli@Sun.COM 	ret = psSetStmfProp(propType, propVal);
556112682SSrivijitha.Dugganapalli@Sun.COM 	switch (ret) {
556212682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_SUCCESS:
556312682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_STATUS_SUCCESS;
556412682SSrivijitha.Dugganapalli@Sun.COM 			break;
556512682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_ERROR_BUSY:
556612682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_BUSY;
556712682SSrivijitha.Dugganapalli@Sun.COM 			break;
556812682SSrivijitha.Dugganapalli@Sun.COM 		default:
556912682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_DEBUG,
557012682SSrivijitha.Dugganapalli@Sun.COM 			    "stmfSetStmfProp:psSetStmfProp:error(%d)",
557112682SSrivijitha.Dugganapalli@Sun.COM 			    ret);
557212682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_STATUS_ERROR;
557312682SSrivijitha.Dugganapalli@Sun.COM 			break;
557412682SSrivijitha.Dugganapalli@Sun.COM 	}
557512682SSrivijitha.Dugganapalli@Sun.COM 	return (ret);
557612682SSrivijitha.Dugganapalli@Sun.COM }
557712682SSrivijitha.Dugganapalli@Sun.COM 
557812682SSrivijitha.Dugganapalli@Sun.COM 
557912682SSrivijitha.Dugganapalli@Sun.COM int
stmfGetStmfProp(uint8_t propType,char * propVal,size_t * propLen)558012682SSrivijitha.Dugganapalli@Sun.COM stmfGetStmfProp(uint8_t propType, char *propVal, size_t *propLen)
558112682SSrivijitha.Dugganapalli@Sun.COM {
558212682SSrivijitha.Dugganapalli@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
558312682SSrivijitha.Dugganapalli@Sun.COM 	char prop[MAXNAMELEN] = {0};
558412682SSrivijitha.Dugganapalli@Sun.COM 	size_t reqLen;
558512682SSrivijitha.Dugganapalli@Sun.COM 
558612682SSrivijitha.Dugganapalli@Sun.COM 	if (propVal == NULL || propLen == NULL) {
558712682SSrivijitha.Dugganapalli@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
558812682SSrivijitha.Dugganapalli@Sun.COM 	}
558912682SSrivijitha.Dugganapalli@Sun.COM 	switch (propType) {
559012682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_DEFAULT_LU_STATE:
559112682SSrivijitha.Dugganapalli@Sun.COM 			break;
559212682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_DEFAULT_TARGET_PORT_STATE:
559312682SSrivijitha.Dugganapalli@Sun.COM 			break;
559412682SSrivijitha.Dugganapalli@Sun.COM 		default:
559512682SSrivijitha.Dugganapalli@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
559612682SSrivijitha.Dugganapalli@Sun.COM 	}
559712682SSrivijitha.Dugganapalli@Sun.COM 	ret = psGetStmfProp(propType, prop);
559812682SSrivijitha.Dugganapalli@Sun.COM 	if ((reqLen = strlcpy(propVal, prop, *propLen)) >= *propLen) {
559912682SSrivijitha.Dugganapalli@Sun.COM 		*propLen = reqLen + 1;
560012682SSrivijitha.Dugganapalli@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
560112682SSrivijitha.Dugganapalli@Sun.COM 	}
560212682SSrivijitha.Dugganapalli@Sun.COM 
560312682SSrivijitha.Dugganapalli@Sun.COM 	switch (ret) {
560412682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_SUCCESS:
560512682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_STATUS_SUCCESS;
560612682SSrivijitha.Dugganapalli@Sun.COM 			break;
560712682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_ERROR_BUSY:
560812682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_BUSY;
560912682SSrivijitha.Dugganapalli@Sun.COM 			break;
561012682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
561112682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
561212682SSrivijitha.Dugganapalli@Sun.COM 			break;
561312682SSrivijitha.Dugganapalli@Sun.COM 		default:
561412682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_DEBUG,
561512682SSrivijitha.Dugganapalli@Sun.COM 			    "stmfGetStmfProp:psGetStmfProp:error(%d)",
561612682SSrivijitha.Dugganapalli@Sun.COM 			    ret);
561712682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_STATUS_ERROR;
561812682SSrivijitha.Dugganapalli@Sun.COM 			break;
561912682SSrivijitha.Dugganapalli@Sun.COM 	}
562012682SSrivijitha.Dugganapalli@Sun.COM 	return (ret);
562112682SSrivijitha.Dugganapalli@Sun.COM }
562212682SSrivijitha.Dugganapalli@Sun.COM 
562312682SSrivijitha.Dugganapalli@Sun.COM static int
setStmfProp(stmf_set_props_t * stmf_set_props)562412682SSrivijitha.Dugganapalli@Sun.COM setStmfProp(stmf_set_props_t *stmf_set_props)
562512682SSrivijitha.Dugganapalli@Sun.COM {
562612682SSrivijitha.Dugganapalli@Sun.COM 	char propVal[MAXNAMELEN] = {0};
562712682SSrivijitha.Dugganapalli@Sun.COM 	int ret;
562812682SSrivijitha.Dugganapalli@Sun.COM 	if ((ret = psGetStmfProp(STMF_DEFAULT_LU_STATE, propVal)) ==
562912682SSrivijitha.Dugganapalli@Sun.COM 	    STMF_PS_SUCCESS) {
563012682SSrivijitha.Dugganapalli@Sun.COM 		if (strncmp(propVal, "offline", strlen(propVal)) == 0) {
563112682SSrivijitha.Dugganapalli@Sun.COM 			stmf_set_props->default_lu_state_value =
563212682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_STATE_OFFLINE;
563312682SSrivijitha.Dugganapalli@Sun.COM 		} else {
563412682SSrivijitha.Dugganapalli@Sun.COM 			stmf_set_props->default_lu_state_value =
563512682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_STATE_ONLINE;
563612682SSrivijitha.Dugganapalli@Sun.COM 		}
563712682SSrivijitha.Dugganapalli@Sun.COM 	} else {
563812682SSrivijitha.Dugganapalli@Sun.COM 		syslog(LOG_DEBUG,
563912682SSrivijitha.Dugganapalli@Sun.COM 		    "DefaultLuState:psSetStmfProp:error(%d)", ret);
564012682SSrivijitha.Dugganapalli@Sun.COM 		goto done;
564112682SSrivijitha.Dugganapalli@Sun.COM 	}
564212682SSrivijitha.Dugganapalli@Sun.COM 
564312682SSrivijitha.Dugganapalli@Sun.COM 	if ((ret = psGetStmfProp(STMF_DEFAULT_TARGET_PORT_STATE, propVal)) ==
564412682SSrivijitha.Dugganapalli@Sun.COM 	    STMF_PS_SUCCESS) {
564512682SSrivijitha.Dugganapalli@Sun.COM 		if (strncmp(propVal, "offline", strlen(propVal)) == 0) {
564612682SSrivijitha.Dugganapalli@Sun.COM 			stmf_set_props->default_target_state_value =
564712682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_STATE_OFFLINE;
564812682SSrivijitha.Dugganapalli@Sun.COM 		} else {
564912682SSrivijitha.Dugganapalli@Sun.COM 			stmf_set_props->default_target_state_value =
565012682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_STATE_ONLINE;
565112682SSrivijitha.Dugganapalli@Sun.COM 		}
565212682SSrivijitha.Dugganapalli@Sun.COM 	} else {
565312682SSrivijitha.Dugganapalli@Sun.COM 		syslog(LOG_DEBUG,
565412682SSrivijitha.Dugganapalli@Sun.COM 		    "DefaultTargetPortState:psSetStmfProp:error(%d)", ret);
565512682SSrivijitha.Dugganapalli@Sun.COM 		goto done;
565612682SSrivijitha.Dugganapalli@Sun.COM 	}
565712682SSrivijitha.Dugganapalli@Sun.COM done:
565812682SSrivijitha.Dugganapalli@Sun.COM 	switch (ret) {
565912682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_SUCCESS:
566012682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_STATUS_SUCCESS;
566112682SSrivijitha.Dugganapalli@Sun.COM 			break;
566212682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
566312682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
566412682SSrivijitha.Dugganapalli@Sun.COM 			break;
566512682SSrivijitha.Dugganapalli@Sun.COM 		case STMF_PS_ERROR_BUSY:
566612682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_ERROR_BUSY;
566712682SSrivijitha.Dugganapalli@Sun.COM 			break;
566812682SSrivijitha.Dugganapalli@Sun.COM 		default:
566912682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_STATUS_ERROR;
567012682SSrivijitha.Dugganapalli@Sun.COM 			break;
567112682SSrivijitha.Dugganapalli@Sun.COM 	}
567212682SSrivijitha.Dugganapalli@Sun.COM 	return (ret);
567312682SSrivijitha.Dugganapalli@Sun.COM }
567412682SSrivijitha.Dugganapalli@Sun.COM 
567512682SSrivijitha.Dugganapalli@Sun.COM static int
loadStmfProp(int fd)567612682SSrivijitha.Dugganapalli@Sun.COM loadStmfProp(int fd)
567712682SSrivijitha.Dugganapalli@Sun.COM {
567812682SSrivijitha.Dugganapalli@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
567912682SSrivijitha.Dugganapalli@Sun.COM 	int ioctlRet;
568012682SSrivijitha.Dugganapalli@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
568112682SSrivijitha.Dugganapalli@Sun.COM 	stmf_set_props_t *stmf_set_props = NULL;
568212682SSrivijitha.Dugganapalli@Sun.COM 
568312682SSrivijitha.Dugganapalli@Sun.COM 	stmf_set_props = (stmf_set_props_t *)
568412682SSrivijitha.Dugganapalli@Sun.COM 	    calloc(1, (sizeof (stmf_set_props_t)));
568512682SSrivijitha.Dugganapalli@Sun.COM 	if (stmf_set_props == NULL) {
568612682SSrivijitha.Dugganapalli@Sun.COM 		ret = STMF_ERROR_NOMEM;
568712682SSrivijitha.Dugganapalli@Sun.COM 		goto done;
568812682SSrivijitha.Dugganapalli@Sun.COM 	}
568912682SSrivijitha.Dugganapalli@Sun.COM 
569012682SSrivijitha.Dugganapalli@Sun.COM 	/* Loading the default property values from smf */
569112682SSrivijitha.Dugganapalli@Sun.COM 
569212682SSrivijitha.Dugganapalli@Sun.COM 	if ((ret = setStmfProp(stmf_set_props)) != STMF_STATUS_SUCCESS)
569312682SSrivijitha.Dugganapalli@Sun.COM 		goto done;
569412682SSrivijitha.Dugganapalli@Sun.COM 
569512682SSrivijitha.Dugganapalli@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
569612682SSrivijitha.Dugganapalli@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_set_props_t);
569712682SSrivijitha.Dugganapalli@Sun.COM 	stmfIoctl.stmf_ibuf =
569812682SSrivijitha.Dugganapalli@Sun.COM 	    (uint64_t)(unsigned long)stmf_set_props;
569912682SSrivijitha.Dugganapalli@Sun.COM 
570012682SSrivijitha.Dugganapalli@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_SET_STMF_PROPS,
570112682SSrivijitha.Dugganapalli@Sun.COM 	    &stmfIoctl);
570212682SSrivijitha.Dugganapalli@Sun.COM 
570312682SSrivijitha.Dugganapalli@Sun.COM 	if (ioctlRet != 0) {
570412682SSrivijitha.Dugganapalli@Sun.COM 		switch (errno) {
570512682SSrivijitha.Dugganapalli@Sun.COM 			case EBUSY:
570612682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_ERROR_BUSY;
570712682SSrivijitha.Dugganapalli@Sun.COM 				break;
570812682SSrivijitha.Dugganapalli@Sun.COM 			case EPERM:
570912682SSrivijitha.Dugganapalli@Sun.COM 			case EACCES:
571012682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_ERROR_PERM;
571112682SSrivijitha.Dugganapalli@Sun.COM 				break;
571212682SSrivijitha.Dugganapalli@Sun.COM 			case ENOENT:
571312682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
571412682SSrivijitha.Dugganapalli@Sun.COM 				break;
571512682SSrivijitha.Dugganapalli@Sun.COM 			default:
571612682SSrivijitha.Dugganapalli@Sun.COM 				syslog(LOG_DEBUG,
571712682SSrivijitha.Dugganapalli@Sun.COM 				    "setDefaultStmfState:"
571812682SSrivijitha.Dugganapalli@Sun.COM 				    "ioctl errno(%d)", errno);
571912682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_STATUS_ERROR;
572012682SSrivijitha.Dugganapalli@Sun.COM 				break;
572112682SSrivijitha.Dugganapalli@Sun.COM 		}
572212682SSrivijitha.Dugganapalli@Sun.COM 	}
572312682SSrivijitha.Dugganapalli@Sun.COM done:
572412682SSrivijitha.Dugganapalli@Sun.COM 	if (stmf_set_props != NULL) {
572512682SSrivijitha.Dugganapalli@Sun.COM 		free(stmf_set_props);
572612682SSrivijitha.Dugganapalli@Sun.COM 	}
572712682SSrivijitha.Dugganapalli@Sun.COM 	return (ret);
572812682SSrivijitha.Dugganapalli@Sun.COM }
572912682SSrivijitha.Dugganapalli@Sun.COM 
573012682SSrivijitha.Dugganapalli@Sun.COM int
stmfLoadStmfProps(void)573112682SSrivijitha.Dugganapalli@Sun.COM stmfLoadStmfProps(void)
573212682SSrivijitha.Dugganapalli@Sun.COM {
573312682SSrivijitha.Dugganapalli@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
573412682SSrivijitha.Dugganapalli@Sun.COM 	int fd;
573512682SSrivijitha.Dugganapalli@Sun.COM 	/* open control node for stmf */
573612682SSrivijitha.Dugganapalli@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
573712682SSrivijitha.Dugganapalli@Sun.COM 	    != STMF_STATUS_SUCCESS) {
573812682SSrivijitha.Dugganapalli@Sun.COM 		goto done;
573912682SSrivijitha.Dugganapalli@Sun.COM 	}
574012682SSrivijitha.Dugganapalli@Sun.COM 	ret = loadStmfProp(fd);
574112682SSrivijitha.Dugganapalli@Sun.COM 
574212682SSrivijitha.Dugganapalli@Sun.COM 	(void) close(fd);
574312682SSrivijitha.Dugganapalli@Sun.COM done:
574412682SSrivijitha.Dugganapalli@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
574512682SSrivijitha.Dugganapalli@Sun.COM 		syslog(LOG_DEBUG,
574612682SSrivijitha.Dugganapalli@Sun.COM 		    "stmfLoadStmfProps:Failed");
574712682SSrivijitha.Dugganapalli@Sun.COM 	}
574812682SSrivijitha.Dugganapalli@Sun.COM 	return (ret);
574912682SSrivijitha.Dugganapalli@Sun.COM }
57507836SJohn.Forte@Sun.COM 
57517836SJohn.Forte@Sun.COM /*
57527836SJohn.Forte@Sun.COM  * stmfOnline
57537836SJohn.Forte@Sun.COM  *
57547836SJohn.Forte@Sun.COM  * Purpose: Online stmf service
57557836SJohn.Forte@Sun.COM  *
57567836SJohn.Forte@Sun.COM  */
57577836SJohn.Forte@Sun.COM int
stmfOnline(void)57587836SJohn.Forte@Sun.COM stmfOnline(void)
57597836SJohn.Forte@Sun.COM {
57607836SJohn.Forte@Sun.COM 	int ret;
57617836SJohn.Forte@Sun.COM 	int fd;
57627836SJohn.Forte@Sun.COM 	stmfState state;
57637836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
57647836SJohn.Forte@Sun.COM 
57657836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
57667836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
57677836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
57687836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
57697836SJohn.Forte@Sun.COM 		}
57707836SJohn.Forte@Sun.COM 	} else {
57717836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
57727836SJohn.Forte@Sun.COM 	}
57737836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_ONLINE;
57747836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
57757836SJohn.Forte@Sun.COM 	/*
57767836SJohn.Forte@Sun.COM 	 * Open control node for stmf
57777836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
57787836SJohn.Forte@Sun.COM 	 */
57797836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
57807836SJohn.Forte@Sun.COM 		return (ret);
57817836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
57827836SJohn.Forte@Sun.COM 	(void) close(fd);
57837836SJohn.Forte@Sun.COM 	return (ret);
57847836SJohn.Forte@Sun.COM }
57857836SJohn.Forte@Sun.COM 
57867836SJohn.Forte@Sun.COM /*
57877836SJohn.Forte@Sun.COM  * stmfOffline
57887836SJohn.Forte@Sun.COM  *
57897836SJohn.Forte@Sun.COM  * Purpose: Offline stmf service
57907836SJohn.Forte@Sun.COM  *
57917836SJohn.Forte@Sun.COM  */
57927836SJohn.Forte@Sun.COM int
stmfOffline(void)57937836SJohn.Forte@Sun.COM stmfOffline(void)
57947836SJohn.Forte@Sun.COM {
57957836SJohn.Forte@Sun.COM 	int ret;
57967836SJohn.Forte@Sun.COM 	int fd;
57977836SJohn.Forte@Sun.COM 	stmfState state;
57987836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
57997836SJohn.Forte@Sun.COM 
58007836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
58017836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
58027836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
58037836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_OFFLINE);
58047836SJohn.Forte@Sun.COM 		}
58057836SJohn.Forte@Sun.COM 	} else {
58067836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
58077836SJohn.Forte@Sun.COM 	}
58087836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_OFFLINE;
58097836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
58107836SJohn.Forte@Sun.COM 
58117836SJohn.Forte@Sun.COM 	/*
58127836SJohn.Forte@Sun.COM 	 * Open control node for stmf
58137836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
58147836SJohn.Forte@Sun.COM 	 */
58157836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
58167836SJohn.Forte@Sun.COM 		return (ret);
58177836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
58187836SJohn.Forte@Sun.COM 	(void) close(fd);
58197836SJohn.Forte@Sun.COM 	return (ret);
58207836SJohn.Forte@Sun.COM }
58217836SJohn.Forte@Sun.COM 
58227836SJohn.Forte@Sun.COM 
58237836SJohn.Forte@Sun.COM /*
58247836SJohn.Forte@Sun.COM  * stmfOfflineTarget
58257836SJohn.Forte@Sun.COM  *
58267836SJohn.Forte@Sun.COM  * Purpose: Change state of target to offline
58277836SJohn.Forte@Sun.COM  *
58287836SJohn.Forte@Sun.COM  * devid - devid of the target to offline
58297836SJohn.Forte@Sun.COM  */
58307836SJohn.Forte@Sun.COM int
stmfOfflineTarget(stmfDevid * devid)58317836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid)
58327836SJohn.Forte@Sun.COM {
58337836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
58347836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
58357836SJohn.Forte@Sun.COM 	int fd;
58367836SJohn.Forte@Sun.COM 
58377836SJohn.Forte@Sun.COM 	if (devid == NULL) {
58387836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
58397836SJohn.Forte@Sun.COM 	}
58407836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
58417836SJohn.Forte@Sun.COM 
58427836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_OFFLINE;
58437836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
58447836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
58457836SJohn.Forte@Sun.COM 	    devid->identLength);
58467836SJohn.Forte@Sun.COM 	/*
58477836SJohn.Forte@Sun.COM 	 * Open control node for stmf
58487836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
58497836SJohn.Forte@Sun.COM 	 */
58507836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
58517836SJohn.Forte@Sun.COM 		return (ret);
58527836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
58537836SJohn.Forte@Sun.COM 	(void) close(fd);
58547836SJohn.Forte@Sun.COM 	return (ret);
58557836SJohn.Forte@Sun.COM }
58567836SJohn.Forte@Sun.COM 
58577836SJohn.Forte@Sun.COM /*
58587836SJohn.Forte@Sun.COM  * stmfOfflineLogicalUnit
58597836SJohn.Forte@Sun.COM  *
58607836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to offline
58617836SJohn.Forte@Sun.COM  *
58627836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to offline
58637836SJohn.Forte@Sun.COM  */
58647836SJohn.Forte@Sun.COM int
stmfOfflineLogicalUnit(stmfGuid * lu)58657836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu)
58667836SJohn.Forte@Sun.COM {
58677836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
58687836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
58697836SJohn.Forte@Sun.COM 	int fd;
58707836SJohn.Forte@Sun.COM 
58717836SJohn.Forte@Sun.COM 	if (lu == NULL) {
58727836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
58737836SJohn.Forte@Sun.COM 	}
58747836SJohn.Forte@Sun.COM 
58757836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
58767836SJohn.Forte@Sun.COM 
58777836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_OFFLINE;
58787836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
58797836SJohn.Forte@Sun.COM 	/*
58807836SJohn.Forte@Sun.COM 	 * Open control node for stmf
58817836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
58827836SJohn.Forte@Sun.COM 	 */
58837836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
58847836SJohn.Forte@Sun.COM 		return (ret);
58857836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
58867836SJohn.Forte@Sun.COM 	(void) close(fd);
58877836SJohn.Forte@Sun.COM 	return (ret);
58887836SJohn.Forte@Sun.COM }
58897836SJohn.Forte@Sun.COM 
58907836SJohn.Forte@Sun.COM /*
58917836SJohn.Forte@Sun.COM  * stmfOnlineTarget
58927836SJohn.Forte@Sun.COM  *
58937836SJohn.Forte@Sun.COM  * Purpose: Change state of target to online
58947836SJohn.Forte@Sun.COM  *
58957836SJohn.Forte@Sun.COM  * devid - devid of the target to online
58967836SJohn.Forte@Sun.COM  */
58977836SJohn.Forte@Sun.COM int
stmfOnlineTarget(stmfDevid * devid)58987836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid)
58997836SJohn.Forte@Sun.COM {
59007836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
59017836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
59027836SJohn.Forte@Sun.COM 	int fd;
59037836SJohn.Forte@Sun.COM 
59047836SJohn.Forte@Sun.COM 	if (devid == NULL) {
59057836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
59067836SJohn.Forte@Sun.COM 	}
59077836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
59087836SJohn.Forte@Sun.COM 
59097836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_ONLINE;
59107836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
59117836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
59127836SJohn.Forte@Sun.COM 	    devid->identLength);
59137836SJohn.Forte@Sun.COM 	/*
59147836SJohn.Forte@Sun.COM 	 * Open control node for stmf
59157836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
59167836SJohn.Forte@Sun.COM 	 */
59177836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
59187836SJohn.Forte@Sun.COM 		return (ret);
59197836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
59207836SJohn.Forte@Sun.COM 	(void) close(fd);
59217836SJohn.Forte@Sun.COM 	return (ret);
59227836SJohn.Forte@Sun.COM }
59237836SJohn.Forte@Sun.COM 
59247836SJohn.Forte@Sun.COM /*
59257836SJohn.Forte@Sun.COM  * stmfOnlineLogicalUnit
59267836SJohn.Forte@Sun.COM  *
59277836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to online
59287836SJohn.Forte@Sun.COM  *
59297836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to online
59307836SJohn.Forte@Sun.COM  */
59317836SJohn.Forte@Sun.COM int
stmfOnlineLogicalUnit(stmfGuid * lu)59327836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu)
59337836SJohn.Forte@Sun.COM {
59347836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
59357836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
59367836SJohn.Forte@Sun.COM 	int fd;
59377836SJohn.Forte@Sun.COM 
59387836SJohn.Forte@Sun.COM 	if (lu == NULL) {
59397836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
59407836SJohn.Forte@Sun.COM 	}
59417836SJohn.Forte@Sun.COM 
59427836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
59437836SJohn.Forte@Sun.COM 
59447836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_ONLINE;
59457836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
59467836SJohn.Forte@Sun.COM 	/*
59477836SJohn.Forte@Sun.COM 	 * Open control node for stmf
59487836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
59497836SJohn.Forte@Sun.COM 	 */
59507836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
59517836SJohn.Forte@Sun.COM 		return (ret);
59527836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
59537836SJohn.Forte@Sun.COM 	(void) close(fd);
59547836SJohn.Forte@Sun.COM 	return (ret);
59557836SJohn.Forte@Sun.COM }
59567836SJohn.Forte@Sun.COM 
59577836SJohn.Forte@Sun.COM /*
59587836SJohn.Forte@Sun.COM  * stmfRemoveFromHostGroup
59597836SJohn.Forte@Sun.COM  *
59607836SJohn.Forte@Sun.COM  * Purpose: Removes an initiator from an initiator group
59617836SJohn.Forte@Sun.COM  *
59627836SJohn.Forte@Sun.COM  * hostGroupName - name of an initiator group
59637836SJohn.Forte@Sun.COM  * hostName - name of host group member to remove
59647836SJohn.Forte@Sun.COM  */
59657836SJohn.Forte@Sun.COM int
stmfRemoveFromHostGroup(stmfGroupName * hostGroupName,stmfDevid * hostName)59667836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
59677836SJohn.Forte@Sun.COM {
59687836SJohn.Forte@Sun.COM 	int ret;
59697836SJohn.Forte@Sun.COM 	int fd;
59707836SJohn.Forte@Sun.COM 
59717836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
59727836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
59737836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
59747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
59757836SJohn.Forte@Sun.COM 	}
59767836SJohn.Forte@Sun.COM 
59777836SJohn.Forte@Sun.COM 	/* call init */
59787836SJohn.Forte@Sun.COM 	ret = initializeConfig();
59797836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
59807836SJohn.Forte@Sun.COM 		return (ret);
59817836SJohn.Forte@Sun.COM 	}
59827836SJohn.Forte@Sun.COM 
59837836SJohn.Forte@Sun.COM 	/*
59847836SJohn.Forte@Sun.COM 	 * Open control node for stmf
59857836SJohn.Forte@Sun.COM 	 */
59867836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
59877836SJohn.Forte@Sun.COM 		return (ret);
59887836SJohn.Forte@Sun.COM 
59897836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
59907836SJohn.Forte@Sun.COM 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
59917836SJohn.Forte@Sun.COM 		goto done;
59927836SJohn.Forte@Sun.COM 	}
59937836SJohn.Forte@Sun.COM 
59949585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
59959585STim.Szeto@Sun.COM 		goto done;
59969585STim.Szeto@Sun.COM 	}
59979585STim.Szeto@Sun.COM 
59987836SJohn.Forte@Sun.COM 	ret = psRemoveHostGroupMember((char *)hostGroupName,
59997836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
60007836SJohn.Forte@Sun.COM 	switch (ret) {
60017836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
60027836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
60037836SJohn.Forte@Sun.COM 			break;
60047836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
60057836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
60067836SJohn.Forte@Sun.COM 			break;
60077836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
60087836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
60097836SJohn.Forte@Sun.COM 			break;
60107836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
60117836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
60127836SJohn.Forte@Sun.COM 			break;
60137836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
60147836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
60157836SJohn.Forte@Sun.COM 			break;
60167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
60177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
60187836SJohn.Forte@Sun.COM 			break;
60197836SJohn.Forte@Sun.COM 		default:
60207836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
60217836SJohn.Forte@Sun.COM 			    "stmfRemoveFromHostGroup"
60227836SJohn.Forte@Sun.COM 			    "psRemoveHostGroupMember:error(%d)", ret);
60237836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
60247836SJohn.Forte@Sun.COM 			break;
60257836SJohn.Forte@Sun.COM 	}
60267836SJohn.Forte@Sun.COM 
60277836SJohn.Forte@Sun.COM done:
60287836SJohn.Forte@Sun.COM 	(void) close(fd);
60297836SJohn.Forte@Sun.COM 	return (ret);
60307836SJohn.Forte@Sun.COM }
60317836SJohn.Forte@Sun.COM 
60327836SJohn.Forte@Sun.COM /*
60337836SJohn.Forte@Sun.COM  * stmfRemoveFromTargetGroup
60347836SJohn.Forte@Sun.COM  *
60357836SJohn.Forte@Sun.COM  * Purpose: Removes a local port from a local port group
60367836SJohn.Forte@Sun.COM  *
60377836SJohn.Forte@Sun.COM  * targetGroupName - name of a target group
60387836SJohn.Forte@Sun.COM  * targetName - name of target to remove
60397836SJohn.Forte@Sun.COM  */
60407836SJohn.Forte@Sun.COM int
stmfRemoveFromTargetGroup(stmfGroupName * targetGroupName,stmfDevid * targetName)60417836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
60427836SJohn.Forte@Sun.COM {
60437836SJohn.Forte@Sun.COM 	int ret;
60447836SJohn.Forte@Sun.COM 	int fd;
60457836SJohn.Forte@Sun.COM 
60467836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
60477836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
60487836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
60497836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
60507836SJohn.Forte@Sun.COM 	}
60517836SJohn.Forte@Sun.COM 
60527836SJohn.Forte@Sun.COM 	/* call init */
60537836SJohn.Forte@Sun.COM 	ret = initializeConfig();
60547836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
60557836SJohn.Forte@Sun.COM 		return (ret);
60567836SJohn.Forte@Sun.COM 	}
60577836SJohn.Forte@Sun.COM 
60587836SJohn.Forte@Sun.COM 	/*
60597836SJohn.Forte@Sun.COM 	 * Open control node for stmf
60607836SJohn.Forte@Sun.COM 	 */
60617836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
60627836SJohn.Forte@Sun.COM 		return (ret);
60637836SJohn.Forte@Sun.COM 
60647836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
60657836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
60667836SJohn.Forte@Sun.COM 		goto done;
60677836SJohn.Forte@Sun.COM 	}
60687836SJohn.Forte@Sun.COM 
60699585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
60709585STim.Szeto@Sun.COM 		goto done;
60719585STim.Szeto@Sun.COM 	}
60729585STim.Szeto@Sun.COM 
60737836SJohn.Forte@Sun.COM 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
60747836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
60757836SJohn.Forte@Sun.COM 	switch (ret) {
60767836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
60777836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
60787836SJohn.Forte@Sun.COM 			break;
60797836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
60807836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
60817836SJohn.Forte@Sun.COM 			break;
60827836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
60837836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
60847836SJohn.Forte@Sun.COM 			break;
60857836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
60867836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
60877836SJohn.Forte@Sun.COM 			break;
60887836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
60897836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
60907836SJohn.Forte@Sun.COM 			break;
60917836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
60927836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
60937836SJohn.Forte@Sun.COM 			break;
60947836SJohn.Forte@Sun.COM 		default:
60957836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
60967836SJohn.Forte@Sun.COM 			    "stmfRemoveFromTargetGroup"
60977836SJohn.Forte@Sun.COM 			    "psRemoveTargetGroupMember:error(%d)", ret);
60987836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
60997836SJohn.Forte@Sun.COM 			break;
61007836SJohn.Forte@Sun.COM 	}
61017836SJohn.Forte@Sun.COM 
61027836SJohn.Forte@Sun.COM done:
61037836SJohn.Forte@Sun.COM 	(void) close(fd);
61047836SJohn.Forte@Sun.COM 	return (ret);
61057836SJohn.Forte@Sun.COM }
61067836SJohn.Forte@Sun.COM 
61077836SJohn.Forte@Sun.COM /*
61087836SJohn.Forte@Sun.COM  * stmfRemoveViewEntry
61097836SJohn.Forte@Sun.COM  *
61107836SJohn.Forte@Sun.COM  * Purpose: Removes a view entry from a logical unit
61117836SJohn.Forte@Sun.COM  *
61127836SJohn.Forte@Sun.COM  * lu - guid of lu for which view entry is being removed
61137836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry to remove
61147836SJohn.Forte@Sun.COM  *
61157836SJohn.Forte@Sun.COM  */
61167836SJohn.Forte@Sun.COM int
stmfRemoveViewEntry(stmfGuid * lu,uint32_t viewEntryIndex)61177836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
61187836SJohn.Forte@Sun.COM {
61197836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
61207836SJohn.Forte@Sun.COM 	int fd;
61217836SJohn.Forte@Sun.COM 	int ioctlRet;
61227836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
61237836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
61247836SJohn.Forte@Sun.COM 
61257836SJohn.Forte@Sun.COM 	if (lu == NULL) {
61267836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
61277836SJohn.Forte@Sun.COM 	}
61287836SJohn.Forte@Sun.COM 
61297836SJohn.Forte@Sun.COM 	/* call init */
61307836SJohn.Forte@Sun.COM 	ret = initializeConfig();
61317836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
61327836SJohn.Forte@Sun.COM 		return (ret);
61337836SJohn.Forte@Sun.COM 	}
61347836SJohn.Forte@Sun.COM 
61357836SJohn.Forte@Sun.COM 	/*
61367836SJohn.Forte@Sun.COM 	 * Open control node for stmf
61377836SJohn.Forte@Sun.COM 	 */
61387836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
61397836SJohn.Forte@Sun.COM 		return (ret);
61407836SJohn.Forte@Sun.COM 
61417836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
61427836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
61437836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx = viewEntryIndex;
61447836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
61457836SJohn.Forte@Sun.COM 
61467836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
61477836SJohn.Forte@Sun.COM 	/*
61487836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
61497836SJohn.Forte@Sun.COM 	 */
61507836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
61517836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
61527836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
61537836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
61547836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
61557836SJohn.Forte@Sun.COM 		switch (errno) {
61567836SJohn.Forte@Sun.COM 			case EBUSY:
61577836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
61587836SJohn.Forte@Sun.COM 				break;
61599585STim.Szeto@Sun.COM 			case EPERM:
61609585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
61619585STim.Szeto@Sun.COM 				break;
61627836SJohn.Forte@Sun.COM 			case EACCES:
61637836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
61647836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
61657836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
61667836SJohn.Forte@Sun.COM 						break;
61677836SJohn.Forte@Sun.COM 					default:
61687836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
61697836SJohn.Forte@Sun.COM 						break;
61707836SJohn.Forte@Sun.COM 				}
61717836SJohn.Forte@Sun.COM 				break;
61727836SJohn.Forte@Sun.COM 			case ENODEV:
61737836SJohn.Forte@Sun.COM 			case ENOENT:
61747836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
61757836SJohn.Forte@Sun.COM 				break;
61767836SJohn.Forte@Sun.COM 			default:
61777836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
61787836SJohn.Forte@Sun.COM 				    "stmfRemoveViewEntry:ioctl errno(%d)",
61797836SJohn.Forte@Sun.COM 				    errno);
61807836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
61817836SJohn.Forte@Sun.COM 				break;
61827836SJohn.Forte@Sun.COM 		}
61837836SJohn.Forte@Sun.COM 		goto done;
61847836SJohn.Forte@Sun.COM 	}
61857836SJohn.Forte@Sun.COM 
61869585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
61879585STim.Szeto@Sun.COM 		goto done;
61889585STim.Szeto@Sun.COM 	}
61899585STim.Szeto@Sun.COM 
61907836SJohn.Forte@Sun.COM 	ret = psRemoveViewEntry(lu, viewEntryIndex);
61917836SJohn.Forte@Sun.COM 	switch (ret) {
61927836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
61937836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
61947836SJohn.Forte@Sun.COM 			break;
61957836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
61967836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
61977836SJohn.Forte@Sun.COM 			break;
61987836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
61997836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
62007836SJohn.Forte@Sun.COM 			break;
62017836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
62027836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
62037836SJohn.Forte@Sun.COM 			break;
62047836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
62057836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
62067836SJohn.Forte@Sun.COM 			break;
62077836SJohn.Forte@Sun.COM 		default:
62087836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
62097836SJohn.Forte@Sun.COM 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
62107836SJohn.Forte@Sun.COM 			    ret);
62117836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
62127836SJohn.Forte@Sun.COM 			break;
62137836SJohn.Forte@Sun.COM 	}
62147836SJohn.Forte@Sun.COM 
62157836SJohn.Forte@Sun.COM done:
62167836SJohn.Forte@Sun.COM 	(void) close(fd);
62177836SJohn.Forte@Sun.COM 	return (ret);
62187836SJohn.Forte@Sun.COM }
62197836SJohn.Forte@Sun.COM 
62207836SJohn.Forte@Sun.COM /*
62217836SJohn.Forte@Sun.COM  * stmfSetProviderData
62227836SJohn.Forte@Sun.COM  *
62237836SJohn.Forte@Sun.COM  * Purpose: set the provider data
62247836SJohn.Forte@Sun.COM  *
62257836SJohn.Forte@Sun.COM  * providerName - unique name of provider
62267836SJohn.Forte@Sun.COM  * nvl - nvlist to set
62277836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
62287836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
62297836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
62307836SJohn.Forte@Sun.COM  */
62317836SJohn.Forte@Sun.COM int
stmfSetProviderData(char * providerName,nvlist_t * nvl,int providerType)62327836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
62337836SJohn.Forte@Sun.COM {
62347836SJohn.Forte@Sun.COM 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
62357836SJohn.Forte@Sun.COM 	    NULL));
62367836SJohn.Forte@Sun.COM }
62377836SJohn.Forte@Sun.COM 
62387836SJohn.Forte@Sun.COM /*
62397836SJohn.Forte@Sun.COM  * stmfSetProviderDataProt
62407836SJohn.Forte@Sun.COM  *
62417836SJohn.Forte@Sun.COM  * Purpose: set the provider data
62427836SJohn.Forte@Sun.COM  *
62437836SJohn.Forte@Sun.COM  * providerName - unique name of provider
62447836SJohn.Forte@Sun.COM  * nvl - nvlist to set
62457836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
62467836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
62477836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
62487836SJohn.Forte@Sun.COM  * setToken - Stale data token returned in the stmfGetProviderDataProt()
62497836SJohn.Forte@Sun.COM  *	      call or NULL.
62507836SJohn.Forte@Sun.COM  */
62517836SJohn.Forte@Sun.COM int
stmfSetProviderDataProt(char * providerName,nvlist_t * nvl,int providerType,uint64_t * setToken)62527836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
62537836SJohn.Forte@Sun.COM     uint64_t *setToken)
62547836SJohn.Forte@Sun.COM {
62557836SJohn.Forte@Sun.COM 	int ret;
62567836SJohn.Forte@Sun.COM 	int fd;
62577836SJohn.Forte@Sun.COM 
62587836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
62597836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
62607836SJohn.Forte@Sun.COM 	}
62617836SJohn.Forte@Sun.COM 
62627836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
62637836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
62647836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
62657836SJohn.Forte@Sun.COM 	}
62667836SJohn.Forte@Sun.COM 
62677836SJohn.Forte@Sun.COM 	/* call init */
62687836SJohn.Forte@Sun.COM 	ret = initializeConfig();
62697836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
62707836SJohn.Forte@Sun.COM 		return (ret);
62717836SJohn.Forte@Sun.COM 	}
62727836SJohn.Forte@Sun.COM 
62737836SJohn.Forte@Sun.COM 	/*
62747836SJohn.Forte@Sun.COM 	 * Open control node for stmf
62757836SJohn.Forte@Sun.COM 	 */
62767836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
62777836SJohn.Forte@Sun.COM 		return (ret);
62787836SJohn.Forte@Sun.COM 
62799585STim.Szeto@Sun.COM 	ret = setProviderData(fd, providerName, nvl, providerType, setToken);
62807836SJohn.Forte@Sun.COM 
62817836SJohn.Forte@Sun.COM 	(void) close(fd);
62827836SJohn.Forte@Sun.COM 
62837836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
62847836SJohn.Forte@Sun.COM 		goto done;
62857836SJohn.Forte@Sun.COM 	}
62867836SJohn.Forte@Sun.COM 
62879585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
62889585STim.Szeto@Sun.COM 		goto done;
62899585STim.Szeto@Sun.COM 	}
62909585STim.Szeto@Sun.COM 
62917836SJohn.Forte@Sun.COM 	/* setting driver provider data successful. Now persist it */
62929585STim.Szeto@Sun.COM 	ret = psSetProviderData(providerName, nvl, providerType, NULL);
62937836SJohn.Forte@Sun.COM 	switch (ret) {
62947836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
62957836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
62967836SJohn.Forte@Sun.COM 			break;
62977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
62987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
62997836SJohn.Forte@Sun.COM 			break;
63007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
63017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
63027836SJohn.Forte@Sun.COM 			break;
63037836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
63047836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
63057836SJohn.Forte@Sun.COM 			break;
63067836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
63077836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
63087836SJohn.Forte@Sun.COM 			break;
63097836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_PROV_DATA_STALE:
63107836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PROV_DATA_STALE;
63117836SJohn.Forte@Sun.COM 			break;
63127836SJohn.Forte@Sun.COM 		default:
63137836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
63147836SJohn.Forte@Sun.COM 			    "stmfSetProviderData"
63157836SJohn.Forte@Sun.COM 			    "psSetProviderData:error(%d)", ret);
63167836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
63177836SJohn.Forte@Sun.COM 			break;
63187836SJohn.Forte@Sun.COM 	}
63197836SJohn.Forte@Sun.COM 
63207836SJohn.Forte@Sun.COM done:
63217836SJohn.Forte@Sun.COM 	return (ret);
63227836SJohn.Forte@Sun.COM }
63237836SJohn.Forte@Sun.COM 
63247836SJohn.Forte@Sun.COM /*
63259585STim.Szeto@Sun.COM  * getProviderData
63269585STim.Szeto@Sun.COM  *
63279585STim.Szeto@Sun.COM  * Purpose: set the provider data from stmf
63289585STim.Szeto@Sun.COM  *
63299585STim.Szeto@Sun.COM  * providerName - unique name of provider
63309585STim.Szeto@Sun.COM  * nvl - nvlist to load/retrieve
63319585STim.Szeto@Sun.COM  * providerType - logical unit or port provider
63329585STim.Szeto@Sun.COM  * setToken - returned stale data token
63339585STim.Szeto@Sun.COM  */
63349585STim.Szeto@Sun.COM int
getProviderData(char * providerName,nvlist_t ** nvl,int providerType,uint64_t * setToken)63359585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType,
63369585STim.Szeto@Sun.COM     uint64_t *setToken)
63379585STim.Szeto@Sun.COM {
63389585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
63399585STim.Szeto@Sun.COM 	int fd;
63409585STim.Szeto@Sun.COM 	int ioctlRet;
63419585STim.Szeto@Sun.COM 	size_t nvlistSize = ALLOC_PP_DATA_SIZE;
63429585STim.Szeto@Sun.COM 	int retryCnt = 0;
63439585STim.Szeto@Sun.COM 	int retryCntMax = MAX_PROVIDER_RETRY;
63449585STim.Szeto@Sun.COM 	stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
63459585STim.Szeto@Sun.COM 	boolean_t retry = B_TRUE;
63469585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
63479585STim.Szeto@Sun.COM 
63489585STim.Szeto@Sun.COM 	if (providerName == NULL) {
63499585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
63509585STim.Szeto@Sun.COM 	}
63519585STim.Szeto@Sun.COM 
63529585STim.Szeto@Sun.COM 	/*
63539585STim.Szeto@Sun.COM 	 * Open control node for stmf
63549585STim.Szeto@Sun.COM 	 */
63559585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
63569585STim.Szeto@Sun.COM 		return (ret);
63579585STim.Szeto@Sun.COM 
63589585STim.Szeto@Sun.COM 	/* set provider name and provider type */
63599585STim.Szeto@Sun.COM 	if (strlcpy(ppi.ppi_name, providerName,
63609585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) >=
63619585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) {
63629585STim.Szeto@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
63639585STim.Szeto@Sun.COM 		goto done;
63649585STim.Szeto@Sun.COM 	}
63659585STim.Szeto@Sun.COM 	switch (providerType) {
63669585STim.Szeto@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
63679585STim.Szeto@Sun.COM 			ppi.ppi_lu_provider = 1;
63689585STim.Szeto@Sun.COM 			break;
63699585STim.Szeto@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
63709585STim.Szeto@Sun.COM 			ppi.ppi_port_provider = 1;
63719585STim.Szeto@Sun.COM 			break;
63729585STim.Szeto@Sun.COM 		default:
63739585STim.Szeto@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
63749585STim.Szeto@Sun.COM 			goto done;
63759585STim.Szeto@Sun.COM 	}
63769585STim.Szeto@Sun.COM 
63779585STim.Szeto@Sun.COM 	do {
63789585STim.Szeto@Sun.COM 		/* allocate memory for ioctl */
63799585STim.Szeto@Sun.COM 		ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
63809585STim.Szeto@Sun.COM 		    sizeof (stmf_ppioctl_data_t));
63819585STim.Szeto@Sun.COM 		if (ppi_out == NULL) {
63829585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
63839585STim.Szeto@Sun.COM 			goto done;
63849585STim.Szeto@Sun.COM 
63859585STim.Szeto@Sun.COM 		}
63869585STim.Szeto@Sun.COM 
63879585STim.Szeto@Sun.COM 		/* set the size of the ioctl data to allocated buffer */
63889585STim.Szeto@Sun.COM 		ppi.ppi_data_size = nvlistSize;
63899585STim.Szeto@Sun.COM 
63909585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
63919585STim.Szeto@Sun.COM 
63929585STim.Szeto@Sun.COM 		stmfIoctl.stmf_version = STMF_VERSION_1;
63939585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
63949585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
63959585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
63969585STim.Szeto@Sun.COM 		    nvlistSize;
63979585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
63989585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
63999585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
64009585STim.Szeto@Sun.COM 			switch (errno) {
64019585STim.Szeto@Sun.COM 				case EBUSY:
64029585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
64039585STim.Szeto@Sun.COM 					break;
64049585STim.Szeto@Sun.COM 				case EPERM:
64059585STim.Szeto@Sun.COM 				case EACCES:
64069585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
64079585STim.Szeto@Sun.COM 					break;
64089585STim.Szeto@Sun.COM 				case EINVAL:
64099585STim.Szeto@Sun.COM 					if (stmfIoctl.stmf_error ==
64109585STim.Szeto@Sun.COM 					    STMF_IOCERR_INSUFFICIENT_BUF) {
64119585STim.Szeto@Sun.COM 						nvlistSize =
64129585STim.Szeto@Sun.COM 						    ppi_out->ppi_data_size;
64139585STim.Szeto@Sun.COM 						free(ppi_out);
64149585STim.Szeto@Sun.COM 						ppi_out = NULL;
64159585STim.Szeto@Sun.COM 						if (retryCnt++ > retryCntMax) {
64169585STim.Szeto@Sun.COM 							retry = B_FALSE;
64179585STim.Szeto@Sun.COM 							ret = STMF_ERROR_BUSY;
64189585STim.Szeto@Sun.COM 						} else {
64199585STim.Szeto@Sun.COM 							ret =
64209585STim.Szeto@Sun.COM 							    STMF_STATUS_SUCCESS;
64219585STim.Szeto@Sun.COM 						}
64229585STim.Szeto@Sun.COM 					} else {
64239585STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
64249585STim.Szeto@Sun.COM 						    "getProviderData:ioctl"
64259585STim.Szeto@Sun.COM 						    "unable to retrieve "
64269585STim.Szeto@Sun.COM 						    "nvlist");
64279585STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
64289585STim.Szeto@Sun.COM 					}
64299585STim.Szeto@Sun.COM 					break;
64309585STim.Szeto@Sun.COM 				case ENOENT:
64319585STim.Szeto@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
64329585STim.Szeto@Sun.COM 					break;
64339585STim.Szeto@Sun.COM 				default:
64349585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
64359585STim.Szeto@Sun.COM 					    "getProviderData:ioctl errno(%d)",
64369585STim.Szeto@Sun.COM 					    errno);
64379585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
64389585STim.Szeto@Sun.COM 					break;
64399585STim.Szeto@Sun.COM 			}
64409585STim.Szeto@Sun.COM 			if (ret != STMF_STATUS_SUCCESS)
64419585STim.Szeto@Sun.COM 				goto done;
64429585STim.Szeto@Sun.COM 		}
64439585STim.Szeto@Sun.COM 	} while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
64449585STim.Szeto@Sun.COM 
64459585STim.Szeto@Sun.COM 	if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
64469585STim.Szeto@Sun.COM 	    ppi_out->ppi_data_size, nvl, 0)) != 0) {
64479585STim.Szeto@Sun.COM 		ret = STMF_STATUS_ERROR;
64489585STim.Szeto@Sun.COM 		goto done;
64499585STim.Szeto@Sun.COM 	}
64509585STim.Szeto@Sun.COM 
64519585STim.Szeto@Sun.COM 	/* caller has asked for new token */
64529585STim.Szeto@Sun.COM 	if (setToken) {
64539585STim.Szeto@Sun.COM 		*setToken = ppi_out->ppi_token;
64549585STim.Szeto@Sun.COM 	}
64559585STim.Szeto@Sun.COM done:
64569585STim.Szeto@Sun.COM 	free(ppi_out);
64579585STim.Szeto@Sun.COM 	(void) close(fd);
64589585STim.Szeto@Sun.COM 	return (ret);
64599585STim.Szeto@Sun.COM }
64609585STim.Szeto@Sun.COM 
64619585STim.Szeto@Sun.COM /*
64627836SJohn.Forte@Sun.COM  * setProviderData
64637836SJohn.Forte@Sun.COM  *
64649585STim.Szeto@Sun.COM  * Purpose: set the provider data in stmf
64657836SJohn.Forte@Sun.COM  *
64667836SJohn.Forte@Sun.COM  * providerName - unique name of provider
64677836SJohn.Forte@Sun.COM  * nvl - nvlist to set
64687836SJohn.Forte@Sun.COM  * providerType - logical unit or port provider
64699585STim.Szeto@Sun.COM  * setToken - stale data token to check if not NULL
64707836SJohn.Forte@Sun.COM  */
64717836SJohn.Forte@Sun.COM static int
setProviderData(int fd,char * providerName,nvlist_t * nvl,int providerType,uint64_t * setToken)64729585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
64739585STim.Szeto@Sun.COM     uint64_t *setToken)
64747836SJohn.Forte@Sun.COM {
64757836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
64767836SJohn.Forte@Sun.COM 	int ioctlRet;
64777836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
64787836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t *ppi = NULL;
64799585STim.Szeto@Sun.COM 	uint64_t outToken;
64807836SJohn.Forte@Sun.COM 	char *allocatedNvBuffer;
64817836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
64827836SJohn.Forte@Sun.COM 
64837836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
64847836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
64857836SJohn.Forte@Sun.COM 	}
64867836SJohn.Forte@Sun.COM 
64877836SJohn.Forte@Sun.COM 	/* get size of encoded nvlist */
64887836SJohn.Forte@Sun.COM 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
64897836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
64907836SJohn.Forte@Sun.COM 	}
64917836SJohn.Forte@Sun.COM 
64927836SJohn.Forte@Sun.COM 	/* allocate memory for ioctl */
64937836SJohn.Forte@Sun.COM 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
64947836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t));
64957836SJohn.Forte@Sun.COM 	if (ppi == NULL) {
64967836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
64977836SJohn.Forte@Sun.COM 	}
64987836SJohn.Forte@Sun.COM 
64999585STim.Szeto@Sun.COM 	if (setToken) {
65009585STim.Szeto@Sun.COM 		ppi->ppi_token_valid = 1;
65019585STim.Szeto@Sun.COM 		ppi->ppi_token = *setToken;
65029585STim.Szeto@Sun.COM 	}
65039585STim.Szeto@Sun.COM 
65047836SJohn.Forte@Sun.COM 	allocatedNvBuffer = (char *)&ppi->ppi_data;
65057836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
65067836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
65077836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
65087836SJohn.Forte@Sun.COM 	}
65097836SJohn.Forte@Sun.COM 
65107836SJohn.Forte@Sun.COM 	/* set provider name and provider type */
65117836SJohn.Forte@Sun.COM 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
65127836SJohn.Forte@Sun.COM 	switch (providerType) {
65137836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
65147836SJohn.Forte@Sun.COM 			ppi->ppi_lu_provider = 1;
65157836SJohn.Forte@Sun.COM 			break;
65167836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
65177836SJohn.Forte@Sun.COM 			ppi->ppi_port_provider = 1;
65187836SJohn.Forte@Sun.COM 			break;
65197836SJohn.Forte@Sun.COM 		default:
65207836SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
65217836SJohn.Forte@Sun.COM 	}
65227836SJohn.Forte@Sun.COM 
65237836SJohn.Forte@Sun.COM 	/* set the size of the ioctl data to packed data size */
65247836SJohn.Forte@Sun.COM 	ppi->ppi_data_size = nvlistEncodedSize;
65257836SJohn.Forte@Sun.COM 
65267836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
65277836SJohn.Forte@Sun.COM 
65287836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
65297836SJohn.Forte@Sun.COM 	/*
65307836SJohn.Forte@Sun.COM 	 * Subtracting 8 from the size as that is the size of the last member
65317836SJohn.Forte@Sun.COM 	 * of the structure where the packed data resides
65327836SJohn.Forte@Sun.COM 	 */
65337836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
65347836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t) - 8;
65357836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
65369585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
65379585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
65387836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
65397836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
65407836SJohn.Forte@Sun.COM 		switch (errno) {
65417836SJohn.Forte@Sun.COM 			case EBUSY:
65427836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
65437836SJohn.Forte@Sun.COM 				break;
65449585STim.Szeto@Sun.COM 			case EPERM:
65457836SJohn.Forte@Sun.COM 			case EACCES:
65467836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
65477836SJohn.Forte@Sun.COM 				break;
65489585STim.Szeto@Sun.COM 			case EINVAL:
65499585STim.Szeto@Sun.COM 				if (stmfIoctl.stmf_error ==
65509585STim.Szeto@Sun.COM 				    STMF_IOCERR_PPD_UPDATED) {
65519585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PROV_DATA_STALE;
65529585STim.Szeto@Sun.COM 				} else {
65539585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
65549585STim.Szeto@Sun.COM 				}
65559585STim.Szeto@Sun.COM 				break;
65567836SJohn.Forte@Sun.COM 			default:
65577836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
65587836SJohn.Forte@Sun.COM 				    "setProviderData:ioctl errno(%d)", errno);
65597836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
65607836SJohn.Forte@Sun.COM 				break;
65617836SJohn.Forte@Sun.COM 		}
65627836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS)
65637836SJohn.Forte@Sun.COM 			goto done;
65647836SJohn.Forte@Sun.COM 	}
65657836SJohn.Forte@Sun.COM 
65669585STim.Szeto@Sun.COM 	/* caller has asked for new token */
65679585STim.Szeto@Sun.COM 	if (setToken) {
65689585STim.Szeto@Sun.COM 		*setToken = outToken;
65699585STim.Szeto@Sun.COM 	}
65707836SJohn.Forte@Sun.COM done:
65717836SJohn.Forte@Sun.COM 	free(ppi);
65727836SJohn.Forte@Sun.COM 	return (ret);
65737836SJohn.Forte@Sun.COM }
65749585STim.Szeto@Sun.COM 
65759585STim.Szeto@Sun.COM /*
65769585STim.Szeto@Sun.COM  * set the persistence method in the library only or library and service
65779585STim.Szeto@Sun.COM  */
65789585STim.Szeto@Sun.COM int
stmfSetPersistMethod(uint8_t persistType,boolean_t serviceSet)65799585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
65809585STim.Szeto@Sun.COM {
65819585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
65829585STim.Szeto@Sun.COM 	int oldPersist;
65839585STim.Szeto@Sun.COM 
65849585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
65859585STim.Szeto@Sun.COM 	oldPersist = iPersistType;
65869585STim.Szeto@Sun.COM 	if (persistType == STMF_PERSIST_NONE ||
65879585STim.Szeto@Sun.COM 	    persistType == STMF_PERSIST_SMF) {
65889585STim.Szeto@Sun.COM 		iLibSetPersist = B_TRUE;
65899585STim.Szeto@Sun.COM 		iPersistType = persistType;
65909585STim.Szeto@Sun.COM 	} else {
65919585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
65929585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
65939585STim.Szeto@Sun.COM 	}
65949585STim.Szeto@Sun.COM 	/* Is this for this library open or in SMF */
65959585STim.Szeto@Sun.COM 	if (serviceSet == B_TRUE) {
65969585STim.Szeto@Sun.COM 		ret = psSetServicePersist(persistType);
65979585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
65989585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
65999585STim.Szeto@Sun.COM 			/* Set to old value */
66009585STim.Szeto@Sun.COM 			iPersistType = oldPersist;
66019585STim.Szeto@Sun.COM 		}
66029585STim.Szeto@Sun.COM 	}
66039585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
66049585STim.Szeto@Sun.COM 
66059585STim.Szeto@Sun.COM 	return (ret);
66069585STim.Szeto@Sun.COM }
66079585STim.Szeto@Sun.COM 
66089585STim.Szeto@Sun.COM /*
66099585STim.Szeto@Sun.COM  * Only returns internal state for persist. If unset, goes to ps. If that
66109585STim.Szeto@Sun.COM  * fails, returns default setting
66119585STim.Szeto@Sun.COM  */
66129585STim.Szeto@Sun.COM static uint8_t
iGetPersistMethod()66139585STim.Szeto@Sun.COM iGetPersistMethod()
66149585STim.Szeto@Sun.COM {
66159585STim.Szeto@Sun.COM 
66169585STim.Szeto@Sun.COM 	uint8_t persistType = 0;
66179585STim.Szeto@Sun.COM 
66189585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
66199585STim.Szeto@Sun.COM 	if (iLibSetPersist) {
66209585STim.Szeto@Sun.COM 		persistType = iPersistType;
66219585STim.Szeto@Sun.COM 	} else {
66229585STim.Szeto@Sun.COM 		int ret;
66239585STim.Szeto@Sun.COM 		ret = psGetServicePersist(&persistType);
66249585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
66259585STim.Szeto@Sun.COM 			/* set to default */
66269585STim.Szeto@Sun.COM 			persistType = STMF_DEFAULT_PERSIST;
66279585STim.Szeto@Sun.COM 		}
66289585STim.Szeto@Sun.COM 	}
66299585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
66309585STim.Szeto@Sun.COM 	return (persistType);
66319585STim.Szeto@Sun.COM }
66329585STim.Szeto@Sun.COM 
66339585STim.Szeto@Sun.COM /*
66349585STim.Szeto@Sun.COM  * Returns either library state or persistent config state depending on
66359585STim.Szeto@Sun.COM  * serviceState
66369585STim.Szeto@Sun.COM  */
66379585STim.Szeto@Sun.COM int
stmfGetPersistMethod(uint8_t * persistType,boolean_t serviceState)66389585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
66399585STim.Szeto@Sun.COM {
66409585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
66419585STim.Szeto@Sun.COM 
66429585STim.Szeto@Sun.COM 	if (persistType == NULL) {
66439585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
66449585STim.Szeto@Sun.COM 	}
66459585STim.Szeto@Sun.COM 	if (serviceState) {
66469585STim.Szeto@Sun.COM 		ret = psGetServicePersist(persistType);
66479585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
66489585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
66499585STim.Szeto@Sun.COM 		}
66509585STim.Szeto@Sun.COM 	} else {
66519585STim.Szeto@Sun.COM 		(void) pthread_mutex_lock(&persistenceTypeLock);
66529585STim.Szeto@Sun.COM 		if (iLibSetPersist) {
66539585STim.Szeto@Sun.COM 			*persistType = iPersistType;
66549585STim.Szeto@Sun.COM 		} else {
66559585STim.Szeto@Sun.COM 			*persistType = STMF_DEFAULT_PERSIST;
66569585STim.Szeto@Sun.COM 		}
66579585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
66589585STim.Szeto@Sun.COM 	}
66599585STim.Szeto@Sun.COM 
66609585STim.Szeto@Sun.COM 	return (ret);
66619585STim.Szeto@Sun.COM }
666210691STim.Szeto@Sun.COM 
666310691STim.Szeto@Sun.COM /*
666410725SJohn.Forte@Sun.COM  * stmfPostProxyMsg
666510725SJohn.Forte@Sun.COM  *
666610725SJohn.Forte@Sun.COM  * Purpose: Post a message to the proxy port provider
666710725SJohn.Forte@Sun.COM  *
666810725SJohn.Forte@Sun.COM  * buf - buffer containing message to post
666910725SJohn.Forte@Sun.COM  * buflen - buffer length
667010725SJohn.Forte@Sun.COM  */
667110725SJohn.Forte@Sun.COM int
stmfPostProxyMsg(int hdl,void * buf,uint32_t buflen)667210725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen)
667310725SJohn.Forte@Sun.COM {
667410725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
667510725SJohn.Forte@Sun.COM 	int ioctlRet;
667610725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
667710725SJohn.Forte@Sun.COM 
667810725SJohn.Forte@Sun.COM 	if (buf == NULL) {
667910725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
668010725SJohn.Forte@Sun.COM 	}
668110725SJohn.Forte@Sun.COM 
668210725SJohn.Forte@Sun.COM 	/*
668310725SJohn.Forte@Sun.COM 	 * Issue ioctl to post the message
668410725SJohn.Forte@Sun.COM 	 */
668510725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
668610725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf_size = buflen;
668710725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf;
668810725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl);
668910725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
669010725SJohn.Forte@Sun.COM 		switch (errno) {
669110725SJohn.Forte@Sun.COM 			case EPERM:
669210725SJohn.Forte@Sun.COM 			case EACCES:
669310725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
669410725SJohn.Forte@Sun.COM 				break;
669510725SJohn.Forte@Sun.COM 			default:
669610725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_POST_MSG_FAILED;
669710725SJohn.Forte@Sun.COM 				break;
669810725SJohn.Forte@Sun.COM 		}
669910725SJohn.Forte@Sun.COM 	}
670010725SJohn.Forte@Sun.COM 
670110725SJohn.Forte@Sun.COM 	return (ret);
670210725SJohn.Forte@Sun.COM }
670310725SJohn.Forte@Sun.COM 
670410725SJohn.Forte@Sun.COM /*
670510725SJohn.Forte@Sun.COM  * stmfInitProxyDoor
670610725SJohn.Forte@Sun.COM  *
670710725SJohn.Forte@Sun.COM  * Purpose: Install door in proxy
670810725SJohn.Forte@Sun.COM  *
670910725SJohn.Forte@Sun.COM  * hdl - pointer to returned handle
671010725SJohn.Forte@Sun.COM  * fd - door from door_create()
671110725SJohn.Forte@Sun.COM  */
671210725SJohn.Forte@Sun.COM int
stmfInitProxyDoor(int * hdl,int door)671310725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door)
671410725SJohn.Forte@Sun.COM {
671510725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
671610725SJohn.Forte@Sun.COM 	int ioctlRet;
671710725SJohn.Forte@Sun.COM 	int fd;
671810725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
671910725SJohn.Forte@Sun.COM 
672010725SJohn.Forte@Sun.COM 	if (hdl == NULL) {
672110725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
672210725SJohn.Forte@Sun.COM 	}
672310725SJohn.Forte@Sun.COM 
672410725SJohn.Forte@Sun.COM 	/*
672510725SJohn.Forte@Sun.COM 	 * Open control node for pppt
672610725SJohn.Forte@Sun.COM 	 */
672710725SJohn.Forte@Sun.COM 	if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) {
672810725SJohn.Forte@Sun.COM 		return (ret);
672910725SJohn.Forte@Sun.COM 	}
673010725SJohn.Forte@Sun.COM 
673110725SJohn.Forte@Sun.COM 	/*
673210725SJohn.Forte@Sun.COM 	 * Issue ioctl to install the door
673310725SJohn.Forte@Sun.COM 	 */
673410725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
673510725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_door_fd = (uint32_t)door;
673610725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl);
673710725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
673810725SJohn.Forte@Sun.COM 		switch (errno) {
673910725SJohn.Forte@Sun.COM 			case EPERM:
674010725SJohn.Forte@Sun.COM 			case EACCES:
674110725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
674210725SJohn.Forte@Sun.COM 				break;
674310725SJohn.Forte@Sun.COM 			case EINVAL:
674410725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_INVALID_ARG;
674510725SJohn.Forte@Sun.COM 				break;
674610725SJohn.Forte@Sun.COM 			case EBUSY:
674710725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_DOOR_INSTALLED;
674810725SJohn.Forte@Sun.COM 				break;
674910725SJohn.Forte@Sun.COM 			default:
675010725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
675110725SJohn.Forte@Sun.COM 				break;
675210725SJohn.Forte@Sun.COM 		}
675310725SJohn.Forte@Sun.COM 	}
675410725SJohn.Forte@Sun.COM 
675510725SJohn.Forte@Sun.COM 	/* return driver fd to caller */
675610725SJohn.Forte@Sun.COM 	*hdl = fd;
675710725SJohn.Forte@Sun.COM 	return (ret);
675810725SJohn.Forte@Sun.COM }
675910725SJohn.Forte@Sun.COM 
676010725SJohn.Forte@Sun.COM void
stmfDestroyProxyDoor(int hdl)676110725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl)
676210725SJohn.Forte@Sun.COM {
676310725SJohn.Forte@Sun.COM 	(void) close(hdl);
676410725SJohn.Forte@Sun.COM }
676510725SJohn.Forte@Sun.COM 
676610725SJohn.Forte@Sun.COM /*
676710691STim.Szeto@Sun.COM  * validateLunNumIoctl
676810691STim.Szeto@Sun.COM  *
676910691STim.Szeto@Sun.COM  * Purpose: Issues ioctl to check and get available lun# in view entry
677010691STim.Szeto@Sun.COM  *
677110691STim.Szeto@Sun.COM  * viewEntry - view entry to use
677210691STim.Szeto@Sun.COM  */
677310691STim.Szeto@Sun.COM static int
validateLunNumIoctl(int fd,stmfViewEntry * viewEntry)677410691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry)
677510691STim.Szeto@Sun.COM {
677610691STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
677710691STim.Szeto@Sun.COM 	int ioctlRet;
677810691STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
677910691STim.Szeto@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
678010691STim.Szeto@Sun.COM 
678110691STim.Szeto@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
678210691STim.Szeto@Sun.COM 	/*
678310691STim.Szeto@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
678410691STim.Szeto@Sun.COM 	 * false on input
678510691STim.Szeto@Sun.COM 	 */
678610691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
678710691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
678810691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
678910691STim.Szeto@Sun.COM 
679010691STim.Szeto@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
679110691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
679210691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
679310691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
679410691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
679510691STim.Szeto@Sun.COM 	}
679610691STim.Szeto@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
679710691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup,
679810691STim.Szeto@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
679910691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
680010691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
680110691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
680210691STim.Szeto@Sun.COM 	}
680310691STim.Szeto@Sun.COM 	/* Validating the lun number */
680410691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
680510691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
680610691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
680710691STim.Szeto@Sun.COM 	}
680810691STim.Szeto@Sun.COM 
680910691STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
681010691STim.Szeto@Sun.COM 	/*
681110691STim.Szeto@Sun.COM 	 * Issue ioctl to validate lun# in the view entry
681210691STim.Szeto@Sun.COM 	 */
681310691STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
681410691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
681510691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
681610691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
681710691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
681810691STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl);
681910691STim.Szeto@Sun.COM 
682010691STim.Szeto@Sun.COM 	/* save available lun number */
682110691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
682210691STim.Szeto@Sun.COM 		bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
682310691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
682410691STim.Szeto@Sun.COM 	}
682510691STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
682610691STim.Szeto@Sun.COM 		switch (errno) {
682710691STim.Szeto@Sun.COM 			case EBUSY:
682810691STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
682910691STim.Szeto@Sun.COM 				break;
683010691STim.Szeto@Sun.COM 			case EPERM:
683110691STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
683210691STim.Szeto@Sun.COM 				break;
683310691STim.Szeto@Sun.COM 			case EACCES:
683410691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
683510691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
683610691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
683710691STim.Szeto@Sun.COM 						break;
683810691STim.Szeto@Sun.COM 					default:
683910691STim.Szeto@Sun.COM 						ret = STMF_ERROR_PERM;
684010691STim.Szeto@Sun.COM 						break;
684110691STim.Szeto@Sun.COM 				}
684210691STim.Szeto@Sun.COM 				break;
684310691STim.Szeto@Sun.COM 			default:
684410691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
684510691STim.Szeto@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
684610691STim.Szeto@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
684710691STim.Szeto@Sun.COM 						break;
684810691STim.Szeto@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
684910691STim.Szeto@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
685010691STim.Szeto@Sun.COM 						break;
685110691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
685210691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
685310691STim.Szeto@Sun.COM 						break;
685410691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_HG:
685510691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
685610691STim.Szeto@Sun.COM 						break;
685710691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_TG:
685810691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
685910691STim.Szeto@Sun.COM 						break;
686010691STim.Szeto@Sun.COM 					default:
686110691STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
686210691STim.Szeto@Sun.COM 						    "addViewEntryIoctl"
686310691STim.Szeto@Sun.COM 						    ":error(%d)",
686410691STim.Szeto@Sun.COM 						    stmfIoctl.stmf_error);
686510691STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
686610691STim.Szeto@Sun.COM 						break;
686710691STim.Szeto@Sun.COM 				}
686810691STim.Szeto@Sun.COM 				break;
686910691STim.Szeto@Sun.COM 		}
687010691STim.Szeto@Sun.COM 	}
687110691STim.Szeto@Sun.COM 	return (ret);
687210691STim.Szeto@Sun.COM }
687310691STim.Szeto@Sun.COM 
687410691STim.Szeto@Sun.COM /*
687510691STim.Szeto@Sun.COM  * stmfValidateView
687610691STim.Szeto@Sun.COM  *
687710691STim.Szeto@Sun.COM  * Purpose: Validate or get lun # base on TG, HG of view entry
687810691STim.Szeto@Sun.COM  *
687910691STim.Szeto@Sun.COM  * viewEntry - view entry structure to use
688010691STim.Szeto@Sun.COM  */
688110691STim.Szeto@Sun.COM int
stmfValidateView(stmfViewEntry * viewEntry)688210691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry)
688310691STim.Szeto@Sun.COM {
688410691STim.Szeto@Sun.COM 	int ret;
688510691STim.Szeto@Sun.COM 	int fd;
688610691STim.Szeto@Sun.COM 	stmfViewEntry iViewEntry;
688710691STim.Szeto@Sun.COM 
688810691STim.Szeto@Sun.COM 	if (viewEntry == NULL) {
688910691STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
689010691STim.Szeto@Sun.COM 	}
689110691STim.Szeto@Sun.COM 
689210691STim.Szeto@Sun.COM 	/* initialize and set internal view entry */
689310691STim.Szeto@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
689410691STim.Szeto@Sun.COM 
689510691STim.Szeto@Sun.COM 	if (!viewEntry->allHosts) {
689610691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
689710691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.hostGroup));
689810691STim.Szeto@Sun.COM 	} else {
689910691STim.Szeto@Sun.COM 		iViewEntry.allHosts = B_TRUE;
690010691STim.Szeto@Sun.COM 	}
690110691STim.Szeto@Sun.COM 
690210691STim.Szeto@Sun.COM 	if (!viewEntry->allTargets) {
690310691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
690410691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.targetGroup));
690510691STim.Szeto@Sun.COM 	} else {
690610691STim.Szeto@Sun.COM 		iViewEntry.allTargets = B_TRUE;
690710691STim.Szeto@Sun.COM 	}
690810691STim.Szeto@Sun.COM 
690910691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
691010691STim.Szeto@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
691110691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
691210691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
691310691STim.Szeto@Sun.COM 	}
691410691STim.Szeto@Sun.COM 
691510691STim.Szeto@Sun.COM 	/*
691610691STim.Szeto@Sun.COM 	 * set users return view entry index valid flag to false
691710691STim.Szeto@Sun.COM 	 * in case of failure
691810691STim.Szeto@Sun.COM 	 */
691910691STim.Szeto@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
692010691STim.Szeto@Sun.COM 
692110691STim.Szeto@Sun.COM 	/* Check to ensure service exists */
692210691STim.Szeto@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
692310691STim.Szeto@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
692410691STim.Szeto@Sun.COM 	}
692510691STim.Szeto@Sun.COM 
692610691STim.Szeto@Sun.COM 	/* call init */
692710691STim.Szeto@Sun.COM 	ret = initializeConfig();
692810691STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
692910691STim.Szeto@Sun.COM 		return (ret);
693010691STim.Szeto@Sun.COM 	}
693110691STim.Szeto@Sun.COM 
693210691STim.Szeto@Sun.COM 	/*
693310691STim.Szeto@Sun.COM 	 * Open control node for stmf
693410691STim.Szeto@Sun.COM 	 */
693510691STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
693610691STim.Szeto@Sun.COM 		return (ret);
693710691STim.Szeto@Sun.COM 
693810691STim.Szeto@Sun.COM 	/*
693910691STim.Szeto@Sun.COM 	 * Validate lun# in the view entry from the driver
694010691STim.Szeto@Sun.COM 	 */
694110691STim.Szeto@Sun.COM 	ret = validateLunNumIoctl(fd, &iViewEntry);
694210691STim.Szeto@Sun.COM 	(void) close(fd);
694310691STim.Szeto@Sun.COM 
694410691STim.Szeto@Sun.COM 	/* save available lun number */
694510691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
694610691STim.Szeto@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
694710691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
694810691STim.Szeto@Sun.COM 	}
694910691STim.Szeto@Sun.COM 
695010691STim.Szeto@Sun.COM 	return (ret);
695110691STim.Szeto@Sun.COM }
6952