4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #define _LAYOUT_DLIST_UTIL_C
35 #include <libdiskmgt.h>
37 #include "volume_devconfig.h"
38 #include "volume_dlist.h"
39 #include "volume_output.h"
41 #include "layout_device_cache.h"
42 #include "layout_dlist_util.h"
43 #include "layout_request.h"
45 #include "layout_slice.h" /* destroy_new_slice */
46 #include "layout_svm_util.h"
49 * FUNCTION: compare_strings(void *str1, void *str2)
51 * INPUT: str1 - opaque pointer to a char *
52 * str2 - opaque pointer to a char *
54 * RETURNS: int - <0 - if str1 < str2
58 * PURPOSE: dlist_t helper which compares the two input strings.
60 * Comparison is done with string_case_compare()
70 return (string_case_compare((char *)str1
, (char *)str2
));
74 * FUNCTION: compare_devconfig_sizes(void *devconf1, void *devconf2)
76 * INPUT: devconf1 - opaque pointer
77 * devconf2 - opaque pointer
79 * RETURNS: int - <0 - if devconf1.size_in_blks < devconf2.size_in_blks
80 * 0 - if devconf1.size_in_blks == devconf2.size_in_blks
81 * >0 - if devconf1.size.in_blks > devconf2.size_in_blks
83 * PURPOSE: dlist_t helper which compares the sizes of two devconfig_t
86 * Both input objects are assumed to be devconfig_t pointers.
89 compare_devconfig_sizes(
96 assert(devconf1
!= NULL
);
97 assert(devconf2
!= NULL
);
99 (void) devconfig_get_size_in_blocks((devconfig_t
*)devconf1
, &size1
);
100 (void) devconfig_get_size_in_blocks((devconfig_t
*)devconf2
, &size2
);
102 return (size1
- size2
);
106 * FUNCTION: compare_slice_sizes(void *desc1, void *desc2)
108 * INPUT: desc1 - opaque pointer to a dm_descriptor_t slice handle
109 * desc2 - opaque pointer to a dm_descriptor_t slice handle
111 * RETURNS: int - <0 - if desc1.slicesize < desc2.slicesize
112 * 0 - if desc1.slicesize == desc2.slicesize
113 * >0 - if desc1.slicesize > desc2.slicesize
115 * PURPOSE: dlist_t helper which compares the sizes of two slices
116 * represented as dm_descriptor_t handles.
126 assert(desc1
!= NULL
);
127 assert(desc2
!= NULL
);
129 (void) slice_get_size((uintptr_t)desc1
, &size1
);
130 (void) slice_get_size((uintptr_t)desc2
, &size2
);
132 return (size1
- size2
);
136 * FUNCTION: compare_devconfig_and_descriptor_names(void *devconf,
139 * INPUT: devconf - opaque pointer to a devconfig_t
140 * desc - opaque pointer to a dm_descriptor_t
142 * RETURNS: int - <0 - if devconf name is "less than" descr name
143 * 0 - if devconf name is "equal to" descr name
144 * >0 - if devconf name is "greater than" desc name
146 * PURPOSE: dlist_t helper which compares the name of a devconfig_t
147 * struct to the name for a dm_descriptor_t.
149 * Note that the order of the arguments is important.
150 * This function is intended to be passed into the various
151 * dlist_* functions which take a comparison function.
154 compare_devconfig_and_descriptor_names(
158 char *volname
= NULL
;
159 char *descname
= NULL
;
161 assert(devconf
!= NULL
);
162 assert(desc
!= NULL
);
164 (void) devconfig_get_name((devconfig_t
*)devconf
, &volname
);
165 (void) get_display_name((uintptr_t)desc
, &descname
);
167 return (string_case_compare(volname
, descname
));
171 * FUNCTION: compare_string_to_devconfig_name(void *str, void *devconf)
173 * INPUT: str - opaque pointer to a char *str
174 * devconf - opaque pointer to a devconfig_t
176 * RETURNS: int - <0 - if devconf name is "less than" str
177 * 0 - if devconf name is "equal to" str
178 * >0 - if devconf name is "greater than" str
180 * PURPOSE: dlist_t helper which compares a string to the name of
181 * a devconfig_t struct.
184 compare_string_to_devconfig_name(
188 char *volname
= NULL
;
191 assert(devconf
!= NULL
);
193 (void) devconfig_get_name((devconfig_t
*)devconf
, &volname
);
194 if (volname
== NULL
) {
195 /* no memory for new string(s) */
199 return (string_case_compare(volname
, (char *)str
));
203 * FUNCTION: free_devconfig_object(void *obj)
205 * INPUT: obj - an opaque pointer
209 * PURPOSE: helper which decomposes a devconfig_t struct after a
210 * failed layout attempt.
212 * reclaims allocated space.
213 * releases reserved volume/HSP names
217 free_devconfig_object(
220 devconfig_t
*dev
= NULL
;
222 dlist_t
*iter
= NULL
;
223 component_type_t type
= TYPE_UNKNOWN
;
229 dev
= (devconfig_t
*)obj
;
231 (void) devconfig_get_type(dev
, &type
);
232 (void) devconfig_get_name(dev
, &name
);
234 oprintf(OUTPUT_DEBUG
,
235 gettext(" -->decomposing %s\n"), name
);
245 if (devconfig_isA(dev
, TYPE_HSP
)) {
246 release_hsp_name(name
);
248 release_volume_name(name
);
251 /* decompose volume's components */
252 iter
= devconfig_get_components(dev
);
253 dlist_free_items(iter
, free_devconfig_object
);
255 (void) devconfig_set_components(dev
, NULL
);
261 (void) destroy_new_slice(dev
);
274 * FUNCTION: compare_device_names(
275 * void *str1, void *str2)
277 * INPUT: str1 - opaque pointer
278 * str2 - opaque pointer
280 * RETURNS: int - <0 - if str1 < str2
281 * 0 - if str1 == str2
282 * >0 - if str1 > str2
284 * PURPOSE: dlist_t helper which compares two device name strings.
286 * Both names are assumed to be in CTD form.
288 * Either name may be fully qualified by an absolute
289 * path. If only one name is fully qualified, the
290 * leading path with be stripped off prior to the
293 * Uses string_case_compare() to compare the names.
296 compare_device_names(
300 char *name1
= (char *)str1
;
301 char *name2
= (char *)str2
;
305 assert(str1
!= NULL
);
306 assert(str2
!= NULL
);
308 /* if one doesn't start with '/', just compare device names */
309 if (*name1
!= '/' || *name2
!= '/') {
311 char *short1
= strrchr(name1
, '/');
312 char *short2
= strrchr(name2
, '/');
314 if (short1
== NULL
) {
320 if (short2
== NULL
) {
326 val
= string_case_compare(short2
, short1
);
330 /* if they both start with '/', assume they're full paths */
331 val
= string_case_compare(name2
, name1
);
338 * FUNCTION: compare_descriptors(
339 * void *desc1, void *desc2)
341 * INPUT: desc1 - opaque pointer
342 * desc2 - opaque pointer
344 * RETURNS: int - <0 - if desc1 < desc2
345 * 0 - if desc1 == desc2
346 * >0 - if desc1 > desc2
348 * PURPOSE: dlist_t helper which compares two dm_descriptor_t handles.
355 assert(desc1
!= NULL
);
356 assert(desc2
!= NULL
);
358 return ((uintptr_t)desc1
- (uintptr_t)desc2
);
362 * FUNCTION: compare_descriptor_names(
363 * void *desc1, void *desc2)
365 * INPUT: desc1 - opaque pointer
366 * desc2 - opaque pointer
368 * RETURNS: int - <0 - if desc1.name < desc2.name
369 * 0 - if desc1.name == desc2.name
370 * >0 - if desc1.name > desc2.name
372 * PURPOSE: dlist_t helper which compares the names associated
373 * with the input dm_descriptor_t handles.
375 * Retrieves the names associated with both descriptors
376 * and compares them using string_case_compare.
379 compare_descriptor_names(
386 assert(desc1
!= NULL
);
387 assert(desc2
!= NULL
);
389 (void) get_name((uintptr_t)desc1
, &name1
);
390 (void) get_name((uintptr_t)desc2
, &name2
);
392 return (string_case_compare(name1
, name2
));
396 * FUNCTION: compare_slices_on_same_hba(
397 * void *slice1, void *slice2)
399 * INPUT: slice1 - opaque pointer
400 * slice2 - opaque pointer
402 * RETURNS: int - 0 - if slice1 is on the same hba as slice2
405 * PURPOSE: dlist_t helper which checks whether slice1 is on the
409 compare_slices_on_same_hba(
415 /* Retrieve the names of the slices */
416 if (devconfig_get_name((devconfig_t
*)slice1
, &name1
) == 0 &&
417 devconfig_get_name((devconfig_t
*)slice2
, &name2
) == 0) {
419 dm_descriptor_t desc1
, desc2
;
421 /* Retrieve the disk descriptors for the slices */
422 if (get_disk_for_named_slice(name1
, &desc1
) == 0 &&
423 get_disk_for_named_slice(name2
, &desc2
) == 0) {
425 dlist_t
*hbas1
= NULL
;
426 dlist_t
*hbas2
= NULL
;
428 assert(desc1
!= (dm_descriptor_t
)0);
429 assert(desc2
!= (dm_descriptor_t
)0);
431 /* Retrieve list of HBA descriptors for the slices */
432 if (disk_get_hbas(desc1
, &hbas1
) == 0 &&
433 disk_get_hbas(desc2
, &hbas2
) == 0) {
437 for (itr1
= hbas1
; itr1
!= NULL
; itr1
= itr1
->next
) {
438 dm_descriptor_t hba1
= (uintptr_t)itr1
->obj
;
441 for (itr2
= hbas2
; itr2
!= NULL
; itr2
= itr2
->next
) {
442 dm_descriptor_t hba2
= (uintptr_t)itr2
->obj
;