1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 30*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 31*7c478bd9Sstevel@tonic-gate #include <stdio.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 34*7c478bd9Sstevel@tonic-gate #include <unistd.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #include "libdiskmgt.h" 39*7c478bd9Sstevel@tonic-gate #include "disks_private.h" 40*7c478bd9Sstevel@tonic-gate #include "partition.h" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t drive_assoc_types[]; 44*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t bus_assoc_types[]; 45*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t controller_assoc_types[]; 46*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t media_assoc_types[]; 47*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t slice_assoc_types[]; 48*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t partition_assoc_types[]; 49*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t path_assoc_types[]; 50*7c478bd9Sstevel@tonic-gate extern dm_desc_type_t alias_assoc_types[]; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate static dm_descriptor_t *ptr_array_to_desc_array(descriptor_t **ptrs, int *errp); 53*7c478bd9Sstevel@tonic-gate static descriptor_t **desc_array_to_ptr_array(dm_descriptor_t *da, int *errp); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate void 56*7c478bd9Sstevel@tonic-gate dm_free_descriptor(dm_descriptor_t desc) 57*7c478bd9Sstevel@tonic-gate { 58*7c478bd9Sstevel@tonic-gate descriptor_t *dp; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate if (desc == NULL) { 61*7c478bd9Sstevel@tonic-gate return; 62*7c478bd9Sstevel@tonic-gate } 63*7c478bd9Sstevel@tonic-gate dp = (descriptor_t *)desc; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate cache_wlock(); 66*7c478bd9Sstevel@tonic-gate cache_free_descriptor(dp); 67*7c478bd9Sstevel@tonic-gate cache_unlock(); 68*7c478bd9Sstevel@tonic-gate } 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate void 71*7c478bd9Sstevel@tonic-gate dm_free_descriptors(dm_descriptor_t *desc_list) 72*7c478bd9Sstevel@tonic-gate { 73*7c478bd9Sstevel@tonic-gate descriptor_t **dp; 74*7c478bd9Sstevel@tonic-gate int error; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate if (desc_list == NULL) { 77*7c478bd9Sstevel@tonic-gate return; 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate dp = desc_array_to_ptr_array(desc_list, &error); 80*7c478bd9Sstevel@tonic-gate if (error != 0) { 81*7c478bd9Sstevel@tonic-gate free(desc_list); 82*7c478bd9Sstevel@tonic-gate return; 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate cache_wlock(); 86*7c478bd9Sstevel@tonic-gate cache_free_descriptors(dp); 87*7c478bd9Sstevel@tonic-gate cache_unlock(); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 91*7c478bd9Sstevel@tonic-gate void 92*7c478bd9Sstevel@tonic-gate dm_free_name(char *name) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate free(name); 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate dm_descriptor_t * 98*7c478bd9Sstevel@tonic-gate dm_get_associated_descriptors(dm_descriptor_t desc, dm_desc_type_t type, 99*7c478bd9Sstevel@tonic-gate int *errp) 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate descriptor_t **descs = NULL; 102*7c478bd9Sstevel@tonic-gate descriptor_t *dp; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate dp = (descriptor_t *)desc; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate cache_wlock(); 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 110*7c478bd9Sstevel@tonic-gate cache_unlock(); 111*7c478bd9Sstevel@tonic-gate *errp = EBADF; 112*7c478bd9Sstevel@tonic-gate return (NULL); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 116*7c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 117*7c478bd9Sstevel@tonic-gate cache_unlock(); 118*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 119*7c478bd9Sstevel@tonic-gate return (NULL); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate switch (dp->type) { 123*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 124*7c478bd9Sstevel@tonic-gate descs = drive_get_assoc_descriptors(dp, type, errp); 125*7c478bd9Sstevel@tonic-gate break; 126*7c478bd9Sstevel@tonic-gate case DM_BUS: 127*7c478bd9Sstevel@tonic-gate descs = bus_get_assoc_descriptors(dp, type, errp); 128*7c478bd9Sstevel@tonic-gate break; 129*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 130*7c478bd9Sstevel@tonic-gate descs = controller_get_assoc_descriptors(dp, type, errp); 131*7c478bd9Sstevel@tonic-gate break; 132*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 133*7c478bd9Sstevel@tonic-gate descs = media_get_assoc_descriptors(dp, type, errp); 134*7c478bd9Sstevel@tonic-gate break; 135*7c478bd9Sstevel@tonic-gate case DM_SLICE: 136*7c478bd9Sstevel@tonic-gate descs = slice_get_assoc_descriptors(dp, type, errp); 137*7c478bd9Sstevel@tonic-gate break; 138*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 139*7c478bd9Sstevel@tonic-gate descs = partition_get_assoc_descriptors(dp, type, errp); 140*7c478bd9Sstevel@tonic-gate break; 141*7c478bd9Sstevel@tonic-gate case DM_PATH: 142*7c478bd9Sstevel@tonic-gate descs = path_get_assoc_descriptors(dp, type, errp); 143*7c478bd9Sstevel@tonic-gate break; 144*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 145*7c478bd9Sstevel@tonic-gate descs = alias_get_assoc_descriptors(dp, type, errp); 146*7c478bd9Sstevel@tonic-gate break; 147*7c478bd9Sstevel@tonic-gate default: 148*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 149*7c478bd9Sstevel@tonic-gate break; 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate cache_unlock(); 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate return (ptr_array_to_desc_array(descs, errp)); 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate dm_desc_type_t * 158*7c478bd9Sstevel@tonic-gate dm_get_associated_types(dm_desc_type_t type) 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate switch (type) { 161*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 162*7c478bd9Sstevel@tonic-gate return (drive_assoc_types); 163*7c478bd9Sstevel@tonic-gate case DM_BUS: 164*7c478bd9Sstevel@tonic-gate return (bus_assoc_types); 165*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 166*7c478bd9Sstevel@tonic-gate return (controller_assoc_types); 167*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 168*7c478bd9Sstevel@tonic-gate return (media_assoc_types); 169*7c478bd9Sstevel@tonic-gate case DM_SLICE: 170*7c478bd9Sstevel@tonic-gate return (slice_assoc_types); 171*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 172*7c478bd9Sstevel@tonic-gate return (partition_assoc_types); 173*7c478bd9Sstevel@tonic-gate case DM_PATH: 174*7c478bd9Sstevel@tonic-gate return (path_assoc_types); 175*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 176*7c478bd9Sstevel@tonic-gate return (alias_assoc_types); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate return (NULL); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate nvlist_t * 183*7c478bd9Sstevel@tonic-gate dm_get_attributes(dm_descriptor_t desc, int *errp) 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate descriptor_t *dp; 186*7c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL; 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate dp = (descriptor_t *)desc; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate cache_rlock(); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 194*7c478bd9Sstevel@tonic-gate cache_unlock(); 195*7c478bd9Sstevel@tonic-gate *errp = EBADF; 196*7c478bd9Sstevel@tonic-gate return (NULL); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 200*7c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 201*7c478bd9Sstevel@tonic-gate cache_unlock(); 202*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 203*7c478bd9Sstevel@tonic-gate return (NULL); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate switch (dp->type) { 207*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 208*7c478bd9Sstevel@tonic-gate attrs = drive_get_attributes(dp, errp); 209*7c478bd9Sstevel@tonic-gate break; 210*7c478bd9Sstevel@tonic-gate case DM_BUS: 211*7c478bd9Sstevel@tonic-gate attrs = bus_get_attributes(dp, errp); 212*7c478bd9Sstevel@tonic-gate break; 213*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 214*7c478bd9Sstevel@tonic-gate attrs = controller_get_attributes(dp, errp); 215*7c478bd9Sstevel@tonic-gate break; 216*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 217*7c478bd9Sstevel@tonic-gate attrs = media_get_attributes(dp, errp); 218*7c478bd9Sstevel@tonic-gate break; 219*7c478bd9Sstevel@tonic-gate case DM_SLICE: 220*7c478bd9Sstevel@tonic-gate attrs = slice_get_attributes(dp, errp); 221*7c478bd9Sstevel@tonic-gate break; 222*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 223*7c478bd9Sstevel@tonic-gate attrs = partition_get_attributes(dp, errp); 224*7c478bd9Sstevel@tonic-gate break; 225*7c478bd9Sstevel@tonic-gate case DM_PATH: 226*7c478bd9Sstevel@tonic-gate attrs = path_get_attributes(dp, errp); 227*7c478bd9Sstevel@tonic-gate break; 228*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 229*7c478bd9Sstevel@tonic-gate attrs = alias_get_attributes(dp, errp); 230*7c478bd9Sstevel@tonic-gate break; 231*7c478bd9Sstevel@tonic-gate default: 232*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 233*7c478bd9Sstevel@tonic-gate break; 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate cache_unlock(); 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate return (attrs); 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate dm_descriptor_t 242*7c478bd9Sstevel@tonic-gate dm_get_descriptor_by_name(dm_desc_type_t desc_type, char *name, int *errp) 243*7c478bd9Sstevel@tonic-gate { 244*7c478bd9Sstevel@tonic-gate dm_descriptor_t desc = NULL; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate cache_wlock(); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate switch (desc_type) { 250*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 251*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)drive_get_descriptor_by_name(name, errp); 252*7c478bd9Sstevel@tonic-gate break; 253*7c478bd9Sstevel@tonic-gate case DM_BUS: 254*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)bus_get_descriptor_by_name(name, errp); 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 257*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)controller_get_descriptor_by_name(name, 258*7c478bd9Sstevel@tonic-gate errp); 259*7c478bd9Sstevel@tonic-gate break; 260*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 261*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)media_get_descriptor_by_name(name, errp); 262*7c478bd9Sstevel@tonic-gate break; 263*7c478bd9Sstevel@tonic-gate case DM_SLICE: 264*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)slice_get_descriptor_by_name(name, errp); 265*7c478bd9Sstevel@tonic-gate break; 266*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 267*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)partition_get_descriptor_by_name(name, 268*7c478bd9Sstevel@tonic-gate errp); 269*7c478bd9Sstevel@tonic-gate break; 270*7c478bd9Sstevel@tonic-gate case DM_PATH: 271*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)path_get_descriptor_by_name(name, errp); 272*7c478bd9Sstevel@tonic-gate break; 273*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 274*7c478bd9Sstevel@tonic-gate desc = (uintptr_t)alias_get_descriptor_by_name(name, errp); 275*7c478bd9Sstevel@tonic-gate break; 276*7c478bd9Sstevel@tonic-gate default: 277*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate cache_unlock(); 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate return (desc); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate dm_descriptor_t * 287*7c478bd9Sstevel@tonic-gate dm_get_descriptors(dm_desc_type_t type, int filter[], int *errp) 288*7c478bd9Sstevel@tonic-gate { 289*7c478bd9Sstevel@tonic-gate descriptor_t **descs = NULL; 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate cache_wlock(); 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate switch (type) { 295*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 296*7c478bd9Sstevel@tonic-gate descs = drive_get_descriptors(filter, errp); 297*7c478bd9Sstevel@tonic-gate break; 298*7c478bd9Sstevel@tonic-gate case DM_BUS: 299*7c478bd9Sstevel@tonic-gate descs = bus_get_descriptors(filter, errp); 300*7c478bd9Sstevel@tonic-gate break; 301*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 302*7c478bd9Sstevel@tonic-gate descs = controller_get_descriptors(filter, errp); 303*7c478bd9Sstevel@tonic-gate break; 304*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 305*7c478bd9Sstevel@tonic-gate descs = media_get_descriptors(filter, errp); 306*7c478bd9Sstevel@tonic-gate break; 307*7c478bd9Sstevel@tonic-gate case DM_SLICE: 308*7c478bd9Sstevel@tonic-gate descs = slice_get_descriptors(filter, errp); 309*7c478bd9Sstevel@tonic-gate break; 310*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 311*7c478bd9Sstevel@tonic-gate descs = partition_get_descriptors(filter, errp); 312*7c478bd9Sstevel@tonic-gate break; 313*7c478bd9Sstevel@tonic-gate case DM_PATH: 314*7c478bd9Sstevel@tonic-gate descs = path_get_descriptors(filter, errp); 315*7c478bd9Sstevel@tonic-gate break; 316*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 317*7c478bd9Sstevel@tonic-gate descs = alias_get_descriptors(filter, errp); 318*7c478bd9Sstevel@tonic-gate break; 319*7c478bd9Sstevel@tonic-gate default: 320*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 321*7c478bd9Sstevel@tonic-gate break; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate cache_unlock(); 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate return (ptr_array_to_desc_array(descs, errp)); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate char * 330*7c478bd9Sstevel@tonic-gate dm_get_name(dm_descriptor_t desc, int *errp) 331*7c478bd9Sstevel@tonic-gate { 332*7c478bd9Sstevel@tonic-gate descriptor_t *dp; 333*7c478bd9Sstevel@tonic-gate char *nm = NULL; 334*7c478bd9Sstevel@tonic-gate char *name = NULL; 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate dp = (descriptor_t *)desc; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate cache_rlock(); 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 341*7c478bd9Sstevel@tonic-gate cache_unlock(); 342*7c478bd9Sstevel@tonic-gate *errp = EBADF; 343*7c478bd9Sstevel@tonic-gate return (NULL); 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 347*7c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 348*7c478bd9Sstevel@tonic-gate cache_unlock(); 349*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 350*7c478bd9Sstevel@tonic-gate return (NULL); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate switch (dp->type) { 354*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 355*7c478bd9Sstevel@tonic-gate nm = (drive_get_name(dp)); 356*7c478bd9Sstevel@tonic-gate break; 357*7c478bd9Sstevel@tonic-gate case DM_BUS: 358*7c478bd9Sstevel@tonic-gate nm = (bus_get_name(dp)); 359*7c478bd9Sstevel@tonic-gate break; 360*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 361*7c478bd9Sstevel@tonic-gate nm = (controller_get_name(dp)); 362*7c478bd9Sstevel@tonic-gate break; 363*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 364*7c478bd9Sstevel@tonic-gate nm = (media_get_name(dp)); 365*7c478bd9Sstevel@tonic-gate break; 366*7c478bd9Sstevel@tonic-gate case DM_SLICE: 367*7c478bd9Sstevel@tonic-gate nm = (slice_get_name(dp)); 368*7c478bd9Sstevel@tonic-gate break; 369*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 370*7c478bd9Sstevel@tonic-gate nm = (partition_get_name(dp)); 371*7c478bd9Sstevel@tonic-gate break; 372*7c478bd9Sstevel@tonic-gate case DM_PATH: 373*7c478bd9Sstevel@tonic-gate nm = (path_get_name(dp)); 374*7c478bd9Sstevel@tonic-gate break; 375*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 376*7c478bd9Sstevel@tonic-gate nm = (alias_get_name(dp)); 377*7c478bd9Sstevel@tonic-gate break; 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate cache_unlock(); 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate *errp = 0; 383*7c478bd9Sstevel@tonic-gate if (nm != NULL) { 384*7c478bd9Sstevel@tonic-gate name = strdup(nm); 385*7c478bd9Sstevel@tonic-gate if (name == NULL) { 386*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 387*7c478bd9Sstevel@tonic-gate return (NULL); 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate return (name); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate return (NULL); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate nvlist_t * 395*7c478bd9Sstevel@tonic-gate dm_get_stats(dm_descriptor_t desc, int stat_type, int *errp) 396*7c478bd9Sstevel@tonic-gate { 397*7c478bd9Sstevel@tonic-gate descriptor_t *dp; 398*7c478bd9Sstevel@tonic-gate nvlist_t *stats = NULL; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate dp = (descriptor_t *)desc; 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate cache_rlock(); 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 406*7c478bd9Sstevel@tonic-gate cache_unlock(); 407*7c478bd9Sstevel@tonic-gate *errp = EBADF; 408*7c478bd9Sstevel@tonic-gate return (NULL); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate /* verify that the descriptor is still valid */ 412*7c478bd9Sstevel@tonic-gate if (dp->p.generic == NULL) { 413*7c478bd9Sstevel@tonic-gate cache_unlock(); 414*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 415*7c478bd9Sstevel@tonic-gate return (NULL); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate switch (dp->type) { 419*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 420*7c478bd9Sstevel@tonic-gate stats = drive_get_stats(dp, stat_type, errp); 421*7c478bd9Sstevel@tonic-gate break; 422*7c478bd9Sstevel@tonic-gate case DM_BUS: 423*7c478bd9Sstevel@tonic-gate stats = bus_get_stats(dp, stat_type, errp); 424*7c478bd9Sstevel@tonic-gate break; 425*7c478bd9Sstevel@tonic-gate case DM_CONTROLLER: 426*7c478bd9Sstevel@tonic-gate stats = controller_get_stats(dp, stat_type, errp); 427*7c478bd9Sstevel@tonic-gate break; 428*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 429*7c478bd9Sstevel@tonic-gate stats = media_get_stats(dp, stat_type, errp); 430*7c478bd9Sstevel@tonic-gate break; 431*7c478bd9Sstevel@tonic-gate case DM_SLICE: 432*7c478bd9Sstevel@tonic-gate stats = slice_get_stats(dp, stat_type, errp); 433*7c478bd9Sstevel@tonic-gate break; 434*7c478bd9Sstevel@tonic-gate case DM_PARTITION: 435*7c478bd9Sstevel@tonic-gate stats = partition_get_stats(dp, stat_type, errp); 436*7c478bd9Sstevel@tonic-gate break; 437*7c478bd9Sstevel@tonic-gate case DM_PATH: 438*7c478bd9Sstevel@tonic-gate stats = path_get_stats(dp, stat_type, errp); 439*7c478bd9Sstevel@tonic-gate break; 440*7c478bd9Sstevel@tonic-gate case DM_ALIAS: 441*7c478bd9Sstevel@tonic-gate stats = alias_get_stats(dp, stat_type, errp); 442*7c478bd9Sstevel@tonic-gate break; 443*7c478bd9Sstevel@tonic-gate default: 444*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 445*7c478bd9Sstevel@tonic-gate break; 446*7c478bd9Sstevel@tonic-gate } 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate cache_unlock(); 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate return (stats); 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate dm_desc_type_t 454*7c478bd9Sstevel@tonic-gate dm_get_type(dm_descriptor_t desc) 455*7c478bd9Sstevel@tonic-gate { 456*7c478bd9Sstevel@tonic-gate descriptor_t *dp; 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate dp = (descriptor_t *)desc; 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate cache_rlock(); 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate if (!cache_is_valid_desc(dp)) { 463*7c478bd9Sstevel@tonic-gate cache_unlock(); 464*7c478bd9Sstevel@tonic-gate return (-1); 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate cache_unlock(); 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate return (dp->type); 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate void 473*7c478bd9Sstevel@tonic-gate libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp) 474*7c478bd9Sstevel@tonic-gate { 475*7c478bd9Sstevel@tonic-gate if (*errp == 0) { 476*7c478bd9Sstevel@tonic-gate *errp = nvlist_add_string(attrs, name, val); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate descriptor_t ** 481*7c478bd9Sstevel@tonic-gate libdiskmgt_empty_desc_array(int *errp) 482*7c478bd9Sstevel@tonic-gate { 483*7c478bd9Sstevel@tonic-gate descriptor_t **empty; 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate empty = (descriptor_t **)calloc(1, sizeof (descriptor_t *)); 486*7c478bd9Sstevel@tonic-gate if (empty == NULL) { 487*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 488*7c478bd9Sstevel@tonic-gate return (NULL); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate empty[0] = NULL; 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate *errp = 0; 493*7c478bd9Sstevel@tonic-gate return (empty); 494*7c478bd9Sstevel@tonic-gate } 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate void 497*7c478bd9Sstevel@tonic-gate libdiskmgt_init_debug() 498*7c478bd9Sstevel@tonic-gate { 499*7c478bd9Sstevel@tonic-gate char *valp; 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate if ((valp = getenv(DM_DEBUG)) != NULL) { 502*7c478bd9Sstevel@tonic-gate dm_debug = atoi(valp); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate int 507*7c478bd9Sstevel@tonic-gate libdiskmgt_str_eq(char *nm1, char *nm2) 508*7c478bd9Sstevel@tonic-gate { 509*7c478bd9Sstevel@tonic-gate if (nm1 == NULL) { 510*7c478bd9Sstevel@tonic-gate if (dm_debug) { 511*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "WARNING: str_eq nm1 NULL\n"); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 515*7c478bd9Sstevel@tonic-gate return (1); 516*7c478bd9Sstevel@tonic-gate } else { 517*7c478bd9Sstevel@tonic-gate return (0); 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /* nm1 != NULL */ 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate if (nm2 == NULL) { 524*7c478bd9Sstevel@tonic-gate if (dm_debug) { 525*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "WARNING: str_eq nm2 NULL\n"); 526*7c478bd9Sstevel@tonic-gate } 527*7c478bd9Sstevel@tonic-gate return (0); 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate if (strcmp(nm1, nm2) == 0) { 531*7c478bd9Sstevel@tonic-gate return (1); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate return (0); 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 538*7c478bd9Sstevel@tonic-gate static descriptor_t ** 539*7c478bd9Sstevel@tonic-gate desc_array_to_ptr_array(dm_descriptor_t *descs, int *errp) 540*7c478bd9Sstevel@tonic-gate { 541*7c478bd9Sstevel@tonic-gate #ifdef _LP64 542*7c478bd9Sstevel@tonic-gate return ((descriptor_t **)descs); 543*7c478bd9Sstevel@tonic-gate #else 544*7c478bd9Sstevel@tonic-gate /* convert the 64 bit descriptors to 32 bit ptrs */ 545*7c478bd9Sstevel@tonic-gate int cnt; 546*7c478bd9Sstevel@tonic-gate int i; 547*7c478bd9Sstevel@tonic-gate descriptor_t **da; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate for (cnt = 0; descs[cnt]; cnt++); 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate da = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *)); 552*7c478bd9Sstevel@tonic-gate if (da == NULL) { 553*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 554*7c478bd9Sstevel@tonic-gate return (NULL); 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate for (i = 0; descs[i]; i++) { 558*7c478bd9Sstevel@tonic-gate da[i] = (descriptor_t *)descs[i]; 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate *errp = 0; 561*7c478bd9Sstevel@tonic-gate free(descs); 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate return (da); 564*7c478bd9Sstevel@tonic-gate #endif 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 568*7c478bd9Sstevel@tonic-gate static dm_descriptor_t * 569*7c478bd9Sstevel@tonic-gate ptr_array_to_desc_array(descriptor_t **ptrs, int *errp) 570*7c478bd9Sstevel@tonic-gate { 571*7c478bd9Sstevel@tonic-gate #ifdef _LP64 572*7c478bd9Sstevel@tonic-gate return ((dm_descriptor_t *)ptrs); 573*7c478bd9Sstevel@tonic-gate #else 574*7c478bd9Sstevel@tonic-gate /* convert the 32 bit ptrs to the 64 bit descriptors */ 575*7c478bd9Sstevel@tonic-gate int cnt; 576*7c478bd9Sstevel@tonic-gate int i; 577*7c478bd9Sstevel@tonic-gate dm_descriptor_t *da; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate if (*errp != 0 || ptrs == NULL) { 580*7c478bd9Sstevel@tonic-gate return (NULL); 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate for (cnt = 0; ptrs[cnt]; cnt++); 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate da = (dm_descriptor_t *)calloc(cnt + 1, sizeof (dm_descriptor_t)); 586*7c478bd9Sstevel@tonic-gate if (da == NULL) { 587*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 588*7c478bd9Sstevel@tonic-gate return (NULL); 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate for (i = 0; ptrs[i]; i++) { 592*7c478bd9Sstevel@tonic-gate da[i] = (uintptr_t)ptrs[i]; 593*7c478bd9Sstevel@tonic-gate } 594*7c478bd9Sstevel@tonic-gate *errp = 0; 595*7c478bd9Sstevel@tonic-gate free(ptrs); 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate return (da); 598*7c478bd9Sstevel@tonic-gate #endif 599*7c478bd9Sstevel@tonic-gate } 600