xref: /onnv-gate/usr/src/lib/libstmf/common/stmf.c (revision 10725)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
229585STim.Szeto@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include <stdlib.h>
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <wchar.h>
297836SJohn.Forte@Sun.COM #include <strings.h>
307836SJohn.Forte@Sun.COM #include <sys/types.h>
317836SJohn.Forte@Sun.COM #include <sys/stat.h>
327836SJohn.Forte@Sun.COM #include <fcntl.h>
337836SJohn.Forte@Sun.COM #include <unistd.h>
347836SJohn.Forte@Sun.COM #include <libintl.h>
357836SJohn.Forte@Sun.COM #include <errno.h>
367836SJohn.Forte@Sun.COM #include <string.h>
377836SJohn.Forte@Sun.COM #include <assert.h>
387836SJohn.Forte@Sun.COM #include <libnvpair.h>
397836SJohn.Forte@Sun.COM #include <pthread.h>
407836SJohn.Forte@Sun.COM #include <syslog.h>
417836SJohn.Forte@Sun.COM #include <libstmf.h>
427836SJohn.Forte@Sun.COM #include <netinet/in.h>
437836SJohn.Forte@Sun.COM #include <inttypes.h>
447836SJohn.Forte@Sun.COM #include <store.h>
457836SJohn.Forte@Sun.COM #include <locale.h>
469585STim.Szeto@Sun.COM #include <math.h>
479585STim.Szeto@Sun.COM #include <libstmf_impl.h>
487836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h>
499585STim.Szeto@Sun.COM #include <sys/stmf_sbd_ioctl.h>
50*10725SJohn.Forte@Sun.COM #include <sys/pppt_ioctl.h>
517836SJohn.Forte@Sun.COM 
527836SJohn.Forte@Sun.COM #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
539585STim.Szeto@Sun.COM #define	SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
54*10725SJohn.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
629585STim.Szeto@Sun.COM #define	OUI_SIZE 3
637836SJohn.Forte@Sun.COM #define	IDENT_LENGTH_BYTE 3
647836SJohn.Forte@Sun.COM 
659585STim.Szeto@Sun.COM /* various initial allocation values */
669585STim.Szeto@Sun.COM #define	ALLOC_LU		8192
679585STim.Szeto@Sun.COM #define	ALLOC_TARGET_PORT	2048
689585STim.Szeto@Sun.COM #define	ALLOC_PROVIDER		64
699585STim.Szeto@Sun.COM #define	ALLOC_GROUP		2048
709585STim.Szeto@Sun.COM #define	ALLOC_SESSION		2048
719585STim.Szeto@Sun.COM #define	ALLOC_VE		256
729585STim.Szeto@Sun.COM #define	ALLOC_PP_DATA_SIZE	128*1024
739585STim.Szeto@Sun.COM #define	ALLOC_GRP_MEMBER	256
749585STim.Szeto@Sun.COM 
757836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME	223
769585STim.Szeto@Sun.COM #define	MAX_SERIAL_SIZE 252 + 1
779585STim.Szeto@Sun.COM #define	MAX_LU_ALIAS_SIZE 256
789585STim.Szeto@Sun.COM #define	MAX_SBD_PROPS	MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
797836SJohn.Forte@Sun.COM 
807836SJohn.Forte@Sun.COM #define	OPEN_STMF 0
817836SJohn.Forte@Sun.COM #define	OPEN_EXCL_STMF O_EXCL
827836SJohn.Forte@Sun.COM 
839585STim.Szeto@Sun.COM #define	OPEN_SBD 0
849585STim.Szeto@Sun.COM #define	OPEN_EXCL_SBD O_EXCL
859585STim.Szeto@Sun.COM 
86*10725SJohn.Forte@Sun.COM #define	OPEN_PPPT 0
87*10725SJohn.Forte@Sun.COM #define	OPEN_EXCL_PPPT O_EXCL
88*10725SJohn.Forte@Sun.COM 
897836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_TYPE 0
907836SJohn.Forte@Sun.COM #define	TARGET_TYPE 1
917836SJohn.Forte@Sun.COM #define	STMF_SERVICE_TYPE 2
927836SJohn.Forte@Sun.COM 
939585STim.Szeto@Sun.COM #define	HOST_GROUP   1
949585STim.Szeto@Sun.COM #define	TARGET_GROUP 2
959585STim.Szeto@Sun.COM 
969585STim.Szeto@Sun.COM /* set default persistence here */
979585STim.Szeto@Sun.COM #define	STMF_DEFAULT_PERSIST	STMF_PERSIST_SMF
989585STim.Szeto@Sun.COM 
999585STim.Szeto@Sun.COM #define	MAX_PROVIDER_RETRY 30
1009585STim.Szeto@Sun.COM 
1017836SJohn.Forte@Sun.COM static int openStmf(int, int *fd);
1029585STim.Szeto@Sun.COM static int openSbd(int, int *fd);
103*10725SJohn.Forte@Sun.COM static int openPppt(int, int *fd);
1047836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *);
1057836SJohn.Forte@Sun.COM static int loadStore(int fd);
1067836SJohn.Forte@Sun.COM static int initializeConfig();
1077836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
1087836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *);
1097836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
1107836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *);
1117836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *);
1127836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *);
1137836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int);
1149585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
1159585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *);
1169585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *);
1179585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid);
1189585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
1199585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
1209585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
1219585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *);
1229585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *);
1239585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t);
1249585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *);
1259585STim.Szeto@Sun.COM static int checkHexUpper(char *);
1269585STim.Szeto@Sun.COM static int strToShift(const char *);
1279585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *);
1289585STim.Szeto@Sun.COM static void diskError(uint32_t, int *);
1299585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *);
1309585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
1319585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
1329585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t);
1339585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod();
1349585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int);
1359585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int);
1369585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
1379585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *);
138*10725SJohn.Forte@Sun.COM static int setDiskStandby(stmfGuid *luGuid);
1399585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *);
140*10725SJohn.Forte@Sun.COM static void deleteNonActiveLus();
1419585STim.Szeto@Sun.COM 
1429585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER;
1439585STim.Szeto@Sun.COM static int iPersistType = 0;
1449585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
1459585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE;
1467836SJohn.Forte@Sun.COM 
1477836SJohn.Forte@Sun.COM /*
1487836SJohn.Forte@Sun.COM  * Open for stmf module
1497836SJohn.Forte@Sun.COM  *
1507836SJohn.Forte@Sun.COM  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
1517836SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
1527836SJohn.Forte@Sun.COM  */
1537836SJohn.Forte@Sun.COM static int
1547836SJohn.Forte@Sun.COM openStmf(int flag, int *fd)
1557836SJohn.Forte@Sun.COM {
1567836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
1577836SJohn.Forte@Sun.COM 
1587836SJohn.Forte@Sun.COM 	if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
1597836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
1607836SJohn.Forte@Sun.COM 	} else {
1617836SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
1627836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1639585STim.Szeto@Sun.COM 		} else if (errno == EACCES) {
1649585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERM;
1657836SJohn.Forte@Sun.COM 		} else {
1667836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1677836SJohn.Forte@Sun.COM 		}
1687836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
1697836SJohn.Forte@Sun.COM 		    STMF_PATH, errno);
1707836SJohn.Forte@Sun.COM 	}
1717836SJohn.Forte@Sun.COM 
1727836SJohn.Forte@Sun.COM 	return (ret);
1737836SJohn.Forte@Sun.COM }
1747836SJohn.Forte@Sun.COM 
1757836SJohn.Forte@Sun.COM /*
1769585STim.Szeto@Sun.COM  * Open for sbd module
1779585STim.Szeto@Sun.COM  *
178*10725SJohn.Forte@Sun.COM  * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD)
1799585STim.Szeto@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
1809585STim.Szeto@Sun.COM  */
1819585STim.Szeto@Sun.COM static int
1829585STim.Szeto@Sun.COM openSbd(int flag, int *fd)
1839585STim.Szeto@Sun.COM {
1849585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
1859585STim.Szeto@Sun.COM 
1869585STim.Szeto@Sun.COM 	if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
1879585STim.Szeto@Sun.COM 		ret = STMF_STATUS_SUCCESS;
1889585STim.Szeto@Sun.COM 	} else {
1899585STim.Szeto@Sun.COM 		if (errno == EBUSY) {
1909585STim.Szeto@Sun.COM 			ret = STMF_ERROR_BUSY;
1919585STim.Szeto@Sun.COM 		} else if (errno == EACCES) {
1929585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERM;
1939585STim.Szeto@Sun.COM 		} else {
1949585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
1959585STim.Szeto@Sun.COM 		}
1969585STim.Szeto@Sun.COM 		syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)",
1979585STim.Szeto@Sun.COM 		    SBD_PATH, errno);
1989585STim.Szeto@Sun.COM 	}
1999585STim.Szeto@Sun.COM 
2009585STim.Szeto@Sun.COM 	return (ret);
2019585STim.Szeto@Sun.COM }
2029585STim.Szeto@Sun.COM 
2039585STim.Szeto@Sun.COM /*
204*10725SJohn.Forte@Sun.COM  * Open for pppt module
205*10725SJohn.Forte@Sun.COM  *
206*10725SJohn.Forte@Sun.COM  * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT)
207*10725SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
208*10725SJohn.Forte@Sun.COM  */
209*10725SJohn.Forte@Sun.COM static int
210*10725SJohn.Forte@Sun.COM openPppt(int flag, int *fd)
211*10725SJohn.Forte@Sun.COM {
212*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
213*10725SJohn.Forte@Sun.COM 
214*10725SJohn.Forte@Sun.COM 	if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) {
215*10725SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
216*10725SJohn.Forte@Sun.COM 	} else {
217*10725SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
218*10725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
219*10725SJohn.Forte@Sun.COM 		} else if (errno == EACCES) {
220*10725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PERM;
221*10725SJohn.Forte@Sun.COM 		} else {
222*10725SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
223*10725SJohn.Forte@Sun.COM 		}
224*10725SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)",
225*10725SJohn.Forte@Sun.COM 		    PPPT_PATH, errno);
226*10725SJohn.Forte@Sun.COM 	}
227*10725SJohn.Forte@Sun.COM 
228*10725SJohn.Forte@Sun.COM 	return (ret);
229*10725SJohn.Forte@Sun.COM }
230*10725SJohn.Forte@Sun.COM 
231*10725SJohn.Forte@Sun.COM /*
2327836SJohn.Forte@Sun.COM  * initializeConfig
2337836SJohn.Forte@Sun.COM  *
2347836SJohn.Forte@Sun.COM  * This routine should be called before any ioctl requiring initialization
2357836SJohn.Forte@Sun.COM  * which is basically everything except stmfGetState(), setStmfState() and
2367836SJohn.Forte@Sun.COM  * stmfLoadConfig().
2377836SJohn.Forte@Sun.COM  */
2387836SJohn.Forte@Sun.COM static int
2397836SJohn.Forte@Sun.COM initializeConfig()
2407836SJohn.Forte@Sun.COM {
2417836SJohn.Forte@Sun.COM 	int ret;
2427836SJohn.Forte@Sun.COM 	stmfState state;
2437836SJohn.Forte@Sun.COM 
2447836SJohn.Forte@Sun.COM 
2457836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2467836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2477836SJohn.Forte@Sun.COM 		return (ret);
2487836SJohn.Forte@Sun.COM 	}
2497836SJohn.Forte@Sun.COM 
2507836SJohn.Forte@Sun.COM 	/* if we've already initialized or in the process, return success */
2517836SJohn.Forte@Sun.COM 	if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
2527836SJohn.Forte@Sun.COM 	    state.configState == STMF_CONFIG_STATE_INIT) {
2537836SJohn.Forte@Sun.COM 		return (STMF_STATUS_SUCCESS);
2547836SJohn.Forte@Sun.COM 	}
2557836SJohn.Forte@Sun.COM 
2567836SJohn.Forte@Sun.COM 	ret = stmfLoadConfig();
2577836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2587836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
2597836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfLoadConfig:error(%d)", ret);
2607836SJohn.Forte@Sun.COM 		return (ret);
2617836SJohn.Forte@Sun.COM 	}
2627836SJohn.Forte@Sun.COM 
2637836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2647836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2657836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
2667836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfGetState:error(%d)", ret);
2677836SJohn.Forte@Sun.COM 		return (ret);
2687836SJohn.Forte@Sun.COM 	}
2697836SJohn.Forte@Sun.COM 
2707836SJohn.Forte@Sun.COM 	if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
2717836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
2727836SJohn.Forte@Sun.COM 		    state.configState);
2737836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_ERROR;
2747836SJohn.Forte@Sun.COM 	}
2757836SJohn.Forte@Sun.COM 
2767836SJohn.Forte@Sun.COM 	return (ret);
2777836SJohn.Forte@Sun.COM }
2787836SJohn.Forte@Sun.COM 
2797836SJohn.Forte@Sun.COM 
2807836SJohn.Forte@Sun.COM /*
2817836SJohn.Forte@Sun.COM  * groupIoctl
2827836SJohn.Forte@Sun.COM  *
2837836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for create/delete on group
2847836SJohn.Forte@Sun.COM  *
2857836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group cmd
2867836SJohn.Forte@Sun.COM  * groupName - groupName to create or delete
2877836SJohn.Forte@Sun.COM  */
2887836SJohn.Forte@Sun.COM static int
2897836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName)
2907836SJohn.Forte@Sun.COM {
2917836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2927836SJohn.Forte@Sun.COM 	int ioctlRet;
2937836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2947836SJohn.Forte@Sun.COM 	stmf_group_name_t iGroupName;
2957836SJohn.Forte@Sun.COM 
2967836SJohn.Forte@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
2977836SJohn.Forte@Sun.COM 
2987836SJohn.Forte@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
2997836SJohn.Forte@Sun.COM 
3007836SJohn.Forte@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
3017836SJohn.Forte@Sun.COM 
3027836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3037836SJohn.Forte@Sun.COM 	/*
3047836SJohn.Forte@Sun.COM 	 * Issue ioctl to create the host group
3057836SJohn.Forte@Sun.COM 	 */
3067836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3077836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
3087836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3097836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3107836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3117836SJohn.Forte@Sun.COM 		switch (errno) {
3129585STim.Szeto@Sun.COM 			case EPERM:
3137836SJohn.Forte@Sun.COM 			case EACCES:
3147836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3157836SJohn.Forte@Sun.COM 				break;
3167836SJohn.Forte@Sun.COM 			default:
3177836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
3187836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_EXISTS:
3197836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_EXISTS:
3207836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
3217836SJohn.Forte@Sun.COM 						break;
3227836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_IN_USE:
3237836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_IN_USE:
3247836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_GROUP_IN_USE;
3257836SJohn.Forte@Sun.COM 						break;
3267836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
3277836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
3287836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
3297836SJohn.Forte@Sun.COM 						break;
3307836SJohn.Forte@Sun.COM 					default:
3317836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
3327836SJohn.Forte@Sun.COM 						    "groupIoctl:error(%d)",
3337836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
3347836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
3357836SJohn.Forte@Sun.COM 						break;
3367836SJohn.Forte@Sun.COM 				}
3377836SJohn.Forte@Sun.COM 				break;
3387836SJohn.Forte@Sun.COM 		}
3397836SJohn.Forte@Sun.COM 	}
3407836SJohn.Forte@Sun.COM done:
3417836SJohn.Forte@Sun.COM 	return (ret);
3427836SJohn.Forte@Sun.COM }
3437836SJohn.Forte@Sun.COM 
3447836SJohn.Forte@Sun.COM /*
3459585STim.Szeto@Sun.COM  * groupMemberIoctl
3467836SJohn.Forte@Sun.COM  *
3477836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for add/remove member on group
3487836SJohn.Forte@Sun.COM  *
3497836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group member cmd
3507836SJohn.Forte@Sun.COM  * groupName - groupName to add to or remove from
3517836SJohn.Forte@Sun.COM  * devid - group member to add or remove
3527836SJohn.Forte@Sun.COM  */
3537836SJohn.Forte@Sun.COM static int
3547836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
3557836SJohn.Forte@Sun.COM {
3567836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
3577836SJohn.Forte@Sun.COM 	int ioctlRet;
3587836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
3597836SJohn.Forte@Sun.COM 	stmf_group_op_data_t stmfGroupData;
3607836SJohn.Forte@Sun.COM 
3617836SJohn.Forte@Sun.COM 	bzero(&stmfGroupData, sizeof (stmfGroupData));
3627836SJohn.Forte@Sun.COM 
3637836SJohn.Forte@Sun.COM 	bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	stmfGroupData.group.name_size = strlen((char *)groupName);
3667836SJohn.Forte@Sun.COM 	stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
3677836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
3687836SJohn.Forte@Sun.COM 	    devid->identLength);
3697836SJohn.Forte@Sun.COM 
3707836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3717836SJohn.Forte@Sun.COM 	/*
3727836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
3737836SJohn.Forte@Sun.COM 	 */
3747836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3757836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
3767836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
3777836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3787836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3797836SJohn.Forte@Sun.COM 		switch (errno) {
3807836SJohn.Forte@Sun.COM 			case EBUSY:
3819884STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
3829884STim.Szeto@Sun.COM 					case STMF_IOCERR_TG_NEED_TG_OFFLINE:
3839884STim.Szeto@Sun.COM 						ret = STMF_ERROR_TG_ONLINE;
3849884STim.Szeto@Sun.COM 						break;
3859884STim.Szeto@Sun.COM 					default:
3869884STim.Szeto@Sun.COM 						ret = STMF_ERROR_BUSY;
3879884STim.Szeto@Sun.COM 						break;
3889884STim.Szeto@Sun.COM 				}
3897836SJohn.Forte@Sun.COM 				break;
3909585STim.Szeto@Sun.COM 			case EPERM:
3917836SJohn.Forte@Sun.COM 			case EACCES:
3927836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3937836SJohn.Forte@Sun.COM 				break;
3947836SJohn.Forte@Sun.COM 			default:
3957836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
3967836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_ENTRY_EXISTS:
3977836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_ENTRY_EXISTS:
3987836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
3997836SJohn.Forte@Sun.COM 						break;
4007836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG_ENTRY:
4017836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG_ENTRY:
4027836SJohn.Forte@Sun.COM 						ret =
4037836SJohn.Forte@Sun.COM 						    STMF_ERROR_MEMBER_NOT_FOUND;
4047836SJohn.Forte@Sun.COM 						break;
4057836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
4067836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
4077836SJohn.Forte@Sun.COM 						ret =
4087836SJohn.Forte@Sun.COM 						    STMF_ERROR_GROUP_NOT_FOUND;
4097836SJohn.Forte@Sun.COM 						break;
4107836SJohn.Forte@Sun.COM 					default:
4117836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
4127836SJohn.Forte@Sun.COM 						    "groupMemberIoctl:error"
4137836SJohn.Forte@Sun.COM 						    "(%d)",
4147836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
4157836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
4167836SJohn.Forte@Sun.COM 						break;
4177836SJohn.Forte@Sun.COM 				}
4187836SJohn.Forte@Sun.COM 				break;
4197836SJohn.Forte@Sun.COM 		}
4207836SJohn.Forte@Sun.COM 	}
4217836SJohn.Forte@Sun.COM done:
4227836SJohn.Forte@Sun.COM 	return (ret);
4237836SJohn.Forte@Sun.COM }
4247836SJohn.Forte@Sun.COM 
4257836SJohn.Forte@Sun.COM /*
4269585STim.Szeto@Sun.COM  * qsort function
4279585STim.Szeto@Sun.COM  * sort on veIndex
4289585STim.Szeto@Sun.COM  */
4299585STim.Szeto@Sun.COM static int
4309585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2)
4319585STim.Szeto@Sun.COM {
4329585STim.Szeto@Sun.COM 
4339585STim.Szeto@Sun.COM 	stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
4349585STim.Szeto@Sun.COM 	if (v1->veIndex > v2->veIndex)
4359585STim.Szeto@Sun.COM 		return (1);
4369585STim.Szeto@Sun.COM 	if (v1->veIndex < v2->veIndex)
4379585STim.Szeto@Sun.COM 		return (-1);
4389585STim.Szeto@Sun.COM 	return (0);
4399585STim.Szeto@Sun.COM }
4409585STim.Szeto@Sun.COM 
4419585STim.Szeto@Sun.COM /*
4427836SJohn.Forte@Sun.COM  * guidCompare
4437836SJohn.Forte@Sun.COM  *
4447836SJohn.Forte@Sun.COM  * qsort function
4457836SJohn.Forte@Sun.COM  * sort on guid
4467836SJohn.Forte@Sun.COM  */
4477836SJohn.Forte@Sun.COM static int
4487836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2)
4497836SJohn.Forte@Sun.COM {
4507836SJohn.Forte@Sun.COM 
4517836SJohn.Forte@Sun.COM 	stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
4527836SJohn.Forte@Sun.COM 	int i;
4537836SJohn.Forte@Sun.COM 
4547836SJohn.Forte@Sun.COM 	for (i = 0; i < sizeof (stmfGuid); i++) {
4557836SJohn.Forte@Sun.COM 		if (g1->guid[i] > g2->guid[i])
4567836SJohn.Forte@Sun.COM 			return (1);
4577836SJohn.Forte@Sun.COM 		if (g1->guid[i] < g2->guid[i])
4587836SJohn.Forte@Sun.COM 			return (-1);
4597836SJohn.Forte@Sun.COM 	}
4607836SJohn.Forte@Sun.COM 
4617836SJohn.Forte@Sun.COM 	return (0);
4627836SJohn.Forte@Sun.COM }
4637836SJohn.Forte@Sun.COM 
4647836SJohn.Forte@Sun.COM /*
4657836SJohn.Forte@Sun.COM  * stmfAddToHostGroup
4667836SJohn.Forte@Sun.COM  *
4677836SJohn.Forte@Sun.COM  * Purpose: Adds an initiator to an existing host group
4687836SJohn.Forte@Sun.COM  *
4697836SJohn.Forte@Sun.COM  * hostGroupName - name of an existing host group
4707836SJohn.Forte@Sun.COM  * hostName - name of initiator to add
4717836SJohn.Forte@Sun.COM  */
4727836SJohn.Forte@Sun.COM int
4737836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
4747836SJohn.Forte@Sun.COM {
4757836SJohn.Forte@Sun.COM 	int ret;
4767836SJohn.Forte@Sun.COM 	int fd;
4777836SJohn.Forte@Sun.COM 
4787836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
4797836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
4807836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
4817836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
4827836SJohn.Forte@Sun.COM 	}
4837836SJohn.Forte@Sun.COM 
4847836SJohn.Forte@Sun.COM 	/* call init */
4857836SJohn.Forte@Sun.COM 	ret = initializeConfig();
4867836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
4877836SJohn.Forte@Sun.COM 		return (ret);
4887836SJohn.Forte@Sun.COM 	}
4897836SJohn.Forte@Sun.COM 
4907836SJohn.Forte@Sun.COM 	/*
4917836SJohn.Forte@Sun.COM 	 * Open control node for stmf
4927836SJohn.Forte@Sun.COM 	 */
4937836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4947836SJohn.Forte@Sun.COM 		return (ret);
4957836SJohn.Forte@Sun.COM 
4967836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
4977836SJohn.Forte@Sun.COM 	    hostName)) != STMF_STATUS_SUCCESS) {
4987836SJohn.Forte@Sun.COM 		goto done;
4997836SJohn.Forte@Sun.COM 	}
5007836SJohn.Forte@Sun.COM 
5019585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5029585STim.Szeto@Sun.COM 		goto done;
5039585STim.Szeto@Sun.COM 	}
5049585STim.Szeto@Sun.COM 
5057836SJohn.Forte@Sun.COM 	ret = psAddHostGroupMember((char *)hostGroupName,
5067836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
5077836SJohn.Forte@Sun.COM 	switch (ret) {
5087836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
5097836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
5107836SJohn.Forte@Sun.COM 			break;
5117836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
5127836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
5137836SJohn.Forte@Sun.COM 			break;
5147836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5157836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5167836SJohn.Forte@Sun.COM 			break;
5177836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
5187836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
5197836SJohn.Forte@Sun.COM 			break;
5207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5227836SJohn.Forte@Sun.COM 			break;
5237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
5247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5257836SJohn.Forte@Sun.COM 			break;
5267836SJohn.Forte@Sun.COM 		default:
5277836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
5287836SJohn.Forte@Sun.COM 			    "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
5297836SJohn.Forte@Sun.COM 			    ret);
5307836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
5317836SJohn.Forte@Sun.COM 			break;
5327836SJohn.Forte@Sun.COM 	}
5337836SJohn.Forte@Sun.COM 
5347836SJohn.Forte@Sun.COM done:
5357836SJohn.Forte@Sun.COM 	(void) close(fd);
5367836SJohn.Forte@Sun.COM 	return (ret);
5377836SJohn.Forte@Sun.COM }
5387836SJohn.Forte@Sun.COM 
5397836SJohn.Forte@Sun.COM /*
5407836SJohn.Forte@Sun.COM  * stmfAddToTargetGroup
5417836SJohn.Forte@Sun.COM  *
5427836SJohn.Forte@Sun.COM  * Purpose: Adds a local port to an existing target group
5437836SJohn.Forte@Sun.COM  *
5447836SJohn.Forte@Sun.COM  * targetGroupName - name of an existing target group
5457836SJohn.Forte@Sun.COM  * targetName - name of target to add
5467836SJohn.Forte@Sun.COM  */
5477836SJohn.Forte@Sun.COM int
5487836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
5497836SJohn.Forte@Sun.COM {
5507836SJohn.Forte@Sun.COM 	int ret;
5517836SJohn.Forte@Sun.COM 	int fd;
5527836SJohn.Forte@Sun.COM 
5537836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
5547836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
5557836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
5567836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
5577836SJohn.Forte@Sun.COM 	}
5587836SJohn.Forte@Sun.COM 
5597836SJohn.Forte@Sun.COM 	/* call init */
5607836SJohn.Forte@Sun.COM 	ret = initializeConfig();
5617836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
5627836SJohn.Forte@Sun.COM 		return (ret);
5637836SJohn.Forte@Sun.COM 	}
5647836SJohn.Forte@Sun.COM 
5657836SJohn.Forte@Sun.COM 	/*
5667836SJohn.Forte@Sun.COM 	 * Open control node for stmf
5677836SJohn.Forte@Sun.COM 	 */
5687836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5697836SJohn.Forte@Sun.COM 		return (ret);
5707836SJohn.Forte@Sun.COM 
5717836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
5727836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
5737836SJohn.Forte@Sun.COM 		goto done;
5747836SJohn.Forte@Sun.COM 	}
5757836SJohn.Forte@Sun.COM 
5769585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5779585STim.Szeto@Sun.COM 		goto done;
5789585STim.Szeto@Sun.COM 	}
5799585STim.Szeto@Sun.COM 
5807836SJohn.Forte@Sun.COM 	ret = psAddTargetGroupMember((char *)targetGroupName,
5817836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
5827836SJohn.Forte@Sun.COM 	switch (ret) {
5837836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
5847836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
5857836SJohn.Forte@Sun.COM 			break;
5867836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
5877836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
5887836SJohn.Forte@Sun.COM 			break;
5897836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5907836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5917836SJohn.Forte@Sun.COM 			break;
5927836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
5937836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
5947836SJohn.Forte@Sun.COM 			break;
5957836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5967836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5977836SJohn.Forte@Sun.COM 			break;
5987836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
5997836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
6007836SJohn.Forte@Sun.COM 			break;
6017836SJohn.Forte@Sun.COM 		default:
6027836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
6037836SJohn.Forte@Sun.COM 			    "stmfAddToTargetGroup:psAddTargetGroupMember:"
6047836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
6057836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
6067836SJohn.Forte@Sun.COM 			break;
6077836SJohn.Forte@Sun.COM 	}
6087836SJohn.Forte@Sun.COM 
6097836SJohn.Forte@Sun.COM done:
6107836SJohn.Forte@Sun.COM 	(void) close(fd);
6117836SJohn.Forte@Sun.COM 	return (ret);
6127836SJohn.Forte@Sun.COM }
6137836SJohn.Forte@Sun.COM 
6147836SJohn.Forte@Sun.COM /*
6157836SJohn.Forte@Sun.COM  * addViewEntryIoctl
6167836SJohn.Forte@Sun.COM  *
6177836SJohn.Forte@Sun.COM  * Purpose: Issues ioctl to add a view entry
6187836SJohn.Forte@Sun.COM  *
6197836SJohn.Forte@Sun.COM  * lu - Logical Unit identifier to which the view entry is added
6207836SJohn.Forte@Sun.COM  * viewEntry - view entry to add
6217836SJohn.Forte@Sun.COM  * init - When set to B_TRUE, we are in the init state, i.e. don't call open
6227836SJohn.Forte@Sun.COM  */
6237836SJohn.Forte@Sun.COM static int
6247836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
6257836SJohn.Forte@Sun.COM {
6267836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
6277836SJohn.Forte@Sun.COM 	int ioctlRet;
6287836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
6297836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
6307836SJohn.Forte@Sun.COM 
6317836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6327836SJohn.Forte@Sun.COM 	/*
6337836SJohn.Forte@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
6347836SJohn.Forte@Sun.COM 	 * false on input
6357836SJohn.Forte@Sun.COM 	 */
6367836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
6377836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
6387836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
6397836SJohn.Forte@Sun.COM 
6407836SJohn.Forte@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
6417836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
6427836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
6437836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
6447836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
6457836SJohn.Forte@Sun.COM 	}
6467836SJohn.Forte@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
6477836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup,
6487836SJohn.Forte@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
6497836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
6507836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
6517836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
6527836SJohn.Forte@Sun.COM 	}
6537836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
6547836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
6557836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
6567836SJohn.Forte@Sun.COM 	}
6577836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
6587836SJohn.Forte@Sun.COM 
6597836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
6607836SJohn.Forte@Sun.COM 	/*
6617836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
6627836SJohn.Forte@Sun.COM 	 */
6637836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
6647836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6657836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6667836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
6677836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6687836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
6697836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
6707836SJohn.Forte@Sun.COM 		switch (errno) {
6717836SJohn.Forte@Sun.COM 			case EBUSY:
6727836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
6737836SJohn.Forte@Sun.COM 				break;
6749585STim.Szeto@Sun.COM 			case EPERM:
6759585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
6769585STim.Szeto@Sun.COM 				break;
6777836SJohn.Forte@Sun.COM 			case EACCES:
6787836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
6797836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6807836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
6817836SJohn.Forte@Sun.COM 						break;
6827836SJohn.Forte@Sun.COM 					default:
6837836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
6847836SJohn.Forte@Sun.COM 						break;
6857836SJohn.Forte@Sun.COM 				}
6867836SJohn.Forte@Sun.COM 				break;
6877836SJohn.Forte@Sun.COM 			default:
6887836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
6897836SJohn.Forte@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
6907836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
6917836SJohn.Forte@Sun.COM 						break;
6927836SJohn.Forte@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
6937836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
6947836SJohn.Forte@Sun.COM 						break;
6957836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6967836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
6977836SJohn.Forte@Sun.COM 						break;
6987836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
6997836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
7007836SJohn.Forte@Sun.COM 						break;
7017836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
7027836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
7037836SJohn.Forte@Sun.COM 						break;
7047836SJohn.Forte@Sun.COM 					default:
7057836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
7067836SJohn.Forte@Sun.COM 						    "addViewEntryIoctl"
7077836SJohn.Forte@Sun.COM 						    ":error(%d)",
7087836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
7097836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
7107836SJohn.Forte@Sun.COM 						break;
7117836SJohn.Forte@Sun.COM 				}
7127836SJohn.Forte@Sun.COM 				break;
7137836SJohn.Forte@Sun.COM 		}
7147836SJohn.Forte@Sun.COM 		goto done;
7157836SJohn.Forte@Sun.COM 	}
7167836SJohn.Forte@Sun.COM 
7177836SJohn.Forte@Sun.COM 	/* copy lu nbr back to caller's view entry on success */
7187836SJohn.Forte@Sun.COM 	viewEntry->veIndex = ioctlViewEntry.ve_ndx;
7197836SJohn.Forte@Sun.COM 	if (ioctlViewEntry.ve_lu_number_valid) {
7207836SJohn.Forte@Sun.COM 		bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
7217836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
7227836SJohn.Forte@Sun.COM 	}
7237836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
7247836SJohn.Forte@Sun.COM 
7257836SJohn.Forte@Sun.COM done:
7267836SJohn.Forte@Sun.COM 	return (ret);
7277836SJohn.Forte@Sun.COM }
7287836SJohn.Forte@Sun.COM 
7297836SJohn.Forte@Sun.COM /*
7307836SJohn.Forte@Sun.COM  * stmfAddViewEntry
7317836SJohn.Forte@Sun.COM  *
7327836SJohn.Forte@Sun.COM  * Purpose: Adds a view entry to a logical unit
7337836SJohn.Forte@Sun.COM  *
7347836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to which the view entry is added
7357836SJohn.Forte@Sun.COM  * viewEntry - view entry structure to add
7367836SJohn.Forte@Sun.COM  */
7377836SJohn.Forte@Sun.COM int
7387836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
7397836SJohn.Forte@Sun.COM {
7407836SJohn.Forte@Sun.COM 	int ret;
7417836SJohn.Forte@Sun.COM 	int fd;
7427836SJohn.Forte@Sun.COM 	stmfViewEntry iViewEntry;
7437836SJohn.Forte@Sun.COM 
7447836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntry == NULL) {
7457836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
7467836SJohn.Forte@Sun.COM 	}
7477836SJohn.Forte@Sun.COM 
7487836SJohn.Forte@Sun.COM 	/* initialize and set internal view entry */
7497836SJohn.Forte@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
7507836SJohn.Forte@Sun.COM 
7517836SJohn.Forte@Sun.COM 	if (!viewEntry->allHosts) {
7527836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
7537836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.hostGroup));
7547836SJohn.Forte@Sun.COM 	} else {
7557836SJohn.Forte@Sun.COM 		iViewEntry.allHosts = B_TRUE;
7567836SJohn.Forte@Sun.COM 	}
7577836SJohn.Forte@Sun.COM 
7587836SJohn.Forte@Sun.COM 	if (!viewEntry->allTargets) {
7597836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
7607836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.targetGroup));
7617836SJohn.Forte@Sun.COM 	} else {
7627836SJohn.Forte@Sun.COM 		iViewEntry.allTargets = B_TRUE;
7637836SJohn.Forte@Sun.COM 	}
7647836SJohn.Forte@Sun.COM 
7657836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
7667836SJohn.Forte@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
7677836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
7687836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
7697836SJohn.Forte@Sun.COM 	}
7707836SJohn.Forte@Sun.COM 
7717836SJohn.Forte@Sun.COM 	/*
7727836SJohn.Forte@Sun.COM 	 * set users return view entry index valid flag to false
7737836SJohn.Forte@Sun.COM 	 * in case of failure
7747836SJohn.Forte@Sun.COM 	 */
7757836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
7767836SJohn.Forte@Sun.COM 
7777836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
7787836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
7797836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
7807836SJohn.Forte@Sun.COM 	}
7817836SJohn.Forte@Sun.COM 
7827836SJohn.Forte@Sun.COM 	/* call init */
7837836SJohn.Forte@Sun.COM 	ret = initializeConfig();
7847836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
7857836SJohn.Forte@Sun.COM 		return (ret);
7867836SJohn.Forte@Sun.COM 	}
7877836SJohn.Forte@Sun.COM 
7887836SJohn.Forte@Sun.COM 	/*
7897836SJohn.Forte@Sun.COM 	 * Open control node for stmf
7907836SJohn.Forte@Sun.COM 	 */
7917836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
7927836SJohn.Forte@Sun.COM 		return (ret);
7937836SJohn.Forte@Sun.COM 
7947836SJohn.Forte@Sun.COM 	/*
7957836SJohn.Forte@Sun.COM 	 * First add the view entry to the driver
7967836SJohn.Forte@Sun.COM 	 */
7977836SJohn.Forte@Sun.COM 	ret = addViewEntryIoctl(fd, lu, &iViewEntry);
7987836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
7997836SJohn.Forte@Sun.COM 		goto done;
8007836SJohn.Forte@Sun.COM 	}
8017836SJohn.Forte@Sun.COM 
8029585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
8039585STim.Szeto@Sun.COM 		goto done;
8049585STim.Szeto@Sun.COM 	}
8059585STim.Szeto@Sun.COM 
8067836SJohn.Forte@Sun.COM 	/*
8077836SJohn.Forte@Sun.COM 	 * If the add to driver was successful, add it to the persistent
8087836SJohn.Forte@Sun.COM 	 * store.
8097836SJohn.Forte@Sun.COM 	 */
8107836SJohn.Forte@Sun.COM 	ret = psAddViewEntry(lu, &iViewEntry);
8117836SJohn.Forte@Sun.COM 	switch (ret) {
8127836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
8137836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
8147836SJohn.Forte@Sun.COM 			break;
8157836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
8167836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
8177836SJohn.Forte@Sun.COM 			break;
8187836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
8197836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
8207836SJohn.Forte@Sun.COM 			break;
8217836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
8227836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
8237836SJohn.Forte@Sun.COM 			break;
8247836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
8257836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
8267836SJohn.Forte@Sun.COM 			break;
8277836SJohn.Forte@Sun.COM 		default:
8287836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
8297836SJohn.Forte@Sun.COM 			    "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
8307836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
8317836SJohn.Forte@Sun.COM 			break;
8327836SJohn.Forte@Sun.COM 	}
8337836SJohn.Forte@Sun.COM 
8347836SJohn.Forte@Sun.COM done:
8357836SJohn.Forte@Sun.COM 	(void) close(fd);
8367836SJohn.Forte@Sun.COM 
8377836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
8387836SJohn.Forte@Sun.COM 		/* set caller's view entry on success */
8397836SJohn.Forte@Sun.COM 		viewEntry->veIndexValid = iViewEntry.veIndexValid;
8407836SJohn.Forte@Sun.COM 		viewEntry->veIndex = iViewEntry.veIndex;
8417836SJohn.Forte@Sun.COM 		viewEntry->luNbrValid = B_TRUE;
8427836SJohn.Forte@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
8437836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
8447836SJohn.Forte@Sun.COM 	}
8457836SJohn.Forte@Sun.COM 	return (ret);
8467836SJohn.Forte@Sun.COM }
8477836SJohn.Forte@Sun.COM 
8487836SJohn.Forte@Sun.COM /*
8497836SJohn.Forte@Sun.COM  * stmfClearProviderData
8507836SJohn.Forte@Sun.COM  *
8517836SJohn.Forte@Sun.COM  * Purpose: delete all provider data for specified provider
8527836SJohn.Forte@Sun.COM  *
8537836SJohn.Forte@Sun.COM  * providerName - name of provider for which data should be deleted
8547836SJohn.Forte@Sun.COM  */
8557836SJohn.Forte@Sun.COM int
8567836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType)
8577836SJohn.Forte@Sun.COM {
8587836SJohn.Forte@Sun.COM 	int ret;
8597836SJohn.Forte@Sun.COM 	int fd;
8607836SJohn.Forte@Sun.COM 	int ioctlRet;
8617836SJohn.Forte@Sun.COM 	int savedErrno;
8627836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
8637836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t ppi;
8647836SJohn.Forte@Sun.COM 
8657836SJohn.Forte@Sun.COM 	/* call init */
8667836SJohn.Forte@Sun.COM 	ret = initializeConfig();
8677836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
8687836SJohn.Forte@Sun.COM 		return (ret);
8697836SJohn.Forte@Sun.COM 	}
8707836SJohn.Forte@Sun.COM 
8717836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
8727836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8737836SJohn.Forte@Sun.COM 	}
8747836SJohn.Forte@Sun.COM 
8757836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
8767836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
8777836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8787836SJohn.Forte@Sun.COM 	}
8797836SJohn.Forte@Sun.COM 
8807836SJohn.Forte@Sun.COM 	/*
8817836SJohn.Forte@Sun.COM 	 * Open control node for stmf
8827836SJohn.Forte@Sun.COM 	 */
8837836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
8847836SJohn.Forte@Sun.COM 		return (ret);
8857836SJohn.Forte@Sun.COM 
8867836SJohn.Forte@Sun.COM 	bzero(&ppi, sizeof (ppi));
8877836SJohn.Forte@Sun.COM 
8887836SJohn.Forte@Sun.COM 	(void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
8897836SJohn.Forte@Sun.COM 
8907836SJohn.Forte@Sun.COM 	switch (providerType) {
8917836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
8927836SJohn.Forte@Sun.COM 			ppi.ppi_lu_provider = 1;
8937836SJohn.Forte@Sun.COM 			break;
8947836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
8957836SJohn.Forte@Sun.COM 			ppi.ppi_port_provider = 1;
8967836SJohn.Forte@Sun.COM 			break;
8977836SJohn.Forte@Sun.COM 		default:
8987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
8997836SJohn.Forte@Sun.COM 			goto done;
9007836SJohn.Forte@Sun.COM 	}
9017836SJohn.Forte@Sun.COM 
9027836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
9037836SJohn.Forte@Sun.COM 
9047836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
9057836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
9067836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
9077836SJohn.Forte@Sun.COM 
9087836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
9097836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
9107836SJohn.Forte@Sun.COM 		savedErrno = errno;
9117836SJohn.Forte@Sun.COM 		switch (savedErrno) {
9127836SJohn.Forte@Sun.COM 			case EBUSY:
9137836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
9147836SJohn.Forte@Sun.COM 				break;
9159585STim.Szeto@Sun.COM 			case EPERM:
9167836SJohn.Forte@Sun.COM 			case EACCES:
9177836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
9187836SJohn.Forte@Sun.COM 				break;
9197836SJohn.Forte@Sun.COM 			default:
9207836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
9217836SJohn.Forte@Sun.COM 				    "stmfClearProviderData:ioctl error(%d)",
9227836SJohn.Forte@Sun.COM 				    ioctlRet);
9237836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
9247836SJohn.Forte@Sun.COM 				break;
9257836SJohn.Forte@Sun.COM 		}
9267836SJohn.Forte@Sun.COM 		if (savedErrno != ENOENT) {
9277836SJohn.Forte@Sun.COM 			goto done;
9287836SJohn.Forte@Sun.COM 		}
9297836SJohn.Forte@Sun.COM 	}
9307836SJohn.Forte@Sun.COM 
9319585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
9329585STim.Szeto@Sun.COM 		goto done;
9339585STim.Szeto@Sun.COM 	}
9349585STim.Szeto@Sun.COM 
9357836SJohn.Forte@Sun.COM 	ret = psClearProviderData(providerName, providerType);
9367836SJohn.Forte@Sun.COM 	switch (ret) {
9377836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
9387836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
9397836SJohn.Forte@Sun.COM 			break;
9407836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
9417836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
9427836SJohn.Forte@Sun.COM 			break;
9437836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
9447836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
9457836SJohn.Forte@Sun.COM 			break;
9467836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
9477836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
9487836SJohn.Forte@Sun.COM 			break;
9497836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
9507836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
9517836SJohn.Forte@Sun.COM 			break;
9527836SJohn.Forte@Sun.COM 		default:
9537836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
9547836SJohn.Forte@Sun.COM 			    "stmfClearProviderData:psClearProviderData"
9557836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
9567836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
9577836SJohn.Forte@Sun.COM 			break;
9587836SJohn.Forte@Sun.COM 	}
9597836SJohn.Forte@Sun.COM 
9607836SJohn.Forte@Sun.COM done:
9617836SJohn.Forte@Sun.COM 	(void) close(fd);
9627836SJohn.Forte@Sun.COM 	return (ret);
9637836SJohn.Forte@Sun.COM }
9647836SJohn.Forte@Sun.COM 
9657836SJohn.Forte@Sun.COM /*
9667836SJohn.Forte@Sun.COM  * stmfCreateHostGroup
9677836SJohn.Forte@Sun.COM  *
9687836SJohn.Forte@Sun.COM  * Purpose: Create a new initiator group
9697836SJohn.Forte@Sun.COM  *
9707836SJohn.Forte@Sun.COM  * hostGroupName - name of host group to create
9717836SJohn.Forte@Sun.COM  */
9727836SJohn.Forte@Sun.COM int
9737836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName)
9747836SJohn.Forte@Sun.COM {
9757836SJohn.Forte@Sun.COM 	int ret;
9767836SJohn.Forte@Sun.COM 	int fd;
9777836SJohn.Forte@Sun.COM 
9787836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
9797836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
9807836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
9817836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
9827836SJohn.Forte@Sun.COM 	}
9837836SJohn.Forte@Sun.COM 
9847836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
9857836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
9867836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
9877836SJohn.Forte@Sun.COM 	}
9887836SJohn.Forte@Sun.COM 
9897836SJohn.Forte@Sun.COM 	/* call init */
9907836SJohn.Forte@Sun.COM 	ret = initializeConfig();
9917836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
9927836SJohn.Forte@Sun.COM 		return (ret);
9937836SJohn.Forte@Sun.COM 	}
9947836SJohn.Forte@Sun.COM 
9957836SJohn.Forte@Sun.COM 	/*
9967836SJohn.Forte@Sun.COM 	 * Open control node for stmf
9977836SJohn.Forte@Sun.COM 	 */
9987836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
9997836SJohn.Forte@Sun.COM 		return (ret);
10007836SJohn.Forte@Sun.COM 
10017836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
10027836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
10037836SJohn.Forte@Sun.COM 		goto done;
10047836SJohn.Forte@Sun.COM 	}
10057836SJohn.Forte@Sun.COM 
10069585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
10079585STim.Szeto@Sun.COM 		goto done;
10089585STim.Szeto@Sun.COM 	}
10099585STim.Szeto@Sun.COM 
10107836SJohn.Forte@Sun.COM 	ret = psCreateHostGroup((char *)hostGroupName);
10117836SJohn.Forte@Sun.COM 	switch (ret) {
10127836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
10137836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
10147836SJohn.Forte@Sun.COM 			break;
10157836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
10167836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
10177836SJohn.Forte@Sun.COM 			break;
10187836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
10197836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
10207836SJohn.Forte@Sun.COM 			break;
10217836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
10227836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
10237836SJohn.Forte@Sun.COM 			break;
10247836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
10257836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
10267836SJohn.Forte@Sun.COM 			break;
10277836SJohn.Forte@Sun.COM 		default:
10287836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
10297836SJohn.Forte@Sun.COM 			    "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
10307836SJohn.Forte@Sun.COM 			    ret);
10317836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
10327836SJohn.Forte@Sun.COM 			break;
10337836SJohn.Forte@Sun.COM 	}
10347836SJohn.Forte@Sun.COM 
10357836SJohn.Forte@Sun.COM done:
10367836SJohn.Forte@Sun.COM 	(void) close(fd);
10377836SJohn.Forte@Sun.COM 	return (ret);
10387836SJohn.Forte@Sun.COM }
10397836SJohn.Forte@Sun.COM 
10407836SJohn.Forte@Sun.COM /*
10419585STim.Szeto@Sun.COM  * stmfCreateLu
10429585STim.Szeto@Sun.COM  *
10439585STim.Szeto@Sun.COM  * Purpose: Create a logical unit
10449585STim.Szeto@Sun.COM  *
10459585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
10469585STim.Szeto@Sun.COM  *
10479585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
10489585STim.Szeto@Sun.COM  *	    unit
10499585STim.Szeto@Sun.COM  */
10509585STim.Szeto@Sun.COM int
10519585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid)
10529585STim.Szeto@Sun.COM {
10539585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10549585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
10559585STim.Szeto@Sun.COM 
10569585STim.Szeto@Sun.COM 	if (hdl == NULL) {
10579585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10589585STim.Szeto@Sun.COM 	}
10599585STim.Szeto@Sun.COM 
10609585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
10619585STim.Szeto@Sun.COM 		ret = createDiskLu((diskResource *)luPropsHdl->resource,
10629585STim.Szeto@Sun.COM 		    luGuid);
10639585STim.Szeto@Sun.COM 	} else {
10649585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10659585STim.Szeto@Sun.COM 	}
10669585STim.Szeto@Sun.COM 
10679585STim.Szeto@Sun.COM 	return (ret);
10689585STim.Szeto@Sun.COM }
10699585STim.Szeto@Sun.COM 
10709585STim.Szeto@Sun.COM /*
10719585STim.Szeto@Sun.COM  * stmfCreateLuResource
10729585STim.Szeto@Sun.COM  *
10739585STim.Szeto@Sun.COM  * Purpose: Create resource handle for a logical unit
10749585STim.Szeto@Sun.COM  *
10759585STim.Szeto@Sun.COM  * dType - Type of logical unit resource to create
10769585STim.Szeto@Sun.COM  *	   Can be: STMF_DISK
10779585STim.Szeto@Sun.COM  *
10789585STim.Szeto@Sun.COM  * hdl - pointer to luResource
10799585STim.Szeto@Sun.COM  */
10809585STim.Szeto@Sun.COM int
10819585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl)
10829585STim.Szeto@Sun.COM {
10839585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10849585STim.Szeto@Sun.COM 
10859585STim.Szeto@Sun.COM 	if (dType != STMF_DISK || hdl == NULL) {
10869585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10879585STim.Szeto@Sun.COM 	}
10889585STim.Szeto@Sun.COM 
10899585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
10909585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
10919585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
10929585STim.Szeto@Sun.COM 	}
10939585STim.Szeto@Sun.COM 
10949585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
10959585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
10969585STim.Szeto@Sun.COM 		free(*hdl);
10979585STim.Szeto@Sun.COM 		return (ret);
10989585STim.Szeto@Sun.COM 	}
10999585STim.Szeto@Sun.COM 
11009585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
11019585STim.Szeto@Sun.COM }
11029585STim.Szeto@Sun.COM 
11039585STim.Szeto@Sun.COM /*
11049585STim.Szeto@Sun.COM  * Creates a disk logical unit
11059585STim.Szeto@Sun.COM  *
11069585STim.Szeto@Sun.COM  * disk - pointer to diskResource structure that represents the properties
11079585STim.Szeto@Sun.COM  *        for the disk logical unit to be created.
11089585STim.Szeto@Sun.COM  */
11099585STim.Szeto@Sun.COM static int
11109585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid)
11119585STim.Szeto@Sun.COM {
11129585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
11139585STim.Szeto@Sun.COM 	int dataFileNameLen = 0;
11149585STim.Szeto@Sun.COM 	int metaFileNameLen = 0;
11159585STim.Szeto@Sun.COM 	int serialNumLen = 0;
11169585STim.Szeto@Sun.COM 	int luAliasLen = 0;
111710113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
11189585STim.Szeto@Sun.COM 	int sluBufSize = 0;
11199585STim.Szeto@Sun.COM 	int bufOffset = 0;
11209585STim.Szeto@Sun.COM 	int fd = 0;
11219585STim.Szeto@Sun.COM 	int ioctlRet;
11229585STim.Szeto@Sun.COM 	int savedErrno;
11239585STim.Szeto@Sun.COM 	stmfGuid guid;
11249585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
11259585STim.Szeto@Sun.COM 
11269585STim.Szeto@Sun.COM 	sbd_create_and_reg_lu_t *sbdLu = NULL;
11279585STim.Szeto@Sun.COM 
11289585STim.Szeto@Sun.COM 	/*
11299585STim.Szeto@Sun.COM 	 * Open control node for sbd
11309585STim.Szeto@Sun.COM 	 */
11319585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
11329585STim.Szeto@Sun.COM 		return (ret);
11339585STim.Szeto@Sun.COM 
11349585STim.Szeto@Sun.COM 	/* data file name must be specified */
11359585STim.Szeto@Sun.COM 	if (disk->luDataFileNameValid) {
11369585STim.Szeto@Sun.COM 		dataFileNameLen = strlen(disk->luDataFileName);
11379585STim.Szeto@Sun.COM 	} else {
11389585STim.Szeto@Sun.COM 		(void) close(fd);
11399585STim.Szeto@Sun.COM 		return (STMF_ERROR_MISSING_PROP_VAL);
11409585STim.Szeto@Sun.COM 	}
11419585STim.Szeto@Sun.COM 
11429585STim.Szeto@Sun.COM 	sluBufSize += dataFileNameLen + 1;
11439585STim.Szeto@Sun.COM 
11449585STim.Szeto@Sun.COM 	if (disk->luMetaFileNameValid) {
11459585STim.Szeto@Sun.COM 		metaFileNameLen = strlen(disk->luMetaFileName);
11469585STim.Szeto@Sun.COM 		sluBufSize += metaFileNameLen + 1;
11479585STim.Szeto@Sun.COM 	}
11489585STim.Szeto@Sun.COM 
11499585STim.Szeto@Sun.COM 	serialNumLen = strlen(disk->serialNum);
11509585STim.Szeto@Sun.COM 	sluBufSize += serialNumLen;
11519585STim.Szeto@Sun.COM 
11529585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
11539585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
11549585STim.Szeto@Sun.COM 		sluBufSize += luAliasLen + 1;
11559585STim.Szeto@Sun.COM 	}
11569585STim.Szeto@Sun.COM 
115710113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
115810113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
115910113SNattuvetty.Bhavyan@Sun.COM 		sluBufSize += luMgmtUrlLen + 1;
116010113SNattuvetty.Bhavyan@Sun.COM 	}
116110113SNattuvetty.Bhavyan@Sun.COM 
11629585STim.Szeto@Sun.COM 	/*
11639585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
11649585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
11659585STim.Szeto@Sun.COM 	 */
11669585STim.Szeto@Sun.COM 	sbdLu = (sbd_create_and_reg_lu_t *)calloc(1,
11679585STim.Szeto@Sun.COM 	    sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8);
11689585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
11699585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
11709585STim.Szeto@Sun.COM 	}
11719585STim.Szeto@Sun.COM 
11729585STim.Szeto@Sun.COM 	sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) +
11739585STim.Szeto@Sun.COM 	    sluBufSize - 8;
11749585STim.Szeto@Sun.COM 
11759585STim.Szeto@Sun.COM 	if (metaFileNameLen) {
11769585STim.Szeto@Sun.COM 		sbdLu->slu_meta_fname_valid = 1;
11779585STim.Szeto@Sun.COM 		sbdLu->slu_meta_fname_off = bufOffset;
11789585STim.Szeto@Sun.COM 		bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]),
11799585STim.Szeto@Sun.COM 		    metaFileNameLen + 1);
11809585STim.Szeto@Sun.COM 		bufOffset += metaFileNameLen + 1;
11819585STim.Szeto@Sun.COM 	}
11829585STim.Szeto@Sun.COM 
11839585STim.Szeto@Sun.COM 	bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]),
11849585STim.Szeto@Sun.COM 	    dataFileNameLen + 1);
11859585STim.Szeto@Sun.COM 	sbdLu->slu_data_fname_off = bufOffset;
11869585STim.Szeto@Sun.COM 	bufOffset += dataFileNameLen + 1;
11879585STim.Szeto@Sun.COM 
11889585STim.Szeto@Sun.COM 	/* currently, serial # is not passed null terminated to the driver */
11899585STim.Szeto@Sun.COM 	if (disk->serialNumValid) {
11909585STim.Szeto@Sun.COM 		sbdLu->slu_serial_valid = 1;
11919585STim.Szeto@Sun.COM 		sbdLu->slu_serial_off = bufOffset;
11929585STim.Szeto@Sun.COM 		sbdLu->slu_serial_size = serialNumLen;
11939585STim.Szeto@Sun.COM 		bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]),
11949585STim.Szeto@Sun.COM 		    serialNumLen);
11959585STim.Szeto@Sun.COM 		bufOffset += serialNumLen;
11969585STim.Szeto@Sun.COM 	}
11979585STim.Szeto@Sun.COM 
11989585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
11999585STim.Szeto@Sun.COM 		sbdLu->slu_alias_valid = 1;
12009585STim.Szeto@Sun.COM 		sbdLu->slu_alias_off = bufOffset;
12019585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]),
12029585STim.Szeto@Sun.COM 		    luAliasLen + 1);
12039585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
12049585STim.Szeto@Sun.COM 	}
12059585STim.Szeto@Sun.COM 
120610113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
120710113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->slu_mgmt_url_valid = 1;
120810113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->slu_mgmt_url_off = bufOffset;
120910113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]),
121010113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
121110113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
121210113SNattuvetty.Bhavyan@Sun.COM 	}
121310113SNattuvetty.Bhavyan@Sun.COM 
12149585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
12159585STim.Szeto@Sun.COM 		sbdLu->slu_lu_size_valid = 1;
12169585STim.Szeto@Sun.COM 		sbdLu->slu_lu_size = disk->luSize;
12179585STim.Szeto@Sun.COM 	}
12189585STim.Szeto@Sun.COM 
12199585STim.Szeto@Sun.COM 	if (disk->luGuidValid) {
12209585STim.Szeto@Sun.COM 		sbdLu->slu_guid_valid = 1;
12219585STim.Szeto@Sun.COM 		bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid));
12229585STim.Szeto@Sun.COM 	}
12239585STim.Szeto@Sun.COM 
12249585STim.Szeto@Sun.COM 	if (disk->vidValid) {
12259585STim.Szeto@Sun.COM 		sbdLu->slu_vid_valid = 1;
12269585STim.Szeto@Sun.COM 		bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid));
12279585STim.Szeto@Sun.COM 	}
12289585STim.Szeto@Sun.COM 
12299585STim.Szeto@Sun.COM 	if (disk->pidValid) {
12309585STim.Szeto@Sun.COM 		sbdLu->slu_pid_valid = 1;
12319585STim.Szeto@Sun.COM 		bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid));
12329585STim.Szeto@Sun.COM 	}
12339585STim.Szeto@Sun.COM 
12349585STim.Szeto@Sun.COM 	if (disk->revValid) {
12359585STim.Szeto@Sun.COM 		sbdLu->slu_rev_valid = 1;
12369585STim.Szeto@Sun.COM 		bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev));
12379585STim.Szeto@Sun.COM 	}
12389585STim.Szeto@Sun.COM 
12399585STim.Szeto@Sun.COM 	if (disk->companyIdValid) {
12409585STim.Szeto@Sun.COM 		sbdLu->slu_company_id_valid = 1;
12419585STim.Szeto@Sun.COM 		sbdLu->slu_company_id = disk->companyId;
12429585STim.Szeto@Sun.COM 	}
12439585STim.Szeto@Sun.COM 
12449585STim.Szeto@Sun.COM 	if (disk->blkSizeValid) {
12459585STim.Szeto@Sun.COM 		sbdLu->slu_blksize_valid = 1;
12469585STim.Szeto@Sun.COM 		sbdLu->slu_blksize = disk->blkSize;
12479585STim.Szeto@Sun.COM 	}
12489585STim.Szeto@Sun.COM 
12499585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
12509585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
12519585STim.Szeto@Sun.COM 			sbdLu->slu_write_protected = 1;
12529585STim.Szeto@Sun.COM 		}
12539585STim.Szeto@Sun.COM 	}
12549585STim.Szeto@Sun.COM 
12559585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
12569585STim.Szeto@Sun.COM 		sbdLu->slu_writeback_cache_disable_valid = 1;
12579585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
12589585STim.Szeto@Sun.COM 			sbdLu->slu_writeback_cache_disable = 1;
12599585STim.Szeto@Sun.COM 		}
12609585STim.Szeto@Sun.COM 	}
12619585STim.Szeto@Sun.COM 
12629585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
12639585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size;
12649585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
12659585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size;
12669585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
12679585STim.Szeto@Sun.COM 
12689585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl);
12699585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
12709585STim.Szeto@Sun.COM 		savedErrno = errno;
12719585STim.Szeto@Sun.COM 		switch (savedErrno) {
12729585STim.Szeto@Sun.COM 			case EBUSY:
12739585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
12749585STim.Szeto@Sun.COM 				break;
12759585STim.Szeto@Sun.COM 			case EPERM:
12769585STim.Szeto@Sun.COM 			case EACCES:
12779585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
12789585STim.Szeto@Sun.COM 				break;
12799585STim.Szeto@Sun.COM 			default:
12809585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
12819585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
12829585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
12839585STim.Szeto@Sun.COM 					"createDiskLu:ioctl "
12849585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
12859585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
12869585STim.Szeto@Sun.COM 				}
12879585STim.Szeto@Sun.COM 				break;
12889585STim.Szeto@Sun.COM 		}
12899585STim.Szeto@Sun.COM 	}
12909585STim.Szeto@Sun.COM 
12919585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
12929585STim.Szeto@Sun.COM 		goto done;
12939585STim.Szeto@Sun.COM 	}
12949585STim.Szeto@Sun.COM 
12959585STim.Szeto@Sun.COM 	/*
12969585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
12979585STim.Szeto@Sun.COM 	 * NULL
12989585STim.Szeto@Sun.COM 	 */
12999585STim.Szeto@Sun.COM 	if (createdGuid) {
13009585STim.Szeto@Sun.COM 		bcopy(sbdLu->slu_guid, createdGuid->guid,
13019585STim.Szeto@Sun.COM 		    sizeof (sbdLu->slu_guid));
13029585STim.Szeto@Sun.COM 	}
13039585STim.Szeto@Sun.COM 
13049585STim.Szeto@Sun.COM 	bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid));
13059585STim.Szeto@Sun.COM 	if (disk->luMetaFileNameValid) {
13069585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&guid, disk->luMetaFileName);
13079585STim.Szeto@Sun.COM 	} else {
13089585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&guid, disk->luDataFileName);
13099585STim.Szeto@Sun.COM 	}
13109585STim.Szeto@Sun.COM done:
13119585STim.Szeto@Sun.COM 	free(sbdLu);
13129585STim.Szeto@Sun.COM 	(void) close(fd);
13139585STim.Szeto@Sun.COM 	return (ret);
13149585STim.Szeto@Sun.COM }
13159585STim.Szeto@Sun.COM 
13169585STim.Szeto@Sun.COM 
13179585STim.Szeto@Sun.COM /*
13189585STim.Szeto@Sun.COM  * stmfImportLu
13199585STim.Szeto@Sun.COM  *
13209585STim.Szeto@Sun.COM  * Purpose: Import a previously created logical unit
13219585STim.Szeto@Sun.COM  *
13229585STim.Szeto@Sun.COM  * dType - Type of logical unit
13239585STim.Szeto@Sun.COM  *         Can be: STMF_DISK
13249585STim.Szeto@Sun.COM  *
13259585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the imported logical
13269585STim.Szeto@Sun.COM  *	    unit
13279585STim.Szeto@Sun.COM  *
13289585STim.Szeto@Sun.COM  * fname - A file name where the metadata resides
13299585STim.Szeto@Sun.COM  *
13309585STim.Szeto@Sun.COM  */
13319585STim.Szeto@Sun.COM int
13329585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid)
13339585STim.Szeto@Sun.COM {
13349585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
13359585STim.Szeto@Sun.COM 
13369585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
13379585STim.Szeto@Sun.COM 		ret = importDiskLu(fname, luGuid);
13389585STim.Szeto@Sun.COM 	} else {
13399585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13409585STim.Szeto@Sun.COM 	}
13419585STim.Szeto@Sun.COM 
13429585STim.Szeto@Sun.COM 	return (ret);
13439585STim.Szeto@Sun.COM }
13449585STim.Szeto@Sun.COM 
13459585STim.Szeto@Sun.COM /*
13469585STim.Szeto@Sun.COM  * importDiskLu
13479585STim.Szeto@Sun.COM  *
13489585STim.Szeto@Sun.COM  * filename - filename to import
13499585STim.Szeto@Sun.COM  * createdGuid - if not NULL, on success contains the imported guid
13509585STim.Szeto@Sun.COM  *
13519585STim.Szeto@Sun.COM  */
13529585STim.Szeto@Sun.COM static int
13539585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid)
13549585STim.Szeto@Sun.COM {
13559585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
13569585STim.Szeto@Sun.COM 	int fd = 0;
13579585STim.Szeto@Sun.COM 	int ioctlRet;
13589585STim.Szeto@Sun.COM 	int savedErrno;
13599585STim.Szeto@Sun.COM 	int metaFileNameLen;
13609585STim.Szeto@Sun.COM 	stmfGuid iGuid;
13619585STim.Szeto@Sun.COM 	int iluBufSize = 0;
13629585STim.Szeto@Sun.COM 	sbd_import_lu_t *sbdLu = NULL;
13639585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
13649585STim.Szeto@Sun.COM 
13659585STim.Szeto@Sun.COM 	if (fname == NULL) {
13669585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13679585STim.Szeto@Sun.COM 	}
13689585STim.Szeto@Sun.COM 
13699585STim.Szeto@Sun.COM 	/*
13709585STim.Szeto@Sun.COM 	 * Open control node for sbd
13719585STim.Szeto@Sun.COM 	 */
13729585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
13739585STim.Szeto@Sun.COM 		return (ret);
13749585STim.Szeto@Sun.COM 
13759585STim.Szeto@Sun.COM 	metaFileNameLen = strlen(fname);
13769585STim.Szeto@Sun.COM 	iluBufSize += metaFileNameLen + 1;
13779585STim.Szeto@Sun.COM 
13789585STim.Szeto@Sun.COM 	/*
13799585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
13809585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
13819585STim.Szeto@Sun.COM 	 */
13829585STim.Szeto@Sun.COM 	sbdLu = (sbd_import_lu_t *)calloc(1,
13839585STim.Szeto@Sun.COM 	    sizeof (sbd_import_lu_t) + iluBufSize - 8);
13849585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
13859585STim.Szeto@Sun.COM 		(void) close(fd);
13869585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
13879585STim.Szeto@Sun.COM 	}
13889585STim.Szeto@Sun.COM 
13899585STim.Szeto@Sun.COM 	/*
13909585STim.Szeto@Sun.COM 	 * Accept either a data file or meta data file.
13919585STim.Szeto@Sun.COM 	 * sbd will do the right thing here either way.
13929585STim.Szeto@Sun.COM 	 * i.e. if it's a data file, it assumes that the
13939585STim.Szeto@Sun.COM 	 * meta data is shared with the data.
13949585STim.Szeto@Sun.COM 	 */
13959585STim.Szeto@Sun.COM 	(void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen);
13969585STim.Szeto@Sun.COM 
13979585STim.Szeto@Sun.COM 	sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8;
13989585STim.Szeto@Sun.COM 
13999585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
14009585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size;
14019585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
14029585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size;
14039585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
14049585STim.Szeto@Sun.COM 
14059585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl);
14069585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
14079585STim.Szeto@Sun.COM 		savedErrno = errno;
14089585STim.Szeto@Sun.COM 		switch (savedErrno) {
14099585STim.Szeto@Sun.COM 			case EBUSY:
14109585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
14119585STim.Szeto@Sun.COM 				break;
14129585STim.Szeto@Sun.COM 			case EPERM:
14139585STim.Szeto@Sun.COM 			case EACCES:
14149585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
14159585STim.Szeto@Sun.COM 				break;
14169585STim.Szeto@Sun.COM 			default:
14179585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
14189585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
14199585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
14209585STim.Szeto@Sun.COM 					"importDiskLu:ioctl "
14219585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
14229585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
14239585STim.Szeto@Sun.COM 				}
14249585STim.Szeto@Sun.COM 				break;
14259585STim.Szeto@Sun.COM 		}
14269585STim.Szeto@Sun.COM 	}
14279585STim.Szeto@Sun.COM 
14289585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
14299585STim.Szeto@Sun.COM 		goto done;
14309585STim.Szeto@Sun.COM 	}
14319585STim.Szeto@Sun.COM 
14329585STim.Szeto@Sun.COM 	/*
14339585STim.Szeto@Sun.COM 	 * on success, copy the resulting guid into the caller's guid if not
14349585STim.Szeto@Sun.COM 	 * NULL and add it to the persistent store for sbd
14359585STim.Szeto@Sun.COM 	 */
14369585STim.Szeto@Sun.COM 	if (createdGuid) {
14379585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
14389585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14399585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(createdGuid, fname);
14409585STim.Szeto@Sun.COM 	} else {
14419585STim.Szeto@Sun.COM 		bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
14429585STim.Szeto@Sun.COM 		    sizeof (sbdLu->ilu_ret_guid));
14439585STim.Szeto@Sun.COM 		ret = addGuidToDiskStore(&iGuid, fname);
14449585STim.Szeto@Sun.COM 	}
14459585STim.Szeto@Sun.COM done:
14469585STim.Szeto@Sun.COM 	free(sbdLu);
14479585STim.Szeto@Sun.COM 	(void) close(fd);
14489585STim.Szeto@Sun.COM 	return (ret);
14499585STim.Szeto@Sun.COM }
14509585STim.Szeto@Sun.COM 
14519585STim.Szeto@Sun.COM /*
14529585STim.Szeto@Sun.COM  * diskError
14539585STim.Szeto@Sun.COM  *
14549585STim.Szeto@Sun.COM  * Purpose: Translate sbd driver error
14559585STim.Szeto@Sun.COM  */
14569585STim.Szeto@Sun.COM static void
14579585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret)
14589585STim.Szeto@Sun.COM {
14599585STim.Szeto@Sun.COM 	switch (stmfError) {
14609585STim.Szeto@Sun.COM 		case SBD_RET_META_CREATION_FAILED:
14619585STim.Szeto@Sun.COM 		case SBD_RET_ZFS_META_CREATE_FAILED:
14629585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_CREATION;
14639585STim.Szeto@Sun.COM 			break;
14649585STim.Szeto@Sun.COM 		case SBD_RET_INVALID_BLKSIZE:
14659585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_INVALID_BLKSIZE;
14669585STim.Szeto@Sun.COM 			break;
14679585STim.Szeto@Sun.COM 		case SBD_RET_FILE_ALREADY_REGISTERED:
14689585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_IN_USE;
14699585STim.Szeto@Sun.COM 			break;
14709585STim.Szeto@Sun.COM 		case SBD_RET_GUID_ALREADY_REGISTERED:
14719585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_GUID_IN_USE;
14729585STim.Szeto@Sun.COM 			break;
14739585STim.Szeto@Sun.COM 		case SBD_RET_META_PATH_NOT_ABSOLUTE:
14749585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_LOOKUP_FAILED:
14759585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_OPEN_FAILED:
14769585STim.Szeto@Sun.COM 		case SBD_RET_META_FILE_GETATTR_FAILED:
14779585STim.Szeto@Sun.COM 		case SBD_RET_NO_META:
14789585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_META_FILE_NAME;
14799585STim.Szeto@Sun.COM 			break;
14809585STim.Szeto@Sun.COM 		case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
14819585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_LOOKUP_FAILED:
14829585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_OPEN_FAILED:
14839585STim.Szeto@Sun.COM 		case SBD_RET_DATA_FILE_GETATTR_FAILED:
14849585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_DATA_FILE_NAME;
14859585STim.Szeto@Sun.COM 			break;
14869585STim.Szeto@Sun.COM 		case SBD_RET_FILE_SIZE_ERROR:
14879585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_FILE_SIZE_INVALID;
14889585STim.Szeto@Sun.COM 			break;
14899585STim.Szeto@Sun.COM 		case SBD_RET_SIZE_OUT_OF_RANGE:
14909585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
14919585STim.Szeto@Sun.COM 			break;
14929585STim.Szeto@Sun.COM 		case SBD_RET_LU_BUSY:
14939585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_LU_BUSY;
14949585STim.Szeto@Sun.COM 			break;
14959585STim.Szeto@Sun.COM 		case SBD_RET_WRITE_CACHE_SET_FAILED:
14969585STim.Szeto@Sun.COM 			*ret = STMF_ERROR_WRITE_CACHE_SET;
14979585STim.Szeto@Sun.COM 			break;
1498*10725SJohn.Forte@Sun.COM 		case SBD_RET_ACCESS_STATE_FAILED:
1499*10725SJohn.Forte@Sun.COM 			*ret = STMF_ERROR_ACCESS_STATE_SET;
1500*10725SJohn.Forte@Sun.COM 			break;
15019585STim.Szeto@Sun.COM 		default:
15029585STim.Szeto@Sun.COM 			*ret = STMF_STATUS_ERROR;
15039585STim.Szeto@Sun.COM 			break;
15049585STim.Szeto@Sun.COM 	}
15059585STim.Szeto@Sun.COM }
15069585STim.Szeto@Sun.COM 
15079585STim.Szeto@Sun.COM /*
15089585STim.Szeto@Sun.COM  * Creates a logical unit resource of type STMF_DISK.
15099585STim.Szeto@Sun.COM  *
15109585STim.Szeto@Sun.COM  * No defaults should be set here as all defaults are derived from the
15119585STim.Szeto@Sun.COM  * driver's default settings.
15129585STim.Szeto@Sun.COM  */
15139585STim.Szeto@Sun.COM static int
15149585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl)
15159585STim.Szeto@Sun.COM {
15169585STim.Szeto@Sun.COM 	hdl->type = STMF_DISK;
15179585STim.Szeto@Sun.COM 
15189585STim.Szeto@Sun.COM 	hdl->resource = calloc(1, sizeof (diskResource));
15199585STim.Szeto@Sun.COM 	if (hdl->resource == NULL) {
15209585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
15219585STim.Szeto@Sun.COM 	}
15229585STim.Szeto@Sun.COM 
15239585STim.Szeto@Sun.COM 	return (STMF_STATUS_SUCCESS);
15249585STim.Szeto@Sun.COM }
15259585STim.Szeto@Sun.COM 
15269585STim.Szeto@Sun.COM /*
15279585STim.Szeto@Sun.COM  * stmfDeleteLu
15289585STim.Szeto@Sun.COM  *
15299585STim.Szeto@Sun.COM  * Purpose: Delete a logical unit
15309585STim.Szeto@Sun.COM  *
15319585STim.Szeto@Sun.COM  * hdl - handle to logical unit resource created via stmfCreateLuResource
15329585STim.Szeto@Sun.COM  *
15339585STim.Szeto@Sun.COM  * luGuid - If non-NULL, on success, contains the guid of the created logical
15349585STim.Szeto@Sun.COM  *	    unit
15359585STim.Szeto@Sun.COM  */
15369585STim.Szeto@Sun.COM int
15379585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid)
15389585STim.Szeto@Sun.COM {
15399585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15409585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
15419585STim.Szeto@Sun.COM 
15429585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
15439585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
15449585STim.Szeto@Sun.COM 	}
15459585STim.Szeto@Sun.COM 
15469585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
15479585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
15489585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
15499585STim.Szeto@Sun.COM 		return (ret);
15509585STim.Szeto@Sun.COM 	} else {
15519585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
15529585STim.Szeto@Sun.COM 			ret = deleteDiskLu(luGuid);
15539585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
15549585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
15559585STim.Szeto@Sun.COM 		} else {
15569585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
15579585STim.Szeto@Sun.COM 		}
15589585STim.Szeto@Sun.COM 	}
15599585STim.Szeto@Sun.COM 
15609585STim.Szeto@Sun.COM 	return (ret);
15619585STim.Szeto@Sun.COM }
15629585STim.Szeto@Sun.COM 
15639585STim.Szeto@Sun.COM static int
15649585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid)
15659585STim.Szeto@Sun.COM {
15669585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
15679585STim.Szeto@Sun.COM 	int fd;
15689585STim.Szeto@Sun.COM 	int savedErrno;
15699585STim.Szeto@Sun.COM 	int ioctlRet;
15709585STim.Szeto@Sun.COM 	sbd_delete_lu_t deleteLu = {0};
15719585STim.Szeto@Sun.COM 
15729585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
15739585STim.Szeto@Sun.COM 
15749585STim.Szeto@Sun.COM 	/*
15759585STim.Szeto@Sun.COM 	 * Open control node for sbd
15769585STim.Szeto@Sun.COM 	 */
15779585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
15789585STim.Szeto@Sun.COM 		return (ret);
15799585STim.Szeto@Sun.COM 
15809585STim.Szeto@Sun.COM 	ret = removeGuidFromDiskStore(luGuid);
15819585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
15829585STim.Szeto@Sun.COM 		goto done;
15839585STim.Szeto@Sun.COM 	}
15849585STim.Szeto@Sun.COM 
15859585STim.Szeto@Sun.COM 	bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
15869585STim.Szeto@Sun.COM 	deleteLu.dlu_by_guid = 1;
15879585STim.Szeto@Sun.COM 
15889585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
15899585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
15909585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
15919585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
15929585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
15939585STim.Szeto@Sun.COM 		savedErrno = errno;
15949585STim.Szeto@Sun.COM 		switch (savedErrno) {
15959585STim.Szeto@Sun.COM 			case EBUSY:
15969585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
15979585STim.Szeto@Sun.COM 				break;
15989585STim.Szeto@Sun.COM 			case EPERM:
15999585STim.Szeto@Sun.COM 			case EACCES:
16009585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
16019585STim.Szeto@Sun.COM 				break;
16029585STim.Szeto@Sun.COM 			case ENOENT:
16039585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
16049585STim.Szeto@Sun.COM 				break;
16059585STim.Szeto@Sun.COM 			default:
16069585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
16079585STim.Szeto@Sun.COM 				    "deleteDiskLu:ioctl error(%d) (%d) (%d)",
16089585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
16099585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
16109585STim.Szeto@Sun.COM 				break;
16119585STim.Szeto@Sun.COM 		}
16129585STim.Szeto@Sun.COM 	}
16139585STim.Szeto@Sun.COM 
16149585STim.Szeto@Sun.COM done:
16159585STim.Szeto@Sun.COM 	(void) close(fd);
16169585STim.Szeto@Sun.COM 	return (ret);
16179585STim.Szeto@Sun.COM }
16189585STim.Szeto@Sun.COM 
16199585STim.Szeto@Sun.COM /*
1620*10725SJohn.Forte@Sun.COM  * stmfLuStandby
1621*10725SJohn.Forte@Sun.COM  *
1622*10725SJohn.Forte@Sun.COM  * Purpose: Sets access state to standby
1623*10725SJohn.Forte@Sun.COM  *
1624*10725SJohn.Forte@Sun.COM  * luGuid - guid of registered logical unit
1625*10725SJohn.Forte@Sun.COM  *
1626*10725SJohn.Forte@Sun.COM  */
1627*10725SJohn.Forte@Sun.COM int
1628*10725SJohn.Forte@Sun.COM stmfLuStandby(stmfGuid *luGuid)
1629*10725SJohn.Forte@Sun.COM {
1630*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
1631*10725SJohn.Forte@Sun.COM 	stmfLogicalUnitProperties luProps;
1632*10725SJohn.Forte@Sun.COM 
1633*10725SJohn.Forte@Sun.COM 	if (luGuid == NULL) {
1634*10725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1635*10725SJohn.Forte@Sun.COM 	}
1636*10725SJohn.Forte@Sun.COM 
1637*10725SJohn.Forte@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
1638*10725SJohn.Forte@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1639*10725SJohn.Forte@Sun.COM 	    != STMF_STATUS_SUCCESS) {
1640*10725SJohn.Forte@Sun.COM 		return (ret);
1641*10725SJohn.Forte@Sun.COM 	} else {
1642*10725SJohn.Forte@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
1643*10725SJohn.Forte@Sun.COM 			ret = setDiskStandby(luGuid);
1644*10725SJohn.Forte@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1645*10725SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
1646*10725SJohn.Forte@Sun.COM 		} else {
1647*10725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
1648*10725SJohn.Forte@Sun.COM 		}
1649*10725SJohn.Forte@Sun.COM 	}
1650*10725SJohn.Forte@Sun.COM 
1651*10725SJohn.Forte@Sun.COM 	return (ret);
1652*10725SJohn.Forte@Sun.COM }
1653*10725SJohn.Forte@Sun.COM 
1654*10725SJohn.Forte@Sun.COM static int
1655*10725SJohn.Forte@Sun.COM setDiskStandby(stmfGuid *luGuid)
1656*10725SJohn.Forte@Sun.COM {
1657*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
1658*10725SJohn.Forte@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
1659*10725SJohn.Forte@Sun.COM 	sbd_set_lu_standby_t sbdLu = {0};
1660*10725SJohn.Forte@Sun.COM 	int ioctlRet;
1661*10725SJohn.Forte@Sun.COM 	int savedErrno;
1662*10725SJohn.Forte@Sun.COM 	int fd = 0;
1663*10725SJohn.Forte@Sun.COM 
1664*10725SJohn.Forte@Sun.COM 	/*
1665*10725SJohn.Forte@Sun.COM 	 * Open control node for sbd
1666*10725SJohn.Forte@Sun.COM 	 */
1667*10725SJohn.Forte@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1668*10725SJohn.Forte@Sun.COM 		return (ret);
1669*10725SJohn.Forte@Sun.COM 
1670*10725SJohn.Forte@Sun.COM 	bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid));
1671*10725SJohn.Forte@Sun.COM 
1672*10725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
1673*10725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t);
1674*10725SJohn.Forte@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu;
1675*10725SJohn.Forte@Sun.COM 
1676*10725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl);
1677*10725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
1678*10725SJohn.Forte@Sun.COM 		savedErrno = errno;
1679*10725SJohn.Forte@Sun.COM 		switch (savedErrno) {
1680*10725SJohn.Forte@Sun.COM 			case EBUSY:
1681*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
1682*10725SJohn.Forte@Sun.COM 				break;
1683*10725SJohn.Forte@Sun.COM 			case EPERM:
1684*10725SJohn.Forte@Sun.COM 			case EACCES:
1685*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
1686*10725SJohn.Forte@Sun.COM 				break;
1687*10725SJohn.Forte@Sun.COM 			default:
1688*10725SJohn.Forte@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
1689*10725SJohn.Forte@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
1690*10725SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
1691*10725SJohn.Forte@Sun.COM 					"setDiskStandby:ioctl "
1692*10725SJohn.Forte@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
1693*10725SJohn.Forte@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
1694*10725SJohn.Forte@Sun.COM 				}
1695*10725SJohn.Forte@Sun.COM 				break;
1696*10725SJohn.Forte@Sun.COM 		}
1697*10725SJohn.Forte@Sun.COM 	}
1698*10725SJohn.Forte@Sun.COM 	return (ret);
1699*10725SJohn.Forte@Sun.COM }
1700*10725SJohn.Forte@Sun.COM 
1701*10725SJohn.Forte@Sun.COM /*
17029585STim.Szeto@Sun.COM  * stmfModifyLu
17039585STim.Szeto@Sun.COM  *
17049585STim.Szeto@Sun.COM  * Purpose: Modify properties of a logical unit
17059585STim.Szeto@Sun.COM  *
17069585STim.Szeto@Sun.COM  * luGuid - guid of registered logical unit
17079585STim.Szeto@Sun.COM  * prop - property to modify
17089585STim.Szeto@Sun.COM  * propVal - property value to set
17099585STim.Szeto@Sun.COM  *
17109585STim.Szeto@Sun.COM  */
17119585STim.Szeto@Sun.COM int
17129585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
17139585STim.Szeto@Sun.COM {
17149585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17159585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
17169585STim.Szeto@Sun.COM 
17179585STim.Szeto@Sun.COM 	if (luGuid == NULL) {
17189585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17199585STim.Szeto@Sun.COM 	}
17209585STim.Szeto@Sun.COM 
17219585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
17229585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
17239585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
17249585STim.Szeto@Sun.COM 		return (ret);
17259585STim.Szeto@Sun.COM 	} else {
17269585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
17279585STim.Szeto@Sun.COM 			ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
17289585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
17299585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
17309585STim.Szeto@Sun.COM 		} else {
17319585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
17329585STim.Szeto@Sun.COM 		}
17339585STim.Szeto@Sun.COM 	}
17349585STim.Szeto@Sun.COM 
17359585STim.Szeto@Sun.COM 	return (ret);
17369585STim.Szeto@Sun.COM }
17379585STim.Szeto@Sun.COM 
17389585STim.Szeto@Sun.COM /*
17399585STim.Szeto@Sun.COM  * stmfModifyLuByFname
17409585STim.Szeto@Sun.COM  *
17419585STim.Szeto@Sun.COM  * Purpose: Modify a device by filename. Device does not need to be registered.
17429585STim.Szeto@Sun.COM  *
17439585STim.Szeto@Sun.COM  * dType - type of device to modify
17449585STim.Szeto@Sun.COM  *         STMF_DISK
17459585STim.Szeto@Sun.COM  *
17469585STim.Szeto@Sun.COM  * fname - filename or meta filename
17479585STim.Szeto@Sun.COM  * prop - valid property identifier
17489585STim.Szeto@Sun.COM  * propVal - property value
17499585STim.Szeto@Sun.COM  *
17509585STim.Szeto@Sun.COM  */
17519585STim.Szeto@Sun.COM int
17529585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
17539585STim.Szeto@Sun.COM     const char *propVal)
17549585STim.Szeto@Sun.COM {
17559585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17569585STim.Szeto@Sun.COM 	if (fname == NULL) {
17579585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17589585STim.Szeto@Sun.COM 	}
17599585STim.Szeto@Sun.COM 
17609585STim.Szeto@Sun.COM 	if (dType == STMF_DISK) {
17619585STim.Szeto@Sun.COM 		ret = modifyDiskLuProp(NULL, fname, prop, propVal);
17629585STim.Szeto@Sun.COM 	} else {
17639585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17649585STim.Szeto@Sun.COM 	}
17659585STim.Szeto@Sun.COM 
17669585STim.Szeto@Sun.COM 	return (ret);
17679585STim.Szeto@Sun.COM }
17689585STim.Szeto@Sun.COM 
17699585STim.Szeto@Sun.COM static int
17709585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
17719585STim.Szeto@Sun.COM     const char *propVal)
17729585STim.Szeto@Sun.COM {
17739585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17749585STim.Szeto@Sun.COM 	luResource hdl = NULL;
17759585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl;
17769585STim.Szeto@Sun.COM 
17779585STim.Szeto@Sun.COM 	ret = stmfCreateLuResource(STMF_DISK, &hdl);
17789585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17799585STim.Szeto@Sun.COM 		return (ret);
17809585STim.Szeto@Sun.COM 	}
17819585STim.Szeto@Sun.COM 	ret = validateModifyDiskProp(prop);
17829585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17839585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
17849585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_PROP);
17859585STim.Szeto@Sun.COM 	}
17869585STim.Szeto@Sun.COM 	ret = stmfSetLuProp(hdl, prop, propVal);
17879585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17889585STim.Szeto@Sun.COM 		(void) stmfFreeLuResource(hdl);
17899585STim.Szeto@Sun.COM 		return (ret);
17909585STim.Szeto@Sun.COM 	}
17919585STim.Szeto@Sun.COM 	luPropsHdl = hdl;
17929585STim.Szeto@Sun.COM 	ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
17939585STim.Szeto@Sun.COM 	(void) stmfFreeLuResource(hdl);
17949585STim.Szeto@Sun.COM 	return (ret);
17959585STim.Szeto@Sun.COM }
17969585STim.Szeto@Sun.COM 
17979585STim.Szeto@Sun.COM static int
17989585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop)
17999585STim.Szeto@Sun.COM {
18009585STim.Szeto@Sun.COM 	switch (prop) {
18019585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
18029585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
180310113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
18049585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
18059585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
18069585STim.Szeto@Sun.COM 			return (STMF_STATUS_SUCCESS);
18079585STim.Szeto@Sun.COM 			break;
18089585STim.Szeto@Sun.COM 		default:
18099585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
18109585STim.Szeto@Sun.COM 			break;
18119585STim.Szeto@Sun.COM 	}
18129585STim.Szeto@Sun.COM }
18139585STim.Szeto@Sun.COM 
18149585STim.Szeto@Sun.COM static int
18159585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
18169585STim.Szeto@Sun.COM {
18179585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
18189585STim.Szeto@Sun.COM 	int luAliasLen = 0;
181910113SNattuvetty.Bhavyan@Sun.COM 	int luMgmtUrlLen = 0;
18209585STim.Szeto@Sun.COM 	int mluBufSize = 0;
18219585STim.Szeto@Sun.COM 	int bufOffset = 0;
18229585STim.Szeto@Sun.COM 	int fd = 0;
18239585STim.Szeto@Sun.COM 	int ioctlRet;
18249585STim.Szeto@Sun.COM 	int savedErrno;
18259585STim.Szeto@Sun.COM 	int fnameSize = 0;
18269585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
18279585STim.Szeto@Sun.COM 
18289585STim.Szeto@Sun.COM 	sbd_modify_lu_t *sbdLu = NULL;
18299585STim.Szeto@Sun.COM 
18309585STim.Szeto@Sun.COM 	if (luGuid == NULL && fname == NULL) {
18319585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
18329585STim.Szeto@Sun.COM 	}
18339585STim.Szeto@Sun.COM 
18349585STim.Szeto@Sun.COM 	if (fname) {
18359585STim.Szeto@Sun.COM 		fnameSize = strlen(fname) + 1;
18369585STim.Szeto@Sun.COM 		mluBufSize += fnameSize;
18379585STim.Szeto@Sun.COM 	}
18389585STim.Szeto@Sun.COM 
18399585STim.Szeto@Sun.COM 	/*
18409585STim.Szeto@Sun.COM 	 * Open control node for sbd
18419585STim.Szeto@Sun.COM 	 */
18429585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
18439585STim.Szeto@Sun.COM 		return (ret);
18449585STim.Szeto@Sun.COM 
18459585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18469585STim.Szeto@Sun.COM 		luAliasLen = strlen(disk->luAlias);
18479585STim.Szeto@Sun.COM 		mluBufSize += luAliasLen + 1;
18489585STim.Szeto@Sun.COM 	}
18499585STim.Szeto@Sun.COM 
185010113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
185110113SNattuvetty.Bhavyan@Sun.COM 		luMgmtUrlLen = strlen(disk->luMgmtUrl);
185210113SNattuvetty.Bhavyan@Sun.COM 		mluBufSize += luMgmtUrlLen + 1;
185310113SNattuvetty.Bhavyan@Sun.COM 	}
185410113SNattuvetty.Bhavyan@Sun.COM 
18559585STim.Szeto@Sun.COM 	/*
18569585STim.Szeto@Sun.COM 	 * 8 is the size of the buffer set aside for
18579585STim.Szeto@Sun.COM 	 * concatenation of variable length fields
18589585STim.Szeto@Sun.COM 	 */
18599585STim.Szeto@Sun.COM 	sbdLu = (sbd_modify_lu_t *)calloc(1,
18609585STim.Szeto@Sun.COM 	    sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
18619585STim.Szeto@Sun.COM 	if (sbdLu == NULL) {
18629585STim.Szeto@Sun.COM 		(void) close(fd);
18639585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
18649585STim.Szeto@Sun.COM 	}
18659585STim.Szeto@Sun.COM 
18669585STim.Szeto@Sun.COM 	sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
18679585STim.Szeto@Sun.COM 	    mluBufSize - 8 + fnameSize;
18689585STim.Szeto@Sun.COM 
18699585STim.Szeto@Sun.COM 	if (disk->luAliasValid) {
18709585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_valid = 1;
18719585STim.Szeto@Sun.COM 		sbdLu->mlu_alias_off = bufOffset;
18729585STim.Szeto@Sun.COM 		bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
18739585STim.Szeto@Sun.COM 		    luAliasLen + 1);
18749585STim.Szeto@Sun.COM 		bufOffset += luAliasLen + 1;
18759585STim.Szeto@Sun.COM 	}
18769585STim.Szeto@Sun.COM 
187710113SNattuvetty.Bhavyan@Sun.COM 	if (disk->luMgmtUrlValid) {
187810113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_valid = 1;
187910113SNattuvetty.Bhavyan@Sun.COM 		sbdLu->mlu_mgmt_url_off = bufOffset;
188010113SNattuvetty.Bhavyan@Sun.COM 		bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
188110113SNattuvetty.Bhavyan@Sun.COM 		    luMgmtUrlLen + 1);
188210113SNattuvetty.Bhavyan@Sun.COM 		bufOffset += luMgmtUrlLen + 1;
188310113SNattuvetty.Bhavyan@Sun.COM 	}
188410113SNattuvetty.Bhavyan@Sun.COM 
18859585STim.Szeto@Sun.COM 	if (disk->luSizeValid) {
18869585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size_valid = 1;
18879585STim.Szeto@Sun.COM 		sbdLu->mlu_lu_size = disk->luSize;
18889585STim.Szeto@Sun.COM 	}
18899585STim.Szeto@Sun.COM 
18909585STim.Szeto@Sun.COM 	if (disk->writeProtectEnableValid) {
18919585STim.Szeto@Sun.COM 		sbdLu->mlu_write_protected_valid = 1;
18929585STim.Szeto@Sun.COM 		if (disk->writeProtectEnable) {
18939585STim.Szeto@Sun.COM 			sbdLu->mlu_write_protected = 1;
18949585STim.Szeto@Sun.COM 		}
18959585STim.Szeto@Sun.COM 	}
18969585STim.Szeto@Sun.COM 
18979585STim.Szeto@Sun.COM 	if (disk->writebackCacheDisableValid) {
18989585STim.Szeto@Sun.COM 		sbdLu->mlu_writeback_cache_disable_valid = 1;
18999585STim.Szeto@Sun.COM 		if (disk->writebackCacheDisable) {
19009585STim.Szeto@Sun.COM 			sbdLu->mlu_writeback_cache_disable = 1;
19019585STim.Szeto@Sun.COM 		}
19029585STim.Szeto@Sun.COM 	}
19039585STim.Szeto@Sun.COM 
19049585STim.Szeto@Sun.COM 	if (luGuid) {
19059585STim.Szeto@Sun.COM 		bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
19069585STim.Szeto@Sun.COM 		sbdLu->mlu_by_guid = 1;
19079585STim.Szeto@Sun.COM 	} else {
19089585STim.Szeto@Sun.COM 		sbdLu->mlu_fname_off = bufOffset;
19099585STim.Szeto@Sun.COM 		bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
19109585STim.Szeto@Sun.COM 		sbdLu->mlu_by_fname = 1;
19119585STim.Szeto@Sun.COM 	}
19129585STim.Szeto@Sun.COM 
19139585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
19149585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
19159585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
19169585STim.Szeto@Sun.COM 
19179585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
19189585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
19199585STim.Szeto@Sun.COM 		savedErrno = errno;
19209585STim.Szeto@Sun.COM 		switch (savedErrno) {
19219585STim.Szeto@Sun.COM 			case EBUSY:
19229585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
19239585STim.Szeto@Sun.COM 				break;
19249585STim.Szeto@Sun.COM 			case EPERM:
19259585STim.Szeto@Sun.COM 			case EACCES:
19269585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
19279585STim.Szeto@Sun.COM 				break;
19289585STim.Szeto@Sun.COM 			default:
19299585STim.Szeto@Sun.COM 				diskError(sbdIoctl.stmf_error, &ret);
19309585STim.Szeto@Sun.COM 				if (ret == STMF_STATUS_ERROR) {
19319585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
19329585STim.Szeto@Sun.COM 					"modifyDiskLu:ioctl "
19339585STim.Szeto@Sun.COM 					"error(%d) (%d) (%d)", ioctlRet,
19349585STim.Szeto@Sun.COM 					    sbdIoctl.stmf_error, savedErrno);
19359585STim.Szeto@Sun.COM 				}
19369585STim.Szeto@Sun.COM 				break;
19379585STim.Szeto@Sun.COM 		}
19389585STim.Szeto@Sun.COM 	}
19399585STim.Szeto@Sun.COM 
19409585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
19419585STim.Szeto@Sun.COM 		goto done;
19429585STim.Szeto@Sun.COM 	}
19439585STim.Szeto@Sun.COM 
19449585STim.Szeto@Sun.COM done:
19459585STim.Szeto@Sun.COM 	free(sbdLu);
19469585STim.Szeto@Sun.COM 	(void) close(fd);
19479585STim.Szeto@Sun.COM 	return (ret);
19489585STim.Szeto@Sun.COM }
19499585STim.Szeto@Sun.COM 
19509585STim.Szeto@Sun.COM /*
19519585STim.Szeto@Sun.COM  * removeGuidFromDiskStore
19529585STim.Szeto@Sun.COM  *
19539585STim.Szeto@Sun.COM  * Purpose: delete a logical unit from the sbd provider data
19549585STim.Szeto@Sun.COM  */
19559585STim.Szeto@Sun.COM static int
19569585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid)
19579585STim.Szeto@Sun.COM {
19589585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, NULL, B_FALSE));
19599585STim.Szeto@Sun.COM }
19609585STim.Szeto@Sun.COM 
19619585STim.Szeto@Sun.COM 
19629585STim.Szeto@Sun.COM /*
19639585STim.Szeto@Sun.COM  * addGuidToDiskStore
19649585STim.Szeto@Sun.COM  *
19659585STim.Szeto@Sun.COM  * Purpose: add a logical unit to the sbd provider data
19669585STim.Szeto@Sun.COM  */
19679585STim.Szeto@Sun.COM static int
19689585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename)
19699585STim.Szeto@Sun.COM {
19709585STim.Szeto@Sun.COM 	return (persistDiskGuid(guid, filename, B_TRUE));
19719585STim.Szeto@Sun.COM }
19729585STim.Szeto@Sun.COM 
19739585STim.Szeto@Sun.COM 
19749585STim.Szeto@Sun.COM /*
19759585STim.Szeto@Sun.COM  * persistDiskGuid
19769585STim.Szeto@Sun.COM  *
19779585STim.Szeto@Sun.COM  * Purpose: Persist or unpersist a guid for the sbd provider data
19789585STim.Szeto@Sun.COM  *
19799585STim.Szeto@Sun.COM  */
19809585STim.Szeto@Sun.COM static int
19819585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
19829585STim.Szeto@Sun.COM {
19839585STim.Szeto@Sun.COM 	char	    guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
19849585STim.Szeto@Sun.COM 	nvlist_t    *nvl = NULL;
19859585STim.Szeto@Sun.COM 
19869585STim.Szeto@Sun.COM 	uint64_t    setToken;
19879585STim.Szeto@Sun.COM 	boolean_t   retryGetProviderData = B_FALSE;
19889585STim.Szeto@Sun.COM 	boolean_t   newData = B_FALSE;
19899585STim.Szeto@Sun.COM 	int	    ret = STMF_STATUS_SUCCESS;
19909585STim.Szeto@Sun.COM 	int	    retryCnt = 0;
19919585STim.Szeto@Sun.COM 	int	    stmfRet;
19929585STim.Szeto@Sun.COM 
19939585STim.Szeto@Sun.COM 	/* if we're persisting a guid, there must be a filename */
19949585STim.Szeto@Sun.COM 	if (persist && !filename) {
19959585STim.Szeto@Sun.COM 		return (1);
19969585STim.Szeto@Sun.COM 	}
19979585STim.Szeto@Sun.COM 
19989585STim.Szeto@Sun.COM 	/* guid is stored in lowercase ascii hex */
19999585STim.Szeto@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
20009585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
20019585STim.Szeto@Sun.COM 	    "%02x%02x%02x%02x%02x%02x",
20029585STim.Szeto@Sun.COM 	    guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
20039585STim.Szeto@Sun.COM 	    guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
20049585STim.Szeto@Sun.COM 	    guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
20059585STim.Szeto@Sun.COM 	    guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
20069585STim.Szeto@Sun.COM 
20079585STim.Szeto@Sun.COM 
20089585STim.Szeto@Sun.COM 	do {
20099585STim.Szeto@Sun.COM 		retryGetProviderData = B_FALSE;
20109585STim.Szeto@Sun.COM 		stmfRet = stmfGetProviderDataProt("sbd", &nvl,
20119585STim.Szeto@Sun.COM 		    STMF_LU_PROVIDER_TYPE, &setToken);
20129585STim.Szeto@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
20139585STim.Szeto@Sun.COM 			if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
20149585STim.Szeto@Sun.COM 				ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
20159585STim.Szeto@Sun.COM 				if (ret != 0) {
20169585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20179585STim.Szeto@Sun.COM 					    "unpersistGuid:nvlist_alloc(%d)",
20189585STim.Szeto@Sun.COM 					    ret);
20199585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
20209585STim.Szeto@Sun.COM 					goto done;
20219585STim.Szeto@Sun.COM 				}
20229585STim.Szeto@Sun.COM 				newData = B_TRUE;
20239585STim.Szeto@Sun.COM 			} else {
2024*10725SJohn.Forte@Sun.COM 				/*
2025*10725SJohn.Forte@Sun.COM 				 * if we're persisting the data, it's
2026*10725SJohn.Forte@Sun.COM 				 * an error. Otherwise, just return
2027*10725SJohn.Forte@Sun.COM 				 */
2028*10725SJohn.Forte@Sun.COM 				if (persist) {
2029*10725SJohn.Forte@Sun.COM 					ret = stmfRet;
2030*10725SJohn.Forte@Sun.COM 				}
20319585STim.Szeto@Sun.COM 				goto done;
20329585STim.Szeto@Sun.COM 			}
20339585STim.Szeto@Sun.COM 		}
20349585STim.Szeto@Sun.COM 		if (persist) {
20359585STim.Szeto@Sun.COM 			ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
20369585STim.Szeto@Sun.COM 		} else {
20379585STim.Szeto@Sun.COM 			ret = nvlist_remove(nvl, guidAsciiBuf,
20389585STim.Szeto@Sun.COM 			    DATA_TYPE_STRING);
20399585STim.Szeto@Sun.COM 			if (ret == ENOENT) {
20409585STim.Szeto@Sun.COM 				ret = 0;
20419585STim.Szeto@Sun.COM 			}
20429585STim.Szeto@Sun.COM 		}
20439585STim.Szeto@Sun.COM 		if (ret == 0) {
20449585STim.Szeto@Sun.COM 			if (newData) {
20459585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20469585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, NULL);
20479585STim.Szeto@Sun.COM 			} else {
20489585STim.Szeto@Sun.COM 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
20499585STim.Szeto@Sun.COM 				    STMF_LU_PROVIDER_TYPE, &setToken);
20509585STim.Szeto@Sun.COM 			}
20519585STim.Szeto@Sun.COM 			if (stmfRet != STMF_STATUS_SUCCESS) {
20529585STim.Szeto@Sun.COM 				if (stmfRet == STMF_ERROR_BUSY) {
20539585STim.Szeto@Sun.COM 					/* get/set failed, try again */
20549585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20559585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20569585STim.Szeto@Sun.COM 						ret = stmfRet;
20579585STim.Szeto@Sun.COM 						break;
20589585STim.Szeto@Sun.COM 					}
20599585STim.Szeto@Sun.COM 					continue;
20609585STim.Szeto@Sun.COM 				} else if (stmfRet ==
20619585STim.Szeto@Sun.COM 				    STMF_ERROR_PROV_DATA_STALE) {
20629585STim.Szeto@Sun.COM 					/* update failed, try again */
20639585STim.Szeto@Sun.COM 					nvlist_free(nvl);
20649585STim.Szeto@Sun.COM 					nvl = NULL;
20659585STim.Szeto@Sun.COM 					retryGetProviderData = B_TRUE;
20669585STim.Szeto@Sun.COM 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
20679585STim.Szeto@Sun.COM 						ret = stmfRet;
20689585STim.Szeto@Sun.COM 						break;
20699585STim.Szeto@Sun.COM 					}
20709585STim.Szeto@Sun.COM 					continue;
20719585STim.Szeto@Sun.COM 				} else {
20729585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
20739585STim.Szeto@Sun.COM 					    "unpersistGuid:error(%x)", stmfRet);
20749585STim.Szeto@Sun.COM 					ret = stmfRet;
20759585STim.Szeto@Sun.COM 				}
20769585STim.Szeto@Sun.COM 				break;
20779585STim.Szeto@Sun.COM 			}
20789585STim.Szeto@Sun.COM 		} else {
20799585STim.Szeto@Sun.COM 			syslog(LOG_DEBUG,
20809585STim.Szeto@Sun.COM 			    "unpersistGuid:error nvlist_add/remove(%d)",
20819585STim.Szeto@Sun.COM 			    ret);
20829585STim.Szeto@Sun.COM 			ret = STMF_STATUS_ERROR;
20839585STim.Szeto@Sun.COM 		}
20849585STim.Szeto@Sun.COM 	} while (retryGetProviderData);
20859585STim.Szeto@Sun.COM 
20869585STim.Szeto@Sun.COM done:
20879585STim.Szeto@Sun.COM 	nvlist_free(nvl);
20889585STim.Szeto@Sun.COM 	return (ret);
20899585STim.Szeto@Sun.COM }
20909585STim.Szeto@Sun.COM 
20919585STim.Szeto@Sun.COM 
20929585STim.Szeto@Sun.COM /*
20939585STim.Szeto@Sun.COM  * stmfGetLuProp
20949585STim.Szeto@Sun.COM  *
20959585STim.Szeto@Sun.COM  * Purpose: Get current value for a resource property
20969585STim.Szeto@Sun.COM  *
20979585STim.Szeto@Sun.COM  * hdl - luResource from a previous call to stmfCreateLuResource
20989585STim.Szeto@Sun.COM  *
20999585STim.Szeto@Sun.COM  * resourceProp - a valid resource property type
21009585STim.Szeto@Sun.COM  *
21019585STim.Szeto@Sun.COM  * propVal - void pointer to a pointer of the value to be retrieved
21029585STim.Szeto@Sun.COM  */
21039585STim.Szeto@Sun.COM int
21049585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
21059585STim.Szeto@Sun.COM {
21069585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21079585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
21089585STim.Szeto@Sun.COM 	if (hdl == NULL || propLen == NULL || propVal == NULL) {
21099585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21109585STim.Szeto@Sun.COM 	}
21119585STim.Szeto@Sun.COM 
21129585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
21139585STim.Szeto@Sun.COM 		ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
21149585STim.Szeto@Sun.COM 	} else {
21159585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21169585STim.Szeto@Sun.COM 	}
21179585STim.Szeto@Sun.COM 
21189585STim.Szeto@Sun.COM 	return (ret);
21199585STim.Szeto@Sun.COM }
21209585STim.Szeto@Sun.COM 
21219585STim.Szeto@Sun.COM /*
21229585STim.Szeto@Sun.COM  * stmfGetLuResource
21239585STim.Szeto@Sun.COM  *
21249585STim.Szeto@Sun.COM  * Purpose: Get a logical unit resource handle for a given logical unit.
21259585STim.Szeto@Sun.COM  *
21269585STim.Szeto@Sun.COM  * hdl - pointer to luResource
21279585STim.Szeto@Sun.COM  */
21289585STim.Szeto@Sun.COM int
21299585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
21309585STim.Szeto@Sun.COM {
21319585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21329585STim.Szeto@Sun.COM 	stmfLogicalUnitProperties luProps;
21339585STim.Szeto@Sun.COM 
21349585STim.Szeto@Sun.COM 
21359585STim.Szeto@Sun.COM 	/* Check logical unit provider name to call correct dtype function */
21369585STim.Szeto@Sun.COM 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
21379585STim.Szeto@Sun.COM 	    != STMF_STATUS_SUCCESS) {
21389585STim.Szeto@Sun.COM 		return (ret);
21399585STim.Szeto@Sun.COM 	} else {
21409585STim.Szeto@Sun.COM 		if (strcmp(luProps.providerName, "sbd") == 0) {
21419585STim.Szeto@Sun.COM 			ret = getDiskAllProps(luGuid, hdl);
21429585STim.Szeto@Sun.COM 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
21439585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOT_FOUND);
21449585STim.Szeto@Sun.COM 		} else {
21459585STim.Szeto@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
21469585STim.Szeto@Sun.COM 		}
21479585STim.Szeto@Sun.COM 	}
21489585STim.Szeto@Sun.COM 
21499585STim.Szeto@Sun.COM 	return (ret);
21509585STim.Szeto@Sun.COM }
21519585STim.Szeto@Sun.COM 
21529585STim.Szeto@Sun.COM /*
21539585STim.Szeto@Sun.COM  * getDiskAllProps
21549585STim.Szeto@Sun.COM  *
21559585STim.Szeto@Sun.COM  * Purpose: load all disk properties from sbd driver
21569585STim.Szeto@Sun.COM  *
21579585STim.Szeto@Sun.COM  * luGuid - guid of disk device for which properties are to be retrieved
21589585STim.Szeto@Sun.COM  * hdl - allocated luResource into which properties are to be copied
21599585STim.Szeto@Sun.COM  *
21609585STim.Szeto@Sun.COM  */
21619585STim.Szeto@Sun.COM static int
21629585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
21639585STim.Szeto@Sun.COM {
21649585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
21659585STim.Szeto@Sun.COM 	int fd;
21669585STim.Szeto@Sun.COM 	sbd_lu_props_t *sbdProps;
21679585STim.Szeto@Sun.COM 	int ioctlRet;
21689585STim.Szeto@Sun.COM 	int savedErrno;
21699585STim.Szeto@Sun.COM 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
21709585STim.Szeto@Sun.COM 	stmf_iocdata_t sbdIoctl = {0};
21719585STim.Szeto@Sun.COM 
21729585STim.Szeto@Sun.COM 	/*
21739585STim.Szeto@Sun.COM 	 * Open control node for sbd
21749585STim.Szeto@Sun.COM 	 */
21759585STim.Szeto@Sun.COM 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
21769585STim.Szeto@Sun.COM 		return (ret);
21779585STim.Szeto@Sun.COM 
21789585STim.Szeto@Sun.COM 
21799585STim.Szeto@Sun.COM 	*hdl = calloc(1, sizeof (luResourceImpl));
21809585STim.Szeto@Sun.COM 	if (*hdl == NULL) {
21819585STim.Szeto@Sun.COM 		(void) close(fd);
21829585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
21839585STim.Szeto@Sun.COM 	}
21849585STim.Szeto@Sun.COM 
21859585STim.Szeto@Sun.COM 	sbdProps = calloc(1, sbdPropsSize);
21869585STim.Szeto@Sun.COM 	if (sbdProps == NULL) {
21879585STim.Szeto@Sun.COM 		free(*hdl);
21889585STim.Szeto@Sun.COM 		(void) close(fd);
21899585STim.Szeto@Sun.COM 		return (STMF_ERROR_NOMEM);
21909585STim.Szeto@Sun.COM 	}
21919585STim.Szeto@Sun.COM 
21929585STim.Szeto@Sun.COM 	ret = createDiskResource((luResourceImpl *)*hdl);
21939585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
21949585STim.Szeto@Sun.COM 		free(*hdl);
2195*10725SJohn.Forte@Sun.COM 		free(sbdProps);
21969585STim.Szeto@Sun.COM 		(void) close(fd);
21979585STim.Szeto@Sun.COM 		return (ret);
21989585STim.Szeto@Sun.COM 	}
21999585STim.Szeto@Sun.COM 
22009585STim.Szeto@Sun.COM 	sbdProps->slp_input_guid = 1;
22019585STim.Szeto@Sun.COM 	bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
22029585STim.Szeto@Sun.COM 
22039585STim.Szeto@Sun.COM 	sbdIoctl.stmf_version = STMF_VERSION_1;
22049585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf_size = sbdPropsSize;
22059585STim.Szeto@Sun.COM 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
22069585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf_size = sbdPropsSize;
22079585STim.Szeto@Sun.COM 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
22089585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
22099585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
22109585STim.Szeto@Sun.COM 		savedErrno = errno;
22119585STim.Szeto@Sun.COM 		switch (savedErrno) {
22129585STim.Szeto@Sun.COM 			case EBUSY:
22139585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
22149585STim.Szeto@Sun.COM 				break;
22159585STim.Szeto@Sun.COM 			case EPERM:
22169585STim.Szeto@Sun.COM 			case EACCES:
22179585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
22189585STim.Szeto@Sun.COM 				break;
22199585STim.Szeto@Sun.COM 			case ENOENT:
22209585STim.Szeto@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
22219585STim.Szeto@Sun.COM 				break;
22229585STim.Szeto@Sun.COM 			default:
22239585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
22249585STim.Szeto@Sun.COM 				    "getDiskAllProps:ioctl error(%d) (%d) (%d)",
22259585STim.Szeto@Sun.COM 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
22269585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
22279585STim.Szeto@Sun.COM 				break;
22289585STim.Szeto@Sun.COM 		}
22299585STim.Szeto@Sun.COM 	}
22309585STim.Szeto@Sun.COM 
22319585STim.Szeto@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
22329585STim.Szeto@Sun.COM 		ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
22339585STim.Szeto@Sun.COM 	}
22349585STim.Szeto@Sun.COM 
2235*10725SJohn.Forte@Sun.COM 	free(sbdProps);
22369585STim.Szeto@Sun.COM 	(void) close(fd);
22379585STim.Szeto@Sun.COM 	return (ret);
22389585STim.Szeto@Sun.COM }
22399585STim.Szeto@Sun.COM 
22409585STim.Szeto@Sun.COM /*
22419585STim.Szeto@Sun.COM  * loadDiskPropsFromDriver
22429585STim.Szeto@Sun.COM  *
22439585STim.Szeto@Sun.COM  * Purpose: Retrieve all disk type properties from sbd driver
22449585STim.Szeto@Sun.COM  *
22459585STim.Szeto@Sun.COM  * hdl - Allocated luResourceImpl
22469585STim.Szeto@Sun.COM  * sbdProps - sbd_lu_props_t structure returned from sbd driver
22479585STim.Szeto@Sun.COM  *
22489585STim.Szeto@Sun.COM  */
22499585STim.Szeto@Sun.COM static int
22509585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
22519585STim.Szeto@Sun.COM {
22529585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
22539585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
22549585STim.Szeto@Sun.COM 	/* copy guid */
22559585STim.Szeto@Sun.COM 	diskLu->luGuidValid = B_TRUE;
22569585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
22579585STim.Szeto@Sun.COM 
22589585STim.Szeto@Sun.COM 	if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
22599585STim.Szeto@Sun.COM 		diskLu->luMetaFileNameValid = B_TRUE;
22609585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luMetaFileName,
22619585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
22629585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) >=
22639585STim.Szeto@Sun.COM 		    sizeof (diskLu->luMetaFileName)) {
22649585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22659585STim.Szeto@Sun.COM 		}
22669585STim.Szeto@Sun.COM 	}
22679585STim.Szeto@Sun.COM 
22689585STim.Szeto@Sun.COM 	if (sbdProps->slp_data_fname_valid) {
22699585STim.Szeto@Sun.COM 		diskLu->luDataFileNameValid = B_TRUE;
22709585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luDataFileName,
22719585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
22729585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) >=
22739585STim.Szeto@Sun.COM 		    sizeof (diskLu->luDataFileName)) {
22749585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
22759585STim.Szeto@Sun.COM 		}
22769585STim.Szeto@Sun.COM 	}
22779585STim.Szeto@Sun.COM 
22789585STim.Szeto@Sun.COM 	if (sbdProps->slp_serial_valid) {
22799585STim.Szeto@Sun.COM 		diskLu->serialNumValid = B_TRUE;
22809585STim.Szeto@Sun.COM 		bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
22819585STim.Szeto@Sun.COM 		    diskLu->serialNum, sbdProps->slp_serial_size);
22829585STim.Szeto@Sun.COM 	}
22839585STim.Szeto@Sun.COM 
228410113SNattuvetty.Bhavyan@Sun.COM 	if (sbdProps->slp_mgmt_url_valid) {
228510113SNattuvetty.Bhavyan@Sun.COM 		diskLu->luMgmtUrlValid = B_TRUE;
228610113SNattuvetty.Bhavyan@Sun.COM 		if (strlcpy(diskLu->luMgmtUrl,
228710113SNattuvetty.Bhavyan@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
228810113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) >=
228910113SNattuvetty.Bhavyan@Sun.COM 		    sizeof (diskLu->luMgmtUrl)) {
229010113SNattuvetty.Bhavyan@Sun.COM 			return (STMF_STATUS_ERROR);
229110113SNattuvetty.Bhavyan@Sun.COM 		}
229210113SNattuvetty.Bhavyan@Sun.COM 	}
229310113SNattuvetty.Bhavyan@Sun.COM 
22949585STim.Szeto@Sun.COM 	if (sbdProps->slp_alias_valid) {
22959585STim.Szeto@Sun.COM 		diskLu->luAliasValid = B_TRUE;
22969585STim.Szeto@Sun.COM 		if (strlcpy(diskLu->luAlias,
22979585STim.Szeto@Sun.COM 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]),
22989585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) >=
22999585STim.Szeto@Sun.COM 		    sizeof (diskLu->luAlias)) {
23009585STim.Szeto@Sun.COM 			return (STMF_STATUS_ERROR);
23019585STim.Szeto@Sun.COM 		}
23029585STim.Szeto@Sun.COM 	} else { /* set alias to data filename if not set */
23039585STim.Szeto@Sun.COM 		if (sbdProps->slp_data_fname_valid) {
23049585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
23059585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias,
23069585STim.Szeto@Sun.COM 			    (char *)&(sbdProps->slp_buf[
23079585STim.Szeto@Sun.COM 			    sbdProps->slp_data_fname_off]),
23089585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
23099585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
23109585STim.Szeto@Sun.COM 				return (STMF_STATUS_ERROR);
23119585STim.Szeto@Sun.COM 			}
23129585STim.Szeto@Sun.COM 		}
23139585STim.Szeto@Sun.COM 	}
23149585STim.Szeto@Sun.COM 
23159585STim.Szeto@Sun.COM 	diskLu->vidValid = B_TRUE;
23169585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
23179585STim.Szeto@Sun.COM 
23189585STim.Szeto@Sun.COM 	diskLu->pidValid = B_TRUE;
23199585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
23209585STim.Szeto@Sun.COM 
23219585STim.Szeto@Sun.COM 	diskLu->revValid = B_TRUE;
23229585STim.Szeto@Sun.COM 	bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
23239585STim.Szeto@Sun.COM 
23249585STim.Szeto@Sun.COM 	diskLu->writeProtectEnableValid = B_TRUE;
23259585STim.Szeto@Sun.COM 	if (sbdProps->slp_write_protected) {
23269585STim.Szeto@Sun.COM 		diskLu->writeProtectEnable = B_TRUE;
23279585STim.Szeto@Sun.COM 	}
23289585STim.Szeto@Sun.COM 
23299585STim.Szeto@Sun.COM 	diskLu->writebackCacheDisableValid = B_TRUE;
23309585STim.Szeto@Sun.COM 	if (sbdProps->slp_writeback_cache_disable_cur) {
23319585STim.Szeto@Sun.COM 		diskLu->writebackCacheDisable = B_TRUE;
23329585STim.Szeto@Sun.COM 	}
23339585STim.Szeto@Sun.COM 
23349585STim.Szeto@Sun.COM 	diskLu->blkSizeValid = B_TRUE;
23359585STim.Szeto@Sun.COM 	diskLu->blkSize = sbdProps->slp_blksize;
23369585STim.Szeto@Sun.COM 
23379585STim.Szeto@Sun.COM 	diskLu->luSizeValid = B_TRUE;
23389585STim.Szeto@Sun.COM 	diskLu->luSize = sbdProps->slp_lu_size;
23399585STim.Szeto@Sun.COM 
2340*10725SJohn.Forte@Sun.COM 	diskLu->accessState = sbdProps->slp_access_state;
2341*10725SJohn.Forte@Sun.COM 
23429585STim.Szeto@Sun.COM 	return (ret);
23439585STim.Szeto@Sun.COM }
23449585STim.Szeto@Sun.COM 
23459585STim.Szeto@Sun.COM 
23469585STim.Szeto@Sun.COM /*
23479585STim.Szeto@Sun.COM  * stmfSetLuProp
23489585STim.Szeto@Sun.COM  *
23499585STim.Szeto@Sun.COM  * Purpose: set a property on an luResource
23509585STim.Szeto@Sun.COM  *
23519585STim.Szeto@Sun.COM  * hdl - allocated luResource
23529585STim.Szeto@Sun.COM  * prop - property identifier
23539585STim.Szeto@Sun.COM  * propVal - property value to be set
23549585STim.Szeto@Sun.COM  */
23559585STim.Szeto@Sun.COM int
23569585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
23579585STim.Szeto@Sun.COM {
23589585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
23599585STim.Szeto@Sun.COM 	luResourceImpl *luPropsHdl = hdl;
23609585STim.Szeto@Sun.COM 	if (hdl == NULL) {
23619585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
23629585STim.Szeto@Sun.COM 	}
23639585STim.Szeto@Sun.COM 
23649585STim.Szeto@Sun.COM 	if (luPropsHdl->type == STMF_DISK) {
23659585STim.Szeto@Sun.COM 		ret = setDiskProp(luPropsHdl, prop, propVal);
23669585STim.Szeto@Sun.COM 	} else {
23679585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
23689585STim.Szeto@Sun.COM 	}
23699585STim.Szeto@Sun.COM 
23709585STim.Szeto@Sun.COM 	return (ret);
23719585STim.Szeto@Sun.COM }
23729585STim.Szeto@Sun.COM 
23739585STim.Szeto@Sun.COM /*
23749585STim.Szeto@Sun.COM  * getDiskProp
23759585STim.Szeto@Sun.COM  *
23769585STim.Szeto@Sun.COM  * Purpose: retrieve a given property from a logical unit resource of type disk
23779585STim.Szeto@Sun.COM  *
23789585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
23799585STim.Szeto@Sun.COM  * prop - property identifier
23809585STim.Szeto@Sun.COM  * propVal - pointer to character to contain the retrieved property value
23819585STim.Szeto@Sun.COM  * propLen - On input this is the length of propVal. On failure, it contains the
23829585STim.Szeto@Sun.COM  *           number of bytes required for propVal
23839585STim.Szeto@Sun.COM  */
23849585STim.Szeto@Sun.COM static int
23859585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
23869585STim.Szeto@Sun.COM {
23879585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
23889585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
2389*10725SJohn.Forte@Sun.COM 	char accessState[20];
23909585STim.Szeto@Sun.COM 	size_t reqLen;
23919585STim.Szeto@Sun.COM 
2392*10725SJohn.Forte@Sun.COM 	if (prop == STMF_LU_PROP_ACCESS_STATE) {
2393*10725SJohn.Forte@Sun.COM 		if (diskLu->accessState == SBD_LU_ACTIVE) {
2394*10725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_ACTIVE,
2395*10725SJohn.Forte@Sun.COM 			    sizeof (accessState));
2396*10725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) {
2397*10725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
2398*10725SJohn.Forte@Sun.COM 			    STMF_ACCESS_STANDBY_TO_ACTIVE,
2399*10725SJohn.Forte@Sun.COM 			    sizeof (accessState));
2400*10725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState == SBD_LU_STANDBY) {
2401*10725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState, STMF_ACCESS_STANDBY,
2402*10725SJohn.Forte@Sun.COM 			    sizeof (accessState));
2403*10725SJohn.Forte@Sun.COM 		} else if (diskLu->accessState ==
2404*10725SJohn.Forte@Sun.COM 		    SBD_LU_TRANSITION_TO_STANDBY) {
2405*10725SJohn.Forte@Sun.COM 			(void) strlcpy(accessState,
2406*10725SJohn.Forte@Sun.COM 			    STMF_ACCESS_ACTIVE_TO_STANDBY,
2407*10725SJohn.Forte@Sun.COM 			    sizeof (accessState));
2408*10725SJohn.Forte@Sun.COM 		}
2409*10725SJohn.Forte@Sun.COM 		if ((reqLen = strlcpy(propVal, accessState,
2410*10725SJohn.Forte@Sun.COM 		    *propLen)) >= *propLen) {
2411*10725SJohn.Forte@Sun.COM 			*propLen = reqLen + 1;
2412*10725SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
2413*10725SJohn.Forte@Sun.COM 		}
2414*10725SJohn.Forte@Sun.COM 		return (0);
2415*10725SJohn.Forte@Sun.COM 	}
2416*10725SJohn.Forte@Sun.COM 
2417*10725SJohn.Forte@Sun.COM 	if (diskLu->accessState != SBD_LU_ACTIVE) {
2418*10725SJohn.Forte@Sun.COM 		return (STMF_ERROR_NO_PROP_STANDBY);
2419*10725SJohn.Forte@Sun.COM 	}
2420*10725SJohn.Forte@Sun.COM 
24219585STim.Szeto@Sun.COM 	switch (prop) {
24229585STim.Szeto@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE:
24239585STim.Szeto@Sun.COM 			if (diskLu->blkSizeValid == B_FALSE) {
24249585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24259585STim.Szeto@Sun.COM 			}
24269585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen, "%llu",
24279585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->blkSize);
24289585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
24299585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24309585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24319585STim.Szeto@Sun.COM 			}
24329585STim.Szeto@Sun.COM 			break;
24339585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
24349585STim.Szeto@Sun.COM 			if (diskLu->luDataFileNameValid == B_FALSE) {
24359585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24369585STim.Szeto@Sun.COM 			}
24379585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
24389585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
24399585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24409585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24419585STim.Szeto@Sun.COM 			}
24429585STim.Szeto@Sun.COM 			break;
24439585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
24449585STim.Szeto@Sun.COM 			if (diskLu->luMetaFileNameValid == B_FALSE) {
24459585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24469585STim.Szeto@Sun.COM 			}
24479585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
24489585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
24499585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24509585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24519585STim.Szeto@Sun.COM 			}
24529585STim.Szeto@Sun.COM 			break;
245310113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
245410113SNattuvetty.Bhavyan@Sun.COM 			if (diskLu->luMgmtUrlValid == B_FALSE) {
245510113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_NO_PROP);
245610113SNattuvetty.Bhavyan@Sun.COM 			}
245710113SNattuvetty.Bhavyan@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
245810113SNattuvetty.Bhavyan@Sun.COM 			    *propLen)) >= *propLen) {
245910113SNattuvetty.Bhavyan@Sun.COM 				*propLen = reqLen + 1;
246010113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
246110113SNattuvetty.Bhavyan@Sun.COM 			}
246210113SNattuvetty.Bhavyan@Sun.COM 			break;
24639585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
24649585STim.Szeto@Sun.COM 			if (diskLu->luGuidValid == B_FALSE) {
24659585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24669585STim.Szeto@Sun.COM 			}
24679585STim.Szeto@Sun.COM 			reqLen = snprintf(propVal, *propLen,
24689585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
24699585STim.Szeto@Sun.COM 			    "%02X%02X%02X%02X",
24709585STim.Szeto@Sun.COM 			    diskLu->luGuid[0], diskLu->luGuid[1],
24719585STim.Szeto@Sun.COM 			    diskLu->luGuid[2], diskLu->luGuid[3],
24729585STim.Szeto@Sun.COM 			    diskLu->luGuid[4], diskLu->luGuid[5],
24739585STim.Szeto@Sun.COM 			    diskLu->luGuid[6], diskLu->luGuid[7],
24749585STim.Szeto@Sun.COM 			    diskLu->luGuid[8], diskLu->luGuid[9],
24759585STim.Szeto@Sun.COM 			    diskLu->luGuid[10], diskLu->luGuid[11],
24769585STim.Szeto@Sun.COM 			    diskLu->luGuid[12], diskLu->luGuid[13],
24779585STim.Szeto@Sun.COM 			    diskLu->luGuid[14], diskLu->luGuid[15]);
24789585STim.Szeto@Sun.COM 			if (reqLen >= *propLen) {
24799585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24809585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24819585STim.Szeto@Sun.COM 			}
24829585STim.Szeto@Sun.COM 			break;
24839585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
24849585STim.Szeto@Sun.COM 			if (diskLu->serialNumValid == B_FALSE) {
24859585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24869585STim.Szeto@Sun.COM 			}
24879585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->serialNum,
24889585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
24899585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
24909585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
24919585STim.Szeto@Sun.COM 			}
24929585STim.Szeto@Sun.COM 			break;
24939585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
24949585STim.Szeto@Sun.COM 			if (diskLu->luSizeValid == B_FALSE) {
24959585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
24969585STim.Szeto@Sun.COM 			}
24979585STim.Szeto@Sun.COM 			(void) snprintf(propVal, *propLen, "%llu",
24989585STim.Szeto@Sun.COM 			    (u_longlong_t)diskLu->luSize);
24999585STim.Szeto@Sun.COM 			break;
25009585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
25019585STim.Szeto@Sun.COM 			if (diskLu->luAliasValid == B_FALSE) {
25029585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25039585STim.Szeto@Sun.COM 			}
25049585STim.Szeto@Sun.COM 			if ((reqLen = strlcpy(propVal, diskLu->luAlias,
25059585STim.Szeto@Sun.COM 			    *propLen)) >= *propLen) {
25069585STim.Szeto@Sun.COM 				*propLen = reqLen + 1;
25079585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
25089585STim.Szeto@Sun.COM 			}
25099585STim.Szeto@Sun.COM 			break;
25109585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
25119585STim.Szeto@Sun.COM 			if (diskLu->vidValid == B_FALSE) {
25129585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25139585STim.Szeto@Sun.COM 			}
25149585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->vid)) {
25159585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
25169585STim.Szeto@Sun.COM 			}
25179585STim.Szeto@Sun.COM 			bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
25189585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->vid)] = 0;
25199585STim.Szeto@Sun.COM 			break;
25209585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
25219585STim.Szeto@Sun.COM 			if (diskLu->pidValid == B_FALSE) {
25229585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25239585STim.Szeto@Sun.COM 			}
25249585STim.Szeto@Sun.COM 			if (*propLen <= sizeof (diskLu->pid)) {
25259585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
25269585STim.Szeto@Sun.COM 			}
25279585STim.Szeto@Sun.COM 			bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
25289585STim.Szeto@Sun.COM 			propVal[sizeof (diskLu->pid)] = 0;
25299585STim.Szeto@Sun.COM 			break;
25309585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
25319585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnableValid == B_FALSE) {
25329585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25339585STim.Szeto@Sun.COM 			}
25349585STim.Szeto@Sun.COM 			if (diskLu->writeProtectEnable) {
25359585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
25369585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25379585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25389585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25399585STim.Szeto@Sun.COM 				}
25409585STim.Szeto@Sun.COM 			} else {
25419585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
25429585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25439585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25449585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25459585STim.Szeto@Sun.COM 				}
25469585STim.Szeto@Sun.COM 			}
25479585STim.Szeto@Sun.COM 			break;
25489585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
25499585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisableValid == B_FALSE) {
25509585STim.Szeto@Sun.COM 				return (STMF_ERROR_NO_PROP);
25519585STim.Szeto@Sun.COM 			}
25529585STim.Szeto@Sun.COM 			if (diskLu->writebackCacheDisable) {
25539585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "true",
25549585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25559585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25569585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25579585STim.Szeto@Sun.COM 				}
25589585STim.Szeto@Sun.COM 			} else {
25599585STim.Szeto@Sun.COM 				if ((reqLen = strlcpy(propVal, "false",
25609585STim.Szeto@Sun.COM 				    *propLen)) >= *propLen) {
25619585STim.Szeto@Sun.COM 					*propLen = reqLen + 1;
25629585STim.Szeto@Sun.COM 					return (STMF_ERROR_INVALID_ARG);
25639585STim.Szeto@Sun.COM 				}
25649585STim.Szeto@Sun.COM 			}
25659585STim.Szeto@Sun.COM 			break;
25669585STim.Szeto@Sun.COM 		default:
25679585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NO_PROP;
25689585STim.Szeto@Sun.COM 			break;
25699585STim.Szeto@Sun.COM 	}
25709585STim.Szeto@Sun.COM 
25719585STim.Szeto@Sun.COM 	return (ret);
25729585STim.Szeto@Sun.COM }
25739585STim.Szeto@Sun.COM 
25749585STim.Szeto@Sun.COM /*
25759585STim.Szeto@Sun.COM  * setDiskProp
25769585STim.Szeto@Sun.COM  *
25779585STim.Szeto@Sun.COM  * Purpose: set properties for resource of type disk
25789585STim.Szeto@Sun.COM  *
25799585STim.Szeto@Sun.COM  * hdl - allocated luResourceImpl
25809585STim.Szeto@Sun.COM  * resourceProp - valid resource identifier
25819585STim.Szeto@Sun.COM  * propVal - valid resource value
25829585STim.Szeto@Sun.COM  */
25839585STim.Szeto@Sun.COM static int
25849585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
25859585STim.Szeto@Sun.COM {
25869585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
25879585STim.Szeto@Sun.COM 	int i;
25889585STim.Szeto@Sun.COM 	diskResource *diskLu = hdl->resource;
25899585STim.Szeto@Sun.COM 	unsigned long long numericProp = 0;
25909585STim.Szeto@Sun.COM 	char guidProp[LU_ASCII_GUID_SIZE + 1];
25919585STim.Szeto@Sun.COM 	char ouiProp[OUI_ASCII_SIZE + 1];
25929585STim.Szeto@Sun.COM 	unsigned int oui[OUI_SIZE];
25939585STim.Szeto@Sun.COM 	unsigned int guid[LU_GUID_SIZE];
25949585STim.Szeto@Sun.COM 	int propSize;
25959585STim.Szeto@Sun.COM 
25969585STim.Szeto@Sun.COM 
25979585STim.Szeto@Sun.COM 	if (propVal == NULL) {
25989585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
25999585STim.Szeto@Sun.COM 	}
26009585STim.Szeto@Sun.COM 
26019585STim.Szeto@Sun.COM 	switch (resourceProp) {
26029585STim.Szeto@Sun.COM 		case STMF_LU_PROP_ALIAS:
26039585STim.Szeto@Sun.COM 			if (strlcpy(diskLu->luAlias, propVal,
26049585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) >=
26059585STim.Szeto@Sun.COM 			    sizeof (diskLu->luAlias)) {
26069585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26079585STim.Szeto@Sun.COM 			}
26089585STim.Szeto@Sun.COM 			diskLu->luAliasValid = B_TRUE;
26099585STim.Szeto@Sun.COM 			break;
26109585STim.Szeto@Sun.COM 		case STMF_LU_PROP_BLOCK_SIZE:
26119585STim.Szeto@Sun.COM 			(void) sscanf(propVal, "%llu", &numericProp);
26129585STim.Szeto@Sun.COM 			if (numericProp > UINT16_MAX) {
26139585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26149585STim.Szeto@Sun.COM 			}
26159585STim.Szeto@Sun.COM 			diskLu->blkSize = numericProp;
26169585STim.Szeto@Sun.COM 			diskLu->blkSizeValid = B_TRUE;
26179585STim.Szeto@Sun.COM 			break;
26189585STim.Szeto@Sun.COM 		case STMF_LU_PROP_COMPANY_ID:
26199585STim.Szeto@Sun.COM 			if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
26209585STim.Szeto@Sun.COM 			    sizeof (ouiProp)) {
26219585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26229585STim.Szeto@Sun.COM 			}
26239585STim.Szeto@Sun.COM 			if (checkHexUpper(ouiProp) != 0) {
26249585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26259585STim.Szeto@Sun.COM 			}
26269585STim.Szeto@Sun.COM 			(void) sscanf(ouiProp, "%2X%2X%2X",
26279585STim.Szeto@Sun.COM 			    &oui[0], &oui[1], &oui[2]);
26289585STim.Szeto@Sun.COM 
26299585STim.Szeto@Sun.COM 			diskLu->companyId = 0;
26309585STim.Szeto@Sun.COM 			diskLu->companyId += oui[0] << 16;
26319585STim.Szeto@Sun.COM 			diskLu->companyId += oui[1] << 8;
26329585STim.Szeto@Sun.COM 			diskLu->companyId += oui[2];
26339585STim.Szeto@Sun.COM 			diskLu->companyIdValid = B_TRUE;
26349585STim.Szeto@Sun.COM 			break;
26359585STim.Szeto@Sun.COM 		case STMF_LU_PROP_GUID:
26369585STim.Szeto@Sun.COM 			if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
26379585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26389585STim.Szeto@Sun.COM 			}
26399585STim.Szeto@Sun.COM 
26409585STim.Szeto@Sun.COM 			if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
26419585STim.Szeto@Sun.COM 			    sizeof (guidProp)) {
26429585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26439585STim.Szeto@Sun.COM 			}
26449585STim.Szeto@Sun.COM 
26459585STim.Szeto@Sun.COM 			if (checkHexUpper(guidProp) != 0) {
26469585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
26479585STim.Szeto@Sun.COM 			}
26489585STim.Szeto@Sun.COM 
26499585STim.Szeto@Sun.COM 			(void) sscanf(guidProp,
26509585STim.Szeto@Sun.COM 			    "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
26519585STim.Szeto@Sun.COM 			    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
26529585STim.Szeto@Sun.COM 			    &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
26539585STim.Szeto@Sun.COM 			    &guid[10], &guid[11], &guid[12], &guid[13],
26549585STim.Szeto@Sun.COM 			    &guid[14], &guid[15]);
26559585STim.Szeto@Sun.COM 			for (i = 0; i < sizeof (diskLu->luGuid); i++) {
26569585STim.Szeto@Sun.COM 				diskLu->luGuid[i] = guid[i];
26579585STim.Szeto@Sun.COM 			}
26589585STim.Szeto@Sun.COM 			diskLu->luGuidValid = B_TRUE;
26599585STim.Szeto@Sun.COM 			break;
26609585STim.Szeto@Sun.COM 		case STMF_LU_PROP_FILENAME:
26619585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luDataFileName, propVal,
26629585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName))) >=
26639585STim.Szeto@Sun.COM 			    sizeof (diskLu->luDataFileName)) {
26649585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26659585STim.Szeto@Sun.COM 			}
26669585STim.Szeto@Sun.COM 			diskLu->luDataFileNameValid = B_TRUE;
26679585STim.Szeto@Sun.COM 			break;
26689585STim.Szeto@Sun.COM 		case STMF_LU_PROP_META_FILENAME:
26699585STim.Szeto@Sun.COM 			if ((strlcpy(diskLu->luMetaFileName, propVal,
26709585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName))) >=
26719585STim.Szeto@Sun.COM 			    sizeof (diskLu->luMetaFileName)) {
26729585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26739585STim.Szeto@Sun.COM 			}
26749585STim.Szeto@Sun.COM 			diskLu->luMetaFileNameValid = B_TRUE;
26759585STim.Szeto@Sun.COM 			break;
267610113SNattuvetty.Bhavyan@Sun.COM 		case STMF_LU_PROP_MGMT_URL:
267710113SNattuvetty.Bhavyan@Sun.COM 			if ((strlcpy(diskLu->luMgmtUrl, propVal,
267810113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl))) >=
267910113SNattuvetty.Bhavyan@Sun.COM 			    sizeof (diskLu->luMgmtUrl)) {
268010113SNattuvetty.Bhavyan@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
268110113SNattuvetty.Bhavyan@Sun.COM 			}
268210113SNattuvetty.Bhavyan@Sun.COM 			diskLu->luMgmtUrlValid = B_TRUE;
268310113SNattuvetty.Bhavyan@Sun.COM 			break;
26849585STim.Szeto@Sun.COM 		case STMF_LU_PROP_PID:
26859585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
26869585STim.Szeto@Sun.COM 			    sizeof (diskLu->pid)) {
26879585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26889585STim.Szeto@Sun.COM 			}
26899585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->pid, propVal, propSize);
26909585STim.Szeto@Sun.COM 			diskLu->pidValid = B_TRUE;
26919585STim.Szeto@Sun.COM 			break;
26929585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SERIAL_NUM:
26939585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
26949585STim.Szeto@Sun.COM 			    (sizeof (diskLu->serialNum) - 1)) {
26959585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
26969585STim.Szeto@Sun.COM 			}
26979585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->serialNum, propVal, propSize);
26989585STim.Szeto@Sun.COM 			diskLu->serialNumValid = B_TRUE;
26999585STim.Szeto@Sun.COM 			break;
27009585STim.Szeto@Sun.COM 		case STMF_LU_PROP_SIZE:
27019585STim.Szeto@Sun.COM 			if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
27029585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27039585STim.Szeto@Sun.COM 			}
27049585STim.Szeto@Sun.COM 			diskLu->luSizeValid = B_TRUE;
27059585STim.Szeto@Sun.COM 			break;
27069585STim.Szeto@Sun.COM 		case STMF_LU_PROP_VID:
27079585STim.Szeto@Sun.COM 			if ((propSize = strlen(propVal)) >
27089585STim.Szeto@Sun.COM 			    sizeof (diskLu->vid)) {
27099585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_PROPSIZE);
27109585STim.Szeto@Sun.COM 			}
27119585STim.Szeto@Sun.COM 			(void) strncpy(diskLu->vid, propVal, propSize);
27129585STim.Szeto@Sun.COM 			diskLu->vidValid = B_TRUE;
27139585STim.Szeto@Sun.COM 			break;
27149585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_PROTECT:
27159585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
27169585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_TRUE;
27179585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
27189585STim.Szeto@Sun.COM 				diskLu->writeProtectEnable = B_FALSE;
27199585STim.Szeto@Sun.COM 			} else {
27209585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27219585STim.Szeto@Sun.COM 			}
27229585STim.Szeto@Sun.COM 			diskLu->writeProtectEnableValid = B_TRUE;
27239585STim.Szeto@Sun.COM 			break;
27249585STim.Szeto@Sun.COM 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
27259585STim.Szeto@Sun.COM 			if (strcasecmp(propVal, "TRUE") == 0) {
27269585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_TRUE;
27279585STim.Szeto@Sun.COM 			} else if (strcasecmp(propVal, "FALSE") == 0) {
27289585STim.Szeto@Sun.COM 				diskLu->writebackCacheDisable = B_FALSE;
27299585STim.Szeto@Sun.COM 			} else {
27309585STim.Szeto@Sun.COM 				return (STMF_ERROR_INVALID_ARG);
27319585STim.Szeto@Sun.COM 			}
27329585STim.Szeto@Sun.COM 			diskLu->writebackCacheDisableValid = B_TRUE;
27339585STim.Szeto@Sun.COM 			break;
2734*10725SJohn.Forte@Sun.COM 		case STMF_LU_PROP_ACCESS_STATE:
2735*10725SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_PROP;
2736*10725SJohn.Forte@Sun.COM 			break;
27379585STim.Szeto@Sun.COM 		default:
27389585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NO_PROP;
27399585STim.Szeto@Sun.COM 			break;
27409585STim.Szeto@Sun.COM 	}
27419585STim.Szeto@Sun.COM 	return (ret);
27429585STim.Szeto@Sun.COM }
27439585STim.Szeto@Sun.COM 
27449585STim.Szeto@Sun.COM static int
27459585STim.Szeto@Sun.COM checkHexUpper(char *buf)
27469585STim.Szeto@Sun.COM {
27479585STim.Szeto@Sun.COM 	int i;
27489585STim.Szeto@Sun.COM 
27499585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(buf); i++) {
27509585STim.Szeto@Sun.COM 		if (isxdigit(buf[i])) {
27519585STim.Szeto@Sun.COM 			buf[i] = toupper(buf[i]);
27529585STim.Szeto@Sun.COM 			continue;
27539585STim.Szeto@Sun.COM 		}
27549585STim.Szeto@Sun.COM 		return (-1);
27559585STim.Szeto@Sun.COM 	}
27569585STim.Szeto@Sun.COM 
27579585STim.Szeto@Sun.COM 	return (0);
27589585STim.Szeto@Sun.COM }
27599585STim.Szeto@Sun.COM 
27609585STim.Szeto@Sun.COM /*
27619585STim.Szeto@Sun.COM  * Given a numeric suffix, convert the value into a number of bits that the
27629585STim.Szeto@Sun.COM  * resulting value must be shifted.
27639585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
27649585STim.Szeto@Sun.COM  */
27659585STim.Szeto@Sun.COM static int
27669585STim.Szeto@Sun.COM strToShift(const char *buf)
27679585STim.Szeto@Sun.COM {
27689585STim.Szeto@Sun.COM 	const char *ends = "BKMGTPE";
27699585STim.Szeto@Sun.COM 	int i;
27709585STim.Szeto@Sun.COM 
27719585STim.Szeto@Sun.COM 	if (buf[0] == '\0')
27729585STim.Szeto@Sun.COM 		return (0);
27739585STim.Szeto@Sun.COM 
27749585STim.Szeto@Sun.COM 	for (i = 0; i < strlen(ends); i++) {
27759585STim.Szeto@Sun.COM 		if (toupper(buf[0]) == ends[i])
27769585STim.Szeto@Sun.COM 			return (10*i);
27779585STim.Szeto@Sun.COM 	}
27789585STim.Szeto@Sun.COM 
27799585STim.Szeto@Sun.COM 	return (-1);
27809585STim.Szeto@Sun.COM }
27819585STim.Szeto@Sun.COM 
27829585STim.Szeto@Sun.COM int
27839585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl)
27849585STim.Szeto@Sun.COM {
27859585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
27869585STim.Szeto@Sun.COM 	if (hdl == NULL) {
27879585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
27889585STim.Szeto@Sun.COM 	}
27899585STim.Szeto@Sun.COM 
27909585STim.Szeto@Sun.COM 	luResourceImpl *hdlImpl = hdl;
27919585STim.Szeto@Sun.COM 	free(hdlImpl->resource);
27929585STim.Szeto@Sun.COM 	free(hdlImpl);
27939585STim.Szeto@Sun.COM 	return (ret);
27949585STim.Szeto@Sun.COM }
27959585STim.Szeto@Sun.COM 
27969585STim.Szeto@Sun.COM /*
27979585STim.Szeto@Sun.COM  * Convert a string of the form '100G' into a real number. Used when setting
27989585STim.Szeto@Sun.COM  * the size of a logical unit.
27999585STim.Szeto@Sun.COM  * Code lifted from libzfs_util.c
28009585STim.Szeto@Sun.COM  */
28019585STim.Szeto@Sun.COM static int
28029585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num)
28039585STim.Szeto@Sun.COM {
28049585STim.Szeto@Sun.COM 	char *end;
28059585STim.Szeto@Sun.COM 	int shift;
28069585STim.Szeto@Sun.COM 
28079585STim.Szeto@Sun.COM 	*num = 0;
28089585STim.Szeto@Sun.COM 
28099585STim.Szeto@Sun.COM 	/* Check to see if this looks like a number.  */
28109585STim.Szeto@Sun.COM 	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
28119585STim.Szeto@Sun.COM 		return (-1);
28129585STim.Szeto@Sun.COM 	}
28139585STim.Szeto@Sun.COM 
28149585STim.Szeto@Sun.COM 	/* Rely on stroull() to process the numeric portion.  */
28159585STim.Szeto@Sun.COM 	errno = 0;
28169585STim.Szeto@Sun.COM 	*num = strtoull(value, &end, 10);
28179585STim.Szeto@Sun.COM 
28189585STim.Szeto@Sun.COM 	/*
28199585STim.Szeto@Sun.COM 	 * Check for ERANGE, which indicates that the value is too large to fit
28209585STim.Szeto@Sun.COM 	 * in a 64-bit value.
28219585STim.Szeto@Sun.COM 	 */
28229585STim.Szeto@Sun.COM 	if (errno == ERANGE) {
28239585STim.Szeto@Sun.COM 		return (-1);
28249585STim.Szeto@Sun.COM 	}
28259585STim.Szeto@Sun.COM 
28269585STim.Szeto@Sun.COM 	/*
28279585STim.Szeto@Sun.COM 	 * If we have a decimal value, then do the computation with floating
28289585STim.Szeto@Sun.COM 	 * point arithmetic.  Otherwise, use standard arithmetic.
28299585STim.Szeto@Sun.COM 	 */
28309585STim.Szeto@Sun.COM 	if (*end == '.') {
28319585STim.Szeto@Sun.COM 		double fval = strtod(value, &end);
28329585STim.Szeto@Sun.COM 
28339585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
28349585STim.Szeto@Sun.COM 			return (-1);
28359585STim.Szeto@Sun.COM 		}
28369585STim.Szeto@Sun.COM 
28379585STim.Szeto@Sun.COM 		fval *= pow(2, shift);
28389585STim.Szeto@Sun.COM 
28399585STim.Szeto@Sun.COM 		if (fval > UINT64_MAX) {
28409585STim.Szeto@Sun.COM 			return (-1);
28419585STim.Szeto@Sun.COM 		}
28429585STim.Szeto@Sun.COM 
28439585STim.Szeto@Sun.COM 		*num = (uint64_t)fval;
28449585STim.Szeto@Sun.COM 	} else {
28459585STim.Szeto@Sun.COM 		if ((shift = strToShift(end)) == -1) {
28469585STim.Szeto@Sun.COM 			return (-1);
28479585STim.Szeto@Sun.COM 		}
28489585STim.Szeto@Sun.COM 
28499585STim.Szeto@Sun.COM 		/* Check for overflow */
28509585STim.Szeto@Sun.COM 		if (shift >= 64 || (*num << shift) >> shift != *num) {
28519585STim.Szeto@Sun.COM 			return (-1);
28529585STim.Szeto@Sun.COM 		}
28539585STim.Szeto@Sun.COM 
28549585STim.Szeto@Sun.COM 		*num <<= shift;
28559585STim.Szeto@Sun.COM 	}
28569585STim.Szeto@Sun.COM 
28579585STim.Szeto@Sun.COM 	return (0);
28589585STim.Szeto@Sun.COM }
28599585STim.Szeto@Sun.COM 
28609585STim.Szeto@Sun.COM /*
28617836SJohn.Forte@Sun.COM  * stmfCreateTargetGroup
28627836SJohn.Forte@Sun.COM  *
28637836SJohn.Forte@Sun.COM  * Purpose: Create a local port group
28647836SJohn.Forte@Sun.COM  *
28657836SJohn.Forte@Sun.COM  * targetGroupName - name of local port group to create
28667836SJohn.Forte@Sun.COM  */
28677836SJohn.Forte@Sun.COM int
28687836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName)
28697836SJohn.Forte@Sun.COM {
28707836SJohn.Forte@Sun.COM 	int ret;
28717836SJohn.Forte@Sun.COM 	int fd;
28727836SJohn.Forte@Sun.COM 
28737836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
28747836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
28757836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
28767836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28777836SJohn.Forte@Sun.COM 	}
28787836SJohn.Forte@Sun.COM 
28797836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
28807836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
28817836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
28827836SJohn.Forte@Sun.COM 	}
28837836SJohn.Forte@Sun.COM 
28847836SJohn.Forte@Sun.COM 	/* call init */
28857836SJohn.Forte@Sun.COM 	ret = initializeConfig();
28867836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
28877836SJohn.Forte@Sun.COM 		return (ret);
28887836SJohn.Forte@Sun.COM 	}
28897836SJohn.Forte@Sun.COM 
28907836SJohn.Forte@Sun.COM 	/*
28917836SJohn.Forte@Sun.COM 	 * Open control node for stmf
28927836SJohn.Forte@Sun.COM 	 */
28937836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
28947836SJohn.Forte@Sun.COM 		return (ret);
28957836SJohn.Forte@Sun.COM 
28967836SJohn.Forte@Sun.COM 	/*
28977836SJohn.Forte@Sun.COM 	 * Add the group to the driver
28987836SJohn.Forte@Sun.COM 	 */
28997836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
29007836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
29017836SJohn.Forte@Sun.COM 		goto done;
29027836SJohn.Forte@Sun.COM 	}
29037836SJohn.Forte@Sun.COM 
29049585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
29059585STim.Szeto@Sun.COM 		goto done;
29069585STim.Szeto@Sun.COM 	}
29079585STim.Szeto@Sun.COM 
29087836SJohn.Forte@Sun.COM 	/*
29097836SJohn.Forte@Sun.COM 	 * If the add to the driver was successful, add it to the persistent
29107836SJohn.Forte@Sun.COM 	 * store.
29117836SJohn.Forte@Sun.COM 	 */
29127836SJohn.Forte@Sun.COM 	ret = psCreateTargetGroup((char *)targetGroupName);
29137836SJohn.Forte@Sun.COM 	switch (ret) {
29147836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
29157836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
29167836SJohn.Forte@Sun.COM 			break;
29177836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
29187836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
29197836SJohn.Forte@Sun.COM 			break;
29207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
29217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
29227836SJohn.Forte@Sun.COM 			break;
29237836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
29247836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
29257836SJohn.Forte@Sun.COM 			break;
29267836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
29277836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
29287836SJohn.Forte@Sun.COM 			break;
29297836SJohn.Forte@Sun.COM 		default:
29307836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
29317836SJohn.Forte@Sun.COM 			    "stmfCreateTargetGroup:psCreateTargetGroup"
29327836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
29337836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
29347836SJohn.Forte@Sun.COM 			break;
29357836SJohn.Forte@Sun.COM 	}
29367836SJohn.Forte@Sun.COM 
29377836SJohn.Forte@Sun.COM done:
29387836SJohn.Forte@Sun.COM 	(void) close(fd);
29397836SJohn.Forte@Sun.COM 	return (ret);
29407836SJohn.Forte@Sun.COM }
29417836SJohn.Forte@Sun.COM 
29427836SJohn.Forte@Sun.COM /*
29437836SJohn.Forte@Sun.COM  * stmfDeleteHostGroup
29447836SJohn.Forte@Sun.COM  *
29457836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
29467836SJohn.Forte@Sun.COM  *
29477836SJohn.Forte@Sun.COM  * hostGroupName - group to delete
29487836SJohn.Forte@Sun.COM  */
29497836SJohn.Forte@Sun.COM int
29507836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName)
29517836SJohn.Forte@Sun.COM {
29527836SJohn.Forte@Sun.COM 	int ret;
29537836SJohn.Forte@Sun.COM 	int fd;
29547836SJohn.Forte@Sun.COM 
29557836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL) {
29567836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
29577836SJohn.Forte@Sun.COM 	}
29587836SJohn.Forte@Sun.COM 
29597836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
29607836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
29617836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
29627836SJohn.Forte@Sun.COM 	}
29637836SJohn.Forte@Sun.COM 
29647836SJohn.Forte@Sun.COM 	/* call init */
29657836SJohn.Forte@Sun.COM 	ret = initializeConfig();
29667836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
29677836SJohn.Forte@Sun.COM 		return (ret);
29687836SJohn.Forte@Sun.COM 	}
29697836SJohn.Forte@Sun.COM 
29707836SJohn.Forte@Sun.COM 	/*
29717836SJohn.Forte@Sun.COM 	 * Open control node for stmf
29727836SJohn.Forte@Sun.COM 	 */
29737836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
29747836SJohn.Forte@Sun.COM 		return (ret);
29757836SJohn.Forte@Sun.COM 
29767836SJohn.Forte@Sun.COM 	/*
29777836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
29787836SJohn.Forte@Sun.COM 	 */
29797836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
29807836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
29817836SJohn.Forte@Sun.COM 		goto done;
29827836SJohn.Forte@Sun.COM 	}
29837836SJohn.Forte@Sun.COM 
29849585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
29859585STim.Szeto@Sun.COM 		goto done;
29869585STim.Szeto@Sun.COM 	}
29879585STim.Szeto@Sun.COM 
29887836SJohn.Forte@Sun.COM 	/*
29897836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
29907836SJohn.Forte@Sun.COM 	 * persistent store.
29917836SJohn.Forte@Sun.COM 	 */
29927836SJohn.Forte@Sun.COM 	ret = psDeleteHostGroup((char *)hostGroupName);
29937836SJohn.Forte@Sun.COM 	switch (ret) {
29947836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
29957836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
29967836SJohn.Forte@Sun.COM 			break;
29977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
29987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
29997836SJohn.Forte@Sun.COM 			break;
30007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
30017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
30027836SJohn.Forte@Sun.COM 			break;
30037836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
30047836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
30057836SJohn.Forte@Sun.COM 			break;
30067836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
30077836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
30087836SJohn.Forte@Sun.COM 			break;
30097836SJohn.Forte@Sun.COM 		default:
30107836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
30117836SJohn.Forte@Sun.COM 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
30127836SJohn.Forte@Sun.COM 			    ret);
30137836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
30147836SJohn.Forte@Sun.COM 			break;
30157836SJohn.Forte@Sun.COM 	}
30167836SJohn.Forte@Sun.COM 
30177836SJohn.Forte@Sun.COM done:
30187836SJohn.Forte@Sun.COM 	(void) close(fd);
30197836SJohn.Forte@Sun.COM 	return (ret);
30207836SJohn.Forte@Sun.COM }
30217836SJohn.Forte@Sun.COM 
30227836SJohn.Forte@Sun.COM /*
30237836SJohn.Forte@Sun.COM  * stmfDeleteTargetGroup
30247836SJohn.Forte@Sun.COM  *
30257836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
30267836SJohn.Forte@Sun.COM  *
30277836SJohn.Forte@Sun.COM  * targetGroupName - group to delete
30287836SJohn.Forte@Sun.COM  */
30297836SJohn.Forte@Sun.COM int
30307836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
30317836SJohn.Forte@Sun.COM {
30327836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
30337836SJohn.Forte@Sun.COM 	int fd;
30347836SJohn.Forte@Sun.COM 
30357836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL) {
30367836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
30377836SJohn.Forte@Sun.COM 	}
30387836SJohn.Forte@Sun.COM 
30397836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
30407836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
30417836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
30427836SJohn.Forte@Sun.COM 	}
30437836SJohn.Forte@Sun.COM 
30447836SJohn.Forte@Sun.COM 	/* call init */
30457836SJohn.Forte@Sun.COM 	ret = initializeConfig();
30467836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
30477836SJohn.Forte@Sun.COM 		return (ret);
30487836SJohn.Forte@Sun.COM 	}
30497836SJohn.Forte@Sun.COM 
30507836SJohn.Forte@Sun.COM 	/*
30517836SJohn.Forte@Sun.COM 	 * Open control node for stmf
30527836SJohn.Forte@Sun.COM 	 */
30537836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
30547836SJohn.Forte@Sun.COM 		return (ret);
30557836SJohn.Forte@Sun.COM 
30567836SJohn.Forte@Sun.COM 	/*
30577836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
30587836SJohn.Forte@Sun.COM 	 */
30597836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
30607836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
30617836SJohn.Forte@Sun.COM 		goto done;
30627836SJohn.Forte@Sun.COM 	}
30637836SJohn.Forte@Sun.COM 
30649585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
30659585STim.Szeto@Sun.COM 		goto done;
30669585STim.Szeto@Sun.COM 	}
30679585STim.Szeto@Sun.COM 
30687836SJohn.Forte@Sun.COM 	/*
30697836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
30707836SJohn.Forte@Sun.COM 	 * persistent store.
30717836SJohn.Forte@Sun.COM 	 */
30727836SJohn.Forte@Sun.COM 	ret = psDeleteTargetGroup((char *)targetGroupName);
30737836SJohn.Forte@Sun.COM 	switch (ret) {
30747836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
30757836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
30767836SJohn.Forte@Sun.COM 			break;
30777836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
30787836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
30797836SJohn.Forte@Sun.COM 			break;
30807836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
30817836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
30827836SJohn.Forte@Sun.COM 			break;
30837836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
30847836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
30857836SJohn.Forte@Sun.COM 			break;
30867836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
30877836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
30887836SJohn.Forte@Sun.COM 			break;
30897836SJohn.Forte@Sun.COM 		default:
30907836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
30917836SJohn.Forte@Sun.COM 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
30927836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
30937836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
30947836SJohn.Forte@Sun.COM 			break;
30957836SJohn.Forte@Sun.COM 	}
30967836SJohn.Forte@Sun.COM 
30977836SJohn.Forte@Sun.COM done:
30987836SJohn.Forte@Sun.COM 	(void) close(fd);
30997836SJohn.Forte@Sun.COM 	return (ret);
31007836SJohn.Forte@Sun.COM }
31017836SJohn.Forte@Sun.COM 
31027836SJohn.Forte@Sun.COM /*
31037836SJohn.Forte@Sun.COM  * stmfDevidFromIscsiName
31047836SJohn.Forte@Sun.COM  *
31057836SJohn.Forte@Sun.COM  * Purpose: convert an iSCSI name to an stmf devid
31067836SJohn.Forte@Sun.COM  *
31077836SJohn.Forte@Sun.COM  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
31087836SJohn.Forte@Sun.COM  * devid - on success, contains the converted iscsi name
31097836SJohn.Forte@Sun.COM  */
31107836SJohn.Forte@Sun.COM int
31117836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
31127836SJohn.Forte@Sun.COM {
31137836SJohn.Forte@Sun.COM 	if (devid == NULL || iscsiName == NULL)
31147836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31157836SJohn.Forte@Sun.COM 
31167836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
31177836SJohn.Forte@Sun.COM 
31187836SJohn.Forte@Sun.COM 	/* Validate size of target */
31197836SJohn.Forte@Sun.COM 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
31207836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(EUI) ||
31217836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(IQN)) {
31227836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31237836SJohn.Forte@Sun.COM 	}
31247836SJohn.Forte@Sun.COM 
31257836SJohn.Forte@Sun.COM 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
31267836SJohn.Forte@Sun.COM 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
31277836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31287836SJohn.Forte@Sun.COM 	}
31297836SJohn.Forte@Sun.COM 
31307836SJohn.Forte@Sun.COM 	/* copy UTF-8 bytes to ident */
31317836SJohn.Forte@Sun.COM 	bcopy(iscsiName, devid->ident, devid->identLength);
31327836SJohn.Forte@Sun.COM 
31337836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
31347836SJohn.Forte@Sun.COM }
31357836SJohn.Forte@Sun.COM 
31367836SJohn.Forte@Sun.COM /*
31377836SJohn.Forte@Sun.COM  * stmfDevidFromWwn
31387836SJohn.Forte@Sun.COM  *
31397836SJohn.Forte@Sun.COM  * Purpose: convert a WWN to an stmf devid
31407836SJohn.Forte@Sun.COM  *
31417836SJohn.Forte@Sun.COM  * wwn - 8-byte wwn identifier
31427836SJohn.Forte@Sun.COM  * devid - on success, contains the converted wwn
31437836SJohn.Forte@Sun.COM  */
31447836SJohn.Forte@Sun.COM int
31457836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
31467836SJohn.Forte@Sun.COM {
31477836SJohn.Forte@Sun.COM 	if (wwn == NULL || devid == NULL)
31487836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31497836SJohn.Forte@Sun.COM 
31507836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
31517836SJohn.Forte@Sun.COM 
31527836SJohn.Forte@Sun.COM 	/* Copy eui prefix */
31537836SJohn.Forte@Sun.COM 	(void) bcopy(WWN, devid->ident, strlen(WWN));
31547836SJohn.Forte@Sun.COM 
31557836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
31567836SJohn.Forte@Sun.COM 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
31577836SJohn.Forte@Sun.COM 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
31587836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
31597836SJohn.Forte@Sun.COM 
31607836SJohn.Forte@Sun.COM 	devid->identLength = strlen((char *)devid->ident);
31617836SJohn.Forte@Sun.COM 
31627836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
31637836SJohn.Forte@Sun.COM }
31647836SJohn.Forte@Sun.COM 
31657836SJohn.Forte@Sun.COM /*
31667836SJohn.Forte@Sun.COM  * stmfFreeMemory
31677836SJohn.Forte@Sun.COM  *
31687836SJohn.Forte@Sun.COM  * Purpose: Free memory allocated by this library
31697836SJohn.Forte@Sun.COM  *
31707836SJohn.Forte@Sun.COM  * memory - previously allocated pointer of memory managed by library
31717836SJohn.Forte@Sun.COM  */
31727836SJohn.Forte@Sun.COM void
31737836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory)
31747836SJohn.Forte@Sun.COM {
31757836SJohn.Forte@Sun.COM 	free(memory);
31767836SJohn.Forte@Sun.COM }
31777836SJohn.Forte@Sun.COM 
31787836SJohn.Forte@Sun.COM /*
31799585STim.Szeto@Sun.COM  * get host group, target group list from stmf
31807836SJohn.Forte@Sun.COM  *
31819585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
31827836SJohn.Forte@Sun.COM  */
31839585STim.Szeto@Sun.COM static int
31849585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType)
31859585STim.Szeto@Sun.COM {
31869585STim.Szeto@Sun.COM 	int ret;
31879585STim.Szeto@Sun.COM 	int fd;
31889585STim.Szeto@Sun.COM 	int ioctlRet;
31899585STim.Szeto@Sun.COM 	int i;
31909585STim.Szeto@Sun.COM 	int cmd;
31919585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
31929585STim.Szeto@Sun.COM 	/* framework group list */
31939585STim.Szeto@Sun.COM 	stmf_group_name_t *iGroupList = NULL;
31949585STim.Szeto@Sun.COM 	uint32_t groupListSize;
31959585STim.Szeto@Sun.COM 
31969585STim.Szeto@Sun.COM 	if (groupList == NULL) {
31979585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31989585STim.Szeto@Sun.COM 	}
31999585STim.Szeto@Sun.COM 
32009585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
32019585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_LIST;
32029585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
32039585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_LIST;
32049585STim.Szeto@Sun.COM 	} else {
32059585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32069585STim.Szeto@Sun.COM 	}
32079585STim.Szeto@Sun.COM 
32089585STim.Szeto@Sun.COM 	/* call init */
32099585STim.Szeto@Sun.COM 	ret = initializeConfig();
32109585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
32119585STim.Szeto@Sun.COM 		return (ret);
32129585STim.Szeto@Sun.COM 	}
32139585STim.Szeto@Sun.COM 
32149585STim.Szeto@Sun.COM 	/*
32159585STim.Szeto@Sun.COM 	 * Open control node for stmf
32169585STim.Szeto@Sun.COM 	 */
32179585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
32189585STim.Szeto@Sun.COM 		return (ret);
32199585STim.Szeto@Sun.COM 
32209585STim.Szeto@Sun.COM 	/*
32219585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
32229585STim.Szeto@Sun.COM 	 */
32239585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GROUP;
32249585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_group_name_t));
32259585STim.Szeto@Sun.COM 	iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
32269585STim.Szeto@Sun.COM 	if (iGroupList == NULL) {
32279585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
32289585STim.Szeto@Sun.COM 		goto done;
32299585STim.Szeto@Sun.COM 	}
32309585STim.Szeto@Sun.COM 
32319585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
32329585STim.Szeto@Sun.COM 	/*
32339585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
32349585STim.Szeto@Sun.COM 	 */
32359585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
32369585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
32379585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
32389585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
32399585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
32409585STim.Szeto@Sun.COM 		switch (errno) {
32419585STim.Szeto@Sun.COM 			case EBUSY:
32429585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
32439585STim.Szeto@Sun.COM 				break;
32449585STim.Szeto@Sun.COM 			case EPERM:
32459585STim.Szeto@Sun.COM 			case EACCES:
32469585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
32479585STim.Szeto@Sun.COM 				break;
32489585STim.Szeto@Sun.COM 			default:
32499585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
32509585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
32519585STim.Szeto@Sun.COM 				    errno);
32529585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
32539585STim.Szeto@Sun.COM 				break;
32549585STim.Szeto@Sun.COM 		}
32559585STim.Szeto@Sun.COM 		goto done;
32569585STim.Szeto@Sun.COM 	}
32579585STim.Szeto@Sun.COM 	/*
32589585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
32599585STim.Szeto@Sun.COM 	 */
32609585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
32619585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
32629585STim.Szeto@Sun.COM 		    sizeof (stmf_group_name_t);
32639585STim.Szeto@Sun.COM 		iGroupList = realloc(iGroupList, groupListSize);
32649585STim.Szeto@Sun.COM 		if (iGroupList == NULL) {
32659585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
32669585STim.Szeto@Sun.COM 			goto done;
32679585STim.Szeto@Sun.COM 		}
32689585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
32699585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
32709585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
32719585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
32729585STim.Szeto@Sun.COM 			switch (errno) {
32739585STim.Szeto@Sun.COM 				case EBUSY:
32749585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
32759585STim.Szeto@Sun.COM 					break;
32769585STim.Szeto@Sun.COM 				case EPERM:
32779585STim.Szeto@Sun.COM 				case EACCES:
32789585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
32799585STim.Szeto@Sun.COM 					break;
32809585STim.Szeto@Sun.COM 				default:
32819585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
32829585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
32839585STim.Szeto@Sun.COM 					    errno);
32849585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
32859585STim.Szeto@Sun.COM 					break;
32869585STim.Szeto@Sun.COM 			}
32879585STim.Szeto@Sun.COM 			goto done;
32889585STim.Szeto@Sun.COM 		}
32899585STim.Szeto@Sun.COM 	}
32909585STim.Szeto@Sun.COM 
32919585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
329210236SSrivijitha.Dugganapalli@Sun.COM 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
329310236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries);
32949585STim.Szeto@Sun.COM 	if (*groupList == NULL) {
32959585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
32969585STim.Szeto@Sun.COM 		goto done;
32979585STim.Szeto@Sun.COM 	}
32989585STim.Szeto@Sun.COM 	(*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
32999585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
330010113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupList[i].name, (*groupList)->name[i],
33019585STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
33029585STim.Szeto@Sun.COM 	}
33039585STim.Szeto@Sun.COM 
33049585STim.Szeto@Sun.COM done:
33059585STim.Szeto@Sun.COM 	free(iGroupList);
33069585STim.Szeto@Sun.COM 	(void) close(fd);
33079585STim.Szeto@Sun.COM 	return (ret);
33089585STim.Szeto@Sun.COM }
33099585STim.Szeto@Sun.COM 
33109585STim.Szeto@Sun.COM /*
33119585STim.Szeto@Sun.COM  * get host group members, target group members from stmf
33129585STim.Szeto@Sun.COM  *
33139585STim.Szeto@Sun.COM  * groupProps - allocated on success
33149585STim.Szeto@Sun.COM  *
33159585STim.Szeto@Sun.COM  * groupType - HOST_GROUP, TARGET_GROUP
33169585STim.Szeto@Sun.COM  */
33179585STim.Szeto@Sun.COM static int
33189585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
33199585STim.Szeto@Sun.COM     int groupType)
33207836SJohn.Forte@Sun.COM {
33217836SJohn.Forte@Sun.COM 	int ret;
33229585STim.Szeto@Sun.COM 	int fd;
33239585STim.Szeto@Sun.COM 	int ioctlRet;
33249585STim.Szeto@Sun.COM 	int i;
33259585STim.Szeto@Sun.COM 	int cmd;
33269585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
33279585STim.Szeto@Sun.COM 	/* framework group list */
33289585STim.Szeto@Sun.COM 	stmf_group_name_t iGroupName;
33299585STim.Szeto@Sun.COM 	stmf_ge_ident_t *iGroupMembers;
33309585STim.Szeto@Sun.COM 	uint32_t groupListSize;
33319585STim.Szeto@Sun.COM 
33329585STim.Szeto@Sun.COM 	if (groupName == NULL) {
33339585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33349585STim.Szeto@Sun.COM 	}
33359585STim.Szeto@Sun.COM 
33369585STim.Szeto@Sun.COM 	if (groupType == HOST_GROUP) {
33379585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_HG_ENTRIES;
33389585STim.Szeto@Sun.COM 	} else if (groupType == TARGET_GROUP) {
33399585STim.Szeto@Sun.COM 		cmd = STMF_IOCTL_GET_TG_ENTRIES;
33409585STim.Szeto@Sun.COM 	} else {
33417836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33427836SJohn.Forte@Sun.COM 	}
33437836SJohn.Forte@Sun.COM 
33449585STim.Szeto@Sun.COM 	/* call init */
33459585STim.Szeto@Sun.COM 	ret = initializeConfig();
33469585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
33479585STim.Szeto@Sun.COM 		return (ret);
33489585STim.Szeto@Sun.COM 	}
33499585STim.Szeto@Sun.COM 
33509585STim.Szeto@Sun.COM 	/*
33519585STim.Szeto@Sun.COM 	 * Open control node for stmf
33529585STim.Szeto@Sun.COM 	 */
33539585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
33549585STim.Szeto@Sun.COM 		return (ret);
33559585STim.Szeto@Sun.COM 
33569585STim.Szeto@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
33579585STim.Szeto@Sun.COM 
33589585STim.Szeto@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
33599585STim.Szeto@Sun.COM 
33609585STim.Szeto@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
33619585STim.Szeto@Sun.COM 
33629585STim.Szeto@Sun.COM 	/*
33639585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
33649585STim.Szeto@Sun.COM 	 */
33659585STim.Szeto@Sun.COM 	groupListSize = ALLOC_GRP_MEMBER;
33669585STim.Szeto@Sun.COM 	groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
33679585STim.Szeto@Sun.COM 	iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
33689585STim.Szeto@Sun.COM 	if (iGroupMembers == NULL) {
33699585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
33709585STim.Szeto@Sun.COM 		goto done;
33719585STim.Szeto@Sun.COM 	}
33729585STim.Szeto@Sun.COM 
33739585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
33749585STim.Szeto@Sun.COM 	/*
33759585STim.Szeto@Sun.COM 	 * Issue ioctl to get the group list
33769585STim.Szeto@Sun.COM 	 */
33779585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
33789585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
33799585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
33809585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = groupListSize;
33819585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
33829585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
33839585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
33849585STim.Szeto@Sun.COM 		switch (errno) {
33859585STim.Szeto@Sun.COM 			case EBUSY:
33869585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
33879585STim.Szeto@Sun.COM 				break;
33889585STim.Szeto@Sun.COM 			case EPERM:
33899585STim.Szeto@Sun.COM 			case EACCES:
33909585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
33919585STim.Szeto@Sun.COM 				break;
33929585STim.Szeto@Sun.COM 			default:
33939585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
33949585STim.Szeto@Sun.COM 				    "groupListIoctl:ioctl errno(%d)",
33959585STim.Szeto@Sun.COM 				    errno);
33969585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
33979585STim.Szeto@Sun.COM 				break;
33989585STim.Szeto@Sun.COM 		}
33999585STim.Szeto@Sun.COM 		goto done;
34009585STim.Szeto@Sun.COM 	}
34019585STim.Szeto@Sun.COM 	/*
34029585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
34039585STim.Szeto@Sun.COM 	 */
34049585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
34059585STim.Szeto@Sun.COM 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
34069585STim.Szeto@Sun.COM 		    sizeof (stmf_ge_ident_t);
34079585STim.Szeto@Sun.COM 		iGroupMembers = realloc(iGroupMembers, groupListSize);
34089585STim.Szeto@Sun.COM 		if (iGroupMembers == NULL) {
34099585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
34109585STim.Szeto@Sun.COM 			goto done;
34119585STim.Szeto@Sun.COM 		}
34129585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
34139585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
34149585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = groupListSize;
34159585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
34169585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
34179585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
34189585STim.Szeto@Sun.COM 			switch (errno) {
34199585STim.Szeto@Sun.COM 				case EBUSY:
34209585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
34219585STim.Szeto@Sun.COM 					break;
34229585STim.Szeto@Sun.COM 				case EPERM:
34239585STim.Szeto@Sun.COM 				case EACCES:
34249585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
34259585STim.Szeto@Sun.COM 					break;
34269585STim.Szeto@Sun.COM 				default:
34279585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
34289585STim.Szeto@Sun.COM 					    "groupListIoctl:ioctl errno(%d)",
34299585STim.Szeto@Sun.COM 					    errno);
34309585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
34319585STim.Szeto@Sun.COM 					break;
34329585STim.Szeto@Sun.COM 			}
34339585STim.Szeto@Sun.COM 			goto done;
34349585STim.Szeto@Sun.COM 		}
34359585STim.Szeto@Sun.COM 	}
34369585STim.Szeto@Sun.COM 
34379585STim.Szeto@Sun.COM 	/* allocate and copy to caller's buffer */
34389585STim.Szeto@Sun.COM 	*groupProps = (stmfGroupProperties *)calloc(1,
343910236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfGroupProperties) +
344010236SSrivijitha.Dugganapalli@Sun.COM 	    sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries);
34419585STim.Szeto@Sun.COM 	if (*groupProps == NULL) {
34429585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
34439585STim.Szeto@Sun.COM 		goto done;
34449585STim.Szeto@Sun.COM 	}
34459585STim.Szeto@Sun.COM 	(*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
34469585STim.Szeto@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
34479585STim.Szeto@Sun.COM 		(*groupProps)->name[i].identLength =
344810113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size;
344910113SNattuvetty.Bhavyan@Sun.COM 		bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
345010113SNattuvetty.Bhavyan@Sun.COM 		    iGroupMembers[i].ident_size);
34519585STim.Szeto@Sun.COM 	}
34529585STim.Szeto@Sun.COM 
34539585STim.Szeto@Sun.COM done:
34549585STim.Szeto@Sun.COM 	free(iGroupMembers);
34559585STim.Szeto@Sun.COM 	(void) close(fd);
34569585STim.Szeto@Sun.COM 	return (ret);
34579585STim.Szeto@Sun.COM }
34589585STim.Szeto@Sun.COM 
34599585STim.Szeto@Sun.COM /*
34609585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
34619585STim.Szeto@Sun.COM  */
34629585STim.Szeto@Sun.COM static int
34639585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type)
34649585STim.Szeto@Sun.COM {
34659585STim.Szeto@Sun.COM 	int ret;
34669585STim.Szeto@Sun.COM 
34679585STim.Szeto@Sun.COM 	if (groupList == NULL) {
34689585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34699585STim.Szeto@Sun.COM 	}
34709585STim.Szeto@Sun.COM 
34719585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
34729585STim.Szeto@Sun.COM 		ret = psGetHostGroupList(groupList);
34739585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
34749585STim.Szeto@Sun.COM 		ret = psGetTargetGroupList(groupList);
34759585STim.Szeto@Sun.COM 	} else {
34769585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
34779585STim.Szeto@Sun.COM 	}
34787836SJohn.Forte@Sun.COM 	switch (ret) {
34797836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
34807836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
34817836SJohn.Forte@Sun.COM 			break;
34827836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
34837836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
34847836SJohn.Forte@Sun.COM 			break;
34857836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
34867836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
34877836SJohn.Forte@Sun.COM 			break;
34887836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
34897836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
34907836SJohn.Forte@Sun.COM 			break;
34917836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
34927836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
34937836SJohn.Forte@Sun.COM 			break;
34947836SJohn.Forte@Sun.COM 		default:
34957836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
34967836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
34977836SJohn.Forte@Sun.COM 			    ret);
34987836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
34997836SJohn.Forte@Sun.COM 			break;
35007836SJohn.Forte@Sun.COM 	}
35017836SJohn.Forte@Sun.COM 
35027836SJohn.Forte@Sun.COM 	return (ret);
35037836SJohn.Forte@Sun.COM }
35047836SJohn.Forte@Sun.COM 
35057836SJohn.Forte@Sun.COM /*
35069585STim.Szeto@Sun.COM  * stmfGetHostGroupList
35077836SJohn.Forte@Sun.COM  *
35089585STim.Szeto@Sun.COM  * Purpose: Retrieves the list of initiator group oids
35099585STim.Szeto@Sun.COM  *
35109585STim.Szeto@Sun.COM  * hostGroupList - pointer to pointer to hostGroupList structure
35119585STim.Szeto@Sun.COM  *                 on success, this contains the host group list.
35127836SJohn.Forte@Sun.COM  */
35137836SJohn.Forte@Sun.COM int
35149585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList)
35159585STim.Szeto@Sun.COM {
35169585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_ERROR;
35179585STim.Szeto@Sun.COM 
35189585STim.Szeto@Sun.COM 	if (hostGroupList == NULL) {
35199585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35209585STim.Szeto@Sun.COM 	}
35219585STim.Szeto@Sun.COM 
35229585STim.Szeto@Sun.COM 	ret = groupListIoctl(hostGroupList, HOST_GROUP);
35239585STim.Szeto@Sun.COM 	return (ret);
35249585STim.Szeto@Sun.COM }
35259585STim.Szeto@Sun.COM 
35269585STim.Szeto@Sun.COM 
35279585STim.Szeto@Sun.COM /*
35289585STim.Szeto@Sun.COM  * Purpose: access persistent config data for host groups and target groups
35299585STim.Szeto@Sun.COM  */
35309585STim.Szeto@Sun.COM static int
35319585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName,
35329585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp, int type)
35337836SJohn.Forte@Sun.COM {
35347836SJohn.Forte@Sun.COM 	int ret;
35357836SJohn.Forte@Sun.COM 
35369585STim.Szeto@Sun.COM 	if (groupName == NULL) {
35377836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35387836SJohn.Forte@Sun.COM 	}
35397836SJohn.Forte@Sun.COM 
35409585STim.Szeto@Sun.COM 	if (type == HOST_GROUP) {
35419585STim.Szeto@Sun.COM 		ret = psGetHostGroupMemberList((char *)groupName, groupProp);
35429585STim.Szeto@Sun.COM 	} else if (type == TARGET_GROUP) {
35439585STim.Szeto@Sun.COM 		ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
35449585STim.Szeto@Sun.COM 	} else {
35459585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35469585STim.Szeto@Sun.COM 	}
35477836SJohn.Forte@Sun.COM 	switch (ret) {
35487836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
35497836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
35507836SJohn.Forte@Sun.COM 			break;
35517836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
35527836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
35537836SJohn.Forte@Sun.COM 			break;
35547836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
35557836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
35567836SJohn.Forte@Sun.COM 			break;
35577836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
35587836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
35597836SJohn.Forte@Sun.COM 			break;
35607836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
35617836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
35627836SJohn.Forte@Sun.COM 			break;
35637836SJohn.Forte@Sun.COM 		default:
35647836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
35659585STim.Szeto@Sun.COM 			    "iLoadGroupMembersFromPs:psGetHostGroupList:"
35669585STim.Szeto@Sun.COM 			    "error(%d)", ret);
35677836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
35687836SJohn.Forte@Sun.COM 			break;
35697836SJohn.Forte@Sun.COM 	}
35707836SJohn.Forte@Sun.COM 
35717836SJohn.Forte@Sun.COM 	return (ret);
35727836SJohn.Forte@Sun.COM }
35737836SJohn.Forte@Sun.COM 
35747836SJohn.Forte@Sun.COM /*
35759585STim.Szeto@Sun.COM  * stmfGetHostGroupMembers
35769585STim.Szeto@Sun.COM  *
35779585STim.Szeto@Sun.COM  * Purpose: Retrieves the group properties for a host group
35789585STim.Szeto@Sun.COM  *
35799585STim.Szeto@Sun.COM  * groupName - name of group for which to retrieve host group members.
35809585STim.Szeto@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
35819585STim.Szeto@Sun.COM  *             on success, this contains the list of group members.
35829585STim.Szeto@Sun.COM  */
35839585STim.Szeto@Sun.COM int
35849585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName,
35859585STim.Szeto@Sun.COM     stmfGroupProperties **groupProp)
35869585STim.Szeto@Sun.COM {
35879585STim.Szeto@Sun.COM 	int ret;
35889585STim.Szeto@Sun.COM 
35899585STim.Szeto@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
35909585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
35919585STim.Szeto@Sun.COM 	}
35929585STim.Szeto@Sun.COM 
35939585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
35949585STim.Szeto@Sun.COM 
35959585STim.Szeto@Sun.COM 	return (ret);
35969585STim.Szeto@Sun.COM }
35979585STim.Szeto@Sun.COM 
35989585STim.Szeto@Sun.COM /*
35997836SJohn.Forte@Sun.COM  * stmfGetProviderData
36007836SJohn.Forte@Sun.COM  *
36017836SJohn.Forte@Sun.COM  * Purpose: Get provider data list
36027836SJohn.Forte@Sun.COM  *
36037836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
36047836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
36057836SJohn.Forte@Sun.COM  *       retrieved.
36067836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
36077836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
36087836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
36097836SJohn.Forte@Sun.COM  */
36107836SJohn.Forte@Sun.COM int
36117836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
36127836SJohn.Forte@Sun.COM {
36137836SJohn.Forte@Sun.COM 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
36147836SJohn.Forte@Sun.COM 	    NULL));
36157836SJohn.Forte@Sun.COM }
36167836SJohn.Forte@Sun.COM 
36177836SJohn.Forte@Sun.COM /*
36187836SJohn.Forte@Sun.COM  * stmfGetProviderDataProt
36197836SJohn.Forte@Sun.COM  *
36207836SJohn.Forte@Sun.COM  * Purpose: Get provider data list with token
36217836SJohn.Forte@Sun.COM  *
36227836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
36237836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
36247836SJohn.Forte@Sun.COM  *       retrieved.
36257836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
36267836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
36277836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
36287836SJohn.Forte@Sun.COM  * setToken - Returns the stale data token
36297836SJohn.Forte@Sun.COM  */
36307836SJohn.Forte@Sun.COM int
36317836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
36327836SJohn.Forte@Sun.COM     uint64_t *setToken)
36337836SJohn.Forte@Sun.COM {
36347836SJohn.Forte@Sun.COM 	int ret;
36357836SJohn.Forte@Sun.COM 
36367836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
36377836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36387836SJohn.Forte@Sun.COM 	}
36397836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
36407836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
36417836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
36427836SJohn.Forte@Sun.COM 	}
36437836SJohn.Forte@Sun.COM 	/* call init */
36447836SJohn.Forte@Sun.COM 	ret = initializeConfig();
36457836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
36467836SJohn.Forte@Sun.COM 		return (ret);
36477836SJohn.Forte@Sun.COM 	}
36489585STim.Szeto@Sun.COM 	return (getProviderData(providerName, nvl, providerType, setToken));
36497836SJohn.Forte@Sun.COM }
36507836SJohn.Forte@Sun.COM 
36517836SJohn.Forte@Sun.COM /*
36527836SJohn.Forte@Sun.COM  * stmfGetProviderDataList
36537836SJohn.Forte@Sun.COM  *
36547836SJohn.Forte@Sun.COM  * Purpose: Get the list of providers currently persisting data
36557836SJohn.Forte@Sun.COM  *
36567836SJohn.Forte@Sun.COM  * providerList - pointer to pointer to an stmfProviderList structure allocated
36577836SJohn.Forte@Sun.COM  *                by the caller. Will contain the list of providers on success.
36587836SJohn.Forte@Sun.COM  */
36597836SJohn.Forte@Sun.COM int
36607836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList)
36617836SJohn.Forte@Sun.COM {
36627836SJohn.Forte@Sun.COM 	int ret;
36637836SJohn.Forte@Sun.COM 
36647836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(providerList);
36657836SJohn.Forte@Sun.COM 	switch (ret) {
36667836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
36677836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
36687836SJohn.Forte@Sun.COM 			break;
36697836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
36707836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
36717836SJohn.Forte@Sun.COM 			break;
36727836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
36737836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
36747836SJohn.Forte@Sun.COM 			break;
36757836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
36767836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
36777836SJohn.Forte@Sun.COM 			break;
36787836SJohn.Forte@Sun.COM 		default:
36797836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
36807836SJohn.Forte@Sun.COM 			    "stmfGetProviderDataList:psGetProviderDataList"
36817836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
36827836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
36837836SJohn.Forte@Sun.COM 			break;
36847836SJohn.Forte@Sun.COM 	}
36857836SJohn.Forte@Sun.COM 
36867836SJohn.Forte@Sun.COM 	return (ret);
36877836SJohn.Forte@Sun.COM }
36887836SJohn.Forte@Sun.COM 
36897836SJohn.Forte@Sun.COM 
36907836SJohn.Forte@Sun.COM /*
36917836SJohn.Forte@Sun.COM  * stmfGetSessionList
36927836SJohn.Forte@Sun.COM  *
36937836SJohn.Forte@Sun.COM  * Purpose: Retrieves the session list for a target (devid)
36947836SJohn.Forte@Sun.COM  *
36957836SJohn.Forte@Sun.COM  * devid - devid of target for which to retrieve session information.
36967836SJohn.Forte@Sun.COM  * sessionList - pointer to pointer to stmfSessionList structure
36977836SJohn.Forte@Sun.COM  *             on success, this contains the list of initiator sessions.
36987836SJohn.Forte@Sun.COM  */
36997836SJohn.Forte@Sun.COM int
37007836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
37017836SJohn.Forte@Sun.COM {
37027836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
37037836SJohn.Forte@Sun.COM 	int fd;
37047836SJohn.Forte@Sun.COM 	int ioctlRet;
37057836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_SESSION_LIST;
37067836SJohn.Forte@Sun.COM 	int i;
37077836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
370810261SCharles.Ting@Sun.COM 	slist_scsi_session_t *fSessionList, *fSessionListP = NULL;
37097836SJohn.Forte@Sun.COM 	uint8_t ident[260];
37107836SJohn.Forte@Sun.COM 	uint32_t fSessionListSize;
37117836SJohn.Forte@Sun.COM 
37127836SJohn.Forte@Sun.COM 	if (sessionList == NULL || devid == NULL) {
37137836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
37147836SJohn.Forte@Sun.COM 	}
37157836SJohn.Forte@Sun.COM 
37167836SJohn.Forte@Sun.COM 	/* call init */
37177836SJohn.Forte@Sun.COM 	ret = initializeConfig();
37187836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
37197836SJohn.Forte@Sun.COM 		return (ret);
37207836SJohn.Forte@Sun.COM 	}
37217836SJohn.Forte@Sun.COM 
37227836SJohn.Forte@Sun.COM 	/*
37237836SJohn.Forte@Sun.COM 	 * Open control node for stmf
37247836SJohn.Forte@Sun.COM 	 */
37257836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
37267836SJohn.Forte@Sun.COM 		return (ret);
37277836SJohn.Forte@Sun.COM 
37287836SJohn.Forte@Sun.COM 	/*
37297836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
37307836SJohn.Forte@Sun.COM 	 */
37319585STim.Szeto@Sun.COM 	fSessionListSize = ALLOC_SESSION;
37327836SJohn.Forte@Sun.COM 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
37337836SJohn.Forte@Sun.COM 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
373410261SCharles.Ting@Sun.COM 	fSessionListP = fSessionList;
37357836SJohn.Forte@Sun.COM 	if (fSessionList == NULL) {
373610261SCharles.Ting@Sun.COM 		ret = STMF_ERROR_NOMEM;
373710261SCharles.Ting@Sun.COM 		goto done;
37387836SJohn.Forte@Sun.COM 	}
37397836SJohn.Forte@Sun.COM 
37407836SJohn.Forte@Sun.COM 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
37417836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
37427836SJohn.Forte@Sun.COM 	    devid->identLength);
37437836SJohn.Forte@Sun.COM 
37447836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
37457836SJohn.Forte@Sun.COM 	/*
37467836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the session list
37477836SJohn.Forte@Sun.COM 	 */
37487836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
37497836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
37507836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
37517836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fSessionListSize;
37527836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
37537836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
37547836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
37557836SJohn.Forte@Sun.COM 		switch (errno) {
37567836SJohn.Forte@Sun.COM 			case EBUSY:
37577836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
37587836SJohn.Forte@Sun.COM 				break;
37599585STim.Szeto@Sun.COM 			case EPERM:
37607836SJohn.Forte@Sun.COM 			case EACCES:
37617836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
37627836SJohn.Forte@Sun.COM 				break;
37637836SJohn.Forte@Sun.COM 			default:
37647836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
37657836SJohn.Forte@Sun.COM 				    "stmfGetSessionList:ioctl errno(%d)",
37667836SJohn.Forte@Sun.COM 				    errno);
37677836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
37687836SJohn.Forte@Sun.COM 				break;
37697836SJohn.Forte@Sun.COM 		}
37707836SJohn.Forte@Sun.COM 		goto done;
37717836SJohn.Forte@Sun.COM 	}
37727836SJohn.Forte@Sun.COM 	/*
37737836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
37747836SJohn.Forte@Sun.COM 	 */
37759585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
37767836SJohn.Forte@Sun.COM 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
37777836SJohn.Forte@Sun.COM 		    sizeof (slist_scsi_session_t);
37787836SJohn.Forte@Sun.COM 		fSessionList = realloc(fSessionList, fSessionListSize);
37797836SJohn.Forte@Sun.COM 		if (fSessionList == NULL) {
378010261SCharles.Ting@Sun.COM 			ret = STMF_ERROR_NOMEM;
378110261SCharles.Ting@Sun.COM 			goto done;
37827836SJohn.Forte@Sun.COM 		}
378310261SCharles.Ting@Sun.COM 		fSessionListP = fSessionList;
37847836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fSessionListSize;
37857836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
37867836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
37877836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
37887836SJohn.Forte@Sun.COM 			switch (errno) {
37897836SJohn.Forte@Sun.COM 				case EBUSY:
37907836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
37917836SJohn.Forte@Sun.COM 					break;
37929585STim.Szeto@Sun.COM 				case EPERM:
37937836SJohn.Forte@Sun.COM 				case EACCES:
37947836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
37957836SJohn.Forte@Sun.COM 					break;
37967836SJohn.Forte@Sun.COM 				default:
37977836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
37987836SJohn.Forte@Sun.COM 					    "stmfGetSessionList:ioctl "
37997836SJohn.Forte@Sun.COM 					    "errno(%d)", errno);
38007836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
38017836SJohn.Forte@Sun.COM 					break;
38027836SJohn.Forte@Sun.COM 			}
38037836SJohn.Forte@Sun.COM 			goto done;
38047836SJohn.Forte@Sun.COM 		}
38057836SJohn.Forte@Sun.COM 	}
38067836SJohn.Forte@Sun.COM 
38077836SJohn.Forte@Sun.COM 	/*
38087836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
38097836SJohn.Forte@Sun.COM 	 */
38107836SJohn.Forte@Sun.COM 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
38117836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
38127836SJohn.Forte@Sun.COM 	if (*sessionList == NULL) {
38137836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
38147836SJohn.Forte@Sun.COM 		free(sessionList);
38157836SJohn.Forte@Sun.COM 		goto done;
38167836SJohn.Forte@Sun.COM 	}
38177836SJohn.Forte@Sun.COM 
38187836SJohn.Forte@Sun.COM 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
38197836SJohn.Forte@Sun.COM 
38207836SJohn.Forte@Sun.COM 	/*
38217836SJohn.Forte@Sun.COM 	 * copy session info to caller's buffer
38227836SJohn.Forte@Sun.COM 	 */
38237836SJohn.Forte@Sun.COM 	for (i = 0; i < (*sessionList)->cnt; i++) {
38247836SJohn.Forte@Sun.COM 		(*sessionList)->session[i].initiator.identLength =
38257836SJohn.Forte@Sun.COM 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
38267836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
38277836SJohn.Forte@Sun.COM 		    (*sessionList)->session[i].initiator.ident,
38287836SJohn.Forte@Sun.COM 		    STMF_IDENT_LENGTH);
38297836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->alias),
38307836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].alias),
38317836SJohn.Forte@Sun.COM 		    sizeof ((*sessionList)->session[i].alias));
38327836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList++->creation_time),
38337836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].creationTime),
38347836SJohn.Forte@Sun.COM 		    sizeof (time_t));
38357836SJohn.Forte@Sun.COM 	}
38367836SJohn.Forte@Sun.COM done:
38377836SJohn.Forte@Sun.COM 	(void) close(fd);
383810261SCharles.Ting@Sun.COM 	free(fSessionListP);
38397836SJohn.Forte@Sun.COM 	return (ret);
38407836SJohn.Forte@Sun.COM }
38417836SJohn.Forte@Sun.COM 
38427836SJohn.Forte@Sun.COM /*
38437836SJohn.Forte@Sun.COM  * stmfGetTargetGroupList
38447836SJohn.Forte@Sun.COM  *
38457836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target groups
38467836SJohn.Forte@Sun.COM  *
38477836SJohn.Forte@Sun.COM  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
38487836SJohn.Forte@Sun.COM  *		     success, it contains the list of target groups.
38497836SJohn.Forte@Sun.COM  */
38507836SJohn.Forte@Sun.COM int
38517836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList)
38527836SJohn.Forte@Sun.COM {
38537836SJohn.Forte@Sun.COM 	int ret;
38547836SJohn.Forte@Sun.COM 
38557836SJohn.Forte@Sun.COM 	if (targetGroupList == NULL) {
38567836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38577836SJohn.Forte@Sun.COM 	}
38587836SJohn.Forte@Sun.COM 
38599585STim.Szeto@Sun.COM 	ret = groupListIoctl(targetGroupList, TARGET_GROUP);
38607836SJohn.Forte@Sun.COM 	return (ret);
38617836SJohn.Forte@Sun.COM }
38627836SJohn.Forte@Sun.COM 
38637836SJohn.Forte@Sun.COM /*
38647836SJohn.Forte@Sun.COM  * stmfGetTargetGroupMembers
38657836SJohn.Forte@Sun.COM  *
38667836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group members for a target group
38677836SJohn.Forte@Sun.COM  *
38687836SJohn.Forte@Sun.COM  * groupName - name of target group for which to retrieve members.
38697836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
38707836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
38717836SJohn.Forte@Sun.COM  */
38727836SJohn.Forte@Sun.COM int
38737836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName,
38747836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
38757836SJohn.Forte@Sun.COM {
38767836SJohn.Forte@Sun.COM 	int ret;
38777836SJohn.Forte@Sun.COM 
38787836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
38797836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
38807836SJohn.Forte@Sun.COM 	}
38817836SJohn.Forte@Sun.COM 
38829585STim.Szeto@Sun.COM 	ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
38837836SJohn.Forte@Sun.COM 
38847836SJohn.Forte@Sun.COM 	return (ret);
38857836SJohn.Forte@Sun.COM }
38867836SJohn.Forte@Sun.COM 
38877836SJohn.Forte@Sun.COM /*
38887836SJohn.Forte@Sun.COM  * stmfGetTargetList
38897836SJohn.Forte@Sun.COM  *
38907836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target ports
38917836SJohn.Forte@Sun.COM  *
38927836SJohn.Forte@Sun.COM  * targetList - pointer to a pointer to an stmfDevidList structure.
38937836SJohn.Forte@Sun.COM  *		    On success, it contains the list of local ports (target).
38947836SJohn.Forte@Sun.COM  */
38957836SJohn.Forte@Sun.COM int
38967836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList)
38977836SJohn.Forte@Sun.COM {
38987836SJohn.Forte@Sun.COM 	int ret;
38997836SJohn.Forte@Sun.COM 	int fd;
39007836SJohn.Forte@Sun.COM 	int ioctlRet;
39017836SJohn.Forte@Sun.COM 	int i;
39027836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
39037836SJohn.Forte@Sun.COM 	/* framework target port list */
39049585STim.Szeto@Sun.COM 	slist_target_port_t *fTargetList, *fTargetListP = NULL;
39057836SJohn.Forte@Sun.COM 	uint32_t fTargetListSize;
39067836SJohn.Forte@Sun.COM 
39077836SJohn.Forte@Sun.COM 	if (targetList == NULL) {
39087836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
39097836SJohn.Forte@Sun.COM 	}
39107836SJohn.Forte@Sun.COM 
39117836SJohn.Forte@Sun.COM 	/* call init */
39127836SJohn.Forte@Sun.COM 	ret = initializeConfig();
39137836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
39147836SJohn.Forte@Sun.COM 		return (ret);
39157836SJohn.Forte@Sun.COM 	}
39167836SJohn.Forte@Sun.COM 
39177836SJohn.Forte@Sun.COM 	/*
39187836SJohn.Forte@Sun.COM 	 * Open control node for stmf
39197836SJohn.Forte@Sun.COM 	 */
39207836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
39217836SJohn.Forte@Sun.COM 		return (ret);
39227836SJohn.Forte@Sun.COM 
39237836SJohn.Forte@Sun.COM 	/*
39247836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
39257836SJohn.Forte@Sun.COM 	 */
39269585STim.Szeto@Sun.COM 	fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
39278252SJohn.Forte@Sun.COM 	fTargetListP = fTargetList =
39288252SJohn.Forte@Sun.COM 	    (slist_target_port_t *)calloc(1, fTargetListSize);
39297836SJohn.Forte@Sun.COM 	if (fTargetList == NULL) {
39309585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
39317836SJohn.Forte@Sun.COM 		goto done;
39327836SJohn.Forte@Sun.COM 	}
39337836SJohn.Forte@Sun.COM 
39347836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
39357836SJohn.Forte@Sun.COM 	/*
39368252SJohn.Forte@Sun.COM 	 * Issue ioctl to retrieve target list
39377836SJohn.Forte@Sun.COM 	 */
39387836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
39397836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fTargetListSize;
39407836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
39417836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
39427836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
39437836SJohn.Forte@Sun.COM 		switch (errno) {
39447836SJohn.Forte@Sun.COM 			case EBUSY:
39457836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
39467836SJohn.Forte@Sun.COM 				break;
39479585STim.Szeto@Sun.COM 			case EPERM:
39487836SJohn.Forte@Sun.COM 			case EACCES:
39497836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
39507836SJohn.Forte@Sun.COM 				break;
39517836SJohn.Forte@Sun.COM 			default:
39527836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
39537836SJohn.Forte@Sun.COM 				    "stmfGetTargetList:ioctl errno(%d)", errno);
39547836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
39557836SJohn.Forte@Sun.COM 				break;
39567836SJohn.Forte@Sun.COM 		}
39577836SJohn.Forte@Sun.COM 		goto done;
39587836SJohn.Forte@Sun.COM 	}
39597836SJohn.Forte@Sun.COM 	/*
39607836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
39617836SJohn.Forte@Sun.COM 	 */
39629585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
39637836SJohn.Forte@Sun.COM 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
39648116SJohn.Forte@Sun.COM 		    sizeof (slist_target_port_t);
39658252SJohn.Forte@Sun.COM 		fTargetListP = fTargetList =
39668252SJohn.Forte@Sun.COM 		    realloc(fTargetList, fTargetListSize);
39677836SJohn.Forte@Sun.COM 		if (fTargetList == NULL) {
39689585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
39699585STim.Szeto@Sun.COM 			goto done;
39707836SJohn.Forte@Sun.COM 		}
39717836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fTargetListSize;
39727836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
39737836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
39747836SJohn.Forte@Sun.COM 		    &stmfIoctl);
39757836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
39767836SJohn.Forte@Sun.COM 			switch (errno) {
39777836SJohn.Forte@Sun.COM 				case EBUSY:
39787836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
39797836SJohn.Forte@Sun.COM 					break;
39809585STim.Szeto@Sun.COM 				case EPERM:
39817836SJohn.Forte@Sun.COM 				case EACCES:
39827836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
39837836SJohn.Forte@Sun.COM 					break;
39847836SJohn.Forte@Sun.COM 				default:
39857836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
39867836SJohn.Forte@Sun.COM 					    "stmfGetTargetList:ioctl errno(%d)",
39877836SJohn.Forte@Sun.COM 					    errno);
39887836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
39897836SJohn.Forte@Sun.COM 					break;
39907836SJohn.Forte@Sun.COM 			}
39917836SJohn.Forte@Sun.COM 			goto done;
39927836SJohn.Forte@Sun.COM 		}
39937836SJohn.Forte@Sun.COM 	}
39947836SJohn.Forte@Sun.COM 
39957836SJohn.Forte@Sun.COM 	*targetList = (stmfDevidList *)calloc(1,
39967836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
39977836SJohn.Forte@Sun.COM 	    sizeof (stmfDevidList));
39989585STim.Szeto@Sun.COM 	if (*targetList == NULL) {
39999585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
40009585STim.Szeto@Sun.COM 		goto done;
40019585STim.Szeto@Sun.COM 	}
40027836SJohn.Forte@Sun.COM 
40037836SJohn.Forte@Sun.COM 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
40047836SJohn.Forte@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
40057836SJohn.Forte@Sun.COM 		(*targetList)->devid[i].identLength =
40067836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE];
40077836SJohn.Forte@Sun.COM 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
40087836SJohn.Forte@Sun.COM 		    &(*targetList)->devid[i].ident,
40097836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE]);
40107836SJohn.Forte@Sun.COM 	}
40117836SJohn.Forte@Sun.COM 
40127836SJohn.Forte@Sun.COM done:
40137836SJohn.Forte@Sun.COM 	(void) close(fd);
40148252SJohn.Forte@Sun.COM 	free(fTargetListP);
40157836SJohn.Forte@Sun.COM 	return (ret);
40167836SJohn.Forte@Sun.COM }
40177836SJohn.Forte@Sun.COM 
40187836SJohn.Forte@Sun.COM /*
40197836SJohn.Forte@Sun.COM  * stmfGetTargetProperties
40207836SJohn.Forte@Sun.COM  *
40217836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
40227836SJohn.Forte@Sun.COM  *
40237836SJohn.Forte@Sun.COM  * devid - devid of the target for which to retrieve properties
40247836SJohn.Forte@Sun.COM  * targetProps - pointer to an stmfTargetProperties structure.
40257836SJohn.Forte@Sun.COM  *		On success, it contains the target properties for
40267836SJohn.Forte@Sun.COM  *		the specified devid.
40277836SJohn.Forte@Sun.COM  */
40287836SJohn.Forte@Sun.COM int
40297836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
40307836SJohn.Forte@Sun.COM {
40317836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
40327836SJohn.Forte@Sun.COM 	int fd;
40337836SJohn.Forte@Sun.COM 	int ioctlRet;
40347836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
40357836SJohn.Forte@Sun.COM 	sioc_target_port_props_t targetProperties;
4036*10725SJohn.Forte@Sun.COM 	scsi_devid_desc_t *scsiDevid;
40377836SJohn.Forte@Sun.COM 
40387836SJohn.Forte@Sun.COM 	if (devid == NULL || targetProps == NULL) {
40397836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
40407836SJohn.Forte@Sun.COM 	}
40417836SJohn.Forte@Sun.COM 
40427836SJohn.Forte@Sun.COM 	/* call init */
40437836SJohn.Forte@Sun.COM 	ret = initializeConfig();
40447836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
40457836SJohn.Forte@Sun.COM 		return (ret);
40467836SJohn.Forte@Sun.COM 	}
40477836SJohn.Forte@Sun.COM 
40487836SJohn.Forte@Sun.COM 	/*
40497836SJohn.Forte@Sun.COM 	 * Open control node for stmf
40507836SJohn.Forte@Sun.COM 	 */
40517836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
40527836SJohn.Forte@Sun.COM 		return (ret);
40537836SJohn.Forte@Sun.COM 
40547836SJohn.Forte@Sun.COM 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
40557836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
40567836SJohn.Forte@Sun.COM 	    devid->identLength);
40577836SJohn.Forte@Sun.COM 
40587836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
40597836SJohn.Forte@Sun.COM 	/*
40607836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
40617836SJohn.Forte@Sun.COM 	 */
40627836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
40637836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
40647836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
40657836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
40667836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
40677836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
40687836SJohn.Forte@Sun.COM 	    &stmfIoctl);
40697836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
40707836SJohn.Forte@Sun.COM 		switch (errno) {
40717836SJohn.Forte@Sun.COM 			case EBUSY:
40727836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
40737836SJohn.Forte@Sun.COM 				break;
40749585STim.Szeto@Sun.COM 			case EPERM:
40757836SJohn.Forte@Sun.COM 			case EACCES:
40767836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
40777836SJohn.Forte@Sun.COM 				break;
40787836SJohn.Forte@Sun.COM 			case ENOENT:
40797836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
40807836SJohn.Forte@Sun.COM 				break;
40817836SJohn.Forte@Sun.COM 			default:
40827836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
40837836SJohn.Forte@Sun.COM 				    "stmfGetTargetProperties:ioctl errno(%d)",
40847836SJohn.Forte@Sun.COM 				    errno);
40857836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
40867836SJohn.Forte@Sun.COM 				break;
40877836SJohn.Forte@Sun.COM 		}
40887836SJohn.Forte@Sun.COM 		goto done;
40897836SJohn.Forte@Sun.COM 	}
40907836SJohn.Forte@Sun.COM 
40917836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
40927836SJohn.Forte@Sun.COM 	    sizeof (targetProperties.tgt_provider_name));
40937836SJohn.Forte@Sun.COM 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
40947836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINE;
40957836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
40967836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
40977836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
40987836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINING;
40997836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
41007836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
41017836SJohn.Forte@Sun.COM 	}
41027836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_alias, targetProps->alias,
41037836SJohn.Forte@Sun.COM 	    sizeof (targetProps->alias));
4104*10725SJohn.Forte@Sun.COM 
4105*10725SJohn.Forte@Sun.COM 	scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id;
4106*10725SJohn.Forte@Sun.COM 	targetProps->protocol = scsiDevid->protocol_id;
4107*10725SJohn.Forte@Sun.COM 
41087836SJohn.Forte@Sun.COM done:
41097836SJohn.Forte@Sun.COM 	(void) close(fd);
41107836SJohn.Forte@Sun.COM 	return (ret);
41117836SJohn.Forte@Sun.COM }
41127836SJohn.Forte@Sun.COM 
41137836SJohn.Forte@Sun.COM /*
41147836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitList
41157836SJohn.Forte@Sun.COM  *
41167836SJohn.Forte@Sun.COM  * Purpose: Retrieves list of logical unit Object IDs
41177836SJohn.Forte@Sun.COM  *
41187836SJohn.Forte@Sun.COM  * luList - pointer to a pointer to a stmfGuidList structure. On success,
41197836SJohn.Forte@Sun.COM  *          it contains the list of logical unit guids.
41207836SJohn.Forte@Sun.COM  *
41217836SJohn.Forte@Sun.COM  */
41227836SJohn.Forte@Sun.COM int
41237836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList)
41247836SJohn.Forte@Sun.COM {
41257836SJohn.Forte@Sun.COM 	int ret;
41267836SJohn.Forte@Sun.COM 	int fd;
41277836SJohn.Forte@Sun.COM 	int ioctlRet;
41287836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_LU_LIST;
41299585STim.Szeto@Sun.COM 	int i;
41307836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
41317836SJohn.Forte@Sun.COM 	slist_lu_t *fLuList;
41327836SJohn.Forte@Sun.COM 	uint32_t fLuListSize;
41339585STim.Szeto@Sun.COM 	uint32_t listCnt;
41347836SJohn.Forte@Sun.COM 
41357836SJohn.Forte@Sun.COM 	if (luList == NULL) {
41367836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
41377836SJohn.Forte@Sun.COM 	}
41387836SJohn.Forte@Sun.COM 
41397836SJohn.Forte@Sun.COM 	/* call init */
41407836SJohn.Forte@Sun.COM 	ret = initializeConfig();
41417836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
41427836SJohn.Forte@Sun.COM 		return (ret);
41437836SJohn.Forte@Sun.COM 	}
41447836SJohn.Forte@Sun.COM 
41457836SJohn.Forte@Sun.COM 	/*
41467836SJohn.Forte@Sun.COM 	 * Open control node for stmf
41477836SJohn.Forte@Sun.COM 	 */
41487836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
41497836SJohn.Forte@Sun.COM 		return (ret);
41507836SJohn.Forte@Sun.COM 
41517836SJohn.Forte@Sun.COM 	/*
41527836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
41537836SJohn.Forte@Sun.COM 	 */
41549585STim.Szeto@Sun.COM 	fLuListSize = ALLOC_LU;
41557836SJohn.Forte@Sun.COM 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
41567836SJohn.Forte@Sun.COM 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
41577836SJohn.Forte@Sun.COM 	if (fLuList == NULL) {
41589585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
41599585STim.Szeto@Sun.COM 		goto done;
41607836SJohn.Forte@Sun.COM 	}
41617836SJohn.Forte@Sun.COM 
41627836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
41637836SJohn.Forte@Sun.COM 	/*
41647836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the LU list
41657836SJohn.Forte@Sun.COM 	 */
41667836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
41677836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fLuListSize;
41687836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
41697836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
41707836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
41717836SJohn.Forte@Sun.COM 		switch (errno) {
41727836SJohn.Forte@Sun.COM 			case EBUSY:
41737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
41747836SJohn.Forte@Sun.COM 				break;
41759585STim.Szeto@Sun.COM 			case EPERM:
41767836SJohn.Forte@Sun.COM 			case EACCES:
41777836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
41787836SJohn.Forte@Sun.COM 				break;
41797836SJohn.Forte@Sun.COM 			default:
41807836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
41817836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
41827836SJohn.Forte@Sun.COM 				    errno);
41837836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
41847836SJohn.Forte@Sun.COM 				break;
41857836SJohn.Forte@Sun.COM 		}
41867836SJohn.Forte@Sun.COM 		goto done;
41877836SJohn.Forte@Sun.COM 	}
41887836SJohn.Forte@Sun.COM 	/*
41897836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
41907836SJohn.Forte@Sun.COM 	 */
41919585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
41927836SJohn.Forte@Sun.COM 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
41937836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
41949585STim.Szeto@Sun.COM 		free(fLuList);
41959585STim.Szeto@Sun.COM 		fLuList = (slist_lu_t *)calloc(1, fLuListSize);
41967836SJohn.Forte@Sun.COM 		if (fLuList == NULL) {
41979585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
41989585STim.Szeto@Sun.COM 			goto done;
41997836SJohn.Forte@Sun.COM 		}
42007836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fLuListSize;
42017836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
42027836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
42037836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
42047836SJohn.Forte@Sun.COM 			switch (errno) {
42057836SJohn.Forte@Sun.COM 				case EBUSY:
42067836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
42077836SJohn.Forte@Sun.COM 					break;
42089585STim.Szeto@Sun.COM 				case EPERM:
42097836SJohn.Forte@Sun.COM 				case EACCES:
42107836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
42117836SJohn.Forte@Sun.COM 					break;
42127836SJohn.Forte@Sun.COM 				default:
42137836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
42147836SJohn.Forte@Sun.COM 					    "stmfGetLogicalUnitList:"
42157836SJohn.Forte@Sun.COM 					    "ioctl errno(%d)", errno);
42167836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
42177836SJohn.Forte@Sun.COM 					break;
42187836SJohn.Forte@Sun.COM 			}
42197836SJohn.Forte@Sun.COM 			goto done;
42207836SJohn.Forte@Sun.COM 		}
42217836SJohn.Forte@Sun.COM 	}
42227836SJohn.Forte@Sun.COM 
42237836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
42247836SJohn.Forte@Sun.COM 		goto done;
42257836SJohn.Forte@Sun.COM 	}
42267836SJohn.Forte@Sun.COM 
42279585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
42287836SJohn.Forte@Sun.COM 
42297836SJohn.Forte@Sun.COM 	/*
42307836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
42317836SJohn.Forte@Sun.COM 	 */
42327836SJohn.Forte@Sun.COM 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
42339585STim.Szeto@Sun.COM 	    listCnt * sizeof (stmfGuid));
42347836SJohn.Forte@Sun.COM 	if (*luList == NULL) {
42357836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
42367836SJohn.Forte@Sun.COM 		goto done;
42377836SJohn.Forte@Sun.COM 	}
42387836SJohn.Forte@Sun.COM 
42399585STim.Szeto@Sun.COM 	(*luList)->cnt = listCnt;
42409585STim.Szeto@Sun.COM 
42419585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
42429585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
42439585STim.Szeto@Sun.COM 		bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
42449585STim.Szeto@Sun.COM 		    sizeof (stmfGuid));
42459585STim.Szeto@Sun.COM 	}
42469585STim.Szeto@Sun.COM 
42477836SJohn.Forte@Sun.COM 	/*
42489585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
42497836SJohn.Forte@Sun.COM 	 */
42509585STim.Szeto@Sun.COM 	qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
42519585STim.Szeto@Sun.COM 	    sizeof (stmfGuid), guidCompare);
42527836SJohn.Forte@Sun.COM 
42537836SJohn.Forte@Sun.COM done:
42547836SJohn.Forte@Sun.COM 	(void) close(fd);
42557836SJohn.Forte@Sun.COM 	/*
42567836SJohn.Forte@Sun.COM 	 * free internal buffers
42577836SJohn.Forte@Sun.COM 	 */
42587836SJohn.Forte@Sun.COM 	free(fLuList);
42597836SJohn.Forte@Sun.COM 	return (ret);
42607836SJohn.Forte@Sun.COM }
42617836SJohn.Forte@Sun.COM 
42627836SJohn.Forte@Sun.COM /*
42637836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitProperties
42647836SJohn.Forte@Sun.COM  *
42657836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
42667836SJohn.Forte@Sun.COM  *
42677836SJohn.Forte@Sun.COM  * lu - guid of the logical unit for which to retrieve properties
42687836SJohn.Forte@Sun.COM  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
42697836SJohn.Forte@Sun.COM  *               it contains the logical unit properties for the specified guid.
42707836SJohn.Forte@Sun.COM  */
42717836SJohn.Forte@Sun.COM int
42727836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
42737836SJohn.Forte@Sun.COM {
42747836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
42757836SJohn.Forte@Sun.COM 	int stmfRet;
42767836SJohn.Forte@Sun.COM 	int fd;
42777836SJohn.Forte@Sun.COM 	int ioctlRet;
42787836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
42797836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
42807836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
42817836SJohn.Forte@Sun.COM 	sioc_lu_props_t fLuProps;
42827836SJohn.Forte@Sun.COM 
42839585STim.Szeto@Sun.COM 	if (lu == NULL || luProps == NULL) {
42849585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
42857836SJohn.Forte@Sun.COM 	}
42867836SJohn.Forte@Sun.COM 
42877836SJohn.Forte@Sun.COM 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
42887836SJohn.Forte@Sun.COM 
42897836SJohn.Forte@Sun.COM 	/* call init */
42907836SJohn.Forte@Sun.COM 	ret = initializeConfig();
42917836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
42927836SJohn.Forte@Sun.COM 		return (ret);
42937836SJohn.Forte@Sun.COM 	}
42947836SJohn.Forte@Sun.COM 
42957836SJohn.Forte@Sun.COM 	/*
42967836SJohn.Forte@Sun.COM 	 * Open control node for stmf
42977836SJohn.Forte@Sun.COM 	 */
42987836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
42997836SJohn.Forte@Sun.COM 		return (ret);
43007836SJohn.Forte@Sun.COM 
43017836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
43027836SJohn.Forte@Sun.COM 	/*
43037836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
43047836SJohn.Forte@Sun.COM 	 */
43057836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
43067836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
43077836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
43087836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
43097836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
43107836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
43117836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
43127836SJohn.Forte@Sun.COM 		switch (errno) {
43137836SJohn.Forte@Sun.COM 			case EBUSY:
43147836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
43157836SJohn.Forte@Sun.COM 				break;
43169585STim.Szeto@Sun.COM 			case EPERM:
43177836SJohn.Forte@Sun.COM 			case EACCES:
43187836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
43197836SJohn.Forte@Sun.COM 				break;
43207836SJohn.Forte@Sun.COM 			case ENOENT:
43217836SJohn.Forte@Sun.COM 				stmfRet = stmfGetViewEntryList(lu,
43227836SJohn.Forte@Sun.COM 				    &viewEntryList);
43237836SJohn.Forte@Sun.COM 				if (stmfRet == STMF_STATUS_SUCCESS) {
43247836SJohn.Forte@Sun.COM 					luProps->status =
43257836SJohn.Forte@Sun.COM 					    STMF_LOGICAL_UNIT_UNREGISTERED;
43267836SJohn.Forte@Sun.COM 					if (viewEntryList->cnt > 0) {
43277836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_SUCCESS;
43287836SJohn.Forte@Sun.COM 					} else {
43297836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
43307836SJohn.Forte@Sun.COM 					}
43317836SJohn.Forte@Sun.COM 				} else {
43327836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
43337836SJohn.Forte@Sun.COM 				}
43347836SJohn.Forte@Sun.COM 				stmfFreeMemory(viewEntryList);
43357836SJohn.Forte@Sun.COM 				break;
43367836SJohn.Forte@Sun.COM 			default:
43377836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
43387836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnit:ioctl errno(%d)",
43397836SJohn.Forte@Sun.COM 				    errno);
43407836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
43417836SJohn.Forte@Sun.COM 				break;
43427836SJohn.Forte@Sun.COM 		}
43437836SJohn.Forte@Sun.COM 		goto done;
43447836SJohn.Forte@Sun.COM 	}
43457836SJohn.Forte@Sun.COM 
43467836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
43477836SJohn.Forte@Sun.COM 	    sizeof (fLuProps.lu_provider_name));
43487836SJohn.Forte@Sun.COM 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
43497836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
43507836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
43517836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
43527836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
43537836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
43547836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
43557836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
43567836SJohn.Forte@Sun.COM 	}
43577836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
43587836SJohn.Forte@Sun.COM done:
43597836SJohn.Forte@Sun.COM 	(void) close(fd);
43607836SJohn.Forte@Sun.COM 	return (ret);
43617836SJohn.Forte@Sun.COM }
43627836SJohn.Forte@Sun.COM 
43637836SJohn.Forte@Sun.COM /*
43647836SJohn.Forte@Sun.COM  * stmfGetState
43657836SJohn.Forte@Sun.COM  *
43667836SJohn.Forte@Sun.COM  * Purpose: retrieve the current state of the stmf module
43677836SJohn.Forte@Sun.COM  *
43687836SJohn.Forte@Sun.COM  * state - pointer to stmfState structure allocated by the caller
43697836SJohn.Forte@Sun.COM  *         On success, contains the state of stmf
43707836SJohn.Forte@Sun.COM  */
43717836SJohn.Forte@Sun.COM int
43727836SJohn.Forte@Sun.COM stmfGetState(stmfState *state)
43737836SJohn.Forte@Sun.COM {
43747836SJohn.Forte@Sun.COM 	int ret;
43757836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
43767836SJohn.Forte@Sun.COM 
43777836SJohn.Forte@Sun.COM 	if (state == NULL) {
43787836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
43797836SJohn.Forte@Sun.COM 	}
43807836SJohn.Forte@Sun.COM 
43817836SJohn.Forte@Sun.COM 	ret = getStmfState(&iState);
43827836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
43837836SJohn.Forte@Sun.COM 		return (ret);
43847836SJohn.Forte@Sun.COM 	}
43857836SJohn.Forte@Sun.COM 	switch (iState.state) {
43867836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINE:
43877836SJohn.Forte@Sun.COM 			state->operationalState =
43887836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINE;
43897836SJohn.Forte@Sun.COM 			break;
43907836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINE:
43917836SJohn.Forte@Sun.COM 			state->operationalState =
43927836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINE;
43937836SJohn.Forte@Sun.COM 			break;
43947836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINING:
43957836SJohn.Forte@Sun.COM 			state->operationalState =
43967836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINING;
43977836SJohn.Forte@Sun.COM 			break;
43987836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINING:
43997836SJohn.Forte@Sun.COM 			state->operationalState =
44007836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINING;
44017836SJohn.Forte@Sun.COM 			break;
44027836SJohn.Forte@Sun.COM 		default:
44037836SJohn.Forte@Sun.COM 			state->operationalState =
44047836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_UNKNOWN;
44057836SJohn.Forte@Sun.COM 			break;
44067836SJohn.Forte@Sun.COM 	}
44077836SJohn.Forte@Sun.COM 	switch (iState.config_state) {
44087836SJohn.Forte@Sun.COM 		case STMF_CONFIG_NONE:
44097836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_NONE;
44107836SJohn.Forte@Sun.COM 			break;
44117836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT:
44127836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_INIT;
44137836SJohn.Forte@Sun.COM 			break;
44147836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT_DONE:
44157836SJohn.Forte@Sun.COM 			state->configState =
44167836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_INIT_DONE;
44177836SJohn.Forte@Sun.COM 			break;
44187836SJohn.Forte@Sun.COM 		default:
44197836SJohn.Forte@Sun.COM 			state->configState =
44207836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_UNKNOWN;
44217836SJohn.Forte@Sun.COM 			break;
44227836SJohn.Forte@Sun.COM 	}
44237836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
44247836SJohn.Forte@Sun.COM }
44257836SJohn.Forte@Sun.COM 
44267836SJohn.Forte@Sun.COM /*
44277836SJohn.Forte@Sun.COM  * stmfGetViewEntryList
44287836SJohn.Forte@Sun.COM  *
44297836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of view entries for the specified
44307836SJohn.Forte@Sun.COM  *          logical unit.
44317836SJohn.Forte@Sun.COM  *
44327836SJohn.Forte@Sun.COM  * lu - the guid of the logical unit for which to retrieve the view entry list
44337836SJohn.Forte@Sun.COM  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
44347836SJohn.Forte@Sun.COM  *                 success, contains the list of view entries.
44357836SJohn.Forte@Sun.COM  */
44367836SJohn.Forte@Sun.COM int
44377836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
44387836SJohn.Forte@Sun.COM {
44397836SJohn.Forte@Sun.COM 	int ret;
44409585STim.Szeto@Sun.COM 	int fd;
44419585STim.Szeto@Sun.COM 	int ioctlRet;
44429585STim.Szeto@Sun.COM 	int cmd = STMF_IOCTL_LU_VE_LIST;
44439585STim.Szeto@Sun.COM 	int i;
44449585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
44459585STim.Szeto@Sun.COM 	stmf_view_op_entry_t *fVeList;
44469585STim.Szeto@Sun.COM 	uint32_t fVeListSize;
44479585STim.Szeto@Sun.COM 	uint32_t listCnt;
44487836SJohn.Forte@Sun.COM 
44497836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntryList == NULL) {
44507836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
44517836SJohn.Forte@Sun.COM 	}
44527836SJohn.Forte@Sun.COM 
44539585STim.Szeto@Sun.COM 	/* call init */
44549585STim.Szeto@Sun.COM 	ret = initializeConfig();
44559585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
44569585STim.Szeto@Sun.COM 		return (ret);
44579585STim.Szeto@Sun.COM 	}
44589585STim.Szeto@Sun.COM 
44599585STim.Szeto@Sun.COM 	/*
44609585STim.Szeto@Sun.COM 	 * Open control node for stmf
44619585STim.Szeto@Sun.COM 	 */
44629585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
44639585STim.Szeto@Sun.COM 		return (ret);
44649585STim.Szeto@Sun.COM 
44659585STim.Szeto@Sun.COM 	/*
44669585STim.Szeto@Sun.COM 	 * Allocate ioctl input buffer
44679585STim.Szeto@Sun.COM 	 */
44689585STim.Szeto@Sun.COM 	fVeListSize = ALLOC_VE;
44699585STim.Szeto@Sun.COM 	fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
44709585STim.Szeto@Sun.COM 	fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
44719585STim.Szeto@Sun.COM 	if (fVeList == NULL) {
44729585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
44739585STim.Szeto@Sun.COM 		goto done;
44749585STim.Szeto@Sun.COM 	}
44759585STim.Szeto@Sun.COM 
44769585STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
44779585STim.Szeto@Sun.COM 	/*
44789585STim.Szeto@Sun.COM 	 * Issue ioctl to get the LU list
44799585STim.Szeto@Sun.COM 	 */
44809585STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
44819585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
44829585STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
44839585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = fVeListSize;
44849585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
44859585STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
44869585STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
44879585STim.Szeto@Sun.COM 		switch (errno) {
44889585STim.Szeto@Sun.COM 			case EBUSY:
44899585STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
44909585STim.Szeto@Sun.COM 				break;
44919585STim.Szeto@Sun.COM 			case EPERM:
44929585STim.Szeto@Sun.COM 			case EACCES:
44939585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
44949585STim.Szeto@Sun.COM 				break;
44959585STim.Szeto@Sun.COM 			default:
44969585STim.Szeto@Sun.COM 				syslog(LOG_DEBUG,
44979585STim.Szeto@Sun.COM 				    "stmfGetViewEntryList:ioctl errno(%d)",
44989585STim.Szeto@Sun.COM 				    errno);
44999585STim.Szeto@Sun.COM 				ret = STMF_STATUS_ERROR;
45009585STim.Szeto@Sun.COM 				break;
45019585STim.Szeto@Sun.COM 		}
45029585STim.Szeto@Sun.COM 		goto done;
45039585STim.Szeto@Sun.COM 	}
45049585STim.Szeto@Sun.COM 	/*
45059585STim.Szeto@Sun.COM 	 * Check whether input buffer was large enough
45069585STim.Szeto@Sun.COM 	 */
45079585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
45089585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
45099585STim.Szeto@Sun.COM 		fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
45109585STim.Szeto@Sun.COM 		    sizeof (stmf_view_op_entry_t);
45119585STim.Szeto@Sun.COM 		free(fVeList);
45129585STim.Szeto@Sun.COM 		fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
45139585STim.Szeto@Sun.COM 		if (fVeList == NULL) {
45149585STim.Szeto@Sun.COM 			return (STMF_ERROR_NOMEM);
45159585STim.Szeto@Sun.COM 		}
45169585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = fVeListSize;
45179585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
45189585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
45199585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
45209585STim.Szeto@Sun.COM 			switch (errno) {
45219585STim.Szeto@Sun.COM 				case EBUSY:
45229585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
45239585STim.Szeto@Sun.COM 					break;
45249585STim.Szeto@Sun.COM 				case EPERM:
45259585STim.Szeto@Sun.COM 				case EACCES:
45269585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
45279585STim.Szeto@Sun.COM 					break;
45289585STim.Szeto@Sun.COM 				default:
45299585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
45309585STim.Szeto@Sun.COM 					    "stmfGetLogicalUnitList:"
45319585STim.Szeto@Sun.COM 					    "ioctl errno(%d)", errno);
45329585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
45339585STim.Szeto@Sun.COM 					break;
45349585STim.Szeto@Sun.COM 			}
45359585STim.Szeto@Sun.COM 			goto done;
45369585STim.Szeto@Sun.COM 		}
45379585STim.Szeto@Sun.COM 	}
45389585STim.Szeto@Sun.COM 
45399585STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
45409585STim.Szeto@Sun.COM 		goto done;
45419585STim.Szeto@Sun.COM 	}
45429585STim.Szeto@Sun.COM 
45439585STim.Szeto@Sun.COM 	if (stmfIoctl.stmf_obuf_nentries == 0) {
45449585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOT_FOUND;
45459585STim.Szeto@Sun.COM 		goto done;
45469585STim.Szeto@Sun.COM 	}
45479585STim.Szeto@Sun.COM 
45489585STim.Szeto@Sun.COM 	listCnt = stmfIoctl.stmf_obuf_nentries;
45499585STim.Szeto@Sun.COM 
45509585STim.Szeto@Sun.COM 	/*
45519585STim.Szeto@Sun.COM 	 * allocate caller's buffer with the final size
45529585STim.Szeto@Sun.COM 	 */
45539585STim.Szeto@Sun.COM 	*viewEntryList = (stmfViewEntryList *)calloc(1,
45549585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
45559585STim.Szeto@Sun.COM 	if (*viewEntryList == NULL) {
45569585STim.Szeto@Sun.COM 		ret = STMF_ERROR_NOMEM;
45579585STim.Szeto@Sun.COM 		goto done;
45589585STim.Szeto@Sun.COM 	}
45599585STim.Szeto@Sun.COM 
45609585STim.Szeto@Sun.COM 	(*viewEntryList)->cnt = listCnt;
45619585STim.Szeto@Sun.COM 
45629585STim.Szeto@Sun.COM 	/* copy to caller's buffer */
45639585STim.Szeto@Sun.COM 	for (i = 0; i < listCnt; i++) {
45649585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndexValid = B_TRUE;
45659585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
45669585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_hosts == 1) {
45679585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allHosts = B_TRUE;
45689585STim.Szeto@Sun.COM 		} else {
45699585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_host_group.name,
45709585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].hostGroup,
45719585STim.Szeto@Sun.COM 			    fVeList[i].ve_host_group.name_size);
45729585STim.Szeto@Sun.COM 		}
45739585STim.Szeto@Sun.COM 		if (fVeList[i].ve_all_targets == 1) {
45749585STim.Szeto@Sun.COM 			(*viewEntryList)->ve[i].allTargets = B_TRUE;
45759585STim.Szeto@Sun.COM 		} else {
45769585STim.Szeto@Sun.COM 			bcopy(fVeList[i].ve_target_group.name,
45779585STim.Szeto@Sun.COM 			    (*viewEntryList)->ve[i].targetGroup,
45789585STim.Szeto@Sun.COM 			    fVeList[i].ve_target_group.name_size);
45799585STim.Szeto@Sun.COM 		}
45809585STim.Szeto@Sun.COM 		bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
45819585STim.Szeto@Sun.COM 		    sizeof ((*viewEntryList)->ve[i].luNbr));
45829585STim.Szeto@Sun.COM 		(*viewEntryList)->ve[i].luNbrValid = B_TRUE;
45839585STim.Szeto@Sun.COM 	}
45849585STim.Szeto@Sun.COM 
45859585STim.Szeto@Sun.COM 	/*
45869585STim.Szeto@Sun.COM 	 * sort the list. This gives a consistent view across gets
45879585STim.Szeto@Sun.COM 	 */
45889585STim.Szeto@Sun.COM 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
45899585STim.Szeto@Sun.COM 	    sizeof (stmfViewEntry), viewEntryCompare);
45909585STim.Szeto@Sun.COM 
45919585STim.Szeto@Sun.COM done:
45929585STim.Szeto@Sun.COM 	(void) close(fd);
45939585STim.Szeto@Sun.COM 	/*
45949585STim.Szeto@Sun.COM 	 * free internal buffers
45959585STim.Szeto@Sun.COM 	 */
45969585STim.Szeto@Sun.COM 	free(fVeList);
45977836SJohn.Forte@Sun.COM 	return (ret);
45987836SJohn.Forte@Sun.COM }
45997836SJohn.Forte@Sun.COM 
46009585STim.Szeto@Sun.COM 
46017836SJohn.Forte@Sun.COM /*
46027836SJohn.Forte@Sun.COM  * loadHostGroups
46037836SJohn.Forte@Sun.COM  *
46047836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the host groups into stmf
46057836SJohn.Forte@Sun.COM  *
46067836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
46077836SJohn.Forte@Sun.COM  * groupList - populated host group list
46087836SJohn.Forte@Sun.COM  */
46097836SJohn.Forte@Sun.COM static int
46107836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList)
46117836SJohn.Forte@Sun.COM {
46127836SJohn.Forte@Sun.COM 	int i, j;
46137836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
46147836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
46157836SJohn.Forte@Sun.COM 
46167836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
46177836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
46187836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
46197836SJohn.Forte@Sun.COM 			goto out;
46207836SJohn.Forte@Sun.COM 		}
46219585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
46229585STim.Szeto@Sun.COM 		    &groupProps, HOST_GROUP);
46237836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
46247836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
46257836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
46267836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
46277836SJohn.Forte@Sun.COM 				goto out;
46287836SJohn.Forte@Sun.COM 			}
46297836SJohn.Forte@Sun.COM 		}
46307836SJohn.Forte@Sun.COM 	}
46317836SJohn.Forte@Sun.COM 
46327836SJohn.Forte@Sun.COM 
46337836SJohn.Forte@Sun.COM out:
46347836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
46357836SJohn.Forte@Sun.COM 	return (ret);
46367836SJohn.Forte@Sun.COM }
46377836SJohn.Forte@Sun.COM 
46387836SJohn.Forte@Sun.COM /*
46397836SJohn.Forte@Sun.COM  * loadTargetGroups
46407836SJohn.Forte@Sun.COM  *
46417836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the target groups into stmf
46427836SJohn.Forte@Sun.COM  *
46437836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
46447836SJohn.Forte@Sun.COM  * groupList - populated target group list.
46457836SJohn.Forte@Sun.COM  */
46467836SJohn.Forte@Sun.COM static int
46477836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList)
46487836SJohn.Forte@Sun.COM {
46497836SJohn.Forte@Sun.COM 	int i, j;
46507836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
46517836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
46527836SJohn.Forte@Sun.COM 
46537836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
46547836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
46557836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
46567836SJohn.Forte@Sun.COM 			goto out;
46577836SJohn.Forte@Sun.COM 		}
46589585STim.Szeto@Sun.COM 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
46599585STim.Szeto@Sun.COM 		    &groupProps, TARGET_GROUP);
46607836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
46617836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
46627836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
46637836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
46647836SJohn.Forte@Sun.COM 				goto out;
46657836SJohn.Forte@Sun.COM 			}
46667836SJohn.Forte@Sun.COM 		}
46677836SJohn.Forte@Sun.COM 	}
46687836SJohn.Forte@Sun.COM 
46697836SJohn.Forte@Sun.COM 
46707836SJohn.Forte@Sun.COM out:
46717836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
46727836SJohn.Forte@Sun.COM 	return (ret);
46737836SJohn.Forte@Sun.COM }
46747836SJohn.Forte@Sun.COM 
46757836SJohn.Forte@Sun.COM 
46767836SJohn.Forte@Sun.COM /*
46777836SJohn.Forte@Sun.COM  * loadStore
46787836SJohn.Forte@Sun.COM  *
46797836SJohn.Forte@Sun.COM  * Purpose: Load the configuration data from the store
46807836SJohn.Forte@Sun.COM  *
46817836SJohn.Forte@Sun.COM  * First load the host groups and target groups, then the view entries
46827836SJohn.Forte@Sun.COM  * and finally the provider data
46837836SJohn.Forte@Sun.COM  *
46847836SJohn.Forte@Sun.COM  * fd - file descriptor of control node for stmf.
46857836SJohn.Forte@Sun.COM  */
46867836SJohn.Forte@Sun.COM static int
46877836SJohn.Forte@Sun.COM loadStore(int fd)
46887836SJohn.Forte@Sun.COM {
46897836SJohn.Forte@Sun.COM 	int ret;
46907836SJohn.Forte@Sun.COM 	int i, j;
46917836SJohn.Forte@Sun.COM 	stmfGroupList *groupList = NULL;
46927836SJohn.Forte@Sun.COM 	stmfGuidList *guidList = NULL;
46937836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
46947836SJohn.Forte@Sun.COM 	stmfProviderList *providerList = NULL;
46957836SJohn.Forte@Sun.COM 	int providerType;
46967836SJohn.Forte@Sun.COM 	nvlist_t *nvl = NULL;
46977836SJohn.Forte@Sun.COM 
46987836SJohn.Forte@Sun.COM 
46997836SJohn.Forte@Sun.COM 
47007836SJohn.Forte@Sun.COM 	/* load host groups */
47019585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
47027836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47037836SJohn.Forte@Sun.COM 		return (ret);
47047836SJohn.Forte@Sun.COM 	}
47057836SJohn.Forte@Sun.COM 	ret = loadHostGroups(fd, groupList);
47067836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47077836SJohn.Forte@Sun.COM 		goto out;
47087836SJohn.Forte@Sun.COM 	}
47097836SJohn.Forte@Sun.COM 
47107836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
47117836SJohn.Forte@Sun.COM 	groupList = NULL;
47127836SJohn.Forte@Sun.COM 
47137836SJohn.Forte@Sun.COM 	/* load target groups */
47149585STim.Szeto@Sun.COM 	ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
47157836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47167836SJohn.Forte@Sun.COM 		goto out;
47177836SJohn.Forte@Sun.COM 	}
47187836SJohn.Forte@Sun.COM 	ret = loadTargetGroups(fd, groupList);
47197836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47207836SJohn.Forte@Sun.COM 		goto out;
47217836SJohn.Forte@Sun.COM 	}
47227836SJohn.Forte@Sun.COM 
47237836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
47247836SJohn.Forte@Sun.COM 	groupList = NULL;
47257836SJohn.Forte@Sun.COM 
47267836SJohn.Forte@Sun.COM 	/* Get the guid list */
47277836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&guidList);
47287836SJohn.Forte@Sun.COM 	switch (ret) {
47297836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
47307836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
47317836SJohn.Forte@Sun.COM 			break;
47327836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
47337836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
47347836SJohn.Forte@Sun.COM 			break;
47357836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
47367836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
47377836SJohn.Forte@Sun.COM 			break;
47387836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
47397836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
47407836SJohn.Forte@Sun.COM 			break;
47417836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
47427836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
47437836SJohn.Forte@Sun.COM 			break;
47447836SJohn.Forte@Sun.COM 		default:
47457836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
47467836SJohn.Forte@Sun.COM 			break;
47477836SJohn.Forte@Sun.COM 	}
47487836SJohn.Forte@Sun.COM 
47497836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
47507836SJohn.Forte@Sun.COM 		goto out;
47517836SJohn.Forte@Sun.COM 	}
47527836SJohn.Forte@Sun.COM 
47537836SJohn.Forte@Sun.COM 	/*
47547836SJohn.Forte@Sun.COM 	 * We have the guid list, now get the corresponding
47557836SJohn.Forte@Sun.COM 	 * view entries for each guid
47567836SJohn.Forte@Sun.COM 	 */
47577836SJohn.Forte@Sun.COM 	for (i = 0; i < guidList->cnt; i++) {
47587836SJohn.Forte@Sun.COM 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
47597836SJohn.Forte@Sun.COM 		switch (ret) {
47607836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
47617836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
47627836SJohn.Forte@Sun.COM 				break;
47637836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
47647836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
47657836SJohn.Forte@Sun.COM 				break;
47667836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
47677836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
47687836SJohn.Forte@Sun.COM 				break;
47697836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
47707836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
47717836SJohn.Forte@Sun.COM 				break;
47727836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
47737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
47747836SJohn.Forte@Sun.COM 				break;
47757836SJohn.Forte@Sun.COM 			default:
47767836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
47777836SJohn.Forte@Sun.COM 				break;
47787836SJohn.Forte@Sun.COM 		}
47797836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
47807836SJohn.Forte@Sun.COM 			goto out;
47817836SJohn.Forte@Sun.COM 		}
47827836SJohn.Forte@Sun.COM 		for (j = 0; j < viewEntryList->cnt; j++) {
47837836SJohn.Forte@Sun.COM 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
47847836SJohn.Forte@Sun.COM 			    &viewEntryList->ve[j]);
47857836SJohn.Forte@Sun.COM 			if (ret != STMF_STATUS_SUCCESS) {
47867836SJohn.Forte@Sun.COM 				goto out;
47877836SJohn.Forte@Sun.COM 			}
47887836SJohn.Forte@Sun.COM 		}
47897836SJohn.Forte@Sun.COM 	}
47907836SJohn.Forte@Sun.COM 
47917836SJohn.Forte@Sun.COM 	/* get the list of providers that have data */
47927836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(&providerList);
47937836SJohn.Forte@Sun.COM 	switch (ret) {
47947836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
47957836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
47967836SJohn.Forte@Sun.COM 			break;
47977836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
47987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
47997836SJohn.Forte@Sun.COM 			break;
48007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
48017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
48027836SJohn.Forte@Sun.COM 			break;
48037836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48047836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
48057836SJohn.Forte@Sun.COM 			break;
48067836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
48077836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
48087836SJohn.Forte@Sun.COM 			break;
48097836SJohn.Forte@Sun.COM 		default:
48107836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
48117836SJohn.Forte@Sun.COM 			break;
48127836SJohn.Forte@Sun.COM 	}
48137836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
48147836SJohn.Forte@Sun.COM 		goto out;
48157836SJohn.Forte@Sun.COM 	}
48167836SJohn.Forte@Sun.COM 
48177836SJohn.Forte@Sun.COM 	for (i = 0; i < providerList->cnt; i++) {
48187836SJohn.Forte@Sun.COM 		providerType = providerList->provider[i].providerType;
48197836SJohn.Forte@Sun.COM 		ret = psGetProviderData(providerList->provider[i].name,
48207836SJohn.Forte@Sun.COM 		    &nvl, providerType, NULL);
48217836SJohn.Forte@Sun.COM 		switch (ret) {
48227836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
48237836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
48247836SJohn.Forte@Sun.COM 				break;
48257836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
48267836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
48277836SJohn.Forte@Sun.COM 				break;
48287836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
48297836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
48307836SJohn.Forte@Sun.COM 				break;
48317836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48327836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
48337836SJohn.Forte@Sun.COM 				break;
48347836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
48357836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
48367836SJohn.Forte@Sun.COM 				break;
48377836SJohn.Forte@Sun.COM 			default:
48387836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
48397836SJohn.Forte@Sun.COM 				break;
48407836SJohn.Forte@Sun.COM 		}
48417836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
48427836SJohn.Forte@Sun.COM 			goto out;
48437836SJohn.Forte@Sun.COM 		}
48447836SJohn.Forte@Sun.COM 
48457836SJohn.Forte@Sun.COM 		/* call setProviderData */
48467836SJohn.Forte@Sun.COM 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
48479585STim.Szeto@Sun.COM 		    providerType, NULL);
48487836SJohn.Forte@Sun.COM 		switch (ret) {
48497836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
48507836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
48517836SJohn.Forte@Sun.COM 				break;
48527836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
48537836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
48547836SJohn.Forte@Sun.COM 				break;
48557836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
48567836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
48577836SJohn.Forte@Sun.COM 				break;
48587836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
48597836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
48607836SJohn.Forte@Sun.COM 				break;
48617836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
48627836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
48637836SJohn.Forte@Sun.COM 				break;
48647836SJohn.Forte@Sun.COM 			default:
48657836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
48667836SJohn.Forte@Sun.COM 				break;
48677836SJohn.Forte@Sun.COM 		}
48687836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
48697836SJohn.Forte@Sun.COM 			goto out;
48707836SJohn.Forte@Sun.COM 		}
48717836SJohn.Forte@Sun.COM 
48727836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
48737836SJohn.Forte@Sun.COM 		nvl = NULL;
48747836SJohn.Forte@Sun.COM 	}
48757836SJohn.Forte@Sun.COM out:
48767836SJohn.Forte@Sun.COM 	if (groupList != NULL) {
48777836SJohn.Forte@Sun.COM 		free(groupList);
48787836SJohn.Forte@Sun.COM 	}
48797836SJohn.Forte@Sun.COM 	if (guidList != NULL) {
48807836SJohn.Forte@Sun.COM 		free(guidList);
48817836SJohn.Forte@Sun.COM 	}
48827836SJohn.Forte@Sun.COM 	if (viewEntryList != NULL) {
48837836SJohn.Forte@Sun.COM 		free(viewEntryList);
48847836SJohn.Forte@Sun.COM 	}
48857836SJohn.Forte@Sun.COM 	if (nvl != NULL) {
48867836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
48877836SJohn.Forte@Sun.COM 	}
48887836SJohn.Forte@Sun.COM 	return (ret);
48897836SJohn.Forte@Sun.COM }
48907836SJohn.Forte@Sun.COM 
48917836SJohn.Forte@Sun.COM /*
4892*10725SJohn.Forte@Sun.COM  * stmfGetAluaState
4893*10725SJohn.Forte@Sun.COM  *
4894*10725SJohn.Forte@Sun.COM  * Purpose - Get the alua state
4895*10725SJohn.Forte@Sun.COM  *
4896*10725SJohn.Forte@Sun.COM  */
4897*10725SJohn.Forte@Sun.COM int
4898*10725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node)
4899*10725SJohn.Forte@Sun.COM {
4900*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
4901*10725SJohn.Forte@Sun.COM 	int fd;
4902*10725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
4903*10725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
4904*10725SJohn.Forte@Sun.COM 	int ioctlRet;
4905*10725SJohn.Forte@Sun.COM 
4906*10725SJohn.Forte@Sun.COM 	if (enabled == NULL || node == NULL) {
4907*10725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
4908*10725SJohn.Forte@Sun.COM 	}
4909*10725SJohn.Forte@Sun.COM 
4910*10725SJohn.Forte@Sun.COM 	/*
4911*10725SJohn.Forte@Sun.COM 	 * Open control node for stmf
4912*10725SJohn.Forte@Sun.COM 	 */
4913*10725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4914*10725SJohn.Forte@Sun.COM 		return (ret);
4915*10725SJohn.Forte@Sun.COM 
4916*10725SJohn.Forte@Sun.COM 	/*
4917*10725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
4918*10725SJohn.Forte@Sun.COM 	 */
4919*10725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
4920*10725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (alua_state);
4921*10725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state;
4922*10725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl);
4923*10725SJohn.Forte@Sun.COM 
4924*10725SJohn.Forte@Sun.COM 	(void) close(fd);
4925*10725SJohn.Forte@Sun.COM 
4926*10725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
4927*10725SJohn.Forte@Sun.COM 		switch (errno) {
4928*10725SJohn.Forte@Sun.COM 			case EBUSY:
4929*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
4930*10725SJohn.Forte@Sun.COM 				break;
4931*10725SJohn.Forte@Sun.COM 			case EPERM:
4932*10725SJohn.Forte@Sun.COM 			case EACCES:
4933*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
4934*10725SJohn.Forte@Sun.COM 				break;
4935*10725SJohn.Forte@Sun.COM 			default:
4936*10725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
4937*10725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
4938*10725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
4939*10725SJohn.Forte@Sun.COM 				break;
4940*10725SJohn.Forte@Sun.COM 		}
4941*10725SJohn.Forte@Sun.COM 	} else {
4942*10725SJohn.Forte@Sun.COM 		if (alua_state.alua_state == 1) {
4943*10725SJohn.Forte@Sun.COM 			*enabled = B_TRUE;
4944*10725SJohn.Forte@Sun.COM 		} else {
4945*10725SJohn.Forte@Sun.COM 			*enabled = B_FALSE;
4946*10725SJohn.Forte@Sun.COM 		}
4947*10725SJohn.Forte@Sun.COM 		*node = alua_state.alua_node;
4948*10725SJohn.Forte@Sun.COM 	}
4949*10725SJohn.Forte@Sun.COM 
4950*10725SJohn.Forte@Sun.COM 	return (ret);
4951*10725SJohn.Forte@Sun.COM }
4952*10725SJohn.Forte@Sun.COM 
4953*10725SJohn.Forte@Sun.COM /*
4954*10725SJohn.Forte@Sun.COM  * stmfSetAluaState
4955*10725SJohn.Forte@Sun.COM  *
4956*10725SJohn.Forte@Sun.COM  * Purpose - set the alua state to enabled/disabled
4957*10725SJohn.Forte@Sun.COM  *
4958*10725SJohn.Forte@Sun.COM  */
4959*10725SJohn.Forte@Sun.COM int
4960*10725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node)
4961*10725SJohn.Forte@Sun.COM {
4962*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
4963*10725SJohn.Forte@Sun.COM 	int fd;
4964*10725SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl = {0};
4965*10725SJohn.Forte@Sun.COM 	stmf_alua_state_desc_t alua_state = {0};
4966*10725SJohn.Forte@Sun.COM 	int ioctlRet;
4967*10725SJohn.Forte@Sun.COM 
4968*10725SJohn.Forte@Sun.COM 	if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) {
4969*10725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
4970*10725SJohn.Forte@Sun.COM 	}
4971*10725SJohn.Forte@Sun.COM 
4972*10725SJohn.Forte@Sun.COM 	if (enabled) {
4973*10725SJohn.Forte@Sun.COM 		alua_state.alua_state = 1;
4974*10725SJohn.Forte@Sun.COM 	}
4975*10725SJohn.Forte@Sun.COM 
4976*10725SJohn.Forte@Sun.COM 	alua_state.alua_node = node;
4977*10725SJohn.Forte@Sun.COM 
4978*10725SJohn.Forte@Sun.COM 	/*
4979*10725SJohn.Forte@Sun.COM 	 * Open control node for stmf
4980*10725SJohn.Forte@Sun.COM 	 */
4981*10725SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4982*10725SJohn.Forte@Sun.COM 		return (ret);
4983*10725SJohn.Forte@Sun.COM 
4984*10725SJohn.Forte@Sun.COM 	/*
4985*10725SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
4986*10725SJohn.Forte@Sun.COM 	 */
4987*10725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
4988*10725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (alua_state);
4989*10725SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state;
4990*10725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl);
4991*10725SJohn.Forte@Sun.COM 
4992*10725SJohn.Forte@Sun.COM 	(void) close(fd);
4993*10725SJohn.Forte@Sun.COM 
4994*10725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
4995*10725SJohn.Forte@Sun.COM 		switch (errno) {
4996*10725SJohn.Forte@Sun.COM 			case EBUSY:
4997*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
4998*10725SJohn.Forte@Sun.COM 				break;
4999*10725SJohn.Forte@Sun.COM 			case EPERM:
5000*10725SJohn.Forte@Sun.COM 			case EACCES:
5001*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
5002*10725SJohn.Forte@Sun.COM 				break;
5003*10725SJohn.Forte@Sun.COM 			default:
5004*10725SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
5005*10725SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
5006*10725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
5007*10725SJohn.Forte@Sun.COM 				break;
5008*10725SJohn.Forte@Sun.COM 		}
5009*10725SJohn.Forte@Sun.COM 	}
5010*10725SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
5011*10725SJohn.Forte@Sun.COM 		deleteNonActiveLus();
5012*10725SJohn.Forte@Sun.COM 	}
5013*10725SJohn.Forte@Sun.COM 
5014*10725SJohn.Forte@Sun.COM 	return (ret);
5015*10725SJohn.Forte@Sun.COM }
5016*10725SJohn.Forte@Sun.COM 
5017*10725SJohn.Forte@Sun.COM static void
5018*10725SJohn.Forte@Sun.COM deleteNonActiveLus()
5019*10725SJohn.Forte@Sun.COM {
5020*10725SJohn.Forte@Sun.COM 	int stmfRet;
5021*10725SJohn.Forte@Sun.COM 	int i;
5022*10725SJohn.Forte@Sun.COM 	stmfGuidList *luList;
5023*10725SJohn.Forte@Sun.COM 	luResource hdl = NULL;
5024*10725SJohn.Forte@Sun.COM 	char propVal[10];
5025*10725SJohn.Forte@Sun.COM 	size_t propValSize = sizeof (propVal);
5026*10725SJohn.Forte@Sun.COM 
5027*10725SJohn.Forte@Sun.COM 	stmfRet = stmfGetLogicalUnitList(&luList);
5028*10725SJohn.Forte@Sun.COM 	if (stmfRet != STMF_STATUS_SUCCESS) {
5029*10725SJohn.Forte@Sun.COM 		return;
5030*10725SJohn.Forte@Sun.COM 	}
5031*10725SJohn.Forte@Sun.COM 
5032*10725SJohn.Forte@Sun.COM 	for (i = 0; i < luList->cnt; i++) {
5033*10725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuResource(&luList->guid[i], &hdl);
5034*10725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
5035*10725SJohn.Forte@Sun.COM 			goto err;
5036*10725SJohn.Forte@Sun.COM 		}
5037*10725SJohn.Forte@Sun.COM 		stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
5038*10725SJohn.Forte@Sun.COM 		    &propValSize);
5039*10725SJohn.Forte@Sun.COM 		if (stmfRet != STMF_STATUS_SUCCESS) {
5040*10725SJohn.Forte@Sun.COM 			goto err;
5041*10725SJohn.Forte@Sun.COM 		}
5042*10725SJohn.Forte@Sun.COM 		if (propVal[0] == '0') {
5043*10725SJohn.Forte@Sun.COM 			(void) stmfFreeLuResource(hdl);
5044*10725SJohn.Forte@Sun.COM 			hdl = NULL;
5045*10725SJohn.Forte@Sun.COM 			continue;
5046*10725SJohn.Forte@Sun.COM 		}
5047*10725SJohn.Forte@Sun.COM 		(void) stmfDeleteLu(&luList->guid[i]);
5048*10725SJohn.Forte@Sun.COM 		(void) stmfFreeLuResource(hdl);
5049*10725SJohn.Forte@Sun.COM 		hdl = NULL;
5050*10725SJohn.Forte@Sun.COM 	}
5051*10725SJohn.Forte@Sun.COM 
5052*10725SJohn.Forte@Sun.COM err:
5053*10725SJohn.Forte@Sun.COM 	stmfFreeMemory(luList);
5054*10725SJohn.Forte@Sun.COM 	(void) stmfFreeLuResource(hdl);
5055*10725SJohn.Forte@Sun.COM }
5056*10725SJohn.Forte@Sun.COM 
5057*10725SJohn.Forte@Sun.COM /*
50587836SJohn.Forte@Sun.COM  * stmfLoadConfig
50597836SJohn.Forte@Sun.COM  *
50607836SJohn.Forte@Sun.COM  * Purpose - load the configuration data from smf into stmf
50617836SJohn.Forte@Sun.COM  *
50627836SJohn.Forte@Sun.COM  */
50637836SJohn.Forte@Sun.COM int
50647836SJohn.Forte@Sun.COM stmfLoadConfig(void)
50657836SJohn.Forte@Sun.COM {
50669585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
50677836SJohn.Forte@Sun.COM 	int fd;
50687836SJohn.Forte@Sun.COM 	stmf_state_desc_t stmfStateSet;
50697836SJohn.Forte@Sun.COM 	stmfState state;
50707836SJohn.Forte@Sun.COM 
50719585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
50729585STim.Szeto@Sun.COM 		stmfStateSet.state = STMF_STATE_OFFLINE;
507310560SSusan.Gleeson@Sun.COM 
50749585STim.Szeto@Sun.COM 		if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
50759585STim.Szeto@Sun.COM 		    != STMF_STATUS_SUCCESS) {
50769585STim.Szeto@Sun.COM 			return (ret);
50779585STim.Szeto@Sun.COM 		}
507810560SSusan.Gleeson@Sun.COM 		/*
507910560SSusan.Gleeson@Sun.COM 		 * Configuration not stored persistently; nothing to
508010560SSusan.Gleeson@Sun.COM 		 * initialize so do not set to STMF_CONFIG_INIT.
508110560SSusan.Gleeson@Sun.COM 		 */
50829585STim.Szeto@Sun.COM 		stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
50839585STim.Szeto@Sun.COM 		goto done;
50849585STim.Szeto@Sun.COM 	}
50857836SJohn.Forte@Sun.COM 
50867836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
50877836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
50887836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
50897836SJohn.Forte@Sun.COM 	}
50907836SJohn.Forte@Sun.COM 
50917836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
50927836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
50937836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
50947836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
50957836SJohn.Forte@Sun.COM 		}
50967836SJohn.Forte@Sun.COM 	} else {
50977836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
50987836SJohn.Forte@Sun.COM 	}
50997836SJohn.Forte@Sun.COM 
51007836SJohn.Forte@Sun.COM 
51017836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
51027836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT;
51037836SJohn.Forte@Sun.COM 
51047836SJohn.Forte@Sun.COM 	/*
51057836SJohn.Forte@Sun.COM 	 * Open control node for stmf
51067836SJohn.Forte@Sun.COM 	 */
51077836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
51087836SJohn.Forte@Sun.COM 		return (ret);
51097836SJohn.Forte@Sun.COM 
51107836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
51117836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
51127836SJohn.Forte@Sun.COM 		goto done;
51137836SJohn.Forte@Sun.COM 	}
51147836SJohn.Forte@Sun.COM 
51157836SJohn.Forte@Sun.COM 	/* Load the persistent configuration data */
51167836SJohn.Forte@Sun.COM 	ret = loadStore(fd);
51177836SJohn.Forte@Sun.COM 	if (ret != 0) {
51187836SJohn.Forte@Sun.COM 		goto done;
51197836SJohn.Forte@Sun.COM 	}
51207836SJohn.Forte@Sun.COM 
51217836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
51227836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
51237836SJohn.Forte@Sun.COM 
51247836SJohn.Forte@Sun.COM done:
51257836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
51267836SJohn.Forte@Sun.COM 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
51277836SJohn.Forte@Sun.COM 	}
51287836SJohn.Forte@Sun.COM 	(void) close(fd);
51297836SJohn.Forte@Sun.COM 	return (ret);
51307836SJohn.Forte@Sun.COM }
51317836SJohn.Forte@Sun.COM 
51329585STim.Szeto@Sun.COM 
51337836SJohn.Forte@Sun.COM /*
51347836SJohn.Forte@Sun.COM  * getStmfState
51357836SJohn.Forte@Sun.COM  *
51367836SJohn.Forte@Sun.COM  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
51377836SJohn.Forte@Sun.COM  *             information of the stmf service on success.
51387836SJohn.Forte@Sun.COM  */
51397836SJohn.Forte@Sun.COM static int
51407836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState)
51417836SJohn.Forte@Sun.COM {
51427836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
51437836SJohn.Forte@Sun.COM 	int fd;
51447836SJohn.Forte@Sun.COM 	int ioctlRet;
51457836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
51467836SJohn.Forte@Sun.COM 
51477836SJohn.Forte@Sun.COM 	/*
51487836SJohn.Forte@Sun.COM 	 * Open control node for stmf
51497836SJohn.Forte@Sun.COM 	 */
51507836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
51517836SJohn.Forte@Sun.COM 		return (ret);
51527836SJohn.Forte@Sun.COM 
51537836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
51547836SJohn.Forte@Sun.COM 	/*
51557836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
51567836SJohn.Forte@Sun.COM 	 */
51577836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
51587836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
51597836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
51607836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
51617836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
51627836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
51637836SJohn.Forte@Sun.COM 
51647836SJohn.Forte@Sun.COM 	(void) close(fd);
51657836SJohn.Forte@Sun.COM 
51667836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
51677836SJohn.Forte@Sun.COM 		switch (errno) {
51687836SJohn.Forte@Sun.COM 			case EBUSY:
51697836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
51707836SJohn.Forte@Sun.COM 				break;
51717836SJohn.Forte@Sun.COM 			case EPERM:
51727836SJohn.Forte@Sun.COM 			case EACCES:
51737836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
51747836SJohn.Forte@Sun.COM 				break;
51757836SJohn.Forte@Sun.COM 			default:
51767836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
51777836SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
51787836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
51797836SJohn.Forte@Sun.COM 				break;
51807836SJohn.Forte@Sun.COM 		}
51817836SJohn.Forte@Sun.COM 	}
51827836SJohn.Forte@Sun.COM 	return (ret);
51837836SJohn.Forte@Sun.COM }
51847836SJohn.Forte@Sun.COM 
51857836SJohn.Forte@Sun.COM 
51867836SJohn.Forte@Sun.COM /*
51877836SJohn.Forte@Sun.COM  * setStmfState
51887836SJohn.Forte@Sun.COM  *
51897836SJohn.Forte@Sun.COM  * stmfState - pointer to caller set state structure
51907836SJohn.Forte@Sun.COM  * objectType - one of:
51917836SJohn.Forte@Sun.COM  *		LOGICAL_UNIT_TYPE
51927836SJohn.Forte@Sun.COM  *		TARGET_TYPE
51937836SJohn.Forte@Sun.COM  *		STMF_SERVICE_TYPE
51947836SJohn.Forte@Sun.COM  */
51957836SJohn.Forte@Sun.COM static int
51967836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
51977836SJohn.Forte@Sun.COM {
51987836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
51997836SJohn.Forte@Sun.COM 	int ioctlRet;
52007836SJohn.Forte@Sun.COM 	int cmd;
52017836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
52027836SJohn.Forte@Sun.COM 
52037836SJohn.Forte@Sun.COM 	switch (objectType) {
52047836SJohn.Forte@Sun.COM 		case LOGICAL_UNIT_TYPE:
52057836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_LU_STATE;
52067836SJohn.Forte@Sun.COM 			break;
52077836SJohn.Forte@Sun.COM 		case TARGET_TYPE:
52087836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
52097836SJohn.Forte@Sun.COM 			break;
52107836SJohn.Forte@Sun.COM 		case STMF_SERVICE_TYPE:
52117836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_STMF_STATE;
52127836SJohn.Forte@Sun.COM 			break;
52137836SJohn.Forte@Sun.COM 		default:
52147836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
52157836SJohn.Forte@Sun.COM 			goto done;
52167836SJohn.Forte@Sun.COM 	}
52177836SJohn.Forte@Sun.COM 
52187836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
52197836SJohn.Forte@Sun.COM 	/*
52207836SJohn.Forte@Sun.COM 	 * Issue ioctl to set the stmf state
52217836SJohn.Forte@Sun.COM 	 */
52227836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
52237836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
52247836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
52257836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
52267836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
52277836SJohn.Forte@Sun.COM 		switch (errno) {
52287836SJohn.Forte@Sun.COM 			case EBUSY:
52297836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
52307836SJohn.Forte@Sun.COM 				break;
52319585STim.Szeto@Sun.COM 			case EPERM:
52327836SJohn.Forte@Sun.COM 			case EACCES:
52337836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
52347836SJohn.Forte@Sun.COM 				break;
52357836SJohn.Forte@Sun.COM 			case ENOENT:
52367836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
52377836SJohn.Forte@Sun.COM 				break;
52387836SJohn.Forte@Sun.COM 			default:
52397836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
52407836SJohn.Forte@Sun.COM 				    "setStmfState:ioctl errno(%d)", errno);
52417836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
52427836SJohn.Forte@Sun.COM 				break;
52437836SJohn.Forte@Sun.COM 		}
52447836SJohn.Forte@Sun.COM 	}
52457836SJohn.Forte@Sun.COM done:
52467836SJohn.Forte@Sun.COM 	return (ret);
52477836SJohn.Forte@Sun.COM }
52487836SJohn.Forte@Sun.COM 
52497836SJohn.Forte@Sun.COM /*
52507836SJohn.Forte@Sun.COM  * stmfOnline
52517836SJohn.Forte@Sun.COM  *
52527836SJohn.Forte@Sun.COM  * Purpose: Online stmf service
52537836SJohn.Forte@Sun.COM  *
52547836SJohn.Forte@Sun.COM  */
52557836SJohn.Forte@Sun.COM int
52567836SJohn.Forte@Sun.COM stmfOnline(void)
52577836SJohn.Forte@Sun.COM {
52587836SJohn.Forte@Sun.COM 	int ret;
52597836SJohn.Forte@Sun.COM 	int fd;
52607836SJohn.Forte@Sun.COM 	stmfState state;
52617836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
52627836SJohn.Forte@Sun.COM 
52637836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
52647836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
52657836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
52667836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
52677836SJohn.Forte@Sun.COM 		}
52687836SJohn.Forte@Sun.COM 	} else {
52697836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
52707836SJohn.Forte@Sun.COM 	}
52717836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_ONLINE;
52727836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
52737836SJohn.Forte@Sun.COM 	/*
52747836SJohn.Forte@Sun.COM 	 * Open control node for stmf
52757836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
52767836SJohn.Forte@Sun.COM 	 */
52777836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
52787836SJohn.Forte@Sun.COM 		return (ret);
52797836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
52807836SJohn.Forte@Sun.COM 	(void) close(fd);
52817836SJohn.Forte@Sun.COM 	return (ret);
52827836SJohn.Forte@Sun.COM }
52837836SJohn.Forte@Sun.COM 
52847836SJohn.Forte@Sun.COM /*
52857836SJohn.Forte@Sun.COM  * stmfOffline
52867836SJohn.Forte@Sun.COM  *
52877836SJohn.Forte@Sun.COM  * Purpose: Offline stmf service
52887836SJohn.Forte@Sun.COM  *
52897836SJohn.Forte@Sun.COM  */
52907836SJohn.Forte@Sun.COM int
52917836SJohn.Forte@Sun.COM stmfOffline(void)
52927836SJohn.Forte@Sun.COM {
52937836SJohn.Forte@Sun.COM 	int ret;
52947836SJohn.Forte@Sun.COM 	int fd;
52957836SJohn.Forte@Sun.COM 	stmfState state;
52967836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
52977836SJohn.Forte@Sun.COM 
52987836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
52997836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
53007836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
53017836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_OFFLINE);
53027836SJohn.Forte@Sun.COM 		}
53037836SJohn.Forte@Sun.COM 	} else {
53047836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
53057836SJohn.Forte@Sun.COM 	}
53067836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_OFFLINE;
53077836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
53087836SJohn.Forte@Sun.COM 
53097836SJohn.Forte@Sun.COM 	/*
53107836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53117836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
53127836SJohn.Forte@Sun.COM 	 */
53137836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53147836SJohn.Forte@Sun.COM 		return (ret);
53157836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
53167836SJohn.Forte@Sun.COM 	(void) close(fd);
53177836SJohn.Forte@Sun.COM 	return (ret);
53187836SJohn.Forte@Sun.COM }
53197836SJohn.Forte@Sun.COM 
53207836SJohn.Forte@Sun.COM 
53217836SJohn.Forte@Sun.COM /*
53227836SJohn.Forte@Sun.COM  * stmfOfflineTarget
53237836SJohn.Forte@Sun.COM  *
53247836SJohn.Forte@Sun.COM  * Purpose: Change state of target to offline
53257836SJohn.Forte@Sun.COM  *
53267836SJohn.Forte@Sun.COM  * devid - devid of the target to offline
53277836SJohn.Forte@Sun.COM  */
53287836SJohn.Forte@Sun.COM int
53297836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid)
53307836SJohn.Forte@Sun.COM {
53317836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
53327836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
53337836SJohn.Forte@Sun.COM 	int fd;
53347836SJohn.Forte@Sun.COM 
53357836SJohn.Forte@Sun.COM 	if (devid == NULL) {
53367836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
53377836SJohn.Forte@Sun.COM 	}
53387836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
53397836SJohn.Forte@Sun.COM 
53407836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_OFFLINE;
53417836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
53427836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
53437836SJohn.Forte@Sun.COM 	    devid->identLength);
53447836SJohn.Forte@Sun.COM 	/*
53457836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53467836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
53477836SJohn.Forte@Sun.COM 	 */
53487836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53497836SJohn.Forte@Sun.COM 		return (ret);
53507836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
53517836SJohn.Forte@Sun.COM 	(void) close(fd);
53527836SJohn.Forte@Sun.COM 	return (ret);
53537836SJohn.Forte@Sun.COM }
53547836SJohn.Forte@Sun.COM 
53557836SJohn.Forte@Sun.COM /*
53567836SJohn.Forte@Sun.COM  * stmfOfflineLogicalUnit
53577836SJohn.Forte@Sun.COM  *
53587836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to offline
53597836SJohn.Forte@Sun.COM  *
53607836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to offline
53617836SJohn.Forte@Sun.COM  */
53627836SJohn.Forte@Sun.COM int
53637836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu)
53647836SJohn.Forte@Sun.COM {
53657836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
53667836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
53677836SJohn.Forte@Sun.COM 	int fd;
53687836SJohn.Forte@Sun.COM 
53697836SJohn.Forte@Sun.COM 	if (lu == NULL) {
53707836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
53717836SJohn.Forte@Sun.COM 	}
53727836SJohn.Forte@Sun.COM 
53737836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
53747836SJohn.Forte@Sun.COM 
53757836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_OFFLINE;
53767836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
53777836SJohn.Forte@Sun.COM 	/*
53787836SJohn.Forte@Sun.COM 	 * Open control node for stmf
53797836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
53807836SJohn.Forte@Sun.COM 	 */
53817836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
53827836SJohn.Forte@Sun.COM 		return (ret);
53837836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
53847836SJohn.Forte@Sun.COM 	(void) close(fd);
53857836SJohn.Forte@Sun.COM 	return (ret);
53867836SJohn.Forte@Sun.COM }
53877836SJohn.Forte@Sun.COM 
53887836SJohn.Forte@Sun.COM /*
53897836SJohn.Forte@Sun.COM  * stmfOnlineTarget
53907836SJohn.Forte@Sun.COM  *
53917836SJohn.Forte@Sun.COM  * Purpose: Change state of target to online
53927836SJohn.Forte@Sun.COM  *
53937836SJohn.Forte@Sun.COM  * devid - devid of the target to online
53947836SJohn.Forte@Sun.COM  */
53957836SJohn.Forte@Sun.COM int
53967836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid)
53977836SJohn.Forte@Sun.COM {
53987836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
53997836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54007836SJohn.Forte@Sun.COM 	int fd;
54017836SJohn.Forte@Sun.COM 
54027836SJohn.Forte@Sun.COM 	if (devid == NULL) {
54037836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
54047836SJohn.Forte@Sun.COM 	}
54057836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
54067836SJohn.Forte@Sun.COM 
54077836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_ONLINE;
54087836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
54097836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
54107836SJohn.Forte@Sun.COM 	    devid->identLength);
54117836SJohn.Forte@Sun.COM 	/*
54127836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54137836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
54147836SJohn.Forte@Sun.COM 	 */
54157836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
54167836SJohn.Forte@Sun.COM 		return (ret);
54177836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
54187836SJohn.Forte@Sun.COM 	(void) close(fd);
54197836SJohn.Forte@Sun.COM 	return (ret);
54207836SJohn.Forte@Sun.COM }
54217836SJohn.Forte@Sun.COM 
54227836SJohn.Forte@Sun.COM /*
54237836SJohn.Forte@Sun.COM  * stmfOnlineLogicalUnit
54247836SJohn.Forte@Sun.COM  *
54257836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to online
54267836SJohn.Forte@Sun.COM  *
54277836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to online
54287836SJohn.Forte@Sun.COM  */
54297836SJohn.Forte@Sun.COM int
54307836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu)
54317836SJohn.Forte@Sun.COM {
54327836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
54337836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
54347836SJohn.Forte@Sun.COM 	int fd;
54357836SJohn.Forte@Sun.COM 
54367836SJohn.Forte@Sun.COM 	if (lu == NULL) {
54377836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
54387836SJohn.Forte@Sun.COM 	}
54397836SJohn.Forte@Sun.COM 
54407836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
54417836SJohn.Forte@Sun.COM 
54427836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_ONLINE;
54437836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
54447836SJohn.Forte@Sun.COM 	/*
54457836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54467836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
54477836SJohn.Forte@Sun.COM 	 */
54487836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
54497836SJohn.Forte@Sun.COM 		return (ret);
54507836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
54517836SJohn.Forte@Sun.COM 	(void) close(fd);
54527836SJohn.Forte@Sun.COM 	return (ret);
54537836SJohn.Forte@Sun.COM }
54547836SJohn.Forte@Sun.COM 
54557836SJohn.Forte@Sun.COM /*
54567836SJohn.Forte@Sun.COM  * stmfRemoveFromHostGroup
54577836SJohn.Forte@Sun.COM  *
54587836SJohn.Forte@Sun.COM  * Purpose: Removes an initiator from an initiator group
54597836SJohn.Forte@Sun.COM  *
54607836SJohn.Forte@Sun.COM  * hostGroupName - name of an initiator group
54617836SJohn.Forte@Sun.COM  * hostName - name of host group member to remove
54627836SJohn.Forte@Sun.COM  */
54637836SJohn.Forte@Sun.COM int
54647836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
54657836SJohn.Forte@Sun.COM {
54667836SJohn.Forte@Sun.COM 	int ret;
54677836SJohn.Forte@Sun.COM 	int fd;
54687836SJohn.Forte@Sun.COM 
54697836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
54707836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
54717836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
54727836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
54737836SJohn.Forte@Sun.COM 	}
54747836SJohn.Forte@Sun.COM 
54757836SJohn.Forte@Sun.COM 	/* call init */
54767836SJohn.Forte@Sun.COM 	ret = initializeConfig();
54777836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
54787836SJohn.Forte@Sun.COM 		return (ret);
54797836SJohn.Forte@Sun.COM 	}
54807836SJohn.Forte@Sun.COM 
54817836SJohn.Forte@Sun.COM 	/*
54827836SJohn.Forte@Sun.COM 	 * Open control node for stmf
54837836SJohn.Forte@Sun.COM 	 */
54847836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
54857836SJohn.Forte@Sun.COM 		return (ret);
54867836SJohn.Forte@Sun.COM 
54877836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
54887836SJohn.Forte@Sun.COM 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
54897836SJohn.Forte@Sun.COM 		goto done;
54907836SJohn.Forte@Sun.COM 	}
54917836SJohn.Forte@Sun.COM 
54929585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
54939585STim.Szeto@Sun.COM 		goto done;
54949585STim.Szeto@Sun.COM 	}
54959585STim.Szeto@Sun.COM 
54967836SJohn.Forte@Sun.COM 	ret = psRemoveHostGroupMember((char *)hostGroupName,
54977836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
54987836SJohn.Forte@Sun.COM 	switch (ret) {
54997836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
55007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
55017836SJohn.Forte@Sun.COM 			break;
55027836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
55037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
55047836SJohn.Forte@Sun.COM 			break;
55057836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
55067836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
55077836SJohn.Forte@Sun.COM 			break;
55087836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
55097836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
55107836SJohn.Forte@Sun.COM 			break;
55117836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
55127836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
55137836SJohn.Forte@Sun.COM 			break;
55147836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
55157836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
55167836SJohn.Forte@Sun.COM 			break;
55177836SJohn.Forte@Sun.COM 		default:
55187836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
55197836SJohn.Forte@Sun.COM 			    "stmfRemoveFromHostGroup"
55207836SJohn.Forte@Sun.COM 			    "psRemoveHostGroupMember:error(%d)", ret);
55217836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
55227836SJohn.Forte@Sun.COM 			break;
55237836SJohn.Forte@Sun.COM 	}
55247836SJohn.Forte@Sun.COM 
55257836SJohn.Forte@Sun.COM done:
55267836SJohn.Forte@Sun.COM 	(void) close(fd);
55277836SJohn.Forte@Sun.COM 	return (ret);
55287836SJohn.Forte@Sun.COM }
55297836SJohn.Forte@Sun.COM 
55307836SJohn.Forte@Sun.COM /*
55317836SJohn.Forte@Sun.COM  * stmfRemoveFromTargetGroup
55327836SJohn.Forte@Sun.COM  *
55337836SJohn.Forte@Sun.COM  * Purpose: Removes a local port from a local port group
55347836SJohn.Forte@Sun.COM  *
55357836SJohn.Forte@Sun.COM  * targetGroupName - name of a target group
55367836SJohn.Forte@Sun.COM  * targetName - name of target to remove
55377836SJohn.Forte@Sun.COM  */
55387836SJohn.Forte@Sun.COM int
55397836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
55407836SJohn.Forte@Sun.COM {
55417836SJohn.Forte@Sun.COM 	int ret;
55427836SJohn.Forte@Sun.COM 	int fd;
55437836SJohn.Forte@Sun.COM 
55447836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
55457836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
55467836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
55477836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
55487836SJohn.Forte@Sun.COM 	}
55497836SJohn.Forte@Sun.COM 
55507836SJohn.Forte@Sun.COM 	/* call init */
55517836SJohn.Forte@Sun.COM 	ret = initializeConfig();
55527836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
55537836SJohn.Forte@Sun.COM 		return (ret);
55547836SJohn.Forte@Sun.COM 	}
55557836SJohn.Forte@Sun.COM 
55567836SJohn.Forte@Sun.COM 	/*
55577836SJohn.Forte@Sun.COM 	 * Open control node for stmf
55587836SJohn.Forte@Sun.COM 	 */
55597836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
55607836SJohn.Forte@Sun.COM 		return (ret);
55617836SJohn.Forte@Sun.COM 
55627836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
55637836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
55647836SJohn.Forte@Sun.COM 		goto done;
55657836SJohn.Forte@Sun.COM 	}
55667836SJohn.Forte@Sun.COM 
55679585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
55689585STim.Szeto@Sun.COM 		goto done;
55699585STim.Szeto@Sun.COM 	}
55709585STim.Szeto@Sun.COM 
55717836SJohn.Forte@Sun.COM 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
55727836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
55737836SJohn.Forte@Sun.COM 	switch (ret) {
55747836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
55757836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
55767836SJohn.Forte@Sun.COM 			break;
55777836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
55787836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
55797836SJohn.Forte@Sun.COM 			break;
55807836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
55817836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
55827836SJohn.Forte@Sun.COM 			break;
55837836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
55847836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
55857836SJohn.Forte@Sun.COM 			break;
55867836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
55877836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
55887836SJohn.Forte@Sun.COM 			break;
55897836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
55907836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
55917836SJohn.Forte@Sun.COM 			break;
55927836SJohn.Forte@Sun.COM 		default:
55937836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
55947836SJohn.Forte@Sun.COM 			    "stmfRemoveFromTargetGroup"
55957836SJohn.Forte@Sun.COM 			    "psRemoveTargetGroupMember:error(%d)", ret);
55967836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
55977836SJohn.Forte@Sun.COM 			break;
55987836SJohn.Forte@Sun.COM 	}
55997836SJohn.Forte@Sun.COM 
56007836SJohn.Forte@Sun.COM done:
56017836SJohn.Forte@Sun.COM 	(void) close(fd);
56027836SJohn.Forte@Sun.COM 	return (ret);
56037836SJohn.Forte@Sun.COM }
56047836SJohn.Forte@Sun.COM 
56057836SJohn.Forte@Sun.COM /*
56067836SJohn.Forte@Sun.COM  * stmfRemoveViewEntry
56077836SJohn.Forte@Sun.COM  *
56087836SJohn.Forte@Sun.COM  * Purpose: Removes a view entry from a logical unit
56097836SJohn.Forte@Sun.COM  *
56107836SJohn.Forte@Sun.COM  * lu - guid of lu for which view entry is being removed
56117836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry to remove
56127836SJohn.Forte@Sun.COM  *
56137836SJohn.Forte@Sun.COM  */
56147836SJohn.Forte@Sun.COM int
56157836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
56167836SJohn.Forte@Sun.COM {
56177836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
56187836SJohn.Forte@Sun.COM 	int fd;
56197836SJohn.Forte@Sun.COM 	int ioctlRet;
56207836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
56217836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
56227836SJohn.Forte@Sun.COM 
56237836SJohn.Forte@Sun.COM 	if (lu == NULL) {
56247836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
56257836SJohn.Forte@Sun.COM 	}
56267836SJohn.Forte@Sun.COM 
56277836SJohn.Forte@Sun.COM 	/* call init */
56287836SJohn.Forte@Sun.COM 	ret = initializeConfig();
56297836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
56307836SJohn.Forte@Sun.COM 		return (ret);
56317836SJohn.Forte@Sun.COM 	}
56327836SJohn.Forte@Sun.COM 
56337836SJohn.Forte@Sun.COM 	/*
56347836SJohn.Forte@Sun.COM 	 * Open control node for stmf
56357836SJohn.Forte@Sun.COM 	 */
56367836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
56377836SJohn.Forte@Sun.COM 		return (ret);
56387836SJohn.Forte@Sun.COM 
56397836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
56407836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
56417836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx = viewEntryIndex;
56427836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
56437836SJohn.Forte@Sun.COM 
56447836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
56457836SJohn.Forte@Sun.COM 	/*
56467836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
56477836SJohn.Forte@Sun.COM 	 */
56487836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
56497836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
56507836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
56517836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
56527836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
56537836SJohn.Forte@Sun.COM 		switch (errno) {
56547836SJohn.Forte@Sun.COM 			case EBUSY:
56557836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
56567836SJohn.Forte@Sun.COM 				break;
56579585STim.Szeto@Sun.COM 			case EPERM:
56589585STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
56599585STim.Szeto@Sun.COM 				break;
56607836SJohn.Forte@Sun.COM 			case EACCES:
56617836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
56627836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
56637836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
56647836SJohn.Forte@Sun.COM 						break;
56657836SJohn.Forte@Sun.COM 					default:
56667836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
56677836SJohn.Forte@Sun.COM 						break;
56687836SJohn.Forte@Sun.COM 				}
56697836SJohn.Forte@Sun.COM 				break;
56707836SJohn.Forte@Sun.COM 			case ENODEV:
56717836SJohn.Forte@Sun.COM 			case ENOENT:
56727836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
56737836SJohn.Forte@Sun.COM 				break;
56747836SJohn.Forte@Sun.COM 			default:
56757836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
56767836SJohn.Forte@Sun.COM 				    "stmfRemoveViewEntry:ioctl errno(%d)",
56777836SJohn.Forte@Sun.COM 				    errno);
56787836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
56797836SJohn.Forte@Sun.COM 				break;
56807836SJohn.Forte@Sun.COM 		}
56817836SJohn.Forte@Sun.COM 		goto done;
56827836SJohn.Forte@Sun.COM 	}
56837836SJohn.Forte@Sun.COM 
56849585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
56859585STim.Szeto@Sun.COM 		goto done;
56869585STim.Szeto@Sun.COM 	}
56879585STim.Szeto@Sun.COM 
56887836SJohn.Forte@Sun.COM 	ret = psRemoveViewEntry(lu, viewEntryIndex);
56897836SJohn.Forte@Sun.COM 	switch (ret) {
56907836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
56917836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
56927836SJohn.Forte@Sun.COM 			break;
56937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
56947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
56957836SJohn.Forte@Sun.COM 			break;
56967836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
56977836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
56987836SJohn.Forte@Sun.COM 			break;
56997836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
57007836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
57017836SJohn.Forte@Sun.COM 			break;
57027836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
57037836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
57047836SJohn.Forte@Sun.COM 			break;
57057836SJohn.Forte@Sun.COM 		default:
57067836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
57077836SJohn.Forte@Sun.COM 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
57087836SJohn.Forte@Sun.COM 			    ret);
57097836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
57107836SJohn.Forte@Sun.COM 			break;
57117836SJohn.Forte@Sun.COM 	}
57127836SJohn.Forte@Sun.COM 
57137836SJohn.Forte@Sun.COM done:
57147836SJohn.Forte@Sun.COM 	(void) close(fd);
57157836SJohn.Forte@Sun.COM 	return (ret);
57167836SJohn.Forte@Sun.COM }
57177836SJohn.Forte@Sun.COM 
57187836SJohn.Forte@Sun.COM /*
57197836SJohn.Forte@Sun.COM  * stmfSetProviderData
57207836SJohn.Forte@Sun.COM  *
57217836SJohn.Forte@Sun.COM  * Purpose: set the provider data
57227836SJohn.Forte@Sun.COM  *
57237836SJohn.Forte@Sun.COM  * providerName - unique name of provider
57247836SJohn.Forte@Sun.COM  * nvl - nvlist to set
57257836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
57267836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
57277836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
57287836SJohn.Forte@Sun.COM  */
57297836SJohn.Forte@Sun.COM int
57307836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
57317836SJohn.Forte@Sun.COM {
57327836SJohn.Forte@Sun.COM 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
57337836SJohn.Forte@Sun.COM 	    NULL));
57347836SJohn.Forte@Sun.COM }
57357836SJohn.Forte@Sun.COM 
57367836SJohn.Forte@Sun.COM /*
57377836SJohn.Forte@Sun.COM  * stmfSetProviderDataProt
57387836SJohn.Forte@Sun.COM  *
57397836SJohn.Forte@Sun.COM  * Purpose: set the provider data
57407836SJohn.Forte@Sun.COM  *
57417836SJohn.Forte@Sun.COM  * providerName - unique name of provider
57427836SJohn.Forte@Sun.COM  * nvl - nvlist to set
57437836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
57447836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
57457836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
57467836SJohn.Forte@Sun.COM  * setToken - Stale data token returned in the stmfGetProviderDataProt()
57477836SJohn.Forte@Sun.COM  *	      call or NULL.
57487836SJohn.Forte@Sun.COM  */
57497836SJohn.Forte@Sun.COM int
57507836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
57517836SJohn.Forte@Sun.COM     uint64_t *setToken)
57527836SJohn.Forte@Sun.COM {
57537836SJohn.Forte@Sun.COM 	int ret;
57547836SJohn.Forte@Sun.COM 	int fd;
57557836SJohn.Forte@Sun.COM 
57567836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
57577836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
57587836SJohn.Forte@Sun.COM 	}
57597836SJohn.Forte@Sun.COM 
57607836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
57617836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
57627836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
57637836SJohn.Forte@Sun.COM 	}
57647836SJohn.Forte@Sun.COM 
57657836SJohn.Forte@Sun.COM 	/* call init */
57667836SJohn.Forte@Sun.COM 	ret = initializeConfig();
57677836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
57687836SJohn.Forte@Sun.COM 		return (ret);
57697836SJohn.Forte@Sun.COM 	}
57707836SJohn.Forte@Sun.COM 
57717836SJohn.Forte@Sun.COM 	/*
57727836SJohn.Forte@Sun.COM 	 * Open control node for stmf
57737836SJohn.Forte@Sun.COM 	 */
57747836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
57757836SJohn.Forte@Sun.COM 		return (ret);
57767836SJohn.Forte@Sun.COM 
57779585STim.Szeto@Sun.COM 	ret = setProviderData(fd, providerName, nvl, providerType, setToken);
57787836SJohn.Forte@Sun.COM 
57797836SJohn.Forte@Sun.COM 	(void) close(fd);
57807836SJohn.Forte@Sun.COM 
57817836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
57827836SJohn.Forte@Sun.COM 		goto done;
57837836SJohn.Forte@Sun.COM 	}
57847836SJohn.Forte@Sun.COM 
57859585STim.Szeto@Sun.COM 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
57869585STim.Szeto@Sun.COM 		goto done;
57879585STim.Szeto@Sun.COM 	}
57889585STim.Szeto@Sun.COM 
57897836SJohn.Forte@Sun.COM 	/* setting driver provider data successful. Now persist it */
57909585STim.Szeto@Sun.COM 	ret = psSetProviderData(providerName, nvl, providerType, NULL);
57917836SJohn.Forte@Sun.COM 	switch (ret) {
57927836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
57937836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
57947836SJohn.Forte@Sun.COM 			break;
57957836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
57967836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
57977836SJohn.Forte@Sun.COM 			break;
57987836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
57997836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
58007836SJohn.Forte@Sun.COM 			break;
58017836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
58027836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
58037836SJohn.Forte@Sun.COM 			break;
58047836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
58057836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
58067836SJohn.Forte@Sun.COM 			break;
58077836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_PROV_DATA_STALE:
58087836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PROV_DATA_STALE;
58097836SJohn.Forte@Sun.COM 			break;
58107836SJohn.Forte@Sun.COM 		default:
58117836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
58127836SJohn.Forte@Sun.COM 			    "stmfSetProviderData"
58137836SJohn.Forte@Sun.COM 			    "psSetProviderData:error(%d)", ret);
58147836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
58157836SJohn.Forte@Sun.COM 			break;
58167836SJohn.Forte@Sun.COM 	}
58177836SJohn.Forte@Sun.COM 
58187836SJohn.Forte@Sun.COM done:
58197836SJohn.Forte@Sun.COM 	return (ret);
58207836SJohn.Forte@Sun.COM }
58217836SJohn.Forte@Sun.COM 
58227836SJohn.Forte@Sun.COM /*
58239585STim.Szeto@Sun.COM  * getProviderData
58249585STim.Szeto@Sun.COM  *
58259585STim.Szeto@Sun.COM  * Purpose: set the provider data from stmf
58269585STim.Szeto@Sun.COM  *
58279585STim.Szeto@Sun.COM  * providerName - unique name of provider
58289585STim.Szeto@Sun.COM  * nvl - nvlist to load/retrieve
58299585STim.Szeto@Sun.COM  * providerType - logical unit or port provider
58309585STim.Szeto@Sun.COM  * setToken - returned stale data token
58319585STim.Szeto@Sun.COM  */
58329585STim.Szeto@Sun.COM int
58339585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType,
58349585STim.Szeto@Sun.COM     uint64_t *setToken)
58359585STim.Szeto@Sun.COM {
58369585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
58379585STim.Szeto@Sun.COM 	int fd;
58389585STim.Szeto@Sun.COM 	int ioctlRet;
58399585STim.Szeto@Sun.COM 	size_t nvlistSize = ALLOC_PP_DATA_SIZE;
58409585STim.Szeto@Sun.COM 	int retryCnt = 0;
58419585STim.Szeto@Sun.COM 	int retryCntMax = MAX_PROVIDER_RETRY;
58429585STim.Szeto@Sun.COM 	stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
58439585STim.Szeto@Sun.COM 	boolean_t retry = B_TRUE;
58449585STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
58459585STim.Szeto@Sun.COM 
58469585STim.Szeto@Sun.COM 	if (providerName == NULL) {
58479585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
58489585STim.Szeto@Sun.COM 	}
58499585STim.Szeto@Sun.COM 
58509585STim.Szeto@Sun.COM 	/*
58519585STim.Szeto@Sun.COM 	 * Open control node for stmf
58529585STim.Szeto@Sun.COM 	 */
58539585STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
58549585STim.Szeto@Sun.COM 		return (ret);
58559585STim.Szeto@Sun.COM 
58569585STim.Szeto@Sun.COM 	/* set provider name and provider type */
58579585STim.Szeto@Sun.COM 	if (strlcpy(ppi.ppi_name, providerName,
58589585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) >=
58599585STim.Szeto@Sun.COM 	    sizeof (ppi.ppi_name)) {
58609585STim.Szeto@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
58619585STim.Szeto@Sun.COM 		goto done;
58629585STim.Szeto@Sun.COM 	}
58639585STim.Szeto@Sun.COM 	switch (providerType) {
58649585STim.Szeto@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
58659585STim.Szeto@Sun.COM 			ppi.ppi_lu_provider = 1;
58669585STim.Szeto@Sun.COM 			break;
58679585STim.Szeto@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
58689585STim.Szeto@Sun.COM 			ppi.ppi_port_provider = 1;
58699585STim.Szeto@Sun.COM 			break;
58709585STim.Szeto@Sun.COM 		default:
58719585STim.Szeto@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
58729585STim.Szeto@Sun.COM 			goto done;
58739585STim.Szeto@Sun.COM 	}
58749585STim.Szeto@Sun.COM 
58759585STim.Szeto@Sun.COM 	do {
58769585STim.Szeto@Sun.COM 		/* allocate memory for ioctl */
58779585STim.Szeto@Sun.COM 		ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
58789585STim.Szeto@Sun.COM 		    sizeof (stmf_ppioctl_data_t));
58799585STim.Szeto@Sun.COM 		if (ppi_out == NULL) {
58809585STim.Szeto@Sun.COM 			ret = STMF_ERROR_NOMEM;
58819585STim.Szeto@Sun.COM 			goto done;
58829585STim.Szeto@Sun.COM 
58839585STim.Szeto@Sun.COM 		}
58849585STim.Szeto@Sun.COM 
58859585STim.Szeto@Sun.COM 		/* set the size of the ioctl data to allocated buffer */
58869585STim.Szeto@Sun.COM 		ppi.ppi_data_size = nvlistSize;
58879585STim.Szeto@Sun.COM 
58889585STim.Szeto@Sun.COM 		bzero(&stmfIoctl, sizeof (stmfIoctl));
58899585STim.Szeto@Sun.COM 
58909585STim.Szeto@Sun.COM 		stmfIoctl.stmf_version = STMF_VERSION_1;
58919585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
58929585STim.Szeto@Sun.COM 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
58939585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
58949585STim.Szeto@Sun.COM 		    nvlistSize;
58959585STim.Szeto@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
58969585STim.Szeto@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
58979585STim.Szeto@Sun.COM 		if (ioctlRet != 0) {
58989585STim.Szeto@Sun.COM 			switch (errno) {
58999585STim.Szeto@Sun.COM 				case EBUSY:
59009585STim.Szeto@Sun.COM 					ret = STMF_ERROR_BUSY;
59019585STim.Szeto@Sun.COM 					break;
59029585STim.Szeto@Sun.COM 				case EPERM:
59039585STim.Szeto@Sun.COM 				case EACCES:
59049585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PERM;
59059585STim.Szeto@Sun.COM 					break;
59069585STim.Szeto@Sun.COM 				case EINVAL:
59079585STim.Szeto@Sun.COM 					if (stmfIoctl.stmf_error ==
59089585STim.Szeto@Sun.COM 					    STMF_IOCERR_INSUFFICIENT_BUF) {
59099585STim.Szeto@Sun.COM 						nvlistSize =
59109585STim.Szeto@Sun.COM 						    ppi_out->ppi_data_size;
59119585STim.Szeto@Sun.COM 						free(ppi_out);
59129585STim.Szeto@Sun.COM 						ppi_out = NULL;
59139585STim.Szeto@Sun.COM 						if (retryCnt++ > retryCntMax) {
59149585STim.Szeto@Sun.COM 							retry = B_FALSE;
59159585STim.Szeto@Sun.COM 							ret = STMF_ERROR_BUSY;
59169585STim.Szeto@Sun.COM 						} else {
59179585STim.Szeto@Sun.COM 							ret =
59189585STim.Szeto@Sun.COM 							    STMF_STATUS_SUCCESS;
59199585STim.Szeto@Sun.COM 						}
59209585STim.Szeto@Sun.COM 					} else {
59219585STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
59229585STim.Szeto@Sun.COM 						    "getProviderData:ioctl"
59239585STim.Szeto@Sun.COM 						    "unable to retrieve "
59249585STim.Szeto@Sun.COM 						    "nvlist");
59259585STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
59269585STim.Szeto@Sun.COM 					}
59279585STim.Szeto@Sun.COM 					break;
59289585STim.Szeto@Sun.COM 				case ENOENT:
59299585STim.Szeto@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
59309585STim.Szeto@Sun.COM 					break;
59319585STim.Szeto@Sun.COM 				default:
59329585STim.Szeto@Sun.COM 					syslog(LOG_DEBUG,
59339585STim.Szeto@Sun.COM 					    "getProviderData:ioctl errno(%d)",
59349585STim.Szeto@Sun.COM 					    errno);
59359585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
59369585STim.Szeto@Sun.COM 					break;
59379585STim.Szeto@Sun.COM 			}
59389585STim.Szeto@Sun.COM 			if (ret != STMF_STATUS_SUCCESS)
59399585STim.Szeto@Sun.COM 				goto done;
59409585STim.Szeto@Sun.COM 		}
59419585STim.Szeto@Sun.COM 	} while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
59429585STim.Szeto@Sun.COM 
59439585STim.Szeto@Sun.COM 	if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
59449585STim.Szeto@Sun.COM 	    ppi_out->ppi_data_size, nvl, 0)) != 0) {
59459585STim.Szeto@Sun.COM 		ret = STMF_STATUS_ERROR;
59469585STim.Szeto@Sun.COM 		goto done;
59479585STim.Szeto@Sun.COM 	}
59489585STim.Szeto@Sun.COM 
59499585STim.Szeto@Sun.COM 	/* caller has asked for new token */
59509585STim.Szeto@Sun.COM 	if (setToken) {
59519585STim.Szeto@Sun.COM 		*setToken = ppi_out->ppi_token;
59529585STim.Szeto@Sun.COM 	}
59539585STim.Szeto@Sun.COM done:
59549585STim.Szeto@Sun.COM 	free(ppi_out);
59559585STim.Szeto@Sun.COM 	(void) close(fd);
59569585STim.Szeto@Sun.COM 	return (ret);
59579585STim.Szeto@Sun.COM }
59589585STim.Szeto@Sun.COM 
59599585STim.Szeto@Sun.COM /*
59607836SJohn.Forte@Sun.COM  * setProviderData
59617836SJohn.Forte@Sun.COM  *
59629585STim.Szeto@Sun.COM  * Purpose: set the provider data in stmf
59637836SJohn.Forte@Sun.COM  *
59647836SJohn.Forte@Sun.COM  * providerName - unique name of provider
59657836SJohn.Forte@Sun.COM  * nvl - nvlist to set
59667836SJohn.Forte@Sun.COM  * providerType - logical unit or port provider
59679585STim.Szeto@Sun.COM  * setToken - stale data token to check if not NULL
59687836SJohn.Forte@Sun.COM  */
59697836SJohn.Forte@Sun.COM static int
59709585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
59719585STim.Szeto@Sun.COM     uint64_t *setToken)
59727836SJohn.Forte@Sun.COM {
59737836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
59747836SJohn.Forte@Sun.COM 	int ioctlRet;
59757836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
59767836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t *ppi = NULL;
59779585STim.Szeto@Sun.COM 	uint64_t outToken;
59787836SJohn.Forte@Sun.COM 	char *allocatedNvBuffer;
59797836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
59807836SJohn.Forte@Sun.COM 
59817836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
59827836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
59837836SJohn.Forte@Sun.COM 	}
59847836SJohn.Forte@Sun.COM 
59857836SJohn.Forte@Sun.COM 	/* get size of encoded nvlist */
59867836SJohn.Forte@Sun.COM 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
59877836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
59887836SJohn.Forte@Sun.COM 	}
59897836SJohn.Forte@Sun.COM 
59907836SJohn.Forte@Sun.COM 	/* allocate memory for ioctl */
59917836SJohn.Forte@Sun.COM 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
59927836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t));
59937836SJohn.Forte@Sun.COM 	if (ppi == NULL) {
59947836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
59957836SJohn.Forte@Sun.COM 	}
59967836SJohn.Forte@Sun.COM 
59979585STim.Szeto@Sun.COM 	if (setToken) {
59989585STim.Szeto@Sun.COM 		ppi->ppi_token_valid = 1;
59999585STim.Szeto@Sun.COM 		ppi->ppi_token = *setToken;
60009585STim.Szeto@Sun.COM 	}
60019585STim.Szeto@Sun.COM 
60027836SJohn.Forte@Sun.COM 	allocatedNvBuffer = (char *)&ppi->ppi_data;
60037836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
60047836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
60057836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
60067836SJohn.Forte@Sun.COM 	}
60077836SJohn.Forte@Sun.COM 
60087836SJohn.Forte@Sun.COM 	/* set provider name and provider type */
60097836SJohn.Forte@Sun.COM 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
60107836SJohn.Forte@Sun.COM 	switch (providerType) {
60117836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
60127836SJohn.Forte@Sun.COM 			ppi->ppi_lu_provider = 1;
60137836SJohn.Forte@Sun.COM 			break;
60147836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
60157836SJohn.Forte@Sun.COM 			ppi->ppi_port_provider = 1;
60167836SJohn.Forte@Sun.COM 			break;
60177836SJohn.Forte@Sun.COM 		default:
60187836SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
60197836SJohn.Forte@Sun.COM 	}
60207836SJohn.Forte@Sun.COM 
60217836SJohn.Forte@Sun.COM 	/* set the size of the ioctl data to packed data size */
60227836SJohn.Forte@Sun.COM 	ppi->ppi_data_size = nvlistEncodedSize;
60237836SJohn.Forte@Sun.COM 
60247836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
60257836SJohn.Forte@Sun.COM 
60267836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
60277836SJohn.Forte@Sun.COM 	/*
60287836SJohn.Forte@Sun.COM 	 * Subtracting 8 from the size as that is the size of the last member
60297836SJohn.Forte@Sun.COM 	 * of the structure where the packed data resides
60307836SJohn.Forte@Sun.COM 	 */
60317836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
60327836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t) - 8;
60337836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
60349585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
60359585STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
60367836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
60377836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
60387836SJohn.Forte@Sun.COM 		switch (errno) {
60397836SJohn.Forte@Sun.COM 			case EBUSY:
60407836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
60417836SJohn.Forte@Sun.COM 				break;
60429585STim.Szeto@Sun.COM 			case EPERM:
60437836SJohn.Forte@Sun.COM 			case EACCES:
60447836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
60457836SJohn.Forte@Sun.COM 				break;
60469585STim.Szeto@Sun.COM 			case EINVAL:
60479585STim.Szeto@Sun.COM 				if (stmfIoctl.stmf_error ==
60489585STim.Szeto@Sun.COM 				    STMF_IOCERR_PPD_UPDATED) {
60499585STim.Szeto@Sun.COM 					ret = STMF_ERROR_PROV_DATA_STALE;
60509585STim.Szeto@Sun.COM 				} else {
60519585STim.Szeto@Sun.COM 					ret = STMF_STATUS_ERROR;
60529585STim.Szeto@Sun.COM 				}
60539585STim.Szeto@Sun.COM 				break;
60547836SJohn.Forte@Sun.COM 			default:
60557836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
60567836SJohn.Forte@Sun.COM 				    "setProviderData:ioctl errno(%d)", errno);
60577836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
60587836SJohn.Forte@Sun.COM 				break;
60597836SJohn.Forte@Sun.COM 		}
60607836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS)
60617836SJohn.Forte@Sun.COM 			goto done;
60627836SJohn.Forte@Sun.COM 	}
60637836SJohn.Forte@Sun.COM 
60649585STim.Szeto@Sun.COM 	/* caller has asked for new token */
60659585STim.Szeto@Sun.COM 	if (setToken) {
60669585STim.Szeto@Sun.COM 		*setToken = outToken;
60679585STim.Szeto@Sun.COM 	}
60687836SJohn.Forte@Sun.COM done:
60697836SJohn.Forte@Sun.COM 	free(ppi);
60707836SJohn.Forte@Sun.COM 	return (ret);
60717836SJohn.Forte@Sun.COM }
60729585STim.Szeto@Sun.COM 
60739585STim.Szeto@Sun.COM /*
60749585STim.Szeto@Sun.COM  * set the persistence method in the library only or library and service
60759585STim.Szeto@Sun.COM  */
60769585STim.Szeto@Sun.COM int
60779585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
60789585STim.Szeto@Sun.COM {
60799585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
60809585STim.Szeto@Sun.COM 	int oldPersist;
60819585STim.Szeto@Sun.COM 
60829585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
60839585STim.Szeto@Sun.COM 	oldPersist = iPersistType;
60849585STim.Szeto@Sun.COM 	if (persistType == STMF_PERSIST_NONE ||
60859585STim.Szeto@Sun.COM 	    persistType == STMF_PERSIST_SMF) {
60869585STim.Szeto@Sun.COM 		iLibSetPersist = B_TRUE;
60879585STim.Szeto@Sun.COM 		iPersistType = persistType;
60889585STim.Szeto@Sun.COM 	} else {
60899585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
60909585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
60919585STim.Szeto@Sun.COM 	}
60929585STim.Szeto@Sun.COM 	/* Is this for this library open or in SMF */
60939585STim.Szeto@Sun.COM 	if (serviceSet == B_TRUE) {
60949585STim.Szeto@Sun.COM 		ret = psSetServicePersist(persistType);
60959585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
60969585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
60979585STim.Szeto@Sun.COM 			/* Set to old value */
60989585STim.Szeto@Sun.COM 			iPersistType = oldPersist;
60999585STim.Szeto@Sun.COM 		}
61009585STim.Szeto@Sun.COM 	}
61019585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
61029585STim.Szeto@Sun.COM 
61039585STim.Szeto@Sun.COM 	return (ret);
61049585STim.Szeto@Sun.COM }
61059585STim.Szeto@Sun.COM 
61069585STim.Szeto@Sun.COM /*
61079585STim.Szeto@Sun.COM  * Only returns internal state for persist. If unset, goes to ps. If that
61089585STim.Szeto@Sun.COM  * fails, returns default setting
61099585STim.Szeto@Sun.COM  */
61109585STim.Szeto@Sun.COM static uint8_t
61119585STim.Szeto@Sun.COM iGetPersistMethod()
61129585STim.Szeto@Sun.COM {
61139585STim.Szeto@Sun.COM 
61149585STim.Szeto@Sun.COM 	uint8_t persistType = 0;
61159585STim.Szeto@Sun.COM 
61169585STim.Szeto@Sun.COM 	(void) pthread_mutex_lock(&persistenceTypeLock);
61179585STim.Szeto@Sun.COM 	if (iLibSetPersist) {
61189585STim.Szeto@Sun.COM 		persistType = iPersistType;
61199585STim.Szeto@Sun.COM 	} else {
61209585STim.Szeto@Sun.COM 		int ret;
61219585STim.Szeto@Sun.COM 		ret = psGetServicePersist(&persistType);
61229585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
61239585STim.Szeto@Sun.COM 			/* set to default */
61249585STim.Szeto@Sun.COM 			persistType = STMF_DEFAULT_PERSIST;
61259585STim.Szeto@Sun.COM 		}
61269585STim.Szeto@Sun.COM 	}
61279585STim.Szeto@Sun.COM 	(void) pthread_mutex_unlock(&persistenceTypeLock);
61289585STim.Szeto@Sun.COM 	return (persistType);
61299585STim.Szeto@Sun.COM }
61309585STim.Szeto@Sun.COM 
61319585STim.Szeto@Sun.COM /*
61329585STim.Szeto@Sun.COM  * Returns either library state or persistent config state depending on
61339585STim.Szeto@Sun.COM  * serviceState
61349585STim.Szeto@Sun.COM  */
61359585STim.Szeto@Sun.COM int
61369585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
61379585STim.Szeto@Sun.COM {
61389585STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
61399585STim.Szeto@Sun.COM 
61409585STim.Szeto@Sun.COM 	if (persistType == NULL) {
61419585STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
61429585STim.Szeto@Sun.COM 	}
61439585STim.Szeto@Sun.COM 	if (serviceState) {
61449585STim.Szeto@Sun.COM 		ret = psGetServicePersist(persistType);
61459585STim.Szeto@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
61469585STim.Szeto@Sun.COM 			ret = STMF_ERROR_PERSIST_TYPE;
61479585STim.Szeto@Sun.COM 		}
61489585STim.Szeto@Sun.COM 	} else {
61499585STim.Szeto@Sun.COM 		(void) pthread_mutex_lock(&persistenceTypeLock);
61509585STim.Szeto@Sun.COM 		if (iLibSetPersist) {
61519585STim.Szeto@Sun.COM 			*persistType = iPersistType;
61529585STim.Szeto@Sun.COM 		} else {
61539585STim.Szeto@Sun.COM 			*persistType = STMF_DEFAULT_PERSIST;
61549585STim.Szeto@Sun.COM 		}
61559585STim.Szeto@Sun.COM 		(void) pthread_mutex_unlock(&persistenceTypeLock);
61569585STim.Szeto@Sun.COM 	}
61579585STim.Szeto@Sun.COM 
61589585STim.Szeto@Sun.COM 	return (ret);
61599585STim.Szeto@Sun.COM }
616010691STim.Szeto@Sun.COM 
616110691STim.Szeto@Sun.COM /*
6162*10725SJohn.Forte@Sun.COM  * stmfPostProxyMsg
6163*10725SJohn.Forte@Sun.COM  *
6164*10725SJohn.Forte@Sun.COM  * Purpose: Post a message to the proxy port provider
6165*10725SJohn.Forte@Sun.COM  *
6166*10725SJohn.Forte@Sun.COM  * buf - buffer containing message to post
6167*10725SJohn.Forte@Sun.COM  * buflen - buffer length
6168*10725SJohn.Forte@Sun.COM  */
6169*10725SJohn.Forte@Sun.COM int
6170*10725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen)
6171*10725SJohn.Forte@Sun.COM {
6172*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
6173*10725SJohn.Forte@Sun.COM 	int ioctlRet;
6174*10725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
6175*10725SJohn.Forte@Sun.COM 
6176*10725SJohn.Forte@Sun.COM 	if (buf == NULL) {
6177*10725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
6178*10725SJohn.Forte@Sun.COM 	}
6179*10725SJohn.Forte@Sun.COM 
6180*10725SJohn.Forte@Sun.COM 	/*
6181*10725SJohn.Forte@Sun.COM 	 * Issue ioctl to post the message
6182*10725SJohn.Forte@Sun.COM 	 */
6183*10725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
6184*10725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf_size = buflen;
6185*10725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf;
6186*10725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl);
6187*10725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
6188*10725SJohn.Forte@Sun.COM 		switch (errno) {
6189*10725SJohn.Forte@Sun.COM 			case EPERM:
6190*10725SJohn.Forte@Sun.COM 			case EACCES:
6191*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
6192*10725SJohn.Forte@Sun.COM 				break;
6193*10725SJohn.Forte@Sun.COM 			default:
6194*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_POST_MSG_FAILED;
6195*10725SJohn.Forte@Sun.COM 				break;
6196*10725SJohn.Forte@Sun.COM 		}
6197*10725SJohn.Forte@Sun.COM 	}
6198*10725SJohn.Forte@Sun.COM 
6199*10725SJohn.Forte@Sun.COM 	return (ret);
6200*10725SJohn.Forte@Sun.COM }
6201*10725SJohn.Forte@Sun.COM 
6202*10725SJohn.Forte@Sun.COM /*
6203*10725SJohn.Forte@Sun.COM  * stmfInitProxyDoor
6204*10725SJohn.Forte@Sun.COM  *
6205*10725SJohn.Forte@Sun.COM  * Purpose: Install door in proxy
6206*10725SJohn.Forte@Sun.COM  *
6207*10725SJohn.Forte@Sun.COM  * hdl - pointer to returned handle
6208*10725SJohn.Forte@Sun.COM  * fd - door from door_create()
6209*10725SJohn.Forte@Sun.COM  */
6210*10725SJohn.Forte@Sun.COM int
6211*10725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door)
6212*10725SJohn.Forte@Sun.COM {
6213*10725SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
6214*10725SJohn.Forte@Sun.COM 	int ioctlRet;
6215*10725SJohn.Forte@Sun.COM 	int fd;
6216*10725SJohn.Forte@Sun.COM 	pppt_iocdata_t ppptIoctl = {0};
6217*10725SJohn.Forte@Sun.COM 
6218*10725SJohn.Forte@Sun.COM 	if (hdl == NULL) {
6219*10725SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
6220*10725SJohn.Forte@Sun.COM 	}
6221*10725SJohn.Forte@Sun.COM 
6222*10725SJohn.Forte@Sun.COM 	/*
6223*10725SJohn.Forte@Sun.COM 	 * Open control node for pppt
6224*10725SJohn.Forte@Sun.COM 	 */
6225*10725SJohn.Forte@Sun.COM 	if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) {
6226*10725SJohn.Forte@Sun.COM 		return (ret);
6227*10725SJohn.Forte@Sun.COM 	}
6228*10725SJohn.Forte@Sun.COM 
6229*10725SJohn.Forte@Sun.COM 	/*
6230*10725SJohn.Forte@Sun.COM 	 * Issue ioctl to install the door
6231*10725SJohn.Forte@Sun.COM 	 */
6232*10725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_version = PPPT_VERSION_1;
6233*10725SJohn.Forte@Sun.COM 	ppptIoctl.pppt_door_fd = (uint32_t)door;
6234*10725SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl);
6235*10725SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
6236*10725SJohn.Forte@Sun.COM 		switch (errno) {
6237*10725SJohn.Forte@Sun.COM 			case EPERM:
6238*10725SJohn.Forte@Sun.COM 			case EACCES:
6239*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
6240*10725SJohn.Forte@Sun.COM 				break;
6241*10725SJohn.Forte@Sun.COM 			case EINVAL:
6242*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_INVALID_ARG;
6243*10725SJohn.Forte@Sun.COM 				break;
6244*10725SJohn.Forte@Sun.COM 			case EBUSY:
6245*10725SJohn.Forte@Sun.COM 				ret = STMF_ERROR_DOOR_INSTALLED;
6246*10725SJohn.Forte@Sun.COM 				break;
6247*10725SJohn.Forte@Sun.COM 			default:
6248*10725SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
6249*10725SJohn.Forte@Sun.COM 				break;
6250*10725SJohn.Forte@Sun.COM 		}
6251*10725SJohn.Forte@Sun.COM 	}
6252*10725SJohn.Forte@Sun.COM 
6253*10725SJohn.Forte@Sun.COM 	/* return driver fd to caller */
6254*10725SJohn.Forte@Sun.COM 	*hdl = fd;
6255*10725SJohn.Forte@Sun.COM 	return (ret);
6256*10725SJohn.Forte@Sun.COM }
6257*10725SJohn.Forte@Sun.COM 
6258*10725SJohn.Forte@Sun.COM void
6259*10725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl)
6260*10725SJohn.Forte@Sun.COM {
6261*10725SJohn.Forte@Sun.COM 	(void) close(hdl);
6262*10725SJohn.Forte@Sun.COM }
6263*10725SJohn.Forte@Sun.COM 
6264*10725SJohn.Forte@Sun.COM /*
626510691STim.Szeto@Sun.COM  * validateLunNumIoctl
626610691STim.Szeto@Sun.COM  *
626710691STim.Szeto@Sun.COM  * Purpose: Issues ioctl to check and get available lun# in view entry
626810691STim.Szeto@Sun.COM  *
626910691STim.Szeto@Sun.COM  * viewEntry - view entry to use
627010691STim.Szeto@Sun.COM  */
627110691STim.Szeto@Sun.COM static int
627210691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry)
627310691STim.Szeto@Sun.COM {
627410691STim.Szeto@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
627510691STim.Szeto@Sun.COM 	int ioctlRet;
627610691STim.Szeto@Sun.COM 	stmf_iocdata_t stmfIoctl;
627710691STim.Szeto@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
627810691STim.Szeto@Sun.COM 
627910691STim.Szeto@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
628010691STim.Szeto@Sun.COM 	/*
628110691STim.Szeto@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
628210691STim.Szeto@Sun.COM 	 * false on input
628310691STim.Szeto@Sun.COM 	 */
628410691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
628510691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
628610691STim.Szeto@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
628710691STim.Szeto@Sun.COM 
628810691STim.Szeto@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
628910691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
629010691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
629110691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
629210691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
629310691STim.Szeto@Sun.COM 	}
629410691STim.Szeto@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
629510691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup,
629610691STim.Szeto@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
629710691STim.Szeto@Sun.COM 		    sizeof (stmfGroupName));
629810691STim.Szeto@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
629910691STim.Szeto@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
630010691STim.Szeto@Sun.COM 	}
630110691STim.Szeto@Sun.COM 	/* Validating the lun number */
630210691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
630310691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
630410691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
630510691STim.Szeto@Sun.COM 	}
630610691STim.Szeto@Sun.COM 
630710691STim.Szeto@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
630810691STim.Szeto@Sun.COM 	/*
630910691STim.Szeto@Sun.COM 	 * Issue ioctl to validate lun# in the view entry
631010691STim.Szeto@Sun.COM 	 */
631110691STim.Szeto@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
631210691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
631310691STim.Szeto@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
631410691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
631510691STim.Szeto@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
631610691STim.Szeto@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl);
631710691STim.Szeto@Sun.COM 
631810691STim.Szeto@Sun.COM 	/* save available lun number */
631910691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
632010691STim.Szeto@Sun.COM 		bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
632110691STim.Szeto@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
632210691STim.Szeto@Sun.COM 	}
632310691STim.Szeto@Sun.COM 	if (ioctlRet != 0) {
632410691STim.Szeto@Sun.COM 		switch (errno) {
632510691STim.Szeto@Sun.COM 			case EBUSY:
632610691STim.Szeto@Sun.COM 				ret = STMF_ERROR_BUSY;
632710691STim.Szeto@Sun.COM 				break;
632810691STim.Szeto@Sun.COM 			case EPERM:
632910691STim.Szeto@Sun.COM 				ret = STMF_ERROR_PERM;
633010691STim.Szeto@Sun.COM 				break;
633110691STim.Szeto@Sun.COM 			case EACCES:
633210691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
633310691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
633410691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
633510691STim.Szeto@Sun.COM 						break;
633610691STim.Szeto@Sun.COM 					default:
633710691STim.Szeto@Sun.COM 						ret = STMF_ERROR_PERM;
633810691STim.Szeto@Sun.COM 						break;
633910691STim.Szeto@Sun.COM 				}
634010691STim.Szeto@Sun.COM 				break;
634110691STim.Szeto@Sun.COM 			default:
634210691STim.Szeto@Sun.COM 				switch (stmfIoctl.stmf_error) {
634310691STim.Szeto@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
634410691STim.Szeto@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
634510691STim.Szeto@Sun.COM 						break;
634610691STim.Szeto@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
634710691STim.Szeto@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
634810691STim.Szeto@Sun.COM 						break;
634910691STim.Szeto@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
635010691STim.Szeto@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
635110691STim.Szeto@Sun.COM 						break;
635210691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_HG:
635310691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
635410691STim.Szeto@Sun.COM 						break;
635510691STim.Szeto@Sun.COM 					case STMF_IOCERR_INVALID_TG:
635610691STim.Szeto@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
635710691STim.Szeto@Sun.COM 						break;
635810691STim.Szeto@Sun.COM 					default:
635910691STim.Szeto@Sun.COM 						syslog(LOG_DEBUG,
636010691STim.Szeto@Sun.COM 						    "addViewEntryIoctl"
636110691STim.Szeto@Sun.COM 						    ":error(%d)",
636210691STim.Szeto@Sun.COM 						    stmfIoctl.stmf_error);
636310691STim.Szeto@Sun.COM 						ret = STMF_STATUS_ERROR;
636410691STim.Szeto@Sun.COM 						break;
636510691STim.Szeto@Sun.COM 				}
636610691STim.Szeto@Sun.COM 				break;
636710691STim.Szeto@Sun.COM 		}
636810691STim.Szeto@Sun.COM 	}
636910691STim.Szeto@Sun.COM 	return (ret);
637010691STim.Szeto@Sun.COM }
637110691STim.Szeto@Sun.COM 
637210691STim.Szeto@Sun.COM /*
637310691STim.Szeto@Sun.COM  * stmfValidateView
637410691STim.Szeto@Sun.COM  *
637510691STim.Szeto@Sun.COM  * Purpose: Validate or get lun # base on TG, HG of view entry
637610691STim.Szeto@Sun.COM  *
637710691STim.Szeto@Sun.COM  * viewEntry - view entry structure to use
637810691STim.Szeto@Sun.COM  */
637910691STim.Szeto@Sun.COM int
638010691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry)
638110691STim.Szeto@Sun.COM {
638210691STim.Szeto@Sun.COM 	int ret;
638310691STim.Szeto@Sun.COM 	int fd;
638410691STim.Szeto@Sun.COM 	stmfViewEntry iViewEntry;
638510691STim.Szeto@Sun.COM 
638610691STim.Szeto@Sun.COM 	if (viewEntry == NULL) {
638710691STim.Szeto@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
638810691STim.Szeto@Sun.COM 	}
638910691STim.Szeto@Sun.COM 
639010691STim.Szeto@Sun.COM 	/* initialize and set internal view entry */
639110691STim.Szeto@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
639210691STim.Szeto@Sun.COM 
639310691STim.Szeto@Sun.COM 	if (!viewEntry->allHosts) {
639410691STim.Szeto@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
639510691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.hostGroup));
639610691STim.Szeto@Sun.COM 	} else {
639710691STim.Szeto@Sun.COM 		iViewEntry.allHosts = B_TRUE;
639810691STim.Szeto@Sun.COM 	}
639910691STim.Szeto@Sun.COM 
640010691STim.Szeto@Sun.COM 	if (!viewEntry->allTargets) {
640110691STim.Szeto@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
640210691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.targetGroup));
640310691STim.Szeto@Sun.COM 	} else {
640410691STim.Szeto@Sun.COM 		iViewEntry.allTargets = B_TRUE;
640510691STim.Szeto@Sun.COM 	}
640610691STim.Szeto@Sun.COM 
640710691STim.Szeto@Sun.COM 	if (viewEntry->luNbrValid) {
640810691STim.Szeto@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
640910691STim.Szeto@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
641010691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
641110691STim.Szeto@Sun.COM 	}
641210691STim.Szeto@Sun.COM 
641310691STim.Szeto@Sun.COM 	/*
641410691STim.Szeto@Sun.COM 	 * set users return view entry index valid flag to false
641510691STim.Szeto@Sun.COM 	 * in case of failure
641610691STim.Szeto@Sun.COM 	 */
641710691STim.Szeto@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
641810691STim.Szeto@Sun.COM 
641910691STim.Szeto@Sun.COM 	/* Check to ensure service exists */
642010691STim.Szeto@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
642110691STim.Szeto@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
642210691STim.Szeto@Sun.COM 	}
642310691STim.Szeto@Sun.COM 
642410691STim.Szeto@Sun.COM 	/* call init */
642510691STim.Szeto@Sun.COM 	ret = initializeConfig();
642610691STim.Szeto@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
642710691STim.Szeto@Sun.COM 		return (ret);
642810691STim.Szeto@Sun.COM 	}
642910691STim.Szeto@Sun.COM 
643010691STim.Szeto@Sun.COM 	/*
643110691STim.Szeto@Sun.COM 	 * Open control node for stmf
643210691STim.Szeto@Sun.COM 	 */
643310691STim.Szeto@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
643410691STim.Szeto@Sun.COM 		return (ret);
643510691STim.Szeto@Sun.COM 
643610691STim.Szeto@Sun.COM 	/*
643710691STim.Szeto@Sun.COM 	 * Validate lun# in the view entry from the driver
643810691STim.Szeto@Sun.COM 	 */
643910691STim.Szeto@Sun.COM 	ret = validateLunNumIoctl(fd, &iViewEntry);
644010691STim.Szeto@Sun.COM 	(void) close(fd);
644110691STim.Szeto@Sun.COM 
644210691STim.Szeto@Sun.COM 	/* save available lun number */
644310691STim.Szeto@Sun.COM 	if (!viewEntry->luNbrValid) {
644410691STim.Szeto@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
644510691STim.Szeto@Sun.COM 		    sizeof (iViewEntry.luNbr));
644610691STim.Szeto@Sun.COM 	}
644710691STim.Szeto@Sun.COM 
644810691STim.Szeto@Sun.COM 	return (ret);
644910691STim.Szeto@Sun.COM }
6450