2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
12 * Copyright 2020 Toomas Soome <tsoome@me.com>
15 #include <sys/types.h>
18 #include <libzfsbootenv.h>
19 #include <sys/zfs_bootenv.h>
20 #include <sys/vdev_impl.h>
23 * Get or create nvlist. If key is not NULL, get nvlist from bootenv,
24 * otherwise return bootenv.
27 lzbe_nvlist_get(const char *pool
, const char *key
, void **ptr
)
30 zpool_handle_t
*zphdl
;
34 if (pool
== NULL
|| *pool
== '\0')
37 if ((hdl
= libzfs_init()) == NULL
) {
41 zphdl
= zpool_open(hdl
, pool
);
47 rv
= zpool_get_bootenv(zphdl
, &nv
);
52 rv
= nvlist_lookup_nvlist(nv
, key
, &nvl
);
54 rv
= nvlist_dup(nvl
, &dup
, 0);
62 rv
= nvlist_alloc(&nv
, NV_UNIQUE_NAME
, 0);
74 lzbe_nvlist_set(const char *pool
, const char *key
, void *ptr
)
77 zpool_handle_t
*zphdl
;
82 if (pool
== NULL
|| *pool
== '\0')
85 if ((hdl
= libzfs_init()) == NULL
) {
89 zphdl
= zpool_open(hdl
, pool
);
96 rv
= zpool_get_bootenv(zphdl
, &nv
);
99 * We got the nvlist, check for version.
100 * if version is missing or is not VB_NVLIST,
103 rv
= nvlist_lookup_uint64(nv
, BOOTENV_VERSION
,
105 if (rv
!= 0 || version
!= VB_NVLIST
) {
106 /* Drop this nvlist */
108 /* Create and prepare new nvlist */
109 nv
= fnvlist_alloc();
110 fnvlist_add_uint64(nv
, BOOTENV_VERSION
,
113 rv
= nvlist_add_nvlist(nv
, key
, ptr
);
115 rv
= zpool_set_bootenv(zphdl
, nv
);
119 rv
= zpool_set_bootenv(zphdl
, ptr
);
128 * free nvlist we got via lzbe_nvlist_get()
131 lzbe_nvlist_free(void *ptr
)
136 static const char *typenames
[] = {
147 "DATA_TYPE_BYTE_ARRAY",
148 "DATA_TYPE_INT16_ARRAY",
149 "DATA_TYPE_UINT16_ARRAY",
150 "DATA_TYPE_INT32_ARRAY",
151 "DATA_TYPE_UINT32_ARRAY",
152 "DATA_TYPE_INT64_ARRAY",
153 "DATA_TYPE_UINT64_ARRAY",
154 "DATA_TYPE_STRING_ARRAY",
157 "DATA_TYPE_NVLIST_ARRAY",
158 "DATA_TYPE_BOOLEAN_VALUE",
161 "DATA_TYPE_BOOLEAN_ARRAY",
162 "DATA_TYPE_INT8_ARRAY",
163 "DATA_TYPE_UINT8_ARRAY"
167 nvpair_type_from_name(const char *name
)
171 for (i
= 0; i
< ARRAY_SIZE(typenames
); i
++) {
172 if (strcmp(name
, typenames
[i
]) == 0)
179 * Add pair defined by key, type and value into nvlist.
182 lzbe_add_pair(void *ptr
, const char *key
, const char *type
, void *value
,
189 if (ptr
== NULL
|| key
== NULL
|| value
== NULL
)
193 type
= "DATA_TYPE_STRING";
194 dt
= nvpair_type_from_name(type
);
195 if (dt
== DATA_TYPE_UNKNOWN
)
200 if (size
!= sizeof (uint8_t)) {
204 rv
= nvlist_add_byte(nv
, key
, *(uint8_t *)value
);
207 case DATA_TYPE_INT16
:
208 if (size
!= sizeof (int16_t)) {
212 rv
= nvlist_add_int16(nv
, key
, *(int16_t *)value
);
215 case DATA_TYPE_UINT16
:
216 if (size
!= sizeof (uint16_t)) {
220 rv
= nvlist_add_uint16(nv
, key
, *(uint16_t *)value
);
223 case DATA_TYPE_INT32
:
224 if (size
!= sizeof (int32_t)) {
228 rv
= nvlist_add_int32(nv
, key
, *(int32_t *)value
);
231 case DATA_TYPE_UINT32
:
232 if (size
!= sizeof (uint32_t)) {
236 rv
= nvlist_add_uint32(nv
, key
, *(uint32_t *)value
);
239 case DATA_TYPE_INT64
:
240 if (size
!= sizeof (int64_t)) {
244 rv
= nvlist_add_int64(nv
, key
, *(int64_t *)value
);
247 case DATA_TYPE_UINT64
:
248 if (size
!= sizeof (uint64_t)) {
252 rv
= nvlist_add_uint64(nv
, key
, *(uint64_t *)value
);
255 case DATA_TYPE_STRING
:
256 rv
= nvlist_add_string(nv
, key
, value
);
259 case DATA_TYPE_BYTE_ARRAY
:
260 rv
= nvlist_add_byte_array(nv
, key
, value
, size
);
263 case DATA_TYPE_INT16_ARRAY
:
264 rv
= nvlist_add_int16_array(nv
, key
, value
, size
);
267 case DATA_TYPE_UINT16_ARRAY
:
268 rv
= nvlist_add_uint16_array(nv
, key
, value
, size
);
271 case DATA_TYPE_INT32_ARRAY
:
272 rv
= nvlist_add_int32_array(nv
, key
, value
, size
);
275 case DATA_TYPE_UINT32_ARRAY
:
276 rv
= nvlist_add_uint32_array(nv
, key
, value
, size
);
279 case DATA_TYPE_INT64_ARRAY
:
280 rv
= nvlist_add_int64_array(nv
, key
, value
, size
);
283 case DATA_TYPE_UINT64_ARRAY
:
284 rv
= nvlist_add_uint64_array(nv
, key
, value
, size
);
287 case DATA_TYPE_STRING_ARRAY
:
288 rv
= nvlist_add_string_array(nv
, key
, value
, size
);
291 case DATA_TYPE_NVLIST
:
292 rv
= nvlist_add_nvlist(nv
, key
, (nvlist_t
*)value
);
295 case DATA_TYPE_NVLIST_ARRAY
:
296 rv
= nvlist_add_nvlist_array(nv
, key
, (const nvlist_t
**)value
,
300 case DATA_TYPE_BOOLEAN_VALUE
:
301 if (size
!= sizeof (boolean_t
)) {
305 rv
= nvlist_add_boolean_value(nv
, key
, *(boolean_t
*)value
);
309 if (size
!= sizeof (int8_t)) {
313 rv
= nvlist_add_int8(nv
, key
, *(int8_t *)value
);
316 case DATA_TYPE_UINT8
:
317 if (size
!= sizeof (uint8_t)) {
321 rv
= nvlist_add_uint8(nv
, key
, *(uint8_t *)value
);
324 case DATA_TYPE_BOOLEAN_ARRAY
:
325 rv
= nvlist_add_boolean_array(nv
, key
, value
, size
);
328 case DATA_TYPE_INT8_ARRAY
:
329 rv
= nvlist_add_int8_array(nv
, key
, value
, size
);
332 case DATA_TYPE_UINT8_ARRAY
:
333 rv
= nvlist_add_uint8_array(nv
, key
, value
, size
);
344 lzbe_remove_pair(void *ptr
, const char *key
)
347 return (nvlist_remove_all(ptr
, key
));