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