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