xref: /illumos-gate/usr/src/man/man9f/nvlist_alloc.9f (revision b9cf0daf)
1.\"
2.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved.
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 or
9.\" http://www.opensolaris.org/os/licensing.
10.\" See the License for the specific language governing permissions
11.\" and limitations under the License.
12.\"
13.\" When distributing Covered Code, include this CDDL HEADER in each
14.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15.\" If applicable, add the following below this CDDL HEADER, with the
16.\" fields enclosed by brackets "[]" replaced with your own identifying
17.\" information: Portions Copyright [yyyy] [name of copyright owner]
18.\"
19.\" Copyright 2021 Oxide Computer Company
20.Dd June 12, 2021
21.Dt NVLIST_ALLOC 9F
22.Os
23.Sh NAME
24.Nm nvlist_alloc ,
25.Nm nvlist_free ,
26.Nm nvlist_size ,
27.Nm nvlist_pack ,
28.Nm nvlist_unpack ,
29.Nm nvlist_dup ,
30.Nm nv_alloc_init ,
31.Nm nv_alloc_fini ,
32.Nm nvlist_xalloc ,
33.Nm nvlist_xpack ,
34.Nm nvlist_xunpack ,
35.Nm nvlist_xdup ,
36.Nm nvlist_merge
37.Nd Manage a name-value pair list
38.Sh SYNOPSIS
39.In sys/nvpair.h
40.Ss List Manipulation
41.Ft int
42.Fo nvlist_alloc
43.Fa "nvlist_t **nvlp"
44.Fa "uint_t nvflag"
45.Fa "int kmflag"
46.Fc
47.Ft int
48.Fo nvlist_xalloc
49.Fa "nvlist_t **nvlp"
50.Fa "uint_t nvflag"
51.Fa "nv_alloc_t *nva"
52.Fc
53.Ft void
54.Fo nvlist_free
55.Fa "nvlist_t *nvl"
56.Fc
57.Ft int
58.Fo nvlist_size
59.Fa "nvlist_t *nvl"
60.Fa "size_t *size"
61.Fa "int encoding"
62.Fc
63.Ft int
64.Fo nvlist_pack
65.Fa "nvlist_t *nvl"
66.Fa "char **bufp"
67.Fa "size_t *buflen"
68.Fa "int encoding"
69.Fa "int flag"
70.Fc
71.Ft int
72.Fo nvlist_xpack
73.Fa "nvlist_t *nvl"
74.Fa "char **bufp"
75.Fa "size_t *buflen"
76.Fa "int encoding"
77.Fa "nv_alloc_t *nva"
78.Fc
79.Ft int
80.Fo nvlist_unpack
81.Fa "char *buf"
82.Fa "size_t buflen"
83.Fa "nvlist_t **nvlp"
84.Fa "int kmflag"
85.Fc
86.Ft int
87.Fo nvlist_xunpack
88.Fa "char *buf"
89.Fa size_t buflen"
90.Fa nvlist_t **nvlp"
91.Fa nv_alloc_t *nva"
92.Fc
93.Ft int
94.Fo nvlist_dup
95.Fa "nvlist_t *nvl"
96.Fa "nvlist_t **nvlp"
97.Fa "int kmflag"
98.Fc
99.Ft int
100.Fo nvlist_xdup
101.Fa "nvlist_t *nvl"
102.Fa "nvlist_t **nvlp"
103.Fa "nv_alloc_t *nva"
104.Fc
105.Ft int
106.Fo nvlist_merge
107.Fa "nvlist_t *dst"
108.Fa "nvlist_t *nvl"
109.Fa "int kmflag"
110.Fc
111.Ss Pluggable Allocator Configuration
112.Ft "nv_alloc_t *"
113.Fo nvlist_lookup_nv_alloc
114.Fa "nvlist_t *nvl"
115.Fc
116.Ft int
117.Fo nv_alloc_init
118.Fa "nv_alloc_t *nva"
119.Fa "const nv_alloc_ops_t *nvo"
120.Fa "..."
121.Fc
122.Ft void
123.Fo nv_alloc_reset
124.Fa "nv_alloc_t *nva"
125.Fc
126.Ft void
127.Fo nv_alloc_fini
128.Fa "nv_alloc_t *nva"
129.Fc
130.Ss Pluggable Allocation Initialization with Fixed Allocator
131.Ft int
132.Fo nv_alloc_init
133.Fa "nv_alloc_t *nva"
134.Fa "nv_fixed_ops"
135.Fa "void *bufptr"
136.Fa "sz"
137.Fc
138.Sh INTERFACE LEVEL
139illumos DDI specific (illumos DDI)
140.Sh PARAMETERS
141.Bl -tag -width Fa
142.It Fa nvlp
143Address of a pointer to list of name-value pairs
144.Pq Ft nvlist_t .
145.It Fa nvflag
146Specify bit fields defining
147.Ft nvlist_t
148properties:
149.Bl -tag -width Dv
150.It Dv NV_UNIQUE_NAME
151nvpair names are unique.
152.It Dv NV_UNIQUE_NAME_TYPE
153Name-data type combination is unique
154.El
155.It Fa kmflag
156Kernel memory allocation policy, either
157.Dv KM_SLEEP
158or
159.Dv KM_NOSLEEP .
160.It Fa nvl
161.Ft nvlist_t
162to be processed.
163.It Fa dst
164Destination
165.Ft nvlist_t .
166.It Fa size
167Pointer to buffer to contain the encoded size.
168.It Fa bufp
169Address of buffer to pack nvlist into.
170Must be 8-byte aligned.
171If
172.Dv NULL ,
173library will allocate memory.
174.It buf
175Buffer containing packed
176.Ft nvlist_t .
177.It buflen buflen
178Size of buffer
179.Fa bufp
180or
181.Fa buf
182points to.
183.It Fa encoding
184Encoding method for packing.
185.It Fa nvo
186Pluggable allocator operations pointer
187.Pq Ft nv_alloc_ops_t .
188.It nva
189Points to a
190.Ft nv_alloc_t
191structure to be used for the specified
192.Ft nvlist_t .
193.El
194.Sh DESCRIPTION
195.Ss List Manipulation
196The
197.Fn nvlist_alloc
198function allocates a new name-value pair list and updates
199.Fa nvlp
200to point to the handle.
201The argument
202.Fa nvflag
203specifies
204.Ft nvlist_t
205properties to remain persistent across packing, unpacking, and duplication.
206.Pp
207If
208.Dv NV_UNIQUE_NAME
209is specified for nvflag, existing nvpairs with matching names are removed
210before the new nvpair is added.
211If
212.Dv NV_UNIQUE_NAME_TYPE
213is specified for nvflag, existing nvpairs with matching names and data types
214are removed before the new nvpair is added.
215See
216.Xr nvlist_add_byte 9F
217for more details.
218.Pp
219The
220.Fn nvlist_xalloc
221function differs from
222.Fn nvlist_alloc
223in that
224.Fn nvlist_xalloc
225can use a different allocator, as described in the
226.Sx Pluggable Allocators
227section.
228.Pp
229The
230.Fn nvlist_free
231function frees a name-value pair list.
232If
233.Fa nvl
234is a null pointer, no action occurs.
235.Pp
236The
237.Fn nvlist_size
238function returns the minimum size of a contiguous buffer large enough to pack
239.Fa nvl .
240The
241.Fa encoding
242parameter specifies the method of encoding when packing
243.Fa nvl
244Supported encoding methods are:
245.Bl -tag -width Dv -offset indent
246.It Dv NV_ENCODE_NATIVE
247Straight
248.Fn bcopy
249as described in
250.Xr bcopy 9F .
251.It Dv NV_ENCODE_XDR
252Use XDR encoding, suitable for sending to another host.
253.El
254.Pp
255The
256.Fn nvlist_pack
257function packs
258.Fa nvl
259into contiguous memory starting at
260.Pf * Fa bufp .
261The
262.Fa encoding
263parameter specifies the method of encoding (see above).
264.Bl -bullet -offset indent
265.It
266If
267.Pf * Fa bufp
268is not
269.Dv NULL ,
270.Pf * Fa bufp
271is expected to be a caller-allocated buffer of size
272.Pf * Fa buflen .
273The
274.Fa kmflag
275argument is ignored.
276.It
277If
278.Pf * Fa bufp
279is
280.Dv NULL ,
281the library allocates memory and updates
282.Pf * Fa bufp
283to point to the memory and updates
284.Pf * Fa buflen
285to contain the size of the allocated memory.
286The value of
287.Fa kmflag
288indicates the memory allocation policy
289.El
290.Pp
291The
292.Fn nvlist_xpack
293function differs from
294.Fn nvlist_pack
295in that
296.Fn nvlist_xpack
297can use a different allocator.
298.Pp
299The
300.Fn nvlist_unpack
301function takes a buffer with a packed
302.Ft nvlist_t
303and unpacks it into a searchable
304.Ft nvlist_t .
305The library allocates memory for
306.Ft nvlist_t .
307The caller is responsible for freeing the memory by calling
308.Fn nvlist_free
309.Pp
310The
311.Fn nvlist_xunpack
312function differs from
313.Fn nvlist_unpack
314in that
315.Fn nvlist_xunpack
316can use a different allocator.
317.Pp
318The
319.Fn nvlist_dup
320function makes a copy of
321.Fa nvl
322and updates
323.Fa nvlp
324to point to the copy.
325.Pp
326The
327.Fn nvlist_xdup
328function differs from
329.Fn nvlist_dup
330in that
331.Fn nvlist_xdup
332can use a different allocator.
333.Pp
334The
335.Fn nvlist_merge
336function adds copies of all name-value pairs from
337.Fa "nvlist_t nvl"
338to
339.Fa "nvlist_t dst" .
340Name-value pairs in
341.Fa dst
342are replaced with name-value pairs from
343.Fa nvl
344which have identical names
345.Po
346if
347.Fa dst
348has the type
349.Dv NV_UNIQUE_NAME
350.Pc
351or identical names and types
352.Po
353if
354.Fa dst
355has the type
356.Dv NV_UNIQUE_NAME_TYPE
357.Pc .
358.Pp
359The
360.Fn nvlist_lookup_nv_alloc
361function retrieves the pointer to the allocator used when manipulating a
362name-value pair list.
363.Ss "Pluggable Allocators"
364The
365.Fn nv_alloc_init ,
366.Fn nv_alloc_reset ,
367and
368.Fn nv_alloc_fini
369functions provide an interface that specifies the allocator to be used when
370manipulating a name-value pair list.
371.Pp
372The
373.Fn nv_alloc_init
374determines allocator properties and puts them into
375the
376.Fa nva
377argument.
378You need to specify the
379.Fa nv_arg
380argument, the
381.Fa nvo
382argument and an optional variable argument list.
383The optional arguments are passed to the
384.Pf * Fn nv_ao_init
385function.
386.Pp
387The
388.Fa nva
389argument must be passed to
390.Fn nvlist_xalloc ,
391.Fn nvlist_xpack ,
392.Fn nvlist_xunpack ,
393and
394.Fn nvlist_xdup .
395.Pp
396The
397.Fn nv_alloc_reset
398function resets the allocator properties to the data specified by
399.Fn nv_alloc_init .
400When no
401.Pf * Fn nv_ao_reset
402function is specified,
403.Fn nv_alloc_reset
404is without effect.
405.Pp
406The
407.Fn nv_alloc_fini
408destroys the allocator properties determined by
409.Fn nv_alloc_init .
410When a
411.Pf * Fn nv_ao_fini
412routine is specified, it is
413called from
414.Fn nv_alloc_fini .
415.Pp
416The disposition of the allocated objects and the memory used to store them is
417left to the allocator implementation.
418.Pp
419The
420.Va nv_alloc_sleep
421and
422.Va nv_alloc_nosleep
423.Ft nv_alloc_t
424pointers may be used with
425.Fn nvlist_xalloc
426to mimic the behavior of
427.Fn nvlist_alloc
428with
429.Dv KM_SLEEP and
430.Dv KM_NOSLEEP ,
431respectively.
432.Pp
433The nvpair framework provides a fixed-buffer allocator, accessible via
434.Pp
435Given a buffer size and address, the fixed-buffer allocator allows for the
436creation of nvlists in contexts where
437.Xr malloc 3C
438or
439.Xr kmem_alloc 9F
440services may not be available.
441The fixed-buffer allocator is designed primarily to support the creation of
442nvlists.
443.Pp
444Memory freed using
445.Fn nvlist_free ,
446pair-removal, or similar routines is not reclaimed.
447.Pp
448When used to initialize the fixed-buffer allocator,
449.Fn nv_alloc_init
450should be called as follows:
451.Pp
452.Fo nv_alloc_init
453.Fa "nv_alloc_t *nva"
454.Fa "nv_fixed_ops"
455.Fa "void *bufptr"
456.Fa "size_t sz"
457.Fc .
458.Pp
459When invoked on a fixed-buffer, the
460\fBnv_alloc_reset()\fR
461function resets the fixed buffer and prepares it for re-use.
462The framework consumer is responsible for freeing the buffer passed to
463\fBnv_alloc_init()\fR.
464.Ss Creating Pluggable Allocators
465Any producer of name-value pairs may possibly specify his own allocator
466routines.
467You must provide the following pluggable allocator operations in the allocator
468implementation.
469.Bd -literal -offset indent
470int (*nv_ao_init)(nv_alloc_t *nva, va_list nv_valist);
471void (*nv_ao_fini)(nv_alloc_t *nva);
472void *(*nv_ao_alloc)(nv_alloc_t *nva, size_t sz);
473void (*nv_ao_reset)(nv_alloc_t *nva);
474void (*nv_ao_free)(nv_alloc_t *nva, void *buf, size_t sz);
475.Ed
476.Pp
477The
478.Fa nva
479argument of the allocator implementation is always the first argument.
480.Pp
481The optional
482.Pf * Fn nv_ao_init
483function is responsible for filling the data specified by
484.Fn nv_alloc_init
485into the
486.Fa nva_arg
487member.
488 The
489.Pf * Fn nv_ao_init
490function is called only when
491.Fn nv_alloc_init
492is executed.
493.Pp
494The optional
495.Pf * Fn nv_ao_fini
496function is responsible for the cleanup of the allocator implementation.
497It is called by
498.Fn nv_alloc_fini .
499.Pp
500The required
501.Pf * Fn nv_ao_alloc
502function is used in the nvpair allocation framework for memory allocation.
503The
504.Fa sz
505argument specifies the size of the requested buffer.
506.Pp
507The optional
508.Pf * Fn nv_ao_reset
509function is responsible for resetting the
510.Fa nva_arg
511member to the data specified by
512.Fn nv_alloc_init .
513.Pp
514The required
515.Pf * Fn nv_ao_free
516function is used in the nvpair allocator framework for memory de-allocation.
517The argument
518.Fa buf
519is a pointer to a block
520previously allocated by
521.Pf * Fn nv_ao_alloc
522function.
523The size argument
524.Fa sz
525must exactly match the original allocation.
526.Pp
527The disposition of the allocated objects and the memory used to store them is
528left to the allocator implementation.
529.Sh CONTEXT
530The
531.Fn nvlist_alloc ,
532.Fn nvlist_pack ,
533.Fn nvlist_unpack ,
534and
535.Fn nvlist_dup
536functions can be called from interrupt context only if the
537.Dv KM_NOSLEEP
538flag is set.
539They can be called from user context with any valid flag.
540.Pp
541The
542.Fn nvlist_xalloc ,
543.Fn nvlist_xpack ,
544.Fn nvlist_xunpack ,
545and
546.Fn nvlist_xdup
547functions can be called from interrupt context only if
548.Pq 1
549the default allocator is used and the
550.Dv KM_NOSLEEP
551flag is set or
552.Pq 2
553the specified allocator did not sleep for free memory
554.Pq for example, it uses a pre-allocated buffer for memory allocations .
555.Pp
556These functions can be called from user or kernel context with any valid flag.
557.Sh RETURN VALUES
558For
559.Fn nvlist_alloc ,
560.Fn nvlist_dup ,
561.Fn nvlist_xalloc ,
562and
563.Fn nvlist_xdup :
564.Bl -tag -width Er
565.It Er 0
566success
567.It Er EINVAL
568invalid argument
569.It Er ENOMEM
570insufficient memory
571.El
572.Pp
573For
574.Fn nvlist_pack ,
575.Fn nvlist_unpack ,
576.Fn nvlist_xpack ,
577and
578.Fn nvlist_xunpack :
579.Bl -tag -width Er
580.It Sy 0
581success
582.It Er EINVAL
583invalid argument
584.It Er ENOMEM
585insufficient memory
586.It Er EFAULT
587encode/decode error
588.It Er ENOTSUP
589encode/decode method not supported
590.El
591.Pp
592For
593.Fn nvlist_size :
594.Bl -tag -width Er
595.It Sy 0
596success
597.It Er EINVAL
598.El
599.Pp
600The
601.Fn nvlist_lookup_nv_alloc
602function returns a pointer to the allocator or
603.Dv NULL
604if there is no allocator.
605.Sh USAGE
606The fixed-buffer allocator is very simple allocator.
607It uses a pre-allocated buffer for memory allocations and it can be used in
608interrupt context.
609You are responsible for allocation and de-allocation for the pre-allocated
610buffer.
611.Sh EXAMPLES
612.Sy Example 1
613Using the fixed-buffer allocator
614.Bd -literal -offset indent
615#include <sys/nvpair.h>
616
617/* initialize the nvpair allocator framework */
618static nv_alloc_t *
619init(char *buf, size_t size)
620{
621	nv_alloc_t *nvap;
622
623	if ((nvap = kmem_alloc(sizeof(nv_alloc_t), KM_SLEEP)) == NULL)
624	   return (NULL);
625
626	if (nv_alloc_init(nvap, nv_fixed_ops, buf, size) == 0)
627	   return (nvap);
628
629	return (NULL);
630}
631
632static void
633fini(nv_alloc_t *nvap)
634{
635	nv_alloc_fini(nvap);
636	kmem_free(nvap, sizeof(nv_alloc_t));
637}
638
639static int
640interrupt_context(nv_alloc_t *nva)
641{
642	nvlist_t *nvl;
643	int error;
644
645	if ((error = nvlist_xalloc(&nvl, NV_UNIQUE_NAME, nva)) != 0)
646	    return (-1);
647
648	if ((error = nvlist_add_int32(nvl, "name", 1234)) == 0)
649	    error = send_nvl(nvl);
650
651	nvlist_free(nvl);
652	return (error);
653}
654.Ed
655.Sh SEE ALSO
656.Xr bcopy 9F ,
657.Xr kmem_alloc 9F ,
658.Xr nvlist_add_byte 9F
659