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