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 /*
227836SJohn.Forte@Sun.COM  * Copyright 2008 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>
467836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h>
477836SJohn.Forte@Sun.COM 
487836SJohn.Forte@Sun.COM #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
497836SJohn.Forte@Sun.COM 
507836SJohn.Forte@Sun.COM #define	EUI "eui."
517836SJohn.Forte@Sun.COM #define	WWN "wwn."
527836SJohn.Forte@Sun.COM #define	IQN "iqn."
537836SJohn.Forte@Sun.COM #define	WWN_ASCII_SIZE 16
547836SJohn.Forte@Sun.COM #define	IDENT_LENGTH_BYTE 3
557836SJohn.Forte@Sun.COM 
567836SJohn.Forte@Sun.COM #define	MAX_LU		2<<16 - 1
577836SJohn.Forte@Sun.COM #define	MAX_TARGET_PORT	1024
587836SJohn.Forte@Sun.COM #define	MAX_PROVIDER	1024
597836SJohn.Forte@Sun.COM #define	MAX_GROUP	1024
607836SJohn.Forte@Sun.COM #define	MAX_SESSION	1024
617836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME	223
627836SJohn.Forte@Sun.COM 
637836SJohn.Forte@Sun.COM #define	OPEN_STMF 0
647836SJohn.Forte@Sun.COM #define	OPEN_EXCL_STMF O_EXCL
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_TYPE 0
677836SJohn.Forte@Sun.COM #define	TARGET_TYPE 1
687836SJohn.Forte@Sun.COM #define	STMF_SERVICE_TYPE 2
697836SJohn.Forte@Sun.COM 
707836SJohn.Forte@Sun.COM static int openStmf(int, int *fd);
717836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *);
727836SJohn.Forte@Sun.COM static int loadStore(int fd);
737836SJohn.Forte@Sun.COM static int initializeConfig();
747836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
757836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *);
767836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
777836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *);
787836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *);
797836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *);
807836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int);
817836SJohn.Forte@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int);
827836SJohn.Forte@Sun.COM 
837836SJohn.Forte@Sun.COM /*
847836SJohn.Forte@Sun.COM  * Open for stmf module
857836SJohn.Forte@Sun.COM  *
867836SJohn.Forte@Sun.COM  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
877836SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
887836SJohn.Forte@Sun.COM  */
897836SJohn.Forte@Sun.COM static int
907836SJohn.Forte@Sun.COM openStmf(int flag, int *fd)
917836SJohn.Forte@Sun.COM {
927836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
937836SJohn.Forte@Sun.COM 
947836SJohn.Forte@Sun.COM 	if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
957836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
967836SJohn.Forte@Sun.COM 	} else {
977836SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
987836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
997836SJohn.Forte@Sun.COM 		} else {
1007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1017836SJohn.Forte@Sun.COM 		}
1027836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
1037836SJohn.Forte@Sun.COM 		    STMF_PATH, errno);
1047836SJohn.Forte@Sun.COM 	}
1057836SJohn.Forte@Sun.COM 
1067836SJohn.Forte@Sun.COM 	return (ret);
1077836SJohn.Forte@Sun.COM }
1087836SJohn.Forte@Sun.COM 
1097836SJohn.Forte@Sun.COM /*
1107836SJohn.Forte@Sun.COM  * initializeConfig
1117836SJohn.Forte@Sun.COM  *
1127836SJohn.Forte@Sun.COM  * This routine should be called before any ioctl requiring initialization
1137836SJohn.Forte@Sun.COM  * which is basically everything except stmfGetState(), setStmfState() and
1147836SJohn.Forte@Sun.COM  * stmfLoadConfig().
1157836SJohn.Forte@Sun.COM  */
1167836SJohn.Forte@Sun.COM static int
1177836SJohn.Forte@Sun.COM initializeConfig()
1187836SJohn.Forte@Sun.COM {
1197836SJohn.Forte@Sun.COM 	int ret;
1207836SJohn.Forte@Sun.COM 	stmfState state;
1217836SJohn.Forte@Sun.COM 
1227836SJohn.Forte@Sun.COM 
1237836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
1247836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1257836SJohn.Forte@Sun.COM 		return (ret);
1267836SJohn.Forte@Sun.COM 	}
1277836SJohn.Forte@Sun.COM 
1287836SJohn.Forte@Sun.COM 	/* if we've already initialized or in the process, return success */
1297836SJohn.Forte@Sun.COM 	if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
1307836SJohn.Forte@Sun.COM 	    state.configState == STMF_CONFIG_STATE_INIT) {
1317836SJohn.Forte@Sun.COM 		return (STMF_STATUS_SUCCESS);
1327836SJohn.Forte@Sun.COM 	}
1337836SJohn.Forte@Sun.COM 
1347836SJohn.Forte@Sun.COM 	ret = stmfLoadConfig();
1357836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1367836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
1377836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfLoadConfig:error(%d)", ret);
1387836SJohn.Forte@Sun.COM 		return (ret);
1397836SJohn.Forte@Sun.COM 	}
1407836SJohn.Forte@Sun.COM 
1417836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
1427836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1437836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
1447836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfGetState:error(%d)", ret);
1457836SJohn.Forte@Sun.COM 		return (ret);
1467836SJohn.Forte@Sun.COM 	}
1477836SJohn.Forte@Sun.COM 
1487836SJohn.Forte@Sun.COM 	if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
1497836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
1507836SJohn.Forte@Sun.COM 		    state.configState);
1517836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_ERROR;
1527836SJohn.Forte@Sun.COM 	}
1537836SJohn.Forte@Sun.COM 
1547836SJohn.Forte@Sun.COM 	return (ret);
1557836SJohn.Forte@Sun.COM }
1567836SJohn.Forte@Sun.COM 
1577836SJohn.Forte@Sun.COM 
1587836SJohn.Forte@Sun.COM /*
1597836SJohn.Forte@Sun.COM  * groupIoctl
1607836SJohn.Forte@Sun.COM  *
1617836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for create/delete on group
1627836SJohn.Forte@Sun.COM  *
1637836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group cmd
1647836SJohn.Forte@Sun.COM  * groupName - groupName to create or delete
1657836SJohn.Forte@Sun.COM  */
1667836SJohn.Forte@Sun.COM static int
1677836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName)
1687836SJohn.Forte@Sun.COM {
1697836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
1707836SJohn.Forte@Sun.COM 	int ioctlRet;
1717836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
1727836SJohn.Forte@Sun.COM 	stmf_group_name_t iGroupName;
1737836SJohn.Forte@Sun.COM 
1747836SJohn.Forte@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
1757836SJohn.Forte@Sun.COM 
1767836SJohn.Forte@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
1777836SJohn.Forte@Sun.COM 
1787836SJohn.Forte@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
1797836SJohn.Forte@Sun.COM 
1807836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
1817836SJohn.Forte@Sun.COM 	/*
1827836SJohn.Forte@Sun.COM 	 * Issue ioctl to create the host group
1837836SJohn.Forte@Sun.COM 	 */
1847836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
1857836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
1867836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
1877836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
1887836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
1897836SJohn.Forte@Sun.COM 		switch (errno) {
1907836SJohn.Forte@Sun.COM 			case EACCES:
1917836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
1927836SJohn.Forte@Sun.COM 				break;
1937836SJohn.Forte@Sun.COM 			default:
1947836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
1957836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_EXISTS:
1967836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_EXISTS:
1977836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
1987836SJohn.Forte@Sun.COM 						break;
1997836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_IN_USE:
2007836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_IN_USE:
2017836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_GROUP_IN_USE;
2027836SJohn.Forte@Sun.COM 						break;
2037836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
2047836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
2057836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
2067836SJohn.Forte@Sun.COM 						break;
2077836SJohn.Forte@Sun.COM 					default:
2087836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
2097836SJohn.Forte@Sun.COM 						    "groupIoctl:error(%d)",
2107836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
2117836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
2127836SJohn.Forte@Sun.COM 						break;
2137836SJohn.Forte@Sun.COM 				}
2147836SJohn.Forte@Sun.COM 				break;
2157836SJohn.Forte@Sun.COM 		}
2167836SJohn.Forte@Sun.COM 	}
2177836SJohn.Forte@Sun.COM done:
2187836SJohn.Forte@Sun.COM 	return (ret);
2197836SJohn.Forte@Sun.COM }
2207836SJohn.Forte@Sun.COM 
2217836SJohn.Forte@Sun.COM /*
2227836SJohn.Forte@Sun.COM  * groupIoctl
2237836SJohn.Forte@Sun.COM  *
2247836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for add/remove member on group
2257836SJohn.Forte@Sun.COM  *
2267836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group member cmd
2277836SJohn.Forte@Sun.COM  * groupName - groupName to add to or remove from
2287836SJohn.Forte@Sun.COM  * devid - group member to add or remove
2297836SJohn.Forte@Sun.COM  */
2307836SJohn.Forte@Sun.COM static int
2317836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
2327836SJohn.Forte@Sun.COM {
2337836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2347836SJohn.Forte@Sun.COM 	int ioctlRet;
2357836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2367836SJohn.Forte@Sun.COM 	stmf_group_op_data_t stmfGroupData;
2377836SJohn.Forte@Sun.COM 
2387836SJohn.Forte@Sun.COM 	bzero(&stmfGroupData, sizeof (stmfGroupData));
2397836SJohn.Forte@Sun.COM 
2407836SJohn.Forte@Sun.COM 	bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
2417836SJohn.Forte@Sun.COM 
2427836SJohn.Forte@Sun.COM 	stmfGroupData.group.name_size = strlen((char *)groupName);
2437836SJohn.Forte@Sun.COM 	stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
2447836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
2457836SJohn.Forte@Sun.COM 	    devid->identLength);
2467836SJohn.Forte@Sun.COM 
2477836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
2487836SJohn.Forte@Sun.COM 	/*
2497836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
2507836SJohn.Forte@Sun.COM 	 */
2517836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
2527836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
2537836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
2547836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
2557836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
2567836SJohn.Forte@Sun.COM 		switch (errno) {
2577836SJohn.Forte@Sun.COM 			case EBUSY:
2587836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2597836SJohn.Forte@Sun.COM 				break;
2607836SJohn.Forte@Sun.COM 			case EACCES:
2617836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
2627836SJohn.Forte@Sun.COM 				break;
2637836SJohn.Forte@Sun.COM 			default:
2647836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
2657836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_ENTRY_EXISTS:
2667836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_ENTRY_EXISTS:
2677836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
2687836SJohn.Forte@Sun.COM 						break;
2697836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG_ENTRY:
2707836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG_ENTRY:
2717836SJohn.Forte@Sun.COM 						ret =
2727836SJohn.Forte@Sun.COM 						    STMF_ERROR_MEMBER_NOT_FOUND;
2737836SJohn.Forte@Sun.COM 						break;
2747836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
2757836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
2767836SJohn.Forte@Sun.COM 						ret =
2777836SJohn.Forte@Sun.COM 						    STMF_ERROR_GROUP_NOT_FOUND;
2787836SJohn.Forte@Sun.COM 						break;
2797836SJohn.Forte@Sun.COM 					default:
2807836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
2817836SJohn.Forte@Sun.COM 						    "groupMemberIoctl:error"
2827836SJohn.Forte@Sun.COM 						    "(%d)",
2837836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
2847836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
2857836SJohn.Forte@Sun.COM 						break;
2867836SJohn.Forte@Sun.COM 				}
2877836SJohn.Forte@Sun.COM 				break;
2887836SJohn.Forte@Sun.COM 		}
2897836SJohn.Forte@Sun.COM 	}
2907836SJohn.Forte@Sun.COM done:
2917836SJohn.Forte@Sun.COM 	return (ret);
2927836SJohn.Forte@Sun.COM }
2937836SJohn.Forte@Sun.COM 
2947836SJohn.Forte@Sun.COM /*
2957836SJohn.Forte@Sun.COM  * guidCompare
2967836SJohn.Forte@Sun.COM  *
2977836SJohn.Forte@Sun.COM  * qsort function
2987836SJohn.Forte@Sun.COM  * sort on guid
2997836SJohn.Forte@Sun.COM  */
3007836SJohn.Forte@Sun.COM static int
3017836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2)
3027836SJohn.Forte@Sun.COM {
3037836SJohn.Forte@Sun.COM 
3047836SJohn.Forte@Sun.COM 	stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
3057836SJohn.Forte@Sun.COM 	int i;
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM 	for (i = 0; i < sizeof (stmfGuid); i++) {
3087836SJohn.Forte@Sun.COM 		if (g1->guid[i] > g2->guid[i])
3097836SJohn.Forte@Sun.COM 			return (1);
3107836SJohn.Forte@Sun.COM 		if (g1->guid[i] < g2->guid[i])
3117836SJohn.Forte@Sun.COM 			return (-1);
3127836SJohn.Forte@Sun.COM 	}
3137836SJohn.Forte@Sun.COM 
3147836SJohn.Forte@Sun.COM 	return (0);
3157836SJohn.Forte@Sun.COM }
3167836SJohn.Forte@Sun.COM 
3177836SJohn.Forte@Sun.COM /*
3187836SJohn.Forte@Sun.COM  * stmfAddToHostGroup
3197836SJohn.Forte@Sun.COM  *
3207836SJohn.Forte@Sun.COM  * Purpose: Adds an initiator to an existing host group
3217836SJohn.Forte@Sun.COM  *
3227836SJohn.Forte@Sun.COM  * hostGroupName - name of an existing host group
3237836SJohn.Forte@Sun.COM  * hostName - name of initiator to add
3247836SJohn.Forte@Sun.COM  */
3257836SJohn.Forte@Sun.COM int
3267836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
3277836SJohn.Forte@Sun.COM {
3287836SJohn.Forte@Sun.COM 	int ret;
3297836SJohn.Forte@Sun.COM 	int fd;
3307836SJohn.Forte@Sun.COM 
3317836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
3327836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
3337836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
3347836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
3357836SJohn.Forte@Sun.COM 	}
3367836SJohn.Forte@Sun.COM 
3377836SJohn.Forte@Sun.COM 	/* call init */
3387836SJohn.Forte@Sun.COM 	ret = initializeConfig();
3397836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
3407836SJohn.Forte@Sun.COM 		return (ret);
3417836SJohn.Forte@Sun.COM 	}
3427836SJohn.Forte@Sun.COM 
3437836SJohn.Forte@Sun.COM 	/*
3447836SJohn.Forte@Sun.COM 	 * Open control node for stmf
3457836SJohn.Forte@Sun.COM 	 */
3467836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3477836SJohn.Forte@Sun.COM 		return (ret);
3487836SJohn.Forte@Sun.COM 
3497836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
3507836SJohn.Forte@Sun.COM 	    hostName)) != STMF_STATUS_SUCCESS) {
3517836SJohn.Forte@Sun.COM 		goto done;
3527836SJohn.Forte@Sun.COM 	}
3537836SJohn.Forte@Sun.COM 
3547836SJohn.Forte@Sun.COM 	ret = psAddHostGroupMember((char *)hostGroupName,
3557836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
3567836SJohn.Forte@Sun.COM 	switch (ret) {
3577836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
3587836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
3597836SJohn.Forte@Sun.COM 			break;
3607836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
3617836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
3627836SJohn.Forte@Sun.COM 			break;
3637836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
3647836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
3657836SJohn.Forte@Sun.COM 			break;
3667836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
3677836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
3687836SJohn.Forte@Sun.COM 			break;
3697836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3707836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3717836SJohn.Forte@Sun.COM 			break;
3727836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
3737836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3747836SJohn.Forte@Sun.COM 			break;
3757836SJohn.Forte@Sun.COM 		default:
3767836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
3777836SJohn.Forte@Sun.COM 			    "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
3787836SJohn.Forte@Sun.COM 			    ret);
3797836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
3807836SJohn.Forte@Sun.COM 			break;
3817836SJohn.Forte@Sun.COM 	}
3827836SJohn.Forte@Sun.COM 
3837836SJohn.Forte@Sun.COM done:
3847836SJohn.Forte@Sun.COM 	(void) close(fd);
3857836SJohn.Forte@Sun.COM 	return (ret);
3867836SJohn.Forte@Sun.COM }
3877836SJohn.Forte@Sun.COM 
3887836SJohn.Forte@Sun.COM /*
3897836SJohn.Forte@Sun.COM  * stmfAddToTargetGroup
3907836SJohn.Forte@Sun.COM  *
3917836SJohn.Forte@Sun.COM  * Purpose: Adds a local port to an existing target group
3927836SJohn.Forte@Sun.COM  *
3937836SJohn.Forte@Sun.COM  * targetGroupName - name of an existing target group
3947836SJohn.Forte@Sun.COM  * targetName - name of target to add
3957836SJohn.Forte@Sun.COM  */
3967836SJohn.Forte@Sun.COM int
3977836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
3987836SJohn.Forte@Sun.COM {
3997836SJohn.Forte@Sun.COM 	int ret;
4007836SJohn.Forte@Sun.COM 	int fd;
4017836SJohn.Forte@Sun.COM 	stmfState state;
4027836SJohn.Forte@Sun.COM 
4037836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
4047836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
4057836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
4067836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
4077836SJohn.Forte@Sun.COM 	}
4087836SJohn.Forte@Sun.COM 
4097836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
4107836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
4117836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
4127836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
4137836SJohn.Forte@Sun.COM 		}
4147836SJohn.Forte@Sun.COM 	} else {
4157836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
4167836SJohn.Forte@Sun.COM 	}
4177836SJohn.Forte@Sun.COM 
4187836SJohn.Forte@Sun.COM 	/* call init */
4197836SJohn.Forte@Sun.COM 	ret = initializeConfig();
4207836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
4217836SJohn.Forte@Sun.COM 		return (ret);
4227836SJohn.Forte@Sun.COM 	}
4237836SJohn.Forte@Sun.COM 
4247836SJohn.Forte@Sun.COM 	/*
4257836SJohn.Forte@Sun.COM 	 * Open control node for stmf
4267836SJohn.Forte@Sun.COM 	 */
4277836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4287836SJohn.Forte@Sun.COM 		return (ret);
4297836SJohn.Forte@Sun.COM 
4307836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
4317836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
4327836SJohn.Forte@Sun.COM 		goto done;
4337836SJohn.Forte@Sun.COM 	}
4347836SJohn.Forte@Sun.COM 
4357836SJohn.Forte@Sun.COM 	ret = psAddTargetGroupMember((char *)targetGroupName,
4367836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
4377836SJohn.Forte@Sun.COM 	switch (ret) {
4387836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
4397836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
4407836SJohn.Forte@Sun.COM 			break;
4417836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
4427836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
4437836SJohn.Forte@Sun.COM 			break;
4447836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
4457836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
4467836SJohn.Forte@Sun.COM 			break;
4477836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
4487836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
4497836SJohn.Forte@Sun.COM 			break;
4507836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
4517836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
4527836SJohn.Forte@Sun.COM 			break;
4537836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
4547836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
4557836SJohn.Forte@Sun.COM 			break;
4567836SJohn.Forte@Sun.COM 		default:
4577836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
4587836SJohn.Forte@Sun.COM 			    "stmfAddToTargetGroup:psAddTargetGroupMember:"
4597836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
4607836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
4617836SJohn.Forte@Sun.COM 			break;
4627836SJohn.Forte@Sun.COM 	}
4637836SJohn.Forte@Sun.COM 
4647836SJohn.Forte@Sun.COM done:
4657836SJohn.Forte@Sun.COM 	(void) close(fd);
4667836SJohn.Forte@Sun.COM 	return (ret);
4677836SJohn.Forte@Sun.COM }
4687836SJohn.Forte@Sun.COM 
4697836SJohn.Forte@Sun.COM /*
4707836SJohn.Forte@Sun.COM  * addViewEntryIoctl
4717836SJohn.Forte@Sun.COM  *
4727836SJohn.Forte@Sun.COM  * Purpose: Issues ioctl to add a view entry
4737836SJohn.Forte@Sun.COM  *
4747836SJohn.Forte@Sun.COM  * lu - Logical Unit identifier to which the view entry is added
4757836SJohn.Forte@Sun.COM  * viewEntry - view entry to add
4767836SJohn.Forte@Sun.COM  * init - When set to B_TRUE, we are in the init state, i.e. don't call open
4777836SJohn.Forte@Sun.COM  */
4787836SJohn.Forte@Sun.COM static int
4797836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
4807836SJohn.Forte@Sun.COM {
4817836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
4827836SJohn.Forte@Sun.COM 	int ioctlRet;
4837836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
4847836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
4857836SJohn.Forte@Sun.COM 
4867836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
4877836SJohn.Forte@Sun.COM 	/*
4887836SJohn.Forte@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
4897836SJohn.Forte@Sun.COM 	 * false on input
4907836SJohn.Forte@Sun.COM 	 */
4917836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
4927836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
4937836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
4947836SJohn.Forte@Sun.COM 
4957836SJohn.Forte@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
4967836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
4977836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
4987836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
4997836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
5007836SJohn.Forte@Sun.COM 	}
5017836SJohn.Forte@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
5027836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup,
5037836SJohn.Forte@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
5047836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
5057836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
5067836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
5077836SJohn.Forte@Sun.COM 	}
5087836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
5097836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
5107836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
5117836SJohn.Forte@Sun.COM 	}
5127836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
5137836SJohn.Forte@Sun.COM 
5147836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
5157836SJohn.Forte@Sun.COM 	/*
5167836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
5177836SJohn.Forte@Sun.COM 	 */
5187836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
5197836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
5207836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
5217836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
5227836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
5237836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
5247836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
5257836SJohn.Forte@Sun.COM 		switch (errno) {
5267836SJohn.Forte@Sun.COM 			case EBUSY:
5277836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
5287836SJohn.Forte@Sun.COM 				break;
5297836SJohn.Forte@Sun.COM 			case EACCES:
5307836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
5317836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
5327836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
5337836SJohn.Forte@Sun.COM 						break;
5347836SJohn.Forte@Sun.COM 					default:
5357836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
5367836SJohn.Forte@Sun.COM 						break;
5377836SJohn.Forte@Sun.COM 				}
5387836SJohn.Forte@Sun.COM 				break;
5397836SJohn.Forte@Sun.COM 			default:
5407836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
5417836SJohn.Forte@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
5427836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
5437836SJohn.Forte@Sun.COM 						break;
5447836SJohn.Forte@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
5457836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
5467836SJohn.Forte@Sun.COM 						break;
5477836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
5487836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
5497836SJohn.Forte@Sun.COM 						break;
5507836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
5517836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
5527836SJohn.Forte@Sun.COM 						break;
5537836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
5547836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
5557836SJohn.Forte@Sun.COM 						break;
5567836SJohn.Forte@Sun.COM 					default:
5577836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
5587836SJohn.Forte@Sun.COM 						    "addViewEntryIoctl"
5597836SJohn.Forte@Sun.COM 						    ":error(%d)",
5607836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
5617836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
5627836SJohn.Forte@Sun.COM 						break;
5637836SJohn.Forte@Sun.COM 				}
5647836SJohn.Forte@Sun.COM 				break;
5657836SJohn.Forte@Sun.COM 		}
5667836SJohn.Forte@Sun.COM 		goto done;
5677836SJohn.Forte@Sun.COM 	}
5687836SJohn.Forte@Sun.COM 
5697836SJohn.Forte@Sun.COM 	/* copy lu nbr back to caller's view entry on success */
5707836SJohn.Forte@Sun.COM 	viewEntry->veIndex = ioctlViewEntry.ve_ndx;
5717836SJohn.Forte@Sun.COM 	if (ioctlViewEntry.ve_lu_number_valid) {
5727836SJohn.Forte@Sun.COM 		bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
5737836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
5747836SJohn.Forte@Sun.COM 	}
5757836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
5767836SJohn.Forte@Sun.COM 
5777836SJohn.Forte@Sun.COM done:
5787836SJohn.Forte@Sun.COM 	return (ret);
5797836SJohn.Forte@Sun.COM }
5807836SJohn.Forte@Sun.COM 
5817836SJohn.Forte@Sun.COM /*
5827836SJohn.Forte@Sun.COM  * stmfAddViewEntry
5837836SJohn.Forte@Sun.COM  *
5847836SJohn.Forte@Sun.COM  * Purpose: Adds a view entry to a logical unit
5857836SJohn.Forte@Sun.COM  *
5867836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to which the view entry is added
5877836SJohn.Forte@Sun.COM  * viewEntry - view entry structure to add
5887836SJohn.Forte@Sun.COM  */
5897836SJohn.Forte@Sun.COM int
5907836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
5917836SJohn.Forte@Sun.COM {
5927836SJohn.Forte@Sun.COM 	int ret;
5937836SJohn.Forte@Sun.COM 	int fd;
5947836SJohn.Forte@Sun.COM 	stmfViewEntry iViewEntry;
5957836SJohn.Forte@Sun.COM 
5967836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntry == NULL) {
5977836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
5987836SJohn.Forte@Sun.COM 	}
5997836SJohn.Forte@Sun.COM 
6007836SJohn.Forte@Sun.COM 	/* initialize and set internal view entry */
6017836SJohn.Forte@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
6027836SJohn.Forte@Sun.COM 
6037836SJohn.Forte@Sun.COM 	if (!viewEntry->allHosts) {
6047836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
6057836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.hostGroup));
6067836SJohn.Forte@Sun.COM 	} else {
6077836SJohn.Forte@Sun.COM 		iViewEntry.allHosts = B_TRUE;
6087836SJohn.Forte@Sun.COM 	}
6097836SJohn.Forte@Sun.COM 
6107836SJohn.Forte@Sun.COM 	if (!viewEntry->allTargets) {
6117836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
6127836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.targetGroup));
6137836SJohn.Forte@Sun.COM 	} else {
6147836SJohn.Forte@Sun.COM 		iViewEntry.allTargets = B_TRUE;
6157836SJohn.Forte@Sun.COM 	}
6167836SJohn.Forte@Sun.COM 
6177836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
6187836SJohn.Forte@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
6197836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
6207836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
6217836SJohn.Forte@Sun.COM 	}
6227836SJohn.Forte@Sun.COM 
6237836SJohn.Forte@Sun.COM 	/*
6247836SJohn.Forte@Sun.COM 	 * set users return view entry index valid flag to false
6257836SJohn.Forte@Sun.COM 	 * in case of failure
6267836SJohn.Forte@Sun.COM 	 */
6277836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
6287836SJohn.Forte@Sun.COM 
6297836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
6307836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
6317836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
6327836SJohn.Forte@Sun.COM 	}
6337836SJohn.Forte@Sun.COM 
6347836SJohn.Forte@Sun.COM 	/* call init */
6357836SJohn.Forte@Sun.COM 	ret = initializeConfig();
6367836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
6377836SJohn.Forte@Sun.COM 		return (ret);
6387836SJohn.Forte@Sun.COM 	}
6397836SJohn.Forte@Sun.COM 
6407836SJohn.Forte@Sun.COM 	/*
6417836SJohn.Forte@Sun.COM 	 * Open control node for stmf
6427836SJohn.Forte@Sun.COM 	 */
6437836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6447836SJohn.Forte@Sun.COM 		return (ret);
6457836SJohn.Forte@Sun.COM 
6467836SJohn.Forte@Sun.COM 	/*
6477836SJohn.Forte@Sun.COM 	 * First add the view entry to the driver
6487836SJohn.Forte@Sun.COM 	 */
6497836SJohn.Forte@Sun.COM 	ret = addViewEntryIoctl(fd, lu, &iViewEntry);
6507836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
6517836SJohn.Forte@Sun.COM 		goto done;
6527836SJohn.Forte@Sun.COM 	}
6537836SJohn.Forte@Sun.COM 
6547836SJohn.Forte@Sun.COM 	/*
6557836SJohn.Forte@Sun.COM 	 * If the add to driver was successful, add it to the persistent
6567836SJohn.Forte@Sun.COM 	 * store.
6577836SJohn.Forte@Sun.COM 	 */
6587836SJohn.Forte@Sun.COM 	ret = psAddViewEntry(lu, &iViewEntry);
6597836SJohn.Forte@Sun.COM 	switch (ret) {
6607836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
6617836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
6627836SJohn.Forte@Sun.COM 			break;
6637836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
6647836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
6657836SJohn.Forte@Sun.COM 			break;
6667836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
6677836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
6687836SJohn.Forte@Sun.COM 			break;
6697836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6707836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
6717836SJohn.Forte@Sun.COM 			break;
6727836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
6737836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
6747836SJohn.Forte@Sun.COM 			break;
6757836SJohn.Forte@Sun.COM 		default:
6767836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
6777836SJohn.Forte@Sun.COM 			    "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
6787836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
6797836SJohn.Forte@Sun.COM 			break;
6807836SJohn.Forte@Sun.COM 	}
6817836SJohn.Forte@Sun.COM 
6827836SJohn.Forte@Sun.COM done:
6837836SJohn.Forte@Sun.COM 	(void) close(fd);
6847836SJohn.Forte@Sun.COM 
6857836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
6867836SJohn.Forte@Sun.COM 		/* set caller's view entry on success */
6877836SJohn.Forte@Sun.COM 		viewEntry->veIndexValid = iViewEntry.veIndexValid;
6887836SJohn.Forte@Sun.COM 		viewEntry->veIndex = iViewEntry.veIndex;
6897836SJohn.Forte@Sun.COM 		viewEntry->luNbrValid = B_TRUE;
6907836SJohn.Forte@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
6917836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
6927836SJohn.Forte@Sun.COM 	}
6937836SJohn.Forte@Sun.COM 	return (ret);
6947836SJohn.Forte@Sun.COM }
6957836SJohn.Forte@Sun.COM 
6967836SJohn.Forte@Sun.COM /*
6977836SJohn.Forte@Sun.COM  * stmfClearProviderData
6987836SJohn.Forte@Sun.COM  *
6997836SJohn.Forte@Sun.COM  * Purpose: delete all provider data for specified provider
7007836SJohn.Forte@Sun.COM  *
7017836SJohn.Forte@Sun.COM  * providerName - name of provider for which data should be deleted
7027836SJohn.Forte@Sun.COM  */
7037836SJohn.Forte@Sun.COM int
7047836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType)
7057836SJohn.Forte@Sun.COM {
7067836SJohn.Forte@Sun.COM 	int ret;
7077836SJohn.Forte@Sun.COM 	int fd;
7087836SJohn.Forte@Sun.COM 	int ioctlRet;
7097836SJohn.Forte@Sun.COM 	int savedErrno;
7107836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
7117836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t ppi;
7127836SJohn.Forte@Sun.COM 
7137836SJohn.Forte@Sun.COM 	/* call init */
7147836SJohn.Forte@Sun.COM 	ret = initializeConfig();
7157836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
7167836SJohn.Forte@Sun.COM 		return (ret);
7177836SJohn.Forte@Sun.COM 	}
7187836SJohn.Forte@Sun.COM 
7197836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
7207836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
7217836SJohn.Forte@Sun.COM 	}
7227836SJohn.Forte@Sun.COM 
7237836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
7247836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
7257836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
7267836SJohn.Forte@Sun.COM 	}
7277836SJohn.Forte@Sun.COM 
7287836SJohn.Forte@Sun.COM 	/*
7297836SJohn.Forte@Sun.COM 	 * Open control node for stmf
7307836SJohn.Forte@Sun.COM 	 */
7317836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
7327836SJohn.Forte@Sun.COM 		return (ret);
7337836SJohn.Forte@Sun.COM 
7347836SJohn.Forte@Sun.COM 	bzero(&ppi, sizeof (ppi));
7357836SJohn.Forte@Sun.COM 
7367836SJohn.Forte@Sun.COM 	(void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
7377836SJohn.Forte@Sun.COM 
7387836SJohn.Forte@Sun.COM 	switch (providerType) {
7397836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
7407836SJohn.Forte@Sun.COM 			ppi.ppi_lu_provider = 1;
7417836SJohn.Forte@Sun.COM 			break;
7427836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
7437836SJohn.Forte@Sun.COM 			ppi.ppi_port_provider = 1;
7447836SJohn.Forte@Sun.COM 			break;
7457836SJohn.Forte@Sun.COM 		default:
7467836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
7477836SJohn.Forte@Sun.COM 			goto done;
7487836SJohn.Forte@Sun.COM 	}
7497836SJohn.Forte@Sun.COM 
7507836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
7517836SJohn.Forte@Sun.COM 
7527836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
7537836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
7547836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
7557836SJohn.Forte@Sun.COM 
7567836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
7577836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
7587836SJohn.Forte@Sun.COM 		savedErrno = errno;
7597836SJohn.Forte@Sun.COM 		switch (savedErrno) {
7607836SJohn.Forte@Sun.COM 			case EBUSY:
7617836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
7627836SJohn.Forte@Sun.COM 				break;
7637836SJohn.Forte@Sun.COM 			case EACCES:
7647836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
7657836SJohn.Forte@Sun.COM 				break;
7667836SJohn.Forte@Sun.COM 			default:
7677836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
7687836SJohn.Forte@Sun.COM 				    "stmfClearProviderData:ioctl error(%d)",
7697836SJohn.Forte@Sun.COM 				    ioctlRet);
7707836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
7717836SJohn.Forte@Sun.COM 				break;
7727836SJohn.Forte@Sun.COM 		}
7737836SJohn.Forte@Sun.COM 		if (savedErrno != ENOENT) {
7747836SJohn.Forte@Sun.COM 			goto done;
7757836SJohn.Forte@Sun.COM 		}
7767836SJohn.Forte@Sun.COM 	}
7777836SJohn.Forte@Sun.COM 
7787836SJohn.Forte@Sun.COM 	ret = psClearProviderData(providerName, providerType);
7797836SJohn.Forte@Sun.COM 	switch (ret) {
7807836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
7817836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
7827836SJohn.Forte@Sun.COM 			break;
7837836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
7847836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
7857836SJohn.Forte@Sun.COM 			break;
7867836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
7877836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
7887836SJohn.Forte@Sun.COM 			break;
7897836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
7907836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
7917836SJohn.Forte@Sun.COM 			break;
7927836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
7937836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
7947836SJohn.Forte@Sun.COM 			break;
7957836SJohn.Forte@Sun.COM 		default:
7967836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
7977836SJohn.Forte@Sun.COM 			    "stmfClearProviderData:psClearProviderData"
7987836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
7997836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
8007836SJohn.Forte@Sun.COM 			break;
8017836SJohn.Forte@Sun.COM 	}
8027836SJohn.Forte@Sun.COM 
8037836SJohn.Forte@Sun.COM done:
8047836SJohn.Forte@Sun.COM 	(void) close(fd);
8057836SJohn.Forte@Sun.COM 	return (ret);
8067836SJohn.Forte@Sun.COM }
8077836SJohn.Forte@Sun.COM 
8087836SJohn.Forte@Sun.COM /*
8097836SJohn.Forte@Sun.COM  * stmfCreateHostGroup
8107836SJohn.Forte@Sun.COM  *
8117836SJohn.Forte@Sun.COM  * Purpose: Create a new initiator group
8127836SJohn.Forte@Sun.COM  *
8137836SJohn.Forte@Sun.COM  * hostGroupName - name of host group to create
8147836SJohn.Forte@Sun.COM  */
8157836SJohn.Forte@Sun.COM int
8167836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName)
8177836SJohn.Forte@Sun.COM {
8187836SJohn.Forte@Sun.COM 	int ret;
8197836SJohn.Forte@Sun.COM 	int fd;
8207836SJohn.Forte@Sun.COM 
8217836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
8227836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
8237836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
8247836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8257836SJohn.Forte@Sun.COM 	}
8267836SJohn.Forte@Sun.COM 
8277836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
8287836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
8297836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
8307836SJohn.Forte@Sun.COM 	}
8317836SJohn.Forte@Sun.COM 
8327836SJohn.Forte@Sun.COM 	/* call init */
8337836SJohn.Forte@Sun.COM 	ret = initializeConfig();
8347836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
8357836SJohn.Forte@Sun.COM 		return (ret);
8367836SJohn.Forte@Sun.COM 	}
8377836SJohn.Forte@Sun.COM 
8387836SJohn.Forte@Sun.COM 	/*
8397836SJohn.Forte@Sun.COM 	 * Open control node for stmf
8407836SJohn.Forte@Sun.COM 	 */
8417836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
8427836SJohn.Forte@Sun.COM 		return (ret);
8437836SJohn.Forte@Sun.COM 
8447836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
8457836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
8467836SJohn.Forte@Sun.COM 		goto done;
8477836SJohn.Forte@Sun.COM 	}
8487836SJohn.Forte@Sun.COM 
8497836SJohn.Forte@Sun.COM 	ret = psCreateHostGroup((char *)hostGroupName);
8507836SJohn.Forte@Sun.COM 	switch (ret) {
8517836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
8527836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
8537836SJohn.Forte@Sun.COM 			break;
8547836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
8557836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
8567836SJohn.Forte@Sun.COM 			break;
8577836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
8587836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
8597836SJohn.Forte@Sun.COM 			break;
8607836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
8617836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
8627836SJohn.Forte@Sun.COM 			break;
8637836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
8647836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
8657836SJohn.Forte@Sun.COM 			break;
8667836SJohn.Forte@Sun.COM 		default:
8677836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
8687836SJohn.Forte@Sun.COM 			    "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
8697836SJohn.Forte@Sun.COM 			    ret);
8707836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
8717836SJohn.Forte@Sun.COM 			break;
8727836SJohn.Forte@Sun.COM 	}
8737836SJohn.Forte@Sun.COM 
8747836SJohn.Forte@Sun.COM done:
8757836SJohn.Forte@Sun.COM 	(void) close(fd);
8767836SJohn.Forte@Sun.COM 	return (ret);
8777836SJohn.Forte@Sun.COM }
8787836SJohn.Forte@Sun.COM 
8797836SJohn.Forte@Sun.COM /*
8807836SJohn.Forte@Sun.COM  * stmfCreateTargetGroup
8817836SJohn.Forte@Sun.COM  *
8827836SJohn.Forte@Sun.COM  * Purpose: Create a local port group
8837836SJohn.Forte@Sun.COM  *
8847836SJohn.Forte@Sun.COM  * targetGroupName - name of local port group to create
8857836SJohn.Forte@Sun.COM  */
8867836SJohn.Forte@Sun.COM int
8877836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName)
8887836SJohn.Forte@Sun.COM {
8897836SJohn.Forte@Sun.COM 	int ret;
8907836SJohn.Forte@Sun.COM 	int fd;
8917836SJohn.Forte@Sun.COM 
8927836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
8937836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
8947836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
8957836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
8967836SJohn.Forte@Sun.COM 	}
8977836SJohn.Forte@Sun.COM 
8987836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
8997836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
9007836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
9017836SJohn.Forte@Sun.COM 	}
9027836SJohn.Forte@Sun.COM 
9037836SJohn.Forte@Sun.COM 	/* call init */
9047836SJohn.Forte@Sun.COM 	ret = initializeConfig();
9057836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
9067836SJohn.Forte@Sun.COM 		return (ret);
9077836SJohn.Forte@Sun.COM 	}
9087836SJohn.Forte@Sun.COM 
9097836SJohn.Forte@Sun.COM 	/*
9107836SJohn.Forte@Sun.COM 	 * Open control node for stmf
9117836SJohn.Forte@Sun.COM 	 */
9127836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
9137836SJohn.Forte@Sun.COM 		return (ret);
9147836SJohn.Forte@Sun.COM 
9157836SJohn.Forte@Sun.COM 	/*
9167836SJohn.Forte@Sun.COM 	 * Add the group to the driver
9177836SJohn.Forte@Sun.COM 	 */
9187836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
9197836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
9207836SJohn.Forte@Sun.COM 		goto done;
9217836SJohn.Forte@Sun.COM 	}
9227836SJohn.Forte@Sun.COM 
9237836SJohn.Forte@Sun.COM 	/*
9247836SJohn.Forte@Sun.COM 	 * If the add to the driver was successful, add it to the persistent
9257836SJohn.Forte@Sun.COM 	 * store.
9267836SJohn.Forte@Sun.COM 	 */
9277836SJohn.Forte@Sun.COM 	ret = psCreateTargetGroup((char *)targetGroupName);
9287836SJohn.Forte@Sun.COM 	switch (ret) {
9297836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
9307836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
9317836SJohn.Forte@Sun.COM 			break;
9327836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
9337836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
9347836SJohn.Forte@Sun.COM 			break;
9357836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
9367836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
9377836SJohn.Forte@Sun.COM 			break;
9387836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
9397836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
9407836SJohn.Forte@Sun.COM 			break;
9417836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
9427836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
9437836SJohn.Forte@Sun.COM 			break;
9447836SJohn.Forte@Sun.COM 		default:
9457836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
9467836SJohn.Forte@Sun.COM 			    "stmfCreateTargetGroup:psCreateTargetGroup"
9477836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
9487836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
9497836SJohn.Forte@Sun.COM 			break;
9507836SJohn.Forte@Sun.COM 	}
9517836SJohn.Forte@Sun.COM 
9527836SJohn.Forte@Sun.COM done:
9537836SJohn.Forte@Sun.COM 	(void) close(fd);
9547836SJohn.Forte@Sun.COM 	return (ret);
9557836SJohn.Forte@Sun.COM }
9567836SJohn.Forte@Sun.COM 
9577836SJohn.Forte@Sun.COM /*
9587836SJohn.Forte@Sun.COM  * stmfDeleteHostGroup
9597836SJohn.Forte@Sun.COM  *
9607836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
9617836SJohn.Forte@Sun.COM  *
9627836SJohn.Forte@Sun.COM  * hostGroupName - group to delete
9637836SJohn.Forte@Sun.COM  */
9647836SJohn.Forte@Sun.COM int
9657836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName)
9667836SJohn.Forte@Sun.COM {
9677836SJohn.Forte@Sun.COM 	int ret;
9687836SJohn.Forte@Sun.COM 	int fd;
9697836SJohn.Forte@Sun.COM 
9707836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL) {
9717836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
9727836SJohn.Forte@Sun.COM 	}
9737836SJohn.Forte@Sun.COM 
9747836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
9757836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
9767836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
9777836SJohn.Forte@Sun.COM 	}
9787836SJohn.Forte@Sun.COM 
9797836SJohn.Forte@Sun.COM 	/* call init */
9807836SJohn.Forte@Sun.COM 	ret = initializeConfig();
9817836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
9827836SJohn.Forte@Sun.COM 		return (ret);
9837836SJohn.Forte@Sun.COM 	}
9847836SJohn.Forte@Sun.COM 
9857836SJohn.Forte@Sun.COM 	/*
9867836SJohn.Forte@Sun.COM 	 * Open control node for stmf
9877836SJohn.Forte@Sun.COM 	 */
9887836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
9897836SJohn.Forte@Sun.COM 		return (ret);
9907836SJohn.Forte@Sun.COM 
9917836SJohn.Forte@Sun.COM 	/*
9927836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
9937836SJohn.Forte@Sun.COM 	 */
9947836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
9957836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
9967836SJohn.Forte@Sun.COM 		goto done;
9977836SJohn.Forte@Sun.COM 	}
9987836SJohn.Forte@Sun.COM 
9997836SJohn.Forte@Sun.COM 	/*
10007836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
10017836SJohn.Forte@Sun.COM 	 * persistent store.
10027836SJohn.Forte@Sun.COM 	 */
10037836SJohn.Forte@Sun.COM 	ret = psDeleteHostGroup((char *)hostGroupName);
10047836SJohn.Forte@Sun.COM 	switch (ret) {
10057836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
10067836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
10077836SJohn.Forte@Sun.COM 			break;
10087836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
10097836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
10107836SJohn.Forte@Sun.COM 			break;
10117836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
10127836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
10137836SJohn.Forte@Sun.COM 			break;
10147836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
10157836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
10167836SJohn.Forte@Sun.COM 			break;
10177836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
10187836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
10197836SJohn.Forte@Sun.COM 			break;
10207836SJohn.Forte@Sun.COM 		default:
10217836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
10227836SJohn.Forte@Sun.COM 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
10237836SJohn.Forte@Sun.COM 			    ret);
10247836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
10257836SJohn.Forte@Sun.COM 			break;
10267836SJohn.Forte@Sun.COM 	}
10277836SJohn.Forte@Sun.COM 
10287836SJohn.Forte@Sun.COM done:
10297836SJohn.Forte@Sun.COM 	(void) close(fd);
10307836SJohn.Forte@Sun.COM 	return (ret);
10317836SJohn.Forte@Sun.COM }
10327836SJohn.Forte@Sun.COM 
10337836SJohn.Forte@Sun.COM /*
10347836SJohn.Forte@Sun.COM  * stmfDeleteTargetGroup
10357836SJohn.Forte@Sun.COM  *
10367836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
10377836SJohn.Forte@Sun.COM  *
10387836SJohn.Forte@Sun.COM  * targetGroupName - group to delete
10397836SJohn.Forte@Sun.COM  */
10407836SJohn.Forte@Sun.COM int
10417836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
10427836SJohn.Forte@Sun.COM {
10437836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
10447836SJohn.Forte@Sun.COM 	int fd;
10457836SJohn.Forte@Sun.COM 
10467836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL) {
10477836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
10487836SJohn.Forte@Sun.COM 	}
10497836SJohn.Forte@Sun.COM 
10507836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
10517836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
10527836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
10537836SJohn.Forte@Sun.COM 	}
10547836SJohn.Forte@Sun.COM 
10557836SJohn.Forte@Sun.COM 	/* call init */
10567836SJohn.Forte@Sun.COM 	ret = initializeConfig();
10577836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
10587836SJohn.Forte@Sun.COM 		return (ret);
10597836SJohn.Forte@Sun.COM 	}
10607836SJohn.Forte@Sun.COM 
10617836SJohn.Forte@Sun.COM 	/*
10627836SJohn.Forte@Sun.COM 	 * Open control node for stmf
10637836SJohn.Forte@Sun.COM 	 */
10647836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
10657836SJohn.Forte@Sun.COM 		return (ret);
10667836SJohn.Forte@Sun.COM 
10677836SJohn.Forte@Sun.COM 	/*
10687836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
10697836SJohn.Forte@Sun.COM 	 */
10707836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
10717836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
10727836SJohn.Forte@Sun.COM 		goto done;
10737836SJohn.Forte@Sun.COM 	}
10747836SJohn.Forte@Sun.COM 
10757836SJohn.Forte@Sun.COM 	/*
10767836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
10777836SJohn.Forte@Sun.COM 	 * persistent store.
10787836SJohn.Forte@Sun.COM 	 */
10797836SJohn.Forte@Sun.COM 	ret = psDeleteTargetGroup((char *)targetGroupName);
10807836SJohn.Forte@Sun.COM 	switch (ret) {
10817836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
10827836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
10837836SJohn.Forte@Sun.COM 			break;
10847836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
10857836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
10867836SJohn.Forte@Sun.COM 			break;
10877836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
10887836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
10897836SJohn.Forte@Sun.COM 			break;
10907836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
10917836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
10927836SJohn.Forte@Sun.COM 			break;
10937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
10947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
10957836SJohn.Forte@Sun.COM 			break;
10967836SJohn.Forte@Sun.COM 		default:
10977836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
10987836SJohn.Forte@Sun.COM 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
10997836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
11007836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
11017836SJohn.Forte@Sun.COM 			break;
11027836SJohn.Forte@Sun.COM 	}
11037836SJohn.Forte@Sun.COM 
11047836SJohn.Forte@Sun.COM done:
11057836SJohn.Forte@Sun.COM 	(void) close(fd);
11067836SJohn.Forte@Sun.COM 	return (ret);
11077836SJohn.Forte@Sun.COM }
11087836SJohn.Forte@Sun.COM 
11097836SJohn.Forte@Sun.COM /*
11107836SJohn.Forte@Sun.COM  * stmfDevidFromIscsiName
11117836SJohn.Forte@Sun.COM  *
11127836SJohn.Forte@Sun.COM  * Purpose: convert an iSCSI name to an stmf devid
11137836SJohn.Forte@Sun.COM  *
11147836SJohn.Forte@Sun.COM  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
11157836SJohn.Forte@Sun.COM  * devid - on success, contains the converted iscsi name
11167836SJohn.Forte@Sun.COM  */
11177836SJohn.Forte@Sun.COM int
11187836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
11197836SJohn.Forte@Sun.COM {
11207836SJohn.Forte@Sun.COM 	if (devid == NULL || iscsiName == NULL)
11217836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
11227836SJohn.Forte@Sun.COM 
11237836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
11247836SJohn.Forte@Sun.COM 
11257836SJohn.Forte@Sun.COM 	/* Validate size of target */
11267836SJohn.Forte@Sun.COM 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
11277836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(EUI) ||
11287836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(IQN)) {
11297836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
11307836SJohn.Forte@Sun.COM 	}
11317836SJohn.Forte@Sun.COM 
11327836SJohn.Forte@Sun.COM 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
11337836SJohn.Forte@Sun.COM 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
11347836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
11357836SJohn.Forte@Sun.COM 	}
11367836SJohn.Forte@Sun.COM 
11377836SJohn.Forte@Sun.COM 	/* copy UTF-8 bytes to ident */
11387836SJohn.Forte@Sun.COM 	bcopy(iscsiName, devid->ident, devid->identLength);
11397836SJohn.Forte@Sun.COM 
11407836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
11417836SJohn.Forte@Sun.COM }
11427836SJohn.Forte@Sun.COM 
11437836SJohn.Forte@Sun.COM /*
11447836SJohn.Forte@Sun.COM  * stmfDevidFromWwn
11457836SJohn.Forte@Sun.COM  *
11467836SJohn.Forte@Sun.COM  * Purpose: convert a WWN to an stmf devid
11477836SJohn.Forte@Sun.COM  *
11487836SJohn.Forte@Sun.COM  * wwn - 8-byte wwn identifier
11497836SJohn.Forte@Sun.COM  * devid - on success, contains the converted wwn
11507836SJohn.Forte@Sun.COM  */
11517836SJohn.Forte@Sun.COM int
11527836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
11537836SJohn.Forte@Sun.COM {
11547836SJohn.Forte@Sun.COM 	if (wwn == NULL || devid == NULL)
11557836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
11567836SJohn.Forte@Sun.COM 
11577836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
11587836SJohn.Forte@Sun.COM 
11597836SJohn.Forte@Sun.COM 	/* Copy eui prefix */
11607836SJohn.Forte@Sun.COM 	(void) bcopy(WWN, devid->ident, strlen(WWN));
11617836SJohn.Forte@Sun.COM 
11627836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
11637836SJohn.Forte@Sun.COM 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
11647836SJohn.Forte@Sun.COM 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
11657836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
11667836SJohn.Forte@Sun.COM 
11677836SJohn.Forte@Sun.COM 	devid->identLength = strlen((char *)devid->ident);
11687836SJohn.Forte@Sun.COM 
11697836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
11707836SJohn.Forte@Sun.COM }
11717836SJohn.Forte@Sun.COM 
11727836SJohn.Forte@Sun.COM /*
11737836SJohn.Forte@Sun.COM  * stmfFreeMemory
11747836SJohn.Forte@Sun.COM  *
11757836SJohn.Forte@Sun.COM  * Purpose: Free memory allocated by this library
11767836SJohn.Forte@Sun.COM  *
11777836SJohn.Forte@Sun.COM  * memory - previously allocated pointer of memory managed by library
11787836SJohn.Forte@Sun.COM  */
11797836SJohn.Forte@Sun.COM void
11807836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory)
11817836SJohn.Forte@Sun.COM {
11827836SJohn.Forte@Sun.COM 	free(memory);
11837836SJohn.Forte@Sun.COM }
11847836SJohn.Forte@Sun.COM 
11857836SJohn.Forte@Sun.COM /*
11867836SJohn.Forte@Sun.COM  * stmfGetHostGroupList
11877836SJohn.Forte@Sun.COM  *
11887836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of initiator group oids
11897836SJohn.Forte@Sun.COM  *
11907836SJohn.Forte@Sun.COM  * hostGroupList - pointer to pointer to hostGroupList structure
11917836SJohn.Forte@Sun.COM  *                 on success, this contains the host group list.
11927836SJohn.Forte@Sun.COM  */
11937836SJohn.Forte@Sun.COM int
11947836SJohn.Forte@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList)
11957836SJohn.Forte@Sun.COM {
11967836SJohn.Forte@Sun.COM 	int ret;
11977836SJohn.Forte@Sun.COM 
11987836SJohn.Forte@Sun.COM 	if (hostGroupList == NULL) {
11997836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
12007836SJohn.Forte@Sun.COM 	}
12017836SJohn.Forte@Sun.COM 
12027836SJohn.Forte@Sun.COM 	ret = psGetHostGroupList(hostGroupList);
12037836SJohn.Forte@Sun.COM 	switch (ret) {
12047836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
12057836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
12067836SJohn.Forte@Sun.COM 			break;
12077836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
12087836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
12097836SJohn.Forte@Sun.COM 			break;
12107836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
12117836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
12127836SJohn.Forte@Sun.COM 			break;
12137836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
12147836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
12157836SJohn.Forte@Sun.COM 			break;
12167836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
12177836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
12187836SJohn.Forte@Sun.COM 			break;
12197836SJohn.Forte@Sun.COM 		default:
12207836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
12217836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
12227836SJohn.Forte@Sun.COM 			    ret);
12237836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
12247836SJohn.Forte@Sun.COM 			break;
12257836SJohn.Forte@Sun.COM 	}
12267836SJohn.Forte@Sun.COM 
12277836SJohn.Forte@Sun.COM 	return (ret);
12287836SJohn.Forte@Sun.COM }
12297836SJohn.Forte@Sun.COM 
12307836SJohn.Forte@Sun.COM /*
12317836SJohn.Forte@Sun.COM  * stmfGetHostGroupMembers
12327836SJohn.Forte@Sun.COM  *
12337836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group properties for a host group
12347836SJohn.Forte@Sun.COM  *
12357836SJohn.Forte@Sun.COM  * groupName - name of group for which to retrieve host group members.
12367836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
12377836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
12387836SJohn.Forte@Sun.COM  */
12397836SJohn.Forte@Sun.COM int
12407836SJohn.Forte@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName,
12417836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
12427836SJohn.Forte@Sun.COM {
12437836SJohn.Forte@Sun.COM 	int ret;
12447836SJohn.Forte@Sun.COM 
12457836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
12467836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
12477836SJohn.Forte@Sun.COM 	}
12487836SJohn.Forte@Sun.COM 
12497836SJohn.Forte@Sun.COM 	ret = psGetHostGroupMemberList((char *)groupName, groupProp);
12507836SJohn.Forte@Sun.COM 	switch (ret) {
12517836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
12527836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
12537836SJohn.Forte@Sun.COM 			break;
12547836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
12557836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
12567836SJohn.Forte@Sun.COM 			break;
12577836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
12587836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
12597836SJohn.Forte@Sun.COM 			break;
12607836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
12617836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
12627836SJohn.Forte@Sun.COM 			break;
12637836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
12647836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
12657836SJohn.Forte@Sun.COM 			break;
12667836SJohn.Forte@Sun.COM 		default:
12677836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
12687836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupMembers:psGetHostGroupMembers"
12697836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
12707836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
12717836SJohn.Forte@Sun.COM 			break;
12727836SJohn.Forte@Sun.COM 	}
12737836SJohn.Forte@Sun.COM 
12747836SJohn.Forte@Sun.COM 	return (ret);
12757836SJohn.Forte@Sun.COM }
12767836SJohn.Forte@Sun.COM 
12777836SJohn.Forte@Sun.COM /*
12787836SJohn.Forte@Sun.COM  * stmfGetProviderData
12797836SJohn.Forte@Sun.COM  *
12807836SJohn.Forte@Sun.COM  * Purpose: Get provider data list
12817836SJohn.Forte@Sun.COM  *
12827836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
12837836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
12847836SJohn.Forte@Sun.COM  *       retrieved.
12857836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
12867836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
12877836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
12887836SJohn.Forte@Sun.COM  */
12897836SJohn.Forte@Sun.COM int
12907836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
12917836SJohn.Forte@Sun.COM {
12927836SJohn.Forte@Sun.COM 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
12937836SJohn.Forte@Sun.COM 	    NULL));
12947836SJohn.Forte@Sun.COM }
12957836SJohn.Forte@Sun.COM 
12967836SJohn.Forte@Sun.COM /*
12977836SJohn.Forte@Sun.COM  * stmfGetProviderDataProt
12987836SJohn.Forte@Sun.COM  *
12997836SJohn.Forte@Sun.COM  * Purpose: Get provider data list with token
13007836SJohn.Forte@Sun.COM  *
13017836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
13027836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
13037836SJohn.Forte@Sun.COM  *       retrieved.
13047836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
13057836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
13067836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
13077836SJohn.Forte@Sun.COM  * setToken - Returns the stale data token
13087836SJohn.Forte@Sun.COM  */
13097836SJohn.Forte@Sun.COM int
13107836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
13117836SJohn.Forte@Sun.COM     uint64_t *setToken)
13127836SJohn.Forte@Sun.COM {
13137836SJohn.Forte@Sun.COM 	int ret;
13147836SJohn.Forte@Sun.COM 
13157836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
13167836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13177836SJohn.Forte@Sun.COM 	}
13187836SJohn.Forte@Sun.COM 
13197836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
13207836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
13217836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
13227836SJohn.Forte@Sun.COM 	}
13237836SJohn.Forte@Sun.COM 
13247836SJohn.Forte@Sun.COM 	/* call init */
13257836SJohn.Forte@Sun.COM 	ret = initializeConfig();
13267836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
13277836SJohn.Forte@Sun.COM 		return (ret);
13287836SJohn.Forte@Sun.COM 	}
13297836SJohn.Forte@Sun.COM 
13307836SJohn.Forte@Sun.COM 	ret = psGetProviderData(providerName, nvl, providerType, setToken);
13317836SJohn.Forte@Sun.COM 	switch (ret) {
13327836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
13337836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
13347836SJohn.Forte@Sun.COM 			break;
13357836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
13367836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
13377836SJohn.Forte@Sun.COM 			break;
13387836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
13397836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
13407836SJohn.Forte@Sun.COM 			break;
13417836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
13427836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
13437836SJohn.Forte@Sun.COM 			break;
13447836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
13457836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
13467836SJohn.Forte@Sun.COM 			break;
13477836SJohn.Forte@Sun.COM 		default:
13487836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
13497836SJohn.Forte@Sun.COM 			    "stmfGetProviderData:psGetProviderData:error(%d)",
13507836SJohn.Forte@Sun.COM 			    ret);
13517836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
13527836SJohn.Forte@Sun.COM 			break;
13537836SJohn.Forte@Sun.COM 	}
13547836SJohn.Forte@Sun.COM 
13557836SJohn.Forte@Sun.COM 	return (ret);
13567836SJohn.Forte@Sun.COM }
13577836SJohn.Forte@Sun.COM 
13587836SJohn.Forte@Sun.COM /*
13597836SJohn.Forte@Sun.COM  * stmfGetProviderDataList
13607836SJohn.Forte@Sun.COM  *
13617836SJohn.Forte@Sun.COM  * Purpose: Get the list of providers currently persisting data
13627836SJohn.Forte@Sun.COM  *
13637836SJohn.Forte@Sun.COM  * providerList - pointer to pointer to an stmfProviderList structure allocated
13647836SJohn.Forte@Sun.COM  *                by the caller. Will contain the list of providers on success.
13657836SJohn.Forte@Sun.COM  */
13667836SJohn.Forte@Sun.COM int
13677836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList)
13687836SJohn.Forte@Sun.COM {
13697836SJohn.Forte@Sun.COM 	int ret;
13707836SJohn.Forte@Sun.COM 
13717836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(providerList);
13727836SJohn.Forte@Sun.COM 	switch (ret) {
13737836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
13747836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
13757836SJohn.Forte@Sun.COM 			break;
13767836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
13777836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
13787836SJohn.Forte@Sun.COM 			break;
13797836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
13807836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
13817836SJohn.Forte@Sun.COM 			break;
13827836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
13837836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
13847836SJohn.Forte@Sun.COM 			break;
13857836SJohn.Forte@Sun.COM 		default:
13867836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
13877836SJohn.Forte@Sun.COM 			    "stmfGetProviderDataList:psGetProviderDataList"
13887836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
13897836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
13907836SJohn.Forte@Sun.COM 			break;
13917836SJohn.Forte@Sun.COM 	}
13927836SJohn.Forte@Sun.COM 
13937836SJohn.Forte@Sun.COM 	return (ret);
13947836SJohn.Forte@Sun.COM }
13957836SJohn.Forte@Sun.COM 
13967836SJohn.Forte@Sun.COM 
13977836SJohn.Forte@Sun.COM /*
13987836SJohn.Forte@Sun.COM  * stmfGetSessionList
13997836SJohn.Forte@Sun.COM  *
14007836SJohn.Forte@Sun.COM  * Purpose: Retrieves the session list for a target (devid)
14017836SJohn.Forte@Sun.COM  *
14027836SJohn.Forte@Sun.COM  * devid - devid of target for which to retrieve session information.
14037836SJohn.Forte@Sun.COM  * sessionList - pointer to pointer to stmfSessionList structure
14047836SJohn.Forte@Sun.COM  *             on success, this contains the list of initiator sessions.
14057836SJohn.Forte@Sun.COM  */
14067836SJohn.Forte@Sun.COM int
14077836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
14087836SJohn.Forte@Sun.COM {
14097836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
14107836SJohn.Forte@Sun.COM 	int fd;
14117836SJohn.Forte@Sun.COM 	int ioctlRet;
14127836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_SESSION_LIST;
14137836SJohn.Forte@Sun.COM 	int i;
14147836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
14157836SJohn.Forte@Sun.COM 	slist_scsi_session_t *fSessionList;
14167836SJohn.Forte@Sun.COM 	uint8_t ident[260];
14177836SJohn.Forte@Sun.COM 	uint32_t fSessionListSize;
14187836SJohn.Forte@Sun.COM 
14197836SJohn.Forte@Sun.COM 	if (sessionList == NULL || devid == NULL) {
14207836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
14217836SJohn.Forte@Sun.COM 	}
14227836SJohn.Forte@Sun.COM 
14237836SJohn.Forte@Sun.COM 	/* call init */
14247836SJohn.Forte@Sun.COM 	ret = initializeConfig();
14257836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
14267836SJohn.Forte@Sun.COM 		return (ret);
14277836SJohn.Forte@Sun.COM 	}
14287836SJohn.Forte@Sun.COM 
14297836SJohn.Forte@Sun.COM 	/*
14307836SJohn.Forte@Sun.COM 	 * Open control node for stmf
14317836SJohn.Forte@Sun.COM 	 */
14327836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
14337836SJohn.Forte@Sun.COM 		return (ret);
14347836SJohn.Forte@Sun.COM 
14357836SJohn.Forte@Sun.COM 	/*
14367836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
14377836SJohn.Forte@Sun.COM 	 */
14387836SJohn.Forte@Sun.COM 	fSessionListSize = MAX_SESSION;
14397836SJohn.Forte@Sun.COM 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
14407836SJohn.Forte@Sun.COM 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
14417836SJohn.Forte@Sun.COM 	if (fSessionList == NULL) {
14427836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
14437836SJohn.Forte@Sun.COM 	}
14447836SJohn.Forte@Sun.COM 
14457836SJohn.Forte@Sun.COM 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
14467836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
14477836SJohn.Forte@Sun.COM 	    devid->identLength);
14487836SJohn.Forte@Sun.COM 
14497836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
14507836SJohn.Forte@Sun.COM 	/*
14517836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the session list
14527836SJohn.Forte@Sun.COM 	 */
14537836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
14547836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
14557836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
14567836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fSessionListSize;
14577836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
14587836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
14597836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
14607836SJohn.Forte@Sun.COM 		switch (errno) {
14617836SJohn.Forte@Sun.COM 			case EBUSY:
14627836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
14637836SJohn.Forte@Sun.COM 				break;
14647836SJohn.Forte@Sun.COM 			case EACCES:
14657836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
14667836SJohn.Forte@Sun.COM 				break;
14677836SJohn.Forte@Sun.COM 			default:
14687836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
14697836SJohn.Forte@Sun.COM 				    "stmfGetSessionList:ioctl errno(%d)",
14707836SJohn.Forte@Sun.COM 				    errno);
14717836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
14727836SJohn.Forte@Sun.COM 				break;
14737836SJohn.Forte@Sun.COM 		}
14747836SJohn.Forte@Sun.COM 		goto done;
14757836SJohn.Forte@Sun.COM 	}
14767836SJohn.Forte@Sun.COM 	/*
14777836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
14787836SJohn.Forte@Sun.COM 	 */
14797836SJohn.Forte@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > MAX_SESSION) {
14807836SJohn.Forte@Sun.COM 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
14817836SJohn.Forte@Sun.COM 		    sizeof (slist_scsi_session_t);
14827836SJohn.Forte@Sun.COM 		fSessionList = realloc(fSessionList, fSessionListSize);
14837836SJohn.Forte@Sun.COM 		if (fSessionList == NULL) {
14847836SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOMEM);
14857836SJohn.Forte@Sun.COM 		}
14867836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fSessionListSize;
14877836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
14887836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
14897836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
14907836SJohn.Forte@Sun.COM 			switch (errno) {
14917836SJohn.Forte@Sun.COM 				case EBUSY:
14927836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
14937836SJohn.Forte@Sun.COM 					break;
14947836SJohn.Forte@Sun.COM 				case EACCES:
14957836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
14967836SJohn.Forte@Sun.COM 					break;
14977836SJohn.Forte@Sun.COM 				default:
14987836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
14997836SJohn.Forte@Sun.COM 					    "stmfGetSessionList:ioctl "
15007836SJohn.Forte@Sun.COM 					    "errno(%d)", errno);
15017836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
15027836SJohn.Forte@Sun.COM 					break;
15037836SJohn.Forte@Sun.COM 			}
15047836SJohn.Forte@Sun.COM 			goto done;
15057836SJohn.Forte@Sun.COM 		}
15067836SJohn.Forte@Sun.COM 	}
15077836SJohn.Forte@Sun.COM 
15087836SJohn.Forte@Sun.COM 	/*
15097836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
15107836SJohn.Forte@Sun.COM 	 */
15117836SJohn.Forte@Sun.COM 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
15127836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
15137836SJohn.Forte@Sun.COM 	if (*sessionList == NULL) {
15147836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
15157836SJohn.Forte@Sun.COM 		free(sessionList);
15167836SJohn.Forte@Sun.COM 		goto done;
15177836SJohn.Forte@Sun.COM 	}
15187836SJohn.Forte@Sun.COM 
15197836SJohn.Forte@Sun.COM 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
15207836SJohn.Forte@Sun.COM 
15217836SJohn.Forte@Sun.COM 	/*
15227836SJohn.Forte@Sun.COM 	 * copy session info to caller's buffer
15237836SJohn.Forte@Sun.COM 	 */
15247836SJohn.Forte@Sun.COM 	for (i = 0; i < (*sessionList)->cnt; i++) {
15257836SJohn.Forte@Sun.COM 		(*sessionList)->session[i].initiator.identLength =
15267836SJohn.Forte@Sun.COM 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
15277836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
15287836SJohn.Forte@Sun.COM 		    (*sessionList)->session[i].initiator.ident,
15297836SJohn.Forte@Sun.COM 		    STMF_IDENT_LENGTH);
15307836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->alias),
15317836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].alias),
15327836SJohn.Forte@Sun.COM 		    sizeof ((*sessionList)->session[i].alias));
15337836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList++->creation_time),
15347836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].creationTime),
15357836SJohn.Forte@Sun.COM 		    sizeof (time_t));
15367836SJohn.Forte@Sun.COM 	}
15377836SJohn.Forte@Sun.COM done:
15387836SJohn.Forte@Sun.COM 	(void) close(fd);
15397836SJohn.Forte@Sun.COM 	return (ret);
15407836SJohn.Forte@Sun.COM }
15417836SJohn.Forte@Sun.COM 
15427836SJohn.Forte@Sun.COM /*
15437836SJohn.Forte@Sun.COM  * stmfGetTargetGroupList
15447836SJohn.Forte@Sun.COM  *
15457836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target groups
15467836SJohn.Forte@Sun.COM  *
15477836SJohn.Forte@Sun.COM  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
15487836SJohn.Forte@Sun.COM  *		     success, it contains the list of target groups.
15497836SJohn.Forte@Sun.COM  */
15507836SJohn.Forte@Sun.COM int
15517836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList)
15527836SJohn.Forte@Sun.COM {
15537836SJohn.Forte@Sun.COM 	int ret;
15547836SJohn.Forte@Sun.COM 
15557836SJohn.Forte@Sun.COM 	if (targetGroupList == NULL) {
15567836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
15577836SJohn.Forte@Sun.COM 	}
15587836SJohn.Forte@Sun.COM 
15597836SJohn.Forte@Sun.COM 	ret = psGetTargetGroupList(targetGroupList);
15607836SJohn.Forte@Sun.COM 	switch (ret) {
15617836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
15627836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
15637836SJohn.Forte@Sun.COM 			break;
15647836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
15657836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
15667836SJohn.Forte@Sun.COM 			break;
15677836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
15687836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
15697836SJohn.Forte@Sun.COM 			break;
15707836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
15717836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
15727836SJohn.Forte@Sun.COM 			break;
15737836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
15747836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
15757836SJohn.Forte@Sun.COM 			break;
15767836SJohn.Forte@Sun.COM 		default:
15777836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
15787836SJohn.Forte@Sun.COM 			    "stmfGetTargetGroupList:psGetTargetGroupList:"
15797836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
15807836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
15817836SJohn.Forte@Sun.COM 			break;
15827836SJohn.Forte@Sun.COM 	}
15837836SJohn.Forte@Sun.COM 
15847836SJohn.Forte@Sun.COM 	return (ret);
15857836SJohn.Forte@Sun.COM }
15867836SJohn.Forte@Sun.COM 
15877836SJohn.Forte@Sun.COM /*
15887836SJohn.Forte@Sun.COM  * stmfGetTargetGroupMembers
15897836SJohn.Forte@Sun.COM  *
15907836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group members for a target group
15917836SJohn.Forte@Sun.COM  *
15927836SJohn.Forte@Sun.COM  * groupName - name of target group for which to retrieve members.
15937836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
15947836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
15957836SJohn.Forte@Sun.COM  */
15967836SJohn.Forte@Sun.COM int
15977836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName,
15987836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
15997836SJohn.Forte@Sun.COM {
16007836SJohn.Forte@Sun.COM 	int ret;
16017836SJohn.Forte@Sun.COM 
16027836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
16037836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
16047836SJohn.Forte@Sun.COM 	}
16057836SJohn.Forte@Sun.COM 
16067836SJohn.Forte@Sun.COM 	ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
16077836SJohn.Forte@Sun.COM 	switch (ret) {
16087836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
16097836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
16107836SJohn.Forte@Sun.COM 			break;
16117836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
16127836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
16137836SJohn.Forte@Sun.COM 			break;
16147836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
16157836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
16167836SJohn.Forte@Sun.COM 			break;
16177836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
16187836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
16197836SJohn.Forte@Sun.COM 			break;
16207836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
16217836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
16227836SJohn.Forte@Sun.COM 			break;
16237836SJohn.Forte@Sun.COM 		default:
16247836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
16257836SJohn.Forte@Sun.COM 			    "stmfGetTargetGroupMembers:psGetTargetGroupMembers:"
16267836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
16277836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
16287836SJohn.Forte@Sun.COM 			break;
16297836SJohn.Forte@Sun.COM 	}
16307836SJohn.Forte@Sun.COM 
16317836SJohn.Forte@Sun.COM 	return (ret);
16327836SJohn.Forte@Sun.COM }
16337836SJohn.Forte@Sun.COM 
16347836SJohn.Forte@Sun.COM /*
16357836SJohn.Forte@Sun.COM  * stmfGetTargetList
16367836SJohn.Forte@Sun.COM  *
16377836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target ports
16387836SJohn.Forte@Sun.COM  *
16397836SJohn.Forte@Sun.COM  * targetList - pointer to a pointer to an stmfDevidList structure.
16407836SJohn.Forte@Sun.COM  *		    On success, it contains the list of local ports (target).
16417836SJohn.Forte@Sun.COM  */
16427836SJohn.Forte@Sun.COM int
16437836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList)
16447836SJohn.Forte@Sun.COM {
16457836SJohn.Forte@Sun.COM 	int ret;
16467836SJohn.Forte@Sun.COM 	int fd;
16477836SJohn.Forte@Sun.COM 	int ioctlRet;
16487836SJohn.Forte@Sun.COM 	int i;
16497836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
16507836SJohn.Forte@Sun.COM 	/* framework target port list */
1651*8252SJohn.Forte@Sun.COM 	slist_target_port_t *fTargetList, *fTargetListP;
16527836SJohn.Forte@Sun.COM 	uint32_t fTargetListSize;
16537836SJohn.Forte@Sun.COM 
16547836SJohn.Forte@Sun.COM 	if (targetList == NULL) {
16557836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
16567836SJohn.Forte@Sun.COM 	}
16577836SJohn.Forte@Sun.COM 
16587836SJohn.Forte@Sun.COM 	/* call init */
16597836SJohn.Forte@Sun.COM 	ret = initializeConfig();
16607836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
16617836SJohn.Forte@Sun.COM 		return (ret);
16627836SJohn.Forte@Sun.COM 	}
16637836SJohn.Forte@Sun.COM 
16647836SJohn.Forte@Sun.COM 	/*
16657836SJohn.Forte@Sun.COM 	 * Open control node for stmf
16667836SJohn.Forte@Sun.COM 	 */
16677836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
16687836SJohn.Forte@Sun.COM 		return (ret);
16697836SJohn.Forte@Sun.COM 
16707836SJohn.Forte@Sun.COM 	/*
16717836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
16727836SJohn.Forte@Sun.COM 	 */
16737836SJohn.Forte@Sun.COM 	fTargetListSize = MAX_TARGET_PORT * sizeof (slist_target_port_t);
1674*8252SJohn.Forte@Sun.COM 	fTargetListP = fTargetList =
1675*8252SJohn.Forte@Sun.COM 	    (slist_target_port_t *)calloc(1, fTargetListSize);
16767836SJohn.Forte@Sun.COM 	if (fTargetList == NULL) {
16777836SJohn.Forte@Sun.COM 		goto done;
16787836SJohn.Forte@Sun.COM 	}
16797836SJohn.Forte@Sun.COM 
16807836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
16817836SJohn.Forte@Sun.COM 	/*
1682*8252SJohn.Forte@Sun.COM 	 * Issue ioctl to retrieve target list
16837836SJohn.Forte@Sun.COM 	 */
16847836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
16857836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fTargetListSize;
16867836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
16877836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
16887836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
16897836SJohn.Forte@Sun.COM 		switch (errno) {
16907836SJohn.Forte@Sun.COM 			case EBUSY:
16917836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
16927836SJohn.Forte@Sun.COM 				break;
16937836SJohn.Forte@Sun.COM 			case EACCES:
16947836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
16957836SJohn.Forte@Sun.COM 				break;
16967836SJohn.Forte@Sun.COM 			default:
16977836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
16987836SJohn.Forte@Sun.COM 				    "stmfGetTargetList:ioctl errno(%d)", errno);
16997836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
17007836SJohn.Forte@Sun.COM 				break;
17017836SJohn.Forte@Sun.COM 		}
17027836SJohn.Forte@Sun.COM 		goto done;
17037836SJohn.Forte@Sun.COM 	}
17047836SJohn.Forte@Sun.COM 	/*
17057836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
17067836SJohn.Forte@Sun.COM 	 */
17077836SJohn.Forte@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > MAX_TARGET_PORT) {
17087836SJohn.Forte@Sun.COM 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
17098116SJohn.Forte@Sun.COM 		    sizeof (slist_target_port_t);
1710*8252SJohn.Forte@Sun.COM 		fTargetListP = fTargetList =
1711*8252SJohn.Forte@Sun.COM 		    realloc(fTargetList, fTargetListSize);
17127836SJohn.Forte@Sun.COM 		if (fTargetList == NULL) {
17137836SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOMEM);
17147836SJohn.Forte@Sun.COM 		}
17157836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fTargetListSize;
17167836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
17177836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
17187836SJohn.Forte@Sun.COM 		    &stmfIoctl);
17197836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
17207836SJohn.Forte@Sun.COM 			switch (errno) {
17217836SJohn.Forte@Sun.COM 				case EBUSY:
17227836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
17237836SJohn.Forte@Sun.COM 					break;
17247836SJohn.Forte@Sun.COM 				case EACCES:
17257836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
17267836SJohn.Forte@Sun.COM 					break;
17277836SJohn.Forte@Sun.COM 				default:
17287836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
17297836SJohn.Forte@Sun.COM 					    "stmfGetTargetList:ioctl errno(%d)",
17307836SJohn.Forte@Sun.COM 					    errno);
17317836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
17327836SJohn.Forte@Sun.COM 					break;
17337836SJohn.Forte@Sun.COM 			}
17347836SJohn.Forte@Sun.COM 			goto done;
17357836SJohn.Forte@Sun.COM 		}
17367836SJohn.Forte@Sun.COM 	}
17377836SJohn.Forte@Sun.COM 
17387836SJohn.Forte@Sun.COM 	*targetList = (stmfDevidList *)calloc(1,
17397836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
17407836SJohn.Forte@Sun.COM 	    sizeof (stmfDevidList));
17417836SJohn.Forte@Sun.COM 
17427836SJohn.Forte@Sun.COM 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
17437836SJohn.Forte@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
17447836SJohn.Forte@Sun.COM 		(*targetList)->devid[i].identLength =
17457836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE];
17467836SJohn.Forte@Sun.COM 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
17477836SJohn.Forte@Sun.COM 		    &(*targetList)->devid[i].ident,
17487836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE]);
17497836SJohn.Forte@Sun.COM 	}
17507836SJohn.Forte@Sun.COM 
17517836SJohn.Forte@Sun.COM done:
17527836SJohn.Forte@Sun.COM 	(void) close(fd);
1753*8252SJohn.Forte@Sun.COM 	free(fTargetListP);
17547836SJohn.Forte@Sun.COM 	return (ret);
17557836SJohn.Forte@Sun.COM }
17567836SJohn.Forte@Sun.COM 
17577836SJohn.Forte@Sun.COM /*
17587836SJohn.Forte@Sun.COM  * stmfGetTargetProperties
17597836SJohn.Forte@Sun.COM  *
17607836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
17617836SJohn.Forte@Sun.COM  *
17627836SJohn.Forte@Sun.COM  * devid - devid of the target for which to retrieve properties
17637836SJohn.Forte@Sun.COM  * targetProps - pointer to an stmfTargetProperties structure.
17647836SJohn.Forte@Sun.COM  *		On success, it contains the target properties for
17657836SJohn.Forte@Sun.COM  *		the specified devid.
17667836SJohn.Forte@Sun.COM  */
17677836SJohn.Forte@Sun.COM int
17687836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
17697836SJohn.Forte@Sun.COM {
17707836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
17717836SJohn.Forte@Sun.COM 	int fd;
17727836SJohn.Forte@Sun.COM 	int ioctlRet;
17737836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
17747836SJohn.Forte@Sun.COM 	sioc_target_port_props_t targetProperties;
17757836SJohn.Forte@Sun.COM 
17767836SJohn.Forte@Sun.COM 	if (devid == NULL || targetProps == NULL) {
17777836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
17787836SJohn.Forte@Sun.COM 	}
17797836SJohn.Forte@Sun.COM 
17807836SJohn.Forte@Sun.COM 	/* call init */
17817836SJohn.Forte@Sun.COM 	ret = initializeConfig();
17827836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
17837836SJohn.Forte@Sun.COM 		return (ret);
17847836SJohn.Forte@Sun.COM 	}
17857836SJohn.Forte@Sun.COM 
17867836SJohn.Forte@Sun.COM 	/*
17877836SJohn.Forte@Sun.COM 	 * Open control node for stmf
17887836SJohn.Forte@Sun.COM 	 */
17897836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
17907836SJohn.Forte@Sun.COM 		return (ret);
17917836SJohn.Forte@Sun.COM 
17927836SJohn.Forte@Sun.COM 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
17937836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
17947836SJohn.Forte@Sun.COM 	    devid->identLength);
17957836SJohn.Forte@Sun.COM 
17967836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
17977836SJohn.Forte@Sun.COM 	/*
17987836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
17997836SJohn.Forte@Sun.COM 	 */
18007836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
18017836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
18027836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
18037836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
18047836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
18057836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
18067836SJohn.Forte@Sun.COM 	    &stmfIoctl);
18077836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
18087836SJohn.Forte@Sun.COM 		switch (errno) {
18097836SJohn.Forte@Sun.COM 			case EBUSY:
18107836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
18117836SJohn.Forte@Sun.COM 				break;
18127836SJohn.Forte@Sun.COM 			case EACCES:
18137836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
18147836SJohn.Forte@Sun.COM 				break;
18157836SJohn.Forte@Sun.COM 			case ENOENT:
18167836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
18177836SJohn.Forte@Sun.COM 				break;
18187836SJohn.Forte@Sun.COM 			default:
18197836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
18207836SJohn.Forte@Sun.COM 				    "stmfGetTargetProperties:ioctl errno(%d)",
18217836SJohn.Forte@Sun.COM 				    errno);
18227836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
18237836SJohn.Forte@Sun.COM 				break;
18247836SJohn.Forte@Sun.COM 		}
18257836SJohn.Forte@Sun.COM 		goto done;
18267836SJohn.Forte@Sun.COM 	}
18277836SJohn.Forte@Sun.COM 
18287836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
18297836SJohn.Forte@Sun.COM 	    sizeof (targetProperties.tgt_provider_name));
18307836SJohn.Forte@Sun.COM 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
18317836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINE;
18327836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
18337836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
18347836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
18357836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINING;
18367836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
18377836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
18387836SJohn.Forte@Sun.COM 	}
18397836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_alias, targetProps->alias,
18407836SJohn.Forte@Sun.COM 	    sizeof (targetProps->alias));
18417836SJohn.Forte@Sun.COM done:
18427836SJohn.Forte@Sun.COM 	(void) close(fd);
18437836SJohn.Forte@Sun.COM 	return (ret);
18447836SJohn.Forte@Sun.COM }
18457836SJohn.Forte@Sun.COM 
18467836SJohn.Forte@Sun.COM /*
18477836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitList
18487836SJohn.Forte@Sun.COM  *
18497836SJohn.Forte@Sun.COM  * Purpose: Retrieves list of logical unit Object IDs
18507836SJohn.Forte@Sun.COM  *
18517836SJohn.Forte@Sun.COM  * luList - pointer to a pointer to a stmfGuidList structure. On success,
18527836SJohn.Forte@Sun.COM  *          it contains the list of logical unit guids.
18537836SJohn.Forte@Sun.COM  *
18547836SJohn.Forte@Sun.COM  */
18557836SJohn.Forte@Sun.COM int
18567836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList)
18577836SJohn.Forte@Sun.COM {
18587836SJohn.Forte@Sun.COM 	int ret;
18597836SJohn.Forte@Sun.COM 	int fd;
18607836SJohn.Forte@Sun.COM 	int ioctlRet;
18617836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_LU_LIST;
18627836SJohn.Forte@Sun.COM 	int i, k;
18637836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
18647836SJohn.Forte@Sun.COM 	/* framework lu list */
18657836SJohn.Forte@Sun.COM 	slist_lu_t *fLuList;
18667836SJohn.Forte@Sun.COM 	/* persistent store lu list */
18677836SJohn.Forte@Sun.COM 	stmfGuidList *sLuList = NULL;
18687836SJohn.Forte@Sun.COM 	int finalListSize = 0;
18697836SJohn.Forte@Sun.COM 	int newAllocSize;
18707836SJohn.Forte@Sun.COM 	uint32_t fLuListSize;
18717836SJohn.Forte@Sun.COM 	uint32_t endList;
18727836SJohn.Forte@Sun.COM 
18737836SJohn.Forte@Sun.COM 	if (luList == NULL) {
18747836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
18757836SJohn.Forte@Sun.COM 	}
18767836SJohn.Forte@Sun.COM 
18777836SJohn.Forte@Sun.COM 	/* call init */
18787836SJohn.Forte@Sun.COM 	ret = initializeConfig();
18797836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
18807836SJohn.Forte@Sun.COM 		return (ret);
18817836SJohn.Forte@Sun.COM 	}
18827836SJohn.Forte@Sun.COM 
18837836SJohn.Forte@Sun.COM 	/*
18847836SJohn.Forte@Sun.COM 	 * Open control node for stmf
18857836SJohn.Forte@Sun.COM 	 */
18867836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
18877836SJohn.Forte@Sun.COM 		return (ret);
18887836SJohn.Forte@Sun.COM 
18897836SJohn.Forte@Sun.COM 	/*
18907836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
18917836SJohn.Forte@Sun.COM 	 */
18927836SJohn.Forte@Sun.COM 	fLuListSize = MAX_LU;
18937836SJohn.Forte@Sun.COM 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
18947836SJohn.Forte@Sun.COM 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
18957836SJohn.Forte@Sun.COM 	if (fLuList == NULL) {
18967836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
18977836SJohn.Forte@Sun.COM 	}
18987836SJohn.Forte@Sun.COM 
18997836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
19007836SJohn.Forte@Sun.COM 	/*
19017836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the LU list
19027836SJohn.Forte@Sun.COM 	 */
19037836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
19047836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fLuListSize;
19057836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
19067836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
19077836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
19087836SJohn.Forte@Sun.COM 		switch (errno) {
19097836SJohn.Forte@Sun.COM 			case EBUSY:
19107836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
19117836SJohn.Forte@Sun.COM 				break;
19127836SJohn.Forte@Sun.COM 			case EACCES:
19137836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
19147836SJohn.Forte@Sun.COM 				break;
19157836SJohn.Forte@Sun.COM 			default:
19167836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
19177836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
19187836SJohn.Forte@Sun.COM 				    errno);
19197836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
19207836SJohn.Forte@Sun.COM 				break;
19217836SJohn.Forte@Sun.COM 		}
19227836SJohn.Forte@Sun.COM 		goto done;
19237836SJohn.Forte@Sun.COM 	}
19247836SJohn.Forte@Sun.COM 	/*
19257836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
19267836SJohn.Forte@Sun.COM 	 */
19277836SJohn.Forte@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > MAX_LU) {
19287836SJohn.Forte@Sun.COM 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
19297836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
19307836SJohn.Forte@Sun.COM 		fLuList = realloc(fLuList, fLuListSize);
19317836SJohn.Forte@Sun.COM 		if (fLuList == NULL) {
19327836SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOMEM);
19337836SJohn.Forte@Sun.COM 		}
19347836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fLuListSize;
19357836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
19367836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
19377836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
19387836SJohn.Forte@Sun.COM 			switch (errno) {
19397836SJohn.Forte@Sun.COM 				case EBUSY:
19407836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
19417836SJohn.Forte@Sun.COM 					break;
19427836SJohn.Forte@Sun.COM 				case EACCES:
19437836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
19447836SJohn.Forte@Sun.COM 					break;
19457836SJohn.Forte@Sun.COM 				default:
19467836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
19477836SJohn.Forte@Sun.COM 					    "stmfGetLogicalUnitList:"
19487836SJohn.Forte@Sun.COM 					    "ioctl errno(%d)", errno);
19497836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
19507836SJohn.Forte@Sun.COM 					break;
19517836SJohn.Forte@Sun.COM 			}
19527836SJohn.Forte@Sun.COM 			goto done;
19537836SJohn.Forte@Sun.COM 		}
19547836SJohn.Forte@Sun.COM 	}
19557836SJohn.Forte@Sun.COM 
19567836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&sLuList);
19577836SJohn.Forte@Sun.COM 	switch (ret) {
19587836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
19597836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
19607836SJohn.Forte@Sun.COM 			break;
19617836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
19627836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
19637836SJohn.Forte@Sun.COM 			break;
19647836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
19657836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
19667836SJohn.Forte@Sun.COM 			break;
19677836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
19687836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
19697836SJohn.Forte@Sun.COM 			break;
19707836SJohn.Forte@Sun.COM 		default:
19717836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
19727836SJohn.Forte@Sun.COM 			    "stmfGetLogicalUnitList:psGetLogicalUnitList"
19737836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
19747836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
19757836SJohn.Forte@Sun.COM 			break;
19767836SJohn.Forte@Sun.COM 	}
19777836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
19787836SJohn.Forte@Sun.COM 		goto done;
19797836SJohn.Forte@Sun.COM 	}
19807836SJohn.Forte@Sun.COM 
19817836SJohn.Forte@Sun.COM 	/*
19827836SJohn.Forte@Sun.COM 	 * 2 lists must be merged
19837836SJohn.Forte@Sun.COM 	 * reallocate the store list to add the list from the
19847836SJohn.Forte@Sun.COM 	 * framework
19857836SJohn.Forte@Sun.COM 	 */
19867836SJohn.Forte@Sun.COM 	newAllocSize = sLuList->cnt * sizeof (stmfGuid) + sizeof (stmfGuidList)
19877836SJohn.Forte@Sun.COM 	    + stmfIoctl.stmf_obuf_nentries * sizeof (stmfGuid);
19887836SJohn.Forte@Sun.COM 
19897836SJohn.Forte@Sun.COM 	sLuList = realloc(sLuList, newAllocSize);
19907836SJohn.Forte@Sun.COM 	if (sLuList == NULL) {
19917836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
19927836SJohn.Forte@Sun.COM 		goto done;
19937836SJohn.Forte@Sun.COM 	}
19947836SJohn.Forte@Sun.COM 
19957836SJohn.Forte@Sun.COM 	/*
19967836SJohn.Forte@Sun.COM 	 * add list from ioctl. Start from end of list retrieved from store.
19977836SJohn.Forte@Sun.COM 	 */
19987836SJohn.Forte@Sun.COM 	endList = sLuList->cnt + stmfIoctl.stmf_obuf_nentries;
19997836SJohn.Forte@Sun.COM 	for (k = 0, i = sLuList->cnt; i < endList; i++, k++) {
20007836SJohn.Forte@Sun.COM 		bcopy(&fLuList[k].lu_guid, sLuList->guid[i].guid,
20017836SJohn.Forte@Sun.COM 		    sizeof (stmfGuid));
20027836SJohn.Forte@Sun.COM 	}
20037836SJohn.Forte@Sun.COM 	sLuList->cnt = endList;
20047836SJohn.Forte@Sun.COM 
20057836SJohn.Forte@Sun.COM 	/*
20067836SJohn.Forte@Sun.COM 	 * sort the list for merging
20077836SJohn.Forte@Sun.COM 	 */
20087836SJohn.Forte@Sun.COM 	qsort((void *)&(sLuList->guid[0]), sLuList->cnt,
20097836SJohn.Forte@Sun.COM 	    sizeof (stmfGuid), guidCompare);
20107836SJohn.Forte@Sun.COM 
20117836SJohn.Forte@Sun.COM 	/*
20127836SJohn.Forte@Sun.COM 	 * get final list count
20137836SJohn.Forte@Sun.COM 	 */
20147836SJohn.Forte@Sun.COM 	for (i = 0; i < sLuList->cnt; i++) {
20157836SJohn.Forte@Sun.COM 		if ((i + 1) <= sLuList->cnt) {
20167836SJohn.Forte@Sun.COM 			if (bcmp(sLuList->guid[i].guid, sLuList->guid[i+1].guid,
20177836SJohn.Forte@Sun.COM 			    sizeof (stmfGuid)) == 0) {
20187836SJohn.Forte@Sun.COM 				continue;
20197836SJohn.Forte@Sun.COM 			}
20207836SJohn.Forte@Sun.COM 		}
20217836SJohn.Forte@Sun.COM 		finalListSize++;
20227836SJohn.Forte@Sun.COM 	}
20237836SJohn.Forte@Sun.COM 
20247836SJohn.Forte@Sun.COM 	/*
20257836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
20267836SJohn.Forte@Sun.COM 	 */
20277836SJohn.Forte@Sun.COM 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
20287836SJohn.Forte@Sun.COM 	    finalListSize * sizeof (stmfGuid));
20297836SJohn.Forte@Sun.COM 	if (*luList == NULL) {
20307836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
20317836SJohn.Forte@Sun.COM 		goto done;
20327836SJohn.Forte@Sun.COM 	}
20337836SJohn.Forte@Sun.COM 
20347836SJohn.Forte@Sun.COM 	/*
20357836SJohn.Forte@Sun.COM 	 * copy guids to caller's buffer
20367836SJohn.Forte@Sun.COM 	 */
20377836SJohn.Forte@Sun.COM 	for (k = 0, i = 0; i < sLuList->cnt; i++) {
20387836SJohn.Forte@Sun.COM 		if ((i + 1) <= sLuList->cnt) {
20397836SJohn.Forte@Sun.COM 			if (bcmp(sLuList->guid[i].guid, sLuList->guid[i+1].guid,
20407836SJohn.Forte@Sun.COM 			    sizeof (stmfGuid)) == 0) {
20417836SJohn.Forte@Sun.COM 				continue;
20427836SJohn.Forte@Sun.COM 			}
20437836SJohn.Forte@Sun.COM 		}
20447836SJohn.Forte@Sun.COM 		bcopy(&(sLuList->guid[i].guid), (*luList)->guid[k++].guid,
20457836SJohn.Forte@Sun.COM 		    sizeof (stmfGuid));
20467836SJohn.Forte@Sun.COM 	}
20477836SJohn.Forte@Sun.COM 
20487836SJohn.Forte@Sun.COM 	(*luList)->cnt = finalListSize;
20497836SJohn.Forte@Sun.COM 
20507836SJohn.Forte@Sun.COM done:
20517836SJohn.Forte@Sun.COM 	(void) close(fd);
20527836SJohn.Forte@Sun.COM 	/*
20537836SJohn.Forte@Sun.COM 	 * free internal buffers
20547836SJohn.Forte@Sun.COM 	 */
20557836SJohn.Forte@Sun.COM 	free(fLuList);
20567836SJohn.Forte@Sun.COM 	free(sLuList);
20577836SJohn.Forte@Sun.COM 	return (ret);
20587836SJohn.Forte@Sun.COM }
20597836SJohn.Forte@Sun.COM 
20607836SJohn.Forte@Sun.COM /*
20617836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitProperties
20627836SJohn.Forte@Sun.COM  *
20637836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
20647836SJohn.Forte@Sun.COM  *
20657836SJohn.Forte@Sun.COM  * lu - guid of the logical unit for which to retrieve properties
20667836SJohn.Forte@Sun.COM  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
20677836SJohn.Forte@Sun.COM  *               it contains the logical unit properties for the specified guid.
20687836SJohn.Forte@Sun.COM  */
20697836SJohn.Forte@Sun.COM int
20707836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
20717836SJohn.Forte@Sun.COM {
20727836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
20737836SJohn.Forte@Sun.COM 	int stmfRet;
20747836SJohn.Forte@Sun.COM 	int fd;
20757836SJohn.Forte@Sun.COM 	int ioctlRet;
20767836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
20777836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
20787836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
20797836SJohn.Forte@Sun.COM 	sioc_lu_props_t fLuProps;
20807836SJohn.Forte@Sun.COM 
20817836SJohn.Forte@Sun.COM 	if (luProps == NULL || luProps == NULL) {
20827836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
20837836SJohn.Forte@Sun.COM 	}
20847836SJohn.Forte@Sun.COM 
20857836SJohn.Forte@Sun.COM 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
20867836SJohn.Forte@Sun.COM 
20877836SJohn.Forte@Sun.COM 	/* call init */
20887836SJohn.Forte@Sun.COM 	ret = initializeConfig();
20897836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
20907836SJohn.Forte@Sun.COM 		return (ret);
20917836SJohn.Forte@Sun.COM 	}
20927836SJohn.Forte@Sun.COM 
20937836SJohn.Forte@Sun.COM 	/*
20947836SJohn.Forte@Sun.COM 	 * Open control node for stmf
20957836SJohn.Forte@Sun.COM 	 */
20967836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
20977836SJohn.Forte@Sun.COM 		return (ret);
20987836SJohn.Forte@Sun.COM 
20997836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
21007836SJohn.Forte@Sun.COM 	/*
21017836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
21027836SJohn.Forte@Sun.COM 	 */
21037836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
21047836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
21057836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
21067836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
21077836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
21087836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
21097836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
21107836SJohn.Forte@Sun.COM 		switch (errno) {
21117836SJohn.Forte@Sun.COM 			case EBUSY:
21127836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
21137836SJohn.Forte@Sun.COM 				break;
21147836SJohn.Forte@Sun.COM 			case EACCES:
21157836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
21167836SJohn.Forte@Sun.COM 				break;
21177836SJohn.Forte@Sun.COM 			case ENOENT:
21187836SJohn.Forte@Sun.COM 				stmfRet = stmfGetViewEntryList(lu,
21197836SJohn.Forte@Sun.COM 				    &viewEntryList);
21207836SJohn.Forte@Sun.COM 				if (stmfRet == STMF_STATUS_SUCCESS) {
21217836SJohn.Forte@Sun.COM 					luProps->status =
21227836SJohn.Forte@Sun.COM 					    STMF_LOGICAL_UNIT_UNREGISTERED;
21237836SJohn.Forte@Sun.COM 					if (viewEntryList->cnt > 0) {
21247836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_SUCCESS;
21257836SJohn.Forte@Sun.COM 					} else {
21267836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
21277836SJohn.Forte@Sun.COM 					}
21287836SJohn.Forte@Sun.COM 				} else {
21297836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
21307836SJohn.Forte@Sun.COM 				}
21317836SJohn.Forte@Sun.COM 				stmfFreeMemory(viewEntryList);
21327836SJohn.Forte@Sun.COM 				break;
21337836SJohn.Forte@Sun.COM 			default:
21347836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
21357836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnit:ioctl errno(%d)",
21367836SJohn.Forte@Sun.COM 				    errno);
21377836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
21387836SJohn.Forte@Sun.COM 				break;
21397836SJohn.Forte@Sun.COM 		}
21407836SJohn.Forte@Sun.COM 		goto done;
21417836SJohn.Forte@Sun.COM 	}
21427836SJohn.Forte@Sun.COM 
21437836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
21447836SJohn.Forte@Sun.COM 	    sizeof (fLuProps.lu_provider_name));
21457836SJohn.Forte@Sun.COM 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
21467836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
21477836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
21487836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
21497836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
21507836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
21517836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
21527836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
21537836SJohn.Forte@Sun.COM 	}
21547836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
21557836SJohn.Forte@Sun.COM done:
21567836SJohn.Forte@Sun.COM 	(void) close(fd);
21577836SJohn.Forte@Sun.COM 	return (ret);
21587836SJohn.Forte@Sun.COM }
21597836SJohn.Forte@Sun.COM 
21607836SJohn.Forte@Sun.COM /*
21617836SJohn.Forte@Sun.COM  * stmfGetState
21627836SJohn.Forte@Sun.COM  *
21637836SJohn.Forte@Sun.COM  * Purpose: retrieve the current state of the stmf module
21647836SJohn.Forte@Sun.COM  *
21657836SJohn.Forte@Sun.COM  * state - pointer to stmfState structure allocated by the caller
21667836SJohn.Forte@Sun.COM  *         On success, contains the state of stmf
21677836SJohn.Forte@Sun.COM  */
21687836SJohn.Forte@Sun.COM int
21697836SJohn.Forte@Sun.COM stmfGetState(stmfState *state)
21707836SJohn.Forte@Sun.COM {
21717836SJohn.Forte@Sun.COM 	int ret;
21727836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
21737836SJohn.Forte@Sun.COM 
21747836SJohn.Forte@Sun.COM 	if (state == NULL) {
21757836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
21767836SJohn.Forte@Sun.COM 	}
21777836SJohn.Forte@Sun.COM 
21787836SJohn.Forte@Sun.COM 	ret = getStmfState(&iState);
21797836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
21807836SJohn.Forte@Sun.COM 		return (ret);
21817836SJohn.Forte@Sun.COM 	}
21827836SJohn.Forte@Sun.COM 	switch (iState.state) {
21837836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINE:
21847836SJohn.Forte@Sun.COM 			state->operationalState =
21857836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINE;
21867836SJohn.Forte@Sun.COM 			break;
21877836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINE:
21887836SJohn.Forte@Sun.COM 			state->operationalState =
21897836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINE;
21907836SJohn.Forte@Sun.COM 			break;
21917836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINING:
21927836SJohn.Forte@Sun.COM 			state->operationalState =
21937836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINING;
21947836SJohn.Forte@Sun.COM 			break;
21957836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINING:
21967836SJohn.Forte@Sun.COM 			state->operationalState =
21977836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINING;
21987836SJohn.Forte@Sun.COM 			break;
21997836SJohn.Forte@Sun.COM 		default:
22007836SJohn.Forte@Sun.COM 			state->operationalState =
22017836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_UNKNOWN;
22027836SJohn.Forte@Sun.COM 			break;
22037836SJohn.Forte@Sun.COM 	}
22047836SJohn.Forte@Sun.COM 	switch (iState.config_state) {
22057836SJohn.Forte@Sun.COM 		case STMF_CONFIG_NONE:
22067836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_NONE;
22077836SJohn.Forte@Sun.COM 			break;
22087836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT:
22097836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_INIT;
22107836SJohn.Forte@Sun.COM 			break;
22117836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT_DONE:
22127836SJohn.Forte@Sun.COM 			state->configState =
22137836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_INIT_DONE;
22147836SJohn.Forte@Sun.COM 			break;
22157836SJohn.Forte@Sun.COM 		default:
22167836SJohn.Forte@Sun.COM 			state->configState =
22177836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_UNKNOWN;
22187836SJohn.Forte@Sun.COM 			break;
22197836SJohn.Forte@Sun.COM 	}
22207836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
22217836SJohn.Forte@Sun.COM }
22227836SJohn.Forte@Sun.COM 
22237836SJohn.Forte@Sun.COM /*
22247836SJohn.Forte@Sun.COM  * stmfGetViewEntryList
22257836SJohn.Forte@Sun.COM  *
22267836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of view entries for the specified
22277836SJohn.Forte@Sun.COM  *          logical unit.
22287836SJohn.Forte@Sun.COM  *
22297836SJohn.Forte@Sun.COM  * lu - the guid of the logical unit for which to retrieve the view entry list
22307836SJohn.Forte@Sun.COM  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
22317836SJohn.Forte@Sun.COM  *                 success, contains the list of view entries.
22327836SJohn.Forte@Sun.COM  */
22337836SJohn.Forte@Sun.COM int
22347836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
22357836SJohn.Forte@Sun.COM {
22367836SJohn.Forte@Sun.COM 	int ret;
22377836SJohn.Forte@Sun.COM 
22387836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntryList == NULL) {
22397836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
22407836SJohn.Forte@Sun.COM 	}
22417836SJohn.Forte@Sun.COM 
22427836SJohn.Forte@Sun.COM 	ret = psGetViewEntryList(lu, viewEntryList);
22437836SJohn.Forte@Sun.COM 	switch (ret) {
22447836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
22457836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
22467836SJohn.Forte@Sun.COM 			break;
22477836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
22487836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
22497836SJohn.Forte@Sun.COM 			break;
22507836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
22517836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
22527836SJohn.Forte@Sun.COM 			break;
22537836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
22547836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
22557836SJohn.Forte@Sun.COM 			break;
22567836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
22577836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
22587836SJohn.Forte@Sun.COM 			break;
22597836SJohn.Forte@Sun.COM 		default:
22607836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
22617836SJohn.Forte@Sun.COM 			    "stmfGetViewEntryList:error(%d)", ret);
22627836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
22637836SJohn.Forte@Sun.COM 			break;
22647836SJohn.Forte@Sun.COM 	}
22657836SJohn.Forte@Sun.COM 
22667836SJohn.Forte@Sun.COM 	return (ret);
22677836SJohn.Forte@Sun.COM }
22687836SJohn.Forte@Sun.COM 
22697836SJohn.Forte@Sun.COM /*
22707836SJohn.Forte@Sun.COM  * loadHostGroups
22717836SJohn.Forte@Sun.COM  *
22727836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the host groups into stmf
22737836SJohn.Forte@Sun.COM  *
22747836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
22757836SJohn.Forte@Sun.COM  * groupList - populated host group list
22767836SJohn.Forte@Sun.COM  */
22777836SJohn.Forte@Sun.COM static int
22787836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList)
22797836SJohn.Forte@Sun.COM {
22807836SJohn.Forte@Sun.COM 	int i, j;
22817836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
22827836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
22837836SJohn.Forte@Sun.COM 
22847836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
22857836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
22867836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
22877836SJohn.Forte@Sun.COM 			goto out;
22887836SJohn.Forte@Sun.COM 		}
22897836SJohn.Forte@Sun.COM 		ret = stmfGetHostGroupMembers(&(groupList->name[i]),
22907836SJohn.Forte@Sun.COM 		    &groupProps);
22917836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
22927836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
22937836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
22947836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
22957836SJohn.Forte@Sun.COM 				goto out;
22967836SJohn.Forte@Sun.COM 			}
22977836SJohn.Forte@Sun.COM 		}
22987836SJohn.Forte@Sun.COM 	}
22997836SJohn.Forte@Sun.COM 
23007836SJohn.Forte@Sun.COM 
23017836SJohn.Forte@Sun.COM out:
23027836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
23037836SJohn.Forte@Sun.COM 	return (ret);
23047836SJohn.Forte@Sun.COM }
23057836SJohn.Forte@Sun.COM 
23067836SJohn.Forte@Sun.COM /*
23077836SJohn.Forte@Sun.COM  * loadTargetGroups
23087836SJohn.Forte@Sun.COM  *
23097836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the target groups into stmf
23107836SJohn.Forte@Sun.COM  *
23117836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
23127836SJohn.Forte@Sun.COM  * groupList - populated target group list.
23137836SJohn.Forte@Sun.COM  */
23147836SJohn.Forte@Sun.COM static int
23157836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList)
23167836SJohn.Forte@Sun.COM {
23177836SJohn.Forte@Sun.COM 	int i, j;
23187836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
23197836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
23207836SJohn.Forte@Sun.COM 
23217836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
23227836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
23237836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
23247836SJohn.Forte@Sun.COM 			goto out;
23257836SJohn.Forte@Sun.COM 		}
23267836SJohn.Forte@Sun.COM 		ret = stmfGetTargetGroupMembers(&(groupList->name[i]),
23277836SJohn.Forte@Sun.COM 		    &groupProps);
23287836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
23297836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
23307836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
23317836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
23327836SJohn.Forte@Sun.COM 				goto out;
23337836SJohn.Forte@Sun.COM 			}
23347836SJohn.Forte@Sun.COM 		}
23357836SJohn.Forte@Sun.COM 	}
23367836SJohn.Forte@Sun.COM 
23377836SJohn.Forte@Sun.COM 
23387836SJohn.Forte@Sun.COM out:
23397836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
23407836SJohn.Forte@Sun.COM 	return (ret);
23417836SJohn.Forte@Sun.COM }
23427836SJohn.Forte@Sun.COM 
23437836SJohn.Forte@Sun.COM 
23447836SJohn.Forte@Sun.COM /*
23457836SJohn.Forte@Sun.COM  * loadStore
23467836SJohn.Forte@Sun.COM  *
23477836SJohn.Forte@Sun.COM  * Purpose: Load the configuration data from the store
23487836SJohn.Forte@Sun.COM  *
23497836SJohn.Forte@Sun.COM  * First load the host groups and target groups, then the view entries
23507836SJohn.Forte@Sun.COM  * and finally the provider data
23517836SJohn.Forte@Sun.COM  *
23527836SJohn.Forte@Sun.COM  * fd - file descriptor of control node for stmf.
23537836SJohn.Forte@Sun.COM  */
23547836SJohn.Forte@Sun.COM static int
23557836SJohn.Forte@Sun.COM loadStore(int fd)
23567836SJohn.Forte@Sun.COM {
23577836SJohn.Forte@Sun.COM 	int ret;
23587836SJohn.Forte@Sun.COM 	int i, j;
23597836SJohn.Forte@Sun.COM 	stmfGroupList *groupList = NULL;
23607836SJohn.Forte@Sun.COM 	stmfGuidList *guidList = NULL;
23617836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
23627836SJohn.Forte@Sun.COM 	stmfProviderList *providerList = NULL;
23637836SJohn.Forte@Sun.COM 	int providerType;
23647836SJohn.Forte@Sun.COM 	nvlist_t *nvl = NULL;
23657836SJohn.Forte@Sun.COM 
23667836SJohn.Forte@Sun.COM 
23677836SJohn.Forte@Sun.COM 
23687836SJohn.Forte@Sun.COM 	/* load host groups */
23697836SJohn.Forte@Sun.COM 	ret = stmfGetHostGroupList(&groupList);
23707836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
23717836SJohn.Forte@Sun.COM 		return (ret);
23727836SJohn.Forte@Sun.COM 	}
23737836SJohn.Forte@Sun.COM 	ret = loadHostGroups(fd, groupList);
23747836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
23757836SJohn.Forte@Sun.COM 		goto out;
23767836SJohn.Forte@Sun.COM 	}
23777836SJohn.Forte@Sun.COM 
23787836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
23797836SJohn.Forte@Sun.COM 	groupList = NULL;
23807836SJohn.Forte@Sun.COM 
23817836SJohn.Forte@Sun.COM 	/* load target groups */
23827836SJohn.Forte@Sun.COM 	ret = stmfGetTargetGroupList(&groupList);
23837836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
23847836SJohn.Forte@Sun.COM 		goto out;
23857836SJohn.Forte@Sun.COM 	}
23867836SJohn.Forte@Sun.COM 	ret = loadTargetGroups(fd, groupList);
23877836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
23887836SJohn.Forte@Sun.COM 		goto out;
23897836SJohn.Forte@Sun.COM 	}
23907836SJohn.Forte@Sun.COM 
23917836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
23927836SJohn.Forte@Sun.COM 	groupList = NULL;
23937836SJohn.Forte@Sun.COM 
23947836SJohn.Forte@Sun.COM 	/* Get the guid list */
23957836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&guidList);
23967836SJohn.Forte@Sun.COM 	switch (ret) {
23977836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
23987836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
23997836SJohn.Forte@Sun.COM 			break;
24007836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
24017836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
24027836SJohn.Forte@Sun.COM 			break;
24037836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
24047836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
24057836SJohn.Forte@Sun.COM 			break;
24067836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
24077836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
24087836SJohn.Forte@Sun.COM 			break;
24097836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
24107836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
24117836SJohn.Forte@Sun.COM 			break;
24127836SJohn.Forte@Sun.COM 		default:
24137836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
24147836SJohn.Forte@Sun.COM 			break;
24157836SJohn.Forte@Sun.COM 	}
24167836SJohn.Forte@Sun.COM 
24177836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
24187836SJohn.Forte@Sun.COM 		goto out;
24197836SJohn.Forte@Sun.COM 	}
24207836SJohn.Forte@Sun.COM 
24217836SJohn.Forte@Sun.COM 	/*
24227836SJohn.Forte@Sun.COM 	 * We have the guid list, now get the corresponding
24237836SJohn.Forte@Sun.COM 	 * view entries for each guid
24247836SJohn.Forte@Sun.COM 	 */
24257836SJohn.Forte@Sun.COM 	for (i = 0; i < guidList->cnt; i++) {
24267836SJohn.Forte@Sun.COM 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
24277836SJohn.Forte@Sun.COM 		switch (ret) {
24287836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
24297836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
24307836SJohn.Forte@Sun.COM 				break;
24317836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
24327836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
24337836SJohn.Forte@Sun.COM 				break;
24347836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
24357836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
24367836SJohn.Forte@Sun.COM 				break;
24377836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
24387836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
24397836SJohn.Forte@Sun.COM 				break;
24407836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
24417836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
24427836SJohn.Forte@Sun.COM 				break;
24437836SJohn.Forte@Sun.COM 			default:
24447836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
24457836SJohn.Forte@Sun.COM 				break;
24467836SJohn.Forte@Sun.COM 		}
24477836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
24487836SJohn.Forte@Sun.COM 			goto out;
24497836SJohn.Forte@Sun.COM 		}
24507836SJohn.Forte@Sun.COM 		for (j = 0; j < viewEntryList->cnt; j++) {
24517836SJohn.Forte@Sun.COM 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
24527836SJohn.Forte@Sun.COM 			    &viewEntryList->ve[j]);
24537836SJohn.Forte@Sun.COM 			if (ret != STMF_STATUS_SUCCESS) {
24547836SJohn.Forte@Sun.COM 				goto out;
24557836SJohn.Forte@Sun.COM 			}
24567836SJohn.Forte@Sun.COM 		}
24577836SJohn.Forte@Sun.COM 	}
24587836SJohn.Forte@Sun.COM 
24597836SJohn.Forte@Sun.COM 	/* get the list of providers that have data */
24607836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(&providerList);
24617836SJohn.Forte@Sun.COM 	switch (ret) {
24627836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
24637836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
24647836SJohn.Forte@Sun.COM 			break;
24657836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
24667836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
24677836SJohn.Forte@Sun.COM 			break;
24687836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
24697836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
24707836SJohn.Forte@Sun.COM 			break;
24717836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
24727836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
24737836SJohn.Forte@Sun.COM 			break;
24747836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
24757836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
24767836SJohn.Forte@Sun.COM 			break;
24777836SJohn.Forte@Sun.COM 		default:
24787836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
24797836SJohn.Forte@Sun.COM 			break;
24807836SJohn.Forte@Sun.COM 	}
24817836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
24827836SJohn.Forte@Sun.COM 		goto out;
24837836SJohn.Forte@Sun.COM 	}
24847836SJohn.Forte@Sun.COM 
24857836SJohn.Forte@Sun.COM 	for (i = 0; i < providerList->cnt; i++) {
24867836SJohn.Forte@Sun.COM 		providerType = providerList->provider[i].providerType;
24877836SJohn.Forte@Sun.COM 		ret = psGetProviderData(providerList->provider[i].name,
24887836SJohn.Forte@Sun.COM 		    &nvl, providerType, NULL);
24897836SJohn.Forte@Sun.COM 		switch (ret) {
24907836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
24917836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
24927836SJohn.Forte@Sun.COM 				break;
24937836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
24947836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
24957836SJohn.Forte@Sun.COM 				break;
24967836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
24977836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
24987836SJohn.Forte@Sun.COM 				break;
24997836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
25007836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
25017836SJohn.Forte@Sun.COM 				break;
25027836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
25037836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
25047836SJohn.Forte@Sun.COM 				break;
25057836SJohn.Forte@Sun.COM 			default:
25067836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
25077836SJohn.Forte@Sun.COM 				break;
25087836SJohn.Forte@Sun.COM 		}
25097836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
25107836SJohn.Forte@Sun.COM 			goto out;
25117836SJohn.Forte@Sun.COM 		}
25127836SJohn.Forte@Sun.COM 
25137836SJohn.Forte@Sun.COM 		/* call setProviderData */
25147836SJohn.Forte@Sun.COM 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
25157836SJohn.Forte@Sun.COM 		    providerType);
25167836SJohn.Forte@Sun.COM 		switch (ret) {
25177836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
25187836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
25197836SJohn.Forte@Sun.COM 				break;
25207836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
25217836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
25227836SJohn.Forte@Sun.COM 				break;
25237836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
25247836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
25257836SJohn.Forte@Sun.COM 				break;
25267836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
25277836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
25287836SJohn.Forte@Sun.COM 				break;
25297836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
25307836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
25317836SJohn.Forte@Sun.COM 				break;
25327836SJohn.Forte@Sun.COM 			default:
25337836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
25347836SJohn.Forte@Sun.COM 				break;
25357836SJohn.Forte@Sun.COM 		}
25367836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
25377836SJohn.Forte@Sun.COM 			goto out;
25387836SJohn.Forte@Sun.COM 		}
25397836SJohn.Forte@Sun.COM 
25407836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
25417836SJohn.Forte@Sun.COM 		nvl = NULL;
25427836SJohn.Forte@Sun.COM 	}
25437836SJohn.Forte@Sun.COM out:
25447836SJohn.Forte@Sun.COM 	if (groupList != NULL) {
25457836SJohn.Forte@Sun.COM 		free(groupList);
25467836SJohn.Forte@Sun.COM 	}
25477836SJohn.Forte@Sun.COM 	if (guidList != NULL) {
25487836SJohn.Forte@Sun.COM 		free(guidList);
25497836SJohn.Forte@Sun.COM 	}
25507836SJohn.Forte@Sun.COM 	if (viewEntryList != NULL) {
25517836SJohn.Forte@Sun.COM 		free(viewEntryList);
25527836SJohn.Forte@Sun.COM 	}
25537836SJohn.Forte@Sun.COM 	if (nvl != NULL) {
25547836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
25557836SJohn.Forte@Sun.COM 	}
25567836SJohn.Forte@Sun.COM 	return (ret);
25577836SJohn.Forte@Sun.COM }
25587836SJohn.Forte@Sun.COM 
25597836SJohn.Forte@Sun.COM /*
25607836SJohn.Forte@Sun.COM  * stmfLoadConfig
25617836SJohn.Forte@Sun.COM  *
25627836SJohn.Forte@Sun.COM  * Purpose - load the configuration data from smf into stmf
25637836SJohn.Forte@Sun.COM  *
25647836SJohn.Forte@Sun.COM  */
25657836SJohn.Forte@Sun.COM int
25667836SJohn.Forte@Sun.COM stmfLoadConfig(void)
25677836SJohn.Forte@Sun.COM {
25687836SJohn.Forte@Sun.COM 	int ret;
25697836SJohn.Forte@Sun.COM 	int fd;
25707836SJohn.Forte@Sun.COM 	stmf_state_desc_t stmfStateSet;
25717836SJohn.Forte@Sun.COM 	stmfState state;
25727836SJohn.Forte@Sun.COM 
25737836SJohn.Forte@Sun.COM 
25747836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
25757836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
25767836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
25777836SJohn.Forte@Sun.COM 	}
25787836SJohn.Forte@Sun.COM 
25797836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
25807836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
25817836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
25827836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
25837836SJohn.Forte@Sun.COM 		}
25847836SJohn.Forte@Sun.COM 	} else {
25857836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
25867836SJohn.Forte@Sun.COM 	}
25877836SJohn.Forte@Sun.COM 
25887836SJohn.Forte@Sun.COM 
25897836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
25907836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT;
25917836SJohn.Forte@Sun.COM 
25927836SJohn.Forte@Sun.COM 	/*
25937836SJohn.Forte@Sun.COM 	 * Open control node for stmf
25947836SJohn.Forte@Sun.COM 	 */
25957836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
25967836SJohn.Forte@Sun.COM 		return (ret);
25977836SJohn.Forte@Sun.COM 
25987836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
25997836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
26007836SJohn.Forte@Sun.COM 		goto done;
26017836SJohn.Forte@Sun.COM 	}
26027836SJohn.Forte@Sun.COM 
26037836SJohn.Forte@Sun.COM 	/* Load the persistent configuration data */
26047836SJohn.Forte@Sun.COM 	ret = loadStore(fd);
26057836SJohn.Forte@Sun.COM 	if (ret != 0) {
26067836SJohn.Forte@Sun.COM 		goto done;
26077836SJohn.Forte@Sun.COM 	}
26087836SJohn.Forte@Sun.COM 
26097836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
26107836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
26117836SJohn.Forte@Sun.COM 
26127836SJohn.Forte@Sun.COM done:
26137836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
26147836SJohn.Forte@Sun.COM 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
26157836SJohn.Forte@Sun.COM 	}
26167836SJohn.Forte@Sun.COM 	(void) close(fd);
26177836SJohn.Forte@Sun.COM 	return (ret);
26187836SJohn.Forte@Sun.COM }
26197836SJohn.Forte@Sun.COM 
26207836SJohn.Forte@Sun.COM /*
26217836SJohn.Forte@Sun.COM  * getStmfState
26227836SJohn.Forte@Sun.COM  *
26237836SJohn.Forte@Sun.COM  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
26247836SJohn.Forte@Sun.COM  *             information of the stmf service on success.
26257836SJohn.Forte@Sun.COM  */
26267836SJohn.Forte@Sun.COM static int
26277836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState)
26287836SJohn.Forte@Sun.COM {
26297836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
26307836SJohn.Forte@Sun.COM 	int fd;
26317836SJohn.Forte@Sun.COM 	int ioctlRet;
26327836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
26337836SJohn.Forte@Sun.COM 
26347836SJohn.Forte@Sun.COM 	/*
26357836SJohn.Forte@Sun.COM 	 * Open control node for stmf
26367836SJohn.Forte@Sun.COM 	 */
26377836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
26387836SJohn.Forte@Sun.COM 		return (ret);
26397836SJohn.Forte@Sun.COM 
26407836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
26417836SJohn.Forte@Sun.COM 	/*
26427836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
26437836SJohn.Forte@Sun.COM 	 */
26447836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
26457836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
26467836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
26477836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
26487836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
26497836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
26507836SJohn.Forte@Sun.COM 
26517836SJohn.Forte@Sun.COM 	(void) close(fd);
26527836SJohn.Forte@Sun.COM 
26537836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
26547836SJohn.Forte@Sun.COM 		switch (errno) {
26557836SJohn.Forte@Sun.COM 			case EBUSY:
26567836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
26577836SJohn.Forte@Sun.COM 				break;
26587836SJohn.Forte@Sun.COM 			case EPERM:
26597836SJohn.Forte@Sun.COM 			case EACCES:
26607836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
26617836SJohn.Forte@Sun.COM 				break;
26627836SJohn.Forte@Sun.COM 			default:
26637836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
26647836SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
26657836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
26667836SJohn.Forte@Sun.COM 				break;
26677836SJohn.Forte@Sun.COM 		}
26687836SJohn.Forte@Sun.COM 	}
26697836SJohn.Forte@Sun.COM 	return (ret);
26707836SJohn.Forte@Sun.COM }
26717836SJohn.Forte@Sun.COM 
26727836SJohn.Forte@Sun.COM 
26737836SJohn.Forte@Sun.COM /*
26747836SJohn.Forte@Sun.COM  * setStmfState
26757836SJohn.Forte@Sun.COM  *
26767836SJohn.Forte@Sun.COM  * stmfState - pointer to caller set state structure
26777836SJohn.Forte@Sun.COM  * objectType - one of:
26787836SJohn.Forte@Sun.COM  *		LOGICAL_UNIT_TYPE
26797836SJohn.Forte@Sun.COM  *		TARGET_TYPE
26807836SJohn.Forte@Sun.COM  *		STMF_SERVICE_TYPE
26817836SJohn.Forte@Sun.COM  */
26827836SJohn.Forte@Sun.COM static int
26837836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
26847836SJohn.Forte@Sun.COM {
26857836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
26867836SJohn.Forte@Sun.COM 	int ioctlRet;
26877836SJohn.Forte@Sun.COM 	int cmd;
26887836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
26897836SJohn.Forte@Sun.COM 
26907836SJohn.Forte@Sun.COM 	switch (objectType) {
26917836SJohn.Forte@Sun.COM 		case LOGICAL_UNIT_TYPE:
26927836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_LU_STATE;
26937836SJohn.Forte@Sun.COM 			break;
26947836SJohn.Forte@Sun.COM 		case TARGET_TYPE:
26957836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
26967836SJohn.Forte@Sun.COM 			break;
26977836SJohn.Forte@Sun.COM 		case STMF_SERVICE_TYPE:
26987836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_STMF_STATE;
26997836SJohn.Forte@Sun.COM 			break;
27007836SJohn.Forte@Sun.COM 		default:
27017836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
27027836SJohn.Forte@Sun.COM 			goto done;
27037836SJohn.Forte@Sun.COM 	}
27047836SJohn.Forte@Sun.COM 
27057836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
27067836SJohn.Forte@Sun.COM 	/*
27077836SJohn.Forte@Sun.COM 	 * Issue ioctl to set the stmf state
27087836SJohn.Forte@Sun.COM 	 */
27097836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
27107836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
27117836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
27127836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
27137836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
27147836SJohn.Forte@Sun.COM 		switch (errno) {
27157836SJohn.Forte@Sun.COM 			case EBUSY:
27167836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
27177836SJohn.Forte@Sun.COM 				break;
27187836SJohn.Forte@Sun.COM 			case EACCES:
27197836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
27207836SJohn.Forte@Sun.COM 				break;
27217836SJohn.Forte@Sun.COM 			case ENOENT:
27227836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
27237836SJohn.Forte@Sun.COM 				break;
27247836SJohn.Forte@Sun.COM 			default:
27257836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
27267836SJohn.Forte@Sun.COM 				    "setStmfState:ioctl errno(%d)", errno);
27277836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
27287836SJohn.Forte@Sun.COM 				break;
27297836SJohn.Forte@Sun.COM 		}
27307836SJohn.Forte@Sun.COM 	}
27317836SJohn.Forte@Sun.COM done:
27327836SJohn.Forte@Sun.COM 	return (ret);
27337836SJohn.Forte@Sun.COM }
27347836SJohn.Forte@Sun.COM 
27357836SJohn.Forte@Sun.COM /*
27367836SJohn.Forte@Sun.COM  * stmfOnline
27377836SJohn.Forte@Sun.COM  *
27387836SJohn.Forte@Sun.COM  * Purpose: Online stmf service
27397836SJohn.Forte@Sun.COM  *
27407836SJohn.Forte@Sun.COM  */
27417836SJohn.Forte@Sun.COM int
27427836SJohn.Forte@Sun.COM stmfOnline(void)
27437836SJohn.Forte@Sun.COM {
27447836SJohn.Forte@Sun.COM 	int ret;
27457836SJohn.Forte@Sun.COM 	int fd;
27467836SJohn.Forte@Sun.COM 	stmfState state;
27477836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
27487836SJohn.Forte@Sun.COM 
27497836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
27507836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
27517836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
27527836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
27537836SJohn.Forte@Sun.COM 		}
27547836SJohn.Forte@Sun.COM 	} else {
27557836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
27567836SJohn.Forte@Sun.COM 	}
27577836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_ONLINE;
27587836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
27597836SJohn.Forte@Sun.COM 	/*
27607836SJohn.Forte@Sun.COM 	 * Open control node for stmf
27617836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
27627836SJohn.Forte@Sun.COM 	 */
27637836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
27647836SJohn.Forte@Sun.COM 		return (ret);
27657836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
27667836SJohn.Forte@Sun.COM 	(void) close(fd);
27677836SJohn.Forte@Sun.COM 	return (ret);
27687836SJohn.Forte@Sun.COM }
27697836SJohn.Forte@Sun.COM 
27707836SJohn.Forte@Sun.COM /*
27717836SJohn.Forte@Sun.COM  * stmfOffline
27727836SJohn.Forte@Sun.COM  *
27737836SJohn.Forte@Sun.COM  * Purpose: Offline stmf service
27747836SJohn.Forte@Sun.COM  *
27757836SJohn.Forte@Sun.COM  */
27767836SJohn.Forte@Sun.COM int
27777836SJohn.Forte@Sun.COM stmfOffline(void)
27787836SJohn.Forte@Sun.COM {
27797836SJohn.Forte@Sun.COM 	int ret;
27807836SJohn.Forte@Sun.COM 	int fd;
27817836SJohn.Forte@Sun.COM 	stmfState state;
27827836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
27837836SJohn.Forte@Sun.COM 
27847836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
27857836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
27867836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
27877836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_OFFLINE);
27887836SJohn.Forte@Sun.COM 		}
27897836SJohn.Forte@Sun.COM 	} else {
27907836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
27917836SJohn.Forte@Sun.COM 	}
27927836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_OFFLINE;
27937836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
27947836SJohn.Forte@Sun.COM 
27957836SJohn.Forte@Sun.COM 	/*
27967836SJohn.Forte@Sun.COM 	 * Open control node for stmf
27977836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
27987836SJohn.Forte@Sun.COM 	 */
27997836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
28007836SJohn.Forte@Sun.COM 		return (ret);
28017836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
28027836SJohn.Forte@Sun.COM 	(void) close(fd);
28037836SJohn.Forte@Sun.COM 	return (ret);
28047836SJohn.Forte@Sun.COM }
28057836SJohn.Forte@Sun.COM 
28067836SJohn.Forte@Sun.COM 
28077836SJohn.Forte@Sun.COM /*
28087836SJohn.Forte@Sun.COM  * stmfOfflineTarget
28097836SJohn.Forte@Sun.COM  *
28107836SJohn.Forte@Sun.COM  * Purpose: Change state of target to offline
28117836SJohn.Forte@Sun.COM  *
28127836SJohn.Forte@Sun.COM  * devid - devid of the target to offline
28137836SJohn.Forte@Sun.COM  */
28147836SJohn.Forte@Sun.COM int
28157836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid)
28167836SJohn.Forte@Sun.COM {
28177836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
28187836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
28197836SJohn.Forte@Sun.COM 	int fd;
28207836SJohn.Forte@Sun.COM 
28217836SJohn.Forte@Sun.COM 	if (devid == NULL) {
28227836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28237836SJohn.Forte@Sun.COM 	}
28247836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
28257836SJohn.Forte@Sun.COM 
28267836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_OFFLINE;
28277836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
28287836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
28297836SJohn.Forte@Sun.COM 	    devid->identLength);
28307836SJohn.Forte@Sun.COM 	/*
28317836SJohn.Forte@Sun.COM 	 * Open control node for stmf
28327836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
28337836SJohn.Forte@Sun.COM 	 */
28347836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
28357836SJohn.Forte@Sun.COM 		return (ret);
28367836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
28377836SJohn.Forte@Sun.COM 	(void) close(fd);
28387836SJohn.Forte@Sun.COM 	return (ret);
28397836SJohn.Forte@Sun.COM }
28407836SJohn.Forte@Sun.COM 
28417836SJohn.Forte@Sun.COM /*
28427836SJohn.Forte@Sun.COM  * stmfOfflineLogicalUnit
28437836SJohn.Forte@Sun.COM  *
28447836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to offline
28457836SJohn.Forte@Sun.COM  *
28467836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to offline
28477836SJohn.Forte@Sun.COM  */
28487836SJohn.Forte@Sun.COM int
28497836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu)
28507836SJohn.Forte@Sun.COM {
28517836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
28527836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
28537836SJohn.Forte@Sun.COM 	int fd;
28547836SJohn.Forte@Sun.COM 
28557836SJohn.Forte@Sun.COM 	if (lu == NULL) {
28567836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28577836SJohn.Forte@Sun.COM 	}
28587836SJohn.Forte@Sun.COM 
28597836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
28607836SJohn.Forte@Sun.COM 
28617836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_OFFLINE;
28627836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
28637836SJohn.Forte@Sun.COM 	/*
28647836SJohn.Forte@Sun.COM 	 * Open control node for stmf
28657836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
28667836SJohn.Forte@Sun.COM 	 */
28677836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
28687836SJohn.Forte@Sun.COM 		return (ret);
28697836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
28707836SJohn.Forte@Sun.COM 	(void) close(fd);
28717836SJohn.Forte@Sun.COM 	return (ret);
28727836SJohn.Forte@Sun.COM }
28737836SJohn.Forte@Sun.COM 
28747836SJohn.Forte@Sun.COM /*
28757836SJohn.Forte@Sun.COM  * stmfOnlineTarget
28767836SJohn.Forte@Sun.COM  *
28777836SJohn.Forte@Sun.COM  * Purpose: Change state of target to online
28787836SJohn.Forte@Sun.COM  *
28797836SJohn.Forte@Sun.COM  * devid - devid of the target to online
28807836SJohn.Forte@Sun.COM  */
28817836SJohn.Forte@Sun.COM int
28827836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid)
28837836SJohn.Forte@Sun.COM {
28847836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
28857836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
28867836SJohn.Forte@Sun.COM 	int fd;
28877836SJohn.Forte@Sun.COM 
28887836SJohn.Forte@Sun.COM 	if (devid == NULL) {
28897836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
28907836SJohn.Forte@Sun.COM 	}
28917836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
28927836SJohn.Forte@Sun.COM 
28937836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_ONLINE;
28947836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
28957836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
28967836SJohn.Forte@Sun.COM 	    devid->identLength);
28977836SJohn.Forte@Sun.COM 	/*
28987836SJohn.Forte@Sun.COM 	 * Open control node for stmf
28997836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
29007836SJohn.Forte@Sun.COM 	 */
29017836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
29027836SJohn.Forte@Sun.COM 		return (ret);
29037836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
29047836SJohn.Forte@Sun.COM 	(void) close(fd);
29057836SJohn.Forte@Sun.COM 	return (ret);
29067836SJohn.Forte@Sun.COM }
29077836SJohn.Forte@Sun.COM 
29087836SJohn.Forte@Sun.COM /*
29097836SJohn.Forte@Sun.COM  * stmfOnlineLogicalUnit
29107836SJohn.Forte@Sun.COM  *
29117836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to online
29127836SJohn.Forte@Sun.COM  *
29137836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to online
29147836SJohn.Forte@Sun.COM  */
29157836SJohn.Forte@Sun.COM int
29167836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu)
29177836SJohn.Forte@Sun.COM {
29187836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
29197836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
29207836SJohn.Forte@Sun.COM 	int fd;
29217836SJohn.Forte@Sun.COM 
29227836SJohn.Forte@Sun.COM 	if (lu == NULL) {
29237836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
29247836SJohn.Forte@Sun.COM 	}
29257836SJohn.Forte@Sun.COM 
29267836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
29277836SJohn.Forte@Sun.COM 
29287836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_ONLINE;
29297836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
29307836SJohn.Forte@Sun.COM 	/*
29317836SJohn.Forte@Sun.COM 	 * Open control node for stmf
29327836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
29337836SJohn.Forte@Sun.COM 	 */
29347836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
29357836SJohn.Forte@Sun.COM 		return (ret);
29367836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
29377836SJohn.Forte@Sun.COM 	(void) close(fd);
29387836SJohn.Forte@Sun.COM 	return (ret);
29397836SJohn.Forte@Sun.COM }
29407836SJohn.Forte@Sun.COM 
29417836SJohn.Forte@Sun.COM /*
29427836SJohn.Forte@Sun.COM  * stmfRemoveFromHostGroup
29437836SJohn.Forte@Sun.COM  *
29447836SJohn.Forte@Sun.COM  * Purpose: Removes an initiator from an initiator group
29457836SJohn.Forte@Sun.COM  *
29467836SJohn.Forte@Sun.COM  * hostGroupName - name of an initiator group
29477836SJohn.Forte@Sun.COM  * hostName - name of host group member to remove
29487836SJohn.Forte@Sun.COM  */
29497836SJohn.Forte@Sun.COM int
29507836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
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 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
29577836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
29587836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
29597836SJohn.Forte@Sun.COM 	}
29607836SJohn.Forte@Sun.COM 
29617836SJohn.Forte@Sun.COM 	/* call init */
29627836SJohn.Forte@Sun.COM 	ret = initializeConfig();
29637836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
29647836SJohn.Forte@Sun.COM 		return (ret);
29657836SJohn.Forte@Sun.COM 	}
29667836SJohn.Forte@Sun.COM 
29677836SJohn.Forte@Sun.COM 	/*
29687836SJohn.Forte@Sun.COM 	 * Open control node for stmf
29697836SJohn.Forte@Sun.COM 	 */
29707836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
29717836SJohn.Forte@Sun.COM 		return (ret);
29727836SJohn.Forte@Sun.COM 
29737836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
29747836SJohn.Forte@Sun.COM 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
29757836SJohn.Forte@Sun.COM 		goto done;
29767836SJohn.Forte@Sun.COM 	}
29777836SJohn.Forte@Sun.COM 
29787836SJohn.Forte@Sun.COM 	ret = psRemoveHostGroupMember((char *)hostGroupName,
29797836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
29807836SJohn.Forte@Sun.COM 	switch (ret) {
29817836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
29827836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
29837836SJohn.Forte@Sun.COM 			break;
29847836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
29857836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
29867836SJohn.Forte@Sun.COM 			break;
29877836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
29887836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
29897836SJohn.Forte@Sun.COM 			break;
29907836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
29917836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
29927836SJohn.Forte@Sun.COM 			break;
29937836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
29947836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
29957836SJohn.Forte@Sun.COM 			break;
29967836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
29977836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
29987836SJohn.Forte@Sun.COM 			break;
29997836SJohn.Forte@Sun.COM 		default:
30007836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
30017836SJohn.Forte@Sun.COM 			    "stmfRemoveFromHostGroup"
30027836SJohn.Forte@Sun.COM 			    "psRemoveHostGroupMember:error(%d)", ret);
30037836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
30047836SJohn.Forte@Sun.COM 			break;
30057836SJohn.Forte@Sun.COM 	}
30067836SJohn.Forte@Sun.COM 
30077836SJohn.Forte@Sun.COM done:
30087836SJohn.Forte@Sun.COM 	(void) close(fd);
30097836SJohn.Forte@Sun.COM 	return (ret);
30107836SJohn.Forte@Sun.COM }
30117836SJohn.Forte@Sun.COM 
30127836SJohn.Forte@Sun.COM /*
30137836SJohn.Forte@Sun.COM  * stmfRemoveFromTargetGroup
30147836SJohn.Forte@Sun.COM  *
30157836SJohn.Forte@Sun.COM  * Purpose: Removes a local port from a local port group
30167836SJohn.Forte@Sun.COM  *
30177836SJohn.Forte@Sun.COM  * targetGroupName - name of a target group
30187836SJohn.Forte@Sun.COM  * targetName - name of target to remove
30197836SJohn.Forte@Sun.COM  */
30207836SJohn.Forte@Sun.COM int
30217836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
30227836SJohn.Forte@Sun.COM {
30237836SJohn.Forte@Sun.COM 	int ret;
30247836SJohn.Forte@Sun.COM 	int fd;
30257836SJohn.Forte@Sun.COM 
30267836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
30277836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
30287836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
30297836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
30307836SJohn.Forte@Sun.COM 	}
30317836SJohn.Forte@Sun.COM 
30327836SJohn.Forte@Sun.COM 	/* call init */
30337836SJohn.Forte@Sun.COM 	ret = initializeConfig();
30347836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
30357836SJohn.Forte@Sun.COM 		return (ret);
30367836SJohn.Forte@Sun.COM 	}
30377836SJohn.Forte@Sun.COM 
30387836SJohn.Forte@Sun.COM 	/*
30397836SJohn.Forte@Sun.COM 	 * Open control node for stmf
30407836SJohn.Forte@Sun.COM 	 */
30417836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
30427836SJohn.Forte@Sun.COM 		return (ret);
30437836SJohn.Forte@Sun.COM 
30447836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
30457836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
30467836SJohn.Forte@Sun.COM 		goto done;
30477836SJohn.Forte@Sun.COM 	}
30487836SJohn.Forte@Sun.COM 
30497836SJohn.Forte@Sun.COM 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
30507836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
30517836SJohn.Forte@Sun.COM 	switch (ret) {
30527836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
30537836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
30547836SJohn.Forte@Sun.COM 			break;
30557836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
30567836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
30577836SJohn.Forte@Sun.COM 			break;
30587836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
30597836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
30607836SJohn.Forte@Sun.COM 			break;
30617836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
30627836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
30637836SJohn.Forte@Sun.COM 			break;
30647836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
30657836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
30667836SJohn.Forte@Sun.COM 			break;
30677836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
30687836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
30697836SJohn.Forte@Sun.COM 			break;
30707836SJohn.Forte@Sun.COM 		default:
30717836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
30727836SJohn.Forte@Sun.COM 			    "stmfRemoveFromTargetGroup"
30737836SJohn.Forte@Sun.COM 			    "psRemoveTargetGroupMember:error(%d)", ret);
30747836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
30757836SJohn.Forte@Sun.COM 			break;
30767836SJohn.Forte@Sun.COM 	}
30777836SJohn.Forte@Sun.COM 
30787836SJohn.Forte@Sun.COM done:
30797836SJohn.Forte@Sun.COM 	(void) close(fd);
30807836SJohn.Forte@Sun.COM 	return (ret);
30817836SJohn.Forte@Sun.COM }
30827836SJohn.Forte@Sun.COM 
30837836SJohn.Forte@Sun.COM /*
30847836SJohn.Forte@Sun.COM  * stmfRemoveViewEntry
30857836SJohn.Forte@Sun.COM  *
30867836SJohn.Forte@Sun.COM  * Purpose: Removes a view entry from a logical unit
30877836SJohn.Forte@Sun.COM  *
30887836SJohn.Forte@Sun.COM  * lu - guid of lu for which view entry is being removed
30897836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry to remove
30907836SJohn.Forte@Sun.COM  *
30917836SJohn.Forte@Sun.COM  */
30927836SJohn.Forte@Sun.COM int
30937836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
30947836SJohn.Forte@Sun.COM {
30957836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
30967836SJohn.Forte@Sun.COM 	int fd;
30977836SJohn.Forte@Sun.COM 	int ioctlRet;
30987836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
30997836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
31007836SJohn.Forte@Sun.COM 
31017836SJohn.Forte@Sun.COM 	if (lu == NULL) {
31027836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
31037836SJohn.Forte@Sun.COM 	}
31047836SJohn.Forte@Sun.COM 
31057836SJohn.Forte@Sun.COM 	/* call init */
31067836SJohn.Forte@Sun.COM 	ret = initializeConfig();
31077836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
31087836SJohn.Forte@Sun.COM 		return (ret);
31097836SJohn.Forte@Sun.COM 	}
31107836SJohn.Forte@Sun.COM 
31117836SJohn.Forte@Sun.COM 	/*
31127836SJohn.Forte@Sun.COM 	 * Open control node for stmf
31137836SJohn.Forte@Sun.COM 	 */
31147836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
31157836SJohn.Forte@Sun.COM 		return (ret);
31167836SJohn.Forte@Sun.COM 
31177836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
31187836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
31197836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx = viewEntryIndex;
31207836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
31217836SJohn.Forte@Sun.COM 
31227836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
31237836SJohn.Forte@Sun.COM 	/*
31247836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
31257836SJohn.Forte@Sun.COM 	 */
31267836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
31277836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
31287836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
31297836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
31307836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
31317836SJohn.Forte@Sun.COM 		switch (errno) {
31327836SJohn.Forte@Sun.COM 			case EBUSY:
31337836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
31347836SJohn.Forte@Sun.COM 				break;
31357836SJohn.Forte@Sun.COM 			case EACCES:
31367836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
31377836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
31387836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
31397836SJohn.Forte@Sun.COM 						break;
31407836SJohn.Forte@Sun.COM 					default:
31417836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
31427836SJohn.Forte@Sun.COM 						break;
31437836SJohn.Forte@Sun.COM 				}
31447836SJohn.Forte@Sun.COM 				break;
31457836SJohn.Forte@Sun.COM 			case ENODEV:
31467836SJohn.Forte@Sun.COM 			case ENOENT:
31477836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
31487836SJohn.Forte@Sun.COM 				break;
31497836SJohn.Forte@Sun.COM 			default:
31507836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
31517836SJohn.Forte@Sun.COM 				    "stmfRemoveViewEntry:ioctl errno(%d)",
31527836SJohn.Forte@Sun.COM 				    errno);
31537836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
31547836SJohn.Forte@Sun.COM 				break;
31557836SJohn.Forte@Sun.COM 		}
31567836SJohn.Forte@Sun.COM 		goto done;
31577836SJohn.Forte@Sun.COM 	}
31587836SJohn.Forte@Sun.COM 
31597836SJohn.Forte@Sun.COM 	ret = psRemoveViewEntry(lu, viewEntryIndex);
31607836SJohn.Forte@Sun.COM 	switch (ret) {
31617836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
31627836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
31637836SJohn.Forte@Sun.COM 			break;
31647836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
31657836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
31667836SJohn.Forte@Sun.COM 			break;
31677836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
31687836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
31697836SJohn.Forte@Sun.COM 			break;
31707836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
31717836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
31727836SJohn.Forte@Sun.COM 			break;
31737836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
31747836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
31757836SJohn.Forte@Sun.COM 			break;
31767836SJohn.Forte@Sun.COM 		default:
31777836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
31787836SJohn.Forte@Sun.COM 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
31797836SJohn.Forte@Sun.COM 			    ret);
31807836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
31817836SJohn.Forte@Sun.COM 			break;
31827836SJohn.Forte@Sun.COM 	}
31837836SJohn.Forte@Sun.COM 
31847836SJohn.Forte@Sun.COM done:
31857836SJohn.Forte@Sun.COM 	(void) close(fd);
31867836SJohn.Forte@Sun.COM 	return (ret);
31877836SJohn.Forte@Sun.COM }
31887836SJohn.Forte@Sun.COM 
31897836SJohn.Forte@Sun.COM /*
31907836SJohn.Forte@Sun.COM  * stmfSetProviderData
31917836SJohn.Forte@Sun.COM  *
31927836SJohn.Forte@Sun.COM  * Purpose: set the provider data
31937836SJohn.Forte@Sun.COM  *
31947836SJohn.Forte@Sun.COM  * providerName - unique name of provider
31957836SJohn.Forte@Sun.COM  * nvl - nvlist to set
31967836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
31977836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
31987836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
31997836SJohn.Forte@Sun.COM  */
32007836SJohn.Forte@Sun.COM int
32017836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
32027836SJohn.Forte@Sun.COM {
32037836SJohn.Forte@Sun.COM 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
32047836SJohn.Forte@Sun.COM 	    NULL));
32057836SJohn.Forte@Sun.COM }
32067836SJohn.Forte@Sun.COM 
32077836SJohn.Forte@Sun.COM /*
32087836SJohn.Forte@Sun.COM  * stmfSetProviderDataProt
32097836SJohn.Forte@Sun.COM  *
32107836SJohn.Forte@Sun.COM  * Purpose: set the provider data
32117836SJohn.Forte@Sun.COM  *
32127836SJohn.Forte@Sun.COM  * providerName - unique name of provider
32137836SJohn.Forte@Sun.COM  * nvl - nvlist to set
32147836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
32157836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
32167836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
32177836SJohn.Forte@Sun.COM  * setToken - Stale data token returned in the stmfGetProviderDataProt()
32187836SJohn.Forte@Sun.COM  *	      call or NULL.
32197836SJohn.Forte@Sun.COM  */
32207836SJohn.Forte@Sun.COM int
32217836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
32227836SJohn.Forte@Sun.COM     uint64_t *setToken)
32237836SJohn.Forte@Sun.COM {
32247836SJohn.Forte@Sun.COM 	int ret;
32257836SJohn.Forte@Sun.COM 	int fd;
32267836SJohn.Forte@Sun.COM 
32277836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
32287836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32297836SJohn.Forte@Sun.COM 	}
32307836SJohn.Forte@Sun.COM 
32317836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
32327836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
32337836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
32347836SJohn.Forte@Sun.COM 	}
32357836SJohn.Forte@Sun.COM 
32367836SJohn.Forte@Sun.COM 	/* call init */
32377836SJohn.Forte@Sun.COM 	ret = initializeConfig();
32387836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
32397836SJohn.Forte@Sun.COM 		return (ret);
32407836SJohn.Forte@Sun.COM 	}
32417836SJohn.Forte@Sun.COM 
32427836SJohn.Forte@Sun.COM 	/*
32437836SJohn.Forte@Sun.COM 	 * Open control node for stmf
32447836SJohn.Forte@Sun.COM 	 */
32457836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
32467836SJohn.Forte@Sun.COM 		return (ret);
32477836SJohn.Forte@Sun.COM 
32487836SJohn.Forte@Sun.COM 	ret = setProviderData(fd, providerName, nvl, providerType);
32497836SJohn.Forte@Sun.COM 
32507836SJohn.Forte@Sun.COM 	(void) close(fd);
32517836SJohn.Forte@Sun.COM 
32527836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
32537836SJohn.Forte@Sun.COM 		goto done;
32547836SJohn.Forte@Sun.COM 	}
32557836SJohn.Forte@Sun.COM 
32567836SJohn.Forte@Sun.COM 	/* setting driver provider data successful. Now persist it */
32577836SJohn.Forte@Sun.COM 	ret = psSetProviderData(providerName, nvl, providerType, setToken);
32587836SJohn.Forte@Sun.COM 	switch (ret) {
32597836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
32607836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
32617836SJohn.Forte@Sun.COM 			break;
32627836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
32637836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
32647836SJohn.Forte@Sun.COM 			break;
32657836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
32667836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
32677836SJohn.Forte@Sun.COM 			break;
32687836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
32697836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
32707836SJohn.Forte@Sun.COM 			break;
32717836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
32727836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
32737836SJohn.Forte@Sun.COM 			break;
32747836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_PROV_DATA_STALE:
32757836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PROV_DATA_STALE;
32767836SJohn.Forte@Sun.COM 			break;
32777836SJohn.Forte@Sun.COM 		default:
32787836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
32797836SJohn.Forte@Sun.COM 			    "stmfSetProviderData"
32807836SJohn.Forte@Sun.COM 			    "psSetProviderData:error(%d)", ret);
32817836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
32827836SJohn.Forte@Sun.COM 			break;
32837836SJohn.Forte@Sun.COM 	}
32847836SJohn.Forte@Sun.COM 
32857836SJohn.Forte@Sun.COM done:
32867836SJohn.Forte@Sun.COM 	return (ret);
32877836SJohn.Forte@Sun.COM }
32887836SJohn.Forte@Sun.COM 
32897836SJohn.Forte@Sun.COM /*
32907836SJohn.Forte@Sun.COM  * setProviderData
32917836SJohn.Forte@Sun.COM  *
32927836SJohn.Forte@Sun.COM  * Purpose: set the provider data
32937836SJohn.Forte@Sun.COM  *
32947836SJohn.Forte@Sun.COM  * providerName - unique name of provider
32957836SJohn.Forte@Sun.COM  * nvl - nvlist to set
32967836SJohn.Forte@Sun.COM  * providerType - logical unit or port provider
32977836SJohn.Forte@Sun.COM  */
32987836SJohn.Forte@Sun.COM static int
32997836SJohn.Forte@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType)
33007836SJohn.Forte@Sun.COM {
33017836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
33027836SJohn.Forte@Sun.COM 	int ioctlRet;
33037836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
33047836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t *ppi = NULL;
33057836SJohn.Forte@Sun.COM 	char *allocatedNvBuffer;
33067836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
33077836SJohn.Forte@Sun.COM 
33087836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
33097836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
33107836SJohn.Forte@Sun.COM 	}
33117836SJohn.Forte@Sun.COM 
33127836SJohn.Forte@Sun.COM 	/* get size of encoded nvlist */
33137836SJohn.Forte@Sun.COM 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
33147836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
33157836SJohn.Forte@Sun.COM 	}
33167836SJohn.Forte@Sun.COM 
33177836SJohn.Forte@Sun.COM 	/* allocate memory for ioctl */
33187836SJohn.Forte@Sun.COM 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
33197836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t));
33207836SJohn.Forte@Sun.COM 	if (ppi == NULL) {
33217836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
33227836SJohn.Forte@Sun.COM 	}
33237836SJohn.Forte@Sun.COM 
33247836SJohn.Forte@Sun.COM 	allocatedNvBuffer = (char *)&ppi->ppi_data;
33257836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
33267836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
33277836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
33287836SJohn.Forte@Sun.COM 	}
33297836SJohn.Forte@Sun.COM 
33307836SJohn.Forte@Sun.COM 	/* set provider name and provider type */
33317836SJohn.Forte@Sun.COM 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
33327836SJohn.Forte@Sun.COM 	switch (providerType) {
33337836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
33347836SJohn.Forte@Sun.COM 			ppi->ppi_lu_provider = 1;
33357836SJohn.Forte@Sun.COM 			break;
33367836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
33377836SJohn.Forte@Sun.COM 			ppi->ppi_port_provider = 1;
33387836SJohn.Forte@Sun.COM 			break;
33397836SJohn.Forte@Sun.COM 		default:
33407836SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
33417836SJohn.Forte@Sun.COM 	}
33427836SJohn.Forte@Sun.COM 
33437836SJohn.Forte@Sun.COM 	/* set the size of the ioctl data to packed data size */
33447836SJohn.Forte@Sun.COM 	ppi->ppi_data_size = nvlistEncodedSize;
33457836SJohn.Forte@Sun.COM 
33467836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
33477836SJohn.Forte@Sun.COM 
33487836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
33497836SJohn.Forte@Sun.COM 	/*
33507836SJohn.Forte@Sun.COM 	 * Subtracting 8 from the size as that is the size of the last member
33517836SJohn.Forte@Sun.COM 	 * of the structure where the packed data resides
33527836SJohn.Forte@Sun.COM 	 */
33537836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
33547836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t) - 8;
33557836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
33567836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
33577836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
33587836SJohn.Forte@Sun.COM 		switch (errno) {
33597836SJohn.Forte@Sun.COM 			case EBUSY:
33607836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
33617836SJohn.Forte@Sun.COM 				break;
33627836SJohn.Forte@Sun.COM 			case EACCES:
33637836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
33647836SJohn.Forte@Sun.COM 				break;
33657836SJohn.Forte@Sun.COM 			default:
33667836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
33677836SJohn.Forte@Sun.COM 				    "setProviderData:ioctl errno(%d)", errno);
33687836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
33697836SJohn.Forte@Sun.COM 				break;
33707836SJohn.Forte@Sun.COM 		}
33717836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS)
33727836SJohn.Forte@Sun.COM 			goto done;
33737836SJohn.Forte@Sun.COM 	}
33747836SJohn.Forte@Sun.COM 
33757836SJohn.Forte@Sun.COM done:
33767836SJohn.Forte@Sun.COM 	free(ppi);
33777836SJohn.Forte@Sun.COM 	return (ret);
33787836SJohn.Forte@Sun.COM }
3379