xref: /freebsd/sys/contrib/openzfs/module/nvpair/nvpair.c (revision 3332f1b444d4a73238e9f59cca27bfc95fe936bd)
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 /*
23  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright (c) 2015, 2017 by Delphix. All rights reserved.
25  * Copyright 2018 RackTop Systems.
26  */
27 
28 /*
29  * Links to Illumos.org for more information on Interface Libraries:
30  * [1] https://illumos.org/man/3lib/libnvpair
31  * [2] https://illumos.org/man/3nvpair/nvlist_alloc
32  * [3] https://illumos.org/man/9f/nvlist_alloc
33  * [4] https://illumos.org/man/9f/nvlist_next_nvpair
34  * [5] https://illumos.org/man/9f/nvpair_value_byte
35  */
36 
37 #include <sys/debug.h>
38 #include <sys/isa_defs.h>
39 #include <sys/nvpair.h>
40 #include <sys/nvpair_impl.h>
41 #include <sys/types.h>
42 #include <sys/param.h>
43 #include <sys/strings.h>
44 #include <rpc/xdr.h>
45 #include <sys/mod.h>
46 
47 #if defined(_KERNEL)
48 #include <sys/sunddi.h>
49 #include <sys/sysmacros.h>
50 #else
51 #include <stdarg.h>
52 #include <stdlib.h>
53 #include <stddef.h>
54 #endif
55 
56 #define	skip_whitespace(p)	while ((*(p) == ' ') || (*(p) == '\t')) p++
57 
58 /*
59  * nvpair.c - Provides kernel & userland interfaces for manipulating
60  *	name-value pairs.
61  *
62  * Overview Diagram
63  *
64  *  +--------------+
65  *  |  nvlist_t    |
66  *  |--------------|
67  *  | nvl_version  |
68  *  | nvl_nvflag   |
69  *  | nvl_priv    -+-+
70  *  | nvl_flag     | |
71  *  | nvl_pad      | |
72  *  +--------------+ |
73  *                   V
74  *      +--------------+      last i_nvp in list
75  *      | nvpriv_t     |  +--------------------->
76  *      |--------------|  |
77  *   +--+- nvp_list    |  |   +------------+
78  *   |  |  nvp_last   -+--+   + nv_alloc_t |
79  *   |  |  nvp_curr    |      |------------|
80  *   |  |  nvp_nva    -+----> | nva_ops    |
81  *   |  |  nvp_stat    |      | nva_arg    |
82  *   |  +--------------+      +------------+
83  *   |
84  *   +-------+
85  *           V
86  *   +---------------------+      +-------------------+
87  *   |  i_nvp_t            |  +-->|  i_nvp_t          |  +-->
88  *   |---------------------|  |   |-------------------|  |
89  *   | nvi_next           -+--+   | nvi_next         -+--+
90  *   | nvi_prev (NULL)     | <----+ nvi_prev          |
91  *   | . . . . . . . . . . |      | . . . . . . . . . |
92  *   | nvp (nvpair_t)      |      | nvp (nvpair_t)    |
93  *   |  - nvp_size         |      |  - nvp_size       |
94  *   |  - nvp_name_sz      |      |  - nvp_name_sz    |
95  *   |  - nvp_value_elem   |      |  - nvp_value_elem |
96  *   |  - nvp_type         |      |  - nvp_type       |
97  *   |  - data ...         |      |  - data ...       |
98  *   +---------------------+      +-------------------+
99  *
100  *
101  *
102  *   +---------------------+              +---------------------+
103  *   |  i_nvp_t            |  +-->    +-->|  i_nvp_t (last)     |
104  *   |---------------------|  |       |   |---------------------|
105  *   |  nvi_next          -+--+ ... --+   | nvi_next (NULL)     |
106  * <-+- nvi_prev           |<-- ...  <----+ nvi_prev            |
107  *   | . . . . . . . . .   |              | . . . . . . . . .   |
108  *   | nvp (nvpair_t)      |              | nvp (nvpair_t)      |
109  *   |  - nvp_size         |              |  - nvp_size         |
110  *   |  - nvp_name_sz      |              |  - nvp_name_sz      |
111  *   |  - nvp_value_elem   |              |  - nvp_value_elem   |
112  *   |  - DATA_TYPE_NVLIST |              |  - nvp_type         |
113  *   |  - data (embedded)  |              |  - data ...         |
114  *   |    nvlist name      |              +---------------------+
115  *   |  +--------------+   |
116  *   |  |  nvlist_t    |   |
117  *   |  |--------------|   |
118  *   |  | nvl_version  |   |
119  *   |  | nvl_nvflag   |   |
120  *   |  | nvl_priv   --+---+---->
121  *   |  | nvl_flag     |   |
122  *   |  | nvl_pad      |   |
123  *   |  +--------------+   |
124  *   +---------------------+
125  *
126  *
127  * N.B. nvpair_t may be aligned on 4 byte boundary, so +4 will
128  * allow value to be aligned on 8 byte boundary
129  *
130  * name_len is the length of the name string including the null terminator
131  * so it must be >= 1
132  */
133 #define	NVP_SIZE_CALC(name_len, data_len) \
134 	(NV_ALIGN((sizeof (nvpair_t)) + name_len) + NV_ALIGN(data_len))
135 
136 static int i_get_value_size(data_type_t type, const void *data, uint_t nelem);
137 static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type,
138     uint_t nelem, const void *data);
139 
140 #define	NV_STAT_EMBEDDED	0x1
141 #define	EMBEDDED_NVL(nvp)	((nvlist_t *)(void *)NVP_VALUE(nvp))
142 #define	EMBEDDED_NVL_ARRAY(nvp)	((nvlist_t **)(void *)NVP_VALUE(nvp))
143 
144 #define	NVP_VALOFF(nvp)	(NV_ALIGN(sizeof (nvpair_t) + (nvp)->nvp_name_sz))
145 #define	NVPAIR2I_NVP(nvp) \
146 	((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_nvp)))
147 
148 #ifdef _KERNEL
149 int nvpair_max_recursion = 20;
150 #else
151 int nvpair_max_recursion = 100;
152 #endif
153 
154 uint64_t nvlist_hashtable_init_size = (1 << 4);
155 
156 int
157 nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
158 {
159 	va_list valist;
160 	int err = 0;
161 
162 	nva->nva_ops = nvo;
163 	nva->nva_arg = NULL;
164 
165 	va_start(valist, nvo);
166 	if (nva->nva_ops->nv_ao_init != NULL)
167 		err = nva->nva_ops->nv_ao_init(nva, valist);
168 	va_end(valist);
169 
170 	return (err);
171 }
172 
173 void
174 nv_alloc_reset(nv_alloc_t *nva)
175 {
176 	if (nva->nva_ops->nv_ao_reset != NULL)
177 		nva->nva_ops->nv_ao_reset(nva);
178 }
179 
180 void
181 nv_alloc_fini(nv_alloc_t *nva)
182 {
183 	if (nva->nva_ops->nv_ao_fini != NULL)
184 		nva->nva_ops->nv_ao_fini(nva);
185 }
186 
187 nv_alloc_t *
188 nvlist_lookup_nv_alloc(nvlist_t *nvl)
189 {
190 	nvpriv_t *priv;
191 
192 	if (nvl == NULL ||
193 	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
194 		return (NULL);
195 
196 	return (priv->nvp_nva);
197 }
198 
199 static void *
200 nv_mem_zalloc(nvpriv_t *nvp, size_t size)
201 {
202 	nv_alloc_t *nva = nvp->nvp_nva;
203 	void *buf;
204 
205 	if ((buf = nva->nva_ops->nv_ao_alloc(nva, size)) != NULL)
206 		bzero(buf, size);
207 
208 	return (buf);
209 }
210 
211 static void
212 nv_mem_free(nvpriv_t *nvp, void *buf, size_t size)
213 {
214 	nv_alloc_t *nva = nvp->nvp_nva;
215 
216 	nva->nva_ops->nv_ao_free(nva, buf, size);
217 }
218 
219 static void
220 nv_priv_init(nvpriv_t *priv, nv_alloc_t *nva, uint32_t stat)
221 {
222 	bzero(priv, sizeof (nvpriv_t));
223 
224 	priv->nvp_nva = nva;
225 	priv->nvp_stat = stat;
226 }
227 
228 static nvpriv_t *
229 nv_priv_alloc(nv_alloc_t *nva)
230 {
231 	nvpriv_t *priv;
232 
233 	/*
234 	 * nv_mem_alloc() cannot called here because it needs the priv
235 	 * argument.
236 	 */
237 	if ((priv = nva->nva_ops->nv_ao_alloc(nva, sizeof (nvpriv_t))) == NULL)
238 		return (NULL);
239 
240 	nv_priv_init(priv, nva, 0);
241 
242 	return (priv);
243 }
244 
245 /*
246  * Embedded lists need their own nvpriv_t's.  We create a new
247  * nvpriv_t using the parameters and allocator from the parent
248  * list's nvpriv_t.
249  */
250 static nvpriv_t *
251 nv_priv_alloc_embedded(nvpriv_t *priv)
252 {
253 	nvpriv_t *emb_priv;
254 
255 	if ((emb_priv = nv_mem_zalloc(priv, sizeof (nvpriv_t))) == NULL)
256 		return (NULL);
257 
258 	nv_priv_init(emb_priv, priv->nvp_nva, NV_STAT_EMBEDDED);
259 
260 	return (emb_priv);
261 }
262 
263 static int
264 nvt_tab_alloc(nvpriv_t *priv, uint64_t buckets)
265 {
266 	ASSERT3P(priv->nvp_hashtable, ==, NULL);
267 	ASSERT0(priv->nvp_nbuckets);
268 	ASSERT0(priv->nvp_nentries);
269 
270 	i_nvp_t **tab = nv_mem_zalloc(priv, buckets * sizeof (i_nvp_t *));
271 	if (tab == NULL)
272 		return (ENOMEM);
273 
274 	priv->nvp_hashtable = tab;
275 	priv->nvp_nbuckets = buckets;
276 	return (0);
277 }
278 
279 static void
280 nvt_tab_free(nvpriv_t *priv)
281 {
282 	i_nvp_t **tab = priv->nvp_hashtable;
283 	if (tab == NULL) {
284 		ASSERT0(priv->nvp_nbuckets);
285 		ASSERT0(priv->nvp_nentries);
286 		return;
287 	}
288 
289 	nv_mem_free(priv, tab, priv->nvp_nbuckets * sizeof (i_nvp_t *));
290 
291 	priv->nvp_hashtable = NULL;
292 	priv->nvp_nbuckets = 0;
293 	priv->nvp_nentries = 0;
294 }
295 
296 static uint32_t
297 nvt_hash(const char *p)
298 {
299 	uint32_t g, hval = 0;
300 
301 	while (*p) {
302 		hval = (hval << 4) + *p++;
303 		if ((g = (hval & 0xf0000000)) != 0)
304 			hval ^= g >> 24;
305 		hval &= ~g;
306 	}
307 	return (hval);
308 }
309 
310 static boolean_t
311 nvt_nvpair_match(nvpair_t *nvp1, nvpair_t *nvp2, uint32_t nvflag)
312 {
313 	boolean_t match = B_FALSE;
314 	if (nvflag & NV_UNIQUE_NAME_TYPE) {
315 		if (strcmp(NVP_NAME(nvp1), NVP_NAME(nvp2)) == 0 &&
316 		    NVP_TYPE(nvp1) == NVP_TYPE(nvp2))
317 			match = B_TRUE;
318 	} else {
319 		ASSERT(nvflag == 0 || nvflag & NV_UNIQUE_NAME);
320 		if (strcmp(NVP_NAME(nvp1), NVP_NAME(nvp2)) == 0)
321 			match = B_TRUE;
322 	}
323 	return (match);
324 }
325 
326 static nvpair_t *
327 nvt_lookup_name_type(nvlist_t *nvl, const char *name, data_type_t type)
328 {
329 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
330 	ASSERT(priv != NULL);
331 
332 	i_nvp_t **tab = priv->nvp_hashtable;
333 
334 	if (tab == NULL) {
335 		ASSERT3P(priv->nvp_list, ==, NULL);
336 		ASSERT0(priv->nvp_nbuckets);
337 		ASSERT0(priv->nvp_nentries);
338 		return (NULL);
339 	} else {
340 		ASSERT(priv->nvp_nbuckets != 0);
341 	}
342 
343 	uint64_t hash = nvt_hash(name);
344 	uint64_t index = hash & (priv->nvp_nbuckets - 1);
345 
346 	ASSERT3U(index, <, priv->nvp_nbuckets);
347 	i_nvp_t *entry = tab[index];
348 
349 	for (i_nvp_t *e = entry; e != NULL; e = e->nvi_hashtable_next) {
350 		if (strcmp(NVP_NAME(&e->nvi_nvp), name) == 0 &&
351 		    (type == DATA_TYPE_DONTCARE ||
352 		    NVP_TYPE(&e->nvi_nvp) == type))
353 			return (&e->nvi_nvp);
354 	}
355 	return (NULL);
356 }
357 
358 static nvpair_t *
359 nvt_lookup_name(nvlist_t *nvl, const char *name)
360 {
361 	return (nvt_lookup_name_type(nvl, name, DATA_TYPE_DONTCARE));
362 }
363 
364 static int
365 nvt_resize(nvpriv_t *priv, uint32_t new_size)
366 {
367 	i_nvp_t **tab = priv->nvp_hashtable;
368 
369 	/*
370 	 * Migrate all the entries from the current table
371 	 * to a newly-allocated table with the new size by
372 	 * re-adjusting the pointers of their entries.
373 	 */
374 	uint32_t size = priv->nvp_nbuckets;
375 	uint32_t new_mask = new_size - 1;
376 	ASSERT(ISP2(new_size));
377 
378 	i_nvp_t **new_tab = nv_mem_zalloc(priv, new_size * sizeof (i_nvp_t *));
379 	if (new_tab == NULL)
380 		return (ENOMEM);
381 
382 	uint32_t nentries = 0;
383 	for (uint32_t i = 0; i < size; i++) {
384 		i_nvp_t *next, *e = tab[i];
385 
386 		while (e != NULL) {
387 			next = e->nvi_hashtable_next;
388 
389 			uint32_t hash = nvt_hash(NVP_NAME(&e->nvi_nvp));
390 			uint32_t index = hash & new_mask;
391 
392 			e->nvi_hashtable_next = new_tab[index];
393 			new_tab[index] = e;
394 			nentries++;
395 
396 			e = next;
397 		}
398 		tab[i] = NULL;
399 	}
400 	ASSERT3U(nentries, ==, priv->nvp_nentries);
401 
402 	nvt_tab_free(priv);
403 
404 	priv->nvp_hashtable = new_tab;
405 	priv->nvp_nbuckets = new_size;
406 	priv->nvp_nentries = nentries;
407 
408 	return (0);
409 }
410 
411 static boolean_t
412 nvt_needs_togrow(nvpriv_t *priv)
413 {
414 	/*
415 	 * Grow only when we have more elements than buckets
416 	 * and the # of buckets doesn't overflow.
417 	 */
418 	return (priv->nvp_nentries > priv->nvp_nbuckets &&
419 	    (UINT32_MAX >> 1) >= priv->nvp_nbuckets);
420 }
421 
422 /*
423  * Allocate a new table that's twice the size of the old one,
424  * and migrate all the entries from the old one to the new
425  * one by re-adjusting their pointers.
426  */
427 static int
428 nvt_grow(nvpriv_t *priv)
429 {
430 	uint32_t current_size = priv->nvp_nbuckets;
431 	/* ensure we won't overflow */
432 	ASSERT3U(UINT32_MAX >> 1, >=, current_size);
433 	return (nvt_resize(priv, current_size << 1));
434 }
435 
436 static boolean_t
437 nvt_needs_toshrink(nvpriv_t *priv)
438 {
439 	/*
440 	 * Shrink only when the # of elements is less than or
441 	 * equal to 1/4 the # of buckets. Never shrink less than
442 	 * nvlist_hashtable_init_size.
443 	 */
444 	ASSERT3U(priv->nvp_nbuckets, >=, nvlist_hashtable_init_size);
445 	if (priv->nvp_nbuckets == nvlist_hashtable_init_size)
446 		return (B_FALSE);
447 	return (priv->nvp_nentries <= (priv->nvp_nbuckets >> 2));
448 }
449 
450 /*
451  * Allocate a new table that's half the size of the old one,
452  * and migrate all the entries from the old one to the new
453  * one by re-adjusting their pointers.
454  */
455 static int
456 nvt_shrink(nvpriv_t *priv)
457 {
458 	uint32_t current_size = priv->nvp_nbuckets;
459 	/* ensure we won't overflow */
460 	ASSERT3U(current_size, >=, nvlist_hashtable_init_size);
461 	return (nvt_resize(priv, current_size >> 1));
462 }
463 
464 static int
465 nvt_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
466 {
467 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
468 
469 	if (nvt_needs_toshrink(priv)) {
470 		int err = nvt_shrink(priv);
471 		if (err != 0)
472 			return (err);
473 	}
474 	i_nvp_t **tab = priv->nvp_hashtable;
475 
476 	char *name = NVP_NAME(nvp);
477 	uint64_t hash = nvt_hash(name);
478 	uint64_t index = hash & (priv->nvp_nbuckets - 1);
479 
480 	ASSERT3U(index, <, priv->nvp_nbuckets);
481 	i_nvp_t *bucket = tab[index];
482 
483 	for (i_nvp_t *prev = NULL, *e = bucket;
484 	    e != NULL; prev = e, e = e->nvi_hashtable_next) {
485 		if (nvt_nvpair_match(&e->nvi_nvp, nvp, nvl->nvl_nvflag)) {
486 			if (prev != NULL) {
487 				prev->nvi_hashtable_next =
488 				    e->nvi_hashtable_next;
489 			} else {
490 				ASSERT3P(e, ==, bucket);
491 				tab[index] = e->nvi_hashtable_next;
492 			}
493 			e->nvi_hashtable_next = NULL;
494 			priv->nvp_nentries--;
495 			break;
496 		}
497 	}
498 
499 	return (0);
500 }
501 
502 static int
503 nvt_add_nvpair(nvlist_t *nvl, nvpair_t *nvp)
504 {
505 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
506 
507 	/* initialize nvpair table now if it doesn't exist. */
508 	if (priv->nvp_hashtable == NULL) {
509 		int err = nvt_tab_alloc(priv, nvlist_hashtable_init_size);
510 		if (err != 0)
511 			return (err);
512 	}
513 
514 	/*
515 	 * if we don't allow duplicate entries, make sure to
516 	 * unlink any existing entries from the table.
517 	 */
518 	if (nvl->nvl_nvflag != 0) {
519 		int err = nvt_remove_nvpair(nvl, nvp);
520 		if (err != 0)
521 			return (err);
522 	}
523 
524 	if (nvt_needs_togrow(priv)) {
525 		int err = nvt_grow(priv);
526 		if (err != 0)
527 			return (err);
528 	}
529 	i_nvp_t **tab = priv->nvp_hashtable;
530 
531 	char *name = NVP_NAME(nvp);
532 	uint64_t hash = nvt_hash(name);
533 	uint64_t index = hash & (priv->nvp_nbuckets - 1);
534 
535 	ASSERT3U(index, <, priv->nvp_nbuckets);
536 	// cppcheck-suppress nullPointerRedundantCheck
537 	i_nvp_t *bucket = tab[index];
538 
539 	/* insert link at the beginning of the bucket */
540 	i_nvp_t *new_entry = NVPAIR2I_NVP(nvp);
541 	ASSERT3P(new_entry->nvi_hashtable_next, ==, NULL);
542 	new_entry->nvi_hashtable_next = bucket;
543 	// cppcheck-suppress nullPointerRedundantCheck
544 	tab[index] = new_entry;
545 
546 	priv->nvp_nentries++;
547 	return (0);
548 }
549 
550 static void
551 nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv)
552 {
553 	nvl->nvl_version = NV_VERSION;
554 	nvl->nvl_nvflag = nvflag & (NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE);
555 	nvl->nvl_priv = (uint64_t)(uintptr_t)priv;
556 	nvl->nvl_flag = 0;
557 	nvl->nvl_pad = 0;
558 }
559 
560 uint_t
561 nvlist_nvflag(nvlist_t *nvl)
562 {
563 	return (nvl->nvl_nvflag);
564 }
565 
566 static nv_alloc_t *
567 nvlist_nv_alloc(int kmflag)
568 {
569 #if defined(_KERNEL)
570 	switch (kmflag) {
571 	case KM_SLEEP:
572 		return (nv_alloc_sleep);
573 	case KM_NOSLEEP:
574 		return (nv_alloc_nosleep);
575 	default:
576 		return (nv_alloc_pushpage);
577 	}
578 #else
579 	return (nv_alloc_nosleep);
580 #endif /* _KERNEL */
581 }
582 
583 /*
584  * nvlist_alloc - Allocate nvlist.
585  */
586 int
587 nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag)
588 {
589 	return (nvlist_xalloc(nvlp, nvflag, nvlist_nv_alloc(kmflag)));
590 }
591 
592 int
593 nvlist_xalloc(nvlist_t **nvlp, uint_t nvflag, nv_alloc_t *nva)
594 {
595 	nvpriv_t *priv;
596 
597 	if (nvlp == NULL || nva == NULL)
598 		return (EINVAL);
599 
600 	if ((priv = nv_priv_alloc(nva)) == NULL)
601 		return (ENOMEM);
602 
603 	if ((*nvlp = nv_mem_zalloc(priv,
604 	    NV_ALIGN(sizeof (nvlist_t)))) == NULL) {
605 		nv_mem_free(priv, priv, sizeof (nvpriv_t));
606 		return (ENOMEM);
607 	}
608 
609 	nvlist_init(*nvlp, nvflag, priv);
610 
611 	return (0);
612 }
613 
614 /*
615  * nvp_buf_alloc - Allocate i_nvp_t for storing a new nv pair.
616  */
617 static nvpair_t *
618 nvp_buf_alloc(nvlist_t *nvl, size_t len)
619 {
620 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
621 	i_nvp_t *buf;
622 	nvpair_t *nvp;
623 	size_t nvsize;
624 
625 	/*
626 	 * Allocate the buffer
627 	 */
628 	nvsize = len + offsetof(i_nvp_t, nvi_nvp);
629 
630 	if ((buf = nv_mem_zalloc(priv, nvsize)) == NULL)
631 		return (NULL);
632 
633 	nvp = &buf->nvi_nvp;
634 	nvp->nvp_size = len;
635 
636 	return (nvp);
637 }
638 
639 /*
640  * nvp_buf_free - de-Allocate an i_nvp_t.
641  */
642 static void
643 nvp_buf_free(nvlist_t *nvl, nvpair_t *nvp)
644 {
645 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
646 	size_t nvsize = nvp->nvp_size + offsetof(i_nvp_t, nvi_nvp);
647 
648 	nv_mem_free(priv, NVPAIR2I_NVP(nvp), nvsize);
649 }
650 
651 /*
652  * nvp_buf_link - link a new nv pair into the nvlist.
653  */
654 static void
655 nvp_buf_link(nvlist_t *nvl, nvpair_t *nvp)
656 {
657 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
658 	i_nvp_t *curr = NVPAIR2I_NVP(nvp);
659 
660 	/* Put element at end of nvlist */
661 	if (priv->nvp_list == NULL) {
662 		priv->nvp_list = priv->nvp_last = curr;
663 	} else {
664 		curr->nvi_prev = priv->nvp_last;
665 		priv->nvp_last->nvi_next = curr;
666 		priv->nvp_last = curr;
667 	}
668 }
669 
670 /*
671  * nvp_buf_unlink - unlink an removed nvpair out of the nvlist.
672  */
673 static void
674 nvp_buf_unlink(nvlist_t *nvl, nvpair_t *nvp)
675 {
676 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
677 	i_nvp_t *curr = NVPAIR2I_NVP(nvp);
678 
679 	/*
680 	 * protect nvlist_next_nvpair() against walking on freed memory.
681 	 */
682 	if (priv->nvp_curr == curr)
683 		priv->nvp_curr = curr->nvi_next;
684 
685 	if (curr == priv->nvp_list)
686 		priv->nvp_list = curr->nvi_next;
687 	else
688 		curr->nvi_prev->nvi_next = curr->nvi_next;
689 
690 	if (curr == priv->nvp_last)
691 		priv->nvp_last = curr->nvi_prev;
692 	else
693 		curr->nvi_next->nvi_prev = curr->nvi_prev;
694 }
695 
696 /*
697  * take a nvpair type and number of elements and make sure the are valid
698  */
699 static int
700 i_validate_type_nelem(data_type_t type, uint_t nelem)
701 {
702 	switch (type) {
703 	case DATA_TYPE_BOOLEAN:
704 		if (nelem != 0)
705 			return (EINVAL);
706 		break;
707 	case DATA_TYPE_BOOLEAN_VALUE:
708 	case DATA_TYPE_BYTE:
709 	case DATA_TYPE_INT8:
710 	case DATA_TYPE_UINT8:
711 	case DATA_TYPE_INT16:
712 	case DATA_TYPE_UINT16:
713 	case DATA_TYPE_INT32:
714 	case DATA_TYPE_UINT32:
715 	case DATA_TYPE_INT64:
716 	case DATA_TYPE_UINT64:
717 	case DATA_TYPE_STRING:
718 	case DATA_TYPE_HRTIME:
719 	case DATA_TYPE_NVLIST:
720 #if !defined(_KERNEL)
721 	case DATA_TYPE_DOUBLE:
722 #endif
723 		if (nelem != 1)
724 			return (EINVAL);
725 		break;
726 	case DATA_TYPE_BOOLEAN_ARRAY:
727 	case DATA_TYPE_BYTE_ARRAY:
728 	case DATA_TYPE_INT8_ARRAY:
729 	case DATA_TYPE_UINT8_ARRAY:
730 	case DATA_TYPE_INT16_ARRAY:
731 	case DATA_TYPE_UINT16_ARRAY:
732 	case DATA_TYPE_INT32_ARRAY:
733 	case DATA_TYPE_UINT32_ARRAY:
734 	case DATA_TYPE_INT64_ARRAY:
735 	case DATA_TYPE_UINT64_ARRAY:
736 	case DATA_TYPE_STRING_ARRAY:
737 	case DATA_TYPE_NVLIST_ARRAY:
738 		/* we allow arrays with 0 elements */
739 		break;
740 	default:
741 		return (EINVAL);
742 	}
743 	return (0);
744 }
745 
746 /*
747  * Verify nvp_name_sz and check the name string length.
748  */
749 static int
750 i_validate_nvpair_name(nvpair_t *nvp)
751 {
752 	if ((nvp->nvp_name_sz <= 0) ||
753 	    (nvp->nvp_size < NVP_SIZE_CALC(nvp->nvp_name_sz, 0)))
754 		return (EFAULT);
755 
756 	/* verify the name string, make sure its terminated */
757 	if (NVP_NAME(nvp)[nvp->nvp_name_sz - 1] != '\0')
758 		return (EFAULT);
759 
760 	return (strlen(NVP_NAME(nvp)) == nvp->nvp_name_sz - 1 ? 0 : EFAULT);
761 }
762 
763 static int
764 i_validate_nvpair_value(data_type_t type, uint_t nelem, const void *data)
765 {
766 	switch (type) {
767 	case DATA_TYPE_BOOLEAN_VALUE:
768 		if (*(boolean_t *)data != B_TRUE &&
769 		    *(boolean_t *)data != B_FALSE)
770 			return (EINVAL);
771 		break;
772 	case DATA_TYPE_BOOLEAN_ARRAY: {
773 		int i;
774 
775 		for (i = 0; i < nelem; i++)
776 			if (((boolean_t *)data)[i] != B_TRUE &&
777 			    ((boolean_t *)data)[i] != B_FALSE)
778 				return (EINVAL);
779 		break;
780 	}
781 	default:
782 		break;
783 	}
784 
785 	return (0);
786 }
787 
788 /*
789  * This function takes a pointer to what should be a nvpair and it's size
790  * and then verifies that all the nvpair fields make sense and can be
791  * trusted.  This function is used when decoding packed nvpairs.
792  */
793 static int
794 i_validate_nvpair(nvpair_t *nvp)
795 {
796 	data_type_t type = NVP_TYPE(nvp);
797 	int size1, size2;
798 
799 	/* verify nvp_name_sz, check the name string length */
800 	if (i_validate_nvpair_name(nvp) != 0)
801 		return (EFAULT);
802 
803 	if (i_validate_nvpair_value(type, NVP_NELEM(nvp), NVP_VALUE(nvp)) != 0)
804 		return (EFAULT);
805 
806 	/*
807 	 * verify nvp_type, nvp_value_elem, and also possibly
808 	 * verify string values and get the value size.
809 	 */
810 	size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp));
811 	size1 = nvp->nvp_size - NVP_VALOFF(nvp);
812 	if (size2 < 0 || size1 != NV_ALIGN(size2))
813 		return (EFAULT);
814 
815 	return (0);
816 }
817 
818 static int
819 nvlist_copy_pairs(nvlist_t *snvl, nvlist_t *dnvl)
820 {
821 	nvpriv_t *priv;
822 	i_nvp_t *curr;
823 
824 	if ((priv = (nvpriv_t *)(uintptr_t)snvl->nvl_priv) == NULL)
825 		return (EINVAL);
826 
827 	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
828 		nvpair_t *nvp = &curr->nvi_nvp;
829 		int err;
830 
831 		if ((err = nvlist_add_common(dnvl, NVP_NAME(nvp), NVP_TYPE(nvp),
832 		    NVP_NELEM(nvp), NVP_VALUE(nvp))) != 0)
833 			return (err);
834 	}
835 
836 	return (0);
837 }
838 
839 /*
840  * Frees all memory allocated for an nvpair (like embedded lists) with
841  * the exception of the nvpair buffer itself.
842  */
843 static void
844 nvpair_free(nvpair_t *nvp)
845 {
846 	switch (NVP_TYPE(nvp)) {
847 	case DATA_TYPE_NVLIST:
848 		nvlist_free(EMBEDDED_NVL(nvp));
849 		break;
850 	case DATA_TYPE_NVLIST_ARRAY: {
851 		nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
852 		int i;
853 
854 		for (i = 0; i < NVP_NELEM(nvp); i++)
855 			if (nvlp[i] != NULL)
856 				nvlist_free(nvlp[i]);
857 		break;
858 	}
859 	default:
860 		break;
861 	}
862 }
863 
864 /*
865  * nvlist_free - free an unpacked nvlist
866  */
867 void
868 nvlist_free(nvlist_t *nvl)
869 {
870 	nvpriv_t *priv;
871 	i_nvp_t *curr;
872 
873 	if (nvl == NULL ||
874 	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
875 		return;
876 
877 	/*
878 	 * Unpacked nvlist are linked through i_nvp_t
879 	 */
880 	curr = priv->nvp_list;
881 	while (curr != NULL) {
882 		nvpair_t *nvp = &curr->nvi_nvp;
883 		curr = curr->nvi_next;
884 
885 		nvpair_free(nvp);
886 		nvp_buf_free(nvl, nvp);
887 	}
888 
889 	if (!(priv->nvp_stat & NV_STAT_EMBEDDED))
890 		nv_mem_free(priv, nvl, NV_ALIGN(sizeof (nvlist_t)));
891 	else
892 		nvl->nvl_priv = 0;
893 
894 	nvt_tab_free(priv);
895 	nv_mem_free(priv, priv, sizeof (nvpriv_t));
896 }
897 
898 static int
899 nvlist_contains_nvp(nvlist_t *nvl, nvpair_t *nvp)
900 {
901 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
902 	i_nvp_t *curr;
903 
904 	if (nvp == NULL)
905 		return (0);
906 
907 	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
908 		if (&curr->nvi_nvp == nvp)
909 			return (1);
910 
911 	return (0);
912 }
913 
914 /*
915  * Make a copy of nvlist
916  */
917 int
918 nvlist_dup(nvlist_t *nvl, nvlist_t **nvlp, int kmflag)
919 {
920 	return (nvlist_xdup(nvl, nvlp, nvlist_nv_alloc(kmflag)));
921 }
922 
923 int
924 nvlist_xdup(nvlist_t *nvl, nvlist_t **nvlp, nv_alloc_t *nva)
925 {
926 	int err;
927 	nvlist_t *ret;
928 
929 	if (nvl == NULL || nvlp == NULL)
930 		return (EINVAL);
931 
932 	if ((err = nvlist_xalloc(&ret, nvl->nvl_nvflag, nva)) != 0)
933 		return (err);
934 
935 	if ((err = nvlist_copy_pairs(nvl, ret)) != 0)
936 		nvlist_free(ret);
937 	else
938 		*nvlp = ret;
939 
940 	return (err);
941 }
942 
943 /*
944  * Remove all with matching name
945  */
946 int
947 nvlist_remove_all(nvlist_t *nvl, const char *name)
948 {
949 	int error = ENOENT;
950 
951 	if (nvl == NULL || name == NULL || nvl->nvl_priv == 0)
952 		return (EINVAL);
953 
954 	nvpair_t *nvp;
955 	while ((nvp = nvt_lookup_name(nvl, name)) != NULL) {
956 		VERIFY0(nvlist_remove_nvpair(nvl, nvp));
957 		error = 0;
958 	}
959 
960 	return (error);
961 }
962 
963 /*
964  * Remove first one with matching name and type
965  */
966 int
967 nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type)
968 {
969 	if (nvl == NULL || name == NULL || nvl->nvl_priv == 0)
970 		return (EINVAL);
971 
972 	nvpair_t *nvp = nvt_lookup_name_type(nvl, name, type);
973 	if (nvp == NULL)
974 		return (ENOENT);
975 
976 	return (nvlist_remove_nvpair(nvl, nvp));
977 }
978 
979 int
980 nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
981 {
982 	if (nvl == NULL || nvp == NULL)
983 		return (EINVAL);
984 
985 	int err = nvt_remove_nvpair(nvl, nvp);
986 	if (err != 0)
987 		return (err);
988 
989 	nvp_buf_unlink(nvl, nvp);
990 	nvpair_free(nvp);
991 	nvp_buf_free(nvl, nvp);
992 	return (0);
993 }
994 
995 /*
996  * This function calculates the size of an nvpair value.
997  *
998  * The data argument controls the behavior in case of the data types
999  * 	DATA_TYPE_STRING    	and
1000  *	DATA_TYPE_STRING_ARRAY
1001  * Is data == NULL then the size of the string(s) is excluded.
1002  */
1003 static int
1004 i_get_value_size(data_type_t type, const void *data, uint_t nelem)
1005 {
1006 	uint64_t value_sz;
1007 
1008 	if (i_validate_type_nelem(type, nelem) != 0)
1009 		return (-1);
1010 
1011 	/* Calculate required size for holding value */
1012 	switch (type) {
1013 	case DATA_TYPE_BOOLEAN:
1014 		value_sz = 0;
1015 		break;
1016 	case DATA_TYPE_BOOLEAN_VALUE:
1017 		value_sz = sizeof (boolean_t);
1018 		break;
1019 	case DATA_TYPE_BYTE:
1020 		value_sz = sizeof (uchar_t);
1021 		break;
1022 	case DATA_TYPE_INT8:
1023 		value_sz = sizeof (int8_t);
1024 		break;
1025 	case DATA_TYPE_UINT8:
1026 		value_sz = sizeof (uint8_t);
1027 		break;
1028 	case DATA_TYPE_INT16:
1029 		value_sz = sizeof (int16_t);
1030 		break;
1031 	case DATA_TYPE_UINT16:
1032 		value_sz = sizeof (uint16_t);
1033 		break;
1034 	case DATA_TYPE_INT32:
1035 		value_sz = sizeof (int32_t);
1036 		break;
1037 	case DATA_TYPE_UINT32:
1038 		value_sz = sizeof (uint32_t);
1039 		break;
1040 	case DATA_TYPE_INT64:
1041 		value_sz = sizeof (int64_t);
1042 		break;
1043 	case DATA_TYPE_UINT64:
1044 		value_sz = sizeof (uint64_t);
1045 		break;
1046 #if !defined(_KERNEL)
1047 	case DATA_TYPE_DOUBLE:
1048 		value_sz = sizeof (double);
1049 		break;
1050 #endif
1051 	case DATA_TYPE_STRING:
1052 		if (data == NULL)
1053 			value_sz = 0;
1054 		else
1055 			value_sz = strlen(data) + 1;
1056 		break;
1057 	case DATA_TYPE_BOOLEAN_ARRAY:
1058 		value_sz = (uint64_t)nelem * sizeof (boolean_t);
1059 		break;
1060 	case DATA_TYPE_BYTE_ARRAY:
1061 		value_sz = (uint64_t)nelem * sizeof (uchar_t);
1062 		break;
1063 	case DATA_TYPE_INT8_ARRAY:
1064 		value_sz = (uint64_t)nelem * sizeof (int8_t);
1065 		break;
1066 	case DATA_TYPE_UINT8_ARRAY:
1067 		value_sz = (uint64_t)nelem * sizeof (uint8_t);
1068 		break;
1069 	case DATA_TYPE_INT16_ARRAY:
1070 		value_sz = (uint64_t)nelem * sizeof (int16_t);
1071 		break;
1072 	case DATA_TYPE_UINT16_ARRAY:
1073 		value_sz = (uint64_t)nelem * sizeof (uint16_t);
1074 		break;
1075 	case DATA_TYPE_INT32_ARRAY:
1076 		value_sz = (uint64_t)nelem * sizeof (int32_t);
1077 		break;
1078 	case DATA_TYPE_UINT32_ARRAY:
1079 		value_sz = (uint64_t)nelem * sizeof (uint32_t);
1080 		break;
1081 	case DATA_TYPE_INT64_ARRAY:
1082 		value_sz = (uint64_t)nelem * sizeof (int64_t);
1083 		break;
1084 	case DATA_TYPE_UINT64_ARRAY:
1085 		value_sz = (uint64_t)nelem * sizeof (uint64_t);
1086 		break;
1087 	case DATA_TYPE_STRING_ARRAY:
1088 		value_sz = (uint64_t)nelem * sizeof (uint64_t);
1089 
1090 		if (data != NULL) {
1091 			char *const *strs = data;
1092 			uint_t i;
1093 
1094 			/* no alignment requirement for strings */
1095 			for (i = 0; i < nelem; i++) {
1096 				if (strs[i] == NULL)
1097 					return (-1);
1098 				value_sz += strlen(strs[i]) + 1;
1099 			}
1100 		}
1101 		break;
1102 	case DATA_TYPE_HRTIME:
1103 		value_sz = sizeof (hrtime_t);
1104 		break;
1105 	case DATA_TYPE_NVLIST:
1106 		value_sz = NV_ALIGN(sizeof (nvlist_t));
1107 		break;
1108 	case DATA_TYPE_NVLIST_ARRAY:
1109 		value_sz = (uint64_t)nelem * sizeof (uint64_t) +
1110 		    (uint64_t)nelem * NV_ALIGN(sizeof (nvlist_t));
1111 		break;
1112 	default:
1113 		return (-1);
1114 	}
1115 
1116 	return (value_sz > INT32_MAX ? -1 : (int)value_sz);
1117 }
1118 
1119 static int
1120 nvlist_copy_embedded(nvlist_t *nvl, nvlist_t *onvl, nvlist_t *emb_nvl)
1121 {
1122 	nvpriv_t *priv;
1123 	int err;
1124 
1125 	if ((priv = nv_priv_alloc_embedded((nvpriv_t *)(uintptr_t)
1126 	    nvl->nvl_priv)) == NULL)
1127 		return (ENOMEM);
1128 
1129 	nvlist_init(emb_nvl, onvl->nvl_nvflag, priv);
1130 
1131 	if ((err = nvlist_copy_pairs(onvl, emb_nvl)) != 0) {
1132 		nvlist_free(emb_nvl);
1133 		emb_nvl->nvl_priv = 0;
1134 	}
1135 
1136 	return (err);
1137 }
1138 
1139 /*
1140  * nvlist_add_common - Add new <name,value> pair to nvlist
1141  */
1142 static int
1143 nvlist_add_common(nvlist_t *nvl, const char *name,
1144     data_type_t type, uint_t nelem, const void *data)
1145 {
1146 	nvpair_t *nvp;
1147 	uint_t i;
1148 
1149 	int nvp_sz, name_sz, value_sz;
1150 	int err = 0;
1151 
1152 	if (name == NULL || nvl == NULL || nvl->nvl_priv == 0)
1153 		return (EINVAL);
1154 
1155 	if (nelem != 0 && data == NULL)
1156 		return (EINVAL);
1157 
1158 	/*
1159 	 * Verify type and nelem and get the value size.
1160 	 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
1161 	 * is the size of the string(s) included.
1162 	 */
1163 	if ((value_sz = i_get_value_size(type, data, nelem)) < 0)
1164 		return (EINVAL);
1165 
1166 	if (i_validate_nvpair_value(type, nelem, data) != 0)
1167 		return (EINVAL);
1168 
1169 	/*
1170 	 * If we're adding an nvlist or nvlist array, ensure that we are not
1171 	 * adding the input nvlist to itself, which would cause recursion,
1172 	 * and ensure that no NULL nvlist pointers are present.
1173 	 */
1174 	switch (type) {
1175 	case DATA_TYPE_NVLIST:
1176 		if (data == nvl || data == NULL)
1177 			return (EINVAL);
1178 		break;
1179 	case DATA_TYPE_NVLIST_ARRAY: {
1180 		nvlist_t **onvlp = (nvlist_t **)data;
1181 		for (i = 0; i < nelem; i++) {
1182 			if (onvlp[i] == nvl || onvlp[i] == NULL)
1183 				return (EINVAL);
1184 		}
1185 		break;
1186 	}
1187 	default:
1188 		break;
1189 	}
1190 
1191 	/* calculate sizes of the nvpair elements and the nvpair itself */
1192 	name_sz = strlen(name) + 1;
1193 	if (name_sz >= 1ULL << (sizeof (nvp->nvp_name_sz) * NBBY - 1))
1194 		return (EINVAL);
1195 
1196 	nvp_sz = NVP_SIZE_CALC(name_sz, value_sz);
1197 
1198 	if ((nvp = nvp_buf_alloc(nvl, nvp_sz)) == NULL)
1199 		return (ENOMEM);
1200 
1201 	ASSERT(nvp->nvp_size == nvp_sz);
1202 	nvp->nvp_name_sz = name_sz;
1203 	nvp->nvp_value_elem = nelem;
1204 	nvp->nvp_type = type;
1205 	bcopy(name, NVP_NAME(nvp), name_sz);
1206 
1207 	switch (type) {
1208 	case DATA_TYPE_BOOLEAN:
1209 		break;
1210 	case DATA_TYPE_STRING_ARRAY: {
1211 		char *const *strs = data;
1212 		char *buf = NVP_VALUE(nvp);
1213 		char **cstrs = (void *)buf;
1214 
1215 		/* skip pre-allocated space for pointer array */
1216 		buf += nelem * sizeof (uint64_t);
1217 		for (i = 0; i < nelem; i++) {
1218 			int slen = strlen(strs[i]) + 1;
1219 			bcopy(strs[i], buf, slen);
1220 			cstrs[i] = buf;
1221 			buf += slen;
1222 		}
1223 		break;
1224 	}
1225 	case DATA_TYPE_NVLIST: {
1226 		nvlist_t *nnvl = EMBEDDED_NVL(nvp);
1227 		nvlist_t *onvl = (nvlist_t *)data;
1228 
1229 		if ((err = nvlist_copy_embedded(nvl, onvl, nnvl)) != 0) {
1230 			nvp_buf_free(nvl, nvp);
1231 			return (err);
1232 		}
1233 		break;
1234 	}
1235 	case DATA_TYPE_NVLIST_ARRAY: {
1236 		nvlist_t **onvlp = (nvlist_t **)data;
1237 		nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
1238 		nvlist_t *embedded = (nvlist_t *)
1239 		    ((uintptr_t)nvlp + nelem * sizeof (uint64_t));
1240 
1241 		for (i = 0; i < nelem; i++) {
1242 			if ((err = nvlist_copy_embedded(nvl,
1243 			    onvlp[i], embedded)) != 0) {
1244 				/*
1245 				 * Free any successfully created lists
1246 				 */
1247 				nvpair_free(nvp);
1248 				nvp_buf_free(nvl, nvp);
1249 				return (err);
1250 			}
1251 
1252 			nvlp[i] = embedded++;
1253 		}
1254 		break;
1255 	}
1256 	default:
1257 		bcopy(data, NVP_VALUE(nvp), value_sz);
1258 	}
1259 
1260 	/* if unique name, remove before add */
1261 	if (nvl->nvl_nvflag & NV_UNIQUE_NAME)
1262 		(void) nvlist_remove_all(nvl, name);
1263 	else if (nvl->nvl_nvflag & NV_UNIQUE_NAME_TYPE)
1264 		(void) nvlist_remove(nvl, name, type);
1265 
1266 	err = nvt_add_nvpair(nvl, nvp);
1267 	if (err != 0) {
1268 		nvpair_free(nvp);
1269 		nvp_buf_free(nvl, nvp);
1270 		return (err);
1271 	}
1272 	nvp_buf_link(nvl, nvp);
1273 
1274 	return (0);
1275 }
1276 
1277 int
1278 nvlist_add_boolean(nvlist_t *nvl, const char *name)
1279 {
1280 	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN, 0, NULL));
1281 }
1282 
1283 int
1284 nvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t val)
1285 {
1286 	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_VALUE, 1, &val));
1287 }
1288 
1289 int
1290 nvlist_add_byte(nvlist_t *nvl, const char *name, uchar_t val)
1291 {
1292 	return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE, 1, &val));
1293 }
1294 
1295 int
1296 nvlist_add_int8(nvlist_t *nvl, const char *name, int8_t val)
1297 {
1298 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT8, 1, &val));
1299 }
1300 
1301 int
1302 nvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
1303 {
1304 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8, 1, &val));
1305 }
1306 
1307 int
1308 nvlist_add_int16(nvlist_t *nvl, const char *name, int16_t val)
1309 {
1310 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT16, 1, &val));
1311 }
1312 
1313 int
1314 nvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
1315 {
1316 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16, 1, &val));
1317 }
1318 
1319 int
1320 nvlist_add_int32(nvlist_t *nvl, const char *name, int32_t val)
1321 {
1322 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT32, 1, &val));
1323 }
1324 
1325 int
1326 nvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t val)
1327 {
1328 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32, 1, &val));
1329 }
1330 
1331 int
1332 nvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val)
1333 {
1334 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT64, 1, &val));
1335 }
1336 
1337 int
1338 nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
1339 {
1340 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val));
1341 }
1342 
1343 #if !defined(_KERNEL)
1344 int
1345 nvlist_add_double(nvlist_t *nvl, const char *name, double val)
1346 {
1347 	return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val));
1348 }
1349 #endif
1350 
1351 int
1352 nvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
1353 {
1354 	return (nvlist_add_common(nvl, name, DATA_TYPE_STRING, 1, (void *)val));
1355 }
1356 
1357 int
1358 nvlist_add_boolean_array(nvlist_t *nvl, const char *name,
1359     boolean_t *a, uint_t n)
1360 {
1361 	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_ARRAY, n, a));
1362 }
1363 
1364 int
1365 nvlist_add_byte_array(nvlist_t *nvl, const char *name, uchar_t *a, uint_t n)
1366 {
1367 	return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
1368 }
1369 
1370 int
1371 nvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *a, uint_t n)
1372 {
1373 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
1374 }
1375 
1376 int
1377 nvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *a, uint_t n)
1378 {
1379 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
1380 }
1381 
1382 int
1383 nvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *a, uint_t n)
1384 {
1385 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
1386 }
1387 
1388 int
1389 nvlist_add_uint16_array(nvlist_t *nvl, const char *name, uint16_t *a, uint_t n)
1390 {
1391 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
1392 }
1393 
1394 int
1395 nvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *a, uint_t n)
1396 {
1397 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
1398 }
1399 
1400 int
1401 nvlist_add_uint32_array(nvlist_t *nvl, const char *name, uint32_t *a, uint_t n)
1402 {
1403 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
1404 }
1405 
1406 int
1407 nvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *a, uint_t n)
1408 {
1409 	return (nvlist_add_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
1410 }
1411 
1412 int
1413 nvlist_add_uint64_array(nvlist_t *nvl, const char *name, uint64_t *a, uint_t n)
1414 {
1415 	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
1416 }
1417 
1418 int
1419 nvlist_add_string_array(nvlist_t *nvl, const char *name,
1420     char *const *a, uint_t n)
1421 {
1422 	return (nvlist_add_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
1423 }
1424 
1425 int
1426 nvlist_add_hrtime(nvlist_t *nvl, const char *name, hrtime_t val)
1427 {
1428 	return (nvlist_add_common(nvl, name, DATA_TYPE_HRTIME, 1, &val));
1429 }
1430 
1431 int
1432 nvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
1433 {
1434 	return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST, 1, val));
1435 }
1436 
1437 int
1438 nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **a, uint_t n)
1439 {
1440 	return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
1441 }
1442 
1443 /* reading name-value pairs */
1444 nvpair_t *
1445 nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1446 {
1447 	nvpriv_t *priv;
1448 	i_nvp_t *curr;
1449 
1450 	if (nvl == NULL ||
1451 	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1452 		return (NULL);
1453 
1454 	curr = NVPAIR2I_NVP(nvp);
1455 
1456 	/*
1457 	 * Ensure that nvp is a valid nvpair on this nvlist.
1458 	 * NB: nvp_curr is used only as a hint so that we don't always
1459 	 * have to walk the list to determine if nvp is still on the list.
1460 	 */
1461 	if (nvp == NULL)
1462 		curr = priv->nvp_list;
1463 	else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
1464 		curr = curr->nvi_next;
1465 	else
1466 		curr = NULL;
1467 
1468 	priv->nvp_curr = curr;
1469 
1470 	return (curr != NULL ? &curr->nvi_nvp : NULL);
1471 }
1472 
1473 nvpair_t *
1474 nvlist_prev_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1475 {
1476 	nvpriv_t *priv;
1477 	i_nvp_t *curr;
1478 
1479 	if (nvl == NULL ||
1480 	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1481 		return (NULL);
1482 
1483 	curr = NVPAIR2I_NVP(nvp);
1484 
1485 	if (nvp == NULL)
1486 		curr = priv->nvp_last;
1487 	else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
1488 		curr = curr->nvi_prev;
1489 	else
1490 		curr = NULL;
1491 
1492 	priv->nvp_curr = curr;
1493 
1494 	return (curr != NULL ? &curr->nvi_nvp : NULL);
1495 }
1496 
1497 boolean_t
1498 nvlist_empty(nvlist_t *nvl)
1499 {
1500 	nvpriv_t *priv;
1501 
1502 	if (nvl == NULL ||
1503 	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1504 		return (B_TRUE);
1505 
1506 	return (priv->nvp_list == NULL);
1507 }
1508 
1509 char *
1510 nvpair_name(nvpair_t *nvp)
1511 {
1512 	return (NVP_NAME(nvp));
1513 }
1514 
1515 data_type_t
1516 nvpair_type(nvpair_t *nvp)
1517 {
1518 	return (NVP_TYPE(nvp));
1519 }
1520 
1521 int
1522 nvpair_type_is_array(nvpair_t *nvp)
1523 {
1524 	data_type_t type = NVP_TYPE(nvp);
1525 
1526 	if ((type == DATA_TYPE_BYTE_ARRAY) ||
1527 	    (type == DATA_TYPE_INT8_ARRAY) ||
1528 	    (type == DATA_TYPE_UINT8_ARRAY) ||
1529 	    (type == DATA_TYPE_INT16_ARRAY) ||
1530 	    (type == DATA_TYPE_UINT16_ARRAY) ||
1531 	    (type == DATA_TYPE_INT32_ARRAY) ||
1532 	    (type == DATA_TYPE_UINT32_ARRAY) ||
1533 	    (type == DATA_TYPE_INT64_ARRAY) ||
1534 	    (type == DATA_TYPE_UINT64_ARRAY) ||
1535 	    (type == DATA_TYPE_BOOLEAN_ARRAY) ||
1536 	    (type == DATA_TYPE_STRING_ARRAY) ||
1537 	    (type == DATA_TYPE_NVLIST_ARRAY))
1538 		return (1);
1539 	return (0);
1540 
1541 }
1542 
1543 static int
1544 nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
1545 {
1546 	int value_sz;
1547 
1548 	if (nvp == NULL || nvpair_type(nvp) != type)
1549 		return (EINVAL);
1550 
1551 	/*
1552 	 * For non-array types, we copy the data.
1553 	 * For array types (including string), we set a pointer.
1554 	 */
1555 	switch (type) {
1556 	case DATA_TYPE_BOOLEAN:
1557 		if (nelem != NULL)
1558 			*nelem = 0;
1559 		break;
1560 
1561 	case DATA_TYPE_BOOLEAN_VALUE:
1562 	case DATA_TYPE_BYTE:
1563 	case DATA_TYPE_INT8:
1564 	case DATA_TYPE_UINT8:
1565 	case DATA_TYPE_INT16:
1566 	case DATA_TYPE_UINT16:
1567 	case DATA_TYPE_INT32:
1568 	case DATA_TYPE_UINT32:
1569 	case DATA_TYPE_INT64:
1570 	case DATA_TYPE_UINT64:
1571 	case DATA_TYPE_HRTIME:
1572 #if !defined(_KERNEL)
1573 	case DATA_TYPE_DOUBLE:
1574 #endif
1575 		if (data == NULL)
1576 			return (EINVAL);
1577 		if ((value_sz = i_get_value_size(type, NULL, 1)) < 0)
1578 			return (EINVAL);
1579 		bcopy(NVP_VALUE(nvp), data, (size_t)value_sz);
1580 		if (nelem != NULL)
1581 			*nelem = 1;
1582 		break;
1583 
1584 	case DATA_TYPE_NVLIST:
1585 	case DATA_TYPE_STRING:
1586 		if (data == NULL)
1587 			return (EINVAL);
1588 		*(void **)data = (void *)NVP_VALUE(nvp);
1589 		if (nelem != NULL)
1590 			*nelem = 1;
1591 		break;
1592 
1593 	case DATA_TYPE_BOOLEAN_ARRAY:
1594 	case DATA_TYPE_BYTE_ARRAY:
1595 	case DATA_TYPE_INT8_ARRAY:
1596 	case DATA_TYPE_UINT8_ARRAY:
1597 	case DATA_TYPE_INT16_ARRAY:
1598 	case DATA_TYPE_UINT16_ARRAY:
1599 	case DATA_TYPE_INT32_ARRAY:
1600 	case DATA_TYPE_UINT32_ARRAY:
1601 	case DATA_TYPE_INT64_ARRAY:
1602 	case DATA_TYPE_UINT64_ARRAY:
1603 	case DATA_TYPE_STRING_ARRAY:
1604 	case DATA_TYPE_NVLIST_ARRAY:
1605 		if (nelem == NULL || data == NULL)
1606 			return (EINVAL);
1607 		if ((*nelem = NVP_NELEM(nvp)) != 0)
1608 			*(void **)data = (void *)NVP_VALUE(nvp);
1609 		else
1610 			*(void **)data = NULL;
1611 		break;
1612 
1613 	default:
1614 		return (ENOTSUP);
1615 	}
1616 
1617 	return (0);
1618 }
1619 
1620 static int
1621 nvlist_lookup_common(nvlist_t *nvl, const char *name, data_type_t type,
1622     uint_t *nelem, void *data)
1623 {
1624 	if (name == NULL || nvl == NULL || nvl->nvl_priv == 0)
1625 		return (EINVAL);
1626 
1627 	if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE)))
1628 		return (ENOTSUP);
1629 
1630 	nvpair_t *nvp = nvt_lookup_name_type(nvl, name, type);
1631 	if (nvp == NULL)
1632 		return (ENOENT);
1633 
1634 	return (nvpair_value_common(nvp, type, nelem, data));
1635 }
1636 
1637 int
1638 nvlist_lookup_boolean(nvlist_t *nvl, const char *name)
1639 {
1640 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_BOOLEAN, NULL, NULL));
1641 }
1642 
1643 int
1644 nvlist_lookup_boolean_value(nvlist_t *nvl, const char *name, boolean_t *val)
1645 {
1646 	return (nvlist_lookup_common(nvl, name,
1647 	    DATA_TYPE_BOOLEAN_VALUE, NULL, val));
1648 }
1649 
1650 int
1651 nvlist_lookup_byte(nvlist_t *nvl, const char *name, uchar_t *val)
1652 {
1653 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE, NULL, val));
1654 }
1655 
1656 int
1657 nvlist_lookup_int8(nvlist_t *nvl, const char *name, int8_t *val)
1658 {
1659 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8, NULL, val));
1660 }
1661 
1662 int
1663 nvlist_lookup_uint8(nvlist_t *nvl, const char *name, uint8_t *val)
1664 {
1665 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8, NULL, val));
1666 }
1667 
1668 int
1669 nvlist_lookup_int16(nvlist_t *nvl, const char *name, int16_t *val)
1670 {
1671 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16, NULL, val));
1672 }
1673 
1674 int
1675 nvlist_lookup_uint16(nvlist_t *nvl, const char *name, uint16_t *val)
1676 {
1677 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16, NULL, val));
1678 }
1679 
1680 int
1681 nvlist_lookup_int32(nvlist_t *nvl, const char *name, int32_t *val)
1682 {
1683 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32, NULL, val));
1684 }
1685 
1686 int
1687 nvlist_lookup_uint32(nvlist_t *nvl, const char *name, uint32_t *val)
1688 {
1689 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32, NULL, val));
1690 }
1691 
1692 int
1693 nvlist_lookup_int64(nvlist_t *nvl, const char *name, int64_t *val)
1694 {
1695 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64, NULL, val));
1696 }
1697 
1698 int
1699 nvlist_lookup_uint64(nvlist_t *nvl, const char *name, uint64_t *val)
1700 {
1701 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val));
1702 }
1703 
1704 #if !defined(_KERNEL)
1705 int
1706 nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val)
1707 {
1708 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val));
1709 }
1710 #endif
1711 
1712 int
1713 nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
1714 {
1715 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val));
1716 }
1717 
1718 int
1719 nvlist_lookup_nvlist(nvlist_t *nvl, const char *name, nvlist_t **val)
1720 {
1721 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST, NULL, val));
1722 }
1723 
1724 int
1725 nvlist_lookup_boolean_array(nvlist_t *nvl, const char *name,
1726     boolean_t **a, uint_t *n)
1727 {
1728 	return (nvlist_lookup_common(nvl, name,
1729 	    DATA_TYPE_BOOLEAN_ARRAY, n, a));
1730 }
1731 
1732 int
1733 nvlist_lookup_byte_array(nvlist_t *nvl, const char *name,
1734     uchar_t **a, uint_t *n)
1735 {
1736 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
1737 }
1738 
1739 int
1740 nvlist_lookup_int8_array(nvlist_t *nvl, const char *name, int8_t **a, uint_t *n)
1741 {
1742 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
1743 }
1744 
1745 int
1746 nvlist_lookup_uint8_array(nvlist_t *nvl, const char *name,
1747     uint8_t **a, uint_t *n)
1748 {
1749 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
1750 }
1751 
1752 int
1753 nvlist_lookup_int16_array(nvlist_t *nvl, const char *name,
1754     int16_t **a, uint_t *n)
1755 {
1756 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
1757 }
1758 
1759 int
1760 nvlist_lookup_uint16_array(nvlist_t *nvl, const char *name,
1761     uint16_t **a, uint_t *n)
1762 {
1763 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
1764 }
1765 
1766 int
1767 nvlist_lookup_int32_array(nvlist_t *nvl, const char *name,
1768     int32_t **a, uint_t *n)
1769 {
1770 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
1771 }
1772 
1773 int
1774 nvlist_lookup_uint32_array(nvlist_t *nvl, const char *name,
1775     uint32_t **a, uint_t *n)
1776 {
1777 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
1778 }
1779 
1780 int
1781 nvlist_lookup_int64_array(nvlist_t *nvl, const char *name,
1782     int64_t **a, uint_t *n)
1783 {
1784 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
1785 }
1786 
1787 int
1788 nvlist_lookup_uint64_array(nvlist_t *nvl, const char *name,
1789     uint64_t **a, uint_t *n)
1790 {
1791 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
1792 }
1793 
1794 int
1795 nvlist_lookup_string_array(nvlist_t *nvl, const char *name,
1796     char ***a, uint_t *n)
1797 {
1798 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
1799 }
1800 
1801 int
1802 nvlist_lookup_nvlist_array(nvlist_t *nvl, const char *name,
1803     nvlist_t ***a, uint_t *n)
1804 {
1805 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
1806 }
1807 
1808 int
1809 nvlist_lookup_hrtime(nvlist_t *nvl, const char *name, hrtime_t *val)
1810 {
1811 	return (nvlist_lookup_common(nvl, name, DATA_TYPE_HRTIME, NULL, val));
1812 }
1813 
1814 int
1815 nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...)
1816 {
1817 	va_list ap;
1818 	char *name;
1819 	int noentok = (flag & NV_FLAG_NOENTOK ? 1 : 0);
1820 	int ret = 0;
1821 
1822 	va_start(ap, flag);
1823 	while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
1824 		data_type_t type;
1825 		void *val;
1826 		uint_t *nelem;
1827 
1828 		switch (type = va_arg(ap, data_type_t)) {
1829 		case DATA_TYPE_BOOLEAN:
1830 			ret = nvlist_lookup_common(nvl, name, type, NULL, NULL);
1831 			break;
1832 
1833 		case DATA_TYPE_BOOLEAN_VALUE:
1834 		case DATA_TYPE_BYTE:
1835 		case DATA_TYPE_INT8:
1836 		case DATA_TYPE_UINT8:
1837 		case DATA_TYPE_INT16:
1838 		case DATA_TYPE_UINT16:
1839 		case DATA_TYPE_INT32:
1840 		case DATA_TYPE_UINT32:
1841 		case DATA_TYPE_INT64:
1842 		case DATA_TYPE_UINT64:
1843 		case DATA_TYPE_HRTIME:
1844 		case DATA_TYPE_STRING:
1845 		case DATA_TYPE_NVLIST:
1846 #if !defined(_KERNEL)
1847 		case DATA_TYPE_DOUBLE:
1848 #endif
1849 			val = va_arg(ap, void *);
1850 			ret = nvlist_lookup_common(nvl, name, type, NULL, val);
1851 			break;
1852 
1853 		case DATA_TYPE_BYTE_ARRAY:
1854 		case DATA_TYPE_BOOLEAN_ARRAY:
1855 		case DATA_TYPE_INT8_ARRAY:
1856 		case DATA_TYPE_UINT8_ARRAY:
1857 		case DATA_TYPE_INT16_ARRAY:
1858 		case DATA_TYPE_UINT16_ARRAY:
1859 		case DATA_TYPE_INT32_ARRAY:
1860 		case DATA_TYPE_UINT32_ARRAY:
1861 		case DATA_TYPE_INT64_ARRAY:
1862 		case DATA_TYPE_UINT64_ARRAY:
1863 		case DATA_TYPE_STRING_ARRAY:
1864 		case DATA_TYPE_NVLIST_ARRAY:
1865 			val = va_arg(ap, void *);
1866 			nelem = va_arg(ap, uint_t *);
1867 			ret = nvlist_lookup_common(nvl, name, type, nelem, val);
1868 			break;
1869 
1870 		default:
1871 			ret = EINVAL;
1872 		}
1873 
1874 		if (ret == ENOENT && noentok)
1875 			ret = 0;
1876 	}
1877 	va_end(ap);
1878 
1879 	return (ret);
1880 }
1881 
1882 /*
1883  * Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function
1884  * returns zero and a pointer to the matching nvpair is returned in '*ret'
1885  * (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate
1886  * multiple levels of embedded nvlists, with 'sep' as the separator. As an
1887  * example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or
1888  * "a.d[3].e[1]".  This matches the C syntax for array embed (for convenience,
1889  * code also supports "a.d[3]e[1]" syntax).
1890  *
1891  * If 'ip' is non-NULL and the last name component is an array, return the
1892  * value of the "...[index]" array index in *ip. For an array reference that
1893  * is not indexed, *ip will be returned as -1. If there is a syntax error in
1894  * 'name', and 'ep' is non-NULL then *ep will be set to point to the location
1895  * inside the 'name' string where the syntax error was detected.
1896  */
1897 static int
1898 nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
1899     nvpair_t **ret, int *ip, char **ep)
1900 {
1901 	nvpair_t	*nvp;
1902 	const char	*np;
1903 	char		*sepp = NULL;
1904 	char		*idxp, *idxep;
1905 	nvlist_t	**nva;
1906 	long		idx = 0;
1907 	int		n;
1908 
1909 	if (ip)
1910 		*ip = -1;			/* not indexed */
1911 	if (ep)
1912 		*ep = NULL;
1913 
1914 	if ((nvl == NULL) || (name == NULL))
1915 		return (EINVAL);
1916 
1917 	sepp = NULL;
1918 	idx = 0;
1919 	/* step through components of name */
1920 	for (np = name; np && *np; np = sepp) {
1921 		/* ensure unique names */
1922 		if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME))
1923 			return (ENOTSUP);
1924 
1925 		/* skip white space */
1926 		skip_whitespace(np);
1927 		if (*np == 0)
1928 			break;
1929 
1930 		/* set 'sepp' to end of current component 'np' */
1931 		if (sep)
1932 			sepp = strchr(np, sep);
1933 		else
1934 			sepp = NULL;
1935 
1936 		/* find start of next "[ index ]..." */
1937 		idxp = strchr(np, '[');
1938 
1939 		/* if sepp comes first, set idxp to NULL */
1940 		if (sepp && idxp && (sepp < idxp))
1941 			idxp = NULL;
1942 
1943 		/*
1944 		 * At this point 'idxp' is set if there is an index
1945 		 * expected for the current component.
1946 		 */
1947 		if (idxp) {
1948 			/* set 'n' to length of current 'np' name component */
1949 			n = idxp++ - np;
1950 
1951 			/* keep sepp up to date for *ep use as we advance */
1952 			skip_whitespace(idxp);
1953 			sepp = idxp;
1954 
1955 			/* determine the index value */
1956 #if defined(_KERNEL)
1957 			if (ddi_strtol(idxp, &idxep, 0, &idx))
1958 				goto fail;
1959 #else
1960 			idx = strtol(idxp, &idxep, 0);
1961 #endif
1962 			if (idxep == idxp)
1963 				goto fail;
1964 
1965 			/* keep sepp up to date for *ep use as we advance */
1966 			sepp = idxep;
1967 
1968 			/* skip white space index value and check for ']' */
1969 			skip_whitespace(sepp);
1970 			if (*sepp++ != ']')
1971 				goto fail;
1972 
1973 			/* for embedded arrays, support C syntax: "a[1].b" */
1974 			skip_whitespace(sepp);
1975 			if (sep && (*sepp == sep))
1976 				sepp++;
1977 		} else if (sepp) {
1978 			n = sepp++ - np;
1979 		} else {
1980 			n = strlen(np);
1981 		}
1982 
1983 		/* trim trailing whitespace by reducing length of 'np' */
1984 		if (n == 0)
1985 			goto fail;
1986 		for (n--; (np[n] == ' ') || (np[n] == '\t'); n--)
1987 			;
1988 		n++;
1989 
1990 		/* skip whitespace, and set sepp to NULL if complete */
1991 		if (sepp) {
1992 			skip_whitespace(sepp);
1993 			if (*sepp == 0)
1994 				sepp = NULL;
1995 		}
1996 
1997 		/*
1998 		 * At this point:
1999 		 * o  'n' is the length of current 'np' component.
2000 		 * o  'idxp' is set if there was an index, and value 'idx'.
2001 		 * o  'sepp' is set to the beginning of the next component,
2002 		 *    and set to NULL if we have no more components.
2003 		 *
2004 		 * Search for nvpair with matching component name.
2005 		 */
2006 		for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
2007 		    nvp = nvlist_next_nvpair(nvl, nvp)) {
2008 
2009 			/* continue if no match on name */
2010 			if (strncmp(np, nvpair_name(nvp), n) ||
2011 			    (strlen(nvpair_name(nvp)) != n))
2012 				continue;
2013 
2014 			/* if indexed, verify type is array oriented */
2015 			if (idxp && !nvpair_type_is_array(nvp))
2016 				goto fail;
2017 
2018 			/*
2019 			 * Full match found, return nvp and idx if this
2020 			 * was the last component.
2021 			 */
2022 			if (sepp == NULL) {
2023 				if (ret)
2024 					*ret = nvp;
2025 				if (ip && idxp)
2026 					*ip = (int)idx;	/* return index */
2027 				return (0);		/* found */
2028 			}
2029 
2030 			/*
2031 			 * More components: current match must be
2032 			 * of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY
2033 			 * to support going deeper.
2034 			 */
2035 			if (nvpair_type(nvp) == DATA_TYPE_NVLIST) {
2036 				nvl = EMBEDDED_NVL(nvp);
2037 				break;
2038 			} else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) {
2039 				(void) nvpair_value_nvlist_array(nvp,
2040 				    &nva, (uint_t *)&n);
2041 				if ((n < 0) || (idx >= n))
2042 					goto fail;
2043 				nvl = nva[idx];
2044 				break;
2045 			}
2046 
2047 			/* type does not support more levels */
2048 			goto fail;
2049 		}
2050 		if (nvp == NULL)
2051 			goto fail;		/* 'name' not found */
2052 
2053 		/* search for match of next component in embedded 'nvl' list */
2054 	}
2055 
2056 fail:	if (ep && sepp)
2057 		*ep = sepp;
2058 	return (EINVAL);
2059 }
2060 
2061 /*
2062  * Return pointer to nvpair with specified 'name'.
2063  */
2064 int
2065 nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret)
2066 {
2067 	return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL));
2068 }
2069 
2070 /*
2071  * Determine if named nvpair exists in nvlist (use embedded separator of '.'
2072  * and return array index).  See nvlist_lookup_nvpair_ei_sep for more detailed
2073  * description.
2074  */
2075 int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl,
2076     const char *name, nvpair_t **ret, int *ip, char **ep)
2077 {
2078 	return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep));
2079 }
2080 
2081 boolean_t
2082 nvlist_exists(nvlist_t *nvl, const char *name)
2083 {
2084 	nvpriv_t *priv;
2085 	nvpair_t *nvp;
2086 	i_nvp_t *curr;
2087 
2088 	if (name == NULL || nvl == NULL ||
2089 	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
2090 		return (B_FALSE);
2091 
2092 	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
2093 		nvp = &curr->nvi_nvp;
2094 
2095 		if (strcmp(name, NVP_NAME(nvp)) == 0)
2096 			return (B_TRUE);
2097 	}
2098 
2099 	return (B_FALSE);
2100 }
2101 
2102 int
2103 nvpair_value_boolean_value(nvpair_t *nvp, boolean_t *val)
2104 {
2105 	return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_VALUE, NULL, val));
2106 }
2107 
2108 int
2109 nvpair_value_byte(nvpair_t *nvp, uchar_t *val)
2110 {
2111 	return (nvpair_value_common(nvp, DATA_TYPE_BYTE, NULL, val));
2112 }
2113 
2114 int
2115 nvpair_value_int8(nvpair_t *nvp, int8_t *val)
2116 {
2117 	return (nvpair_value_common(nvp, DATA_TYPE_INT8, NULL, val));
2118 }
2119 
2120 int
2121 nvpair_value_uint8(nvpair_t *nvp, uint8_t *val)
2122 {
2123 	return (nvpair_value_common(nvp, DATA_TYPE_UINT8, NULL, val));
2124 }
2125 
2126 int
2127 nvpair_value_int16(nvpair_t *nvp, int16_t *val)
2128 {
2129 	return (nvpair_value_common(nvp, DATA_TYPE_INT16, NULL, val));
2130 }
2131 
2132 int
2133 nvpair_value_uint16(nvpair_t *nvp, uint16_t *val)
2134 {
2135 	return (nvpair_value_common(nvp, DATA_TYPE_UINT16, NULL, val));
2136 }
2137 
2138 int
2139 nvpair_value_int32(nvpair_t *nvp, int32_t *val)
2140 {
2141 	return (nvpair_value_common(nvp, DATA_TYPE_INT32, NULL, val));
2142 }
2143 
2144 int
2145 nvpair_value_uint32(nvpair_t *nvp, uint32_t *val)
2146 {
2147 	return (nvpair_value_common(nvp, DATA_TYPE_UINT32, NULL, val));
2148 }
2149 
2150 int
2151 nvpair_value_int64(nvpair_t *nvp, int64_t *val)
2152 {
2153 	return (nvpair_value_common(nvp, DATA_TYPE_INT64, NULL, val));
2154 }
2155 
2156 int
2157 nvpair_value_uint64(nvpair_t *nvp, uint64_t *val)
2158 {
2159 	return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val));
2160 }
2161 
2162 #if !defined(_KERNEL)
2163 int
2164 nvpair_value_double(nvpair_t *nvp, double *val)
2165 {
2166 	return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val));
2167 }
2168 #endif
2169 
2170 int
2171 nvpair_value_string(nvpair_t *nvp, char **val)
2172 {
2173 	return (nvpair_value_common(nvp, DATA_TYPE_STRING, NULL, val));
2174 }
2175 
2176 int
2177 nvpair_value_nvlist(nvpair_t *nvp, nvlist_t **val)
2178 {
2179 	return (nvpair_value_common(nvp, DATA_TYPE_NVLIST, NULL, val));
2180 }
2181 
2182 int
2183 nvpair_value_boolean_array(nvpair_t *nvp, boolean_t **val, uint_t *nelem)
2184 {
2185 	return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_ARRAY, nelem, val));
2186 }
2187 
2188 int
2189 nvpair_value_byte_array(nvpair_t *nvp, uchar_t **val, uint_t *nelem)
2190 {
2191 	return (nvpair_value_common(nvp, DATA_TYPE_BYTE_ARRAY, nelem, val));
2192 }
2193 
2194 int
2195 nvpair_value_int8_array(nvpair_t *nvp, int8_t **val, uint_t *nelem)
2196 {
2197 	return (nvpair_value_common(nvp, DATA_TYPE_INT8_ARRAY, nelem, val));
2198 }
2199 
2200 int
2201 nvpair_value_uint8_array(nvpair_t *nvp, uint8_t **val, uint_t *nelem)
2202 {
2203 	return (nvpair_value_common(nvp, DATA_TYPE_UINT8_ARRAY, nelem, val));
2204 }
2205 
2206 int
2207 nvpair_value_int16_array(nvpair_t *nvp, int16_t **val, uint_t *nelem)
2208 {
2209 	return (nvpair_value_common(nvp, DATA_TYPE_INT16_ARRAY, nelem, val));
2210 }
2211 
2212 int
2213 nvpair_value_uint16_array(nvpair_t *nvp, uint16_t **val, uint_t *nelem)
2214 {
2215 	return (nvpair_value_common(nvp, DATA_TYPE_UINT16_ARRAY, nelem, val));
2216 }
2217 
2218 int
2219 nvpair_value_int32_array(nvpair_t *nvp, int32_t **val, uint_t *nelem)
2220 {
2221 	return (nvpair_value_common(nvp, DATA_TYPE_INT32_ARRAY, nelem, val));
2222 }
2223 
2224 int
2225 nvpair_value_uint32_array(nvpair_t *nvp, uint32_t **val, uint_t *nelem)
2226 {
2227 	return (nvpair_value_common(nvp, DATA_TYPE_UINT32_ARRAY, nelem, val));
2228 }
2229 
2230 int
2231 nvpair_value_int64_array(nvpair_t *nvp, int64_t **val, uint_t *nelem)
2232 {
2233 	return (nvpair_value_common(nvp, DATA_TYPE_INT64_ARRAY, nelem, val));
2234 }
2235 
2236 int
2237 nvpair_value_uint64_array(nvpair_t *nvp, uint64_t **val, uint_t *nelem)
2238 {
2239 	return (nvpair_value_common(nvp, DATA_TYPE_UINT64_ARRAY, nelem, val));
2240 }
2241 
2242 int
2243 nvpair_value_string_array(nvpair_t *nvp, char ***val, uint_t *nelem)
2244 {
2245 	return (nvpair_value_common(nvp, DATA_TYPE_STRING_ARRAY, nelem, val));
2246 }
2247 
2248 int
2249 nvpair_value_nvlist_array(nvpair_t *nvp, nvlist_t ***val, uint_t *nelem)
2250 {
2251 	return (nvpair_value_common(nvp, DATA_TYPE_NVLIST_ARRAY, nelem, val));
2252 }
2253 
2254 int
2255 nvpair_value_hrtime(nvpair_t *nvp, hrtime_t *val)
2256 {
2257 	return (nvpair_value_common(nvp, DATA_TYPE_HRTIME, NULL, val));
2258 }
2259 
2260 /*
2261  * Add specified pair to the list.
2262  */
2263 int
2264 nvlist_add_nvpair(nvlist_t *nvl, nvpair_t *nvp)
2265 {
2266 	if (nvl == NULL || nvp == NULL)
2267 		return (EINVAL);
2268 
2269 	return (nvlist_add_common(nvl, NVP_NAME(nvp), NVP_TYPE(nvp),
2270 	    NVP_NELEM(nvp), NVP_VALUE(nvp)));
2271 }
2272 
2273 /*
2274  * Merge the supplied nvlists and put the result in dst.
2275  * The merged list will contain all names specified in both lists,
2276  * the values are taken from nvl in the case of duplicates.
2277  * Return 0 on success.
2278  */
2279 /*ARGSUSED*/
2280 int
2281 nvlist_merge(nvlist_t *dst, nvlist_t *nvl, int flag)
2282 {
2283 	if (nvl == NULL || dst == NULL)
2284 		return (EINVAL);
2285 
2286 	if (dst != nvl)
2287 		return (nvlist_copy_pairs(nvl, dst));
2288 
2289 	return (0);
2290 }
2291 
2292 /*
2293  * Encoding related routines
2294  */
2295 #define	NVS_OP_ENCODE	0
2296 #define	NVS_OP_DECODE	1
2297 #define	NVS_OP_GETSIZE	2
2298 
2299 typedef struct nvs_ops nvs_ops_t;
2300 
2301 typedef struct {
2302 	int		nvs_op;
2303 	const nvs_ops_t	*nvs_ops;
2304 	void		*nvs_private;
2305 	nvpriv_t	*nvs_priv;
2306 	int		nvs_recursion;
2307 } nvstream_t;
2308 
2309 /*
2310  * nvs operations are:
2311  *   - nvs_nvlist
2312  *     encoding / decoding of an nvlist header (nvlist_t)
2313  *     calculates the size used for header and end detection
2314  *
2315  *   - nvs_nvpair
2316  *     responsible for the first part of encoding / decoding of an nvpair
2317  *     calculates the decoded size of an nvpair
2318  *
2319  *   - nvs_nvp_op
2320  *     second part of encoding / decoding of an nvpair
2321  *
2322  *   - nvs_nvp_size
2323  *     calculates the encoding size of an nvpair
2324  *
2325  *   - nvs_nvl_fini
2326  *     encodes the end detection mark (zeros).
2327  */
2328 struct nvs_ops {
2329 	int (*nvs_nvlist)(nvstream_t *, nvlist_t *, size_t *);
2330 	int (*nvs_nvpair)(nvstream_t *, nvpair_t *, size_t *);
2331 	int (*nvs_nvp_op)(nvstream_t *, nvpair_t *);
2332 	int (*nvs_nvp_size)(nvstream_t *, nvpair_t *, size_t *);
2333 	int (*nvs_nvl_fini)(nvstream_t *);
2334 };
2335 
2336 typedef struct {
2337 	char	nvh_encoding;	/* nvs encoding method */
2338 	char	nvh_endian;	/* nvs endian */
2339 	char	nvh_reserved1;	/* reserved for future use */
2340 	char	nvh_reserved2;	/* reserved for future use */
2341 } nvs_header_t;
2342 
2343 static int
2344 nvs_encode_pairs(nvstream_t *nvs, nvlist_t *nvl)
2345 {
2346 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
2347 	i_nvp_t *curr;
2348 
2349 	/*
2350 	 * Walk nvpair in list and encode each nvpair
2351 	 */
2352 	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
2353 		if (nvs->nvs_ops->nvs_nvpair(nvs, &curr->nvi_nvp, NULL) != 0)
2354 			return (EFAULT);
2355 
2356 	return (nvs->nvs_ops->nvs_nvl_fini(nvs));
2357 }
2358 
2359 static int
2360 nvs_decode_pairs(nvstream_t *nvs, nvlist_t *nvl)
2361 {
2362 	nvpair_t *nvp;
2363 	size_t nvsize;
2364 	int err;
2365 
2366 	/*
2367 	 * Get decoded size of next pair in stream, alloc
2368 	 * memory for nvpair_t, then decode the nvpair
2369 	 */
2370 	while ((err = nvs->nvs_ops->nvs_nvpair(nvs, NULL, &nvsize)) == 0) {
2371 		if (nvsize == 0) /* end of list */
2372 			break;
2373 
2374 		/* make sure len makes sense */
2375 		if (nvsize < NVP_SIZE_CALC(1, 0))
2376 			return (EFAULT);
2377 
2378 		if ((nvp = nvp_buf_alloc(nvl, nvsize)) == NULL)
2379 			return (ENOMEM);
2380 
2381 		if ((err = nvs->nvs_ops->nvs_nvp_op(nvs, nvp)) != 0) {
2382 			nvp_buf_free(nvl, nvp);
2383 			return (err);
2384 		}
2385 
2386 		if (i_validate_nvpair(nvp) != 0) {
2387 			nvpair_free(nvp);
2388 			nvp_buf_free(nvl, nvp);
2389 			return (EFAULT);
2390 		}
2391 
2392 		err = nvt_add_nvpair(nvl, nvp);
2393 		if (err != 0) {
2394 			nvpair_free(nvp);
2395 			nvp_buf_free(nvl, nvp);
2396 			return (err);
2397 		}
2398 		nvp_buf_link(nvl, nvp);
2399 	}
2400 	return (err);
2401 }
2402 
2403 static int
2404 nvs_getsize_pairs(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
2405 {
2406 	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
2407 	i_nvp_t *curr;
2408 	uint64_t nvsize = *buflen;
2409 	size_t size;
2410 
2411 	/*
2412 	 * Get encoded size of nvpairs in nvlist
2413 	 */
2414 	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
2415 		if (nvs->nvs_ops->nvs_nvp_size(nvs, &curr->nvi_nvp, &size) != 0)
2416 			return (EINVAL);
2417 
2418 		if ((nvsize += size) > INT32_MAX)
2419 			return (EINVAL);
2420 	}
2421 
2422 	*buflen = nvsize;
2423 	return (0);
2424 }
2425 
2426 static int
2427 nvs_operation(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
2428 {
2429 	int err;
2430 
2431 	if (nvl->nvl_priv == 0)
2432 		return (EFAULT);
2433 
2434 	/*
2435 	 * Perform the operation, starting with header, then each nvpair
2436 	 */
2437 	if ((err = nvs->nvs_ops->nvs_nvlist(nvs, nvl, buflen)) != 0)
2438 		return (err);
2439 
2440 	switch (nvs->nvs_op) {
2441 	case NVS_OP_ENCODE:
2442 		err = nvs_encode_pairs(nvs, nvl);
2443 		break;
2444 
2445 	case NVS_OP_DECODE:
2446 		err = nvs_decode_pairs(nvs, nvl);
2447 		break;
2448 
2449 	case NVS_OP_GETSIZE:
2450 		err = nvs_getsize_pairs(nvs, nvl, buflen);
2451 		break;
2452 
2453 	default:
2454 		err = EINVAL;
2455 	}
2456 
2457 	return (err);
2458 }
2459 
2460 static int
2461 nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
2462 {
2463 	switch (nvs->nvs_op) {
2464 	case NVS_OP_ENCODE: {
2465 		int err;
2466 
2467 		if (nvs->nvs_recursion >= nvpair_max_recursion)
2468 			return (EINVAL);
2469 		nvs->nvs_recursion++;
2470 		err = nvs_operation(nvs, embedded, NULL);
2471 		nvs->nvs_recursion--;
2472 		return (err);
2473 	}
2474 	case NVS_OP_DECODE: {
2475 		nvpriv_t *priv;
2476 		int err;
2477 
2478 		if (embedded->nvl_version != NV_VERSION)
2479 			return (ENOTSUP);
2480 
2481 		if ((priv = nv_priv_alloc_embedded(nvs->nvs_priv)) == NULL)
2482 			return (ENOMEM);
2483 
2484 		nvlist_init(embedded, embedded->nvl_nvflag, priv);
2485 
2486 		if (nvs->nvs_recursion >= nvpair_max_recursion) {
2487 			nvlist_free(embedded);
2488 			return (EINVAL);
2489 		}
2490 		nvs->nvs_recursion++;
2491 		if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
2492 			nvlist_free(embedded);
2493 		nvs->nvs_recursion--;
2494 		return (err);
2495 	}
2496 	default:
2497 		break;
2498 	}
2499 
2500 	return (EINVAL);
2501 }
2502 
2503 static int
2504 nvs_embedded_nvl_array(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2505 {
2506 	size_t nelem = NVP_NELEM(nvp);
2507 	nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
2508 	int i;
2509 
2510 	switch (nvs->nvs_op) {
2511 	case NVS_OP_ENCODE:
2512 		for (i = 0; i < nelem; i++)
2513 			if (nvs_embedded(nvs, nvlp[i]) != 0)
2514 				return (EFAULT);
2515 		break;
2516 
2517 	case NVS_OP_DECODE: {
2518 		size_t len = nelem * sizeof (uint64_t);
2519 		nvlist_t *embedded = (nvlist_t *)((uintptr_t)nvlp + len);
2520 
2521 		bzero(nvlp, len);	/* don't trust packed data */
2522 		for (i = 0; i < nelem; i++) {
2523 			if (nvs_embedded(nvs, embedded) != 0) {
2524 				nvpair_free(nvp);
2525 				return (EFAULT);
2526 			}
2527 
2528 			nvlp[i] = embedded++;
2529 		}
2530 		break;
2531 	}
2532 	case NVS_OP_GETSIZE: {
2533 		uint64_t nvsize = 0;
2534 
2535 		for (i = 0; i < nelem; i++) {
2536 			size_t nvp_sz = 0;
2537 
2538 			if (nvs_operation(nvs, nvlp[i], &nvp_sz) != 0)
2539 				return (EINVAL);
2540 
2541 			if ((nvsize += nvp_sz) > INT32_MAX)
2542 				return (EINVAL);
2543 		}
2544 
2545 		*size = nvsize;
2546 		break;
2547 	}
2548 	default:
2549 		return (EINVAL);
2550 	}
2551 
2552 	return (0);
2553 }
2554 
2555 static int nvs_native(nvstream_t *, nvlist_t *, char *, size_t *);
2556 static int nvs_xdr(nvstream_t *, nvlist_t *, char *, size_t *);
2557 
2558 /*
2559  * Common routine for nvlist operations:
2560  * encode, decode, getsize (encoded size).
2561  */
2562 static int
2563 nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding,
2564     int nvs_op)
2565 {
2566 	int err = 0;
2567 	nvstream_t nvs;
2568 	int nvl_endian;
2569 #if defined(_ZFS_LITTLE_ENDIAN)
2570 	int host_endian = 1;
2571 #elif defined(_ZFS_BIG_ENDIAN)
2572 	int host_endian = 0;
2573 #else
2574 #error "No endian defined!"
2575 #endif	/* _ZFS_LITTLE_ENDIAN */
2576 	nvs_header_t *nvh;
2577 
2578 	if (buflen == NULL || nvl == NULL ||
2579 	    (nvs.nvs_priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
2580 		return (EINVAL);
2581 
2582 	nvs.nvs_op = nvs_op;
2583 	nvs.nvs_recursion = 0;
2584 
2585 	/*
2586 	 * For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
2587 	 * a buffer is allocated.  The first 4 bytes in the buffer are
2588 	 * used for encoding method and host endian.
2589 	 */
2590 	switch (nvs_op) {
2591 	case NVS_OP_ENCODE:
2592 		if (buf == NULL || *buflen < sizeof (nvs_header_t))
2593 			return (EINVAL);
2594 
2595 		nvh = (void *)buf;
2596 		nvh->nvh_encoding = encoding;
2597 		nvh->nvh_endian = nvl_endian = host_endian;
2598 		nvh->nvh_reserved1 = 0;
2599 		nvh->nvh_reserved2 = 0;
2600 		break;
2601 
2602 	case NVS_OP_DECODE:
2603 		if (buf == NULL || *buflen < sizeof (nvs_header_t))
2604 			return (EINVAL);
2605 
2606 		/* get method of encoding from first byte */
2607 		nvh = (void *)buf;
2608 		encoding = nvh->nvh_encoding;
2609 		nvl_endian = nvh->nvh_endian;
2610 		break;
2611 
2612 	case NVS_OP_GETSIZE:
2613 		nvl_endian = host_endian;
2614 
2615 		/*
2616 		 * add the size for encoding
2617 		 */
2618 		*buflen = sizeof (nvs_header_t);
2619 		break;
2620 
2621 	default:
2622 		return (ENOTSUP);
2623 	}
2624 
2625 	/*
2626 	 * Create an nvstream with proper encoding method
2627 	 */
2628 	switch (encoding) {
2629 	case NV_ENCODE_NATIVE:
2630 		/*
2631 		 * check endianness, in case we are unpacking
2632 		 * from a file
2633 		 */
2634 		if (nvl_endian != host_endian)
2635 			return (ENOTSUP);
2636 		err = nvs_native(&nvs, nvl, buf, buflen);
2637 		break;
2638 	case NV_ENCODE_XDR:
2639 		err = nvs_xdr(&nvs, nvl, buf, buflen);
2640 		break;
2641 	default:
2642 		err = ENOTSUP;
2643 		break;
2644 	}
2645 
2646 	return (err);
2647 }
2648 
2649 int
2650 nvlist_size(nvlist_t *nvl, size_t *size, int encoding)
2651 {
2652 	return (nvlist_common(nvl, NULL, size, encoding, NVS_OP_GETSIZE));
2653 }
2654 
2655 /*
2656  * Pack nvlist into contiguous memory
2657  */
2658 int
2659 nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
2660     int kmflag)
2661 {
2662 	return (nvlist_xpack(nvl, bufp, buflen, encoding,
2663 	    nvlist_nv_alloc(kmflag)));
2664 }
2665 
2666 int
2667 nvlist_xpack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
2668     nv_alloc_t *nva)
2669 {
2670 	nvpriv_t nvpriv;
2671 	size_t alloc_size;
2672 	char *buf;
2673 	int err;
2674 
2675 	if (nva == NULL || nvl == NULL || bufp == NULL || buflen == NULL)
2676 		return (EINVAL);
2677 
2678 	if (*bufp != NULL)
2679 		return (nvlist_common(nvl, *bufp, buflen, encoding,
2680 		    NVS_OP_ENCODE));
2681 
2682 	/*
2683 	 * Here is a difficult situation:
2684 	 * 1. The nvlist has fixed allocator properties.
2685 	 *    All other nvlist routines (like nvlist_add_*, ...) use
2686 	 *    these properties.
2687 	 * 2. When using nvlist_pack() the user can specify their own
2688 	 *    allocator properties (e.g. by using KM_NOSLEEP).
2689 	 *
2690 	 * We use the user specified properties (2). A clearer solution
2691 	 * will be to remove the kmflag from nvlist_pack(), but we will
2692 	 * not change the interface.
2693 	 */
2694 	nv_priv_init(&nvpriv, nva, 0);
2695 
2696 	if ((err = nvlist_size(nvl, &alloc_size, encoding)))
2697 		return (err);
2698 
2699 	if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL)
2700 		return (ENOMEM);
2701 
2702 	if ((err = nvlist_common(nvl, buf, &alloc_size, encoding,
2703 	    NVS_OP_ENCODE)) != 0) {
2704 		nv_mem_free(&nvpriv, buf, alloc_size);
2705 	} else {
2706 		*buflen = alloc_size;
2707 		*bufp = buf;
2708 	}
2709 
2710 	return (err);
2711 }
2712 
2713 /*
2714  * Unpack buf into an nvlist_t
2715  */
2716 int
2717 nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag)
2718 {
2719 	return (nvlist_xunpack(buf, buflen, nvlp, nvlist_nv_alloc(kmflag)));
2720 }
2721 
2722 int
2723 nvlist_xunpack(char *buf, size_t buflen, nvlist_t **nvlp, nv_alloc_t *nva)
2724 {
2725 	nvlist_t *nvl;
2726 	int err;
2727 
2728 	if (nvlp == NULL)
2729 		return (EINVAL);
2730 
2731 	if ((err = nvlist_xalloc(&nvl, 0, nva)) != 0)
2732 		return (err);
2733 
2734 	if ((err = nvlist_common(nvl, buf, &buflen, NV_ENCODE_NATIVE,
2735 	    NVS_OP_DECODE)) != 0)
2736 		nvlist_free(nvl);
2737 	else
2738 		*nvlp = nvl;
2739 
2740 	return (err);
2741 }
2742 
2743 /*
2744  * Native encoding functions
2745  */
2746 typedef struct {
2747 	/*
2748 	 * This structure is used when decoding a packed nvpair in
2749 	 * the native format.  n_base points to a buffer containing the
2750 	 * packed nvpair.  n_end is a pointer to the end of the buffer.
2751 	 * (n_end actually points to the first byte past the end of the
2752 	 * buffer.)  n_curr is a pointer that lies between n_base and n_end.
2753 	 * It points to the current data that we are decoding.
2754 	 * The amount of data left in the buffer is equal to n_end - n_curr.
2755 	 * n_flag is used to recognize a packed embedded list.
2756 	 */
2757 	caddr_t n_base;
2758 	caddr_t n_end;
2759 	caddr_t n_curr;
2760 	uint_t  n_flag;
2761 } nvs_native_t;
2762 
2763 static int
2764 nvs_native_create(nvstream_t *nvs, nvs_native_t *native, char *buf,
2765     size_t buflen)
2766 {
2767 	switch (nvs->nvs_op) {
2768 	case NVS_OP_ENCODE:
2769 	case NVS_OP_DECODE:
2770 		nvs->nvs_private = native;
2771 		native->n_curr = native->n_base = buf;
2772 		native->n_end = buf + buflen;
2773 		native->n_flag = 0;
2774 		return (0);
2775 
2776 	case NVS_OP_GETSIZE:
2777 		nvs->nvs_private = native;
2778 		native->n_curr = native->n_base = native->n_end = NULL;
2779 		native->n_flag = 0;
2780 		return (0);
2781 	default:
2782 		return (EINVAL);
2783 	}
2784 }
2785 
2786 /*ARGSUSED*/
2787 static void
2788 nvs_native_destroy(nvstream_t *nvs)
2789 {
2790 }
2791 
2792 static int
2793 native_cp(nvstream_t *nvs, void *buf, size_t size)
2794 {
2795 	nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2796 
2797 	if (native->n_curr + size > native->n_end)
2798 		return (EFAULT);
2799 
2800 	/*
2801 	 * The bcopy() below eliminates alignment requirement
2802 	 * on the buffer (stream) and is preferred over direct access.
2803 	 */
2804 	switch (nvs->nvs_op) {
2805 	case NVS_OP_ENCODE:
2806 		bcopy(buf, native->n_curr, size);
2807 		break;
2808 	case NVS_OP_DECODE:
2809 		bcopy(native->n_curr, buf, size);
2810 		break;
2811 	default:
2812 		return (EINVAL);
2813 	}
2814 
2815 	native->n_curr += size;
2816 	return (0);
2817 }
2818 
2819 /*
2820  * operate on nvlist_t header
2821  */
2822 static int
2823 nvs_native_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
2824 {
2825 	nvs_native_t *native = nvs->nvs_private;
2826 
2827 	switch (nvs->nvs_op) {
2828 	case NVS_OP_ENCODE:
2829 	case NVS_OP_DECODE:
2830 		if (native->n_flag)
2831 			return (0);	/* packed embedded list */
2832 
2833 		native->n_flag = 1;
2834 
2835 		/* copy version and nvflag of the nvlist_t */
2836 		if (native_cp(nvs, &nvl->nvl_version, sizeof (int32_t)) != 0 ||
2837 		    native_cp(nvs, &nvl->nvl_nvflag, sizeof (int32_t)) != 0)
2838 			return (EFAULT);
2839 
2840 		return (0);
2841 
2842 	case NVS_OP_GETSIZE:
2843 		/*
2844 		 * if calculate for packed embedded list
2845 		 * 	4 for end of the embedded list
2846 		 * else
2847 		 * 	2 * sizeof (int32_t) for nvl_version and nvl_nvflag
2848 		 * 	and 4 for end of the entire list
2849 		 */
2850 		if (native->n_flag) {
2851 			*size += 4;
2852 		} else {
2853 			native->n_flag = 1;
2854 			*size += 2 * sizeof (int32_t) + 4;
2855 		}
2856 
2857 		return (0);
2858 
2859 	default:
2860 		return (EINVAL);
2861 	}
2862 }
2863 
2864 static int
2865 nvs_native_nvl_fini(nvstream_t *nvs)
2866 {
2867 	if (nvs->nvs_op == NVS_OP_ENCODE) {
2868 		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2869 		/*
2870 		 * Add 4 zero bytes at end of nvlist. They are used
2871 		 * for end detection by the decode routine.
2872 		 */
2873 		if (native->n_curr + sizeof (int) > native->n_end)
2874 			return (EFAULT);
2875 
2876 		bzero(native->n_curr, sizeof (int));
2877 		native->n_curr += sizeof (int);
2878 	}
2879 
2880 	return (0);
2881 }
2882 
2883 static int
2884 nvpair_native_embedded(nvstream_t *nvs, nvpair_t *nvp)
2885 {
2886 	if (nvs->nvs_op == NVS_OP_ENCODE) {
2887 		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2888 		nvlist_t *packed = (void *)
2889 		    (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
2890 		/*
2891 		 * Null out the pointer that is meaningless in the packed
2892 		 * structure. The address may not be aligned, so we have
2893 		 * to use bzero.
2894 		 */
2895 		bzero((char *)packed + offsetof(nvlist_t, nvl_priv),
2896 		    sizeof (uint64_t));
2897 	}
2898 
2899 	return (nvs_embedded(nvs, EMBEDDED_NVL(nvp)));
2900 }
2901 
2902 static int
2903 nvpair_native_embedded_array(nvstream_t *nvs, nvpair_t *nvp)
2904 {
2905 	if (nvs->nvs_op == NVS_OP_ENCODE) {
2906 		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2907 		char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp);
2908 		size_t len = NVP_NELEM(nvp) * sizeof (uint64_t);
2909 		nvlist_t *packed = (nvlist_t *)((uintptr_t)value + len);
2910 		int i;
2911 		/*
2912 		 * Null out pointers that are meaningless in the packed
2913 		 * structure. The addresses may not be aligned, so we have
2914 		 * to use bzero.
2915 		 */
2916 		bzero(value, len);
2917 
2918 		for (i = 0; i < NVP_NELEM(nvp); i++, packed++)
2919 			/*
2920 			 * Null out the pointer that is meaningless in the
2921 			 * packed structure. The address may not be aligned,
2922 			 * so we have to use bzero.
2923 			 */
2924 			bzero((char *)packed + offsetof(nvlist_t, nvl_priv),
2925 			    sizeof (uint64_t));
2926 	}
2927 
2928 	return (nvs_embedded_nvl_array(nvs, nvp, NULL));
2929 }
2930 
2931 static void
2932 nvpair_native_string_array(nvstream_t *nvs, nvpair_t *nvp)
2933 {
2934 	switch (nvs->nvs_op) {
2935 	case NVS_OP_ENCODE: {
2936 		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2937 		uint64_t *strp = (void *)
2938 		    (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
2939 		/*
2940 		 * Null out pointers that are meaningless in the packed
2941 		 * structure. The addresses may not be aligned, so we have
2942 		 * to use bzero.
2943 		 */
2944 		bzero(strp, NVP_NELEM(nvp) * sizeof (uint64_t));
2945 		break;
2946 	}
2947 	case NVS_OP_DECODE: {
2948 		char **strp = (void *)NVP_VALUE(nvp);
2949 		char *buf = ((char *)strp + NVP_NELEM(nvp) * sizeof (uint64_t));
2950 		int i;
2951 
2952 		for (i = 0; i < NVP_NELEM(nvp); i++) {
2953 			strp[i] = buf;
2954 			buf += strlen(buf) + 1;
2955 		}
2956 		break;
2957 	}
2958 	}
2959 }
2960 
2961 static int
2962 nvs_native_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
2963 {
2964 	data_type_t type;
2965 	int value_sz;
2966 	int ret = 0;
2967 
2968 	/*
2969 	 * We do the initial bcopy of the data before we look at
2970 	 * the nvpair type, because when we're decoding, we won't
2971 	 * have the correct values for the pair until we do the bcopy.
2972 	 */
2973 	switch (nvs->nvs_op) {
2974 	case NVS_OP_ENCODE:
2975 	case NVS_OP_DECODE:
2976 		if (native_cp(nvs, nvp, nvp->nvp_size) != 0)
2977 			return (EFAULT);
2978 		break;
2979 	default:
2980 		return (EINVAL);
2981 	}
2982 
2983 	/* verify nvp_name_sz, check the name string length */
2984 	if (i_validate_nvpair_name(nvp) != 0)
2985 		return (EFAULT);
2986 
2987 	type = NVP_TYPE(nvp);
2988 
2989 	/*
2990 	 * Verify type and nelem and get the value size.
2991 	 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
2992 	 * is the size of the string(s) excluded.
2993 	 */
2994 	if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0)
2995 		return (EFAULT);
2996 
2997 	if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size)
2998 		return (EFAULT);
2999 
3000 	switch (type) {
3001 	case DATA_TYPE_NVLIST:
3002 		ret = nvpair_native_embedded(nvs, nvp);
3003 		break;
3004 	case DATA_TYPE_NVLIST_ARRAY:
3005 		ret = nvpair_native_embedded_array(nvs, nvp);
3006 		break;
3007 	case DATA_TYPE_STRING_ARRAY:
3008 		nvpair_native_string_array(nvs, nvp);
3009 		break;
3010 	default:
3011 		break;
3012 	}
3013 
3014 	return (ret);
3015 }
3016 
3017 static int
3018 nvs_native_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3019 {
3020 	uint64_t nvp_sz = nvp->nvp_size;
3021 
3022 	switch (NVP_TYPE(nvp)) {
3023 	case DATA_TYPE_NVLIST: {
3024 		size_t nvsize = 0;
3025 
3026 		if (nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize) != 0)
3027 			return (EINVAL);
3028 
3029 		nvp_sz += nvsize;
3030 		break;
3031 	}
3032 	case DATA_TYPE_NVLIST_ARRAY: {
3033 		size_t nvsize;
3034 
3035 		if (nvs_embedded_nvl_array(nvs, nvp, &nvsize) != 0)
3036 			return (EINVAL);
3037 
3038 		nvp_sz += nvsize;
3039 		break;
3040 	}
3041 	default:
3042 		break;
3043 	}
3044 
3045 	if (nvp_sz > INT32_MAX)
3046 		return (EINVAL);
3047 
3048 	*size = nvp_sz;
3049 
3050 	return (0);
3051 }
3052 
3053 static int
3054 nvs_native_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3055 {
3056 	switch (nvs->nvs_op) {
3057 	case NVS_OP_ENCODE:
3058 		return (nvs_native_nvp_op(nvs, nvp));
3059 
3060 	case NVS_OP_DECODE: {
3061 		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
3062 		int32_t decode_len;
3063 
3064 		/* try to read the size value from the stream */
3065 		if (native->n_curr + sizeof (int32_t) > native->n_end)
3066 			return (EFAULT);
3067 		bcopy(native->n_curr, &decode_len, sizeof (int32_t));
3068 
3069 		/* sanity check the size value */
3070 		if (decode_len < 0 ||
3071 		    decode_len > native->n_end - native->n_curr)
3072 			return (EFAULT);
3073 
3074 		*size = decode_len;
3075 
3076 		/*
3077 		 * If at the end of the stream then move the cursor
3078 		 * forward, otherwise nvpair_native_op() will read
3079 		 * the entire nvpair at the same cursor position.
3080 		 */
3081 		if (*size == 0)
3082 			native->n_curr += sizeof (int32_t);
3083 		break;
3084 	}
3085 
3086 	default:
3087 		return (EINVAL);
3088 	}
3089 
3090 	return (0);
3091 }
3092 
3093 static const nvs_ops_t nvs_native_ops = {
3094 	.nvs_nvlist = nvs_native_nvlist,
3095 	.nvs_nvpair = nvs_native_nvpair,
3096 	.nvs_nvp_op = nvs_native_nvp_op,
3097 	.nvs_nvp_size = nvs_native_nvp_size,
3098 	.nvs_nvl_fini = nvs_native_nvl_fini
3099 };
3100 
3101 static int
3102 nvs_native(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
3103 {
3104 	nvs_native_t native;
3105 	int err;
3106 
3107 	nvs->nvs_ops = &nvs_native_ops;
3108 
3109 	if ((err = nvs_native_create(nvs, &native, buf + sizeof (nvs_header_t),
3110 	    *buflen - sizeof (nvs_header_t))) != 0)
3111 		return (err);
3112 
3113 	err = nvs_operation(nvs, nvl, buflen);
3114 
3115 	nvs_native_destroy(nvs);
3116 
3117 	return (err);
3118 }
3119 
3120 /*
3121  * XDR encoding functions
3122  *
3123  * An xdr packed nvlist is encoded as:
3124  *
3125  *  - encoding method and host endian (4 bytes)
3126  *  - nvl_version (4 bytes)
3127  *  - nvl_nvflag (4 bytes)
3128  *
3129  *  - encoded nvpairs, the format of one xdr encoded nvpair is:
3130  *	- encoded size of the nvpair (4 bytes)
3131  *	- decoded size of the nvpair (4 bytes)
3132  *	- name string, (4 + sizeof(NV_ALIGN4(string))
3133  *	  a string is coded as size (4 bytes) and data
3134  *	- data type (4 bytes)
3135  *	- number of elements in the nvpair (4 bytes)
3136  *	- data
3137  *
3138  *  - 2 zero's for end of the entire list (8 bytes)
3139  */
3140 static int
3141 nvs_xdr_create(nvstream_t *nvs, XDR *xdr, char *buf, size_t buflen)
3142 {
3143 	/* xdr data must be 4 byte aligned */
3144 	if ((ulong_t)buf % 4 != 0)
3145 		return (EFAULT);
3146 
3147 	switch (nvs->nvs_op) {
3148 	case NVS_OP_ENCODE:
3149 		xdrmem_create(xdr, buf, (uint_t)buflen, XDR_ENCODE);
3150 		nvs->nvs_private = xdr;
3151 		return (0);
3152 	case NVS_OP_DECODE:
3153 		xdrmem_create(xdr, buf, (uint_t)buflen, XDR_DECODE);
3154 		nvs->nvs_private = xdr;
3155 		return (0);
3156 	case NVS_OP_GETSIZE:
3157 		nvs->nvs_private = NULL;
3158 		return (0);
3159 	default:
3160 		return (EINVAL);
3161 	}
3162 }
3163 
3164 static void
3165 nvs_xdr_destroy(nvstream_t *nvs)
3166 {
3167 	switch (nvs->nvs_op) {
3168 	case NVS_OP_ENCODE:
3169 	case NVS_OP_DECODE:
3170 		xdr_destroy((XDR *)nvs->nvs_private);
3171 		break;
3172 	default:
3173 		break;
3174 	}
3175 }
3176 
3177 static int
3178 nvs_xdr_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
3179 {
3180 	switch (nvs->nvs_op) {
3181 	case NVS_OP_ENCODE:
3182 	case NVS_OP_DECODE: {
3183 		XDR 	*xdr = nvs->nvs_private;
3184 
3185 		if (!xdr_int(xdr, &nvl->nvl_version) ||
3186 		    !xdr_u_int(xdr, &nvl->nvl_nvflag))
3187 			return (EFAULT);
3188 		break;
3189 	}
3190 	case NVS_OP_GETSIZE: {
3191 		/*
3192 		 * 2 * 4 for nvl_version + nvl_nvflag
3193 		 * and 8 for end of the entire list
3194 		 */
3195 		*size += 2 * 4 + 8;
3196 		break;
3197 	}
3198 	default:
3199 		return (EINVAL);
3200 	}
3201 	return (0);
3202 }
3203 
3204 static int
3205 nvs_xdr_nvl_fini(nvstream_t *nvs)
3206 {
3207 	if (nvs->nvs_op == NVS_OP_ENCODE) {
3208 		XDR *xdr = nvs->nvs_private;
3209 		int zero = 0;
3210 
3211 		if (!xdr_int(xdr, &zero) || !xdr_int(xdr, &zero))
3212 			return (EFAULT);
3213 	}
3214 
3215 	return (0);
3216 }
3217 
3218 /*
3219  * xdrproc_t-compatible callbacks for xdr_array()
3220  */
3221 
3222 #if defined(_KERNEL) && defined(__linux__) /* Linux kernel */
3223 
3224 #define	NVS_BUILD_XDRPROC_T(type)		\
3225 static bool_t					\
3226 nvs_xdr_nvp_##type(XDR *xdrs, void *ptr)	\
3227 {						\
3228 	return (xdr_##type(xdrs, ptr));		\
3229 }
3230 
3231 #elif !defined(_KERNEL) && defined(XDR_CONTROL) /* tirpc */
3232 
3233 #define	NVS_BUILD_XDRPROC_T(type)		\
3234 static bool_t					\
3235 nvs_xdr_nvp_##type(XDR *xdrs, ...)		\
3236 {						\
3237 	va_list args;				\
3238 	void *ptr;				\
3239 						\
3240 	va_start(args, xdrs);			\
3241 	ptr = va_arg(args, void *);		\
3242 	va_end(args);				\
3243 						\
3244 	return (xdr_##type(xdrs, ptr));		\
3245 }
3246 
3247 #else /* FreeBSD, sunrpc */
3248 
3249 #define	NVS_BUILD_XDRPROC_T(type)		\
3250 static bool_t					\
3251 nvs_xdr_nvp_##type(XDR *xdrs, void *ptr, ...)	\
3252 {						\
3253 	return (xdr_##type(xdrs, ptr));		\
3254 }
3255 
3256 #endif
3257 
3258 /* BEGIN CSTYLED */
3259 NVS_BUILD_XDRPROC_T(char);
3260 NVS_BUILD_XDRPROC_T(short);
3261 NVS_BUILD_XDRPROC_T(u_short);
3262 NVS_BUILD_XDRPROC_T(int);
3263 NVS_BUILD_XDRPROC_T(u_int);
3264 NVS_BUILD_XDRPROC_T(longlong_t);
3265 NVS_BUILD_XDRPROC_T(u_longlong_t);
3266 /* END CSTYLED */
3267 
3268 /*
3269  * The format of xdr encoded nvpair is:
3270  * encode_size, decode_size, name string, data type, nelem, data
3271  */
3272 static int
3273 nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
3274 {
3275 	ASSERT(nvs != NULL && nvp != NULL);
3276 
3277 	data_type_t type;
3278 	char	*buf;
3279 	char	*buf_end = (char *)nvp + nvp->nvp_size;
3280 	int	value_sz;
3281 	uint_t	nelem, buflen;
3282 	bool_t	ret = FALSE;
3283 	XDR	*xdr = nvs->nvs_private;
3284 
3285 	ASSERT(xdr != NULL);
3286 
3287 	/* name string */
3288 	if ((buf = NVP_NAME(nvp)) >= buf_end)
3289 		return (EFAULT);
3290 	buflen = buf_end - buf;
3291 
3292 	if (!xdr_string(xdr, &buf, buflen - 1))
3293 		return (EFAULT);
3294 	nvp->nvp_name_sz = strlen(buf) + 1;
3295 
3296 	/* type and nelem */
3297 	if (!xdr_int(xdr, (int *)&nvp->nvp_type) ||
3298 	    !xdr_int(xdr, &nvp->nvp_value_elem))
3299 		return (EFAULT);
3300 
3301 	type = NVP_TYPE(nvp);
3302 	nelem = nvp->nvp_value_elem;
3303 
3304 	/*
3305 	 * Verify type and nelem and get the value size.
3306 	 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
3307 	 * is the size of the string(s) excluded.
3308 	 */
3309 	if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0)
3310 		return (EFAULT);
3311 
3312 	/* if there is no data to extract then return */
3313 	if (nelem == 0)
3314 		return (0);
3315 
3316 	/* value */
3317 	if ((buf = NVP_VALUE(nvp)) >= buf_end)
3318 		return (EFAULT);
3319 	buflen = buf_end - buf;
3320 
3321 	if (buflen < value_sz)
3322 		return (EFAULT);
3323 
3324 	switch (type) {
3325 	case DATA_TYPE_NVLIST:
3326 		if (nvs_embedded(nvs, (void *)buf) == 0)
3327 			return (0);
3328 		break;
3329 
3330 	case DATA_TYPE_NVLIST_ARRAY:
3331 		if (nvs_embedded_nvl_array(nvs, nvp, NULL) == 0)
3332 			return (0);
3333 		break;
3334 
3335 	case DATA_TYPE_BOOLEAN:
3336 		ret = TRUE;
3337 		break;
3338 
3339 	case DATA_TYPE_BYTE:
3340 	case DATA_TYPE_INT8:
3341 	case DATA_TYPE_UINT8:
3342 		ret = xdr_char(xdr, buf);
3343 		break;
3344 
3345 	case DATA_TYPE_INT16:
3346 		ret = xdr_short(xdr, (void *)buf);
3347 		break;
3348 
3349 	case DATA_TYPE_UINT16:
3350 		ret = xdr_u_short(xdr, (void *)buf);
3351 		break;
3352 
3353 	case DATA_TYPE_BOOLEAN_VALUE:
3354 	case DATA_TYPE_INT32:
3355 		ret = xdr_int(xdr, (void *)buf);
3356 		break;
3357 
3358 	case DATA_TYPE_UINT32:
3359 		ret = xdr_u_int(xdr, (void *)buf);
3360 		break;
3361 
3362 	case DATA_TYPE_INT64:
3363 		ret = xdr_longlong_t(xdr, (void *)buf);
3364 		break;
3365 
3366 	case DATA_TYPE_UINT64:
3367 		ret = xdr_u_longlong_t(xdr, (void *)buf);
3368 		break;
3369 
3370 	case DATA_TYPE_HRTIME:
3371 		/*
3372 		 * NOTE: must expose the definition of hrtime_t here
3373 		 */
3374 		ret = xdr_longlong_t(xdr, (void *)buf);
3375 		break;
3376 #if !defined(_KERNEL)
3377 	case DATA_TYPE_DOUBLE:
3378 		ret = xdr_double(xdr, (void *)buf);
3379 		break;
3380 #endif
3381 	case DATA_TYPE_STRING:
3382 		ret = xdr_string(xdr, &buf, buflen - 1);
3383 		break;
3384 
3385 	case DATA_TYPE_BYTE_ARRAY:
3386 		ret = xdr_opaque(xdr, buf, nelem);
3387 		break;
3388 
3389 	case DATA_TYPE_INT8_ARRAY:
3390 	case DATA_TYPE_UINT8_ARRAY:
3391 		ret = xdr_array(xdr, &buf, &nelem, buflen, sizeof (int8_t),
3392 		    nvs_xdr_nvp_char);
3393 		break;
3394 
3395 	case DATA_TYPE_INT16_ARRAY:
3396 		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int16_t),
3397 		    sizeof (int16_t), nvs_xdr_nvp_short);
3398 		break;
3399 
3400 	case DATA_TYPE_UINT16_ARRAY:
3401 		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint16_t),
3402 		    sizeof (uint16_t), nvs_xdr_nvp_u_short);
3403 		break;
3404 
3405 	case DATA_TYPE_BOOLEAN_ARRAY:
3406 	case DATA_TYPE_INT32_ARRAY:
3407 		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int32_t),
3408 		    sizeof (int32_t), nvs_xdr_nvp_int);
3409 		break;
3410 
3411 	case DATA_TYPE_UINT32_ARRAY:
3412 		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint32_t),
3413 		    sizeof (uint32_t), nvs_xdr_nvp_u_int);
3414 		break;
3415 
3416 	case DATA_TYPE_INT64_ARRAY:
3417 		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int64_t),
3418 		    sizeof (int64_t), nvs_xdr_nvp_longlong_t);
3419 		break;
3420 
3421 	case DATA_TYPE_UINT64_ARRAY:
3422 		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint64_t),
3423 		    sizeof (uint64_t), nvs_xdr_nvp_u_longlong_t);
3424 		break;
3425 
3426 	case DATA_TYPE_STRING_ARRAY: {
3427 		size_t len = nelem * sizeof (uint64_t);
3428 		char **strp = (void *)buf;
3429 		int i;
3430 
3431 		if (nvs->nvs_op == NVS_OP_DECODE)
3432 			bzero(buf, len);	/* don't trust packed data */
3433 
3434 		for (i = 0; i < nelem; i++) {
3435 			if (buflen <= len)
3436 				return (EFAULT);
3437 
3438 			buf += len;
3439 			buflen -= len;
3440 
3441 			if (xdr_string(xdr, &buf, buflen - 1) != TRUE)
3442 				return (EFAULT);
3443 
3444 			if (nvs->nvs_op == NVS_OP_DECODE)
3445 				strp[i] = buf;
3446 			len = strlen(buf) + 1;
3447 		}
3448 		ret = TRUE;
3449 		break;
3450 	}
3451 	default:
3452 		break;
3453 	}
3454 
3455 	return (ret == TRUE ? 0 : EFAULT);
3456 }
3457 
3458 static int
3459 nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3460 {
3461 	data_type_t type = NVP_TYPE(nvp);
3462 	/*
3463 	 * encode_size + decode_size + name string size + data type + nelem
3464 	 * where name string size = 4 + NV_ALIGN4(strlen(NVP_NAME(nvp)))
3465 	 */
3466 	uint64_t nvp_sz = 4 + 4 + 4 + NV_ALIGN4(strlen(NVP_NAME(nvp))) + 4 + 4;
3467 
3468 	switch (type) {
3469 	case DATA_TYPE_BOOLEAN:
3470 		break;
3471 
3472 	case DATA_TYPE_BOOLEAN_VALUE:
3473 	case DATA_TYPE_BYTE:
3474 	case DATA_TYPE_INT8:
3475 	case DATA_TYPE_UINT8:
3476 	case DATA_TYPE_INT16:
3477 	case DATA_TYPE_UINT16:
3478 	case DATA_TYPE_INT32:
3479 	case DATA_TYPE_UINT32:
3480 		nvp_sz += 4;	/* 4 is the minimum xdr unit */
3481 		break;
3482 
3483 	case DATA_TYPE_INT64:
3484 	case DATA_TYPE_UINT64:
3485 	case DATA_TYPE_HRTIME:
3486 #if !defined(_KERNEL)
3487 	case DATA_TYPE_DOUBLE:
3488 #endif
3489 		nvp_sz += 8;
3490 		break;
3491 
3492 	case DATA_TYPE_STRING:
3493 		nvp_sz += 4 + NV_ALIGN4(strlen((char *)NVP_VALUE(nvp)));
3494 		break;
3495 
3496 	case DATA_TYPE_BYTE_ARRAY:
3497 		nvp_sz += NV_ALIGN4(NVP_NELEM(nvp));
3498 		break;
3499 
3500 	case DATA_TYPE_BOOLEAN_ARRAY:
3501 	case DATA_TYPE_INT8_ARRAY:
3502 	case DATA_TYPE_UINT8_ARRAY:
3503 	case DATA_TYPE_INT16_ARRAY:
3504 	case DATA_TYPE_UINT16_ARRAY:
3505 	case DATA_TYPE_INT32_ARRAY:
3506 	case DATA_TYPE_UINT32_ARRAY:
3507 		nvp_sz += 4 + 4 * (uint64_t)NVP_NELEM(nvp);
3508 		break;
3509 
3510 	case DATA_TYPE_INT64_ARRAY:
3511 	case DATA_TYPE_UINT64_ARRAY:
3512 		nvp_sz += 4 + 8 * (uint64_t)NVP_NELEM(nvp);
3513 		break;
3514 
3515 	case DATA_TYPE_STRING_ARRAY: {
3516 		int i;
3517 		char **strs = (void *)NVP_VALUE(nvp);
3518 
3519 		for (i = 0; i < NVP_NELEM(nvp); i++)
3520 			nvp_sz += 4 + NV_ALIGN4(strlen(strs[i]));
3521 
3522 		break;
3523 	}
3524 
3525 	case DATA_TYPE_NVLIST:
3526 	case DATA_TYPE_NVLIST_ARRAY: {
3527 		size_t nvsize = 0;
3528 		int old_nvs_op = nvs->nvs_op;
3529 		int err;
3530 
3531 		nvs->nvs_op = NVS_OP_GETSIZE;
3532 		if (type == DATA_TYPE_NVLIST)
3533 			err = nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize);
3534 		else
3535 			err = nvs_embedded_nvl_array(nvs, nvp, &nvsize);
3536 		nvs->nvs_op = old_nvs_op;
3537 
3538 		if (err != 0)
3539 			return (EINVAL);
3540 
3541 		nvp_sz += nvsize;
3542 		break;
3543 	}
3544 
3545 	default:
3546 		return (EINVAL);
3547 	}
3548 
3549 	if (nvp_sz > INT32_MAX)
3550 		return (EINVAL);
3551 
3552 	*size = nvp_sz;
3553 
3554 	return (0);
3555 }
3556 
3557 
3558 /*
3559  * The NVS_XDR_MAX_LEN macro takes a packed xdr buffer of size x and estimates
3560  * the largest nvpair that could be encoded in the buffer.
3561  *
3562  * See comments above nvpair_xdr_op() for the format of xdr encoding.
3563  * The size of a xdr packed nvpair without any data is 5 words.
3564  *
3565  * Using the size of the data directly as an estimate would be ok
3566  * in all cases except one.  If the data type is of DATA_TYPE_STRING_ARRAY
3567  * then the actual nvpair has space for an array of pointers to index
3568  * the strings.  These pointers are not encoded into the packed xdr buffer.
3569  *
3570  * If the data is of type DATA_TYPE_STRING_ARRAY and all the strings are
3571  * of length 0, then each string is encoded in xdr format as a single word.
3572  * Therefore when expanded to an nvpair there will be 2.25 word used for
3573  * each string.  (a int64_t allocated for pointer usage, and a single char
3574  * for the null termination.)
3575  *
3576  * This is the calculation performed by the NVS_XDR_MAX_LEN macro.
3577  */
3578 #define	NVS_XDR_HDR_LEN		((size_t)(5 * 4))
3579 #define	NVS_XDR_DATA_LEN(y)	(((size_t)(y) <= NVS_XDR_HDR_LEN) ? \
3580 					0 : ((size_t)(y) - NVS_XDR_HDR_LEN))
3581 #define	NVS_XDR_MAX_LEN(x)	(NVP_SIZE_CALC(1, 0) + \
3582 					(NVS_XDR_DATA_LEN(x) * 2) + \
3583 					NV_ALIGN4((NVS_XDR_DATA_LEN(x) / 4)))
3584 
3585 static int
3586 nvs_xdr_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3587 {
3588 	XDR 	*xdr = nvs->nvs_private;
3589 	int32_t	encode_len, decode_len;
3590 
3591 	switch (nvs->nvs_op) {
3592 	case NVS_OP_ENCODE: {
3593 		size_t nvsize;
3594 
3595 		if (nvs_xdr_nvp_size(nvs, nvp, &nvsize) != 0)
3596 			return (EFAULT);
3597 
3598 		decode_len = nvp->nvp_size;
3599 		encode_len = nvsize;
3600 		if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
3601 			return (EFAULT);
3602 
3603 		return (nvs_xdr_nvp_op(nvs, nvp));
3604 	}
3605 	case NVS_OP_DECODE: {
3606 		struct xdr_bytesrec bytesrec;
3607 
3608 		/* get the encode and decode size */
3609 		if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
3610 			return (EFAULT);
3611 		*size = decode_len;
3612 
3613 		/* are we at the end of the stream? */
3614 		if (*size == 0)
3615 			return (0);
3616 
3617 		/* sanity check the size parameter */
3618 		if (!xdr_control(xdr, XDR_GET_BYTES_AVAIL, &bytesrec))
3619 			return (EFAULT);
3620 
3621 		if (*size > NVS_XDR_MAX_LEN(bytesrec.xc_num_avail))
3622 			return (EFAULT);
3623 		break;
3624 	}
3625 
3626 	default:
3627 		return (EINVAL);
3628 	}
3629 	return (0);
3630 }
3631 
3632 static const struct nvs_ops nvs_xdr_ops = {
3633 	.nvs_nvlist = nvs_xdr_nvlist,
3634 	.nvs_nvpair = nvs_xdr_nvpair,
3635 	.nvs_nvp_op = nvs_xdr_nvp_op,
3636 	.nvs_nvp_size = nvs_xdr_nvp_size,
3637 	.nvs_nvl_fini = nvs_xdr_nvl_fini
3638 };
3639 
3640 static int
3641 nvs_xdr(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
3642 {
3643 	XDR xdr;
3644 	int err;
3645 
3646 	nvs->nvs_ops = &nvs_xdr_ops;
3647 
3648 	if ((err = nvs_xdr_create(nvs, &xdr, buf + sizeof (nvs_header_t),
3649 	    *buflen - sizeof (nvs_header_t))) != 0)
3650 		return (err);
3651 
3652 	err = nvs_operation(nvs, nvl, buflen);
3653 
3654 	nvs_xdr_destroy(nvs);
3655 
3656 	return (err);
3657 }
3658 
3659 #if defined(_KERNEL)
3660 static int __init
3661 nvpair_init(void)
3662 {
3663 	return (0);
3664 }
3665 
3666 static void __exit
3667 nvpair_fini(void)
3668 {
3669 }
3670 
3671 module_init(nvpair_init);
3672 module_exit(nvpair_fini);
3673 #endif
3674 
3675 ZFS_MODULE_DESCRIPTION("Generic name/value pair implementation");
3676 ZFS_MODULE_AUTHOR(ZFS_META_AUTHOR);
3677 ZFS_MODULE_LICENSE(ZFS_META_LICENSE);
3678 ZFS_MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
3679 
3680 EXPORT_SYMBOL(nv_alloc_init);
3681 EXPORT_SYMBOL(nv_alloc_reset);
3682 EXPORT_SYMBOL(nv_alloc_fini);
3683 
3684 /* list management */
3685 EXPORT_SYMBOL(nvlist_alloc);
3686 EXPORT_SYMBOL(nvlist_free);
3687 EXPORT_SYMBOL(nvlist_size);
3688 EXPORT_SYMBOL(nvlist_pack);
3689 EXPORT_SYMBOL(nvlist_unpack);
3690 EXPORT_SYMBOL(nvlist_dup);
3691 EXPORT_SYMBOL(nvlist_merge);
3692 
3693 EXPORT_SYMBOL(nvlist_xalloc);
3694 EXPORT_SYMBOL(nvlist_xpack);
3695 EXPORT_SYMBOL(nvlist_xunpack);
3696 EXPORT_SYMBOL(nvlist_xdup);
3697 EXPORT_SYMBOL(nvlist_lookup_nv_alloc);
3698 
3699 EXPORT_SYMBOL(nvlist_add_nvpair);
3700 EXPORT_SYMBOL(nvlist_add_boolean);
3701 EXPORT_SYMBOL(nvlist_add_boolean_value);
3702 EXPORT_SYMBOL(nvlist_add_byte);
3703 EXPORT_SYMBOL(nvlist_add_int8);
3704 EXPORT_SYMBOL(nvlist_add_uint8);
3705 EXPORT_SYMBOL(nvlist_add_int16);
3706 EXPORT_SYMBOL(nvlist_add_uint16);
3707 EXPORT_SYMBOL(nvlist_add_int32);
3708 EXPORT_SYMBOL(nvlist_add_uint32);
3709 EXPORT_SYMBOL(nvlist_add_int64);
3710 EXPORT_SYMBOL(nvlist_add_uint64);
3711 EXPORT_SYMBOL(nvlist_add_string);
3712 EXPORT_SYMBOL(nvlist_add_nvlist);
3713 EXPORT_SYMBOL(nvlist_add_boolean_array);
3714 EXPORT_SYMBOL(nvlist_add_byte_array);
3715 EXPORT_SYMBOL(nvlist_add_int8_array);
3716 EXPORT_SYMBOL(nvlist_add_uint8_array);
3717 EXPORT_SYMBOL(nvlist_add_int16_array);
3718 EXPORT_SYMBOL(nvlist_add_uint16_array);
3719 EXPORT_SYMBOL(nvlist_add_int32_array);
3720 EXPORT_SYMBOL(nvlist_add_uint32_array);
3721 EXPORT_SYMBOL(nvlist_add_int64_array);
3722 EXPORT_SYMBOL(nvlist_add_uint64_array);
3723 EXPORT_SYMBOL(nvlist_add_string_array);
3724 EXPORT_SYMBOL(nvlist_add_nvlist_array);
3725 EXPORT_SYMBOL(nvlist_next_nvpair);
3726 EXPORT_SYMBOL(nvlist_prev_nvpair);
3727 EXPORT_SYMBOL(nvlist_empty);
3728 EXPORT_SYMBOL(nvlist_add_hrtime);
3729 
3730 EXPORT_SYMBOL(nvlist_remove);
3731 EXPORT_SYMBOL(nvlist_remove_nvpair);
3732 EXPORT_SYMBOL(nvlist_remove_all);
3733 
3734 EXPORT_SYMBOL(nvlist_lookup_boolean);
3735 EXPORT_SYMBOL(nvlist_lookup_boolean_value);
3736 EXPORT_SYMBOL(nvlist_lookup_byte);
3737 EXPORT_SYMBOL(nvlist_lookup_int8);
3738 EXPORT_SYMBOL(nvlist_lookup_uint8);
3739 EXPORT_SYMBOL(nvlist_lookup_int16);
3740 EXPORT_SYMBOL(nvlist_lookup_uint16);
3741 EXPORT_SYMBOL(nvlist_lookup_int32);
3742 EXPORT_SYMBOL(nvlist_lookup_uint32);
3743 EXPORT_SYMBOL(nvlist_lookup_int64);
3744 EXPORT_SYMBOL(nvlist_lookup_uint64);
3745 EXPORT_SYMBOL(nvlist_lookup_string);
3746 EXPORT_SYMBOL(nvlist_lookup_nvlist);
3747 EXPORT_SYMBOL(nvlist_lookup_boolean_array);
3748 EXPORT_SYMBOL(nvlist_lookup_byte_array);
3749 EXPORT_SYMBOL(nvlist_lookup_int8_array);
3750 EXPORT_SYMBOL(nvlist_lookup_uint8_array);
3751 EXPORT_SYMBOL(nvlist_lookup_int16_array);
3752 EXPORT_SYMBOL(nvlist_lookup_uint16_array);
3753 EXPORT_SYMBOL(nvlist_lookup_int32_array);
3754 EXPORT_SYMBOL(nvlist_lookup_uint32_array);
3755 EXPORT_SYMBOL(nvlist_lookup_int64_array);
3756 EXPORT_SYMBOL(nvlist_lookup_uint64_array);
3757 EXPORT_SYMBOL(nvlist_lookup_string_array);
3758 EXPORT_SYMBOL(nvlist_lookup_nvlist_array);
3759 EXPORT_SYMBOL(nvlist_lookup_hrtime);
3760 EXPORT_SYMBOL(nvlist_lookup_pairs);
3761 
3762 EXPORT_SYMBOL(nvlist_lookup_nvpair);
3763 EXPORT_SYMBOL(nvlist_exists);
3764 
3765 /* processing nvpair */
3766 EXPORT_SYMBOL(nvpair_name);
3767 EXPORT_SYMBOL(nvpair_type);
3768 EXPORT_SYMBOL(nvpair_value_boolean_value);
3769 EXPORT_SYMBOL(nvpair_value_byte);
3770 EXPORT_SYMBOL(nvpair_value_int8);
3771 EXPORT_SYMBOL(nvpair_value_uint8);
3772 EXPORT_SYMBOL(nvpair_value_int16);
3773 EXPORT_SYMBOL(nvpair_value_uint16);
3774 EXPORT_SYMBOL(nvpair_value_int32);
3775 EXPORT_SYMBOL(nvpair_value_uint32);
3776 EXPORT_SYMBOL(nvpair_value_int64);
3777 EXPORT_SYMBOL(nvpair_value_uint64);
3778 EXPORT_SYMBOL(nvpair_value_string);
3779 EXPORT_SYMBOL(nvpair_value_nvlist);
3780 EXPORT_SYMBOL(nvpair_value_boolean_array);
3781 EXPORT_SYMBOL(nvpair_value_byte_array);
3782 EXPORT_SYMBOL(nvpair_value_int8_array);
3783 EXPORT_SYMBOL(nvpair_value_uint8_array);
3784 EXPORT_SYMBOL(nvpair_value_int16_array);
3785 EXPORT_SYMBOL(nvpair_value_uint16_array);
3786 EXPORT_SYMBOL(nvpair_value_int32_array);
3787 EXPORT_SYMBOL(nvpair_value_uint32_array);
3788 EXPORT_SYMBOL(nvpair_value_int64_array);
3789 EXPORT_SYMBOL(nvpair_value_uint64_array);
3790 EXPORT_SYMBOL(nvpair_value_string_array);
3791 EXPORT_SYMBOL(nvpair_value_nvlist_array);
3792 EXPORT_SYMBOL(nvpair_value_hrtime);
3793