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 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 2369fb9702Smike_s * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <fcntl.h> 307c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 317c478bd9Sstevel@tonic-gate #include <stdio.h> 327c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 337c478bd9Sstevel@tonic-gate #include <sys/types.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <stdlib.h> 367c478bd9Sstevel@tonic-gate #include <string.h> 37*3e1bd7a2Ssjelinek #include <libintl.h> 38*3e1bd7a2Ssjelinek #include <locale.h> 39*3e1bd7a2Ssjelinek #include <sys/debug.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 45*3e1bd7a2Ssjelinek extern char *getfullblkname(); 46*3e1bd7a2Ssjelinek 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate extern dm_desc_type_t drive_assoc_types[]; 497c478bd9Sstevel@tonic-gate extern dm_desc_type_t bus_assoc_types[]; 507c478bd9Sstevel@tonic-gate extern dm_desc_type_t controller_assoc_types[]; 517c478bd9Sstevel@tonic-gate extern dm_desc_type_t media_assoc_types[]; 527c478bd9Sstevel@tonic-gate extern dm_desc_type_t slice_assoc_types[]; 537c478bd9Sstevel@tonic-gate extern dm_desc_type_t partition_assoc_types[]; 547c478bd9Sstevel@tonic-gate extern dm_desc_type_t path_assoc_types[]; 557c478bd9Sstevel@tonic-gate extern dm_desc_type_t alias_assoc_types[]; 567c478bd9Sstevel@tonic-gate 57*3e1bd7a2Ssjelinek 587c478bd9Sstevel@tonic-gate static dm_descriptor_t *ptr_array_to_desc_array(descriptor_t **ptrs, int *errp); 597c478bd9Sstevel@tonic-gate static descriptor_t **desc_array_to_ptr_array(dm_descriptor_t *da, int *errp); 60*3e1bd7a2Ssjelinek static int build_usage_string(char *dname, char *by, char *data, char **use, 61*3e1bd7a2Ssjelinek int *found, int *errp); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate void 647c478bd9Sstevel@tonic-gate dm_free_descriptor(dm_descriptor_t desc) 657c478bd9Sstevel@tonic-gate { 667c478bd9Sstevel@tonic-gate descriptor_t *dp; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate if (desc == NULL) { 697c478bd9Sstevel@tonic-gate return; 707c478bd9Sstevel@tonic-gate } 7169fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate cache_wlock(); 747c478bd9Sstevel@tonic-gate cache_free_descriptor(dp); 757c478bd9Sstevel@tonic-gate cache_unlock(); 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate void 797c478bd9Sstevel@tonic-gate dm_free_descriptors(dm_descriptor_t *desc_list) 807c478bd9Sstevel@tonic-gate { 817c478bd9Sstevel@tonic-gate descriptor_t **dp; 827c478bd9Sstevel@tonic-gate int error; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate if (desc_list == NULL) { 857c478bd9Sstevel@tonic-gate return; 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate dp = desc_array_to_ptr_array(desc_list, &error); 887c478bd9Sstevel@tonic-gate if (error != 0) { 897c478bd9Sstevel@tonic-gate free(desc_list); 907c478bd9Sstevel@tonic-gate return; 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate cache_wlock(); 947c478bd9Sstevel@tonic-gate cache_free_descriptors(dp); 957c478bd9Sstevel@tonic-gate cache_unlock(); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 997c478bd9Sstevel@tonic-gate void 1007c478bd9Sstevel@tonic-gate dm_free_name(char *name) 1017c478bd9Sstevel@tonic-gate { 1027c478bd9Sstevel@tonic-gate free(name); 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate dm_descriptor_t * 1067c478bd9Sstevel@tonic-gate dm_get_associated_descriptors(dm_descriptor_t desc, dm_desc_type_t type, 1077c478bd9Sstevel@tonic-gate int *errp) 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate descriptor_t **descs = NULL; 1107c478bd9Sstevel@tonic-gate descriptor_t *dp; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate 11369fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate cache_wlock(); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 1187c478bd9Sstevel@tonic-gate cache_unlock(); 1197c478bd9Sstevel@tonic-gate *errp = EBADF; 1207c478bd9Sstevel@tonic-gate return (NULL); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 1247c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 1257c478bd9Sstevel@tonic-gate cache_unlock(); 1267c478bd9Sstevel@tonic-gate *errp = ENODEV; 1277c478bd9Sstevel@tonic-gate return (NULL); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate switch (dp->type) { 1317c478bd9Sstevel@tonic-gate case DM_DRIVE: 1327c478bd9Sstevel@tonic-gate descs = drive_get_assoc_descriptors(dp, type, errp); 1337c478bd9Sstevel@tonic-gate break; 1347c478bd9Sstevel@tonic-gate case DM_BUS: 1357c478bd9Sstevel@tonic-gate descs = bus_get_assoc_descriptors(dp, type, errp); 1367c478bd9Sstevel@tonic-gate break; 1377c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 1387c478bd9Sstevel@tonic-gate descs = controller_get_assoc_descriptors(dp, type, errp); 1397c478bd9Sstevel@tonic-gate break; 1407c478bd9Sstevel@tonic-gate case DM_MEDIA: 1417c478bd9Sstevel@tonic-gate descs = media_get_assoc_descriptors(dp, type, errp); 1427c478bd9Sstevel@tonic-gate break; 1437c478bd9Sstevel@tonic-gate case DM_SLICE: 1447c478bd9Sstevel@tonic-gate descs = slice_get_assoc_descriptors(dp, type, errp); 1457c478bd9Sstevel@tonic-gate break; 1467c478bd9Sstevel@tonic-gate case DM_PARTITION: 1477c478bd9Sstevel@tonic-gate descs = partition_get_assoc_descriptors(dp, type, errp); 1487c478bd9Sstevel@tonic-gate break; 1497c478bd9Sstevel@tonic-gate case DM_PATH: 1507c478bd9Sstevel@tonic-gate descs = path_get_assoc_descriptors(dp, type, errp); 1517c478bd9Sstevel@tonic-gate break; 1527c478bd9Sstevel@tonic-gate case DM_ALIAS: 1537c478bd9Sstevel@tonic-gate descs = alias_get_assoc_descriptors(dp, type, errp); 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate default: 1567c478bd9Sstevel@tonic-gate *errp = EINVAL; 1577c478bd9Sstevel@tonic-gate break; 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate cache_unlock(); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate return (ptr_array_to_desc_array(descs, errp)); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate dm_desc_type_t * 1667c478bd9Sstevel@tonic-gate dm_get_associated_types(dm_desc_type_t type) 1677c478bd9Sstevel@tonic-gate { 1687c478bd9Sstevel@tonic-gate switch (type) { 1697c478bd9Sstevel@tonic-gate case DM_DRIVE: 1707c478bd9Sstevel@tonic-gate return (drive_assoc_types); 1717c478bd9Sstevel@tonic-gate case DM_BUS: 1727c478bd9Sstevel@tonic-gate return (bus_assoc_types); 1737c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 1747c478bd9Sstevel@tonic-gate return (controller_assoc_types); 1757c478bd9Sstevel@tonic-gate case DM_MEDIA: 1767c478bd9Sstevel@tonic-gate return (media_assoc_types); 1777c478bd9Sstevel@tonic-gate case DM_SLICE: 1787c478bd9Sstevel@tonic-gate return (slice_assoc_types); 1797c478bd9Sstevel@tonic-gate case DM_PARTITION: 1807c478bd9Sstevel@tonic-gate return (partition_assoc_types); 1817c478bd9Sstevel@tonic-gate case DM_PATH: 1827c478bd9Sstevel@tonic-gate return (path_assoc_types); 1837c478bd9Sstevel@tonic-gate case DM_ALIAS: 1847c478bd9Sstevel@tonic-gate return (alias_assoc_types); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate return (NULL); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate nvlist_t * 1917c478bd9Sstevel@tonic-gate dm_get_attributes(dm_descriptor_t desc, int *errp) 1927c478bd9Sstevel@tonic-gate { 1937c478bd9Sstevel@tonic-gate descriptor_t *dp; 1947c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate 19769fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate cache_rlock(); 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 2027c478bd9Sstevel@tonic-gate cache_unlock(); 2037c478bd9Sstevel@tonic-gate *errp = EBADF; 2047c478bd9Sstevel@tonic-gate return (NULL); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 2087c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 2097c478bd9Sstevel@tonic-gate cache_unlock(); 2107c478bd9Sstevel@tonic-gate *errp = ENODEV; 2117c478bd9Sstevel@tonic-gate return (NULL); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate switch (dp->type) { 2157c478bd9Sstevel@tonic-gate case DM_DRIVE: 2167c478bd9Sstevel@tonic-gate attrs = drive_get_attributes(dp, errp); 2177c478bd9Sstevel@tonic-gate break; 2187c478bd9Sstevel@tonic-gate case DM_BUS: 2197c478bd9Sstevel@tonic-gate attrs = bus_get_attributes(dp, errp); 2207c478bd9Sstevel@tonic-gate break; 2217c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 2227c478bd9Sstevel@tonic-gate attrs = controller_get_attributes(dp, errp); 2237c478bd9Sstevel@tonic-gate break; 2247c478bd9Sstevel@tonic-gate case DM_MEDIA: 2257c478bd9Sstevel@tonic-gate attrs = media_get_attributes(dp, errp); 2267c478bd9Sstevel@tonic-gate break; 2277c478bd9Sstevel@tonic-gate case DM_SLICE: 2287c478bd9Sstevel@tonic-gate attrs = slice_get_attributes(dp, errp); 2297c478bd9Sstevel@tonic-gate break; 2307c478bd9Sstevel@tonic-gate case DM_PARTITION: 2317c478bd9Sstevel@tonic-gate attrs = partition_get_attributes(dp, errp); 2327c478bd9Sstevel@tonic-gate break; 2337c478bd9Sstevel@tonic-gate case DM_PATH: 2347c478bd9Sstevel@tonic-gate attrs = path_get_attributes(dp, errp); 2357c478bd9Sstevel@tonic-gate break; 2367c478bd9Sstevel@tonic-gate case DM_ALIAS: 2377c478bd9Sstevel@tonic-gate attrs = alias_get_attributes(dp, errp); 2387c478bd9Sstevel@tonic-gate break; 2397c478bd9Sstevel@tonic-gate default: 2407c478bd9Sstevel@tonic-gate *errp = EINVAL; 2417c478bd9Sstevel@tonic-gate break; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate cache_unlock(); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate return (attrs); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate dm_descriptor_t 2507c478bd9Sstevel@tonic-gate dm_get_descriptor_by_name(dm_desc_type_t desc_type, char *name, int *errp) 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate dm_descriptor_t desc = NULL; 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate cache_wlock(); 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate switch (desc_type) { 2587c478bd9Sstevel@tonic-gate case DM_DRIVE: 2597c478bd9Sstevel@tonic-gate desc = (uintptr_t)drive_get_descriptor_by_name(name, errp); 2607c478bd9Sstevel@tonic-gate break; 2617c478bd9Sstevel@tonic-gate case DM_BUS: 2627c478bd9Sstevel@tonic-gate desc = (uintptr_t)bus_get_descriptor_by_name(name, errp); 2637c478bd9Sstevel@tonic-gate break; 2647c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 2657c478bd9Sstevel@tonic-gate desc = (uintptr_t)controller_get_descriptor_by_name(name, 2667c478bd9Sstevel@tonic-gate errp); 2677c478bd9Sstevel@tonic-gate break; 2687c478bd9Sstevel@tonic-gate case DM_MEDIA: 2697c478bd9Sstevel@tonic-gate desc = (uintptr_t)media_get_descriptor_by_name(name, errp); 2707c478bd9Sstevel@tonic-gate break; 2717c478bd9Sstevel@tonic-gate case DM_SLICE: 2727c478bd9Sstevel@tonic-gate desc = (uintptr_t)slice_get_descriptor_by_name(name, errp); 2737c478bd9Sstevel@tonic-gate break; 2747c478bd9Sstevel@tonic-gate case DM_PARTITION: 2757c478bd9Sstevel@tonic-gate desc = (uintptr_t)partition_get_descriptor_by_name(name, 2767c478bd9Sstevel@tonic-gate errp); 2777c478bd9Sstevel@tonic-gate break; 2787c478bd9Sstevel@tonic-gate case DM_PATH: 2797c478bd9Sstevel@tonic-gate desc = (uintptr_t)path_get_descriptor_by_name(name, errp); 2807c478bd9Sstevel@tonic-gate break; 2817c478bd9Sstevel@tonic-gate case DM_ALIAS: 2827c478bd9Sstevel@tonic-gate desc = (uintptr_t)alias_get_descriptor_by_name(name, errp); 2837c478bd9Sstevel@tonic-gate break; 2847c478bd9Sstevel@tonic-gate default: 2857c478bd9Sstevel@tonic-gate *errp = EINVAL; 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate cache_unlock(); 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate return (desc); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate dm_descriptor_t * 2957c478bd9Sstevel@tonic-gate dm_get_descriptors(dm_desc_type_t type, int filter[], int *errp) 2967c478bd9Sstevel@tonic-gate { 2977c478bd9Sstevel@tonic-gate descriptor_t **descs = NULL; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate cache_wlock(); 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate switch (type) { 3037c478bd9Sstevel@tonic-gate case DM_DRIVE: 3047c478bd9Sstevel@tonic-gate descs = drive_get_descriptors(filter, errp); 3057c478bd9Sstevel@tonic-gate break; 3067c478bd9Sstevel@tonic-gate case DM_BUS: 3077c478bd9Sstevel@tonic-gate descs = bus_get_descriptors(filter, errp); 3087c478bd9Sstevel@tonic-gate break; 3097c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 3107c478bd9Sstevel@tonic-gate descs = controller_get_descriptors(filter, errp); 3117c478bd9Sstevel@tonic-gate break; 3127c478bd9Sstevel@tonic-gate case DM_MEDIA: 3137c478bd9Sstevel@tonic-gate descs = media_get_descriptors(filter, errp); 3147c478bd9Sstevel@tonic-gate break; 3157c478bd9Sstevel@tonic-gate case DM_SLICE: 3167c478bd9Sstevel@tonic-gate descs = slice_get_descriptors(filter, errp); 3177c478bd9Sstevel@tonic-gate break; 3187c478bd9Sstevel@tonic-gate case DM_PARTITION: 3197c478bd9Sstevel@tonic-gate descs = partition_get_descriptors(filter, errp); 3207c478bd9Sstevel@tonic-gate break; 3217c478bd9Sstevel@tonic-gate case DM_PATH: 3227c478bd9Sstevel@tonic-gate descs = path_get_descriptors(filter, errp); 3237c478bd9Sstevel@tonic-gate break; 3247c478bd9Sstevel@tonic-gate case DM_ALIAS: 3257c478bd9Sstevel@tonic-gate descs = alias_get_descriptors(filter, errp); 3267c478bd9Sstevel@tonic-gate break; 3277c478bd9Sstevel@tonic-gate default: 3287c478bd9Sstevel@tonic-gate *errp = EINVAL; 3297c478bd9Sstevel@tonic-gate break; 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate cache_unlock(); 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate return (ptr_array_to_desc_array(descs, errp)); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate char * 3387c478bd9Sstevel@tonic-gate dm_get_name(dm_descriptor_t desc, int *errp) 3397c478bd9Sstevel@tonic-gate { 3407c478bd9Sstevel@tonic-gate descriptor_t *dp; 3417c478bd9Sstevel@tonic-gate char *nm = NULL; 3427c478bd9Sstevel@tonic-gate char *name = NULL; 3437c478bd9Sstevel@tonic-gate 34469fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc; 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate cache_rlock(); 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 3497c478bd9Sstevel@tonic-gate cache_unlock(); 3507c478bd9Sstevel@tonic-gate *errp = EBADF; 3517c478bd9Sstevel@tonic-gate return (NULL); 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 3557c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 3567c478bd9Sstevel@tonic-gate cache_unlock(); 3577c478bd9Sstevel@tonic-gate *errp = ENODEV; 3587c478bd9Sstevel@tonic-gate return (NULL); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate switch (dp->type) { 3627c478bd9Sstevel@tonic-gate case DM_DRIVE: 3637c478bd9Sstevel@tonic-gate nm = (drive_get_name(dp)); 3647c478bd9Sstevel@tonic-gate break; 3657c478bd9Sstevel@tonic-gate case DM_BUS: 3667c478bd9Sstevel@tonic-gate nm = (bus_get_name(dp)); 3677c478bd9Sstevel@tonic-gate break; 3687c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 3697c478bd9Sstevel@tonic-gate nm = (controller_get_name(dp)); 3707c478bd9Sstevel@tonic-gate break; 3717c478bd9Sstevel@tonic-gate case DM_MEDIA: 3727c478bd9Sstevel@tonic-gate nm = (media_get_name(dp)); 3737c478bd9Sstevel@tonic-gate break; 3747c478bd9Sstevel@tonic-gate case DM_SLICE: 3757c478bd9Sstevel@tonic-gate nm = (slice_get_name(dp)); 3767c478bd9Sstevel@tonic-gate break; 3777c478bd9Sstevel@tonic-gate case DM_PARTITION: 3787c478bd9Sstevel@tonic-gate nm = (partition_get_name(dp)); 3797c478bd9Sstevel@tonic-gate break; 3807c478bd9Sstevel@tonic-gate case DM_PATH: 3817c478bd9Sstevel@tonic-gate nm = (path_get_name(dp)); 3827c478bd9Sstevel@tonic-gate break; 3837c478bd9Sstevel@tonic-gate case DM_ALIAS: 3847c478bd9Sstevel@tonic-gate nm = (alias_get_name(dp)); 3857c478bd9Sstevel@tonic-gate break; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate cache_unlock(); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate *errp = 0; 3917c478bd9Sstevel@tonic-gate if (nm != NULL) { 3927c478bd9Sstevel@tonic-gate name = strdup(nm); 3937c478bd9Sstevel@tonic-gate if (name == NULL) { 3947c478bd9Sstevel@tonic-gate *errp = ENOMEM; 3957c478bd9Sstevel@tonic-gate return (NULL); 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate return (name); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate return (NULL); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate nvlist_t * 4037c478bd9Sstevel@tonic-gate dm_get_stats(dm_descriptor_t desc, int stat_type, int *errp) 4047c478bd9Sstevel@tonic-gate { 4057c478bd9Sstevel@tonic-gate descriptor_t *dp; 4067c478bd9Sstevel@tonic-gate nvlist_t *stats = NULL; 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate 40969fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc; 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate cache_rlock(); 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 414*3e1bd7a2Ssjelinek cache_unlock(); 415*3e1bd7a2Ssjelinek *errp = EBADF; 416*3e1bd7a2Ssjelinek return (NULL); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 4207c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 421*3e1bd7a2Ssjelinek cache_unlock(); 422*3e1bd7a2Ssjelinek *errp = ENODEV; 423*3e1bd7a2Ssjelinek return (NULL); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate switch (dp->type) { 4277c478bd9Sstevel@tonic-gate case DM_DRIVE: 428*3e1bd7a2Ssjelinek stats = drive_get_stats(dp, stat_type, errp); 429*3e1bd7a2Ssjelinek break; 4307c478bd9Sstevel@tonic-gate case DM_BUS: 431*3e1bd7a2Ssjelinek stats = bus_get_stats(dp, stat_type, errp); 432*3e1bd7a2Ssjelinek break; 4337c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 434*3e1bd7a2Ssjelinek stats = controller_get_stats(dp, stat_type, errp); 435*3e1bd7a2Ssjelinek break; 4367c478bd9Sstevel@tonic-gate case DM_MEDIA: 437*3e1bd7a2Ssjelinek stats = media_get_stats(dp, stat_type, errp); 438*3e1bd7a2Ssjelinek break; 4397c478bd9Sstevel@tonic-gate case DM_SLICE: 440*3e1bd7a2Ssjelinek if (stat_type == DM_SLICE_STAT_USE) { 441*3e1bd7a2Ssjelinek /* 442*3e1bd7a2Ssjelinek * If NOINUSE_CHECK is set, we do not perform 443*3e1bd7a2Ssjelinek * the in use checking if the user has set stat_type 444*3e1bd7a2Ssjelinek * DM_SLICE_STAT_USE 445*3e1bd7a2Ssjelinek */ 446*3e1bd7a2Ssjelinek if (getenv("NOINUSE_CHECK") != NULL) { 447*3e1bd7a2Ssjelinek stats = NULL; 448*3e1bd7a2Ssjelinek break; 449*3e1bd7a2Ssjelinek } 450*3e1bd7a2Ssjelinek } 451*3e1bd7a2Ssjelinek stats = slice_get_stats(dp, stat_type, errp); 452*3e1bd7a2Ssjelinek break; 4537c478bd9Sstevel@tonic-gate case DM_PARTITION: 454*3e1bd7a2Ssjelinek stats = partition_get_stats(dp, stat_type, errp); 455*3e1bd7a2Ssjelinek break; 4567c478bd9Sstevel@tonic-gate case DM_PATH: 457*3e1bd7a2Ssjelinek stats = path_get_stats(dp, stat_type, errp); 458*3e1bd7a2Ssjelinek break; 4597c478bd9Sstevel@tonic-gate case DM_ALIAS: 460*3e1bd7a2Ssjelinek stats = alias_get_stats(dp, stat_type, errp); 461*3e1bd7a2Ssjelinek break; 4627c478bd9Sstevel@tonic-gate default: 463*3e1bd7a2Ssjelinek *errp = EINVAL; 464*3e1bd7a2Ssjelinek break; 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate cache_unlock(); 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate return (stats); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate dm_desc_type_t 4737c478bd9Sstevel@tonic-gate dm_get_type(dm_descriptor_t desc) 4747c478bd9Sstevel@tonic-gate { 4757c478bd9Sstevel@tonic-gate descriptor_t *dp; 4767c478bd9Sstevel@tonic-gate 47769fb9702Smike_s dp = (descriptor_t *)(uintptr_t)desc; 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate cache_rlock(); 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 4827c478bd9Sstevel@tonic-gate cache_unlock(); 4837c478bd9Sstevel@tonic-gate return (-1); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate cache_unlock(); 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate return (dp->type); 4897c478bd9Sstevel@tonic-gate } 490*3e1bd7a2Ssjelinek /* 491*3e1bd7a2Ssjelinek * Returns, via slices paramater, a dm_descriptor_t list of 492*3e1bd7a2Ssjelinek * slices for the named disk drive. 493*3e1bd7a2Ssjelinek */ 494*3e1bd7a2Ssjelinek void 495*3e1bd7a2Ssjelinek dm_get_slices(char *drive, dm_descriptor_t **slices, int *errp) 496*3e1bd7a2Ssjelinek { 497*3e1bd7a2Ssjelinek dm_descriptor_t alias; 498*3e1bd7a2Ssjelinek dm_descriptor_t *media; 499*3e1bd7a2Ssjelinek dm_descriptor_t *disk; 5007c478bd9Sstevel@tonic-gate 501*3e1bd7a2Ssjelinek *slices = NULL; 502*3e1bd7a2Ssjelinek *errp = 0; 503*3e1bd7a2Ssjelinek 504*3e1bd7a2Ssjelinek if (drive == NULL) { 505*3e1bd7a2Ssjelinek return; 506*3e1bd7a2Ssjelinek } 507*3e1bd7a2Ssjelinek 508*3e1bd7a2Ssjelinek alias = dm_get_descriptor_by_name(DM_ALIAS, drive, errp); 509*3e1bd7a2Ssjelinek 510*3e1bd7a2Ssjelinek /* 511*3e1bd7a2Ssjelinek * Errors must be handled by the caller. The dm_descriptor_t * 512*3e1bd7a2Ssjelinek * values will be NULL if an error occured in these calls. 513*3e1bd7a2Ssjelinek */ 514*3e1bd7a2Ssjelinek 515*3e1bd7a2Ssjelinek if (alias != NULL) { 516*3e1bd7a2Ssjelinek disk = dm_get_associated_descriptors(alias, DM_DRIVE, errp); 517*3e1bd7a2Ssjelinek dm_free_descriptor(alias); 518*3e1bd7a2Ssjelinek if (disk != NULL) { 519*3e1bd7a2Ssjelinek media = dm_get_associated_descriptors(*disk, 520*3e1bd7a2Ssjelinek DM_MEDIA, errp); 521*3e1bd7a2Ssjelinek dm_free_descriptors(disk); 522*3e1bd7a2Ssjelinek if (media != NULL) { 523*3e1bd7a2Ssjelinek *slices = dm_get_associated_descriptors(*media, 524*3e1bd7a2Ssjelinek DM_SLICE, errp); 525*3e1bd7a2Ssjelinek dm_free_descriptors(media); 526*3e1bd7a2Ssjelinek } 527*3e1bd7a2Ssjelinek } 528*3e1bd7a2Ssjelinek } 529*3e1bd7a2Ssjelinek } 530*3e1bd7a2Ssjelinek /* 531*3e1bd7a2Ssjelinek * Convenience function to get slice stats 532*3e1bd7a2Ssjelinek */ 533*3e1bd7a2Ssjelinek void 534*3e1bd7a2Ssjelinek dm_get_slice_stats(char *slice, nvlist_t **dev_stats, int *errp) 535*3e1bd7a2Ssjelinek { 536*3e1bd7a2Ssjelinek dm_descriptor_t devp; 537*3e1bd7a2Ssjelinek 538*3e1bd7a2Ssjelinek *dev_stats = NULL; 539*3e1bd7a2Ssjelinek *errp = 0; 540*3e1bd7a2Ssjelinek 541*3e1bd7a2Ssjelinek if (slice == NULL) { 542*3e1bd7a2Ssjelinek return; 543*3e1bd7a2Ssjelinek } 544*3e1bd7a2Ssjelinek 545*3e1bd7a2Ssjelinek /* 546*3e1bd7a2Ssjelinek * Errors must be handled by the caller. The dm_descriptor_t * 547*3e1bd7a2Ssjelinek * values will be NULL if an error occured in these calls. 548*3e1bd7a2Ssjelinek */ 549*3e1bd7a2Ssjelinek devp = dm_get_descriptor_by_name(DM_SLICE, slice, errp); 550*3e1bd7a2Ssjelinek if (devp != NULL) { 551*3e1bd7a2Ssjelinek *dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE, 552*3e1bd7a2Ssjelinek errp); 553*3e1bd7a2Ssjelinek dm_free_descriptor(devp); 554*3e1bd7a2Ssjelinek } 555*3e1bd7a2Ssjelinek } 556*3e1bd7a2Ssjelinek 557*3e1bd7a2Ssjelinek /* 558*3e1bd7a2Ssjelinek * Returns 'in use' details, if found, about a specific dev_name, 559*3e1bd7a2Ssjelinek * based on the caller(who). It is important to note that it is possible 560*3e1bd7a2Ssjelinek * for there to be more than one 'in use' statistic regarding a dev_name. 561*3e1bd7a2Ssjelinek * The **msg parameter returns a list of 'in use' details. This message 562*3e1bd7a2Ssjelinek * is formatted via gettext(). 563*3e1bd7a2Ssjelinek */ 564*3e1bd7a2Ssjelinek int 565*3e1bd7a2Ssjelinek dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp) 566*3e1bd7a2Ssjelinek { 567*3e1bd7a2Ssjelinek nvlist_t *dev_stats = NULL; 568*3e1bd7a2Ssjelinek char *by, *data; 569*3e1bd7a2Ssjelinek nvpair_t *nvwhat = NULL; 570*3e1bd7a2Ssjelinek nvpair_t *nvdesc = NULL; 571*3e1bd7a2Ssjelinek int found = 0; 572*3e1bd7a2Ssjelinek char *dname = NULL; 573*3e1bd7a2Ssjelinek 574*3e1bd7a2Ssjelinek *errp = 0; 575*3e1bd7a2Ssjelinek *msg = NULL; 576*3e1bd7a2Ssjelinek 577*3e1bd7a2Ssjelinek dname = getfullblkname(dev_name); 578*3e1bd7a2Ssjelinek /* 579*3e1bd7a2Ssjelinek * If we cannot find the block name, we cannot check the device 580*3e1bd7a2Ssjelinek * for in use statistics. So, return found, which is == 0. 581*3e1bd7a2Ssjelinek */ 582*3e1bd7a2Ssjelinek if (dname == NULL || *dname == '\0') { 583*3e1bd7a2Ssjelinek return (found); 584*3e1bd7a2Ssjelinek } 585*3e1bd7a2Ssjelinek 586*3e1bd7a2Ssjelinek dm_get_slice_stats(dname, &dev_stats, errp); 587*3e1bd7a2Ssjelinek if (dev_stats == NULL) { 588*3e1bd7a2Ssjelinek /* 589*3e1bd7a2Ssjelinek * If there is an error, but it isn't a no device found error 590*3e1bd7a2Ssjelinek * return the error as recorded. Otherwise, with a full 591*3e1bd7a2Ssjelinek * block name, we might not be able to get the slice 592*3e1bd7a2Ssjelinek * associated, and will get an ENODEV error. For example, 593*3e1bd7a2Ssjelinek * an SVM metadevice will return a value from getfullblkname() 594*3e1bd7a2Ssjelinek * but libdiskmgt won't be able to find this device for 595*3e1bd7a2Ssjelinek * statistics gathering. This is expected and we should not 596*3e1bd7a2Ssjelinek * report errnoneous errors. 597*3e1bd7a2Ssjelinek */ 598*3e1bd7a2Ssjelinek if (*errp) { 599*3e1bd7a2Ssjelinek if (*errp == ENODEV) { 600*3e1bd7a2Ssjelinek *errp = 0; 601*3e1bd7a2Ssjelinek } 602*3e1bd7a2Ssjelinek } 603*3e1bd7a2Ssjelinek free(dname); 604*3e1bd7a2Ssjelinek return (found); 605*3e1bd7a2Ssjelinek } 606*3e1bd7a2Ssjelinek 607*3e1bd7a2Ssjelinek for (;;) { 608*3e1bd7a2Ssjelinek 609*3e1bd7a2Ssjelinek nvwhat = nvlist_next_nvpair(dev_stats, nvdesc); 610*3e1bd7a2Ssjelinek nvdesc = nvlist_next_nvpair(dev_stats, nvwhat); 611*3e1bd7a2Ssjelinek 612*3e1bd7a2Ssjelinek /* 613*3e1bd7a2Ssjelinek * End of the list found. 614*3e1bd7a2Ssjelinek */ 615*3e1bd7a2Ssjelinek if (nvwhat == NULL || nvdesc == NULL) { 616*3e1bd7a2Ssjelinek break; 617*3e1bd7a2Ssjelinek } 618*3e1bd7a2Ssjelinek /* 619*3e1bd7a2Ssjelinek * Otherwise, we check to see if this client(who) cares 620*3e1bd7a2Ssjelinek * about this in use scenario 621*3e1bd7a2Ssjelinek */ 622*3e1bd7a2Ssjelinek 623*3e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0); 624*3e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0); 625*3e1bd7a2Ssjelinek /* 626*3e1bd7a2Ssjelinek * If we error getting the string value continue on 627*3e1bd7a2Ssjelinek * to the next pair(if there is one) 628*3e1bd7a2Ssjelinek */ 629*3e1bd7a2Ssjelinek if (nvpair_value_string(nvwhat, &by)) { 630*3e1bd7a2Ssjelinek continue; 631*3e1bd7a2Ssjelinek } 632*3e1bd7a2Ssjelinek if (nvpair_value_string(nvdesc, &data)) { 633*3e1bd7a2Ssjelinek continue; 634*3e1bd7a2Ssjelinek } 635*3e1bd7a2Ssjelinek 636*3e1bd7a2Ssjelinek switch (who) { 637*3e1bd7a2Ssjelinek case DM_WHO_MKFS: 638*3e1bd7a2Ssjelinek /* 639*3e1bd7a2Ssjelinek * mkfs is not in use for these cases. 640*3e1bd7a2Ssjelinek * All others are in use. 641*3e1bd7a2Ssjelinek */ 642*3e1bd7a2Ssjelinek if (strcmp(by, DM_USE_LU) == 0 || 643*3e1bd7a2Ssjelinek strcmp(by, DM_USE_FS) == 0) { 644*3e1bd7a2Ssjelinek break; 645*3e1bd7a2Ssjelinek } 646*3e1bd7a2Ssjelinek if (build_usage_string(dname, 647*3e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 648*3e1bd7a2Ssjelinek if (*errp) { 649*3e1bd7a2Ssjelinek goto out; 650*3e1bd7a2Ssjelinek } 651*3e1bd7a2Ssjelinek } 652*3e1bd7a2Ssjelinek break; 653*3e1bd7a2Ssjelinek case DM_WHO_SWAP: 654*3e1bd7a2Ssjelinek /* 655*3e1bd7a2Ssjelinek * Not in use for this. 656*3e1bd7a2Ssjelinek */ 657*3e1bd7a2Ssjelinek if (strcmp(by, DM_USE_DUMP) == 0 || 658*3e1bd7a2Ssjelinek strcmp(by, DM_USE_FS) == 0) { 659*3e1bd7a2Ssjelinek break; 660*3e1bd7a2Ssjelinek } 661*3e1bd7a2Ssjelinek 662*3e1bd7a2Ssjelinek if (build_usage_string(dname, 663*3e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 664*3e1bd7a2Ssjelinek if (*errp) { 665*3e1bd7a2Ssjelinek goto out; 666*3e1bd7a2Ssjelinek } 667*3e1bd7a2Ssjelinek } 668*3e1bd7a2Ssjelinek break; 669*3e1bd7a2Ssjelinek case DM_WHO_DUMP: 670*3e1bd7a2Ssjelinek /* 671*3e1bd7a2Ssjelinek * Not in use for this. 672*3e1bd7a2Ssjelinek */ 673*3e1bd7a2Ssjelinek if ((strcmp(by, DM_USE_MOUNT) == 0 && 674*3e1bd7a2Ssjelinek strcmp(data, "swap") == 0) || 675*3e1bd7a2Ssjelinek strcmp(by, DM_USE_DUMP) == 0 || 676*3e1bd7a2Ssjelinek strcmp(by, DM_USE_FS) == 0) { 677*3e1bd7a2Ssjelinek break; 678*3e1bd7a2Ssjelinek } 679*3e1bd7a2Ssjelinek if (build_usage_string(dname, 680*3e1bd7a2Ssjelinek by, data, msg, &found, errp)) { 681*3e1bd7a2Ssjelinek if (*errp) { 682*3e1bd7a2Ssjelinek goto out; 683*3e1bd7a2Ssjelinek } 684*3e1bd7a2Ssjelinek } 685*3e1bd7a2Ssjelinek break; 686*3e1bd7a2Ssjelinek 687*3e1bd7a2Ssjelinek case DM_WHO_FORMAT: 688*3e1bd7a2Ssjelinek if (strcmp(by, DM_USE_FS) == 0) 689*3e1bd7a2Ssjelinek break; 690*3e1bd7a2Ssjelinek if (build_usage_string(dname, 691*3e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 692*3e1bd7a2Ssjelinek if (*errp) { 693*3e1bd7a2Ssjelinek goto out; 694*3e1bd7a2Ssjelinek } 695*3e1bd7a2Ssjelinek } 696*3e1bd7a2Ssjelinek break; 697*3e1bd7a2Ssjelinek default: 698*3e1bd7a2Ssjelinek /* 699*3e1bd7a2Ssjelinek * nothing found in use for this client 700*3e1bd7a2Ssjelinek * of libdiskmgt. Default is 'not in use'. 701*3e1bd7a2Ssjelinek */ 702*3e1bd7a2Ssjelinek break; 703*3e1bd7a2Ssjelinek } 704*3e1bd7a2Ssjelinek } 705*3e1bd7a2Ssjelinek out: 706*3e1bd7a2Ssjelinek if (dname != NULL) 707*3e1bd7a2Ssjelinek free(dname); 708*3e1bd7a2Ssjelinek if (dev_stats != NULL) 709*3e1bd7a2Ssjelinek nvlist_free(dev_stats); 710*3e1bd7a2Ssjelinek 711*3e1bd7a2Ssjelinek return (found); 712*3e1bd7a2Ssjelinek } 713*3e1bd7a2Ssjelinek 714*3e1bd7a2Ssjelinek void 715*3e1bd7a2Ssjelinek dm_get_usage_string(char *what, char *how, char **usage_string) 716*3e1bd7a2Ssjelinek { 717*3e1bd7a2Ssjelinek 718*3e1bd7a2Ssjelinek 719*3e1bd7a2Ssjelinek if (usage_string == NULL || what == NULL) { 720*3e1bd7a2Ssjelinek return; 721*3e1bd7a2Ssjelinek } 722*3e1bd7a2Ssjelinek *usage_string = NULL; 723*3e1bd7a2Ssjelinek 724*3e1bd7a2Ssjelinek if (strcmp(what, DM_USE_MOUNT) == 0) { 725*3e1bd7a2Ssjelinek if (strcmp(how, "swap") == 0) { 726*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 727*3e1bd7a2Ssjelinek "%s is currently used by swap. Please see swap(1M)." 728*3e1bd7a2Ssjelinek "\n"); 729*3e1bd7a2Ssjelinek } else { 730*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 731*3e1bd7a2Ssjelinek "%s is currently mounted on %s." 732*3e1bd7a2Ssjelinek " Please see umount(1M).\n"); 733*3e1bd7a2Ssjelinek } 734*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VFSTAB) == 0) { 735*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 736*3e1bd7a2Ssjelinek "%s is normally mounted on %s according to /etc/vfstab. " 737*3e1bd7a2Ssjelinek "Please remove this entry to use this device.\n"); 738*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_FS) == 0) { 739*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 740*3e1bd7a2Ssjelinek "Warning: %s contains a %s filesystem.\n"); 741*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_SVM) == 0) { 742*3e1bd7a2Ssjelinek if (strcmp(how, "mdb") == 0) { 743*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 744*3e1bd7a2Ssjelinek "%s contains an SVM %s. Please see " 745*3e1bd7a2Ssjelinek "metadb(1M).\n"); 746*3e1bd7a2Ssjelinek } else { 747*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 748*3e1bd7a2Ssjelinek "%s is part of SVM volume %s. " 749*3e1bd7a2Ssjelinek "Please see metaclear(1M).\n"); 750*3e1bd7a2Ssjelinek } 751*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VXVM) == 0) { 752*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 753*3e1bd7a2Ssjelinek "%s is part of VxVM volume %s.\n"); 754*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_LU) == 0) { 755*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 756*3e1bd7a2Ssjelinek "%s is in use for live upgrade %s. Please see ludelete(1M)." 757*3e1bd7a2Ssjelinek "\n"); 758*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_DUMP) == 0) { 759*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 760*3e1bd7a2Ssjelinek "%s is in use by %s. Please see dumpadm(1M)." 761*3e1bd7a2Ssjelinek "\n"); 762*3e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_ZPOOL) == 0) { 763*3e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 764*3e1bd7a2Ssjelinek "%s is in use by zpool %s. Please see zpool(1M)." 765*3e1bd7a2Ssjelinek "\n"); 766*3e1bd7a2Ssjelinek } 767*3e1bd7a2Ssjelinek } 7687c478bd9Sstevel@tonic-gate void 7697c478bd9Sstevel@tonic-gate libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp) 7707c478bd9Sstevel@tonic-gate { 7717c478bd9Sstevel@tonic-gate if (*errp == 0) { 7727c478bd9Sstevel@tonic-gate *errp = nvlist_add_string(attrs, name, val); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate descriptor_t ** 7777c478bd9Sstevel@tonic-gate libdiskmgt_empty_desc_array(int *errp) 7787c478bd9Sstevel@tonic-gate { 7797c478bd9Sstevel@tonic-gate descriptor_t **empty; 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate empty = (descriptor_t **)calloc(1, sizeof (descriptor_t *)); 7827c478bd9Sstevel@tonic-gate if (empty == NULL) { 7837c478bd9Sstevel@tonic-gate *errp = ENOMEM; 7847c478bd9Sstevel@tonic-gate return (NULL); 7857c478bd9Sstevel@tonic-gate } 7867c478bd9Sstevel@tonic-gate empty[0] = NULL; 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate *errp = 0; 7897c478bd9Sstevel@tonic-gate return (empty); 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate void 7937c478bd9Sstevel@tonic-gate libdiskmgt_init_debug() 7947c478bd9Sstevel@tonic-gate { 7957c478bd9Sstevel@tonic-gate char *valp; 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate if ((valp = getenv(DM_DEBUG)) != NULL) { 7987c478bd9Sstevel@tonic-gate dm_debug = atoi(valp); 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate int 8037c478bd9Sstevel@tonic-gate libdiskmgt_str_eq(char *nm1, char *nm2) 8047c478bd9Sstevel@tonic-gate { 8057c478bd9Sstevel@tonic-gate if (nm1 == NULL) { 8067c478bd9Sstevel@tonic-gate if (dm_debug) { 8077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "WARNING: str_eq nm1 NULL\n"); 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 8117c478bd9Sstevel@tonic-gate return (1); 8127c478bd9Sstevel@tonic-gate } else { 8137c478bd9Sstevel@tonic-gate return (0); 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate /* nm1 != NULL */ 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 8207c478bd9Sstevel@tonic-gate if (dm_debug) { 8217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "WARNING: str_eq nm2 NULL\n"); 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate return (0); 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate if (strcmp(nm1, nm2) == 0) { 8277c478bd9Sstevel@tonic-gate return (1); 8287c478bd9Sstevel@tonic-gate } 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate return (0); 8317c478bd9Sstevel@tonic-gate } 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8347c478bd9Sstevel@tonic-gate static descriptor_t ** 8357c478bd9Sstevel@tonic-gate desc_array_to_ptr_array(dm_descriptor_t *descs, int *errp) 8367c478bd9Sstevel@tonic-gate { 8377c478bd9Sstevel@tonic-gate #ifdef _LP64 8387c478bd9Sstevel@tonic-gate return ((descriptor_t **)descs); 8397c478bd9Sstevel@tonic-gate #else 8407c478bd9Sstevel@tonic-gate /* convert the 64 bit descriptors to 32 bit ptrs */ 8417c478bd9Sstevel@tonic-gate int cnt; 8427c478bd9Sstevel@tonic-gate int i; 8437c478bd9Sstevel@tonic-gate descriptor_t **da; 8447c478bd9Sstevel@tonic-gate 8457c478bd9Sstevel@tonic-gate for (cnt = 0; descs[cnt]; cnt++); 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate da = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); 8487c478bd9Sstevel@tonic-gate if (da == NULL) { 8497c478bd9Sstevel@tonic-gate *errp = ENOMEM; 8507c478bd9Sstevel@tonic-gate return (NULL); 8517c478bd9Sstevel@tonic-gate } 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate for (i = 0; descs[i]; i++) { 85469fb9702Smike_s da[i] = (descriptor_t *)(uintptr_t)descs[i]; 8557c478bd9Sstevel@tonic-gate } 8567c478bd9Sstevel@tonic-gate *errp = 0; 8577c478bd9Sstevel@tonic-gate free(descs); 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate return (da); 8607c478bd9Sstevel@tonic-gate #endif 8617c478bd9Sstevel@tonic-gate } 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8647c478bd9Sstevel@tonic-gate static dm_descriptor_t * 8657c478bd9Sstevel@tonic-gate ptr_array_to_desc_array(descriptor_t **ptrs, int *errp) 8667c478bd9Sstevel@tonic-gate { 8677c478bd9Sstevel@tonic-gate #ifdef _LP64 8687c478bd9Sstevel@tonic-gate return ((dm_descriptor_t *)ptrs); 8697c478bd9Sstevel@tonic-gate #else 8707c478bd9Sstevel@tonic-gate /* convert the 32 bit ptrs to the 64 bit descriptors */ 8717c478bd9Sstevel@tonic-gate int cnt; 8727c478bd9Sstevel@tonic-gate int i; 8737c478bd9Sstevel@tonic-gate dm_descriptor_t *da; 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate if (*errp != 0 || ptrs == NULL) { 8767c478bd9Sstevel@tonic-gate return (NULL); 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate for (cnt = 0; ptrs[cnt]; cnt++); 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate da = (dm_descriptor_t *)calloc(cnt + 1, sizeof (dm_descriptor_t)); 8827c478bd9Sstevel@tonic-gate if (da == NULL) { 8837c478bd9Sstevel@tonic-gate *errp = ENOMEM; 8847c478bd9Sstevel@tonic-gate return (NULL); 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate for (i = 0; ptrs[i]; i++) { 8887c478bd9Sstevel@tonic-gate da[i] = (uintptr_t)ptrs[i]; 8897c478bd9Sstevel@tonic-gate } 8907c478bd9Sstevel@tonic-gate *errp = 0; 8917c478bd9Sstevel@tonic-gate free(ptrs); 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate return (da); 8947c478bd9Sstevel@tonic-gate #endif 8957c478bd9Sstevel@tonic-gate } 896*3e1bd7a2Ssjelinek /* 897*3e1bd7a2Ssjelinek * Build the usage string for the in use data. Return the build string in 898*3e1bd7a2Ssjelinek * the msg parameter. This function takes care of reallocing all the memory 899*3e1bd7a2Ssjelinek * for this usage string. Usage string is returned already formatted for 900*3e1bd7a2Ssjelinek * localization. 901*3e1bd7a2Ssjelinek */ 902*3e1bd7a2Ssjelinek static int 903*3e1bd7a2Ssjelinek build_usage_string(char *dname, char *by, char *data, char **msg, 904*3e1bd7a2Ssjelinek int *found, int *errp) 905*3e1bd7a2Ssjelinek { 906*3e1bd7a2Ssjelinek int len0; 907*3e1bd7a2Ssjelinek int len1; 908*3e1bd7a2Ssjelinek char *use; 909*3e1bd7a2Ssjelinek char *p; 910*3e1bd7a2Ssjelinek 911*3e1bd7a2Ssjelinek *errp = 0; 912*3e1bd7a2Ssjelinek 913*3e1bd7a2Ssjelinek dm_get_usage_string(by, data, &use); 914*3e1bd7a2Ssjelinek if (!use) { 915*3e1bd7a2Ssjelinek return (-1); 916*3e1bd7a2Ssjelinek } 917*3e1bd7a2Ssjelinek 918*3e1bd7a2Ssjelinek if (*msg) 919*3e1bd7a2Ssjelinek len0 = strlen(*msg); 920*3e1bd7a2Ssjelinek else 921*3e1bd7a2Ssjelinek len0 = 0; 922*3e1bd7a2Ssjelinek /* LINTED */ 923*3e1bd7a2Ssjelinek len1 = snprintf(NULL, 0, use, dname, data); 924*3e1bd7a2Ssjelinek 925*3e1bd7a2Ssjelinek /* 926*3e1bd7a2Ssjelinek * If multiple in use details they 927*3e1bd7a2Ssjelinek * are listed 1 per line for ease of 928*3e1bd7a2Ssjelinek * reading. dm_find_usage_string 929*3e1bd7a2Ssjelinek * formats these appropriately. 930*3e1bd7a2Ssjelinek */ 931*3e1bd7a2Ssjelinek if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) { 932*3e1bd7a2Ssjelinek *errp = errno; 933*3e1bd7a2Ssjelinek free(*msg); 934*3e1bd7a2Ssjelinek return (-1); 935*3e1bd7a2Ssjelinek } 936*3e1bd7a2Ssjelinek *msg = p; 937*3e1bd7a2Ssjelinek 938*3e1bd7a2Ssjelinek /* LINTED */ 939*3e1bd7a2Ssjelinek (void) snprintf(*msg + len0, len1 + 1, use, dname, data); 940*3e1bd7a2Ssjelinek (*found)++; 941*3e1bd7a2Ssjelinek return (0); 942*3e1bd7a2Ssjelinek } 943