1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM #include <stdlib.h>
27*7836SJohn.Forte@Sun.COM #include <stdio.h>
28*7836SJohn.Forte@Sun.COM #include <wchar.h>
29*7836SJohn.Forte@Sun.COM #include <strings.h>
30*7836SJohn.Forte@Sun.COM #include <sys/types.h>
31*7836SJohn.Forte@Sun.COM #include <sys/stat.h>
32*7836SJohn.Forte@Sun.COM #include <fcntl.h>
33*7836SJohn.Forte@Sun.COM #include <unistd.h>
34*7836SJohn.Forte@Sun.COM #include <libintl.h>
35*7836SJohn.Forte@Sun.COM #include <errno.h>
36*7836SJohn.Forte@Sun.COM #include <string.h>
37*7836SJohn.Forte@Sun.COM #include <assert.h>
38*7836SJohn.Forte@Sun.COM #include <libnvpair.h>
39*7836SJohn.Forte@Sun.COM #include <pthread.h>
40*7836SJohn.Forte@Sun.COM #include <syslog.h>
41*7836SJohn.Forte@Sun.COM #include <libstmf.h>
42*7836SJohn.Forte@Sun.COM #include <netinet/in.h>
43*7836SJohn.Forte@Sun.COM #include <inttypes.h>
44*7836SJohn.Forte@Sun.COM #include <store.h>
45*7836SJohn.Forte@Sun.COM #include <locale.h>
46*7836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h>
47*7836SJohn.Forte@Sun.COM 
48*7836SJohn.Forte@Sun.COM #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
49*7836SJohn.Forte@Sun.COM 
50*7836SJohn.Forte@Sun.COM #define	EUI "eui."
51*7836SJohn.Forte@Sun.COM #define	WWN "wwn."
52*7836SJohn.Forte@Sun.COM #define	IQN "iqn."
53*7836SJohn.Forte@Sun.COM #define	WWN_ASCII_SIZE 16
54*7836SJohn.Forte@Sun.COM #define	IDENT_LENGTH_BYTE 3
55*7836SJohn.Forte@Sun.COM 
56*7836SJohn.Forte@Sun.COM #define	MAX_LU		2<<16 - 1
57*7836SJohn.Forte@Sun.COM #define	MAX_TARGET_PORT	1024
58*7836SJohn.Forte@Sun.COM #define	MAX_PROVIDER	1024
59*7836SJohn.Forte@Sun.COM #define	MAX_GROUP	1024
60*7836SJohn.Forte@Sun.COM #define	MAX_SESSION	1024
61*7836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME	223
62*7836SJohn.Forte@Sun.COM 
63*7836SJohn.Forte@Sun.COM #define	OPEN_STMF 0
64*7836SJohn.Forte@Sun.COM #define	OPEN_EXCL_STMF O_EXCL
65*7836SJohn.Forte@Sun.COM 
66*7836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_TYPE 0
67*7836SJohn.Forte@Sun.COM #define	TARGET_TYPE 1
68*7836SJohn.Forte@Sun.COM #define	STMF_SERVICE_TYPE 2
69*7836SJohn.Forte@Sun.COM 
70*7836SJohn.Forte@Sun.COM static int openStmf(int, int *fd);
71*7836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *);
72*7836SJohn.Forte@Sun.COM static int loadStore(int fd);
73*7836SJohn.Forte@Sun.COM static int initializeConfig();
74*7836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
75*7836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *);
76*7836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
77*7836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *);
78*7836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *);
79*7836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *);
80*7836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int);
81*7836SJohn.Forte@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int);
82*7836SJohn.Forte@Sun.COM 
83*7836SJohn.Forte@Sun.COM /*
84*7836SJohn.Forte@Sun.COM  * Open for stmf module
85*7836SJohn.Forte@Sun.COM  *
86*7836SJohn.Forte@Sun.COM  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
87*7836SJohn.Forte@Sun.COM  * fd - pointer to integer. On success, contains the stmf file descriptor
88*7836SJohn.Forte@Sun.COM  */
89*7836SJohn.Forte@Sun.COM static int
90*7836SJohn.Forte@Sun.COM openStmf(int flag, int *fd)
91*7836SJohn.Forte@Sun.COM {
92*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_ERROR;
93*7836SJohn.Forte@Sun.COM 
94*7836SJohn.Forte@Sun.COM 	if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
95*7836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_SUCCESS;
96*7836SJohn.Forte@Sun.COM 	} else {
97*7836SJohn.Forte@Sun.COM 		if (errno == EBUSY) {
98*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
99*7836SJohn.Forte@Sun.COM 		} else {
100*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
101*7836SJohn.Forte@Sun.COM 		}
102*7836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
103*7836SJohn.Forte@Sun.COM 		    STMF_PATH, errno);
104*7836SJohn.Forte@Sun.COM 	}
105*7836SJohn.Forte@Sun.COM 
106*7836SJohn.Forte@Sun.COM 	return (ret);
107*7836SJohn.Forte@Sun.COM }
108*7836SJohn.Forte@Sun.COM 
109*7836SJohn.Forte@Sun.COM /*
110*7836SJohn.Forte@Sun.COM  * initializeConfig
111*7836SJohn.Forte@Sun.COM  *
112*7836SJohn.Forte@Sun.COM  * This routine should be called before any ioctl requiring initialization
113*7836SJohn.Forte@Sun.COM  * which is basically everything except stmfGetState(), setStmfState() and
114*7836SJohn.Forte@Sun.COM  * stmfLoadConfig().
115*7836SJohn.Forte@Sun.COM  */
116*7836SJohn.Forte@Sun.COM static int
117*7836SJohn.Forte@Sun.COM initializeConfig()
118*7836SJohn.Forte@Sun.COM {
119*7836SJohn.Forte@Sun.COM 	int ret;
120*7836SJohn.Forte@Sun.COM 	stmfState state;
121*7836SJohn.Forte@Sun.COM 
122*7836SJohn.Forte@Sun.COM 
123*7836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
124*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
125*7836SJohn.Forte@Sun.COM 		return (ret);
126*7836SJohn.Forte@Sun.COM 	}
127*7836SJohn.Forte@Sun.COM 
128*7836SJohn.Forte@Sun.COM 	/* if we've already initialized or in the process, return success */
129*7836SJohn.Forte@Sun.COM 	if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
130*7836SJohn.Forte@Sun.COM 	    state.configState == STMF_CONFIG_STATE_INIT) {
131*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_SUCCESS);
132*7836SJohn.Forte@Sun.COM 	}
133*7836SJohn.Forte@Sun.COM 
134*7836SJohn.Forte@Sun.COM 	ret = stmfLoadConfig();
135*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
136*7836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
137*7836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfLoadConfig:error(%d)", ret);
138*7836SJohn.Forte@Sun.COM 		return (ret);
139*7836SJohn.Forte@Sun.COM 	}
140*7836SJohn.Forte@Sun.COM 
141*7836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
142*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
143*7836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG,
144*7836SJohn.Forte@Sun.COM 		    "initializeConfig:stmfGetState:error(%d)", ret);
145*7836SJohn.Forte@Sun.COM 		return (ret);
146*7836SJohn.Forte@Sun.COM 	}
147*7836SJohn.Forte@Sun.COM 
148*7836SJohn.Forte@Sun.COM 	if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
149*7836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
150*7836SJohn.Forte@Sun.COM 		    state.configState);
151*7836SJohn.Forte@Sun.COM 		ret = STMF_STATUS_ERROR;
152*7836SJohn.Forte@Sun.COM 	}
153*7836SJohn.Forte@Sun.COM 
154*7836SJohn.Forte@Sun.COM 	return (ret);
155*7836SJohn.Forte@Sun.COM }
156*7836SJohn.Forte@Sun.COM 
157*7836SJohn.Forte@Sun.COM 
158*7836SJohn.Forte@Sun.COM /*
159*7836SJohn.Forte@Sun.COM  * groupIoctl
160*7836SJohn.Forte@Sun.COM  *
161*7836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for create/delete on group
162*7836SJohn.Forte@Sun.COM  *
163*7836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group cmd
164*7836SJohn.Forte@Sun.COM  * groupName - groupName to create or delete
165*7836SJohn.Forte@Sun.COM  */
166*7836SJohn.Forte@Sun.COM static int
167*7836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName)
168*7836SJohn.Forte@Sun.COM {
169*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
170*7836SJohn.Forte@Sun.COM 	int ioctlRet;
171*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
172*7836SJohn.Forte@Sun.COM 	stmf_group_name_t iGroupName;
173*7836SJohn.Forte@Sun.COM 
174*7836SJohn.Forte@Sun.COM 	bzero(&iGroupName, sizeof (iGroupName));
175*7836SJohn.Forte@Sun.COM 
176*7836SJohn.Forte@Sun.COM 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
177*7836SJohn.Forte@Sun.COM 
178*7836SJohn.Forte@Sun.COM 	iGroupName.name_size = strlen((char *)groupName);
179*7836SJohn.Forte@Sun.COM 
180*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
181*7836SJohn.Forte@Sun.COM 	/*
182*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to create the host group
183*7836SJohn.Forte@Sun.COM 	 */
184*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
185*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
186*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
187*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
188*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
189*7836SJohn.Forte@Sun.COM 		switch (errno) {
190*7836SJohn.Forte@Sun.COM 			case EACCES:
191*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
192*7836SJohn.Forte@Sun.COM 				break;
193*7836SJohn.Forte@Sun.COM 			default:
194*7836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
195*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_EXISTS:
196*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_EXISTS:
197*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
198*7836SJohn.Forte@Sun.COM 						break;
199*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_IN_USE:
200*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_IN_USE:
201*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_GROUP_IN_USE;
202*7836SJohn.Forte@Sun.COM 						break;
203*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
204*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
205*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
206*7836SJohn.Forte@Sun.COM 						break;
207*7836SJohn.Forte@Sun.COM 					default:
208*7836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
209*7836SJohn.Forte@Sun.COM 						    "groupIoctl:error(%d)",
210*7836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
211*7836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
212*7836SJohn.Forte@Sun.COM 						break;
213*7836SJohn.Forte@Sun.COM 				}
214*7836SJohn.Forte@Sun.COM 				break;
215*7836SJohn.Forte@Sun.COM 		}
216*7836SJohn.Forte@Sun.COM 	}
217*7836SJohn.Forte@Sun.COM done:
218*7836SJohn.Forte@Sun.COM 	return (ret);
219*7836SJohn.Forte@Sun.COM }
220*7836SJohn.Forte@Sun.COM 
221*7836SJohn.Forte@Sun.COM /*
222*7836SJohn.Forte@Sun.COM  * groupIoctl
223*7836SJohn.Forte@Sun.COM  *
224*7836SJohn.Forte@Sun.COM  * Purpose: issue ioctl for add/remove member on group
225*7836SJohn.Forte@Sun.COM  *
226*7836SJohn.Forte@Sun.COM  * cmd - valid STMF ioctl group member cmd
227*7836SJohn.Forte@Sun.COM  * groupName - groupName to add to or remove from
228*7836SJohn.Forte@Sun.COM  * devid - group member to add or remove
229*7836SJohn.Forte@Sun.COM  */
230*7836SJohn.Forte@Sun.COM static int
231*7836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
232*7836SJohn.Forte@Sun.COM {
233*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
234*7836SJohn.Forte@Sun.COM 	int ioctlRet;
235*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
236*7836SJohn.Forte@Sun.COM 	stmf_group_op_data_t stmfGroupData;
237*7836SJohn.Forte@Sun.COM 
238*7836SJohn.Forte@Sun.COM 	bzero(&stmfGroupData, sizeof (stmfGroupData));
239*7836SJohn.Forte@Sun.COM 
240*7836SJohn.Forte@Sun.COM 	bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
241*7836SJohn.Forte@Sun.COM 
242*7836SJohn.Forte@Sun.COM 	stmfGroupData.group.name_size = strlen((char *)groupName);
243*7836SJohn.Forte@Sun.COM 	stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
244*7836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
245*7836SJohn.Forte@Sun.COM 	    devid->identLength);
246*7836SJohn.Forte@Sun.COM 
247*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
248*7836SJohn.Forte@Sun.COM 	/*
249*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
250*7836SJohn.Forte@Sun.COM 	 */
251*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
252*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
253*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
254*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
255*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
256*7836SJohn.Forte@Sun.COM 		switch (errno) {
257*7836SJohn.Forte@Sun.COM 			case EBUSY:
258*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
259*7836SJohn.Forte@Sun.COM 				break;
260*7836SJohn.Forte@Sun.COM 			case EACCES:
261*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
262*7836SJohn.Forte@Sun.COM 				break;
263*7836SJohn.Forte@Sun.COM 			default:
264*7836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
265*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_TG_ENTRY_EXISTS:
266*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_HG_ENTRY_EXISTS:
267*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_EXISTS;
268*7836SJohn.Forte@Sun.COM 						break;
269*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG_ENTRY:
270*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG_ENTRY:
271*7836SJohn.Forte@Sun.COM 						ret =
272*7836SJohn.Forte@Sun.COM 						    STMF_ERROR_MEMBER_NOT_FOUND;
273*7836SJohn.Forte@Sun.COM 						break;
274*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
275*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
276*7836SJohn.Forte@Sun.COM 						ret =
277*7836SJohn.Forte@Sun.COM 						    STMF_ERROR_GROUP_NOT_FOUND;
278*7836SJohn.Forte@Sun.COM 						break;
279*7836SJohn.Forte@Sun.COM 					default:
280*7836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
281*7836SJohn.Forte@Sun.COM 						    "groupMemberIoctl:error"
282*7836SJohn.Forte@Sun.COM 						    "(%d)",
283*7836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
284*7836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
285*7836SJohn.Forte@Sun.COM 						break;
286*7836SJohn.Forte@Sun.COM 				}
287*7836SJohn.Forte@Sun.COM 				break;
288*7836SJohn.Forte@Sun.COM 		}
289*7836SJohn.Forte@Sun.COM 	}
290*7836SJohn.Forte@Sun.COM done:
291*7836SJohn.Forte@Sun.COM 	return (ret);
292*7836SJohn.Forte@Sun.COM }
293*7836SJohn.Forte@Sun.COM 
294*7836SJohn.Forte@Sun.COM /*
295*7836SJohn.Forte@Sun.COM  * guidCompare
296*7836SJohn.Forte@Sun.COM  *
297*7836SJohn.Forte@Sun.COM  * qsort function
298*7836SJohn.Forte@Sun.COM  * sort on guid
299*7836SJohn.Forte@Sun.COM  */
300*7836SJohn.Forte@Sun.COM static int
301*7836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2)
302*7836SJohn.Forte@Sun.COM {
303*7836SJohn.Forte@Sun.COM 
304*7836SJohn.Forte@Sun.COM 	stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
305*7836SJohn.Forte@Sun.COM 	int i;
306*7836SJohn.Forte@Sun.COM 
307*7836SJohn.Forte@Sun.COM 	for (i = 0; i < sizeof (stmfGuid); i++) {
308*7836SJohn.Forte@Sun.COM 		if (g1->guid[i] > g2->guid[i])
309*7836SJohn.Forte@Sun.COM 			return (1);
310*7836SJohn.Forte@Sun.COM 		if (g1->guid[i] < g2->guid[i])
311*7836SJohn.Forte@Sun.COM 			return (-1);
312*7836SJohn.Forte@Sun.COM 	}
313*7836SJohn.Forte@Sun.COM 
314*7836SJohn.Forte@Sun.COM 	return (0);
315*7836SJohn.Forte@Sun.COM }
316*7836SJohn.Forte@Sun.COM 
317*7836SJohn.Forte@Sun.COM /*
318*7836SJohn.Forte@Sun.COM  * stmfAddToHostGroup
319*7836SJohn.Forte@Sun.COM  *
320*7836SJohn.Forte@Sun.COM  * Purpose: Adds an initiator to an existing host group
321*7836SJohn.Forte@Sun.COM  *
322*7836SJohn.Forte@Sun.COM  * hostGroupName - name of an existing host group
323*7836SJohn.Forte@Sun.COM  * hostName - name of initiator to add
324*7836SJohn.Forte@Sun.COM  */
325*7836SJohn.Forte@Sun.COM int
326*7836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
327*7836SJohn.Forte@Sun.COM {
328*7836SJohn.Forte@Sun.COM 	int ret;
329*7836SJohn.Forte@Sun.COM 	int fd;
330*7836SJohn.Forte@Sun.COM 
331*7836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
332*7836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
333*7836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
334*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
335*7836SJohn.Forte@Sun.COM 	}
336*7836SJohn.Forte@Sun.COM 
337*7836SJohn.Forte@Sun.COM 	/* call init */
338*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
339*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
340*7836SJohn.Forte@Sun.COM 		return (ret);
341*7836SJohn.Forte@Sun.COM 	}
342*7836SJohn.Forte@Sun.COM 
343*7836SJohn.Forte@Sun.COM 	/*
344*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
345*7836SJohn.Forte@Sun.COM 	 */
346*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
347*7836SJohn.Forte@Sun.COM 		return (ret);
348*7836SJohn.Forte@Sun.COM 
349*7836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
350*7836SJohn.Forte@Sun.COM 	    hostName)) != STMF_STATUS_SUCCESS) {
351*7836SJohn.Forte@Sun.COM 		goto done;
352*7836SJohn.Forte@Sun.COM 	}
353*7836SJohn.Forte@Sun.COM 
354*7836SJohn.Forte@Sun.COM 	ret = psAddHostGroupMember((char *)hostGroupName,
355*7836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
356*7836SJohn.Forte@Sun.COM 	switch (ret) {
357*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
358*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
359*7836SJohn.Forte@Sun.COM 			break;
360*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
361*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
362*7836SJohn.Forte@Sun.COM 			break;
363*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
364*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
365*7836SJohn.Forte@Sun.COM 			break;
366*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
367*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
368*7836SJohn.Forte@Sun.COM 			break;
369*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
370*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
371*7836SJohn.Forte@Sun.COM 			break;
372*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
373*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
374*7836SJohn.Forte@Sun.COM 			break;
375*7836SJohn.Forte@Sun.COM 		default:
376*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
377*7836SJohn.Forte@Sun.COM 			    "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
378*7836SJohn.Forte@Sun.COM 			    ret);
379*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
380*7836SJohn.Forte@Sun.COM 			break;
381*7836SJohn.Forte@Sun.COM 	}
382*7836SJohn.Forte@Sun.COM 
383*7836SJohn.Forte@Sun.COM done:
384*7836SJohn.Forte@Sun.COM 	(void) close(fd);
385*7836SJohn.Forte@Sun.COM 	return (ret);
386*7836SJohn.Forte@Sun.COM }
387*7836SJohn.Forte@Sun.COM 
388*7836SJohn.Forte@Sun.COM /*
389*7836SJohn.Forte@Sun.COM  * stmfAddToTargetGroup
390*7836SJohn.Forte@Sun.COM  *
391*7836SJohn.Forte@Sun.COM  * Purpose: Adds a local port to an existing target group
392*7836SJohn.Forte@Sun.COM  *
393*7836SJohn.Forte@Sun.COM  * targetGroupName - name of an existing target group
394*7836SJohn.Forte@Sun.COM  * targetName - name of target to add
395*7836SJohn.Forte@Sun.COM  */
396*7836SJohn.Forte@Sun.COM int
397*7836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
398*7836SJohn.Forte@Sun.COM {
399*7836SJohn.Forte@Sun.COM 	int ret;
400*7836SJohn.Forte@Sun.COM 	int fd;
401*7836SJohn.Forte@Sun.COM 	stmfState state;
402*7836SJohn.Forte@Sun.COM 
403*7836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
404*7836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
405*7836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
406*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
407*7836SJohn.Forte@Sun.COM 	}
408*7836SJohn.Forte@Sun.COM 
409*7836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
410*7836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
411*7836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
412*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
413*7836SJohn.Forte@Sun.COM 		}
414*7836SJohn.Forte@Sun.COM 	} else {
415*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
416*7836SJohn.Forte@Sun.COM 	}
417*7836SJohn.Forte@Sun.COM 
418*7836SJohn.Forte@Sun.COM 	/* call init */
419*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
420*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
421*7836SJohn.Forte@Sun.COM 		return (ret);
422*7836SJohn.Forte@Sun.COM 	}
423*7836SJohn.Forte@Sun.COM 
424*7836SJohn.Forte@Sun.COM 	/*
425*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
426*7836SJohn.Forte@Sun.COM 	 */
427*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
428*7836SJohn.Forte@Sun.COM 		return (ret);
429*7836SJohn.Forte@Sun.COM 
430*7836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
431*7836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
432*7836SJohn.Forte@Sun.COM 		goto done;
433*7836SJohn.Forte@Sun.COM 	}
434*7836SJohn.Forte@Sun.COM 
435*7836SJohn.Forte@Sun.COM 	ret = psAddTargetGroupMember((char *)targetGroupName,
436*7836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
437*7836SJohn.Forte@Sun.COM 	switch (ret) {
438*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
439*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
440*7836SJohn.Forte@Sun.COM 			break;
441*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
442*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
443*7836SJohn.Forte@Sun.COM 			break;
444*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
445*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
446*7836SJohn.Forte@Sun.COM 			break;
447*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
448*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
449*7836SJohn.Forte@Sun.COM 			break;
450*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
451*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
452*7836SJohn.Forte@Sun.COM 			break;
453*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
454*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
455*7836SJohn.Forte@Sun.COM 			break;
456*7836SJohn.Forte@Sun.COM 		default:
457*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
458*7836SJohn.Forte@Sun.COM 			    "stmfAddToTargetGroup:psAddTargetGroupMember:"
459*7836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
460*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
461*7836SJohn.Forte@Sun.COM 			break;
462*7836SJohn.Forte@Sun.COM 	}
463*7836SJohn.Forte@Sun.COM 
464*7836SJohn.Forte@Sun.COM done:
465*7836SJohn.Forte@Sun.COM 	(void) close(fd);
466*7836SJohn.Forte@Sun.COM 	return (ret);
467*7836SJohn.Forte@Sun.COM }
468*7836SJohn.Forte@Sun.COM 
469*7836SJohn.Forte@Sun.COM /*
470*7836SJohn.Forte@Sun.COM  * addViewEntryIoctl
471*7836SJohn.Forte@Sun.COM  *
472*7836SJohn.Forte@Sun.COM  * Purpose: Issues ioctl to add a view entry
473*7836SJohn.Forte@Sun.COM  *
474*7836SJohn.Forte@Sun.COM  * lu - Logical Unit identifier to which the view entry is added
475*7836SJohn.Forte@Sun.COM  * viewEntry - view entry to add
476*7836SJohn.Forte@Sun.COM  * init - When set to B_TRUE, we are in the init state, i.e. don't call open
477*7836SJohn.Forte@Sun.COM  */
478*7836SJohn.Forte@Sun.COM static int
479*7836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
480*7836SJohn.Forte@Sun.COM {
481*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
482*7836SJohn.Forte@Sun.COM 	int ioctlRet;
483*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
484*7836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
485*7836SJohn.Forte@Sun.COM 
486*7836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
487*7836SJohn.Forte@Sun.COM 	/*
488*7836SJohn.Forte@Sun.COM 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
489*7836SJohn.Forte@Sun.COM 	 * false on input
490*7836SJohn.Forte@Sun.COM 	 */
491*7836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
492*7836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
493*7836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
494*7836SJohn.Forte@Sun.COM 
495*7836SJohn.Forte@Sun.COM 	if (viewEntry->allHosts == B_FALSE) {
496*7836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
497*7836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
498*7836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_host_group.name_size =
499*7836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->hostGroup);
500*7836SJohn.Forte@Sun.COM 	}
501*7836SJohn.Forte@Sun.COM 	if (viewEntry->allTargets == B_FALSE) {
502*7836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup,
503*7836SJohn.Forte@Sun.COM 		    &ioctlViewEntry.ve_target_group.name,
504*7836SJohn.Forte@Sun.COM 		    sizeof (stmfGroupName));
505*7836SJohn.Forte@Sun.COM 		ioctlViewEntry.ve_target_group.name_size =
506*7836SJohn.Forte@Sun.COM 		    strlen((char *)viewEntry->targetGroup);
507*7836SJohn.Forte@Sun.COM 	}
508*7836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
509*7836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
510*7836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
511*7836SJohn.Forte@Sun.COM 	}
512*7836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
513*7836SJohn.Forte@Sun.COM 
514*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
515*7836SJohn.Forte@Sun.COM 	/*
516*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
517*7836SJohn.Forte@Sun.COM 	 */
518*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
519*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
520*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
521*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
522*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
523*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
524*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
525*7836SJohn.Forte@Sun.COM 		switch (errno) {
526*7836SJohn.Forte@Sun.COM 			case EBUSY:
527*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
528*7836SJohn.Forte@Sun.COM 				break;
529*7836SJohn.Forte@Sun.COM 			case EACCES:
530*7836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
531*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
532*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
533*7836SJohn.Forte@Sun.COM 						break;
534*7836SJohn.Forte@Sun.COM 					default:
535*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
536*7836SJohn.Forte@Sun.COM 						break;
537*7836SJohn.Forte@Sun.COM 				}
538*7836SJohn.Forte@Sun.COM 				break;
539*7836SJohn.Forte@Sun.COM 			default:
540*7836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
541*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_LU_NUMBER_IN_USE:
542*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_LUN_IN_USE;
543*7836SJohn.Forte@Sun.COM 						break;
544*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
545*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_VE_CONFLICT;
546*7836SJohn.Forte@Sun.COM 						break;
547*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
548*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
549*7836SJohn.Forte@Sun.COM 						break;
550*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_HG:
551*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_HG;
552*7836SJohn.Forte@Sun.COM 						break;
553*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_INVALID_TG:
554*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_INVALID_TG;
555*7836SJohn.Forte@Sun.COM 						break;
556*7836SJohn.Forte@Sun.COM 					default:
557*7836SJohn.Forte@Sun.COM 						syslog(LOG_DEBUG,
558*7836SJohn.Forte@Sun.COM 						    "addViewEntryIoctl"
559*7836SJohn.Forte@Sun.COM 						    ":error(%d)",
560*7836SJohn.Forte@Sun.COM 						    stmfIoctl.stmf_error);
561*7836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_ERROR;
562*7836SJohn.Forte@Sun.COM 						break;
563*7836SJohn.Forte@Sun.COM 				}
564*7836SJohn.Forte@Sun.COM 				break;
565*7836SJohn.Forte@Sun.COM 		}
566*7836SJohn.Forte@Sun.COM 		goto done;
567*7836SJohn.Forte@Sun.COM 	}
568*7836SJohn.Forte@Sun.COM 
569*7836SJohn.Forte@Sun.COM 	/* copy lu nbr back to caller's view entry on success */
570*7836SJohn.Forte@Sun.COM 	viewEntry->veIndex = ioctlViewEntry.ve_ndx;
571*7836SJohn.Forte@Sun.COM 	if (ioctlViewEntry.ve_lu_number_valid) {
572*7836SJohn.Forte@Sun.COM 		bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
573*7836SJohn.Forte@Sun.COM 		    sizeof (ioctlViewEntry.ve_lu_nbr));
574*7836SJohn.Forte@Sun.COM 	}
575*7836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
576*7836SJohn.Forte@Sun.COM 
577*7836SJohn.Forte@Sun.COM done:
578*7836SJohn.Forte@Sun.COM 	return (ret);
579*7836SJohn.Forte@Sun.COM }
580*7836SJohn.Forte@Sun.COM 
581*7836SJohn.Forte@Sun.COM /*
582*7836SJohn.Forte@Sun.COM  * stmfAddViewEntry
583*7836SJohn.Forte@Sun.COM  *
584*7836SJohn.Forte@Sun.COM  * Purpose: Adds a view entry to a logical unit
585*7836SJohn.Forte@Sun.COM  *
586*7836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to which the view entry is added
587*7836SJohn.Forte@Sun.COM  * viewEntry - view entry structure to add
588*7836SJohn.Forte@Sun.COM  */
589*7836SJohn.Forte@Sun.COM int
590*7836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
591*7836SJohn.Forte@Sun.COM {
592*7836SJohn.Forte@Sun.COM 	int ret;
593*7836SJohn.Forte@Sun.COM 	int fd;
594*7836SJohn.Forte@Sun.COM 	stmfViewEntry iViewEntry;
595*7836SJohn.Forte@Sun.COM 
596*7836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntry == NULL) {
597*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
598*7836SJohn.Forte@Sun.COM 	}
599*7836SJohn.Forte@Sun.COM 
600*7836SJohn.Forte@Sun.COM 	/* initialize and set internal view entry */
601*7836SJohn.Forte@Sun.COM 	bzero(&iViewEntry, sizeof (iViewEntry));
602*7836SJohn.Forte@Sun.COM 
603*7836SJohn.Forte@Sun.COM 	if (!viewEntry->allHosts) {
604*7836SJohn.Forte@Sun.COM 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
605*7836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.hostGroup));
606*7836SJohn.Forte@Sun.COM 	} else {
607*7836SJohn.Forte@Sun.COM 		iViewEntry.allHosts = B_TRUE;
608*7836SJohn.Forte@Sun.COM 	}
609*7836SJohn.Forte@Sun.COM 
610*7836SJohn.Forte@Sun.COM 	if (!viewEntry->allTargets) {
611*7836SJohn.Forte@Sun.COM 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
612*7836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.targetGroup));
613*7836SJohn.Forte@Sun.COM 	} else {
614*7836SJohn.Forte@Sun.COM 		iViewEntry.allTargets = B_TRUE;
615*7836SJohn.Forte@Sun.COM 	}
616*7836SJohn.Forte@Sun.COM 
617*7836SJohn.Forte@Sun.COM 	if (viewEntry->luNbrValid) {
618*7836SJohn.Forte@Sun.COM 		iViewEntry.luNbrValid = B_TRUE;
619*7836SJohn.Forte@Sun.COM 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
620*7836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
621*7836SJohn.Forte@Sun.COM 	}
622*7836SJohn.Forte@Sun.COM 
623*7836SJohn.Forte@Sun.COM 	/*
624*7836SJohn.Forte@Sun.COM 	 * set users return view entry index valid flag to false
625*7836SJohn.Forte@Sun.COM 	 * in case of failure
626*7836SJohn.Forte@Sun.COM 	 */
627*7836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_FALSE;
628*7836SJohn.Forte@Sun.COM 
629*7836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
630*7836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
631*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
632*7836SJohn.Forte@Sun.COM 	}
633*7836SJohn.Forte@Sun.COM 
634*7836SJohn.Forte@Sun.COM 	/* call init */
635*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
636*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
637*7836SJohn.Forte@Sun.COM 		return (ret);
638*7836SJohn.Forte@Sun.COM 	}
639*7836SJohn.Forte@Sun.COM 
640*7836SJohn.Forte@Sun.COM 	/*
641*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
642*7836SJohn.Forte@Sun.COM 	 */
643*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
644*7836SJohn.Forte@Sun.COM 		return (ret);
645*7836SJohn.Forte@Sun.COM 
646*7836SJohn.Forte@Sun.COM 	/*
647*7836SJohn.Forte@Sun.COM 	 * First add the view entry to the driver
648*7836SJohn.Forte@Sun.COM 	 */
649*7836SJohn.Forte@Sun.COM 	ret = addViewEntryIoctl(fd, lu, &iViewEntry);
650*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
651*7836SJohn.Forte@Sun.COM 		goto done;
652*7836SJohn.Forte@Sun.COM 	}
653*7836SJohn.Forte@Sun.COM 
654*7836SJohn.Forte@Sun.COM 	/*
655*7836SJohn.Forte@Sun.COM 	 * If the add to driver was successful, add it to the persistent
656*7836SJohn.Forte@Sun.COM 	 * store.
657*7836SJohn.Forte@Sun.COM 	 */
658*7836SJohn.Forte@Sun.COM 	ret = psAddViewEntry(lu, &iViewEntry);
659*7836SJohn.Forte@Sun.COM 	switch (ret) {
660*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
661*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
662*7836SJohn.Forte@Sun.COM 			break;
663*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
664*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
665*7836SJohn.Forte@Sun.COM 			break;
666*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
667*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
668*7836SJohn.Forte@Sun.COM 			break;
669*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
670*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
671*7836SJohn.Forte@Sun.COM 			break;
672*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
673*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
674*7836SJohn.Forte@Sun.COM 			break;
675*7836SJohn.Forte@Sun.COM 		default:
676*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
677*7836SJohn.Forte@Sun.COM 			    "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
678*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
679*7836SJohn.Forte@Sun.COM 			break;
680*7836SJohn.Forte@Sun.COM 	}
681*7836SJohn.Forte@Sun.COM 
682*7836SJohn.Forte@Sun.COM done:
683*7836SJohn.Forte@Sun.COM 	(void) close(fd);
684*7836SJohn.Forte@Sun.COM 
685*7836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
686*7836SJohn.Forte@Sun.COM 		/* set caller's view entry on success */
687*7836SJohn.Forte@Sun.COM 		viewEntry->veIndexValid = iViewEntry.veIndexValid;
688*7836SJohn.Forte@Sun.COM 		viewEntry->veIndex = iViewEntry.veIndex;
689*7836SJohn.Forte@Sun.COM 		viewEntry->luNbrValid = B_TRUE;
690*7836SJohn.Forte@Sun.COM 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
691*7836SJohn.Forte@Sun.COM 		    sizeof (iViewEntry.luNbr));
692*7836SJohn.Forte@Sun.COM 	}
693*7836SJohn.Forte@Sun.COM 	return (ret);
694*7836SJohn.Forte@Sun.COM }
695*7836SJohn.Forte@Sun.COM 
696*7836SJohn.Forte@Sun.COM /*
697*7836SJohn.Forte@Sun.COM  * stmfClearProviderData
698*7836SJohn.Forte@Sun.COM  *
699*7836SJohn.Forte@Sun.COM  * Purpose: delete all provider data for specified provider
700*7836SJohn.Forte@Sun.COM  *
701*7836SJohn.Forte@Sun.COM  * providerName - name of provider for which data should be deleted
702*7836SJohn.Forte@Sun.COM  */
703*7836SJohn.Forte@Sun.COM int
704*7836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType)
705*7836SJohn.Forte@Sun.COM {
706*7836SJohn.Forte@Sun.COM 	int ret;
707*7836SJohn.Forte@Sun.COM 	int fd;
708*7836SJohn.Forte@Sun.COM 	int ioctlRet;
709*7836SJohn.Forte@Sun.COM 	int savedErrno;
710*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
711*7836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t ppi;
712*7836SJohn.Forte@Sun.COM 
713*7836SJohn.Forte@Sun.COM 	/* call init */
714*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
715*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
716*7836SJohn.Forte@Sun.COM 		return (ret);
717*7836SJohn.Forte@Sun.COM 	}
718*7836SJohn.Forte@Sun.COM 
719*7836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
720*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
721*7836SJohn.Forte@Sun.COM 	}
722*7836SJohn.Forte@Sun.COM 
723*7836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
724*7836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
725*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
726*7836SJohn.Forte@Sun.COM 	}
727*7836SJohn.Forte@Sun.COM 
728*7836SJohn.Forte@Sun.COM 	/*
729*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
730*7836SJohn.Forte@Sun.COM 	 */
731*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
732*7836SJohn.Forte@Sun.COM 		return (ret);
733*7836SJohn.Forte@Sun.COM 
734*7836SJohn.Forte@Sun.COM 	bzero(&ppi, sizeof (ppi));
735*7836SJohn.Forte@Sun.COM 
736*7836SJohn.Forte@Sun.COM 	(void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
737*7836SJohn.Forte@Sun.COM 
738*7836SJohn.Forte@Sun.COM 	switch (providerType) {
739*7836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
740*7836SJohn.Forte@Sun.COM 			ppi.ppi_lu_provider = 1;
741*7836SJohn.Forte@Sun.COM 			break;
742*7836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
743*7836SJohn.Forte@Sun.COM 			ppi.ppi_port_provider = 1;
744*7836SJohn.Forte@Sun.COM 			break;
745*7836SJohn.Forte@Sun.COM 		default:
746*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_INVALID_ARG;
747*7836SJohn.Forte@Sun.COM 			goto done;
748*7836SJohn.Forte@Sun.COM 	}
749*7836SJohn.Forte@Sun.COM 
750*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
751*7836SJohn.Forte@Sun.COM 
752*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
753*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
754*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
755*7836SJohn.Forte@Sun.COM 
756*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
757*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
758*7836SJohn.Forte@Sun.COM 		savedErrno = errno;
759*7836SJohn.Forte@Sun.COM 		switch (savedErrno) {
760*7836SJohn.Forte@Sun.COM 			case EBUSY:
761*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
762*7836SJohn.Forte@Sun.COM 				break;
763*7836SJohn.Forte@Sun.COM 			case EACCES:
764*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
765*7836SJohn.Forte@Sun.COM 				break;
766*7836SJohn.Forte@Sun.COM 			default:
767*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
768*7836SJohn.Forte@Sun.COM 				    "stmfClearProviderData:ioctl error(%d)",
769*7836SJohn.Forte@Sun.COM 				    ioctlRet);
770*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
771*7836SJohn.Forte@Sun.COM 				break;
772*7836SJohn.Forte@Sun.COM 		}
773*7836SJohn.Forte@Sun.COM 		if (savedErrno != ENOENT) {
774*7836SJohn.Forte@Sun.COM 			goto done;
775*7836SJohn.Forte@Sun.COM 		}
776*7836SJohn.Forte@Sun.COM 	}
777*7836SJohn.Forte@Sun.COM 
778*7836SJohn.Forte@Sun.COM 	ret = psClearProviderData(providerName, providerType);
779*7836SJohn.Forte@Sun.COM 	switch (ret) {
780*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
781*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
782*7836SJohn.Forte@Sun.COM 			break;
783*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
784*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
785*7836SJohn.Forte@Sun.COM 			break;
786*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
787*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
788*7836SJohn.Forte@Sun.COM 			break;
789*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
790*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
791*7836SJohn.Forte@Sun.COM 			break;
792*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
793*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
794*7836SJohn.Forte@Sun.COM 			break;
795*7836SJohn.Forte@Sun.COM 		default:
796*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
797*7836SJohn.Forte@Sun.COM 			    "stmfClearProviderData:psClearProviderData"
798*7836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
799*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
800*7836SJohn.Forte@Sun.COM 			break;
801*7836SJohn.Forte@Sun.COM 	}
802*7836SJohn.Forte@Sun.COM 
803*7836SJohn.Forte@Sun.COM done:
804*7836SJohn.Forte@Sun.COM 	(void) close(fd);
805*7836SJohn.Forte@Sun.COM 	return (ret);
806*7836SJohn.Forte@Sun.COM }
807*7836SJohn.Forte@Sun.COM 
808*7836SJohn.Forte@Sun.COM /*
809*7836SJohn.Forte@Sun.COM  * stmfCreateHostGroup
810*7836SJohn.Forte@Sun.COM  *
811*7836SJohn.Forte@Sun.COM  * Purpose: Create a new initiator group
812*7836SJohn.Forte@Sun.COM  *
813*7836SJohn.Forte@Sun.COM  * hostGroupName - name of host group to create
814*7836SJohn.Forte@Sun.COM  */
815*7836SJohn.Forte@Sun.COM int
816*7836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName)
817*7836SJohn.Forte@Sun.COM {
818*7836SJohn.Forte@Sun.COM 	int ret;
819*7836SJohn.Forte@Sun.COM 	int fd;
820*7836SJohn.Forte@Sun.COM 
821*7836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
822*7836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
823*7836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
824*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
825*7836SJohn.Forte@Sun.COM 	}
826*7836SJohn.Forte@Sun.COM 
827*7836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
828*7836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
829*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
830*7836SJohn.Forte@Sun.COM 	}
831*7836SJohn.Forte@Sun.COM 
832*7836SJohn.Forte@Sun.COM 	/* call init */
833*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
834*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
835*7836SJohn.Forte@Sun.COM 		return (ret);
836*7836SJohn.Forte@Sun.COM 	}
837*7836SJohn.Forte@Sun.COM 
838*7836SJohn.Forte@Sun.COM 	/*
839*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
840*7836SJohn.Forte@Sun.COM 	 */
841*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
842*7836SJohn.Forte@Sun.COM 		return (ret);
843*7836SJohn.Forte@Sun.COM 
844*7836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
845*7836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
846*7836SJohn.Forte@Sun.COM 		goto done;
847*7836SJohn.Forte@Sun.COM 	}
848*7836SJohn.Forte@Sun.COM 
849*7836SJohn.Forte@Sun.COM 	ret = psCreateHostGroup((char *)hostGroupName);
850*7836SJohn.Forte@Sun.COM 	switch (ret) {
851*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
852*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
853*7836SJohn.Forte@Sun.COM 			break;
854*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
855*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
856*7836SJohn.Forte@Sun.COM 			break;
857*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
858*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
859*7836SJohn.Forte@Sun.COM 			break;
860*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
861*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
862*7836SJohn.Forte@Sun.COM 			break;
863*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
864*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
865*7836SJohn.Forte@Sun.COM 			break;
866*7836SJohn.Forte@Sun.COM 		default:
867*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
868*7836SJohn.Forte@Sun.COM 			    "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
869*7836SJohn.Forte@Sun.COM 			    ret);
870*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
871*7836SJohn.Forte@Sun.COM 			break;
872*7836SJohn.Forte@Sun.COM 	}
873*7836SJohn.Forte@Sun.COM 
874*7836SJohn.Forte@Sun.COM done:
875*7836SJohn.Forte@Sun.COM 	(void) close(fd);
876*7836SJohn.Forte@Sun.COM 	return (ret);
877*7836SJohn.Forte@Sun.COM }
878*7836SJohn.Forte@Sun.COM 
879*7836SJohn.Forte@Sun.COM /*
880*7836SJohn.Forte@Sun.COM  * stmfCreateTargetGroup
881*7836SJohn.Forte@Sun.COM  *
882*7836SJohn.Forte@Sun.COM  * Purpose: Create a local port group
883*7836SJohn.Forte@Sun.COM  *
884*7836SJohn.Forte@Sun.COM  * targetGroupName - name of local port group to create
885*7836SJohn.Forte@Sun.COM  */
886*7836SJohn.Forte@Sun.COM int
887*7836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName)
888*7836SJohn.Forte@Sun.COM {
889*7836SJohn.Forte@Sun.COM 	int ret;
890*7836SJohn.Forte@Sun.COM 	int fd;
891*7836SJohn.Forte@Sun.COM 
892*7836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
893*7836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
894*7836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName))) {
895*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
896*7836SJohn.Forte@Sun.COM 	}
897*7836SJohn.Forte@Sun.COM 
898*7836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
899*7836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
900*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
901*7836SJohn.Forte@Sun.COM 	}
902*7836SJohn.Forte@Sun.COM 
903*7836SJohn.Forte@Sun.COM 	/* call init */
904*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
905*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
906*7836SJohn.Forte@Sun.COM 		return (ret);
907*7836SJohn.Forte@Sun.COM 	}
908*7836SJohn.Forte@Sun.COM 
909*7836SJohn.Forte@Sun.COM 	/*
910*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
911*7836SJohn.Forte@Sun.COM 	 */
912*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
913*7836SJohn.Forte@Sun.COM 		return (ret);
914*7836SJohn.Forte@Sun.COM 
915*7836SJohn.Forte@Sun.COM 	/*
916*7836SJohn.Forte@Sun.COM 	 * Add the group to the driver
917*7836SJohn.Forte@Sun.COM 	 */
918*7836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
919*7836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
920*7836SJohn.Forte@Sun.COM 		goto done;
921*7836SJohn.Forte@Sun.COM 	}
922*7836SJohn.Forte@Sun.COM 
923*7836SJohn.Forte@Sun.COM 	/*
924*7836SJohn.Forte@Sun.COM 	 * If the add to the driver was successful, add it to the persistent
925*7836SJohn.Forte@Sun.COM 	 * store.
926*7836SJohn.Forte@Sun.COM 	 */
927*7836SJohn.Forte@Sun.COM 	ret = psCreateTargetGroup((char *)targetGroupName);
928*7836SJohn.Forte@Sun.COM 	switch (ret) {
929*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
930*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
931*7836SJohn.Forte@Sun.COM 			break;
932*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
933*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
934*7836SJohn.Forte@Sun.COM 			break;
935*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
936*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
937*7836SJohn.Forte@Sun.COM 			break;
938*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
939*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
940*7836SJohn.Forte@Sun.COM 			break;
941*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
942*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
943*7836SJohn.Forte@Sun.COM 			break;
944*7836SJohn.Forte@Sun.COM 		default:
945*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
946*7836SJohn.Forte@Sun.COM 			    "stmfCreateTargetGroup:psCreateTargetGroup"
947*7836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
948*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
949*7836SJohn.Forte@Sun.COM 			break;
950*7836SJohn.Forte@Sun.COM 	}
951*7836SJohn.Forte@Sun.COM 
952*7836SJohn.Forte@Sun.COM done:
953*7836SJohn.Forte@Sun.COM 	(void) close(fd);
954*7836SJohn.Forte@Sun.COM 	return (ret);
955*7836SJohn.Forte@Sun.COM }
956*7836SJohn.Forte@Sun.COM 
957*7836SJohn.Forte@Sun.COM /*
958*7836SJohn.Forte@Sun.COM  * stmfDeleteHostGroup
959*7836SJohn.Forte@Sun.COM  *
960*7836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
961*7836SJohn.Forte@Sun.COM  *
962*7836SJohn.Forte@Sun.COM  * hostGroupName - group to delete
963*7836SJohn.Forte@Sun.COM  */
964*7836SJohn.Forte@Sun.COM int
965*7836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName)
966*7836SJohn.Forte@Sun.COM {
967*7836SJohn.Forte@Sun.COM 	int ret;
968*7836SJohn.Forte@Sun.COM 	int fd;
969*7836SJohn.Forte@Sun.COM 
970*7836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL) {
971*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
972*7836SJohn.Forte@Sun.COM 	}
973*7836SJohn.Forte@Sun.COM 
974*7836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
975*7836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
976*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
977*7836SJohn.Forte@Sun.COM 	}
978*7836SJohn.Forte@Sun.COM 
979*7836SJohn.Forte@Sun.COM 	/* call init */
980*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
981*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
982*7836SJohn.Forte@Sun.COM 		return (ret);
983*7836SJohn.Forte@Sun.COM 	}
984*7836SJohn.Forte@Sun.COM 
985*7836SJohn.Forte@Sun.COM 	/*
986*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
987*7836SJohn.Forte@Sun.COM 	 */
988*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
989*7836SJohn.Forte@Sun.COM 		return (ret);
990*7836SJohn.Forte@Sun.COM 
991*7836SJohn.Forte@Sun.COM 	/*
992*7836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
993*7836SJohn.Forte@Sun.COM 	 */
994*7836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
995*7836SJohn.Forte@Sun.COM 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
996*7836SJohn.Forte@Sun.COM 		goto done;
997*7836SJohn.Forte@Sun.COM 	}
998*7836SJohn.Forte@Sun.COM 
999*7836SJohn.Forte@Sun.COM 	/*
1000*7836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
1001*7836SJohn.Forte@Sun.COM 	 * persistent store.
1002*7836SJohn.Forte@Sun.COM 	 */
1003*7836SJohn.Forte@Sun.COM 	ret = psDeleteHostGroup((char *)hostGroupName);
1004*7836SJohn.Forte@Sun.COM 	switch (ret) {
1005*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1006*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1007*7836SJohn.Forte@Sun.COM 			break;
1008*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1009*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1010*7836SJohn.Forte@Sun.COM 			break;
1011*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1012*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1013*7836SJohn.Forte@Sun.COM 			break;
1014*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1015*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1016*7836SJohn.Forte@Sun.COM 			break;
1017*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1018*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1019*7836SJohn.Forte@Sun.COM 			break;
1020*7836SJohn.Forte@Sun.COM 		default:
1021*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1022*7836SJohn.Forte@Sun.COM 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
1023*7836SJohn.Forte@Sun.COM 			    ret);
1024*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1025*7836SJohn.Forte@Sun.COM 			break;
1026*7836SJohn.Forte@Sun.COM 	}
1027*7836SJohn.Forte@Sun.COM 
1028*7836SJohn.Forte@Sun.COM done:
1029*7836SJohn.Forte@Sun.COM 	(void) close(fd);
1030*7836SJohn.Forte@Sun.COM 	return (ret);
1031*7836SJohn.Forte@Sun.COM }
1032*7836SJohn.Forte@Sun.COM 
1033*7836SJohn.Forte@Sun.COM /*
1034*7836SJohn.Forte@Sun.COM  * stmfDeleteTargetGroup
1035*7836SJohn.Forte@Sun.COM  *
1036*7836SJohn.Forte@Sun.COM  * Purpose: Delete an initiator or local port group
1037*7836SJohn.Forte@Sun.COM  *
1038*7836SJohn.Forte@Sun.COM  * targetGroupName - group to delete
1039*7836SJohn.Forte@Sun.COM  */
1040*7836SJohn.Forte@Sun.COM int
1041*7836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
1042*7836SJohn.Forte@Sun.COM {
1043*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
1044*7836SJohn.Forte@Sun.COM 	int fd;
1045*7836SJohn.Forte@Sun.COM 
1046*7836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL) {
1047*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1048*7836SJohn.Forte@Sun.COM 	}
1049*7836SJohn.Forte@Sun.COM 
1050*7836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
1051*7836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
1052*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
1053*7836SJohn.Forte@Sun.COM 	}
1054*7836SJohn.Forte@Sun.COM 
1055*7836SJohn.Forte@Sun.COM 	/* call init */
1056*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
1057*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1058*7836SJohn.Forte@Sun.COM 		return (ret);
1059*7836SJohn.Forte@Sun.COM 	}
1060*7836SJohn.Forte@Sun.COM 
1061*7836SJohn.Forte@Sun.COM 	/*
1062*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
1063*7836SJohn.Forte@Sun.COM 	 */
1064*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1065*7836SJohn.Forte@Sun.COM 		return (ret);
1066*7836SJohn.Forte@Sun.COM 
1067*7836SJohn.Forte@Sun.COM 	/*
1068*7836SJohn.Forte@Sun.COM 	 * Remove the group from the driver
1069*7836SJohn.Forte@Sun.COM 	 */
1070*7836SJohn.Forte@Sun.COM 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
1071*7836SJohn.Forte@Sun.COM 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
1072*7836SJohn.Forte@Sun.COM 		goto done;
1073*7836SJohn.Forte@Sun.COM 	}
1074*7836SJohn.Forte@Sun.COM 
1075*7836SJohn.Forte@Sun.COM 	/*
1076*7836SJohn.Forte@Sun.COM 	 * If the remove from the driver was successful, remove it from the
1077*7836SJohn.Forte@Sun.COM 	 * persistent store.
1078*7836SJohn.Forte@Sun.COM 	 */
1079*7836SJohn.Forte@Sun.COM 	ret = psDeleteTargetGroup((char *)targetGroupName);
1080*7836SJohn.Forte@Sun.COM 	switch (ret) {
1081*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1082*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1083*7836SJohn.Forte@Sun.COM 			break;
1084*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1085*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1086*7836SJohn.Forte@Sun.COM 			break;
1087*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1088*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1089*7836SJohn.Forte@Sun.COM 			break;
1090*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1091*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1092*7836SJohn.Forte@Sun.COM 			break;
1093*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1094*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1095*7836SJohn.Forte@Sun.COM 			break;
1096*7836SJohn.Forte@Sun.COM 		default:
1097*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1098*7836SJohn.Forte@Sun.COM 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
1099*7836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
1100*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1101*7836SJohn.Forte@Sun.COM 			break;
1102*7836SJohn.Forte@Sun.COM 	}
1103*7836SJohn.Forte@Sun.COM 
1104*7836SJohn.Forte@Sun.COM done:
1105*7836SJohn.Forte@Sun.COM 	(void) close(fd);
1106*7836SJohn.Forte@Sun.COM 	return (ret);
1107*7836SJohn.Forte@Sun.COM }
1108*7836SJohn.Forte@Sun.COM 
1109*7836SJohn.Forte@Sun.COM /*
1110*7836SJohn.Forte@Sun.COM  * stmfDevidFromIscsiName
1111*7836SJohn.Forte@Sun.COM  *
1112*7836SJohn.Forte@Sun.COM  * Purpose: convert an iSCSI name to an stmf devid
1113*7836SJohn.Forte@Sun.COM  *
1114*7836SJohn.Forte@Sun.COM  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
1115*7836SJohn.Forte@Sun.COM  * devid - on success, contains the converted iscsi name
1116*7836SJohn.Forte@Sun.COM  */
1117*7836SJohn.Forte@Sun.COM int
1118*7836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
1119*7836SJohn.Forte@Sun.COM {
1120*7836SJohn.Forte@Sun.COM 	if (devid == NULL || iscsiName == NULL)
1121*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1122*7836SJohn.Forte@Sun.COM 
1123*7836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
1124*7836SJohn.Forte@Sun.COM 
1125*7836SJohn.Forte@Sun.COM 	/* Validate size of target */
1126*7836SJohn.Forte@Sun.COM 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
1127*7836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(EUI) ||
1128*7836SJohn.Forte@Sun.COM 	    devid->identLength < strlen(IQN)) {
1129*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1130*7836SJohn.Forte@Sun.COM 	}
1131*7836SJohn.Forte@Sun.COM 
1132*7836SJohn.Forte@Sun.COM 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
1133*7836SJohn.Forte@Sun.COM 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
1134*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1135*7836SJohn.Forte@Sun.COM 	}
1136*7836SJohn.Forte@Sun.COM 
1137*7836SJohn.Forte@Sun.COM 	/* copy UTF-8 bytes to ident */
1138*7836SJohn.Forte@Sun.COM 	bcopy(iscsiName, devid->ident, devid->identLength);
1139*7836SJohn.Forte@Sun.COM 
1140*7836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
1141*7836SJohn.Forte@Sun.COM }
1142*7836SJohn.Forte@Sun.COM 
1143*7836SJohn.Forte@Sun.COM /*
1144*7836SJohn.Forte@Sun.COM  * stmfDevidFromWwn
1145*7836SJohn.Forte@Sun.COM  *
1146*7836SJohn.Forte@Sun.COM  * Purpose: convert a WWN to an stmf devid
1147*7836SJohn.Forte@Sun.COM  *
1148*7836SJohn.Forte@Sun.COM  * wwn - 8-byte wwn identifier
1149*7836SJohn.Forte@Sun.COM  * devid - on success, contains the converted wwn
1150*7836SJohn.Forte@Sun.COM  */
1151*7836SJohn.Forte@Sun.COM int
1152*7836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
1153*7836SJohn.Forte@Sun.COM {
1154*7836SJohn.Forte@Sun.COM 	if (wwn == NULL || devid == NULL)
1155*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1156*7836SJohn.Forte@Sun.COM 
1157*7836SJohn.Forte@Sun.COM 	bzero(devid, sizeof (stmfDevid));
1158*7836SJohn.Forte@Sun.COM 
1159*7836SJohn.Forte@Sun.COM 	/* Copy eui prefix */
1160*7836SJohn.Forte@Sun.COM 	(void) bcopy(WWN, devid->ident, strlen(WWN));
1161*7836SJohn.Forte@Sun.COM 
1162*7836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
1163*7836SJohn.Forte@Sun.COM 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
1164*7836SJohn.Forte@Sun.COM 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
1165*7836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
1166*7836SJohn.Forte@Sun.COM 
1167*7836SJohn.Forte@Sun.COM 	devid->identLength = strlen((char *)devid->ident);
1168*7836SJohn.Forte@Sun.COM 
1169*7836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
1170*7836SJohn.Forte@Sun.COM }
1171*7836SJohn.Forte@Sun.COM 
1172*7836SJohn.Forte@Sun.COM /*
1173*7836SJohn.Forte@Sun.COM  * stmfFreeMemory
1174*7836SJohn.Forte@Sun.COM  *
1175*7836SJohn.Forte@Sun.COM  * Purpose: Free memory allocated by this library
1176*7836SJohn.Forte@Sun.COM  *
1177*7836SJohn.Forte@Sun.COM  * memory - previously allocated pointer of memory managed by library
1178*7836SJohn.Forte@Sun.COM  */
1179*7836SJohn.Forte@Sun.COM void
1180*7836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory)
1181*7836SJohn.Forte@Sun.COM {
1182*7836SJohn.Forte@Sun.COM 	free(memory);
1183*7836SJohn.Forte@Sun.COM }
1184*7836SJohn.Forte@Sun.COM 
1185*7836SJohn.Forte@Sun.COM /*
1186*7836SJohn.Forte@Sun.COM  * stmfGetHostGroupList
1187*7836SJohn.Forte@Sun.COM  *
1188*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of initiator group oids
1189*7836SJohn.Forte@Sun.COM  *
1190*7836SJohn.Forte@Sun.COM  * hostGroupList - pointer to pointer to hostGroupList structure
1191*7836SJohn.Forte@Sun.COM  *                 on success, this contains the host group list.
1192*7836SJohn.Forte@Sun.COM  */
1193*7836SJohn.Forte@Sun.COM int
1194*7836SJohn.Forte@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList)
1195*7836SJohn.Forte@Sun.COM {
1196*7836SJohn.Forte@Sun.COM 	int ret;
1197*7836SJohn.Forte@Sun.COM 
1198*7836SJohn.Forte@Sun.COM 	if (hostGroupList == NULL) {
1199*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1200*7836SJohn.Forte@Sun.COM 	}
1201*7836SJohn.Forte@Sun.COM 
1202*7836SJohn.Forte@Sun.COM 	ret = psGetHostGroupList(hostGroupList);
1203*7836SJohn.Forte@Sun.COM 	switch (ret) {
1204*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1205*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1206*7836SJohn.Forte@Sun.COM 			break;
1207*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1208*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1209*7836SJohn.Forte@Sun.COM 			break;
1210*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1211*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1212*7836SJohn.Forte@Sun.COM 			break;
1213*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1214*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1215*7836SJohn.Forte@Sun.COM 			break;
1216*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1217*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1218*7836SJohn.Forte@Sun.COM 			break;
1219*7836SJohn.Forte@Sun.COM 		default:
1220*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1221*7836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
1222*7836SJohn.Forte@Sun.COM 			    ret);
1223*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1224*7836SJohn.Forte@Sun.COM 			break;
1225*7836SJohn.Forte@Sun.COM 	}
1226*7836SJohn.Forte@Sun.COM 
1227*7836SJohn.Forte@Sun.COM 	return (ret);
1228*7836SJohn.Forte@Sun.COM }
1229*7836SJohn.Forte@Sun.COM 
1230*7836SJohn.Forte@Sun.COM /*
1231*7836SJohn.Forte@Sun.COM  * stmfGetHostGroupMembers
1232*7836SJohn.Forte@Sun.COM  *
1233*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group properties for a host group
1234*7836SJohn.Forte@Sun.COM  *
1235*7836SJohn.Forte@Sun.COM  * groupName - name of group for which to retrieve host group members.
1236*7836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
1237*7836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
1238*7836SJohn.Forte@Sun.COM  */
1239*7836SJohn.Forte@Sun.COM int
1240*7836SJohn.Forte@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName,
1241*7836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
1242*7836SJohn.Forte@Sun.COM {
1243*7836SJohn.Forte@Sun.COM 	int ret;
1244*7836SJohn.Forte@Sun.COM 
1245*7836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
1246*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1247*7836SJohn.Forte@Sun.COM 	}
1248*7836SJohn.Forte@Sun.COM 
1249*7836SJohn.Forte@Sun.COM 	ret = psGetHostGroupMemberList((char *)groupName, groupProp);
1250*7836SJohn.Forte@Sun.COM 	switch (ret) {
1251*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1252*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1253*7836SJohn.Forte@Sun.COM 			break;
1254*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1255*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1256*7836SJohn.Forte@Sun.COM 			break;
1257*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1258*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1259*7836SJohn.Forte@Sun.COM 			break;
1260*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1261*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1262*7836SJohn.Forte@Sun.COM 			break;
1263*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1264*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1265*7836SJohn.Forte@Sun.COM 			break;
1266*7836SJohn.Forte@Sun.COM 		default:
1267*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1268*7836SJohn.Forte@Sun.COM 			    "stmfGetHostGroupMembers:psGetHostGroupMembers"
1269*7836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
1270*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1271*7836SJohn.Forte@Sun.COM 			break;
1272*7836SJohn.Forte@Sun.COM 	}
1273*7836SJohn.Forte@Sun.COM 
1274*7836SJohn.Forte@Sun.COM 	return (ret);
1275*7836SJohn.Forte@Sun.COM }
1276*7836SJohn.Forte@Sun.COM 
1277*7836SJohn.Forte@Sun.COM /*
1278*7836SJohn.Forte@Sun.COM  * stmfGetProviderData
1279*7836SJohn.Forte@Sun.COM  *
1280*7836SJohn.Forte@Sun.COM  * Purpose: Get provider data list
1281*7836SJohn.Forte@Sun.COM  *
1282*7836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
1283*7836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
1284*7836SJohn.Forte@Sun.COM  *       retrieved.
1285*7836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
1286*7836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
1287*7836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
1288*7836SJohn.Forte@Sun.COM  */
1289*7836SJohn.Forte@Sun.COM int
1290*7836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
1291*7836SJohn.Forte@Sun.COM {
1292*7836SJohn.Forte@Sun.COM 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
1293*7836SJohn.Forte@Sun.COM 	    NULL));
1294*7836SJohn.Forte@Sun.COM }
1295*7836SJohn.Forte@Sun.COM 
1296*7836SJohn.Forte@Sun.COM /*
1297*7836SJohn.Forte@Sun.COM  * stmfGetProviderDataProt
1298*7836SJohn.Forte@Sun.COM  *
1299*7836SJohn.Forte@Sun.COM  * Purpose: Get provider data list with token
1300*7836SJohn.Forte@Sun.COM  *
1301*7836SJohn.Forte@Sun.COM  * providerName - name of provider for which to retrieve the data
1302*7836SJohn.Forte@Sun.COM  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
1303*7836SJohn.Forte@Sun.COM  *       retrieved.
1304*7836SJohn.Forte@Sun.COM  * providerType - type of provider for which to retrieve data.
1305*7836SJohn.Forte@Sun.COM  *		    STMF_LU_PROVIDER_TYPE
1306*7836SJohn.Forte@Sun.COM  *		    STMF_PORT_PROVIDER_TYPE
1307*7836SJohn.Forte@Sun.COM  * setToken - Returns the stale data token
1308*7836SJohn.Forte@Sun.COM  */
1309*7836SJohn.Forte@Sun.COM int
1310*7836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
1311*7836SJohn.Forte@Sun.COM     uint64_t *setToken)
1312*7836SJohn.Forte@Sun.COM {
1313*7836SJohn.Forte@Sun.COM 	int ret;
1314*7836SJohn.Forte@Sun.COM 
1315*7836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
1316*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1317*7836SJohn.Forte@Sun.COM 	}
1318*7836SJohn.Forte@Sun.COM 
1319*7836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
1320*7836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
1321*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1322*7836SJohn.Forte@Sun.COM 	}
1323*7836SJohn.Forte@Sun.COM 
1324*7836SJohn.Forte@Sun.COM 	/* call init */
1325*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
1326*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1327*7836SJohn.Forte@Sun.COM 		return (ret);
1328*7836SJohn.Forte@Sun.COM 	}
1329*7836SJohn.Forte@Sun.COM 
1330*7836SJohn.Forte@Sun.COM 	ret = psGetProviderData(providerName, nvl, providerType, setToken);
1331*7836SJohn.Forte@Sun.COM 	switch (ret) {
1332*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1333*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1334*7836SJohn.Forte@Sun.COM 			break;
1335*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1336*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1337*7836SJohn.Forte@Sun.COM 			break;
1338*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1339*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1340*7836SJohn.Forte@Sun.COM 			break;
1341*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1342*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1343*7836SJohn.Forte@Sun.COM 			break;
1344*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1345*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1346*7836SJohn.Forte@Sun.COM 			break;
1347*7836SJohn.Forte@Sun.COM 		default:
1348*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1349*7836SJohn.Forte@Sun.COM 			    "stmfGetProviderData:psGetProviderData:error(%d)",
1350*7836SJohn.Forte@Sun.COM 			    ret);
1351*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1352*7836SJohn.Forte@Sun.COM 			break;
1353*7836SJohn.Forte@Sun.COM 	}
1354*7836SJohn.Forte@Sun.COM 
1355*7836SJohn.Forte@Sun.COM 	return (ret);
1356*7836SJohn.Forte@Sun.COM }
1357*7836SJohn.Forte@Sun.COM 
1358*7836SJohn.Forte@Sun.COM /*
1359*7836SJohn.Forte@Sun.COM  * stmfGetProviderDataList
1360*7836SJohn.Forte@Sun.COM  *
1361*7836SJohn.Forte@Sun.COM  * Purpose: Get the list of providers currently persisting data
1362*7836SJohn.Forte@Sun.COM  *
1363*7836SJohn.Forte@Sun.COM  * providerList - pointer to pointer to an stmfProviderList structure allocated
1364*7836SJohn.Forte@Sun.COM  *                by the caller. Will contain the list of providers on success.
1365*7836SJohn.Forte@Sun.COM  */
1366*7836SJohn.Forte@Sun.COM int
1367*7836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList)
1368*7836SJohn.Forte@Sun.COM {
1369*7836SJohn.Forte@Sun.COM 	int ret;
1370*7836SJohn.Forte@Sun.COM 
1371*7836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(providerList);
1372*7836SJohn.Forte@Sun.COM 	switch (ret) {
1373*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1374*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1375*7836SJohn.Forte@Sun.COM 			break;
1376*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1377*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1378*7836SJohn.Forte@Sun.COM 			break;
1379*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1380*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1381*7836SJohn.Forte@Sun.COM 			break;
1382*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1383*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1384*7836SJohn.Forte@Sun.COM 			break;
1385*7836SJohn.Forte@Sun.COM 		default:
1386*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1387*7836SJohn.Forte@Sun.COM 			    "stmfGetProviderDataList:psGetProviderDataList"
1388*7836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
1389*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1390*7836SJohn.Forte@Sun.COM 			break;
1391*7836SJohn.Forte@Sun.COM 	}
1392*7836SJohn.Forte@Sun.COM 
1393*7836SJohn.Forte@Sun.COM 	return (ret);
1394*7836SJohn.Forte@Sun.COM }
1395*7836SJohn.Forte@Sun.COM 
1396*7836SJohn.Forte@Sun.COM 
1397*7836SJohn.Forte@Sun.COM /*
1398*7836SJohn.Forte@Sun.COM  * stmfGetSessionList
1399*7836SJohn.Forte@Sun.COM  *
1400*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the session list for a target (devid)
1401*7836SJohn.Forte@Sun.COM  *
1402*7836SJohn.Forte@Sun.COM  * devid - devid of target for which to retrieve session information.
1403*7836SJohn.Forte@Sun.COM  * sessionList - pointer to pointer to stmfSessionList structure
1404*7836SJohn.Forte@Sun.COM  *             on success, this contains the list of initiator sessions.
1405*7836SJohn.Forte@Sun.COM  */
1406*7836SJohn.Forte@Sun.COM int
1407*7836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
1408*7836SJohn.Forte@Sun.COM {
1409*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
1410*7836SJohn.Forte@Sun.COM 	int fd;
1411*7836SJohn.Forte@Sun.COM 	int ioctlRet;
1412*7836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_SESSION_LIST;
1413*7836SJohn.Forte@Sun.COM 	int i;
1414*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
1415*7836SJohn.Forte@Sun.COM 	slist_scsi_session_t *fSessionList;
1416*7836SJohn.Forte@Sun.COM 	uint8_t ident[260];
1417*7836SJohn.Forte@Sun.COM 	uint32_t fSessionListSize;
1418*7836SJohn.Forte@Sun.COM 
1419*7836SJohn.Forte@Sun.COM 	if (sessionList == NULL || devid == NULL) {
1420*7836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
1421*7836SJohn.Forte@Sun.COM 	}
1422*7836SJohn.Forte@Sun.COM 
1423*7836SJohn.Forte@Sun.COM 	/* call init */
1424*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
1425*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1426*7836SJohn.Forte@Sun.COM 		return (ret);
1427*7836SJohn.Forte@Sun.COM 	}
1428*7836SJohn.Forte@Sun.COM 
1429*7836SJohn.Forte@Sun.COM 	/*
1430*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
1431*7836SJohn.Forte@Sun.COM 	 */
1432*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1433*7836SJohn.Forte@Sun.COM 		return (ret);
1434*7836SJohn.Forte@Sun.COM 
1435*7836SJohn.Forte@Sun.COM 	/*
1436*7836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
1437*7836SJohn.Forte@Sun.COM 	 */
1438*7836SJohn.Forte@Sun.COM 	fSessionListSize = MAX_SESSION;
1439*7836SJohn.Forte@Sun.COM 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
1440*7836SJohn.Forte@Sun.COM 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
1441*7836SJohn.Forte@Sun.COM 	if (fSessionList == NULL) {
1442*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
1443*7836SJohn.Forte@Sun.COM 	}
1444*7836SJohn.Forte@Sun.COM 
1445*7836SJohn.Forte@Sun.COM 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
1446*7836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
1447*7836SJohn.Forte@Sun.COM 	    devid->identLength);
1448*7836SJohn.Forte@Sun.COM 
1449*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
1450*7836SJohn.Forte@Sun.COM 	/*
1451*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the session list
1452*7836SJohn.Forte@Sun.COM 	 */
1453*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
1454*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
1455*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
1456*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fSessionListSize;
1457*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
1458*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
1459*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
1460*7836SJohn.Forte@Sun.COM 		switch (errno) {
1461*7836SJohn.Forte@Sun.COM 			case EBUSY:
1462*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
1463*7836SJohn.Forte@Sun.COM 				break;
1464*7836SJohn.Forte@Sun.COM 			case EACCES:
1465*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
1466*7836SJohn.Forte@Sun.COM 				break;
1467*7836SJohn.Forte@Sun.COM 			default:
1468*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
1469*7836SJohn.Forte@Sun.COM 				    "stmfGetSessionList:ioctl errno(%d)",
1470*7836SJohn.Forte@Sun.COM 				    errno);
1471*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
1472*7836SJohn.Forte@Sun.COM 				break;
1473*7836SJohn.Forte@Sun.COM 		}
1474*7836SJohn.Forte@Sun.COM 		goto done;
1475*7836SJohn.Forte@Sun.COM 	}
1476*7836SJohn.Forte@Sun.COM 	/*
1477*7836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
1478*7836SJohn.Forte@Sun.COM 	 */
1479*7836SJohn.Forte@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > MAX_SESSION) {
1480*7836SJohn.Forte@Sun.COM 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
1481*7836SJohn.Forte@Sun.COM 		    sizeof (slist_scsi_session_t);
1482*7836SJohn.Forte@Sun.COM 		fSessionList = realloc(fSessionList, fSessionListSize);
1483*7836SJohn.Forte@Sun.COM 		if (fSessionList == NULL) {
1484*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOMEM);
1485*7836SJohn.Forte@Sun.COM 		}
1486*7836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fSessionListSize;
1487*7836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
1488*7836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
1489*7836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
1490*7836SJohn.Forte@Sun.COM 			switch (errno) {
1491*7836SJohn.Forte@Sun.COM 				case EBUSY:
1492*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
1493*7836SJohn.Forte@Sun.COM 					break;
1494*7836SJohn.Forte@Sun.COM 				case EACCES:
1495*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
1496*7836SJohn.Forte@Sun.COM 					break;
1497*7836SJohn.Forte@Sun.COM 				default:
1498*7836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
1499*7836SJohn.Forte@Sun.COM 					    "stmfGetSessionList:ioctl "
1500*7836SJohn.Forte@Sun.COM 					    "errno(%d)", errno);
1501*7836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
1502*7836SJohn.Forte@Sun.COM 					break;
1503*7836SJohn.Forte@Sun.COM 			}
1504*7836SJohn.Forte@Sun.COM 			goto done;
1505*7836SJohn.Forte@Sun.COM 		}
1506*7836SJohn.Forte@Sun.COM 	}
1507*7836SJohn.Forte@Sun.COM 
1508*7836SJohn.Forte@Sun.COM 	/*
1509*7836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
1510*7836SJohn.Forte@Sun.COM 	 */
1511*7836SJohn.Forte@Sun.COM 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
1512*7836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
1513*7836SJohn.Forte@Sun.COM 	if (*sessionList == NULL) {
1514*7836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
1515*7836SJohn.Forte@Sun.COM 		free(sessionList);
1516*7836SJohn.Forte@Sun.COM 		goto done;
1517*7836SJohn.Forte@Sun.COM 	}
1518*7836SJohn.Forte@Sun.COM 
1519*7836SJohn.Forte@Sun.COM 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
1520*7836SJohn.Forte@Sun.COM 
1521*7836SJohn.Forte@Sun.COM 	/*
1522*7836SJohn.Forte@Sun.COM 	 * copy session info to caller's buffer
1523*7836SJohn.Forte@Sun.COM 	 */
1524*7836SJohn.Forte@Sun.COM 	for (i = 0; i < (*sessionList)->cnt; i++) {
1525*7836SJohn.Forte@Sun.COM 		(*sessionList)->session[i].initiator.identLength =
1526*7836SJohn.Forte@Sun.COM 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
1527*7836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
1528*7836SJohn.Forte@Sun.COM 		    (*sessionList)->session[i].initiator.ident,
1529*7836SJohn.Forte@Sun.COM 		    STMF_IDENT_LENGTH);
1530*7836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList->alias),
1531*7836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].alias),
1532*7836SJohn.Forte@Sun.COM 		    sizeof ((*sessionList)->session[i].alias));
1533*7836SJohn.Forte@Sun.COM 		bcopy(&(fSessionList++->creation_time),
1534*7836SJohn.Forte@Sun.COM 		    &((*sessionList)->session[i].creationTime),
1535*7836SJohn.Forte@Sun.COM 		    sizeof (time_t));
1536*7836SJohn.Forte@Sun.COM 	}
1537*7836SJohn.Forte@Sun.COM done:
1538*7836SJohn.Forte@Sun.COM 	(void) close(fd);
1539*7836SJohn.Forte@Sun.COM 	return (ret);
1540*7836SJohn.Forte@Sun.COM }
1541*7836SJohn.Forte@Sun.COM 
1542*7836SJohn.Forte@Sun.COM /*
1543*7836SJohn.Forte@Sun.COM  * stmfGetTargetGroupList
1544*7836SJohn.Forte@Sun.COM  *
1545*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target groups
1546*7836SJohn.Forte@Sun.COM  *
1547*7836SJohn.Forte@Sun.COM  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
1548*7836SJohn.Forte@Sun.COM  *		     success, it contains the list of target groups.
1549*7836SJohn.Forte@Sun.COM  */
1550*7836SJohn.Forte@Sun.COM int
1551*7836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList)
1552*7836SJohn.Forte@Sun.COM {
1553*7836SJohn.Forte@Sun.COM 	int ret;
1554*7836SJohn.Forte@Sun.COM 
1555*7836SJohn.Forte@Sun.COM 	if (targetGroupList == NULL) {
1556*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1557*7836SJohn.Forte@Sun.COM 	}
1558*7836SJohn.Forte@Sun.COM 
1559*7836SJohn.Forte@Sun.COM 	ret = psGetTargetGroupList(targetGroupList);
1560*7836SJohn.Forte@Sun.COM 	switch (ret) {
1561*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1562*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1563*7836SJohn.Forte@Sun.COM 			break;
1564*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1565*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1566*7836SJohn.Forte@Sun.COM 			break;
1567*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1568*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1569*7836SJohn.Forte@Sun.COM 			break;
1570*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1571*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1572*7836SJohn.Forte@Sun.COM 			break;
1573*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1574*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1575*7836SJohn.Forte@Sun.COM 			break;
1576*7836SJohn.Forte@Sun.COM 		default:
1577*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1578*7836SJohn.Forte@Sun.COM 			    "stmfGetTargetGroupList:psGetTargetGroupList:"
1579*7836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
1580*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1581*7836SJohn.Forte@Sun.COM 			break;
1582*7836SJohn.Forte@Sun.COM 	}
1583*7836SJohn.Forte@Sun.COM 
1584*7836SJohn.Forte@Sun.COM 	return (ret);
1585*7836SJohn.Forte@Sun.COM }
1586*7836SJohn.Forte@Sun.COM 
1587*7836SJohn.Forte@Sun.COM /*
1588*7836SJohn.Forte@Sun.COM  * stmfGetTargetGroupMembers
1589*7836SJohn.Forte@Sun.COM  *
1590*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the group members for a target group
1591*7836SJohn.Forte@Sun.COM  *
1592*7836SJohn.Forte@Sun.COM  * groupName - name of target group for which to retrieve members.
1593*7836SJohn.Forte@Sun.COM  * groupProp - pointer to pointer to stmfGroupProperties structure
1594*7836SJohn.Forte@Sun.COM  *             on success, this contains the list of group members.
1595*7836SJohn.Forte@Sun.COM  */
1596*7836SJohn.Forte@Sun.COM int
1597*7836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName,
1598*7836SJohn.Forte@Sun.COM     stmfGroupProperties **groupProp)
1599*7836SJohn.Forte@Sun.COM {
1600*7836SJohn.Forte@Sun.COM 	int ret;
1601*7836SJohn.Forte@Sun.COM 
1602*7836SJohn.Forte@Sun.COM 	if (groupName == NULL || groupProp == NULL) {
1603*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1604*7836SJohn.Forte@Sun.COM 	}
1605*7836SJohn.Forte@Sun.COM 
1606*7836SJohn.Forte@Sun.COM 	ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
1607*7836SJohn.Forte@Sun.COM 	switch (ret) {
1608*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1609*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1610*7836SJohn.Forte@Sun.COM 			break;
1611*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
1612*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
1613*7836SJohn.Forte@Sun.COM 			break;
1614*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1615*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1616*7836SJohn.Forte@Sun.COM 			break;
1617*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1618*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1619*7836SJohn.Forte@Sun.COM 			break;
1620*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1621*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1622*7836SJohn.Forte@Sun.COM 			break;
1623*7836SJohn.Forte@Sun.COM 		default:
1624*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1625*7836SJohn.Forte@Sun.COM 			    "stmfGetTargetGroupMembers:psGetTargetGroupMembers:"
1626*7836SJohn.Forte@Sun.COM 			    "error(%d)", ret);
1627*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1628*7836SJohn.Forte@Sun.COM 			break;
1629*7836SJohn.Forte@Sun.COM 	}
1630*7836SJohn.Forte@Sun.COM 
1631*7836SJohn.Forte@Sun.COM 	return (ret);
1632*7836SJohn.Forte@Sun.COM }
1633*7836SJohn.Forte@Sun.COM 
1634*7836SJohn.Forte@Sun.COM /*
1635*7836SJohn.Forte@Sun.COM  * stmfGetTargetList
1636*7836SJohn.Forte@Sun.COM  *
1637*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of target ports
1638*7836SJohn.Forte@Sun.COM  *
1639*7836SJohn.Forte@Sun.COM  * targetList - pointer to a pointer to an stmfDevidList structure.
1640*7836SJohn.Forte@Sun.COM  *		    On success, it contains the list of local ports (target).
1641*7836SJohn.Forte@Sun.COM  */
1642*7836SJohn.Forte@Sun.COM int
1643*7836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList)
1644*7836SJohn.Forte@Sun.COM {
1645*7836SJohn.Forte@Sun.COM 	int ret;
1646*7836SJohn.Forte@Sun.COM 	int fd;
1647*7836SJohn.Forte@Sun.COM 	int ioctlRet;
1648*7836SJohn.Forte@Sun.COM 	int i;
1649*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
1650*7836SJohn.Forte@Sun.COM 	/* framework target port list */
1651*7836SJohn.Forte@Sun.COM 	slist_target_port_t *fTargetList;
1652*7836SJohn.Forte@Sun.COM 	uint32_t fTargetListSize;
1653*7836SJohn.Forte@Sun.COM 
1654*7836SJohn.Forte@Sun.COM 	if (targetList == NULL) {
1655*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1656*7836SJohn.Forte@Sun.COM 	}
1657*7836SJohn.Forte@Sun.COM 
1658*7836SJohn.Forte@Sun.COM 	/* call init */
1659*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
1660*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1661*7836SJohn.Forte@Sun.COM 		return (ret);
1662*7836SJohn.Forte@Sun.COM 	}
1663*7836SJohn.Forte@Sun.COM 
1664*7836SJohn.Forte@Sun.COM 	/*
1665*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
1666*7836SJohn.Forte@Sun.COM 	 */
1667*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1668*7836SJohn.Forte@Sun.COM 		return (ret);
1669*7836SJohn.Forte@Sun.COM 
1670*7836SJohn.Forte@Sun.COM 	/*
1671*7836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
1672*7836SJohn.Forte@Sun.COM 	 */
1673*7836SJohn.Forte@Sun.COM 	fTargetListSize = MAX_TARGET_PORT * sizeof (slist_target_port_t);
1674*7836SJohn.Forte@Sun.COM 	fTargetList = (slist_target_port_t *)calloc(1, fTargetListSize);
1675*7836SJohn.Forte@Sun.COM 	if (fTargetList == NULL) {
1676*7836SJohn.Forte@Sun.COM 		goto done;
1677*7836SJohn.Forte@Sun.COM 	}
1678*7836SJohn.Forte@Sun.COM 
1679*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
1680*7836SJohn.Forte@Sun.COM 	/*
1681*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
1682*7836SJohn.Forte@Sun.COM 	 */
1683*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
1684*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fTargetListSize;
1685*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
1686*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
1687*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
1688*7836SJohn.Forte@Sun.COM 		switch (errno) {
1689*7836SJohn.Forte@Sun.COM 			case EBUSY:
1690*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
1691*7836SJohn.Forte@Sun.COM 				break;
1692*7836SJohn.Forte@Sun.COM 			case EACCES:
1693*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
1694*7836SJohn.Forte@Sun.COM 				break;
1695*7836SJohn.Forte@Sun.COM 			default:
1696*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
1697*7836SJohn.Forte@Sun.COM 				    "stmfGetTargetList:ioctl errno(%d)", errno);
1698*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
1699*7836SJohn.Forte@Sun.COM 				break;
1700*7836SJohn.Forte@Sun.COM 		}
1701*7836SJohn.Forte@Sun.COM 		goto done;
1702*7836SJohn.Forte@Sun.COM 	}
1703*7836SJohn.Forte@Sun.COM 	/*
1704*7836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
1705*7836SJohn.Forte@Sun.COM 	 */
1706*7836SJohn.Forte@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > MAX_TARGET_PORT) {
1707*7836SJohn.Forte@Sun.COM 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
1708*7836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
1709*7836SJohn.Forte@Sun.COM 		fTargetList = realloc(fTargetList, fTargetListSize);
1710*7836SJohn.Forte@Sun.COM 		if (fTargetList == NULL) {
1711*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOMEM);
1712*7836SJohn.Forte@Sun.COM 		}
1713*7836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fTargetListSize;
1714*7836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
1715*7836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
1716*7836SJohn.Forte@Sun.COM 		    &stmfIoctl);
1717*7836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
1718*7836SJohn.Forte@Sun.COM 			switch (errno) {
1719*7836SJohn.Forte@Sun.COM 				case EBUSY:
1720*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
1721*7836SJohn.Forte@Sun.COM 					break;
1722*7836SJohn.Forte@Sun.COM 				case EACCES:
1723*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
1724*7836SJohn.Forte@Sun.COM 					break;
1725*7836SJohn.Forte@Sun.COM 				default:
1726*7836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
1727*7836SJohn.Forte@Sun.COM 					    "stmfGetTargetList:ioctl errno(%d)",
1728*7836SJohn.Forte@Sun.COM 					    errno);
1729*7836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
1730*7836SJohn.Forte@Sun.COM 					break;
1731*7836SJohn.Forte@Sun.COM 			}
1732*7836SJohn.Forte@Sun.COM 			goto done;
1733*7836SJohn.Forte@Sun.COM 		}
1734*7836SJohn.Forte@Sun.COM 	}
1735*7836SJohn.Forte@Sun.COM 
1736*7836SJohn.Forte@Sun.COM 	*targetList = (stmfDevidList *)calloc(1,
1737*7836SJohn.Forte@Sun.COM 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
1738*7836SJohn.Forte@Sun.COM 	    sizeof (stmfDevidList));
1739*7836SJohn.Forte@Sun.COM 
1740*7836SJohn.Forte@Sun.COM 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
1741*7836SJohn.Forte@Sun.COM 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
1742*7836SJohn.Forte@Sun.COM 		(*targetList)->devid[i].identLength =
1743*7836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE];
1744*7836SJohn.Forte@Sun.COM 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
1745*7836SJohn.Forte@Sun.COM 		    &(*targetList)->devid[i].ident,
1746*7836SJohn.Forte@Sun.COM 		    fTargetList->target[IDENT_LENGTH_BYTE]);
1747*7836SJohn.Forte@Sun.COM 	}
1748*7836SJohn.Forte@Sun.COM 
1749*7836SJohn.Forte@Sun.COM done:
1750*7836SJohn.Forte@Sun.COM 	(void) close(fd);
1751*7836SJohn.Forte@Sun.COM 	free(fTargetList);
1752*7836SJohn.Forte@Sun.COM 	return (ret);
1753*7836SJohn.Forte@Sun.COM }
1754*7836SJohn.Forte@Sun.COM 
1755*7836SJohn.Forte@Sun.COM /*
1756*7836SJohn.Forte@Sun.COM  * stmfGetTargetProperties
1757*7836SJohn.Forte@Sun.COM  *
1758*7836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
1759*7836SJohn.Forte@Sun.COM  *
1760*7836SJohn.Forte@Sun.COM  * devid - devid of the target for which to retrieve properties
1761*7836SJohn.Forte@Sun.COM  * targetProps - pointer to an stmfTargetProperties structure.
1762*7836SJohn.Forte@Sun.COM  *		On success, it contains the target properties for
1763*7836SJohn.Forte@Sun.COM  *		the specified devid.
1764*7836SJohn.Forte@Sun.COM  */
1765*7836SJohn.Forte@Sun.COM int
1766*7836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
1767*7836SJohn.Forte@Sun.COM {
1768*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
1769*7836SJohn.Forte@Sun.COM 	int fd;
1770*7836SJohn.Forte@Sun.COM 	int ioctlRet;
1771*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
1772*7836SJohn.Forte@Sun.COM 	sioc_target_port_props_t targetProperties;
1773*7836SJohn.Forte@Sun.COM 
1774*7836SJohn.Forte@Sun.COM 	if (devid == NULL || targetProps == NULL) {
1775*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1776*7836SJohn.Forte@Sun.COM 	}
1777*7836SJohn.Forte@Sun.COM 
1778*7836SJohn.Forte@Sun.COM 	/* call init */
1779*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
1780*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1781*7836SJohn.Forte@Sun.COM 		return (ret);
1782*7836SJohn.Forte@Sun.COM 	}
1783*7836SJohn.Forte@Sun.COM 
1784*7836SJohn.Forte@Sun.COM 	/*
1785*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
1786*7836SJohn.Forte@Sun.COM 	 */
1787*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1788*7836SJohn.Forte@Sun.COM 		return (ret);
1789*7836SJohn.Forte@Sun.COM 
1790*7836SJohn.Forte@Sun.COM 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
1791*7836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
1792*7836SJohn.Forte@Sun.COM 	    devid->identLength);
1793*7836SJohn.Forte@Sun.COM 
1794*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
1795*7836SJohn.Forte@Sun.COM 	/*
1796*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
1797*7836SJohn.Forte@Sun.COM 	 */
1798*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
1799*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
1800*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
1801*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
1802*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
1803*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
1804*7836SJohn.Forte@Sun.COM 	    &stmfIoctl);
1805*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
1806*7836SJohn.Forte@Sun.COM 		switch (errno) {
1807*7836SJohn.Forte@Sun.COM 			case EBUSY:
1808*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
1809*7836SJohn.Forte@Sun.COM 				break;
1810*7836SJohn.Forte@Sun.COM 			case EACCES:
1811*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
1812*7836SJohn.Forte@Sun.COM 				break;
1813*7836SJohn.Forte@Sun.COM 			case ENOENT:
1814*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
1815*7836SJohn.Forte@Sun.COM 				break;
1816*7836SJohn.Forte@Sun.COM 			default:
1817*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
1818*7836SJohn.Forte@Sun.COM 				    "stmfGetTargetProperties:ioctl errno(%d)",
1819*7836SJohn.Forte@Sun.COM 				    errno);
1820*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
1821*7836SJohn.Forte@Sun.COM 				break;
1822*7836SJohn.Forte@Sun.COM 		}
1823*7836SJohn.Forte@Sun.COM 		goto done;
1824*7836SJohn.Forte@Sun.COM 	}
1825*7836SJohn.Forte@Sun.COM 
1826*7836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
1827*7836SJohn.Forte@Sun.COM 	    sizeof (targetProperties.tgt_provider_name));
1828*7836SJohn.Forte@Sun.COM 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
1829*7836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINE;
1830*7836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
1831*7836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
1832*7836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
1833*7836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_ONLINING;
1834*7836SJohn.Forte@Sun.COM 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
1835*7836SJohn.Forte@Sun.COM 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
1836*7836SJohn.Forte@Sun.COM 	}
1837*7836SJohn.Forte@Sun.COM 	bcopy(targetProperties.tgt_alias, targetProps->alias,
1838*7836SJohn.Forte@Sun.COM 	    sizeof (targetProps->alias));
1839*7836SJohn.Forte@Sun.COM done:
1840*7836SJohn.Forte@Sun.COM 	(void) close(fd);
1841*7836SJohn.Forte@Sun.COM 	return (ret);
1842*7836SJohn.Forte@Sun.COM }
1843*7836SJohn.Forte@Sun.COM 
1844*7836SJohn.Forte@Sun.COM /*
1845*7836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitList
1846*7836SJohn.Forte@Sun.COM  *
1847*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves list of logical unit Object IDs
1848*7836SJohn.Forte@Sun.COM  *
1849*7836SJohn.Forte@Sun.COM  * luList - pointer to a pointer to a stmfGuidList structure. On success,
1850*7836SJohn.Forte@Sun.COM  *          it contains the list of logical unit guids.
1851*7836SJohn.Forte@Sun.COM  *
1852*7836SJohn.Forte@Sun.COM  */
1853*7836SJohn.Forte@Sun.COM int
1854*7836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList)
1855*7836SJohn.Forte@Sun.COM {
1856*7836SJohn.Forte@Sun.COM 	int ret;
1857*7836SJohn.Forte@Sun.COM 	int fd;
1858*7836SJohn.Forte@Sun.COM 	int ioctlRet;
1859*7836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_LU_LIST;
1860*7836SJohn.Forte@Sun.COM 	int i, k;
1861*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
1862*7836SJohn.Forte@Sun.COM 	/* framework lu list */
1863*7836SJohn.Forte@Sun.COM 	slist_lu_t *fLuList;
1864*7836SJohn.Forte@Sun.COM 	/* persistent store lu list */
1865*7836SJohn.Forte@Sun.COM 	stmfGuidList *sLuList = NULL;
1866*7836SJohn.Forte@Sun.COM 	int finalListSize = 0;
1867*7836SJohn.Forte@Sun.COM 	int newAllocSize;
1868*7836SJohn.Forte@Sun.COM 	uint32_t fLuListSize;
1869*7836SJohn.Forte@Sun.COM 	uint32_t endList;
1870*7836SJohn.Forte@Sun.COM 
1871*7836SJohn.Forte@Sun.COM 	if (luList == NULL) {
1872*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
1873*7836SJohn.Forte@Sun.COM 	}
1874*7836SJohn.Forte@Sun.COM 
1875*7836SJohn.Forte@Sun.COM 	/* call init */
1876*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
1877*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1878*7836SJohn.Forte@Sun.COM 		return (ret);
1879*7836SJohn.Forte@Sun.COM 	}
1880*7836SJohn.Forte@Sun.COM 
1881*7836SJohn.Forte@Sun.COM 	/*
1882*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
1883*7836SJohn.Forte@Sun.COM 	 */
1884*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1885*7836SJohn.Forte@Sun.COM 		return (ret);
1886*7836SJohn.Forte@Sun.COM 
1887*7836SJohn.Forte@Sun.COM 	/*
1888*7836SJohn.Forte@Sun.COM 	 * Allocate ioctl input buffer
1889*7836SJohn.Forte@Sun.COM 	 */
1890*7836SJohn.Forte@Sun.COM 	fLuListSize = MAX_LU;
1891*7836SJohn.Forte@Sun.COM 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
1892*7836SJohn.Forte@Sun.COM 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
1893*7836SJohn.Forte@Sun.COM 	if (fLuList == NULL) {
1894*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
1895*7836SJohn.Forte@Sun.COM 	}
1896*7836SJohn.Forte@Sun.COM 
1897*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
1898*7836SJohn.Forte@Sun.COM 	/*
1899*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the LU list
1900*7836SJohn.Forte@Sun.COM 	 */
1901*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
1902*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = fLuListSize;
1903*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
1904*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
1905*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
1906*7836SJohn.Forte@Sun.COM 		switch (errno) {
1907*7836SJohn.Forte@Sun.COM 			case EBUSY:
1908*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
1909*7836SJohn.Forte@Sun.COM 				break;
1910*7836SJohn.Forte@Sun.COM 			case EACCES:
1911*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
1912*7836SJohn.Forte@Sun.COM 				break;
1913*7836SJohn.Forte@Sun.COM 			default:
1914*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
1915*7836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
1916*7836SJohn.Forte@Sun.COM 				    errno);
1917*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
1918*7836SJohn.Forte@Sun.COM 				break;
1919*7836SJohn.Forte@Sun.COM 		}
1920*7836SJohn.Forte@Sun.COM 		goto done;
1921*7836SJohn.Forte@Sun.COM 	}
1922*7836SJohn.Forte@Sun.COM 	/*
1923*7836SJohn.Forte@Sun.COM 	 * Check whether input buffer was large enough
1924*7836SJohn.Forte@Sun.COM 	 */
1925*7836SJohn.Forte@Sun.COM 	if (stmfIoctl.stmf_obuf_max_nentries > MAX_LU) {
1926*7836SJohn.Forte@Sun.COM 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
1927*7836SJohn.Forte@Sun.COM 		    sizeof (slist_lu_t);
1928*7836SJohn.Forte@Sun.COM 		fLuList = realloc(fLuList, fLuListSize);
1929*7836SJohn.Forte@Sun.COM 		if (fLuList == NULL) {
1930*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_NOMEM);
1931*7836SJohn.Forte@Sun.COM 		}
1932*7836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf_size = fLuListSize;
1933*7836SJohn.Forte@Sun.COM 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
1934*7836SJohn.Forte@Sun.COM 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
1935*7836SJohn.Forte@Sun.COM 		if (ioctlRet != 0) {
1936*7836SJohn.Forte@Sun.COM 			switch (errno) {
1937*7836SJohn.Forte@Sun.COM 				case EBUSY:
1938*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_BUSY;
1939*7836SJohn.Forte@Sun.COM 					break;
1940*7836SJohn.Forte@Sun.COM 				case EACCES:
1941*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_PERM;
1942*7836SJohn.Forte@Sun.COM 					break;
1943*7836SJohn.Forte@Sun.COM 				default:
1944*7836SJohn.Forte@Sun.COM 					syslog(LOG_DEBUG,
1945*7836SJohn.Forte@Sun.COM 					    "stmfGetLogicalUnitList:"
1946*7836SJohn.Forte@Sun.COM 					    "ioctl errno(%d)", errno);
1947*7836SJohn.Forte@Sun.COM 					ret = STMF_STATUS_ERROR;
1948*7836SJohn.Forte@Sun.COM 					break;
1949*7836SJohn.Forte@Sun.COM 			}
1950*7836SJohn.Forte@Sun.COM 			goto done;
1951*7836SJohn.Forte@Sun.COM 		}
1952*7836SJohn.Forte@Sun.COM 	}
1953*7836SJohn.Forte@Sun.COM 
1954*7836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&sLuList);
1955*7836SJohn.Forte@Sun.COM 	switch (ret) {
1956*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
1957*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
1958*7836SJohn.Forte@Sun.COM 			break;
1959*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
1960*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
1961*7836SJohn.Forte@Sun.COM 			break;
1962*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1963*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
1964*7836SJohn.Forte@Sun.COM 			break;
1965*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
1966*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
1967*7836SJohn.Forte@Sun.COM 			break;
1968*7836SJohn.Forte@Sun.COM 		default:
1969*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
1970*7836SJohn.Forte@Sun.COM 			    "stmfGetLogicalUnitList:psGetLogicalUnitList"
1971*7836SJohn.Forte@Sun.COM 			    ":error(%d)", ret);
1972*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
1973*7836SJohn.Forte@Sun.COM 			break;
1974*7836SJohn.Forte@Sun.COM 	}
1975*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
1976*7836SJohn.Forte@Sun.COM 		goto done;
1977*7836SJohn.Forte@Sun.COM 	}
1978*7836SJohn.Forte@Sun.COM 
1979*7836SJohn.Forte@Sun.COM 	/*
1980*7836SJohn.Forte@Sun.COM 	 * 2 lists must be merged
1981*7836SJohn.Forte@Sun.COM 	 * reallocate the store list to add the list from the
1982*7836SJohn.Forte@Sun.COM 	 * framework
1983*7836SJohn.Forte@Sun.COM 	 */
1984*7836SJohn.Forte@Sun.COM 	newAllocSize = sLuList->cnt * sizeof (stmfGuid) + sizeof (stmfGuidList)
1985*7836SJohn.Forte@Sun.COM 	    + stmfIoctl.stmf_obuf_nentries * sizeof (stmfGuid);
1986*7836SJohn.Forte@Sun.COM 
1987*7836SJohn.Forte@Sun.COM 	sLuList = realloc(sLuList, newAllocSize);
1988*7836SJohn.Forte@Sun.COM 	if (sLuList == NULL) {
1989*7836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
1990*7836SJohn.Forte@Sun.COM 		goto done;
1991*7836SJohn.Forte@Sun.COM 	}
1992*7836SJohn.Forte@Sun.COM 
1993*7836SJohn.Forte@Sun.COM 	/*
1994*7836SJohn.Forte@Sun.COM 	 * add list from ioctl. Start from end of list retrieved from store.
1995*7836SJohn.Forte@Sun.COM 	 */
1996*7836SJohn.Forte@Sun.COM 	endList = sLuList->cnt + stmfIoctl.stmf_obuf_nentries;
1997*7836SJohn.Forte@Sun.COM 	for (k = 0, i = sLuList->cnt; i < endList; i++, k++) {
1998*7836SJohn.Forte@Sun.COM 		bcopy(&fLuList[k].lu_guid, sLuList->guid[i].guid,
1999*7836SJohn.Forte@Sun.COM 		    sizeof (stmfGuid));
2000*7836SJohn.Forte@Sun.COM 	}
2001*7836SJohn.Forte@Sun.COM 	sLuList->cnt = endList;
2002*7836SJohn.Forte@Sun.COM 
2003*7836SJohn.Forte@Sun.COM 	/*
2004*7836SJohn.Forte@Sun.COM 	 * sort the list for merging
2005*7836SJohn.Forte@Sun.COM 	 */
2006*7836SJohn.Forte@Sun.COM 	qsort((void *)&(sLuList->guid[0]), sLuList->cnt,
2007*7836SJohn.Forte@Sun.COM 	    sizeof (stmfGuid), guidCompare);
2008*7836SJohn.Forte@Sun.COM 
2009*7836SJohn.Forte@Sun.COM 	/*
2010*7836SJohn.Forte@Sun.COM 	 * get final list count
2011*7836SJohn.Forte@Sun.COM 	 */
2012*7836SJohn.Forte@Sun.COM 	for (i = 0; i < sLuList->cnt; i++) {
2013*7836SJohn.Forte@Sun.COM 		if ((i + 1) <= sLuList->cnt) {
2014*7836SJohn.Forte@Sun.COM 			if (bcmp(sLuList->guid[i].guid, sLuList->guid[i+1].guid,
2015*7836SJohn.Forte@Sun.COM 			    sizeof (stmfGuid)) == 0) {
2016*7836SJohn.Forte@Sun.COM 				continue;
2017*7836SJohn.Forte@Sun.COM 			}
2018*7836SJohn.Forte@Sun.COM 		}
2019*7836SJohn.Forte@Sun.COM 		finalListSize++;
2020*7836SJohn.Forte@Sun.COM 	}
2021*7836SJohn.Forte@Sun.COM 
2022*7836SJohn.Forte@Sun.COM 	/*
2023*7836SJohn.Forte@Sun.COM 	 * allocate caller's buffer with the final size
2024*7836SJohn.Forte@Sun.COM 	 */
2025*7836SJohn.Forte@Sun.COM 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
2026*7836SJohn.Forte@Sun.COM 	    finalListSize * sizeof (stmfGuid));
2027*7836SJohn.Forte@Sun.COM 	if (*luList == NULL) {
2028*7836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_NOMEM;
2029*7836SJohn.Forte@Sun.COM 		goto done;
2030*7836SJohn.Forte@Sun.COM 	}
2031*7836SJohn.Forte@Sun.COM 
2032*7836SJohn.Forte@Sun.COM 	/*
2033*7836SJohn.Forte@Sun.COM 	 * copy guids to caller's buffer
2034*7836SJohn.Forte@Sun.COM 	 */
2035*7836SJohn.Forte@Sun.COM 	for (k = 0, i = 0; i < sLuList->cnt; i++) {
2036*7836SJohn.Forte@Sun.COM 		if ((i + 1) <= sLuList->cnt) {
2037*7836SJohn.Forte@Sun.COM 			if (bcmp(sLuList->guid[i].guid, sLuList->guid[i+1].guid,
2038*7836SJohn.Forte@Sun.COM 			    sizeof (stmfGuid)) == 0) {
2039*7836SJohn.Forte@Sun.COM 				continue;
2040*7836SJohn.Forte@Sun.COM 			}
2041*7836SJohn.Forte@Sun.COM 		}
2042*7836SJohn.Forte@Sun.COM 		bcopy(&(sLuList->guid[i].guid), (*luList)->guid[k++].guid,
2043*7836SJohn.Forte@Sun.COM 		    sizeof (stmfGuid));
2044*7836SJohn.Forte@Sun.COM 	}
2045*7836SJohn.Forte@Sun.COM 
2046*7836SJohn.Forte@Sun.COM 	(*luList)->cnt = finalListSize;
2047*7836SJohn.Forte@Sun.COM 
2048*7836SJohn.Forte@Sun.COM done:
2049*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2050*7836SJohn.Forte@Sun.COM 	/*
2051*7836SJohn.Forte@Sun.COM 	 * free internal buffers
2052*7836SJohn.Forte@Sun.COM 	 */
2053*7836SJohn.Forte@Sun.COM 	free(fLuList);
2054*7836SJohn.Forte@Sun.COM 	free(sLuList);
2055*7836SJohn.Forte@Sun.COM 	return (ret);
2056*7836SJohn.Forte@Sun.COM }
2057*7836SJohn.Forte@Sun.COM 
2058*7836SJohn.Forte@Sun.COM /*
2059*7836SJohn.Forte@Sun.COM  * stmfGetLogicalUnitProperties
2060*7836SJohn.Forte@Sun.COM  *
2061*7836SJohn.Forte@Sun.COM  * Purpose:  Retrieves the properties for a logical unit
2062*7836SJohn.Forte@Sun.COM  *
2063*7836SJohn.Forte@Sun.COM  * lu - guid of the logical unit for which to retrieve properties
2064*7836SJohn.Forte@Sun.COM  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
2065*7836SJohn.Forte@Sun.COM  *               it contains the logical unit properties for the specified guid.
2066*7836SJohn.Forte@Sun.COM  */
2067*7836SJohn.Forte@Sun.COM int
2068*7836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
2069*7836SJohn.Forte@Sun.COM {
2070*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2071*7836SJohn.Forte@Sun.COM 	int stmfRet;
2072*7836SJohn.Forte@Sun.COM 	int fd;
2073*7836SJohn.Forte@Sun.COM 	int ioctlRet;
2074*7836SJohn.Forte@Sun.COM 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
2075*7836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
2076*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2077*7836SJohn.Forte@Sun.COM 	sioc_lu_props_t fLuProps;
2078*7836SJohn.Forte@Sun.COM 
2079*7836SJohn.Forte@Sun.COM 	if (luProps == NULL || luProps == NULL) {
2080*7836SJohn.Forte@Sun.COM 		ret = STMF_ERROR_INVALID_ARG;
2081*7836SJohn.Forte@Sun.COM 	}
2082*7836SJohn.Forte@Sun.COM 
2083*7836SJohn.Forte@Sun.COM 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
2084*7836SJohn.Forte@Sun.COM 
2085*7836SJohn.Forte@Sun.COM 	/* call init */
2086*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
2087*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2088*7836SJohn.Forte@Sun.COM 		return (ret);
2089*7836SJohn.Forte@Sun.COM 	}
2090*7836SJohn.Forte@Sun.COM 
2091*7836SJohn.Forte@Sun.COM 	/*
2092*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2093*7836SJohn.Forte@Sun.COM 	 */
2094*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
2095*7836SJohn.Forte@Sun.COM 		return (ret);
2096*7836SJohn.Forte@Sun.COM 
2097*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
2098*7836SJohn.Forte@Sun.COM 	/*
2099*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the host group
2100*7836SJohn.Forte@Sun.COM 	 */
2101*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
2102*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
2103*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
2104*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
2105*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
2106*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
2107*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
2108*7836SJohn.Forte@Sun.COM 		switch (errno) {
2109*7836SJohn.Forte@Sun.COM 			case EBUSY:
2110*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2111*7836SJohn.Forte@Sun.COM 				break;
2112*7836SJohn.Forte@Sun.COM 			case EACCES:
2113*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
2114*7836SJohn.Forte@Sun.COM 				break;
2115*7836SJohn.Forte@Sun.COM 			case ENOENT:
2116*7836SJohn.Forte@Sun.COM 				stmfRet = stmfGetViewEntryList(lu,
2117*7836SJohn.Forte@Sun.COM 				    &viewEntryList);
2118*7836SJohn.Forte@Sun.COM 				if (stmfRet == STMF_STATUS_SUCCESS) {
2119*7836SJohn.Forte@Sun.COM 					luProps->status =
2120*7836SJohn.Forte@Sun.COM 					    STMF_LOGICAL_UNIT_UNREGISTERED;
2121*7836SJohn.Forte@Sun.COM 					if (viewEntryList->cnt > 0) {
2122*7836SJohn.Forte@Sun.COM 						ret = STMF_STATUS_SUCCESS;
2123*7836SJohn.Forte@Sun.COM 					} else {
2124*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_NOT_FOUND;
2125*7836SJohn.Forte@Sun.COM 					}
2126*7836SJohn.Forte@Sun.COM 				} else {
2127*7836SJohn.Forte@Sun.COM 					ret = STMF_ERROR_NOT_FOUND;
2128*7836SJohn.Forte@Sun.COM 				}
2129*7836SJohn.Forte@Sun.COM 				stmfFreeMemory(viewEntryList);
2130*7836SJohn.Forte@Sun.COM 				break;
2131*7836SJohn.Forte@Sun.COM 			default:
2132*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
2133*7836SJohn.Forte@Sun.COM 				    "stmfGetLogicalUnit:ioctl errno(%d)",
2134*7836SJohn.Forte@Sun.COM 				    errno);
2135*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
2136*7836SJohn.Forte@Sun.COM 				break;
2137*7836SJohn.Forte@Sun.COM 		}
2138*7836SJohn.Forte@Sun.COM 		goto done;
2139*7836SJohn.Forte@Sun.COM 	}
2140*7836SJohn.Forte@Sun.COM 
2141*7836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
2142*7836SJohn.Forte@Sun.COM 	    sizeof (fLuProps.lu_provider_name));
2143*7836SJohn.Forte@Sun.COM 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
2144*7836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
2145*7836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
2146*7836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
2147*7836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
2148*7836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
2149*7836SJohn.Forte@Sun.COM 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
2150*7836SJohn.Forte@Sun.COM 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
2151*7836SJohn.Forte@Sun.COM 	}
2152*7836SJohn.Forte@Sun.COM 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
2153*7836SJohn.Forte@Sun.COM done:
2154*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2155*7836SJohn.Forte@Sun.COM 	return (ret);
2156*7836SJohn.Forte@Sun.COM }
2157*7836SJohn.Forte@Sun.COM 
2158*7836SJohn.Forte@Sun.COM /*
2159*7836SJohn.Forte@Sun.COM  * stmfGetState
2160*7836SJohn.Forte@Sun.COM  *
2161*7836SJohn.Forte@Sun.COM  * Purpose: retrieve the current state of the stmf module
2162*7836SJohn.Forte@Sun.COM  *
2163*7836SJohn.Forte@Sun.COM  * state - pointer to stmfState structure allocated by the caller
2164*7836SJohn.Forte@Sun.COM  *         On success, contains the state of stmf
2165*7836SJohn.Forte@Sun.COM  */
2166*7836SJohn.Forte@Sun.COM int
2167*7836SJohn.Forte@Sun.COM stmfGetState(stmfState *state)
2168*7836SJohn.Forte@Sun.COM {
2169*7836SJohn.Forte@Sun.COM 	int ret;
2170*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
2171*7836SJohn.Forte@Sun.COM 
2172*7836SJohn.Forte@Sun.COM 	if (state == NULL) {
2173*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2174*7836SJohn.Forte@Sun.COM 	}
2175*7836SJohn.Forte@Sun.COM 
2176*7836SJohn.Forte@Sun.COM 	ret = getStmfState(&iState);
2177*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2178*7836SJohn.Forte@Sun.COM 		return (ret);
2179*7836SJohn.Forte@Sun.COM 	}
2180*7836SJohn.Forte@Sun.COM 	switch (iState.state) {
2181*7836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINE:
2182*7836SJohn.Forte@Sun.COM 			state->operationalState =
2183*7836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINE;
2184*7836SJohn.Forte@Sun.COM 			break;
2185*7836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINE:
2186*7836SJohn.Forte@Sun.COM 			state->operationalState =
2187*7836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINE;
2188*7836SJohn.Forte@Sun.COM 			break;
2189*7836SJohn.Forte@Sun.COM 		case STMF_STATE_ONLINING:
2190*7836SJohn.Forte@Sun.COM 			state->operationalState =
2191*7836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_ONLINING;
2192*7836SJohn.Forte@Sun.COM 			break;
2193*7836SJohn.Forte@Sun.COM 		case STMF_STATE_OFFLINING:
2194*7836SJohn.Forte@Sun.COM 			state->operationalState =
2195*7836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_OFFLINING;
2196*7836SJohn.Forte@Sun.COM 			break;
2197*7836SJohn.Forte@Sun.COM 		default:
2198*7836SJohn.Forte@Sun.COM 			state->operationalState =
2199*7836SJohn.Forte@Sun.COM 			    STMF_SERVICE_STATE_UNKNOWN;
2200*7836SJohn.Forte@Sun.COM 			break;
2201*7836SJohn.Forte@Sun.COM 	}
2202*7836SJohn.Forte@Sun.COM 	switch (iState.config_state) {
2203*7836SJohn.Forte@Sun.COM 		case STMF_CONFIG_NONE:
2204*7836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_NONE;
2205*7836SJohn.Forte@Sun.COM 			break;
2206*7836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT:
2207*7836SJohn.Forte@Sun.COM 			state->configState = STMF_CONFIG_STATE_INIT;
2208*7836SJohn.Forte@Sun.COM 			break;
2209*7836SJohn.Forte@Sun.COM 		case STMF_CONFIG_INIT_DONE:
2210*7836SJohn.Forte@Sun.COM 			state->configState =
2211*7836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_INIT_DONE;
2212*7836SJohn.Forte@Sun.COM 			break;
2213*7836SJohn.Forte@Sun.COM 		default:
2214*7836SJohn.Forte@Sun.COM 			state->configState =
2215*7836SJohn.Forte@Sun.COM 			    STMF_CONFIG_STATE_UNKNOWN;
2216*7836SJohn.Forte@Sun.COM 			break;
2217*7836SJohn.Forte@Sun.COM 	}
2218*7836SJohn.Forte@Sun.COM 	return (STMF_STATUS_SUCCESS);
2219*7836SJohn.Forte@Sun.COM }
2220*7836SJohn.Forte@Sun.COM 
2221*7836SJohn.Forte@Sun.COM /*
2222*7836SJohn.Forte@Sun.COM  * stmfGetViewEntryList
2223*7836SJohn.Forte@Sun.COM  *
2224*7836SJohn.Forte@Sun.COM  * Purpose: Retrieves the list of view entries for the specified
2225*7836SJohn.Forte@Sun.COM  *          logical unit.
2226*7836SJohn.Forte@Sun.COM  *
2227*7836SJohn.Forte@Sun.COM  * lu - the guid of the logical unit for which to retrieve the view entry list
2228*7836SJohn.Forte@Sun.COM  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
2229*7836SJohn.Forte@Sun.COM  *                 success, contains the list of view entries.
2230*7836SJohn.Forte@Sun.COM  */
2231*7836SJohn.Forte@Sun.COM int
2232*7836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
2233*7836SJohn.Forte@Sun.COM {
2234*7836SJohn.Forte@Sun.COM 	int ret;
2235*7836SJohn.Forte@Sun.COM 
2236*7836SJohn.Forte@Sun.COM 	if (lu == NULL || viewEntryList == NULL) {
2237*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2238*7836SJohn.Forte@Sun.COM 	}
2239*7836SJohn.Forte@Sun.COM 
2240*7836SJohn.Forte@Sun.COM 	ret = psGetViewEntryList(lu, viewEntryList);
2241*7836SJohn.Forte@Sun.COM 	switch (ret) {
2242*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
2243*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
2244*7836SJohn.Forte@Sun.COM 			break;
2245*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
2246*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
2247*7836SJohn.Forte@Sun.COM 			break;
2248*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
2249*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
2250*7836SJohn.Forte@Sun.COM 			break;
2251*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2252*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2253*7836SJohn.Forte@Sun.COM 			break;
2254*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
2255*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2256*7836SJohn.Forte@Sun.COM 			break;
2257*7836SJohn.Forte@Sun.COM 		default:
2258*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
2259*7836SJohn.Forte@Sun.COM 			    "stmfGetViewEntryList:error(%d)", ret);
2260*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
2261*7836SJohn.Forte@Sun.COM 			break;
2262*7836SJohn.Forte@Sun.COM 	}
2263*7836SJohn.Forte@Sun.COM 
2264*7836SJohn.Forte@Sun.COM 	return (ret);
2265*7836SJohn.Forte@Sun.COM }
2266*7836SJohn.Forte@Sun.COM 
2267*7836SJohn.Forte@Sun.COM /*
2268*7836SJohn.Forte@Sun.COM  * loadHostGroups
2269*7836SJohn.Forte@Sun.COM  *
2270*7836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the host groups into stmf
2271*7836SJohn.Forte@Sun.COM  *
2272*7836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
2273*7836SJohn.Forte@Sun.COM  * groupList - populated host group list
2274*7836SJohn.Forte@Sun.COM  */
2275*7836SJohn.Forte@Sun.COM static int
2276*7836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList)
2277*7836SJohn.Forte@Sun.COM {
2278*7836SJohn.Forte@Sun.COM 	int i, j;
2279*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2280*7836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
2281*7836SJohn.Forte@Sun.COM 
2282*7836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
2283*7836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
2284*7836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
2285*7836SJohn.Forte@Sun.COM 			goto out;
2286*7836SJohn.Forte@Sun.COM 		}
2287*7836SJohn.Forte@Sun.COM 		ret = stmfGetHostGroupMembers(&(groupList->name[i]),
2288*7836SJohn.Forte@Sun.COM 		    &groupProps);
2289*7836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
2290*7836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
2291*7836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
2292*7836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
2293*7836SJohn.Forte@Sun.COM 				goto out;
2294*7836SJohn.Forte@Sun.COM 			}
2295*7836SJohn.Forte@Sun.COM 		}
2296*7836SJohn.Forte@Sun.COM 	}
2297*7836SJohn.Forte@Sun.COM 
2298*7836SJohn.Forte@Sun.COM 
2299*7836SJohn.Forte@Sun.COM out:
2300*7836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
2301*7836SJohn.Forte@Sun.COM 	return (ret);
2302*7836SJohn.Forte@Sun.COM }
2303*7836SJohn.Forte@Sun.COM 
2304*7836SJohn.Forte@Sun.COM /*
2305*7836SJohn.Forte@Sun.COM  * loadTargetGroups
2306*7836SJohn.Forte@Sun.COM  *
2307*7836SJohn.Forte@Sun.COM  * Purpose - issues the ioctl to load the target groups into stmf
2308*7836SJohn.Forte@Sun.COM  *
2309*7836SJohn.Forte@Sun.COM  * fd - file descriptor for the control node of stmf.
2310*7836SJohn.Forte@Sun.COM  * groupList - populated target group list.
2311*7836SJohn.Forte@Sun.COM  */
2312*7836SJohn.Forte@Sun.COM static int
2313*7836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList)
2314*7836SJohn.Forte@Sun.COM {
2315*7836SJohn.Forte@Sun.COM 	int i, j;
2316*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2317*7836SJohn.Forte@Sun.COM 	stmfGroupProperties *groupProps = NULL;
2318*7836SJohn.Forte@Sun.COM 
2319*7836SJohn.Forte@Sun.COM 	for (i = 0; i < groupList->cnt; i++) {
2320*7836SJohn.Forte@Sun.COM 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
2321*7836SJohn.Forte@Sun.COM 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
2322*7836SJohn.Forte@Sun.COM 			goto out;
2323*7836SJohn.Forte@Sun.COM 		}
2324*7836SJohn.Forte@Sun.COM 		ret = stmfGetTargetGroupMembers(&(groupList->name[i]),
2325*7836SJohn.Forte@Sun.COM 		    &groupProps);
2326*7836SJohn.Forte@Sun.COM 		for (j = 0; j < groupProps->cnt; j++) {
2327*7836SJohn.Forte@Sun.COM 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
2328*7836SJohn.Forte@Sun.COM 			    &(groupList->name[i]), &(groupProps->name[j])))
2329*7836SJohn.Forte@Sun.COM 			    != STMF_STATUS_SUCCESS) {
2330*7836SJohn.Forte@Sun.COM 				goto out;
2331*7836SJohn.Forte@Sun.COM 			}
2332*7836SJohn.Forte@Sun.COM 		}
2333*7836SJohn.Forte@Sun.COM 	}
2334*7836SJohn.Forte@Sun.COM 
2335*7836SJohn.Forte@Sun.COM 
2336*7836SJohn.Forte@Sun.COM out:
2337*7836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupProps);
2338*7836SJohn.Forte@Sun.COM 	return (ret);
2339*7836SJohn.Forte@Sun.COM }
2340*7836SJohn.Forte@Sun.COM 
2341*7836SJohn.Forte@Sun.COM 
2342*7836SJohn.Forte@Sun.COM /*
2343*7836SJohn.Forte@Sun.COM  * loadStore
2344*7836SJohn.Forte@Sun.COM  *
2345*7836SJohn.Forte@Sun.COM  * Purpose: Load the configuration data from the store
2346*7836SJohn.Forte@Sun.COM  *
2347*7836SJohn.Forte@Sun.COM  * First load the host groups and target groups, then the view entries
2348*7836SJohn.Forte@Sun.COM  * and finally the provider data
2349*7836SJohn.Forte@Sun.COM  *
2350*7836SJohn.Forte@Sun.COM  * fd - file descriptor of control node for stmf.
2351*7836SJohn.Forte@Sun.COM  */
2352*7836SJohn.Forte@Sun.COM static int
2353*7836SJohn.Forte@Sun.COM loadStore(int fd)
2354*7836SJohn.Forte@Sun.COM {
2355*7836SJohn.Forte@Sun.COM 	int ret;
2356*7836SJohn.Forte@Sun.COM 	int i, j;
2357*7836SJohn.Forte@Sun.COM 	stmfGroupList *groupList = NULL;
2358*7836SJohn.Forte@Sun.COM 	stmfGuidList *guidList = NULL;
2359*7836SJohn.Forte@Sun.COM 	stmfViewEntryList *viewEntryList = NULL;
2360*7836SJohn.Forte@Sun.COM 	stmfProviderList *providerList = NULL;
2361*7836SJohn.Forte@Sun.COM 	int providerType;
2362*7836SJohn.Forte@Sun.COM 	nvlist_t *nvl = NULL;
2363*7836SJohn.Forte@Sun.COM 
2364*7836SJohn.Forte@Sun.COM 
2365*7836SJohn.Forte@Sun.COM 
2366*7836SJohn.Forte@Sun.COM 	/* load host groups */
2367*7836SJohn.Forte@Sun.COM 	ret = stmfGetHostGroupList(&groupList);
2368*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2369*7836SJohn.Forte@Sun.COM 		return (ret);
2370*7836SJohn.Forte@Sun.COM 	}
2371*7836SJohn.Forte@Sun.COM 	ret = loadHostGroups(fd, groupList);
2372*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2373*7836SJohn.Forte@Sun.COM 		goto out;
2374*7836SJohn.Forte@Sun.COM 	}
2375*7836SJohn.Forte@Sun.COM 
2376*7836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
2377*7836SJohn.Forte@Sun.COM 	groupList = NULL;
2378*7836SJohn.Forte@Sun.COM 
2379*7836SJohn.Forte@Sun.COM 	/* load target groups */
2380*7836SJohn.Forte@Sun.COM 	ret = stmfGetTargetGroupList(&groupList);
2381*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2382*7836SJohn.Forte@Sun.COM 		goto out;
2383*7836SJohn.Forte@Sun.COM 	}
2384*7836SJohn.Forte@Sun.COM 	ret = loadTargetGroups(fd, groupList);
2385*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2386*7836SJohn.Forte@Sun.COM 		goto out;
2387*7836SJohn.Forte@Sun.COM 	}
2388*7836SJohn.Forte@Sun.COM 
2389*7836SJohn.Forte@Sun.COM 	stmfFreeMemory(groupList);
2390*7836SJohn.Forte@Sun.COM 	groupList = NULL;
2391*7836SJohn.Forte@Sun.COM 
2392*7836SJohn.Forte@Sun.COM 	/* Get the guid list */
2393*7836SJohn.Forte@Sun.COM 	ret = psGetLogicalUnitList(&guidList);
2394*7836SJohn.Forte@Sun.COM 	switch (ret) {
2395*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
2396*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
2397*7836SJohn.Forte@Sun.COM 			break;
2398*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
2399*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
2400*7836SJohn.Forte@Sun.COM 			break;
2401*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
2402*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
2403*7836SJohn.Forte@Sun.COM 			break;
2404*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2405*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2406*7836SJohn.Forte@Sun.COM 			break;
2407*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
2408*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2409*7836SJohn.Forte@Sun.COM 			break;
2410*7836SJohn.Forte@Sun.COM 		default:
2411*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
2412*7836SJohn.Forte@Sun.COM 			break;
2413*7836SJohn.Forte@Sun.COM 	}
2414*7836SJohn.Forte@Sun.COM 
2415*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2416*7836SJohn.Forte@Sun.COM 		goto out;
2417*7836SJohn.Forte@Sun.COM 	}
2418*7836SJohn.Forte@Sun.COM 
2419*7836SJohn.Forte@Sun.COM 	/*
2420*7836SJohn.Forte@Sun.COM 	 * We have the guid list, now get the corresponding
2421*7836SJohn.Forte@Sun.COM 	 * view entries for each guid
2422*7836SJohn.Forte@Sun.COM 	 */
2423*7836SJohn.Forte@Sun.COM 	for (i = 0; i < guidList->cnt; i++) {
2424*7836SJohn.Forte@Sun.COM 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
2425*7836SJohn.Forte@Sun.COM 		switch (ret) {
2426*7836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
2427*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
2428*7836SJohn.Forte@Sun.COM 				break;
2429*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
2430*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
2431*7836SJohn.Forte@Sun.COM 				break;
2432*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
2433*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2434*7836SJohn.Forte@Sun.COM 				break;
2435*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2436*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
2437*7836SJohn.Forte@Sun.COM 				break;
2438*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
2439*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
2440*7836SJohn.Forte@Sun.COM 				break;
2441*7836SJohn.Forte@Sun.COM 			default:
2442*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
2443*7836SJohn.Forte@Sun.COM 				break;
2444*7836SJohn.Forte@Sun.COM 		}
2445*7836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
2446*7836SJohn.Forte@Sun.COM 			goto out;
2447*7836SJohn.Forte@Sun.COM 		}
2448*7836SJohn.Forte@Sun.COM 		for (j = 0; j < viewEntryList->cnt; j++) {
2449*7836SJohn.Forte@Sun.COM 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
2450*7836SJohn.Forte@Sun.COM 			    &viewEntryList->ve[j]);
2451*7836SJohn.Forte@Sun.COM 			if (ret != STMF_STATUS_SUCCESS) {
2452*7836SJohn.Forte@Sun.COM 				goto out;
2453*7836SJohn.Forte@Sun.COM 			}
2454*7836SJohn.Forte@Sun.COM 		}
2455*7836SJohn.Forte@Sun.COM 	}
2456*7836SJohn.Forte@Sun.COM 
2457*7836SJohn.Forte@Sun.COM 	/* get the list of providers that have data */
2458*7836SJohn.Forte@Sun.COM 	ret = psGetProviderDataList(&providerList);
2459*7836SJohn.Forte@Sun.COM 	switch (ret) {
2460*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
2461*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
2462*7836SJohn.Forte@Sun.COM 			break;
2463*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
2464*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
2465*7836SJohn.Forte@Sun.COM 			break;
2466*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
2467*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
2468*7836SJohn.Forte@Sun.COM 			break;
2469*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2470*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2471*7836SJohn.Forte@Sun.COM 			break;
2472*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
2473*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2474*7836SJohn.Forte@Sun.COM 			break;
2475*7836SJohn.Forte@Sun.COM 		default:
2476*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
2477*7836SJohn.Forte@Sun.COM 			break;
2478*7836SJohn.Forte@Sun.COM 	}
2479*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2480*7836SJohn.Forte@Sun.COM 		goto out;
2481*7836SJohn.Forte@Sun.COM 	}
2482*7836SJohn.Forte@Sun.COM 
2483*7836SJohn.Forte@Sun.COM 	for (i = 0; i < providerList->cnt; i++) {
2484*7836SJohn.Forte@Sun.COM 		providerType = providerList->provider[i].providerType;
2485*7836SJohn.Forte@Sun.COM 		ret = psGetProviderData(providerList->provider[i].name,
2486*7836SJohn.Forte@Sun.COM 		    &nvl, providerType, NULL);
2487*7836SJohn.Forte@Sun.COM 		switch (ret) {
2488*7836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
2489*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
2490*7836SJohn.Forte@Sun.COM 				break;
2491*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
2492*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
2493*7836SJohn.Forte@Sun.COM 				break;
2494*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
2495*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2496*7836SJohn.Forte@Sun.COM 				break;
2497*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2498*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
2499*7836SJohn.Forte@Sun.COM 				break;
2500*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
2501*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
2502*7836SJohn.Forte@Sun.COM 				break;
2503*7836SJohn.Forte@Sun.COM 			default:
2504*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
2505*7836SJohn.Forte@Sun.COM 				break;
2506*7836SJohn.Forte@Sun.COM 		}
2507*7836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
2508*7836SJohn.Forte@Sun.COM 			goto out;
2509*7836SJohn.Forte@Sun.COM 		}
2510*7836SJohn.Forte@Sun.COM 
2511*7836SJohn.Forte@Sun.COM 		/* call setProviderData */
2512*7836SJohn.Forte@Sun.COM 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
2513*7836SJohn.Forte@Sun.COM 		    providerType);
2514*7836SJohn.Forte@Sun.COM 		switch (ret) {
2515*7836SJohn.Forte@Sun.COM 			case STMF_PS_SUCCESS:
2516*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_SUCCESS;
2517*7836SJohn.Forte@Sun.COM 				break;
2518*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_NOT_FOUND:
2519*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
2520*7836SJohn.Forte@Sun.COM 				break;
2521*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_BUSY:
2522*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2523*7836SJohn.Forte@Sun.COM 				break;
2524*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2525*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
2526*7836SJohn.Forte@Sun.COM 				break;
2527*7836SJohn.Forte@Sun.COM 			case STMF_PS_ERROR_VERSION_MISMATCH:
2528*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
2529*7836SJohn.Forte@Sun.COM 				break;
2530*7836SJohn.Forte@Sun.COM 			default:
2531*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
2532*7836SJohn.Forte@Sun.COM 				break;
2533*7836SJohn.Forte@Sun.COM 		}
2534*7836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS) {
2535*7836SJohn.Forte@Sun.COM 			goto out;
2536*7836SJohn.Forte@Sun.COM 		}
2537*7836SJohn.Forte@Sun.COM 
2538*7836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
2539*7836SJohn.Forte@Sun.COM 		nvl = NULL;
2540*7836SJohn.Forte@Sun.COM 	}
2541*7836SJohn.Forte@Sun.COM out:
2542*7836SJohn.Forte@Sun.COM 	if (groupList != NULL) {
2543*7836SJohn.Forte@Sun.COM 		free(groupList);
2544*7836SJohn.Forte@Sun.COM 	}
2545*7836SJohn.Forte@Sun.COM 	if (guidList != NULL) {
2546*7836SJohn.Forte@Sun.COM 		free(guidList);
2547*7836SJohn.Forte@Sun.COM 	}
2548*7836SJohn.Forte@Sun.COM 	if (viewEntryList != NULL) {
2549*7836SJohn.Forte@Sun.COM 		free(viewEntryList);
2550*7836SJohn.Forte@Sun.COM 	}
2551*7836SJohn.Forte@Sun.COM 	if (nvl != NULL) {
2552*7836SJohn.Forte@Sun.COM 		nvlist_free(nvl);
2553*7836SJohn.Forte@Sun.COM 	}
2554*7836SJohn.Forte@Sun.COM 	return (ret);
2555*7836SJohn.Forte@Sun.COM }
2556*7836SJohn.Forte@Sun.COM 
2557*7836SJohn.Forte@Sun.COM /*
2558*7836SJohn.Forte@Sun.COM  * stmfLoadConfig
2559*7836SJohn.Forte@Sun.COM  *
2560*7836SJohn.Forte@Sun.COM  * Purpose - load the configuration data from smf into stmf
2561*7836SJohn.Forte@Sun.COM  *
2562*7836SJohn.Forte@Sun.COM  */
2563*7836SJohn.Forte@Sun.COM int
2564*7836SJohn.Forte@Sun.COM stmfLoadConfig(void)
2565*7836SJohn.Forte@Sun.COM {
2566*7836SJohn.Forte@Sun.COM 	int ret;
2567*7836SJohn.Forte@Sun.COM 	int fd;
2568*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t stmfStateSet;
2569*7836SJohn.Forte@Sun.COM 	stmfState state;
2570*7836SJohn.Forte@Sun.COM 
2571*7836SJohn.Forte@Sun.COM 
2572*7836SJohn.Forte@Sun.COM 	/* Check to ensure service exists */
2573*7836SJohn.Forte@Sun.COM 	if (psCheckService() != STMF_STATUS_SUCCESS) {
2574*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_SERVICE_NOT_FOUND);
2575*7836SJohn.Forte@Sun.COM 	}
2576*7836SJohn.Forte@Sun.COM 
2577*7836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2578*7836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
2579*7836SJohn.Forte@Sun.COM 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
2580*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
2581*7836SJohn.Forte@Sun.COM 		}
2582*7836SJohn.Forte@Sun.COM 	} else {
2583*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
2584*7836SJohn.Forte@Sun.COM 	}
2585*7836SJohn.Forte@Sun.COM 
2586*7836SJohn.Forte@Sun.COM 
2587*7836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
2588*7836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT;
2589*7836SJohn.Forte@Sun.COM 
2590*7836SJohn.Forte@Sun.COM 	/*
2591*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2592*7836SJohn.Forte@Sun.COM 	 */
2593*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2594*7836SJohn.Forte@Sun.COM 		return (ret);
2595*7836SJohn.Forte@Sun.COM 
2596*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
2597*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2598*7836SJohn.Forte@Sun.COM 		goto done;
2599*7836SJohn.Forte@Sun.COM 	}
2600*7836SJohn.Forte@Sun.COM 
2601*7836SJohn.Forte@Sun.COM 	/* Load the persistent configuration data */
2602*7836SJohn.Forte@Sun.COM 	ret = loadStore(fd);
2603*7836SJohn.Forte@Sun.COM 	if (ret != 0) {
2604*7836SJohn.Forte@Sun.COM 		goto done;
2605*7836SJohn.Forte@Sun.COM 	}
2606*7836SJohn.Forte@Sun.COM 
2607*7836SJohn.Forte@Sun.COM 	stmfStateSet.state = STMF_STATE_OFFLINE;
2608*7836SJohn.Forte@Sun.COM 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
2609*7836SJohn.Forte@Sun.COM 
2610*7836SJohn.Forte@Sun.COM done:
2611*7836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
2612*7836SJohn.Forte@Sun.COM 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
2613*7836SJohn.Forte@Sun.COM 	}
2614*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2615*7836SJohn.Forte@Sun.COM 	return (ret);
2616*7836SJohn.Forte@Sun.COM }
2617*7836SJohn.Forte@Sun.COM 
2618*7836SJohn.Forte@Sun.COM /*
2619*7836SJohn.Forte@Sun.COM  * getStmfState
2620*7836SJohn.Forte@Sun.COM  *
2621*7836SJohn.Forte@Sun.COM  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
2622*7836SJohn.Forte@Sun.COM  *             information of the stmf service on success.
2623*7836SJohn.Forte@Sun.COM  */
2624*7836SJohn.Forte@Sun.COM static int
2625*7836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState)
2626*7836SJohn.Forte@Sun.COM {
2627*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2628*7836SJohn.Forte@Sun.COM 	int fd;
2629*7836SJohn.Forte@Sun.COM 	int ioctlRet;
2630*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2631*7836SJohn.Forte@Sun.COM 
2632*7836SJohn.Forte@Sun.COM 	/*
2633*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2634*7836SJohn.Forte@Sun.COM 	 */
2635*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
2636*7836SJohn.Forte@Sun.COM 		return (ret);
2637*7836SJohn.Forte@Sun.COM 
2638*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
2639*7836SJohn.Forte@Sun.COM 	/*
2640*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to get the stmf state
2641*7836SJohn.Forte@Sun.COM 	 */
2642*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
2643*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
2644*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
2645*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
2646*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
2647*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
2648*7836SJohn.Forte@Sun.COM 
2649*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2650*7836SJohn.Forte@Sun.COM 
2651*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
2652*7836SJohn.Forte@Sun.COM 		switch (errno) {
2653*7836SJohn.Forte@Sun.COM 			case EBUSY:
2654*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2655*7836SJohn.Forte@Sun.COM 				break;
2656*7836SJohn.Forte@Sun.COM 			case EPERM:
2657*7836SJohn.Forte@Sun.COM 			case EACCES:
2658*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
2659*7836SJohn.Forte@Sun.COM 				break;
2660*7836SJohn.Forte@Sun.COM 			default:
2661*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
2662*7836SJohn.Forte@Sun.COM 				    "getStmfState:ioctl errno(%d)", errno);
2663*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
2664*7836SJohn.Forte@Sun.COM 				break;
2665*7836SJohn.Forte@Sun.COM 		}
2666*7836SJohn.Forte@Sun.COM 	}
2667*7836SJohn.Forte@Sun.COM 	return (ret);
2668*7836SJohn.Forte@Sun.COM }
2669*7836SJohn.Forte@Sun.COM 
2670*7836SJohn.Forte@Sun.COM 
2671*7836SJohn.Forte@Sun.COM /*
2672*7836SJohn.Forte@Sun.COM  * setStmfState
2673*7836SJohn.Forte@Sun.COM  *
2674*7836SJohn.Forte@Sun.COM  * stmfState - pointer to caller set state structure
2675*7836SJohn.Forte@Sun.COM  * objectType - one of:
2676*7836SJohn.Forte@Sun.COM  *		LOGICAL_UNIT_TYPE
2677*7836SJohn.Forte@Sun.COM  *		TARGET_TYPE
2678*7836SJohn.Forte@Sun.COM  *		STMF_SERVICE_TYPE
2679*7836SJohn.Forte@Sun.COM  */
2680*7836SJohn.Forte@Sun.COM static int
2681*7836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
2682*7836SJohn.Forte@Sun.COM {
2683*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2684*7836SJohn.Forte@Sun.COM 	int ioctlRet;
2685*7836SJohn.Forte@Sun.COM 	int cmd;
2686*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
2687*7836SJohn.Forte@Sun.COM 
2688*7836SJohn.Forte@Sun.COM 	switch (objectType) {
2689*7836SJohn.Forte@Sun.COM 		case LOGICAL_UNIT_TYPE:
2690*7836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_LU_STATE;
2691*7836SJohn.Forte@Sun.COM 			break;
2692*7836SJohn.Forte@Sun.COM 		case TARGET_TYPE:
2693*7836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
2694*7836SJohn.Forte@Sun.COM 			break;
2695*7836SJohn.Forte@Sun.COM 		case STMF_SERVICE_TYPE:
2696*7836SJohn.Forte@Sun.COM 			cmd = STMF_IOCTL_SET_STMF_STATE;
2697*7836SJohn.Forte@Sun.COM 			break;
2698*7836SJohn.Forte@Sun.COM 		default:
2699*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
2700*7836SJohn.Forte@Sun.COM 			goto done;
2701*7836SJohn.Forte@Sun.COM 	}
2702*7836SJohn.Forte@Sun.COM 
2703*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
2704*7836SJohn.Forte@Sun.COM 	/*
2705*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to set the stmf state
2706*7836SJohn.Forte@Sun.COM 	 */
2707*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
2708*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
2709*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
2710*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
2711*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
2712*7836SJohn.Forte@Sun.COM 		switch (errno) {
2713*7836SJohn.Forte@Sun.COM 			case EBUSY:
2714*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
2715*7836SJohn.Forte@Sun.COM 				break;
2716*7836SJohn.Forte@Sun.COM 			case EACCES:
2717*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
2718*7836SJohn.Forte@Sun.COM 				break;
2719*7836SJohn.Forte@Sun.COM 			case ENOENT:
2720*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
2721*7836SJohn.Forte@Sun.COM 				break;
2722*7836SJohn.Forte@Sun.COM 			default:
2723*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
2724*7836SJohn.Forte@Sun.COM 				    "setStmfState:ioctl errno(%d)", errno);
2725*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
2726*7836SJohn.Forte@Sun.COM 				break;
2727*7836SJohn.Forte@Sun.COM 		}
2728*7836SJohn.Forte@Sun.COM 	}
2729*7836SJohn.Forte@Sun.COM done:
2730*7836SJohn.Forte@Sun.COM 	return (ret);
2731*7836SJohn.Forte@Sun.COM }
2732*7836SJohn.Forte@Sun.COM 
2733*7836SJohn.Forte@Sun.COM /*
2734*7836SJohn.Forte@Sun.COM  * stmfOnline
2735*7836SJohn.Forte@Sun.COM  *
2736*7836SJohn.Forte@Sun.COM  * Purpose: Online stmf service
2737*7836SJohn.Forte@Sun.COM  *
2738*7836SJohn.Forte@Sun.COM  */
2739*7836SJohn.Forte@Sun.COM int
2740*7836SJohn.Forte@Sun.COM stmfOnline(void)
2741*7836SJohn.Forte@Sun.COM {
2742*7836SJohn.Forte@Sun.COM 	int ret;
2743*7836SJohn.Forte@Sun.COM 	int fd;
2744*7836SJohn.Forte@Sun.COM 	stmfState state;
2745*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
2746*7836SJohn.Forte@Sun.COM 
2747*7836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2748*7836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
2749*7836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
2750*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_ONLINE);
2751*7836SJohn.Forte@Sun.COM 		}
2752*7836SJohn.Forte@Sun.COM 	} else {
2753*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
2754*7836SJohn.Forte@Sun.COM 	}
2755*7836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_ONLINE;
2756*7836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
2757*7836SJohn.Forte@Sun.COM 	/*
2758*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2759*7836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
2760*7836SJohn.Forte@Sun.COM 	 */
2761*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2762*7836SJohn.Forte@Sun.COM 		return (ret);
2763*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
2764*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2765*7836SJohn.Forte@Sun.COM 	return (ret);
2766*7836SJohn.Forte@Sun.COM }
2767*7836SJohn.Forte@Sun.COM 
2768*7836SJohn.Forte@Sun.COM /*
2769*7836SJohn.Forte@Sun.COM  * stmfOffline
2770*7836SJohn.Forte@Sun.COM  *
2771*7836SJohn.Forte@Sun.COM  * Purpose: Offline stmf service
2772*7836SJohn.Forte@Sun.COM  *
2773*7836SJohn.Forte@Sun.COM  */
2774*7836SJohn.Forte@Sun.COM int
2775*7836SJohn.Forte@Sun.COM stmfOffline(void)
2776*7836SJohn.Forte@Sun.COM {
2777*7836SJohn.Forte@Sun.COM 	int ret;
2778*7836SJohn.Forte@Sun.COM 	int fd;
2779*7836SJohn.Forte@Sun.COM 	stmfState state;
2780*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t iState;
2781*7836SJohn.Forte@Sun.COM 
2782*7836SJohn.Forte@Sun.COM 	ret = stmfGetState(&state);
2783*7836SJohn.Forte@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
2784*7836SJohn.Forte@Sun.COM 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
2785*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_SERVICE_OFFLINE);
2786*7836SJohn.Forte@Sun.COM 		}
2787*7836SJohn.Forte@Sun.COM 	} else {
2788*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
2789*7836SJohn.Forte@Sun.COM 	}
2790*7836SJohn.Forte@Sun.COM 	iState.state = STMF_STATE_OFFLINE;
2791*7836SJohn.Forte@Sun.COM 	iState.config_state = STMF_CONFIG_NONE;
2792*7836SJohn.Forte@Sun.COM 
2793*7836SJohn.Forte@Sun.COM 	/*
2794*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2795*7836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
2796*7836SJohn.Forte@Sun.COM 	 */
2797*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2798*7836SJohn.Forte@Sun.COM 		return (ret);
2799*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
2800*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2801*7836SJohn.Forte@Sun.COM 	return (ret);
2802*7836SJohn.Forte@Sun.COM }
2803*7836SJohn.Forte@Sun.COM 
2804*7836SJohn.Forte@Sun.COM 
2805*7836SJohn.Forte@Sun.COM /*
2806*7836SJohn.Forte@Sun.COM  * stmfOfflineTarget
2807*7836SJohn.Forte@Sun.COM  *
2808*7836SJohn.Forte@Sun.COM  * Purpose: Change state of target to offline
2809*7836SJohn.Forte@Sun.COM  *
2810*7836SJohn.Forte@Sun.COM  * devid - devid of the target to offline
2811*7836SJohn.Forte@Sun.COM  */
2812*7836SJohn.Forte@Sun.COM int
2813*7836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid)
2814*7836SJohn.Forte@Sun.COM {
2815*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
2816*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2817*7836SJohn.Forte@Sun.COM 	int fd;
2818*7836SJohn.Forte@Sun.COM 
2819*7836SJohn.Forte@Sun.COM 	if (devid == NULL) {
2820*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2821*7836SJohn.Forte@Sun.COM 	}
2822*7836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
2823*7836SJohn.Forte@Sun.COM 
2824*7836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_OFFLINE;
2825*7836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
2826*7836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
2827*7836SJohn.Forte@Sun.COM 	    devid->identLength);
2828*7836SJohn.Forte@Sun.COM 	/*
2829*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2830*7836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
2831*7836SJohn.Forte@Sun.COM 	 */
2832*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2833*7836SJohn.Forte@Sun.COM 		return (ret);
2834*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
2835*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2836*7836SJohn.Forte@Sun.COM 	return (ret);
2837*7836SJohn.Forte@Sun.COM }
2838*7836SJohn.Forte@Sun.COM 
2839*7836SJohn.Forte@Sun.COM /*
2840*7836SJohn.Forte@Sun.COM  * stmfOfflineLogicalUnit
2841*7836SJohn.Forte@Sun.COM  *
2842*7836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to offline
2843*7836SJohn.Forte@Sun.COM  *
2844*7836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to offline
2845*7836SJohn.Forte@Sun.COM  */
2846*7836SJohn.Forte@Sun.COM int
2847*7836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu)
2848*7836SJohn.Forte@Sun.COM {
2849*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
2850*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2851*7836SJohn.Forte@Sun.COM 	int fd;
2852*7836SJohn.Forte@Sun.COM 
2853*7836SJohn.Forte@Sun.COM 	if (lu == NULL) {
2854*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2855*7836SJohn.Forte@Sun.COM 	}
2856*7836SJohn.Forte@Sun.COM 
2857*7836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
2858*7836SJohn.Forte@Sun.COM 
2859*7836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_OFFLINE;
2860*7836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
2861*7836SJohn.Forte@Sun.COM 	/*
2862*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2863*7836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
2864*7836SJohn.Forte@Sun.COM 	 */
2865*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2866*7836SJohn.Forte@Sun.COM 		return (ret);
2867*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
2868*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2869*7836SJohn.Forte@Sun.COM 	return (ret);
2870*7836SJohn.Forte@Sun.COM }
2871*7836SJohn.Forte@Sun.COM 
2872*7836SJohn.Forte@Sun.COM /*
2873*7836SJohn.Forte@Sun.COM  * stmfOnlineTarget
2874*7836SJohn.Forte@Sun.COM  *
2875*7836SJohn.Forte@Sun.COM  * Purpose: Change state of target to online
2876*7836SJohn.Forte@Sun.COM  *
2877*7836SJohn.Forte@Sun.COM  * devid - devid of the target to online
2878*7836SJohn.Forte@Sun.COM  */
2879*7836SJohn.Forte@Sun.COM int
2880*7836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid)
2881*7836SJohn.Forte@Sun.COM {
2882*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t targetState;
2883*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2884*7836SJohn.Forte@Sun.COM 	int fd;
2885*7836SJohn.Forte@Sun.COM 
2886*7836SJohn.Forte@Sun.COM 	if (devid == NULL) {
2887*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2888*7836SJohn.Forte@Sun.COM 	}
2889*7836SJohn.Forte@Sun.COM 	bzero(&targetState, sizeof (targetState));
2890*7836SJohn.Forte@Sun.COM 
2891*7836SJohn.Forte@Sun.COM 	targetState.state = STMF_STATE_ONLINE;
2892*7836SJohn.Forte@Sun.COM 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
2893*7836SJohn.Forte@Sun.COM 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
2894*7836SJohn.Forte@Sun.COM 	    devid->identLength);
2895*7836SJohn.Forte@Sun.COM 	/*
2896*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2897*7836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
2898*7836SJohn.Forte@Sun.COM 	 */
2899*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2900*7836SJohn.Forte@Sun.COM 		return (ret);
2901*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
2902*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2903*7836SJohn.Forte@Sun.COM 	return (ret);
2904*7836SJohn.Forte@Sun.COM }
2905*7836SJohn.Forte@Sun.COM 
2906*7836SJohn.Forte@Sun.COM /*
2907*7836SJohn.Forte@Sun.COM  * stmfOnlineLogicalUnit
2908*7836SJohn.Forte@Sun.COM  *
2909*7836SJohn.Forte@Sun.COM  * Purpose: Change state of logical unit to online
2910*7836SJohn.Forte@Sun.COM  *
2911*7836SJohn.Forte@Sun.COM  * lu - guid of the logical unit to online
2912*7836SJohn.Forte@Sun.COM  */
2913*7836SJohn.Forte@Sun.COM int
2914*7836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu)
2915*7836SJohn.Forte@Sun.COM {
2916*7836SJohn.Forte@Sun.COM 	stmf_state_desc_t luState;
2917*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
2918*7836SJohn.Forte@Sun.COM 	int fd;
2919*7836SJohn.Forte@Sun.COM 
2920*7836SJohn.Forte@Sun.COM 	if (lu == NULL) {
2921*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2922*7836SJohn.Forte@Sun.COM 	}
2923*7836SJohn.Forte@Sun.COM 
2924*7836SJohn.Forte@Sun.COM 	bzero(&luState, sizeof (luState));
2925*7836SJohn.Forte@Sun.COM 
2926*7836SJohn.Forte@Sun.COM 	luState.state = STMF_STATE_ONLINE;
2927*7836SJohn.Forte@Sun.COM 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
2928*7836SJohn.Forte@Sun.COM 	/*
2929*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2930*7836SJohn.Forte@Sun.COM 	 * to make call to setStmfState()
2931*7836SJohn.Forte@Sun.COM 	 */
2932*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
2933*7836SJohn.Forte@Sun.COM 		return (ret);
2934*7836SJohn.Forte@Sun.COM 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
2935*7836SJohn.Forte@Sun.COM 	(void) close(fd);
2936*7836SJohn.Forte@Sun.COM 	return (ret);
2937*7836SJohn.Forte@Sun.COM }
2938*7836SJohn.Forte@Sun.COM 
2939*7836SJohn.Forte@Sun.COM /*
2940*7836SJohn.Forte@Sun.COM  * stmfRemoveFromHostGroup
2941*7836SJohn.Forte@Sun.COM  *
2942*7836SJohn.Forte@Sun.COM  * Purpose: Removes an initiator from an initiator group
2943*7836SJohn.Forte@Sun.COM  *
2944*7836SJohn.Forte@Sun.COM  * hostGroupName - name of an initiator group
2945*7836SJohn.Forte@Sun.COM  * hostName - name of host group member to remove
2946*7836SJohn.Forte@Sun.COM  */
2947*7836SJohn.Forte@Sun.COM int
2948*7836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
2949*7836SJohn.Forte@Sun.COM {
2950*7836SJohn.Forte@Sun.COM 	int ret;
2951*7836SJohn.Forte@Sun.COM 	int fd;
2952*7836SJohn.Forte@Sun.COM 
2953*7836SJohn.Forte@Sun.COM 	if (hostGroupName == NULL ||
2954*7836SJohn.Forte@Sun.COM 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
2955*7836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || hostName == NULL) {
2956*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
2957*7836SJohn.Forte@Sun.COM 	}
2958*7836SJohn.Forte@Sun.COM 
2959*7836SJohn.Forte@Sun.COM 	/* call init */
2960*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
2961*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
2962*7836SJohn.Forte@Sun.COM 		return (ret);
2963*7836SJohn.Forte@Sun.COM 	}
2964*7836SJohn.Forte@Sun.COM 
2965*7836SJohn.Forte@Sun.COM 	/*
2966*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
2967*7836SJohn.Forte@Sun.COM 	 */
2968*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
2969*7836SJohn.Forte@Sun.COM 		return (ret);
2970*7836SJohn.Forte@Sun.COM 
2971*7836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
2972*7836SJohn.Forte@Sun.COM 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
2973*7836SJohn.Forte@Sun.COM 		goto done;
2974*7836SJohn.Forte@Sun.COM 	}
2975*7836SJohn.Forte@Sun.COM 
2976*7836SJohn.Forte@Sun.COM 	ret = psRemoveHostGroupMember((char *)hostGroupName,
2977*7836SJohn.Forte@Sun.COM 	    (char *)hostName->ident);
2978*7836SJohn.Forte@Sun.COM 	switch (ret) {
2979*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
2980*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
2981*7836SJohn.Forte@Sun.COM 			break;
2982*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
2983*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
2984*7836SJohn.Forte@Sun.COM 			break;
2985*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
2986*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
2987*7836SJohn.Forte@Sun.COM 			break;
2988*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
2989*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
2990*7836SJohn.Forte@Sun.COM 			break;
2991*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2992*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2993*7836SJohn.Forte@Sun.COM 			break;
2994*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
2995*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2996*7836SJohn.Forte@Sun.COM 			break;
2997*7836SJohn.Forte@Sun.COM 		default:
2998*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
2999*7836SJohn.Forte@Sun.COM 			    "stmfRemoveFromHostGroup"
3000*7836SJohn.Forte@Sun.COM 			    "psRemoveHostGroupMember:error(%d)", ret);
3001*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
3002*7836SJohn.Forte@Sun.COM 			break;
3003*7836SJohn.Forte@Sun.COM 	}
3004*7836SJohn.Forte@Sun.COM 
3005*7836SJohn.Forte@Sun.COM done:
3006*7836SJohn.Forte@Sun.COM 	(void) close(fd);
3007*7836SJohn.Forte@Sun.COM 	return (ret);
3008*7836SJohn.Forte@Sun.COM }
3009*7836SJohn.Forte@Sun.COM 
3010*7836SJohn.Forte@Sun.COM /*
3011*7836SJohn.Forte@Sun.COM  * stmfRemoveFromTargetGroup
3012*7836SJohn.Forte@Sun.COM  *
3013*7836SJohn.Forte@Sun.COM  * Purpose: Removes a local port from a local port group
3014*7836SJohn.Forte@Sun.COM  *
3015*7836SJohn.Forte@Sun.COM  * targetGroupName - name of a target group
3016*7836SJohn.Forte@Sun.COM  * targetName - name of target to remove
3017*7836SJohn.Forte@Sun.COM  */
3018*7836SJohn.Forte@Sun.COM int
3019*7836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
3020*7836SJohn.Forte@Sun.COM {
3021*7836SJohn.Forte@Sun.COM 	int ret;
3022*7836SJohn.Forte@Sun.COM 	int fd;
3023*7836SJohn.Forte@Sun.COM 
3024*7836SJohn.Forte@Sun.COM 	if (targetGroupName == NULL ||
3025*7836SJohn.Forte@Sun.COM 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
3026*7836SJohn.Forte@Sun.COM 	    == sizeof (stmfGroupName)) || targetName == NULL) {
3027*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
3028*7836SJohn.Forte@Sun.COM 	}
3029*7836SJohn.Forte@Sun.COM 
3030*7836SJohn.Forte@Sun.COM 	/* call init */
3031*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
3032*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
3033*7836SJohn.Forte@Sun.COM 		return (ret);
3034*7836SJohn.Forte@Sun.COM 	}
3035*7836SJohn.Forte@Sun.COM 
3036*7836SJohn.Forte@Sun.COM 	/*
3037*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
3038*7836SJohn.Forte@Sun.COM 	 */
3039*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3040*7836SJohn.Forte@Sun.COM 		return (ret);
3041*7836SJohn.Forte@Sun.COM 
3042*7836SJohn.Forte@Sun.COM 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
3043*7836SJohn.Forte@Sun.COM 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
3044*7836SJohn.Forte@Sun.COM 		goto done;
3045*7836SJohn.Forte@Sun.COM 	}
3046*7836SJohn.Forte@Sun.COM 
3047*7836SJohn.Forte@Sun.COM 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
3048*7836SJohn.Forte@Sun.COM 	    (char *)targetName->ident);
3049*7836SJohn.Forte@Sun.COM 	switch (ret) {
3050*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
3051*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
3052*7836SJohn.Forte@Sun.COM 			break;
3053*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
3054*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
3055*7836SJohn.Forte@Sun.COM 			break;
3056*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
3057*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_GROUP_NOT_FOUND;
3058*7836SJohn.Forte@Sun.COM 			break;
3059*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
3060*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
3061*7836SJohn.Forte@Sun.COM 			break;
3062*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3063*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3064*7836SJohn.Forte@Sun.COM 			break;
3065*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
3066*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3067*7836SJohn.Forte@Sun.COM 			break;
3068*7836SJohn.Forte@Sun.COM 		default:
3069*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
3070*7836SJohn.Forte@Sun.COM 			    "stmfRemoveFromTargetGroup"
3071*7836SJohn.Forte@Sun.COM 			    "psRemoveTargetGroupMember:error(%d)", ret);
3072*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
3073*7836SJohn.Forte@Sun.COM 			break;
3074*7836SJohn.Forte@Sun.COM 	}
3075*7836SJohn.Forte@Sun.COM 
3076*7836SJohn.Forte@Sun.COM done:
3077*7836SJohn.Forte@Sun.COM 	(void) close(fd);
3078*7836SJohn.Forte@Sun.COM 	return (ret);
3079*7836SJohn.Forte@Sun.COM }
3080*7836SJohn.Forte@Sun.COM 
3081*7836SJohn.Forte@Sun.COM /*
3082*7836SJohn.Forte@Sun.COM  * stmfRemoveViewEntry
3083*7836SJohn.Forte@Sun.COM  *
3084*7836SJohn.Forte@Sun.COM  * Purpose: Removes a view entry from a logical unit
3085*7836SJohn.Forte@Sun.COM  *
3086*7836SJohn.Forte@Sun.COM  * lu - guid of lu for which view entry is being removed
3087*7836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry to remove
3088*7836SJohn.Forte@Sun.COM  *
3089*7836SJohn.Forte@Sun.COM  */
3090*7836SJohn.Forte@Sun.COM int
3091*7836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
3092*7836SJohn.Forte@Sun.COM {
3093*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
3094*7836SJohn.Forte@Sun.COM 	int fd;
3095*7836SJohn.Forte@Sun.COM 	int ioctlRet;
3096*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
3097*7836SJohn.Forte@Sun.COM 	stmf_view_op_entry_t ioctlViewEntry;
3098*7836SJohn.Forte@Sun.COM 
3099*7836SJohn.Forte@Sun.COM 	if (lu == NULL) {
3100*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
3101*7836SJohn.Forte@Sun.COM 	}
3102*7836SJohn.Forte@Sun.COM 
3103*7836SJohn.Forte@Sun.COM 	/* call init */
3104*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
3105*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
3106*7836SJohn.Forte@Sun.COM 		return (ret);
3107*7836SJohn.Forte@Sun.COM 	}
3108*7836SJohn.Forte@Sun.COM 
3109*7836SJohn.Forte@Sun.COM 	/*
3110*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
3111*7836SJohn.Forte@Sun.COM 	 */
3112*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3113*7836SJohn.Forte@Sun.COM 		return (ret);
3114*7836SJohn.Forte@Sun.COM 
3115*7836SJohn.Forte@Sun.COM 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
3116*7836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
3117*7836SJohn.Forte@Sun.COM 	ioctlViewEntry.ve_ndx = viewEntryIndex;
3118*7836SJohn.Forte@Sun.COM 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
3119*7836SJohn.Forte@Sun.COM 
3120*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3121*7836SJohn.Forte@Sun.COM 	/*
3122*7836SJohn.Forte@Sun.COM 	 * Issue ioctl to add to the view entry
3123*7836SJohn.Forte@Sun.COM 	 */
3124*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3125*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
3126*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
3127*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
3128*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3129*7836SJohn.Forte@Sun.COM 		switch (errno) {
3130*7836SJohn.Forte@Sun.COM 			case EBUSY:
3131*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
3132*7836SJohn.Forte@Sun.COM 				break;
3133*7836SJohn.Forte@Sun.COM 			case EACCES:
3134*7836SJohn.Forte@Sun.COM 				switch (stmfIoctl.stmf_error) {
3135*7836SJohn.Forte@Sun.COM 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
3136*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_CONFIG_NONE;
3137*7836SJohn.Forte@Sun.COM 						break;
3138*7836SJohn.Forte@Sun.COM 					default:
3139*7836SJohn.Forte@Sun.COM 						ret = STMF_ERROR_PERM;
3140*7836SJohn.Forte@Sun.COM 						break;
3141*7836SJohn.Forte@Sun.COM 				}
3142*7836SJohn.Forte@Sun.COM 				break;
3143*7836SJohn.Forte@Sun.COM 			case ENODEV:
3144*7836SJohn.Forte@Sun.COM 			case ENOENT:
3145*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_NOT_FOUND;
3146*7836SJohn.Forte@Sun.COM 				break;
3147*7836SJohn.Forte@Sun.COM 			default:
3148*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
3149*7836SJohn.Forte@Sun.COM 				    "stmfRemoveViewEntry:ioctl errno(%d)",
3150*7836SJohn.Forte@Sun.COM 				    errno);
3151*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
3152*7836SJohn.Forte@Sun.COM 				break;
3153*7836SJohn.Forte@Sun.COM 		}
3154*7836SJohn.Forte@Sun.COM 		goto done;
3155*7836SJohn.Forte@Sun.COM 	}
3156*7836SJohn.Forte@Sun.COM 
3157*7836SJohn.Forte@Sun.COM 	ret = psRemoveViewEntry(lu, viewEntryIndex);
3158*7836SJohn.Forte@Sun.COM 	switch (ret) {
3159*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
3160*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
3161*7836SJohn.Forte@Sun.COM 			break;
3162*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_NOT_FOUND:
3163*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_NOT_FOUND;
3164*7836SJohn.Forte@Sun.COM 			break;
3165*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
3166*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
3167*7836SJohn.Forte@Sun.COM 			break;
3168*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3169*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3170*7836SJohn.Forte@Sun.COM 			break;
3171*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
3172*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3173*7836SJohn.Forte@Sun.COM 			break;
3174*7836SJohn.Forte@Sun.COM 		default:
3175*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
3176*7836SJohn.Forte@Sun.COM 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
3177*7836SJohn.Forte@Sun.COM 			    ret);
3178*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
3179*7836SJohn.Forte@Sun.COM 			break;
3180*7836SJohn.Forte@Sun.COM 	}
3181*7836SJohn.Forte@Sun.COM 
3182*7836SJohn.Forte@Sun.COM done:
3183*7836SJohn.Forte@Sun.COM 	(void) close(fd);
3184*7836SJohn.Forte@Sun.COM 	return (ret);
3185*7836SJohn.Forte@Sun.COM }
3186*7836SJohn.Forte@Sun.COM 
3187*7836SJohn.Forte@Sun.COM /*
3188*7836SJohn.Forte@Sun.COM  * stmfSetProviderData
3189*7836SJohn.Forte@Sun.COM  *
3190*7836SJohn.Forte@Sun.COM  * Purpose: set the provider data
3191*7836SJohn.Forte@Sun.COM  *
3192*7836SJohn.Forte@Sun.COM  * providerName - unique name of provider
3193*7836SJohn.Forte@Sun.COM  * nvl - nvlist to set
3194*7836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
3195*7836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
3196*7836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
3197*7836SJohn.Forte@Sun.COM  */
3198*7836SJohn.Forte@Sun.COM int
3199*7836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
3200*7836SJohn.Forte@Sun.COM {
3201*7836SJohn.Forte@Sun.COM 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
3202*7836SJohn.Forte@Sun.COM 	    NULL));
3203*7836SJohn.Forte@Sun.COM }
3204*7836SJohn.Forte@Sun.COM 
3205*7836SJohn.Forte@Sun.COM /*
3206*7836SJohn.Forte@Sun.COM  * stmfSetProviderDataProt
3207*7836SJohn.Forte@Sun.COM  *
3208*7836SJohn.Forte@Sun.COM  * Purpose: set the provider data
3209*7836SJohn.Forte@Sun.COM  *
3210*7836SJohn.Forte@Sun.COM  * providerName - unique name of provider
3211*7836SJohn.Forte@Sun.COM  * nvl - nvlist to set
3212*7836SJohn.Forte@Sun.COM  * providerType - type of provider for which to set data
3213*7836SJohn.Forte@Sun.COM  *		STMF_LU_PROVIDER_TYPE
3214*7836SJohn.Forte@Sun.COM  *		STMF_PORT_PROVIDER_TYPE
3215*7836SJohn.Forte@Sun.COM  * setToken - Stale data token returned in the stmfGetProviderDataProt()
3216*7836SJohn.Forte@Sun.COM  *	      call or NULL.
3217*7836SJohn.Forte@Sun.COM  */
3218*7836SJohn.Forte@Sun.COM int
3219*7836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
3220*7836SJohn.Forte@Sun.COM     uint64_t *setToken)
3221*7836SJohn.Forte@Sun.COM {
3222*7836SJohn.Forte@Sun.COM 	int ret;
3223*7836SJohn.Forte@Sun.COM 	int fd;
3224*7836SJohn.Forte@Sun.COM 
3225*7836SJohn.Forte@Sun.COM 	if (providerName == NULL || nvl == NULL) {
3226*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
3227*7836SJohn.Forte@Sun.COM 	}
3228*7836SJohn.Forte@Sun.COM 
3229*7836SJohn.Forte@Sun.COM 	if (providerType != STMF_LU_PROVIDER_TYPE &&
3230*7836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE) {
3231*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
3232*7836SJohn.Forte@Sun.COM 	}
3233*7836SJohn.Forte@Sun.COM 
3234*7836SJohn.Forte@Sun.COM 	/* call init */
3235*7836SJohn.Forte@Sun.COM 	ret = initializeConfig();
3236*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
3237*7836SJohn.Forte@Sun.COM 		return (ret);
3238*7836SJohn.Forte@Sun.COM 	}
3239*7836SJohn.Forte@Sun.COM 
3240*7836SJohn.Forte@Sun.COM 	/*
3241*7836SJohn.Forte@Sun.COM 	 * Open control node for stmf
3242*7836SJohn.Forte@Sun.COM 	 */
3243*7836SJohn.Forte@Sun.COM 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3244*7836SJohn.Forte@Sun.COM 		return (ret);
3245*7836SJohn.Forte@Sun.COM 
3246*7836SJohn.Forte@Sun.COM 	ret = setProviderData(fd, providerName, nvl, providerType);
3247*7836SJohn.Forte@Sun.COM 
3248*7836SJohn.Forte@Sun.COM 	(void) close(fd);
3249*7836SJohn.Forte@Sun.COM 
3250*7836SJohn.Forte@Sun.COM 	if (ret != STMF_STATUS_SUCCESS) {
3251*7836SJohn.Forte@Sun.COM 		goto done;
3252*7836SJohn.Forte@Sun.COM 	}
3253*7836SJohn.Forte@Sun.COM 
3254*7836SJohn.Forte@Sun.COM 	/* setting driver provider data successful. Now persist it */
3255*7836SJohn.Forte@Sun.COM 	ret = psSetProviderData(providerName, nvl, providerType, setToken);
3256*7836SJohn.Forte@Sun.COM 	switch (ret) {
3257*7836SJohn.Forte@Sun.COM 		case STMF_PS_SUCCESS:
3258*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_SUCCESS;
3259*7836SJohn.Forte@Sun.COM 			break;
3260*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_EXISTS:
3261*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_EXISTS;
3262*7836SJohn.Forte@Sun.COM 			break;
3263*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_BUSY:
3264*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_BUSY;
3265*7836SJohn.Forte@Sun.COM 			break;
3266*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3267*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3268*7836SJohn.Forte@Sun.COM 			break;
3269*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_VERSION_MISMATCH:
3270*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3271*7836SJohn.Forte@Sun.COM 			break;
3272*7836SJohn.Forte@Sun.COM 		case STMF_PS_ERROR_PROV_DATA_STALE:
3273*7836SJohn.Forte@Sun.COM 			ret = STMF_ERROR_PROV_DATA_STALE;
3274*7836SJohn.Forte@Sun.COM 			break;
3275*7836SJohn.Forte@Sun.COM 		default:
3276*7836SJohn.Forte@Sun.COM 			syslog(LOG_DEBUG,
3277*7836SJohn.Forte@Sun.COM 			    "stmfSetProviderData"
3278*7836SJohn.Forte@Sun.COM 			    "psSetProviderData:error(%d)", ret);
3279*7836SJohn.Forte@Sun.COM 			ret = STMF_STATUS_ERROR;
3280*7836SJohn.Forte@Sun.COM 			break;
3281*7836SJohn.Forte@Sun.COM 	}
3282*7836SJohn.Forte@Sun.COM 
3283*7836SJohn.Forte@Sun.COM done:
3284*7836SJohn.Forte@Sun.COM 	return (ret);
3285*7836SJohn.Forte@Sun.COM }
3286*7836SJohn.Forte@Sun.COM 
3287*7836SJohn.Forte@Sun.COM /*
3288*7836SJohn.Forte@Sun.COM  * setProviderData
3289*7836SJohn.Forte@Sun.COM  *
3290*7836SJohn.Forte@Sun.COM  * Purpose: set the provider data
3291*7836SJohn.Forte@Sun.COM  *
3292*7836SJohn.Forte@Sun.COM  * providerName - unique name of provider
3293*7836SJohn.Forte@Sun.COM  * nvl - nvlist to set
3294*7836SJohn.Forte@Sun.COM  * providerType - logical unit or port provider
3295*7836SJohn.Forte@Sun.COM  */
3296*7836SJohn.Forte@Sun.COM static int
3297*7836SJohn.Forte@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType)
3298*7836SJohn.Forte@Sun.COM {
3299*7836SJohn.Forte@Sun.COM 	int ret = STMF_STATUS_SUCCESS;
3300*7836SJohn.Forte@Sun.COM 	int ioctlRet;
3301*7836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
3302*7836SJohn.Forte@Sun.COM 	stmf_ppioctl_data_t *ppi = NULL;
3303*7836SJohn.Forte@Sun.COM 	char *allocatedNvBuffer;
3304*7836SJohn.Forte@Sun.COM 	stmf_iocdata_t stmfIoctl;
3305*7836SJohn.Forte@Sun.COM 
3306*7836SJohn.Forte@Sun.COM 	if (providerName == NULL) {
3307*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_INVALID_ARG);
3308*7836SJohn.Forte@Sun.COM 	}
3309*7836SJohn.Forte@Sun.COM 
3310*7836SJohn.Forte@Sun.COM 	/* get size of encoded nvlist */
3311*7836SJohn.Forte@Sun.COM 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
3312*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
3313*7836SJohn.Forte@Sun.COM 	}
3314*7836SJohn.Forte@Sun.COM 
3315*7836SJohn.Forte@Sun.COM 	/* allocate memory for ioctl */
3316*7836SJohn.Forte@Sun.COM 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
3317*7836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t));
3318*7836SJohn.Forte@Sun.COM 	if (ppi == NULL) {
3319*7836SJohn.Forte@Sun.COM 		return (STMF_ERROR_NOMEM);
3320*7836SJohn.Forte@Sun.COM 	}
3321*7836SJohn.Forte@Sun.COM 
3322*7836SJohn.Forte@Sun.COM 	allocatedNvBuffer = (char *)&ppi->ppi_data;
3323*7836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
3324*7836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
3325*7836SJohn.Forte@Sun.COM 		return (STMF_STATUS_ERROR);
3326*7836SJohn.Forte@Sun.COM 	}
3327*7836SJohn.Forte@Sun.COM 
3328*7836SJohn.Forte@Sun.COM 	/* set provider name and provider type */
3329*7836SJohn.Forte@Sun.COM 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
3330*7836SJohn.Forte@Sun.COM 	switch (providerType) {
3331*7836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
3332*7836SJohn.Forte@Sun.COM 			ppi->ppi_lu_provider = 1;
3333*7836SJohn.Forte@Sun.COM 			break;
3334*7836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
3335*7836SJohn.Forte@Sun.COM 			ppi->ppi_port_provider = 1;
3336*7836SJohn.Forte@Sun.COM 			break;
3337*7836SJohn.Forte@Sun.COM 		default:
3338*7836SJohn.Forte@Sun.COM 			return (STMF_ERROR_INVALID_ARG);
3339*7836SJohn.Forte@Sun.COM 	}
3340*7836SJohn.Forte@Sun.COM 
3341*7836SJohn.Forte@Sun.COM 	/* set the size of the ioctl data to packed data size */
3342*7836SJohn.Forte@Sun.COM 	ppi->ppi_data_size = nvlistEncodedSize;
3343*7836SJohn.Forte@Sun.COM 
3344*7836SJohn.Forte@Sun.COM 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3345*7836SJohn.Forte@Sun.COM 
3346*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_version = STMF_VERSION_1;
3347*7836SJohn.Forte@Sun.COM 	/*
3348*7836SJohn.Forte@Sun.COM 	 * Subtracting 8 from the size as that is the size of the last member
3349*7836SJohn.Forte@Sun.COM 	 * of the structure where the packed data resides
3350*7836SJohn.Forte@Sun.COM 	 */
3351*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
3352*7836SJohn.Forte@Sun.COM 	    sizeof (stmf_ppioctl_data_t) - 8;
3353*7836SJohn.Forte@Sun.COM 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
3354*7836SJohn.Forte@Sun.COM 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
3355*7836SJohn.Forte@Sun.COM 	if (ioctlRet != 0) {
3356*7836SJohn.Forte@Sun.COM 		switch (errno) {
3357*7836SJohn.Forte@Sun.COM 			case EBUSY:
3358*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_BUSY;
3359*7836SJohn.Forte@Sun.COM 				break;
3360*7836SJohn.Forte@Sun.COM 			case EACCES:
3361*7836SJohn.Forte@Sun.COM 				ret = STMF_ERROR_PERM;
3362*7836SJohn.Forte@Sun.COM 				break;
3363*7836SJohn.Forte@Sun.COM 			default:
3364*7836SJohn.Forte@Sun.COM 				syslog(LOG_DEBUG,
3365*7836SJohn.Forte@Sun.COM 				    "setProviderData:ioctl errno(%d)", errno);
3366*7836SJohn.Forte@Sun.COM 				ret = STMF_STATUS_ERROR;
3367*7836SJohn.Forte@Sun.COM 				break;
3368*7836SJohn.Forte@Sun.COM 		}
3369*7836SJohn.Forte@Sun.COM 		if (ret != STMF_STATUS_SUCCESS)
3370*7836SJohn.Forte@Sun.COM 			goto done;
3371*7836SJohn.Forte@Sun.COM 	}
3372*7836SJohn.Forte@Sun.COM 
3373*7836SJohn.Forte@Sun.COM done:
3374*7836SJohn.Forte@Sun.COM 	free(ppi);
3375*7836SJohn.Forte@Sun.COM 	return (ret);
3376*7836SJohn.Forte@Sun.COM }
3377