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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Routines for traversing and packing/unpacking the handle 30 * returned from ri_init. 31 */ 32 33 #include <stdlib.h> 34 #include <strings.h> 35 #include "rsrc_info.h" 36 #include "rsrc_info_impl.h" 37 38 static int ap_list_pack(ri_ap_t *, char **, size_t *, int); 39 static int ap_list_unpack(char *, size_t, ri_ap_t **); 40 static int ap_pack(ri_ap_t *, char **, size_t *, int); 41 static int ap_unpack(char *, size_t, ri_ap_t *); 42 static int dev_list_pack(ri_dev_t *, char **, size_t *, int); 43 static int dev_list_unpack(char *, size_t, ri_dev_t **); 44 static int dev_pack(ri_dev_t *, char **, size_t *, int); 45 static int dev_unpack(char *, size_t, ri_dev_t *); 46 static int client_list_pack(ri_client_t *, char **, size_t *, int); 47 static int client_list_unpack(char *, size_t, ri_client_t **); 48 static int client_pack(ri_client_t *, char **, size_t *, int); 49 static int client_unpack(char *, size_t, ri_client_t *); 50 static int pack_add_byte_array(nvlist_t *, char *, nvlist_t *, int); 51 static int lookup_unpack_byte_array(nvlist_t *, char *, nvlist_t **); 52 static void ri_ap_free(ri_ap_t *); 53 54 void 55 ri_fini(ri_hdl_t *hdl) 56 { 57 ri_ap_t *ap; 58 ri_client_t *client; 59 60 if (hdl == NULL) 61 return; 62 63 while ((ap = hdl->aps) != NULL) { 64 hdl->aps = ap->next; 65 ri_ap_free(ap); 66 } 67 while ((client = hdl->cpu_cap_clients) != NULL) { 68 hdl->cpu_cap_clients = client->next; 69 ri_client_free(client); 70 } 71 while ((client = hdl->mem_cap_clients) != NULL) { 72 hdl->mem_cap_clients = client->next; 73 ri_client_free(client); 74 } 75 free(hdl); 76 } 77 78 static void 79 ri_ap_free(ri_ap_t *ap) 80 { 81 ri_dev_t *dev; 82 83 assert(ap != NULL); 84 85 if (ap->conf_props != NULL) 86 nvlist_free(ap->conf_props); 87 88 while ((dev = ap->cpus) != NULL) { 89 ap->cpus = dev->next; 90 ri_dev_free(dev); 91 } 92 while ((dev = ap->mems) != NULL) { 93 ap->mems = dev->next; 94 ri_dev_free(dev); 95 } 96 while ((dev = ap->ios) != NULL) { 97 ap->ios = dev->next; 98 ri_dev_free(dev); 99 } 100 free(ap); 101 } 102 103 void 104 ri_dev_free(ri_dev_t *dev) 105 { 106 ri_client_t *client; 107 108 assert(dev != NULL); 109 110 nvlist_free(dev->conf_props); 111 while ((client = dev->rcm_clients) != NULL) { 112 dev->rcm_clients = client->next; 113 ri_client_free(client); 114 } 115 free(dev); 116 } 117 118 void 119 ri_client_free(ri_client_t *client) 120 { 121 assert(client != NULL); 122 123 if (client->usg_props != NULL) 124 nvlist_free(client->usg_props); 125 if (client->v_props != NULL) 126 nvlist_free(client->v_props); 127 free(client); 128 } 129 130 /* 131 * Pack everything contained in the handle up inside out. 132 */ 133 int 134 ri_pack(ri_hdl_t *hdl, caddr_t *bufp, size_t *sizep, int encoding) 135 { 136 nvlist_t *nvl = NULL; 137 char *buf = NULL; 138 size_t size = 0; 139 140 if (bufp == NULL || sizep == NULL) 141 return (RI_INVAL); 142 143 *sizep = 0; 144 *bufp = NULL; 145 146 /* 147 * Check the handle. If it is NULL, there 148 * is nothing to pack, so we are done. 149 */ 150 if (hdl == NULL) { 151 return (RI_SUCCESS); 152 } 153 154 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 155 dprintf((stderr, "nvlist_alloc fail\n", errno)); 156 goto fail; 157 } 158 159 if (nvlist_add_int32(nvl, RI_HDL_FLAGS, hdl->flags) != 0) { 160 dprintf((stderr, "nvlist_add_int32 fail\n")); 161 goto fail; 162 } 163 164 if (ap_list_pack(hdl->aps, &buf, &size, encoding) != 0 || 165 nvlist_add_byte_array(nvl, RI_HDL_APS, (uchar_t *)buf, size) != 0) { 166 goto fail; 167 } 168 169 s_free(buf); 170 if (client_list_pack(hdl->cpu_cap_clients, &buf, &size, 171 encoding) != 0 || 172 nvlist_add_byte_array(nvl, RI_HDL_CPU_CAPS, (uchar_t *)buf, 173 size) != 0) { 174 goto fail; 175 } 176 177 s_free(buf); 178 if (client_list_pack(hdl->mem_cap_clients, &buf, &size, 179 encoding) != 0 || 180 nvlist_add_byte_array(nvl, RI_HDL_MEM_CAPS, (uchar_t *)buf, 181 size) != 0) { 182 goto fail; 183 } 184 185 s_free(buf); 186 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 187 dprintf((stderr, "nvlist_pack fail\n")); 188 goto fail; 189 } 190 191 nvlist_free(nvl); 192 *bufp = buf; 193 *sizep = size; 194 195 return (RI_SUCCESS); 196 197 fail: 198 s_free(buf); 199 if (nvl != NULL) 200 nvlist_free(nvl); 201 202 return (RI_FAILURE); 203 } 204 205 /* 206 * Pack a list of attachment point handles. 207 */ 208 static int 209 ap_list_pack(ri_ap_t *aplist, char **bufp, size_t *sizep, int encoding) 210 { 211 nvlist_t *nvl = NULL; 212 char *buf = NULL; 213 size_t size; 214 215 assert(bufp != NULL && sizep != NULL); 216 217 *sizep = 0; 218 *bufp = NULL; 219 220 if (nvlist_alloc(&nvl, 0, 0) != 0) { 221 dprintf((stderr, "nvlist_alloc fail\n")); 222 return (-1); 223 } 224 225 while (aplist != NULL) { 226 s_free(buf); 227 if (ap_pack(aplist, &buf, &size, encoding) != 0) 228 goto fail; 229 230 if (nvlist_add_byte_array(nvl, RI_AP_T, (uchar_t *)buf, 231 size) != 0) { 232 dprintf((stderr, "nvlist_add_byte_array fail " 233 "(%s)\n", RI_AP_T)); 234 goto fail; 235 } 236 aplist = aplist->next; 237 } 238 239 s_free(buf); 240 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 241 dprintf((stderr, "nvlist_pack fail\n")); 242 goto fail; 243 } 244 245 nvlist_free(nvl); 246 *bufp = buf; 247 *sizep = size; 248 249 return (0); 250 251 fail: 252 s_free(buf); 253 if (nvl != NULL) 254 nvlist_free(nvl); 255 256 return (-1); 257 } 258 259 /* 260 * Pack a list of ri_dev_t's. 261 */ 262 static int 263 dev_list_pack(ri_dev_t *devlist, char **bufp, size_t *sizep, int encoding) 264 { 265 nvlist_t *nvl = NULL; 266 char *buf = NULL; 267 size_t size = 0; 268 269 assert(bufp != NULL && sizep != NULL); 270 271 *sizep = 0; 272 *bufp = NULL; 273 274 if (nvlist_alloc(&nvl, 0, 0) != 0) { 275 dprintf((stderr, "nvlist_alloc fail\n")); 276 return (-1); 277 } 278 279 while (devlist != NULL) { 280 s_free(buf); 281 if (dev_pack(devlist, &buf, &size, encoding) != 0) 282 goto fail; 283 284 if (nvlist_add_byte_array(nvl, RI_DEV_T, (uchar_t *)buf, 285 size) != 0) { 286 dprintf((stderr, "nvlist_add_byte_array fail " 287 "(%s)\n", RI_DEV_T)); 288 goto fail; 289 } 290 devlist = devlist->next; 291 } 292 293 s_free(buf); 294 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 295 dprintf((stderr, "nvlist_pack fail\n")); 296 goto fail; 297 } 298 299 nvlist_free(nvl); 300 *bufp = buf; 301 *sizep = size; 302 303 return (0); 304 305 fail: 306 s_free(buf); 307 if (nvl != NULL) 308 nvlist_free(nvl); 309 310 return (-1); 311 } 312 313 /* 314 * Pack a list of ri_client_t's. 315 */ 316 static int 317 client_list_pack(ri_client_t *client_list, char **bufp, size_t *sizep, 318 int encoding) 319 { 320 nvlist_t *nvl = NULL; 321 char *buf = NULL; 322 size_t size = 0; 323 324 assert(bufp != NULL && sizep != NULL); 325 326 *sizep = 0; 327 *bufp = NULL; 328 329 if (nvlist_alloc(&nvl, 0, 0) != 0) { 330 dprintf((stderr, "nvlist_alloc fail\n")); 331 return (-1); 332 } 333 334 while (client_list != NULL) { 335 s_free(buf); 336 if (client_pack(client_list, &buf, &size, encoding) != 0) 337 goto fail; 338 339 if (nvlist_add_byte_array(nvl, RI_CLIENT_T, (uchar_t *)buf, 340 size) != 0) { 341 dprintf((stderr, "nvlist_add_byte_array fail " 342 "(%s)\n", RI_CLIENT_T)); 343 goto fail; 344 } 345 client_list = client_list->next; 346 } 347 348 s_free(buf); 349 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 350 dprintf((stderr, "nvlist_pack fail\n")); 351 goto fail; 352 } 353 354 nvlist_free(nvl); 355 *bufp = buf; 356 *sizep = size; 357 358 return (0); 359 360 fail: 361 s_free(buf); 362 if (nvl != NULL) 363 nvlist_free(nvl); 364 365 return (-1); 366 } 367 368 static int 369 ap_pack(ri_ap_t *ap, char **bufp, size_t *sizep, int encoding) 370 { 371 nvlist_t *nvl = NULL; 372 char *buf = NULL; 373 size_t size = 0; 374 375 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 376 dprintf((stderr, "nvlist_alloc fail\n")); 377 return (-1); 378 } 379 380 if (pack_add_byte_array(ap->conf_props, RI_AP_PROPS, nvl, 381 encoding) != 0) 382 goto fail; 383 384 if (dev_list_pack(ap->cpus, &buf, &size, encoding) != 0) 385 goto fail; 386 387 if (nvlist_add_byte_array(nvl, RI_AP_CPUS, (uchar_t *)buf, 388 size) != 0) { 389 dprintf((stderr, "nvlist_add_byte_array (%s)\n", RI_AP_CPUS)); 390 goto fail; 391 } 392 393 s_free(buf); 394 if (dev_list_pack(ap->mems, &buf, &size, encoding) != 0) 395 goto fail; 396 397 if (nvlist_add_byte_array(nvl, RI_AP_MEMS, (uchar_t *)buf, 398 size) != 0) { 399 dprintf((stderr, "nvlist_add_byte_array (%s)n", RI_AP_MEMS)); 400 goto fail; 401 } 402 403 s_free(buf); 404 if (dev_list_pack(ap->ios, &buf, &size, encoding) != 0) 405 goto fail; 406 407 if (nvlist_add_byte_array(nvl, RI_AP_IOS, (uchar_t *)buf, 408 size) != 0) { 409 dprintf((stderr, "nvlist_add_byte_array (%s)n", RI_AP_IOS)); 410 goto fail; 411 } 412 413 s_free(buf); 414 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 415 dprintf((stderr, "nvlist_pack fail\n")); 416 goto fail; 417 } 418 419 nvlist_free(nvl); 420 *bufp = buf; 421 *sizep = size; 422 423 return (0); 424 425 fail: 426 s_free(buf); 427 if (nvl != NULL) 428 nvlist_free(nvl); 429 430 return (-1); 431 } 432 433 static int 434 dev_pack(ri_dev_t *dev, char **bufp, size_t *sizep, int encoding) 435 { 436 nvlist_t *nvl = NULL; 437 char *buf = NULL; 438 size_t size = 0; 439 440 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 441 dprintf((stderr, "nvlist_alloc fail\n")); 442 return (-1); 443 } 444 445 if (pack_add_byte_array(dev->conf_props, RI_DEV_PROPS, nvl, 446 encoding) != 0) 447 goto fail; 448 449 if (client_list_pack(dev->rcm_clients, &buf, &size, encoding) != 0) 450 goto fail; 451 452 if (nvlist_add_byte_array(nvl, RI_DEV_CLIENTS, (uchar_t *)buf, 453 size) != 0) { 454 dprintf((stderr, "nvlist_add_byte_array (%s)n", 455 RI_DEV_CLIENTS)); 456 goto fail; 457 } 458 459 s_free(buf); 460 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 461 dprintf((stderr, "nvlist_pack fail\n")); 462 goto fail; 463 } 464 465 nvlist_free(nvl); 466 *bufp = buf; 467 *sizep = size; 468 469 return (0); 470 471 fail: 472 s_free(buf); 473 if (nvl != NULL) 474 nvlist_free(nvl); 475 476 return (-1); 477 } 478 479 static int 480 client_pack(ri_client_t *client, char **bufp, size_t *sizep, int encoding) 481 { 482 nvlist_t *nvl = NULL; 483 char *buf = NULL; 484 size_t size = 0; 485 486 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 487 dprintf((stderr, "nvlist_alloc fail\n")); 488 return (-1); 489 } 490 491 if (pack_add_byte_array(client->usg_props, RI_CLIENT_USAGE_PROPS, 492 nvl, encoding) != 0) { 493 goto fail; 494 } 495 496 /* 497 * This will only be present if RI_VERBOSE was specified 498 * in the call to ri_init. 499 */ 500 if (client->v_props != NULL && pack_add_byte_array(client->v_props, 501 RI_CLIENT_VERB_PROPS, nvl, encoding) != 0) { 502 goto fail; 503 } 504 505 if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) { 506 dprintf((stderr, "nvlist_pack fail\n")); 507 goto fail; 508 } 509 510 nvlist_free(nvl); 511 *bufp = buf; 512 *sizep = size; 513 514 return (0); 515 516 fail: 517 s_free(buf); 518 if (nvl != NULL) 519 nvlist_free(nvl); 520 521 return (-1); 522 } 523 524 /* 525 * Pack nvlist_t and add as byte array to another nvlist_t. 526 */ 527 static int 528 pack_add_byte_array(nvlist_t *nvl_packme, char *name, nvlist_t *nvl, 529 int encoding) 530 { 531 char *buf = NULL; 532 size_t size = 0; 533 534 if (nvlist_pack(nvl_packme, &buf, &size, encoding, 0) != 0) { 535 dprintf((stderr, "nvlist_pack fail (%s)\n", name)); 536 s_free(buf); 537 return (-1); 538 } 539 540 if (nvlist_add_byte_array(nvl, name, (uchar_t *)buf, size) != 0) { 541 dprintf((stderr, "nvlist_add_byte_array fail (%s)\n", name)); 542 return (-1); 543 } 544 545 s_free(buf); 546 return (0); 547 } 548 549 /* 550 * Unpack buf into ri_hdl_t. 551 */ 552 int 553 ri_unpack(caddr_t buf, size_t size, ri_hdl_t **hdlp) 554 { 555 ri_hdl_t *ri_hdl = NULL; 556 nvlist_t *nvl = NULL; 557 558 if (hdlp == NULL) 559 return (RI_INVAL); 560 561 *hdlp = NULL; 562 if ((ri_hdl = calloc(1, sizeof (*ri_hdl))) == NULL) { 563 dprintf((stderr, "calloc: %s\n", strerror(errno))); 564 return (RI_FAILURE); 565 } 566 567 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 568 dprintf((stderr, "nvlist_unpack fail\n")); 569 goto fail; 570 } 571 572 if (nvlist_lookup_int32(nvl, RI_HDL_FLAGS, &ri_hdl->flags) != 0) { 573 dprintf((stderr, "nvlist_lookup_int32 fail (%s)\n", 574 RI_HDL_FLAGS)); 575 goto fail; 576 } 577 578 buf = NULL; 579 size = 0; 580 if (nvlist_lookup_byte_array(nvl, RI_HDL_APS, (uchar_t **)&buf, 581 (uint_t *)&size) != 0) { 582 dprintf((stderr, "nvlist_lookup_int32 fail (%s)\n", 583 RI_HDL_APS)); 584 goto fail; 585 } 586 587 if (ap_list_unpack(buf, size, &ri_hdl->aps) != 0) 588 goto fail; 589 590 buf = NULL; 591 size = 0; 592 if (nvlist_lookup_byte_array(nvl, RI_HDL_CPU_CAPS, (uchar_t **)&buf, 593 (uint_t *)&size) != 0) { 594 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 595 RI_HDL_CPU_CAPS)); 596 goto fail; 597 } 598 599 if (client_list_unpack(buf, size, &ri_hdl->cpu_cap_clients) != 0) 600 goto fail; 601 602 buf = NULL; 603 size = 0; 604 if (nvlist_lookup_byte_array(nvl, RI_HDL_MEM_CAPS, (uchar_t **)&buf, 605 (uint_t *)&size) != 0) { 606 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 607 RI_HDL_MEM_CAPS)); 608 goto fail; 609 } 610 611 if (client_list_unpack(buf, size, &ri_hdl->mem_cap_clients) != 0) 612 goto fail; 613 614 *hdlp = ri_hdl; 615 616 return (0); 617 618 fail: 619 free(ri_hdl); 620 if (nvl != NULL) 621 nvlist_free(nvl); 622 623 return (-1); 624 } 625 626 static int 627 ap_list_unpack(char *buf, size_t size, ri_ap_t **aps) 628 { 629 nvpair_t *nvp = NULL; 630 nvlist_t *nvl; 631 ri_ap_t *aplist = NULL; 632 ri_ap_t *prev = NULL; 633 ri_ap_t *tmp = NULL; 634 635 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 636 dprintf((stderr, "nvlist_unpack fail\n")); 637 return (-1); 638 } 639 640 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 641 assert(strcmp(nvpair_name(nvp), RI_AP_T) == 0 && 642 nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY); 643 644 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 645 dprintf((stderr, "calloc: %s\n", strerror(errno))); 646 goto fail; 647 } 648 649 buf = NULL; 650 size = 0; 651 if (nvpair_value_byte_array(nvp, (uchar_t **)&buf, 652 (uint_t *)&size) != 0) { 653 dprintf((stderr, "nvpair_value_byte_array fail\n")); 654 goto fail; 655 } 656 657 if (ap_unpack(buf, size, tmp) != 0) 658 goto fail; 659 660 if (aplist == NULL) { 661 prev = aplist = tmp; 662 } else { 663 prev->next = tmp; 664 prev = tmp; 665 } 666 } 667 668 nvlist_free(nvl); 669 *aps = aplist; 670 671 return (0); 672 673 fail: 674 if (nvl != NULL) 675 nvlist_free(nvl); 676 if (aplist != NULL) { 677 while ((tmp = aplist) != NULL) { 678 aplist = aplist->next; 679 ri_ap_free(tmp); 680 } 681 } 682 683 return (-1); 684 } 685 686 static int 687 dev_list_unpack(char *buf, size_t size, ri_dev_t **devs) 688 { 689 nvpair_t *nvp = NULL; 690 nvlist_t *nvl; 691 ri_dev_t *devlist = NULL; 692 ri_dev_t *prev = NULL; 693 ri_dev_t *tmp = NULL; 694 695 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 696 dprintf((stderr, "nvlist_unpack fail\n")); 697 return (-1); 698 } 699 700 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 701 assert(strcmp(nvpair_name(nvp), RI_DEV_T) == 0 && 702 nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY); 703 704 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 705 dprintf((stderr, "calloc: %s\n", strerror(errno))); 706 goto fail; 707 } 708 709 if (nvpair_value_byte_array(nvp, (uchar_t **)&buf, 710 (uint_t *)&size) != 0) { 711 dprintf((stderr, "nvpair_value_byte_array fail\n")); 712 goto fail; 713 } 714 715 if (dev_unpack(buf, size, tmp) != 0) 716 goto fail; 717 718 if (devlist == NULL) { 719 prev = devlist = tmp; 720 } else { 721 prev->next = tmp; 722 prev = tmp; 723 } 724 } 725 726 nvlist_free(nvl); 727 *devs = devlist; 728 729 return (0); 730 731 fail: 732 if (nvl != NULL) 733 nvlist_free(nvl); 734 if (devlist != NULL) { 735 while ((tmp = devlist) != NULL) { 736 devlist = devlist->next; 737 ri_dev_free(tmp); 738 } 739 } 740 741 return (-1); 742 } 743 744 static int 745 client_list_unpack(char *buf, size_t size, ri_client_t **clients) 746 { 747 nvpair_t *nvp = NULL; 748 nvlist_t *nvl; 749 ri_client_t *client_list = NULL; 750 ri_client_t *prev = NULL; 751 ri_client_t *tmp = NULL; 752 753 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 754 dprintf((stderr, "nvlist_unpack fail\n")); 755 return (-1); 756 } 757 758 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 759 assert(strcmp(nvpair_name(nvp), RI_CLIENT_T) == 0); 760 assert(nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY); 761 762 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 763 dprintf((stderr, "calloc: %s\n", strerror(errno))); 764 goto fail; 765 } 766 767 buf = NULL; 768 size = 0; 769 if (nvpair_value_byte_array(nvp, (uchar_t **)&buf, 770 (uint_t *)&size) != 0) { 771 dprintf((stderr, "nvpair_value_byte_array fail\n")); 772 goto fail; 773 } 774 775 if (client_unpack(buf, size, tmp) != 0) 776 goto fail; 777 778 if (client_list == NULL) { 779 prev = client_list = tmp; 780 } else { 781 prev->next = tmp; 782 prev = tmp; 783 } 784 } 785 786 nvlist_free(nvl); 787 *clients = client_list; 788 789 return (0); 790 791 fail: 792 if (nvl != NULL) 793 nvlist_free(nvl); 794 if (client_list != NULL) { 795 while ((tmp = client_list) != NULL) { 796 client_list = client_list->next; 797 ri_client_free(tmp); 798 } 799 } 800 801 return (-1); 802 } 803 804 static int 805 client_unpack(char *buf, size_t size, ri_client_t *client) 806 { 807 nvlist_t *nvl; 808 809 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 810 dprintf((stderr, "nvlist_unpack fail\n")); 811 return (-1); 812 } 813 814 if (lookup_unpack_byte_array(nvl, RI_CLIENT_USAGE_PROPS, 815 &client->usg_props) != 0) { 816 nvlist_free(nvl); 817 return (-1); 818 } 819 820 #ifdef DEBUG 821 nvlist_print(stderr, client->usg_props); 822 #endif /* DEBUG */ 823 824 /* 825 * Verbose properties for RCM clients only present if 826 * RI_VERBOSE was specified for ri_init. 827 */ 828 buf = NULL; 829 size = 0; 830 if (nvlist_lookup_byte_array(nvl, RI_CLIENT_VERB_PROPS, 831 (uchar_t **)&buf, (uint_t *)&size) == 0) { 832 if (nvlist_unpack(buf, size, &client->v_props, 0) != 0) { 833 dprintf((stderr, "nvlist_unpack fail (%s)\n", 834 RI_CLIENT_VERB_PROPS)); 835 nvlist_free(nvl); 836 return (-1); 837 } 838 } 839 840 nvlist_free(nvl); 841 842 return (0); 843 } 844 845 static int 846 dev_unpack(char *buf, size_t size, ri_dev_t *dev) 847 { 848 nvlist_t *nvl; 849 850 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 851 dprintf((stderr, "nvlist_unpack fail\n")); 852 return (-1); 853 } 854 855 if (lookup_unpack_byte_array(nvl, RI_DEV_PROPS, 856 &dev->conf_props) != 0) { 857 nvlist_free(nvl); 858 return (-1); 859 } 860 861 #ifdef DEBUG 862 nvlist_print(stderr, dev->conf_props); 863 #endif /* DEBUG */ 864 865 if (nvlist_lookup_byte_array(nvl, RI_DEV_CLIENTS, (uchar_t **)&buf, 866 (uint_t *)&size) != 0) { 867 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 868 RI_DEV_CLIENTS)); 869 nvlist_free(nvl); 870 return (-1); 871 } 872 873 if (client_list_unpack(buf, size, &dev->rcm_clients) != 0) { 874 nvlist_free(nvl); 875 return (-1); 876 } 877 878 nvlist_free(nvl); 879 880 return (0); 881 } 882 883 static int 884 ap_unpack(char *buf, size_t size, ri_ap_t *ap) 885 { 886 nvlist_t *nvl; 887 888 if (nvlist_unpack(buf, size, &nvl, 0) != 0) { 889 dprintf((stderr, "nvlist_unpack fail\n")); 890 return (-1); 891 } 892 893 if (lookup_unpack_byte_array(nvl, RI_AP_PROPS, &ap->conf_props) != 0) { 894 nvlist_free(nvl); 895 return (-1); 896 } 897 898 #ifdef DEBUG 899 nvlist_print(stderr, ap->conf_props); 900 #endif /* DEBUG */ 901 902 if (nvlist_lookup_byte_array(nvl, RI_AP_CPUS, (uchar_t **)&buf, 903 (uint_t *)&size) != 0) { 904 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 905 RI_AP_CPUS)); 906 nvlist_free(nvl); 907 return (-1); 908 } 909 910 if (dev_list_unpack(buf, size, &ap->cpus) != 0) { 911 nvlist_free(nvl); 912 return (-1); 913 } 914 915 if (nvlist_lookup_byte_array(nvl, RI_AP_MEMS, (uchar_t **)&buf, 916 (uint_t *)&size) != 0) { 917 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 918 RI_AP_MEMS)); 919 nvlist_free(nvl); 920 return (-1); 921 } 922 923 if (dev_list_unpack(buf, size, &ap->mems) != 0) { 924 nvlist_free(nvl); 925 return (-1); 926 } 927 928 if (nvlist_lookup_byte_array(nvl, RI_AP_IOS, (uchar_t **)&buf, 929 (uint_t *)&size) != 0) { 930 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 931 RI_AP_IOS)); 932 nvlist_free(nvl); 933 return (-1); 934 } 935 936 if (dev_list_unpack(buf, size, &ap->ios) != 0) { 937 nvlist_free(nvl); 938 return (-1); 939 } 940 941 nvlist_free(nvl); 942 943 return (0); 944 } 945 946 /* 947 * Lookup byte array in old nvlist_t and unpack into new nvlist_t. 948 */ 949 static int 950 lookup_unpack_byte_array(nvlist_t *old_nvl, char *name, nvlist_t **new_nvl) 951 { 952 char *buf = NULL; 953 size_t size = 0; 954 955 if (nvlist_lookup_byte_array(old_nvl, name, (uchar_t **)&buf, 956 (uint_t *)&size) != 0) { 957 dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n", 958 name)); 959 return (-1); 960 } 961 962 if (nvlist_unpack(buf, size, new_nvl, 0) != 0) { 963 dprintf((stderr, "nvlist_unpack fail (%s)\n", name)); 964 return (-1); 965 } 966 967 return (0); 968 } 969 970 ri_ap_t * 971 ri_ap_next(ri_hdl_t *hdl, ri_ap_t *ap) 972 { 973 if (hdl == NULL) { 974 errno = EINVAL; 975 return (NULL); 976 } 977 return ((ap == NULL) ? hdl->aps : ap->next); 978 } 979 980 nvlist_t * 981 ri_ap_conf_props(ri_ap_t *ap) 982 { 983 if (ap == NULL) { 984 errno = EINVAL; 985 return (NULL); 986 } 987 return (ap->conf_props); 988 } 989 990 ri_dev_t * 991 ri_cpu_next(ri_ap_t *ap, ri_dev_t *cpu) 992 { 993 if (ap == NULL) { 994 errno = EINVAL; 995 return (NULL); 996 } 997 return ((cpu == NULL) ? ap->cpus : cpu->next); 998 } 999 1000 ri_dev_t * 1001 ri_mem_next(ri_ap_t *ap, ri_dev_t *mem) 1002 { 1003 if (ap == NULL) { 1004 errno = EINVAL; 1005 return (NULL); 1006 } 1007 return ((mem == NULL) ? ap->mems : mem->next); 1008 } 1009 1010 ri_dev_t * 1011 ri_io_next(ri_ap_t *ap, ri_dev_t *io) 1012 { 1013 if (ap == NULL) { 1014 errno = EINVAL; 1015 return (NULL); 1016 } 1017 return ((io == NULL) ? ap->ios : io->next); 1018 } 1019 1020 ri_client_t * 1021 ri_client_next(ri_dev_t *dev, ri_client_t *rcm_client) 1022 { 1023 if (dev == NULL) { 1024 errno = EINVAL; 1025 return (NULL); 1026 } 1027 return ((rcm_client == NULL) ? dev->rcm_clients : rcm_client->next); 1028 } 1029 1030 nvlist_t * 1031 ri_dev_conf_props(ri_dev_t *dev) 1032 { 1033 if (dev == NULL) { 1034 errno = EINVAL; 1035 return (NULL); 1036 } 1037 return (dev->conf_props); 1038 } 1039 1040 nvlist_t * 1041 ri_client_usage_props(ri_client_t *rcm_client) 1042 { 1043 if (rcm_client == NULL) { 1044 errno = EINVAL; 1045 return (NULL); 1046 } 1047 return (rcm_client->usg_props); 1048 } 1049 1050 nvlist_t * 1051 ri_client_verbose_props(ri_client_t *rcm_client) 1052 { 1053 if (rcm_client == NULL) { 1054 errno = EINVAL; 1055 return (NULL); 1056 } 1057 return (rcm_client->v_props); 1058 } 1059 1060 ri_client_t * 1061 ri_cpu_cap_client_next(ri_hdl_t *hdl, ri_client_t *rcm_client) 1062 { 1063 if (hdl == NULL) { 1064 errno = EINVAL; 1065 return (NULL); 1066 } 1067 return ((rcm_client == NULL) ? hdl->cpu_cap_clients : rcm_client->next); 1068 } 1069 1070 ri_client_t * 1071 ri_mem_cap_client_next(ri_hdl_t *hdl, ri_client_t *rcm_client) 1072 { 1073 if (hdl == NULL) { 1074 errno = EINVAL; 1075 return (NULL); 1076 } 1077 return ((rcm_client == NULL) ? hdl->mem_cap_clients : rcm_client->next); 1078 } 1079