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 687c478bd9Sstevel@tonic-gate dm_free_descriptor(dm_descriptor_t desc) 697c478bd9Sstevel@tonic-gate { 707c478bd9Sstevel@tonic-gate descriptor_t *dp; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate if (desc == NULL) { 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 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 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 * 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 * 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 * 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 2547c478bd9Sstevel@tonic-gate dm_get_descriptor_by_name(dm_desc_type_t desc_type, char *name, int *errp) 2557c478bd9Sstevel@tonic-gate { 2567c478bd9Sstevel@tonic-gate dm_descriptor_t desc = NULL; 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 * 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 * 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 * 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 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 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 5193e1bd7a2Ssjelinek if (alias != NULL) { 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 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); 5543e1bd7a2Ssjelinek if (devp != NULL) { 5553e1bd7a2Ssjelinek *dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE, 5563e1bd7a2Ssjelinek errp); 5573e1bd7a2Ssjelinek dm_free_descriptor(devp); 5583e1bd7a2Ssjelinek } 5593e1bd7a2Ssjelinek } 5603e1bd7a2Ssjelinek 56146a2abf2Seschrock /* 56246a2abf2Seschrock * Checks for overlapping slices. If the given device is a slice, and it 56346a2abf2Seschrock * overlaps with any non-backup slice on the disk, return true with a detailed 56446a2abf2Seschrock * description similar to dm_inuse(). 56546a2abf2Seschrock */ 56646a2abf2Seschrock int 56746a2abf2Seschrock dm_isoverlapping(char *slicename, char **overlaps_with, int *errp) 56846a2abf2Seschrock { 56946a2abf2Seschrock dm_descriptor_t slice = NULL; 57046a2abf2Seschrock dm_descriptor_t *media = NULL; 57146a2abf2Seschrock dm_descriptor_t *slices = NULL; 57246a2abf2Seschrock int i = 0; 57346a2abf2Seschrock uint32_t in_snum; 57446a2abf2Seschrock uint64_t start_block = 0; 57546a2abf2Seschrock uint64_t end_block = 0; 57646a2abf2Seschrock uint64_t media_size = 0; 57746a2abf2Seschrock uint64_t size = 0; 57846a2abf2Seschrock nvlist_t *media_attrs = NULL; 57946a2abf2Seschrock nvlist_t *slice_attrs = NULL; 58046a2abf2Seschrock int ret = 0; 58146a2abf2Seschrock 58246a2abf2Seschrock slice = dm_get_descriptor_by_name(DM_SLICE, slicename, errp); 58346a2abf2Seschrock if (slice == NULL) 58446a2abf2Seschrock goto out; 58546a2abf2Seschrock 58646a2abf2Seschrock /* 58746a2abf2Seschrock * Get the list of slices be fetching the associated media, and then all 58846a2abf2Seschrock * associated slices. 58946a2abf2Seschrock */ 59046a2abf2Seschrock media = dm_get_associated_descriptors(slice, DM_MEDIA, errp); 59146a2abf2Seschrock if (media == NULL || *media == NULL || *errp != 0) 59246a2abf2Seschrock goto out; 59346a2abf2Seschrock 59446a2abf2Seschrock slices = dm_get_associated_descriptors(*media, DM_SLICE, errp); 59546a2abf2Seschrock if (slices == NULL || *slices == NULL || *errp != 0) 59646a2abf2Seschrock goto out; 59746a2abf2Seschrock 59846a2abf2Seschrock media_attrs = dm_get_attributes(*media, errp); 59946a2abf2Seschrock if (media_attrs == NULL || *errp) 60046a2abf2Seschrock goto out; 60146a2abf2Seschrock 60246a2abf2Seschrock *errp = nvlist_lookup_uint64(media_attrs, DM_NACCESSIBLE, &media_size); 60346a2abf2Seschrock if (*errp != 0) 60446a2abf2Seschrock goto out; 60546a2abf2Seschrock 60646a2abf2Seschrock slice_attrs = dm_get_attributes(slice, errp); 60746a2abf2Seschrock if (slice_attrs == NULL || *errp != 0) 60846a2abf2Seschrock goto out; 60946a2abf2Seschrock 61046a2abf2Seschrock *errp = nvlist_lookup_uint64(slice_attrs, DM_START, &start_block); 61146a2abf2Seschrock if (*errp != 0) 61246a2abf2Seschrock goto out; 61346a2abf2Seschrock 61446a2abf2Seschrock *errp = nvlist_lookup_uint64(slice_attrs, DM_SIZE, &size); 61546a2abf2Seschrock if (*errp != 0) 61646a2abf2Seschrock goto out; 61746a2abf2Seschrock 61846a2abf2Seschrock *errp = nvlist_lookup_uint32(slice_attrs, DM_INDEX, &in_snum); 61946a2abf2Seschrock if (*errp != 0) 62046a2abf2Seschrock goto out; 62146a2abf2Seschrock 62246a2abf2Seschrock end_block = (start_block + size) - 1; 62346a2abf2Seschrock 62446a2abf2Seschrock for (i = 0; slices[i]; i ++) { 62546a2abf2Seschrock uint64_t other_start; 62646a2abf2Seschrock uint64_t other_end; 62746a2abf2Seschrock uint64_t other_size; 62846a2abf2Seschrock uint32_t snum; 62946a2abf2Seschrock 63046a2abf2Seschrock nvlist_t *other_attrs = dm_get_attributes(slices[i], errp); 63146a2abf2Seschrock 63246a2abf2Seschrock if (other_attrs == NULL) 63346a2abf2Seschrock continue; 63446a2abf2Seschrock 63546a2abf2Seschrock if (*errp != 0) 63646a2abf2Seschrock goto out; 63746a2abf2Seschrock 63846a2abf2Seschrock *errp = nvlist_lookup_uint64(other_attrs, DM_START, 63946a2abf2Seschrock &other_start); 64046a2abf2Seschrock if (*errp) { 64146a2abf2Seschrock nvlist_free(other_attrs); 64246a2abf2Seschrock goto out; 64346a2abf2Seschrock } 64446a2abf2Seschrock 64546a2abf2Seschrock *errp = nvlist_lookup_uint64(other_attrs, DM_SIZE, 64646a2abf2Seschrock &other_size); 64746a2abf2Seschrock 64846a2abf2Seschrock if (*errp) { 64946a2abf2Seschrock nvlist_free(other_attrs); 65046a2abf2Seschrock ret = -1; 65146a2abf2Seschrock goto out; 65246a2abf2Seschrock } 65346a2abf2Seschrock 65446a2abf2Seschrock other_end = (other_size + other_start) - 1; 65546a2abf2Seschrock 65646a2abf2Seschrock *errp = nvlist_lookup_uint32(other_attrs, DM_INDEX, 65746a2abf2Seschrock &snum); 65846a2abf2Seschrock 65946a2abf2Seschrock if (*errp) { 66046a2abf2Seschrock nvlist_free(other_attrs); 66146a2abf2Seschrock ret = -1; 66246a2abf2Seschrock goto out; 66346a2abf2Seschrock } 66446a2abf2Seschrock 66546a2abf2Seschrock /* 66646a2abf2Seschrock * Check to see if there are > 2 overlapping regions 66746a2abf2Seschrock * on this media in the same region as this slice. 66846a2abf2Seschrock * This is done by assuming the following: 66946a2abf2Seschrock * Slice 2 is the backup slice if it is the size 67046a2abf2Seschrock * of the whole disk 67146a2abf2Seschrock * If slice 2 is the overlap and slice 2 is the size of 67246a2abf2Seschrock * the whole disk, continue. If another slice is found 67346a2abf2Seschrock * that overlaps with our slice, return it. 67446a2abf2Seschrock * There is the potential that there is more than one slice 67546a2abf2Seschrock * that our slice overlaps with, however, we only return 67646a2abf2Seschrock * the first overlapping slice we find. 67746a2abf2Seschrock * 67846a2abf2Seschrock */ 67946a2abf2Seschrock if (start_block >= other_start && start_block <= other_end) { 68046a2abf2Seschrock if ((snum == 2 && (other_size == media_size)) || 68146a2abf2Seschrock snum == in_snum) { 68246a2abf2Seschrock continue; 68346a2abf2Seschrock } else { 68446a2abf2Seschrock char *str = dm_get_name(slices[i], errp); 68546a2abf2Seschrock if (*errp != 0) { 68646a2abf2Seschrock nvlist_free(other_attrs); 68746a2abf2Seschrock ret = -1; 68846a2abf2Seschrock goto out; 68946a2abf2Seschrock } 69046a2abf2Seschrock *overlaps_with = strdup(str); 69146a2abf2Seschrock dm_free_name(str); 69246a2abf2Seschrock nvlist_free(other_attrs); 69346a2abf2Seschrock ret = 1; 69446a2abf2Seschrock goto out; 69546a2abf2Seschrock } 69646a2abf2Seschrock } else if (other_start >= start_block && 69746a2abf2Seschrock other_start <= end_block) { 69846a2abf2Seschrock if ((snum == 2 && (other_size == media_size)) || 69946a2abf2Seschrock snum == in_snum) { 70046a2abf2Seschrock continue; 70146a2abf2Seschrock } else { 70246a2abf2Seschrock char *str = dm_get_name(slices[i], errp); 70346a2abf2Seschrock if (*errp != 0) { 70446a2abf2Seschrock nvlist_free(other_attrs); 70546a2abf2Seschrock ret = -1; 70646a2abf2Seschrock goto out; 70746a2abf2Seschrock } 70846a2abf2Seschrock *overlaps_with = strdup(str); 70946a2abf2Seschrock dm_free_name(str); 71046a2abf2Seschrock nvlist_free(other_attrs); 71146a2abf2Seschrock ret = 1; 71246a2abf2Seschrock goto out; 71346a2abf2Seschrock } 71446a2abf2Seschrock } 71546a2abf2Seschrock nvlist_free(other_attrs); 71646a2abf2Seschrock } 71746a2abf2Seschrock 71846a2abf2Seschrock out: 719*aab83bb8SJosef 'Jeff' Sipek nvlist_free(media_attrs); 720*aab83bb8SJosef 'Jeff' Sipek nvlist_free(slice_attrs); 72146a2abf2Seschrock 72246a2abf2Seschrock if (slices) 72346a2abf2Seschrock dm_free_descriptors(slices); 72446a2abf2Seschrock if (media) 72546a2abf2Seschrock dm_free_descriptors(media); 72646a2abf2Seschrock if (slice) 72746a2abf2Seschrock dm_free_descriptor(slice); 72846a2abf2Seschrock 72946a2abf2Seschrock return (ret); 73046a2abf2Seschrock } 73146a2abf2Seschrock 732181c2f42Smmusante /* 733181c2f42Smmusante * Get the full list of swap entries. Returns -1 on error, or >= 0 to 734181c2f42Smmusante * indicate the number of entries in the list. Callers are responsible 735181c2f42Smmusante * for calling dm_free_swapentries() to deallocate memory. If this 736181c2f42Smmusante * returns 0, the swaptbl_t still needs to be freed. 737181c2f42Smmusante */ 738181c2f42Smmusante int 739181c2f42Smmusante dm_get_swapentries(swaptbl_t **stp, int *errp) 740181c2f42Smmusante { 741181c2f42Smmusante int count, i; 742181c2f42Smmusante swaptbl_t *tbl; 743181c2f42Smmusante char *ptr; 744181c2f42Smmusante 745181c2f42Smmusante *stp = NULL; 746181c2f42Smmusante 747181c2f42Smmusante /* get number of swap entries */ 748181c2f42Smmusante if ((count = swapctl(SC_GETNSWP, NULL)) < 0) { 749181c2f42Smmusante *errp = errno; 750181c2f42Smmusante return (-1); 751181c2f42Smmusante } 752181c2f42Smmusante 753181c2f42Smmusante if (count == 0) { 754181c2f42Smmusante return (0); 755181c2f42Smmusante } 756181c2f42Smmusante 757181c2f42Smmusante /* allocate space */ 758181c2f42Smmusante tbl = calloc(1, sizeof (int) + count * sizeof (swapent_t)); 759181c2f42Smmusante if (tbl == NULL) { 760181c2f42Smmusante *errp = ENOMEM; 761181c2f42Smmusante return (-1); 762181c2f42Smmusante } 763181c2f42Smmusante 764181c2f42Smmusante ptr = calloc(1, count * MAXPATHLEN); 765181c2f42Smmusante if (ptr == NULL) { 766181c2f42Smmusante *errp = ENOMEM; 767181c2f42Smmusante free(tbl); 768181c2f42Smmusante return (-1); 769181c2f42Smmusante } 770181c2f42Smmusante 771181c2f42Smmusante /* set up pointers to the pathnames */ 772181c2f42Smmusante tbl->swt_n = count; 773181c2f42Smmusante for (i = 0; i < count; i++) { 774181c2f42Smmusante tbl->swt_ent[i].ste_path = ptr; 775181c2f42Smmusante ptr += MAXPATHLEN; 776181c2f42Smmusante } 777181c2f42Smmusante 778181c2f42Smmusante /* get list of swap paths */ 779181c2f42Smmusante count = swapctl(SC_LIST, tbl); 780181c2f42Smmusante if (count < 0) { 781181c2f42Smmusante *errp = errno; 782181c2f42Smmusante free(ptr); 783181c2f42Smmusante free(tbl); 784181c2f42Smmusante return (-1); 785181c2f42Smmusante } 786181c2f42Smmusante 787181c2f42Smmusante *stp = tbl; 788181c2f42Smmusante return (count); 789181c2f42Smmusante } 790181c2f42Smmusante 791181c2f42Smmusante /* ARGSUSED */ 792181c2f42Smmusante void 793181c2f42Smmusante dm_free_swapentries(swaptbl_t *stp) 794181c2f42Smmusante { 795181c2f42Smmusante ASSERT(stp != NULL); 796181c2f42Smmusante 797181c2f42Smmusante free(stp->swt_ent[0].ste_path); 798181c2f42Smmusante free(stp); 799181c2f42Smmusante } 800181c2f42Smmusante 801181c2f42Smmusante /* 802181c2f42Smmusante * Check a slice to see if it's being used by swap. 803181c2f42Smmusante */ 804181c2f42Smmusante int 805181c2f42Smmusante dm_inuse_swap(const char *dev_name, int *errp) 806181c2f42Smmusante { 807181c2f42Smmusante int count; 808181c2f42Smmusante int found; 809181c2f42Smmusante swaptbl_t *tbl = NULL; 810181c2f42Smmusante 811181c2f42Smmusante *errp = 0; 812181c2f42Smmusante 813181c2f42Smmusante count = dm_get_swapentries(&tbl, errp); 814181c2f42Smmusante if (count < 0 || *errp) { 815181c2f42Smmusante if (tbl) 816181c2f42Smmusante dm_free_swapentries(tbl); 817181c2f42Smmusante return (-1); 818181c2f42Smmusante } 819181c2f42Smmusante 820181c2f42Smmusante /* if there are no swap entries, we're done */ 821181c2f42Smmusante if (!count) { 822181c2f42Smmusante return (0); 823181c2f42Smmusante } 824181c2f42Smmusante 825181c2f42Smmusante ASSERT(tbl != NULL); 826181c2f42Smmusante 827181c2f42Smmusante found = 0; 828181c2f42Smmusante while (count--) { 829181c2f42Smmusante if (strcmp(dev_name, tbl->swt_ent[count].ste_path) == 0) { 830181c2f42Smmusante found = 1; 831181c2f42Smmusante break; 832181c2f42Smmusante } 833181c2f42Smmusante } 834181c2f42Smmusante 835181c2f42Smmusante dm_free_swapentries(tbl); 836181c2f42Smmusante return (found); 837181c2f42Smmusante } 838181c2f42Smmusante 8393e1bd7a2Ssjelinek /* 8403e1bd7a2Ssjelinek * Returns 'in use' details, if found, about a specific dev_name, 8413e1bd7a2Ssjelinek * based on the caller(who). It is important to note that it is possible 8423e1bd7a2Ssjelinek * for there to be more than one 'in use' statistic regarding a dev_name. 8433e1bd7a2Ssjelinek * The **msg parameter returns a list of 'in use' details. This message 8443e1bd7a2Ssjelinek * is formatted via gettext(). 8453e1bd7a2Ssjelinek */ 8463e1bd7a2Ssjelinek int 8473e1bd7a2Ssjelinek dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp) 8483e1bd7a2Ssjelinek { 8493e1bd7a2Ssjelinek nvlist_t *dev_stats = NULL; 8503e1bd7a2Ssjelinek char *by, *data; 8513e1bd7a2Ssjelinek nvpair_t *nvwhat = NULL; 8523e1bd7a2Ssjelinek nvpair_t *nvdesc = NULL; 8533e1bd7a2Ssjelinek int found = 0; 854181c2f42Smmusante int err; 8553e1bd7a2Ssjelinek char *dname = NULL; 8563e1bd7a2Ssjelinek 8573e1bd7a2Ssjelinek *errp = 0; 8583e1bd7a2Ssjelinek *msg = NULL; 8593e1bd7a2Ssjelinek 86082d71480Ssjelinek /* 86182d71480Ssjelinek * If the user doesn't want to do in use checking, return. 86282d71480Ssjelinek */ 86382d71480Ssjelinek 86482d71480Ssjelinek if (NOINUSE_SET) 86582d71480Ssjelinek return (0); 86682d71480Ssjelinek 8673e1bd7a2Ssjelinek dname = getfullblkname(dev_name); 8683e1bd7a2Ssjelinek /* 8693e1bd7a2Ssjelinek * If we cannot find the block name, we cannot check the device 8703e1bd7a2Ssjelinek * for in use statistics. So, return found, which is == 0. 8713e1bd7a2Ssjelinek */ 8723e1bd7a2Ssjelinek if (dname == NULL || *dname == '\0') { 8733e1bd7a2Ssjelinek return (found); 8743e1bd7a2Ssjelinek } 8753e1bd7a2Ssjelinek 876181c2f42Smmusante /* 877181c2f42Smmusante * Slice stats for swap devices are only returned if mounted 878181c2f42Smmusante * (e.g. /tmp). Other devices or files being used for swap 879181c2f42Smmusante * are ignored, so we add a special check here to use swapctl(2) 880181c2f42Smmusante * to perform in-use checking. 881181c2f42Smmusante */ 882181c2f42Smmusante if (ANY_ZPOOL_USE(who) && (err = dm_inuse_swap(dname, errp))) { 883181c2f42Smmusante 884181c2f42Smmusante /* on error, dm_inuse_swap sets errp */ 885181c2f42Smmusante if (err < 0) { 886181c2f42Smmusante free(dname); 887181c2f42Smmusante return (err); 888181c2f42Smmusante } 889181c2f42Smmusante 890181c2f42Smmusante /* simulate a mounted swap device */ 891181c2f42Smmusante (void) build_usage_string(dname, DM_USE_MOUNT, "swap", msg, 892181c2f42Smmusante &found, errp); 893181c2f42Smmusante 894181c2f42Smmusante /* if this fails, dm_get_usage_string changed */ 895181c2f42Smmusante ASSERT(found == 1); 896181c2f42Smmusante 897181c2f42Smmusante free(dname); 898181c2f42Smmusante return (found); 899181c2f42Smmusante } 900181c2f42Smmusante 9013e1bd7a2Ssjelinek dm_get_slice_stats(dname, &dev_stats, errp); 9023e1bd7a2Ssjelinek if (dev_stats == NULL) { 9033e1bd7a2Ssjelinek /* 9043e1bd7a2Ssjelinek * If there is an error, but it isn't a no device found error 9053e1bd7a2Ssjelinek * return the error as recorded. Otherwise, with a full 9063e1bd7a2Ssjelinek * block name, we might not be able to get the slice 9073e1bd7a2Ssjelinek * associated, and will get an ENODEV error. For example, 9083e1bd7a2Ssjelinek * an SVM metadevice will return a value from getfullblkname() 9093e1bd7a2Ssjelinek * but libdiskmgt won't be able to find this device for 9103e1bd7a2Ssjelinek * statistics gathering. This is expected and we should not 9113e1bd7a2Ssjelinek * report errnoneous errors. 9123e1bd7a2Ssjelinek */ 9133e1bd7a2Ssjelinek if (*errp) { 9143e1bd7a2Ssjelinek if (*errp == ENODEV) { 9153e1bd7a2Ssjelinek *errp = 0; 9163e1bd7a2Ssjelinek } 9173e1bd7a2Ssjelinek } 9183e1bd7a2Ssjelinek free(dname); 9193e1bd7a2Ssjelinek return (found); 9203e1bd7a2Ssjelinek } 9213e1bd7a2Ssjelinek 9223e1bd7a2Ssjelinek for (;;) { 9233e1bd7a2Ssjelinek 9243e1bd7a2Ssjelinek nvwhat = nvlist_next_nvpair(dev_stats, nvdesc); 9253e1bd7a2Ssjelinek nvdesc = nvlist_next_nvpair(dev_stats, nvwhat); 9263e1bd7a2Ssjelinek 9273e1bd7a2Ssjelinek /* 9283e1bd7a2Ssjelinek * End of the list found. 9293e1bd7a2Ssjelinek */ 9303e1bd7a2Ssjelinek if (nvwhat == NULL || nvdesc == NULL) { 9313e1bd7a2Ssjelinek break; 9323e1bd7a2Ssjelinek } 9333e1bd7a2Ssjelinek /* 9343e1bd7a2Ssjelinek * Otherwise, we check to see if this client(who) cares 9353e1bd7a2Ssjelinek * about this in use scenario 9363e1bd7a2Ssjelinek */ 9373e1bd7a2Ssjelinek 9383e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0); 9393e1bd7a2Ssjelinek ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0); 9403e1bd7a2Ssjelinek /* 9413e1bd7a2Ssjelinek * If we error getting the string value continue on 9423e1bd7a2Ssjelinek * to the next pair(if there is one) 9433e1bd7a2Ssjelinek */ 9443e1bd7a2Ssjelinek if (nvpair_value_string(nvwhat, &by)) { 9453e1bd7a2Ssjelinek continue; 9463e1bd7a2Ssjelinek } 9473e1bd7a2Ssjelinek if (nvpair_value_string(nvdesc, &data)) { 9483e1bd7a2Ssjelinek continue; 9493e1bd7a2Ssjelinek } 9503e1bd7a2Ssjelinek 9513e1bd7a2Ssjelinek switch (who) { 9523e1bd7a2Ssjelinek case DM_WHO_MKFS: 9533e1bd7a2Ssjelinek /* 9543e1bd7a2Ssjelinek * mkfs is not in use for these cases. 9553e1bd7a2Ssjelinek * All others are in use. 9563e1bd7a2Ssjelinek */ 9573e1bd7a2Ssjelinek if (strcmp(by, DM_USE_LU) == 0 || 95846a2abf2Seschrock strcmp(by, DM_USE_FS) == 0 || 95946a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) { 9603e1bd7a2Ssjelinek break; 9613e1bd7a2Ssjelinek } 9623e1bd7a2Ssjelinek if (build_usage_string(dname, 9633e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 9643e1bd7a2Ssjelinek if (*errp) { 9653e1bd7a2Ssjelinek goto out; 9663e1bd7a2Ssjelinek } 9673e1bd7a2Ssjelinek } 9683e1bd7a2Ssjelinek break; 9693e1bd7a2Ssjelinek case DM_WHO_SWAP: 9703e1bd7a2Ssjelinek /* 9713e1bd7a2Ssjelinek * Not in use for this. 9723e1bd7a2Ssjelinek */ 9733e1bd7a2Ssjelinek if (strcmp(by, DM_USE_DUMP) == 0 || 97446a2abf2Seschrock strcmp(by, DM_USE_FS) == 0 || 97546a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) { 9763e1bd7a2Ssjelinek break; 9773e1bd7a2Ssjelinek } 978efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (strcmp(by, DM_USE_LU) == 0 && 979efd79defSsriman bhavanam - Sun Microsystems - Bangalore India strcmp(data, "-") == 0) { 980efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break; 981efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } 982efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (strcmp(by, DM_USE_VFSTAB) == 0 && 983efd79defSsriman bhavanam - Sun Microsystems - Bangalore India strcmp(data, "") == 0) { 984efd79defSsriman bhavanam - Sun Microsystems - Bangalore India break; 985efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } 9863e1bd7a2Ssjelinek if (build_usage_string(dname, 9873e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 9883e1bd7a2Ssjelinek if (*errp) { 9893e1bd7a2Ssjelinek goto out; 9903e1bd7a2Ssjelinek } 9913e1bd7a2Ssjelinek } 9923e1bd7a2Ssjelinek break; 9933e1bd7a2Ssjelinek case DM_WHO_DUMP: 9943e1bd7a2Ssjelinek /* 9953e1bd7a2Ssjelinek * Not in use for this. 9963e1bd7a2Ssjelinek */ 9973e1bd7a2Ssjelinek if ((strcmp(by, DM_USE_MOUNT) == 0 && 9983e1bd7a2Ssjelinek strcmp(data, "swap") == 0) || 9993e1bd7a2Ssjelinek strcmp(by, DM_USE_DUMP) == 0 || 100046a2abf2Seschrock strcmp(by, DM_USE_FS) == 0 || 100146a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) { 10023e1bd7a2Ssjelinek break; 10033e1bd7a2Ssjelinek } 10043e1bd7a2Ssjelinek if (build_usage_string(dname, 10053e1bd7a2Ssjelinek by, data, msg, &found, errp)) { 10063e1bd7a2Ssjelinek if (*errp) { 10073e1bd7a2Ssjelinek goto out; 10083e1bd7a2Ssjelinek } 10093e1bd7a2Ssjelinek } 10103e1bd7a2Ssjelinek break; 10113e1bd7a2Ssjelinek 10123e1bd7a2Ssjelinek case DM_WHO_FORMAT: 101346a2abf2Seschrock if (strcmp(by, DM_USE_FS) == 0 || 101446a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) 10153e1bd7a2Ssjelinek break; 10163e1bd7a2Ssjelinek if (build_usage_string(dname, 10173e1bd7a2Ssjelinek by, data, msg, &found, errp) != 0) { 10183e1bd7a2Ssjelinek if (*errp) { 10193e1bd7a2Ssjelinek goto out; 10203e1bd7a2Ssjelinek } 10213e1bd7a2Ssjelinek } 10223e1bd7a2Ssjelinek break; 102346a2abf2Seschrock 102446a2abf2Seschrock case DM_WHO_ZPOOL_FORCE: 102546a2abf2Seschrock if (strcmp(by, DM_USE_FS) == 0 || 102646a2abf2Seschrock strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) 102746a2abf2Seschrock break; 102846a2abf2Seschrock /* FALLTHROUGH */ 102946a2abf2Seschrock case DM_WHO_ZPOOL: 103046a2abf2Seschrock if (build_usage_string(dname, 103146a2abf2Seschrock by, data, msg, &found, errp) != 0) { 103246a2abf2Seschrock if (*errp) 103346a2abf2Seschrock goto out; 103446a2abf2Seschrock } 103546a2abf2Seschrock break; 103646a2abf2Seschrock 103746657f8dSmmusante case DM_WHO_ZPOOL_SPARE: 103846657f8dSmmusante if (strcmp(by, DM_USE_SPARE_ZPOOL) != 0) { 103946657f8dSmmusante if (build_usage_string(dname, by, 104046657f8dSmmusante data, msg, &found, errp) != 0) { 104146657f8dSmmusante if (*errp) 104246657f8dSmmusante goto out; 104346657f8dSmmusante } 104446657f8dSmmusante } 104546657f8dSmmusante break; 104646657f8dSmmusante 10473e1bd7a2Ssjelinek default: 10483e1bd7a2Ssjelinek /* 10493e1bd7a2Ssjelinek * nothing found in use for this client 10503e1bd7a2Ssjelinek * of libdiskmgt. Default is 'not in use'. 10513e1bd7a2Ssjelinek */ 10523e1bd7a2Ssjelinek break; 10533e1bd7a2Ssjelinek } 10543e1bd7a2Ssjelinek } 10553e1bd7a2Ssjelinek out: 10563e1bd7a2Ssjelinek if (dname != NULL) 10573e1bd7a2Ssjelinek free(dname); 1058*aab83bb8SJosef 'Jeff' Sipek nvlist_free(dev_stats); 10593e1bd7a2Ssjelinek 10603e1bd7a2Ssjelinek return (found); 10613e1bd7a2Ssjelinek } 10623e1bd7a2Ssjelinek 10633e1bd7a2Ssjelinek void 10643e1bd7a2Ssjelinek dm_get_usage_string(char *what, char *how, char **usage_string) 10653e1bd7a2Ssjelinek { 10663e1bd7a2Ssjelinek 10673e1bd7a2Ssjelinek 10683e1bd7a2Ssjelinek if (usage_string == NULL || what == NULL) { 10693e1bd7a2Ssjelinek return; 10703e1bd7a2Ssjelinek } 10713e1bd7a2Ssjelinek *usage_string = NULL; 10723e1bd7a2Ssjelinek 10733e1bd7a2Ssjelinek if (strcmp(what, DM_USE_MOUNT) == 0) { 10743e1bd7a2Ssjelinek if (strcmp(how, "swap") == 0) { 10753e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 10763e1bd7a2Ssjelinek "%s is currently used by swap. Please see swap(1M)." 10773e1bd7a2Ssjelinek "\n"); 10783e1bd7a2Ssjelinek } else { 10793e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 10803e1bd7a2Ssjelinek "%s is currently mounted on %s." 10813e1bd7a2Ssjelinek " Please see umount(1M).\n"); 10823e1bd7a2Ssjelinek } 10833e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VFSTAB) == 0) { 10843e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 10853e1bd7a2Ssjelinek "%s is normally mounted on %s according to /etc/vfstab. " 10863e1bd7a2Ssjelinek "Please remove this entry to use this device.\n"); 10873e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_FS) == 0) { 10883e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 108946a2abf2Seschrock "%s contains a %s filesystem.\n"); 10903e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_SVM) == 0) { 10913e1bd7a2Ssjelinek if (strcmp(how, "mdb") == 0) { 10923e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 10933e1bd7a2Ssjelinek "%s contains an SVM %s. Please see " 10943e1bd7a2Ssjelinek "metadb(1M).\n"); 10953e1bd7a2Ssjelinek } else { 10963e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 10973e1bd7a2Ssjelinek "%s is part of SVM volume %s. " 10983e1bd7a2Ssjelinek "Please see metaclear(1M).\n"); 10993e1bd7a2Ssjelinek } 11003e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_VXVM) == 0) { 11013e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 11023e1bd7a2Ssjelinek "%s is part of VxVM volume %s.\n"); 11033e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_LU) == 0) { 11043e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 11053e1bd7a2Ssjelinek "%s is in use for live upgrade %s. Please see ludelete(1M)." 11063e1bd7a2Ssjelinek "\n"); 11073e1bd7a2Ssjelinek } else if (strcmp(what, DM_USE_DUMP) == 0) { 11083e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 11093e1bd7a2Ssjelinek "%s is in use by %s. Please see dumpadm(1M)." 11103e1bd7a2Ssjelinek "\n"); 111146a2abf2Seschrock } else if (strcmp(what, DM_USE_EXPORTED_ZPOOL) == 0) { 111246a2abf2Seschrock *usage_string = dgettext(TEXT_DOMAIN, 111346a2abf2Seschrock "%s is part of exported or potentially active ZFS pool %s. " 111446a2abf2Seschrock "Please see zpool(1M).\n"); 111546a2abf2Seschrock } else if (strcmp(what, DM_USE_ACTIVE_ZPOOL) == 0) { 11163e1bd7a2Ssjelinek *usage_string = dgettext(TEXT_DOMAIN, 111746a2abf2Seschrock "%s is part of active ZFS pool %s. Please see zpool(1M)." 11183e1bd7a2Ssjelinek "\n"); 111999653d4eSeschrock } else if (strcmp(what, DM_USE_SPARE_ZPOOL) == 0) { 112099653d4eSeschrock *usage_string = dgettext(TEXT_DOMAIN, 112199653d4eSeschrock "%s is reserved as a hot spare for ZFS pool %s. Please " 112299653d4eSeschrock "see zpool(1M).\n"); 1123fa94a07fSbrendan } else if (strcmp(what, DM_USE_L2CACHE_ZPOOL) == 0) { 1124fa94a07fSbrendan *usage_string = dgettext(TEXT_DOMAIN, 1125fa94a07fSbrendan "%s is in use as a cache device for ZFS pool %s. " 1126fa94a07fSbrendan "Please see zpool(1M).\n"); 11273e1bd7a2Ssjelinek } 11283e1bd7a2Ssjelinek } 11297c478bd9Sstevel@tonic-gate void 11307c478bd9Sstevel@tonic-gate libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp) 11317c478bd9Sstevel@tonic-gate { 11327c478bd9Sstevel@tonic-gate if (*errp == 0) { 11337c478bd9Sstevel@tonic-gate *errp = nvlist_add_string(attrs, name, val); 11347c478bd9Sstevel@tonic-gate } 11357c478bd9Sstevel@tonic-gate } 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate descriptor_t ** 11387c478bd9Sstevel@tonic-gate libdiskmgt_empty_desc_array(int *errp) 11397c478bd9Sstevel@tonic-gate { 11407c478bd9Sstevel@tonic-gate descriptor_t **empty; 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate empty = (descriptor_t **)calloc(1, sizeof (descriptor_t *)); 11437c478bd9Sstevel@tonic-gate if (empty == NULL) { 1144efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM; 1145efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL); 11467c478bd9Sstevel@tonic-gate } 11477c478bd9Sstevel@tonic-gate empty[0] = NULL; 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate *errp = 0; 11507c478bd9Sstevel@tonic-gate return (empty); 11517c478bd9Sstevel@tonic-gate } 11527c478bd9Sstevel@tonic-gate 11537c478bd9Sstevel@tonic-gate void 11547c478bd9Sstevel@tonic-gate libdiskmgt_init_debug() 11557c478bd9Sstevel@tonic-gate { 11567c478bd9Sstevel@tonic-gate char *valp; 11577c478bd9Sstevel@tonic-gate 11587c478bd9Sstevel@tonic-gate if ((valp = getenv(DM_DEBUG)) != NULL) { 1159efd79defSsriman bhavanam - Sun Microsystems - Bangalore India dm_debug = atoi(valp); 11607c478bd9Sstevel@tonic-gate } 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate 11637c478bd9Sstevel@tonic-gate int 11647c478bd9Sstevel@tonic-gate libdiskmgt_str_eq(char *nm1, char *nm2) 11657c478bd9Sstevel@tonic-gate { 11667c478bd9Sstevel@tonic-gate if (nm1 == NULL) { 1167efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (dm_debug) { 1168efd79defSsriman bhavanam - Sun Microsystems - Bangalore India (void) fprintf(stderr, "WARNING: str_eq nm1 NULL\n"); 1169efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } 11707c478bd9Sstevel@tonic-gate 1171efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (nm2 == NULL) { 1172efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (1); 1173efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } else { 1174efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (0); 1175efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } 11767c478bd9Sstevel@tonic-gate } 11777c478bd9Sstevel@tonic-gate 11787c478bd9Sstevel@tonic-gate /* nm1 != NULL */ 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 1181efd79defSsriman bhavanam - Sun Microsystems - Bangalore India if (dm_debug) { 1182efd79defSsriman bhavanam - Sun Microsystems - Bangalore India (void) fprintf(stderr, "WARNING: str_eq nm2 NULL\n"); 1183efd79defSsriman bhavanam - Sun Microsystems - Bangalore India } 1184efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (0); 11857c478bd9Sstevel@tonic-gate } 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate if (strcmp(nm1, nm2) == 0) { 1188efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (1); 11897c478bd9Sstevel@tonic-gate } 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate return (0); 11927c478bd9Sstevel@tonic-gate } 11937c478bd9Sstevel@tonic-gate 11947c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 11957c478bd9Sstevel@tonic-gate static descriptor_t ** 11967c478bd9Sstevel@tonic-gate desc_array_to_ptr_array(dm_descriptor_t *descs, int *errp) 11977c478bd9Sstevel@tonic-gate { 11987c478bd9Sstevel@tonic-gate #ifdef _LP64 11997c478bd9Sstevel@tonic-gate return ((descriptor_t **)descs); 12007c478bd9Sstevel@tonic-gate #else 12017c478bd9Sstevel@tonic-gate /* convert the 64 bit descriptors to 32 bit ptrs */ 12027c478bd9Sstevel@tonic-gate int cnt; 12037c478bd9Sstevel@tonic-gate int i; 12047c478bd9Sstevel@tonic-gate descriptor_t **da; 12057c478bd9Sstevel@tonic-gate 1206efd79defSsriman bhavanam - Sun Microsystems - Bangalore India for (cnt = 0; descs[cnt]; cnt++) 1207efd79defSsriman bhavanam - Sun Microsystems - Bangalore India ; 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate da = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); 12107c478bd9Sstevel@tonic-gate if (da == NULL) { 1211efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM; 1212efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL); 12137c478bd9Sstevel@tonic-gate } 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate for (i = 0; descs[i]; i++) { 1216efd79defSsriman bhavanam - Sun Microsystems - Bangalore India da[i] = (descriptor_t *)(uintptr_t)descs[i]; 12177c478bd9Sstevel@tonic-gate } 12187c478bd9Sstevel@tonic-gate *errp = 0; 12197c478bd9Sstevel@tonic-gate free(descs); 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate return (da); 12227c478bd9Sstevel@tonic-gate #endif 12237c478bd9Sstevel@tonic-gate } 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 12267c478bd9Sstevel@tonic-gate static dm_descriptor_t * 12277c478bd9Sstevel@tonic-gate ptr_array_to_desc_array(descriptor_t **ptrs, int *errp) 12287c478bd9Sstevel@tonic-gate { 12297c478bd9Sstevel@tonic-gate #ifdef _LP64 12307c478bd9Sstevel@tonic-gate return ((dm_descriptor_t *)ptrs); 12317c478bd9Sstevel@tonic-gate #else 12327c478bd9Sstevel@tonic-gate /* convert the 32 bit ptrs to the 64 bit descriptors */ 12337c478bd9Sstevel@tonic-gate int cnt; 12347c478bd9Sstevel@tonic-gate int i; 12357c478bd9Sstevel@tonic-gate dm_descriptor_t *da; 12367c478bd9Sstevel@tonic-gate 12377c478bd9Sstevel@tonic-gate if (*errp != 0 || ptrs == NULL) { 1238efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL); 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate 1241efd79defSsriman bhavanam - Sun Microsystems - Bangalore India for (cnt = 0; ptrs[cnt]; cnt++) 1242efd79defSsriman bhavanam - Sun Microsystems - Bangalore India ; 12437c478bd9Sstevel@tonic-gate 12447c478bd9Sstevel@tonic-gate da = (dm_descriptor_t *)calloc(cnt + 1, sizeof (dm_descriptor_t)); 12457c478bd9Sstevel@tonic-gate if (da == NULL) { 1246efd79defSsriman bhavanam - Sun Microsystems - Bangalore India *errp = ENOMEM; 1247efd79defSsriman bhavanam - Sun Microsystems - Bangalore India return (NULL); 12487c478bd9Sstevel@tonic-gate } 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate for (i = 0; ptrs[i]; i++) { 1251efd79defSsriman bhavanam - Sun Microsystems - Bangalore India da[i] = (uintptr_t)ptrs[i]; 12527c478bd9Sstevel@tonic-gate } 12537c478bd9Sstevel@tonic-gate *errp = 0; 12547c478bd9Sstevel@tonic-gate free(ptrs); 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate return (da); 12577c478bd9Sstevel@tonic-gate #endif 12587c478bd9Sstevel@tonic-gate } 12593e1bd7a2Ssjelinek /* 12603e1bd7a2Ssjelinek * Build the usage string for the in use data. Return the build string in 12613e1bd7a2Ssjelinek * the msg parameter. This function takes care of reallocing all the memory 12623e1bd7a2Ssjelinek * for this usage string. Usage string is returned already formatted for 12633e1bd7a2Ssjelinek * localization. 12643e1bd7a2Ssjelinek */ 12653e1bd7a2Ssjelinek static int 12663e1bd7a2Ssjelinek build_usage_string(char *dname, char *by, char *data, char **msg, 12673e1bd7a2Ssjelinek int *found, int *errp) 12683e1bd7a2Ssjelinek { 12693e1bd7a2Ssjelinek int len0; 12703e1bd7a2Ssjelinek int len1; 12713e1bd7a2Ssjelinek char *use; 12723e1bd7a2Ssjelinek char *p; 12733e1bd7a2Ssjelinek 12743e1bd7a2Ssjelinek *errp = 0; 12753e1bd7a2Ssjelinek 12763e1bd7a2Ssjelinek dm_get_usage_string(by, data, &use); 12773e1bd7a2Ssjelinek if (!use) { 12783e1bd7a2Ssjelinek return (-1); 12793e1bd7a2Ssjelinek } 12803e1bd7a2Ssjelinek 12813e1bd7a2Ssjelinek if (*msg) 12823e1bd7a2Ssjelinek len0 = strlen(*msg); 12833e1bd7a2Ssjelinek else 12843e1bd7a2Ssjelinek len0 = 0; 12853e1bd7a2Ssjelinek /* LINTED */ 12863e1bd7a2Ssjelinek len1 = snprintf(NULL, 0, use, dname, data); 12873e1bd7a2Ssjelinek 12883e1bd7a2Ssjelinek /* 12893e1bd7a2Ssjelinek * If multiple in use details they 12903e1bd7a2Ssjelinek * are listed 1 per line for ease of 12913e1bd7a2Ssjelinek * reading. dm_find_usage_string 12923e1bd7a2Ssjelinek * formats these appropriately. 12933e1bd7a2Ssjelinek */ 12943e1bd7a2Ssjelinek if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) { 12953e1bd7a2Ssjelinek *errp = errno; 12963e1bd7a2Ssjelinek free(*msg); 12973e1bd7a2Ssjelinek return (-1); 12983e1bd7a2Ssjelinek } 12993e1bd7a2Ssjelinek *msg = p; 13003e1bd7a2Ssjelinek 13013e1bd7a2Ssjelinek /* LINTED */ 13023e1bd7a2Ssjelinek (void) snprintf(*msg + len0, len1 + 1, use, dname, data); 13033e1bd7a2Ssjelinek (*found)++; 13043e1bd7a2Ssjelinek return (0); 13053e1bd7a2Ssjelinek } 1306