17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
599653d4eSeschrock * Common Development and Distribution License (the "License").
699653d4eSeschrock * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22efd79defSsriman bhavanam - Sun Microsystems - Bangalore India * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <fcntl.h>
277c478bd9Sstevel@tonic-gate #include <libdevinfo.h>
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <unistd.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
343e1bd7a2Ssjelinek #include <libintl.h>
353e1bd7a2Ssjelinek #include <locale.h>
363e1bd7a2Ssjelinek #include <sys/debug.h>
37181c2f42Smmusante #include <strings.h>
38181c2f42Smmusante #include <sys/stat.h>
39181c2f42Smmusante #include <sys/swap.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #include "libdiskmgt.h"
427c478bd9Sstevel@tonic-gate #include "disks_private.h"
437c478bd9Sstevel@tonic-gate #include "partition.h"
447c478bd9Sstevel@tonic-gate
45181c2f42Smmusante #define ANY_ZPOOL_USE(who) \
46181c2f42Smmusante (((who) == DM_WHO_ZPOOL_FORCE) || \
47181c2f42Smmusante ((who) == DM_WHO_ZPOOL) || \
48181c2f42Smmusante ((who) == DM_WHO_ZPOOL_SPARE))
493e1bd7a2Ssjelinek
50181c2f42Smmusante extern char *getfullblkname();
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate extern dm_desc_type_t drive_assoc_types[];
537c478bd9Sstevel@tonic-gate extern dm_desc_type_t bus_assoc_types[];
547c478bd9Sstevel@tonic-gate extern dm_desc_type_t controller_assoc_types[];
557c478bd9Sstevel@tonic-gate extern dm_desc_type_t media_assoc_types[];
567c478bd9Sstevel@tonic-gate extern dm_desc_type_t slice_assoc_types[];
577c478bd9Sstevel@tonic-gate extern dm_desc_type_t partition_assoc_types[];
587c478bd9Sstevel@tonic-gate extern dm_desc_type_t path_assoc_types[];
597c478bd9Sstevel@tonic-gate extern dm_desc_type_t alias_assoc_types[];
607c478bd9Sstevel@tonic-gate
613e1bd7a2Ssjelinek
627c478bd9Sstevel@tonic-gate static dm_descriptor_t *ptr_array_to_desc_array(descriptor_t **ptrs, int *errp);
637c478bd9Sstevel@tonic-gate static descriptor_t **desc_array_to_ptr_array(dm_descriptor_t *da, int *errp);
643e1bd7a2Ssjelinek static int build_usage_string(char *dname, char *by, char *data, char **use,
653e1bd7a2Ssjelinek int *found, int *errp);
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate void
dm_free_descriptor(dm_descriptor_t desc)687c478bd9Sstevel@tonic-gate dm_free_descriptor(dm_descriptor_t desc)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate descriptor_t *dp;
717c478bd9Sstevel@tonic-gate
72bd401f05SToomas Soome if (desc == 0) {
73efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return;
747c478bd9Sstevel@tonic-gate }
7569fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc;
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate cache_wlock();
787c478bd9Sstevel@tonic-gate cache_free_descriptor(dp);
797c478bd9Sstevel@tonic-gate cache_unlock();
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate void
dm_free_descriptors(dm_descriptor_t * desc_list)837c478bd9Sstevel@tonic-gate dm_free_descriptors(dm_descriptor_t *desc_list)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate descriptor_t **dp;
867c478bd9Sstevel@tonic-gate int error;
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate if (desc_list == NULL) {
89efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return;
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate dp = desc_array_to_ptr_array(desc_list, &error);
927c478bd9Sstevel@tonic-gate if (error != 0) {
93efd79defSsriman bhavanam - Sun Microsystems - Bangalore India free(desc_list);
94efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return;
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate cache_wlock();
987c478bd9Sstevel@tonic-gate cache_free_descriptors(dp);
997c478bd9Sstevel@tonic-gate cache_unlock();
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1037c478bd9Sstevel@tonic-gate void
dm_free_name(char * name)1047c478bd9Sstevel@tonic-gate dm_free_name(char *name)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate free(name);
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate dm_descriptor_t *
dm_get_associated_descriptors(dm_descriptor_t desc,dm_desc_type_t type,int * errp)1107c478bd9Sstevel@tonic-gate dm_get_associated_descriptors(dm_descriptor_t desc, dm_desc_type_t type,
1117c478bd9Sstevel@tonic-gate int *errp)
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate descriptor_t **descs = NULL;
1147c478bd9Sstevel@tonic-gate descriptor_t *dp;
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate
11769fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc;
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate cache_wlock();
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) {
122efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
123efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EBADF;
124efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */
1287c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) {
129efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
130efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENODEV;
131efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate switch (dp->type) {
1357c478bd9Sstevel@tonic-gate case DM_DRIVE:
136efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = drive_get_assoc_descriptors(dp, type, errp);
137efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1387c478bd9Sstevel@tonic-gate case DM_BUS:
139efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = bus_get_assoc_descriptors(dp, type, errp);
140efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1417c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
142efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = controller_get_assoc_descriptors(dp, type, errp);
143efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1447c478bd9Sstevel@tonic-gate case DM_MEDIA:
145efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = media_get_assoc_descriptors(dp, type, errp);
146efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1477c478bd9Sstevel@tonic-gate case DM_SLICE:
148efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = slice_get_assoc_descriptors(dp, type, errp);
149efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1507c478bd9Sstevel@tonic-gate case DM_PARTITION:
151efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = partition_get_assoc_descriptors(dp, type, errp);
152efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1537c478bd9Sstevel@tonic-gate case DM_PATH:
154efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = path_get_assoc_descriptors(dp, type, errp);
155efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1567c478bd9Sstevel@tonic-gate case DM_ALIAS:
157efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = alias_get_assoc_descriptors(dp, type, errp);
158efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1597c478bd9Sstevel@tonic-gate default:
160efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EINVAL;
161efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate cache_unlock();
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate return (ptr_array_to_desc_array(descs, errp));
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate dm_desc_type_t *
dm_get_associated_types(dm_desc_type_t type)1707c478bd9Sstevel@tonic-gate dm_get_associated_types(dm_desc_type_t type)
1717c478bd9Sstevel@tonic-gate {
1727c478bd9Sstevel@tonic-gate switch (type) {
1737c478bd9Sstevel@tonic-gate case DM_DRIVE:
174efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (drive_assoc_types);
1757c478bd9Sstevel@tonic-gate case DM_BUS:
176efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (bus_assoc_types);
1777c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
178efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (controller_assoc_types);
1797c478bd9Sstevel@tonic-gate case DM_MEDIA:
180efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (media_assoc_types);
1817c478bd9Sstevel@tonic-gate case DM_SLICE:
182efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (slice_assoc_types);
1837c478bd9Sstevel@tonic-gate case DM_PARTITION:
184efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (partition_assoc_types);
1857c478bd9Sstevel@tonic-gate case DM_PATH:
186efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (path_assoc_types);
1877c478bd9Sstevel@tonic-gate case DM_ALIAS:
188efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (alias_assoc_types);
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate return (NULL);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate nvlist_t *
dm_get_attributes(dm_descriptor_t desc,int * errp)1957c478bd9Sstevel@tonic-gate dm_get_attributes(dm_descriptor_t desc, int *errp)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate descriptor_t *dp;
1987c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL;
1997c478bd9Sstevel@tonic-gate
2007c478bd9Sstevel@tonic-gate
20169fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc;
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate cache_rlock();
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) {
206efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
207efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EBADF;
208efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */
2127c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) {
213efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
214efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENODEV;
215efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate switch (dp->type) {
2197c478bd9Sstevel@tonic-gate case DM_DRIVE:
220efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = drive_get_attributes(dp, errp);
221efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2227c478bd9Sstevel@tonic-gate case DM_BUS:
223efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = bus_get_attributes(dp, errp);
224efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2257c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
226efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = controller_get_attributes(dp, errp);
227efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2287c478bd9Sstevel@tonic-gate case DM_MEDIA:
229efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = media_get_attributes(dp, errp);
230efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2317c478bd9Sstevel@tonic-gate case DM_SLICE:
232efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = slice_get_attributes(dp, errp);
233efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2347c478bd9Sstevel@tonic-gate case DM_PARTITION:
235efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = partition_get_attributes(dp, errp);
236efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2377c478bd9Sstevel@tonic-gate case DM_PATH:
238efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = path_get_attributes(dp, errp);
239efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2407c478bd9Sstevel@tonic-gate case DM_ALIAS:
241efd79defSsriman bhavanam - Sun Microsystems - Bangalore India attrs = alias_get_attributes(dp, errp);
242efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2437c478bd9Sstevel@tonic-gate default:
244efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EINVAL;
245efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate cache_unlock();
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate return (attrs);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate dm_descriptor_t
dm_get_descriptor_by_name(dm_desc_type_t desc_type,char * name,int * errp)2547c478bd9Sstevel@tonic-gate dm_get_descriptor_by_name(dm_desc_type_t desc_type, char *name, int *errp)
2557c478bd9Sstevel@tonic-gate {
256bd401f05SToomas Soome dm_descriptor_t desc = 0;
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate cache_wlock();
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate switch (desc_type) {
2627c478bd9Sstevel@tonic-gate case DM_DRIVE:
263efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)drive_get_descriptor_by_name(name, errp);
264efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2657c478bd9Sstevel@tonic-gate case DM_BUS:
266efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)bus_get_descriptor_by_name(name, errp);
267efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2687c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
269efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)controller_get_descriptor_by_name(name,
270efd79defSsriman bhavanam - Sun Microsystems - Bangalore India errp);
271efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2727c478bd9Sstevel@tonic-gate case DM_MEDIA:
273efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)media_get_descriptor_by_name(name, errp);
274efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2757c478bd9Sstevel@tonic-gate case DM_SLICE:
276efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)slice_get_descriptor_by_name(name, errp);
277efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2787c478bd9Sstevel@tonic-gate case DM_PARTITION:
279efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)partition_get_descriptor_by_name(name,
280efd79defSsriman bhavanam - Sun Microsystems - Bangalore India errp);
281efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2827c478bd9Sstevel@tonic-gate case DM_PATH:
283efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)path_get_descriptor_by_name(name, errp);
284efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2857c478bd9Sstevel@tonic-gate case DM_ALIAS:
286efd79defSsriman bhavanam - Sun Microsystems - Bangalore India desc = (uintptr_t)alias_get_descriptor_by_name(name, errp);
287efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2887c478bd9Sstevel@tonic-gate default:
289efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EINVAL;
290efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate cache_unlock();
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate return (desc);
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate dm_descriptor_t *
dm_get_descriptors(dm_desc_type_t type,int filter[],int * errp)2997c478bd9Sstevel@tonic-gate dm_get_descriptors(dm_desc_type_t type, int filter[], int *errp)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate descriptor_t **descs = NULL;
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate cache_wlock();
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate switch (type) {
3077c478bd9Sstevel@tonic-gate case DM_DRIVE:
308efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = drive_get_descriptors(filter, errp);
309efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3107c478bd9Sstevel@tonic-gate case DM_BUS:
311efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = bus_get_descriptors(filter, errp);
312efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3137c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
314efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = controller_get_descriptors(filter, errp);
315efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3167c478bd9Sstevel@tonic-gate case DM_MEDIA:
317efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = media_get_descriptors(filter, errp);
318efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3197c478bd9Sstevel@tonic-gate case DM_SLICE:
320efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = slice_get_descriptors(filter, errp);
321efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3227c478bd9Sstevel@tonic-gate case DM_PARTITION:
323efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = partition_get_descriptors(filter, errp);
324efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3257c478bd9Sstevel@tonic-gate case DM_PATH:
326efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = path_get_descriptors(filter, errp);
327efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3287c478bd9Sstevel@tonic-gate case DM_ALIAS:
329efd79defSsriman bhavanam - Sun Microsystems - Bangalore India descs = alias_get_descriptors(filter, errp);
330efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3317c478bd9Sstevel@tonic-gate default:
332efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EINVAL;
333efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate cache_unlock();
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate return (ptr_array_to_desc_array(descs, errp));
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate char *
dm_get_name(dm_descriptor_t desc,int * errp)3427c478bd9Sstevel@tonic-gate dm_get_name(dm_descriptor_t desc, int *errp)
3437c478bd9Sstevel@tonic-gate {
3447c478bd9Sstevel@tonic-gate descriptor_t *dp;
3457c478bd9Sstevel@tonic-gate char *nm = NULL;
3467c478bd9Sstevel@tonic-gate char *name = NULL;
3477c478bd9Sstevel@tonic-gate
34869fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc;
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate cache_rlock();
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) {
353efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
354efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = EBADF;
355efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */
3597c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) {
360efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
361efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENODEV;
362efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate
3657c478bd9Sstevel@tonic-gate switch (dp->type) {
3667c478bd9Sstevel@tonic-gate case DM_DRIVE:
367efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (drive_get_name(dp));
368efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3697c478bd9Sstevel@tonic-gate case DM_BUS:
370efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (bus_get_name(dp));
371efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3727c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
373efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (controller_get_name(dp));
374efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3757c478bd9Sstevel@tonic-gate case DM_MEDIA:
376efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (media_get_name(dp));
377efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3787c478bd9Sstevel@tonic-gate case DM_SLICE:
379efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (slice_get_name(dp));
380efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3817c478bd9Sstevel@tonic-gate case DM_PARTITION:
382efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (partition_get_name(dp));
383efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3847c478bd9Sstevel@tonic-gate case DM_PATH:
385efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (path_get_name(dp));
386efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3877c478bd9Sstevel@tonic-gate case DM_ALIAS:
388efd79defSsriman bhavanam - Sun Microsystems - Bangalore India nm = (alias_get_name(dp));
389efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
3907c478bd9Sstevel@tonic-gate }
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate cache_unlock();
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate *errp = 0;
3957c478bd9Sstevel@tonic-gate if (nm != NULL) {
396efd79defSsriman bhavanam - Sun Microsystems - Bangalore India name = strdup(nm);
397efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (name == NULL) {
398efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM;
399efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
400efd79defSsriman bhavanam - Sun Microsystems - Bangalore India }
401efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (name);
4027c478bd9Sstevel@tonic-gate }
4037c478bd9Sstevel@tonic-gate return (NULL);
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate nvlist_t *
dm_get_stats(dm_descriptor_t desc,int stat_type,int * errp)4077c478bd9Sstevel@tonic-gate dm_get_stats(dm_descriptor_t desc, int stat_type, int *errp)
4087c478bd9Sstevel@tonic-gate {
4097c478bd9Sstevel@tonic-gate descriptor_t *dp;
4107c478bd9Sstevel@tonic-gate nvlist_t *stats = NULL;
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate
41369fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc;
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate cache_rlock();
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) {
4183e1bd7a2Ssjelinek cache_unlock();
4193e1bd7a2Ssjelinek *errp = EBADF;
4203e1bd7a2Ssjelinek return (NULL);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */
4247c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) {
4253e1bd7a2Ssjelinek cache_unlock();
4263e1bd7a2Ssjelinek *errp = ENODEV;
4273e1bd7a2Ssjelinek return (NULL);
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate
4307c478bd9Sstevel@tonic-gate switch (dp->type) {
4317c478bd9Sstevel@tonic-gate case DM_DRIVE:
4323e1bd7a2Ssjelinek stats = drive_get_stats(dp, stat_type, errp);
4333e1bd7a2Ssjelinek break;
4347c478bd9Sstevel@tonic-gate case DM_BUS:
4353e1bd7a2Ssjelinek stats = bus_get_stats(dp, stat_type, errp);
4363e1bd7a2Ssjelinek break;
4377c478bd9Sstevel@tonic-gate case DM_CONTROLLER:
4383e1bd7a2Ssjelinek stats = controller_get_stats(dp, stat_type, errp);
4393e1bd7a2Ssjelinek break;
4407c478bd9Sstevel@tonic-gate case DM_MEDIA:
4413e1bd7a2Ssjelinek stats = media_get_stats(dp, stat_type, errp);
4423e1bd7a2Ssjelinek break;
4437c478bd9Sstevel@tonic-gate case DM_SLICE:
4443e1bd7a2Ssjelinek if (stat_type == DM_SLICE_STAT_USE) {
4453e1bd7a2Ssjelinek /*
4463e1bd7a2Ssjelinek * If NOINUSE_CHECK is set, we do not perform
4473e1bd7a2Ssjelinek * the in use checking if the user has set stat_type
4483e1bd7a2Ssjelinek * DM_SLICE_STAT_USE
4493e1bd7a2Ssjelinek */
45082d71480Ssjelinek if (NOINUSE_SET) {
4513e1bd7a2Ssjelinek stats = NULL;
4523e1bd7a2Ssjelinek break;
4533e1bd7a2Ssjelinek }
4543e1bd7a2Ssjelinek }
4553e1bd7a2Ssjelinek stats = slice_get_stats(dp, stat_type, errp);
4563e1bd7a2Ssjelinek break;
4577c478bd9Sstevel@tonic-gate case DM_PARTITION:
4583e1bd7a2Ssjelinek stats = partition_get_stats(dp, stat_type, errp);
4593e1bd7a2Ssjelinek break;
4607c478bd9Sstevel@tonic-gate case DM_PATH:
4613e1bd7a2Ssjelinek stats = path_get_stats(dp, stat_type, errp);
4623e1bd7a2Ssjelinek break;
4637c478bd9Sstevel@tonic-gate case DM_ALIAS:
4643e1bd7a2Ssjelinek stats = alias_get_stats(dp, stat_type, errp);
4653e1bd7a2Ssjelinek break;
4667c478bd9Sstevel@tonic-gate default:
4673e1bd7a2Ssjelinek *errp = EINVAL;
4683e1bd7a2Ssjelinek break;
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate cache_unlock();
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate return (stats);
4747c478bd9Sstevel@tonic-gate }
4757c478bd9Sstevel@tonic-gate
4767c478bd9Sstevel@tonic-gate dm_desc_type_t
dm_get_type(dm_descriptor_t desc)4777c478bd9Sstevel@tonic-gate dm_get_type(dm_descriptor_t desc)
4787c478bd9Sstevel@tonic-gate {
4797c478bd9Sstevel@tonic-gate descriptor_t *dp;
4807c478bd9Sstevel@tonic-gate
48169fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc;
4827c478bd9Sstevel@tonic-gate
4837c478bd9Sstevel@tonic-gate cache_rlock();
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) {
486efd79defSsriman bhavanam - Sun Microsystems - Bangalore India cache_unlock();
487efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (-1);
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate cache_unlock();
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate return (dp->type);
4937c478bd9Sstevel@tonic-gate }
4943e1bd7a2Ssjelinek /*
4953e1bd7a2Ssjelinek * Returns, via slices paramater, a dm_descriptor_t list of
4963e1bd7a2Ssjelinek * slices for the named disk drive.
4973e1bd7a2Ssjelinek */
4983e1bd7a2Ssjelinek void
dm_get_slices(char * drive,dm_descriptor_t ** slices,int * errp)4993e1bd7a2Ssjelinek dm_get_slices(char *drive, dm_descriptor_t **slices, int *errp)
5003e1bd7a2Ssjelinek {
5013e1bd7a2Ssjelinek dm_descriptor_t alias;
5023e1bd7a2Ssjelinek dm_descriptor_t *media;
5033e1bd7a2Ssjelinek dm_descriptor_t *disk;
5047c478bd9Sstevel@tonic-gate
5053e1bd7a2Ssjelinek *slices = NULL;
5063e1bd7a2Ssjelinek *errp = 0;
5073e1bd7a2Ssjelinek
5083e1bd7a2Ssjelinek if (drive == NULL) {
5093e1bd7a2Ssjelinek return;
5103e1bd7a2Ssjelinek }
5113e1bd7a2Ssjelinek
5123e1bd7a2Ssjelinek alias = dm_get_descriptor_by_name(DM_ALIAS, drive, errp);
5133e1bd7a2Ssjelinek
5143e1bd7a2Ssjelinek /*
5153e1bd7a2Ssjelinek * Errors must be handled by the caller. The dm_descriptor_t *
5163e1bd7a2Ssjelinek * values will be NULL if an error occured in these calls.
5173e1bd7a2Ssjelinek */
5183e1bd7a2Ssjelinek
519bd401f05SToomas Soome if (alias != 0) {
5203e1bd7a2Ssjelinek disk = dm_get_associated_descriptors(alias, DM_DRIVE, errp);
5213e1bd7a2Ssjelinek dm_free_descriptor(alias);
5223e1bd7a2Ssjelinek if (disk != NULL) {
5233e1bd7a2Ssjelinek media = dm_get_associated_descriptors(*disk,
5243e1bd7a2Ssjelinek DM_MEDIA, errp);
5253e1bd7a2Ssjelinek dm_free_descriptors(disk);
5263e1bd7a2Ssjelinek if (media != NULL) {
5273e1bd7a2Ssjelinek *slices = dm_get_associated_descriptors(*media,
5283e1bd7a2Ssjelinek DM_SLICE, errp);
5293e1bd7a2Ssjelinek dm_free_descriptors(media);
5303e1bd7a2Ssjelinek }
5313e1bd7a2Ssjelinek }
5323e1bd7a2Ssjelinek }
5333e1bd7a2Ssjelinek }
5343e1bd7a2Ssjelinek /*
5353e1bd7a2Ssjelinek * Convenience function to get slice stats
5363e1bd7a2Ssjelinek */
5373e1bd7a2Ssjelinek void
dm_get_slice_stats(char * slice,nvlist_t ** dev_stats,int * errp)5383e1bd7a2Ssjelinek dm_get_slice_stats(char *slice, nvlist_t **dev_stats, int *errp)
5393e1bd7a2Ssjelinek {
5403e1bd7a2Ssjelinek dm_descriptor_t devp;
5413e1bd7a2Ssjelinek
5423e1bd7a2Ssjelinek *dev_stats = NULL;
5433e1bd7a2Ssjelinek *errp = 0;
5443e1bd7a2Ssjelinek
5453e1bd7a2Ssjelinek if (slice == NULL) {
5463e1bd7a2Ssjelinek return;
5473e1bd7a2Ssjelinek }
5483e1bd7a2Ssjelinek
5493e1bd7a2Ssjelinek /*
5503e1bd7a2Ssjelinek * Errors must be handled by the caller. The dm_descriptor_t *
5513e1bd7a2Ssjelinek * values will be NULL if an error occured in these calls.
5523e1bd7a2Ssjelinek */
5533e1bd7a2Ssjelinek devp = dm_get_descriptor_by_name(DM_SLICE, slice, errp);
554bd401f05SToomas Soome if (devp != 0) {
555bd401f05SToomas Soome *dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE, errp);
5563e1bd7a2Ssjelinek dm_free_descriptor(devp);
5573e1bd7a2Ssjelinek }
5583e1bd7a2Ssjelinek }
5593e1bd7a2Ssjelinek
56046a2abf2Seschrock /*
56146a2abf2Seschrock * Checks for overlapping slices. If the given device is a slice, and it
56246a2abf2Seschrock * overlaps with any non-backup slice on the disk, return true with a detailed
56346a2abf2Seschrock * description similar to dm_inuse().
56446a2abf2Seschrock */
56546a2abf2Seschrock int
dm_isoverlapping(char * slicename,char ** overlaps_with,int * errp)56646a2abf2Seschrock dm_isoverlapping(char *slicename, char **overlaps_with, int *errp)
56746a2abf2Seschrock {
568bd401f05SToomas Soome dm_descriptor_t slice = 0;
56946a2abf2Seschrock dm_descriptor_t *media = NULL;
57046a2abf2Seschrock dm_descriptor_t *slices = NULL;
57146a2abf2Seschrock int i = 0;
57246a2abf2Seschrock uint32_t in_snum;
57346a2abf2Seschrock uint64_t start_block = 0;
57446a2abf2Seschrock uint64_t end_block = 0;
57546a2abf2Seschrock uint64_t media_size = 0;
57646a2abf2Seschrock uint64_t size = 0;
57746a2abf2Seschrock nvlist_t *media_attrs = NULL;
57846a2abf2Seschrock nvlist_t *slice_attrs = NULL;
57946a2abf2Seschrock int ret = 0;
58046a2abf2Seschrock
58146a2abf2Seschrock slice = dm_get_descriptor_by_name(DM_SLICE, slicename, errp);
582bd401f05SToomas Soome if (slice == 0)
58346a2abf2Seschrock goto out;
58446a2abf2Seschrock
58546a2abf2Seschrock /*
58646a2abf2Seschrock * Get the list of slices be fetching the associated media, and then all
58746a2abf2Seschrock * associated slices.
58846a2abf2Seschrock */
58946a2abf2Seschrock media = dm_get_associated_descriptors(slice, DM_MEDIA, errp);
590bd401f05SToomas Soome if (media == NULL || *media == 0 || *errp != 0)
59146a2abf2Seschrock goto out;
59246a2abf2Seschrock
59346a2abf2Seschrock slices = dm_get_associated_descriptors(*media, DM_SLICE, errp);
594bd401f05SToomas Soome if (slices == NULL || *slices == 0 || *errp != 0)
59546a2abf2Seschrock goto out;
59646a2abf2Seschrock
59746a2abf2Seschrock media_attrs = dm_get_attributes(*media, errp);
59846a2abf2Seschrock if (media_attrs == NULL || *errp)
59946a2abf2Seschrock goto out;
60046a2abf2Seschrock
60146a2abf2Seschrock *errp = nvlist_lookup_uint64(media_attrs, DM_NACCESSIBLE, &media_size);
60246a2abf2Seschrock if (*errp != 0)
60346a2abf2Seschrock goto out;
60446a2abf2Seschrock
60546a2abf2Seschrock slice_attrs = dm_get_attributes(slice, errp);
60646a2abf2Seschrock if (slice_attrs == NULL || *errp != 0)
60746a2abf2Seschrock goto out;
60846a2abf2Seschrock
60946a2abf2Seschrock *errp = nvlist_lookup_uint64(slice_attrs, DM_START, &start_block);
61046a2abf2Seschrock if (*errp != 0)
61146a2abf2Seschrock goto out;
61246a2abf2Seschrock
61346a2abf2Seschrock *errp = nvlist_lookup_uint64(slice_attrs, DM_SIZE, &size);
61446a2abf2Seschrock if (*errp != 0)
61546a2abf2Seschrock goto out;
61646a2abf2Seschrock
61746a2abf2Seschrock *errp = nvlist_lookup_uint32(slice_attrs, DM_INDEX, &in_snum);
61846a2abf2Seschrock if (*errp != 0)
61946a2abf2Seschrock goto out;
62046a2abf2Seschrock
62146a2abf2Seschrock end_block = (start_block + size) - 1;
62246a2abf2Seschrock
62346a2abf2Seschrock for (i = 0; slices[i]; i ++) {
62446a2abf2Seschrock uint64_t other_start;
62546a2abf2Seschrock uint64_t other_end;
62646a2abf2Seschrock uint64_t other_size;
62746a2abf2Seschrock uint32_t snum;
62846a2abf2Seschrock
62946a2abf2Seschrock nvlist_t *other_attrs = dm_get_attributes(slices[i], errp);
63046a2abf2Seschrock
63146a2abf2Seschrock if (other_attrs == NULL)
63246a2abf2Seschrock continue;
63346a2abf2Seschrock
63446a2abf2Seschrock if (*errp != 0)
63546a2abf2Seschrock goto out;
63646a2abf2Seschrock
63746a2abf2Seschrock *errp = nvlist_lookup_uint64(other_attrs, DM_START,
63846a2abf2Seschrock &other_start);
63946a2abf2Seschrock if (*errp) {
64046a2abf2Seschrock nvlist_free(other_attrs);
64146a2abf2Seschrock goto out;
64246a2abf2Seschrock }
64346a2abf2Seschrock
64446a2abf2Seschrock *errp = nvlist_lookup_uint64(other_attrs, DM_SIZE,
64546a2abf2Seschrock &other_size);
64646a2abf2Seschrock
64746a2abf2Seschrock if (*errp) {
64846a2abf2Seschrock nvlist_free(other_attrs);
64946a2abf2Seschrock ret = -1;
65046a2abf2Seschrock goto out;
65146a2abf2Seschrock }
65246a2abf2Seschrock
65346a2abf2Seschrock other_end = (other_size + other_start) - 1;
65446a2abf2Seschrock
65546a2abf2Seschrock *errp = nvlist_lookup_uint32(other_attrs, DM_INDEX,
65646a2abf2Seschrock &snum);
65746a2abf2Seschrock
65846a2abf2Seschrock if (*errp) {
65946a2abf2Seschrock nvlist_free(other_attrs);
66046a2abf2Seschrock ret = -1;
66146a2abf2Seschrock goto out;
66246a2abf2Seschrock }
66346a2abf2Seschrock
66446a2abf2Seschrock /*
66546a2abf2Seschrock * Check to see if there are > 2 overlapping regions
66646a2abf2Seschrock * on this media in the same region as this slice.
66746a2abf2Seschrock * This is done by assuming the following:
66846a2abf2Seschrock * Slice 2 is the backup slice if it is the size
66946a2abf2Seschrock * of the whole disk
67046a2abf2Seschrock * If slice 2 is the overlap and slice 2 is the size of
67146a2abf2Seschrock * the whole disk, continue. If another slice is found
67246a2abf2Seschrock * that overlaps with our slice, return it.
67346a2abf2Seschrock * There is the potential that there is more than one slice
67446a2abf2Seschrock * that our slice overlaps with, however, we only return
67546a2abf2Seschrock * the first overlapping slice we find.
67646a2abf2Seschrock *
67746a2abf2Seschrock */
67846a2abf2Seschrock if (start_block >= other_start && start_block <= other_end) {
67946a2abf2Seschrock if ((snum == 2 && (other_size == media_size)) ||
68046a2abf2Seschrock snum == in_snum) {
68146a2abf2Seschrock continue;
68246a2abf2Seschrock } else {
68346a2abf2Seschrock char *str = dm_get_name(slices[i], errp);
68446a2abf2Seschrock if (*errp != 0) {
68546a2abf2Seschrock nvlist_free(other_attrs);
68646a2abf2Seschrock ret = -1;
68746a2abf2Seschrock goto out;
68846a2abf2Seschrock }
68946a2abf2Seschrock *overlaps_with = strdup(str);
69046a2abf2Seschrock dm_free_name(str);
69146a2abf2Seschrock nvlist_free(other_attrs);
69246a2abf2Seschrock ret = 1;
69346a2abf2Seschrock goto out;
69446a2abf2Seschrock }
69546a2abf2Seschrock } else if (other_start >= start_block &&
69646a2abf2Seschrock other_start <= end_block) {
69746a2abf2Seschrock if ((snum == 2 && (other_size == media_size)) ||
69846a2abf2Seschrock snum == in_snum) {
69946a2abf2Seschrock continue;
70046a2abf2Seschrock } else {
70146a2abf2Seschrock char *str = dm_get_name(slices[i], errp);
70246a2abf2Seschrock if (*errp != 0) {
70346a2abf2Seschrock nvlist_free(other_attrs);
70446a2abf2Seschrock ret = -1;
70546a2abf2Seschrock goto out;
70646a2abf2Seschrock }
70746a2abf2Seschrock *overlaps_with = strdup(str);
70846a2abf2Seschrock dm_free_name(str);
70946a2abf2Seschrock nvlist_free(other_attrs);
71046a2abf2Seschrock ret = 1;
71146a2abf2Seschrock goto out;
71246a2abf2Seschrock }
71346a2abf2Seschrock }
71446a2abf2Seschrock nvlist_free(other_attrs);
71546a2abf2Seschrock }
71646a2abf2Seschrock
71746a2abf2Seschrock out:
718aab83bb8SJosef 'Jeff' Sipek nvlist_free(media_attrs);
719aab83bb8SJosef 'Jeff' Sipek nvlist_free(slice_attrs);
72046a2abf2Seschrock
72146a2abf2Seschrock if (slices)
72246a2abf2Seschrock dm_free_descriptors(slices);
72346a2abf2Seschrock if (media)
72446a2abf2Seschrock dm_free_descriptors(media);
72546a2abf2Seschrock if (slice)
72646a2abf2Seschrock dm_free_descriptor(slice);
72746a2abf2Seschrock
72846a2abf2Seschrock return (ret);
72946a2abf2Seschrock }
73046a2abf2Seschrock
731181c2f42Smmusante /*
732181c2f42Smmusante * Get the full list of swap entries. Returns -1 on error, or >= 0 to
733181c2f42Smmusante * indicate the number of entries in the list. Callers are responsible
734181c2f42Smmusante * for calling dm_free_swapentries() to deallocate memory. If this
735181c2f42Smmusante * returns 0, the swaptbl_t still needs to be freed.
736181c2f42Smmusante */
737181c2f42Smmusante int
dm_get_swapentries(swaptbl_t ** stp,int * errp)738181c2f42Smmusante dm_get_swapentries(swaptbl_t **stp, int *errp)
739181c2f42Smmusante {
740181c2f42Smmusante int count, i;
741181c2f42Smmusante swaptbl_t *tbl;
742181c2f42Smmusante char *ptr;
743181c2f42Smmusante
744181c2f42Smmusante *stp = NULL;
745181c2f42Smmusante
746181c2f42Smmusante /* get number of swap entries */
747181c2f42Smmusante if ((count = swapctl(SC_GETNSWP, NULL)) < 0) {
748181c2f42Smmusante *errp = errno;
749181c2f42Smmusante return (-1);
750181c2f42Smmusante }
751181c2f42Smmusante
752181c2f42Smmusante if (count == 0) {
753181c2f42Smmusante return (0);
754181c2f42Smmusante }
755181c2f42Smmusante
756181c2f42Smmusante /* allocate space */
757181c2f42Smmusante tbl = calloc(1, sizeof (int) + count * sizeof (swapent_t));
758181c2f42Smmusante if (tbl == NULL) {
759181c2f42Smmusante *errp = ENOMEM;
760181c2f42Smmusante return (-1);
761181c2f42Smmusante }
762181c2f42Smmusante
763181c2f42Smmusante ptr = calloc(1, count * MAXPATHLEN);
764181c2f42Smmusante if (ptr == NULL) {
765181c2f42Smmusante *errp = ENOMEM;
766181c2f42Smmusante free(tbl);
767181c2f42Smmusante return (-1);
768181c2f42Smmusante }
769181c2f42Smmusante
770181c2f42Smmusante /* set up pointers to the pathnames */
771181c2f42Smmusante tbl->swt_n = count;
772181c2f42Smmusante for (i = 0; i < count; i++) {
773181c2f42Smmusante tbl->swt_ent[i].ste_path = ptr;
774181c2f42Smmusante ptr += MAXPATHLEN;
775181c2f42Smmusante }
776181c2f42Smmusante
777181c2f42Smmusante /* get list of swap paths */
778181c2f42Smmusante count = swapctl(SC_LIST, tbl);
779181c2f42Smmusante if (count < 0) {
780181c2f42Smmusante *errp = errno;
781181c2f42Smmusante free(ptr);
782181c2f42Smmusante free(tbl);
783181c2f42Smmusante return (-1);
784181c2f42Smmusante }
785181c2f42Smmusante
786181c2f42Smmusante *stp = tbl;
787181c2f42Smmusante return (count);
788181c2f42Smmusante }
789181c2f42Smmusante
790181c2f42Smmusante /* ARGSUSED */
791181c2f42Smmusante void
dm_free_swapentries(swaptbl_t * stp)792181c2f42Smmusante dm_free_swapentries(swaptbl_t *stp)
793181c2f42Smmusante {
794181c2f42Smmusante ASSERT(stp != NULL);
795181c2f42Smmusante
796181c2f42Smmusante free(stp->swt_ent[0].ste_path);
797181c2f42Smmusante free(stp);
798181c2f42Smmusante }
799181c2f42Smmusante
800181c2f42Smmusante /*
801181c2f42Smmusante * Check a slice to see if it's being used by swap.
802181c2f42Smmusante */
803181c2f42Smmusante int
dm_inuse_swap(const char * dev_name,int * errp)804181c2f42Smmusante dm_inuse_swap(const char *dev_name, int *errp)
805181c2f42Smmusante {
806181c2f42Smmusante int count;
807181c2f42Smmusante int found;
808181c2f42Smmusante swaptbl_t *tbl = NULL;
809181c2f42Smmusante
810181c2f42Smmusante *errp = 0;
811181c2f42Smmusante
812181c2f42Smmusante count = dm_get_swapentries(&tbl, errp);
813181c2f42Smmusante if (count < 0 || *errp) {
814181c2f42Smmusante if (tbl)
815181c2f42Smmusante dm_free_swapentries(tbl);
816181c2f42Smmusante return (-1);
817181c2f42Smmusante }
818181c2f42Smmusante
819181c2f42Smmusante /* if there are no swap entries, we're done */
820181c2f42Smmusante if (!count) {
821181c2f42Smmusante return (0);
822181c2f42Smmusante }
823181c2f42Smmusante
824181c2f42Smmusante ASSERT(tbl != NULL);
825181c2f42Smmusante
826181c2f42Smmusante found = 0;
827181c2f42Smmusante while (count--) {
828181c2f42Smmusante if (strcmp(dev_name, tbl->swt_ent[count].ste_path) == 0) {
829181c2f42Smmusante found = 1;
830181c2f42Smmusante break;
831181c2f42Smmusante }
832181c2f42Smmusante }
833181c2f42Smmusante
834181c2f42Smmusante dm_free_swapentries(tbl);
835181c2f42Smmusante return (found);
836181c2f42Smmusante }
837181c2f42Smmusante
8383e1bd7a2Ssjelinek /*
8393e1bd7a2Ssjelinek * Returns 'in use' details, if found, about a specific dev_name,
8403e1bd7a2Ssjelinek * based on the caller(who). It is important to note that it is possible
8413e1bd7a2Ssjelinek * for there to be more than one 'in use' statistic regarding a dev_name.
8423e1bd7a2Ssjelinek * The **msg parameter returns a list of 'in use' details. This message
8433e1bd7a2Ssjelinek * is formatted via gettext().
8443e1bd7a2Ssjelinek */
8453e1bd7a2Ssjelinek int
dm_inuse(char * dev_name,char ** msg,dm_who_type_t who,int * errp)8463e1bd7a2Ssjelinek dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
8473e1bd7a2Ssjelinek {
8483e1bd7a2Ssjelinek nvlist_t *dev_stats = NULL;
8493e1bd7a2Ssjelinek char *by, *data;
8503e1bd7a2Ssjelinek nvpair_t *nvwhat = NULL;
8513e1bd7a2Ssjelinek nvpair_t *nvdesc = NULL;
8523e1bd7a2Ssjelinek int found = 0;
853181c2f42Smmusante int err;
8543e1bd7a2Ssjelinek char *dname = NULL;
8553e1bd7a2Ssjelinek
8563e1bd7a2Ssjelinek *errp = 0;
8573e1bd7a2Ssjelinek *msg = NULL;
8583e1bd7a2Ssjelinek
85982d71480Ssjelinek /*
86082d71480Ssjelinek * If the user doesn't want to do in use checking, return.
86182d71480Ssjelinek */
86282d71480Ssjelinek
86382d71480Ssjelinek if (NOINUSE_SET)
86482d71480Ssjelinek return (0);
86582d71480Ssjelinek
8663e1bd7a2Ssjelinek dname = getfullblkname(dev_name);
8673e1bd7a2Ssjelinek /*
8683e1bd7a2Ssjelinek * If we cannot find the block name, we cannot check the device
8693e1bd7a2Ssjelinek * for in use statistics. So, return found, which is == 0.
8703e1bd7a2Ssjelinek */
8713e1bd7a2Ssjelinek if (dname == NULL || *dname == '\0') {
8723e1bd7a2Ssjelinek return (found);
8733e1bd7a2Ssjelinek }
8743e1bd7a2Ssjelinek
875181c2f42Smmusante /*
876181c2f42Smmusante * Slice stats for swap devices are only returned if mounted
877181c2f42Smmusante * (e.g. /tmp). Other devices or files being used for swap
878181c2f42Smmusante * are ignored, so we add a special check here to use swapctl(2)
879181c2f42Smmusante * to perform in-use checking.
880181c2f42Smmusante */
881181c2f42Smmusante if (ANY_ZPOOL_USE(who) && (err = dm_inuse_swap(dname, errp))) {
882181c2f42Smmusante
883181c2f42Smmusante /* on error, dm_inuse_swap sets errp */
884181c2f42Smmusante if (err < 0) {
885181c2f42Smmusante free(dname);
886181c2f42Smmusante return (err);
887181c2f42Smmusante }
888181c2f42Smmusante
889181c2f42Smmusante /* simulate a mounted swap device */
890181c2f42Smmusante (void) build_usage_string(dname, DM_USE_MOUNT, "swap", msg,
891181c2f42Smmusante &found, errp);
892181c2f42Smmusante
893181c2f42Smmusante /* if this fails, dm_get_usage_string changed */
894181c2f42Smmusante ASSERT(found == 1);
895181c2f42Smmusante
896181c2f42Smmusante free(dname);
897181c2f42Smmusante return (found);
898181c2f42Smmusante }
899181c2f42Smmusante
9003e1bd7a2Ssjelinek dm_get_slice_stats(dname, &dev_stats, errp);
9013e1bd7a2Ssjelinek if (dev_stats == NULL) {
9023e1bd7a2Ssjelinek /*
9033e1bd7a2Ssjelinek * If there is an error, but it isn't a no device found error
9043e1bd7a2Ssjelinek * return the error as recorded. Otherwise, with a full
9053e1bd7a2Ssjelinek * block name, we might not be able to get the slice
9065f10ef69SYuri Pankov * associated, and will get an ENODEV error.
9073e1bd7a2Ssjelinek */
9085f10ef69SYuri Pankov if (*errp == ENODEV)
9095f10ef69SYuri Pankov *errp = 0;
9103e1bd7a2Ssjelinek free(dname);
9113e1bd7a2Ssjelinek return (found);
9123e1bd7a2Ssjelinek }
9133e1bd7a2Ssjelinek
9143e1bd7a2Ssjelinek for (;;) {
9153e1bd7a2Ssjelinek
9163e1bd7a2Ssjelinek nvwhat = nvlist_next_nvpair(dev_stats, nvdesc);
9173e1bd7a2Ssjelinek nvdesc = nvlist_next_nvpair(dev_stats, nvwhat);
9183e1bd7a2Ssjelinek
9193e1bd7a2Ssjelinek /*
9203e1bd7a2Ssjelinek * End of the list found.
9213e1bd7a2Ssjelinek */
9223e1bd7a2Ssjelinek if (nvwhat == NULL || nvdesc == NULL) {
9233e1bd7a2Ssjelinek break;
9243e1bd7a2Ssjelinek }
9253e1bd7a2Ssjelinek /*
9263e1bd7a2Ssjelinek * Otherwise, we check to see if this client(who) cares
9273e1bd7a2Ssjelinek * about this in use scenario
9283e1bd7a2Ssjelinek */
9293e1bd7a2Ssjelinek
9303e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0);
9313e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0);
9323e1bd7a2Ssjelinek /*
9333e1bd7a2Ssjelinek * If we error getting the string value continue on
9343e1bd7a2Ssjelinek * to the next pair(if there is one)
9353e1bd7a2Ssjelinek */
9363e1bd7a2Ssjelinek if (nvpair_value_string(nvwhat, &by)) {
9373e1bd7a2Ssjelinek continue;
9383e1bd7a2Ssjelinek }
9393e1bd7a2Ssjelinek if (nvpair_value_string(nvdesc, &data)) {
9403e1bd7a2Ssjelinek continue;
9413e1bd7a2Ssjelinek }
9423e1bd7a2Ssjelinek
9433e1bd7a2Ssjelinek switch (who) {
9443e1bd7a2Ssjelinek case DM_WHO_MKFS:
9453e1bd7a2Ssjelinek /*
9463e1bd7a2Ssjelinek * mkfs is not in use for these cases.
9473e1bd7a2Ssjelinek * All others are in use.
9483e1bd7a2Ssjelinek */
9493e1bd7a2Ssjelinek if (strcmp(by, DM_USE_LU) == 0 ||
95046a2abf2Seschrock strcmp(by, DM_USE_FS) == 0 ||
95146a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
9523e1bd7a2Ssjelinek break;
9533e1bd7a2Ssjelinek }
9543e1bd7a2Ssjelinek if (build_usage_string(dname,
9553e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) {
9563e1bd7a2Ssjelinek if (*errp) {
9573e1bd7a2Ssjelinek goto out;
9583e1bd7a2Ssjelinek }
9593e1bd7a2Ssjelinek }
9603e1bd7a2Ssjelinek break;
9613e1bd7a2Ssjelinek case DM_WHO_SWAP:
9623e1bd7a2Ssjelinek /*
9633e1bd7a2Ssjelinek * Not in use for this.
9643e1bd7a2Ssjelinek */
9653e1bd7a2Ssjelinek if (strcmp(by, DM_USE_DUMP) == 0 ||
96646a2abf2Seschrock strcmp(by, DM_USE_FS) == 0 ||
96746a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
9683e1bd7a2Ssjelinek break;
9693e1bd7a2Ssjelinek }
970efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (strcmp(by, DM_USE_LU) == 0 &&
971efd79defSsriman bhavanam - Sun Microsystems - Bangalore India strcmp(data, "-") == 0) {
972efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
973efd79defSsriman bhavanam - Sun Microsystems - Bangalore India }
974efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (strcmp(by, DM_USE_VFSTAB) == 0 &&
975efd79defSsriman bhavanam - Sun Microsystems - Bangalore India strcmp(data, "") == 0) {
976efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break;
977efd79defSsriman bhavanam - Sun Microsystems - Bangalore India }
9783e1bd7a2Ssjelinek if (build_usage_string(dname,
9793e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) {
9803e1bd7a2Ssjelinek if (*errp) {
9813e1bd7a2Ssjelinek goto out;
9823e1bd7a2Ssjelinek }
9833e1bd7a2Ssjelinek }
9843e1bd7a2Ssjelinek break;
9853e1bd7a2Ssjelinek case DM_WHO_DUMP:
9863e1bd7a2Ssjelinek /*
9873e1bd7a2Ssjelinek * Not in use for this.
9883e1bd7a2Ssjelinek */
9893e1bd7a2Ssjelinek if ((strcmp(by, DM_USE_MOUNT) == 0 &&
9903e1bd7a2Ssjelinek strcmp(data, "swap") == 0) ||
9913e1bd7a2Ssjelinek strcmp(by, DM_USE_DUMP) == 0 ||
99246a2abf2Seschrock strcmp(by, DM_USE_FS) == 0 ||
99346a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
9943e1bd7a2Ssjelinek break;
9953e1bd7a2Ssjelinek }
9963e1bd7a2Ssjelinek if (build_usage_string(dname,
9973e1bd7a2Ssjelinek by, data, msg, &found, errp)) {
9983e1bd7a2Ssjelinek if (*errp) {
9993e1bd7a2Ssjelinek goto out;
10003e1bd7a2Ssjelinek }
10013e1bd7a2Ssjelinek }
10023e1bd7a2Ssjelinek break;
10033e1bd7a2Ssjelinek
10043e1bd7a2Ssjelinek case DM_WHO_FORMAT:
100546a2abf2Seschrock if (strcmp(by, DM_USE_FS) == 0 ||
100646a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0)
10073e1bd7a2Ssjelinek break;
10083e1bd7a2Ssjelinek if (build_usage_string(dname,
10093e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) {
10103e1bd7a2Ssjelinek if (*errp) {
10113e1bd7a2Ssjelinek goto out;
10123e1bd7a2Ssjelinek }
10133e1bd7a2Ssjelinek }
10143e1bd7a2Ssjelinek break;
101546a2abf2Seschrock
101646a2abf2Seschrock case DM_WHO_ZPOOL_FORCE:
101746a2abf2Seschrock if (strcmp(by, DM_USE_FS) == 0 ||
101846a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0)
101946a2abf2Seschrock break;
102046a2abf2Seschrock /* FALLTHROUGH */
102146a2abf2Seschrock case DM_WHO_ZPOOL:
102246a2abf2Seschrock if (build_usage_string(dname,
102346a2abf2Seschrock by, data, msg, &found, errp) != 0) {
102446a2abf2Seschrock if (*errp)
102546a2abf2Seschrock goto out;
102646a2abf2Seschrock }
102746a2abf2Seschrock break;
102846a2abf2Seschrock
102946657f8dSmmusante case DM_WHO_ZPOOL_SPARE:
103046657f8dSmmusante if (strcmp(by, DM_USE_SPARE_ZPOOL) != 0) {
103146657f8dSmmusante if (build_usage_string(dname, by,
103246657f8dSmmusante data, msg, &found, errp) != 0) {
103346657f8dSmmusante if (*errp)
103446657f8dSmmusante goto out;
103546657f8dSmmusante }
103646657f8dSmmusante }
103746657f8dSmmusante break;
103846657f8dSmmusante
10393e1bd7a2Ssjelinek default:
10403e1bd7a2Ssjelinek /*
10413e1bd7a2Ssjelinek * nothing found in use for this client
10423e1bd7a2Ssjelinek * of libdiskmgt. Default is 'not in use'.
10433e1bd7a2Ssjelinek */
10443e1bd7a2Ssjelinek break;
10453e1bd7a2Ssjelinek }
10463e1bd7a2Ssjelinek }
10473e1bd7a2Ssjelinek out:
10483e1bd7a2Ssjelinek if (dname != NULL)
10493e1bd7a2Ssjelinek free(dname);
1050aab83bb8SJosef 'Jeff' Sipek nvlist_free(dev_stats);
10513e1bd7a2Ssjelinek
10523e1bd7a2Ssjelinek return (found);
10533e1bd7a2Ssjelinek }
10543e1bd7a2Ssjelinek
10553e1bd7a2Ssjelinek void
dm_get_usage_string(char * what,char * how,char ** usage_string)10563e1bd7a2Ssjelinek dm_get_usage_string(char *what, char *how, char **usage_string)
10573e1bd7a2Ssjelinek {
10583e1bd7a2Ssjelinek
10593e1bd7a2Ssjelinek
10603e1bd7a2Ssjelinek if (usage_string == NULL || what == NULL) {
10613e1bd7a2Ssjelinek return;
10623e1bd7a2Ssjelinek }
10633e1bd7a2Ssjelinek *usage_string = NULL;
10643e1bd7a2Ssjelinek
10653e1bd7a2Ssjelinek if (strcmp(what, DM_USE_MOUNT) == 0) {
10663e1bd7a2Ssjelinek if (strcmp(how, "swap") == 0) {
10673e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
1068*bbf21555SRichard Lowe "%s is currently used by swap. Please see swap(8)."
10693e1bd7a2Ssjelinek "\n");
10703e1bd7a2Ssjelinek } else {
10713e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
10723e1bd7a2Ssjelinek "%s is currently mounted on %s."
1073*bbf21555SRichard Lowe " Please see umount(8).\n");
10743e1bd7a2Ssjelinek }
10753e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VFSTAB) == 0) {
10763e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
10773e1bd7a2Ssjelinek "%s is normally mounted on %s according to /etc/vfstab. "
10783e1bd7a2Ssjelinek "Please remove this entry to use this device.\n");
10793e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_FS) == 0) {
10803e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
108146a2abf2Seschrock "%s contains a %s filesystem.\n");
10823e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VXVM) == 0) {
10833e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
10843e1bd7a2Ssjelinek "%s is part of VxVM volume %s.\n");
10853e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_LU) == 0) {
10863e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
1087*bbf21555SRichard Lowe "%s is in use for live upgrade %s. Please see ludelete(8)."
10883e1bd7a2Ssjelinek "\n");
10893e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_DUMP) == 0) {
10903e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
1091*bbf21555SRichard Lowe "%s is in use by %s. Please see dumpadm(8)."
10923e1bd7a2Ssjelinek "\n");
109346a2abf2Seschrock } else if (strcmp(what, DM_USE_EXPORTED_ZPOOL) == 0) {
109446a2abf2Seschrock *usage_string = dgettext(TEXT_DOMAIN,
109546a2abf2Seschrock "%s is part of exported or potentially active ZFS pool %s. "
1096*bbf21555SRichard Lowe "Please see zpool(8).\n");
109746a2abf2Seschrock } else if (strcmp(what, DM_USE_ACTIVE_ZPOOL) == 0) {
10983e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN,
1099*bbf21555SRichard Lowe "%s is part of active ZFS pool %s. Please see zpool(8)."
11003e1bd7a2Ssjelinek "\n");
110199653d4eSeschrock } else if (strcmp(what, DM_USE_SPARE_ZPOOL) == 0) {
110299653d4eSeschrock *usage_string = dgettext(TEXT_DOMAIN,
110399653d4eSeschrock "%s is reserved as a hot spare for ZFS pool %s. Please "
1104*bbf21555SRichard Lowe "see zpool(8).\n");
1105fa94a07fSbrendan } else if (strcmp(what, DM_USE_L2CACHE_ZPOOL) == 0) {
1106fa94a07fSbrendan *usage_string = dgettext(TEXT_DOMAIN,
1107fa94a07fSbrendan "%s is in use as a cache device for ZFS pool %s. "
1108*bbf21555SRichard Lowe "Please see zpool(8).\n");
11093e1bd7a2Ssjelinek }
11103e1bd7a2Ssjelinek }
11117c478bd9Sstevel@tonic-gate void
libdiskmgt_add_str(nvlist_t * attrs,char * name,char * val,int * errp)11127c478bd9Sstevel@tonic-gate libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp)
11137c478bd9Sstevel@tonic-gate {
11147c478bd9Sstevel@tonic-gate if (*errp == 0) {
11157c478bd9Sstevel@tonic-gate *errp = nvlist_add_string(attrs, name, val);
11167c478bd9Sstevel@tonic-gate }
11177c478bd9Sstevel@tonic-gate }
11187c478bd9Sstevel@tonic-gate
11197c478bd9Sstevel@tonic-gate descriptor_t **
libdiskmgt_empty_desc_array(int * errp)11207c478bd9Sstevel@tonic-gate libdiskmgt_empty_desc_array(int *errp)
11217c478bd9Sstevel@tonic-gate {
11227c478bd9Sstevel@tonic-gate descriptor_t **empty;
11237c478bd9Sstevel@tonic-gate
11247c478bd9Sstevel@tonic-gate empty = (descriptor_t **)calloc(1, sizeof (descriptor_t *));
11257c478bd9Sstevel@tonic-gate if (empty == NULL) {
1126efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM;
1127efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
11287c478bd9Sstevel@tonic-gate }
11297c478bd9Sstevel@tonic-gate empty[0] = NULL;
11307c478bd9Sstevel@tonic-gate
11317c478bd9Sstevel@tonic-gate *errp = 0;
11327c478bd9Sstevel@tonic-gate return (empty);
11337c478bd9Sstevel@tonic-gate }
11347c478bd9Sstevel@tonic-gate
11357c478bd9Sstevel@tonic-gate void
libdiskmgt_init_debug()11367c478bd9Sstevel@tonic-gate libdiskmgt_init_debug()
11377c478bd9Sstevel@tonic-gate {
11387c478bd9Sstevel@tonic-gate char *valp;
11397c478bd9Sstevel@tonic-gate
11407c478bd9Sstevel@tonic-gate if ((valp = getenv(DM_DEBUG)) != NULL) {
1141efd79defSsriman bhavanam - Sun Microsystems - Bangalore India dm_debug = atoi(valp);
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate }
11447c478bd9Sstevel@tonic-gate
11457c478bd9Sstevel@tonic-gate int
libdiskmgt_str_eq(char * nm1,char * nm2)11467c478bd9Sstevel@tonic-gate libdiskmgt_str_eq(char *nm1, char *nm2)
11477c478bd9Sstevel@tonic-gate {
11487c478bd9Sstevel@tonic-gate if (nm1 == NULL) {
1149efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (dm_debug) {
1150efd79defSsriman bhavanam - Sun Microsystems - Bangalore India (void) fprintf(stderr, "WARNING: str_eq nm1 NULL\n");
1151efd79defSsriman bhavanam - Sun Microsystems - Bangalore India }
11527c478bd9Sstevel@tonic-gate
1153efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (nm2 == NULL) {
1154efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (1);
1155efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } else {
1156efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (0);
1157efd79defSsriman bhavanam - Sun Microsystems - Bangalore India }
11587c478bd9Sstevel@tonic-gate }
11597c478bd9Sstevel@tonic-gate
11607c478bd9Sstevel@tonic-gate /* nm1 != NULL */
11617c478bd9Sstevel@tonic-gate
11627c478bd9Sstevel@tonic-gate if (nm2 == NULL) {
1163efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (dm_debug) {
1164efd79defSsriman bhavanam - Sun Microsystems - Bangalore India (void) fprintf(stderr, "WARNING: str_eq nm2 NULL\n");
1165efd79defSsriman bhavanam - Sun Microsystems - Bangalore India }
1166efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (0);
11677c478bd9Sstevel@tonic-gate }
11687c478bd9Sstevel@tonic-gate
11697c478bd9Sstevel@tonic-gate if (strcmp(nm1, nm2) == 0) {
1170efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (1);
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate
11737c478bd9Sstevel@tonic-gate return (0);
11747c478bd9Sstevel@tonic-gate }
11757c478bd9Sstevel@tonic-gate
11767c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11777c478bd9Sstevel@tonic-gate static descriptor_t **
desc_array_to_ptr_array(dm_descriptor_t * descs,int * errp)11787c478bd9Sstevel@tonic-gate desc_array_to_ptr_array(dm_descriptor_t *descs, int *errp)
11797c478bd9Sstevel@tonic-gate {
11807c478bd9Sstevel@tonic-gate #ifdef _LP64
11817c478bd9Sstevel@tonic-gate return ((descriptor_t **)descs);
11827c478bd9Sstevel@tonic-gate #else
11837c478bd9Sstevel@tonic-gate /* convert the 64 bit descriptors to 32 bit ptrs */
11847c478bd9Sstevel@tonic-gate int cnt;
11857c478bd9Sstevel@tonic-gate int i;
11867c478bd9Sstevel@tonic-gate descriptor_t **da;
11877c478bd9Sstevel@tonic-gate
1188efd79defSsriman bhavanam - Sun Microsystems - Bangalore India for (cnt = 0; descs[cnt]; cnt++)
1189efd79defSsriman bhavanam - Sun Microsystems - Bangalore India ;
11907c478bd9Sstevel@tonic-gate
11917c478bd9Sstevel@tonic-gate da = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *));
11927c478bd9Sstevel@tonic-gate if (da == NULL) {
1193efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM;
1194efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
11957c478bd9Sstevel@tonic-gate }
11967c478bd9Sstevel@tonic-gate
11977c478bd9Sstevel@tonic-gate for (i = 0; descs[i]; i++) {
1198efd79defSsriman bhavanam - Sun Microsystems - Bangalore India da[i] = (descriptor_t *)(uintptr_t)descs[i];
11997c478bd9Sstevel@tonic-gate }
12007c478bd9Sstevel@tonic-gate *errp = 0;
12017c478bd9Sstevel@tonic-gate free(descs);
12027c478bd9Sstevel@tonic-gate
12037c478bd9Sstevel@tonic-gate return (da);
12047c478bd9Sstevel@tonic-gate #endif
12057c478bd9Sstevel@tonic-gate }
12067c478bd9Sstevel@tonic-gate
12077c478bd9Sstevel@tonic-gate /*ARGSUSED*/
12087c478bd9Sstevel@tonic-gate static dm_descriptor_t *
ptr_array_to_desc_array(descriptor_t ** ptrs,int * errp)12097c478bd9Sstevel@tonic-gate ptr_array_to_desc_array(descriptor_t **ptrs, int *errp)
12107c478bd9Sstevel@tonic-gate {
12117c478bd9Sstevel@tonic-gate #ifdef _LP64
12127c478bd9Sstevel@tonic-gate return ((dm_descriptor_t *)ptrs);
12137c478bd9Sstevel@tonic-gate #else
12147c478bd9Sstevel@tonic-gate /* convert the 32 bit ptrs to the 64 bit descriptors */
12157c478bd9Sstevel@tonic-gate int cnt;
12167c478bd9Sstevel@tonic-gate int i;
12177c478bd9Sstevel@tonic-gate dm_descriptor_t *da;
12187c478bd9Sstevel@tonic-gate
12197c478bd9Sstevel@tonic-gate if (*errp != 0 || ptrs == NULL) {
1220efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
12217c478bd9Sstevel@tonic-gate }
12227c478bd9Sstevel@tonic-gate
1223efd79defSsriman bhavanam - Sun Microsystems - Bangalore India for (cnt = 0; ptrs[cnt]; cnt++)
1224efd79defSsriman bhavanam - Sun Microsystems - Bangalore India ;
12257c478bd9Sstevel@tonic-gate
12267c478bd9Sstevel@tonic-gate da = (dm_descriptor_t *)calloc(cnt + 1, sizeof (dm_descriptor_t));
12277c478bd9Sstevel@tonic-gate if (da == NULL) {
1228efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM;
1229efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL);
12307c478bd9Sstevel@tonic-gate }
12317c478bd9Sstevel@tonic-gate
12327c478bd9Sstevel@tonic-gate for (i = 0; ptrs[i]; i++) {
1233efd79defSsriman bhavanam - Sun Microsystems - Bangalore India da[i] = (uintptr_t)ptrs[i];
12347c478bd9Sstevel@tonic-gate }
12357c478bd9Sstevel@tonic-gate *errp = 0;
12367c478bd9Sstevel@tonic-gate free(ptrs);
12377c478bd9Sstevel@tonic-gate
12387c478bd9Sstevel@tonic-gate return (da);
12397c478bd9Sstevel@tonic-gate #endif
12407c478bd9Sstevel@tonic-gate }
12413e1bd7a2Ssjelinek /*
12423e1bd7a2Ssjelinek * Build the usage string for the in use data. Return the build string in
12433e1bd7a2Ssjelinek * the msg parameter. This function takes care of reallocing all the memory
12443e1bd7a2Ssjelinek * for this usage string. Usage string is returned already formatted for
12453e1bd7a2Ssjelinek * localization.
12463e1bd7a2Ssjelinek */
12473e1bd7a2Ssjelinek static int
build_usage_string(char * dname,char * by,char * data,char ** msg,int * found,int * errp)12483e1bd7a2Ssjelinek build_usage_string(char *dname, char *by, char *data, char **msg,
12493e1bd7a2Ssjelinek int *found, int *errp)
12503e1bd7a2Ssjelinek {
12513e1bd7a2Ssjelinek int len0;
12523e1bd7a2Ssjelinek int len1;
12533e1bd7a2Ssjelinek char *use;
12543e1bd7a2Ssjelinek char *p;
12553e1bd7a2Ssjelinek
12563e1bd7a2Ssjelinek *errp = 0;
12573e1bd7a2Ssjelinek
12583e1bd7a2Ssjelinek dm_get_usage_string(by, data, &use);
12593e1bd7a2Ssjelinek if (!use) {
12603e1bd7a2Ssjelinek return (-1);
12613e1bd7a2Ssjelinek }
12623e1bd7a2Ssjelinek
12633e1bd7a2Ssjelinek if (*msg)
12643e1bd7a2Ssjelinek len0 = strlen(*msg);
12653e1bd7a2Ssjelinek else
12663e1bd7a2Ssjelinek len0 = 0;
12673e1bd7a2Ssjelinek /* LINTED */
12683e1bd7a2Ssjelinek len1 = snprintf(NULL, 0, use, dname, data);
12693e1bd7a2Ssjelinek
12703e1bd7a2Ssjelinek /*
12713e1bd7a2Ssjelinek * If multiple in use details they
12723e1bd7a2Ssjelinek * are listed 1 per line for ease of
12733e1bd7a2Ssjelinek * reading. dm_find_usage_string
12743e1bd7a2Ssjelinek * formats these appropriately.
12753e1bd7a2Ssjelinek */
12763e1bd7a2Ssjelinek if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) {
12773e1bd7a2Ssjelinek *errp = errno;
12783e1bd7a2Ssjelinek free(*msg);
12793e1bd7a2Ssjelinek return (-1);
12803e1bd7a2Ssjelinek }
12813e1bd7a2Ssjelinek *msg = p;
12823e1bd7a2Ssjelinek
12833e1bd7a2Ssjelinek /* LINTED */
12843e1bd7a2Ssjelinek (void) snprintf(*msg + len0, len1 + 1, use, dname, data);
12853e1bd7a2Ssjelinek (*found)++;
12863e1bd7a2Ssjelinek return (0);
12873e1bd7a2Ssjelinek }
1288