1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include "volume_devconfig.h"
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <ctype.h>
33*0Sstevel@tonic-gate #include <meta.h>
34*0Sstevel@tonic-gate #include "volume_nvpair.h"
35*0Sstevel@tonic-gate #include "volume_error.h"
36*0Sstevel@tonic-gate #include "volume_output.h"
37*0Sstevel@tonic-gate #include "volume_string.h"
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate /*
40*0Sstevel@tonic-gate  * Methods which manipulate a devconfig_t struct
41*0Sstevel@tonic-gate  */
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate /*
44*0Sstevel@tonic-gate  * Constructor: Create a devconfig_t struct.  This devconfig_t must be
45*0Sstevel@tonic-gate  * freed with free_devconfig().
46*0Sstevel@tonic-gate  *
47*0Sstevel@tonic-gate  * @param       devconfig
48*0Sstevel@tonic-gate  *              RETURN: a new devconfig_t
49*0Sstevel@tonic-gate  *
50*0Sstevel@tonic-gate  * @param       type
51*0Sstevel@tonic-gate  *              the type of devconfig_t to create
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * @return      0
54*0Sstevel@tonic-gate  *              if successful
55*0Sstevel@tonic-gate  *
56*0Sstevel@tonic-gate  * @return      non-zero
57*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
58*0Sstevel@tonic-gate  *              retrieve the associated error message.
59*0Sstevel@tonic-gate  */
60*0Sstevel@tonic-gate int
new_devconfig(devconfig_t ** devconfig,component_type_t type)61*0Sstevel@tonic-gate new_devconfig(
62*0Sstevel@tonic-gate 	devconfig_t **devconfig,
63*0Sstevel@tonic-gate 	component_type_t type)
64*0Sstevel@tonic-gate {
65*0Sstevel@tonic-gate 	int error;
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate 	*devconfig = (devconfig_t *)calloc(1, sizeof (devconfig_t));
68*0Sstevel@tonic-gate 	if (*devconfig == NULL) {
69*0Sstevel@tonic-gate 	    volume_set_error(gettext("new_devconfig() calloc() failed\n"));
70*0Sstevel@tonic-gate 	    return (-1);
71*0Sstevel@tonic-gate 	}
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate 	/* Create attribute list */
74*0Sstevel@tonic-gate 	if ((error = nvlist_alloc(&((*devconfig)->attributes),
75*0Sstevel@tonic-gate 	    NV_UNIQUE_NAME_TYPE, 0)) != 0) {
76*0Sstevel@tonic-gate 	    volume_set_error(gettext("devconfig_t nvlist_alloc() failed\n"));
77*0Sstevel@tonic-gate 	    free_devconfig(*devconfig);
78*0Sstevel@tonic-gate 	    return (error);
79*0Sstevel@tonic-gate 	}
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate 	if ((error = devconfig_set_type(*devconfig, type)) != 0) {
82*0Sstevel@tonic-gate 	    free_devconfig(*devconfig);
83*0Sstevel@tonic-gate 	    return (error);
84*0Sstevel@tonic-gate 	}
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	return (0);
87*0Sstevel@tonic-gate }
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate /*
90*0Sstevel@tonic-gate  * Free memory (recursively) allocated to a devconfig_t struct
91*0Sstevel@tonic-gate  *
92*0Sstevel@tonic-gate  * @param       arg
93*0Sstevel@tonic-gate  *              pointer to the devconfig_t to be freed
94*0Sstevel@tonic-gate  */
95*0Sstevel@tonic-gate void
free_devconfig(void * arg)96*0Sstevel@tonic-gate free_devconfig(
97*0Sstevel@tonic-gate 	void *arg)
98*0Sstevel@tonic-gate {
99*0Sstevel@tonic-gate 	devconfig_t *devconfig = (devconfig_t *)arg;
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	if (devconfig == NULL) {
102*0Sstevel@tonic-gate 	    return;
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	/* Free the attributes nvlist */
106*0Sstevel@tonic-gate 	if (devconfig->attributes != NULL) {
107*0Sstevel@tonic-gate 	    nvlist_free(devconfig->attributes);
108*0Sstevel@tonic-gate 	}
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate 	/* Free available devices */
111*0Sstevel@tonic-gate 	if (devconfig->available != NULL) {
112*0Sstevel@tonic-gate 	    free_string_array(devconfig->available);
113*0Sstevel@tonic-gate 	}
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	/* Free unavailable devices */
116*0Sstevel@tonic-gate 	if (devconfig->unavailable != NULL) {
117*0Sstevel@tonic-gate 	    free_string_array(devconfig->unavailable);
118*0Sstevel@tonic-gate 	}
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	/* Free the components */
121*0Sstevel@tonic-gate 	if (devconfig->components != NULL) {
122*0Sstevel@tonic-gate 	    dlist_free_items(devconfig->components, free_devconfig);
123*0Sstevel@tonic-gate 	}
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 	/* Free the devconfig itself */
126*0Sstevel@tonic-gate 	free(devconfig);
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate /*
130*0Sstevel@tonic-gate  * Check the type of the given device.
131*0Sstevel@tonic-gate  *
132*0Sstevel@tonic-gate  * @param       device
133*0Sstevel@tonic-gate  *              the device whose type to check
134*0Sstevel@tonic-gate  *
135*0Sstevel@tonic-gate  * @param       type
136*0Sstevel@tonic-gate  *              the type of the device against which to compare
137*0Sstevel@tonic-gate  *
138*0Sstevel@tonic-gate  * @return      B_TRUE if the device is of the given type, B_FALSE
139*0Sstevel@tonic-gate  *              otherwise
140*0Sstevel@tonic-gate  */
141*0Sstevel@tonic-gate boolean_t
devconfig_isA(devconfig_t * device,component_type_t type)142*0Sstevel@tonic-gate devconfig_isA(
143*0Sstevel@tonic-gate 	devconfig_t *device,
144*0Sstevel@tonic-gate 	component_type_t type)
145*0Sstevel@tonic-gate {
146*0Sstevel@tonic-gate 	component_type_t curtype;
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	if (device == NULL) {
149*0Sstevel@tonic-gate 	    return (B_FALSE);
150*0Sstevel@tonic-gate 	}
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate 	if (devconfig_get_type(device, &curtype) != 0) {
153*0Sstevel@tonic-gate 	    return (B_FALSE);
154*0Sstevel@tonic-gate 	}
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	if (curtype != type) {
157*0Sstevel@tonic-gate 	    return (B_FALSE);
158*0Sstevel@tonic-gate 	}
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	return (B_TRUE);
161*0Sstevel@tonic-gate }
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate /*
164*0Sstevel@tonic-gate  * Get the first component of the given type from the given
165*0Sstevel@tonic-gate  * devconfig_t.  Create the component if create is B_TRUE.
166*0Sstevel@tonic-gate  *
167*0Sstevel@tonic-gate  * @return      ENOENT
168*0Sstevel@tonic-gate  *              if the requested component does not exist and its
169*0Sstevel@tonic-gate  *              creation was not requested
170*0Sstevel@tonic-gate  *
171*0Sstevel@tonic-gate  * @return      0
172*0Sstevel@tonic-gate  *              if the requested component exists or was created
173*0Sstevel@tonic-gate  *
174*0Sstevel@tonic-gate  * @return      non-zero
175*0Sstevel@tonic-gate  *              if the requested component did not exist and could not
176*0Sstevel@tonic-gate  *              be created
177*0Sstevel@tonic-gate  */
178*0Sstevel@tonic-gate int
devconfig_get_component(devconfig_t * device,component_type_t type,devconfig_t ** component,boolean_t create)179*0Sstevel@tonic-gate devconfig_get_component(
180*0Sstevel@tonic-gate 	devconfig_t *device,
181*0Sstevel@tonic-gate 	component_type_t type,
182*0Sstevel@tonic-gate 	devconfig_t **component,
183*0Sstevel@tonic-gate 	boolean_t create)
184*0Sstevel@tonic-gate {
185*0Sstevel@tonic-gate 	dlist_t *list;
186*0Sstevel@tonic-gate 	int error = 0;
187*0Sstevel@tonic-gate 	char *typestr = devconfig_type_to_str(type);
188*0Sstevel@tonic-gate 
189*0Sstevel@tonic-gate 	oprintf(OUTPUT_DEBUG, gettext("Searching for singleton %s\n"), typestr);
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 	/* For each component of this device... */
192*0Sstevel@tonic-gate 	for (list = devconfig_get_components(device);
193*0Sstevel@tonic-gate 	    list != NULL; list = list->next) {
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 	    *component = (devconfig_t *)list->obj;
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	    /* Is this subcomponent an instance of the given type? */
198*0Sstevel@tonic-gate 	    if (*component != NULL && devconfig_isA(*component, type)) {
199*0Sstevel@tonic-gate 		oprintf(OUTPUT_DEBUG, gettext("Found %s\n"), typestr);
200*0Sstevel@tonic-gate 		return (0);
201*0Sstevel@tonic-gate 	    }
202*0Sstevel@tonic-gate 	}
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	/* No component found */
205*0Sstevel@tonic-gate 	error = ENOENT;
206*0Sstevel@tonic-gate 	*component = NULL;
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	oprintf(OUTPUT_DEBUG, gettext("%s not found\n"), typestr);
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 	if (create == B_TRUE) {
211*0Sstevel@tonic-gate 	    oprintf(OUTPUT_DEBUG, gettext("Creating %s\n"), typestr);
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 		/*
214*0Sstevel@tonic-gate 		 * An existing singleton component of the given type was
215*0Sstevel@tonic-gate 		 * not found under the given disk set.  So, create one.
216*0Sstevel@tonic-gate 		 */
217*0Sstevel@tonic-gate 	    if ((error = new_devconfig(component, type)) == 0) {
218*0Sstevel@tonic-gate 		/* Attach new component to given device */
219*0Sstevel@tonic-gate 		devconfig_set_components(
220*0Sstevel@tonic-gate 		    device, dlist_append(dlist_new_item(*component),
221*0Sstevel@tonic-gate 		    devconfig_get_components(device), AT_TAIL));
222*0Sstevel@tonic-gate 	    }
223*0Sstevel@tonic-gate 	}
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	return (error);
226*0Sstevel@tonic-gate }
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate /*
229*0Sstevel@tonic-gate  * Set the available devices for use in creating this device
230*0Sstevel@tonic-gate  *
231*0Sstevel@tonic-gate  * @param       device
232*0Sstevel@tonic-gate  *              a devconfig_t representing the device to modify
233*0Sstevel@tonic-gate  *
234*0Sstevel@tonic-gate  * @param       available
235*0Sstevel@tonic-gate  *              A NULL-terminated array of device names
236*0Sstevel@tonic-gate  */
237*0Sstevel@tonic-gate void
devconfig_set_available(devconfig_t * device,char ** available)238*0Sstevel@tonic-gate devconfig_set_available(
239*0Sstevel@tonic-gate 	devconfig_t *device,
240*0Sstevel@tonic-gate 	char **available)
241*0Sstevel@tonic-gate {
242*0Sstevel@tonic-gate 	device->available = available;
243*0Sstevel@tonic-gate }
244*0Sstevel@tonic-gate 
245*0Sstevel@tonic-gate /*
246*0Sstevel@tonic-gate  * Get the available devices for use in creating this device
247*0Sstevel@tonic-gate  *
248*0Sstevel@tonic-gate  * @param       device
249*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
250*0Sstevel@tonic-gate  *
251*0Sstevel@tonic-gate  * @return      available
252*0Sstevel@tonic-gate  *              A NULL-terminated array of device names
253*0Sstevel@tonic-gate  */
254*0Sstevel@tonic-gate char **
devconfig_get_available(devconfig_t * device)255*0Sstevel@tonic-gate devconfig_get_available(
256*0Sstevel@tonic-gate 	devconfig_t *device)
257*0Sstevel@tonic-gate {
258*0Sstevel@tonic-gate 	return (device->available);
259*0Sstevel@tonic-gate }
260*0Sstevel@tonic-gate 
261*0Sstevel@tonic-gate /*
262*0Sstevel@tonic-gate  * Set the unavailable devices which may not be used in creating this
263*0Sstevel@tonic-gate  * device
264*0Sstevel@tonic-gate  *
265*0Sstevel@tonic-gate  * @param       device
266*0Sstevel@tonic-gate  *              a devconfig_t representing the device to modify
267*0Sstevel@tonic-gate  *
268*0Sstevel@tonic-gate  * @param       available
269*0Sstevel@tonic-gate  *              A NULL-terminated array of device names
270*0Sstevel@tonic-gate  */
271*0Sstevel@tonic-gate void
devconfig_set_unavailable(devconfig_t * device,char ** unavailable)272*0Sstevel@tonic-gate devconfig_set_unavailable(
273*0Sstevel@tonic-gate 	devconfig_t *device,
274*0Sstevel@tonic-gate 	char **unavailable)
275*0Sstevel@tonic-gate {
276*0Sstevel@tonic-gate 	device->unavailable = unavailable;
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate /*
280*0Sstevel@tonic-gate  * Get the unavailable devices for use in creating this device
281*0Sstevel@tonic-gate  *
282*0Sstevel@tonic-gate  * @param       device
283*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
284*0Sstevel@tonic-gate  *
285*0Sstevel@tonic-gate  * @return      unavailable
286*0Sstevel@tonic-gate  *              A NULL-terminated array of device names
287*0Sstevel@tonic-gate  */
288*0Sstevel@tonic-gate char **
devconfig_get_unavailable(devconfig_t * device)289*0Sstevel@tonic-gate devconfig_get_unavailable(
290*0Sstevel@tonic-gate 	devconfig_t *device)
291*0Sstevel@tonic-gate {
292*0Sstevel@tonic-gate 	return (device->unavailable);
293*0Sstevel@tonic-gate }
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate /*
296*0Sstevel@tonic-gate  * Set the subcomponent devices of a given device
297*0Sstevel@tonic-gate  *
298*0Sstevel@tonic-gate  * @param       device
299*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
300*0Sstevel@tonic-gate  *
301*0Sstevel@tonic-gate  * @param       components
302*0Sstevel@tonic-gate  *              A dlist_t containing devconfig_t devices
303*0Sstevel@tonic-gate  */
304*0Sstevel@tonic-gate void
devconfig_set_components(devconfig_t * device,dlist_t * components)305*0Sstevel@tonic-gate devconfig_set_components(
306*0Sstevel@tonic-gate 	devconfig_t *device,
307*0Sstevel@tonic-gate 	dlist_t *components)
308*0Sstevel@tonic-gate {
309*0Sstevel@tonic-gate 	device->components = components;
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate /*
313*0Sstevel@tonic-gate  * Get the subcomponent devices of a given device
314*0Sstevel@tonic-gate  *
315*0Sstevel@tonic-gate  * @param       device
316*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
317*0Sstevel@tonic-gate  *
318*0Sstevel@tonic-gate  * @return      A dlist_t containing devconfig_t devices
319*0Sstevel@tonic-gate  */
320*0Sstevel@tonic-gate dlist_t *
devconfig_get_components(devconfig_t * device)321*0Sstevel@tonic-gate devconfig_get_components(
322*0Sstevel@tonic-gate 	devconfig_t *device)
323*0Sstevel@tonic-gate {
324*0Sstevel@tonic-gate 	return (device->components);
325*0Sstevel@tonic-gate }
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate /*
328*0Sstevel@tonic-gate  * Set the device name
329*0Sstevel@tonic-gate  *
330*0Sstevel@tonic-gate  * @param       device
331*0Sstevel@tonic-gate  *              a devconfig_t representing the device to modify
332*0Sstevel@tonic-gate  *
333*0Sstevel@tonic-gate  * @param       name
334*0Sstevel@tonic-gate  *              the value to set as the device name
335*0Sstevel@tonic-gate  *
336*0Sstevel@tonic-gate  * @return      0
337*0Sstevel@tonic-gate  *              if successful
338*0Sstevel@tonic-gate  *
339*0Sstevel@tonic-gate  * @return      non-zero
340*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
341*0Sstevel@tonic-gate  *              retrieve the associated error message.
342*0Sstevel@tonic-gate  */
343*0Sstevel@tonic-gate int
devconfig_set_name(devconfig_t * device,char * name)344*0Sstevel@tonic-gate devconfig_set_name(
345*0Sstevel@tonic-gate 	devconfig_t *device,
346*0Sstevel@tonic-gate 	char *name)
347*0Sstevel@tonic-gate {
348*0Sstevel@tonic-gate 	return (set_string(device->attributes, ATTR_NAME, name));
349*0Sstevel@tonic-gate }
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate /*
352*0Sstevel@tonic-gate  * Set the disk set name
353*0Sstevel@tonic-gate  *
354*0Sstevel@tonic-gate  * @param       diskset
355*0Sstevel@tonic-gate  *              a devconfig_t representing the diskset to modify
356*0Sstevel@tonic-gate  *
357*0Sstevel@tonic-gate  * @param       name
358*0Sstevel@tonic-gate  *              the value to set as the device name
359*0Sstevel@tonic-gate  *
360*0Sstevel@tonic-gate  * @return      0
361*0Sstevel@tonic-gate  *              if successful
362*0Sstevel@tonic-gate  *
363*0Sstevel@tonic-gate  * @return      non-zero
364*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
365*0Sstevel@tonic-gate  *              retrieve the associated error message.
366*0Sstevel@tonic-gate  */
367*0Sstevel@tonic-gate int
devconfig_set_diskset_name(devconfig_t * diskset,char * name)368*0Sstevel@tonic-gate devconfig_set_diskset_name(
369*0Sstevel@tonic-gate 	devconfig_t *diskset,
370*0Sstevel@tonic-gate 	char *name)
371*0Sstevel@tonic-gate {
372*0Sstevel@tonic-gate 	md_error_t error = mdnullerror;
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate 	/* Verify syntax of disk set name */
375*0Sstevel@tonic-gate 	if (meta_set_checkname(name, &error)) {
376*0Sstevel@tonic-gate 	    volume_set_error(gettext("invalid disk set name: %s"), name);
377*0Sstevel@tonic-gate 	    return (-1);
378*0Sstevel@tonic-gate 	}
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate 	return (devconfig_set_name(diskset, name));
381*0Sstevel@tonic-gate }
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate /*
384*0Sstevel@tonic-gate  * Set the device name
385*0Sstevel@tonic-gate  *
386*0Sstevel@tonic-gate  * @param       hsp
387*0Sstevel@tonic-gate  *              a devconfig_t representing the hsp to modify
388*0Sstevel@tonic-gate  *
389*0Sstevel@tonic-gate  * @param       name
390*0Sstevel@tonic-gate  *              the value to set as the device name
391*0Sstevel@tonic-gate  *
392*0Sstevel@tonic-gate  * @return      0
393*0Sstevel@tonic-gate  *              if successful
394*0Sstevel@tonic-gate  *
395*0Sstevel@tonic-gate  * @return      non-zero
396*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
397*0Sstevel@tonic-gate  *              retrieve the associated error message.
398*0Sstevel@tonic-gate  */
399*0Sstevel@tonic-gate int
devconfig_set_hsp_name(devconfig_t * hsp,char * name)400*0Sstevel@tonic-gate devconfig_set_hsp_name(
401*0Sstevel@tonic-gate 	devconfig_t *hsp,
402*0Sstevel@tonic-gate 	char *name)
403*0Sstevel@tonic-gate {
404*0Sstevel@tonic-gate 	/* Validate name */
405*0Sstevel@tonic-gate 	if (!is_hspname(name)) {
406*0Sstevel@tonic-gate 	    volume_set_error(gettext("invalid hot spare pool name: %s"), name);
407*0Sstevel@tonic-gate 	    return (-1);
408*0Sstevel@tonic-gate 	}
409*0Sstevel@tonic-gate 
410*0Sstevel@tonic-gate 	return (devconfig_set_name(hsp, name));
411*0Sstevel@tonic-gate }
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate /*
414*0Sstevel@tonic-gate  * Set the device name
415*0Sstevel@tonic-gate  *
416*0Sstevel@tonic-gate  * @param       volume
417*0Sstevel@tonic-gate  *              a devconfig_t representing the volume to modify
418*0Sstevel@tonic-gate  *
419*0Sstevel@tonic-gate  * @param       name
420*0Sstevel@tonic-gate  *              the value to set as the device name
421*0Sstevel@tonic-gate  *
422*0Sstevel@tonic-gate  * @return      0
423*0Sstevel@tonic-gate  *              if successful
424*0Sstevel@tonic-gate  *
425*0Sstevel@tonic-gate  * @return      non-zero
426*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
427*0Sstevel@tonic-gate  *              retrieve the associated error message.
428*0Sstevel@tonic-gate  */
429*0Sstevel@tonic-gate int
devconfig_set_volume_name(devconfig_t * volume,char * name)430*0Sstevel@tonic-gate devconfig_set_volume_name(
431*0Sstevel@tonic-gate 	devconfig_t *volume,
432*0Sstevel@tonic-gate 	char *name)
433*0Sstevel@tonic-gate {
434*0Sstevel@tonic-gate 	/* Validate name */
435*0Sstevel@tonic-gate 	if (!is_metaname(name)) {
436*0Sstevel@tonic-gate 	    volume_set_error(gettext("invalid volume name: %s"), name);
437*0Sstevel@tonic-gate 	    return (-1);
438*0Sstevel@tonic-gate 	}
439*0Sstevel@tonic-gate 
440*0Sstevel@tonic-gate 	return (devconfig_set_name(volume, name));
441*0Sstevel@tonic-gate }
442*0Sstevel@tonic-gate 
443*0Sstevel@tonic-gate /*
444*0Sstevel@tonic-gate  * Get the device name
445*0Sstevel@tonic-gate  *
446*0Sstevel@tonic-gate  * @param       volume
447*0Sstevel@tonic-gate  *              a devconfig_t representing the volume to examine
448*0Sstevel@tonic-gate  *
449*0Sstevel@tonic-gate  * @param       name
450*0Sstevel@tonic-gate  *              RETURN: the device name
451*0Sstevel@tonic-gate  *
452*0Sstevel@tonic-gate  * @return      0
453*0Sstevel@tonic-gate  *              if successful
454*0Sstevel@tonic-gate  *
455*0Sstevel@tonic-gate  * @return      non-zero
456*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
457*0Sstevel@tonic-gate  *              retrieve the associated error message.
458*0Sstevel@tonic-gate  */
459*0Sstevel@tonic-gate int
devconfig_get_name(devconfig_t * device,char ** name)460*0Sstevel@tonic-gate devconfig_get_name(
461*0Sstevel@tonic-gate 	devconfig_t *device,
462*0Sstevel@tonic-gate 	char **name)
463*0Sstevel@tonic-gate {
464*0Sstevel@tonic-gate 	int error = get_string(device->attributes, ATTR_NAME, name);
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
467*0Sstevel@tonic-gate 	if (error == ENOENT) {
468*0Sstevel@tonic-gate 	    volume_set_error(gettext("device name not set"));
469*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
470*0Sstevel@tonic-gate 	}
471*0Sstevel@tonic-gate 
472*0Sstevel@tonic-gate 	return (error);
473*0Sstevel@tonic-gate }
474*0Sstevel@tonic-gate 
475*0Sstevel@tonic-gate /*
476*0Sstevel@tonic-gate  * Set the device type
477*0Sstevel@tonic-gate  *
478*0Sstevel@tonic-gate  * @param       device
479*0Sstevel@tonic-gate  *              a devconfig_t representing the device to modify
480*0Sstevel@tonic-gate  *
481*0Sstevel@tonic-gate  * @param       type
482*0Sstevel@tonic-gate  *              the value to set as the device type
483*0Sstevel@tonic-gate  *
484*0Sstevel@tonic-gate  * @return      0
485*0Sstevel@tonic-gate  *              if successful
486*0Sstevel@tonic-gate  *
487*0Sstevel@tonic-gate  * @return      non-zero
488*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
489*0Sstevel@tonic-gate  *              retrieve the associated error message.
490*0Sstevel@tonic-gate  */
491*0Sstevel@tonic-gate int
devconfig_set_type(devconfig_t * device,component_type_t type)492*0Sstevel@tonic-gate devconfig_set_type(
493*0Sstevel@tonic-gate 	devconfig_t *device,
494*0Sstevel@tonic-gate 	component_type_t type)
495*0Sstevel@tonic-gate {
496*0Sstevel@tonic-gate 	return (set_uint16(device->attributes, ATTR_TYPE, (uint16_t)type));
497*0Sstevel@tonic-gate }
498*0Sstevel@tonic-gate 
499*0Sstevel@tonic-gate /*
500*0Sstevel@tonic-gate  * Get the device type
501*0Sstevel@tonic-gate  *
502*0Sstevel@tonic-gate  * @param       device
503*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
504*0Sstevel@tonic-gate  *
505*0Sstevel@tonic-gate  * @param       type
506*0Sstevel@tonic-gate  *              RETURN: the device type
507*0Sstevel@tonic-gate  *
508*0Sstevel@tonic-gate  * @return      0
509*0Sstevel@tonic-gate  *              if successful
510*0Sstevel@tonic-gate  *
511*0Sstevel@tonic-gate  * @return      non-zero
512*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
513*0Sstevel@tonic-gate  *              retrieve the associated error message.
514*0Sstevel@tonic-gate  */
515*0Sstevel@tonic-gate int
devconfig_get_type(devconfig_t * device,component_type_t * type)516*0Sstevel@tonic-gate devconfig_get_type(
517*0Sstevel@tonic-gate 	devconfig_t *device,
518*0Sstevel@tonic-gate 	component_type_t *type)
519*0Sstevel@tonic-gate {
520*0Sstevel@tonic-gate 	uint16_t val;
521*0Sstevel@tonic-gate 	int error = get_uint16(device->attributes, ATTR_TYPE, &val);
522*0Sstevel@tonic-gate 
523*0Sstevel@tonic-gate 	switch (error) {
524*0Sstevel@tonic-gate 	    /* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
525*0Sstevel@tonic-gate 	    case ENOENT:
526*0Sstevel@tonic-gate 		volume_set_error(gettext("device type not set"));
527*0Sstevel@tonic-gate 		error = ERR_ATTR_UNSET;
528*0Sstevel@tonic-gate 	    break;
529*0Sstevel@tonic-gate 
530*0Sstevel@tonic-gate 	    /* Success */
531*0Sstevel@tonic-gate 	    case 0:
532*0Sstevel@tonic-gate 		*type = (component_type_t)val;
533*0Sstevel@tonic-gate 	}
534*0Sstevel@tonic-gate 
535*0Sstevel@tonic-gate 	return (error);
536*0Sstevel@tonic-gate }
537*0Sstevel@tonic-gate 
538*0Sstevel@tonic-gate /*
539*0Sstevel@tonic-gate  * Set the device size (for volume, mirror, stripe, concat) in bytes
540*0Sstevel@tonic-gate  *
541*0Sstevel@tonic-gate  * Note that size in bytes in a 64-bit field cannot hold the size that
542*0Sstevel@tonic-gate  * can be accessed in a 16 byte CDB.  Since CDBs operate on blocks,
543*0Sstevel@tonic-gate  * the max capacity is 2^73 bytes with 512 byte blocks.
544*0Sstevel@tonic-gate  *
545*0Sstevel@tonic-gate  * @param       device
546*0Sstevel@tonic-gate  *              a devconfig_t representing the device to modify
547*0Sstevel@tonic-gate  *
548*0Sstevel@tonic-gate  * @param       size_in_bytes
549*0Sstevel@tonic-gate  *              the value to set as the device size in bytes
550*0Sstevel@tonic-gate  *
551*0Sstevel@tonic-gate  * @return      0
552*0Sstevel@tonic-gate  *              if successful
553*0Sstevel@tonic-gate  *
554*0Sstevel@tonic-gate  * @return      non-zero
555*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
556*0Sstevel@tonic-gate  *              retrieve the associated error message.
557*0Sstevel@tonic-gate  */
558*0Sstevel@tonic-gate int
devconfig_set_size(devconfig_t * device,uint64_t size_in_bytes)559*0Sstevel@tonic-gate devconfig_set_size(
560*0Sstevel@tonic-gate 	devconfig_t *device,
561*0Sstevel@tonic-gate 	uint64_t size_in_bytes)
562*0Sstevel@tonic-gate {
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate 	/* Validate against limits */
565*0Sstevel@tonic-gate 	/* LINTED -- MIN_SIZE may be 0 */
566*0Sstevel@tonic-gate 	if (size_in_bytes < MIN_SIZE) {
567*0Sstevel@tonic-gate 	    volume_set_error(gettext("size (in bytes) too small: %llu"),
568*0Sstevel@tonic-gate 		(unsigned long long)size_in_bytes);
569*0Sstevel@tonic-gate 	    return (-1);
570*0Sstevel@tonic-gate 	}
571*0Sstevel@tonic-gate 
572*0Sstevel@tonic-gate 	return (set_uint64(device->attributes,
573*0Sstevel@tonic-gate 	    ATTR_SIZEINBYTES, size_in_bytes));
574*0Sstevel@tonic-gate }
575*0Sstevel@tonic-gate 
576*0Sstevel@tonic-gate /*
577*0Sstevel@tonic-gate  * Get the device size (for volume, mirror, stripe, concat) in bytes
578*0Sstevel@tonic-gate  *
579*0Sstevel@tonic-gate  * Note that size in bytes in a 64-bit field cannot hold the size that
580*0Sstevel@tonic-gate  * can be accessed in a 16 byte CDB.  Since CDBs operate on blocks,
581*0Sstevel@tonic-gate  * the max capacity is 2^73 bytes with 512 byte blocks.
582*0Sstevel@tonic-gate  *
583*0Sstevel@tonic-gate  * @param       device
584*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
585*0Sstevel@tonic-gate  *
586*0Sstevel@tonic-gate  * @param       size_in_bytes
587*0Sstevel@tonic-gate  *              RETURN: the device size in bytes
588*0Sstevel@tonic-gate  *
589*0Sstevel@tonic-gate  * @return      0
590*0Sstevel@tonic-gate  *              if successful
591*0Sstevel@tonic-gate  *
592*0Sstevel@tonic-gate  * @return      non-zero
593*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
594*0Sstevel@tonic-gate  *              retrieve the associated error message.
595*0Sstevel@tonic-gate  */
596*0Sstevel@tonic-gate int
devconfig_get_size(devconfig_t * device,uint64_t * size_in_bytes)597*0Sstevel@tonic-gate devconfig_get_size(
598*0Sstevel@tonic-gate 	devconfig_t *device,
599*0Sstevel@tonic-gate 	uint64_t *size_in_bytes)
600*0Sstevel@tonic-gate {
601*0Sstevel@tonic-gate 	int error = get_uint64(
602*0Sstevel@tonic-gate 	    device->attributes, ATTR_SIZEINBYTES, size_in_bytes);
603*0Sstevel@tonic-gate 
604*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
605*0Sstevel@tonic-gate 	if (error == ENOENT) {
606*0Sstevel@tonic-gate 	    volume_set_error(gettext("size (in bytes) not set"));
607*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
608*0Sstevel@tonic-gate 	}
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate 	return (error);
611*0Sstevel@tonic-gate }
612*0Sstevel@tonic-gate 
613*0Sstevel@tonic-gate /*
614*0Sstevel@tonic-gate  * Set the device size in blocks
615*0Sstevel@tonic-gate  *
616*0Sstevel@tonic-gate  * @param       device
617*0Sstevel@tonic-gate  *              a devconfig_t representing the device to modify
618*0Sstevel@tonic-gate  *
619*0Sstevel@tonic-gate  * @param       type
620*0Sstevel@tonic-gate  *              the value to set as the device size in blocks
621*0Sstevel@tonic-gate  *
622*0Sstevel@tonic-gate  * @return      0
623*0Sstevel@tonic-gate  *              if successful
624*0Sstevel@tonic-gate  *
625*0Sstevel@tonic-gate  * @return      non-zero
626*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
627*0Sstevel@tonic-gate  *              retrieve the associated error message.
628*0Sstevel@tonic-gate  */
629*0Sstevel@tonic-gate int
devconfig_set_size_in_blocks(devconfig_t * device,uint64_t size_in_blocks)630*0Sstevel@tonic-gate devconfig_set_size_in_blocks(
631*0Sstevel@tonic-gate 	devconfig_t *device,
632*0Sstevel@tonic-gate 	uint64_t size_in_blocks)
633*0Sstevel@tonic-gate {
634*0Sstevel@tonic-gate 	/* Validate against limits */
635*0Sstevel@tonic-gate 	/* LINTED -- MIN_SIZE_IN_BLOCKS may be 0 */
636*0Sstevel@tonic-gate 	if (size_in_blocks < MIN_SIZE_IN_BLOCKS) {
637*0Sstevel@tonic-gate 	    volume_set_error(gettext("size (in blocks) too small: %llu"),
638*0Sstevel@tonic-gate 		(unsigned long long)size_in_blocks);
639*0Sstevel@tonic-gate 	    return (-1);
640*0Sstevel@tonic-gate 	}
641*0Sstevel@tonic-gate 
642*0Sstevel@tonic-gate 	return (set_uint64(device->attributes,
643*0Sstevel@tonic-gate 	    ATTR_SIZEINBLOCKS, size_in_blocks));
644*0Sstevel@tonic-gate }
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate /*
647*0Sstevel@tonic-gate  * Get the device size in blocks
648*0Sstevel@tonic-gate  *
649*0Sstevel@tonic-gate  * @param       device
650*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
651*0Sstevel@tonic-gate  *
652*0Sstevel@tonic-gate  * @param       size_in_blocks
653*0Sstevel@tonic-gate  *              RETURN: the device size in blocks
654*0Sstevel@tonic-gate  *
655*0Sstevel@tonic-gate  * @return      0
656*0Sstevel@tonic-gate  *              if successful
657*0Sstevel@tonic-gate  *
658*0Sstevel@tonic-gate  * @return      non-zero
659*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
660*0Sstevel@tonic-gate  *              retrieve the associated error message.
661*0Sstevel@tonic-gate  */
662*0Sstevel@tonic-gate int
devconfig_get_size_in_blocks(devconfig_t * device,uint64_t * size_in_blocks)663*0Sstevel@tonic-gate devconfig_get_size_in_blocks(
664*0Sstevel@tonic-gate 	devconfig_t *device,
665*0Sstevel@tonic-gate 	uint64_t *size_in_blocks)
666*0Sstevel@tonic-gate {
667*0Sstevel@tonic-gate 	int error = get_uint64(
668*0Sstevel@tonic-gate 	    device->attributes, ATTR_SIZEINBLOCKS, size_in_blocks);
669*0Sstevel@tonic-gate 
670*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
671*0Sstevel@tonic-gate 	if (error == ENOENT) {
672*0Sstevel@tonic-gate 	    volume_set_error(gettext("size (in blocks) not set"));
673*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
674*0Sstevel@tonic-gate 	}
675*0Sstevel@tonic-gate 
676*0Sstevel@tonic-gate 	return (error);
677*0Sstevel@tonic-gate }
678*0Sstevel@tonic-gate 
679*0Sstevel@tonic-gate /*
680*0Sstevel@tonic-gate  * Set the the slice index
681*0Sstevel@tonic-gate  *
682*0Sstevel@tonic-gate  * @param       slice
683*0Sstevel@tonic-gate  *              a devconfig_t representing the slice to modify
684*0Sstevel@tonic-gate  *
685*0Sstevel@tonic-gate  * @param       index
686*0Sstevel@tonic-gate  *              the value to set as the the slice index
687*0Sstevel@tonic-gate  *
688*0Sstevel@tonic-gate  * @return      0
689*0Sstevel@tonic-gate  *              if successful
690*0Sstevel@tonic-gate  *
691*0Sstevel@tonic-gate  * @return      non-zero
692*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
693*0Sstevel@tonic-gate  *              retrieve the associated error message.
694*0Sstevel@tonic-gate  */
695*0Sstevel@tonic-gate int
devconfig_set_slice_index(devconfig_t * slice,uint16_t index)696*0Sstevel@tonic-gate devconfig_set_slice_index(
697*0Sstevel@tonic-gate 	devconfig_t *slice,
698*0Sstevel@tonic-gate 	uint16_t index)
699*0Sstevel@tonic-gate {
700*0Sstevel@tonic-gate 	return (set_uint16(slice->attributes, ATTR_SLICE_INDEX, index));
701*0Sstevel@tonic-gate }
702*0Sstevel@tonic-gate 
703*0Sstevel@tonic-gate /*
704*0Sstevel@tonic-gate  * Get the slice index
705*0Sstevel@tonic-gate  *
706*0Sstevel@tonic-gate  * @param       device
707*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
708*0Sstevel@tonic-gate  *
709*0Sstevel@tonic-gate  * @param       index
710*0Sstevel@tonic-gate  *              RETURN: the slice index
711*0Sstevel@tonic-gate  *
712*0Sstevel@tonic-gate  * @return      0
713*0Sstevel@tonic-gate  *              if successful
714*0Sstevel@tonic-gate  *
715*0Sstevel@tonic-gate  * @return      non-zero
716*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
717*0Sstevel@tonic-gate  *              retrieve the associated error message.
718*0Sstevel@tonic-gate  */
719*0Sstevel@tonic-gate int
devconfig_get_slice_index(devconfig_t * slice,uint16_t * index)720*0Sstevel@tonic-gate devconfig_get_slice_index(
721*0Sstevel@tonic-gate 	devconfig_t *slice,
722*0Sstevel@tonic-gate 	uint16_t *index)
723*0Sstevel@tonic-gate {
724*0Sstevel@tonic-gate 	int error = get_uint16(slice->attributes, ATTR_SLICE_INDEX, index);
725*0Sstevel@tonic-gate 
726*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
727*0Sstevel@tonic-gate 	if (error == ENOENT) {
728*0Sstevel@tonic-gate 	    volume_set_error(gettext("slice index not set"));
729*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
730*0Sstevel@tonic-gate 	}
731*0Sstevel@tonic-gate 
732*0Sstevel@tonic-gate 	return (error);
733*0Sstevel@tonic-gate }
734*0Sstevel@tonic-gate 
735*0Sstevel@tonic-gate /*
736*0Sstevel@tonic-gate  * Set the the slice start block
737*0Sstevel@tonic-gate  *
738*0Sstevel@tonic-gate  * @param       slice
739*0Sstevel@tonic-gate  *              a devconfig_t representing the slice to modify
740*0Sstevel@tonic-gate  *
741*0Sstevel@tonic-gate  * @param       start_block
742*0Sstevel@tonic-gate  *              the value to set as the the slice start block
743*0Sstevel@tonic-gate  *
744*0Sstevel@tonic-gate  * @return      0
745*0Sstevel@tonic-gate  *              if successful
746*0Sstevel@tonic-gate  *
747*0Sstevel@tonic-gate  * @return      non-zero
748*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
749*0Sstevel@tonic-gate  *              retrieve the associated error message.
750*0Sstevel@tonic-gate  */
751*0Sstevel@tonic-gate int
devconfig_set_slice_start_block(devconfig_t * slice,uint64_t start_block)752*0Sstevel@tonic-gate devconfig_set_slice_start_block(
753*0Sstevel@tonic-gate 	devconfig_t *slice,
754*0Sstevel@tonic-gate 	uint64_t start_block)
755*0Sstevel@tonic-gate {
756*0Sstevel@tonic-gate 	return (set_uint64(slice->attributes,
757*0Sstevel@tonic-gate 	    ATTR_SLICE_STARTSECTOR, start_block));
758*0Sstevel@tonic-gate }
759*0Sstevel@tonic-gate 
760*0Sstevel@tonic-gate /*
761*0Sstevel@tonic-gate  * Get the slice start block
762*0Sstevel@tonic-gate  *
763*0Sstevel@tonic-gate  * @param       device
764*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
765*0Sstevel@tonic-gate  *
766*0Sstevel@tonic-gate  * @param       start_block
767*0Sstevel@tonic-gate  *              RETURN: the slice start block
768*0Sstevel@tonic-gate  *
769*0Sstevel@tonic-gate  * @return      0
770*0Sstevel@tonic-gate  *              if successful
771*0Sstevel@tonic-gate  *
772*0Sstevel@tonic-gate  * @return      non-zero
773*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
774*0Sstevel@tonic-gate  *              retrieve the associated error message.
775*0Sstevel@tonic-gate  */
776*0Sstevel@tonic-gate int
devconfig_get_slice_start_block(devconfig_t * slice,uint64_t * start_block)777*0Sstevel@tonic-gate devconfig_get_slice_start_block(
778*0Sstevel@tonic-gate 	devconfig_t *slice,
779*0Sstevel@tonic-gate 	uint64_t *start_block)
780*0Sstevel@tonic-gate {
781*0Sstevel@tonic-gate 	int error = get_uint64(
782*0Sstevel@tonic-gate 	    slice->attributes, ATTR_SLICE_STARTSECTOR, start_block);
783*0Sstevel@tonic-gate 
784*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
785*0Sstevel@tonic-gate 	if (error == ENOENT) {
786*0Sstevel@tonic-gate 	    volume_set_error(gettext("slice start block not set"));
787*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
788*0Sstevel@tonic-gate 	}
789*0Sstevel@tonic-gate 
790*0Sstevel@tonic-gate 	return (error);
791*0Sstevel@tonic-gate }
792*0Sstevel@tonic-gate 
793*0Sstevel@tonic-gate /*
794*0Sstevel@tonic-gate  * Set the number of subcomponents in mirror
795*0Sstevel@tonic-gate  *
796*0Sstevel@tonic-gate  * @param       mirror
797*0Sstevel@tonic-gate  *              a devconfig_t representing the mirror to modify
798*0Sstevel@tonic-gate  *
799*0Sstevel@tonic-gate  * @param       nsubs
800*0Sstevel@tonic-gate  *              the value to set as the number of subcomponents in
801*0Sstevel@tonic-gate  *              mirror
802*0Sstevel@tonic-gate  *
803*0Sstevel@tonic-gate  * @return      0
804*0Sstevel@tonic-gate  *              if successful
805*0Sstevel@tonic-gate  *
806*0Sstevel@tonic-gate  * @return      non-zero
807*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
808*0Sstevel@tonic-gate  *              retrieve the associated error message.
809*0Sstevel@tonic-gate  */
810*0Sstevel@tonic-gate int
devconfig_set_mirror_nsubs(devconfig_t * mirror,uint16_t nsubs)811*0Sstevel@tonic-gate devconfig_set_mirror_nsubs(
812*0Sstevel@tonic-gate 	devconfig_t *mirror,
813*0Sstevel@tonic-gate 	uint16_t nsubs)
814*0Sstevel@tonic-gate {
815*0Sstevel@tonic-gate 	/* Validate against limits */
816*0Sstevel@tonic-gate 	if (nsubs < 1 || nsubs > NMIRROR) {
817*0Sstevel@tonic-gate 	    volume_set_error(
818*0Sstevel@tonic-gate 		gettext("number of submirrors (%d) out of valid range (%d-%d)"),
819*0Sstevel@tonic-gate 		nsubs, 1, NMIRROR);
820*0Sstevel@tonic-gate 	    return (-1);
821*0Sstevel@tonic-gate 	}
822*0Sstevel@tonic-gate 
823*0Sstevel@tonic-gate 	return (set_uint16(mirror->attributes, ATTR_MIRROR_NSUBMIRRORS, nsubs));
824*0Sstevel@tonic-gate }
825*0Sstevel@tonic-gate 
826*0Sstevel@tonic-gate /*
827*0Sstevel@tonic-gate  * Get number of subcomponents in mirror
828*0Sstevel@tonic-gate  *
829*0Sstevel@tonic-gate  * @param       device
830*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
831*0Sstevel@tonic-gate  *
832*0Sstevel@tonic-gate  * @param       nsubs
833*0Sstevel@tonic-gate  *              RETURN: number of subcomponents in mirror
834*0Sstevel@tonic-gate  *
835*0Sstevel@tonic-gate  * @return      0
836*0Sstevel@tonic-gate  *              if successful
837*0Sstevel@tonic-gate  *
838*0Sstevel@tonic-gate  * @return      non-zero
839*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
840*0Sstevel@tonic-gate  *              retrieve the associated error message.
841*0Sstevel@tonic-gate  */
842*0Sstevel@tonic-gate int
devconfig_get_mirror_nsubs(devconfig_t * mirror,uint16_t * nsubs)843*0Sstevel@tonic-gate devconfig_get_mirror_nsubs(
844*0Sstevel@tonic-gate 	devconfig_t *mirror,
845*0Sstevel@tonic-gate 	uint16_t *nsubs)
846*0Sstevel@tonic-gate {
847*0Sstevel@tonic-gate 	int error = get_uint16(
848*0Sstevel@tonic-gate 	    mirror->attributes, ATTR_MIRROR_NSUBMIRRORS, nsubs);
849*0Sstevel@tonic-gate 
850*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
851*0Sstevel@tonic-gate 	if (error == ENOENT) {
852*0Sstevel@tonic-gate 	    volume_set_error(gettext("number or submirrors not set"));
853*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
854*0Sstevel@tonic-gate 	}
855*0Sstevel@tonic-gate 
856*0Sstevel@tonic-gate 	return (error);
857*0Sstevel@tonic-gate }
858*0Sstevel@tonic-gate 
859*0Sstevel@tonic-gate /*
860*0Sstevel@tonic-gate  * Set the read strategy for mirror
861*0Sstevel@tonic-gate  *
862*0Sstevel@tonic-gate  * @param       mirror
863*0Sstevel@tonic-gate  *              a devconfig_t representing the mirror to modify
864*0Sstevel@tonic-gate  *
865*0Sstevel@tonic-gate  * @param       read
866*0Sstevel@tonic-gate  *              the value to set as the read strategy for mirror
867*0Sstevel@tonic-gate  *
868*0Sstevel@tonic-gate  * @return      0
869*0Sstevel@tonic-gate  *              if successful
870*0Sstevel@tonic-gate  *
871*0Sstevel@tonic-gate  * @return      non-zero
872*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
873*0Sstevel@tonic-gate  *              retrieve the associated error message.
874*0Sstevel@tonic-gate  */
875*0Sstevel@tonic-gate int
devconfig_set_mirror_read(devconfig_t * mirror,mirror_read_strategy_t read)876*0Sstevel@tonic-gate devconfig_set_mirror_read(
877*0Sstevel@tonic-gate 	devconfig_t *mirror,
878*0Sstevel@tonic-gate 	mirror_read_strategy_t read)
879*0Sstevel@tonic-gate {
880*0Sstevel@tonic-gate 	return (set_uint16(mirror->attributes,
881*0Sstevel@tonic-gate 	    ATTR_MIRROR_READ, (uint16_t)read));
882*0Sstevel@tonic-gate }
883*0Sstevel@tonic-gate 
884*0Sstevel@tonic-gate /*
885*0Sstevel@tonic-gate  * Get read strategy for mirror
886*0Sstevel@tonic-gate  *
887*0Sstevel@tonic-gate  * @param       device
888*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
889*0Sstevel@tonic-gate  *
890*0Sstevel@tonic-gate  * @param       read
891*0Sstevel@tonic-gate  *              RETURN: read strategy for mirror
892*0Sstevel@tonic-gate  *
893*0Sstevel@tonic-gate  * @return      0
894*0Sstevel@tonic-gate  *              if successful
895*0Sstevel@tonic-gate  *
896*0Sstevel@tonic-gate  * @return      non-zero
897*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
898*0Sstevel@tonic-gate  *              retrieve the associated error message.
899*0Sstevel@tonic-gate  */
900*0Sstevel@tonic-gate int
devconfig_get_mirror_read(devconfig_t * mirror,mirror_read_strategy_t * read)901*0Sstevel@tonic-gate devconfig_get_mirror_read(
902*0Sstevel@tonic-gate 	devconfig_t *mirror,
903*0Sstevel@tonic-gate 	mirror_read_strategy_t *read)
904*0Sstevel@tonic-gate {
905*0Sstevel@tonic-gate 	uint16_t val;
906*0Sstevel@tonic-gate 	int error = get_uint16(mirror->attributes, ATTR_MIRROR_READ, &val);
907*0Sstevel@tonic-gate 
908*0Sstevel@tonic-gate 	switch (error) {
909*0Sstevel@tonic-gate 	    /* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
910*0Sstevel@tonic-gate 	    case ENOENT:
911*0Sstevel@tonic-gate 		volume_set_error(gettext("mirror read strategy not set"));
912*0Sstevel@tonic-gate 		error = ERR_ATTR_UNSET;
913*0Sstevel@tonic-gate 	    break;
914*0Sstevel@tonic-gate 
915*0Sstevel@tonic-gate 	    /* Success */
916*0Sstevel@tonic-gate 	    case 0:
917*0Sstevel@tonic-gate 		*read = (mirror_read_strategy_t)val;
918*0Sstevel@tonic-gate 	}
919*0Sstevel@tonic-gate 
920*0Sstevel@tonic-gate 	return (error);
921*0Sstevel@tonic-gate }
922*0Sstevel@tonic-gate 
923*0Sstevel@tonic-gate /*
924*0Sstevel@tonic-gate  * Set the write strategy for mirror
925*0Sstevel@tonic-gate  *
926*0Sstevel@tonic-gate  * @param       mirror
927*0Sstevel@tonic-gate  *              a devconfig_t representing the mirror to modify
928*0Sstevel@tonic-gate  *
929*0Sstevel@tonic-gate  * @param       write
930*0Sstevel@tonic-gate  *              the value to set as the write strategy for mirror
931*0Sstevel@tonic-gate  *
932*0Sstevel@tonic-gate  * @return      0
933*0Sstevel@tonic-gate  *              if successful
934*0Sstevel@tonic-gate  *
935*0Sstevel@tonic-gate  * @return      non-zero
936*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
937*0Sstevel@tonic-gate  *              retrieve the associated error message.
938*0Sstevel@tonic-gate  */
939*0Sstevel@tonic-gate int
devconfig_set_mirror_write(devconfig_t * mirror,mirror_write_strategy_t write)940*0Sstevel@tonic-gate devconfig_set_mirror_write(
941*0Sstevel@tonic-gate 	devconfig_t *mirror,
942*0Sstevel@tonic-gate 	mirror_write_strategy_t write)
943*0Sstevel@tonic-gate {
944*0Sstevel@tonic-gate 	return (set_uint16(mirror->attributes,
945*0Sstevel@tonic-gate 	    ATTR_MIRROR_WRITE, (uint16_t)write));
946*0Sstevel@tonic-gate }
947*0Sstevel@tonic-gate 
948*0Sstevel@tonic-gate /*
949*0Sstevel@tonic-gate  * Get write strategy for mirror
950*0Sstevel@tonic-gate  *
951*0Sstevel@tonic-gate  * @param       device
952*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
953*0Sstevel@tonic-gate  *
954*0Sstevel@tonic-gate  * @param       write
955*0Sstevel@tonic-gate  *              RETURN: write strategy for mirror
956*0Sstevel@tonic-gate  *
957*0Sstevel@tonic-gate  * @return      0
958*0Sstevel@tonic-gate  *              if successful
959*0Sstevel@tonic-gate  *
960*0Sstevel@tonic-gate  * @return      non-zero
961*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
962*0Sstevel@tonic-gate  *              retrieve the associated error message.
963*0Sstevel@tonic-gate  */
964*0Sstevel@tonic-gate int
devconfig_get_mirror_write(devconfig_t * mirror,mirror_write_strategy_t * write)965*0Sstevel@tonic-gate devconfig_get_mirror_write(
966*0Sstevel@tonic-gate 	devconfig_t *mirror,
967*0Sstevel@tonic-gate 	mirror_write_strategy_t *write)
968*0Sstevel@tonic-gate {
969*0Sstevel@tonic-gate 	uint16_t val;
970*0Sstevel@tonic-gate 	int error = get_uint16(mirror->attributes, ATTR_MIRROR_WRITE, &val);
971*0Sstevel@tonic-gate 
972*0Sstevel@tonic-gate 	switch (error) {
973*0Sstevel@tonic-gate 	    /* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
974*0Sstevel@tonic-gate 	    case ENOENT:
975*0Sstevel@tonic-gate 		volume_set_error(gettext("mirror write strategy not set"));
976*0Sstevel@tonic-gate 		error = ERR_ATTR_UNSET;
977*0Sstevel@tonic-gate 	    break;
978*0Sstevel@tonic-gate 
979*0Sstevel@tonic-gate 	    /* Success */
980*0Sstevel@tonic-gate 	    case 0:
981*0Sstevel@tonic-gate 		*write = (mirror_write_strategy_t)val;
982*0Sstevel@tonic-gate 	}
983*0Sstevel@tonic-gate 
984*0Sstevel@tonic-gate 	return (error);
985*0Sstevel@tonic-gate }
986*0Sstevel@tonic-gate 
987*0Sstevel@tonic-gate /*
988*0Sstevel@tonic-gate  * Set the resync pass for mirror
989*0Sstevel@tonic-gate  *
990*0Sstevel@tonic-gate  * @param       mirror
991*0Sstevel@tonic-gate  *              a devconfig_t representing the mirror to modify
992*0Sstevel@tonic-gate  *
993*0Sstevel@tonic-gate  * @param       pass
994*0Sstevel@tonic-gate  *              the value to set as the resync pass for mirror
995*0Sstevel@tonic-gate  *
996*0Sstevel@tonic-gate  * @return      0
997*0Sstevel@tonic-gate  *              if successful
998*0Sstevel@tonic-gate  *
999*0Sstevel@tonic-gate  * @return      non-zero
1000*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1001*0Sstevel@tonic-gate  *              retrieve the associated error message.
1002*0Sstevel@tonic-gate  */
1003*0Sstevel@tonic-gate int
devconfig_set_mirror_pass(devconfig_t * mirror,uint16_t pass)1004*0Sstevel@tonic-gate devconfig_set_mirror_pass(
1005*0Sstevel@tonic-gate 	devconfig_t *mirror,
1006*0Sstevel@tonic-gate 	uint16_t pass)
1007*0Sstevel@tonic-gate {
1008*0Sstevel@tonic-gate 	/* Validate against max value */
1009*0Sstevel@tonic-gate 	if (pass > MD_PASS_MAX) {
1010*0Sstevel@tonic-gate 	    volume_set_error(
1011*0Sstevel@tonic-gate 		gettext("mirror pass number (%d) out of valid range (0-%d)"),
1012*0Sstevel@tonic-gate 		pass, MD_PASS_MAX);
1013*0Sstevel@tonic-gate 	    return (-1);
1014*0Sstevel@tonic-gate 	}
1015*0Sstevel@tonic-gate 
1016*0Sstevel@tonic-gate 	return (set_uint16(mirror->attributes, ATTR_MIRROR_PASSNUM, pass));
1017*0Sstevel@tonic-gate }
1018*0Sstevel@tonic-gate 
1019*0Sstevel@tonic-gate /*
1020*0Sstevel@tonic-gate  * Get resync pass for mirror
1021*0Sstevel@tonic-gate  *
1022*0Sstevel@tonic-gate  * @param       device
1023*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1024*0Sstevel@tonic-gate  *
1025*0Sstevel@tonic-gate  * @param       pass
1026*0Sstevel@tonic-gate  *              RETURN: resync pass for mirror
1027*0Sstevel@tonic-gate  *
1028*0Sstevel@tonic-gate  * @return      0
1029*0Sstevel@tonic-gate  *              if successful
1030*0Sstevel@tonic-gate  *
1031*0Sstevel@tonic-gate  * @return      non-zero
1032*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1033*0Sstevel@tonic-gate  *              retrieve the associated error message.
1034*0Sstevel@tonic-gate  */
1035*0Sstevel@tonic-gate int
devconfig_get_mirror_pass(devconfig_t * mirror,uint16_t * pass)1036*0Sstevel@tonic-gate devconfig_get_mirror_pass(
1037*0Sstevel@tonic-gate 	devconfig_t *mirror,
1038*0Sstevel@tonic-gate 	uint16_t *pass)
1039*0Sstevel@tonic-gate {
1040*0Sstevel@tonic-gate 	int error = get_uint16(mirror->attributes, ATTR_MIRROR_PASSNUM, pass);
1041*0Sstevel@tonic-gate 
1042*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1043*0Sstevel@tonic-gate 	if (error == ENOENT) {
1044*0Sstevel@tonic-gate 	    volume_set_error(gettext("mirror pass number not set"));
1045*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1046*0Sstevel@tonic-gate 	}
1047*0Sstevel@tonic-gate 
1048*0Sstevel@tonic-gate 	return (error);
1049*0Sstevel@tonic-gate }
1050*0Sstevel@tonic-gate 
1051*0Sstevel@tonic-gate /*
1052*0Sstevel@tonic-gate  * Set the minimum number of components in stripe
1053*0Sstevel@tonic-gate  *
1054*0Sstevel@tonic-gate  * @param       stripe
1055*0Sstevel@tonic-gate  *              a devconfig_t representing the stripe to modify
1056*0Sstevel@tonic-gate  *
1057*0Sstevel@tonic-gate  * @param       mincomp
1058*0Sstevel@tonic-gate  *              the value to set as the minimum number of components
1059*0Sstevel@tonic-gate  *              in stripe
1060*0Sstevel@tonic-gate  *
1061*0Sstevel@tonic-gate  * @return      0
1062*0Sstevel@tonic-gate  *              if successful
1063*0Sstevel@tonic-gate  *
1064*0Sstevel@tonic-gate  * @return      non-zero
1065*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1066*0Sstevel@tonic-gate  *              retrieve the associated error message.
1067*0Sstevel@tonic-gate  */
1068*0Sstevel@tonic-gate int
devconfig_set_stripe_mincomp(devconfig_t * stripe,uint16_t mincomp)1069*0Sstevel@tonic-gate devconfig_set_stripe_mincomp(
1070*0Sstevel@tonic-gate 	devconfig_t *stripe,
1071*0Sstevel@tonic-gate 	uint16_t mincomp)
1072*0Sstevel@tonic-gate {
1073*0Sstevel@tonic-gate 	/* Validate against minimum value */
1074*0Sstevel@tonic-gate 	if (mincomp < MIN_NSTRIPE_COMP) {
1075*0Sstevel@tonic-gate 	    volume_set_error(gettext(
1076*0Sstevel@tonic-gate 		"minimum stripe components (%d) below minimum allowable (%d)"),
1077*0Sstevel@tonic-gate 		mincomp, MIN_NSTRIPE_COMP);
1078*0Sstevel@tonic-gate 	    return (-1);
1079*0Sstevel@tonic-gate 	}
1080*0Sstevel@tonic-gate 
1081*0Sstevel@tonic-gate 	return (set_uint16(stripe->attributes, ATTR_STRIPE_MINCOMP, mincomp));
1082*0Sstevel@tonic-gate }
1083*0Sstevel@tonic-gate 
1084*0Sstevel@tonic-gate /*
1085*0Sstevel@tonic-gate  * Get minimum number of components in stripe
1086*0Sstevel@tonic-gate  *
1087*0Sstevel@tonic-gate  * @param       device
1088*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1089*0Sstevel@tonic-gate  *
1090*0Sstevel@tonic-gate  * @param       mincomp
1091*0Sstevel@tonic-gate  *              RETURN: minimum number of components in stripe
1092*0Sstevel@tonic-gate  *
1093*0Sstevel@tonic-gate  * @return      0
1094*0Sstevel@tonic-gate  *              if successful
1095*0Sstevel@tonic-gate  *
1096*0Sstevel@tonic-gate  * @return      non-zero
1097*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1098*0Sstevel@tonic-gate  *              retrieve the associated error message.
1099*0Sstevel@tonic-gate  */
1100*0Sstevel@tonic-gate int
devconfig_get_stripe_mincomp(devconfig_t * stripe,uint16_t * mincomp)1101*0Sstevel@tonic-gate devconfig_get_stripe_mincomp(
1102*0Sstevel@tonic-gate 	devconfig_t *stripe,
1103*0Sstevel@tonic-gate 	uint16_t *mincomp)
1104*0Sstevel@tonic-gate {
1105*0Sstevel@tonic-gate 	int error = get_uint16(
1106*0Sstevel@tonic-gate 	    stripe->attributes, ATTR_STRIPE_MINCOMP, mincomp);
1107*0Sstevel@tonic-gate 
1108*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1109*0Sstevel@tonic-gate 	if (error == ENOENT) {
1110*0Sstevel@tonic-gate 	    volume_set_error(
1111*0Sstevel@tonic-gate 		gettext("minimum number of stripe components not set"));
1112*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1113*0Sstevel@tonic-gate 	}
1114*0Sstevel@tonic-gate 
1115*0Sstevel@tonic-gate 	return (error);
1116*0Sstevel@tonic-gate }
1117*0Sstevel@tonic-gate 
1118*0Sstevel@tonic-gate /*
1119*0Sstevel@tonic-gate  * Set the maximum number of components in stripe
1120*0Sstevel@tonic-gate  *
1121*0Sstevel@tonic-gate  * @param       stripe
1122*0Sstevel@tonic-gate  *              a devconfig_t representing the stripe to modify
1123*0Sstevel@tonic-gate  *
1124*0Sstevel@tonic-gate  * @param       maxcomp
1125*0Sstevel@tonic-gate  *              the value to set as the maximum number of components
1126*0Sstevel@tonic-gate  *              in stripe
1127*0Sstevel@tonic-gate  *
1128*0Sstevel@tonic-gate  * @return      0
1129*0Sstevel@tonic-gate  *              if successful
1130*0Sstevel@tonic-gate  *
1131*0Sstevel@tonic-gate  * @return      non-zero
1132*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1133*0Sstevel@tonic-gate  *              retrieve the associated error message.
1134*0Sstevel@tonic-gate  */
1135*0Sstevel@tonic-gate int
devconfig_set_stripe_maxcomp(devconfig_t * stripe,uint16_t maxcomp)1136*0Sstevel@tonic-gate devconfig_set_stripe_maxcomp(
1137*0Sstevel@tonic-gate 	devconfig_t *stripe,
1138*0Sstevel@tonic-gate 	uint16_t maxcomp)
1139*0Sstevel@tonic-gate {
1140*0Sstevel@tonic-gate 	/* Validate against minimum value */
1141*0Sstevel@tonic-gate 	if (maxcomp < MIN_NSTRIPE_COMP) {
1142*0Sstevel@tonic-gate 	    volume_set_error(gettext(
1143*0Sstevel@tonic-gate 		"maximum stripe components (%d) below minimum allowable (%d)"),
1144*0Sstevel@tonic-gate 		maxcomp, MIN_NSTRIPE_COMP);
1145*0Sstevel@tonic-gate 	    return (-1);
1146*0Sstevel@tonic-gate 	}
1147*0Sstevel@tonic-gate 
1148*0Sstevel@tonic-gate 	return (set_uint16(stripe->attributes, ATTR_STRIPE_MAXCOMP, maxcomp));
1149*0Sstevel@tonic-gate }
1150*0Sstevel@tonic-gate 
1151*0Sstevel@tonic-gate /*
1152*0Sstevel@tonic-gate  * Get maximum number of components in stripe
1153*0Sstevel@tonic-gate  *
1154*0Sstevel@tonic-gate  * @param       device
1155*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1156*0Sstevel@tonic-gate  *
1157*0Sstevel@tonic-gate  * @param       maxcomp
1158*0Sstevel@tonic-gate  *              RETURN: maximum number of components in stripe
1159*0Sstevel@tonic-gate  *
1160*0Sstevel@tonic-gate  * @return      0
1161*0Sstevel@tonic-gate  *              if successful
1162*0Sstevel@tonic-gate  *
1163*0Sstevel@tonic-gate  * @return      non-zero
1164*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1165*0Sstevel@tonic-gate  *              retrieve the associated error message.
1166*0Sstevel@tonic-gate  */
1167*0Sstevel@tonic-gate int
devconfig_get_stripe_maxcomp(devconfig_t * stripe,uint16_t * maxcomp)1168*0Sstevel@tonic-gate devconfig_get_stripe_maxcomp(
1169*0Sstevel@tonic-gate 	devconfig_t *stripe,
1170*0Sstevel@tonic-gate 	uint16_t *maxcomp)
1171*0Sstevel@tonic-gate {
1172*0Sstevel@tonic-gate 	int error = get_uint16(
1173*0Sstevel@tonic-gate 	    stripe->attributes, ATTR_STRIPE_MAXCOMP, maxcomp);
1174*0Sstevel@tonic-gate 
1175*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1176*0Sstevel@tonic-gate 	if (error == ENOENT) {
1177*0Sstevel@tonic-gate 	    volume_set_error(
1178*0Sstevel@tonic-gate 		gettext("maximum number of stripe components not set"));
1179*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1180*0Sstevel@tonic-gate 	}
1181*0Sstevel@tonic-gate 
1182*0Sstevel@tonic-gate 	return (error);
1183*0Sstevel@tonic-gate }
1184*0Sstevel@tonic-gate 
1185*0Sstevel@tonic-gate /*
1186*0Sstevel@tonic-gate  * Set the stripe interlace
1187*0Sstevel@tonic-gate  *
1188*0Sstevel@tonic-gate  * @param       stripe
1189*0Sstevel@tonic-gate  *              a devconfig_t representing the stripe to modify
1190*0Sstevel@tonic-gate  *
1191*0Sstevel@tonic-gate  * @param       interlace
1192*0Sstevel@tonic-gate  *              the value to set as the stripe interlace
1193*0Sstevel@tonic-gate  *
1194*0Sstevel@tonic-gate  * @return      0
1195*0Sstevel@tonic-gate  *              if successful
1196*0Sstevel@tonic-gate  *
1197*0Sstevel@tonic-gate  * @return      non-zero
1198*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1199*0Sstevel@tonic-gate  *              retrieve the associated error message.
1200*0Sstevel@tonic-gate  */
1201*0Sstevel@tonic-gate int
devconfig_set_stripe_interlace(devconfig_t * stripe,uint64_t interlace)1202*0Sstevel@tonic-gate devconfig_set_stripe_interlace(
1203*0Sstevel@tonic-gate 	devconfig_t *stripe,
1204*0Sstevel@tonic-gate 	uint64_t interlace)
1205*0Sstevel@tonic-gate {
1206*0Sstevel@tonic-gate 	if (interlace < MININTERLACE || interlace > MAXINTERLACE) {
1207*0Sstevel@tonic-gate 	    char *intstr = NULL;
1208*0Sstevel@tonic-gate 	    char *minstr = NULL;
1209*0Sstevel@tonic-gate 	    char *maxstr = NULL;
1210*0Sstevel@tonic-gate 
1211*0Sstevel@tonic-gate 	    /* Get string representations of interlaces */
1212*0Sstevel@tonic-gate 	    bytes_to_sizestr(interlace, &intstr, universal_units, B_FALSE);
1213*0Sstevel@tonic-gate 	    bytes_to_sizestr(MININTERLACE, &minstr, universal_units, B_FALSE);
1214*0Sstevel@tonic-gate 	    bytes_to_sizestr(MAXINTERLACE, &maxstr, universal_units, B_FALSE);
1215*0Sstevel@tonic-gate 
1216*0Sstevel@tonic-gate 	    volume_set_error(
1217*0Sstevel@tonic-gate 		gettext("interlace (%s) out of valid range (%s - %s)"),
1218*0Sstevel@tonic-gate 		intstr, minstr, maxstr);
1219*0Sstevel@tonic-gate 
1220*0Sstevel@tonic-gate 	    free(intstr);
1221*0Sstevel@tonic-gate 	    free(minstr);
1222*0Sstevel@tonic-gate 	    free(maxstr);
1223*0Sstevel@tonic-gate 
1224*0Sstevel@tonic-gate 	    return (-1);
1225*0Sstevel@tonic-gate 	}
1226*0Sstevel@tonic-gate 
1227*0Sstevel@tonic-gate 	return (set_uint64(stripe->attributes,
1228*0Sstevel@tonic-gate 	    ATTR_STRIPE_INTERLACE, interlace));
1229*0Sstevel@tonic-gate }
1230*0Sstevel@tonic-gate 
1231*0Sstevel@tonic-gate /*
1232*0Sstevel@tonic-gate  * Get stripe interlace
1233*0Sstevel@tonic-gate  *
1234*0Sstevel@tonic-gate  * @param       device
1235*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1236*0Sstevel@tonic-gate  *
1237*0Sstevel@tonic-gate  * @param       interlace
1238*0Sstevel@tonic-gate  *              RETURN: stripe interlace
1239*0Sstevel@tonic-gate  *
1240*0Sstevel@tonic-gate  * @return      0
1241*0Sstevel@tonic-gate  *              if successful
1242*0Sstevel@tonic-gate  *
1243*0Sstevel@tonic-gate  * @return      non-zero
1244*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1245*0Sstevel@tonic-gate  *              retrieve the associated error message.
1246*0Sstevel@tonic-gate  */
1247*0Sstevel@tonic-gate int
devconfig_get_stripe_interlace(devconfig_t * stripe,uint64_t * interlace)1248*0Sstevel@tonic-gate devconfig_get_stripe_interlace(
1249*0Sstevel@tonic-gate 	devconfig_t *stripe,
1250*0Sstevel@tonic-gate 	uint64_t *interlace)
1251*0Sstevel@tonic-gate {
1252*0Sstevel@tonic-gate 	int error = get_uint64(
1253*0Sstevel@tonic-gate 	    stripe->attributes, ATTR_STRIPE_INTERLACE, interlace);
1254*0Sstevel@tonic-gate 
1255*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1256*0Sstevel@tonic-gate 	if (error == ENOENT) {
1257*0Sstevel@tonic-gate 	    volume_set_error(gettext("stripe interlace not set"));
1258*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1259*0Sstevel@tonic-gate 	}
1260*0Sstevel@tonic-gate 
1261*0Sstevel@tonic-gate 	return (error);
1262*0Sstevel@tonic-gate }
1263*0Sstevel@tonic-gate 
1264*0Sstevel@tonic-gate /*
1265*0Sstevel@tonic-gate  * Set the redundancy level for a volume.
1266*0Sstevel@tonic-gate  *
1267*0Sstevel@tonic-gate  * @param       volume
1268*0Sstevel@tonic-gate  *              a devconfig_t representing the volume to modify
1269*0Sstevel@tonic-gate  *
1270*0Sstevel@tonic-gate  * @param       rlevel
1271*0Sstevel@tonic-gate  *              If 0, a stripe will be created.  If > 0, a mirror with
1272*0Sstevel@tonic-gate  *              this number of submirrors will be created.
1273*0Sstevel@tonic-gate  *
1274*0Sstevel@tonic-gate  * @return      0
1275*0Sstevel@tonic-gate  *              if successful
1276*0Sstevel@tonic-gate  *
1277*0Sstevel@tonic-gate  * @return      non-zero
1278*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1279*0Sstevel@tonic-gate  *              retrieve the associated error message.
1280*0Sstevel@tonic-gate  */
1281*0Sstevel@tonic-gate int
devconfig_set_volume_redundancy_level(devconfig_t * volume,uint16_t rlevel)1282*0Sstevel@tonic-gate devconfig_set_volume_redundancy_level(
1283*0Sstevel@tonic-gate 	devconfig_t *volume,
1284*0Sstevel@tonic-gate 	uint16_t rlevel)
1285*0Sstevel@tonic-gate {
1286*0Sstevel@tonic-gate 	/* Validate against limits */
1287*0Sstevel@tonic-gate 	if (rlevel > NMIRROR) {
1288*0Sstevel@tonic-gate 	    volume_set_error(gettext(
1289*0Sstevel@tonic-gate 		"volume redundancy level (%d) out of valid range (%d-%d)"),
1290*0Sstevel@tonic-gate 		rlevel, 0, NMIRROR);
1291*0Sstevel@tonic-gate 	    return (-1);
1292*0Sstevel@tonic-gate 	}
1293*0Sstevel@tonic-gate 
1294*0Sstevel@tonic-gate 	return (set_uint16(volume->attributes, ATTR_VOLUME_REDUNDANCY, rlevel));
1295*0Sstevel@tonic-gate }
1296*0Sstevel@tonic-gate 
1297*0Sstevel@tonic-gate /*
1298*0Sstevel@tonic-gate  * Get the redundancy level for a volume.
1299*0Sstevel@tonic-gate  *
1300*0Sstevel@tonic-gate  * @param       device
1301*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1302*0Sstevel@tonic-gate  *
1303*0Sstevel@tonic-gate  * @param       rlevel
1304*0Sstevel@tonic-gate  *              RETURN: the redundancy level for a volume
1305*0Sstevel@tonic-gate  *
1306*0Sstevel@tonic-gate  * @return      0
1307*0Sstevel@tonic-gate  *              if successful
1308*0Sstevel@tonic-gate  *
1309*0Sstevel@tonic-gate  * @return      non-zero
1310*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1311*0Sstevel@tonic-gate  *              retrieve the associated error message.
1312*0Sstevel@tonic-gate  */
1313*0Sstevel@tonic-gate int
devconfig_get_volume_redundancy_level(devconfig_t * volume,uint16_t * rlevel)1314*0Sstevel@tonic-gate devconfig_get_volume_redundancy_level(
1315*0Sstevel@tonic-gate 	devconfig_t *volume,
1316*0Sstevel@tonic-gate 	uint16_t *rlevel)
1317*0Sstevel@tonic-gate {
1318*0Sstevel@tonic-gate 	int error = get_uint16(
1319*0Sstevel@tonic-gate 	    volume->attributes, ATTR_VOLUME_REDUNDANCY, rlevel);
1320*0Sstevel@tonic-gate 
1321*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1322*0Sstevel@tonic-gate 	if (error == ENOENT) {
1323*0Sstevel@tonic-gate 	    volume_set_error(gettext("volume redundancy level not set"));
1324*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1325*0Sstevel@tonic-gate 	}
1326*0Sstevel@tonic-gate 
1327*0Sstevel@tonic-gate 	return (error);
1328*0Sstevel@tonic-gate }
1329*0Sstevel@tonic-gate 
1330*0Sstevel@tonic-gate /*
1331*0Sstevel@tonic-gate  * Set the number of paths in volume
1332*0Sstevel@tonic-gate  *
1333*0Sstevel@tonic-gate  * @param       volume
1334*0Sstevel@tonic-gate  *              a devconfig_t representing the volume to modify
1335*0Sstevel@tonic-gate  *
1336*0Sstevel@tonic-gate  * @param       npaths
1337*0Sstevel@tonic-gate  *              the value to set as the number of paths in volume
1338*0Sstevel@tonic-gate  *
1339*0Sstevel@tonic-gate  * @return      0
1340*0Sstevel@tonic-gate  *              if successful
1341*0Sstevel@tonic-gate  *
1342*0Sstevel@tonic-gate  * @return      non-zero
1343*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1344*0Sstevel@tonic-gate  *              retrieve the associated error message.
1345*0Sstevel@tonic-gate  */
1346*0Sstevel@tonic-gate int
devconfig_set_volume_npaths(devconfig_t * volume,uint16_t npaths)1347*0Sstevel@tonic-gate devconfig_set_volume_npaths(
1348*0Sstevel@tonic-gate 	devconfig_t *volume,
1349*0Sstevel@tonic-gate 	uint16_t npaths)
1350*0Sstevel@tonic-gate {
1351*0Sstevel@tonic-gate 	/* Validate against limits */
1352*0Sstevel@tonic-gate 	if (npaths < MIN_NDATAPATHS || npaths > MAX_NDATAPATHS) {
1353*0Sstevel@tonic-gate 	    volume_set_error(
1354*0Sstevel@tonic-gate 		gettext("number of data paths (%d) out of valid range (%d-%d)"),
1355*0Sstevel@tonic-gate 		npaths, MIN_NDATAPATHS, MAX_NDATAPATHS);
1356*0Sstevel@tonic-gate 	    return (-1);
1357*0Sstevel@tonic-gate 	}
1358*0Sstevel@tonic-gate 
1359*0Sstevel@tonic-gate 	return (set_uint16(volume->attributes, ATTR_VOLUME_DATAPATHS, npaths));
1360*0Sstevel@tonic-gate }
1361*0Sstevel@tonic-gate 
1362*0Sstevel@tonic-gate /*
1363*0Sstevel@tonic-gate  * Get number of paths in volume
1364*0Sstevel@tonic-gate  *
1365*0Sstevel@tonic-gate  * @param       device
1366*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1367*0Sstevel@tonic-gate  *
1368*0Sstevel@tonic-gate  * @param       npaths
1369*0Sstevel@tonic-gate  *              RETURN: number of paths in volume
1370*0Sstevel@tonic-gate  *
1371*0Sstevel@tonic-gate  * @return      0
1372*0Sstevel@tonic-gate  *              if successful
1373*0Sstevel@tonic-gate  *
1374*0Sstevel@tonic-gate  * @return      non-zero
1375*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1376*0Sstevel@tonic-gate  *              retrieve the associated error message.
1377*0Sstevel@tonic-gate  */
1378*0Sstevel@tonic-gate int
devconfig_get_volume_npaths(devconfig_t * volume,uint16_t * npaths)1379*0Sstevel@tonic-gate devconfig_get_volume_npaths(
1380*0Sstevel@tonic-gate 	devconfig_t *volume,
1381*0Sstevel@tonic-gate 	uint16_t *npaths)
1382*0Sstevel@tonic-gate {
1383*0Sstevel@tonic-gate 	int error = get_uint16(
1384*0Sstevel@tonic-gate 	    volume->attributes, ATTR_VOLUME_DATAPATHS, npaths);
1385*0Sstevel@tonic-gate 
1386*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1387*0Sstevel@tonic-gate 	if (error == ENOENT) {
1388*0Sstevel@tonic-gate 	    volume_set_error(gettext("number of data paths not set"));
1389*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1390*0Sstevel@tonic-gate 	}
1391*0Sstevel@tonic-gate 
1392*0Sstevel@tonic-gate 	return (error);
1393*0Sstevel@tonic-gate }
1394*0Sstevel@tonic-gate 
1395*0Sstevel@tonic-gate /*
1396*0Sstevel@tonic-gate  * Set the HSP creation option (for volume, stripe, concat, mirror)
1397*0Sstevel@tonic-gate  *
1398*0Sstevel@tonic-gate  * @param       volume
1399*0Sstevel@tonic-gate  *              a devconfig_t representing the volume to modify
1400*0Sstevel@tonic-gate  *
1401*0Sstevel@tonic-gate  * @param       usehsp
1402*0Sstevel@tonic-gate  *              the value to set as the HSP creation option
1403*0Sstevel@tonic-gate  *
1404*0Sstevel@tonic-gate  * @return      0
1405*0Sstevel@tonic-gate  *              if successful
1406*0Sstevel@tonic-gate  *
1407*0Sstevel@tonic-gate  * @return      non-zero
1408*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1409*0Sstevel@tonic-gate  *              retrieve the associated error message.
1410*0Sstevel@tonic-gate  */
1411*0Sstevel@tonic-gate int
devconfig_set_volume_usehsp(devconfig_t * volume,boolean_t usehsp)1412*0Sstevel@tonic-gate devconfig_set_volume_usehsp(
1413*0Sstevel@tonic-gate 	devconfig_t *volume,
1414*0Sstevel@tonic-gate 	boolean_t usehsp)
1415*0Sstevel@tonic-gate {
1416*0Sstevel@tonic-gate 	return (set_boolean(volume->attributes, ATTR_VOLUME_USEHSP, usehsp));
1417*0Sstevel@tonic-gate }
1418*0Sstevel@tonic-gate 
1419*0Sstevel@tonic-gate /*
1420*0Sstevel@tonic-gate  * Get HSP creation option (for volume, stripe, concat, mirror)
1421*0Sstevel@tonic-gate  *
1422*0Sstevel@tonic-gate  * @param       device
1423*0Sstevel@tonic-gate  *              a devconfig_t representing the device to examine
1424*0Sstevel@tonic-gate  *
1425*0Sstevel@tonic-gate  * @param       usehsp
1426*0Sstevel@tonic-gate  *              RETURN: HSP creation option (for volume, stripe,
1427*0Sstevel@tonic-gate  *              concat, mirror)
1428*0Sstevel@tonic-gate  *
1429*0Sstevel@tonic-gate  * @return      0
1430*0Sstevel@tonic-gate  *              if successful
1431*0Sstevel@tonic-gate  *
1432*0Sstevel@tonic-gate  * @return      non-zero
1433*0Sstevel@tonic-gate  *              if an error occurred.  Use get_error_string() to
1434*0Sstevel@tonic-gate  *              retrieve the associated error message.
1435*0Sstevel@tonic-gate  */
1436*0Sstevel@tonic-gate int
devconfig_get_volume_usehsp(devconfig_t * volume,boolean_t * usehsp)1437*0Sstevel@tonic-gate devconfig_get_volume_usehsp(
1438*0Sstevel@tonic-gate 	devconfig_t *volume,
1439*0Sstevel@tonic-gate 	boolean_t *usehsp)
1440*0Sstevel@tonic-gate {
1441*0Sstevel@tonic-gate 	int error = get_boolean(
1442*0Sstevel@tonic-gate 	    volume->attributes, ATTR_VOLUME_USEHSP, usehsp);
1443*0Sstevel@tonic-gate 
1444*0Sstevel@tonic-gate 	/* Convert ENOENT to ERR_ATTR_UNSET for a custom error message */
1445*0Sstevel@tonic-gate 	if (error == ENOENT) {
1446*0Sstevel@tonic-gate 	    volume_set_error(gettext("volume usehsp not set"));
1447*0Sstevel@tonic-gate 	    error = ERR_ATTR_UNSET;
1448*0Sstevel@tonic-gate 	}
1449*0Sstevel@tonic-gate 
1450*0Sstevel@tonic-gate 	return (error);
1451*0Sstevel@tonic-gate }
1452*0Sstevel@tonic-gate 
1453*0Sstevel@tonic-gate /*
1454*0Sstevel@tonic-gate  * Get the string representation of the volume's type
1455*0Sstevel@tonic-gate  *
1456*0Sstevel@tonic-gate  * @param       type
1457*0Sstevel@tonic-gate  *              a valid component_type_t
1458*0Sstevel@tonic-gate  *
1459*0Sstevel@tonic-gate  * @return      an internationalized string representing the given
1460*0Sstevel@tonic-gate  *              type
1461*0Sstevel@tonic-gate  */
1462*0Sstevel@tonic-gate char *
devconfig_type_to_str(component_type_t type)1463*0Sstevel@tonic-gate devconfig_type_to_str(
1464*0Sstevel@tonic-gate 	component_type_t type)
1465*0Sstevel@tonic-gate {
1466*0Sstevel@tonic-gate 	char *str;
1467*0Sstevel@tonic-gate 
1468*0Sstevel@tonic-gate 	switch (type) {
1469*0Sstevel@tonic-gate 	    case TYPE_CONCAT:	    str = gettext("Concat");	    break;
1470*0Sstevel@tonic-gate 	    case TYPE_CONTROLLER:   str = gettext("Controller");    break;
1471*0Sstevel@tonic-gate 	    case TYPE_DISKSET:	    str = gettext("Diskset");	    break;
1472*0Sstevel@tonic-gate 	    case TYPE_DRIVE:	    str = gettext("Disk");	    break;
1473*0Sstevel@tonic-gate 	    case TYPE_EXTENT:	    str = gettext("Extent");	    break;
1474*0Sstevel@tonic-gate 	    case TYPE_HOST:	    str = gettext("Host");	    break;
1475*0Sstevel@tonic-gate 	    case TYPE_HSP:	    str = gettext("Hot Spare Pool"); break;
1476*0Sstevel@tonic-gate 	    case TYPE_MIRROR:	    str = gettext("Mirror");	    break;
1477*0Sstevel@tonic-gate 	    case TYPE_RAID5:	    str = gettext("Raid5");	    break;
1478*0Sstevel@tonic-gate 	    case TYPE_SLICE:	    str = gettext("Slice");	    break;
1479*0Sstevel@tonic-gate 	    case TYPE_SOFTPART:	    str = gettext("Soft Partition"); break;
1480*0Sstevel@tonic-gate 	    case TYPE_STRIPE:	    str = gettext("Stripe");	    break;
1481*0Sstevel@tonic-gate 	    case TYPE_TRANS:	    str = gettext("Trans");	    break;
1482*0Sstevel@tonic-gate 	    case TYPE_VOLUME:	    str = gettext("Volume");	    break;
1483*0Sstevel@tonic-gate 	    default:
1484*0Sstevel@tonic-gate 	    case TYPE_UNKNOWN:	    str = gettext("Unknown");	    break;
1485*0Sstevel@tonic-gate 	}
1486*0Sstevel@tonic-gate 
1487*0Sstevel@tonic-gate 	return (str);
1488*0Sstevel@tonic-gate }
1489*0Sstevel@tonic-gate 
1490*0Sstevel@tonic-gate /*
1491*0Sstevel@tonic-gate  * Get the string representation of the mirror's read strategy
1492*0Sstevel@tonic-gate  *
1493*0Sstevel@tonic-gate  * @param       read
1494*0Sstevel@tonic-gate  *              a valid mirror_read_strategy_t
1495*0Sstevel@tonic-gate  *
1496*0Sstevel@tonic-gate  * @return      an internationalized string representing the given
1497*0Sstevel@tonic-gate  *              read strategy
1498*0Sstevel@tonic-gate  */
1499*0Sstevel@tonic-gate char *
devconfig_read_strategy_to_str(mirror_read_strategy_t read)1500*0Sstevel@tonic-gate devconfig_read_strategy_to_str(
1501*0Sstevel@tonic-gate 	mirror_read_strategy_t read)
1502*0Sstevel@tonic-gate {
1503*0Sstevel@tonic-gate 	char *str;
1504*0Sstevel@tonic-gate 
1505*0Sstevel@tonic-gate 	switch (read) {
1506*0Sstevel@tonic-gate 	    case MIRROR_READ_ROUNDROBIN: str = gettext("ROUNDROBIN");	break;
1507*0Sstevel@tonic-gate 	    case MIRROR_READ_GEOMETRIC:	 str = gettext("GEOMETRIC");	break;
1508*0Sstevel@tonic-gate 	    case MIRROR_READ_FIRST:	 str = gettext("FIRST");	break;
1509*0Sstevel@tonic-gate 	    default:			 str = "";
1510*0Sstevel@tonic-gate 	}
1511*0Sstevel@tonic-gate 
1512*0Sstevel@tonic-gate 	return (str);
1513*0Sstevel@tonic-gate }
1514*0Sstevel@tonic-gate 
1515*0Sstevel@tonic-gate /*
1516*0Sstevel@tonic-gate  * Get the string representation of the mirror's write strategy
1517*0Sstevel@tonic-gate  *
1518*0Sstevel@tonic-gate  * @param       write
1519*0Sstevel@tonic-gate  *              a valid mirror_write_strategy_t
1520*0Sstevel@tonic-gate  *
1521*0Sstevel@tonic-gate  * @return      an internationalized string representing the given
1522*0Sstevel@tonic-gate  *              write strategy
1523*0Sstevel@tonic-gate  */
1524*0Sstevel@tonic-gate char *
devconfig_write_strategy_to_str(mirror_write_strategy_t write)1525*0Sstevel@tonic-gate devconfig_write_strategy_to_str(
1526*0Sstevel@tonic-gate 	mirror_write_strategy_t write)
1527*0Sstevel@tonic-gate {
1528*0Sstevel@tonic-gate 	char *str;
1529*0Sstevel@tonic-gate 
1530*0Sstevel@tonic-gate 	switch (write) {
1531*0Sstevel@tonic-gate 	    case MIRROR_WRITE_PARALLEL:	str = gettext("PARALLEL");	break;
1532*0Sstevel@tonic-gate 	    case MIRROR_WRITE_SERIAL:	str = gettext("SERIAL");	break;
1533*0Sstevel@tonic-gate 	    default:			str = "";
1534*0Sstevel@tonic-gate 	}
1535*0Sstevel@tonic-gate 
1536*0Sstevel@tonic-gate 	return (str);
1537*0Sstevel@tonic-gate }
1538*0Sstevel@tonic-gate 
1539*0Sstevel@tonic-gate #ifdef DEBUG
1540*0Sstevel@tonic-gate /*
1541*0Sstevel@tonic-gate  * Dump the contents of a devconfig_t struct to stdout.
1542*0Sstevel@tonic-gate  *
1543*0Sstevel@tonic-gate  * @param       device
1544*0Sstevel@tonic-gate  *              the devconfig_t to examine
1545*0Sstevel@tonic-gate  *
1546*0Sstevel@tonic-gate  * @param       prefix
1547*0Sstevel@tonic-gate  *              a prefix string to print before each line
1548*0Sstevel@tonic-gate  */
1549*0Sstevel@tonic-gate void
devconfig_dump(devconfig_t * device,char * prefix)1550*0Sstevel@tonic-gate devconfig_dump(
1551*0Sstevel@tonic-gate 	devconfig_t *device,
1552*0Sstevel@tonic-gate 	char *prefix)
1553*0Sstevel@tonic-gate {
1554*0Sstevel@tonic-gate 	dlist_t *comps = NULL;
1555*0Sstevel@tonic-gate 	char **array = NULL;
1556*0Sstevel@tonic-gate 	char *str = NULL;
1557*0Sstevel@tonic-gate 	int i = 0;
1558*0Sstevel@tonic-gate 
1559*0Sstevel@tonic-gate 	component_type_t type = TYPE_UNKNOWN;
1560*0Sstevel@tonic-gate 	boolean_t bool = B_FALSE;
1561*0Sstevel@tonic-gate 	uint16_t val16 = 0;
1562*0Sstevel@tonic-gate 	uint64_t val64 = 0;
1563*0Sstevel@tonic-gate 	mirror_read_strategy_t read;
1564*0Sstevel@tonic-gate 	mirror_write_strategy_t write;
1565*0Sstevel@tonic-gate 
1566*0Sstevel@tonic-gate 	if (device == NULL) {
1567*0Sstevel@tonic-gate 	    return;
1568*0Sstevel@tonic-gate 	}
1569*0Sstevel@tonic-gate 
1570*0Sstevel@tonic-gate 	/* Type */
1571*0Sstevel@tonic-gate 	if (devconfig_get_type(device, &type) == 0) {
1572*0Sstevel@tonic-gate 	    printf("%s%s\n", prefix, devconfig_type_to_str(type));
1573*0Sstevel@tonic-gate 	}
1574*0Sstevel@tonic-gate 
1575*0Sstevel@tonic-gate 	/* Name */
1576*0Sstevel@tonic-gate 	if (devconfig_get_name(device, &str) == 0) {
1577*0Sstevel@tonic-gate 	    printf("%s  name: %s\n", prefix, str);
1578*0Sstevel@tonic-gate 	}
1579*0Sstevel@tonic-gate 
1580*0Sstevel@tonic-gate 	/* Size in bytes */
1581*0Sstevel@tonic-gate 	if (devconfig_get_size(device, &val64) == 0) {
1582*0Sstevel@tonic-gate 	    printf("%s  size in bytes: %llu\n", prefix, val64);
1583*0Sstevel@tonic-gate 	}
1584*0Sstevel@tonic-gate 
1585*0Sstevel@tonic-gate 	/* Size in blocks */
1586*0Sstevel@tonic-gate 	if (devconfig_get_size_in_blocks(device, &val64) == 0) {
1587*0Sstevel@tonic-gate 	    printf("%s  size in blocks: %llu\n", prefix, val64);
1588*0Sstevel@tonic-gate 	}
1589*0Sstevel@tonic-gate 
1590*0Sstevel@tonic-gate 	/* Use HSP */
1591*0Sstevel@tonic-gate 	if (devconfig_get_volume_usehsp(device, &bool) == 0) {
1592*0Sstevel@tonic-gate 	    printf("%s  usehsp: %s\n", prefix, bool? "TRUE" : "FALSE");
1593*0Sstevel@tonic-gate 	}
1594*0Sstevel@tonic-gate 
1595*0Sstevel@tonic-gate 	switch (type) {
1596*0Sstevel@tonic-gate 	    case TYPE_VOLUME:
1597*0Sstevel@tonic-gate 		/* Volume rlevel */
1598*0Sstevel@tonic-gate 		if (devconfig_get_volume_redundancy_level(
1599*0Sstevel@tonic-gate 		    device, &val16) == 0) {
1600*0Sstevel@tonic-gate 		    printf("%s  volume redundancy level: %d\n", prefix, val16);
1601*0Sstevel@tonic-gate 		}
1602*0Sstevel@tonic-gate 
1603*0Sstevel@tonic-gate 		/* Volume npaths */
1604*0Sstevel@tonic-gate 		if (devconfig_get_volume_npaths(device, &val16) == 0) {
1605*0Sstevel@tonic-gate 		    printf("%s  volume npaths: %d\n", prefix, val16);
1606*0Sstevel@tonic-gate 		}
1607*0Sstevel@tonic-gate 	    break;
1608*0Sstevel@tonic-gate 
1609*0Sstevel@tonic-gate 	    case TYPE_MIRROR:
1610*0Sstevel@tonic-gate 
1611*0Sstevel@tonic-gate 		/* Mirror nsubs */
1612*0Sstevel@tonic-gate 		if (devconfig_get_mirror_nsubs(device, &val16) == 0) {
1613*0Sstevel@tonic-gate 		    printf("%s  mirror nsubs: %d\n", prefix, val16);
1614*0Sstevel@tonic-gate 		}
1615*0Sstevel@tonic-gate 
1616*0Sstevel@tonic-gate 		/* Mirror read */
1617*0Sstevel@tonic-gate 		if (devconfig_get_mirror_read(device, &read) == 0) {
1618*0Sstevel@tonic-gate 		    printf("%s  mirror read: %s\n", prefix,
1619*0Sstevel@tonic-gate 			devconfig_read_strategy_to_str(read));
1620*0Sstevel@tonic-gate 		}
1621*0Sstevel@tonic-gate 
1622*0Sstevel@tonic-gate 		/* Mirror write */
1623*0Sstevel@tonic-gate 		if (devconfig_get_mirror_write(device, &write) == 0) {
1624*0Sstevel@tonic-gate 		    printf("%s  mirror write: %s\n", prefix,
1625*0Sstevel@tonic-gate 			devconfig_write_strategy_to_str(write));
1626*0Sstevel@tonic-gate 		}
1627*0Sstevel@tonic-gate 
1628*0Sstevel@tonic-gate 		/* Mirror pass */
1629*0Sstevel@tonic-gate 		if (devconfig_get_mirror_pass(device, &val16) == 0) {
1630*0Sstevel@tonic-gate 		    printf("%s  mirror pass: %d\n", prefix, val16);
1631*0Sstevel@tonic-gate 		}
1632*0Sstevel@tonic-gate 	    break;
1633*0Sstevel@tonic-gate 
1634*0Sstevel@tonic-gate 	    case TYPE_STRIPE:
1635*0Sstevel@tonic-gate 		/* Stripe mincomp */
1636*0Sstevel@tonic-gate 		if (devconfig_get_stripe_mincomp(device, &val16) == 0) {
1637*0Sstevel@tonic-gate 		    printf("%s  stripe mincomp: %d\n", prefix, val16);
1638*0Sstevel@tonic-gate 		}
1639*0Sstevel@tonic-gate 
1640*0Sstevel@tonic-gate 		/* Stripe maxcomp */
1641*0Sstevel@tonic-gate 		if (devconfig_get_stripe_maxcomp(device, &val16) == 0) {
1642*0Sstevel@tonic-gate 		    printf("%s  stripe maxcomp: %d\n", prefix, val16);
1643*0Sstevel@tonic-gate 		}
1644*0Sstevel@tonic-gate 
1645*0Sstevel@tonic-gate 		/* Stripe interlace */
1646*0Sstevel@tonic-gate 		if (devconfig_get_stripe_interlace(device, &val64) == 0) {
1647*0Sstevel@tonic-gate 		    printf("%s  stripe interlace: %lld\n", prefix, val64);
1648*0Sstevel@tonic-gate 		}
1649*0Sstevel@tonic-gate 	    break;
1650*0Sstevel@tonic-gate 
1651*0Sstevel@tonic-gate 	    case TYPE_SLICE:
1652*0Sstevel@tonic-gate 		/* Slice index */
1653*0Sstevel@tonic-gate 		if (devconfig_get_slice_index(device, &val16) == 0) {
1654*0Sstevel@tonic-gate 		    printf("%s  slice index: %d\n", prefix, val16);
1655*0Sstevel@tonic-gate 		}
1656*0Sstevel@tonic-gate 
1657*0Sstevel@tonic-gate 		/* Slice start block */
1658*0Sstevel@tonic-gate 		if (devconfig_get_slice_start_block(device, &val64) == 0) {
1659*0Sstevel@tonic-gate 		    printf("%s  slice start block: %llu\n", prefix, val64);
1660*0Sstevel@tonic-gate 		}
1661*0Sstevel@tonic-gate 	    break;
1662*0Sstevel@tonic-gate 	}
1663*0Sstevel@tonic-gate 
1664*0Sstevel@tonic-gate 	array = devconfig_get_available(device);
1665*0Sstevel@tonic-gate 	if (array != NULL) {
1666*0Sstevel@tonic-gate 	    printf("%s  available:\n", prefix);
1667*0Sstevel@tonic-gate 	    for (i = 0; array[i] != NULL; i++) {
1668*0Sstevel@tonic-gate 		printf("%s    %s\n", prefix, array[i]);
1669*0Sstevel@tonic-gate 	    }
1670*0Sstevel@tonic-gate 	}
1671*0Sstevel@tonic-gate 
1672*0Sstevel@tonic-gate 	array = devconfig_get_unavailable(device);
1673*0Sstevel@tonic-gate 	if (array != NULL) {
1674*0Sstevel@tonic-gate 	    printf("%s  unavailable:\n", prefix);
1675*0Sstevel@tonic-gate 	    for (i = 0; array[i] != NULL; i++) {
1676*0Sstevel@tonic-gate 		printf("%s    %s\n", prefix, array[i]);
1677*0Sstevel@tonic-gate 	    }
1678*0Sstevel@tonic-gate 	}
1679*0Sstevel@tonic-gate 
1680*0Sstevel@tonic-gate 	printf("\n");
1681*0Sstevel@tonic-gate 
1682*0Sstevel@tonic-gate 	comps = devconfig_get_components(device);
1683*0Sstevel@tonic-gate 	if (comps != NULL) {
1684*0Sstevel@tonic-gate 	    char buf[128];
1685*0Sstevel@tonic-gate 	    snprintf(buf, 128, "%s%s", prefix, "    ");
1686*0Sstevel@tonic-gate 	    for (; comps != NULL; comps = comps->next) {
1687*0Sstevel@tonic-gate 		devconfig_dump((devconfig_t *)comps->obj, buf);
1688*0Sstevel@tonic-gate 	    }
1689*0Sstevel@tonic-gate 	}
1690*0Sstevel@tonic-gate }
1691*0Sstevel@tonic-gate #endif /* DEBUG */
1692