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