2 * Copyright (c) 2009-2013 The FreeBSD Foundation
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/endian.h>
35 #include <sys/queue.h>
39 #include <sys/errno.h>
41 #include <sys/malloc.h>
42 #include <sys/systm.h>
44 #include <machine/stdarg.h>
56 #include "common_impl.h"
64 #include <sys/nv_impl.h>
65 #include <sys/nvlist_impl.h>
66 #include <sys/nvpair_impl.h>
70 #define PJDLOG_ASSERT(...) MPASS(__VA_ARGS__)
71 #define PJDLOG_RASSERT(expr, ...) KASSERT(expr, (__VA_ARGS__))
72 #define PJDLOG_ABORT(...) panic(__VA_ARGS__)
75 #define PJDLOG_ASSERT(...) assert(__VA_ARGS__)
76 #define PJDLOG_RASSERT(expr, ...) assert(expr)
77 #define PJDLOG_ABORT(...) abort()
81 #define NVPAIR_MAGIC 0x6e7670 /* "nvp" */
89 TAILQ_ENTRY(nvpair) nvp_next;
92 #define NVPAIR_ASSERT(nvp) do { \
93 PJDLOG_ASSERT((nvp) != NULL); \
94 PJDLOG_ASSERT((nvp)->nvp_magic == NVPAIR_MAGIC); \
97 struct nvpair_header {
99 uint16_t nvph_namesize;
100 uint64_t nvph_datasize;
105 nvpair_assert(const nvpair_t *nvp)
112 nvpair_nvlist(const nvpair_t *nvp)
117 return (nvp->nvp_list);
121 nvpair_next(const nvpair_t *nvp)
125 PJDLOG_ASSERT(nvp->nvp_list != NULL);
127 return (TAILQ_NEXT(nvp, nvp_next));
131 nvpair_prev(const nvpair_t *nvp)
135 PJDLOG_ASSERT(nvp->nvp_list != NULL);
137 return (TAILQ_PREV(nvp, nvl_head, nvp_next));
141 nvpair_insert(struct nvl_head *head, nvpair_t *nvp, nvlist_t *nvl)
145 PJDLOG_ASSERT(nvp->nvp_list == NULL);
146 PJDLOG_ASSERT(!nvlist_exists(nvl, nvpair_name(nvp)));
148 TAILQ_INSERT_TAIL(head, nvp, nvp_next);
153 nvpair_remove_nvlist(nvpair_t *nvp)
157 /* XXX: DECONST is bad, mkay? */
158 nvl = __DECONST(nvlist_t *, nvpair_get_nvlist(nvp));
159 PJDLOG_ASSERT(nvl != NULL);
160 nvlist_set_parent(nvl, NULL);
164 nvpair_remove(struct nvl_head *head, nvpair_t *nvp, const nvlist_t *nvl)
168 PJDLOG_ASSERT(nvp->nvp_list == nvl);
170 if (nvpair_type(nvp) == NV_TYPE_NVLIST)
171 nvpair_remove_nvlist(nvp);
173 TAILQ_REMOVE(head, nvp, nvp_next);
174 nvp->nvp_list = NULL;
178 nvpair_clone(const nvpair_t *nvp)
187 name = nvpair_name(nvp);
189 switch (nvpair_type(nvp)) {
191 newnvp = nvpair_create_null(name);
194 newnvp = nvpair_create_bool(name, nvpair_get_bool(nvp));
197 newnvp = nvpair_create_number(name, nvpair_get_number(nvp));
200 newnvp = nvpair_create_string(name, nvpair_get_string(nvp));
203 newnvp = nvpair_create_nvlist(name, nvpair_get_nvlist(nvp));
206 case NV_TYPE_DESCRIPTOR:
207 newnvp = nvpair_create_descriptor(name,
208 nvpair_get_descriptor(nvp));
212 data = nvpair_get_binary(nvp, &datasize);
213 newnvp = nvpair_create_binary(name, data, datasize);
216 PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp));
223 nvpair_header_size(void)
226 return (sizeof(struct nvpair_header));
230 nvpair_size(const nvpair_t *nvp)
235 return (nvp->nvp_datasize);
239 nvpair_pack_header(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp)
241 struct nvpair_header nvphdr;
246 nvphdr.nvph_type = nvp->nvp_type;
247 namesize = strlen(nvp->nvp_name) + 1;
248 PJDLOG_ASSERT(namesize > 0 && namesize <= UINT16_MAX);
249 nvphdr.nvph_namesize = namesize;
250 nvphdr.nvph_datasize = nvp->nvp_datasize;
251 PJDLOG_ASSERT(*leftp >= sizeof(nvphdr));
252 memcpy(ptr, &nvphdr, sizeof(nvphdr));
253 ptr += sizeof(nvphdr);
254 *leftp -= sizeof(nvphdr);
256 PJDLOG_ASSERT(*leftp >= namesize);
257 memcpy(ptr, nvp->nvp_name, namesize);
265 nvpair_pack_null(const nvpair_t *nvp, unsigned char *ptr,
266 size_t *leftp __unused)
270 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL);
276 nvpair_pack_bool(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp)
281 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL);
283 value = (uint8_t)nvp->nvp_data;
285 PJDLOG_ASSERT(*leftp >= sizeof(value));
286 memcpy(ptr, &value, sizeof(value));
287 ptr += sizeof(value);
288 *leftp -= sizeof(value);
294 nvpair_pack_number(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp)
299 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER);
301 value = (uint64_t)nvp->nvp_data;
303 PJDLOG_ASSERT(*leftp >= sizeof(value));
304 memcpy(ptr, &value, sizeof(value));
305 ptr += sizeof(value);
306 *leftp -= sizeof(value);
312 nvpair_pack_string(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp)
316 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING);
318 PJDLOG_ASSERT(*leftp >= nvp->nvp_datasize);
319 memcpy(ptr, (const void *)(intptr_t)nvp->nvp_data, nvp->nvp_datasize);
320 ptr += nvp->nvp_datasize;
321 *leftp -= nvp->nvp_datasize;
327 nvpair_pack_nvlist_up(unsigned char *ptr, size_t *leftp)
329 struct nvpair_header nvphdr;
331 const char *name = "";
334 nvphdr.nvph_type = NV_TYPE_NVLIST_UP;
335 nvphdr.nvph_namesize = namesize;
336 nvphdr.nvph_datasize = 0;
337 PJDLOG_ASSERT(*leftp >= sizeof(nvphdr));
338 memcpy(ptr, &nvphdr, sizeof(nvphdr));
339 ptr += sizeof(nvphdr);
340 *leftp -= sizeof(nvphdr);
342 PJDLOG_ASSERT(*leftp >= namesize);
343 memcpy(ptr, name, namesize);
352 nvpair_pack_descriptor(const nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp,
358 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR);
360 value = (int64_t)nvp->nvp_data;
363 * If there is a real descriptor here, we change its number
364 * to position in the array of descriptors send via control
367 PJDLOG_ASSERT(fdidxp != NULL);
373 PJDLOG_ASSERT(*leftp >= sizeof(value));
374 memcpy(ptr, &value, sizeof(value));
375 ptr += sizeof(value);
376 *leftp -= sizeof(value);
383 nvpair_pack_binary(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp)
387 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY);
389 PJDLOG_ASSERT(*leftp >= nvp->nvp_datasize);
390 memcpy(ptr, (const void *)(intptr_t)nvp->nvp_data, nvp->nvp_datasize);
391 ptr += nvp->nvp_datasize;
392 *leftp -= nvp->nvp_datasize;
398 nvpair_init_datasize(nvpair_t *nvp)
403 if (nvp->nvp_type == NV_TYPE_NVLIST) {
404 if (nvp->nvp_data == 0) {
405 nvp->nvp_datasize = 0;
408 nvlist_size((const nvlist_t *)(intptr_t)nvp->nvp_data);
413 const unsigned char *
414 nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
417 struct nvpair_header nvphdr;
419 if (*leftp < sizeof(nvphdr))
422 memcpy(&nvphdr, ptr, sizeof(nvphdr));
423 ptr += sizeof(nvphdr);
424 *leftp -= sizeof(nvphdr);
426 #if NV_TYPE_FIRST > 0
427 if (nvphdr.nvph_type < NV_TYPE_FIRST)
430 if (nvphdr.nvph_type > NV_TYPE_LAST &&
431 nvphdr.nvph_type != NV_TYPE_NVLIST_UP) {
435 #if BYTE_ORDER == BIG_ENDIAN
437 nvphdr.nvph_namesize = le16toh(nvphdr.nvph_namesize);
438 nvphdr.nvph_datasize = le64toh(nvphdr.nvph_datasize);
442 nvphdr.nvph_namesize = be16toh(nvphdr.nvph_namesize);
443 nvphdr.nvph_datasize = be64toh(nvphdr.nvph_datasize);
447 if (nvphdr.nvph_namesize > NV_NAME_MAX)
449 if (*leftp < nvphdr.nvph_namesize)
451 if (nvphdr.nvph_namesize < 1)
453 if (strnlen((const char *)ptr, nvphdr.nvph_namesize) !=
454 (size_t)(nvphdr.nvph_namesize - 1)) {
458 memcpy(nvp->nvp_name, ptr, nvphdr.nvph_namesize);
459 ptr += nvphdr.nvph_namesize;
460 *leftp -= nvphdr.nvph_namesize;
462 if (*leftp < nvphdr.nvph_datasize)
465 nvp->nvp_type = nvphdr.nvph_type;
467 nvp->nvp_datasize = nvphdr.nvph_datasize;
471 RESTORE_ERRNO(EINVAL);
475 const unsigned char *
476 nvpair_unpack_null(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr,
477 size_t *leftp __unused)
480 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL);
482 if (nvp->nvp_datasize != 0) {
483 RESTORE_ERRNO(EINVAL);
490 const unsigned char *
491 nvpair_unpack_bool(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr,
496 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL);
498 if (nvp->nvp_datasize != sizeof(value)) {
499 RESTORE_ERRNO(EINVAL);
502 if (*leftp < sizeof(value)) {
503 RESTORE_ERRNO(EINVAL);
507 memcpy(&value, ptr, sizeof(value));
508 ptr += sizeof(value);
509 *leftp -= sizeof(value);
511 if (value != 0 && value != 1) {
512 RESTORE_ERRNO(EINVAL);
516 nvp->nvp_data = (uint64_t)value;
521 const unsigned char *
522 nvpair_unpack_number(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
526 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER);
528 if (nvp->nvp_datasize != sizeof(uint64_t)) {
529 RESTORE_ERRNO(EINVAL);
532 if (*leftp < sizeof(uint64_t)) {
533 RESTORE_ERRNO(EINVAL);
538 nvp->nvp_data = be64dec(ptr);
540 nvp->nvp_data = le64dec(ptr);
541 ptr += sizeof(uint64_t);
542 *leftp -= sizeof(uint64_t);
547 const unsigned char *
548 nvpair_unpack_string(bool isbe __unused, nvpair_t *nvp,
549 const unsigned char *ptr, size_t *leftp)
552 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING);
554 if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) {
555 RESTORE_ERRNO(EINVAL);
559 if (strnlen((const char *)ptr, nvp->nvp_datasize) !=
560 nvp->nvp_datasize - 1) {
561 RESTORE_ERRNO(EINVAL);
565 nvp->nvp_data = (uint64_t)(uintptr_t)nv_strdup((const char *)ptr);
566 if (nvp->nvp_data == 0)
569 ptr += nvp->nvp_datasize;
570 *leftp -= nvp->nvp_datasize;
575 const unsigned char *
576 nvpair_unpack_nvlist(bool isbe __unused, nvpair_t *nvp,
577 const unsigned char *ptr, size_t *leftp, size_t nfds, nvlist_t **child)
581 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST);
583 if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) {
584 RESTORE_ERRNO(EINVAL);
588 value = nvlist_create(0);
592 ptr = nvlist_unpack_header(value, ptr, nfds, NULL, leftp);
596 nvp->nvp_data = (uint64_t)(uintptr_t)value;
603 const unsigned char *
604 nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
605 size_t *leftp, const int *fds, size_t nfds)
609 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR);
611 if (nvp->nvp_datasize != sizeof(idx)) {
615 if (*leftp < sizeof(idx)) {
630 if ((size_t)idx >= nfds) {
635 nvp->nvp_data = (uint64_t)fds[idx];
638 *leftp -= sizeof(idx);
644 const unsigned char *
645 nvpair_unpack_binary(bool isbe __unused, nvpair_t *nvp,
646 const unsigned char *ptr, size_t *leftp)
650 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY);
652 if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) {
653 RESTORE_ERRNO(EINVAL);
657 value = nv_malloc(nvp->nvp_datasize);
661 memcpy(value, ptr, nvp->nvp_datasize);
662 ptr += nvp->nvp_datasize;
663 *leftp -= nvp->nvp_datasize;
665 nvp->nvp_data = (uint64_t)(uintptr_t)value;
670 const unsigned char *
671 nvpair_unpack(bool isbe, const unsigned char *ptr, size_t *leftp,
676 nvp = nv_calloc(1, sizeof(*nvp) + NV_NAME_MAX);
679 nvp->nvp_name = (char *)(nvp + 1);
681 ptr = nvpair_unpack_header(isbe, nvp, ptr, leftp);
684 tmp = nv_realloc(nvp, sizeof(*nvp) + strlen(nvp->nvp_name) + 1);
689 /* Update nvp_name after realloc(). */
690 nvp->nvp_name = (char *)(nvp + 1);
691 nvp->nvp_data = 0x00;
692 nvp->nvp_magic = NVPAIR_MAGIC;
701 nvpair_type(const nvpair_t *nvp)
706 return (nvp->nvp_type);
710 nvpair_name(const nvpair_t *nvp)
715 return (nvp->nvp_name);
719 nvpair_allocv(int type, uint64_t data, size_t datasize, const char *namefmt,
726 PJDLOG_ASSERT(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST);
728 namelen = nv_vasprintf(&name, namefmt, nameap);
732 PJDLOG_ASSERT(namelen > 0);
733 if (namelen >= NV_NAME_MAX) {
735 RESTORE_ERRNO(ENAMETOOLONG);
739 nvp = nv_calloc(1, sizeof(*nvp) + namelen + 1);
741 nvp->nvp_name = (char *)(nvp + 1);
742 memcpy(nvp->nvp_name, name, namelen + 1);
743 nvp->nvp_type = type;
744 nvp->nvp_data = data;
745 nvp->nvp_datasize = datasize;
746 nvp->nvp_magic = NVPAIR_MAGIC;
754 nvpair_create_null(const char *name)
757 return (nvpair_createf_null("%s", name));
761 nvpair_create_bool(const char *name, bool value)
764 return (nvpair_createf_bool(value, "%s", name));
768 nvpair_create_number(const char *name, uint64_t value)
771 return (nvpair_createf_number(value, "%s", name));
775 nvpair_create_string(const char *name, const char *value)
778 return (nvpair_createf_string(value, "%s", name));
782 nvpair_create_stringf(const char *name, const char *valuefmt, ...)
787 va_start(valueap, valuefmt);
788 nvp = nvpair_create_stringv(name, valuefmt, valueap);
795 nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap)
801 len = nv_vasprintf(&str, valuefmt, valueap);
804 nvp = nvpair_create_string(name, str);
811 nvpair_create_nvlist(const char *name, const nvlist_t *value)
814 return (nvpair_createf_nvlist(value, "%s", name));
819 nvpair_create_descriptor(const char *name, int value)
822 return (nvpair_createf_descriptor(value, "%s", name));
827 nvpair_create_binary(const char *name, const void *value, size_t size)
830 return (nvpair_createf_binary(value, size, "%s", name));
834 nvpair_createf_null(const char *namefmt, ...)
839 va_start(nameap, namefmt);
840 nvp = nvpair_createv_null(namefmt, nameap);
847 nvpair_createf_bool(bool value, const char *namefmt, ...)
852 va_start(nameap, namefmt);
853 nvp = nvpair_createv_bool(value, namefmt, nameap);
860 nvpair_createf_number(uint64_t value, const char *namefmt, ...)
865 va_start(nameap, namefmt);
866 nvp = nvpair_createv_number(value, namefmt, nameap);
873 nvpair_createf_string(const char *value, const char *namefmt, ...)
878 va_start(nameap, namefmt);
879 nvp = nvpair_createv_string(value, namefmt, nameap);
886 nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...)
891 va_start(nameap, namefmt);
892 nvp = nvpair_createv_nvlist(value, namefmt, nameap);
900 nvpair_createf_descriptor(int value, const char *namefmt, ...)
905 va_start(nameap, namefmt);
906 nvp = nvpair_createv_descriptor(value, namefmt, nameap);
914 nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...)
919 va_start(nameap, namefmt);
920 nvp = nvpair_createv_binary(value, size, namefmt, nameap);
927 nvpair_createv_null(const char *namefmt, va_list nameap)
930 return (nvpair_allocv(NV_TYPE_NULL, 0, 0, namefmt, nameap));
934 nvpair_createv_bool(bool value, const char *namefmt, va_list nameap)
937 return (nvpair_allocv(NV_TYPE_BOOL, value ? 1 : 0, sizeof(uint8_t),
942 nvpair_createv_number(uint64_t value, const char *namefmt, va_list nameap)
945 return (nvpair_allocv(NV_TYPE_NUMBER, value, sizeof(value), namefmt,
950 nvpair_createv_string(const char *value, const char *namefmt, va_list nameap)
957 RESTORE_ERRNO(EINVAL);
961 data = nv_strdup(value);
964 size = strlen(value) + 1;
966 nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)data, size,
975 nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt,
982 RESTORE_ERRNO(EINVAL);
986 nvl = nvlist_clone(value);
990 nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvl, 0,
995 nvlist_set_parent(nvl, nvp);
1002 nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap)
1006 if (value < 0 || !fd_is_valid(value)) {
1011 value = fcntl(value, F_DUPFD_CLOEXEC, 0);
1015 nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value,
1016 sizeof(int64_t), namefmt, nameap);
1025 nvpair_createv_binary(const void *value, size_t size, const char *namefmt,
1031 if (value == NULL || size == 0) {
1032 RESTORE_ERRNO(EINVAL);
1036 data = nv_malloc(size);
1039 memcpy(data, value, size);
1041 nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)data, size,
1050 nvpair_move_string(const char *name, char *value)
1053 return (nvpair_movef_string(value, "%s", name));
1057 nvpair_move_nvlist(const char *name, nvlist_t *value)
1060 return (nvpair_movef_nvlist(value, "%s", name));
1065 nvpair_move_descriptor(const char *name, int value)
1068 return (nvpair_movef_descriptor(value, "%s", name));
1073 nvpair_move_binary(const char *name, void *value, size_t size)
1076 return (nvpair_movef_binary(value, size, "%s", name));
1080 nvpair_movef_string(char *value, const char *namefmt, ...)
1085 va_start(nameap, namefmt);
1086 nvp = nvpair_movev_string(value, namefmt, nameap);
1093 nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...)
1098 va_start(nameap, namefmt);
1099 nvp = nvpair_movev_nvlist(value, namefmt, nameap);
1107 nvpair_movef_descriptor(int value, const char *namefmt, ...)
1112 va_start(nameap, namefmt);
1113 nvp = nvpair_movev_descriptor(value, namefmt, nameap);
1121 nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...)
1126 va_start(nameap, namefmt);
1127 nvp = nvpair_movev_binary(value, size, namefmt, nameap);
1134 nvpair_movev_string(char *value, const char *namefmt, va_list nameap)
1139 if (value == NULL) {
1140 RESTORE_ERRNO(EINVAL);
1144 nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)value,
1145 strlen(value) + 1, namefmt, nameap);
1149 RESTORE_ERRNO(serrno);
1156 nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap)
1160 if (value == NULL || nvlist_get_nvpair_parent(value) != NULL) {
1161 RESTORE_ERRNO(EINVAL);
1165 if (nvlist_error(value) != 0) {
1166 RESTORE_ERRNO(nvlist_error(value));
1167 nvlist_destroy(value);
1171 nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value, 0,
1174 nvlist_destroy(value);
1176 nvlist_set_parent(value, nvp);
1183 nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap)
1188 if (value < 0 || !fd_is_valid(value)) {
1193 nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value,
1194 sizeof(int64_t), namefmt, nameap);
1206 nvpair_movev_binary(void *value, size_t size, const char *namefmt,
1212 if (value == NULL || size == 0) {
1213 RESTORE_ERRNO(EINVAL);
1217 nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size,
1222 RESTORE_ERRNO(serrno);
1229 nvpair_get_bool(const nvpair_t *nvp)
1234 return (nvp->nvp_data == 1);
1238 nvpair_get_number(const nvpair_t *nvp)
1243 return (nvp->nvp_data);
1247 nvpair_get_string(const nvpair_t *nvp)
1251 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING);
1253 return ((const char *)(intptr_t)nvp->nvp_data);
1257 nvpair_get_nvlist(const nvpair_t *nvp)
1261 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST);
1263 return ((const nvlist_t *)(intptr_t)nvp->nvp_data);
1268 nvpair_get_descriptor(const nvpair_t *nvp)
1272 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR);
1274 return ((int)nvp->nvp_data);
1279 nvpair_get_binary(const nvpair_t *nvp, size_t *sizep)
1283 PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY);
1286 *sizep = nvp->nvp_datasize;
1287 return ((const void *)(intptr_t)nvp->nvp_data);
1291 nvpair_free(nvpair_t *nvp)
1295 PJDLOG_ASSERT(nvp->nvp_list == NULL);
1298 switch (nvp->nvp_type) {
1300 case NV_TYPE_DESCRIPTOR:
1301 close((int)nvp->nvp_data);
1304 case NV_TYPE_NVLIST:
1305 nvlist_destroy((nvlist_t *)(intptr_t)nvp->nvp_data);
1307 case NV_TYPE_STRING:
1308 nv_free((char *)(intptr_t)nvp->nvp_data);
1310 case NV_TYPE_BINARY:
1311 nv_free((void *)(intptr_t)nvp->nvp_data);
1318 nvpair_free_structure(nvpair_t *nvp)
1322 PJDLOG_ASSERT(nvp->nvp_list == NULL);
1329 nvpair_type_string(int type)
1337 case NV_TYPE_NUMBER:
1339 case NV_TYPE_STRING:
1341 case NV_TYPE_NVLIST:
1343 case NV_TYPE_DESCRIPTOR:
1344 return ("DESCRIPTOR");
1345 case NV_TYPE_BINARY:
1348 return ("<UNKNOWN>");