事件特性定义为名称-值对列表。Solaris DDI 提供了用于在名称-值对中存储信息的例程和结构。名称-值对保留在 nvlist_t 结构中,此结构对于驱动程序是不透明的。名称-值对的值可以是布尔值、int、字节、字符串、nvlist 或这些数据类型的数组。int 可以定义为 16 位、32 位或 64 位,可以带符号,也可不带符号。
下面是创建名称-值对列表的步骤。
使用 nvlist_alloc(9F) 创建 nvlist_t 结构。
nvlist_alloc() 接口会采用以下三个参数:
nvlp-指向 nvlist_t 结构指针的指针
nvflag-指示名称-值对的名称唯一性的标志。如果此标志设置为 NV_UNIQUE_NAME_TYPE,则会从列表中删除与新对的名称和类型相匹配的任何现有对。如果标志设置为 NV_UNIQUE_NAME,则会删除任何同名的现有对,而不考虑对的类型。只要对的类型不同,通过指定 NV_UNIQUE_NAME_TYPE,列表即可包含两个或多个同名的对,但如果指定 NV_UNIQUE_NAME,则列表中只能有一个对名称实例。如果未设置标志,则不会执行任何唯一性检查,将由列表的使用方负责处理同名的对。
kmflag-指示内核内存分配策略的标志。如果此参数设置为 KM_SLEEP,则驱动程序会阻塞,直到请求的内存可进行分配为止。KM_SLEEP 分配可能会休眠,但是保证会成功。KM_NOSLEEP 分配保证不会休眠,但是可能会在当前无可用内存时返回 NULL。
使用名称-值对填充 nvlist。例如,要添加字符串,请使用 nvlist_add_string(9F)。要添加 32 位整数数组,请使用 nvlist_add_int32_array(9F)。nvlist_add_boolean(9F) 手册页包含用于添加对的可用接口的完整列表。
要取消分配列表,请使用 nvlist_free(9F)。
以下代码样例说明如何创建名称-值对列表。
nvlist_t* create_nvlist() { int err; char *str = "child"; int32_t ints[] = {0, 1, 2}; nvlist_t *nvl; err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); /* allocate list */ if (err) return (NULL); if ((nvlist_add_string(nvl, "name", str) != 0) || (nvlist_add_int32_array(nvl, "prop", ints, 3) != 0)) { nvlist_free(nvl); return (NULL); } return (nvl); }
驱动程序可通过相应类型的查找函数(如 nvlist_lookup_int32_array(9F))来检索 nvlist 中的元素,此类查找函数将要搜索的名称-值对的名称作为参数。
仅当在调用 nvlist_alloc(9F) 时指定了 NV_UNIQUE_NAME 或 NV_UNIQUE_NAME_TYPE 的情况下,这些接口才会正常工作。否则,将返回 ENOTSUP,因为此列表不能包含多个同名的对。
可以将名称-值列表中的各对放在连续内存中。此方法有助于将列表传递给已订阅了通知的实体。第一步是使用 nvlist_size(9F) 获取列表所需的内存块的大小。第二步是使用 nvlist_pack(9F) 将列表压缩到缓冲区中。收到缓冲区内容的使用方可使用 nvlist_unpack(9F) 解压缩缓冲区。
用户级开发者和内核级开发者均可使用用于处理名称-值对的函数。可以在《man pages section 3: Library Interfaces and Headers》和《man pages section 9: DDI and DKI Kernel Functions》中找到这些函数的相同手册页。有关针对名称-值对执行操作的函数的列表,请参见下表。
表 5–1 使用名称-值对的函数
手册页 |
用途/函数 |
---|---|
向列表中添加名称-值对。函数包括: nvlist_add_boolean()、nvlist_add_boolean_value ()、nvlist_add_byte()、nvlist_add_int8()、 nvlist_add_uint8()、nvlist_add_int16()、nvlist_add_uint16 ()、nvlist_add_int32()、nvlist_add_uint32()、 nvlist_add_int64()、nvlist_add_uint64()、nvlist_add_string ()、nvlist_add_nvlist()、nvlist_add_nvpair()、 nvlist_add_boolean_array()、nvlist_add_int8_array、nvlist_add_uint8_array ()、nvlist_add_nvlist_array()、nvlist_add_byte_array ()、nvlist_add_int16_array()、nvlist_add_uint16_array ()、nvlist_add_int32_array()、nvlist_add_uint32_array ()、nvlist_add_int64_array()、nvlist_add_uint64_array ()、nvlist_add_string_array() |
|
处理名称-值列表缓冲区。函数包括: nvlist_alloc()、nvlist_free()、 nvlist_size()、nvlist_pack()、nvlist_unpack ()、nvlist_dup()、nvlist_merge() |
|
搜索名称-值对。函数包括: nvlist_lookup_boolean()、nvlist_lookup_boolean_value ()、nvlist_lookup_byte()、nvlist_lookup_int8 ()、nvlist_lookup_int16()、nvlist_lookup_int32 ()、nvlist_lookup_int64()、nvlist_lookup_uint8 ()、nvlist_lookup_uint16()、nvlist_lookup_uint32 ()、nvlist_lookup_uint64()、nvlist_lookup_string ()、nvlist_lookup_nvlist()、nvlist_lookup_boolean_array、nvlist_lookup_byte_array()、nvlist_lookup_int8_array()、 nvlist_lookup_int16_array()、nvlist_lookup_int32_array()、 nvlist_lookup_int64_array()、nvlist_lookup_uint8_array()、 nvlist_lookup_uint16_array()、nvlist_lookup_uint32_array()、 nvlist_lookup_uint64_array()、nvlist_lookup_string_array()、 nvlist_lookup_nvlist_array()、nvlist_lookup_pairs() |
|
获取名称-值对数据。函数包括: nvlist_next_nvpair()、nvpair_name()、 nvpair_type() |
|
删除名称-值对。函数包括: nv_remove()、nv_remove_all() |