A brief overview of the Solaris 10 nvpair library
Solaris 10 code often uses a data structure called nvpairs (or nvlists), including all throughout the ZFS code, even in the kernel. There doesn't seem to be a good overview of the libnvpair library, and since I've just spent the past couple of weeks up to my elbows in the OpenSolaris ZFS codebase it seems like a good time to write down what I've learned about nvlists and nvpairs before I forget it.
The basic overview is that an nvlist is a list, possibly nested, of names (keys) and values, aka nvpairs. An nvpair has a name (a C string, although Solaris code always uses #defines for them and so hides this in header files), a value, and the type of the value. There are a lot of possible nvpair value types, but two important ones are nvlists and nvlist arrays. A nvlist value is just another nested nvlist; an nvlist array is, well, an array of them. As an example, in ZFS pool configurations a vdev is an nvlist and the list of devices in it is an nvlist array.
(In common practice there can't be duplicate keys in a given nvlist. While you can create nvlists where this is not the case, this causes a lot of the convenient 'get the element with name X' retrieval functions to stop working.)
The Solaris code I've seen has pretty much used nvlists as if they were some peculiar and awkward hybrid of C structs and Python dictionaries. (For example, the ZFS kernel code keeps a bunch of things in nvlists instead of unpacking them into structs.)
That the keys are strings and nvpairs carry type information makes an nvlist self-describing; if you want, you can print out an arbitrary nvlist without knowing anything about its structure beforehand (including descending into its children). However, nvlists are not self-identifying in the way that, say, XML files usually are, in that there is no particular label that will tell you what a random nvlist is for or represents.
Nvlists can be serialized to disk and then loaded back again. As you might guess from everything so far, a ZFS pool's configuration is stored as an nvlist that is then embedded in the pool. For that matter, ZFS device labels are also nvlists.
(It is probably not quite true that everything that moves in Solaris 10 is an nvlist, but it sometimes feels like it.)