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 2004 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 <libintl.h> 30 #include <string.h> 31 #include "volume_nvpair.h" 32 #include "volume_error.h" 33 34 /* 35 * ****************************************************************** 36 * 37 * Function prototypes 38 * 39 * ****************************************************************** 40 */ 41 42 static nvpair_t *nvlist_walk_nvpair(nvlist_t *nvl, 43 const char *name, data_type_t type, nvpair_t *nvp); 44 45 /* 46 * ****************************************************************** 47 * 48 * External functions 49 * 50 * ****************************************************************** 51 */ 52 53 /* 54 * Get the named uint16 from the given nvlist_t. 55 * 56 * @param attrs 57 * the nvlist_t to search 58 * 59 * @param which 60 * the string key for this element in the list 61 * 62 * @param val 63 * RETURN: the value of the requested uint16 64 * 65 * @return 0 66 * if successful 67 * 68 * @return ENOENT 69 * if no matching name-value pair is found 70 */ 71 int 72 get_uint16( 73 nvlist_t *attrs, 74 char *which, 75 uint16_t *val) 76 { 77 int error; 78 nvpair_t *match = 79 nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT16, NULL); 80 81 if (match == NULL) { 82 error = ENOENT; 83 } else { 84 error = nvpair_value_uint16(match, val); 85 } 86 87 return (error); 88 } 89 90 /* 91 * Set the named uint16 in the given nvlist_t. 92 * 93 * @param attrs 94 * the nvlist_t to search 95 * 96 * @param which 97 * the string key for this element in the list 98 * 99 * @param val 100 * the value to set 101 * 102 * @return 0 103 * if successful 104 * 105 * @return EINVAL 106 * if there is an invalid argument 107 * 108 * @return ENOMEM 109 * if there is insufficient memory 110 */ 111 int 112 set_uint16( 113 nvlist_t *attrs, 114 char *which, 115 uint16_t val) 116 { 117 int error = 0; 118 119 if ((error = nvlist_add_uint16(attrs, which, val)) != 0) { 120 volume_set_error( 121 gettext("nvlist_add_int16(%s) failed: %d\n"), which, error); 122 } 123 124 return (error); 125 } 126 127 /* 128 * Get the named uint32 from the given nvlist_t. 129 * 130 * @param attrs 131 * the nvlist_t to search 132 * 133 * @param which 134 * the string key for this element in the list 135 * 136 * @param val 137 * RETURN: the value of the requested uint32 138 * 139 * @return 0 140 * if successful 141 * 142 * @return ENOENT 143 * if no matching name-value pair is found 144 */ 145 int 146 get_uint32( 147 nvlist_t *attrs, 148 char *which, 149 uint32_t *val) 150 { 151 int error; 152 nvpair_t *match = 153 nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT32, NULL); 154 155 if (match == NULL) { 156 error = ENOENT; 157 } else { 158 error = nvpair_value_uint32(match, val); 159 } 160 161 return (error); 162 } 163 164 /* 165 * Set the named uint32 in the given nvlist_t. 166 * 167 * @param attrs 168 * the nvlist_t to search 169 * 170 * @param which 171 * the string key for this element in the list 172 * 173 * @param val 174 * the value to set 175 * 176 * @return 0 177 * if successful 178 * 179 * @return EINVAL 180 * if there is an invalid argument 181 * 182 * @return ENOMEM 183 * if there is insufficient memory 184 */ 185 int 186 set_uint32( 187 nvlist_t *attrs, 188 char *which, 189 uint32_t val) 190 { 191 int error = 0; 192 193 if ((error = nvlist_add_uint32(attrs, which, val)) != 0) { 194 volume_set_error( 195 gettext("nvlist_add_int32(%s) failed: %d\n"), which, error); 196 } 197 198 return (error); 199 } 200 201 /* 202 * Get the named uint64 from the given nvlist_t. 203 * 204 * @param attrs 205 * the nvlist_t to search 206 * 207 * @param which 208 * the string key for this element in the list 209 * 210 * @param val 211 * RETURN: the value of the requested uint64 212 * 213 * @return 0 214 * if successful 215 * 216 * @return ENOENT 217 * if no matching name-value pair is found 218 */ 219 int 220 get_uint64( 221 nvlist_t *attrs, 222 char *which, 223 uint64_t *val) 224 { 225 int error; 226 nvpair_t *match = 227 nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT64, NULL); 228 229 if (match == NULL) { 230 error = ENOENT; 231 } else { 232 error = nvpair_value_uint64(match, val); 233 } 234 235 return (error); 236 } 237 238 /* 239 * Set the named uint64 in the given nvlist_t. 240 * 241 * @param attrs 242 * the nvlist_t to search 243 * 244 * @param which 245 * the string key for this element in the list 246 * 247 * @param val 248 * the value to set 249 * 250 * @return 0 251 * if successful 252 * 253 * @return EINVAL 254 * if there is an invalid argument 255 * 256 * @return ENOMEM 257 * if there is insufficient memory 258 */ 259 int 260 set_uint64( 261 nvlist_t *attrs, 262 char *which, 263 uint64_t val) 264 { 265 int error = 0; 266 267 if ((error = nvlist_add_uint64(attrs, which, val)) != 0) { 268 volume_set_error( 269 gettext("nvlist_add_int64(%s) failed: %d\n"), which, error); 270 } 271 272 return (error); 273 } 274 275 /* 276 * Set the named boolean in the given nvlist_t. 277 * 278 * @param attrs 279 * the nvlist_t to search 280 * 281 * @param which 282 * the string key for this element in the list 283 * 284 * @param val 285 * the value to set 286 * 287 * @return 0 288 * if successful 289 * 290 * @return EINVAL 291 * if there is an invalid argument 292 * 293 * @return ENOMEM 294 * if there is insufficient memory 295 */ 296 int 297 set_boolean( 298 nvlist_t *attrs, 299 char *which, 300 boolean_t val) 301 { 302 /* 303 * Use set_uint16 to distinguish "attr = B_FALSE" from 304 * "attribute unset". 305 */ 306 return (set_uint16(attrs, which, val == B_TRUE ? 1 : 0)); 307 } 308 309 /* 310 * Get the named boolean from the given nvlist_t. 311 * 312 * @param attrs 313 * the nvlist_t to search 314 * 315 * @param which 316 * the string key for this element in the list 317 * 318 * @param boolval 319 * RETURN: the value of the requested boolean 320 * 321 * @return 0 322 * if successful 323 * 324 * @return ENOENT 325 * if no matching name-value pair is found 326 */ 327 int 328 get_boolean( 329 nvlist_t *attrs, 330 char *which, 331 boolean_t *boolval) 332 { 333 int error; 334 uint16_t val; 335 336 /* 337 * Use get_uint16 to distinguish "attr = B_FALSE" from 338 * "attribute unset". 339 */ 340 if ((error = get_uint16(attrs, which, &val)) == 0) { 341 *boolval = (val ? B_TRUE : B_FALSE); 342 } 343 344 return (error); 345 } 346 347 /* 348 * Get the named string from the given nvlist_t. 349 * 350 * @param attrs 351 * the nvlist_t to search 352 * 353 * @param which 354 * the string key for this element in the list 355 * 356 * @param str 357 * RETURN: the requested string 358 * 359 * @return 0 360 * if successful 361 * 362 * @return ENOENT 363 * if no matching name-value pair is found 364 */ 365 int 366 get_string( 367 nvlist_t *attrs, 368 char *which, 369 char **str) 370 { 371 int error; 372 nvpair_t *match = 373 nvlist_walk_nvpair(attrs, which, DATA_TYPE_STRING, NULL); 374 375 if (match == NULL) { 376 error = ENOENT; 377 } else { 378 error = nvpair_value_string(match, str); 379 } 380 381 return (error); 382 } 383 384 /* 385 * Set the named string in the given nvlist_t. 386 * 387 * @param attrs 388 * the nvlist_t to search 389 * 390 * @param which 391 * the string key for this element in the list 392 * 393 * @param val 394 * the value to set 395 * 396 * @return 0 397 * if successful 398 * 399 * @return EINVAL 400 * if there is an invalid argument 401 * 402 * @return ENOMEM 403 * if there is insufficient memory 404 */ 405 int 406 set_string( 407 nvlist_t *attrs, 408 char *which, 409 char *val) 410 { 411 int error = 0; 412 413 if ((error = nvlist_add_string(attrs, which, val)) != 0) { 414 volume_set_error( 415 gettext("nvlist_add_string(%s) failed: %d\n"), which, error); 416 } 417 418 return (error); 419 } 420 421 /* 422 * Get the named uint16 array from the given nvlist_t. 423 * 424 * @param attrs 425 * the nvlist_t to search 426 * 427 * @param which 428 * the string key for this element in the list 429 * 430 * @param val 431 * RETURN: the value of the requested uint16 array 432 * 433 * @param nelem 434 * RETURN: the number of elements in the array 435 * 436 * @return 0 437 * if successful 438 * 439 * @return ENOENT 440 * if no matching name-value pair is found 441 */ 442 int 443 get_uint16_array( 444 nvlist_t *attrs, 445 char *which, 446 uint16_t **val, 447 uint_t *nelem) 448 { 449 int error; 450 nvpair_t *match = 451 nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT16_ARRAY, NULL); 452 453 if (match == NULL) { 454 error = ENOENT; 455 } else { 456 error = nvpair_value_uint16_array(match, val, nelem); 457 } 458 459 return (error); 460 } 461 462 /* 463 * Set the named uint16 array from the given nvlist_t. 464 * 465 * @param attrs 466 * the nvlist_t to search 467 * 468 * @param which 469 * the string key for this element in the list 470 * 471 * @param val 472 * the value of the requested uint16 array 473 * 474 * @param nelem 475 * the number of elements in the array 476 * 477 * @return 0 478 * if successful 479 * 480 * @return EINVAL 481 * if there is an invalid argument 482 * 483 * @return ENOMEM 484 * if there is insufficient memory 485 */ 486 int 487 set_uint16_array( 488 nvlist_t *attrs, 489 char *which, 490 uint16_t *val, 491 uint_t nelem) 492 { 493 int error = 0; 494 495 if ((error = nvlist_add_uint16_array( 496 attrs, which, val, nelem)) != 0) { 497 volume_set_error( 498 gettext("nvlist_add_uint16_array(%s) failed: %d.\n"), 499 which, error); 500 } 501 502 return (error); 503 } 504 505 /* 506 * Get the named uint64 array from the given nvlist_t. 507 * 508 * @param attrs 509 * the nvlist_t to search 510 * 511 * @param which 512 * the string key for this element in the list 513 * 514 * @param val 515 * RETURN: the value of the requested uint64 array 516 * 517 * @param nelem 518 * RETURN: the number of elements in the array 519 * 520 * @return 0 521 * if successful 522 * 523 * @return ENOENT 524 * if no matching name-value pair is found 525 */ 526 int 527 get_uint64_array( 528 nvlist_t *attrs, 529 char *which, 530 uint64_t **val, 531 uint_t *nelem) 532 { 533 int error; 534 nvpair_t *match = 535 nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT64_ARRAY, NULL); 536 537 if (match == NULL) { 538 error = ENOENT; 539 } else { 540 error = nvpair_value_uint64_array(match, val, nelem); 541 } 542 543 return (error); 544 } 545 546 /* 547 * Set the named uint64 array from the given nvlist_t. 548 * 549 * @param attrs 550 * the nvlist_t to search 551 * 552 * @param which 553 * the string key for this element in the list 554 * 555 * @param val 556 * the value of the requested uint64 array 557 * 558 * @param nelem 559 * the number of elements in the array 560 * 561 * @return 0 562 * if successful 563 * 564 * @return EINVAL 565 * if there is an invalid argument 566 * 567 * @return ENOMEM 568 * if there is insufficient memory 569 */ 570 int 571 set_uint64_array( 572 nvlist_t *attrs, 573 char *which, 574 uint64_t *val, 575 uint_t nelem) 576 { 577 int error = 0; 578 579 if ((error = nvlist_add_uint64_array( 580 attrs, which, val, nelem)) != 0) { 581 volume_set_error( 582 gettext("nvlist_add_uint64_array(%s) failed: %d.\n"), 583 which, error); 584 } 585 586 return (error); 587 } 588 589 /* 590 * Get the named string array from the given nvlist_t. 591 * 592 * @param attrs 593 * the nvlist_t to search 594 * 595 * @param which 596 * the string key for this element in the list 597 * 598 * @param val 599 * RETURN: the value of the requested string array 600 * 601 * @param nelem 602 * RETURN: the number of elements in the array 603 * 604 * @return 0 605 * if successful 606 * 607 * @return ENOENT 608 * if no matching name-value pair is found 609 */ 610 int 611 get_string_array( 612 nvlist_t *attrs, 613 char *which, 614 char ***val, 615 uint_t *nelem) 616 { 617 int error; 618 nvpair_t *match = 619 nvlist_walk_nvpair(attrs, which, DATA_TYPE_STRING_ARRAY, NULL); 620 621 if (match == NULL) { 622 error = ENOENT; 623 } else { 624 error = nvpair_value_string_array(match, val, nelem); 625 } 626 627 return (error); 628 } 629 630 /* 631 * Set the named string array from the given nvlist_t. 632 * 633 * @param attrs 634 * the nvlist_t to search 635 * 636 * @param which 637 * the string key for this element in the list 638 * 639 * @param val 640 * the value of the requested string array 641 * 642 * @param nelem 643 * the number of elements in the array 644 * 645 * @return 0 646 * if successful 647 * 648 * @return EINVAL 649 * if there is an invalid argument 650 * 651 * @return ENOMEM 652 * if there is insufficient memory 653 */ 654 int 655 set_string_array( 656 nvlist_t *attrs, 657 char *which, 658 char **val, 659 uint_t nelem) 660 { 661 int error = 0; 662 663 if ((error = nvlist_add_string_array( 664 attrs, which, val, nelem)) != 0) { 665 volume_set_error( 666 gettext("nvlist_add_string_array(%s) failed: %d.\n"), 667 which, error); 668 } 669 670 return (error); 671 } 672 673 /* 674 * ****************************************************************** 675 * 676 * Static functions 677 * 678 * ****************************************************************** 679 */ 680 681 /* 682 * Get a handle to the next nvpair with the specified name and data 683 * type in the list following the given nvpair. 684 * 685 * Some variation of this function will likely appear in the libnvpair 686 * library per 4981923. 687 * 688 * @param nvl 689 * the nvlist_t to search 690 * 691 * @param name 692 * the string key for the pair to find in the list, or 693 * NULL to match any name 694 * 695 * @param type 696 * the data type for the pair to find in the list, or 697 * DATA_TYPE_UNKNOWN to match any type 698 * 699 * @param nvp 700 * the pair to search from in the list, or NULL to search 701 * from the beginning of the list 702 * 703 * @return the next nvpair in the list matching the given 704 * criteria, or NULL if no matching nvpair is found 705 */ 706 static nvpair_t * 707 nvlist_walk_nvpair( 708 nvlist_t *nvl, 709 const char *name, 710 data_type_t type, 711 nvpair_t *nvp) 712 { 713 /* For each nvpair in the list following nvp... */ 714 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 715 716 /* Does this pair's name match the given name? */ 717 if ((name == NULL || strcmp(nvpair_name(nvp), name) == 0) && 718 719 /* Does this pair's type match the given type? */ 720 (type == DATA_TYPE_UNKNOWN || type == nvpair_type(nvp))) { 721 return (nvp); 722 } 723 } 724 725 return (NULL); 726 } 727