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