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