The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/nvpair/nvpair.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 59231be69ae1601f9c23c6ca63d691c3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.