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