NVLIST_ALLOC(9F)        Kernel Functions for Drivers        NVLIST_ALLOC(9F)
NAME
     nvlist_alloc, 
nvlist_free, 
nvlist_size, 
nvlist_pack, 
nvlist_unpack,     
nvlist_dup, 
nv_alloc_init, 
nv_alloc_fini, 
nvlist_xalloc, 
nvlist_xpack,     
nvlist_xunpack, 
nvlist_xdup, 
nvlist_merge - Manage a name-value pair
     list
SYNOPSIS
     #include <sys/nvpair.h>   List Manipulation
     int     nvlist_alloc(
nvlist_t **nvlp, 
uint_t nvflag, 
int kmflag);     
int     nvlist_xalloc(
nvlist_t **nvlp, 
uint_t nvflag, 
nv_alloc_t *nva);     
void     nvlist_free(
nvlist_t *nvl);     
int     nvlist_size(
nvlist_t *nvl, 
size_t *size, 
int encoding);     
int     nvlist_pack(
nvlist_t *nvl, 
char **bufp, 
size_t *buflen, 
int encoding,         
int flag);     
int     nvlist_xpack(
nvlist_t *nvl, 
char **bufp, 
size_t *buflen, 
int encoding,         
nv_alloc_t *nva);     
int     nvlist_unpack(
char *buf, 
size_t buflen, 
nvlist_t **nvlp, 
int kmflag);     
int     nvlist_xunpack(
char *buf, 
size_t, 
buflen", 
nvlist_t, 
**nvlp",         
nv_alloc_t, 
*nva");     
int     nvlist_dup(
nvlist_t *nvl, 
nvlist_t **nvlp, 
int kmflag);     
int     nvlist_xdup(
nvlist_t *nvl, 
nvlist_t **nvlp, 
nv_alloc_t *nva);     
int     nvlist_merge(
nvlist_t *dst, 
nvlist_t *nvl, 
int kmflag);
   Pluggable Allocator Configuration
     nv_alloc_t *     nvlist_lookup_nv_alloc(
nvlist_t *nvl);     
int     nv_alloc_init(
nv_alloc_t *nva, 
const nv_alloc_ops_t *nvo, 
...);     
void     nv_alloc_reset(
nv_alloc_t *nva);     
void     nv_alloc_fini(
nv_alloc_t *nva);
   Pluggable Allocation Initialization with Fixed Allocator
     int     nv_alloc_init(
nv_alloc_t *nva, 
nv_fixed_ops, 
void *bufptr, 
sz);
INTERFACE LEVEL
     illumos DDI specific (illumos DDI)
PARAMETERS
     nvlp          Address of a pointer to list of name-value pairs
                   (
nvlist_t).     
nvflag        Specify bit fields defining 
nvlist_t properties:
                   NV_UNIQUE_NAME
                                 nvpair names are unique.
                   NV_UNIQUE_NAME_TYPE
                                 Name-data type combination is unique     
kmflag        Kernel memory allocation policy, either KM_SLEEP or
                   KM_NOSLEEP.     
nvl           nvlist_t to be processed.     
dst           Destination 
nvlist_t.     
size          Pointer to buffer to contain the encoded size.     
bufp          Address of buffer to pack nvlist into.  Must be 8-byte
                   aligned.  If NULL, library will allocate memory.
     buf           Buffer containing packed 
nvlist_t.
     buflen buflen
                   Size of buffer 
bufp or 
buf points to.     
encoding      Encoding method for packing.     
nvo           Pluggable allocator operations pointer (
nv_alloc_ops_t).
     nva           Points to a 
nv_alloc_t structure to be used for the
                   specified 
nvlist_t.
DESCRIPTION
   List Manipulation
     The 
nvlist_alloc() function allocates a new name-value pair list and
     updates 
nvlp to point to the handle.  The argument 
nvflag specifies     
nvlist_t properties to remain persistent across packing, unpacking, and
     duplication.
     If NV_UNIQUE_NAME is specified for nvflag, existing nvpairs with
     matching names are removed before the new nvpair is added.  If
     NV_UNIQUE_NAME_TYPE is specified for nvflag, existing nvpairs with
     matching names and data types are removed before the new nvpair is
     added.  See 
nvlist_add_byte(9F) for more details.
     The 
nvlist_xalloc() function differs from 
nvlist_alloc() in that     
nvlist_xalloc() can use a different allocator, as described in the     
Pluggable Allocators section.
     The 
nvlist_free() function frees a name-value pair list.  If 
nvl is a
     null pointer, no action occurs.
     The 
nvlist_size() function returns the minimum size of a contiguous
     buffer large enough to pack 
nvl.  The 
encoding parameter specifies the
     method of encoding when packing 
nvl Supported encoding methods are:
           NV_ENCODE_NATIVE
                         Straight 
bcopy() as described in 
bcopy(9F).
           NV_ENCODE_XDR
                         Use XDR encoding, suitable for sending to another
                         host.
     The 
nvlist_pack() function packs 
nvl into contiguous memory starting at
     *
bufp.  The 
encoding parameter specifies the method of encoding (see
     above).           
+o   If *
bufp is not NULL, *
bufp is expected to be a caller-
               allocated buffer of size *
buflen.  The 
kmflag argument is
               ignored.           
+o   If *
bufp is NULL, the library allocates memory and updates
               *
bufp to point to the memory and updates *
buflen to contain
               the size of the allocated memory.  The value of 
kmflag               indicates the memory allocation policy
     The 
nvlist_xpack() function differs from 
nvlist_pack() in that     
nvlist_xpack() can use a different allocator.
     The 
nvlist_unpack() function takes a buffer with a packed 
nvlist_t and
     unpacks it into a searchable 
nvlist_t.  The library allocates memory
     for 
nvlist_t.  The caller is responsible for freeing the memory by
     calling 
nvlist_free()
     The 
nvlist_xunpack() function differs from 
nvlist_unpack() in that     
nvlist_xunpack() can use a different allocator.
     The 
nvlist_dup() function makes a copy of 
nvl and updates 
nvlp to point
     to the copy.
     The 
nvlist_xdup() function differs from 
nvlist_dup() in that     
nvlist_xdup() can use a different allocator.
     The 
nvlist_merge() function adds copies of all name-value pairs from     
nvlist_t nvl to 
nvlist_t dst.  Name-value pairs in 
dst are replaced
     with name-value pairs from 
nvl which have identical names (if 
dst has
     the type NV_UNIQUE_NAME) or identical names and types (if 
dst has the
     type NV_UNIQUE_NAME_TYPE).
     The 
nvlist_lookup_nv_alloc() function retrieves the pointer to the
     allocator used when manipulating a name-value pair list.
   Pluggable Allocators
     The 
nv_alloc_init(), 
nv_alloc_reset(), and 
nv_alloc_fini() functions
     provide an interface that specifies the allocator to be used when
     manipulating a name-value pair list.
     The 
nv_alloc_init() determines allocator properties and puts them into
     the 
nva argument.  You need to specify the 
nv_arg argument, the 
nvo     argument and an optional variable argument list.  The optional
     arguments are passed to the *
nv_ao_init() function.
     The 
nva argument must be passed to 
nvlist_xalloc(), 
nvlist_xpack(),     
nvlist_xunpack(), and 
nvlist_xdup().
     The 
nv_alloc_reset() function resets the allocator properties to the
     data specified by 
nv_alloc_init().  When no *
nv_ao_reset() function is
     specified, 
nv_alloc_reset() is without effect.
     The 
nv_alloc_fini() destroys the allocator properties determined by     
nv_alloc_init().  When a *
nv_ao_fini() routine is specified, it is
     called from 
nv_alloc_fini().
     The disposition of the allocated objects and the memory used to store
     them is left to the allocator implementation.
     The 
nv_alloc_sleep and 
nv_alloc_nosleep nv_alloc_t pointers may be used
     with 
nvlist_xalloc() to mimic the behavior of 
nvlist_alloc() with
     KM_SLEEP and KM_NOSLEEP, respectively.
     The nvpair framework provides a fixed-buffer allocator, accessible via
     Given a buffer size and address, the fixed-buffer allocator allows for
     the creation of nvlists in contexts where 
malloc(3C) or 
kmem_alloc(9F)     services may not be available.  The fixed-buffer allocator is designed
     primarily to support the creation of nvlists.
     Memory freed using 
nvlist_free(), pair-removal, or similar routines is
     not reclaimed.
     When used to initialize the fixed-buffer allocator, 
nv_alloc_init()
     should be called as follows:     
nv_alloc_init(
nv_alloc_t *nva, 
nv_fixed_ops, 
void *bufptr, 
size_t sz).
     When invoked on a fixed-buffer, the 
nv_alloc_reset() function resets
     the fixed buffer and prepares it for re-use.  The framework consumer is
     responsible for freeing the buffer passed to 
nv_alloc_init().
   Creating Pluggable Allocators
     Any producer of name-value pairs may possibly specify his own allocator
     routines.  You must provide the following pluggable allocator
     operations in the allocator implementation.
           int (*nv_ao_init)(nv_alloc_t *nva, va_list nv_valist);
           void (*nv_ao_fini)(nv_alloc_t *nva);
           void *(*nv_ao_alloc)(nv_alloc_t *nva, size_t sz);
           void (*nv_ao_reset)(nv_alloc_t *nva);
           void (*nv_ao_free)(nv_alloc_t *nva, void *buf, size_t sz);
     The 
nva argument of the allocator implementation is always the first
     argument.
     The optional *
nv_ao_init() function is responsible for filling the data
     specified by 
nv_alloc_init() into the 
nva_arg member.
      The *
nv_ao_init() function is called only when 
nv_alloc_init() is
     executed.
     The optional *
nv_ao_fini() function is responsible for the cleanup of
     the allocator implementation.  It is called by 
nv_alloc_fini().
     The required *
nv_ao_alloc() function is used in the nvpair allocation
     framework for memory allocation.  The 
sz argument specifies the size of
     the requested buffer.
     The optional *
nv_ao_reset() function is responsible for resetting the     
nva_arg member to the data specified by 
nv_alloc_init().
     The required *
nv_ao_free() function is used in the nvpair allocator
     framework for memory de-allocation.  The argument 
buf is a pointer to a
     block previously allocated by *
nv_ao_alloc() function.  The size
     argument 
sz must exactly match the original allocation.
     The disposition of the allocated objects and the memory used to store
     them is left to the allocator implementation.
CONTEXT
     The 
nvlist_alloc(), 
nvlist_pack(), 
nvlist_unpack(), and 
nvlist_dup()
     functions can be called from interrupt context only if the KM_NOSLEEP
     flag is set.  They can be called from user context with any valid flag.
     The 
nvlist_xalloc(), 
nvlist_xpack(), 
nvlist_xunpack(), and     
nvlist_xdup() functions can be called from interrupt context only if
     (1) the default allocator is used and the KM_NOSLEEP flag is set or (2)
     the specified allocator did not sleep for free memory (for example, it
     uses a pre-allocated buffer for memory allocations).
     These functions can be called from user or kernel context with any
     valid flag.
RETURN VALUES
     For 
nvlist_alloc(), 
nvlist_dup(), 
nvlist_xalloc(), and 
nvlist_xdup():
     0                  success
     EINVAL             invalid argument
     ENOMEM             insufficient memory
     For 
nvlist_pack(), 
nvlist_unpack(), 
nvlist_xpack(), and     
nvlist_xunpack():     
0                  success
     EINVAL             invalid argument
     ENOMEM             insufficient memory
     EFAULT             encode/decode error
     ENOTSUP            encode/decode method not supported
     For 
nvlist_size():     
0                  success
     EINVAL
     The 
nvlist_lookup_nv_alloc() function returns a pointer to the
     allocator or NULL if there is no allocator.
USAGE
     The fixed-buffer allocator is very simple allocator.  It uses a pre-
     allocated buffer for memory allocations and it can be used in interrupt
     context.  You are responsible for allocation and de-allocation for the
     pre-allocated buffer.
EXAMPLES
     Example 1 Using the fixed-buffer allocator
           #include <sys/nvpair.h>
           /* initialize the nvpair allocator framework */
           static nv_alloc_t *
           init(char *buf, size_t size)
           {
                   nv_alloc_t *nvap;
                   if ((nvap = kmem_alloc(sizeof(nv_alloc_t), KM_SLEEP)) == NULL)
                      return (NULL);
                   if (nv_alloc_init(nvap, nv_fixed_ops, buf, size) == 0)
                      return (nvap);
                   return (NULL);
           }
           static void
           fini(nv_alloc_t *nvap)
           {
                   nv_alloc_fini(nvap);
                   kmem_free(nvap, sizeof(nv_alloc_t));
           }
           static int
           interrupt_context(nv_alloc_t *nva)
           {
                   nvlist_t *nvl;
                   int error;
                   if ((error = nvlist_xalloc(&nvl, NV_UNIQUE_NAME, nva)) != 0)
                       return (-1);
                   if ((error = nvlist_add_int32(nvl, "name", 1234)) == 0)
                       error = send_nvl(nvl);
                   nvlist_free(nvl);
                   return (error);
           }
SEE ALSO
     bcopy(9F), 
kmem_alloc(9F), 
nvlist_add_byte(9F)illumos                         June 12, 2021                        illumos