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 2003 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 <string.h> 30 #include <libintl.h> 31 #include "volume_defaults.h" 32 #include "volume_error.h" 33 34 /* 35 * Methods which manipulate a defaults_t struct 36 */ 37 38 static int defaults_get_singleton_component( 39 defaults_t *defaults, char *disksetname, 40 component_type_t type, devconfig_t **component, boolean_t create); 41 42 /* 43 * Constructor: Create a defaults_t struct populated with default 44 * values. This defaults_t must be freed. 45 * 46 * @param defaults 47 * RETURN: a pointer to a new defaults_t 48 * 49 * @return 0 50 * if successful 51 * 52 * @return non-zero 53 * if an error occurred. Use get_error_string() to 54 * retrieve the associated error message. 55 */ 56 int 57 new_defaults( 58 defaults_t **defaults) 59 { 60 devconfig_t *diskset; 61 int error = 0; 62 63 *defaults = (defaults_t *)calloc(1, sizeof (defaults_t)); 64 if (*defaults == NULL) { 65 volume_set_error(gettext("new_defaults calloc() failed")); 66 return (-1); 67 } 68 69 /* 70 * Create initial "global" (disk set-independent) defaults, as 71 * a devconfig_t of type disk set with NULL name 72 */ 73 if ((error = new_devconfig(&diskset, TYPE_DISKSET)) != 0) { 74 free_defaults(*defaults); 75 return (error); 76 } 77 78 /* Append global defaults disk set to disksets */ 79 defaults_set_disksets( 80 *defaults, dlist_append(dlist_new_item(diskset), 81 defaults_get_disksets(*defaults), AT_TAIL)); 82 83 /* Set defaults */ 84 if ((error = defaults_set_mirror_nsubs( 85 *defaults, NULL, DEFAULT_MIRROR_NSUBS)) != 0 || 86 87 (error = defaults_set_mirror_read( 88 *defaults, NULL, DEFAULT_MIRROR_READ)) != 0 || 89 90 (error = defaults_set_mirror_write( 91 *defaults, NULL, DEFAULT_MIRROR_WRITE)) != 0 || 92 93 (error = defaults_set_mirror_pass( 94 *defaults, NULL, DEFAULT_MIRROR_PASS)) != 0 || 95 96 (error = defaults_set_mirror_usehsp( 97 *defaults, NULL, DEFAULT_MIRROR_USEHSP)) != 0 || 98 99 (error = defaults_set_concat_usehsp( 100 *defaults, NULL, DEFAULT_CONCAT_USEHSP)) != 0 || 101 102 (error = defaults_set_stripe_interlace( 103 *defaults, NULL, DEFAULT_STRIPE_INTERLACE)) != 0 || 104 105 (error = defaults_set_stripe_mincomp( 106 *defaults, NULL, DEFAULT_STRIPE_MINCOMP)) != 0 || 107 108 (error = defaults_set_stripe_maxcomp( 109 *defaults, NULL, DEFAULT_STRIPE_MAXCOMP)) != 0 || 110 111 (error = defaults_set_stripe_usehsp( 112 *defaults, NULL, DEFAULT_STRIPE_USEHSP)) != 0 || 113 114 (error = defaults_set_volume_redundancy_level( 115 *defaults, NULL, DEFAULT_VOLUME_REDUND_LEVEL)) != 0 || 116 117 (error = defaults_set_volume_npaths( 118 *defaults, NULL, DEFAULT_VOLUME_NPATHS)) != 0 || 119 120 (error = defaults_set_volume_usehsp( 121 *defaults, NULL, DEFAULT_VOLUME_USEHSP)) != 0) { 122 123 free_defaults(*defaults); 124 return (error); 125 } 126 127 return (0); 128 } 129 130 /* 131 * Free memory (recursively) allocated to a defaults_t struct 132 * 133 * @param arg 134 * pointer to the defaults_t struct to free 135 */ 136 void 137 free_defaults( 138 void *arg) 139 { 140 defaults_t *defaults = (defaults_t *)arg; 141 142 if (defaults == NULL) { 143 return; 144 } 145 146 /* Free the disksets */ 147 if (defaults->disksets != NULL) { 148 dlist_free_items(defaults->disksets, free_devconfig); 149 } 150 151 /* Free the devconfig itself */ 152 free(defaults); 153 } 154 155 /* 156 * Set list of diskset specific defaults 157 * 158 * @param defaults 159 * a defaults_t hierarchy representing default settings 160 * for all disk sets and specific disk sets 161 * 162 * @param disksets 163 * a dlist_t representing the defaults for specific 164 * named disk sets 165 */ 166 void 167 defaults_set_disksets( 168 defaults_t *defaults, 169 dlist_t *disksets) 170 { 171 defaults->disksets = disksets; 172 } 173 174 /* 175 * Get list of diskset specific defaults 176 * 177 * @param defaults 178 * a defaults_t hierarchy representing default settings 179 * for all disk sets and specific disk sets 180 * 181 * @return a dlist_t representing the defaults for specific 182 * named disk sets 183 */ 184 dlist_t * 185 defaults_get_disksets( 186 defaults_t *defaults) 187 { 188 return (defaults->disksets); 189 } 190 191 /* 192 * Get a disk set with the given name from the given defaults_t 193 * 194 * @param defaults 195 * a defaults_t hierarchy representing default settings 196 * for all disk sets and specific disk sets 197 * 198 * @param name 199 * the name of the disk set whose defaults to retrieve, 200 * or NULL to get the defaults for all disk sets 201 * 202 * @param diskset 203 * RETURN: defaults for the given named disk set, or 204 * defaults for all disk sets if name is NULL 205 * 206 * @return ENOENT 207 * if the named disk set does not exist 208 * 209 * @return 0 210 * if the named disk set exists 211 */ 212 int 213 defaults_get_diskset_by_name( 214 defaults_t *defaults, 215 char *name, 216 devconfig_t **diskset) 217 { 218 dlist_t *list; 219 *diskset = NULL; 220 221 /* Get list of disk sets */ 222 list = defaults_get_disksets(defaults); 223 if (list != NULL) { 224 225 /* For each disk set-specific defaults... */ 226 for (; list != NULL; list = list->next) { 227 228 char *dname = NULL; 229 devconfig_t *d = (devconfig_t *)list->obj; 230 231 /* Get the name if this disk set */ 232 devconfig_get_name(d, &dname); 233 234 /* Do the names match? */ 235 if ( 236 /* Global defaults disk set */ 237 (name == NULL && dname == NULL) || 238 239 /* Named disk set */ 240 (name != NULL && dname != NULL && 241 strcmp(name, dname) == 0)) { 242 243 *diskset = d; 244 break; 245 } 246 } 247 } 248 249 /* Diskset doesn't exist */ 250 if (*diskset == NULL) { 251 return (ENOENT); 252 } 253 254 return (0); 255 } 256 257 /* 258 * Get the first component of the given type from the given disk set. 259 * If not found, create the component if requested. 260 * 261 * @return ENOENT 262 * if the given disk set does not exist, or it exists, 263 * but the requested component does not exist under it 264 * and its creation was not requested 265 * 266 * @return 0 267 * if the requested component exists or was created 268 * 269 * @return non-zero 270 * if the requested component does not exist and could 271 * not be created 272 */ 273 static int 274 defaults_get_singleton_component( 275 defaults_t *defaults, 276 char *disksetname, 277 component_type_t type, 278 devconfig_t **component, 279 boolean_t create) 280 { 281 int error; 282 devconfig_t *diskset; 283 284 /* Get the disk set referred to */ 285 if ((error = defaults_get_diskset_by_name( 286 defaults, disksetname, &diskset)) != 0) { 287 288 volume_set_error( 289 gettext("could not get defaults for disk set %s"), 290 disksetname == NULL ? gettext("<NULL>") : disksetname); 291 292 return (error); 293 } 294 295 /* 296 * Get the singleton component under this disk set, create if 297 * requested 298 */ 299 return (devconfig_get_component(diskset, type, component, create)); 300 } 301 302 /* 303 * Set name of the the default HSP to use 304 * 305 * @param defaults 306 * a defaults_t hierarchy representing default settings 307 * for all disk sets and specific disk sets 308 * 309 * @param diskset 310 * the name of the disk set to which to apply this 311 * default setting, or NULL to apply default 312 * setting to all disk sets 313 * 314 * @param name 315 * the name of the default HSP to use 316 * 317 * @return 0 318 * if successful 319 * 320 * @return non-zero 321 * if an error occurred. Use get_error_string() to 322 * retrieve the associated error message. 323 */ 324 int 325 defaults_set_hsp_name( 326 defaults_t *defaults, 327 char *diskset, 328 char *name) 329 { 330 devconfig_t *hsp = NULL; 331 int error = 0; 332 333 /* Get/create singleton HSP element for this disk set */ 334 if ((error = defaults_get_singleton_component( 335 defaults, diskset, TYPE_HSP, &hsp, TRUE)) != 0) { 336 /* volume_set_error already called */ 337 return (error); 338 } 339 340 /* Set the name attribute */ 341 return (devconfig_set_hsp_name(hsp, name)); 342 } 343 344 /* 345 * Get the name of the default HSP to use 346 * 347 * @param defaults 348 * a defaults_t hierarchy representing default settings 349 * for all disk sets and specific disk sets 350 * 351 * @param diskset 352 * the name of the disk set to which to apply this 353 * default setting, or NULL to apply default 354 * setting to all disk sets 355 * 356 * @param name 357 * RETURN: the name of the default HSP to use 358 * 359 * @return 0 360 * if successful 361 * 362 * @return non-zero 363 * if an error occurred. Use get_error_string() to 364 * retrieve the associated error message. 365 */ 366 int 367 defaults_get_hsp_name( 368 defaults_t *defaults, 369 char *diskset, 370 char **name) 371 { 372 char *disksets[2]; 373 devconfig_t *hsp; 374 int error; 375 int i = 0; 376 377 /* Check both the given and global (NULL) disk sets for the value */ 378 disksets[0] = diskset; 379 disksets[1] = NULL; 380 do { 381 /* Get/create singleton HSP element for this disk set */ 382 error = defaults_get_singleton_component( 383 defaults, disksets[i], TYPE_HSP, &hsp, FALSE); 384 385 switch (error) { 386 /* HSP found for this disk set */ 387 case 0: 388 /* Get the nsubs attribute */ 389 if ((error = devconfig_get_name(hsp, name)) == 0) { 390 /* nsubs attribute found */ 391 return (0); 392 } 393 394 /* FALLTHROUGH */ 395 396 /* HSP not found for this disk set */ 397 case ENOENT: 398 break; 399 400 /* Invalid disk set, or HSP couldn't be created */ 401 default: 402 /* volume_set_error already called */ 403 return (error); 404 } 405 406 /* Stop after the global (NULL) disk set has been searched */ 407 } while (disksets[i++] != NULL); 408 409 return (ENOENT); 410 } 411 412 /* 413 * Set the default number of submirrors for mirrored volumes 414 * 415 * @param defaults 416 * a defaults_t hierarchy representing default settings 417 * for all disk sets and specific disk sets 418 * 419 * @param diskset 420 * the name of the disk set to which to apply this 421 * default setting, or NULL to apply default 422 * setting to all disk sets 423 * 424 * @param val 425 * the value to set as the default number of submirrors 426 * for mirrored volumes 427 * 428 * @return 0 429 * if successful 430 * 431 * @return non-zero 432 * if an error occurred. Use get_error_string() to 433 * retrieve the associated error message. 434 */ 435 int 436 defaults_set_mirror_nsubs( 437 defaults_t *defaults, 438 char *diskset, 439 uint16_t val) 440 { 441 devconfig_t *mirror = NULL; 442 int error = 0; 443 444 /* Get/create singleton mirror element for this disk set */ 445 if ((error = defaults_get_singleton_component( 446 defaults, diskset, TYPE_MIRROR, &mirror, TRUE)) != 0) { 447 /* volume_set_error already called */ 448 return (error); 449 } 450 451 /* Set the nsubs attribute */ 452 return (devconfig_set_mirror_nsubs(mirror, val)); 453 } 454 455 /* 456 * Get the default number of submirrors for mirrored volumes 457 * 458 * @param defaults 459 * a defaults_t hierarchy representing default settings 460 * for all disk sets and specific disk sets 461 * 462 * @param diskset 463 * the name of the disk set to which to apply this 464 * default setting, or NULL to apply default 465 * setting to all disk sets 466 * 467 * @param val 468 * RETURN: the default number of submirrors for mirrored 469 * volumes 470 * 471 * @return 0 472 * if successful 473 * 474 * @return non-zero 475 * if an error occurred. Use get_error_string() to 476 * retrieve the associated error message. 477 */ 478 int 479 defaults_get_mirror_nsubs( 480 defaults_t *defaults, 481 char *diskset, 482 uint16_t *val) 483 { 484 char *disksets[2]; 485 devconfig_t *mirror; 486 int error; 487 int i = 0; 488 489 /* Check both the given and global (NULL) disk sets for the value */ 490 disksets[0] = diskset; 491 disksets[1] = NULL; 492 do { 493 /* Get/create singleton mirror element for this disk set */ 494 error = defaults_get_singleton_component( 495 defaults, disksets[i], TYPE_MIRROR, &mirror, FALSE); 496 497 switch (error) { 498 /* mirror found for this disk set */ 499 case 0: 500 /* Get the nsubs attribute */ 501 if ((error = devconfig_get_mirror_nsubs( 502 mirror, val)) == 0) { 503 /* nsubs attribute found */ 504 return (0); 505 } 506 507 /* FALLTHROUGH */ 508 509 /* mirror not found for this disk set */ 510 case ENOENT: 511 break; 512 513 /* Invalid disk set, or mirror couldn't be created */ 514 default: 515 /* volume_set_error already called */ 516 return (error); 517 } 518 519 /* Stop after the global (NULL) disk set has been searched */ 520 } while (disksets[i++] != NULL); 521 522 return (ENOENT); 523 } 524 525 /* 526 * Set the default read strategy for mirrored volumes 527 * 528 * @param defaults 529 * a defaults_t hierarchy representing default settings 530 * for all disk sets and specific disk sets 531 * 532 * @param diskset 533 * the name of the disk set to which to apply this 534 * default setting, or NULL to apply default 535 * setting to all disk sets 536 * 537 * @param val 538 * the value to set as the default read strategy for 539 * mirrored volumes 540 * 541 * @return 0 542 * if successful 543 * 544 * @return non-zero 545 * if an error occurred. Use get_error_string() to 546 * retrieve the associated error message. 547 */ 548 int 549 defaults_set_mirror_read( 550 defaults_t *defaults, 551 char *diskset, 552 mirror_read_strategy_t val) 553 { 554 devconfig_t *mirror = NULL; 555 int error = 0; 556 557 /* Get/create singleton mirror element for this disk set */ 558 if ((error = defaults_get_singleton_component( 559 defaults, diskset, TYPE_MIRROR, &mirror, TRUE)) != 0) { 560 /* volume_set_error already called */ 561 return (error); 562 } 563 564 /* Set the read attribute */ 565 return (devconfig_set_mirror_read(mirror, val)); 566 } 567 568 /* 569 * Get the default read strategy for mirrored volumes 570 * 571 * @param defaults 572 * a defaults_t hierarchy representing default settings 573 * for all disk sets and specific disk sets 574 * 575 * @param diskset 576 * the name of the disk set to which to apply this 577 * default setting, or NULL to apply default 578 * setting to all disk sets 579 * 580 * @param val 581 * RETURN: the default read strategy for mirrored volumes 582 * 583 * @return 0 584 * if successful 585 * 586 * @return non-zero 587 * if an error occurred. Use get_error_string() to 588 * retrieve the associated error message. 589 */ 590 int 591 defaults_get_mirror_read( 592 defaults_t *defaults, 593 char *diskset, 594 mirror_read_strategy_t *val) 595 { 596 char *disksets[2]; 597 devconfig_t *mirror; 598 int error; 599 int i = 0; 600 601 /* Check both the given and global (NULL) disk sets for the value */ 602 disksets[0] = diskset; 603 disksets[1] = NULL; 604 do { 605 /* Get/create singleton mirror element for this disk set */ 606 error = defaults_get_singleton_component( 607 defaults, disksets[i], TYPE_MIRROR, &mirror, FALSE); 608 609 switch (error) { 610 /* mirror found for this disk set */ 611 case 0: 612 /* Get the read attribute */ 613 if ((error = devconfig_get_mirror_read(mirror, val)) == 0) { 614 /* read attribute found */ 615 return (0); 616 } 617 618 /* FALLTHROUGH */ 619 620 /* mirror not found for this disk set */ 621 case ENOENT: 622 break; 623 624 /* Invalid disk set, or mirror couldn't be created */ 625 default: 626 /* volume_set_error already called */ 627 return (error); 628 } 629 630 /* Stop after the global (NULL) disk set has been searched */ 631 } while (disksets[i++] != NULL); 632 633 return (ENOENT); 634 } 635 636 /* 637 * Set the default write strategy for mirrored volumes 638 * 639 * @param defaults 640 * a defaults_t hierarchy representing default settings 641 * for all disk sets and specific disk sets 642 * 643 * @param diskset 644 * the name of the disk set to which to apply this 645 * default setting, or NULL to apply default 646 * setting to all disk sets 647 * 648 * @param val 649 * the value to set as the default write strategy for 650 * mirrored volumes 651 * 652 * @return 0 653 * if successful 654 * 655 * @return non-zero 656 * if an error occurred. Use get_error_string() to 657 * retrieve the associated error message. 658 */ 659 int 660 defaults_set_mirror_write( 661 defaults_t *defaults, 662 char *diskset, 663 mirror_write_strategy_t val) 664 { 665 devconfig_t *mirror = NULL; 666 int error = 0; 667 668 /* Get/create singleton mirror element for this disk set */ 669 if ((error = defaults_get_singleton_component( 670 defaults, diskset, TYPE_MIRROR, &mirror, TRUE)) != 0) { 671 /* volume_set_error already called */ 672 return (error); 673 } 674 675 /* Set the write attribute */ 676 return (devconfig_set_mirror_write(mirror, val)); 677 } 678 679 /* 680 * Get the default write strategy for mirrored volumes 681 * 682 * @param defaults 683 * a defaults_t hierarchy representing default settings 684 * for all disk sets and specific disk sets 685 * 686 * @param diskset 687 * the name of the disk set to which to apply this 688 * default setting, or NULL to apply default 689 * setting to all disk sets 690 * 691 * @param val 692 * RETURN: the default write strategy for mirrored 693 * volumes 694 * 695 * @return 0 696 * if successful 697 * 698 * @return non-zero 699 * if an error occurred. Use get_error_string() to 700 * retrieve the associated error message. 701 */ 702 int 703 defaults_get_mirror_write( 704 defaults_t *defaults, 705 char *diskset, 706 mirror_write_strategy_t *val) 707 { 708 char *disksets[2]; 709 devconfig_t *mirror; 710 int error; 711 int i = 0; 712 713 /* Check both the given and global (NULL) disk sets for the value */ 714 disksets[0] = diskset; 715 disksets[1] = NULL; 716 do { 717 /* Get/create singleton mirror element for this disk set */ 718 error = defaults_get_singleton_component( 719 defaults, disksets[i], TYPE_MIRROR, &mirror, FALSE); 720 721 switch (error) { 722 /* mirror found for this disk set */ 723 case 0: 724 /* Get the write attribute */ 725 if ((error = devconfig_get_mirror_write( 726 mirror, val)) == 0) { 727 /* write attribute found */ 728 return (0); 729 } 730 731 /* FALLTHROUGH */ 732 733 /* mirror not found for this disk set */ 734 case ENOENT: 735 break; 736 737 /* Invalid disk set, or mirror couldn't be created */ 738 default: 739 /* volume_set_error already called */ 740 return (error); 741 } 742 743 /* Stop after the global (NULL) disk set has been searched */ 744 } while (disksets[i++] != NULL); 745 746 return (ENOENT); 747 } 748 749 /* 750 * Set the default resync pass for mirrored volumes 751 * 752 * @param defaults 753 * a defaults_t hierarchy representing default settings 754 * for all disk sets and specific disk sets 755 * 756 * @param diskset 757 * the name of the disk set to which to apply this 758 * default setting, or NULL to apply default 759 * setting to all disk sets 760 * 761 * @param val 762 * the value to set as the default resync pass for 763 * mirrored volumes 764 * 765 * @return 0 766 * if successful 767 * 768 * @return non-zero 769 * if an error occurred. Use get_error_string() to 770 * retrieve the associated error message. 771 */ 772 int 773 defaults_set_mirror_pass( 774 defaults_t *defaults, 775 char *diskset, 776 uint16_t val) 777 { 778 devconfig_t *mirror = NULL; 779 int error = 0; 780 781 /* Get/create singleton mirror element for this disk set */ 782 if ((error = defaults_get_singleton_component( 783 defaults, diskset, TYPE_MIRROR, &mirror, TRUE)) != 0) { 784 /* volume_set_error already called */ 785 return (error); 786 } 787 788 /* Set the pass attribute */ 789 return (devconfig_set_mirror_pass(mirror, val)); 790 } 791 792 /* 793 * Get the default resync pass for mirrored volumes 794 * 795 * @param defaults 796 * a defaults_t hierarchy representing default settings 797 * for all disk sets and specific disk sets 798 * 799 * @param diskset 800 * the name of the disk set to which to apply this 801 * default setting, or NULL to apply default 802 * setting to all disk sets 803 * 804 * @param val 805 * RETURN: the default resync pass for mirrored volumes 806 * 807 * @return 0 808 * if successful 809 * 810 * @return non-zero 811 * if an error occurred. Use get_error_string() to 812 * retrieve the associated error message. 813 */ 814 int 815 defaults_get_mirror_pass( 816 defaults_t *defaults, 817 char *diskset, 818 uint16_t *val) 819 { 820 char *disksets[2]; 821 devconfig_t *mirror; 822 int error; 823 int i = 0; 824 825 /* Check both the given and global (NULL) disk sets for the value */ 826 disksets[0] = diskset; 827 disksets[1] = NULL; 828 do { 829 /* Get/create singleton mirror element for this disk set */ 830 error = defaults_get_singleton_component( 831 defaults, disksets[i], TYPE_MIRROR, &mirror, FALSE); 832 833 switch (error) { 834 /* mirror found for this disk set */ 835 case 0: 836 /* Get the pass attribute */ 837 if ((error = devconfig_get_mirror_pass(mirror, val)) == 0) { 838 /* pass attribute found */ 839 return (0); 840 } 841 842 /* FALLTHROUGH */ 843 844 /* mirror not found for this disk set */ 845 case ENOENT: 846 break; 847 848 /* Invalid disk set, or mirror couldn't be created */ 849 default: 850 /* volume_set_error already called */ 851 return (error); 852 } 853 854 /* Stop after the global (NULL) disk set has been searched */ 855 } while (disksets[i++] != NULL); 856 857 return (ENOENT); 858 } 859 860 /* 861 * Set the default HSP creation flag for mirrored volumes 862 * 863 * @param defaults 864 * a defaults_t hierarchy representing default settings 865 * for all disk sets and specific disk sets 866 * 867 * @param diskset 868 * the name of the disk set to which to apply this 869 * default setting, or NULL to apply default 870 * setting to all disk sets 871 * 872 * @param val 873 * the value to set as the default HSP creation flag for 874 * mirrored volumes 875 * 876 * @return 0 877 * if successful 878 * 879 * @return non-zero 880 * if an error occurred. Use get_error_string() to 881 * retrieve the associated error message. 882 */ 883 int 884 defaults_set_mirror_usehsp( 885 defaults_t *defaults, 886 char *diskset, 887 boolean_t val) 888 { 889 devconfig_t *mirror = NULL; 890 int error = 0; 891 892 /* Get/create singleton mirror element for this disk set */ 893 if ((error = defaults_get_singleton_component( 894 defaults, diskset, TYPE_MIRROR, &mirror, TRUE)) != 0) { 895 /* volume_set_error already called */ 896 return (error); 897 } 898 899 /* Set the usehsp attribute */ 900 return (devconfig_set_volume_usehsp(mirror, val)); 901 } 902 903 /* 904 * Get the default HSP creation flag for mirrored volumes 905 * 906 * @param defaults 907 * a defaults_t hierarchy representing default settings 908 * for all disk sets and specific disk sets 909 * 910 * @param diskset 911 * the name of the disk set to which to apply this 912 * default setting, or NULL to apply default 913 * setting to all disk sets 914 * 915 * @param val 916 * RETURN: the default HSP creation flag for mirrored 917 * volumes 918 * 919 * @return 0 920 * if successful 921 * 922 * @return non-zero 923 * if an error occurred. Use get_error_string() to 924 * retrieve the associated error message. 925 */ 926 int 927 defaults_get_mirror_usehsp( 928 defaults_t *defaults, 929 char *diskset, 930 boolean_t *val) 931 { 932 char *disksets[2]; 933 devconfig_t *mirror; 934 int error; 935 int i = 0; 936 937 /* Check both the given and global (NULL) disk sets for the value */ 938 disksets[0] = diskset; 939 disksets[1] = NULL; 940 do { 941 /* Get/create singleton mirror element for this disk set */ 942 error = defaults_get_singleton_component( 943 defaults, disksets[i], TYPE_MIRROR, &mirror, FALSE); 944 945 switch (error) { 946 /* mirror found for this disk set */ 947 case 0: 948 /* Get the usehsp attribute */ 949 if ((error = devconfig_get_volume_usehsp( 950 mirror, val)) == 0) { 951 /* usehsp attribute found */ 952 return (0); 953 } 954 955 /* FALLTHROUGH */ 956 957 /* mirror not found for this disk set */ 958 case ENOENT: 959 break; 960 961 /* Invalid disk set, or mirror couldn't be created */ 962 default: 963 /* volume_set_error already called */ 964 return (error); 965 } 966 967 /* Stop after the global (NULL) disk set has been searched */ 968 } while (disksets[i++] != NULL); 969 970 return (ENOENT); 971 } 972 973 /* 974 * Set the default HSP creation flag for concatenated volumes 975 * 976 * @param defaults 977 * a defaults_t hierarchy representing default settings 978 * for all disk sets and specific disk sets 979 * 980 * @param diskset 981 * the name of the disk set to which to apply this 982 * default setting, or NULL to apply default 983 * setting to all disk sets 984 * 985 * @param val 986 * the value to set as the default HSP creation flag for 987 * concatenated volumes 988 * 989 * @return 0 990 * if successful 991 * 992 * @return non-zero 993 * if an error occurred. Use get_error_string() to 994 * retrieve the associated error message. 995 */ 996 int 997 defaults_set_concat_usehsp( 998 defaults_t *defaults, 999 char *diskset, 1000 boolean_t val) 1001 { 1002 devconfig_t *concat = NULL; 1003 int error = 0; 1004 1005 /* Get/create singleton concat element for this disk set */ 1006 if ((error = defaults_get_singleton_component( 1007 defaults, diskset, TYPE_CONCAT, &concat, TRUE)) != 0) { 1008 /* volume_set_error already called */ 1009 return (error); 1010 } 1011 1012 /* Set the usehsp attribute */ 1013 return (devconfig_set_volume_usehsp(concat, val)); 1014 } 1015 1016 /* 1017 * Get the default HSP creation flag for concatenated volumes 1018 * 1019 * @param defaults 1020 * a defaults_t hierarchy representing default settings 1021 * for all disk sets and specific disk sets 1022 * 1023 * @param diskset 1024 * the name of the disk set to which to apply this 1025 * default setting, or NULL to apply default 1026 * setting to all disk sets 1027 * 1028 * @param val 1029 * RETURN: the default HSP creation flag for concatenated 1030 * volumes 1031 * 1032 * @return 0 1033 * if successful 1034 * 1035 * @return non-zero 1036 * if an error occurred. Use get_error_string() to 1037 * retrieve the associated error message. 1038 */ 1039 int 1040 defaults_get_concat_usehsp( 1041 defaults_t *defaults, 1042 char *diskset, 1043 boolean_t *val) 1044 { 1045 char *disksets[2]; 1046 devconfig_t *concat; 1047 int error; 1048 int i = 0; 1049 1050 /* Check both the given and global (NULL) disk sets for the value */ 1051 disksets[0] = diskset; 1052 disksets[1] = NULL; 1053 do { 1054 /* Get/create singleton concat element for this disk set */ 1055 error = defaults_get_singleton_component( 1056 defaults, disksets[i], TYPE_CONCAT, &concat, FALSE); 1057 1058 switch (error) { 1059 /* concat found for this disk set */ 1060 case 0: 1061 /* Get the usehsp attribute */ 1062 if ((error = devconfig_get_volume_usehsp( 1063 concat, val)) == 0) { 1064 /* usehsp attribute found */ 1065 return (0); 1066 } 1067 1068 /* FALLTHROUGH */ 1069 1070 /* concat not found for this disk set */ 1071 case ENOENT: 1072 break; 1073 1074 /* Invalid disk set, or concat couldn't be created */ 1075 default: 1076 /* volume_set_error already called */ 1077 return (error); 1078 } 1079 1080 /* Stop after the global (NULL) disk set has been searched */ 1081 } while (disksets[i++] != NULL); 1082 1083 return (ENOENT); 1084 } 1085 1086 /* 1087 * Set the default minimum number of components for striped volumes 1088 * 1089 * @param defaults 1090 * a defaults_t hierarchy representing default settings 1091 * for all disk sets and specific disk sets 1092 * 1093 * @param diskset 1094 * the name of the disk set to which to apply this 1095 * default setting, or NULL to apply default 1096 * setting to all disk sets 1097 * 1098 * @param val 1099 * the value to set as the default minimum number of 1100 * components for striped volumes 1101 * 1102 * @return 0 1103 * if successful 1104 * 1105 * @return non-zero 1106 * if an error occurred. Use get_error_string() to 1107 * retrieve the associated error message. 1108 */ 1109 int 1110 defaults_set_stripe_mincomp( 1111 defaults_t *defaults, 1112 char *diskset, 1113 uint16_t val) 1114 { 1115 devconfig_t *stripe = NULL; 1116 int error = 0; 1117 1118 /* Get/create singleton stripe element for this disk set */ 1119 if ((error = defaults_get_singleton_component( 1120 defaults, diskset, TYPE_STRIPE, &stripe, TRUE)) != 0) { 1121 /* volume_set_error already called */ 1122 return (error); 1123 } 1124 1125 /* Set the mincomp attribute */ 1126 return (devconfig_set_stripe_mincomp(stripe, val)); 1127 } 1128 1129 /* 1130 * Get the default minimum number of components for striped volumes 1131 * 1132 * @param defaults 1133 * a defaults_t hierarchy representing default settings 1134 * for all disk sets and specific disk sets 1135 * 1136 * @param diskset 1137 * the name of the disk set to which to apply this 1138 * default setting, or NULL to apply default 1139 * setting to all disk sets 1140 * 1141 * @param val 1142 * RETURN: the default minimum number of components for 1143 * striped volumes 1144 * 1145 * @return 0 1146 * if successful 1147 * 1148 * @return non-zero 1149 * if an error occurred. Use get_error_string() to 1150 * retrieve the associated error message. 1151 */ 1152 int 1153 defaults_get_stripe_mincomp( 1154 defaults_t *defaults, 1155 char *diskset, 1156 uint16_t *val) 1157 { 1158 char *disksets[2]; 1159 devconfig_t *stripe; 1160 int error; 1161 int i = 0; 1162 1163 /* Check both the given and global (NULL) disk sets for the value */ 1164 disksets[0] = diskset; 1165 disksets[1] = NULL; 1166 do { 1167 /* Get/create singleton stripe element for this disk set */ 1168 error = defaults_get_singleton_component( 1169 defaults, disksets[i], TYPE_STRIPE, &stripe, FALSE); 1170 1171 switch (error) { 1172 /* stripe found for this disk set */ 1173 case 0: 1174 /* Get the mincomp attribute */ 1175 if ((error = devconfig_get_stripe_mincomp( 1176 stripe, val)) == 0) { 1177 /* mincomp attribute found */ 1178 return (0); 1179 } 1180 1181 /* FALLTHROUGH */ 1182 1183 /* stripe not found for this disk set */ 1184 case ENOENT: 1185 break; 1186 1187 /* Invalid disk set, or stripe couldn't be created */ 1188 default: 1189 /* volume_set_error already called */ 1190 return (error); 1191 } 1192 1193 /* Stop after the global (NULL) disk set has been searched */ 1194 } while (disksets[i++] != NULL); 1195 1196 return (ENOENT); 1197 } 1198 1199 /* 1200 * Set the default maximum number of components for striped volumes 1201 * 1202 * @param defaults 1203 * a defaults_t hierarchy representing default settings 1204 * for all disk sets and specific disk sets 1205 * 1206 * @param diskset 1207 * the name of the disk set to which to apply this 1208 * default setting, or NULL to apply default 1209 * setting to all disk sets 1210 * 1211 * @param val 1212 * the value to set as the default maximum number of 1213 * components for striped volumes 1214 * 1215 * @return 0 1216 * if successful 1217 * 1218 * @return non-zero 1219 * if an error occurred. Use get_error_string() to 1220 * retrieve the associated error message. 1221 */ 1222 int 1223 defaults_set_stripe_maxcomp( 1224 defaults_t *defaults, 1225 char *diskset, 1226 uint16_t val) 1227 { 1228 devconfig_t *stripe = NULL; 1229 int error = 0; 1230 1231 /* Get/create singleton stripe element for this disk set */ 1232 if ((error = defaults_get_singleton_component( 1233 defaults, diskset, TYPE_STRIPE, &stripe, TRUE)) != 0) { 1234 /* volume_set_error already called */ 1235 return (error); 1236 } 1237 1238 /* Set the maxcomp attribute */ 1239 return (devconfig_set_stripe_maxcomp(stripe, val)); 1240 } 1241 1242 /* 1243 * Get the default maximum number of components for striped volumes 1244 * 1245 * @param defaults 1246 * a defaults_t hierarchy representing default settings 1247 * for all disk sets and specific disk sets 1248 * 1249 * @param diskset 1250 * the name of the disk set to which to apply this 1251 * default setting, or NULL to apply default 1252 * setting to all disk sets 1253 * 1254 * @param val 1255 * RETURN: the default maximum number of components for 1256 * striped volumes 1257 * 1258 * @return 0 1259 * if successful 1260 * 1261 * @return non-zero 1262 * if an error occurred. Use get_error_string() to 1263 * retrieve the associated error message. 1264 */ 1265 int 1266 defaults_get_stripe_maxcomp( 1267 defaults_t *defaults, 1268 char *diskset, 1269 uint16_t *val) 1270 { 1271 char *disksets[2]; 1272 devconfig_t *stripe; 1273 int error; 1274 int i = 0; 1275 1276 /* Check both the given and global (NULL) disk sets for the value */ 1277 disksets[0] = diskset; 1278 disksets[1] = NULL; 1279 do { 1280 /* Get/create singleton stripe element for this disk set */ 1281 error = defaults_get_singleton_component( 1282 defaults, disksets[i], TYPE_STRIPE, &stripe, FALSE); 1283 1284 switch (error) { 1285 /* stripe found for this disk set */ 1286 case 0: 1287 /* Get the maxcomp attribute */ 1288 if ((error = devconfig_get_stripe_maxcomp( 1289 stripe, val)) == 0) { 1290 /* maxcomp attribute found */ 1291 return (0); 1292 } 1293 1294 /* FALLTHROUGH */ 1295 1296 /* stripe not found for this disk set */ 1297 case ENOENT: 1298 break; 1299 1300 /* Invalid disk set, or stripe couldn't be created */ 1301 default: 1302 /* volume_set_error already called */ 1303 return (error); 1304 } 1305 1306 /* Stop after the global (NULL) disk set has been searched */ 1307 } while (disksets[i++] != NULL); 1308 1309 return (ENOENT); 1310 } 1311 1312 /* 1313 * Set the default interlace for striped volumes 1314 * 1315 * @param defaults 1316 * a defaults_t hierarchy representing default settings 1317 * for all disk sets and specific disk sets 1318 * 1319 * @param diskset 1320 * the name of the disk set to which to apply this 1321 * default setting, or NULL to apply default 1322 * setting to all disk sets 1323 * 1324 * @param val 1325 * the value to set as the default interlace for striped 1326 * volumes 1327 * 1328 * @return 0 1329 * if successful 1330 * 1331 * @return non-zero 1332 * if an error occurred. Use get_error_string() to 1333 * retrieve the associated error message. 1334 */ 1335 int 1336 defaults_set_stripe_interlace( 1337 defaults_t *defaults, 1338 char *diskset, 1339 uint64_t val) 1340 { 1341 devconfig_t *stripe = NULL; 1342 int error = 0; 1343 1344 /* Get/create singleton stripe element for this disk set */ 1345 if ((error = defaults_get_singleton_component( 1346 defaults, diskset, TYPE_STRIPE, &stripe, TRUE)) != 0) { 1347 /* volume_set_error already called */ 1348 return (error); 1349 } 1350 1351 /* Set the interlace attribute */ 1352 return (devconfig_set_stripe_interlace(stripe, val)); 1353 } 1354 1355 /* 1356 * Get the default interlace for striped volumes 1357 * 1358 * @param defaults 1359 * a defaults_t hierarchy representing default settings 1360 * for all disk sets and specific disk sets 1361 * 1362 * @param diskset 1363 * the name of the disk set to which to apply this 1364 * default setting, or NULL to apply default 1365 * setting to all disk sets 1366 * 1367 * @param val 1368 * RETURN: the default interlace for striped volumes 1369 * 1370 * @return 0 1371 * if successful 1372 * 1373 * @return non-zero 1374 * if an error occurred. Use get_error_string() to 1375 * retrieve the associated error message. 1376 */ 1377 int 1378 defaults_get_stripe_interlace( 1379 defaults_t *defaults, 1380 char *diskset, 1381 uint64_t *val) 1382 { 1383 char *disksets[2]; 1384 devconfig_t *stripe; 1385 int error; 1386 int i = 0; 1387 1388 /* Check both the given and global (NULL) disk sets for the value */ 1389 disksets[0] = diskset; 1390 disksets[1] = NULL; 1391 do { 1392 /* Get/create singleton stripe element for this disk set */ 1393 error = defaults_get_singleton_component( 1394 defaults, disksets[i], TYPE_STRIPE, &stripe, FALSE); 1395 1396 switch (error) { 1397 /* stripe found for this disk set */ 1398 case 0: 1399 /* Get the interlace attribute */ 1400 if ((error = devconfig_get_stripe_interlace( 1401 stripe, val)) == 0) { 1402 /* interlace attribute found */ 1403 return (0); 1404 } 1405 1406 /* FALLTHROUGH */ 1407 1408 /* stripe not found for this disk set */ 1409 case ENOENT: 1410 break; 1411 1412 /* Invalid disk set, or stripe couldn't be created */ 1413 default: 1414 /* volume_set_error already called */ 1415 return (error); 1416 } 1417 1418 /* Stop after the global (NULL) disk set has been searched */ 1419 } while (disksets[i++] != NULL); 1420 1421 return (ENOENT); 1422 } 1423 1424 /* 1425 * Set the default HSP creation flag for striped volumes 1426 * 1427 * @param defaults 1428 * a defaults_t hierarchy representing default settings 1429 * for all disk sets and specific disk sets 1430 * 1431 * @param diskset 1432 * the name of the disk set to which to apply this 1433 * default setting, or NULL to apply default 1434 * setting to all disk sets 1435 * 1436 * @param val 1437 * the value to set as the default HSP creation flag for 1438 * striped volumes 1439 * 1440 * @return 0 1441 * if successful 1442 * 1443 * @return non-zero 1444 * if an error occurred. Use get_error_string() to 1445 * retrieve the associated error message. 1446 */ 1447 int 1448 defaults_set_stripe_usehsp( 1449 defaults_t *defaults, 1450 char *diskset, 1451 boolean_t val) 1452 { 1453 devconfig_t *stripe = NULL; 1454 int error = 0; 1455 1456 /* Get/create singleton stripe element for this disk set */ 1457 if ((error = defaults_get_singleton_component( 1458 defaults, diskset, TYPE_STRIPE, &stripe, TRUE)) != 0) { 1459 /* volume_set_error already called */ 1460 return (error); 1461 } 1462 1463 /* Set the usehsp attribute */ 1464 return (devconfig_set_volume_usehsp(stripe, val)); 1465 } 1466 1467 /* 1468 * Get the default HSP creation flag for striped volumes 1469 * 1470 * @param defaults 1471 * a defaults_t hierarchy representing default settings 1472 * for all disk sets and specific disk sets 1473 * 1474 * @param diskset 1475 * the name of the disk set to which to apply this 1476 * default setting, or NULL to apply default 1477 * setting to all disk sets 1478 * 1479 * @param val 1480 * RETURN: the default HSP creation flag for striped 1481 * volumes 1482 * 1483 * @return 0 1484 * if successful 1485 * 1486 * @return non-zero 1487 * if an error occurred. Use get_error_string() to 1488 * retrieve the associated error message. 1489 */ 1490 int 1491 defaults_get_stripe_usehsp( 1492 defaults_t *defaults, 1493 char *diskset, 1494 boolean_t *val) 1495 { 1496 char *disksets[2]; 1497 devconfig_t *stripe; 1498 int error; 1499 int i = 0; 1500 1501 /* Check both the given and global (NULL) disk sets for the value */ 1502 disksets[0] = diskset; 1503 disksets[1] = NULL; 1504 do { 1505 /* Get/create singleton stripe element for this disk set */ 1506 error = defaults_get_singleton_component( 1507 defaults, disksets[i], TYPE_STRIPE, &stripe, FALSE); 1508 1509 switch (error) { 1510 /* stripe found for this disk set */ 1511 case 0: 1512 /* Get the usehsp attribute */ 1513 if ((error = devconfig_get_volume_usehsp( 1514 stripe, val)) == 0) { 1515 /* usehsp attribute found */ 1516 return (0); 1517 } 1518 1519 /* FALLTHROUGH */ 1520 1521 /* stripe not found for this disk set */ 1522 case ENOENT: 1523 break; 1524 1525 /* Invalid disk set, or stripe couldn't be created */ 1526 default: 1527 /* volume_set_error already called */ 1528 return (error); 1529 } 1530 1531 /* Stop after the global (NULL) disk set has been searched */ 1532 } while (disksets[i++] != NULL); 1533 1534 return (ENOENT); 1535 } 1536 1537 /* 1538 * Set the default redundancy level for generic volumes. 1539 * 1540 * @param defaults 1541 * a defaults_t hierarchy representing default settings 1542 * for all disk sets and specific disk sets 1543 * 1544 * @param diskset 1545 * the name of the disk set to which to apply this 1546 * default setting, or NULL to apply default 1547 * setting to all disk sets 1548 * 1549 * @param val 1550 * If 0, a stripe will be created by default. If > 0, a 1551 * mirror with this number of submirrors will be created 1552 * by default. 1553 * 1554 * @return 0 1555 * if successful 1556 * 1557 * @return non-zero 1558 * if an error occurred. Use get_error_string() to 1559 * retrieve the associated error message. 1560 */ 1561 int 1562 defaults_set_volume_redundancy_level( 1563 defaults_t *defaults, 1564 char *diskset, 1565 uint16_t val) 1566 { 1567 devconfig_t *volume = NULL; 1568 int error = 0; 1569 1570 /* Get/create singleton volume element for this disk set */ 1571 if ((error = defaults_get_singleton_component( 1572 defaults, diskset, TYPE_VOLUME, &volume, TRUE)) != 0) { 1573 /* volume_set_error already called */ 1574 return (error); 1575 } 1576 1577 /* Set the redundancy level */ 1578 return (devconfig_set_volume_redundancy_level(volume, val)); 1579 } 1580 1581 /* 1582 * Get the default redundancy level for generic volumes. 1583 * 1584 * @param defaults 1585 * a defaults_t hierarchy representing default settings 1586 * for all disk sets and specific disk sets 1587 * 1588 * @param diskset 1589 * the name of the disk set to which to apply this 1590 * default setting, or NULL to apply default 1591 * setting to all disk sets 1592 * 1593 * @param val 1594 * RETURN: the default redundancy level for generic 1595 * volumes 1596 * 1597 * @return 0 1598 * if successful 1599 * 1600 * @return non-zero 1601 * if an error occurred. Use get_error_string() to 1602 * retrieve the associated error message. 1603 */ 1604 int 1605 defaults_get_volume_redundancy_level( 1606 defaults_t *defaults, 1607 char *diskset, 1608 uint16_t *val) 1609 { 1610 char *disksets[2]; 1611 devconfig_t *volume; 1612 int error; 1613 int i = 0; 1614 1615 /* Check both the given and global (NULL) disk sets for the value */ 1616 disksets[0] = diskset; 1617 disksets[1] = NULL; 1618 do { 1619 /* Get/create singleton volume element for this disk set */ 1620 error = defaults_get_singleton_component( 1621 defaults, disksets[i], TYPE_VOLUME, &volume, FALSE); 1622 1623 switch (error) { 1624 /* volume found for this disk set */ 1625 case 0: 1626 /* Get the redundancy level */ 1627 if ((error = devconfig_get_volume_redundancy_level( 1628 volume, val)) == 0) { 1629 /* redundancy level found */ 1630 return (0); 1631 } 1632 1633 /* FALLTHROUGH */ 1634 1635 /* volume not found for this disk set */ 1636 case ENOENT: 1637 break; 1638 1639 /* Invalid disk set, or volume couldn't be created */ 1640 default: 1641 /* volume_set_error already called */ 1642 return (error); 1643 } 1644 1645 /* Stop after the global (NULL) disk set has been searched */ 1646 } while (disksets[i++] != NULL); 1647 1648 return (ENOENT); 1649 } 1650 1651 /* 1652 * Set the default number of data paths for generic volume 1653 * 1654 * @param defaults 1655 * a defaults_t hierarchy representing default settings 1656 * for all disk sets and specific disk sets 1657 * 1658 * @param diskset 1659 * the name of the disk set to which to apply this 1660 * default setting, or NULL to apply default 1661 * setting to all disk sets 1662 * 1663 * @param val 1664 * the value to set as the default number of data paths 1665 * for generic volume 1666 * 1667 * @return 0 1668 * if successful 1669 * 1670 * @return non-zero 1671 * if an error occurred. Use get_error_string() to 1672 * retrieve the associated error message. 1673 */ 1674 int 1675 defaults_set_volume_npaths( 1676 defaults_t *defaults, 1677 char *diskset, 1678 uint16_t val) 1679 { 1680 devconfig_t *volume = NULL; 1681 int error = 0; 1682 1683 /* Get/create singleton volume element for this disk set */ 1684 if ((error = defaults_get_singleton_component( 1685 defaults, diskset, TYPE_VOLUME, &volume, TRUE)) != 0) { 1686 /* volume_set_error already called */ 1687 return (error); 1688 } 1689 1690 /* Set the npaths attribute */ 1691 return (devconfig_set_volume_npaths(volume, val)); 1692 } 1693 1694 /* 1695 * Get the default number of data paths for generic volume 1696 * 1697 * @param defaults 1698 * a defaults_t hierarchy representing default settings 1699 * for all disk sets and specific disk sets 1700 * 1701 * @param diskset 1702 * the name of the disk set to which to apply this 1703 * default setting, or NULL to apply default 1704 * setting to all disk sets 1705 * 1706 * @param val 1707 * RETURN: the default number of data paths for generic 1708 * volume 1709 * 1710 * @return 0 1711 * if successful 1712 * 1713 * @return non-zero 1714 * if an error occurred. Use get_error_string() to 1715 * retrieve the associated error message. 1716 */ 1717 int 1718 defaults_get_volume_npaths( 1719 defaults_t *defaults, 1720 char *diskset, 1721 uint16_t *val) 1722 { 1723 char *disksets[2]; 1724 devconfig_t *volume; 1725 int error; 1726 int i = 0; 1727 1728 /* Check both the given and global (NULL) disk sets for the value */ 1729 disksets[0] = diskset; 1730 disksets[1] = NULL; 1731 do { 1732 /* Get/create singleton volume element for this disk set */ 1733 error = defaults_get_singleton_component( 1734 defaults, disksets[i], TYPE_VOLUME, &volume, FALSE); 1735 1736 switch (error) { 1737 /* volume found for this disk set */ 1738 case 0: 1739 /* Get the npaths attribute */ 1740 if ((error = devconfig_get_volume_npaths( 1741 volume, val)) == 0) { 1742 /* npaths attribute found */ 1743 return (0); 1744 } 1745 1746 /* FALLTHROUGH */ 1747 1748 /* volume not found for this disk set */ 1749 case ENOENT: 1750 break; 1751 1752 /* Invalid disk set, or volume couldn't be created */ 1753 default: 1754 /* volume_set_error already called */ 1755 return (error); 1756 } 1757 1758 /* Stop after the global (NULL) disk set has been searched */ 1759 } while (disksets[i++] != NULL); 1760 1761 return (ENOENT); 1762 } 1763 1764 /* 1765 * Set the default HSP creation flag for generic volume 1766 * 1767 * @param defaults 1768 * a defaults_t hierarchy representing default settings 1769 * for all disk sets and specific disk sets 1770 * 1771 * @param diskset 1772 * the name of the disk set to which to apply this 1773 * default setting, or NULL to apply default 1774 * setting to all disk sets 1775 * 1776 * @param val 1777 * the value to set as the default HSP creation flag for 1778 * generic volume 1779 * 1780 * @return 0 1781 * if successful 1782 * 1783 * @return non-zero 1784 * if an error occurred. Use get_error_string() to 1785 * retrieve the associated error message. 1786 */ 1787 int 1788 defaults_set_volume_usehsp( 1789 defaults_t *defaults, 1790 char *diskset, 1791 boolean_t val) 1792 { 1793 devconfig_t *volume = NULL; 1794 int error = 0; 1795 1796 /* Get/create singleton volume element for this disk set */ 1797 if ((error = defaults_get_singleton_component( 1798 defaults, diskset, TYPE_VOLUME, &volume, TRUE)) != 0) { 1799 /* volume_set_error already called */ 1800 return (error); 1801 } 1802 1803 /* Set the usehsp attribute */ 1804 return (devconfig_set_volume_usehsp(volume, val)); 1805 } 1806 1807 /* 1808 * Get the default HSP creation flag for generic volume 1809 * 1810 * @param defaults 1811 * a defaults_t hierarchy representing default settings 1812 * for all disk sets and specific disk sets 1813 * 1814 * @param diskset 1815 * the name of the disk set to which to apply this 1816 * default setting, or NULL to apply default 1817 * setting to all disk sets 1818 * 1819 * @param val 1820 * RETURN: the default HSP creation flag for generic 1821 * volume 1822 * 1823 * @return 0 1824 * if successful 1825 * 1826 * @return non-zero 1827 * if an error occurred. Use get_error_string() to 1828 * retrieve the associated error message. 1829 */ 1830 int 1831 defaults_get_volume_usehsp( 1832 defaults_t *defaults, 1833 char *diskset, 1834 boolean_t *val) 1835 { 1836 char *disksets[2]; 1837 devconfig_t *volume; 1838 int error; 1839 int i = 0; 1840 1841 /* Check both the given and global (NULL) disk sets for the value */ 1842 disksets[0] = diskset; 1843 disksets[1] = NULL; 1844 do { 1845 /* Get/create singleton volume element for this disk set */ 1846 error = defaults_get_singleton_component( 1847 defaults, disksets[i], TYPE_VOLUME, &volume, FALSE); 1848 1849 switch (error) { 1850 /* volume found for this disk set */ 1851 case 0: 1852 /* Get the usehsp attribute */ 1853 if ((error = devconfig_get_volume_usehsp( 1854 volume, val)) == 0) { 1855 /* usehsp attribute found */ 1856 return (0); 1857 } 1858 1859 /* FALLTHROUGH */ 1860 1861 /* volume not found for this disk set */ 1862 case ENOENT: 1863 break; 1864 1865 /* Invalid disk set, or volume couldn't be created */ 1866 default: 1867 /* volume_set_error already called */ 1868 return (error); 1869 } 1870 1871 /* Stop after the global (NULL) disk set has been searched */ 1872 } while (disksets[i++] != NULL); 1873 1874 return (ENOENT); 1875 } 1876