xref: /titanic_44/usr/src/lib/libstmf/common/stmf.c (revision 8fe960854f0d52e2e8a80ba68e8621a5ac6a866d)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
22*8fe96085Stim szeto  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte 
26fcf3ce44SJohn Forte #include <stdlib.h>
27fcf3ce44SJohn Forte #include <stdio.h>
28fcf3ce44SJohn Forte #include <wchar.h>
29fcf3ce44SJohn Forte #include <strings.h>
30fcf3ce44SJohn Forte #include <sys/types.h>
31fcf3ce44SJohn Forte #include <sys/stat.h>
32fcf3ce44SJohn Forte #include <fcntl.h>
33fcf3ce44SJohn Forte #include <unistd.h>
34fcf3ce44SJohn Forte #include <libintl.h>
35fcf3ce44SJohn Forte #include <errno.h>
36fcf3ce44SJohn Forte #include <string.h>
37fcf3ce44SJohn Forte #include <assert.h>
38fcf3ce44SJohn Forte #include <libnvpair.h>
39fcf3ce44SJohn Forte #include <pthread.h>
40fcf3ce44SJohn Forte #include <syslog.h>
41fcf3ce44SJohn Forte #include <libstmf.h>
42fcf3ce44SJohn Forte #include <netinet/in.h>
43fcf3ce44SJohn Forte #include <inttypes.h>
44fcf3ce44SJohn Forte #include <store.h>
45fcf3ce44SJohn Forte #include <locale.h>
46*8fe96085Stim szeto #include <math.h>
47*8fe96085Stim szeto #include <libstmf_impl.h>
48fcf3ce44SJohn Forte #include <sys/stmf_ioctl.h>
49*8fe96085Stim szeto #include <sys/stmf_sbd_ioctl.h>
50fcf3ce44SJohn Forte 
51fcf3ce44SJohn Forte #define	STMF_PATH    "/devices/pseudo/stmf@0:admin"
52*8fe96085Stim szeto #define	SBD_PATH    "/devices/pseudo/stmf_sbd@0:admin"
53fcf3ce44SJohn Forte 
54fcf3ce44SJohn Forte #define	EUI "eui."
55fcf3ce44SJohn Forte #define	WWN "wwn."
56fcf3ce44SJohn Forte #define	IQN "iqn."
57*8fe96085Stim szeto #define	LU_ASCII_GUID_SIZE 32
58*8fe96085Stim szeto #define	LU_GUID_SIZE 16
59*8fe96085Stim szeto #define	OUI_ASCII_SIZE 6
60*8fe96085Stim szeto #define	OUI_SIZE 3
61fcf3ce44SJohn Forte #define	IDENT_LENGTH_BYTE 3
62fcf3ce44SJohn Forte 
63*8fe96085Stim szeto /* various initial allocation values */
64*8fe96085Stim szeto #define	ALLOC_LU		8192
65*8fe96085Stim szeto #define	ALLOC_TARGET_PORT	2048
66*8fe96085Stim szeto #define	ALLOC_PROVIDER		64
67*8fe96085Stim szeto #define	ALLOC_GROUP		2048
68*8fe96085Stim szeto #define	ALLOC_SESSION		2048
69*8fe96085Stim szeto #define	ALLOC_VE		256
70*8fe96085Stim szeto #define	ALLOC_PP_DATA_SIZE	128*1024
71*8fe96085Stim szeto #define	ALLOC_GRP_MEMBER	256
72*8fe96085Stim szeto 
73fcf3ce44SJohn Forte #define	MAX_ISCSI_NAME	223
74*8fe96085Stim szeto #define	MAX_SERIAL_SIZE 252 + 1
75*8fe96085Stim szeto #define	MAX_LU_ALIAS_SIZE 256
76*8fe96085Stim szeto #define	MAX_SBD_PROPS	MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
77fcf3ce44SJohn Forte 
78fcf3ce44SJohn Forte #define	OPEN_STMF 0
79fcf3ce44SJohn Forte #define	OPEN_EXCL_STMF O_EXCL
80fcf3ce44SJohn Forte 
81*8fe96085Stim szeto #define	OPEN_SBD 0
82*8fe96085Stim szeto #define	OPEN_EXCL_SBD O_EXCL
83*8fe96085Stim szeto 
84fcf3ce44SJohn Forte #define	LOGICAL_UNIT_TYPE 0
85fcf3ce44SJohn Forte #define	TARGET_TYPE 1
86fcf3ce44SJohn Forte #define	STMF_SERVICE_TYPE 2
87fcf3ce44SJohn Forte 
88*8fe96085Stim szeto #define	HOST_GROUP   1
89*8fe96085Stim szeto #define	TARGET_GROUP 2
90*8fe96085Stim szeto 
91*8fe96085Stim szeto /* set default persistence here */
92*8fe96085Stim szeto #define	STMF_DEFAULT_PERSIST	STMF_PERSIST_SMF
93*8fe96085Stim szeto 
94*8fe96085Stim szeto #define	MAX_PROVIDER_RETRY 30
95*8fe96085Stim szeto 
96fcf3ce44SJohn Forte static int openStmf(int, int *fd);
97*8fe96085Stim szeto static int openSbd(int, int *fd);
98fcf3ce44SJohn Forte static int groupIoctl(int fd, int cmd, stmfGroupName *);
99fcf3ce44SJohn Forte static int loadStore(int fd);
100fcf3ce44SJohn Forte static int initializeConfig();
101fcf3ce44SJohn Forte static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
102fcf3ce44SJohn Forte static int guidCompare(const void *, const void *);
103fcf3ce44SJohn Forte static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
104fcf3ce44SJohn Forte static int loadHostGroups(int fd, stmfGroupList *);
105fcf3ce44SJohn Forte static int loadTargetGroups(int fd, stmfGroupList *);
106fcf3ce44SJohn Forte static int getStmfState(stmf_state_desc_t *);
107fcf3ce44SJohn Forte static int setStmfState(int fd, stmf_state_desc_t *, int);
108*8fe96085Stim szeto static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
109*8fe96085Stim szeto static int createDiskResource(luResourceImpl *);
110*8fe96085Stim szeto static int createDiskLu(diskResource *, stmfGuid *);
111*8fe96085Stim szeto static int deleteDiskLu(stmfGuid *luGuid);
112*8fe96085Stim szeto static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
113*8fe96085Stim szeto static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
114*8fe96085Stim szeto static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
115*8fe96085Stim szeto static int removeGuidFromDiskStore(stmfGuid *);
116*8fe96085Stim szeto static int addGuidToDiskStore(stmfGuid *, char *);
117*8fe96085Stim szeto static int persistDiskGuid(stmfGuid *, char *, boolean_t);
118*8fe96085Stim szeto static int setDiskProp(luResourceImpl *, uint32_t, const char *);
119*8fe96085Stim szeto static int checkHexUpper(char *);
120*8fe96085Stim szeto static int strToShift(const char *);
121*8fe96085Stim szeto static int niceStrToNum(const char *, uint64_t *);
122*8fe96085Stim szeto static void diskError(uint32_t, int *);
123*8fe96085Stim szeto static int importDiskLu(char *fname, stmfGuid *);
124*8fe96085Stim szeto static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
125*8fe96085Stim szeto static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
126*8fe96085Stim szeto static int validateModifyDiskProp(uint32_t);
127*8fe96085Stim szeto static uint8_t iGetPersistMethod();
128*8fe96085Stim szeto static int groupListIoctl(stmfGroupList **, int);
129*8fe96085Stim szeto static int iLoadGroupFromPs(stmfGroupList **, int);
130*8fe96085Stim szeto static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
131*8fe96085Stim szeto static int getProviderData(char *, nvlist_t **, int, uint64_t *);
132*8fe96085Stim szeto static int viewEntryCompare(const void *, const void *);
133*8fe96085Stim szeto 
134*8fe96085Stim szeto static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER;
135*8fe96085Stim szeto static int iPersistType = 0;
136*8fe96085Stim szeto /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
137*8fe96085Stim szeto static boolean_t iLibSetPersist = B_FALSE;
138fcf3ce44SJohn Forte 
139fcf3ce44SJohn Forte /*
140fcf3ce44SJohn Forte  * Open for stmf module
141fcf3ce44SJohn Forte  *
142fcf3ce44SJohn Forte  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
143fcf3ce44SJohn Forte  * fd - pointer to integer. On success, contains the stmf file descriptor
144fcf3ce44SJohn Forte  */
145fcf3ce44SJohn Forte static int
146fcf3ce44SJohn Forte openStmf(int flag, int *fd)
147fcf3ce44SJohn Forte {
148fcf3ce44SJohn Forte 	int ret = STMF_STATUS_ERROR;
149fcf3ce44SJohn Forte 
150fcf3ce44SJohn Forte 	if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
151fcf3ce44SJohn Forte 		ret = STMF_STATUS_SUCCESS;
152fcf3ce44SJohn Forte 	} else {
153fcf3ce44SJohn Forte 		if (errno == EBUSY) {
154fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
155*8fe96085Stim szeto 		} else if (errno == EACCES) {
156*8fe96085Stim szeto 			ret = STMF_ERROR_PERM;
157fcf3ce44SJohn Forte 		} else {
158fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
159fcf3ce44SJohn Forte 		}
160fcf3ce44SJohn Forte 		syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
161fcf3ce44SJohn Forte 		    STMF_PATH, errno);
162fcf3ce44SJohn Forte 	}
163fcf3ce44SJohn Forte 
164fcf3ce44SJohn Forte 	return (ret);
165fcf3ce44SJohn Forte }
166fcf3ce44SJohn Forte 
167fcf3ce44SJohn Forte /*
168*8fe96085Stim szeto  * Open for sbd module
169*8fe96085Stim szeto  *
170*8fe96085Stim szeto  * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
171*8fe96085Stim szeto  * fd - pointer to integer. On success, contains the stmf file descriptor
172*8fe96085Stim szeto  */
173*8fe96085Stim szeto static int
174*8fe96085Stim szeto openSbd(int flag, int *fd)
175*8fe96085Stim szeto {
176*8fe96085Stim szeto 	int ret = STMF_STATUS_ERROR;
177*8fe96085Stim szeto 
178*8fe96085Stim szeto 	if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
179*8fe96085Stim szeto 		ret = STMF_STATUS_SUCCESS;
180*8fe96085Stim szeto 	} else {
181*8fe96085Stim szeto 		if (errno == EBUSY) {
182*8fe96085Stim szeto 			ret = STMF_ERROR_BUSY;
183*8fe96085Stim szeto 		} else if (errno == EACCES) {
184*8fe96085Stim szeto 			ret = STMF_ERROR_PERM;
185*8fe96085Stim szeto 		} else {
186*8fe96085Stim szeto 			ret = STMF_STATUS_ERROR;
187*8fe96085Stim szeto 		}
188*8fe96085Stim szeto 		syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)",
189*8fe96085Stim szeto 		    SBD_PATH, errno);
190*8fe96085Stim szeto 	}
191*8fe96085Stim szeto 
192*8fe96085Stim szeto 	return (ret);
193*8fe96085Stim szeto }
194*8fe96085Stim szeto 
195*8fe96085Stim szeto /*
196fcf3ce44SJohn Forte  * initializeConfig
197fcf3ce44SJohn Forte  *
198fcf3ce44SJohn Forte  * This routine should be called before any ioctl requiring initialization
199fcf3ce44SJohn Forte  * which is basically everything except stmfGetState(), setStmfState() and
200fcf3ce44SJohn Forte  * stmfLoadConfig().
201fcf3ce44SJohn Forte  */
202fcf3ce44SJohn Forte static int
203fcf3ce44SJohn Forte initializeConfig()
204fcf3ce44SJohn Forte {
205fcf3ce44SJohn Forte 	int ret;
206fcf3ce44SJohn Forte 	stmfState state;
207fcf3ce44SJohn Forte 
208fcf3ce44SJohn Forte 
209fcf3ce44SJohn Forte 	ret = stmfGetState(&state);
210fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
211fcf3ce44SJohn Forte 		return (ret);
212fcf3ce44SJohn Forte 	}
213fcf3ce44SJohn Forte 
214fcf3ce44SJohn Forte 	/* if we've already initialized or in the process, return success */
215fcf3ce44SJohn Forte 	if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
216fcf3ce44SJohn Forte 	    state.configState == STMF_CONFIG_STATE_INIT) {
217fcf3ce44SJohn Forte 		return (STMF_STATUS_SUCCESS);
218fcf3ce44SJohn Forte 	}
219fcf3ce44SJohn Forte 
220fcf3ce44SJohn Forte 	ret = stmfLoadConfig();
221fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
222fcf3ce44SJohn Forte 		syslog(LOG_DEBUG,
223fcf3ce44SJohn Forte 		    "initializeConfig:stmfLoadConfig:error(%d)", ret);
224fcf3ce44SJohn Forte 		return (ret);
225fcf3ce44SJohn Forte 	}
226fcf3ce44SJohn Forte 
227fcf3ce44SJohn Forte 	ret = stmfGetState(&state);
228fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
229fcf3ce44SJohn Forte 		syslog(LOG_DEBUG,
230fcf3ce44SJohn Forte 		    "initializeConfig:stmfGetState:error(%d)", ret);
231fcf3ce44SJohn Forte 		return (ret);
232fcf3ce44SJohn Forte 	}
233fcf3ce44SJohn Forte 
234fcf3ce44SJohn Forte 	if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
235fcf3ce44SJohn Forte 		syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
236fcf3ce44SJohn Forte 		    state.configState);
237fcf3ce44SJohn Forte 		ret = STMF_STATUS_ERROR;
238fcf3ce44SJohn Forte 	}
239fcf3ce44SJohn Forte 
240fcf3ce44SJohn Forte 	return (ret);
241fcf3ce44SJohn Forte }
242fcf3ce44SJohn Forte 
243fcf3ce44SJohn Forte 
244fcf3ce44SJohn Forte /*
245fcf3ce44SJohn Forte  * groupIoctl
246fcf3ce44SJohn Forte  *
247fcf3ce44SJohn Forte  * Purpose: issue ioctl for create/delete on group
248fcf3ce44SJohn Forte  *
249fcf3ce44SJohn Forte  * cmd - valid STMF ioctl group cmd
250fcf3ce44SJohn Forte  * groupName - groupName to create or delete
251fcf3ce44SJohn Forte  */
252fcf3ce44SJohn Forte static int
253fcf3ce44SJohn Forte groupIoctl(int fd, int cmd, stmfGroupName *groupName)
254fcf3ce44SJohn Forte {
255fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
256fcf3ce44SJohn Forte 	int ioctlRet;
257fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
258fcf3ce44SJohn Forte 	stmf_group_name_t iGroupName;
259fcf3ce44SJohn Forte 
260fcf3ce44SJohn Forte 	bzero(&iGroupName, sizeof (iGroupName));
261fcf3ce44SJohn Forte 
262fcf3ce44SJohn Forte 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
263fcf3ce44SJohn Forte 
264fcf3ce44SJohn Forte 	iGroupName.name_size = strlen((char *)groupName);
265fcf3ce44SJohn Forte 
266fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
267fcf3ce44SJohn Forte 	/*
268fcf3ce44SJohn Forte 	 * Issue ioctl to create the host group
269fcf3ce44SJohn Forte 	 */
270fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
271fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
272fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
273fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
274fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
275fcf3ce44SJohn Forte 		switch (errno) {
276*8fe96085Stim szeto 			case EPERM:
277fcf3ce44SJohn Forte 			case EACCES:
278fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
279fcf3ce44SJohn Forte 				break;
280fcf3ce44SJohn Forte 			default:
281fcf3ce44SJohn Forte 				switch (stmfIoctl.stmf_error) {
282fcf3ce44SJohn Forte 					case STMF_IOCERR_TG_EXISTS:
283fcf3ce44SJohn Forte 					case STMF_IOCERR_HG_EXISTS:
284fcf3ce44SJohn Forte 						ret = STMF_ERROR_EXISTS;
285fcf3ce44SJohn Forte 						break;
286fcf3ce44SJohn Forte 					case STMF_IOCERR_TG_IN_USE:
287fcf3ce44SJohn Forte 					case STMF_IOCERR_HG_IN_USE:
288fcf3ce44SJohn Forte 						ret = STMF_ERROR_GROUP_IN_USE;
289fcf3ce44SJohn Forte 						break;
290fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_HG:
291fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_TG:
292fcf3ce44SJohn Forte 						ret = STMF_ERROR_NOT_FOUND;
293fcf3ce44SJohn Forte 						break;
294fcf3ce44SJohn Forte 					default:
295fcf3ce44SJohn Forte 						syslog(LOG_DEBUG,
296fcf3ce44SJohn Forte 						    "groupIoctl:error(%d)",
297fcf3ce44SJohn Forte 						    stmfIoctl.stmf_error);
298fcf3ce44SJohn Forte 						ret = STMF_STATUS_ERROR;
299fcf3ce44SJohn Forte 						break;
300fcf3ce44SJohn Forte 				}
301fcf3ce44SJohn Forte 				break;
302fcf3ce44SJohn Forte 		}
303fcf3ce44SJohn Forte 	}
304fcf3ce44SJohn Forte done:
305fcf3ce44SJohn Forte 	return (ret);
306fcf3ce44SJohn Forte }
307fcf3ce44SJohn Forte 
308fcf3ce44SJohn Forte /*
309*8fe96085Stim szeto  * groupMemberIoctl
310fcf3ce44SJohn Forte  *
311fcf3ce44SJohn Forte  * Purpose: issue ioctl for add/remove member on group
312fcf3ce44SJohn Forte  *
313fcf3ce44SJohn Forte  * cmd - valid STMF ioctl group member cmd
314fcf3ce44SJohn Forte  * groupName - groupName to add to or remove from
315fcf3ce44SJohn Forte  * devid - group member to add or remove
316fcf3ce44SJohn Forte  */
317fcf3ce44SJohn Forte static int
318fcf3ce44SJohn Forte groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
319fcf3ce44SJohn Forte {
320fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
321fcf3ce44SJohn Forte 	int ioctlRet;
322fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
323fcf3ce44SJohn Forte 	stmf_group_op_data_t stmfGroupData;
324fcf3ce44SJohn Forte 
325fcf3ce44SJohn Forte 	bzero(&stmfGroupData, sizeof (stmfGroupData));
326fcf3ce44SJohn Forte 
327fcf3ce44SJohn Forte 	bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
328fcf3ce44SJohn Forte 
329fcf3ce44SJohn Forte 	stmfGroupData.group.name_size = strlen((char *)groupName);
330fcf3ce44SJohn Forte 	stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
331fcf3ce44SJohn Forte 	bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
332fcf3ce44SJohn Forte 	    devid->identLength);
333fcf3ce44SJohn Forte 
334fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
335fcf3ce44SJohn Forte 	/*
336fcf3ce44SJohn Forte 	 * Issue ioctl to add to the host group
337fcf3ce44SJohn Forte 	 */
338fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
339fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
340fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
341fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
342fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
343fcf3ce44SJohn Forte 		switch (errno) {
344fcf3ce44SJohn Forte 			case EBUSY:
345fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
346fcf3ce44SJohn Forte 				break;
347*8fe96085Stim szeto 			case EPERM:
348fcf3ce44SJohn Forte 			case EACCES:
349fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
350fcf3ce44SJohn Forte 				break;
351fcf3ce44SJohn Forte 			default:
352fcf3ce44SJohn Forte 				switch (stmfIoctl.stmf_error) {
353fcf3ce44SJohn Forte 					case STMF_IOCERR_TG_ENTRY_EXISTS:
354fcf3ce44SJohn Forte 					case STMF_IOCERR_HG_ENTRY_EXISTS:
355fcf3ce44SJohn Forte 						ret = STMF_ERROR_EXISTS;
356fcf3ce44SJohn Forte 						break;
357fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_TG_ENTRY:
358fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_HG_ENTRY:
359fcf3ce44SJohn Forte 						ret =
360fcf3ce44SJohn Forte 						    STMF_ERROR_MEMBER_NOT_FOUND;
361fcf3ce44SJohn Forte 						break;
362fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_TG:
363fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_HG:
364fcf3ce44SJohn Forte 						ret =
365fcf3ce44SJohn Forte 						    STMF_ERROR_GROUP_NOT_FOUND;
366fcf3ce44SJohn Forte 						break;
367fcf3ce44SJohn Forte 					default:
368fcf3ce44SJohn Forte 						syslog(LOG_DEBUG,
369fcf3ce44SJohn Forte 						    "groupMemberIoctl:error"
370fcf3ce44SJohn Forte 						    "(%d)",
371fcf3ce44SJohn Forte 						    stmfIoctl.stmf_error);
372fcf3ce44SJohn Forte 						ret = STMF_STATUS_ERROR;
373fcf3ce44SJohn Forte 						break;
374fcf3ce44SJohn Forte 				}
375fcf3ce44SJohn Forte 				break;
376fcf3ce44SJohn Forte 		}
377fcf3ce44SJohn Forte 	}
378fcf3ce44SJohn Forte done:
379fcf3ce44SJohn Forte 	return (ret);
380fcf3ce44SJohn Forte }
381fcf3ce44SJohn Forte 
382fcf3ce44SJohn Forte /*
383*8fe96085Stim szeto  * qsort function
384*8fe96085Stim szeto  * sort on veIndex
385*8fe96085Stim szeto  */
386*8fe96085Stim szeto static int
387*8fe96085Stim szeto viewEntryCompare(const void *p1, const void *p2)
388*8fe96085Stim szeto {
389*8fe96085Stim szeto 
390*8fe96085Stim szeto 	stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
391*8fe96085Stim szeto 	if (v1->veIndex > v2->veIndex)
392*8fe96085Stim szeto 		return (1);
393*8fe96085Stim szeto 	if (v1->veIndex < v2->veIndex)
394*8fe96085Stim szeto 		return (-1);
395*8fe96085Stim szeto 	return (0);
396*8fe96085Stim szeto }
397*8fe96085Stim szeto 
398*8fe96085Stim szeto /*
399fcf3ce44SJohn Forte  * guidCompare
400fcf3ce44SJohn Forte  *
401fcf3ce44SJohn Forte  * qsort function
402fcf3ce44SJohn Forte  * sort on guid
403fcf3ce44SJohn Forte  */
404fcf3ce44SJohn Forte static int
405fcf3ce44SJohn Forte guidCompare(const void *p1, const void *p2)
406fcf3ce44SJohn Forte {
407fcf3ce44SJohn Forte 
408fcf3ce44SJohn Forte 	stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
409fcf3ce44SJohn Forte 	int i;
410fcf3ce44SJohn Forte 
411fcf3ce44SJohn Forte 	for (i = 0; i < sizeof (stmfGuid); i++) {
412fcf3ce44SJohn Forte 		if (g1->guid[i] > g2->guid[i])
413fcf3ce44SJohn Forte 			return (1);
414fcf3ce44SJohn Forte 		if (g1->guid[i] < g2->guid[i])
415fcf3ce44SJohn Forte 			return (-1);
416fcf3ce44SJohn Forte 	}
417fcf3ce44SJohn Forte 
418fcf3ce44SJohn Forte 	return (0);
419fcf3ce44SJohn Forte }
420fcf3ce44SJohn Forte 
421fcf3ce44SJohn Forte /*
422fcf3ce44SJohn Forte  * stmfAddToHostGroup
423fcf3ce44SJohn Forte  *
424fcf3ce44SJohn Forte  * Purpose: Adds an initiator to an existing host group
425fcf3ce44SJohn Forte  *
426fcf3ce44SJohn Forte  * hostGroupName - name of an existing host group
427fcf3ce44SJohn Forte  * hostName - name of initiator to add
428fcf3ce44SJohn Forte  */
429fcf3ce44SJohn Forte int
430fcf3ce44SJohn Forte stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
431fcf3ce44SJohn Forte {
432fcf3ce44SJohn Forte 	int ret;
433fcf3ce44SJohn Forte 	int fd;
434fcf3ce44SJohn Forte 
435fcf3ce44SJohn Forte 	if (hostGroupName == NULL ||
436fcf3ce44SJohn Forte 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
437fcf3ce44SJohn Forte 	    == sizeof (stmfGroupName)) || hostName == NULL) {
438fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
439fcf3ce44SJohn Forte 	}
440fcf3ce44SJohn Forte 
441fcf3ce44SJohn Forte 	/* call init */
442fcf3ce44SJohn Forte 	ret = initializeConfig();
443fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
444fcf3ce44SJohn Forte 		return (ret);
445fcf3ce44SJohn Forte 	}
446fcf3ce44SJohn Forte 
447fcf3ce44SJohn Forte 	/*
448fcf3ce44SJohn Forte 	 * Open control node for stmf
449fcf3ce44SJohn Forte 	 */
450fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
451fcf3ce44SJohn Forte 		return (ret);
452fcf3ce44SJohn Forte 
453fcf3ce44SJohn Forte 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
454fcf3ce44SJohn Forte 	    hostName)) != STMF_STATUS_SUCCESS) {
455fcf3ce44SJohn Forte 		goto done;
456fcf3ce44SJohn Forte 	}
457fcf3ce44SJohn Forte 
458*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
459*8fe96085Stim szeto 		goto done;
460*8fe96085Stim szeto 	}
461*8fe96085Stim szeto 
462fcf3ce44SJohn Forte 	ret = psAddHostGroupMember((char *)hostGroupName,
463fcf3ce44SJohn Forte 	    (char *)hostName->ident);
464fcf3ce44SJohn Forte 	switch (ret) {
465fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
466fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
467fcf3ce44SJohn Forte 			break;
468fcf3ce44SJohn Forte 		case STMF_PS_ERROR_EXISTS:
469fcf3ce44SJohn Forte 			ret = STMF_ERROR_EXISTS;
470fcf3ce44SJohn Forte 			break;
471fcf3ce44SJohn Forte 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
472fcf3ce44SJohn Forte 			ret = STMF_ERROR_GROUP_NOT_FOUND;
473fcf3ce44SJohn Forte 			break;
474fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
475fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
476fcf3ce44SJohn Forte 			break;
477fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
478fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
479fcf3ce44SJohn Forte 			break;
480fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
481fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
482fcf3ce44SJohn Forte 			break;
483fcf3ce44SJohn Forte 		default:
484fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
485fcf3ce44SJohn Forte 			    "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
486fcf3ce44SJohn Forte 			    ret);
487fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
488fcf3ce44SJohn Forte 			break;
489fcf3ce44SJohn Forte 	}
490fcf3ce44SJohn Forte 
491fcf3ce44SJohn Forte done:
492fcf3ce44SJohn Forte 	(void) close(fd);
493fcf3ce44SJohn Forte 	return (ret);
494fcf3ce44SJohn Forte }
495fcf3ce44SJohn Forte 
496fcf3ce44SJohn Forte /*
497fcf3ce44SJohn Forte  * stmfAddToTargetGroup
498fcf3ce44SJohn Forte  *
499fcf3ce44SJohn Forte  * Purpose: Adds a local port to an existing target group
500fcf3ce44SJohn Forte  *
501fcf3ce44SJohn Forte  * targetGroupName - name of an existing target group
502fcf3ce44SJohn Forte  * targetName - name of target to add
503fcf3ce44SJohn Forte  */
504fcf3ce44SJohn Forte int
505fcf3ce44SJohn Forte stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
506fcf3ce44SJohn Forte {
507fcf3ce44SJohn Forte 	int ret;
508fcf3ce44SJohn Forte 	int fd;
509fcf3ce44SJohn Forte 	stmfState state;
510fcf3ce44SJohn Forte 
511fcf3ce44SJohn Forte 	if (targetGroupName == NULL ||
512fcf3ce44SJohn Forte 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
513fcf3ce44SJohn Forte 	    == sizeof (stmfGroupName)) || targetName == NULL) {
514fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
515fcf3ce44SJohn Forte 	}
516fcf3ce44SJohn Forte 
517fcf3ce44SJohn Forte 	ret = stmfGetState(&state);
518fcf3ce44SJohn Forte 	if (ret == STMF_STATUS_SUCCESS) {
519fcf3ce44SJohn Forte 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
520fcf3ce44SJohn Forte 			return (STMF_ERROR_SERVICE_ONLINE);
521fcf3ce44SJohn Forte 		}
522fcf3ce44SJohn Forte 	} else {
523fcf3ce44SJohn Forte 		return (STMF_STATUS_ERROR);
524fcf3ce44SJohn Forte 	}
525fcf3ce44SJohn Forte 
526fcf3ce44SJohn Forte 	/* call init */
527fcf3ce44SJohn Forte 	ret = initializeConfig();
528fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
529fcf3ce44SJohn Forte 		return (ret);
530fcf3ce44SJohn Forte 	}
531fcf3ce44SJohn Forte 
532fcf3ce44SJohn Forte 	/*
533fcf3ce44SJohn Forte 	 * Open control node for stmf
534fcf3ce44SJohn Forte 	 */
535fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
536fcf3ce44SJohn Forte 		return (ret);
537fcf3ce44SJohn Forte 
538fcf3ce44SJohn Forte 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
539fcf3ce44SJohn Forte 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
540fcf3ce44SJohn Forte 		goto done;
541fcf3ce44SJohn Forte 	}
542fcf3ce44SJohn Forte 
543*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
544*8fe96085Stim szeto 		goto done;
545*8fe96085Stim szeto 	}
546*8fe96085Stim szeto 
547fcf3ce44SJohn Forte 	ret = psAddTargetGroupMember((char *)targetGroupName,
548fcf3ce44SJohn Forte 	    (char *)targetName->ident);
549fcf3ce44SJohn Forte 	switch (ret) {
550fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
551fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
552fcf3ce44SJohn Forte 			break;
553fcf3ce44SJohn Forte 		case STMF_PS_ERROR_EXISTS:
554fcf3ce44SJohn Forte 			ret = STMF_ERROR_EXISTS;
555fcf3ce44SJohn Forte 			break;
556fcf3ce44SJohn Forte 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
557fcf3ce44SJohn Forte 			ret = STMF_ERROR_GROUP_NOT_FOUND;
558fcf3ce44SJohn Forte 			break;
559fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
560fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
561fcf3ce44SJohn Forte 			break;
562fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
563fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
564fcf3ce44SJohn Forte 			break;
565fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
566fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
567fcf3ce44SJohn Forte 			break;
568fcf3ce44SJohn Forte 		default:
569fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
570fcf3ce44SJohn Forte 			    "stmfAddToTargetGroup:psAddTargetGroupMember:"
571fcf3ce44SJohn Forte 			    "error(%d)", ret);
572fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
573fcf3ce44SJohn Forte 			break;
574fcf3ce44SJohn Forte 	}
575fcf3ce44SJohn Forte 
576fcf3ce44SJohn Forte done:
577fcf3ce44SJohn Forte 	(void) close(fd);
578fcf3ce44SJohn Forte 	return (ret);
579fcf3ce44SJohn Forte }
580fcf3ce44SJohn Forte 
581fcf3ce44SJohn Forte /*
582fcf3ce44SJohn Forte  * addViewEntryIoctl
583fcf3ce44SJohn Forte  *
584fcf3ce44SJohn Forte  * Purpose: Issues ioctl to add a view entry
585fcf3ce44SJohn Forte  *
586fcf3ce44SJohn Forte  * lu - Logical Unit identifier to which the view entry is added
587fcf3ce44SJohn Forte  * viewEntry - view entry to add
588fcf3ce44SJohn Forte  * init - When set to B_TRUE, we are in the init state, i.e. don't call open
589fcf3ce44SJohn Forte  */
590fcf3ce44SJohn Forte static int
591fcf3ce44SJohn Forte addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
592fcf3ce44SJohn Forte {
593fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
594fcf3ce44SJohn Forte 	int ioctlRet;
595fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
596fcf3ce44SJohn Forte 	stmf_view_op_entry_t ioctlViewEntry;
597fcf3ce44SJohn Forte 
598fcf3ce44SJohn Forte 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
599fcf3ce44SJohn Forte 	/*
600fcf3ce44SJohn Forte 	 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
601fcf3ce44SJohn Forte 	 * false on input
602fcf3ce44SJohn Forte 	 */
603fcf3ce44SJohn Forte 	ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
604fcf3ce44SJohn Forte 	ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
605fcf3ce44SJohn Forte 	ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
606fcf3ce44SJohn Forte 
607fcf3ce44SJohn Forte 	if (viewEntry->allHosts == B_FALSE) {
608fcf3ce44SJohn Forte 		bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
609fcf3ce44SJohn Forte 		    sizeof (stmfGroupName));
610fcf3ce44SJohn Forte 		ioctlViewEntry.ve_host_group.name_size =
611fcf3ce44SJohn Forte 		    strlen((char *)viewEntry->hostGroup);
612fcf3ce44SJohn Forte 	}
613fcf3ce44SJohn Forte 	if (viewEntry->allTargets == B_FALSE) {
614fcf3ce44SJohn Forte 		bcopy(viewEntry->targetGroup,
615fcf3ce44SJohn Forte 		    &ioctlViewEntry.ve_target_group.name,
616fcf3ce44SJohn Forte 		    sizeof (stmfGroupName));
617fcf3ce44SJohn Forte 		ioctlViewEntry.ve_target_group.name_size =
618fcf3ce44SJohn Forte 		    strlen((char *)viewEntry->targetGroup);
619fcf3ce44SJohn Forte 	}
620fcf3ce44SJohn Forte 	if (viewEntry->luNbrValid) {
621fcf3ce44SJohn Forte 		bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
622fcf3ce44SJohn Forte 		    sizeof (ioctlViewEntry.ve_lu_nbr));
623fcf3ce44SJohn Forte 	}
624fcf3ce44SJohn Forte 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
625fcf3ce44SJohn Forte 
626fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
627fcf3ce44SJohn Forte 	/*
628fcf3ce44SJohn Forte 	 * Issue ioctl to add to the view entry
629fcf3ce44SJohn Forte 	 */
630fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
631fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
632fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
633fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
634fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
635fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
636fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
637fcf3ce44SJohn Forte 		switch (errno) {
638fcf3ce44SJohn Forte 			case EBUSY:
639fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
640fcf3ce44SJohn Forte 				break;
641*8fe96085Stim szeto 			case EPERM:
642*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
643*8fe96085Stim szeto 				break;
644fcf3ce44SJohn Forte 			case EACCES:
645fcf3ce44SJohn Forte 				switch (stmfIoctl.stmf_error) {
646fcf3ce44SJohn Forte 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
647fcf3ce44SJohn Forte 						ret = STMF_ERROR_CONFIG_NONE;
648fcf3ce44SJohn Forte 						break;
649fcf3ce44SJohn Forte 					default:
650fcf3ce44SJohn Forte 						ret = STMF_ERROR_PERM;
651fcf3ce44SJohn Forte 						break;
652fcf3ce44SJohn Forte 				}
653fcf3ce44SJohn Forte 				break;
654fcf3ce44SJohn Forte 			default:
655fcf3ce44SJohn Forte 				switch (stmfIoctl.stmf_error) {
656fcf3ce44SJohn Forte 					case STMF_IOCERR_LU_NUMBER_IN_USE:
657fcf3ce44SJohn Forte 						ret = STMF_ERROR_LUN_IN_USE;
658fcf3ce44SJohn Forte 						break;
659fcf3ce44SJohn Forte 					case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
660fcf3ce44SJohn Forte 						ret = STMF_ERROR_VE_CONFLICT;
661fcf3ce44SJohn Forte 						break;
662fcf3ce44SJohn Forte 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
663fcf3ce44SJohn Forte 						ret = STMF_ERROR_CONFIG_NONE;
664fcf3ce44SJohn Forte 						break;
665fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_HG:
666fcf3ce44SJohn Forte 						ret = STMF_ERROR_INVALID_HG;
667fcf3ce44SJohn Forte 						break;
668fcf3ce44SJohn Forte 					case STMF_IOCERR_INVALID_TG:
669fcf3ce44SJohn Forte 						ret = STMF_ERROR_INVALID_TG;
670fcf3ce44SJohn Forte 						break;
671fcf3ce44SJohn Forte 					default:
672fcf3ce44SJohn Forte 						syslog(LOG_DEBUG,
673fcf3ce44SJohn Forte 						    "addViewEntryIoctl"
674fcf3ce44SJohn Forte 						    ":error(%d)",
675fcf3ce44SJohn Forte 						    stmfIoctl.stmf_error);
676fcf3ce44SJohn Forte 						ret = STMF_STATUS_ERROR;
677fcf3ce44SJohn Forte 						break;
678fcf3ce44SJohn Forte 				}
679fcf3ce44SJohn Forte 				break;
680fcf3ce44SJohn Forte 		}
681fcf3ce44SJohn Forte 		goto done;
682fcf3ce44SJohn Forte 	}
683fcf3ce44SJohn Forte 
684fcf3ce44SJohn Forte 	/* copy lu nbr back to caller's view entry on success */
685fcf3ce44SJohn Forte 	viewEntry->veIndex = ioctlViewEntry.ve_ndx;
686fcf3ce44SJohn Forte 	if (ioctlViewEntry.ve_lu_number_valid) {
687fcf3ce44SJohn Forte 		bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
688fcf3ce44SJohn Forte 		    sizeof (ioctlViewEntry.ve_lu_nbr));
689fcf3ce44SJohn Forte 	}
690fcf3ce44SJohn Forte 	viewEntry->luNbrValid = B_TRUE;
691fcf3ce44SJohn Forte 
692fcf3ce44SJohn Forte done:
693fcf3ce44SJohn Forte 	return (ret);
694fcf3ce44SJohn Forte }
695fcf3ce44SJohn Forte 
696fcf3ce44SJohn Forte /*
697fcf3ce44SJohn Forte  * stmfAddViewEntry
698fcf3ce44SJohn Forte  *
699fcf3ce44SJohn Forte  * Purpose: Adds a view entry to a logical unit
700fcf3ce44SJohn Forte  *
701fcf3ce44SJohn Forte  * lu - guid of the logical unit to which the view entry is added
702fcf3ce44SJohn Forte  * viewEntry - view entry structure to add
703fcf3ce44SJohn Forte  */
704fcf3ce44SJohn Forte int
705fcf3ce44SJohn Forte stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
706fcf3ce44SJohn Forte {
707fcf3ce44SJohn Forte 	int ret;
708fcf3ce44SJohn Forte 	int fd;
709fcf3ce44SJohn Forte 	stmfViewEntry iViewEntry;
710fcf3ce44SJohn Forte 
711fcf3ce44SJohn Forte 	if (lu == NULL || viewEntry == NULL) {
712fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
713fcf3ce44SJohn Forte 	}
714fcf3ce44SJohn Forte 
715fcf3ce44SJohn Forte 	/* initialize and set internal view entry */
716fcf3ce44SJohn Forte 	bzero(&iViewEntry, sizeof (iViewEntry));
717fcf3ce44SJohn Forte 
718fcf3ce44SJohn Forte 	if (!viewEntry->allHosts) {
719fcf3ce44SJohn Forte 		bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
720fcf3ce44SJohn Forte 		    sizeof (iViewEntry.hostGroup));
721fcf3ce44SJohn Forte 	} else {
722fcf3ce44SJohn Forte 		iViewEntry.allHosts = B_TRUE;
723fcf3ce44SJohn Forte 	}
724fcf3ce44SJohn Forte 
725fcf3ce44SJohn Forte 	if (!viewEntry->allTargets) {
726fcf3ce44SJohn Forte 		bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
727fcf3ce44SJohn Forte 		    sizeof (iViewEntry.targetGroup));
728fcf3ce44SJohn Forte 	} else {
729fcf3ce44SJohn Forte 		iViewEntry.allTargets = B_TRUE;
730fcf3ce44SJohn Forte 	}
731fcf3ce44SJohn Forte 
732fcf3ce44SJohn Forte 	if (viewEntry->luNbrValid) {
733fcf3ce44SJohn Forte 		iViewEntry.luNbrValid = B_TRUE;
734fcf3ce44SJohn Forte 		bcopy(viewEntry->luNbr, iViewEntry.luNbr,
735fcf3ce44SJohn Forte 		    sizeof (iViewEntry.luNbr));
736fcf3ce44SJohn Forte 	}
737fcf3ce44SJohn Forte 
738fcf3ce44SJohn Forte 	/*
739fcf3ce44SJohn Forte 	 * set users return view entry index valid flag to false
740fcf3ce44SJohn Forte 	 * in case of failure
741fcf3ce44SJohn Forte 	 */
742fcf3ce44SJohn Forte 	viewEntry->veIndexValid = B_FALSE;
743fcf3ce44SJohn Forte 
744fcf3ce44SJohn Forte 	/* Check to ensure service exists */
745fcf3ce44SJohn Forte 	if (psCheckService() != STMF_STATUS_SUCCESS) {
746fcf3ce44SJohn Forte 		return (STMF_ERROR_SERVICE_NOT_FOUND);
747fcf3ce44SJohn Forte 	}
748fcf3ce44SJohn Forte 
749fcf3ce44SJohn Forte 	/* call init */
750fcf3ce44SJohn Forte 	ret = initializeConfig();
751fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
752fcf3ce44SJohn Forte 		return (ret);
753fcf3ce44SJohn Forte 	}
754fcf3ce44SJohn Forte 
755fcf3ce44SJohn Forte 	/*
756fcf3ce44SJohn Forte 	 * Open control node for stmf
757fcf3ce44SJohn Forte 	 */
758fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
759fcf3ce44SJohn Forte 		return (ret);
760fcf3ce44SJohn Forte 
761fcf3ce44SJohn Forte 	/*
762fcf3ce44SJohn Forte 	 * First add the view entry to the driver
763fcf3ce44SJohn Forte 	 */
764fcf3ce44SJohn Forte 	ret = addViewEntryIoctl(fd, lu, &iViewEntry);
765fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
766fcf3ce44SJohn Forte 		goto done;
767fcf3ce44SJohn Forte 	}
768fcf3ce44SJohn Forte 
769*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
770*8fe96085Stim szeto 		goto done;
771*8fe96085Stim szeto 	}
772*8fe96085Stim szeto 
773fcf3ce44SJohn Forte 	/*
774fcf3ce44SJohn Forte 	 * If the add to driver was successful, add it to the persistent
775fcf3ce44SJohn Forte 	 * store.
776fcf3ce44SJohn Forte 	 */
777fcf3ce44SJohn Forte 	ret = psAddViewEntry(lu, &iViewEntry);
778fcf3ce44SJohn Forte 	switch (ret) {
779fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
780fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
781fcf3ce44SJohn Forte 			break;
782fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
783fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
784fcf3ce44SJohn Forte 			break;
785fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
786fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
787fcf3ce44SJohn Forte 			break;
788fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
789fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
790fcf3ce44SJohn Forte 			break;
791fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
792fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
793fcf3ce44SJohn Forte 			break;
794fcf3ce44SJohn Forte 		default:
795fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
796fcf3ce44SJohn Forte 			    "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
797fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
798fcf3ce44SJohn Forte 			break;
799fcf3ce44SJohn Forte 	}
800fcf3ce44SJohn Forte 
801fcf3ce44SJohn Forte done:
802fcf3ce44SJohn Forte 	(void) close(fd);
803fcf3ce44SJohn Forte 
804fcf3ce44SJohn Forte 	if (ret == STMF_STATUS_SUCCESS) {
805fcf3ce44SJohn Forte 		/* set caller's view entry on success */
806fcf3ce44SJohn Forte 		viewEntry->veIndexValid = iViewEntry.veIndexValid;
807fcf3ce44SJohn Forte 		viewEntry->veIndex = iViewEntry.veIndex;
808fcf3ce44SJohn Forte 		viewEntry->luNbrValid = B_TRUE;
809fcf3ce44SJohn Forte 		bcopy(iViewEntry.luNbr, viewEntry->luNbr,
810fcf3ce44SJohn Forte 		    sizeof (iViewEntry.luNbr));
811fcf3ce44SJohn Forte 	}
812fcf3ce44SJohn Forte 	return (ret);
813fcf3ce44SJohn Forte }
814fcf3ce44SJohn Forte 
815fcf3ce44SJohn Forte /*
816fcf3ce44SJohn Forte  * stmfClearProviderData
817fcf3ce44SJohn Forte  *
818fcf3ce44SJohn Forte  * Purpose: delete all provider data for specified provider
819fcf3ce44SJohn Forte  *
820fcf3ce44SJohn Forte  * providerName - name of provider for which data should be deleted
821fcf3ce44SJohn Forte  */
822fcf3ce44SJohn Forte int
823fcf3ce44SJohn Forte stmfClearProviderData(char *providerName, int providerType)
824fcf3ce44SJohn Forte {
825fcf3ce44SJohn Forte 	int ret;
826fcf3ce44SJohn Forte 	int fd;
827fcf3ce44SJohn Forte 	int ioctlRet;
828fcf3ce44SJohn Forte 	int savedErrno;
829fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
830fcf3ce44SJohn Forte 	stmf_ppioctl_data_t ppi;
831fcf3ce44SJohn Forte 
832fcf3ce44SJohn Forte 	/* call init */
833fcf3ce44SJohn Forte 	ret = initializeConfig();
834fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
835fcf3ce44SJohn Forte 		return (ret);
836fcf3ce44SJohn Forte 	}
837fcf3ce44SJohn Forte 
838fcf3ce44SJohn Forte 	if (providerName == NULL) {
839fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
840fcf3ce44SJohn Forte 	}
841fcf3ce44SJohn Forte 
842fcf3ce44SJohn Forte 	if (providerType != STMF_LU_PROVIDER_TYPE &&
843fcf3ce44SJohn Forte 	    providerType != STMF_PORT_PROVIDER_TYPE) {
844fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
845fcf3ce44SJohn Forte 	}
846fcf3ce44SJohn Forte 
847fcf3ce44SJohn Forte 	/*
848fcf3ce44SJohn Forte 	 * Open control node for stmf
849fcf3ce44SJohn Forte 	 */
850fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
851fcf3ce44SJohn Forte 		return (ret);
852fcf3ce44SJohn Forte 
853fcf3ce44SJohn Forte 	bzero(&ppi, sizeof (ppi));
854fcf3ce44SJohn Forte 
855fcf3ce44SJohn Forte 	(void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
856fcf3ce44SJohn Forte 
857fcf3ce44SJohn Forte 	switch (providerType) {
858fcf3ce44SJohn Forte 		case STMF_LU_PROVIDER_TYPE:
859fcf3ce44SJohn Forte 			ppi.ppi_lu_provider = 1;
860fcf3ce44SJohn Forte 			break;
861fcf3ce44SJohn Forte 		case STMF_PORT_PROVIDER_TYPE:
862fcf3ce44SJohn Forte 			ppi.ppi_port_provider = 1;
863fcf3ce44SJohn Forte 			break;
864fcf3ce44SJohn Forte 		default:
865fcf3ce44SJohn Forte 			ret = STMF_ERROR_INVALID_ARG;
866fcf3ce44SJohn Forte 			goto done;
867fcf3ce44SJohn Forte 	}
868fcf3ce44SJohn Forte 
869fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
870fcf3ce44SJohn Forte 
871fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
872fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
873fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
874fcf3ce44SJohn Forte 
875fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
876fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
877fcf3ce44SJohn Forte 		savedErrno = errno;
878fcf3ce44SJohn Forte 		switch (savedErrno) {
879fcf3ce44SJohn Forte 			case EBUSY:
880fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
881fcf3ce44SJohn Forte 				break;
882*8fe96085Stim szeto 			case EPERM:
883fcf3ce44SJohn Forte 			case EACCES:
884fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
885fcf3ce44SJohn Forte 				break;
886fcf3ce44SJohn Forte 			default:
887fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
888fcf3ce44SJohn Forte 				    "stmfClearProviderData:ioctl error(%d)",
889fcf3ce44SJohn Forte 				    ioctlRet);
890fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
891fcf3ce44SJohn Forte 				break;
892fcf3ce44SJohn Forte 		}
893fcf3ce44SJohn Forte 		if (savedErrno != ENOENT) {
894fcf3ce44SJohn Forte 			goto done;
895fcf3ce44SJohn Forte 		}
896fcf3ce44SJohn Forte 	}
897fcf3ce44SJohn Forte 
898*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
899*8fe96085Stim szeto 		goto done;
900*8fe96085Stim szeto 	}
901*8fe96085Stim szeto 
902fcf3ce44SJohn Forte 	ret = psClearProviderData(providerName, providerType);
903fcf3ce44SJohn Forte 	switch (ret) {
904fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
905fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
906fcf3ce44SJohn Forte 			break;
907fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
908fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
909fcf3ce44SJohn Forte 			break;
910fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
911fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
912fcf3ce44SJohn Forte 			break;
913fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
914fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
915fcf3ce44SJohn Forte 			break;
916fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
917fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
918fcf3ce44SJohn Forte 			break;
919fcf3ce44SJohn Forte 		default:
920fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
921fcf3ce44SJohn Forte 			    "stmfClearProviderData:psClearProviderData"
922fcf3ce44SJohn Forte 			    ":error(%d)", ret);
923fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
924fcf3ce44SJohn Forte 			break;
925fcf3ce44SJohn Forte 	}
926fcf3ce44SJohn Forte 
927fcf3ce44SJohn Forte done:
928fcf3ce44SJohn Forte 	(void) close(fd);
929fcf3ce44SJohn Forte 	return (ret);
930fcf3ce44SJohn Forte }
931fcf3ce44SJohn Forte 
932fcf3ce44SJohn Forte /*
933fcf3ce44SJohn Forte  * stmfCreateHostGroup
934fcf3ce44SJohn Forte  *
935fcf3ce44SJohn Forte  * Purpose: Create a new initiator group
936fcf3ce44SJohn Forte  *
937fcf3ce44SJohn Forte  * hostGroupName - name of host group to create
938fcf3ce44SJohn Forte  */
939fcf3ce44SJohn Forte int
940fcf3ce44SJohn Forte stmfCreateHostGroup(stmfGroupName *hostGroupName)
941fcf3ce44SJohn Forte {
942fcf3ce44SJohn Forte 	int ret;
943fcf3ce44SJohn Forte 	int fd;
944fcf3ce44SJohn Forte 
945fcf3ce44SJohn Forte 	if (hostGroupName == NULL ||
946fcf3ce44SJohn Forte 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
947fcf3ce44SJohn Forte 	    == sizeof (stmfGroupName))) {
948fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
949fcf3ce44SJohn Forte 	}
950fcf3ce44SJohn Forte 
951fcf3ce44SJohn Forte 	/* Check to ensure service exists */
952fcf3ce44SJohn Forte 	if (psCheckService() != STMF_STATUS_SUCCESS) {
953fcf3ce44SJohn Forte 		return (STMF_ERROR_SERVICE_NOT_FOUND);
954fcf3ce44SJohn Forte 	}
955fcf3ce44SJohn Forte 
956fcf3ce44SJohn Forte 	/* call init */
957fcf3ce44SJohn Forte 	ret = initializeConfig();
958fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
959fcf3ce44SJohn Forte 		return (ret);
960fcf3ce44SJohn Forte 	}
961fcf3ce44SJohn Forte 
962fcf3ce44SJohn Forte 	/*
963fcf3ce44SJohn Forte 	 * Open control node for stmf
964fcf3ce44SJohn Forte 	 */
965fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
966fcf3ce44SJohn Forte 		return (ret);
967fcf3ce44SJohn Forte 
968fcf3ce44SJohn Forte 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
969fcf3ce44SJohn Forte 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
970fcf3ce44SJohn Forte 		goto done;
971fcf3ce44SJohn Forte 	}
972fcf3ce44SJohn Forte 
973*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
974*8fe96085Stim szeto 		goto done;
975*8fe96085Stim szeto 	}
976*8fe96085Stim szeto 
977fcf3ce44SJohn Forte 	ret = psCreateHostGroup((char *)hostGroupName);
978fcf3ce44SJohn Forte 	switch (ret) {
979fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
980fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
981fcf3ce44SJohn Forte 			break;
982fcf3ce44SJohn Forte 		case STMF_PS_ERROR_EXISTS:
983fcf3ce44SJohn Forte 			ret = STMF_ERROR_EXISTS;
984fcf3ce44SJohn Forte 			break;
985fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
986fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
987fcf3ce44SJohn Forte 			break;
988fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
989fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
990fcf3ce44SJohn Forte 			break;
991fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
992fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
993fcf3ce44SJohn Forte 			break;
994fcf3ce44SJohn Forte 		default:
995fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
996fcf3ce44SJohn Forte 			    "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
997fcf3ce44SJohn Forte 			    ret);
998fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
999fcf3ce44SJohn Forte 			break;
1000fcf3ce44SJohn Forte 	}
1001fcf3ce44SJohn Forte 
1002fcf3ce44SJohn Forte done:
1003fcf3ce44SJohn Forte 	(void) close(fd);
1004fcf3ce44SJohn Forte 	return (ret);
1005fcf3ce44SJohn Forte }
1006fcf3ce44SJohn Forte 
1007fcf3ce44SJohn Forte /*
1008*8fe96085Stim szeto  * stmfCreateLu
1009*8fe96085Stim szeto  *
1010*8fe96085Stim szeto  * Purpose: Create a logical unit
1011*8fe96085Stim szeto  *
1012*8fe96085Stim szeto  * hdl - handle to logical unit resource created via stmfCreateLuResource
1013*8fe96085Stim szeto  *
1014*8fe96085Stim szeto  * luGuid - If non-NULL, on success, contains the guid of the created logical
1015*8fe96085Stim szeto  *	    unit
1016*8fe96085Stim szeto  */
1017*8fe96085Stim szeto int
1018*8fe96085Stim szeto stmfCreateLu(luResource hdl, stmfGuid *luGuid)
1019*8fe96085Stim szeto {
1020*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1021*8fe96085Stim szeto 	luResourceImpl *luPropsHdl = hdl;
1022*8fe96085Stim szeto 
1023*8fe96085Stim szeto 	if (hdl == NULL) {
1024*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1025*8fe96085Stim szeto 	}
1026*8fe96085Stim szeto 
1027*8fe96085Stim szeto 	if (luPropsHdl->type == STMF_DISK) {
1028*8fe96085Stim szeto 		ret = createDiskLu((diskResource *)luPropsHdl->resource,
1029*8fe96085Stim szeto 		    luGuid);
1030*8fe96085Stim szeto 	} else {
1031*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1032*8fe96085Stim szeto 	}
1033*8fe96085Stim szeto 
1034*8fe96085Stim szeto 	return (ret);
1035*8fe96085Stim szeto }
1036*8fe96085Stim szeto 
1037*8fe96085Stim szeto /*
1038*8fe96085Stim szeto  * stmfCreateLuResource
1039*8fe96085Stim szeto  *
1040*8fe96085Stim szeto  * Purpose: Create resource handle for a logical unit
1041*8fe96085Stim szeto  *
1042*8fe96085Stim szeto  * dType - Type of logical unit resource to create
1043*8fe96085Stim szeto  *	   Can be: STMF_DISK
1044*8fe96085Stim szeto  *
1045*8fe96085Stim szeto  * hdl - pointer to luResource
1046*8fe96085Stim szeto  */
1047*8fe96085Stim szeto int
1048*8fe96085Stim szeto stmfCreateLuResource(uint16_t dType, luResource *hdl)
1049*8fe96085Stim szeto {
1050*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1051*8fe96085Stim szeto 
1052*8fe96085Stim szeto 	if (dType != STMF_DISK || hdl == NULL) {
1053*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1054*8fe96085Stim szeto 	}
1055*8fe96085Stim szeto 
1056*8fe96085Stim szeto 	*hdl = calloc(1, sizeof (luResourceImpl));
1057*8fe96085Stim szeto 	if (*hdl == NULL) {
1058*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
1059*8fe96085Stim szeto 	}
1060*8fe96085Stim szeto 
1061*8fe96085Stim szeto 	ret = createDiskResource((luResourceImpl *)*hdl);
1062*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1063*8fe96085Stim szeto 		free(*hdl);
1064*8fe96085Stim szeto 		return (ret);
1065*8fe96085Stim szeto 	}
1066*8fe96085Stim szeto 
1067*8fe96085Stim szeto 	return (STMF_STATUS_SUCCESS);
1068*8fe96085Stim szeto }
1069*8fe96085Stim szeto 
1070*8fe96085Stim szeto /*
1071*8fe96085Stim szeto  * Creates a disk logical unit
1072*8fe96085Stim szeto  *
1073*8fe96085Stim szeto  * disk - pointer to diskResource structure that represents the properties
1074*8fe96085Stim szeto  *        for the disk logical unit to be created.
1075*8fe96085Stim szeto  */
1076*8fe96085Stim szeto static int
1077*8fe96085Stim szeto createDiskLu(diskResource *disk, stmfGuid *createdGuid)
1078*8fe96085Stim szeto {
1079*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1080*8fe96085Stim szeto 	int dataFileNameLen = 0;
1081*8fe96085Stim szeto 	int metaFileNameLen = 0;
1082*8fe96085Stim szeto 	int serialNumLen = 0;
1083*8fe96085Stim szeto 	int luAliasLen = 0;
1084*8fe96085Stim szeto 	int sluBufSize = 0;
1085*8fe96085Stim szeto 	int bufOffset = 0;
1086*8fe96085Stim szeto 	int fd = 0;
1087*8fe96085Stim szeto 	int ioctlRet;
1088*8fe96085Stim szeto 	int savedErrno;
1089*8fe96085Stim szeto 	stmfGuid guid;
1090*8fe96085Stim szeto 	stmf_iocdata_t sbdIoctl = {0};
1091*8fe96085Stim szeto 
1092*8fe96085Stim szeto 	sbd_create_and_reg_lu_t *sbdLu = NULL;
1093*8fe96085Stim szeto 
1094*8fe96085Stim szeto 	/*
1095*8fe96085Stim szeto 	 * Open control node for sbd
1096*8fe96085Stim szeto 	 */
1097*8fe96085Stim szeto 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1098*8fe96085Stim szeto 		return (ret);
1099*8fe96085Stim szeto 
1100*8fe96085Stim szeto 	/* data file name must be specified */
1101*8fe96085Stim szeto 	if (disk->luDataFileNameValid) {
1102*8fe96085Stim szeto 		dataFileNameLen = strlen(disk->luDataFileName);
1103*8fe96085Stim szeto 	} else {
1104*8fe96085Stim szeto 		(void) close(fd);
1105*8fe96085Stim szeto 		return (STMF_ERROR_MISSING_PROP_VAL);
1106*8fe96085Stim szeto 	}
1107*8fe96085Stim szeto 
1108*8fe96085Stim szeto 	sluBufSize += dataFileNameLen + 1;
1109*8fe96085Stim szeto 
1110*8fe96085Stim szeto 	if (disk->luMetaFileNameValid) {
1111*8fe96085Stim szeto 		metaFileNameLen = strlen(disk->luMetaFileName);
1112*8fe96085Stim szeto 		sluBufSize += metaFileNameLen + 1;
1113*8fe96085Stim szeto 	}
1114*8fe96085Stim szeto 
1115*8fe96085Stim szeto 	serialNumLen = strlen(disk->serialNum);
1116*8fe96085Stim szeto 	sluBufSize += serialNumLen;
1117*8fe96085Stim szeto 
1118*8fe96085Stim szeto 	if (disk->luAliasValid) {
1119*8fe96085Stim szeto 		luAliasLen = strlen(disk->luAlias);
1120*8fe96085Stim szeto 		sluBufSize += luAliasLen + 1;
1121*8fe96085Stim szeto 	}
1122*8fe96085Stim szeto 
1123*8fe96085Stim szeto 	/*
1124*8fe96085Stim szeto 	 * 8 is the size of the buffer set aside for
1125*8fe96085Stim szeto 	 * concatenation of variable length fields
1126*8fe96085Stim szeto 	 */
1127*8fe96085Stim szeto 	sbdLu = (sbd_create_and_reg_lu_t *)calloc(1,
1128*8fe96085Stim szeto 	    sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8);
1129*8fe96085Stim szeto 	if (sbdLu == NULL) {
1130*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
1131*8fe96085Stim szeto 	}
1132*8fe96085Stim szeto 
1133*8fe96085Stim szeto 	sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) +
1134*8fe96085Stim szeto 	    sluBufSize - 8;
1135*8fe96085Stim szeto 
1136*8fe96085Stim szeto 	if (metaFileNameLen) {
1137*8fe96085Stim szeto 		sbdLu->slu_meta_fname_valid = 1;
1138*8fe96085Stim szeto 		sbdLu->slu_meta_fname_off = bufOffset;
1139*8fe96085Stim szeto 		bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]),
1140*8fe96085Stim szeto 		    metaFileNameLen + 1);
1141*8fe96085Stim szeto 		bufOffset += metaFileNameLen + 1;
1142*8fe96085Stim szeto 	}
1143*8fe96085Stim szeto 
1144*8fe96085Stim szeto 	bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]),
1145*8fe96085Stim szeto 	    dataFileNameLen + 1);
1146*8fe96085Stim szeto 	sbdLu->slu_data_fname_off = bufOffset;
1147*8fe96085Stim szeto 	bufOffset += dataFileNameLen + 1;
1148*8fe96085Stim szeto 
1149*8fe96085Stim szeto 	/* currently, serial # is not passed null terminated to the driver */
1150*8fe96085Stim szeto 	if (disk->serialNumValid) {
1151*8fe96085Stim szeto 		sbdLu->slu_serial_valid = 1;
1152*8fe96085Stim szeto 		sbdLu->slu_serial_off = bufOffset;
1153*8fe96085Stim szeto 		sbdLu->slu_serial_size = serialNumLen;
1154*8fe96085Stim szeto 		bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]),
1155*8fe96085Stim szeto 		    serialNumLen);
1156*8fe96085Stim szeto 		bufOffset += serialNumLen;
1157*8fe96085Stim szeto 	}
1158*8fe96085Stim szeto 
1159*8fe96085Stim szeto 	if (disk->luAliasValid) {
1160*8fe96085Stim szeto 		sbdLu->slu_alias_valid = 1;
1161*8fe96085Stim szeto 		sbdLu->slu_alias_off = bufOffset;
1162*8fe96085Stim szeto 		bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]),
1163*8fe96085Stim szeto 		    luAliasLen + 1);
1164*8fe96085Stim szeto 		bufOffset += luAliasLen + 1;
1165*8fe96085Stim szeto 	}
1166*8fe96085Stim szeto 
1167*8fe96085Stim szeto 	if (disk->luSizeValid) {
1168*8fe96085Stim szeto 		sbdLu->slu_lu_size_valid = 1;
1169*8fe96085Stim szeto 		sbdLu->slu_lu_size = disk->luSize;
1170*8fe96085Stim szeto 	}
1171*8fe96085Stim szeto 
1172*8fe96085Stim szeto 	if (disk->luGuidValid) {
1173*8fe96085Stim szeto 		sbdLu->slu_guid_valid = 1;
1174*8fe96085Stim szeto 		bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid));
1175*8fe96085Stim szeto 	}
1176*8fe96085Stim szeto 
1177*8fe96085Stim szeto 	if (disk->vidValid) {
1178*8fe96085Stim szeto 		sbdLu->slu_vid_valid = 1;
1179*8fe96085Stim szeto 		bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid));
1180*8fe96085Stim szeto 	}
1181*8fe96085Stim szeto 
1182*8fe96085Stim szeto 	if (disk->pidValid) {
1183*8fe96085Stim szeto 		sbdLu->slu_pid_valid = 1;
1184*8fe96085Stim szeto 		bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid));
1185*8fe96085Stim szeto 	}
1186*8fe96085Stim szeto 
1187*8fe96085Stim szeto 	if (disk->revValid) {
1188*8fe96085Stim szeto 		sbdLu->slu_rev_valid = 1;
1189*8fe96085Stim szeto 		bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev));
1190*8fe96085Stim szeto 	}
1191*8fe96085Stim szeto 
1192*8fe96085Stim szeto 	if (disk->companyIdValid) {
1193*8fe96085Stim szeto 		sbdLu->slu_company_id_valid = 1;
1194*8fe96085Stim szeto 		sbdLu->slu_company_id = disk->companyId;
1195*8fe96085Stim szeto 	}
1196*8fe96085Stim szeto 
1197*8fe96085Stim szeto 	if (disk->blkSizeValid) {
1198*8fe96085Stim szeto 		sbdLu->slu_blksize_valid = 1;
1199*8fe96085Stim szeto 		sbdLu->slu_blksize = disk->blkSize;
1200*8fe96085Stim szeto 	}
1201*8fe96085Stim szeto 
1202*8fe96085Stim szeto 	if (disk->writeProtectEnableValid) {
1203*8fe96085Stim szeto 		if (disk->writeProtectEnable) {
1204*8fe96085Stim szeto 			sbdLu->slu_write_protected = 1;
1205*8fe96085Stim szeto 		}
1206*8fe96085Stim szeto 	}
1207*8fe96085Stim szeto 
1208*8fe96085Stim szeto 	if (disk->writebackCacheDisableValid) {
1209*8fe96085Stim szeto 		sbdLu->slu_writeback_cache_disable_valid = 1;
1210*8fe96085Stim szeto 		if (disk->writebackCacheDisable) {
1211*8fe96085Stim szeto 			sbdLu->slu_writeback_cache_disable = 1;
1212*8fe96085Stim szeto 		}
1213*8fe96085Stim szeto 	}
1214*8fe96085Stim szeto 
1215*8fe96085Stim szeto 	sbdIoctl.stmf_version = STMF_VERSION_1;
1216*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size;
1217*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1218*8fe96085Stim szeto 	sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size;
1219*8fe96085Stim szeto 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
1220*8fe96085Stim szeto 
1221*8fe96085Stim szeto 	ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl);
1222*8fe96085Stim szeto 	if (ioctlRet != 0) {
1223*8fe96085Stim szeto 		savedErrno = errno;
1224*8fe96085Stim szeto 		switch (savedErrno) {
1225*8fe96085Stim szeto 			case EBUSY:
1226*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
1227*8fe96085Stim szeto 				break;
1228*8fe96085Stim szeto 			case EPERM:
1229*8fe96085Stim szeto 			case EACCES:
1230*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
1231*8fe96085Stim szeto 				break;
1232*8fe96085Stim szeto 			default:
1233*8fe96085Stim szeto 				diskError(sbdIoctl.stmf_error, &ret);
1234*8fe96085Stim szeto 				if (ret == STMF_STATUS_ERROR) {
1235*8fe96085Stim szeto 					syslog(LOG_DEBUG,
1236*8fe96085Stim szeto 					"createDiskLu:ioctl "
1237*8fe96085Stim szeto 					"error(%d) (%d) (%d)", ioctlRet,
1238*8fe96085Stim szeto 					    sbdIoctl.stmf_error, savedErrno);
1239*8fe96085Stim szeto 				}
1240*8fe96085Stim szeto 				break;
1241*8fe96085Stim szeto 		}
1242*8fe96085Stim szeto 	}
1243*8fe96085Stim szeto 
1244*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1245*8fe96085Stim szeto 		goto done;
1246*8fe96085Stim szeto 	}
1247*8fe96085Stim szeto 
1248*8fe96085Stim szeto 	/*
1249*8fe96085Stim szeto 	 * on success, copy the resulting guid into the caller's guid if not
1250*8fe96085Stim szeto 	 * NULL
1251*8fe96085Stim szeto 	 */
1252*8fe96085Stim szeto 	if (createdGuid) {
1253*8fe96085Stim szeto 		bcopy(sbdLu->slu_guid, createdGuid->guid,
1254*8fe96085Stim szeto 		    sizeof (sbdLu->slu_guid));
1255*8fe96085Stim szeto 	}
1256*8fe96085Stim szeto 
1257*8fe96085Stim szeto 	bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid));
1258*8fe96085Stim szeto 	if (disk->luMetaFileNameValid) {
1259*8fe96085Stim szeto 		ret = addGuidToDiskStore(&guid, disk->luMetaFileName);
1260*8fe96085Stim szeto 	} else {
1261*8fe96085Stim szeto 		ret = addGuidToDiskStore(&guid, disk->luDataFileName);
1262*8fe96085Stim szeto 	}
1263*8fe96085Stim szeto done:
1264*8fe96085Stim szeto 	free(sbdLu);
1265*8fe96085Stim szeto 	(void) close(fd);
1266*8fe96085Stim szeto 	return (ret);
1267*8fe96085Stim szeto }
1268*8fe96085Stim szeto 
1269*8fe96085Stim szeto 
1270*8fe96085Stim szeto /*
1271*8fe96085Stim szeto  * stmfImportLu
1272*8fe96085Stim szeto  *
1273*8fe96085Stim szeto  * Purpose: Import a previously created logical unit
1274*8fe96085Stim szeto  *
1275*8fe96085Stim szeto  * dType - Type of logical unit
1276*8fe96085Stim szeto  *         Can be: STMF_DISK
1277*8fe96085Stim szeto  *
1278*8fe96085Stim szeto  * luGuid - If non-NULL, on success, contains the guid of the imported logical
1279*8fe96085Stim szeto  *	    unit
1280*8fe96085Stim szeto  *
1281*8fe96085Stim szeto  * fname - A file name where the metadata resides
1282*8fe96085Stim szeto  *
1283*8fe96085Stim szeto  */
1284*8fe96085Stim szeto int
1285*8fe96085Stim szeto stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid)
1286*8fe96085Stim szeto {
1287*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1288*8fe96085Stim szeto 
1289*8fe96085Stim szeto 	if (dType == STMF_DISK) {
1290*8fe96085Stim szeto 		ret = importDiskLu(fname, luGuid);
1291*8fe96085Stim szeto 	} else {
1292*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1293*8fe96085Stim szeto 	}
1294*8fe96085Stim szeto 
1295*8fe96085Stim szeto 	return (ret);
1296*8fe96085Stim szeto }
1297*8fe96085Stim szeto 
1298*8fe96085Stim szeto /*
1299*8fe96085Stim szeto  * importDiskLu
1300*8fe96085Stim szeto  *
1301*8fe96085Stim szeto  * filename - filename to import
1302*8fe96085Stim szeto  * createdGuid - if not NULL, on success contains the imported guid
1303*8fe96085Stim szeto  *
1304*8fe96085Stim szeto  */
1305*8fe96085Stim szeto static int
1306*8fe96085Stim szeto importDiskLu(char *fname, stmfGuid *createdGuid)
1307*8fe96085Stim szeto {
1308*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1309*8fe96085Stim szeto 	int fd = 0;
1310*8fe96085Stim szeto 	int ioctlRet;
1311*8fe96085Stim szeto 	int savedErrno;
1312*8fe96085Stim szeto 	int metaFileNameLen;
1313*8fe96085Stim szeto 	stmfGuid iGuid;
1314*8fe96085Stim szeto 	int iluBufSize = 0;
1315*8fe96085Stim szeto 	sbd_import_lu_t *sbdLu = NULL;
1316*8fe96085Stim szeto 	stmf_iocdata_t sbdIoctl = {0};
1317*8fe96085Stim szeto 
1318*8fe96085Stim szeto 	if (fname == NULL) {
1319*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1320*8fe96085Stim szeto 	}
1321*8fe96085Stim szeto 
1322*8fe96085Stim szeto 	/*
1323*8fe96085Stim szeto 	 * Open control node for sbd
1324*8fe96085Stim szeto 	 */
1325*8fe96085Stim szeto 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1326*8fe96085Stim szeto 		return (ret);
1327*8fe96085Stim szeto 
1328*8fe96085Stim szeto 	metaFileNameLen = strlen(fname);
1329*8fe96085Stim szeto 	iluBufSize += metaFileNameLen + 1;
1330*8fe96085Stim szeto 
1331*8fe96085Stim szeto 	/*
1332*8fe96085Stim szeto 	 * 8 is the size of the buffer set aside for
1333*8fe96085Stim szeto 	 * concatenation of variable length fields
1334*8fe96085Stim szeto 	 */
1335*8fe96085Stim szeto 	sbdLu = (sbd_import_lu_t *)calloc(1,
1336*8fe96085Stim szeto 	    sizeof (sbd_import_lu_t) + iluBufSize - 8);
1337*8fe96085Stim szeto 	if (sbdLu == NULL) {
1338*8fe96085Stim szeto 		(void) close(fd);
1339*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
1340*8fe96085Stim szeto 	}
1341*8fe96085Stim szeto 
1342*8fe96085Stim szeto 	/*
1343*8fe96085Stim szeto 	 * Accept either a data file or meta data file.
1344*8fe96085Stim szeto 	 * sbd will do the right thing here either way.
1345*8fe96085Stim szeto 	 * i.e. if it's a data file, it assumes that the
1346*8fe96085Stim szeto 	 * meta data is shared with the data.
1347*8fe96085Stim szeto 	 */
1348*8fe96085Stim szeto 	(void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen);
1349*8fe96085Stim szeto 
1350*8fe96085Stim szeto 	sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8;
1351*8fe96085Stim szeto 
1352*8fe96085Stim szeto 	sbdIoctl.stmf_version = STMF_VERSION_1;
1353*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size;
1354*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1355*8fe96085Stim szeto 	sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size;
1356*8fe96085Stim szeto 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
1357*8fe96085Stim szeto 
1358*8fe96085Stim szeto 	ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl);
1359*8fe96085Stim szeto 	if (ioctlRet != 0) {
1360*8fe96085Stim szeto 		savedErrno = errno;
1361*8fe96085Stim szeto 		switch (savedErrno) {
1362*8fe96085Stim szeto 			case EBUSY:
1363*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
1364*8fe96085Stim szeto 				break;
1365*8fe96085Stim szeto 			case EPERM:
1366*8fe96085Stim szeto 			case EACCES:
1367*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
1368*8fe96085Stim szeto 				break;
1369*8fe96085Stim szeto 			default:
1370*8fe96085Stim szeto 				diskError(sbdIoctl.stmf_error, &ret);
1371*8fe96085Stim szeto 				if (ret == STMF_STATUS_ERROR) {
1372*8fe96085Stim szeto 					syslog(LOG_DEBUG,
1373*8fe96085Stim szeto 					"importDiskLu:ioctl "
1374*8fe96085Stim szeto 					"error(%d) (%d) (%d)", ioctlRet,
1375*8fe96085Stim szeto 					    sbdIoctl.stmf_error, savedErrno);
1376*8fe96085Stim szeto 				}
1377*8fe96085Stim szeto 				break;
1378*8fe96085Stim szeto 		}
1379*8fe96085Stim szeto 	}
1380*8fe96085Stim szeto 
1381*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1382*8fe96085Stim szeto 		goto done;
1383*8fe96085Stim szeto 	}
1384*8fe96085Stim szeto 
1385*8fe96085Stim szeto 	/*
1386*8fe96085Stim szeto 	 * on success, copy the resulting guid into the caller's guid if not
1387*8fe96085Stim szeto 	 * NULL and add it to the persistent store for sbd
1388*8fe96085Stim szeto 	 */
1389*8fe96085Stim szeto 	if (createdGuid) {
1390*8fe96085Stim szeto 		bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
1391*8fe96085Stim szeto 		    sizeof (sbdLu->ilu_ret_guid));
1392*8fe96085Stim szeto 		ret = addGuidToDiskStore(createdGuid, fname);
1393*8fe96085Stim szeto 	} else {
1394*8fe96085Stim szeto 		bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
1395*8fe96085Stim szeto 		    sizeof (sbdLu->ilu_ret_guid));
1396*8fe96085Stim szeto 		ret = addGuidToDiskStore(&iGuid, fname);
1397*8fe96085Stim szeto 	}
1398*8fe96085Stim szeto done:
1399*8fe96085Stim szeto 	free(sbdLu);
1400*8fe96085Stim szeto 	(void) close(fd);
1401*8fe96085Stim szeto 	return (ret);
1402*8fe96085Stim szeto }
1403*8fe96085Stim szeto 
1404*8fe96085Stim szeto /*
1405*8fe96085Stim szeto  * diskError
1406*8fe96085Stim szeto  *
1407*8fe96085Stim szeto  * Purpose: Translate sbd driver error
1408*8fe96085Stim szeto  */
1409*8fe96085Stim szeto static void
1410*8fe96085Stim szeto diskError(uint32_t stmfError, int *ret)
1411*8fe96085Stim szeto {
1412*8fe96085Stim szeto 	switch (stmfError) {
1413*8fe96085Stim szeto 		case SBD_RET_META_CREATION_FAILED:
1414*8fe96085Stim szeto 		case SBD_RET_ZFS_META_CREATE_FAILED:
1415*8fe96085Stim szeto 			*ret = STMF_ERROR_META_CREATION;
1416*8fe96085Stim szeto 			break;
1417*8fe96085Stim szeto 		case SBD_RET_INVALID_BLKSIZE:
1418*8fe96085Stim szeto 			*ret = STMF_ERROR_INVALID_BLKSIZE;
1419*8fe96085Stim szeto 			break;
1420*8fe96085Stim szeto 		case SBD_RET_FILE_ALREADY_REGISTERED:
1421*8fe96085Stim szeto 			*ret = STMF_ERROR_FILE_IN_USE;
1422*8fe96085Stim szeto 			break;
1423*8fe96085Stim szeto 		case SBD_RET_GUID_ALREADY_REGISTERED:
1424*8fe96085Stim szeto 			*ret = STMF_ERROR_GUID_IN_USE;
1425*8fe96085Stim szeto 			break;
1426*8fe96085Stim szeto 		case SBD_RET_META_PATH_NOT_ABSOLUTE:
1427*8fe96085Stim szeto 		case SBD_RET_META_FILE_LOOKUP_FAILED:
1428*8fe96085Stim szeto 		case SBD_RET_META_FILE_OPEN_FAILED:
1429*8fe96085Stim szeto 		case SBD_RET_META_FILE_GETATTR_FAILED:
1430*8fe96085Stim szeto 		case SBD_RET_NO_META:
1431*8fe96085Stim szeto 			*ret = STMF_ERROR_META_FILE_NAME;
1432*8fe96085Stim szeto 			break;
1433*8fe96085Stim szeto 		case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
1434*8fe96085Stim szeto 		case SBD_RET_DATA_FILE_LOOKUP_FAILED:
1435*8fe96085Stim szeto 		case SBD_RET_DATA_FILE_OPEN_FAILED:
1436*8fe96085Stim szeto 		case SBD_RET_DATA_FILE_GETATTR_FAILED:
1437*8fe96085Stim szeto 			*ret = STMF_ERROR_DATA_FILE_NAME;
1438*8fe96085Stim szeto 			break;
1439*8fe96085Stim szeto 		case SBD_RET_FILE_SIZE_ERROR:
1440*8fe96085Stim szeto 			*ret = STMF_ERROR_FILE_SIZE_INVALID;
1441*8fe96085Stim szeto 			break;
1442*8fe96085Stim szeto 		case SBD_RET_SIZE_OUT_OF_RANGE:
1443*8fe96085Stim szeto 			*ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
1444*8fe96085Stim szeto 			break;
1445*8fe96085Stim szeto 		case SBD_RET_LU_BUSY:
1446*8fe96085Stim szeto 			*ret = STMF_ERROR_LU_BUSY;
1447*8fe96085Stim szeto 			break;
1448*8fe96085Stim szeto 		case SBD_RET_WRITE_CACHE_SET_FAILED:
1449*8fe96085Stim szeto 			*ret = STMF_ERROR_WRITE_CACHE_SET;
1450*8fe96085Stim szeto 			break;
1451*8fe96085Stim szeto 		default:
1452*8fe96085Stim szeto 			*ret = STMF_STATUS_ERROR;
1453*8fe96085Stim szeto 			break;
1454*8fe96085Stim szeto 	}
1455*8fe96085Stim szeto }
1456*8fe96085Stim szeto 
1457*8fe96085Stim szeto /*
1458*8fe96085Stim szeto  * Creates a logical unit resource of type STMF_DISK.
1459*8fe96085Stim szeto  *
1460*8fe96085Stim szeto  * No defaults should be set here as all defaults are derived from the
1461*8fe96085Stim szeto  * driver's default settings.
1462*8fe96085Stim szeto  */
1463*8fe96085Stim szeto static int
1464*8fe96085Stim szeto createDiskResource(luResourceImpl *hdl)
1465*8fe96085Stim szeto {
1466*8fe96085Stim szeto 	hdl->type = STMF_DISK;
1467*8fe96085Stim szeto 
1468*8fe96085Stim szeto 	hdl->resource = calloc(1, sizeof (diskResource));
1469*8fe96085Stim szeto 	if (hdl->resource == NULL) {
1470*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
1471*8fe96085Stim szeto 	}
1472*8fe96085Stim szeto 
1473*8fe96085Stim szeto 	return (STMF_STATUS_SUCCESS);
1474*8fe96085Stim szeto }
1475*8fe96085Stim szeto 
1476*8fe96085Stim szeto /*
1477*8fe96085Stim szeto  * stmfDeleteLu
1478*8fe96085Stim szeto  *
1479*8fe96085Stim szeto  * Purpose: Delete a logical unit
1480*8fe96085Stim szeto  *
1481*8fe96085Stim szeto  * hdl - handle to logical unit resource created via stmfCreateLuResource
1482*8fe96085Stim szeto  *
1483*8fe96085Stim szeto  * luGuid - If non-NULL, on success, contains the guid of the created logical
1484*8fe96085Stim szeto  *	    unit
1485*8fe96085Stim szeto  */
1486*8fe96085Stim szeto int
1487*8fe96085Stim szeto stmfDeleteLu(stmfGuid *luGuid)
1488*8fe96085Stim szeto {
1489*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1490*8fe96085Stim szeto 	stmfLogicalUnitProperties luProps;
1491*8fe96085Stim szeto 
1492*8fe96085Stim szeto 	if (luGuid == NULL) {
1493*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1494*8fe96085Stim szeto 	}
1495*8fe96085Stim szeto 
1496*8fe96085Stim szeto 	/* Check logical unit provider name to call correct dtype function */
1497*8fe96085Stim szeto 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1498*8fe96085Stim szeto 	    != STMF_STATUS_SUCCESS) {
1499*8fe96085Stim szeto 		return (ret);
1500*8fe96085Stim szeto 	} else {
1501*8fe96085Stim szeto 		if (strcmp(luProps.providerName, "sbd") == 0) {
1502*8fe96085Stim szeto 			ret = deleteDiskLu(luGuid);
1503*8fe96085Stim szeto 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1504*8fe96085Stim szeto 			return (STMF_ERROR_NOT_FOUND);
1505*8fe96085Stim szeto 		} else {
1506*8fe96085Stim szeto 			return (STMF_ERROR_INVALID_ARG);
1507*8fe96085Stim szeto 		}
1508*8fe96085Stim szeto 	}
1509*8fe96085Stim szeto 
1510*8fe96085Stim szeto 	return (ret);
1511*8fe96085Stim szeto }
1512*8fe96085Stim szeto 
1513*8fe96085Stim szeto static int
1514*8fe96085Stim szeto deleteDiskLu(stmfGuid *luGuid)
1515*8fe96085Stim szeto {
1516*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1517*8fe96085Stim szeto 	int fd;
1518*8fe96085Stim szeto 	int savedErrno;
1519*8fe96085Stim szeto 	int ioctlRet;
1520*8fe96085Stim szeto 	sbd_delete_lu_t deleteLu = {0};
1521*8fe96085Stim szeto 
1522*8fe96085Stim szeto 	stmf_iocdata_t sbdIoctl = {0};
1523*8fe96085Stim szeto 
1524*8fe96085Stim szeto 	/*
1525*8fe96085Stim szeto 	 * Open control node for sbd
1526*8fe96085Stim szeto 	 */
1527*8fe96085Stim szeto 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1528*8fe96085Stim szeto 		return (ret);
1529*8fe96085Stim szeto 
1530*8fe96085Stim szeto 	ret = removeGuidFromDiskStore(luGuid);
1531*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1532*8fe96085Stim szeto 		goto done;
1533*8fe96085Stim szeto 	}
1534*8fe96085Stim szeto 
1535*8fe96085Stim szeto 	bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
1536*8fe96085Stim szeto 	deleteLu.dlu_by_guid = 1;
1537*8fe96085Stim szeto 
1538*8fe96085Stim szeto 	sbdIoctl.stmf_version = STMF_VERSION_1;
1539*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
1540*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
1541*8fe96085Stim szeto 	ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
1542*8fe96085Stim szeto 	if (ioctlRet != 0) {
1543*8fe96085Stim szeto 		savedErrno = errno;
1544*8fe96085Stim szeto 		switch (savedErrno) {
1545*8fe96085Stim szeto 			case EBUSY:
1546*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
1547*8fe96085Stim szeto 				break;
1548*8fe96085Stim szeto 			case EPERM:
1549*8fe96085Stim szeto 			case EACCES:
1550*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
1551*8fe96085Stim szeto 				break;
1552*8fe96085Stim szeto 			case ENOENT:
1553*8fe96085Stim szeto 				ret = STMF_ERROR_NOT_FOUND;
1554*8fe96085Stim szeto 				break;
1555*8fe96085Stim szeto 			default:
1556*8fe96085Stim szeto 				syslog(LOG_DEBUG,
1557*8fe96085Stim szeto 				    "deleteDiskLu:ioctl error(%d) (%d) (%d)",
1558*8fe96085Stim szeto 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
1559*8fe96085Stim szeto 				ret = STMF_STATUS_ERROR;
1560*8fe96085Stim szeto 				break;
1561*8fe96085Stim szeto 		}
1562*8fe96085Stim szeto 	}
1563*8fe96085Stim szeto 
1564*8fe96085Stim szeto done:
1565*8fe96085Stim szeto 	(void) close(fd);
1566*8fe96085Stim szeto 	return (ret);
1567*8fe96085Stim szeto }
1568*8fe96085Stim szeto 
1569*8fe96085Stim szeto /*
1570*8fe96085Stim szeto  * stmfModifyLu
1571*8fe96085Stim szeto  *
1572*8fe96085Stim szeto  * Purpose: Modify properties of a logical unit
1573*8fe96085Stim szeto  *
1574*8fe96085Stim szeto  * luGuid - guid of registered logical unit
1575*8fe96085Stim szeto  * prop - property to modify
1576*8fe96085Stim szeto  * propVal - property value to set
1577*8fe96085Stim szeto  *
1578*8fe96085Stim szeto  */
1579*8fe96085Stim szeto int
1580*8fe96085Stim szeto stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
1581*8fe96085Stim szeto {
1582*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1583*8fe96085Stim szeto 	stmfLogicalUnitProperties luProps;
1584*8fe96085Stim szeto 
1585*8fe96085Stim szeto 	if (luGuid == NULL) {
1586*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1587*8fe96085Stim szeto 	}
1588*8fe96085Stim szeto 
1589*8fe96085Stim szeto 	/* Check logical unit provider name to call correct dtype function */
1590*8fe96085Stim szeto 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1591*8fe96085Stim szeto 	    != STMF_STATUS_SUCCESS) {
1592*8fe96085Stim szeto 		return (ret);
1593*8fe96085Stim szeto 	} else {
1594*8fe96085Stim szeto 		if (strcmp(luProps.providerName, "sbd") == 0) {
1595*8fe96085Stim szeto 			ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
1596*8fe96085Stim szeto 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1597*8fe96085Stim szeto 			return (STMF_ERROR_NOT_FOUND);
1598*8fe96085Stim szeto 		} else {
1599*8fe96085Stim szeto 			return (STMF_ERROR_INVALID_ARG);
1600*8fe96085Stim szeto 		}
1601*8fe96085Stim szeto 	}
1602*8fe96085Stim szeto 
1603*8fe96085Stim szeto 	return (ret);
1604*8fe96085Stim szeto }
1605*8fe96085Stim szeto 
1606*8fe96085Stim szeto /*
1607*8fe96085Stim szeto  * stmfModifyLuByFname
1608*8fe96085Stim szeto  *
1609*8fe96085Stim szeto  * Purpose: Modify a device by filename. Device does not need to be registered.
1610*8fe96085Stim szeto  *
1611*8fe96085Stim szeto  * dType - type of device to modify
1612*8fe96085Stim szeto  *         STMF_DISK
1613*8fe96085Stim szeto  *
1614*8fe96085Stim szeto  * fname - filename or meta filename
1615*8fe96085Stim szeto  * prop - valid property identifier
1616*8fe96085Stim szeto  * propVal - property value
1617*8fe96085Stim szeto  *
1618*8fe96085Stim szeto  */
1619*8fe96085Stim szeto int
1620*8fe96085Stim szeto stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
1621*8fe96085Stim szeto     const char *propVal)
1622*8fe96085Stim szeto {
1623*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1624*8fe96085Stim szeto 	if (fname == NULL) {
1625*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1626*8fe96085Stim szeto 	}
1627*8fe96085Stim szeto 
1628*8fe96085Stim szeto 	if (dType == STMF_DISK) {
1629*8fe96085Stim szeto 		ret = modifyDiskLuProp(NULL, fname, prop, propVal);
1630*8fe96085Stim szeto 	} else {
1631*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1632*8fe96085Stim szeto 	}
1633*8fe96085Stim szeto 
1634*8fe96085Stim szeto 	return (ret);
1635*8fe96085Stim szeto }
1636*8fe96085Stim szeto 
1637*8fe96085Stim szeto static int
1638*8fe96085Stim szeto modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
1639*8fe96085Stim szeto     const char *propVal)
1640*8fe96085Stim szeto {
1641*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1642*8fe96085Stim szeto 	luResource hdl = NULL;
1643*8fe96085Stim szeto 	luResourceImpl *luPropsHdl;
1644*8fe96085Stim szeto 
1645*8fe96085Stim szeto 	ret = stmfCreateLuResource(STMF_DISK, &hdl);
1646*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1647*8fe96085Stim szeto 		return (ret);
1648*8fe96085Stim szeto 	}
1649*8fe96085Stim szeto 	ret = validateModifyDiskProp(prop);
1650*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1651*8fe96085Stim szeto 		(void) stmfFreeLuResource(hdl);
1652*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_PROP);
1653*8fe96085Stim szeto 	}
1654*8fe96085Stim szeto 	ret = stmfSetLuProp(hdl, prop, propVal);
1655*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1656*8fe96085Stim szeto 		(void) stmfFreeLuResource(hdl);
1657*8fe96085Stim szeto 		return (ret);
1658*8fe96085Stim szeto 	}
1659*8fe96085Stim szeto 	luPropsHdl = hdl;
1660*8fe96085Stim szeto 	ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
1661*8fe96085Stim szeto 	(void) stmfFreeLuResource(hdl);
1662*8fe96085Stim szeto 	return (ret);
1663*8fe96085Stim szeto }
1664*8fe96085Stim szeto 
1665*8fe96085Stim szeto static int
1666*8fe96085Stim szeto validateModifyDiskProp(uint32_t prop)
1667*8fe96085Stim szeto {
1668*8fe96085Stim szeto 	switch (prop) {
1669*8fe96085Stim szeto 		case STMF_LU_PROP_ALIAS:
1670*8fe96085Stim szeto 		case STMF_LU_PROP_SIZE:
1671*8fe96085Stim szeto 		case STMF_LU_PROP_WRITE_PROTECT:
1672*8fe96085Stim szeto 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
1673*8fe96085Stim szeto 			return (STMF_STATUS_SUCCESS);
1674*8fe96085Stim szeto 			break;
1675*8fe96085Stim szeto 		default:
1676*8fe96085Stim szeto 			return (STMF_STATUS_ERROR);
1677*8fe96085Stim szeto 			break;
1678*8fe96085Stim szeto 	}
1679*8fe96085Stim szeto }
1680*8fe96085Stim szeto 
1681*8fe96085Stim szeto static int
1682*8fe96085Stim szeto modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
1683*8fe96085Stim szeto {
1684*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1685*8fe96085Stim szeto 	int luAliasLen = 0;
1686*8fe96085Stim szeto 	int mluBufSize = 0;
1687*8fe96085Stim szeto 	int bufOffset = 0;
1688*8fe96085Stim szeto 	int fd = 0;
1689*8fe96085Stim szeto 	int ioctlRet;
1690*8fe96085Stim szeto 	int savedErrno;
1691*8fe96085Stim szeto 	int fnameSize = 0;
1692*8fe96085Stim szeto 	stmf_iocdata_t sbdIoctl = {0};
1693*8fe96085Stim szeto 
1694*8fe96085Stim szeto 	sbd_modify_lu_t *sbdLu = NULL;
1695*8fe96085Stim szeto 
1696*8fe96085Stim szeto 	if (luGuid == NULL && fname == NULL) {
1697*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1698*8fe96085Stim szeto 	}
1699*8fe96085Stim szeto 
1700*8fe96085Stim szeto 	if (fname) {
1701*8fe96085Stim szeto 		fnameSize = strlen(fname) + 1;
1702*8fe96085Stim szeto 		mluBufSize += fnameSize;
1703*8fe96085Stim szeto 	}
1704*8fe96085Stim szeto 
1705*8fe96085Stim szeto 	/*
1706*8fe96085Stim szeto 	 * Open control node for sbd
1707*8fe96085Stim szeto 	 */
1708*8fe96085Stim szeto 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1709*8fe96085Stim szeto 		return (ret);
1710*8fe96085Stim szeto 
1711*8fe96085Stim szeto 	if (disk->luAliasValid) {
1712*8fe96085Stim szeto 		luAliasLen = strlen(disk->luAlias);
1713*8fe96085Stim szeto 		mluBufSize += luAliasLen + 1;
1714*8fe96085Stim szeto 	}
1715*8fe96085Stim szeto 
1716*8fe96085Stim szeto 	/*
1717*8fe96085Stim szeto 	 * 8 is the size of the buffer set aside for
1718*8fe96085Stim szeto 	 * concatenation of variable length fields
1719*8fe96085Stim szeto 	 */
1720*8fe96085Stim szeto 	sbdLu = (sbd_modify_lu_t *)calloc(1,
1721*8fe96085Stim szeto 	    sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
1722*8fe96085Stim szeto 	if (sbdLu == NULL) {
1723*8fe96085Stim szeto 		(void) close(fd);
1724*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
1725*8fe96085Stim szeto 	}
1726*8fe96085Stim szeto 
1727*8fe96085Stim szeto 	sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
1728*8fe96085Stim szeto 	    mluBufSize - 8 + fnameSize;
1729*8fe96085Stim szeto 
1730*8fe96085Stim szeto 	if (disk->luAliasValid) {
1731*8fe96085Stim szeto 		sbdLu->mlu_alias_valid = 1;
1732*8fe96085Stim szeto 		sbdLu->mlu_alias_off = bufOffset;
1733*8fe96085Stim szeto 		bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
1734*8fe96085Stim szeto 		    luAliasLen + 1);
1735*8fe96085Stim szeto 		bufOffset += luAliasLen + 1;
1736*8fe96085Stim szeto 	}
1737*8fe96085Stim szeto 
1738*8fe96085Stim szeto 	if (disk->luSizeValid) {
1739*8fe96085Stim szeto 		sbdLu->mlu_lu_size_valid = 1;
1740*8fe96085Stim szeto 		sbdLu->mlu_lu_size = disk->luSize;
1741*8fe96085Stim szeto 	}
1742*8fe96085Stim szeto 
1743*8fe96085Stim szeto 	if (disk->writeProtectEnableValid) {
1744*8fe96085Stim szeto 		sbdLu->mlu_write_protected_valid = 1;
1745*8fe96085Stim szeto 		if (disk->writeProtectEnable) {
1746*8fe96085Stim szeto 			sbdLu->mlu_write_protected = 1;
1747*8fe96085Stim szeto 		}
1748*8fe96085Stim szeto 	}
1749*8fe96085Stim szeto 
1750*8fe96085Stim szeto 	if (disk->writebackCacheDisableValid) {
1751*8fe96085Stim szeto 		sbdLu->mlu_writeback_cache_disable_valid = 1;
1752*8fe96085Stim szeto 		if (disk->writebackCacheDisable) {
1753*8fe96085Stim szeto 			sbdLu->mlu_writeback_cache_disable = 1;
1754*8fe96085Stim szeto 		}
1755*8fe96085Stim szeto 	}
1756*8fe96085Stim szeto 
1757*8fe96085Stim szeto 	if (luGuid) {
1758*8fe96085Stim szeto 		bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
1759*8fe96085Stim szeto 		sbdLu->mlu_by_guid = 1;
1760*8fe96085Stim szeto 	} else {
1761*8fe96085Stim szeto 		sbdLu->mlu_fname_off = bufOffset;
1762*8fe96085Stim szeto 		bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
1763*8fe96085Stim szeto 		sbdLu->mlu_by_fname = 1;
1764*8fe96085Stim szeto 	}
1765*8fe96085Stim szeto 
1766*8fe96085Stim szeto 	sbdIoctl.stmf_version = STMF_VERSION_1;
1767*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
1768*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1769*8fe96085Stim szeto 
1770*8fe96085Stim szeto 	ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
1771*8fe96085Stim szeto 	if (ioctlRet != 0) {
1772*8fe96085Stim szeto 		savedErrno = errno;
1773*8fe96085Stim szeto 		switch (savedErrno) {
1774*8fe96085Stim szeto 			case EBUSY:
1775*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
1776*8fe96085Stim szeto 				break;
1777*8fe96085Stim szeto 			case EPERM:
1778*8fe96085Stim szeto 			case EACCES:
1779*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
1780*8fe96085Stim szeto 				break;
1781*8fe96085Stim szeto 			default:
1782*8fe96085Stim szeto 				diskError(sbdIoctl.stmf_error, &ret);
1783*8fe96085Stim szeto 				if (ret == STMF_STATUS_ERROR) {
1784*8fe96085Stim szeto 					syslog(LOG_DEBUG,
1785*8fe96085Stim szeto 					"modifyDiskLu:ioctl "
1786*8fe96085Stim szeto 					"error(%d) (%d) (%d)", ioctlRet,
1787*8fe96085Stim szeto 					    sbdIoctl.stmf_error, savedErrno);
1788*8fe96085Stim szeto 				}
1789*8fe96085Stim szeto 				break;
1790*8fe96085Stim szeto 		}
1791*8fe96085Stim szeto 	}
1792*8fe96085Stim szeto 
1793*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
1794*8fe96085Stim szeto 		goto done;
1795*8fe96085Stim szeto 	}
1796*8fe96085Stim szeto 
1797*8fe96085Stim szeto done:
1798*8fe96085Stim szeto 	free(sbdLu);
1799*8fe96085Stim szeto 	(void) close(fd);
1800*8fe96085Stim szeto 	return (ret);
1801*8fe96085Stim szeto }
1802*8fe96085Stim szeto 
1803*8fe96085Stim szeto /*
1804*8fe96085Stim szeto  * removeGuidFromDiskStore
1805*8fe96085Stim szeto  *
1806*8fe96085Stim szeto  * Purpose: delete a logical unit from the sbd provider data
1807*8fe96085Stim szeto  */
1808*8fe96085Stim szeto static int
1809*8fe96085Stim szeto removeGuidFromDiskStore(stmfGuid *guid)
1810*8fe96085Stim szeto {
1811*8fe96085Stim szeto 	return (persistDiskGuid(guid, NULL, B_FALSE));
1812*8fe96085Stim szeto }
1813*8fe96085Stim szeto 
1814*8fe96085Stim szeto 
1815*8fe96085Stim szeto /*
1816*8fe96085Stim szeto  * addGuidToDiskStore
1817*8fe96085Stim szeto  *
1818*8fe96085Stim szeto  * Purpose: add a logical unit to the sbd provider data
1819*8fe96085Stim szeto  */
1820*8fe96085Stim szeto static int
1821*8fe96085Stim szeto addGuidToDiskStore(stmfGuid *guid, char *filename)
1822*8fe96085Stim szeto {
1823*8fe96085Stim szeto 	return (persistDiskGuid(guid, filename, B_TRUE));
1824*8fe96085Stim szeto }
1825*8fe96085Stim szeto 
1826*8fe96085Stim szeto 
1827*8fe96085Stim szeto /*
1828*8fe96085Stim szeto  * persistDiskGuid
1829*8fe96085Stim szeto  *
1830*8fe96085Stim szeto  * Purpose: Persist or unpersist a guid for the sbd provider data
1831*8fe96085Stim szeto  *
1832*8fe96085Stim szeto  */
1833*8fe96085Stim szeto static int
1834*8fe96085Stim szeto persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
1835*8fe96085Stim szeto {
1836*8fe96085Stim szeto 	char	    guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
1837*8fe96085Stim szeto 	nvlist_t    *nvl = NULL;
1838*8fe96085Stim szeto 
1839*8fe96085Stim szeto 	uint64_t    setToken;
1840*8fe96085Stim szeto 	boolean_t   retryGetProviderData = B_FALSE;
1841*8fe96085Stim szeto 	boolean_t   newData = B_FALSE;
1842*8fe96085Stim szeto 	int	    ret = STMF_STATUS_SUCCESS;
1843*8fe96085Stim szeto 	int	    retryCnt = 0;
1844*8fe96085Stim szeto 	int	    stmfRet;
1845*8fe96085Stim szeto 
1846*8fe96085Stim szeto 	/* if we're persisting a guid, there must be a filename */
1847*8fe96085Stim szeto 	if (persist && !filename) {
1848*8fe96085Stim szeto 		return (1);
1849*8fe96085Stim szeto 	}
1850*8fe96085Stim szeto 
1851*8fe96085Stim szeto 	/* guid is stored in lowercase ascii hex */
1852*8fe96085Stim szeto 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
1853*8fe96085Stim szeto 	    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
1854*8fe96085Stim szeto 	    "%02x%02x%02x%02x%02x%02x",
1855*8fe96085Stim szeto 	    guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
1856*8fe96085Stim szeto 	    guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
1857*8fe96085Stim szeto 	    guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
1858*8fe96085Stim szeto 	    guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
1859*8fe96085Stim szeto 
1860*8fe96085Stim szeto 
1861*8fe96085Stim szeto 	do {
1862*8fe96085Stim szeto 		retryGetProviderData = B_FALSE;
1863*8fe96085Stim szeto 		stmfRet = stmfGetProviderDataProt("sbd", &nvl,
1864*8fe96085Stim szeto 		    STMF_LU_PROVIDER_TYPE, &setToken);
1865*8fe96085Stim szeto 		if (stmfRet != STMF_STATUS_SUCCESS) {
1866*8fe96085Stim szeto 			if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
1867*8fe96085Stim szeto 				ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
1868*8fe96085Stim szeto 				if (ret != 0) {
1869*8fe96085Stim szeto 					syslog(LOG_DEBUG,
1870*8fe96085Stim szeto 					    "unpersistGuid:nvlist_alloc(%d)",
1871*8fe96085Stim szeto 					    ret);
1872*8fe96085Stim szeto 					ret = STMF_STATUS_ERROR;
1873*8fe96085Stim szeto 					goto done;
1874*8fe96085Stim szeto 				}
1875*8fe96085Stim szeto 				newData = B_TRUE;
1876*8fe96085Stim szeto 			} else {
1877*8fe96085Stim szeto 				ret = stmfRet;
1878*8fe96085Stim szeto 				goto done;
1879*8fe96085Stim szeto 			}
1880*8fe96085Stim szeto 		}
1881*8fe96085Stim szeto 		if (persist) {
1882*8fe96085Stim szeto 			ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
1883*8fe96085Stim szeto 		} else {
1884*8fe96085Stim szeto 			ret = nvlist_remove(nvl, guidAsciiBuf,
1885*8fe96085Stim szeto 			    DATA_TYPE_STRING);
1886*8fe96085Stim szeto 			if (ret == ENOENT) {
1887*8fe96085Stim szeto 				ret = 0;
1888*8fe96085Stim szeto 			}
1889*8fe96085Stim szeto 		}
1890*8fe96085Stim szeto 		if (ret == 0) {
1891*8fe96085Stim szeto 			if (newData) {
1892*8fe96085Stim szeto 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
1893*8fe96085Stim szeto 				    STMF_LU_PROVIDER_TYPE, NULL);
1894*8fe96085Stim szeto 			} else {
1895*8fe96085Stim szeto 				stmfRet = stmfSetProviderDataProt("sbd", nvl,
1896*8fe96085Stim szeto 				    STMF_LU_PROVIDER_TYPE, &setToken);
1897*8fe96085Stim szeto 			}
1898*8fe96085Stim szeto 			if (stmfRet != STMF_STATUS_SUCCESS) {
1899*8fe96085Stim szeto 				if (stmfRet == STMF_ERROR_BUSY) {
1900*8fe96085Stim szeto 					/* get/set failed, try again */
1901*8fe96085Stim szeto 					retryGetProviderData = B_TRUE;
1902*8fe96085Stim szeto 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
1903*8fe96085Stim szeto 						ret = stmfRet;
1904*8fe96085Stim szeto 						break;
1905*8fe96085Stim szeto 					}
1906*8fe96085Stim szeto 					continue;
1907*8fe96085Stim szeto 				} else if (stmfRet ==
1908*8fe96085Stim szeto 				    STMF_ERROR_PROV_DATA_STALE) {
1909*8fe96085Stim szeto 					/* update failed, try again */
1910*8fe96085Stim szeto 					nvlist_free(nvl);
1911*8fe96085Stim szeto 					nvl = NULL;
1912*8fe96085Stim szeto 					retryGetProviderData = B_TRUE;
1913*8fe96085Stim szeto 					if (retryCnt++ > MAX_PROVIDER_RETRY) {
1914*8fe96085Stim szeto 						ret = stmfRet;
1915*8fe96085Stim szeto 						break;
1916*8fe96085Stim szeto 					}
1917*8fe96085Stim szeto 					continue;
1918*8fe96085Stim szeto 				} else {
1919*8fe96085Stim szeto 					syslog(LOG_DEBUG,
1920*8fe96085Stim szeto 					    "unpersistGuid:error(%x)", stmfRet);
1921*8fe96085Stim szeto 					ret = stmfRet;
1922*8fe96085Stim szeto 				}
1923*8fe96085Stim szeto 				break;
1924*8fe96085Stim szeto 			}
1925*8fe96085Stim szeto 		} else {
1926*8fe96085Stim szeto 			syslog(LOG_DEBUG,
1927*8fe96085Stim szeto 			    "unpersistGuid:error nvlist_add/remove(%d)",
1928*8fe96085Stim szeto 			    ret);
1929*8fe96085Stim szeto 			ret = STMF_STATUS_ERROR;
1930*8fe96085Stim szeto 		}
1931*8fe96085Stim szeto 	} while (retryGetProviderData);
1932*8fe96085Stim szeto 
1933*8fe96085Stim szeto done:
1934*8fe96085Stim szeto 	nvlist_free(nvl);
1935*8fe96085Stim szeto 	return (ret);
1936*8fe96085Stim szeto }
1937*8fe96085Stim szeto 
1938*8fe96085Stim szeto 
1939*8fe96085Stim szeto /*
1940*8fe96085Stim szeto  * stmfGetLuProp
1941*8fe96085Stim szeto  *
1942*8fe96085Stim szeto  * Purpose: Get current value for a resource property
1943*8fe96085Stim szeto  *
1944*8fe96085Stim szeto  * hdl - luResource from a previous call to stmfCreateLuResource
1945*8fe96085Stim szeto  *
1946*8fe96085Stim szeto  * resourceProp - a valid resource property type
1947*8fe96085Stim szeto  *
1948*8fe96085Stim szeto  * propVal - void pointer to a pointer of the value to be retrieved
1949*8fe96085Stim szeto  */
1950*8fe96085Stim szeto int
1951*8fe96085Stim szeto stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
1952*8fe96085Stim szeto {
1953*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1954*8fe96085Stim szeto 	luResourceImpl *luPropsHdl = hdl;
1955*8fe96085Stim szeto 	if (hdl == NULL || propLen == NULL || propVal == NULL) {
1956*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1957*8fe96085Stim szeto 	}
1958*8fe96085Stim szeto 
1959*8fe96085Stim szeto 	if (luPropsHdl->type == STMF_DISK) {
1960*8fe96085Stim szeto 		ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
1961*8fe96085Stim szeto 	} else {
1962*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
1963*8fe96085Stim szeto 	}
1964*8fe96085Stim szeto 
1965*8fe96085Stim szeto 	return (ret);
1966*8fe96085Stim szeto }
1967*8fe96085Stim szeto 
1968*8fe96085Stim szeto /*
1969*8fe96085Stim szeto  * stmfGetLuResource
1970*8fe96085Stim szeto  *
1971*8fe96085Stim szeto  * Purpose: Get a logical unit resource handle for a given logical unit.
1972*8fe96085Stim szeto  *
1973*8fe96085Stim szeto  * hdl - pointer to luResource
1974*8fe96085Stim szeto  */
1975*8fe96085Stim szeto int
1976*8fe96085Stim szeto stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
1977*8fe96085Stim szeto {
1978*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
1979*8fe96085Stim szeto 	stmfLogicalUnitProperties luProps;
1980*8fe96085Stim szeto 
1981*8fe96085Stim szeto 
1982*8fe96085Stim szeto 	/* Check logical unit provider name to call correct dtype function */
1983*8fe96085Stim szeto 	if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1984*8fe96085Stim szeto 	    != STMF_STATUS_SUCCESS) {
1985*8fe96085Stim szeto 		return (ret);
1986*8fe96085Stim szeto 	} else {
1987*8fe96085Stim szeto 		if (strcmp(luProps.providerName, "sbd") == 0) {
1988*8fe96085Stim szeto 			ret = getDiskAllProps(luGuid, hdl);
1989*8fe96085Stim szeto 		} else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1990*8fe96085Stim szeto 			return (STMF_ERROR_NOT_FOUND);
1991*8fe96085Stim szeto 		} else {
1992*8fe96085Stim szeto 			return (STMF_ERROR_INVALID_ARG);
1993*8fe96085Stim szeto 		}
1994*8fe96085Stim szeto 	}
1995*8fe96085Stim szeto 
1996*8fe96085Stim szeto 	return (ret);
1997*8fe96085Stim szeto }
1998*8fe96085Stim szeto 
1999*8fe96085Stim szeto /*
2000*8fe96085Stim szeto  * getDiskAllProps
2001*8fe96085Stim szeto  *
2002*8fe96085Stim szeto  * Purpose: load all disk properties from sbd driver
2003*8fe96085Stim szeto  *
2004*8fe96085Stim szeto  * luGuid - guid of disk device for which properties are to be retrieved
2005*8fe96085Stim szeto  * hdl - allocated luResource into which properties are to be copied
2006*8fe96085Stim szeto  *
2007*8fe96085Stim szeto  */
2008*8fe96085Stim szeto static int
2009*8fe96085Stim szeto getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
2010*8fe96085Stim szeto {
2011*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
2012*8fe96085Stim szeto 	int fd;
2013*8fe96085Stim szeto 	sbd_lu_props_t *sbdProps;
2014*8fe96085Stim szeto 	int ioctlRet;
2015*8fe96085Stim szeto 	int savedErrno;
2016*8fe96085Stim szeto 	int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
2017*8fe96085Stim szeto 	stmf_iocdata_t sbdIoctl = {0};
2018*8fe96085Stim szeto 
2019*8fe96085Stim szeto 	/*
2020*8fe96085Stim szeto 	 * Open control node for sbd
2021*8fe96085Stim szeto 	 */
2022*8fe96085Stim szeto 	if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2023*8fe96085Stim szeto 		return (ret);
2024*8fe96085Stim szeto 
2025*8fe96085Stim szeto 
2026*8fe96085Stim szeto 	*hdl = calloc(1, sizeof (luResourceImpl));
2027*8fe96085Stim szeto 	if (*hdl == NULL) {
2028*8fe96085Stim szeto 		(void) close(fd);
2029*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
2030*8fe96085Stim szeto 	}
2031*8fe96085Stim szeto 
2032*8fe96085Stim szeto 	sbdProps = calloc(1, sbdPropsSize);
2033*8fe96085Stim szeto 	if (sbdProps == NULL) {
2034*8fe96085Stim szeto 		free(*hdl);
2035*8fe96085Stim szeto 		(void) close(fd);
2036*8fe96085Stim szeto 		return (STMF_ERROR_NOMEM);
2037*8fe96085Stim szeto 	}
2038*8fe96085Stim szeto 
2039*8fe96085Stim szeto 	ret = createDiskResource((luResourceImpl *)*hdl);
2040*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
2041*8fe96085Stim szeto 		free(*hdl);
2042*8fe96085Stim szeto 		(void) close(fd);
2043*8fe96085Stim szeto 		return (ret);
2044*8fe96085Stim szeto 	}
2045*8fe96085Stim szeto 
2046*8fe96085Stim szeto 	sbdProps->slp_input_guid = 1;
2047*8fe96085Stim szeto 	bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
2048*8fe96085Stim szeto 
2049*8fe96085Stim szeto 	sbdIoctl.stmf_version = STMF_VERSION_1;
2050*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf_size = sbdPropsSize;
2051*8fe96085Stim szeto 	sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
2052*8fe96085Stim szeto 	sbdIoctl.stmf_obuf_size = sbdPropsSize;
2053*8fe96085Stim szeto 	sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
2054*8fe96085Stim szeto 	ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
2055*8fe96085Stim szeto 	if (ioctlRet != 0) {
2056*8fe96085Stim szeto 		savedErrno = errno;
2057*8fe96085Stim szeto 		switch (savedErrno) {
2058*8fe96085Stim szeto 			case EBUSY:
2059*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
2060*8fe96085Stim szeto 				break;
2061*8fe96085Stim szeto 			case EPERM:
2062*8fe96085Stim szeto 			case EACCES:
2063*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
2064*8fe96085Stim szeto 				break;
2065*8fe96085Stim szeto 			case ENOENT:
2066*8fe96085Stim szeto 				ret = STMF_ERROR_NOT_FOUND;
2067*8fe96085Stim szeto 				break;
2068*8fe96085Stim szeto 			default:
2069*8fe96085Stim szeto 				syslog(LOG_DEBUG,
2070*8fe96085Stim szeto 				    "getDiskAllProps:ioctl error(%d) (%d) (%d)",
2071*8fe96085Stim szeto 				    ioctlRet, sbdIoctl.stmf_error, savedErrno);
2072*8fe96085Stim szeto 				ret = STMF_STATUS_ERROR;
2073*8fe96085Stim szeto 				break;
2074*8fe96085Stim szeto 		}
2075*8fe96085Stim szeto 	}
2076*8fe96085Stim szeto 
2077*8fe96085Stim szeto 	if (ret == STMF_STATUS_SUCCESS) {
2078*8fe96085Stim szeto 		ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
2079*8fe96085Stim szeto 	}
2080*8fe96085Stim szeto 
2081*8fe96085Stim szeto 	(void) close(fd);
2082*8fe96085Stim szeto 	return (ret);
2083*8fe96085Stim szeto }
2084*8fe96085Stim szeto 
2085*8fe96085Stim szeto /*
2086*8fe96085Stim szeto  * loadDiskPropsFromDriver
2087*8fe96085Stim szeto  *
2088*8fe96085Stim szeto  * Purpose: Retrieve all disk type properties from sbd driver
2089*8fe96085Stim szeto  *
2090*8fe96085Stim szeto  * hdl - Allocated luResourceImpl
2091*8fe96085Stim szeto  * sbdProps - sbd_lu_props_t structure returned from sbd driver
2092*8fe96085Stim szeto  *
2093*8fe96085Stim szeto  */
2094*8fe96085Stim szeto static int
2095*8fe96085Stim szeto loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
2096*8fe96085Stim szeto {
2097*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
2098*8fe96085Stim szeto 	diskResource *diskLu = hdl->resource;
2099*8fe96085Stim szeto 	/* copy guid */
2100*8fe96085Stim szeto 	diskLu->luGuidValid = B_TRUE;
2101*8fe96085Stim szeto 	bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
2102*8fe96085Stim szeto 
2103*8fe96085Stim szeto 	if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
2104*8fe96085Stim szeto 		diskLu->luMetaFileNameValid = B_TRUE;
2105*8fe96085Stim szeto 		if (strlcpy(diskLu->luMetaFileName,
2106*8fe96085Stim szeto 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
2107*8fe96085Stim szeto 		    sizeof (diskLu->luMetaFileName)) >=
2108*8fe96085Stim szeto 		    sizeof (diskLu->luMetaFileName)) {
2109*8fe96085Stim szeto 			return (STMF_STATUS_ERROR);
2110*8fe96085Stim szeto 		}
2111*8fe96085Stim szeto 	}
2112*8fe96085Stim szeto 
2113*8fe96085Stim szeto 	if (sbdProps->slp_data_fname_valid) {
2114*8fe96085Stim szeto 		diskLu->luDataFileNameValid = B_TRUE;
2115*8fe96085Stim szeto 		if (strlcpy(diskLu->luDataFileName,
2116*8fe96085Stim szeto 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
2117*8fe96085Stim szeto 		    sizeof (diskLu->luDataFileName)) >=
2118*8fe96085Stim szeto 		    sizeof (diskLu->luDataFileName)) {
2119*8fe96085Stim szeto 			return (STMF_STATUS_ERROR);
2120*8fe96085Stim szeto 		}
2121*8fe96085Stim szeto 	}
2122*8fe96085Stim szeto 
2123*8fe96085Stim szeto 	if (sbdProps->slp_serial_valid) {
2124*8fe96085Stim szeto 		diskLu->serialNumValid = B_TRUE;
2125*8fe96085Stim szeto 		bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
2126*8fe96085Stim szeto 		    diskLu->serialNum, sbdProps->slp_serial_size);
2127*8fe96085Stim szeto 	}
2128*8fe96085Stim szeto 
2129*8fe96085Stim szeto 	if (sbdProps->slp_alias_valid) {
2130*8fe96085Stim szeto 		diskLu->luAliasValid = B_TRUE;
2131*8fe96085Stim szeto 		if (strlcpy(diskLu->luAlias,
2132*8fe96085Stim szeto 		    (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]),
2133*8fe96085Stim szeto 		    sizeof (diskLu->luAlias)) >=
2134*8fe96085Stim szeto 		    sizeof (diskLu->luAlias)) {
2135*8fe96085Stim szeto 			return (STMF_STATUS_ERROR);
2136*8fe96085Stim szeto 		}
2137*8fe96085Stim szeto 	} else { /* set alias to data filename if not set */
2138*8fe96085Stim szeto 		if (sbdProps->slp_data_fname_valid) {
2139*8fe96085Stim szeto 			diskLu->luAliasValid = B_TRUE;
2140*8fe96085Stim szeto 			if (strlcpy(diskLu->luAlias,
2141*8fe96085Stim szeto 			    (char *)&(sbdProps->slp_buf[
2142*8fe96085Stim szeto 			    sbdProps->slp_data_fname_off]),
2143*8fe96085Stim szeto 			    sizeof (diskLu->luAlias)) >=
2144*8fe96085Stim szeto 			    sizeof (diskLu->luAlias)) {
2145*8fe96085Stim szeto 				return (STMF_STATUS_ERROR);
2146*8fe96085Stim szeto 			}
2147*8fe96085Stim szeto 		}
2148*8fe96085Stim szeto 	}
2149*8fe96085Stim szeto 
2150*8fe96085Stim szeto 	diskLu->vidValid = B_TRUE;
2151*8fe96085Stim szeto 	bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
2152*8fe96085Stim szeto 
2153*8fe96085Stim szeto 	diskLu->pidValid = B_TRUE;
2154*8fe96085Stim szeto 	bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
2155*8fe96085Stim szeto 
2156*8fe96085Stim szeto 	diskLu->revValid = B_TRUE;
2157*8fe96085Stim szeto 	bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
2158*8fe96085Stim szeto 
2159*8fe96085Stim szeto 	diskLu->writeProtectEnableValid = B_TRUE;
2160*8fe96085Stim szeto 	if (sbdProps->slp_write_protected) {
2161*8fe96085Stim szeto 		diskLu->writeProtectEnable = B_TRUE;
2162*8fe96085Stim szeto 	}
2163*8fe96085Stim szeto 
2164*8fe96085Stim szeto 	diskLu->writebackCacheDisableValid = B_TRUE;
2165*8fe96085Stim szeto 	if (sbdProps->slp_writeback_cache_disable_cur) {
2166*8fe96085Stim szeto 		diskLu->writebackCacheDisable = B_TRUE;
2167*8fe96085Stim szeto 	}
2168*8fe96085Stim szeto 
2169*8fe96085Stim szeto 	diskLu->blkSizeValid = B_TRUE;
2170*8fe96085Stim szeto 	diskLu->blkSize = sbdProps->slp_blksize;
2171*8fe96085Stim szeto 
2172*8fe96085Stim szeto 	diskLu->luSizeValid = B_TRUE;
2173*8fe96085Stim szeto 	diskLu->luSize = sbdProps->slp_lu_size;
2174*8fe96085Stim szeto 
2175*8fe96085Stim szeto 	return (ret);
2176*8fe96085Stim szeto }
2177*8fe96085Stim szeto 
2178*8fe96085Stim szeto 
2179*8fe96085Stim szeto /*
2180*8fe96085Stim szeto  * stmfSetLuProp
2181*8fe96085Stim szeto  *
2182*8fe96085Stim szeto  * Purpose: set a property on an luResource
2183*8fe96085Stim szeto  *
2184*8fe96085Stim szeto  * hdl - allocated luResource
2185*8fe96085Stim szeto  * prop - property identifier
2186*8fe96085Stim szeto  * propVal - property value to be set
2187*8fe96085Stim szeto  */
2188*8fe96085Stim szeto int
2189*8fe96085Stim szeto stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
2190*8fe96085Stim szeto {
2191*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
2192*8fe96085Stim szeto 	luResourceImpl *luPropsHdl = hdl;
2193*8fe96085Stim szeto 	if (hdl == NULL) {
2194*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
2195*8fe96085Stim szeto 	}
2196*8fe96085Stim szeto 
2197*8fe96085Stim szeto 	if (luPropsHdl->type == STMF_DISK) {
2198*8fe96085Stim szeto 		ret = setDiskProp(luPropsHdl, prop, propVal);
2199*8fe96085Stim szeto 	} else {
2200*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
2201*8fe96085Stim szeto 	}
2202*8fe96085Stim szeto 
2203*8fe96085Stim szeto 	return (ret);
2204*8fe96085Stim szeto }
2205*8fe96085Stim szeto 
2206*8fe96085Stim szeto /*
2207*8fe96085Stim szeto  * getDiskProp
2208*8fe96085Stim szeto  *
2209*8fe96085Stim szeto  * Purpose: retrieve a given property from a logical unit resource of type disk
2210*8fe96085Stim szeto  *
2211*8fe96085Stim szeto  * hdl - allocated luResourceImpl
2212*8fe96085Stim szeto  * prop - property identifier
2213*8fe96085Stim szeto  * propVal - pointer to character to contain the retrieved property value
2214*8fe96085Stim szeto  * propLen - On input this is the length of propVal. On failure, it contains the
2215*8fe96085Stim szeto  *           number of bytes required for propVal
2216*8fe96085Stim szeto  */
2217*8fe96085Stim szeto static int
2218*8fe96085Stim szeto getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
2219*8fe96085Stim szeto {
2220*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
2221*8fe96085Stim szeto 	diskResource *diskLu = hdl->resource;
2222*8fe96085Stim szeto 	size_t reqLen;
2223*8fe96085Stim szeto 
2224*8fe96085Stim szeto 	switch (prop) {
2225*8fe96085Stim szeto 		case STMF_LU_PROP_BLOCK_SIZE:
2226*8fe96085Stim szeto 			if (diskLu->blkSizeValid == B_FALSE) {
2227*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2228*8fe96085Stim szeto 			}
2229*8fe96085Stim szeto 			reqLen = snprintf(propVal, *propLen, "%llu",
2230*8fe96085Stim szeto 			    (u_longlong_t)diskLu->blkSize);
2231*8fe96085Stim szeto 			if (reqLen >= *propLen) {
2232*8fe96085Stim szeto 				*propLen = reqLen + 1;
2233*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2234*8fe96085Stim szeto 			}
2235*8fe96085Stim szeto 			break;
2236*8fe96085Stim szeto 		case STMF_LU_PROP_FILENAME:
2237*8fe96085Stim szeto 			if (diskLu->luDataFileNameValid == B_FALSE) {
2238*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2239*8fe96085Stim szeto 			}
2240*8fe96085Stim szeto 			if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
2241*8fe96085Stim szeto 			    *propLen)) >= *propLen) {
2242*8fe96085Stim szeto 				*propLen = reqLen + 1;
2243*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2244*8fe96085Stim szeto 			}
2245*8fe96085Stim szeto 			break;
2246*8fe96085Stim szeto 		case STMF_LU_PROP_META_FILENAME:
2247*8fe96085Stim szeto 			if (diskLu->luMetaFileNameValid == B_FALSE) {
2248*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2249*8fe96085Stim szeto 			}
2250*8fe96085Stim szeto 			if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
2251*8fe96085Stim szeto 			    *propLen)) >= *propLen) {
2252*8fe96085Stim szeto 				*propLen = reqLen + 1;
2253*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2254*8fe96085Stim szeto 			}
2255*8fe96085Stim szeto 			break;
2256*8fe96085Stim szeto 		case STMF_LU_PROP_GUID:
2257*8fe96085Stim szeto 			if (diskLu->luGuidValid == B_FALSE) {
2258*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2259*8fe96085Stim szeto 			}
2260*8fe96085Stim szeto 			reqLen = snprintf(propVal, *propLen,
2261*8fe96085Stim szeto 			    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
2262*8fe96085Stim szeto 			    "%02X%02X%02X%02X",
2263*8fe96085Stim szeto 			    diskLu->luGuid[0], diskLu->luGuid[1],
2264*8fe96085Stim szeto 			    diskLu->luGuid[2], diskLu->luGuid[3],
2265*8fe96085Stim szeto 			    diskLu->luGuid[4], diskLu->luGuid[5],
2266*8fe96085Stim szeto 			    diskLu->luGuid[6], diskLu->luGuid[7],
2267*8fe96085Stim szeto 			    diskLu->luGuid[8], diskLu->luGuid[9],
2268*8fe96085Stim szeto 			    diskLu->luGuid[10], diskLu->luGuid[11],
2269*8fe96085Stim szeto 			    diskLu->luGuid[12], diskLu->luGuid[13],
2270*8fe96085Stim szeto 			    diskLu->luGuid[14], diskLu->luGuid[15]);
2271*8fe96085Stim szeto 			if (reqLen >= *propLen) {
2272*8fe96085Stim szeto 				*propLen = reqLen + 1;
2273*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2274*8fe96085Stim szeto 			}
2275*8fe96085Stim szeto 			break;
2276*8fe96085Stim szeto 		case STMF_LU_PROP_SERIAL_NUM:
2277*8fe96085Stim szeto 			if (diskLu->serialNumValid == B_FALSE) {
2278*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2279*8fe96085Stim szeto 			}
2280*8fe96085Stim szeto 			if ((reqLen = strlcpy(propVal, diskLu->serialNum,
2281*8fe96085Stim szeto 			    *propLen)) >= *propLen) {
2282*8fe96085Stim szeto 				*propLen = reqLen + 1;
2283*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2284*8fe96085Stim szeto 			}
2285*8fe96085Stim szeto 			break;
2286*8fe96085Stim szeto 		case STMF_LU_PROP_SIZE:
2287*8fe96085Stim szeto 			if (diskLu->luSizeValid == B_FALSE) {
2288*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2289*8fe96085Stim szeto 			}
2290*8fe96085Stim szeto 			(void) snprintf(propVal, *propLen, "%llu",
2291*8fe96085Stim szeto 			    (u_longlong_t)diskLu->luSize);
2292*8fe96085Stim szeto 			break;
2293*8fe96085Stim szeto 		case STMF_LU_PROP_ALIAS:
2294*8fe96085Stim szeto 			if (diskLu->luAliasValid == B_FALSE) {
2295*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2296*8fe96085Stim szeto 			}
2297*8fe96085Stim szeto 			if ((reqLen = strlcpy(propVal, diskLu->luAlias,
2298*8fe96085Stim szeto 			    *propLen)) >= *propLen) {
2299*8fe96085Stim szeto 				*propLen = reqLen + 1;
2300*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2301*8fe96085Stim szeto 			}
2302*8fe96085Stim szeto 			break;
2303*8fe96085Stim szeto 		case STMF_LU_PROP_VID:
2304*8fe96085Stim szeto 			if (diskLu->vidValid == B_FALSE) {
2305*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2306*8fe96085Stim szeto 			}
2307*8fe96085Stim szeto 			if (*propLen <= sizeof (diskLu->vid)) {
2308*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2309*8fe96085Stim szeto 			}
2310*8fe96085Stim szeto 			bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
2311*8fe96085Stim szeto 			propVal[sizeof (diskLu->vid)] = 0;
2312*8fe96085Stim szeto 			break;
2313*8fe96085Stim szeto 		case STMF_LU_PROP_PID:
2314*8fe96085Stim szeto 			if (diskLu->pidValid == B_FALSE) {
2315*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2316*8fe96085Stim szeto 			}
2317*8fe96085Stim szeto 			if (*propLen <= sizeof (diskLu->pid)) {
2318*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2319*8fe96085Stim szeto 			}
2320*8fe96085Stim szeto 			bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
2321*8fe96085Stim szeto 			propVal[sizeof (diskLu->pid)] = 0;
2322*8fe96085Stim szeto 			break;
2323*8fe96085Stim szeto 		case STMF_LU_PROP_WRITE_PROTECT:
2324*8fe96085Stim szeto 			if (diskLu->writeProtectEnableValid == B_FALSE) {
2325*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2326*8fe96085Stim szeto 			}
2327*8fe96085Stim szeto 			if (diskLu->writeProtectEnable) {
2328*8fe96085Stim szeto 				if ((reqLen = strlcpy(propVal, "true",
2329*8fe96085Stim szeto 				    *propLen)) >= *propLen) {
2330*8fe96085Stim szeto 					*propLen = reqLen + 1;
2331*8fe96085Stim szeto 					return (STMF_ERROR_INVALID_ARG);
2332*8fe96085Stim szeto 				}
2333*8fe96085Stim szeto 			} else {
2334*8fe96085Stim szeto 				if ((reqLen = strlcpy(propVal, "false",
2335*8fe96085Stim szeto 				    *propLen)) >= *propLen) {
2336*8fe96085Stim szeto 					*propLen = reqLen + 1;
2337*8fe96085Stim szeto 					return (STMF_ERROR_INVALID_ARG);
2338*8fe96085Stim szeto 				}
2339*8fe96085Stim szeto 			}
2340*8fe96085Stim szeto 			break;
2341*8fe96085Stim szeto 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
2342*8fe96085Stim szeto 			if (diskLu->writebackCacheDisableValid == B_FALSE) {
2343*8fe96085Stim szeto 				return (STMF_ERROR_NO_PROP);
2344*8fe96085Stim szeto 			}
2345*8fe96085Stim szeto 			if (diskLu->writebackCacheDisable) {
2346*8fe96085Stim szeto 				if ((reqLen = strlcpy(propVal, "true",
2347*8fe96085Stim szeto 				    *propLen)) >= *propLen) {
2348*8fe96085Stim szeto 					*propLen = reqLen + 1;
2349*8fe96085Stim szeto 					return (STMF_ERROR_INVALID_ARG);
2350*8fe96085Stim szeto 				}
2351*8fe96085Stim szeto 			} else {
2352*8fe96085Stim szeto 				if ((reqLen = strlcpy(propVal, "false",
2353*8fe96085Stim szeto 				    *propLen)) >= *propLen) {
2354*8fe96085Stim szeto 					*propLen = reqLen + 1;
2355*8fe96085Stim szeto 					return (STMF_ERROR_INVALID_ARG);
2356*8fe96085Stim szeto 				}
2357*8fe96085Stim szeto 			}
2358*8fe96085Stim szeto 			break;
2359*8fe96085Stim szeto 		default:
2360*8fe96085Stim szeto 			ret = STMF_ERROR_NO_PROP;
2361*8fe96085Stim szeto 			break;
2362*8fe96085Stim szeto 	}
2363*8fe96085Stim szeto 
2364*8fe96085Stim szeto 	return (ret);
2365*8fe96085Stim szeto }
2366*8fe96085Stim szeto 
2367*8fe96085Stim szeto /*
2368*8fe96085Stim szeto  * setDiskProp
2369*8fe96085Stim szeto  *
2370*8fe96085Stim szeto  * Purpose: set properties for resource of type disk
2371*8fe96085Stim szeto  *
2372*8fe96085Stim szeto  * hdl - allocated luResourceImpl
2373*8fe96085Stim szeto  * resourceProp - valid resource identifier
2374*8fe96085Stim szeto  * propVal - valid resource value
2375*8fe96085Stim szeto  */
2376*8fe96085Stim szeto static int
2377*8fe96085Stim szeto setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
2378*8fe96085Stim szeto {
2379*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
2380*8fe96085Stim szeto 	int i;
2381*8fe96085Stim szeto 	diskResource *diskLu = hdl->resource;
2382*8fe96085Stim szeto 	unsigned long long numericProp = 0;
2383*8fe96085Stim szeto 	char guidProp[LU_ASCII_GUID_SIZE + 1];
2384*8fe96085Stim szeto 	char ouiProp[OUI_ASCII_SIZE + 1];
2385*8fe96085Stim szeto 	unsigned int oui[OUI_SIZE];
2386*8fe96085Stim szeto 	unsigned int guid[LU_GUID_SIZE];
2387*8fe96085Stim szeto 	int propSize;
2388*8fe96085Stim szeto 
2389*8fe96085Stim szeto 
2390*8fe96085Stim szeto 	if (propVal == NULL) {
2391*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
2392*8fe96085Stim szeto 	}
2393*8fe96085Stim szeto 
2394*8fe96085Stim szeto 	switch (resourceProp) {
2395*8fe96085Stim szeto 		case STMF_LU_PROP_ALIAS:
2396*8fe96085Stim szeto 			if (strlcpy(diskLu->luAlias, propVal,
2397*8fe96085Stim szeto 			    sizeof (diskLu->luAlias)) >=
2398*8fe96085Stim szeto 			    sizeof (diskLu->luAlias)) {
2399*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2400*8fe96085Stim szeto 			}
2401*8fe96085Stim szeto 			diskLu->luAliasValid = B_TRUE;
2402*8fe96085Stim szeto 			break;
2403*8fe96085Stim szeto 		case STMF_LU_PROP_BLOCK_SIZE:
2404*8fe96085Stim szeto 			(void) sscanf(propVal, "%llu", &numericProp);
2405*8fe96085Stim szeto 			if (numericProp > UINT16_MAX) {
2406*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2407*8fe96085Stim szeto 			}
2408*8fe96085Stim szeto 			diskLu->blkSize = numericProp;
2409*8fe96085Stim szeto 			diskLu->blkSizeValid = B_TRUE;
2410*8fe96085Stim szeto 			break;
2411*8fe96085Stim szeto 		case STMF_LU_PROP_COMPANY_ID:
2412*8fe96085Stim szeto 			if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
2413*8fe96085Stim szeto 			    sizeof (ouiProp)) {
2414*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2415*8fe96085Stim szeto 			}
2416*8fe96085Stim szeto 			if (checkHexUpper(ouiProp) != 0) {
2417*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2418*8fe96085Stim szeto 			}
2419*8fe96085Stim szeto 			(void) sscanf(ouiProp, "%2X%2X%2X",
2420*8fe96085Stim szeto 			    &oui[0], &oui[1], &oui[2]);
2421*8fe96085Stim szeto 
2422*8fe96085Stim szeto 			diskLu->companyId = 0;
2423*8fe96085Stim szeto 			diskLu->companyId += oui[0] << 16;
2424*8fe96085Stim szeto 			diskLu->companyId += oui[1] << 8;
2425*8fe96085Stim szeto 			diskLu->companyId += oui[2];
2426*8fe96085Stim szeto 			diskLu->companyIdValid = B_TRUE;
2427*8fe96085Stim szeto 			break;
2428*8fe96085Stim szeto 		case STMF_LU_PROP_GUID:
2429*8fe96085Stim szeto 			if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
2430*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2431*8fe96085Stim szeto 			}
2432*8fe96085Stim szeto 
2433*8fe96085Stim szeto 			if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
2434*8fe96085Stim szeto 			    sizeof (guidProp)) {
2435*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2436*8fe96085Stim szeto 			}
2437*8fe96085Stim szeto 
2438*8fe96085Stim szeto 			if (checkHexUpper(guidProp) != 0) {
2439*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2440*8fe96085Stim szeto 			}
2441*8fe96085Stim szeto 
2442*8fe96085Stim szeto 			(void) sscanf(guidProp,
2443*8fe96085Stim szeto 			    "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
2444*8fe96085Stim szeto 			    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
2445*8fe96085Stim szeto 			    &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
2446*8fe96085Stim szeto 			    &guid[10], &guid[11], &guid[12], &guid[13],
2447*8fe96085Stim szeto 			    &guid[14], &guid[15]);
2448*8fe96085Stim szeto 			for (i = 0; i < sizeof (diskLu->luGuid); i++) {
2449*8fe96085Stim szeto 				diskLu->luGuid[i] = guid[i];
2450*8fe96085Stim szeto 			}
2451*8fe96085Stim szeto 			diskLu->luGuidValid = B_TRUE;
2452*8fe96085Stim szeto 			break;
2453*8fe96085Stim szeto 		case STMF_LU_PROP_FILENAME:
2454*8fe96085Stim szeto 			if ((strlcpy(diskLu->luDataFileName, propVal,
2455*8fe96085Stim szeto 			    sizeof (diskLu->luDataFileName))) >=
2456*8fe96085Stim szeto 			    sizeof (diskLu->luDataFileName)) {
2457*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2458*8fe96085Stim szeto 			}
2459*8fe96085Stim szeto 			diskLu->luDataFileNameValid = B_TRUE;
2460*8fe96085Stim szeto 			break;
2461*8fe96085Stim szeto 		case STMF_LU_PROP_META_FILENAME:
2462*8fe96085Stim szeto 			if ((strlcpy(diskLu->luMetaFileName, propVal,
2463*8fe96085Stim szeto 			    sizeof (diskLu->luMetaFileName))) >=
2464*8fe96085Stim szeto 			    sizeof (diskLu->luMetaFileName)) {
2465*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2466*8fe96085Stim szeto 			}
2467*8fe96085Stim szeto 			diskLu->luMetaFileNameValid = B_TRUE;
2468*8fe96085Stim szeto 			break;
2469*8fe96085Stim szeto 		case STMF_LU_PROP_PID:
2470*8fe96085Stim szeto 			if ((propSize = strlen(propVal)) >
2471*8fe96085Stim szeto 			    sizeof (diskLu->pid)) {
2472*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2473*8fe96085Stim szeto 			}
2474*8fe96085Stim szeto 			(void) strncpy(diskLu->pid, propVal, propSize);
2475*8fe96085Stim szeto 			diskLu->pidValid = B_TRUE;
2476*8fe96085Stim szeto 			break;
2477*8fe96085Stim szeto 		case STMF_LU_PROP_SERIAL_NUM:
2478*8fe96085Stim szeto 			if ((propSize = strlen(propVal)) >
2479*8fe96085Stim szeto 			    (sizeof (diskLu->serialNum) - 1)) {
2480*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2481*8fe96085Stim szeto 			}
2482*8fe96085Stim szeto 			(void) strncpy(diskLu->serialNum, propVal, propSize);
2483*8fe96085Stim szeto 			diskLu->serialNumValid = B_TRUE;
2484*8fe96085Stim szeto 			break;
2485*8fe96085Stim szeto 		case STMF_LU_PROP_SIZE:
2486*8fe96085Stim szeto 			if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
2487*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2488*8fe96085Stim szeto 			}
2489*8fe96085Stim szeto 			diskLu->luSizeValid = B_TRUE;
2490*8fe96085Stim szeto 			break;
2491*8fe96085Stim szeto 		case STMF_LU_PROP_VID:
2492*8fe96085Stim szeto 			if ((propSize = strlen(propVal)) >
2493*8fe96085Stim szeto 			    sizeof (diskLu->vid)) {
2494*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_PROPSIZE);
2495*8fe96085Stim szeto 			}
2496*8fe96085Stim szeto 			(void) strncpy(diskLu->vid, propVal, propSize);
2497*8fe96085Stim szeto 			diskLu->vidValid = B_TRUE;
2498*8fe96085Stim szeto 			break;
2499*8fe96085Stim szeto 		case STMF_LU_PROP_WRITE_PROTECT:
2500*8fe96085Stim szeto 			if (strcasecmp(propVal, "TRUE") == 0) {
2501*8fe96085Stim szeto 				diskLu->writeProtectEnable = B_TRUE;
2502*8fe96085Stim szeto 			} else if (strcasecmp(propVal, "FALSE") == 0) {
2503*8fe96085Stim szeto 				diskLu->writeProtectEnable = B_FALSE;
2504*8fe96085Stim szeto 			} else {
2505*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2506*8fe96085Stim szeto 			}
2507*8fe96085Stim szeto 			diskLu->writeProtectEnableValid = B_TRUE;
2508*8fe96085Stim szeto 			break;
2509*8fe96085Stim szeto 		case STMF_LU_PROP_WRITE_CACHE_DISABLE:
2510*8fe96085Stim szeto 			if (strcasecmp(propVal, "TRUE") == 0) {
2511*8fe96085Stim szeto 				diskLu->writebackCacheDisable = B_TRUE;
2512*8fe96085Stim szeto 			} else if (strcasecmp(propVal, "FALSE") == 0) {
2513*8fe96085Stim szeto 				diskLu->writebackCacheDisable = B_FALSE;
2514*8fe96085Stim szeto 			} else {
2515*8fe96085Stim szeto 				return (STMF_ERROR_INVALID_ARG);
2516*8fe96085Stim szeto 			}
2517*8fe96085Stim szeto 			diskLu->writebackCacheDisableValid = B_TRUE;
2518*8fe96085Stim szeto 			break;
2519*8fe96085Stim szeto 		default:
2520*8fe96085Stim szeto 			ret = STMF_ERROR_NO_PROP;
2521*8fe96085Stim szeto 			break;
2522*8fe96085Stim szeto 	}
2523*8fe96085Stim szeto 	return (ret);
2524*8fe96085Stim szeto }
2525*8fe96085Stim szeto 
2526*8fe96085Stim szeto static int
2527*8fe96085Stim szeto checkHexUpper(char *buf)
2528*8fe96085Stim szeto {
2529*8fe96085Stim szeto 	int i;
2530*8fe96085Stim szeto 
2531*8fe96085Stim szeto 	for (i = 0; i < strlen(buf); i++) {
2532*8fe96085Stim szeto 		if (isxdigit(buf[i])) {
2533*8fe96085Stim szeto 			buf[i] = toupper(buf[i]);
2534*8fe96085Stim szeto 			continue;
2535*8fe96085Stim szeto 		}
2536*8fe96085Stim szeto 		return (-1);
2537*8fe96085Stim szeto 	}
2538*8fe96085Stim szeto 
2539*8fe96085Stim szeto 	return (0);
2540*8fe96085Stim szeto }
2541*8fe96085Stim szeto 
2542*8fe96085Stim szeto /*
2543*8fe96085Stim szeto  * Given a numeric suffix, convert the value into a number of bits that the
2544*8fe96085Stim szeto  * resulting value must be shifted.
2545*8fe96085Stim szeto  * Code lifted from libzfs_util.c
2546*8fe96085Stim szeto  */
2547*8fe96085Stim szeto static int
2548*8fe96085Stim szeto strToShift(const char *buf)
2549*8fe96085Stim szeto {
2550*8fe96085Stim szeto 	const char *ends = "BKMGTPE";
2551*8fe96085Stim szeto 	int i;
2552*8fe96085Stim szeto 
2553*8fe96085Stim szeto 	if (buf[0] == '\0')
2554*8fe96085Stim szeto 		return (0);
2555*8fe96085Stim szeto 
2556*8fe96085Stim szeto 	for (i = 0; i < strlen(ends); i++) {
2557*8fe96085Stim szeto 		if (toupper(buf[0]) == ends[i])
2558*8fe96085Stim szeto 			return (10*i);
2559*8fe96085Stim szeto 	}
2560*8fe96085Stim szeto 
2561*8fe96085Stim szeto 	return (-1);
2562*8fe96085Stim szeto }
2563*8fe96085Stim szeto 
2564*8fe96085Stim szeto int
2565*8fe96085Stim szeto stmfFreeLuResource(luResource hdl)
2566*8fe96085Stim szeto {
2567*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
2568*8fe96085Stim szeto 	if (hdl == NULL) {
2569*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
2570*8fe96085Stim szeto 	}
2571*8fe96085Stim szeto 
2572*8fe96085Stim szeto 	luResourceImpl *hdlImpl = hdl;
2573*8fe96085Stim szeto 	free(hdlImpl->resource);
2574*8fe96085Stim szeto 	free(hdlImpl);
2575*8fe96085Stim szeto 	return (ret);
2576*8fe96085Stim szeto }
2577*8fe96085Stim szeto 
2578*8fe96085Stim szeto /*
2579*8fe96085Stim szeto  * Convert a string of the form '100G' into a real number. Used when setting
2580*8fe96085Stim szeto  * the size of a logical unit.
2581*8fe96085Stim szeto  * Code lifted from libzfs_util.c
2582*8fe96085Stim szeto  */
2583*8fe96085Stim szeto static int
2584*8fe96085Stim szeto niceStrToNum(const char *value, uint64_t *num)
2585*8fe96085Stim szeto {
2586*8fe96085Stim szeto 	char *end;
2587*8fe96085Stim szeto 	int shift;
2588*8fe96085Stim szeto 
2589*8fe96085Stim szeto 	*num = 0;
2590*8fe96085Stim szeto 
2591*8fe96085Stim szeto 	/* Check to see if this looks like a number.  */
2592*8fe96085Stim szeto 	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
2593*8fe96085Stim szeto 		return (-1);
2594*8fe96085Stim szeto 	}
2595*8fe96085Stim szeto 
2596*8fe96085Stim szeto 	/* Rely on stroull() to process the numeric portion.  */
2597*8fe96085Stim szeto 	errno = 0;
2598*8fe96085Stim szeto 	*num = strtoull(value, &end, 10);
2599*8fe96085Stim szeto 
2600*8fe96085Stim szeto 	/*
2601*8fe96085Stim szeto 	 * Check for ERANGE, which indicates that the value is too large to fit
2602*8fe96085Stim szeto 	 * in a 64-bit value.
2603*8fe96085Stim szeto 	 */
2604*8fe96085Stim szeto 	if (errno == ERANGE) {
2605*8fe96085Stim szeto 		return (-1);
2606*8fe96085Stim szeto 	}
2607*8fe96085Stim szeto 
2608*8fe96085Stim szeto 	/*
2609*8fe96085Stim szeto 	 * If we have a decimal value, then do the computation with floating
2610*8fe96085Stim szeto 	 * point arithmetic.  Otherwise, use standard arithmetic.
2611*8fe96085Stim szeto 	 */
2612*8fe96085Stim szeto 	if (*end == '.') {
2613*8fe96085Stim szeto 		double fval = strtod(value, &end);
2614*8fe96085Stim szeto 
2615*8fe96085Stim szeto 		if ((shift = strToShift(end)) == -1) {
2616*8fe96085Stim szeto 			return (-1);
2617*8fe96085Stim szeto 		}
2618*8fe96085Stim szeto 
2619*8fe96085Stim szeto 		fval *= pow(2, shift);
2620*8fe96085Stim szeto 
2621*8fe96085Stim szeto 		if (fval > UINT64_MAX) {
2622*8fe96085Stim szeto 			return (-1);
2623*8fe96085Stim szeto 		}
2624*8fe96085Stim szeto 
2625*8fe96085Stim szeto 		*num = (uint64_t)fval;
2626*8fe96085Stim szeto 	} else {
2627*8fe96085Stim szeto 		if ((shift = strToShift(end)) == -1) {
2628*8fe96085Stim szeto 			return (-1);
2629*8fe96085Stim szeto 		}
2630*8fe96085Stim szeto 
2631*8fe96085Stim szeto 		/* Check for overflow */
2632*8fe96085Stim szeto 		if (shift >= 64 || (*num << shift) >> shift != *num) {
2633*8fe96085Stim szeto 			return (-1);
2634*8fe96085Stim szeto 		}
2635*8fe96085Stim szeto 
2636*8fe96085Stim szeto 		*num <<= shift;
2637*8fe96085Stim szeto 	}
2638*8fe96085Stim szeto 
2639*8fe96085Stim szeto 	return (0);
2640*8fe96085Stim szeto }
2641*8fe96085Stim szeto 
2642*8fe96085Stim szeto /*
2643fcf3ce44SJohn Forte  * stmfCreateTargetGroup
2644fcf3ce44SJohn Forte  *
2645fcf3ce44SJohn Forte  * Purpose: Create a local port group
2646fcf3ce44SJohn Forte  *
2647fcf3ce44SJohn Forte  * targetGroupName - name of local port group to create
2648fcf3ce44SJohn Forte  */
2649fcf3ce44SJohn Forte int
2650fcf3ce44SJohn Forte stmfCreateTargetGroup(stmfGroupName *targetGroupName)
2651fcf3ce44SJohn Forte {
2652fcf3ce44SJohn Forte 	int ret;
2653fcf3ce44SJohn Forte 	int fd;
2654fcf3ce44SJohn Forte 
2655fcf3ce44SJohn Forte 	if (targetGroupName == NULL ||
2656fcf3ce44SJohn Forte 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
2657fcf3ce44SJohn Forte 	    == sizeof (stmfGroupName))) {
2658fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2659fcf3ce44SJohn Forte 	}
2660fcf3ce44SJohn Forte 
2661fcf3ce44SJohn Forte 	/* Check to ensure service exists */
2662fcf3ce44SJohn Forte 	if (psCheckService() != STMF_STATUS_SUCCESS) {
2663fcf3ce44SJohn Forte 		return (STMF_ERROR_SERVICE_NOT_FOUND);
2664fcf3ce44SJohn Forte 	}
2665fcf3ce44SJohn Forte 
2666fcf3ce44SJohn Forte 	/* call init */
2667fcf3ce44SJohn Forte 	ret = initializeConfig();
2668fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
2669fcf3ce44SJohn Forte 		return (ret);
2670fcf3ce44SJohn Forte 	}
2671fcf3ce44SJohn Forte 
2672fcf3ce44SJohn Forte 	/*
2673fcf3ce44SJohn Forte 	 * Open control node for stmf
2674fcf3ce44SJohn Forte 	 */
2675fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
2676fcf3ce44SJohn Forte 		return (ret);
2677fcf3ce44SJohn Forte 
2678fcf3ce44SJohn Forte 	/*
2679fcf3ce44SJohn Forte 	 * Add the group to the driver
2680fcf3ce44SJohn Forte 	 */
2681fcf3ce44SJohn Forte 	if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
2682fcf3ce44SJohn Forte 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
2683fcf3ce44SJohn Forte 		goto done;
2684fcf3ce44SJohn Forte 	}
2685fcf3ce44SJohn Forte 
2686*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
2687*8fe96085Stim szeto 		goto done;
2688*8fe96085Stim szeto 	}
2689*8fe96085Stim szeto 
2690fcf3ce44SJohn Forte 	/*
2691fcf3ce44SJohn Forte 	 * If the add to the driver was successful, add it to the persistent
2692fcf3ce44SJohn Forte 	 * store.
2693fcf3ce44SJohn Forte 	 */
2694fcf3ce44SJohn Forte 	ret = psCreateTargetGroup((char *)targetGroupName);
2695fcf3ce44SJohn Forte 	switch (ret) {
2696fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
2697fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
2698fcf3ce44SJohn Forte 			break;
2699fcf3ce44SJohn Forte 		case STMF_PS_ERROR_EXISTS:
2700fcf3ce44SJohn Forte 			ret = STMF_ERROR_EXISTS;
2701fcf3ce44SJohn Forte 			break;
2702fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
2703fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
2704fcf3ce44SJohn Forte 			break;
2705fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2706fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2707fcf3ce44SJohn Forte 			break;
2708fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
2709fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2710fcf3ce44SJohn Forte 			break;
2711fcf3ce44SJohn Forte 		default:
2712fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
2713fcf3ce44SJohn Forte 			    "stmfCreateTargetGroup:psCreateTargetGroup"
2714fcf3ce44SJohn Forte 			    ":error(%d)", ret);
2715fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
2716fcf3ce44SJohn Forte 			break;
2717fcf3ce44SJohn Forte 	}
2718fcf3ce44SJohn Forte 
2719fcf3ce44SJohn Forte done:
2720fcf3ce44SJohn Forte 	(void) close(fd);
2721fcf3ce44SJohn Forte 	return (ret);
2722fcf3ce44SJohn Forte }
2723fcf3ce44SJohn Forte 
2724fcf3ce44SJohn Forte /*
2725fcf3ce44SJohn Forte  * stmfDeleteHostGroup
2726fcf3ce44SJohn Forte  *
2727fcf3ce44SJohn Forte  * Purpose: Delete an initiator or local port group
2728fcf3ce44SJohn Forte  *
2729fcf3ce44SJohn Forte  * hostGroupName - group to delete
2730fcf3ce44SJohn Forte  */
2731fcf3ce44SJohn Forte int
2732fcf3ce44SJohn Forte stmfDeleteHostGroup(stmfGroupName *hostGroupName)
2733fcf3ce44SJohn Forte {
2734fcf3ce44SJohn Forte 	int ret;
2735fcf3ce44SJohn Forte 	int fd;
2736fcf3ce44SJohn Forte 
2737fcf3ce44SJohn Forte 	if (hostGroupName == NULL) {
2738fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2739fcf3ce44SJohn Forte 	}
2740fcf3ce44SJohn Forte 
2741fcf3ce44SJohn Forte 	/* Check to ensure service exists */
2742fcf3ce44SJohn Forte 	if (psCheckService() != STMF_STATUS_SUCCESS) {
2743fcf3ce44SJohn Forte 		return (STMF_ERROR_SERVICE_NOT_FOUND);
2744fcf3ce44SJohn Forte 	}
2745fcf3ce44SJohn Forte 
2746fcf3ce44SJohn Forte 	/* call init */
2747fcf3ce44SJohn Forte 	ret = initializeConfig();
2748fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
2749fcf3ce44SJohn Forte 		return (ret);
2750fcf3ce44SJohn Forte 	}
2751fcf3ce44SJohn Forte 
2752fcf3ce44SJohn Forte 	/*
2753fcf3ce44SJohn Forte 	 * Open control node for stmf
2754fcf3ce44SJohn Forte 	 */
2755fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
2756fcf3ce44SJohn Forte 		return (ret);
2757fcf3ce44SJohn Forte 
2758fcf3ce44SJohn Forte 	/*
2759fcf3ce44SJohn Forte 	 * Remove the group from the driver
2760fcf3ce44SJohn Forte 	 */
2761fcf3ce44SJohn Forte 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
2762fcf3ce44SJohn Forte 	    hostGroupName)) != STMF_STATUS_SUCCESS) {
2763fcf3ce44SJohn Forte 		goto done;
2764fcf3ce44SJohn Forte 	}
2765fcf3ce44SJohn Forte 
2766*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
2767*8fe96085Stim szeto 		goto done;
2768*8fe96085Stim szeto 	}
2769*8fe96085Stim szeto 
2770fcf3ce44SJohn Forte 	/*
2771fcf3ce44SJohn Forte 	 * If the remove from the driver was successful, remove it from the
2772fcf3ce44SJohn Forte 	 * persistent store.
2773fcf3ce44SJohn Forte 	 */
2774fcf3ce44SJohn Forte 	ret = psDeleteHostGroup((char *)hostGroupName);
2775fcf3ce44SJohn Forte 	switch (ret) {
2776fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
2777fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
2778fcf3ce44SJohn Forte 			break;
2779fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
2780fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
2781fcf3ce44SJohn Forte 			break;
2782fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
2783fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
2784fcf3ce44SJohn Forte 			break;
2785fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2786fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2787fcf3ce44SJohn Forte 			break;
2788fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
2789fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2790fcf3ce44SJohn Forte 			break;
2791fcf3ce44SJohn Forte 		default:
2792fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
2793fcf3ce44SJohn Forte 			    "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
2794fcf3ce44SJohn Forte 			    ret);
2795fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
2796fcf3ce44SJohn Forte 			break;
2797fcf3ce44SJohn Forte 	}
2798fcf3ce44SJohn Forte 
2799fcf3ce44SJohn Forte done:
2800fcf3ce44SJohn Forte 	(void) close(fd);
2801fcf3ce44SJohn Forte 	return (ret);
2802fcf3ce44SJohn Forte }
2803fcf3ce44SJohn Forte 
2804fcf3ce44SJohn Forte /*
2805fcf3ce44SJohn Forte  * stmfDeleteTargetGroup
2806fcf3ce44SJohn Forte  *
2807fcf3ce44SJohn Forte  * Purpose: Delete an initiator or local port group
2808fcf3ce44SJohn Forte  *
2809fcf3ce44SJohn Forte  * targetGroupName - group to delete
2810fcf3ce44SJohn Forte  */
2811fcf3ce44SJohn Forte int
2812fcf3ce44SJohn Forte stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
2813fcf3ce44SJohn Forte {
2814fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
2815fcf3ce44SJohn Forte 	int fd;
2816fcf3ce44SJohn Forte 
2817fcf3ce44SJohn Forte 	if (targetGroupName == NULL) {
2818fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2819fcf3ce44SJohn Forte 	}
2820fcf3ce44SJohn Forte 
2821fcf3ce44SJohn Forte 	/* Check to ensure service exists */
2822fcf3ce44SJohn Forte 	if (psCheckService() != STMF_STATUS_SUCCESS) {
2823fcf3ce44SJohn Forte 		return (STMF_ERROR_SERVICE_NOT_FOUND);
2824fcf3ce44SJohn Forte 	}
2825fcf3ce44SJohn Forte 
2826fcf3ce44SJohn Forte 	/* call init */
2827fcf3ce44SJohn Forte 	ret = initializeConfig();
2828fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
2829fcf3ce44SJohn Forte 		return (ret);
2830fcf3ce44SJohn Forte 	}
2831fcf3ce44SJohn Forte 
2832fcf3ce44SJohn Forte 	/*
2833fcf3ce44SJohn Forte 	 * Open control node for stmf
2834fcf3ce44SJohn Forte 	 */
2835fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
2836fcf3ce44SJohn Forte 		return (ret);
2837fcf3ce44SJohn Forte 
2838fcf3ce44SJohn Forte 	/*
2839fcf3ce44SJohn Forte 	 * Remove the group from the driver
2840fcf3ce44SJohn Forte 	 */
2841fcf3ce44SJohn Forte 	if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
2842fcf3ce44SJohn Forte 	    targetGroupName)) != STMF_STATUS_SUCCESS) {
2843fcf3ce44SJohn Forte 		goto done;
2844fcf3ce44SJohn Forte 	}
2845fcf3ce44SJohn Forte 
2846*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
2847*8fe96085Stim szeto 		goto done;
2848*8fe96085Stim szeto 	}
2849*8fe96085Stim szeto 
2850fcf3ce44SJohn Forte 	/*
2851fcf3ce44SJohn Forte 	 * If the remove from the driver was successful, remove it from the
2852fcf3ce44SJohn Forte 	 * persistent store.
2853fcf3ce44SJohn Forte 	 */
2854fcf3ce44SJohn Forte 	ret = psDeleteTargetGroup((char *)targetGroupName);
2855fcf3ce44SJohn Forte 	switch (ret) {
2856fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
2857fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
2858fcf3ce44SJohn Forte 			break;
2859fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
2860fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
2861fcf3ce44SJohn Forte 			break;
2862fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
2863fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
2864fcf3ce44SJohn Forte 			break;
2865fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
2866fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
2867fcf3ce44SJohn Forte 			break;
2868fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
2869fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
2870fcf3ce44SJohn Forte 			break;
2871fcf3ce44SJohn Forte 		default:
2872fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
2873fcf3ce44SJohn Forte 			    "stmfDeleteTargetGroup:psDeleteTargetGroup"
2874fcf3ce44SJohn Forte 			    ":error(%d)", ret);
2875fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
2876fcf3ce44SJohn Forte 			break;
2877fcf3ce44SJohn Forte 	}
2878fcf3ce44SJohn Forte 
2879fcf3ce44SJohn Forte done:
2880fcf3ce44SJohn Forte 	(void) close(fd);
2881fcf3ce44SJohn Forte 	return (ret);
2882fcf3ce44SJohn Forte }
2883fcf3ce44SJohn Forte 
2884fcf3ce44SJohn Forte /*
2885fcf3ce44SJohn Forte  * stmfDevidFromIscsiName
2886fcf3ce44SJohn Forte  *
2887fcf3ce44SJohn Forte  * Purpose: convert an iSCSI name to an stmf devid
2888fcf3ce44SJohn Forte  *
2889fcf3ce44SJohn Forte  * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
2890fcf3ce44SJohn Forte  * devid - on success, contains the converted iscsi name
2891fcf3ce44SJohn Forte  */
2892fcf3ce44SJohn Forte int
2893fcf3ce44SJohn Forte stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
2894fcf3ce44SJohn Forte {
2895fcf3ce44SJohn Forte 	if (devid == NULL || iscsiName == NULL)
2896fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2897fcf3ce44SJohn Forte 
2898fcf3ce44SJohn Forte 	bzero(devid, sizeof (stmfDevid));
2899fcf3ce44SJohn Forte 
2900fcf3ce44SJohn Forte 	/* Validate size of target */
2901fcf3ce44SJohn Forte 	if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
2902fcf3ce44SJohn Forte 	    devid->identLength < strlen(EUI) ||
2903fcf3ce44SJohn Forte 	    devid->identLength < strlen(IQN)) {
2904fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2905fcf3ce44SJohn Forte 	}
2906fcf3ce44SJohn Forte 
2907fcf3ce44SJohn Forte 	if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
2908fcf3ce44SJohn Forte 	    strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
2909fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2910fcf3ce44SJohn Forte 	}
2911fcf3ce44SJohn Forte 
2912fcf3ce44SJohn Forte 	/* copy UTF-8 bytes to ident */
2913fcf3ce44SJohn Forte 	bcopy(iscsiName, devid->ident, devid->identLength);
2914fcf3ce44SJohn Forte 
2915fcf3ce44SJohn Forte 	return (STMF_STATUS_SUCCESS);
2916fcf3ce44SJohn Forte }
2917fcf3ce44SJohn Forte 
2918fcf3ce44SJohn Forte /*
2919fcf3ce44SJohn Forte  * stmfDevidFromWwn
2920fcf3ce44SJohn Forte  *
2921fcf3ce44SJohn Forte  * Purpose: convert a WWN to an stmf devid
2922fcf3ce44SJohn Forte  *
2923fcf3ce44SJohn Forte  * wwn - 8-byte wwn identifier
2924fcf3ce44SJohn Forte  * devid - on success, contains the converted wwn
2925fcf3ce44SJohn Forte  */
2926fcf3ce44SJohn Forte int
2927fcf3ce44SJohn Forte stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
2928fcf3ce44SJohn Forte {
2929fcf3ce44SJohn Forte 	if (wwn == NULL || devid == NULL)
2930fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2931fcf3ce44SJohn Forte 
2932fcf3ce44SJohn Forte 	bzero(devid, sizeof (stmfDevid));
2933fcf3ce44SJohn Forte 
2934fcf3ce44SJohn Forte 	/* Copy eui prefix */
2935fcf3ce44SJohn Forte 	(void) bcopy(WWN, devid->ident, strlen(WWN));
2936fcf3ce44SJohn Forte 
2937fcf3ce44SJohn Forte 	/* Convert to ASCII uppercase hexadecimal string */
2938fcf3ce44SJohn Forte 	(void) snprintf((char *)&devid->ident[strlen(WWN)],
2939fcf3ce44SJohn Forte 	    sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
2940fcf3ce44SJohn Forte 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
2941fcf3ce44SJohn Forte 
2942fcf3ce44SJohn Forte 	devid->identLength = strlen((char *)devid->ident);
2943fcf3ce44SJohn Forte 
2944fcf3ce44SJohn Forte 	return (STMF_STATUS_SUCCESS);
2945fcf3ce44SJohn Forte }
2946fcf3ce44SJohn Forte 
2947fcf3ce44SJohn Forte /*
2948fcf3ce44SJohn Forte  * stmfFreeMemory
2949fcf3ce44SJohn Forte  *
2950fcf3ce44SJohn Forte  * Purpose: Free memory allocated by this library
2951fcf3ce44SJohn Forte  *
2952fcf3ce44SJohn Forte  * memory - previously allocated pointer of memory managed by library
2953fcf3ce44SJohn Forte  */
2954fcf3ce44SJohn Forte void
2955fcf3ce44SJohn Forte stmfFreeMemory(void *memory)
2956fcf3ce44SJohn Forte {
2957fcf3ce44SJohn Forte 	free(memory);
2958fcf3ce44SJohn Forte }
2959fcf3ce44SJohn Forte 
2960fcf3ce44SJohn Forte /*
2961*8fe96085Stim szeto  * get host group, target group list from stmf
2962fcf3ce44SJohn Forte  *
2963*8fe96085Stim szeto  * groupType - HOST_GROUP, TARGET_GROUP
2964fcf3ce44SJohn Forte  */
2965*8fe96085Stim szeto static int
2966*8fe96085Stim szeto groupListIoctl(stmfGroupList **groupList, int groupType)
2967fcf3ce44SJohn Forte {
2968fcf3ce44SJohn Forte 	int ret;
2969*8fe96085Stim szeto 	int fd;
2970*8fe96085Stim szeto 	int ioctlRet;
2971*8fe96085Stim szeto 	int i;
2972*8fe96085Stim szeto 	int cmd;
2973*8fe96085Stim szeto 	stmf_iocdata_t stmfIoctl;
2974*8fe96085Stim szeto 	/* framework group list */
2975*8fe96085Stim szeto 	stmf_group_name_t *iGroupList = NULL;
2976*8fe96085Stim szeto 	uint32_t groupListSize;
2977fcf3ce44SJohn Forte 
2978*8fe96085Stim szeto 	if (groupList == NULL) {
2979fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
2980fcf3ce44SJohn Forte 	}
2981fcf3ce44SJohn Forte 
2982*8fe96085Stim szeto 	if (groupType == HOST_GROUP) {
2983*8fe96085Stim szeto 		cmd = STMF_IOCTL_GET_HG_LIST;
2984*8fe96085Stim szeto 	} else if (groupType == TARGET_GROUP) {
2985*8fe96085Stim szeto 		cmd = STMF_IOCTL_GET_TG_LIST;
2986*8fe96085Stim szeto 	} else {
2987*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
2988*8fe96085Stim szeto 	}
2989*8fe96085Stim szeto 
2990*8fe96085Stim szeto 	/* call init */
2991*8fe96085Stim szeto 	ret = initializeConfig();
2992*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
2993*8fe96085Stim szeto 		return (ret);
2994*8fe96085Stim szeto 	}
2995*8fe96085Stim szeto 
2996*8fe96085Stim szeto 	/*
2997*8fe96085Stim szeto 	 * Open control node for stmf
2998*8fe96085Stim szeto 	 */
2999*8fe96085Stim szeto 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3000*8fe96085Stim szeto 		return (ret);
3001*8fe96085Stim szeto 
3002*8fe96085Stim szeto 	/*
3003*8fe96085Stim szeto 	 * Allocate ioctl input buffer
3004*8fe96085Stim szeto 	 */
3005*8fe96085Stim szeto 	groupListSize = ALLOC_GROUP;
3006*8fe96085Stim szeto 	groupListSize = groupListSize * (sizeof (stmf_group_name_t));
3007*8fe96085Stim szeto 	iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
3008*8fe96085Stim szeto 	if (iGroupList == NULL) {
3009*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3010*8fe96085Stim szeto 		goto done;
3011*8fe96085Stim szeto 	}
3012*8fe96085Stim szeto 
3013*8fe96085Stim szeto 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3014*8fe96085Stim szeto 	/*
3015*8fe96085Stim szeto 	 * Issue ioctl to get the group list
3016*8fe96085Stim szeto 	 */
3017*8fe96085Stim szeto 	stmfIoctl.stmf_version = STMF_VERSION_1;
3018*8fe96085Stim szeto 	stmfIoctl.stmf_obuf_size = groupListSize;
3019*8fe96085Stim szeto 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
3020*8fe96085Stim szeto 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3021*8fe96085Stim szeto 	if (ioctlRet != 0) {
3022*8fe96085Stim szeto 		switch (errno) {
3023*8fe96085Stim szeto 			case EBUSY:
3024*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
3025*8fe96085Stim szeto 				break;
3026*8fe96085Stim szeto 			case EPERM:
3027*8fe96085Stim szeto 			case EACCES:
3028*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
3029*8fe96085Stim szeto 				break;
3030*8fe96085Stim szeto 			default:
3031*8fe96085Stim szeto 				syslog(LOG_DEBUG,
3032*8fe96085Stim szeto 				    "groupListIoctl:ioctl errno(%d)",
3033*8fe96085Stim szeto 				    errno);
3034*8fe96085Stim szeto 				ret = STMF_STATUS_ERROR;
3035*8fe96085Stim szeto 				break;
3036*8fe96085Stim szeto 		}
3037*8fe96085Stim szeto 		goto done;
3038*8fe96085Stim szeto 	}
3039*8fe96085Stim szeto 	/*
3040*8fe96085Stim szeto 	 * Check whether input buffer was large enough
3041*8fe96085Stim szeto 	 */
3042*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
3043*8fe96085Stim szeto 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
3044*8fe96085Stim szeto 		    sizeof (stmf_group_name_t);
3045*8fe96085Stim szeto 		iGroupList = realloc(iGroupList, groupListSize);
3046*8fe96085Stim szeto 		if (iGroupList == NULL) {
3047*8fe96085Stim szeto 			ret = STMF_ERROR_NOMEM;
3048*8fe96085Stim szeto 			goto done;
3049*8fe96085Stim szeto 		}
3050*8fe96085Stim szeto 		stmfIoctl.stmf_obuf_size = groupListSize;
3051*8fe96085Stim szeto 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
3052*8fe96085Stim szeto 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3053*8fe96085Stim szeto 		if (ioctlRet != 0) {
3054*8fe96085Stim szeto 			switch (errno) {
3055*8fe96085Stim szeto 				case EBUSY:
3056*8fe96085Stim szeto 					ret = STMF_ERROR_BUSY;
3057*8fe96085Stim szeto 					break;
3058*8fe96085Stim szeto 				case EPERM:
3059*8fe96085Stim szeto 				case EACCES:
3060*8fe96085Stim szeto 					ret = STMF_ERROR_PERM;
3061*8fe96085Stim szeto 					break;
3062*8fe96085Stim szeto 				default:
3063*8fe96085Stim szeto 					syslog(LOG_DEBUG,
3064*8fe96085Stim szeto 					    "groupListIoctl:ioctl errno(%d)",
3065*8fe96085Stim szeto 					    errno);
3066*8fe96085Stim szeto 					ret = STMF_STATUS_ERROR;
3067*8fe96085Stim szeto 					break;
3068*8fe96085Stim szeto 			}
3069*8fe96085Stim szeto 			goto done;
3070*8fe96085Stim szeto 		}
3071*8fe96085Stim szeto 	}
3072*8fe96085Stim szeto 
3073*8fe96085Stim szeto 	/* allocate and copy to caller's buffer */
3074*8fe96085Stim szeto 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) *
3075*8fe96085Stim szeto 	    stmfIoctl.stmf_obuf_nentries);
3076*8fe96085Stim szeto 	if (*groupList == NULL) {
3077*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3078*8fe96085Stim szeto 		goto done;
3079*8fe96085Stim szeto 	}
3080*8fe96085Stim szeto 	(*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
3081*8fe96085Stim szeto 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
3082*8fe96085Stim szeto 		bcopy(iGroupList->name, (*groupList)->name[i],
3083*8fe96085Stim szeto 		    sizeof (stmfGroupName));
3084*8fe96085Stim szeto 		iGroupList++;
3085*8fe96085Stim szeto 	}
3086*8fe96085Stim szeto 
3087*8fe96085Stim szeto done:
3088*8fe96085Stim szeto 	free(iGroupList);
3089*8fe96085Stim szeto 	(void) close(fd);
3090*8fe96085Stim szeto 	return (ret);
3091*8fe96085Stim szeto }
3092*8fe96085Stim szeto 
3093*8fe96085Stim szeto /*
3094*8fe96085Stim szeto  * get host group members, target group members from stmf
3095*8fe96085Stim szeto  *
3096*8fe96085Stim szeto  * groupProps - allocated on success
3097*8fe96085Stim szeto  *
3098*8fe96085Stim szeto  * groupType - HOST_GROUP, TARGET_GROUP
3099*8fe96085Stim szeto  */
3100*8fe96085Stim szeto static int
3101*8fe96085Stim szeto groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
3102*8fe96085Stim szeto     int groupType)
3103*8fe96085Stim szeto {
3104*8fe96085Stim szeto 	int ret;
3105*8fe96085Stim szeto 	int fd;
3106*8fe96085Stim szeto 	int ioctlRet;
3107*8fe96085Stim szeto 	int i;
3108*8fe96085Stim szeto 	int cmd;
3109*8fe96085Stim szeto 	stmf_iocdata_t stmfIoctl;
3110*8fe96085Stim szeto 	/* framework group list */
3111*8fe96085Stim szeto 	stmf_group_name_t iGroupName;
3112*8fe96085Stim szeto 	stmf_ge_ident_t *iGroupMembers;
3113*8fe96085Stim szeto 	uint32_t groupListSize;
3114*8fe96085Stim szeto 
3115*8fe96085Stim szeto 	if (groupName == NULL) {
3116*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3117*8fe96085Stim szeto 	}
3118*8fe96085Stim szeto 
3119*8fe96085Stim szeto 	if (groupType == HOST_GROUP) {
3120*8fe96085Stim szeto 		cmd = STMF_IOCTL_GET_HG_ENTRIES;
3121*8fe96085Stim szeto 	} else if (groupType == TARGET_GROUP) {
3122*8fe96085Stim szeto 		cmd = STMF_IOCTL_GET_TG_ENTRIES;
3123*8fe96085Stim szeto 	} else {
3124*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3125*8fe96085Stim szeto 	}
3126*8fe96085Stim szeto 
3127*8fe96085Stim szeto 	/* call init */
3128*8fe96085Stim szeto 	ret = initializeConfig();
3129*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
3130*8fe96085Stim szeto 		return (ret);
3131*8fe96085Stim szeto 	}
3132*8fe96085Stim szeto 
3133*8fe96085Stim szeto 	/*
3134*8fe96085Stim szeto 	 * Open control node for stmf
3135*8fe96085Stim szeto 	 */
3136*8fe96085Stim szeto 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3137*8fe96085Stim szeto 		return (ret);
3138*8fe96085Stim szeto 
3139*8fe96085Stim szeto 	bzero(&iGroupName, sizeof (iGroupName));
3140*8fe96085Stim szeto 
3141*8fe96085Stim szeto 	bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
3142*8fe96085Stim szeto 
3143*8fe96085Stim szeto 	iGroupName.name_size = strlen((char *)groupName);
3144*8fe96085Stim szeto 
3145*8fe96085Stim szeto 	/*
3146*8fe96085Stim szeto 	 * Allocate ioctl input buffer
3147*8fe96085Stim szeto 	 */
3148*8fe96085Stim szeto 	groupListSize = ALLOC_GRP_MEMBER;
3149*8fe96085Stim szeto 	groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
3150*8fe96085Stim szeto 	iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
3151*8fe96085Stim szeto 	if (iGroupMembers == NULL) {
3152*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3153*8fe96085Stim szeto 		goto done;
3154*8fe96085Stim szeto 	}
3155*8fe96085Stim szeto 
3156*8fe96085Stim szeto 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3157*8fe96085Stim szeto 	/*
3158*8fe96085Stim szeto 	 * Issue ioctl to get the group list
3159*8fe96085Stim szeto 	 */
3160*8fe96085Stim szeto 	stmfIoctl.stmf_version = STMF_VERSION_1;
3161*8fe96085Stim szeto 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3162*8fe96085Stim szeto 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
3163*8fe96085Stim szeto 	stmfIoctl.stmf_obuf_size = groupListSize;
3164*8fe96085Stim szeto 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
3165*8fe96085Stim szeto 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3166*8fe96085Stim szeto 	if (ioctlRet != 0) {
3167*8fe96085Stim szeto 		switch (errno) {
3168*8fe96085Stim szeto 			case EBUSY:
3169*8fe96085Stim szeto 				ret = STMF_ERROR_BUSY;
3170*8fe96085Stim szeto 				break;
3171*8fe96085Stim szeto 			case EPERM:
3172*8fe96085Stim szeto 			case EACCES:
3173*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
3174*8fe96085Stim szeto 				break;
3175*8fe96085Stim szeto 			default:
3176*8fe96085Stim szeto 				syslog(LOG_DEBUG,
3177*8fe96085Stim szeto 				    "groupListIoctl:ioctl errno(%d)",
3178*8fe96085Stim szeto 				    errno);
3179*8fe96085Stim szeto 				ret = STMF_STATUS_ERROR;
3180*8fe96085Stim szeto 				break;
3181*8fe96085Stim szeto 		}
3182*8fe96085Stim szeto 		goto done;
3183*8fe96085Stim szeto 	}
3184*8fe96085Stim szeto 	/*
3185*8fe96085Stim szeto 	 * Check whether input buffer was large enough
3186*8fe96085Stim szeto 	 */
3187*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
3188*8fe96085Stim szeto 		groupListSize = stmfIoctl.stmf_obuf_max_nentries *
3189*8fe96085Stim szeto 		    sizeof (stmf_ge_ident_t);
3190*8fe96085Stim szeto 		iGroupMembers = realloc(iGroupMembers, groupListSize);
3191*8fe96085Stim szeto 		if (iGroupMembers == NULL) {
3192*8fe96085Stim szeto 			ret = STMF_ERROR_NOMEM;
3193*8fe96085Stim szeto 			goto done;
3194*8fe96085Stim szeto 		}
3195*8fe96085Stim szeto 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3196*8fe96085Stim szeto 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
3197*8fe96085Stim szeto 		stmfIoctl.stmf_obuf_size = groupListSize;
3198*8fe96085Stim szeto 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
3199*8fe96085Stim szeto 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3200*8fe96085Stim szeto 		if (ioctlRet != 0) {
3201*8fe96085Stim szeto 			switch (errno) {
3202*8fe96085Stim szeto 				case EBUSY:
3203*8fe96085Stim szeto 					ret = STMF_ERROR_BUSY;
3204*8fe96085Stim szeto 					break;
3205*8fe96085Stim szeto 				case EPERM:
3206*8fe96085Stim szeto 				case EACCES:
3207*8fe96085Stim szeto 					ret = STMF_ERROR_PERM;
3208*8fe96085Stim szeto 					break;
3209*8fe96085Stim szeto 				default:
3210*8fe96085Stim szeto 					syslog(LOG_DEBUG,
3211*8fe96085Stim szeto 					    "groupListIoctl:ioctl errno(%d)",
3212*8fe96085Stim szeto 					    errno);
3213*8fe96085Stim szeto 					ret = STMF_STATUS_ERROR;
3214*8fe96085Stim szeto 					break;
3215*8fe96085Stim szeto 			}
3216*8fe96085Stim szeto 			goto done;
3217*8fe96085Stim szeto 		}
3218*8fe96085Stim szeto 	}
3219*8fe96085Stim szeto 
3220*8fe96085Stim szeto 	/* allocate and copy to caller's buffer */
3221*8fe96085Stim szeto 	*groupProps = (stmfGroupProperties *)calloc(1,
3222*8fe96085Stim szeto 	    sizeof (stmfGroupProperties) * stmfIoctl.stmf_obuf_nentries);
3223*8fe96085Stim szeto 	if (*groupProps == NULL) {
3224*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3225*8fe96085Stim szeto 		goto done;
3226*8fe96085Stim szeto 	}
3227*8fe96085Stim szeto 	(*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
3228*8fe96085Stim szeto 	for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
3229*8fe96085Stim szeto 		(*groupProps)->name[i].identLength =
3230*8fe96085Stim szeto 		    iGroupMembers->ident_size;
3231*8fe96085Stim szeto 		bcopy(iGroupMembers->ident, (*groupProps)->name[i].ident,
3232*8fe96085Stim szeto 		    iGroupMembers->ident_size);
3233*8fe96085Stim szeto 		iGroupMembers++;
3234*8fe96085Stim szeto 	}
3235*8fe96085Stim szeto 
3236*8fe96085Stim szeto done:
3237*8fe96085Stim szeto 	free(iGroupMembers);
3238*8fe96085Stim szeto 	(void) close(fd);
3239*8fe96085Stim szeto 	return (ret);
3240*8fe96085Stim szeto }
3241*8fe96085Stim szeto 
3242*8fe96085Stim szeto /*
3243*8fe96085Stim szeto  * Purpose: access persistent config data for host groups and target groups
3244*8fe96085Stim szeto  */
3245*8fe96085Stim szeto static int
3246*8fe96085Stim szeto iLoadGroupFromPs(stmfGroupList **groupList, int type)
3247*8fe96085Stim szeto {
3248*8fe96085Stim szeto 	int ret;
3249*8fe96085Stim szeto 
3250*8fe96085Stim szeto 	if (groupList == NULL) {
3251*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3252*8fe96085Stim szeto 	}
3253*8fe96085Stim szeto 
3254*8fe96085Stim szeto 	if (type == HOST_GROUP) {
3255*8fe96085Stim szeto 		ret = psGetHostGroupList(groupList);
3256*8fe96085Stim szeto 	} else if (type == TARGET_GROUP) {
3257*8fe96085Stim szeto 		ret = psGetTargetGroupList(groupList);
3258*8fe96085Stim szeto 	} else {
3259*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3260*8fe96085Stim szeto 	}
3261fcf3ce44SJohn Forte 	switch (ret) {
3262fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
3263fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
3264fcf3ce44SJohn Forte 			break;
3265fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
3266fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
3267fcf3ce44SJohn Forte 			break;
3268fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
3269fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
3270fcf3ce44SJohn Forte 			break;
3271fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3272fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3273fcf3ce44SJohn Forte 			break;
3274fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
3275fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3276fcf3ce44SJohn Forte 			break;
3277fcf3ce44SJohn Forte 		default:
3278fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
3279fcf3ce44SJohn Forte 			    "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
3280fcf3ce44SJohn Forte 			    ret);
3281fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
3282fcf3ce44SJohn Forte 			break;
3283fcf3ce44SJohn Forte 	}
3284fcf3ce44SJohn Forte 
3285fcf3ce44SJohn Forte 	return (ret);
3286fcf3ce44SJohn Forte }
3287fcf3ce44SJohn Forte 
3288fcf3ce44SJohn Forte /*
3289*8fe96085Stim szeto  * stmfGetHostGroupList
3290fcf3ce44SJohn Forte  *
3291*8fe96085Stim szeto  * Purpose: Retrieves the list of initiator group oids
3292fcf3ce44SJohn Forte  *
3293*8fe96085Stim szeto  * hostGroupList - pointer to pointer to hostGroupList structure
3294*8fe96085Stim szeto  *                 on success, this contains the host group list.
3295fcf3ce44SJohn Forte  */
3296fcf3ce44SJohn Forte int
3297*8fe96085Stim szeto stmfGetHostGroupList(stmfGroupList **hostGroupList)
3298fcf3ce44SJohn Forte {
3299*8fe96085Stim szeto 	int ret = STMF_STATUS_ERROR;
3300fcf3ce44SJohn Forte 
3301*8fe96085Stim szeto 	if (hostGroupList == NULL) {
3302fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3303fcf3ce44SJohn Forte 	}
3304fcf3ce44SJohn Forte 
3305*8fe96085Stim szeto 	ret = groupListIoctl(hostGroupList, HOST_GROUP);
3306*8fe96085Stim szeto 	return (ret);
3307*8fe96085Stim szeto }
3308*8fe96085Stim szeto 
3309*8fe96085Stim szeto 
3310*8fe96085Stim szeto /*
3311*8fe96085Stim szeto  * Purpose: access persistent config data for host groups and target groups
3312*8fe96085Stim szeto  */
3313*8fe96085Stim szeto static int
3314*8fe96085Stim szeto iLoadGroupMembersFromPs(stmfGroupName *groupName,
3315*8fe96085Stim szeto     stmfGroupProperties **groupProp, int type)
3316*8fe96085Stim szeto {
3317*8fe96085Stim szeto 	int ret;
3318*8fe96085Stim szeto 
3319*8fe96085Stim szeto 	if (groupName == NULL) {
3320*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3321*8fe96085Stim szeto 	}
3322*8fe96085Stim szeto 
3323*8fe96085Stim szeto 	if (type == HOST_GROUP) {
3324fcf3ce44SJohn Forte 		ret = psGetHostGroupMemberList((char *)groupName, groupProp);
3325*8fe96085Stim szeto 	} else if (type == TARGET_GROUP) {
3326*8fe96085Stim szeto 		ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
3327*8fe96085Stim szeto 	} else {
3328*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3329*8fe96085Stim szeto 	}
3330fcf3ce44SJohn Forte 	switch (ret) {
3331fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
3332fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
3333fcf3ce44SJohn Forte 			break;
3334fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
3335fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
3336fcf3ce44SJohn Forte 			break;
3337fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
3338fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
3339fcf3ce44SJohn Forte 			break;
3340fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3341fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3342fcf3ce44SJohn Forte 			break;
3343fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
3344fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3345fcf3ce44SJohn Forte 			break;
3346fcf3ce44SJohn Forte 		default:
3347fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
3348*8fe96085Stim szeto 			    "iLoadGroupMembersFromPs:psGetHostGroupList:"
3349*8fe96085Stim szeto 			    "error(%d)", ret);
3350fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
3351fcf3ce44SJohn Forte 			break;
3352fcf3ce44SJohn Forte 	}
3353fcf3ce44SJohn Forte 
3354fcf3ce44SJohn Forte 	return (ret);
3355fcf3ce44SJohn Forte }
3356fcf3ce44SJohn Forte 
3357fcf3ce44SJohn Forte /*
3358*8fe96085Stim szeto  * stmfGetHostGroupMembers
3359*8fe96085Stim szeto  *
3360*8fe96085Stim szeto  * Purpose: Retrieves the group properties for a host group
3361*8fe96085Stim szeto  *
3362*8fe96085Stim szeto  * groupName - name of group for which to retrieve host group members.
3363*8fe96085Stim szeto  * groupProp - pointer to pointer to stmfGroupProperties structure
3364*8fe96085Stim szeto  *             on success, this contains the list of group members.
3365*8fe96085Stim szeto  */
3366*8fe96085Stim szeto int
3367*8fe96085Stim szeto stmfGetHostGroupMembers(stmfGroupName *groupName,
3368*8fe96085Stim szeto     stmfGroupProperties **groupProp)
3369*8fe96085Stim szeto {
3370*8fe96085Stim szeto 	int ret;
3371*8fe96085Stim szeto 
3372*8fe96085Stim szeto 	if (groupName == NULL || groupProp == NULL) {
3373*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
3374*8fe96085Stim szeto 	}
3375*8fe96085Stim szeto 
3376*8fe96085Stim szeto 	ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
3377*8fe96085Stim szeto 
3378*8fe96085Stim szeto 	return (ret);
3379*8fe96085Stim szeto }
3380*8fe96085Stim szeto 
3381*8fe96085Stim szeto /*
3382fcf3ce44SJohn Forte  * stmfGetProviderData
3383fcf3ce44SJohn Forte  *
3384fcf3ce44SJohn Forte  * Purpose: Get provider data list
3385fcf3ce44SJohn Forte  *
3386fcf3ce44SJohn Forte  * providerName - name of provider for which to retrieve the data
3387fcf3ce44SJohn Forte  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
3388fcf3ce44SJohn Forte  *       retrieved.
3389fcf3ce44SJohn Forte  * providerType - type of provider for which to retrieve data.
3390fcf3ce44SJohn Forte  *		    STMF_LU_PROVIDER_TYPE
3391fcf3ce44SJohn Forte  *		    STMF_PORT_PROVIDER_TYPE
3392fcf3ce44SJohn Forte  */
3393fcf3ce44SJohn Forte int
3394fcf3ce44SJohn Forte stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
3395fcf3ce44SJohn Forte {
3396fcf3ce44SJohn Forte 	return (stmfGetProviderDataProt(providerName, nvl, providerType,
3397fcf3ce44SJohn Forte 	    NULL));
3398fcf3ce44SJohn Forte }
3399fcf3ce44SJohn Forte 
3400fcf3ce44SJohn Forte /*
3401fcf3ce44SJohn Forte  * stmfGetProviderDataProt
3402fcf3ce44SJohn Forte  *
3403fcf3ce44SJohn Forte  * Purpose: Get provider data list with token
3404fcf3ce44SJohn Forte  *
3405fcf3ce44SJohn Forte  * providerName - name of provider for which to retrieve the data
3406fcf3ce44SJohn Forte  * nvl - pointer to nvlist_t pointer which will contain the nvlist data
3407fcf3ce44SJohn Forte  *       retrieved.
3408fcf3ce44SJohn Forte  * providerType - type of provider for which to retrieve data.
3409fcf3ce44SJohn Forte  *		    STMF_LU_PROVIDER_TYPE
3410fcf3ce44SJohn Forte  *		    STMF_PORT_PROVIDER_TYPE
3411fcf3ce44SJohn Forte  * setToken - Returns the stale data token
3412fcf3ce44SJohn Forte  */
3413fcf3ce44SJohn Forte int
3414fcf3ce44SJohn Forte stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
3415fcf3ce44SJohn Forte     uint64_t *setToken)
3416fcf3ce44SJohn Forte {
3417fcf3ce44SJohn Forte 	int ret;
3418fcf3ce44SJohn Forte 
3419fcf3ce44SJohn Forte 	if (providerName == NULL || nvl == NULL) {
3420fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3421fcf3ce44SJohn Forte 	}
3422fcf3ce44SJohn Forte 	if (providerType != STMF_LU_PROVIDER_TYPE &&
3423fcf3ce44SJohn Forte 	    providerType != STMF_PORT_PROVIDER_TYPE) {
3424fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3425fcf3ce44SJohn Forte 	}
3426fcf3ce44SJohn Forte 	/* call init */
3427fcf3ce44SJohn Forte 	ret = initializeConfig();
3428fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
3429fcf3ce44SJohn Forte 		return (ret);
3430fcf3ce44SJohn Forte 	}
3431*8fe96085Stim szeto 	return (getProviderData(providerName, nvl, providerType, setToken));
3432fcf3ce44SJohn Forte }
3433fcf3ce44SJohn Forte 
3434fcf3ce44SJohn Forte /*
3435fcf3ce44SJohn Forte  * stmfGetProviderDataList
3436fcf3ce44SJohn Forte  *
3437fcf3ce44SJohn Forte  * Purpose: Get the list of providers currently persisting data
3438fcf3ce44SJohn Forte  *
3439fcf3ce44SJohn Forte  * providerList - pointer to pointer to an stmfProviderList structure allocated
3440fcf3ce44SJohn Forte  *                by the caller. Will contain the list of providers on success.
3441fcf3ce44SJohn Forte  */
3442fcf3ce44SJohn Forte int
3443fcf3ce44SJohn Forte stmfGetProviderDataList(stmfProviderList **providerList)
3444fcf3ce44SJohn Forte {
3445fcf3ce44SJohn Forte 	int ret;
3446fcf3ce44SJohn Forte 
3447fcf3ce44SJohn Forte 	ret = psGetProviderDataList(providerList);
3448fcf3ce44SJohn Forte 	switch (ret) {
3449fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
3450fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
3451fcf3ce44SJohn Forte 			break;
3452fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
3453fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
3454fcf3ce44SJohn Forte 			break;
3455fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3456fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
3457fcf3ce44SJohn Forte 			break;
3458fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
3459fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
3460fcf3ce44SJohn Forte 			break;
3461fcf3ce44SJohn Forte 		default:
3462fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
3463fcf3ce44SJohn Forte 			    "stmfGetProviderDataList:psGetProviderDataList"
3464fcf3ce44SJohn Forte 			    ":error(%d)", ret);
3465fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
3466fcf3ce44SJohn Forte 			break;
3467fcf3ce44SJohn Forte 	}
3468fcf3ce44SJohn Forte 
3469fcf3ce44SJohn Forte 	return (ret);
3470fcf3ce44SJohn Forte }
3471fcf3ce44SJohn Forte 
3472fcf3ce44SJohn Forte 
3473fcf3ce44SJohn Forte /*
3474fcf3ce44SJohn Forte  * stmfGetSessionList
3475fcf3ce44SJohn Forte  *
3476fcf3ce44SJohn Forte  * Purpose: Retrieves the session list for a target (devid)
3477fcf3ce44SJohn Forte  *
3478fcf3ce44SJohn Forte  * devid - devid of target for which to retrieve session information.
3479fcf3ce44SJohn Forte  * sessionList - pointer to pointer to stmfSessionList structure
3480fcf3ce44SJohn Forte  *             on success, this contains the list of initiator sessions.
3481fcf3ce44SJohn Forte  */
3482fcf3ce44SJohn Forte int
3483fcf3ce44SJohn Forte stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
3484fcf3ce44SJohn Forte {
3485fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
3486fcf3ce44SJohn Forte 	int fd;
3487fcf3ce44SJohn Forte 	int ioctlRet;
3488fcf3ce44SJohn Forte 	int cmd = STMF_IOCTL_SESSION_LIST;
3489fcf3ce44SJohn Forte 	int i;
3490fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
3491fcf3ce44SJohn Forte 	slist_scsi_session_t *fSessionList;
3492fcf3ce44SJohn Forte 	uint8_t ident[260];
3493fcf3ce44SJohn Forte 	uint32_t fSessionListSize;
3494fcf3ce44SJohn Forte 
3495fcf3ce44SJohn Forte 	if (sessionList == NULL || devid == NULL) {
3496fcf3ce44SJohn Forte 		ret = STMF_ERROR_INVALID_ARG;
3497fcf3ce44SJohn Forte 	}
3498fcf3ce44SJohn Forte 
3499fcf3ce44SJohn Forte 	/* call init */
3500fcf3ce44SJohn Forte 	ret = initializeConfig();
3501fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
3502fcf3ce44SJohn Forte 		return (ret);
3503fcf3ce44SJohn Forte 	}
3504fcf3ce44SJohn Forte 
3505fcf3ce44SJohn Forte 	/*
3506fcf3ce44SJohn Forte 	 * Open control node for stmf
3507fcf3ce44SJohn Forte 	 */
3508fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3509fcf3ce44SJohn Forte 		return (ret);
3510fcf3ce44SJohn Forte 
3511fcf3ce44SJohn Forte 	/*
3512fcf3ce44SJohn Forte 	 * Allocate ioctl input buffer
3513fcf3ce44SJohn Forte 	 */
3514*8fe96085Stim szeto 	fSessionListSize = ALLOC_SESSION;
3515fcf3ce44SJohn Forte 	fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
3516fcf3ce44SJohn Forte 	fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
3517fcf3ce44SJohn Forte 	if (fSessionList == NULL) {
3518fcf3ce44SJohn Forte 		return (STMF_ERROR_NOMEM);
3519fcf3ce44SJohn Forte 	}
3520fcf3ce44SJohn Forte 
3521fcf3ce44SJohn Forte 	ident[IDENT_LENGTH_BYTE] = devid->identLength;
3522fcf3ce44SJohn Forte 	bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
3523fcf3ce44SJohn Forte 	    devid->identLength);
3524fcf3ce44SJohn Forte 
3525fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3526fcf3ce44SJohn Forte 	/*
3527fcf3ce44SJohn Forte 	 * Issue ioctl to get the session list
3528fcf3ce44SJohn Forte 	 */
3529fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
3530fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
3531fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (ident);
3532fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = fSessionListSize;
3533fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
3534fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3535fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
3536fcf3ce44SJohn Forte 		switch (errno) {
3537fcf3ce44SJohn Forte 			case EBUSY:
3538fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
3539fcf3ce44SJohn Forte 				break;
3540*8fe96085Stim szeto 			case EPERM:
3541fcf3ce44SJohn Forte 			case EACCES:
3542fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
3543fcf3ce44SJohn Forte 				break;
3544fcf3ce44SJohn Forte 			default:
3545fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
3546fcf3ce44SJohn Forte 				    "stmfGetSessionList:ioctl errno(%d)",
3547fcf3ce44SJohn Forte 				    errno);
3548fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
3549fcf3ce44SJohn Forte 				break;
3550fcf3ce44SJohn Forte 		}
3551fcf3ce44SJohn Forte 		goto done;
3552fcf3ce44SJohn Forte 	}
3553fcf3ce44SJohn Forte 	/*
3554fcf3ce44SJohn Forte 	 * Check whether input buffer was large enough
3555fcf3ce44SJohn Forte 	 */
3556*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
3557fcf3ce44SJohn Forte 		fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
3558fcf3ce44SJohn Forte 		    sizeof (slist_scsi_session_t);
3559fcf3ce44SJohn Forte 		fSessionList = realloc(fSessionList, fSessionListSize);
3560fcf3ce44SJohn Forte 		if (fSessionList == NULL) {
3561fcf3ce44SJohn Forte 			return (STMF_ERROR_NOMEM);
3562fcf3ce44SJohn Forte 		}
3563fcf3ce44SJohn Forte 		stmfIoctl.stmf_obuf_size = fSessionListSize;
3564fcf3ce44SJohn Forte 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
3565fcf3ce44SJohn Forte 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3566fcf3ce44SJohn Forte 		if (ioctlRet != 0) {
3567fcf3ce44SJohn Forte 			switch (errno) {
3568fcf3ce44SJohn Forte 				case EBUSY:
3569fcf3ce44SJohn Forte 					ret = STMF_ERROR_BUSY;
3570fcf3ce44SJohn Forte 					break;
3571*8fe96085Stim szeto 				case EPERM:
3572fcf3ce44SJohn Forte 				case EACCES:
3573fcf3ce44SJohn Forte 					ret = STMF_ERROR_PERM;
3574fcf3ce44SJohn Forte 					break;
3575fcf3ce44SJohn Forte 				default:
3576fcf3ce44SJohn Forte 					syslog(LOG_DEBUG,
3577fcf3ce44SJohn Forte 					    "stmfGetSessionList:ioctl "
3578fcf3ce44SJohn Forte 					    "errno(%d)", errno);
3579fcf3ce44SJohn Forte 					ret = STMF_STATUS_ERROR;
3580fcf3ce44SJohn Forte 					break;
3581fcf3ce44SJohn Forte 			}
3582fcf3ce44SJohn Forte 			goto done;
3583fcf3ce44SJohn Forte 		}
3584fcf3ce44SJohn Forte 	}
3585fcf3ce44SJohn Forte 
3586fcf3ce44SJohn Forte 	/*
3587fcf3ce44SJohn Forte 	 * allocate caller's buffer with the final size
3588fcf3ce44SJohn Forte 	 */
3589fcf3ce44SJohn Forte 	*sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
3590fcf3ce44SJohn Forte 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
3591fcf3ce44SJohn Forte 	if (*sessionList == NULL) {
3592fcf3ce44SJohn Forte 		ret = STMF_ERROR_NOMEM;
3593fcf3ce44SJohn Forte 		free(sessionList);
3594fcf3ce44SJohn Forte 		goto done;
3595fcf3ce44SJohn Forte 	}
3596fcf3ce44SJohn Forte 
3597fcf3ce44SJohn Forte 	(*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
3598fcf3ce44SJohn Forte 
3599fcf3ce44SJohn Forte 	/*
3600fcf3ce44SJohn Forte 	 * copy session info to caller's buffer
3601fcf3ce44SJohn Forte 	 */
3602fcf3ce44SJohn Forte 	for (i = 0; i < (*sessionList)->cnt; i++) {
3603fcf3ce44SJohn Forte 		(*sessionList)->session[i].initiator.identLength =
3604fcf3ce44SJohn Forte 		    fSessionList->initiator[IDENT_LENGTH_BYTE];
3605fcf3ce44SJohn Forte 		bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
3606fcf3ce44SJohn Forte 		    (*sessionList)->session[i].initiator.ident,
3607fcf3ce44SJohn Forte 		    STMF_IDENT_LENGTH);
3608fcf3ce44SJohn Forte 		bcopy(&(fSessionList->alias),
3609fcf3ce44SJohn Forte 		    &((*sessionList)->session[i].alias),
3610fcf3ce44SJohn Forte 		    sizeof ((*sessionList)->session[i].alias));
3611fcf3ce44SJohn Forte 		bcopy(&(fSessionList++->creation_time),
3612fcf3ce44SJohn Forte 		    &((*sessionList)->session[i].creationTime),
3613fcf3ce44SJohn Forte 		    sizeof (time_t));
3614fcf3ce44SJohn Forte 	}
3615fcf3ce44SJohn Forte done:
3616fcf3ce44SJohn Forte 	(void) close(fd);
3617fcf3ce44SJohn Forte 	return (ret);
3618fcf3ce44SJohn Forte }
3619fcf3ce44SJohn Forte 
3620fcf3ce44SJohn Forte /*
3621fcf3ce44SJohn Forte  * stmfGetTargetGroupList
3622fcf3ce44SJohn Forte  *
3623fcf3ce44SJohn Forte  * Purpose: Retrieves the list of target groups
3624fcf3ce44SJohn Forte  *
3625fcf3ce44SJohn Forte  * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
3626fcf3ce44SJohn Forte  *		     success, it contains the list of target groups.
3627fcf3ce44SJohn Forte  */
3628fcf3ce44SJohn Forte int
3629fcf3ce44SJohn Forte stmfGetTargetGroupList(stmfGroupList **targetGroupList)
3630fcf3ce44SJohn Forte {
3631fcf3ce44SJohn Forte 	int ret;
3632fcf3ce44SJohn Forte 
3633fcf3ce44SJohn Forte 	if (targetGroupList == NULL) {
3634fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3635fcf3ce44SJohn Forte 	}
3636fcf3ce44SJohn Forte 
3637*8fe96085Stim szeto 	ret = groupListIoctl(targetGroupList, TARGET_GROUP);
3638fcf3ce44SJohn Forte 	return (ret);
3639fcf3ce44SJohn Forte }
3640fcf3ce44SJohn Forte 
3641fcf3ce44SJohn Forte /*
3642fcf3ce44SJohn Forte  * stmfGetTargetGroupMembers
3643fcf3ce44SJohn Forte  *
3644fcf3ce44SJohn Forte  * Purpose: Retrieves the group members for a target group
3645fcf3ce44SJohn Forte  *
3646fcf3ce44SJohn Forte  * groupName - name of target group for which to retrieve members.
3647fcf3ce44SJohn Forte  * groupProp - pointer to pointer to stmfGroupProperties structure
3648fcf3ce44SJohn Forte  *             on success, this contains the list of group members.
3649fcf3ce44SJohn Forte  */
3650fcf3ce44SJohn Forte int
3651fcf3ce44SJohn Forte stmfGetTargetGroupMembers(stmfGroupName *groupName,
3652fcf3ce44SJohn Forte     stmfGroupProperties **groupProp)
3653fcf3ce44SJohn Forte {
3654fcf3ce44SJohn Forte 	int ret;
3655fcf3ce44SJohn Forte 
3656fcf3ce44SJohn Forte 	if (groupName == NULL || groupProp == NULL) {
3657fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3658fcf3ce44SJohn Forte 	}
3659fcf3ce44SJohn Forte 
3660*8fe96085Stim szeto 	ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
3661fcf3ce44SJohn Forte 
3662fcf3ce44SJohn Forte 	return (ret);
3663fcf3ce44SJohn Forte }
3664fcf3ce44SJohn Forte 
3665fcf3ce44SJohn Forte /*
3666fcf3ce44SJohn Forte  * stmfGetTargetList
3667fcf3ce44SJohn Forte  *
3668fcf3ce44SJohn Forte  * Purpose: Retrieves the list of target ports
3669fcf3ce44SJohn Forte  *
3670fcf3ce44SJohn Forte  * targetList - pointer to a pointer to an stmfDevidList structure.
3671fcf3ce44SJohn Forte  *		    On success, it contains the list of local ports (target).
3672fcf3ce44SJohn Forte  */
3673fcf3ce44SJohn Forte int
3674fcf3ce44SJohn Forte stmfGetTargetList(stmfDevidList **targetList)
3675fcf3ce44SJohn Forte {
3676fcf3ce44SJohn Forte 	int ret;
3677fcf3ce44SJohn Forte 	int fd;
3678fcf3ce44SJohn Forte 	int ioctlRet;
3679fcf3ce44SJohn Forte 	int i;
3680fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
3681fcf3ce44SJohn Forte 	/* framework target port list */
3682*8fe96085Stim szeto 	slist_target_port_t *fTargetList, *fTargetListP = NULL;
3683fcf3ce44SJohn Forte 	uint32_t fTargetListSize;
3684fcf3ce44SJohn Forte 
3685fcf3ce44SJohn Forte 	if (targetList == NULL) {
3686fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3687fcf3ce44SJohn Forte 	}
3688fcf3ce44SJohn Forte 
3689fcf3ce44SJohn Forte 	/* call init */
3690fcf3ce44SJohn Forte 	ret = initializeConfig();
3691fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
3692fcf3ce44SJohn Forte 		return (ret);
3693fcf3ce44SJohn Forte 	}
3694fcf3ce44SJohn Forte 
3695fcf3ce44SJohn Forte 	/*
3696fcf3ce44SJohn Forte 	 * Open control node for stmf
3697fcf3ce44SJohn Forte 	 */
3698fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3699fcf3ce44SJohn Forte 		return (ret);
3700fcf3ce44SJohn Forte 
3701fcf3ce44SJohn Forte 	/*
3702fcf3ce44SJohn Forte 	 * Allocate ioctl input buffer
3703fcf3ce44SJohn Forte 	 */
3704*8fe96085Stim szeto 	fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
37053e7352aeSJohn Forte 	fTargetListP = fTargetList =
37063e7352aeSJohn Forte 	    (slist_target_port_t *)calloc(1, fTargetListSize);
3707fcf3ce44SJohn Forte 	if (fTargetList == NULL) {
3708*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3709fcf3ce44SJohn Forte 		goto done;
3710fcf3ce44SJohn Forte 	}
3711fcf3ce44SJohn Forte 
3712fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3713fcf3ce44SJohn Forte 	/*
37143e7352aeSJohn Forte 	 * Issue ioctl to retrieve target list
3715fcf3ce44SJohn Forte 	 */
3716fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
3717fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = fTargetListSize;
3718fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
3719fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
3720fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
3721fcf3ce44SJohn Forte 		switch (errno) {
3722fcf3ce44SJohn Forte 			case EBUSY:
3723fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
3724fcf3ce44SJohn Forte 				break;
3725*8fe96085Stim szeto 			case EPERM:
3726fcf3ce44SJohn Forte 			case EACCES:
3727fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
3728fcf3ce44SJohn Forte 				break;
3729fcf3ce44SJohn Forte 			default:
3730fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
3731fcf3ce44SJohn Forte 				    "stmfGetTargetList:ioctl errno(%d)", errno);
3732fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
3733fcf3ce44SJohn Forte 				break;
3734fcf3ce44SJohn Forte 		}
3735fcf3ce44SJohn Forte 		goto done;
3736fcf3ce44SJohn Forte 	}
3737fcf3ce44SJohn Forte 	/*
3738fcf3ce44SJohn Forte 	 * Check whether input buffer was large enough
3739fcf3ce44SJohn Forte 	 */
3740*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
3741fcf3ce44SJohn Forte 		fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
374276602b8dSJohn Forte 		    sizeof (slist_target_port_t);
37433e7352aeSJohn Forte 		fTargetListP = fTargetList =
37443e7352aeSJohn Forte 		    realloc(fTargetList, fTargetListSize);
3745fcf3ce44SJohn Forte 		if (fTargetList == NULL) {
3746*8fe96085Stim szeto 			ret = STMF_ERROR_NOMEM;
3747*8fe96085Stim szeto 			goto done;
3748fcf3ce44SJohn Forte 		}
3749fcf3ce44SJohn Forte 		stmfIoctl.stmf_obuf_size = fTargetListSize;
3750fcf3ce44SJohn Forte 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
3751fcf3ce44SJohn Forte 		ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
3752fcf3ce44SJohn Forte 		    &stmfIoctl);
3753fcf3ce44SJohn Forte 		if (ioctlRet != 0) {
3754fcf3ce44SJohn Forte 			switch (errno) {
3755fcf3ce44SJohn Forte 				case EBUSY:
3756fcf3ce44SJohn Forte 					ret = STMF_ERROR_BUSY;
3757fcf3ce44SJohn Forte 					break;
3758*8fe96085Stim szeto 				case EPERM:
3759fcf3ce44SJohn Forte 				case EACCES:
3760fcf3ce44SJohn Forte 					ret = STMF_ERROR_PERM;
3761fcf3ce44SJohn Forte 					break;
3762fcf3ce44SJohn Forte 				default:
3763fcf3ce44SJohn Forte 					syslog(LOG_DEBUG,
3764fcf3ce44SJohn Forte 					    "stmfGetTargetList:ioctl errno(%d)",
3765fcf3ce44SJohn Forte 					    errno);
3766fcf3ce44SJohn Forte 					ret = STMF_STATUS_ERROR;
3767fcf3ce44SJohn Forte 					break;
3768fcf3ce44SJohn Forte 			}
3769fcf3ce44SJohn Forte 			goto done;
3770fcf3ce44SJohn Forte 		}
3771fcf3ce44SJohn Forte 	}
3772fcf3ce44SJohn Forte 
3773fcf3ce44SJohn Forte 	*targetList = (stmfDevidList *)calloc(1,
3774fcf3ce44SJohn Forte 	    stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
3775fcf3ce44SJohn Forte 	    sizeof (stmfDevidList));
3776*8fe96085Stim szeto 	if (*targetList == NULL) {
3777*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3778*8fe96085Stim szeto 		goto done;
3779*8fe96085Stim szeto 	}
3780fcf3ce44SJohn Forte 
3781fcf3ce44SJohn Forte 	(*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
3782fcf3ce44SJohn Forte 	for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
3783fcf3ce44SJohn Forte 		(*targetList)->devid[i].identLength =
3784fcf3ce44SJohn Forte 		    fTargetList->target[IDENT_LENGTH_BYTE];
3785fcf3ce44SJohn Forte 		bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
3786fcf3ce44SJohn Forte 		    &(*targetList)->devid[i].ident,
3787fcf3ce44SJohn Forte 		    fTargetList->target[IDENT_LENGTH_BYTE]);
3788fcf3ce44SJohn Forte 	}
3789fcf3ce44SJohn Forte 
3790fcf3ce44SJohn Forte done:
3791fcf3ce44SJohn Forte 	(void) close(fd);
37923e7352aeSJohn Forte 	free(fTargetListP);
3793fcf3ce44SJohn Forte 	return (ret);
3794fcf3ce44SJohn Forte }
3795fcf3ce44SJohn Forte 
3796fcf3ce44SJohn Forte /*
3797fcf3ce44SJohn Forte  * stmfGetTargetProperties
3798fcf3ce44SJohn Forte  *
3799fcf3ce44SJohn Forte  * Purpose:  Retrieves the properties for a logical unit
3800fcf3ce44SJohn Forte  *
3801fcf3ce44SJohn Forte  * devid - devid of the target for which to retrieve properties
3802fcf3ce44SJohn Forte  * targetProps - pointer to an stmfTargetProperties structure.
3803fcf3ce44SJohn Forte  *		On success, it contains the target properties for
3804fcf3ce44SJohn Forte  *		the specified devid.
3805fcf3ce44SJohn Forte  */
3806fcf3ce44SJohn Forte int
3807fcf3ce44SJohn Forte stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
3808fcf3ce44SJohn Forte {
3809fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
3810fcf3ce44SJohn Forte 	int fd;
3811fcf3ce44SJohn Forte 	int ioctlRet;
3812fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
3813fcf3ce44SJohn Forte 	sioc_target_port_props_t targetProperties;
3814fcf3ce44SJohn Forte 
3815fcf3ce44SJohn Forte 	if (devid == NULL || targetProps == NULL) {
3816fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3817fcf3ce44SJohn Forte 	}
3818fcf3ce44SJohn Forte 
3819fcf3ce44SJohn Forte 	/* call init */
3820fcf3ce44SJohn Forte 	ret = initializeConfig();
3821fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
3822fcf3ce44SJohn Forte 		return (ret);
3823fcf3ce44SJohn Forte 	}
3824fcf3ce44SJohn Forte 
3825fcf3ce44SJohn Forte 	/*
3826fcf3ce44SJohn Forte 	 * Open control node for stmf
3827fcf3ce44SJohn Forte 	 */
3828fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3829fcf3ce44SJohn Forte 		return (ret);
3830fcf3ce44SJohn Forte 
3831fcf3ce44SJohn Forte 	targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
3832fcf3ce44SJohn Forte 	bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
3833fcf3ce44SJohn Forte 	    devid->identLength);
3834fcf3ce44SJohn Forte 
3835fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3836fcf3ce44SJohn Forte 	/*
3837fcf3ce44SJohn Forte 	 * Issue ioctl to add to the host group
3838fcf3ce44SJohn Forte 	 */
3839fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
3840fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
3841fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
3842fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
3843fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
3844fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
3845fcf3ce44SJohn Forte 	    &stmfIoctl);
3846fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
3847fcf3ce44SJohn Forte 		switch (errno) {
3848fcf3ce44SJohn Forte 			case EBUSY:
3849fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
3850fcf3ce44SJohn Forte 				break;
3851*8fe96085Stim szeto 			case EPERM:
3852fcf3ce44SJohn Forte 			case EACCES:
3853fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
3854fcf3ce44SJohn Forte 				break;
3855fcf3ce44SJohn Forte 			case ENOENT:
3856fcf3ce44SJohn Forte 				ret = STMF_ERROR_NOT_FOUND;
3857fcf3ce44SJohn Forte 				break;
3858fcf3ce44SJohn Forte 			default:
3859fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
3860fcf3ce44SJohn Forte 				    "stmfGetTargetProperties:ioctl errno(%d)",
3861fcf3ce44SJohn Forte 				    errno);
3862fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
3863fcf3ce44SJohn Forte 				break;
3864fcf3ce44SJohn Forte 		}
3865fcf3ce44SJohn Forte 		goto done;
3866fcf3ce44SJohn Forte 	}
3867fcf3ce44SJohn Forte 
3868fcf3ce44SJohn Forte 	bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
3869fcf3ce44SJohn Forte 	    sizeof (targetProperties.tgt_provider_name));
3870fcf3ce44SJohn Forte 	if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
3871fcf3ce44SJohn Forte 		targetProps->status = STMF_TARGET_PORT_ONLINE;
3872fcf3ce44SJohn Forte 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
3873fcf3ce44SJohn Forte 		targetProps->status = STMF_TARGET_PORT_OFFLINE;
3874fcf3ce44SJohn Forte 	} else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
3875fcf3ce44SJohn Forte 		targetProps->status = STMF_TARGET_PORT_ONLINING;
3876fcf3ce44SJohn Forte 	} else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
3877fcf3ce44SJohn Forte 		targetProps->status = STMF_TARGET_PORT_OFFLINING;
3878fcf3ce44SJohn Forte 	}
3879fcf3ce44SJohn Forte 	bcopy(targetProperties.tgt_alias, targetProps->alias,
3880fcf3ce44SJohn Forte 	    sizeof (targetProps->alias));
3881fcf3ce44SJohn Forte done:
3882fcf3ce44SJohn Forte 	(void) close(fd);
3883fcf3ce44SJohn Forte 	return (ret);
3884fcf3ce44SJohn Forte }
3885fcf3ce44SJohn Forte 
3886fcf3ce44SJohn Forte /*
3887fcf3ce44SJohn Forte  * stmfGetLogicalUnitList
3888fcf3ce44SJohn Forte  *
3889fcf3ce44SJohn Forte  * Purpose: Retrieves list of logical unit Object IDs
3890fcf3ce44SJohn Forte  *
3891fcf3ce44SJohn Forte  * luList - pointer to a pointer to a stmfGuidList structure. On success,
3892fcf3ce44SJohn Forte  *          it contains the list of logical unit guids.
3893fcf3ce44SJohn Forte  *
3894fcf3ce44SJohn Forte  */
3895fcf3ce44SJohn Forte int
3896fcf3ce44SJohn Forte stmfGetLogicalUnitList(stmfGuidList **luList)
3897fcf3ce44SJohn Forte {
3898fcf3ce44SJohn Forte 	int ret;
3899fcf3ce44SJohn Forte 	int fd;
3900fcf3ce44SJohn Forte 	int ioctlRet;
3901fcf3ce44SJohn Forte 	int cmd = STMF_IOCTL_LU_LIST;
3902*8fe96085Stim szeto 	int i;
3903fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
3904fcf3ce44SJohn Forte 	slist_lu_t *fLuList;
3905fcf3ce44SJohn Forte 	uint32_t fLuListSize;
3906*8fe96085Stim szeto 	uint32_t listCnt;
3907fcf3ce44SJohn Forte 
3908fcf3ce44SJohn Forte 	if (luList == NULL) {
3909fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
3910fcf3ce44SJohn Forte 	}
3911fcf3ce44SJohn Forte 
3912fcf3ce44SJohn Forte 	/* call init */
3913fcf3ce44SJohn Forte 	ret = initializeConfig();
3914fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
3915fcf3ce44SJohn Forte 		return (ret);
3916fcf3ce44SJohn Forte 	}
3917fcf3ce44SJohn Forte 
3918fcf3ce44SJohn Forte 	/*
3919fcf3ce44SJohn Forte 	 * Open control node for stmf
3920fcf3ce44SJohn Forte 	 */
3921fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3922fcf3ce44SJohn Forte 		return (ret);
3923fcf3ce44SJohn Forte 
3924fcf3ce44SJohn Forte 	/*
3925fcf3ce44SJohn Forte 	 * Allocate ioctl input buffer
3926fcf3ce44SJohn Forte 	 */
3927*8fe96085Stim szeto 	fLuListSize = ALLOC_LU;
3928fcf3ce44SJohn Forte 	fLuListSize = fLuListSize * (sizeof (slist_lu_t));
3929fcf3ce44SJohn Forte 	fLuList = (slist_lu_t *)calloc(1, fLuListSize);
3930fcf3ce44SJohn Forte 	if (fLuList == NULL) {
3931*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
3932*8fe96085Stim szeto 		goto done;
3933fcf3ce44SJohn Forte 	}
3934fcf3ce44SJohn Forte 
3935fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
3936fcf3ce44SJohn Forte 	/*
3937fcf3ce44SJohn Forte 	 * Issue ioctl to get the LU list
3938fcf3ce44SJohn Forte 	 */
3939fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
3940fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = fLuListSize;
3941fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
3942fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3943fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
3944fcf3ce44SJohn Forte 		switch (errno) {
3945fcf3ce44SJohn Forte 			case EBUSY:
3946fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
3947fcf3ce44SJohn Forte 				break;
3948*8fe96085Stim szeto 			case EPERM:
3949fcf3ce44SJohn Forte 			case EACCES:
3950fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
3951fcf3ce44SJohn Forte 				break;
3952fcf3ce44SJohn Forte 			default:
3953fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
3954fcf3ce44SJohn Forte 				    "stmfGetLogicalUnitList:ioctl errno(%d)",
3955fcf3ce44SJohn Forte 				    errno);
3956fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
3957fcf3ce44SJohn Forte 				break;
3958fcf3ce44SJohn Forte 		}
3959fcf3ce44SJohn Forte 		goto done;
3960fcf3ce44SJohn Forte 	}
3961fcf3ce44SJohn Forte 	/*
3962fcf3ce44SJohn Forte 	 * Check whether input buffer was large enough
3963fcf3ce44SJohn Forte 	 */
3964*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
3965fcf3ce44SJohn Forte 		fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
3966fcf3ce44SJohn Forte 		    sizeof (slist_lu_t);
3967*8fe96085Stim szeto 		free(fLuList);
3968*8fe96085Stim szeto 		fLuList = (slist_lu_t *)calloc(1, fLuListSize);
3969fcf3ce44SJohn Forte 		if (fLuList == NULL) {
3970*8fe96085Stim szeto 			ret = STMF_ERROR_NOMEM;
3971*8fe96085Stim szeto 			goto done;
3972fcf3ce44SJohn Forte 		}
3973fcf3ce44SJohn Forte 		stmfIoctl.stmf_obuf_size = fLuListSize;
3974fcf3ce44SJohn Forte 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
3975fcf3ce44SJohn Forte 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3976fcf3ce44SJohn Forte 		if (ioctlRet != 0) {
3977fcf3ce44SJohn Forte 			switch (errno) {
3978fcf3ce44SJohn Forte 				case EBUSY:
3979fcf3ce44SJohn Forte 					ret = STMF_ERROR_BUSY;
3980fcf3ce44SJohn Forte 					break;
3981*8fe96085Stim szeto 				case EPERM:
3982fcf3ce44SJohn Forte 				case EACCES:
3983fcf3ce44SJohn Forte 					ret = STMF_ERROR_PERM;
3984fcf3ce44SJohn Forte 					break;
3985fcf3ce44SJohn Forte 				default:
3986fcf3ce44SJohn Forte 					syslog(LOG_DEBUG,
3987fcf3ce44SJohn Forte 					    "stmfGetLogicalUnitList:"
3988fcf3ce44SJohn Forte 					    "ioctl errno(%d)", errno);
3989fcf3ce44SJohn Forte 					ret = STMF_STATUS_ERROR;
3990fcf3ce44SJohn Forte 					break;
3991fcf3ce44SJohn Forte 			}
3992fcf3ce44SJohn Forte 			goto done;
3993fcf3ce44SJohn Forte 		}
3994fcf3ce44SJohn Forte 	}
3995fcf3ce44SJohn Forte 
3996fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
3997fcf3ce44SJohn Forte 		goto done;
3998fcf3ce44SJohn Forte 	}
3999fcf3ce44SJohn Forte 
4000*8fe96085Stim szeto 	listCnt = stmfIoctl.stmf_obuf_nentries;
4001fcf3ce44SJohn Forte 
4002fcf3ce44SJohn Forte 	/*
4003fcf3ce44SJohn Forte 	 * allocate caller's buffer with the final size
4004fcf3ce44SJohn Forte 	 */
4005fcf3ce44SJohn Forte 	*luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
4006*8fe96085Stim szeto 	    listCnt * sizeof (stmfGuid));
4007fcf3ce44SJohn Forte 	if (*luList == NULL) {
4008fcf3ce44SJohn Forte 		ret = STMF_ERROR_NOMEM;
4009fcf3ce44SJohn Forte 		goto done;
4010fcf3ce44SJohn Forte 	}
4011fcf3ce44SJohn Forte 
4012*8fe96085Stim szeto 	(*luList)->cnt = listCnt;
4013*8fe96085Stim szeto 
4014*8fe96085Stim szeto 	/* copy to caller's buffer */
4015*8fe96085Stim szeto 	for (i = 0; i < listCnt; i++) {
4016*8fe96085Stim szeto 		bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
4017fcf3ce44SJohn Forte 		    sizeof (stmfGuid));
4018fcf3ce44SJohn Forte 	}
4019fcf3ce44SJohn Forte 
4020*8fe96085Stim szeto 	/*
4021*8fe96085Stim szeto 	 * sort the list. This gives a consistent view across gets
4022*8fe96085Stim szeto 	 */
4023*8fe96085Stim szeto 	qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
4024*8fe96085Stim szeto 	    sizeof (stmfGuid), guidCompare);
4025fcf3ce44SJohn Forte 
4026fcf3ce44SJohn Forte done:
4027fcf3ce44SJohn Forte 	(void) close(fd);
4028fcf3ce44SJohn Forte 	/*
4029fcf3ce44SJohn Forte 	 * free internal buffers
4030fcf3ce44SJohn Forte 	 */
4031fcf3ce44SJohn Forte 	free(fLuList);
4032fcf3ce44SJohn Forte 	return (ret);
4033fcf3ce44SJohn Forte }
4034fcf3ce44SJohn Forte 
4035fcf3ce44SJohn Forte /*
4036fcf3ce44SJohn Forte  * stmfGetLogicalUnitProperties
4037fcf3ce44SJohn Forte  *
4038fcf3ce44SJohn Forte  * Purpose:  Retrieves the properties for a logical unit
4039fcf3ce44SJohn Forte  *
4040fcf3ce44SJohn Forte  * lu - guid of the logical unit for which to retrieve properties
4041fcf3ce44SJohn Forte  * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
4042fcf3ce44SJohn Forte  *               it contains the logical unit properties for the specified guid.
4043fcf3ce44SJohn Forte  */
4044fcf3ce44SJohn Forte int
4045fcf3ce44SJohn Forte stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
4046fcf3ce44SJohn Forte {
4047fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4048fcf3ce44SJohn Forte 	int stmfRet;
4049fcf3ce44SJohn Forte 	int fd;
4050fcf3ce44SJohn Forte 	int ioctlRet;
4051fcf3ce44SJohn Forte 	int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
4052fcf3ce44SJohn Forte 	stmfViewEntryList *viewEntryList = NULL;
4053fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
4054fcf3ce44SJohn Forte 	sioc_lu_props_t fLuProps;
4055fcf3ce44SJohn Forte 
4056*8fe96085Stim szeto 	if (lu == NULL || luProps == NULL) {
4057*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
4058fcf3ce44SJohn Forte 	}
4059fcf3ce44SJohn Forte 
4060fcf3ce44SJohn Forte 	bzero(luProps, sizeof (stmfLogicalUnitProperties));
4061fcf3ce44SJohn Forte 
4062fcf3ce44SJohn Forte 	/* call init */
4063fcf3ce44SJohn Forte 	ret = initializeConfig();
4064fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4065fcf3ce44SJohn Forte 		return (ret);
4066fcf3ce44SJohn Forte 	}
4067fcf3ce44SJohn Forte 
4068fcf3ce44SJohn Forte 	/*
4069fcf3ce44SJohn Forte 	 * Open control node for stmf
4070fcf3ce44SJohn Forte 	 */
4071fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4072fcf3ce44SJohn Forte 		return (ret);
4073fcf3ce44SJohn Forte 
4074fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
4075fcf3ce44SJohn Forte 	/*
4076fcf3ce44SJohn Forte 	 * Issue ioctl to add to the host group
4077fcf3ce44SJohn Forte 	 */
4078fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
4079fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
4080fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
4081fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
4082fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
4083fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4084fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
4085fcf3ce44SJohn Forte 		switch (errno) {
4086fcf3ce44SJohn Forte 			case EBUSY:
4087fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4088fcf3ce44SJohn Forte 				break;
4089*8fe96085Stim szeto 			case EPERM:
4090fcf3ce44SJohn Forte 			case EACCES:
4091fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
4092fcf3ce44SJohn Forte 				break;
4093fcf3ce44SJohn Forte 			case ENOENT:
4094fcf3ce44SJohn Forte 				stmfRet = stmfGetViewEntryList(lu,
4095fcf3ce44SJohn Forte 				    &viewEntryList);
4096fcf3ce44SJohn Forte 				if (stmfRet == STMF_STATUS_SUCCESS) {
4097fcf3ce44SJohn Forte 					luProps->status =
4098fcf3ce44SJohn Forte 					    STMF_LOGICAL_UNIT_UNREGISTERED;
4099fcf3ce44SJohn Forte 					if (viewEntryList->cnt > 0) {
4100fcf3ce44SJohn Forte 						ret = STMF_STATUS_SUCCESS;
4101fcf3ce44SJohn Forte 					} else {
4102fcf3ce44SJohn Forte 						ret = STMF_ERROR_NOT_FOUND;
4103fcf3ce44SJohn Forte 					}
4104fcf3ce44SJohn Forte 				} else {
4105fcf3ce44SJohn Forte 					ret = STMF_ERROR_NOT_FOUND;
4106fcf3ce44SJohn Forte 				}
4107fcf3ce44SJohn Forte 				stmfFreeMemory(viewEntryList);
4108fcf3ce44SJohn Forte 				break;
4109fcf3ce44SJohn Forte 			default:
4110fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
4111fcf3ce44SJohn Forte 				    "stmfGetLogicalUnit:ioctl errno(%d)",
4112fcf3ce44SJohn Forte 				    errno);
4113fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4114fcf3ce44SJohn Forte 				break;
4115fcf3ce44SJohn Forte 		}
4116fcf3ce44SJohn Forte 		goto done;
4117fcf3ce44SJohn Forte 	}
4118fcf3ce44SJohn Forte 
4119fcf3ce44SJohn Forte 	bcopy(fLuProps.lu_provider_name, luProps->providerName,
4120fcf3ce44SJohn Forte 	    sizeof (fLuProps.lu_provider_name));
4121fcf3ce44SJohn Forte 	if (fLuProps.lu_state == STMF_STATE_ONLINE) {
4122fcf3ce44SJohn Forte 		luProps->status = STMF_LOGICAL_UNIT_ONLINE;
4123fcf3ce44SJohn Forte 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
4124fcf3ce44SJohn Forte 		luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
4125fcf3ce44SJohn Forte 	} else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
4126fcf3ce44SJohn Forte 		luProps->status = STMF_LOGICAL_UNIT_ONLINING;
4127fcf3ce44SJohn Forte 	} else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
4128fcf3ce44SJohn Forte 		luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
4129fcf3ce44SJohn Forte 	}
4130fcf3ce44SJohn Forte 	bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
4131fcf3ce44SJohn Forte done:
4132fcf3ce44SJohn Forte 	(void) close(fd);
4133fcf3ce44SJohn Forte 	return (ret);
4134fcf3ce44SJohn Forte }
4135fcf3ce44SJohn Forte 
4136fcf3ce44SJohn Forte /*
4137fcf3ce44SJohn Forte  * stmfGetState
4138fcf3ce44SJohn Forte  *
4139fcf3ce44SJohn Forte  * Purpose: retrieve the current state of the stmf module
4140fcf3ce44SJohn Forte  *
4141fcf3ce44SJohn Forte  * state - pointer to stmfState structure allocated by the caller
4142fcf3ce44SJohn Forte  *         On success, contains the state of stmf
4143fcf3ce44SJohn Forte  */
4144fcf3ce44SJohn Forte int
4145fcf3ce44SJohn Forte stmfGetState(stmfState *state)
4146fcf3ce44SJohn Forte {
4147fcf3ce44SJohn Forte 	int ret;
4148fcf3ce44SJohn Forte 	stmf_state_desc_t iState;
4149fcf3ce44SJohn Forte 
4150fcf3ce44SJohn Forte 	if (state == NULL) {
4151fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
4152fcf3ce44SJohn Forte 	}
4153fcf3ce44SJohn Forte 
4154fcf3ce44SJohn Forte 	ret = getStmfState(&iState);
4155fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4156fcf3ce44SJohn Forte 		return (ret);
4157fcf3ce44SJohn Forte 	}
4158fcf3ce44SJohn Forte 	switch (iState.state) {
4159fcf3ce44SJohn Forte 		case STMF_STATE_ONLINE:
4160fcf3ce44SJohn Forte 			state->operationalState =
4161fcf3ce44SJohn Forte 			    STMF_SERVICE_STATE_ONLINE;
4162fcf3ce44SJohn Forte 			break;
4163fcf3ce44SJohn Forte 		case STMF_STATE_OFFLINE:
4164fcf3ce44SJohn Forte 			state->operationalState =
4165fcf3ce44SJohn Forte 			    STMF_SERVICE_STATE_OFFLINE;
4166fcf3ce44SJohn Forte 			break;
4167fcf3ce44SJohn Forte 		case STMF_STATE_ONLINING:
4168fcf3ce44SJohn Forte 			state->operationalState =
4169fcf3ce44SJohn Forte 			    STMF_SERVICE_STATE_ONLINING;
4170fcf3ce44SJohn Forte 			break;
4171fcf3ce44SJohn Forte 		case STMF_STATE_OFFLINING:
4172fcf3ce44SJohn Forte 			state->operationalState =
4173fcf3ce44SJohn Forte 			    STMF_SERVICE_STATE_OFFLINING;
4174fcf3ce44SJohn Forte 			break;
4175fcf3ce44SJohn Forte 		default:
4176fcf3ce44SJohn Forte 			state->operationalState =
4177fcf3ce44SJohn Forte 			    STMF_SERVICE_STATE_UNKNOWN;
4178fcf3ce44SJohn Forte 			break;
4179fcf3ce44SJohn Forte 	}
4180fcf3ce44SJohn Forte 	switch (iState.config_state) {
4181fcf3ce44SJohn Forte 		case STMF_CONFIG_NONE:
4182fcf3ce44SJohn Forte 			state->configState = STMF_CONFIG_STATE_NONE;
4183fcf3ce44SJohn Forte 			break;
4184fcf3ce44SJohn Forte 		case STMF_CONFIG_INIT:
4185fcf3ce44SJohn Forte 			state->configState = STMF_CONFIG_STATE_INIT;
4186fcf3ce44SJohn Forte 			break;
4187fcf3ce44SJohn Forte 		case STMF_CONFIG_INIT_DONE:
4188fcf3ce44SJohn Forte 			state->configState =
4189fcf3ce44SJohn Forte 			    STMF_CONFIG_STATE_INIT_DONE;
4190fcf3ce44SJohn Forte 			break;
4191fcf3ce44SJohn Forte 		default:
4192fcf3ce44SJohn Forte 			state->configState =
4193fcf3ce44SJohn Forte 			    STMF_CONFIG_STATE_UNKNOWN;
4194fcf3ce44SJohn Forte 			break;
4195fcf3ce44SJohn Forte 	}
4196fcf3ce44SJohn Forte 	return (STMF_STATUS_SUCCESS);
4197fcf3ce44SJohn Forte }
4198fcf3ce44SJohn Forte 
4199fcf3ce44SJohn Forte /*
4200fcf3ce44SJohn Forte  * stmfGetViewEntryList
4201fcf3ce44SJohn Forte  *
4202fcf3ce44SJohn Forte  * Purpose: Retrieves the list of view entries for the specified
4203fcf3ce44SJohn Forte  *          logical unit.
4204fcf3ce44SJohn Forte  *
4205fcf3ce44SJohn Forte  * lu - the guid of the logical unit for which to retrieve the view entry list
4206fcf3ce44SJohn Forte  * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
4207fcf3ce44SJohn Forte  *                 success, contains the list of view entries.
4208fcf3ce44SJohn Forte  */
4209fcf3ce44SJohn Forte int
4210fcf3ce44SJohn Forte stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
4211fcf3ce44SJohn Forte {
4212fcf3ce44SJohn Forte 	int ret;
4213*8fe96085Stim szeto 	int fd;
4214*8fe96085Stim szeto 	int ioctlRet;
4215*8fe96085Stim szeto 	int cmd = STMF_IOCTL_LU_VE_LIST;
4216*8fe96085Stim szeto 	int i;
4217*8fe96085Stim szeto 	stmf_iocdata_t stmfIoctl;
4218*8fe96085Stim szeto 	stmf_view_op_entry_t *fVeList;
4219*8fe96085Stim szeto 	uint32_t fVeListSize;
4220*8fe96085Stim szeto 	uint32_t listCnt;
4221fcf3ce44SJohn Forte 
4222fcf3ce44SJohn Forte 	if (lu == NULL || viewEntryList == NULL) {
4223fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
4224fcf3ce44SJohn Forte 	}
4225fcf3ce44SJohn Forte 
4226*8fe96085Stim szeto 	/* call init */
4227*8fe96085Stim szeto 	ret = initializeConfig();
4228*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
4229*8fe96085Stim szeto 		return (ret);
4230*8fe96085Stim szeto 	}
4231*8fe96085Stim szeto 
4232*8fe96085Stim szeto 	/*
4233*8fe96085Stim szeto 	 * Open control node for stmf
4234*8fe96085Stim szeto 	 */
4235*8fe96085Stim szeto 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4236*8fe96085Stim szeto 		return (ret);
4237*8fe96085Stim szeto 
4238*8fe96085Stim szeto 	/*
4239*8fe96085Stim szeto 	 * Allocate ioctl input buffer
4240*8fe96085Stim szeto 	 */
4241*8fe96085Stim szeto 	fVeListSize = ALLOC_VE;
4242*8fe96085Stim szeto 	fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
4243*8fe96085Stim szeto 	fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
4244*8fe96085Stim szeto 	if (fVeList == NULL) {
4245*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
4246*8fe96085Stim szeto 		goto done;
4247*8fe96085Stim szeto 	}
4248*8fe96085Stim szeto 
4249*8fe96085Stim szeto 	bzero(&stmfIoctl, sizeof (stmfIoctl));
4250*8fe96085Stim szeto 	/*
4251*8fe96085Stim szeto 	 * Issue ioctl to get the LU list
4252*8fe96085Stim szeto 	 */
4253*8fe96085Stim szeto 	stmfIoctl.stmf_version = STMF_VERSION_1;
4254*8fe96085Stim szeto 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
4255*8fe96085Stim szeto 	stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
4256*8fe96085Stim szeto 	stmfIoctl.stmf_obuf_size = fVeListSize;
4257*8fe96085Stim szeto 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
4258*8fe96085Stim szeto 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4259*8fe96085Stim szeto 	if (ioctlRet != 0) {
4260*8fe96085Stim szeto 		switch (errno) {
4261*8fe96085Stim szeto 			case EBUSY:
4262fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4263fcf3ce44SJohn Forte 				break;
4264*8fe96085Stim szeto 			case EPERM:
4265*8fe96085Stim szeto 			case EACCES:
4266*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
4267fcf3ce44SJohn Forte 				break;
4268fcf3ce44SJohn Forte 			default:
4269fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
4270*8fe96085Stim szeto 				    "stmfGetViewEntryList:ioctl errno(%d)",
4271*8fe96085Stim szeto 				    errno);
4272fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4273fcf3ce44SJohn Forte 				break;
4274fcf3ce44SJohn Forte 		}
4275*8fe96085Stim szeto 		goto done;
4276*8fe96085Stim szeto 	}
4277*8fe96085Stim szeto 	/*
4278*8fe96085Stim szeto 	 * Check whether input buffer was large enough
4279*8fe96085Stim szeto 	 */
4280*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
4281*8fe96085Stim szeto 		bzero(&stmfIoctl, sizeof (stmfIoctl));
4282*8fe96085Stim szeto 		fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
4283*8fe96085Stim szeto 		    sizeof (stmf_view_op_entry_t);
4284*8fe96085Stim szeto 		free(fVeList);
4285*8fe96085Stim szeto 		fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
4286*8fe96085Stim szeto 		if (fVeList == NULL) {
4287*8fe96085Stim szeto 			return (STMF_ERROR_NOMEM);
4288*8fe96085Stim szeto 		}
4289*8fe96085Stim szeto 		stmfIoctl.stmf_obuf_size = fVeListSize;
4290*8fe96085Stim szeto 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
4291*8fe96085Stim szeto 		ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4292*8fe96085Stim szeto 		if (ioctlRet != 0) {
4293*8fe96085Stim szeto 			switch (errno) {
4294*8fe96085Stim szeto 				case EBUSY:
4295*8fe96085Stim szeto 					ret = STMF_ERROR_BUSY;
4296*8fe96085Stim szeto 					break;
4297*8fe96085Stim szeto 				case EPERM:
4298*8fe96085Stim szeto 				case EACCES:
4299*8fe96085Stim szeto 					ret = STMF_ERROR_PERM;
4300*8fe96085Stim szeto 					break;
4301*8fe96085Stim szeto 				default:
4302*8fe96085Stim szeto 					syslog(LOG_DEBUG,
4303*8fe96085Stim szeto 					    "stmfGetLogicalUnitList:"
4304*8fe96085Stim szeto 					    "ioctl errno(%d)", errno);
4305*8fe96085Stim szeto 					ret = STMF_STATUS_ERROR;
4306*8fe96085Stim szeto 					break;
4307*8fe96085Stim szeto 			}
4308*8fe96085Stim szeto 			goto done;
4309*8fe96085Stim szeto 		}
4310*8fe96085Stim szeto 	}
4311fcf3ce44SJohn Forte 
4312*8fe96085Stim szeto 	if (ret != STMF_STATUS_SUCCESS) {
4313*8fe96085Stim szeto 		goto done;
4314*8fe96085Stim szeto 	}
4315*8fe96085Stim szeto 
4316*8fe96085Stim szeto 	if (stmfIoctl.stmf_obuf_nentries == 0) {
4317*8fe96085Stim szeto 		ret = STMF_ERROR_NOT_FOUND;
4318*8fe96085Stim szeto 		goto done;
4319*8fe96085Stim szeto 	}
4320*8fe96085Stim szeto 
4321*8fe96085Stim szeto 	listCnt = stmfIoctl.stmf_obuf_nentries;
4322*8fe96085Stim szeto 
4323*8fe96085Stim szeto 	/*
4324*8fe96085Stim szeto 	 * allocate caller's buffer with the final size
4325*8fe96085Stim szeto 	 */
4326*8fe96085Stim szeto 	*viewEntryList = (stmfViewEntryList *)calloc(1,
4327*8fe96085Stim szeto 	    sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
4328*8fe96085Stim szeto 	if (*viewEntryList == NULL) {
4329*8fe96085Stim szeto 		ret = STMF_ERROR_NOMEM;
4330*8fe96085Stim szeto 		goto done;
4331*8fe96085Stim szeto 	}
4332*8fe96085Stim szeto 
4333*8fe96085Stim szeto 	(*viewEntryList)->cnt = listCnt;
4334*8fe96085Stim szeto 
4335*8fe96085Stim szeto 	/* copy to caller's buffer */
4336*8fe96085Stim szeto 	for (i = 0; i < listCnt; i++) {
4337*8fe96085Stim szeto 		(*viewEntryList)->ve[i].veIndexValid = B_TRUE;
4338*8fe96085Stim szeto 		(*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
4339*8fe96085Stim szeto 		if (fVeList[i].ve_all_hosts == 1) {
4340*8fe96085Stim szeto 			(*viewEntryList)->ve[i].allHosts = B_TRUE;
4341*8fe96085Stim szeto 		} else {
4342*8fe96085Stim szeto 			bcopy(fVeList[i].ve_host_group.name,
4343*8fe96085Stim szeto 			    (*viewEntryList)->ve[i].hostGroup,
4344*8fe96085Stim szeto 			    fVeList[i].ve_host_group.name_size);
4345*8fe96085Stim szeto 		}
4346*8fe96085Stim szeto 		if (fVeList[i].ve_all_targets == 1) {
4347*8fe96085Stim szeto 			(*viewEntryList)->ve[i].allTargets = B_TRUE;
4348*8fe96085Stim szeto 		} else {
4349*8fe96085Stim szeto 			bcopy(fVeList[i].ve_target_group.name,
4350*8fe96085Stim szeto 			    (*viewEntryList)->ve[i].targetGroup,
4351*8fe96085Stim szeto 			    fVeList[i].ve_target_group.name_size);
4352*8fe96085Stim szeto 		}
4353*8fe96085Stim szeto 		bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
4354*8fe96085Stim szeto 		    sizeof ((*viewEntryList)->ve[i].luNbr));
4355*8fe96085Stim szeto 		(*viewEntryList)->ve[i].luNbrValid = B_TRUE;
4356*8fe96085Stim szeto 	}
4357*8fe96085Stim szeto 
4358*8fe96085Stim szeto 	/*
4359*8fe96085Stim szeto 	 * sort the list. This gives a consistent view across gets
4360*8fe96085Stim szeto 	 */
4361*8fe96085Stim szeto 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
4362*8fe96085Stim szeto 	    sizeof (stmfViewEntry), viewEntryCompare);
4363*8fe96085Stim szeto 
4364*8fe96085Stim szeto done:
4365*8fe96085Stim szeto 	(void) close(fd);
4366*8fe96085Stim szeto 	/*
4367*8fe96085Stim szeto 	 * free internal buffers
4368*8fe96085Stim szeto 	 */
4369*8fe96085Stim szeto 	free(fVeList);
4370fcf3ce44SJohn Forte 	return (ret);
4371fcf3ce44SJohn Forte }
4372fcf3ce44SJohn Forte 
4373*8fe96085Stim szeto 
4374fcf3ce44SJohn Forte /*
4375fcf3ce44SJohn Forte  * loadHostGroups
4376fcf3ce44SJohn Forte  *
4377fcf3ce44SJohn Forte  * Purpose - issues the ioctl to load the host groups into stmf
4378fcf3ce44SJohn Forte  *
4379fcf3ce44SJohn Forte  * fd - file descriptor for the control node of stmf.
4380fcf3ce44SJohn Forte  * groupList - populated host group list
4381fcf3ce44SJohn Forte  */
4382fcf3ce44SJohn Forte static int
4383fcf3ce44SJohn Forte loadHostGroups(int fd, stmfGroupList *groupList)
4384fcf3ce44SJohn Forte {
4385fcf3ce44SJohn Forte 	int i, j;
4386fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4387fcf3ce44SJohn Forte 	stmfGroupProperties *groupProps = NULL;
4388fcf3ce44SJohn Forte 
4389fcf3ce44SJohn Forte 	for (i = 0; i < groupList->cnt; i++) {
4390fcf3ce44SJohn Forte 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
4391fcf3ce44SJohn Forte 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
4392fcf3ce44SJohn Forte 			goto out;
4393fcf3ce44SJohn Forte 		}
4394*8fe96085Stim szeto 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
4395*8fe96085Stim szeto 		    &groupProps, HOST_GROUP);
4396fcf3ce44SJohn Forte 		for (j = 0; j < groupProps->cnt; j++) {
4397fcf3ce44SJohn Forte 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
4398fcf3ce44SJohn Forte 			    &(groupList->name[i]), &(groupProps->name[j])))
4399fcf3ce44SJohn Forte 			    != STMF_STATUS_SUCCESS) {
4400fcf3ce44SJohn Forte 				goto out;
4401fcf3ce44SJohn Forte 			}
4402fcf3ce44SJohn Forte 		}
4403fcf3ce44SJohn Forte 	}
4404fcf3ce44SJohn Forte 
4405fcf3ce44SJohn Forte 
4406fcf3ce44SJohn Forte out:
4407fcf3ce44SJohn Forte 	stmfFreeMemory(groupProps);
4408fcf3ce44SJohn Forte 	return (ret);
4409fcf3ce44SJohn Forte }
4410fcf3ce44SJohn Forte 
4411fcf3ce44SJohn Forte /*
4412fcf3ce44SJohn Forte  * loadTargetGroups
4413fcf3ce44SJohn Forte  *
4414fcf3ce44SJohn Forte  * Purpose - issues the ioctl to load the target groups into stmf
4415fcf3ce44SJohn Forte  *
4416fcf3ce44SJohn Forte  * fd - file descriptor for the control node of stmf.
4417fcf3ce44SJohn Forte  * groupList - populated target group list.
4418fcf3ce44SJohn Forte  */
4419fcf3ce44SJohn Forte static int
4420fcf3ce44SJohn Forte loadTargetGroups(int fd, stmfGroupList *groupList)
4421fcf3ce44SJohn Forte {
4422fcf3ce44SJohn Forte 	int i, j;
4423fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4424fcf3ce44SJohn Forte 	stmfGroupProperties *groupProps = NULL;
4425fcf3ce44SJohn Forte 
4426fcf3ce44SJohn Forte 	for (i = 0; i < groupList->cnt; i++) {
4427fcf3ce44SJohn Forte 		if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
4428fcf3ce44SJohn Forte 		    &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
4429fcf3ce44SJohn Forte 			goto out;
4430fcf3ce44SJohn Forte 		}
4431*8fe96085Stim szeto 		ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
4432*8fe96085Stim szeto 		    &groupProps, TARGET_GROUP);
4433fcf3ce44SJohn Forte 		for (j = 0; j < groupProps->cnt; j++) {
4434fcf3ce44SJohn Forte 			if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
4435fcf3ce44SJohn Forte 			    &(groupList->name[i]), &(groupProps->name[j])))
4436fcf3ce44SJohn Forte 			    != STMF_STATUS_SUCCESS) {
4437fcf3ce44SJohn Forte 				goto out;
4438fcf3ce44SJohn Forte 			}
4439fcf3ce44SJohn Forte 		}
4440fcf3ce44SJohn Forte 	}
4441fcf3ce44SJohn Forte 
4442fcf3ce44SJohn Forte 
4443fcf3ce44SJohn Forte out:
4444fcf3ce44SJohn Forte 	stmfFreeMemory(groupProps);
4445fcf3ce44SJohn Forte 	return (ret);
4446fcf3ce44SJohn Forte }
4447fcf3ce44SJohn Forte 
4448fcf3ce44SJohn Forte 
4449fcf3ce44SJohn Forte /*
4450fcf3ce44SJohn Forte  * loadStore
4451fcf3ce44SJohn Forte  *
4452fcf3ce44SJohn Forte  * Purpose: Load the configuration data from the store
4453fcf3ce44SJohn Forte  *
4454fcf3ce44SJohn Forte  * First load the host groups and target groups, then the view entries
4455fcf3ce44SJohn Forte  * and finally the provider data
4456fcf3ce44SJohn Forte  *
4457fcf3ce44SJohn Forte  * fd - file descriptor of control node for stmf.
4458fcf3ce44SJohn Forte  */
4459fcf3ce44SJohn Forte static int
4460fcf3ce44SJohn Forte loadStore(int fd)
4461fcf3ce44SJohn Forte {
4462fcf3ce44SJohn Forte 	int ret;
4463fcf3ce44SJohn Forte 	int i, j;
4464fcf3ce44SJohn Forte 	stmfGroupList *groupList = NULL;
4465fcf3ce44SJohn Forte 	stmfGuidList *guidList = NULL;
4466fcf3ce44SJohn Forte 	stmfViewEntryList *viewEntryList = NULL;
4467fcf3ce44SJohn Forte 	stmfProviderList *providerList = NULL;
4468fcf3ce44SJohn Forte 	int providerType;
4469fcf3ce44SJohn Forte 	nvlist_t *nvl = NULL;
4470fcf3ce44SJohn Forte 
4471fcf3ce44SJohn Forte 
4472fcf3ce44SJohn Forte 
4473fcf3ce44SJohn Forte 	/* load host groups */
4474*8fe96085Stim szeto 	ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
4475fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4476fcf3ce44SJohn Forte 		return (ret);
4477fcf3ce44SJohn Forte 	}
4478fcf3ce44SJohn Forte 	ret = loadHostGroups(fd, groupList);
4479fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4480fcf3ce44SJohn Forte 		goto out;
4481fcf3ce44SJohn Forte 	}
4482fcf3ce44SJohn Forte 
4483fcf3ce44SJohn Forte 	stmfFreeMemory(groupList);
4484fcf3ce44SJohn Forte 	groupList = NULL;
4485fcf3ce44SJohn Forte 
4486fcf3ce44SJohn Forte 	/* load target groups */
4487*8fe96085Stim szeto 	ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
4488fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4489fcf3ce44SJohn Forte 		goto out;
4490fcf3ce44SJohn Forte 	}
4491fcf3ce44SJohn Forte 	ret = loadTargetGroups(fd, groupList);
4492fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4493fcf3ce44SJohn Forte 		goto out;
4494fcf3ce44SJohn Forte 	}
4495fcf3ce44SJohn Forte 
4496fcf3ce44SJohn Forte 	stmfFreeMemory(groupList);
4497fcf3ce44SJohn Forte 	groupList = NULL;
4498fcf3ce44SJohn Forte 
4499fcf3ce44SJohn Forte 	/* Get the guid list */
4500fcf3ce44SJohn Forte 	ret = psGetLogicalUnitList(&guidList);
4501fcf3ce44SJohn Forte 	switch (ret) {
4502fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
4503fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
4504fcf3ce44SJohn Forte 			break;
4505fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
4506fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
4507fcf3ce44SJohn Forte 			break;
4508fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
4509fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
4510fcf3ce44SJohn Forte 			break;
4511fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
4512fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
4513fcf3ce44SJohn Forte 			break;
4514fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
4515fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
4516fcf3ce44SJohn Forte 			break;
4517fcf3ce44SJohn Forte 		default:
4518fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
4519fcf3ce44SJohn Forte 			break;
4520fcf3ce44SJohn Forte 	}
4521fcf3ce44SJohn Forte 
4522fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4523fcf3ce44SJohn Forte 		goto out;
4524fcf3ce44SJohn Forte 	}
4525fcf3ce44SJohn Forte 
4526fcf3ce44SJohn Forte 	/*
4527fcf3ce44SJohn Forte 	 * We have the guid list, now get the corresponding
4528fcf3ce44SJohn Forte 	 * view entries for each guid
4529fcf3ce44SJohn Forte 	 */
4530fcf3ce44SJohn Forte 	for (i = 0; i < guidList->cnt; i++) {
4531fcf3ce44SJohn Forte 		ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
4532fcf3ce44SJohn Forte 		switch (ret) {
4533fcf3ce44SJohn Forte 			case STMF_PS_SUCCESS:
4534fcf3ce44SJohn Forte 				ret = STMF_STATUS_SUCCESS;
4535fcf3ce44SJohn Forte 				break;
4536fcf3ce44SJohn Forte 			case STMF_PS_ERROR_NOT_FOUND:
4537fcf3ce44SJohn Forte 				ret = STMF_ERROR_NOT_FOUND;
4538fcf3ce44SJohn Forte 				break;
4539fcf3ce44SJohn Forte 			case STMF_PS_ERROR_BUSY:
4540fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4541fcf3ce44SJohn Forte 				break;
4542fcf3ce44SJohn Forte 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
4543fcf3ce44SJohn Forte 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
4544fcf3ce44SJohn Forte 				break;
4545fcf3ce44SJohn Forte 			case STMF_PS_ERROR_VERSION_MISMATCH:
4546fcf3ce44SJohn Forte 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
4547fcf3ce44SJohn Forte 				break;
4548fcf3ce44SJohn Forte 			default:
4549fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4550fcf3ce44SJohn Forte 				break;
4551fcf3ce44SJohn Forte 		}
4552fcf3ce44SJohn Forte 		if (ret != STMF_STATUS_SUCCESS) {
4553fcf3ce44SJohn Forte 			goto out;
4554fcf3ce44SJohn Forte 		}
4555fcf3ce44SJohn Forte 		for (j = 0; j < viewEntryList->cnt; j++) {
4556fcf3ce44SJohn Forte 			ret = addViewEntryIoctl(fd, &guidList->guid[i],
4557fcf3ce44SJohn Forte 			    &viewEntryList->ve[j]);
4558fcf3ce44SJohn Forte 			if (ret != STMF_STATUS_SUCCESS) {
4559fcf3ce44SJohn Forte 				goto out;
4560fcf3ce44SJohn Forte 			}
4561fcf3ce44SJohn Forte 		}
4562fcf3ce44SJohn Forte 	}
4563fcf3ce44SJohn Forte 
4564fcf3ce44SJohn Forte 	/* get the list of providers that have data */
4565fcf3ce44SJohn Forte 	ret = psGetProviderDataList(&providerList);
4566fcf3ce44SJohn Forte 	switch (ret) {
4567fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
4568fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
4569fcf3ce44SJohn Forte 			break;
4570fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
4571fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
4572fcf3ce44SJohn Forte 			break;
4573fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
4574fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
4575fcf3ce44SJohn Forte 			break;
4576fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
4577fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
4578fcf3ce44SJohn Forte 			break;
4579fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
4580fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
4581fcf3ce44SJohn Forte 			break;
4582fcf3ce44SJohn Forte 		default:
4583fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
4584fcf3ce44SJohn Forte 			break;
4585fcf3ce44SJohn Forte 	}
4586fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4587fcf3ce44SJohn Forte 		goto out;
4588fcf3ce44SJohn Forte 	}
4589fcf3ce44SJohn Forte 
4590fcf3ce44SJohn Forte 	for (i = 0; i < providerList->cnt; i++) {
4591fcf3ce44SJohn Forte 		providerType = providerList->provider[i].providerType;
4592fcf3ce44SJohn Forte 		ret = psGetProviderData(providerList->provider[i].name,
4593fcf3ce44SJohn Forte 		    &nvl, providerType, NULL);
4594fcf3ce44SJohn Forte 		switch (ret) {
4595fcf3ce44SJohn Forte 			case STMF_PS_SUCCESS:
4596fcf3ce44SJohn Forte 				ret = STMF_STATUS_SUCCESS;
4597fcf3ce44SJohn Forte 				break;
4598fcf3ce44SJohn Forte 			case STMF_PS_ERROR_NOT_FOUND:
4599fcf3ce44SJohn Forte 				ret = STMF_ERROR_NOT_FOUND;
4600fcf3ce44SJohn Forte 				break;
4601fcf3ce44SJohn Forte 			case STMF_PS_ERROR_BUSY:
4602fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4603fcf3ce44SJohn Forte 				break;
4604fcf3ce44SJohn Forte 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
4605fcf3ce44SJohn Forte 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
4606fcf3ce44SJohn Forte 				break;
4607fcf3ce44SJohn Forte 			case STMF_PS_ERROR_VERSION_MISMATCH:
4608fcf3ce44SJohn Forte 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
4609fcf3ce44SJohn Forte 				break;
4610fcf3ce44SJohn Forte 			default:
4611fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4612fcf3ce44SJohn Forte 				break;
4613fcf3ce44SJohn Forte 		}
4614fcf3ce44SJohn Forte 		if (ret != STMF_STATUS_SUCCESS) {
4615fcf3ce44SJohn Forte 			goto out;
4616fcf3ce44SJohn Forte 		}
4617fcf3ce44SJohn Forte 
4618fcf3ce44SJohn Forte 		/* call setProviderData */
4619fcf3ce44SJohn Forte 		ret = setProviderData(fd, providerList->provider[i].name, nvl,
4620*8fe96085Stim szeto 		    providerType, NULL);
4621fcf3ce44SJohn Forte 		switch (ret) {
4622fcf3ce44SJohn Forte 			case STMF_PS_SUCCESS:
4623fcf3ce44SJohn Forte 				ret = STMF_STATUS_SUCCESS;
4624fcf3ce44SJohn Forte 				break;
4625fcf3ce44SJohn Forte 			case STMF_PS_ERROR_NOT_FOUND:
4626fcf3ce44SJohn Forte 				ret = STMF_ERROR_NOT_FOUND;
4627fcf3ce44SJohn Forte 				break;
4628fcf3ce44SJohn Forte 			case STMF_PS_ERROR_BUSY:
4629fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4630fcf3ce44SJohn Forte 				break;
4631fcf3ce44SJohn Forte 			case STMF_PS_ERROR_SERVICE_NOT_FOUND:
4632fcf3ce44SJohn Forte 				ret = STMF_ERROR_SERVICE_NOT_FOUND;
4633fcf3ce44SJohn Forte 				break;
4634fcf3ce44SJohn Forte 			case STMF_PS_ERROR_VERSION_MISMATCH:
4635fcf3ce44SJohn Forte 				ret = STMF_ERROR_SERVICE_DATA_VERSION;
4636fcf3ce44SJohn Forte 				break;
4637fcf3ce44SJohn Forte 			default:
4638fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4639fcf3ce44SJohn Forte 				break;
4640fcf3ce44SJohn Forte 		}
4641fcf3ce44SJohn Forte 		if (ret != STMF_STATUS_SUCCESS) {
4642fcf3ce44SJohn Forte 			goto out;
4643fcf3ce44SJohn Forte 		}
4644fcf3ce44SJohn Forte 
4645fcf3ce44SJohn Forte 		nvlist_free(nvl);
4646fcf3ce44SJohn Forte 		nvl = NULL;
4647fcf3ce44SJohn Forte 	}
4648fcf3ce44SJohn Forte out:
4649fcf3ce44SJohn Forte 	if (groupList != NULL) {
4650fcf3ce44SJohn Forte 		free(groupList);
4651fcf3ce44SJohn Forte 	}
4652fcf3ce44SJohn Forte 	if (guidList != NULL) {
4653fcf3ce44SJohn Forte 		free(guidList);
4654fcf3ce44SJohn Forte 	}
4655fcf3ce44SJohn Forte 	if (viewEntryList != NULL) {
4656fcf3ce44SJohn Forte 		free(viewEntryList);
4657fcf3ce44SJohn Forte 	}
4658fcf3ce44SJohn Forte 	if (nvl != NULL) {
4659fcf3ce44SJohn Forte 		nvlist_free(nvl);
4660fcf3ce44SJohn Forte 	}
4661fcf3ce44SJohn Forte 	return (ret);
4662fcf3ce44SJohn Forte }
4663fcf3ce44SJohn Forte 
4664fcf3ce44SJohn Forte /*
4665fcf3ce44SJohn Forte  * stmfLoadConfig
4666fcf3ce44SJohn Forte  *
4667fcf3ce44SJohn Forte  * Purpose - load the configuration data from smf into stmf
4668fcf3ce44SJohn Forte  *
4669fcf3ce44SJohn Forte  */
4670fcf3ce44SJohn Forte int
4671fcf3ce44SJohn Forte stmfLoadConfig(void)
4672fcf3ce44SJohn Forte {
4673*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
4674fcf3ce44SJohn Forte 	int fd;
4675fcf3ce44SJohn Forte 	stmf_state_desc_t stmfStateSet;
4676fcf3ce44SJohn Forte 	stmfState state;
4677fcf3ce44SJohn Forte 
4678*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
4679*8fe96085Stim szeto 		stmfStateSet.state = STMF_STATE_OFFLINE;
4680*8fe96085Stim szeto 		stmfStateSet.config_state = STMF_CONFIG_INIT;
4681*8fe96085Stim szeto 		if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
4682*8fe96085Stim szeto 		    != STMF_STATUS_SUCCESS) {
4683*8fe96085Stim szeto 			return (ret);
4684*8fe96085Stim szeto 		}
4685*8fe96085Stim szeto 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
4686*8fe96085Stim szeto 		if (ret != STMF_STATUS_SUCCESS) {
4687*8fe96085Stim szeto 			goto done;
4688*8fe96085Stim szeto 		}
4689*8fe96085Stim szeto 		stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
4690*8fe96085Stim szeto 		goto done;
4691*8fe96085Stim szeto 	}
4692fcf3ce44SJohn Forte 
4693fcf3ce44SJohn Forte 	/* Check to ensure service exists */
4694fcf3ce44SJohn Forte 	if (psCheckService() != STMF_STATUS_SUCCESS) {
4695fcf3ce44SJohn Forte 		return (STMF_ERROR_SERVICE_NOT_FOUND);
4696fcf3ce44SJohn Forte 	}
4697fcf3ce44SJohn Forte 
4698fcf3ce44SJohn Forte 	ret = stmfGetState(&state);
4699fcf3ce44SJohn Forte 	if (ret == STMF_STATUS_SUCCESS) {
4700fcf3ce44SJohn Forte 		if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
4701fcf3ce44SJohn Forte 			return (STMF_ERROR_SERVICE_ONLINE);
4702fcf3ce44SJohn Forte 		}
4703fcf3ce44SJohn Forte 	} else {
4704fcf3ce44SJohn Forte 		return (STMF_STATUS_ERROR);
4705fcf3ce44SJohn Forte 	}
4706fcf3ce44SJohn Forte 
4707fcf3ce44SJohn Forte 
4708fcf3ce44SJohn Forte 	stmfStateSet.state = STMF_STATE_OFFLINE;
4709fcf3ce44SJohn Forte 	stmfStateSet.config_state = STMF_CONFIG_INIT;
4710fcf3ce44SJohn Forte 
4711fcf3ce44SJohn Forte 	/*
4712fcf3ce44SJohn Forte 	 * Open control node for stmf
4713fcf3ce44SJohn Forte 	 */
4714fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
4715fcf3ce44SJohn Forte 		return (ret);
4716fcf3ce44SJohn Forte 
4717fcf3ce44SJohn Forte 	ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
4718fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
4719fcf3ce44SJohn Forte 		goto done;
4720fcf3ce44SJohn Forte 	}
4721fcf3ce44SJohn Forte 
4722fcf3ce44SJohn Forte 	/* Load the persistent configuration data */
4723fcf3ce44SJohn Forte 	ret = loadStore(fd);
4724fcf3ce44SJohn Forte 	if (ret != 0) {
4725fcf3ce44SJohn Forte 		goto done;
4726fcf3ce44SJohn Forte 	}
4727fcf3ce44SJohn Forte 
4728fcf3ce44SJohn Forte 	stmfStateSet.state = STMF_STATE_OFFLINE;
4729fcf3ce44SJohn Forte 	stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
4730fcf3ce44SJohn Forte 
4731fcf3ce44SJohn Forte done:
4732fcf3ce44SJohn Forte 	if (ret == STMF_STATUS_SUCCESS) {
4733fcf3ce44SJohn Forte 		ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
4734fcf3ce44SJohn Forte 	}
4735fcf3ce44SJohn Forte 	(void) close(fd);
4736fcf3ce44SJohn Forte 	return (ret);
4737fcf3ce44SJohn Forte }
4738fcf3ce44SJohn Forte 
4739*8fe96085Stim szeto 
4740fcf3ce44SJohn Forte /*
4741fcf3ce44SJohn Forte  * getStmfState
4742fcf3ce44SJohn Forte  *
4743fcf3ce44SJohn Forte  * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
4744fcf3ce44SJohn Forte  *             information of the stmf service on success.
4745fcf3ce44SJohn Forte  */
4746fcf3ce44SJohn Forte static int
4747fcf3ce44SJohn Forte getStmfState(stmf_state_desc_t *stmfState)
4748fcf3ce44SJohn Forte {
4749fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4750fcf3ce44SJohn Forte 	int fd;
4751fcf3ce44SJohn Forte 	int ioctlRet;
4752fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
4753fcf3ce44SJohn Forte 
4754fcf3ce44SJohn Forte 	/*
4755fcf3ce44SJohn Forte 	 * Open control node for stmf
4756fcf3ce44SJohn Forte 	 */
4757fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4758fcf3ce44SJohn Forte 		return (ret);
4759fcf3ce44SJohn Forte 
4760fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
4761fcf3ce44SJohn Forte 	/*
4762fcf3ce44SJohn Forte 	 * Issue ioctl to get the stmf state
4763fcf3ce44SJohn Forte 	 */
4764fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
4765fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
4766fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
4767fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
4768fcf3ce44SJohn Forte 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
4769fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
4770fcf3ce44SJohn Forte 
4771fcf3ce44SJohn Forte 	(void) close(fd);
4772fcf3ce44SJohn Forte 
4773fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
4774fcf3ce44SJohn Forte 		switch (errno) {
4775fcf3ce44SJohn Forte 			case EBUSY:
4776fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4777fcf3ce44SJohn Forte 				break;
4778fcf3ce44SJohn Forte 			case EPERM:
4779fcf3ce44SJohn Forte 			case EACCES:
4780fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
4781fcf3ce44SJohn Forte 				break;
4782fcf3ce44SJohn Forte 			default:
4783fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
4784fcf3ce44SJohn Forte 				    "getStmfState:ioctl errno(%d)", errno);
4785fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4786fcf3ce44SJohn Forte 				break;
4787fcf3ce44SJohn Forte 		}
4788fcf3ce44SJohn Forte 	}
4789fcf3ce44SJohn Forte 	return (ret);
4790fcf3ce44SJohn Forte }
4791fcf3ce44SJohn Forte 
4792fcf3ce44SJohn Forte 
4793fcf3ce44SJohn Forte /*
4794fcf3ce44SJohn Forte  * setStmfState
4795fcf3ce44SJohn Forte  *
4796fcf3ce44SJohn Forte  * stmfState - pointer to caller set state structure
4797fcf3ce44SJohn Forte  * objectType - one of:
4798fcf3ce44SJohn Forte  *		LOGICAL_UNIT_TYPE
4799fcf3ce44SJohn Forte  *		TARGET_TYPE
4800fcf3ce44SJohn Forte  *		STMF_SERVICE_TYPE
4801fcf3ce44SJohn Forte  */
4802fcf3ce44SJohn Forte static int
4803fcf3ce44SJohn Forte setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
4804fcf3ce44SJohn Forte {
4805fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4806fcf3ce44SJohn Forte 	int ioctlRet;
4807fcf3ce44SJohn Forte 	int cmd;
4808fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
4809fcf3ce44SJohn Forte 
4810fcf3ce44SJohn Forte 	switch (objectType) {
4811fcf3ce44SJohn Forte 		case LOGICAL_UNIT_TYPE:
4812fcf3ce44SJohn Forte 			cmd = STMF_IOCTL_SET_LU_STATE;
4813fcf3ce44SJohn Forte 			break;
4814fcf3ce44SJohn Forte 		case TARGET_TYPE:
4815fcf3ce44SJohn Forte 			cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
4816fcf3ce44SJohn Forte 			break;
4817fcf3ce44SJohn Forte 		case STMF_SERVICE_TYPE:
4818fcf3ce44SJohn Forte 			cmd = STMF_IOCTL_SET_STMF_STATE;
4819fcf3ce44SJohn Forte 			break;
4820fcf3ce44SJohn Forte 		default:
4821fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
4822fcf3ce44SJohn Forte 			goto done;
4823fcf3ce44SJohn Forte 	}
4824fcf3ce44SJohn Forte 
4825fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
4826fcf3ce44SJohn Forte 	/*
4827fcf3ce44SJohn Forte 	 * Issue ioctl to set the stmf state
4828fcf3ce44SJohn Forte 	 */
4829fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
4830fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
4831fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
4832fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4833fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
4834fcf3ce44SJohn Forte 		switch (errno) {
4835fcf3ce44SJohn Forte 			case EBUSY:
4836fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
4837fcf3ce44SJohn Forte 				break;
4838*8fe96085Stim szeto 			case EPERM:
4839fcf3ce44SJohn Forte 			case EACCES:
4840fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
4841fcf3ce44SJohn Forte 				break;
4842fcf3ce44SJohn Forte 			case ENOENT:
4843fcf3ce44SJohn Forte 				ret = STMF_ERROR_NOT_FOUND;
4844fcf3ce44SJohn Forte 				break;
4845fcf3ce44SJohn Forte 			default:
4846fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
4847fcf3ce44SJohn Forte 				    "setStmfState:ioctl errno(%d)", errno);
4848fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
4849fcf3ce44SJohn Forte 				break;
4850fcf3ce44SJohn Forte 		}
4851fcf3ce44SJohn Forte 	}
4852fcf3ce44SJohn Forte done:
4853fcf3ce44SJohn Forte 	return (ret);
4854fcf3ce44SJohn Forte }
4855fcf3ce44SJohn Forte 
4856fcf3ce44SJohn Forte /*
4857fcf3ce44SJohn Forte  * stmfOnline
4858fcf3ce44SJohn Forte  *
4859fcf3ce44SJohn Forte  * Purpose: Online stmf service
4860fcf3ce44SJohn Forte  *
4861fcf3ce44SJohn Forte  */
4862fcf3ce44SJohn Forte int
4863fcf3ce44SJohn Forte stmfOnline(void)
4864fcf3ce44SJohn Forte {
4865fcf3ce44SJohn Forte 	int ret;
4866fcf3ce44SJohn Forte 	int fd;
4867fcf3ce44SJohn Forte 	stmfState state;
4868fcf3ce44SJohn Forte 	stmf_state_desc_t iState;
4869fcf3ce44SJohn Forte 
4870fcf3ce44SJohn Forte 	ret = stmfGetState(&state);
4871fcf3ce44SJohn Forte 	if (ret == STMF_STATUS_SUCCESS) {
4872fcf3ce44SJohn Forte 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
4873fcf3ce44SJohn Forte 			return (STMF_ERROR_SERVICE_ONLINE);
4874fcf3ce44SJohn Forte 		}
4875fcf3ce44SJohn Forte 	} else {
4876fcf3ce44SJohn Forte 		return (STMF_STATUS_ERROR);
4877fcf3ce44SJohn Forte 	}
4878fcf3ce44SJohn Forte 	iState.state = STMF_STATE_ONLINE;
4879fcf3ce44SJohn Forte 	iState.config_state = STMF_CONFIG_NONE;
4880fcf3ce44SJohn Forte 	/*
4881fcf3ce44SJohn Forte 	 * Open control node for stmf
4882fcf3ce44SJohn Forte 	 * to make call to setStmfState()
4883fcf3ce44SJohn Forte 	 */
4884fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
4885fcf3ce44SJohn Forte 		return (ret);
4886fcf3ce44SJohn Forte 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
4887fcf3ce44SJohn Forte 	(void) close(fd);
4888fcf3ce44SJohn Forte 	return (ret);
4889fcf3ce44SJohn Forte }
4890fcf3ce44SJohn Forte 
4891fcf3ce44SJohn Forte /*
4892fcf3ce44SJohn Forte  * stmfOffline
4893fcf3ce44SJohn Forte  *
4894fcf3ce44SJohn Forte  * Purpose: Offline stmf service
4895fcf3ce44SJohn Forte  *
4896fcf3ce44SJohn Forte  */
4897fcf3ce44SJohn Forte int
4898fcf3ce44SJohn Forte stmfOffline(void)
4899fcf3ce44SJohn Forte {
4900fcf3ce44SJohn Forte 	int ret;
4901fcf3ce44SJohn Forte 	int fd;
4902fcf3ce44SJohn Forte 	stmfState state;
4903fcf3ce44SJohn Forte 	stmf_state_desc_t iState;
4904fcf3ce44SJohn Forte 
4905fcf3ce44SJohn Forte 	ret = stmfGetState(&state);
4906fcf3ce44SJohn Forte 	if (ret == STMF_STATUS_SUCCESS) {
4907fcf3ce44SJohn Forte 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
4908fcf3ce44SJohn Forte 			return (STMF_ERROR_SERVICE_OFFLINE);
4909fcf3ce44SJohn Forte 		}
4910fcf3ce44SJohn Forte 	} else {
4911fcf3ce44SJohn Forte 		return (STMF_STATUS_ERROR);
4912fcf3ce44SJohn Forte 	}
4913fcf3ce44SJohn Forte 	iState.state = STMF_STATE_OFFLINE;
4914fcf3ce44SJohn Forte 	iState.config_state = STMF_CONFIG_NONE;
4915fcf3ce44SJohn Forte 
4916fcf3ce44SJohn Forte 	/*
4917fcf3ce44SJohn Forte 	 * Open control node for stmf
4918fcf3ce44SJohn Forte 	 * to make call to setStmfState()
4919fcf3ce44SJohn Forte 	 */
4920fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
4921fcf3ce44SJohn Forte 		return (ret);
4922fcf3ce44SJohn Forte 	ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
4923fcf3ce44SJohn Forte 	(void) close(fd);
4924fcf3ce44SJohn Forte 	return (ret);
4925fcf3ce44SJohn Forte }
4926fcf3ce44SJohn Forte 
4927fcf3ce44SJohn Forte 
4928fcf3ce44SJohn Forte /*
4929fcf3ce44SJohn Forte  * stmfOfflineTarget
4930fcf3ce44SJohn Forte  *
4931fcf3ce44SJohn Forte  * Purpose: Change state of target to offline
4932fcf3ce44SJohn Forte  *
4933fcf3ce44SJohn Forte  * devid - devid of the target to offline
4934fcf3ce44SJohn Forte  */
4935fcf3ce44SJohn Forte int
4936fcf3ce44SJohn Forte stmfOfflineTarget(stmfDevid *devid)
4937fcf3ce44SJohn Forte {
4938fcf3ce44SJohn Forte 	stmf_state_desc_t targetState;
4939fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4940fcf3ce44SJohn Forte 	int fd;
4941fcf3ce44SJohn Forte 
4942fcf3ce44SJohn Forte 	if (devid == NULL) {
4943fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
4944fcf3ce44SJohn Forte 	}
4945fcf3ce44SJohn Forte 	bzero(&targetState, sizeof (targetState));
4946fcf3ce44SJohn Forte 
4947fcf3ce44SJohn Forte 	targetState.state = STMF_STATE_OFFLINE;
4948fcf3ce44SJohn Forte 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
4949fcf3ce44SJohn Forte 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
4950fcf3ce44SJohn Forte 	    devid->identLength);
4951fcf3ce44SJohn Forte 	/*
4952fcf3ce44SJohn Forte 	 * Open control node for stmf
4953fcf3ce44SJohn Forte 	 * to make call to setStmfState()
4954fcf3ce44SJohn Forte 	 */
4955fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
4956fcf3ce44SJohn Forte 		return (ret);
4957fcf3ce44SJohn Forte 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
4958fcf3ce44SJohn Forte 	(void) close(fd);
4959fcf3ce44SJohn Forte 	return (ret);
4960fcf3ce44SJohn Forte }
4961fcf3ce44SJohn Forte 
4962fcf3ce44SJohn Forte /*
4963fcf3ce44SJohn Forte  * stmfOfflineLogicalUnit
4964fcf3ce44SJohn Forte  *
4965fcf3ce44SJohn Forte  * Purpose: Change state of logical unit to offline
4966fcf3ce44SJohn Forte  *
4967fcf3ce44SJohn Forte  * lu - guid of the logical unit to offline
4968fcf3ce44SJohn Forte  */
4969fcf3ce44SJohn Forte int
4970fcf3ce44SJohn Forte stmfOfflineLogicalUnit(stmfGuid *lu)
4971fcf3ce44SJohn Forte {
4972fcf3ce44SJohn Forte 	stmf_state_desc_t luState;
4973fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
4974fcf3ce44SJohn Forte 	int fd;
4975fcf3ce44SJohn Forte 
4976fcf3ce44SJohn Forte 	if (lu == NULL) {
4977fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
4978fcf3ce44SJohn Forte 	}
4979fcf3ce44SJohn Forte 
4980fcf3ce44SJohn Forte 	bzero(&luState, sizeof (luState));
4981fcf3ce44SJohn Forte 
4982fcf3ce44SJohn Forte 	luState.state = STMF_STATE_OFFLINE;
4983fcf3ce44SJohn Forte 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
4984fcf3ce44SJohn Forte 	/*
4985fcf3ce44SJohn Forte 	 * Open control node for stmf
4986fcf3ce44SJohn Forte 	 * to make call to setStmfState()
4987fcf3ce44SJohn Forte 	 */
4988fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
4989fcf3ce44SJohn Forte 		return (ret);
4990fcf3ce44SJohn Forte 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
4991fcf3ce44SJohn Forte 	(void) close(fd);
4992fcf3ce44SJohn Forte 	return (ret);
4993fcf3ce44SJohn Forte }
4994fcf3ce44SJohn Forte 
4995fcf3ce44SJohn Forte /*
4996fcf3ce44SJohn Forte  * stmfOnlineTarget
4997fcf3ce44SJohn Forte  *
4998fcf3ce44SJohn Forte  * Purpose: Change state of target to online
4999fcf3ce44SJohn Forte  *
5000fcf3ce44SJohn Forte  * devid - devid of the target to online
5001fcf3ce44SJohn Forte  */
5002fcf3ce44SJohn Forte int
5003fcf3ce44SJohn Forte stmfOnlineTarget(stmfDevid *devid)
5004fcf3ce44SJohn Forte {
5005fcf3ce44SJohn Forte 	stmf_state_desc_t targetState;
5006fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
5007fcf3ce44SJohn Forte 	int fd;
5008fcf3ce44SJohn Forte 
5009fcf3ce44SJohn Forte 	if (devid == NULL) {
5010fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5011fcf3ce44SJohn Forte 	}
5012fcf3ce44SJohn Forte 	bzero(&targetState, sizeof (targetState));
5013fcf3ce44SJohn Forte 
5014fcf3ce44SJohn Forte 	targetState.state = STMF_STATE_ONLINE;
5015fcf3ce44SJohn Forte 	targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
5016fcf3ce44SJohn Forte 	bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
5017fcf3ce44SJohn Forte 	    devid->identLength);
5018fcf3ce44SJohn Forte 	/*
5019fcf3ce44SJohn Forte 	 * Open control node for stmf
5020fcf3ce44SJohn Forte 	 * to make call to setStmfState()
5021fcf3ce44SJohn Forte 	 */
5022fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5023fcf3ce44SJohn Forte 		return (ret);
5024fcf3ce44SJohn Forte 	ret = setStmfState(fd, &targetState, TARGET_TYPE);
5025fcf3ce44SJohn Forte 	(void) close(fd);
5026fcf3ce44SJohn Forte 	return (ret);
5027fcf3ce44SJohn Forte }
5028fcf3ce44SJohn Forte 
5029fcf3ce44SJohn Forte /*
5030fcf3ce44SJohn Forte  * stmfOnlineLogicalUnit
5031fcf3ce44SJohn Forte  *
5032fcf3ce44SJohn Forte  * Purpose: Change state of logical unit to online
5033fcf3ce44SJohn Forte  *
5034fcf3ce44SJohn Forte  * lu - guid of the logical unit to online
5035fcf3ce44SJohn Forte  */
5036fcf3ce44SJohn Forte int
5037fcf3ce44SJohn Forte stmfOnlineLogicalUnit(stmfGuid *lu)
5038fcf3ce44SJohn Forte {
5039fcf3ce44SJohn Forte 	stmf_state_desc_t luState;
5040fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
5041fcf3ce44SJohn Forte 	int fd;
5042fcf3ce44SJohn Forte 
5043fcf3ce44SJohn Forte 	if (lu == NULL) {
5044fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5045fcf3ce44SJohn Forte 	}
5046fcf3ce44SJohn Forte 
5047fcf3ce44SJohn Forte 	bzero(&luState, sizeof (luState));
5048fcf3ce44SJohn Forte 
5049fcf3ce44SJohn Forte 	luState.state = STMF_STATE_ONLINE;
5050fcf3ce44SJohn Forte 	bcopy(lu, &luState.ident, sizeof (stmfGuid));
5051fcf3ce44SJohn Forte 	/*
5052fcf3ce44SJohn Forte 	 * Open control node for stmf
5053fcf3ce44SJohn Forte 	 * to make call to setStmfState()
5054fcf3ce44SJohn Forte 	 */
5055fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5056fcf3ce44SJohn Forte 		return (ret);
5057fcf3ce44SJohn Forte 	ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
5058fcf3ce44SJohn Forte 	(void) close(fd);
5059fcf3ce44SJohn Forte 	return (ret);
5060fcf3ce44SJohn Forte }
5061fcf3ce44SJohn Forte 
5062fcf3ce44SJohn Forte /*
5063fcf3ce44SJohn Forte  * stmfRemoveFromHostGroup
5064fcf3ce44SJohn Forte  *
5065fcf3ce44SJohn Forte  * Purpose: Removes an initiator from an initiator group
5066fcf3ce44SJohn Forte  *
5067fcf3ce44SJohn Forte  * hostGroupName - name of an initiator group
5068fcf3ce44SJohn Forte  * hostName - name of host group member to remove
5069fcf3ce44SJohn Forte  */
5070fcf3ce44SJohn Forte int
5071fcf3ce44SJohn Forte stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
5072fcf3ce44SJohn Forte {
5073fcf3ce44SJohn Forte 	int ret;
5074fcf3ce44SJohn Forte 	int fd;
5075fcf3ce44SJohn Forte 
5076fcf3ce44SJohn Forte 	if (hostGroupName == NULL ||
5077fcf3ce44SJohn Forte 	    (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
5078fcf3ce44SJohn Forte 	    == sizeof (stmfGroupName)) || hostName == NULL) {
5079fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5080fcf3ce44SJohn Forte 	}
5081fcf3ce44SJohn Forte 
5082fcf3ce44SJohn Forte 	/* call init */
5083fcf3ce44SJohn Forte 	ret = initializeConfig();
5084fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
5085fcf3ce44SJohn Forte 		return (ret);
5086fcf3ce44SJohn Forte 	}
5087fcf3ce44SJohn Forte 
5088fcf3ce44SJohn Forte 	/*
5089fcf3ce44SJohn Forte 	 * Open control node for stmf
5090fcf3ce44SJohn Forte 	 */
5091fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5092fcf3ce44SJohn Forte 		return (ret);
5093fcf3ce44SJohn Forte 
5094fcf3ce44SJohn Forte 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
5095fcf3ce44SJohn Forte 	    hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
5096fcf3ce44SJohn Forte 		goto done;
5097fcf3ce44SJohn Forte 	}
5098fcf3ce44SJohn Forte 
5099*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5100*8fe96085Stim szeto 		goto done;
5101*8fe96085Stim szeto 	}
5102*8fe96085Stim szeto 
5103fcf3ce44SJohn Forte 	ret = psRemoveHostGroupMember((char *)hostGroupName,
5104fcf3ce44SJohn Forte 	    (char *)hostName->ident);
5105fcf3ce44SJohn Forte 	switch (ret) {
5106fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
5107fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
5108fcf3ce44SJohn Forte 			break;
5109fcf3ce44SJohn Forte 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
5110fcf3ce44SJohn Forte 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
5111fcf3ce44SJohn Forte 			break;
5112fcf3ce44SJohn Forte 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5113fcf3ce44SJohn Forte 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5114fcf3ce44SJohn Forte 			break;
5115fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
5116fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
5117fcf3ce44SJohn Forte 			break;
5118fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5119fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5120fcf3ce44SJohn Forte 			break;
5121fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
5122fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5123fcf3ce44SJohn Forte 			break;
5124fcf3ce44SJohn Forte 		default:
5125fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
5126fcf3ce44SJohn Forte 			    "stmfRemoveFromHostGroup"
5127fcf3ce44SJohn Forte 			    "psRemoveHostGroupMember:error(%d)", ret);
5128fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
5129fcf3ce44SJohn Forte 			break;
5130fcf3ce44SJohn Forte 	}
5131fcf3ce44SJohn Forte 
5132fcf3ce44SJohn Forte done:
5133fcf3ce44SJohn Forte 	(void) close(fd);
5134fcf3ce44SJohn Forte 	return (ret);
5135fcf3ce44SJohn Forte }
5136fcf3ce44SJohn Forte 
5137fcf3ce44SJohn Forte /*
5138fcf3ce44SJohn Forte  * stmfRemoveFromTargetGroup
5139fcf3ce44SJohn Forte  *
5140fcf3ce44SJohn Forte  * Purpose: Removes a local port from a local port group
5141fcf3ce44SJohn Forte  *
5142fcf3ce44SJohn Forte  * targetGroupName - name of a target group
5143fcf3ce44SJohn Forte  * targetName - name of target to remove
5144fcf3ce44SJohn Forte  */
5145fcf3ce44SJohn Forte int
5146fcf3ce44SJohn Forte stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
5147fcf3ce44SJohn Forte {
5148fcf3ce44SJohn Forte 	int ret;
5149fcf3ce44SJohn Forte 	int fd;
5150fcf3ce44SJohn Forte 
5151fcf3ce44SJohn Forte 	if (targetGroupName == NULL ||
5152fcf3ce44SJohn Forte 	    (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
5153fcf3ce44SJohn Forte 	    == sizeof (stmfGroupName)) || targetName == NULL) {
5154fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5155fcf3ce44SJohn Forte 	}
5156fcf3ce44SJohn Forte 
5157fcf3ce44SJohn Forte 	/* call init */
5158fcf3ce44SJohn Forte 	ret = initializeConfig();
5159fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
5160fcf3ce44SJohn Forte 		return (ret);
5161fcf3ce44SJohn Forte 	}
5162fcf3ce44SJohn Forte 
5163fcf3ce44SJohn Forte 	/*
5164fcf3ce44SJohn Forte 	 * Open control node for stmf
5165fcf3ce44SJohn Forte 	 */
5166fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5167fcf3ce44SJohn Forte 		return (ret);
5168fcf3ce44SJohn Forte 
5169fcf3ce44SJohn Forte 	if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
5170fcf3ce44SJohn Forte 	    targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
5171fcf3ce44SJohn Forte 		goto done;
5172fcf3ce44SJohn Forte 	}
5173fcf3ce44SJohn Forte 
5174*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5175*8fe96085Stim szeto 		goto done;
5176*8fe96085Stim szeto 	}
5177*8fe96085Stim szeto 
5178fcf3ce44SJohn Forte 	ret = psRemoveTargetGroupMember((char *)targetGroupName,
5179fcf3ce44SJohn Forte 	    (char *)targetName->ident);
5180fcf3ce44SJohn Forte 	switch (ret) {
5181fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
5182fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
5183fcf3ce44SJohn Forte 			break;
5184fcf3ce44SJohn Forte 		case STMF_PS_ERROR_MEMBER_NOT_FOUND:
5185fcf3ce44SJohn Forte 			ret = STMF_ERROR_MEMBER_NOT_FOUND;
5186fcf3ce44SJohn Forte 			break;
5187fcf3ce44SJohn Forte 		case STMF_PS_ERROR_GROUP_NOT_FOUND:
5188fcf3ce44SJohn Forte 			ret = STMF_ERROR_GROUP_NOT_FOUND;
5189fcf3ce44SJohn Forte 			break;
5190fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
5191fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
5192fcf3ce44SJohn Forte 			break;
5193fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5194fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5195fcf3ce44SJohn Forte 			break;
5196fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
5197fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5198fcf3ce44SJohn Forte 			break;
5199fcf3ce44SJohn Forte 		default:
5200fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
5201fcf3ce44SJohn Forte 			    "stmfRemoveFromTargetGroup"
5202fcf3ce44SJohn Forte 			    "psRemoveTargetGroupMember:error(%d)", ret);
5203fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
5204fcf3ce44SJohn Forte 			break;
5205fcf3ce44SJohn Forte 	}
5206fcf3ce44SJohn Forte 
5207fcf3ce44SJohn Forte done:
5208fcf3ce44SJohn Forte 	(void) close(fd);
5209fcf3ce44SJohn Forte 	return (ret);
5210fcf3ce44SJohn Forte }
5211fcf3ce44SJohn Forte 
5212fcf3ce44SJohn Forte /*
5213fcf3ce44SJohn Forte  * stmfRemoveViewEntry
5214fcf3ce44SJohn Forte  *
5215fcf3ce44SJohn Forte  * Purpose: Removes a view entry from a logical unit
5216fcf3ce44SJohn Forte  *
5217fcf3ce44SJohn Forte  * lu - guid of lu for which view entry is being removed
5218fcf3ce44SJohn Forte  * viewEntryIndex - index of view entry to remove
5219fcf3ce44SJohn Forte  *
5220fcf3ce44SJohn Forte  */
5221fcf3ce44SJohn Forte int
5222fcf3ce44SJohn Forte stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
5223fcf3ce44SJohn Forte {
5224fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
5225fcf3ce44SJohn Forte 	int fd;
5226fcf3ce44SJohn Forte 	int ioctlRet;
5227fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
5228fcf3ce44SJohn Forte 	stmf_view_op_entry_t ioctlViewEntry;
5229fcf3ce44SJohn Forte 
5230fcf3ce44SJohn Forte 	if (lu == NULL) {
5231fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5232fcf3ce44SJohn Forte 	}
5233fcf3ce44SJohn Forte 
5234fcf3ce44SJohn Forte 	/* call init */
5235fcf3ce44SJohn Forte 	ret = initializeConfig();
5236fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
5237fcf3ce44SJohn Forte 		return (ret);
5238fcf3ce44SJohn Forte 	}
5239fcf3ce44SJohn Forte 
5240fcf3ce44SJohn Forte 	/*
5241fcf3ce44SJohn Forte 	 * Open control node for stmf
5242fcf3ce44SJohn Forte 	 */
5243fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5244fcf3ce44SJohn Forte 		return (ret);
5245fcf3ce44SJohn Forte 
5246fcf3ce44SJohn Forte 	bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
5247fcf3ce44SJohn Forte 	ioctlViewEntry.ve_ndx_valid = B_TRUE;
5248fcf3ce44SJohn Forte 	ioctlViewEntry.ve_ndx = viewEntryIndex;
5249fcf3ce44SJohn Forte 	bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
5250fcf3ce44SJohn Forte 
5251fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
5252fcf3ce44SJohn Forte 	/*
5253fcf3ce44SJohn Forte 	 * Issue ioctl to add to the view entry
5254fcf3ce44SJohn Forte 	 */
5255fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
5256fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
5257fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
5258fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
5259fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
5260fcf3ce44SJohn Forte 		switch (errno) {
5261fcf3ce44SJohn Forte 			case EBUSY:
5262fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
5263fcf3ce44SJohn Forte 				break;
5264*8fe96085Stim szeto 			case EPERM:
5265*8fe96085Stim szeto 				ret = STMF_ERROR_PERM;
5266*8fe96085Stim szeto 				break;
5267fcf3ce44SJohn Forte 			case EACCES:
5268fcf3ce44SJohn Forte 				switch (stmfIoctl.stmf_error) {
5269fcf3ce44SJohn Forte 					case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
5270fcf3ce44SJohn Forte 						ret = STMF_ERROR_CONFIG_NONE;
5271fcf3ce44SJohn Forte 						break;
5272fcf3ce44SJohn Forte 					default:
5273fcf3ce44SJohn Forte 						ret = STMF_ERROR_PERM;
5274fcf3ce44SJohn Forte 						break;
5275fcf3ce44SJohn Forte 				}
5276fcf3ce44SJohn Forte 				break;
5277fcf3ce44SJohn Forte 			case ENODEV:
5278fcf3ce44SJohn Forte 			case ENOENT:
5279fcf3ce44SJohn Forte 				ret = STMF_ERROR_NOT_FOUND;
5280fcf3ce44SJohn Forte 				break;
5281fcf3ce44SJohn Forte 			default:
5282fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
5283fcf3ce44SJohn Forte 				    "stmfRemoveViewEntry:ioctl errno(%d)",
5284fcf3ce44SJohn Forte 				    errno);
5285fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
5286fcf3ce44SJohn Forte 				break;
5287fcf3ce44SJohn Forte 		}
5288fcf3ce44SJohn Forte 		goto done;
5289fcf3ce44SJohn Forte 	}
5290fcf3ce44SJohn Forte 
5291*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5292*8fe96085Stim szeto 		goto done;
5293*8fe96085Stim szeto 	}
5294*8fe96085Stim szeto 
5295fcf3ce44SJohn Forte 	ret = psRemoveViewEntry(lu, viewEntryIndex);
5296fcf3ce44SJohn Forte 	switch (ret) {
5297fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
5298fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
5299fcf3ce44SJohn Forte 			break;
5300fcf3ce44SJohn Forte 		case STMF_PS_ERROR_NOT_FOUND:
5301fcf3ce44SJohn Forte 			ret = STMF_ERROR_NOT_FOUND;
5302fcf3ce44SJohn Forte 			break;
5303fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
5304fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
5305fcf3ce44SJohn Forte 			break;
5306fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5307fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5308fcf3ce44SJohn Forte 			break;
5309fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
5310fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5311fcf3ce44SJohn Forte 			break;
5312fcf3ce44SJohn Forte 		default:
5313fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
5314fcf3ce44SJohn Forte 			    "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
5315fcf3ce44SJohn Forte 			    ret);
5316fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
5317fcf3ce44SJohn Forte 			break;
5318fcf3ce44SJohn Forte 	}
5319fcf3ce44SJohn Forte 
5320fcf3ce44SJohn Forte done:
5321fcf3ce44SJohn Forte 	(void) close(fd);
5322fcf3ce44SJohn Forte 	return (ret);
5323fcf3ce44SJohn Forte }
5324fcf3ce44SJohn Forte 
5325fcf3ce44SJohn Forte /*
5326fcf3ce44SJohn Forte  * stmfSetProviderData
5327fcf3ce44SJohn Forte  *
5328fcf3ce44SJohn Forte  * Purpose: set the provider data
5329fcf3ce44SJohn Forte  *
5330fcf3ce44SJohn Forte  * providerName - unique name of provider
5331fcf3ce44SJohn Forte  * nvl - nvlist to set
5332fcf3ce44SJohn Forte  * providerType - type of provider for which to set data
5333fcf3ce44SJohn Forte  *		STMF_LU_PROVIDER_TYPE
5334fcf3ce44SJohn Forte  *		STMF_PORT_PROVIDER_TYPE
5335fcf3ce44SJohn Forte  */
5336fcf3ce44SJohn Forte int
5337fcf3ce44SJohn Forte stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
5338fcf3ce44SJohn Forte {
5339fcf3ce44SJohn Forte 	return (stmfSetProviderDataProt(providerName, nvl, providerType,
5340fcf3ce44SJohn Forte 	    NULL));
5341fcf3ce44SJohn Forte }
5342fcf3ce44SJohn Forte 
5343fcf3ce44SJohn Forte /*
5344fcf3ce44SJohn Forte  * stmfSetProviderDataProt
5345fcf3ce44SJohn Forte  *
5346fcf3ce44SJohn Forte  * Purpose: set the provider data
5347fcf3ce44SJohn Forte  *
5348fcf3ce44SJohn Forte  * providerName - unique name of provider
5349fcf3ce44SJohn Forte  * nvl - nvlist to set
5350fcf3ce44SJohn Forte  * providerType - type of provider for which to set data
5351fcf3ce44SJohn Forte  *		STMF_LU_PROVIDER_TYPE
5352fcf3ce44SJohn Forte  *		STMF_PORT_PROVIDER_TYPE
5353fcf3ce44SJohn Forte  * setToken - Stale data token returned in the stmfGetProviderDataProt()
5354fcf3ce44SJohn Forte  *	      call or NULL.
5355fcf3ce44SJohn Forte  */
5356fcf3ce44SJohn Forte int
5357fcf3ce44SJohn Forte stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
5358fcf3ce44SJohn Forte     uint64_t *setToken)
5359fcf3ce44SJohn Forte {
5360fcf3ce44SJohn Forte 	int ret;
5361fcf3ce44SJohn Forte 	int fd;
5362fcf3ce44SJohn Forte 
5363fcf3ce44SJohn Forte 	if (providerName == NULL || nvl == NULL) {
5364fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5365fcf3ce44SJohn Forte 	}
5366fcf3ce44SJohn Forte 
5367fcf3ce44SJohn Forte 	if (providerType != STMF_LU_PROVIDER_TYPE &&
5368fcf3ce44SJohn Forte 	    providerType != STMF_PORT_PROVIDER_TYPE) {
5369fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5370fcf3ce44SJohn Forte 	}
5371fcf3ce44SJohn Forte 
5372fcf3ce44SJohn Forte 	/* call init */
5373fcf3ce44SJohn Forte 	ret = initializeConfig();
5374fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
5375fcf3ce44SJohn Forte 		return (ret);
5376fcf3ce44SJohn Forte 	}
5377fcf3ce44SJohn Forte 
5378fcf3ce44SJohn Forte 	/*
5379fcf3ce44SJohn Forte 	 * Open control node for stmf
5380fcf3ce44SJohn Forte 	 */
5381fcf3ce44SJohn Forte 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5382fcf3ce44SJohn Forte 		return (ret);
5383fcf3ce44SJohn Forte 
5384*8fe96085Stim szeto 	ret = setProviderData(fd, providerName, nvl, providerType, setToken);
5385fcf3ce44SJohn Forte 
5386fcf3ce44SJohn Forte 	(void) close(fd);
5387fcf3ce44SJohn Forte 
5388fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
5389fcf3ce44SJohn Forte 		goto done;
5390fcf3ce44SJohn Forte 	}
5391fcf3ce44SJohn Forte 
5392*8fe96085Stim szeto 	if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5393*8fe96085Stim szeto 		goto done;
5394*8fe96085Stim szeto 	}
5395*8fe96085Stim szeto 
5396fcf3ce44SJohn Forte 	/* setting driver provider data successful. Now persist it */
5397*8fe96085Stim szeto 	ret = psSetProviderData(providerName, nvl, providerType, NULL);
5398fcf3ce44SJohn Forte 	switch (ret) {
5399fcf3ce44SJohn Forte 		case STMF_PS_SUCCESS:
5400fcf3ce44SJohn Forte 			ret = STMF_STATUS_SUCCESS;
5401fcf3ce44SJohn Forte 			break;
5402fcf3ce44SJohn Forte 		case STMF_PS_ERROR_EXISTS:
5403fcf3ce44SJohn Forte 			ret = STMF_ERROR_EXISTS;
5404fcf3ce44SJohn Forte 			break;
5405fcf3ce44SJohn Forte 		case STMF_PS_ERROR_BUSY:
5406fcf3ce44SJohn Forte 			ret = STMF_ERROR_BUSY;
5407fcf3ce44SJohn Forte 			break;
5408fcf3ce44SJohn Forte 		case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5409fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_NOT_FOUND;
5410fcf3ce44SJohn Forte 			break;
5411fcf3ce44SJohn Forte 		case STMF_PS_ERROR_VERSION_MISMATCH:
5412fcf3ce44SJohn Forte 			ret = STMF_ERROR_SERVICE_DATA_VERSION;
5413fcf3ce44SJohn Forte 			break;
5414fcf3ce44SJohn Forte 		case STMF_PS_ERROR_PROV_DATA_STALE:
5415fcf3ce44SJohn Forte 			ret = STMF_ERROR_PROV_DATA_STALE;
5416fcf3ce44SJohn Forte 			break;
5417fcf3ce44SJohn Forte 		default:
5418fcf3ce44SJohn Forte 			syslog(LOG_DEBUG,
5419fcf3ce44SJohn Forte 			    "stmfSetProviderData"
5420fcf3ce44SJohn Forte 			    "psSetProviderData:error(%d)", ret);
5421fcf3ce44SJohn Forte 			ret = STMF_STATUS_ERROR;
5422fcf3ce44SJohn Forte 			break;
5423fcf3ce44SJohn Forte 	}
5424fcf3ce44SJohn Forte 
5425fcf3ce44SJohn Forte done:
5426fcf3ce44SJohn Forte 	return (ret);
5427fcf3ce44SJohn Forte }
5428fcf3ce44SJohn Forte 
5429fcf3ce44SJohn Forte /*
5430*8fe96085Stim szeto  * getProviderData
5431*8fe96085Stim szeto  *
5432*8fe96085Stim szeto  * Purpose: set the provider data from stmf
5433*8fe96085Stim szeto  *
5434*8fe96085Stim szeto  * providerName - unique name of provider
5435*8fe96085Stim szeto  * nvl - nvlist to load/retrieve
5436*8fe96085Stim szeto  * providerType - logical unit or port provider
5437*8fe96085Stim szeto  * setToken - returned stale data token
5438*8fe96085Stim szeto  */
5439*8fe96085Stim szeto int
5440*8fe96085Stim szeto getProviderData(char *providerName, nvlist_t **nvl, int providerType,
5441*8fe96085Stim szeto     uint64_t *setToken)
5442*8fe96085Stim szeto {
5443*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
5444*8fe96085Stim szeto 	int fd;
5445*8fe96085Stim szeto 	int ioctlRet;
5446*8fe96085Stim szeto 	size_t nvlistSize = ALLOC_PP_DATA_SIZE;
5447*8fe96085Stim szeto 	int retryCnt = 0;
5448*8fe96085Stim szeto 	int retryCntMax = MAX_PROVIDER_RETRY;
5449*8fe96085Stim szeto 	stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
5450*8fe96085Stim szeto 	boolean_t retry = B_TRUE;
5451*8fe96085Stim szeto 	stmf_iocdata_t stmfIoctl;
5452*8fe96085Stim szeto 
5453*8fe96085Stim szeto 	if (providerName == NULL) {
5454*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
5455*8fe96085Stim szeto 	}
5456*8fe96085Stim szeto 
5457*8fe96085Stim szeto 	/*
5458*8fe96085Stim szeto 	 * Open control node for stmf
5459*8fe96085Stim szeto 	 */
5460*8fe96085Stim szeto 	if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5461*8fe96085Stim szeto 		return (ret);
5462*8fe96085Stim szeto 
5463*8fe96085Stim szeto 	/* set provider name and provider type */
5464*8fe96085Stim szeto 	if (strlcpy(ppi.ppi_name, providerName,
5465*8fe96085Stim szeto 	    sizeof (ppi.ppi_name)) >=
5466*8fe96085Stim szeto 	    sizeof (ppi.ppi_name)) {
5467*8fe96085Stim szeto 		ret = STMF_ERROR_INVALID_ARG;
5468*8fe96085Stim szeto 		goto done;
5469*8fe96085Stim szeto 	}
5470*8fe96085Stim szeto 	switch (providerType) {
5471*8fe96085Stim szeto 		case STMF_LU_PROVIDER_TYPE:
5472*8fe96085Stim szeto 			ppi.ppi_lu_provider = 1;
5473*8fe96085Stim szeto 			break;
5474*8fe96085Stim szeto 		case STMF_PORT_PROVIDER_TYPE:
5475*8fe96085Stim szeto 			ppi.ppi_port_provider = 1;
5476*8fe96085Stim szeto 			break;
5477*8fe96085Stim szeto 		default:
5478*8fe96085Stim szeto 			ret = STMF_ERROR_INVALID_ARG;
5479*8fe96085Stim szeto 			goto done;
5480*8fe96085Stim szeto 	}
5481*8fe96085Stim szeto 
5482*8fe96085Stim szeto 	do {
5483*8fe96085Stim szeto 		/* allocate memory for ioctl */
5484*8fe96085Stim szeto 		ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
5485*8fe96085Stim szeto 		    sizeof (stmf_ppioctl_data_t));
5486*8fe96085Stim szeto 		if (ppi_out == NULL) {
5487*8fe96085Stim szeto 			ret = STMF_ERROR_NOMEM;
5488*8fe96085Stim szeto 			goto done;
5489*8fe96085Stim szeto 
5490*8fe96085Stim szeto 		}
5491*8fe96085Stim szeto 
5492*8fe96085Stim szeto 		/* set the size of the ioctl data to allocated buffer */
5493*8fe96085Stim szeto 		ppi.ppi_data_size = nvlistSize;
5494*8fe96085Stim szeto 
5495*8fe96085Stim szeto 		bzero(&stmfIoctl, sizeof (stmfIoctl));
5496*8fe96085Stim szeto 
5497*8fe96085Stim szeto 		stmfIoctl.stmf_version = STMF_VERSION_1;
5498*8fe96085Stim szeto 		stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
5499*8fe96085Stim szeto 		stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
5500*8fe96085Stim szeto 		stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
5501*8fe96085Stim szeto 		    nvlistSize;
5502*8fe96085Stim szeto 		stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
5503*8fe96085Stim szeto 		ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
5504*8fe96085Stim szeto 		if (ioctlRet != 0) {
5505*8fe96085Stim szeto 			switch (errno) {
5506*8fe96085Stim szeto 				case EBUSY:
5507*8fe96085Stim szeto 					ret = STMF_ERROR_BUSY;
5508*8fe96085Stim szeto 					break;
5509*8fe96085Stim szeto 				case EPERM:
5510*8fe96085Stim szeto 				case EACCES:
5511*8fe96085Stim szeto 					ret = STMF_ERROR_PERM;
5512*8fe96085Stim szeto 					break;
5513*8fe96085Stim szeto 				case EINVAL:
5514*8fe96085Stim szeto 					if (stmfIoctl.stmf_error ==
5515*8fe96085Stim szeto 					    STMF_IOCERR_INSUFFICIENT_BUF) {
5516*8fe96085Stim szeto 						nvlistSize =
5517*8fe96085Stim szeto 						    ppi_out->ppi_data_size;
5518*8fe96085Stim szeto 						free(ppi_out);
5519*8fe96085Stim szeto 						ppi_out = NULL;
5520*8fe96085Stim szeto 						if (retryCnt++ > retryCntMax) {
5521*8fe96085Stim szeto 							retry = B_FALSE;
5522*8fe96085Stim szeto 							ret = STMF_ERROR_BUSY;
5523*8fe96085Stim szeto 						} else {
5524*8fe96085Stim szeto 							ret =
5525*8fe96085Stim szeto 							    STMF_STATUS_SUCCESS;
5526*8fe96085Stim szeto 						}
5527*8fe96085Stim szeto 					} else {
5528*8fe96085Stim szeto 						syslog(LOG_DEBUG,
5529*8fe96085Stim szeto 						    "getProviderData:ioctl"
5530*8fe96085Stim szeto 						    "unable to retrieve "
5531*8fe96085Stim szeto 						    "nvlist");
5532*8fe96085Stim szeto 						ret = STMF_STATUS_ERROR;
5533*8fe96085Stim szeto 					}
5534*8fe96085Stim szeto 					break;
5535*8fe96085Stim szeto 				case ENOENT:
5536*8fe96085Stim szeto 					ret = STMF_ERROR_NOT_FOUND;
5537*8fe96085Stim szeto 					break;
5538*8fe96085Stim szeto 				default:
5539*8fe96085Stim szeto 					syslog(LOG_DEBUG,
5540*8fe96085Stim szeto 					    "getProviderData:ioctl errno(%d)",
5541*8fe96085Stim szeto 					    errno);
5542*8fe96085Stim szeto 					ret = STMF_STATUS_ERROR;
5543*8fe96085Stim szeto 					break;
5544*8fe96085Stim szeto 			}
5545*8fe96085Stim szeto 			if (ret != STMF_STATUS_SUCCESS)
5546*8fe96085Stim szeto 				goto done;
5547*8fe96085Stim szeto 		}
5548*8fe96085Stim szeto 	} while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
5549*8fe96085Stim szeto 
5550*8fe96085Stim szeto 	if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
5551*8fe96085Stim szeto 	    ppi_out->ppi_data_size, nvl, 0)) != 0) {
5552*8fe96085Stim szeto 		ret = STMF_STATUS_ERROR;
5553*8fe96085Stim szeto 		goto done;
5554*8fe96085Stim szeto 	}
5555*8fe96085Stim szeto 
5556*8fe96085Stim szeto 	/* caller has asked for new token */
5557*8fe96085Stim szeto 	if (setToken) {
5558*8fe96085Stim szeto 		*setToken = ppi_out->ppi_token;
5559*8fe96085Stim szeto 	}
5560*8fe96085Stim szeto done:
5561*8fe96085Stim szeto 	free(ppi_out);
5562*8fe96085Stim szeto 	(void) close(fd);
5563*8fe96085Stim szeto 	return (ret);
5564*8fe96085Stim szeto }
5565*8fe96085Stim szeto 
5566*8fe96085Stim szeto /*
5567fcf3ce44SJohn Forte  * setProviderData
5568fcf3ce44SJohn Forte  *
5569*8fe96085Stim szeto  * Purpose: set the provider data in stmf
5570fcf3ce44SJohn Forte  *
5571fcf3ce44SJohn Forte  * providerName - unique name of provider
5572fcf3ce44SJohn Forte  * nvl - nvlist to set
5573fcf3ce44SJohn Forte  * providerType - logical unit or port provider
5574*8fe96085Stim szeto  * setToken - stale data token to check if not NULL
5575fcf3ce44SJohn Forte  */
5576fcf3ce44SJohn Forte static int
5577*8fe96085Stim szeto setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
5578*8fe96085Stim szeto     uint64_t *setToken)
5579fcf3ce44SJohn Forte {
5580fcf3ce44SJohn Forte 	int ret = STMF_STATUS_SUCCESS;
5581fcf3ce44SJohn Forte 	int ioctlRet;
5582fcf3ce44SJohn Forte 	size_t nvlistEncodedSize;
5583fcf3ce44SJohn Forte 	stmf_ppioctl_data_t *ppi = NULL;
5584*8fe96085Stim szeto 	uint64_t outToken;
5585fcf3ce44SJohn Forte 	char *allocatedNvBuffer;
5586fcf3ce44SJohn Forte 	stmf_iocdata_t stmfIoctl;
5587fcf3ce44SJohn Forte 
5588fcf3ce44SJohn Forte 	if (providerName == NULL) {
5589fcf3ce44SJohn Forte 		return (STMF_ERROR_INVALID_ARG);
5590fcf3ce44SJohn Forte 	}
5591fcf3ce44SJohn Forte 
5592fcf3ce44SJohn Forte 	/* get size of encoded nvlist */
5593fcf3ce44SJohn Forte 	if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
5594fcf3ce44SJohn Forte 		return (STMF_STATUS_ERROR);
5595fcf3ce44SJohn Forte 	}
5596fcf3ce44SJohn Forte 
5597fcf3ce44SJohn Forte 	/* allocate memory for ioctl */
5598fcf3ce44SJohn Forte 	ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
5599fcf3ce44SJohn Forte 	    sizeof (stmf_ppioctl_data_t));
5600fcf3ce44SJohn Forte 	if (ppi == NULL) {
5601fcf3ce44SJohn Forte 		return (STMF_ERROR_NOMEM);
5602fcf3ce44SJohn Forte 	}
5603fcf3ce44SJohn Forte 
5604*8fe96085Stim szeto 	if (setToken) {
5605*8fe96085Stim szeto 		ppi->ppi_token_valid = 1;
5606*8fe96085Stim szeto 		ppi->ppi_token = *setToken;
5607*8fe96085Stim szeto 	}
5608*8fe96085Stim szeto 
5609fcf3ce44SJohn Forte 	allocatedNvBuffer = (char *)&ppi->ppi_data;
5610fcf3ce44SJohn Forte 	if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
5611fcf3ce44SJohn Forte 	    NV_ENCODE_XDR, 0) != 0) {
5612fcf3ce44SJohn Forte 		return (STMF_STATUS_ERROR);
5613fcf3ce44SJohn Forte 	}
5614fcf3ce44SJohn Forte 
5615fcf3ce44SJohn Forte 	/* set provider name and provider type */
5616fcf3ce44SJohn Forte 	(void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
5617fcf3ce44SJohn Forte 	switch (providerType) {
5618fcf3ce44SJohn Forte 		case STMF_LU_PROVIDER_TYPE:
5619fcf3ce44SJohn Forte 			ppi->ppi_lu_provider = 1;
5620fcf3ce44SJohn Forte 			break;
5621fcf3ce44SJohn Forte 		case STMF_PORT_PROVIDER_TYPE:
5622fcf3ce44SJohn Forte 			ppi->ppi_port_provider = 1;
5623fcf3ce44SJohn Forte 			break;
5624fcf3ce44SJohn Forte 		default:
5625fcf3ce44SJohn Forte 			return (STMF_ERROR_INVALID_ARG);
5626fcf3ce44SJohn Forte 	}
5627fcf3ce44SJohn Forte 
5628fcf3ce44SJohn Forte 	/* set the size of the ioctl data to packed data size */
5629fcf3ce44SJohn Forte 	ppi->ppi_data_size = nvlistEncodedSize;
5630fcf3ce44SJohn Forte 
5631fcf3ce44SJohn Forte 	bzero(&stmfIoctl, sizeof (stmfIoctl));
5632fcf3ce44SJohn Forte 
5633fcf3ce44SJohn Forte 	stmfIoctl.stmf_version = STMF_VERSION_1;
5634fcf3ce44SJohn Forte 	/*
5635fcf3ce44SJohn Forte 	 * Subtracting 8 from the size as that is the size of the last member
5636fcf3ce44SJohn Forte 	 * of the structure where the packed data resides
5637fcf3ce44SJohn Forte 	 */
5638fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
5639fcf3ce44SJohn Forte 	    sizeof (stmf_ppioctl_data_t) - 8;
5640fcf3ce44SJohn Forte 	stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
5641*8fe96085Stim szeto 	stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
5642*8fe96085Stim szeto 	stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
5643fcf3ce44SJohn Forte 	ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
5644fcf3ce44SJohn Forte 	if (ioctlRet != 0) {
5645fcf3ce44SJohn Forte 		switch (errno) {
5646fcf3ce44SJohn Forte 			case EBUSY:
5647fcf3ce44SJohn Forte 				ret = STMF_ERROR_BUSY;
5648fcf3ce44SJohn Forte 				break;
5649*8fe96085Stim szeto 			case EPERM:
5650fcf3ce44SJohn Forte 			case EACCES:
5651fcf3ce44SJohn Forte 				ret = STMF_ERROR_PERM;
5652fcf3ce44SJohn Forte 				break;
5653*8fe96085Stim szeto 			case EINVAL:
5654*8fe96085Stim szeto 				if (stmfIoctl.stmf_error ==
5655*8fe96085Stim szeto 				    STMF_IOCERR_PPD_UPDATED) {
5656*8fe96085Stim szeto 					ret = STMF_ERROR_PROV_DATA_STALE;
5657*8fe96085Stim szeto 				} else {
5658*8fe96085Stim szeto 					ret = STMF_STATUS_ERROR;
5659*8fe96085Stim szeto 				}
5660*8fe96085Stim szeto 				break;
5661fcf3ce44SJohn Forte 			default:
5662fcf3ce44SJohn Forte 				syslog(LOG_DEBUG,
5663fcf3ce44SJohn Forte 				    "setProviderData:ioctl errno(%d)", errno);
5664fcf3ce44SJohn Forte 				ret = STMF_STATUS_ERROR;
5665fcf3ce44SJohn Forte 				break;
5666fcf3ce44SJohn Forte 		}
5667fcf3ce44SJohn Forte 		if (ret != STMF_STATUS_SUCCESS)
5668fcf3ce44SJohn Forte 			goto done;
5669fcf3ce44SJohn Forte 	}
5670fcf3ce44SJohn Forte 
5671*8fe96085Stim szeto 	/* caller has asked for new token */
5672*8fe96085Stim szeto 	if (setToken) {
5673*8fe96085Stim szeto 		*setToken = outToken;
5674*8fe96085Stim szeto 	}
5675fcf3ce44SJohn Forte done:
5676fcf3ce44SJohn Forte 	free(ppi);
5677fcf3ce44SJohn Forte 	return (ret);
5678fcf3ce44SJohn Forte }
5679*8fe96085Stim szeto 
5680*8fe96085Stim szeto /*
5681*8fe96085Stim szeto  * set the persistence method in the library only or library and service
5682*8fe96085Stim szeto  */
5683*8fe96085Stim szeto int
5684*8fe96085Stim szeto stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
5685*8fe96085Stim szeto {
5686*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
5687*8fe96085Stim szeto 	int oldPersist;
5688*8fe96085Stim szeto 
5689*8fe96085Stim szeto 	(void) pthread_mutex_lock(&persistenceTypeLock);
5690*8fe96085Stim szeto 	oldPersist = iPersistType;
5691*8fe96085Stim szeto 	if (persistType == STMF_PERSIST_NONE ||
5692*8fe96085Stim szeto 	    persistType == STMF_PERSIST_SMF) {
5693*8fe96085Stim szeto 		iLibSetPersist = B_TRUE;
5694*8fe96085Stim szeto 		iPersistType = persistType;
5695*8fe96085Stim szeto 	} else {
5696*8fe96085Stim szeto 		(void) pthread_mutex_unlock(&persistenceTypeLock);
5697*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
5698*8fe96085Stim szeto 	}
5699*8fe96085Stim szeto 	/* Is this for this library open or in SMF */
5700*8fe96085Stim szeto 	if (serviceSet == B_TRUE) {
5701*8fe96085Stim szeto 		ret = psSetServicePersist(persistType);
5702*8fe96085Stim szeto 		if (ret != STMF_PS_SUCCESS) {
5703*8fe96085Stim szeto 			ret = STMF_ERROR_PERSIST_TYPE;
5704*8fe96085Stim szeto 			/* Set to old value */
5705*8fe96085Stim szeto 			iPersistType = oldPersist;
5706*8fe96085Stim szeto 		}
5707*8fe96085Stim szeto 	}
5708*8fe96085Stim szeto 	(void) pthread_mutex_unlock(&persistenceTypeLock);
5709*8fe96085Stim szeto 
5710*8fe96085Stim szeto 	return (ret);
5711*8fe96085Stim szeto }
5712*8fe96085Stim szeto 
5713*8fe96085Stim szeto /*
5714*8fe96085Stim szeto  * Only returns internal state for persist. If unset, goes to ps. If that
5715*8fe96085Stim szeto  * fails, returns default setting
5716*8fe96085Stim szeto  */
5717*8fe96085Stim szeto static uint8_t
5718*8fe96085Stim szeto iGetPersistMethod()
5719*8fe96085Stim szeto {
5720*8fe96085Stim szeto 
5721*8fe96085Stim szeto 	uint8_t persistType = 0;
5722*8fe96085Stim szeto 
5723*8fe96085Stim szeto 	(void) pthread_mutex_lock(&persistenceTypeLock);
5724*8fe96085Stim szeto 	if (iLibSetPersist) {
5725*8fe96085Stim szeto 		persistType = iPersistType;
5726*8fe96085Stim szeto 	} else {
5727*8fe96085Stim szeto 		int ret;
5728*8fe96085Stim szeto 		ret = psGetServicePersist(&persistType);
5729*8fe96085Stim szeto 		if (ret != STMF_PS_SUCCESS) {
5730*8fe96085Stim szeto 			/* set to default */
5731*8fe96085Stim szeto 			persistType = STMF_DEFAULT_PERSIST;
5732*8fe96085Stim szeto 		}
5733*8fe96085Stim szeto 	}
5734*8fe96085Stim szeto 	(void) pthread_mutex_unlock(&persistenceTypeLock);
5735*8fe96085Stim szeto 	return (persistType);
5736*8fe96085Stim szeto }
5737*8fe96085Stim szeto 
5738*8fe96085Stim szeto /*
5739*8fe96085Stim szeto  * Returns either library state or persistent config state depending on
5740*8fe96085Stim szeto  * serviceState
5741*8fe96085Stim szeto  */
5742*8fe96085Stim szeto int
5743*8fe96085Stim szeto stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
5744*8fe96085Stim szeto {
5745*8fe96085Stim szeto 	int ret = STMF_STATUS_SUCCESS;
5746*8fe96085Stim szeto 
5747*8fe96085Stim szeto 	if (persistType == NULL) {
5748*8fe96085Stim szeto 		return (STMF_ERROR_INVALID_ARG);
5749*8fe96085Stim szeto 	}
5750*8fe96085Stim szeto 	if (serviceState) {
5751*8fe96085Stim szeto 		ret = psGetServicePersist(persistType);
5752*8fe96085Stim szeto 		if (ret != STMF_PS_SUCCESS) {
5753*8fe96085Stim szeto 			ret = STMF_ERROR_PERSIST_TYPE;
5754*8fe96085Stim szeto 		}
5755*8fe96085Stim szeto 	} else {
5756*8fe96085Stim szeto 		(void) pthread_mutex_lock(&persistenceTypeLock);
5757*8fe96085Stim szeto 		if (iLibSetPersist) {
5758*8fe96085Stim szeto 			*persistType = iPersistType;
5759*8fe96085Stim szeto 		} else {
5760*8fe96085Stim szeto 			*persistType = STMF_DEFAULT_PERSIST;
5761*8fe96085Stim szeto 		}
5762*8fe96085Stim szeto 		(void) pthread_mutex_unlock(&persistenceTypeLock);
5763*8fe96085Stim szeto 	}
5764*8fe96085Stim szeto 
5765*8fe96085Stim szeto 	return (ret);
5766*8fe96085Stim szeto }
5767