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> 373e1bd7a2Ssjelinek #include <libintl.h> 383e1bd7a2Ssjelinek #include <locale.h> 393e1bd7a2Ssjelinek #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 453e1bd7a2Ssjelinek extern char *getfullblkname(); 463e1bd7a2Ssjelinek 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 573e1bd7a2Ssjelinek 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); 603e1bd7a2Ssjelinek static int build_usage_string(char *dname, char *by, char *data, char **use, 613e1bd7a2Ssjelinek 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)) { 4147c478bd9Sstevel@tonic-gate cache_unlock(); 4157c478bd9Sstevel@tonic-gate *errp = EBADF; 4167c478bd9Sstevel@tonic-gate 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) { 4217c478bd9Sstevel@tonic-gate cache_unlock(); 4227c478bd9Sstevel@tonic-gate *errp = ENODEV; 4237c478bd9Sstevel@tonic-gate return (NULL); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate switch (dp->type) { 4277c478bd9Sstevel@tonic-gate case DM_DRIVE: 4287c478bd9Sstevel@tonic-gate stats = drive_get_stats(dp, stat_type, errp); 4297c478bd9Sstevel@tonic-gate break; 4307c478bd9Sstevel@tonic-gate case DM_BUS: 4317c478bd9Sstevel@tonic-gate stats = bus_get_stats(dp, stat_type, errp); 4327c478bd9Sstevel@tonic-gate break; 4337c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 4347c478bd9Sstevel@tonic-gate stats = controller_get_stats(dp, stat_type, errp); 4357c478bd9Sstevel@tonic-gate break; 4367c478bd9Sstevel@tonic-gate case DM_MEDIA: 4377c478bd9Sstevel@tonic-gate stats = media_get_stats(dp, stat_type, errp); 4387c478bd9Sstevel@tonic-gate break; 4397c478bd9Sstevel@tonic-gate case DM_SLICE: 4403e1bd7a2Ssjelinek if (stat_type == DM_SLICE_STAT_USE) { 4413e1bd7a2Ssjelinek /* 4423e1bd7a2Ssjelinek * If NOINUSE_CHECK is set, we do not perform 4433e1bd7a2Ssjelinek * the in use checking if the user has set stat_type 4443e1bd7a2Ssjelinek * DM_SLICE_STAT_USE 4453e1bd7a2Ssjelinek */ 446*82d71480Ssjelinek if (NOINUSE_SET) { 4473e1bd7a2Ssjelinek stats = NULL; 4483e1bd7a2Ssjelinek break; 4493e1bd7a2Ssjelinek } 4503e1bd7a2Ssjelinek } 4517c478bd9Sstevel@tonic-gate stats = slice_get_stats(dp, stat_type, errp); 4527c478bd9Sstevel@tonic-gate break; 4537c478bd9Sstevel@tonic-gate case DM_PARTITION: 4547c478bd9Sstevel@tonic-gate stats = partition_get_stats(dp, stat_type, errp); 4557c478bd9Sstevel@tonic-gate break; 4567c478bd9Sstevel@tonic-gate case DM_PATH: 4577c478bd9Sstevel@tonic-gate stats = path_get_stats(dp, stat_type, errp); 4587c478bd9Sstevel@tonic-gate break; 4597c478bd9Sstevel@tonic-gate case DM_ALIAS: 4607c478bd9Sstevel@tonic-gate stats = alias_get_stats(dp, stat_type, errp); 4617c478bd9Sstevel@tonic-gate break; 4627c478bd9Sstevel@tonic-gate default: 4637c478bd9Sstevel@tonic-gate *errp = EINVAL; 4647c478bd9Sstevel@tonic-gate 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 } 4903e1bd7a2Ssjelinek /* 4913e1bd7a2Ssjelinek * Returns, via slices paramater, a dm_descriptor_t list of 4923e1bd7a2Ssjelinek * slices for the named disk drive. 4933e1bd7a2Ssjelinek */ 4943e1bd7a2Ssjelinek void 4953e1bd7a2Ssjelinek dm_get_slices(char *drive, dm_descriptor_t **slices, int *errp) 4963e1bd7a2Ssjelinek { 4973e1bd7a2Ssjelinek dm_descriptor_t alias; 4983e1bd7a2Ssjelinek dm_descriptor_t *media; 4993e1bd7a2Ssjelinek dm_descriptor_t *disk; 5007c478bd9Sstevel@tonic-gate 5013e1bd7a2Ssjelinek *slices = NULL; 5023e1bd7a2Ssjelinek *errp = 0; 5033e1bd7a2Ssjelinek 5043e1bd7a2Ssjelinek if (drive == NULL) { 5053e1bd7a2Ssjelinek return; 5063e1bd7a2Ssjelinek } 5073e1bd7a2Ssjelinek 5083e1bd7a2Ssjelinek alias = dm_get_descriptor_by_name(DM_ALIAS, drive, errp); 5093e1bd7a2Ssjelinek 5103e1bd7a2Ssjelinek /* 5113e1bd7a2Ssjelinek * Errors must be handled by the caller. The dm_descriptor_t * 5123e1bd7a2Ssjelinek * values will be NULL if an error occured in these calls. 5133e1bd7a2Ssjelinek */ 5143e1bd7a2Ssjelinek 5153e1bd7a2Ssjelinek if (alias != NULL) { 5163e1bd7a2Ssjelinek disk = dm_get_associated_descriptors(alias, DM_DRIVE, errp); 5173e1bd7a2Ssjelinek dm_free_descriptor(alias); 5183e1bd7a2Ssjelinek if (disk != NULL) { 5193e1bd7a2Ssjelinek media = dm_get_associated_descriptors(*disk, 5203e1bd7a2Ssjelinek DM_MEDIA, errp); 5213e1bd7a2Ssjelinek dm_free_descriptors(disk); 5223e1bd7a2Ssjelinek if (media != NULL) { 5233e1bd7a2Ssjelinek *slices = dm_get_associated_descriptors(*media, 5243e1bd7a2Ssjelinek DM_SLICE, errp); 5253e1bd7a2Ssjelinek dm_free_descriptors(media); 5263e1bd7a2Ssjelinek } 5273e1bd7a2Ssjelinek } 5283e1bd7a2Ssjelinek } 5293e1bd7a2Ssjelinek } 5303e1bd7a2Ssjelinek /* 5313e1bd7a2Ssjelinek * Convenience function to get slice stats 5323e1bd7a2Ssjelinek */ 5333e1bd7a2Ssjelinek void 5343e1bd7a2Ssjelinek dm_get_slice_stats(char *slice, nvlist_t **dev_stats, int *errp) 5353e1bd7a2Ssjelinek { 5363e1bd7a2Ssjelinek dm_descriptor_t devp; 5373e1bd7a2Ssjelinek 5383e1bd7a2Ssjelinek *dev_stats = NULL; 5393e1bd7a2Ssjelinek *errp = 0; 5403e1bd7a2Ssjelinek 5413e1bd7a2Ssjelinek if (slice == NULL) { 5423e1bd7a2Ssjelinek return; 5433e1bd7a2Ssjelinek } 5443e1bd7a2Ssjelinek 5453e1bd7a2Ssjelinek /* 5463e1bd7a2Ssjelinek * Errors must be handled by the caller. The dm_descriptor_t * 5473e1bd7a2Ssjelinek * values will be NULL if an error occured in these calls. 5483e1bd7a2Ssjelinek */ 5493e1bd7a2Ssjelinek devp = dm_get_descriptor_by_name(DM_SLICE, slice, errp); 5503e1bd7a2Ssjelinek if (devp != NULL) { 5513e1bd7a2Ssjelinek *dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE, 5523e1bd7a2Ssjelinek errp); 5533e1bd7a2Ssjelinek dm_free_descriptor(devp); 5543e1bd7a2Ssjelinek } 5553e1bd7a2Ssjelinek } 5563e1bd7a2Ssjelinek 5573e1bd7a2Ssjelinek /* 5583e1bd7a2Ssjelinek * Returns 'in use' details, if found, about a specific dev_name, 5593e1bd7a2Ssjelinek * based on the caller(who). It is important to note that it is possible 5603e1bd7a2Ssjelinek * for there to be more than one 'in use' statistic regarding a dev_name. 5613e1bd7a2Ssjelinek * The **msg parameter returns a list of 'in use' details. This message 5623e1bd7a2Ssjelinek * is formatted via gettext(). 5633e1bd7a2Ssjelinek */ 5643e1bd7a2Ssjelinek int 5653e1bd7a2Ssjelinek dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp) 5663e1bd7a2Ssjelinek { 5673e1bd7a2Ssjelinek nvlist_t *dev_stats = NULL; 5683e1bd7a2Ssjelinek char *by, *data; 5693e1bd7a2Ssjelinek nvpair_t *nvwhat = NULL; 5703e1bd7a2Ssjelinek nvpair_t *nvdesc = NULL; 5713e1bd7a2Ssjelinek int found = 0; 5723e1bd7a2Ssjelinek char *dname = NULL; 5733e1bd7a2Ssjelinek 574*82d71480Ssjelinek 5753e1bd7a2Ssjelinek *errp = 0; 5763e1bd7a2Ssjelinek *msg = NULL; 5773e1bd7a2Ssjelinek 578*82d71480Ssjelinek /* 579*82d71480Ssjelinek * If the user doesn't want to do in use checking, return. 580*82d71480Ssjelinek */ 581*82d71480Ssjelinek 582*82d71480Ssjelinek if (NOINUSE_SET) 583*82d71480Ssjelinek return (0); 584*82d71480Ssjelinek 5853e1bd7a2Ssjelinek dname = getfullblkname(dev_name); 5863e1bd7a2Ssjelinek /* 5873e1bd7a2Ssjelinek * If we cannot find the block name, we cannot check the device 5883e1bd7a2Ssjelinek * for in use statistics. So, return found, which is == 0. 5893e1bd7a2Ssjelinek */ 5903e1bd7a2Ssjelinek if (dname == NULL || *dname == '\0') { 5913e1bd7a2Ssjelinek return (found); 5923e1bd7a2Ssjelinek } 5933e1bd7a2Ssjelinek 5943e1bd7a2Ssjelinek dm_get_slice_stats(dname, &dev_stats, errp); 5953e1bd7a2Ssjelinek if (dev_stats == NULL) { 5963e1bd7a2Ssjelinek /* 5973e1bd7a2Ssjelinek * If there is an error, but it isn't a no device found error 5983e1bd7a2Ssjelinek * return the error as recorded. Otherwise, with a full 5993e1bd7a2Ssjelinek * block name, we might not be able to get the slice 6003e1bd7a2Ssjelinek * associated, and will get an ENODEV error. For example, 6013e1bd7a2Ssjelinek * an SVM metadevice will return a value from getfullblkname() 6023e1bd7a2Ssjelinek * but libdiskmgt won't be able to find this device for 6033e1bd7a2Ssjelinek * statistics gathering. This is expected and we should not 6043e1bd7a2Ssjelinek * report errnoneous errors. 6053e1bd7a2Ssjelinek */ 6063e1bd7a2Ssjelinek if (*errp) { 6073e1bd7a2Ssjelinek if (*errp == ENODEV) { 6083e1bd7a2Ssjelinek *errp = 0; 6093e1bd7a2Ssjelinek } 6103e1bd7a2Ssjelinek } 6113e1bd7a2Ssjelinek free(dname); 6123e1bd7a2Ssjelinek return (found); 6133e1bd7a2Ssjelinek } 6143e1bd7a2Ssjelinek 6153e1bd7a2Ssjelinek for (;;) { 6163e1bd7a2Ssjelinek 6173e1bd7a2Ssjelinek nvwhat = nvlist_next_nvpair(dev_stats, nvdesc); 6183e1bd7a2Ssjelinek nvdesc = nvlist_next_nvpair(dev_stats, nvwhat); 6193e1bd7a2Ssjelinek 6203e1bd7a2Ssjelinek /* 6213e1bd7a2Ssjelinek * End of the list found. 6223e1bd7a2Ssjelinek */ 6233e1bd7a2Ssjelinek if (nvwhat == NULL || nvdesc == NULL) { 6243e1bd7a2Ssjelinek break; 6253e1bd7a2Ssjelinek } 6263e1bd7a2Ssjelinek /* 6273e1bd7a2Ssjelinek * Otherwise, we check to see if this client(who) cares 6283e1bd7a2Ssjelinek * about this in use scenario 6293e1bd7a2Ssjelinek */ 6303e1bd7a2Ssjelinek 6313e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0); 6323e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0); 6333e1bd7a2Ssjelinek /* 6343e1bd7a2Ssjelinek * If we error getting the string value continue on 6353e1bd7a2Ssjelinek * to the next pair(if there is one) 6363e1bd7a2Ssjelinek */ 6373e1bd7a2Ssjelinek if (nvpair_value_string(nvwhat, &by)) { 6383e1bd7a2Ssjelinek continue; 6393e1bd7a2Ssjelinek } 6403e1bd7a2Ssjelinek if (nvpair_value_string(nvdesc, &data)) { 6413e1bd7a2Ssjelinek continue; 6423e1bd7a2Ssjelinek } 6433e1bd7a2Ssjelinek 6443e1bd7a2Ssjelinek switch (who) { 6453e1bd7a2Ssjelinek case DM_WHO_MKFS: 6463e1bd7a2Ssjelinek /* 6473e1bd7a2Ssjelinek * mkfs is not in use for these cases. 6483e1bd7a2Ssjelinek * All others are in use. 6493e1bd7a2Ssjelinek */ 6503e1bd7a2Ssjelinek if (strcmp(by, DM_USE_LU) == 0 || 6513e1bd7a2Ssjelinek strcmp(by, DM_USE_FS) == 0) { 6523e1bd7a2Ssjelinek break; 6533e1bd7a2Ssjelinek } 6543e1bd7a2Ssjelinek if (build_usage_string(dname, 6553e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 6563e1bd7a2Ssjelinek if (*errp) { 6573e1bd7a2Ssjelinek goto out; 6583e1bd7a2Ssjelinek } 6593e1bd7a2Ssjelinek } 6603e1bd7a2Ssjelinek break; 6613e1bd7a2Ssjelinek case DM_WHO_SWAP: 6623e1bd7a2Ssjelinek /* 6633e1bd7a2Ssjelinek * Not in use for this. 6643e1bd7a2Ssjelinek */ 6653e1bd7a2Ssjelinek if (strcmp(by, DM_USE_DUMP) == 0 || 6663e1bd7a2Ssjelinek strcmp(by, DM_USE_FS) == 0) { 6673e1bd7a2Ssjelinek break; 6683e1bd7a2Ssjelinek } 6693e1bd7a2Ssjelinek 6703e1bd7a2Ssjelinek if (build_usage_string(dname, 6713e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 6723e1bd7a2Ssjelinek if (*errp) { 6733e1bd7a2Ssjelinek goto out; 6743e1bd7a2Ssjelinek } 6753e1bd7a2Ssjelinek } 6763e1bd7a2Ssjelinek break; 6773e1bd7a2Ssjelinek case DM_WHO_DUMP: 6783e1bd7a2Ssjelinek /* 6793e1bd7a2Ssjelinek * Not in use for this. 6803e1bd7a2Ssjelinek */ 6813e1bd7a2Ssjelinek if ((strcmp(by, DM_USE_MOUNT) == 0 && 6823e1bd7a2Ssjelinek strcmp(data, "swap") == 0) || 6833e1bd7a2Ssjelinek strcmp(by, DM_USE_DUMP) == 0 || 6843e1bd7a2Ssjelinek strcmp(by, DM_USE_FS) == 0) { 6853e1bd7a2Ssjelinek break; 6863e1bd7a2Ssjelinek } 6873e1bd7a2Ssjelinek if (build_usage_string(dname, 6883e1bd7a2Ssjelinek by, data, msg, &found, errp)) { 6893e1bd7a2Ssjelinek if (*errp) { 6903e1bd7a2Ssjelinek goto out; 6913e1bd7a2Ssjelinek } 6923e1bd7a2Ssjelinek } 6933e1bd7a2Ssjelinek break; 6943e1bd7a2Ssjelinek 6953e1bd7a2Ssjelinek case DM_WHO_FORMAT: 6963e1bd7a2Ssjelinek if (strcmp(by, DM_USE_FS) == 0) 6973e1bd7a2Ssjelinek break; 6983e1bd7a2Ssjelinek if (build_usage_string(dname, 6993e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 7003e1bd7a2Ssjelinek if (*errp) { 7013e1bd7a2Ssjelinek goto out; 7023e1bd7a2Ssjelinek } 7033e1bd7a2Ssjelinek } 7043e1bd7a2Ssjelinek break; 7053e1bd7a2Ssjelinek default: 7063e1bd7a2Ssjelinek /* 7073e1bd7a2Ssjelinek * nothing found in use for this client 7083e1bd7a2Ssjelinek * of libdiskmgt. Default is 'not in use'. 7093e1bd7a2Ssjelinek */ 7103e1bd7a2Ssjelinek break; 7113e1bd7a2Ssjelinek } 7123e1bd7a2Ssjelinek } 7133e1bd7a2Ssjelinek out: 7143e1bd7a2Ssjelinek if (dname != NULL) 7153e1bd7a2Ssjelinek free(dname); 7163e1bd7a2Ssjelinek if (dev_stats != NULL) 7173e1bd7a2Ssjelinek nvlist_free(dev_stats); 7183e1bd7a2Ssjelinek 7193e1bd7a2Ssjelinek return (found); 7203e1bd7a2Ssjelinek } 7213e1bd7a2Ssjelinek 7223e1bd7a2Ssjelinek void 7233e1bd7a2Ssjelinek dm_get_usage_string(char *what, char *how, char **usage_string) 7243e1bd7a2Ssjelinek { 7253e1bd7a2Ssjelinek 7263e1bd7a2Ssjelinek 7273e1bd7a2Ssjelinek if (usage_string == NULL || what == NULL) { 7283e1bd7a2Ssjelinek return; 7293e1bd7a2Ssjelinek } 7303e1bd7a2Ssjelinek *usage_string = NULL; 7313e1bd7a2Ssjelinek 7323e1bd7a2Ssjelinek if (strcmp(what, DM_USE_MOUNT) == 0) { 7333e1bd7a2Ssjelinek if (strcmp(how, "swap") == 0) { 7343e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7353e1bd7a2Ssjelinek "%s is currently used by swap. Please see swap(1M)." 7363e1bd7a2Ssjelinek "\n"); 7373e1bd7a2Ssjelinek } else { 7383e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7393e1bd7a2Ssjelinek "%s is currently mounted on %s." 7403e1bd7a2Ssjelinek " Please see umount(1M).\n"); 7413e1bd7a2Ssjelinek } 7423e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VFSTAB) == 0) { 7433e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7443e1bd7a2Ssjelinek "%s is normally mounted on %s according to /etc/vfstab. " 7453e1bd7a2Ssjelinek "Please remove this entry to use this device.\n"); 7463e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_FS) == 0) { 7473e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7483e1bd7a2Ssjelinek "Warning: %s contains a %s filesystem.\n"); 7493e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_SVM) == 0) { 7503e1bd7a2Ssjelinek if (strcmp(how, "mdb") == 0) { 7513e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7523e1bd7a2Ssjelinek "%s contains an SVM %s. Please see " 7533e1bd7a2Ssjelinek "metadb(1M).\n"); 7543e1bd7a2Ssjelinek } else { 7553e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7563e1bd7a2Ssjelinek "%s is part of SVM volume %s. " 7573e1bd7a2Ssjelinek "Please see metaclear(1M).\n"); 7583e1bd7a2Ssjelinek } 7593e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VXVM) == 0) { 7603e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7613e1bd7a2Ssjelinek "%s is part of VxVM volume %s.\n"); 7623e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_LU) == 0) { 7633e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7643e1bd7a2Ssjelinek "%s is in use for live upgrade %s. Please see ludelete(1M)." 7653e1bd7a2Ssjelinek "\n"); 7663e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_DUMP) == 0) { 7673e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7683e1bd7a2Ssjelinek "%s is in use by %s. Please see dumpadm(1M)." 7693e1bd7a2Ssjelinek "\n"); 7703e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_ZPOOL) == 0) { 7713e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 7723e1bd7a2Ssjelinek "%s is in use by zpool %s. Please see zpool(1M)." 7733e1bd7a2Ssjelinek "\n"); 7743e1bd7a2Ssjelinek } 7753e1bd7a2Ssjelinek } 7767c478bd9Sstevel@tonic-gate void 7777c478bd9Sstevel@tonic-gate libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp) 7787c478bd9Sstevel@tonic-gate { 7797c478bd9Sstevel@tonic-gate if (*errp == 0) { 7807c478bd9Sstevel@tonic-gate *errp = nvlist_add_string(attrs, name, val); 7817c478bd9Sstevel@tonic-gate } 7827c478bd9Sstevel@tonic-gate } 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate descriptor_t ** 7857c478bd9Sstevel@tonic-gate libdiskmgt_empty_desc_array(int *errp) 7867c478bd9Sstevel@tonic-gate { 7877c478bd9Sstevel@tonic-gate descriptor_t **empty; 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate empty = (descriptor_t **)calloc(1, sizeof (descriptor_t *)); 7907c478bd9Sstevel@tonic-gate if (empty == NULL) { 7917c478bd9Sstevel@tonic-gate *errp = ENOMEM; 7927c478bd9Sstevel@tonic-gate return (NULL); 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate empty[0] = NULL; 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate *errp = 0; 7977c478bd9Sstevel@tonic-gate return (empty); 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate void 8017c478bd9Sstevel@tonic-gate libdiskmgt_init_debug() 8027c478bd9Sstevel@tonic-gate { 8037c478bd9Sstevel@tonic-gate char *valp; 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate if ((valp = getenv(DM_DEBUG)) != NULL) { 8067c478bd9Sstevel@tonic-gate dm_debug = atoi(valp); 8077c478bd9Sstevel@tonic-gate } 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate int 8117c478bd9Sstevel@tonic-gate libdiskmgt_str_eq(char *nm1, char *nm2) 8127c478bd9Sstevel@tonic-gate { 8137c478bd9Sstevel@tonic-gate if (nm1 == NULL) { 8147c478bd9Sstevel@tonic-gate if (dm_debug) { 8157c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "WARNING: str_eq nm1 NULL\n"); 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 8197c478bd9Sstevel@tonic-gate return (1); 8207c478bd9Sstevel@tonic-gate } else { 8217c478bd9Sstevel@tonic-gate return (0); 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate /* nm1 != NULL */ 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 8287c478bd9Sstevel@tonic-gate if (dm_debug) { 8297c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "WARNING: str_eq nm2 NULL\n"); 8307c478bd9Sstevel@tonic-gate } 8317c478bd9Sstevel@tonic-gate return (0); 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate if (strcmp(nm1, nm2) == 0) { 8357c478bd9Sstevel@tonic-gate return (1); 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate return (0); 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8427c478bd9Sstevel@tonic-gate static descriptor_t ** 8437c478bd9Sstevel@tonic-gate desc_array_to_ptr_array(dm_descriptor_t *descs, int *errp) 8447c478bd9Sstevel@tonic-gate { 8457c478bd9Sstevel@tonic-gate #ifdef _LP64 8467c478bd9Sstevel@tonic-gate return ((descriptor_t **)descs); 8477c478bd9Sstevel@tonic-gate #else 8487c478bd9Sstevel@tonic-gate /* convert the 64 bit descriptors to 32 bit ptrs */ 8497c478bd9Sstevel@tonic-gate int cnt; 8507c478bd9Sstevel@tonic-gate int i; 8517c478bd9Sstevel@tonic-gate descriptor_t **da; 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate for (cnt = 0; descs[cnt]; cnt++); 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate da = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); 8567c478bd9Sstevel@tonic-gate if (da == NULL) { 8577c478bd9Sstevel@tonic-gate *errp = ENOMEM; 8587c478bd9Sstevel@tonic-gate return (NULL); 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate for (i = 0; descs[i]; i++) { 86269fb9702Smike_s da[i] = (descriptor_t *)(uintptr_t)descs[i]; 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate *errp = 0; 8657c478bd9Sstevel@tonic-gate free(descs); 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate return (da); 8687c478bd9Sstevel@tonic-gate #endif 8697c478bd9Sstevel@tonic-gate } 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8727c478bd9Sstevel@tonic-gate static dm_descriptor_t * 8737c478bd9Sstevel@tonic-gate ptr_array_to_desc_array(descriptor_t **ptrs, int *errp) 8747c478bd9Sstevel@tonic-gate { 8757c478bd9Sstevel@tonic-gate #ifdef _LP64 8767c478bd9Sstevel@tonic-gate return ((dm_descriptor_t *)ptrs); 8777c478bd9Sstevel@tonic-gate #else 8787c478bd9Sstevel@tonic-gate /* convert the 32 bit ptrs to the 64 bit descriptors */ 8797c478bd9Sstevel@tonic-gate int cnt; 8807c478bd9Sstevel@tonic-gate int i; 8817c478bd9Sstevel@tonic-gate dm_descriptor_t *da; 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate if (*errp != 0 || ptrs == NULL) { 8847c478bd9Sstevel@tonic-gate return (NULL); 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate for (cnt = 0; ptrs[cnt]; cnt++); 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate da = (dm_descriptor_t *)calloc(cnt + 1, sizeof (dm_descriptor_t)); 8907c478bd9Sstevel@tonic-gate if (da == NULL) { 8917c478bd9Sstevel@tonic-gate *errp = ENOMEM; 8927c478bd9Sstevel@tonic-gate return (NULL); 8937c478bd9Sstevel@tonic-gate } 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate for (i = 0; ptrs[i]; i++) { 8967c478bd9Sstevel@tonic-gate da[i] = (uintptr_t)ptrs[i]; 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate *errp = 0; 8997c478bd9Sstevel@tonic-gate free(ptrs); 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate return (da); 9027c478bd9Sstevel@tonic-gate #endif 9037c478bd9Sstevel@tonic-gate } 9043e1bd7a2Ssjelinek /* 9053e1bd7a2Ssjelinek * Build the usage string for the in use data. Return the build string in 9063e1bd7a2Ssjelinek * the msg parameter. This function takes care of reallocing all the memory 9073e1bd7a2Ssjelinek * for this usage string. Usage string is returned already formatted for 9083e1bd7a2Ssjelinek * localization. 9093e1bd7a2Ssjelinek */ 9103e1bd7a2Ssjelinek static int 9113e1bd7a2Ssjelinek build_usage_string(char *dname, char *by, char *data, char **msg, 9123e1bd7a2Ssjelinek int *found, int *errp) 9133e1bd7a2Ssjelinek { 9143e1bd7a2Ssjelinek int len0; 9153e1bd7a2Ssjelinek int len1; 9163e1bd7a2Ssjelinek char *use; 9173e1bd7a2Ssjelinek char *p; 9183e1bd7a2Ssjelinek 9193e1bd7a2Ssjelinek *errp = 0; 9203e1bd7a2Ssjelinek 9213e1bd7a2Ssjelinek dm_get_usage_string(by, data, &use); 9223e1bd7a2Ssjelinek if (!use) { 9233e1bd7a2Ssjelinek return (-1); 9243e1bd7a2Ssjelinek } 9253e1bd7a2Ssjelinek 9263e1bd7a2Ssjelinek if (*msg) 9273e1bd7a2Ssjelinek len0 = strlen(*msg); 9283e1bd7a2Ssjelinek else 9293e1bd7a2Ssjelinek len0 = 0; 9303e1bd7a2Ssjelinek /* LINTED */ 9313e1bd7a2Ssjelinek len1 = snprintf(NULL, 0, use, dname, data); 9323e1bd7a2Ssjelinek 9333e1bd7a2Ssjelinek /* 9343e1bd7a2Ssjelinek * If multiple in use details they 9353e1bd7a2Ssjelinek * are listed 1 per line for ease of 9363e1bd7a2Ssjelinek * reading. dm_find_usage_string 9373e1bd7a2Ssjelinek * formats these appropriately. 9383e1bd7a2Ssjelinek */ 9393e1bd7a2Ssjelinek if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) { 9403e1bd7a2Ssjelinek *errp = errno; 9413e1bd7a2Ssjelinek free(*msg); 9423e1bd7a2Ssjelinek return (-1); 9433e1bd7a2Ssjelinek } 9443e1bd7a2Ssjelinek *msg = p; 9453e1bd7a2Ssjelinek 9463e1bd7a2Ssjelinek /* LINTED */ 9473e1bd7a2Ssjelinek (void) snprintf(*msg + len0, len1 + 1, use, dname, data); 9483e1bd7a2Ssjelinek (*found)++; 9493e1bd7a2Ssjelinek return (0); 9503e1bd7a2Ssjelinek } 951