| NVLIST_ALLOC(9F) | Kernel Functions for Drivers | NVLIST_ALLOC(9F) | 
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
#include
    <sys/nvpair.h>
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);
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);
int
  
  nv_alloc_init(nv_alloc_t *nva,
    nv_fixed_ops, void *bufptr,
    sz);
illumos DDI specific (illumos DDI)
NV_UNIQUE_NAMENV_UNIQUE_NAME_TYPEKM_SLEEP
      or KM_NOSLEEP.NULL, library will allocate memory.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_NATIVEbcopy()
      as described in bcopy(9F).NV_ENCODE_XDRThe
    nvlist_pack()
    function packs nvl into contiguous memory starting at
    *bufp. The encoding parameter
    specifies the method of encoding (see above).
NULL,
      *bufp is expected to be a caller-allocated buffer of
      size *buflen. The kmflag
      argument is ignored.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 policyThe
    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.
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().
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.
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.
For nvlist_alloc(),
    nvlist_dup(),
    nvlist_xalloc(), and
    nvlist_xdup():
0EINVALENOMEMFor nvlist_pack(),
    nvlist_unpack(),
    nvlist_xpack(), and
    nvlist_xunpack():
EINVALENOMEMEFAULTENOTSUPFor nvlist_size():
EINVALThe nvlist_lookup_nv_alloc() function
    returns a pointer to the allocator or NULL if there
    is no allocator.
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.
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);
}
| June 12, 2021 | OmniOS |