7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / cmd / lvm / metassist / layout / layout_dlist_util.c
blob4ced855104644fc6a6c96d29cc4c039ea4e43f54
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
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
31 #include <assert.h>
32 #include <string.h>
34 #include <libintl.h>
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
55 * 0 - if str1 == str2
56 * >0 - if str1 > str2
58 * PURPOSE: dlist_t helper which compares the two input strings.
60 * Comparison is done with string_case_compare()
62 int
63 compare_strings(
64 void *str1,
65 void *str2)
67 assert(str1 != NULL);
68 assert(str2 != NULL);
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
84 * structs.
86 * Both input objects are assumed to be devconfig_t pointers.
88 int
89 compare_devconfig_sizes(
90 void *devconf1,
91 void *devconf2)
93 uint64_t size1 = 0;
94 uint64_t size2 = 0;
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.
119 compare_slice_sizes(
120 void *desc1,
121 void *desc2)
123 uint64_t size1 = 0;
124 uint64_t size2 = 0;
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,
137 * void *desc)
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(
155 void *devconf,
156 void *desc)
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(
185 void *str,
186 void *devconf)
188 char *volname = NULL;
190 assert(str != 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) */
196 return (-1);
199 return (string_case_compare(volname, (char *)str));
203 * FUNCTION: free_devconfig_object(void *obj)
205 * INPUT: obj - an opaque pointer
207 * RETURNS: void
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
214 * undoes slicing
216 void
217 free_devconfig_object(
218 void *obj)
220 devconfig_t *dev = NULL;
221 char *name = NULL;
222 dlist_t *iter = NULL;
223 component_type_t type = TYPE_UNKNOWN;
225 if (obj == NULL) {
226 return;
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);
237 switch (type) {
238 case TYPE_MIRROR:
239 case TYPE_CONCAT:
240 case TYPE_RAID5:
241 case TYPE_HSP:
242 case TYPE_STRIPE:
244 /* release name */
245 if (devconfig_isA(dev, TYPE_HSP)) {
246 release_hsp_name(name);
247 } else {
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);
257 break;
259 case TYPE_SLICE:
261 (void) destroy_new_slice(dev);
263 break;
265 default:
266 break;
270 free_devconfig(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
291 * comparison.
293 * Uses string_case_compare() to compare the names.
296 compare_device_names(
297 void *str1,
298 void *str2)
300 char *name1 = (char *)str1;
301 char *name2 = (char *)str2;
303 int val = 0;
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) {
315 short1 = name1;
316 } else {
317 ++short1;
320 if (short2 == NULL) {
321 short2 = name2;
322 } else {
323 ++short2;
326 val = string_case_compare(short2, short1);
328 } else {
330 /* if they both start with '/', assume they're full paths */
331 val = string_case_compare(name2, name1);
334 return (val);
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.
351 compare_descriptors(
352 void *desc1,
353 void *desc2)
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(
380 void *desc1,
381 void *desc2)
383 char *name1 = NULL;
384 char *name2 = NULL;
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
403 * !0 - otherwise
405 * PURPOSE: dlist_t helper which checks whether slice1 is on the
406 * same hba as slice2
409 compare_slices_on_same_hba(
410 void *slice1,
411 void *slice2)
413 char *name1, *name2;
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) {
435 dlist_t *itr1;
437 for (itr1 = hbas1; itr1 != NULL; itr1 = itr1->next) {
438 dm_descriptor_t hba1 = (uintptr_t)itr1->obj;
439 dlist_t *itr2;
441 for (itr2 = hbas2; itr2 != NULL; itr2 = itr2->next) {
442 dm_descriptor_t hba2 = (uintptr_t)itr2->obj;
444 if (hba1 == hba2) {
445 return (0);
453 return (1);