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
ri_fini(ri_hdl_t * hdl)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
ri_ap_free(ri_ap_t * ap)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
ri_dev_free(ri_dev_t * dev)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
ri_client_free(ri_client_t * client)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
ri_pack(ri_hdl_t * hdl,caddr_t * bufp,size_t * sizep,int encoding)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
ap_list_pack(ri_ap_t * aplist,char ** bufp,size_t * sizep,int encoding)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
dev_list_pack(ri_dev_t * devlist,char ** bufp,size_t * sizep,int encoding)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
client_list_pack(ri_client_t * client_list,char ** bufp,size_t * sizep,int encoding)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
ap_pack(ri_ap_t * ap,char ** bufp,size_t * sizep,int encoding)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
dev_pack(ri_dev_t * dev,char ** bufp,size_t * sizep,int encoding)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
client_pack(ri_client_t * client,char ** bufp,size_t * sizep,int encoding)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
pack_add_byte_array(nvlist_t * nvl_packme,char * name,nvlist_t * nvl,int encoding)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
ri_unpack(caddr_t buf,size_t size,ri_hdl_t ** hdlp)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
ap_list_unpack(char * buf,size_t size,ri_ap_t ** aps)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
dev_list_unpack(char * buf,size_t size,ri_dev_t ** devs)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
client_list_unpack(char * buf,size_t size,ri_client_t ** clients)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
client_unpack(char * buf,size_t size,ri_client_t * client)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
dev_unpack(char * buf,size_t size,ri_dev_t * dev)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
ap_unpack(char * buf,size_t size,ri_ap_t * ap)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
lookup_unpack_byte_array(nvlist_t * old_nvl,char * name,nvlist_t ** new_nvl)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 *
ri_ap_next(ri_hdl_t * hdl,ri_ap_t * ap)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 *
ri_ap_conf_props(ri_ap_t * ap)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 *
ri_cpu_next(ri_ap_t * ap,ri_dev_t * cpu)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 *
ri_mem_next(ri_ap_t * ap,ri_dev_t * mem)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 *
ri_io_next(ri_ap_t * ap,ri_dev_t * io)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 *
ri_client_next(ri_dev_t * dev,ri_client_t * rcm_client)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 *
ri_dev_conf_props(ri_dev_t * dev)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 *
ri_client_usage_props(ri_client_t * rcm_client)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 *
ri_client_verbose_props(ri_client_t * rcm_client)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 *
ri_cpu_cap_client_next(ri_hdl_t * hdl,ri_client_t * rcm_client)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 *
ri_mem_cap_client_next(ri_hdl_t * hdl,ri_client_t * rcm_client)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