1*c3a558e7SSue Gleeson /*
2*c3a558e7SSue Gleeson  * CDDL HEADER START
3*c3a558e7SSue Gleeson  *
4*c3a558e7SSue Gleeson  * The contents of this file are subject to the terms of the
5*c3a558e7SSue Gleeson  * Common Development and Distribution License (the "License").
6*c3a558e7SSue Gleeson  * You may not use this file except in compliance with the License.
7*c3a558e7SSue Gleeson  *
8*c3a558e7SSue Gleeson  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*c3a558e7SSue Gleeson  * or http://www.opensolaris.org/os/licensing.
10*c3a558e7SSue Gleeson  * See the License for the specific language governing permissions
11*c3a558e7SSue Gleeson  * and limitations under the License.
12*c3a558e7SSue Gleeson  *
13*c3a558e7SSue Gleeson  * When distributing Covered Code, include this CDDL HEADER in each
14*c3a558e7SSue Gleeson  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*c3a558e7SSue Gleeson  * If applicable, add the following below this CDDL HEADER, with the
16*c3a558e7SSue Gleeson  * fields enclosed by brackets "[]" replaced with your own identifying
17*c3a558e7SSue Gleeson  * information: Portions Copyright [yyyy] [name of copyright owner]
18*c3a558e7SSue Gleeson  *
19*c3a558e7SSue Gleeson  * CDDL HEADER END
20*c3a558e7SSue Gleeson  */
21*c3a558e7SSue Gleeson /*
22*c3a558e7SSue Gleeson  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23*c3a558e7SSue Gleeson  */
24*c3a558e7SSue Gleeson 
25*c3a558e7SSue Gleeson #include <sys/types.h>
26*c3a558e7SSue Gleeson #include <sys/stat.h>
27*c3a558e7SSue Gleeson #include <limits.h>
28*c3a558e7SSue Gleeson #include <ctype.h>
29*c3a558e7SSue Gleeson #include <fcntl.h>
30*c3a558e7SSue Gleeson #include <errno.h>
31*c3a558e7SSue Gleeson #include <unistd.h>
32*c3a558e7SSue Gleeson #include <strings.h>
33*c3a558e7SSue Gleeson #include <libintl.h>
34*c3a558e7SSue Gleeson #include <libscf.h>
35*c3a558e7SSue Gleeson #include <libnvpair.h>
36*c3a558e7SSue Gleeson 
37*c3a558e7SSue Gleeson #include <libstmf.h>
38*c3a558e7SSue Gleeson #include <libsrpt.h>
39*c3a558e7SSue Gleeson 
40*c3a558e7SSue Gleeson #include "srpt_common.h"
41*c3a558e7SSue Gleeson 
42*c3a558e7SSue Gleeson #define	SRPT_PROV_NAME	"srpt"
43*c3a558e7SSue Gleeson 
44*c3a558e7SSue Gleeson /*
45*c3a558e7SSue Gleeson  * Function:  srpt_GetConfig()
46*c3a558e7SSue Gleeson  *
47*c3a558e7SSue Gleeson  * Parameters:
48*c3a558e7SSue Gleeson  *    cfg	Current SRPT configuration in nvlist form
49*c3a558e7SSue Gleeson  *    token	Configuration generation number.  Use this token
50*c3a558e7SSue Gleeson  *		if updating the configuration with srpt_SetConfig.
51*c3a558e7SSue Gleeson  *
52*c3a558e7SSue Gleeson  * Return Values:
53*c3a558e7SSue Gleeson  *    0		Success
54*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
55*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
56*c3a558e7SSue Gleeson  */
57*c3a558e7SSue Gleeson int
srpt_GetConfig(nvlist_t ** cfg,uint64_t * token)58*c3a558e7SSue Gleeson srpt_GetConfig(nvlist_t **cfg, uint64_t *token)
59*c3a558e7SSue Gleeson {
60*c3a558e7SSue Gleeson 	int		ret = 0;
61*c3a558e7SSue Gleeson 	nvlist_t	*cfg_nv = NULL;
62*c3a558e7SSue Gleeson 	uint64_t	stmf_token = 0;
63*c3a558e7SSue Gleeson 	nvlist_t	*hcanv = NULL;
64*c3a558e7SSue Gleeson 
65*c3a558e7SSue Gleeson 	if (!cfg) {
66*c3a558e7SSue Gleeson 		return (EINVAL);
67*c3a558e7SSue Gleeson 	}
68*c3a558e7SSue Gleeson 
69*c3a558e7SSue Gleeson 	*cfg = NULL;
70*c3a558e7SSue Gleeson 
71*c3a558e7SSue Gleeson 	ret = stmfGetProviderDataProt(SRPT_PROV_NAME, &cfg_nv,
72*c3a558e7SSue Gleeson 	    STMF_PORT_PROVIDER_TYPE, &stmf_token);
73*c3a558e7SSue Gleeson 
74*c3a558e7SSue Gleeson 	if (ret == STMF_STATUS_SUCCESS) {
75*c3a558e7SSue Gleeson 		ret = 0;
76*c3a558e7SSue Gleeson 	} else if (ret == STMF_ERROR_NOT_FOUND) {
77*c3a558e7SSue Gleeson 		/* Not initialized yet */
78*c3a558e7SSue Gleeson 		ret = nvlist_alloc(&cfg_nv, NV_UNIQUE_NAME, 0);
79*c3a558e7SSue Gleeson 		if (ret != 0) {
80*c3a558e7SSue Gleeson 			return (ret);
81*c3a558e7SSue Gleeson 		}
82*c3a558e7SSue Gleeson 		/* create the HCA list */
83*c3a558e7SSue Gleeson 		ret = nvlist_alloc(&hcanv, NV_UNIQUE_NAME, 0);
84*c3a558e7SSue Gleeson 		if (ret == 0) {
85*c3a558e7SSue Gleeson 			ret = nvlist_add_nvlist(cfg_nv, SRPT_PROP_HCALIST,
86*c3a558e7SSue Gleeson 			    hcanv);
87*c3a558e7SSue Gleeson 			if (ret != 0) {
88*c3a558e7SSue Gleeson 				nvlist_free(hcanv);
89*c3a558e7SSue Gleeson 			}
90*c3a558e7SSue Gleeson 		}
91*c3a558e7SSue Gleeson 		if (ret != 0) {
92*c3a558e7SSue Gleeson 			nvlist_free(cfg_nv);
93*c3a558e7SSue Gleeson 			cfg_nv = NULL;
94*c3a558e7SSue Gleeson 		}
95*c3a558e7SSue Gleeson 	} else if (ret == STMF_ERROR_NOMEM) {
96*c3a558e7SSue Gleeson 		ret = ENOMEM;
97*c3a558e7SSue Gleeson 	} else {
98*c3a558e7SSue Gleeson 		ret = EINVAL;
99*c3a558e7SSue Gleeson 	}
100*c3a558e7SSue Gleeson 
101*c3a558e7SSue Gleeson 	*cfg = cfg_nv;
102*c3a558e7SSue Gleeson 	*token = stmf_token;
103*c3a558e7SSue Gleeson 
104*c3a558e7SSue Gleeson 	return (ret);
105*c3a558e7SSue Gleeson }
106*c3a558e7SSue Gleeson 
107*c3a558e7SSue Gleeson /*
108*c3a558e7SSue Gleeson  * Function:  srpt_SetConfig()
109*c3a558e7SSue Gleeson  *
110*c3a558e7SSue Gleeson  * Parameters:
111*c3a558e7SSue Gleeson  *    cfg	SRPT configuration in nvlist form
112*c3a558e7SSue Gleeson  *    token	Configuration generation number from srpt_GetConfig.
113*c3a558e7SSue Gleeson  *		Use this token to ensure the configuration hasn't been
114*c3a558e7SSue Gleeson  *		updated by another user since the time it was fetched.
115*c3a558e7SSue Gleeson  *
116*c3a558e7SSue Gleeson  * Return Values:
117*c3a558e7SSue Gleeson  *    0		Success
118*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
119*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
120*c3a558e7SSue Gleeson  *    ECANCELED Configuration updated by another user
121*c3a558e7SSue Gleeson  */
122*c3a558e7SSue Gleeson int
srpt_SetConfig(nvlist_t * cfg,uint64_t token)123*c3a558e7SSue Gleeson srpt_SetConfig(nvlist_t *cfg, uint64_t token)
124*c3a558e7SSue Gleeson {
125*c3a558e7SSue Gleeson 	int		ret = 0;
126*c3a558e7SSue Gleeson 
127*c3a558e7SSue Gleeson 	ret = stmfSetProviderDataProt(SRPT_PROV_NAME, cfg,
128*c3a558e7SSue Gleeson 	    STMF_PORT_PROVIDER_TYPE, &token);
129*c3a558e7SSue Gleeson 
130*c3a558e7SSue Gleeson 	if (ret == STMF_STATUS_SUCCESS) {
131*c3a558e7SSue Gleeson 		ret = 0;
132*c3a558e7SSue Gleeson 	} else if (ret == STMF_ERROR_NOMEM) {
133*c3a558e7SSue Gleeson 		ret = ENOMEM;
134*c3a558e7SSue Gleeson 	} else if (ret == STMF_ERROR_PROV_DATA_STALE) {
135*c3a558e7SSue Gleeson 		ret = ECANCELED;  /* could be a better errno */
136*c3a558e7SSue Gleeson 	} else {
137*c3a558e7SSue Gleeson 		ret = EINVAL;
138*c3a558e7SSue Gleeson 	}
139*c3a558e7SSue Gleeson 
140*c3a558e7SSue Gleeson 	return (ret);
141*c3a558e7SSue Gleeson }
142*c3a558e7SSue Gleeson 
143*c3a558e7SSue Gleeson /*
144*c3a558e7SSue Gleeson  * Function:  srpt_GetDefaultState()
145*c3a558e7SSue Gleeson  *
146*c3a558e7SSue Gleeson  * Parameters:
147*c3a558e7SSue Gleeson  *    enabled	If B_TRUE, indicates that targets will be created for all
148*c3a558e7SSue Gleeson  *		discovered HCAs that have not been specifically disabled.
149*c3a558e7SSue Gleeson  *		If B_FALSE, targets will not be created unless the HCA has
150*c3a558e7SSue Gleeson  *		been specifically enabled.  See also srpt_SetDefaultState().
151*c3a558e7SSue Gleeson  *
152*c3a558e7SSue Gleeson  * Return Values:
153*c3a558e7SSue Gleeson  *    0		Success
154*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
155*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
156*c3a558e7SSue Gleeson  */
157*c3a558e7SSue Gleeson int
srpt_GetDefaultState(boolean_t * enabled)158*c3a558e7SSue Gleeson srpt_GetDefaultState(boolean_t *enabled)
159*c3a558e7SSue Gleeson {
160*c3a558e7SSue Gleeson 	int		ret;
161*c3a558e7SSue Gleeson 	nvlist_t	*cfgnv;
162*c3a558e7SSue Gleeson 	uint64_t	token;
163*c3a558e7SSue Gleeson 	boolean_t	val = B_TRUE;
164*c3a558e7SSue Gleeson 
165*c3a558e7SSue Gleeson 	if (enabled == NULL) {
166*c3a558e7SSue Gleeson 		return (EINVAL);
167*c3a558e7SSue Gleeson 	}
168*c3a558e7SSue Gleeson 
169*c3a558e7SSue Gleeson 	ret = srpt_GetConfig(&cfgnv, &token);
170*c3a558e7SSue Gleeson 	if (ret != 0) {
171*c3a558e7SSue Gleeson 		return (ret);
172*c3a558e7SSue Gleeson 	}
173*c3a558e7SSue Gleeson 
174*c3a558e7SSue Gleeson 	if (cfgnv != NULL) {
175*c3a558e7SSue Gleeson 		ret = nvlist_lookup_boolean_value(cfgnv,
176*c3a558e7SSue Gleeson 		    SRPT_PROP_DEFAULT_ENABLED, &val);
177*c3a558e7SSue Gleeson 
178*c3a558e7SSue Gleeson 		if (ret == ENOENT) {
179*c3a558e7SSue Gleeson 			ret = 0;
180*c3a558e7SSue Gleeson 		}
181*c3a558e7SSue Gleeson 	}
182*c3a558e7SSue Gleeson 
183*c3a558e7SSue Gleeson 	*enabled = val;
184*c3a558e7SSue Gleeson 	return (ret);
185*c3a558e7SSue Gleeson }
186*c3a558e7SSue Gleeson 
187*c3a558e7SSue Gleeson /*
188*c3a558e7SSue Gleeson  * Function:  srpt_SetDefaultState()
189*c3a558e7SSue Gleeson  *
190*c3a558e7SSue Gleeson  * Parameters:
191*c3a558e7SSue Gleeson  *    enabled	If B_TRUE, indicates that targets will be created for all
192*c3a558e7SSue Gleeson  *		discovered HCAs that have not been specifically disabled.
193*c3a558e7SSue Gleeson  *		If B_FALSE, targets will not be created unless the HCA has
194*c3a558e7SSue Gleeson  *		been specifically enabled.  See also srpt_SetDefaultState().
195*c3a558e7SSue Gleeson  *
196*c3a558e7SSue Gleeson  * Return Values:
197*c3a558e7SSue Gleeson  *    0		Success
198*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
199*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
200*c3a558e7SSue Gleeson  */
201*c3a558e7SSue Gleeson int
srpt_SetDefaultState(boolean_t enabled)202*c3a558e7SSue Gleeson srpt_SetDefaultState(boolean_t enabled)
203*c3a558e7SSue Gleeson {
204*c3a558e7SSue Gleeson 	int		ret;
205*c3a558e7SSue Gleeson 	nvlist_t	*cfgnv;
206*c3a558e7SSue Gleeson 	uint64_t	token;
207*c3a558e7SSue Gleeson 
208*c3a558e7SSue Gleeson 	ret = srpt_GetConfig(&cfgnv, &token);
209*c3a558e7SSue Gleeson 	if (ret != 0) {
210*c3a558e7SSue Gleeson 		return (ret);
211*c3a558e7SSue Gleeson 	}
212*c3a558e7SSue Gleeson 
213*c3a558e7SSue Gleeson 	if (cfgnv == NULL) {
214*c3a558e7SSue Gleeson 		ret = nvlist_alloc(&cfgnv, NV_UNIQUE_NAME, 0);
215*c3a558e7SSue Gleeson 		if (ret != 0) {
216*c3a558e7SSue Gleeson 			return (ret);
217*c3a558e7SSue Gleeson 		}
218*c3a558e7SSue Gleeson 	}
219*c3a558e7SSue Gleeson 
220*c3a558e7SSue Gleeson 	ret = nvlist_add_boolean_value(cfgnv, SRPT_PROP_DEFAULT_ENABLED,
221*c3a558e7SSue Gleeson 	    enabled);
222*c3a558e7SSue Gleeson 
223*c3a558e7SSue Gleeson 	if (ret == 0) {
224*c3a558e7SSue Gleeson 		ret = srpt_SetConfig(cfgnv, token);
225*c3a558e7SSue Gleeson 	}
226*c3a558e7SSue Gleeson 
227*c3a558e7SSue Gleeson 	nvlist_free(cfgnv);
228*c3a558e7SSue Gleeson 
229*c3a558e7SSue Gleeson 	return (ret);
230*c3a558e7SSue Gleeson }
231*c3a558e7SSue Gleeson 
232*c3a558e7SSue Gleeson /*
233*c3a558e7SSue Gleeson  * Function:  srpt_SetTargetState()
234*c3a558e7SSue Gleeson  *
235*c3a558e7SSue Gleeson  * Parameters:
236*c3a558e7SSue Gleeson  *    hca_guid	HCA GUID.  See description of srpt_NormalizeGuid
237*c3a558e7SSue Gleeson  *    enabled	If B_TRUE, indicates that a target will be created for
238*c3a558e7SSue Gleeson  *		this HCA when the SRPT SMF service is enabled.  If B_FALSE,
239*c3a558e7SSue Gleeson  *		a target will not be created
240*c3a558e7SSue Gleeson  *
241*c3a558e7SSue Gleeson  * Return Values:
242*c3a558e7SSue Gleeson  *    0		Success
243*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
244*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
245*c3a558e7SSue Gleeson  */
246*c3a558e7SSue Gleeson int
srpt_SetTargetState(char * hca_guid,boolean_t enabled)247*c3a558e7SSue Gleeson srpt_SetTargetState(char *hca_guid, boolean_t enabled)
248*c3a558e7SSue Gleeson {
249*c3a558e7SSue Gleeson 	int		ret;
250*c3a558e7SSue Gleeson 	nvlist_t	*cfgnv;
251*c3a558e7SSue Gleeson 	uint64_t	token;
252*c3a558e7SSue Gleeson 	nvlist_t	*hcalist;
253*c3a558e7SSue Gleeson 	nvlist_t	*hcanv;
254*c3a558e7SSue Gleeson 	char		guid[32];
255*c3a558e7SSue Gleeson 	uint64_t	hcaguid;
256*c3a558e7SSue Gleeson 
257*c3a558e7SSue Gleeson 	if (hca_guid == NULL) {
258*c3a558e7SSue Gleeson 		return (EINVAL);
259*c3a558e7SSue Gleeson 	}
260*c3a558e7SSue Gleeson 
261*c3a558e7SSue Gleeson 	ret = srpt_NormalizeGuid(hca_guid, guid, sizeof (guid), &hcaguid);
262*c3a558e7SSue Gleeson 	if (ret != 0) {
263*c3a558e7SSue Gleeson 		return (ret);
264*c3a558e7SSue Gleeson 	}
265*c3a558e7SSue Gleeson 
266*c3a558e7SSue Gleeson 	ret = srpt_GetConfig(&cfgnv, &token);
267*c3a558e7SSue Gleeson 	if (ret != 0) {
268*c3a558e7SSue Gleeson 		return (ret);
269*c3a558e7SSue Gleeson 	}
270*c3a558e7SSue Gleeson 
271*c3a558e7SSue Gleeson 	/* get the list of HCAs */
272*c3a558e7SSue Gleeson 	ret = nvlist_lookup_nvlist(cfgnv, SRPT_PROP_HCALIST, &hcalist);
273*c3a558e7SSue Gleeson 	if (ret != 0) {
274*c3a558e7SSue Gleeson 		nvlist_free(cfgnv);
275*c3a558e7SSue Gleeson 		return (ret);
276*c3a558e7SSue Gleeson 	}
277*c3a558e7SSue Gleeson 
278*c3a558e7SSue Gleeson 	ret = nvlist_lookup_nvlist(hcalist, guid, &hcanv);
279*c3a558e7SSue Gleeson 	if (ret == ENOENT) {
280*c3a558e7SSue Gleeson 		/* no entry yet */
281*c3a558e7SSue Gleeson 		ret = nvlist_alloc(&hcanv, NV_UNIQUE_NAME, 0);
282*c3a558e7SSue Gleeson 		if (ret == 0) {
283*c3a558e7SSue Gleeson 			ret = nvlist_add_uint64(hcanv, SRPT_PROP_GUID, hcaguid);
284*c3a558e7SSue Gleeson 		}
285*c3a558e7SSue Gleeson 	}
286*c3a558e7SSue Gleeson 
287*c3a558e7SSue Gleeson 	if (ret == 0) {
288*c3a558e7SSue Gleeson 		ret = nvlist_add_boolean_value(hcanv, SRPT_PROP_ENABLED,
289*c3a558e7SSue Gleeson 		    enabled);
290*c3a558e7SSue Gleeson 	}
291*c3a558e7SSue Gleeson 
292*c3a558e7SSue Gleeson 	if (ret == 0) {
293*c3a558e7SSue Gleeson 		ret = nvlist_add_nvlist(hcalist, guid, hcanv);
294*c3a558e7SSue Gleeson 	}
295*c3a558e7SSue Gleeson 
296*c3a558e7SSue Gleeson 	if (ret == 0) {
297*c3a558e7SSue Gleeson 		ret = srpt_SetConfig(cfgnv, token);
298*c3a558e7SSue Gleeson 	}
299*c3a558e7SSue Gleeson 
300*c3a558e7SSue Gleeson 	nvlist_free(cfgnv);
301*c3a558e7SSue Gleeson 
302*c3a558e7SSue Gleeson 	return (ret);
303*c3a558e7SSue Gleeson }
304*c3a558e7SSue Gleeson 
305*c3a558e7SSue Gleeson /*
306*c3a558e7SSue Gleeson  * Function:  srpt_GetTargetState()
307*c3a558e7SSue Gleeson  *
308*c3a558e7SSue Gleeson  * Parameters:
309*c3a558e7SSue Gleeson  *    hca_guid	HCA GUID.  See description of srpt_NormalizeGuid
310*c3a558e7SSue Gleeson  *    enabled	If B_TRUE, indicates that a target will be created for
311*c3a558e7SSue Gleeson  *		this HCA when the SRPT SMF service is enabled.  If B_FALSE,
312*c3a558e7SSue Gleeson  *		a target will not be created
313*c3a558e7SSue Gleeson  *
314*c3a558e7SSue Gleeson  * Return Values:
315*c3a558e7SSue Gleeson  *    0		Success
316*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
317*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
318*c3a558e7SSue Gleeson  */
319*c3a558e7SSue Gleeson int
srpt_GetTargetState(char * hca_guid,boolean_t * enabled)320*c3a558e7SSue Gleeson srpt_GetTargetState(char *hca_guid, boolean_t *enabled)
321*c3a558e7SSue Gleeson {
322*c3a558e7SSue Gleeson 	int		ret;
323*c3a558e7SSue Gleeson 	nvlist_t	*cfgnv;
324*c3a558e7SSue Gleeson 	uint64_t	token;
325*c3a558e7SSue Gleeson 	nvlist_t	*hcalist;
326*c3a558e7SSue Gleeson 	nvlist_t	*hcanv;
327*c3a558e7SSue Gleeson 	boolean_t	defaultState = B_TRUE;
328*c3a558e7SSue Gleeson 	char		guid[32];
329*c3a558e7SSue Gleeson 
330*c3a558e7SSue Gleeson 	if (hca_guid == NULL) {
331*c3a558e7SSue Gleeson 		return (EINVAL);
332*c3a558e7SSue Gleeson 	}
333*c3a558e7SSue Gleeson 
334*c3a558e7SSue Gleeson 	ret = srpt_NormalizeGuid(hca_guid, guid, sizeof (guid), NULL);
335*c3a558e7SSue Gleeson 	if (ret != 0) {
336*c3a558e7SSue Gleeson 		return (ret);
337*c3a558e7SSue Gleeson 	}
338*c3a558e7SSue Gleeson 
339*c3a558e7SSue Gleeson 	ret = srpt_GetConfig(&cfgnv, &token);
340*c3a558e7SSue Gleeson 	if (ret != 0) {
341*c3a558e7SSue Gleeson 		return (ret);
342*c3a558e7SSue Gleeson 	}
343*c3a558e7SSue Gleeson 
344*c3a558e7SSue Gleeson 	/* get the list of HCAs */
345*c3a558e7SSue Gleeson 	ret = nvlist_lookup_nvlist(cfgnv, SRPT_PROP_HCALIST, &hcalist);
346*c3a558e7SSue Gleeson 	if (ret != 0) {
347*c3a558e7SSue Gleeson 		nvlist_free(cfgnv);
348*c3a558e7SSue Gleeson 		return (ret);
349*c3a558e7SSue Gleeson 	}
350*c3a558e7SSue Gleeson 
351*c3a558e7SSue Gleeson 	/*
352*c3a558e7SSue Gleeson 	 * Find the default, for the likely case that this HCA isn't
353*c3a558e7SSue Gleeson 	 * explicitly set.
354*c3a558e7SSue Gleeson 	 */
355*c3a558e7SSue Gleeson 	(void) nvlist_lookup_boolean_value(cfgnv, SRPT_PROP_DEFAULT_ENABLED,
356*c3a558e7SSue Gleeson 	    &defaultState);
357*c3a558e7SSue Gleeson 
358*c3a558e7SSue Gleeson 	ret = nvlist_lookup_nvlist(hcalist, guid, &hcanv);
359*c3a558e7SSue Gleeson 	if (ret == 0) {
360*c3a558e7SSue Gleeson 		ret = nvlist_lookup_boolean_value(hcanv, SRPT_PROP_ENABLED,
361*c3a558e7SSue Gleeson 		    enabled);
362*c3a558e7SSue Gleeson 	}
363*c3a558e7SSue Gleeson 
364*c3a558e7SSue Gleeson 	if (ret == ENOENT) {
365*c3a558e7SSue Gleeson 		/* not explicitly set, use the default */
366*c3a558e7SSue Gleeson 		*enabled = defaultState;
367*c3a558e7SSue Gleeson 		ret = 0;
368*c3a558e7SSue Gleeson 	}
369*c3a558e7SSue Gleeson 
370*c3a558e7SSue Gleeson 	nvlist_free(cfgnv);
371*c3a558e7SSue Gleeson 
372*c3a558e7SSue Gleeson 	return (ret);
373*c3a558e7SSue Gleeson 
374*c3a558e7SSue Gleeson }
375*c3a558e7SSue Gleeson 
376*c3a558e7SSue Gleeson /*
377*c3a558e7SSue Gleeson  * Function:  srpt_ResetTarget()
378*c3a558e7SSue Gleeson  *
379*c3a558e7SSue Gleeson  * Clears the HCA-specific configuration.  Target creation will revert to
380*c3a558e7SSue Gleeson  * the default.
381*c3a558e7SSue Gleeson  *
382*c3a558e7SSue Gleeson  * Parameters:
383*c3a558e7SSue Gleeson  *    hca_guid	HCA GUID.  See description of srpt_NormalizeGuid
384*c3a558e7SSue Gleeson  *
385*c3a558e7SSue Gleeson  * Return Values:
386*c3a558e7SSue Gleeson  *    0		Success
387*c3a558e7SSue Gleeson  *    ENOMEM	Could not allocate resources
388*c3a558e7SSue Gleeson  *    EINVAL	Invalid parameter
389*c3a558e7SSue Gleeson  */
390*c3a558e7SSue Gleeson int
srpt_ResetTarget(char * hca_guid)391*c3a558e7SSue Gleeson srpt_ResetTarget(char *hca_guid)
392*c3a558e7SSue Gleeson {
393*c3a558e7SSue Gleeson 	int		ret;
394*c3a558e7SSue Gleeson 	nvlist_t	*cfgnv;
395*c3a558e7SSue Gleeson 	nvlist_t	*hcalist;
396*c3a558e7SSue Gleeson 	uint64_t	token;
397*c3a558e7SSue Gleeson 	char		guid[32];
398*c3a558e7SSue Gleeson 
399*c3a558e7SSue Gleeson 	if (hca_guid == NULL) {
400*c3a558e7SSue Gleeson 		return (EINVAL);
401*c3a558e7SSue Gleeson 	}
402*c3a558e7SSue Gleeson 
403*c3a558e7SSue Gleeson 	ret = srpt_NormalizeGuid(hca_guid, guid, sizeof (guid), NULL);
404*c3a558e7SSue Gleeson 	if (ret != 0) {
405*c3a558e7SSue Gleeson 		return (ret);
406*c3a558e7SSue Gleeson 	}
407*c3a558e7SSue Gleeson 
408*c3a558e7SSue Gleeson 	ret = srpt_GetConfig(&cfgnv, &token);
409*c3a558e7SSue Gleeson 	if (ret != 0) {
410*c3a558e7SSue Gleeson 		return (ret);
411*c3a558e7SSue Gleeson 	}
412*c3a558e7SSue Gleeson 
413*c3a558e7SSue Gleeson 	/* get the list of HCAs */
414*c3a558e7SSue Gleeson 	ret = nvlist_lookup_nvlist(cfgnv, SRPT_PROP_HCALIST, &hcalist);
415*c3a558e7SSue Gleeson 	if (ret != 0) {
416*c3a558e7SSue Gleeson 		nvlist_free(cfgnv);
417*c3a558e7SSue Gleeson 		return (ret);
418*c3a558e7SSue Gleeson 	}
419*c3a558e7SSue Gleeson 
420*c3a558e7SSue Gleeson 	/* don't set config if we don't actually change anything */
421*c3a558e7SSue Gleeson 	if (nvlist_exists(hcalist, guid)) {
422*c3a558e7SSue Gleeson 		(void) nvlist_remove_all(hcalist, guid);
423*c3a558e7SSue Gleeson 
424*c3a558e7SSue Gleeson 		if (ret == 0) {
425*c3a558e7SSue Gleeson 			ret = srpt_SetConfig(cfgnv, token);
426*c3a558e7SSue Gleeson 		}
427*c3a558e7SSue Gleeson 	}
428*c3a558e7SSue Gleeson 
429*c3a558e7SSue Gleeson 	nvlist_free(cfgnv);
430*c3a558e7SSue Gleeson 
431*c3a558e7SSue Gleeson 	return (ret);
432*c3a558e7SSue Gleeson }
433*c3a558e7SSue Gleeson 
434*c3a558e7SSue Gleeson /*
435*c3a558e7SSue Gleeson  * srpt_NormalizeGuid()
436*c3a558e7SSue Gleeson  *
437*c3a558e7SSue Gleeson  * Parameters:
438*c3a558e7SSue Gleeson  *    in	HCA GUID.  Must be in one of the following forms:
439*c3a558e7SSue Gleeson  *		    3BA000100CD18	- base hex form
440*c3a558e7SSue Gleeson  *		    0003BA000100CD18	- base hex form with leading zeroes
441*c3a558e7SSue Gleeson  *		    hca:3BA000100CD18	- form from cfgadm and/or /dev/cfg
442*c3a558e7SSue Gleeson  *		    eui.0003BA000100CD18 - EUI form
443*c3a558e7SSue Gleeson  *
444*c3a558e7SSue Gleeson  *    buf	Buffer to hold normalized guid string.  Must be at least
445*c3a558e7SSue Gleeson  *		17 chars long.
446*c3a558e7SSue Gleeson  *    buflen	Length of provided buffer
447*c3a558e7SSue Gleeson  *    int_guid	Optional.  If not NULL, the integer form of the GUID will also
448*c3a558e7SSue Gleeson  *		be returned.
449*c3a558e7SSue Gleeson  * Return Values:
450*c3a558e7SSue Gleeson  *    0		Success
451*c3a558e7SSue Gleeson  *    EINVAL	Invalid HCA GUID or invalid parameter.
452*c3a558e7SSue Gleeson  */
453*c3a558e7SSue Gleeson int
srpt_NormalizeGuid(char * in,char * buf,size_t buflen,uint64_t * int_guid)454*c3a558e7SSue Gleeson srpt_NormalizeGuid(char *in, char *buf, size_t buflen, uint64_t *int_guid)
455*c3a558e7SSue Gleeson {
456*c3a558e7SSue Gleeson 	uint64_t	guid;
457*c3a558e7SSue Gleeson 	char		*bufp = in;
458*c3a558e7SSue Gleeson 	char		*end = NULL;
459*c3a558e7SSue Gleeson 
460*c3a558e7SSue Gleeson 	if ((in == NULL) || (buf == NULL)) {
461*c3a558e7SSue Gleeson 		return (EINVAL);
462*c3a558e7SSue Gleeson 	}
463*c3a558e7SSue Gleeson 
464*c3a558e7SSue Gleeson 	if (strncasecmp(bufp, "eui.", 4) == 0) {
465*c3a558e7SSue Gleeson 		/* EUI form */
466*c3a558e7SSue Gleeson 		bufp += 4;
467*c3a558e7SSue Gleeson 	} else if (strncasecmp(bufp, "hca:", 4) == 0) {
468*c3a558e7SSue Gleeson 		/* cfgadm and /dev/hca form */
469*c3a558e7SSue Gleeson 		bufp += 4;
470*c3a558e7SSue Gleeson 	}
471*c3a558e7SSue Gleeson 
472*c3a558e7SSue Gleeson 	/*
473*c3a558e7SSue Gleeson 	 * strtoull() does not return EINVAL as documented.  Lucky
474*c3a558e7SSue Gleeson 	 * for us, neither 0 nor ULLONG_MAX will be valid.  Trap on
475*c3a558e7SSue Gleeson 	 * those and fail.
476*c3a558e7SSue Gleeson 	 */
477*c3a558e7SSue Gleeson 	guid = strtoull(bufp, &end, 16);
478*c3a558e7SSue Gleeson 	if ((guid == 0) || (guid == ULLONG_MAX) ||
479*c3a558e7SSue Gleeson 	    ((end != NULL) && (strlen(end) > 0))) {
480*c3a558e7SSue Gleeson 		return (EINVAL);
481*c3a558e7SSue Gleeson 	}
482*c3a558e7SSue Gleeson 
483*c3a558e7SSue Gleeson #if 0
484*c3a558e7SSue Gleeson 	(void) snprintf(buf, buflen, "%llX", guid);
485*c3a558e7SSue Gleeson #endif
486*c3a558e7SSue Gleeson 	SRPT_FORMAT_HCAKEY(buf, buflen, guid);
487*c3a558e7SSue Gleeson 
488*c3a558e7SSue Gleeson 	if (int_guid) {
489*c3a558e7SSue Gleeson 		*int_guid = guid;
490*c3a558e7SSue Gleeson 	}
491*c3a558e7SSue Gleeson 
492*c3a558e7SSue Gleeson 	return (0);
493*c3a558e7SSue Gleeson }
494