mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
zfs label bootenv should store data as nvlist
nvlist does allow us to support different data types and systems. To encapsulate user data to/from nvlist, the libzfsbootenv library is provided. Reviewed-by: Arvind Sankar <nivedita@alum.mit.edu> Reviewed-by: Allan Jude <allan@klarasystems.com> Reviewed-by: Paul Dagnelie <pcd@delphix.com> Reviewed-by: Igor Kozhukhov <igor@dilos.org> Signed-off-by: Toomas Soome <tsoome@me.com> Closes #10774
This commit is contained in:
+2
-2
@@ -13,6 +13,6 @@ SUBDIRS += libnvpair
|
||||
# libzutil depends on libefi if present
|
||||
SUBDIRS += libzutil libunicode
|
||||
|
||||
# These four libraries, which are installed as the final build product,
|
||||
# These five libraries, which are installed as the final build product,
|
||||
# incorporate the eight convenience libraries given above.
|
||||
SUBDIRS += libuutil libzfs_core libzfs libzpool
|
||||
SUBDIRS += libuutil libzfs_core libzfs libzpool libzfsbootenv
|
||||
|
||||
+10
-14
@@ -4495,7 +4495,7 @@ zpool_wait_status(zpool_handle_t *zhp, zpool_wait_activity_t activity,
|
||||
}
|
||||
|
||||
int
|
||||
zpool_set_bootenv(zpool_handle_t *zhp, const char *envmap)
|
||||
zpool_set_bootenv(zpool_handle_t *zhp, const nvlist_t *envmap)
|
||||
{
|
||||
int error = lzc_set_bootenv(zhp->zpool_name, envmap);
|
||||
if (error != 0) {
|
||||
@@ -4508,24 +4508,20 @@ zpool_set_bootenv(zpool_handle_t *zhp, const char *envmap)
|
||||
}
|
||||
|
||||
int
|
||||
zpool_get_bootenv(zpool_handle_t *zhp, char *outbuf, size_t size, off_t offset)
|
||||
zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp)
|
||||
{
|
||||
nvlist_t *nvl = NULL;
|
||||
int error = lzc_get_bootenv(zhp->zpool_name, &nvl);
|
||||
nvlist_t *nvl;
|
||||
int error;
|
||||
|
||||
nvl = NULL;
|
||||
error = lzc_get_bootenv(zhp->zpool_name, &nvl);
|
||||
if (error != 0) {
|
||||
(void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
|
||||
dgettext(TEXT_DOMAIN,
|
||||
"error getting bootenv in pool '%s'"), zhp->zpool_name);
|
||||
return (-1);
|
||||
}
|
||||
char *envmap = fnvlist_lookup_string(nvl, "envmap");
|
||||
if (offset >= strlen(envmap)) {
|
||||
fnvlist_free(nvl);
|
||||
return (0);
|
||||
} else {
|
||||
*nvlp = nvl;
|
||||
}
|
||||
|
||||
strncpy(outbuf, envmap + offset, size);
|
||||
int bytes = MIN(strlen(envmap + offset), size);
|
||||
fnvlist_free(nvl);
|
||||
return (bytes);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -1625,13 +1625,9 @@ lzc_wait_fs(const char *fs, zfs_wait_activity_t activity, boolean_t *waited)
|
||||
* Set the bootenv contents for the given pool.
|
||||
*/
|
||||
int
|
||||
lzc_set_bootenv(const char *pool, const char *env)
|
||||
lzc_set_bootenv(const char *pool, const nvlist_t *env)
|
||||
{
|
||||
nvlist_t *args = fnvlist_alloc();
|
||||
fnvlist_add_string(args, "envmap", env);
|
||||
int error = lzc_ioctl(ZFS_IOC_SET_BOOTENV, pool, args, NULL);
|
||||
fnvlist_free(args);
|
||||
return (error);
|
||||
return (lzc_ioctl(ZFS_IOC_SET_BOOTENV, pool, (nvlist_t *)env, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/libzfsbootenv.pc
|
||||
@@ -0,0 +1,32 @@
|
||||
include $(top_srcdir)/config/Rules.am
|
||||
|
||||
pkgconfig_DATA = libzfsbootenv.pc
|
||||
|
||||
lib_LTLIBRARIES = libzfsbootenv.la
|
||||
|
||||
if BUILD_FREEBSD
|
||||
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/freebsd/zfs
|
||||
endif
|
||||
if BUILD_LINUX
|
||||
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/linux/zfs
|
||||
endif
|
||||
|
||||
USER_C = \
|
||||
lzbe_device.c \
|
||||
lzbe_pair.c \
|
||||
lzbe_util.c
|
||||
|
||||
dist_libzfsbootenv_la_SOURCES = \
|
||||
$(USER_C)
|
||||
|
||||
libzfsbootenv_la_LIBADD = \
|
||||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||
|
||||
libzfsbootenv_la_LDFLAGS =
|
||||
|
||||
if !ASAN_ENABLED
|
||||
libzfsbootenv_la_LDFLAGS += -Wl,-z,defs
|
||||
endif
|
||||
|
||||
libzfsbootenv_la_LDFLAGS += -version-info 1:0:0
|
||||
@@ -0,0 +1,12 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libzfsbootenv
|
||||
Description: LibZFSBootENV library
|
||||
Version: @VERSION@
|
||||
URL: https://zfsonlinux.org
|
||||
Requires: libzfs libnvpair
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lzfsbootenv
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2020 Toomas Soome <tsoome@me.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzfsbootenv.h>
|
||||
#include <sys/zfs_bootenv.h>
|
||||
#include <sys/vdev_impl.h>
|
||||
|
||||
/*
|
||||
* Store device name to zpool label bootenv area.
|
||||
* This call will set bootenv version to VB_NVLIST, if bootenv currently
|
||||
* does contain other version, then old data will be replaced.
|
||||
*/
|
||||
int
|
||||
lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device)
|
||||
{
|
||||
libzfs_handle_t *hdl;
|
||||
zpool_handle_t *zphdl;
|
||||
nvlist_t *nv;
|
||||
char *descriptor;
|
||||
uint64_t version;
|
||||
int rv = -1;
|
||||
|
||||
if (pool == NULL || *pool == '\0')
|
||||
return (rv);
|
||||
|
||||
if ((hdl = libzfs_init()) == NULL)
|
||||
return (rv);
|
||||
|
||||
zphdl = zpool_open(hdl, pool);
|
||||
if (zphdl == NULL) {
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
switch (flag) {
|
||||
case lzbe_add:
|
||||
rv = zpool_get_bootenv(zphdl, &nv);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* We got the nvlist, check for version.
|
||||
* if version is missing or is not VB_NVLIST,
|
||||
* create new list.
|
||||
*/
|
||||
rv = nvlist_lookup_uint64(nv, BOOTENV_VERSION,
|
||||
&version);
|
||||
if (rv == 0 && version == VB_NVLIST)
|
||||
break;
|
||||
|
||||
/* Drop this nvlist */
|
||||
fnvlist_free(nv);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case lzbe_replace:
|
||||
nv = fnvlist_alloc();
|
||||
break;
|
||||
default:
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/* version is mandatory */
|
||||
fnvlist_add_uint64(nv, BOOTENV_VERSION, VB_NVLIST);
|
||||
|
||||
/*
|
||||
* If device name is empty, remove boot device configuration.
|
||||
*/
|
||||
if ((device == NULL || *device == '\0')) {
|
||||
if (nvlist_exists(nv, OS_BOOTONCE))
|
||||
fnvlist_remove(nv, OS_BOOTONCE);
|
||||
} else {
|
||||
/*
|
||||
* Use device name directly if it does start with
|
||||
* prefix "zfs:". Otherwise, add prefix and sufix.
|
||||
*/
|
||||
if (strncmp(device, "zfs:", 4) == 0) {
|
||||
fnvlist_add_string(nv, OS_BOOTONCE, device);
|
||||
} else {
|
||||
descriptor = NULL;
|
||||
if (asprintf(&descriptor, "zfs:%s:", device) > 0)
|
||||
fnvlist_add_string(nv, OS_BOOTONCE, descriptor);
|
||||
else
|
||||
rv = ENOMEM;
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
rv = zpool_set_bootenv(zphdl, nv);
|
||||
if (rv != 0)
|
||||
fprintf(stderr, "%s\n", libzfs_error_description(hdl));
|
||||
|
||||
fnvlist_free(nv);
|
||||
zpool_close(zphdl);
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return boot device name from bootenv, if set.
|
||||
*/
|
||||
int
|
||||
lzbe_get_boot_device(const char *pool, char **device)
|
||||
{
|
||||
libzfs_handle_t *hdl;
|
||||
zpool_handle_t *zphdl;
|
||||
nvlist_t *nv;
|
||||
char *val;
|
||||
int rv = -1;
|
||||
|
||||
if (pool == NULL || *pool == '\0' || device == NULL)
|
||||
return (rv);
|
||||
|
||||
if ((hdl = libzfs_init()) == NULL)
|
||||
return (rv);
|
||||
|
||||
zphdl = zpool_open(hdl, pool);
|
||||
if (zphdl == NULL) {
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
rv = zpool_get_bootenv(zphdl, &nv);
|
||||
if (rv == 0) {
|
||||
rv = nvlist_lookup_string(nv, OS_BOOTONCE, &val);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* zfs device descriptor is in form of "zfs:dataset:",
|
||||
* we only do need dataset name.
|
||||
*/
|
||||
if (strncmp(val, "zfs:", 4) == 0) {
|
||||
val += 4;
|
||||
val = strdup(val);
|
||||
if (val != NULL) {
|
||||
size_t len = strlen(val);
|
||||
|
||||
if (val[len - 1] == ':')
|
||||
val[len - 1] = '\0';
|
||||
*device = val;
|
||||
} else {
|
||||
rv = ENOMEM;
|
||||
}
|
||||
} else {
|
||||
rv = EINVAL;
|
||||
}
|
||||
}
|
||||
nvlist_free(nv);
|
||||
}
|
||||
|
||||
zpool_close(zphdl);
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2020 Toomas Soome <tsoome@me.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzfsbootenv.h>
|
||||
|
||||
/*
|
||||
* Get or create nvlist. If key is not NULL, get nvlist from bootenv,
|
||||
* otherwise return bootenv.
|
||||
*/
|
||||
int
|
||||
lzbe_nvlist_get(const char *pool, const char *key, void **ptr)
|
||||
{
|
||||
libzfs_handle_t *hdl;
|
||||
zpool_handle_t *zphdl;
|
||||
nvlist_t *nv;
|
||||
int rv = -1;
|
||||
|
||||
if (pool == NULL || *pool == '\0')
|
||||
return (rv);
|
||||
|
||||
if ((hdl = libzfs_init()) == NULL) {
|
||||
return (rv);
|
||||
}
|
||||
|
||||
zphdl = zpool_open(hdl, pool);
|
||||
if (zphdl == NULL) {
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
rv = zpool_get_bootenv(zphdl, &nv);
|
||||
if (rv == 0) {
|
||||
nvlist_t *nvl, *dup;
|
||||
|
||||
if (key != NULL) {
|
||||
rv = nvlist_lookup_nvlist(nv, key, &nvl);
|
||||
if (rv == 0) {
|
||||
rv = nvlist_dup(nvl, &dup, 0);
|
||||
nvlist_free(nv);
|
||||
if (rv == 0)
|
||||
nv = dup;
|
||||
else
|
||||
nv = NULL;
|
||||
} else {
|
||||
nvlist_free(nv);
|
||||
rv = nvlist_alloc(&nv, NV_UNIQUE_NAME, 0);
|
||||
}
|
||||
}
|
||||
*ptr = nv;
|
||||
}
|
||||
|
||||
zpool_close(zphdl);
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
lzbe_nvlist_set(const char *pool, const char *key, void *ptr)
|
||||
{
|
||||
libzfs_handle_t *hdl;
|
||||
zpool_handle_t *zphdl;
|
||||
nvlist_t *nv;
|
||||
int rv = -1;
|
||||
|
||||
if (pool == NULL || *pool == '\0')
|
||||
return (rv);
|
||||
|
||||
if ((hdl = libzfs_init()) == NULL) {
|
||||
return (rv);
|
||||
}
|
||||
|
||||
zphdl = zpool_open(hdl, pool);
|
||||
if (zphdl == NULL) {
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
if (key != NULL) {
|
||||
rv = zpool_get_bootenv(zphdl, &nv);
|
||||
if (rv == 0) {
|
||||
rv = nvlist_add_nvlist(nv, key, ptr);
|
||||
if (rv == 0)
|
||||
rv = zpool_set_bootenv(zphdl, nv);
|
||||
nvlist_free(nv);
|
||||
}
|
||||
} else {
|
||||
rv = zpool_set_bootenv(zphdl, ptr);
|
||||
}
|
||||
|
||||
zpool_close(zphdl);
|
||||
libzfs_fini(hdl);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* free nvlist we got via lzbe_nvlist_get()
|
||||
*/
|
||||
void
|
||||
lzbe_nvlist_free(void *ptr)
|
||||
{
|
||||
nvlist_free(ptr);
|
||||
}
|
||||
|
||||
static const char *typenames[] = {
|
||||
"DATA_TYPE_UNKNOWN",
|
||||
"DATA_TYPE_BOOLEAN",
|
||||
"DATA_TYPE_BYTE",
|
||||
"DATA_TYPE_INT16",
|
||||
"DATA_TYPE_UINT16",
|
||||
"DATA_TYPE_INT32",
|
||||
"DATA_TYPE_UINT32",
|
||||
"DATA_TYPE_INT64",
|
||||
"DATA_TYPE_UINT64",
|
||||
"DATA_TYPE_STRING",
|
||||
"DATA_TYPE_BYTE_ARRAY",
|
||||
"DATA_TYPE_INT16_ARRAY",
|
||||
"DATA_TYPE_UINT16_ARRAY",
|
||||
"DATA_TYPE_INT32_ARRAY",
|
||||
"DATA_TYPE_UINT32_ARRAY",
|
||||
"DATA_TYPE_INT64_ARRAY",
|
||||
"DATA_TYPE_UINT64_ARRAY",
|
||||
"DATA_TYPE_STRING_ARRAY",
|
||||
"DATA_TYPE_HRTIME",
|
||||
"DATA_TYPE_NVLIST",
|
||||
"DATA_TYPE_NVLIST_ARRAY",
|
||||
"DATA_TYPE_BOOLEAN_VALUE",
|
||||
"DATA_TYPE_INT8",
|
||||
"DATA_TYPE_UINT8",
|
||||
"DATA_TYPE_BOOLEAN_ARRAY",
|
||||
"DATA_TYPE_INT8_ARRAY",
|
||||
"DATA_TYPE_UINT8_ARRAY"
|
||||
};
|
||||
|
||||
static int
|
||||
nvpair_type_from_name(const char *name)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(typenames); i++) {
|
||||
if (strcmp(name, typenames[i]) == 0)
|
||||
return (i);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add pair defined by key, type and value into nvlist.
|
||||
*/
|
||||
int
|
||||
lzbe_add_pair(void *ptr, const char *key, const char *type, void *value,
|
||||
size_t size)
|
||||
{
|
||||
nvlist_t *nv = ptr;
|
||||
data_type_t dt;
|
||||
int rv = 0;
|
||||
|
||||
if (ptr == NULL || key == NULL || value == NULL)
|
||||
return (rv);
|
||||
|
||||
if (type == NULL)
|
||||
type = "DATA_TYPE_STRING";
|
||||
dt = nvpair_type_from_name(type);
|
||||
if (dt == DATA_TYPE_UNKNOWN)
|
||||
return (EINVAL);
|
||||
|
||||
switch (dt) {
|
||||
case DATA_TYPE_BYTE:
|
||||
if (size != sizeof (uint8_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_byte(nv, key, *(uint8_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT16:
|
||||
if (size != sizeof (int16_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_int16(nv, key, *(int16_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT16:
|
||||
if (size != sizeof (uint16_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_uint16(nv, key, *(uint16_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT32:
|
||||
if (size != sizeof (int32_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_int32(nv, key, *(int32_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT32:
|
||||
if (size != sizeof (uint32_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_uint32(nv, key, *(uint32_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT64:
|
||||
if (size != sizeof (int64_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_int64(nv, key, *(int64_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT64:
|
||||
if (size != sizeof (uint64_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_uint64(nv, key, *(uint64_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_STRING:
|
||||
rv = nvlist_add_string(nv, key, value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_BYTE_ARRAY:
|
||||
rv = nvlist_add_byte_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT16_ARRAY:
|
||||
rv = nvlist_add_int16_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT16_ARRAY:
|
||||
rv = nvlist_add_uint16_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT32_ARRAY:
|
||||
rv = nvlist_add_int32_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT32_ARRAY:
|
||||
rv = nvlist_add_uint32_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT64_ARRAY:
|
||||
rv = nvlist_add_int64_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT64_ARRAY:
|
||||
rv = nvlist_add_uint64_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_STRING_ARRAY:
|
||||
rv = nvlist_add_string_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_NVLIST:
|
||||
rv = nvlist_add_nvlist(nv, key, (nvlist_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_NVLIST_ARRAY:
|
||||
rv = nvlist_add_nvlist_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_BOOLEAN_VALUE:
|
||||
if (size != sizeof (boolean_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_boolean_value(nv, key, *(boolean_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT8:
|
||||
if (size != sizeof (int8_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_int8(nv, key, *(int8_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT8:
|
||||
if (size != sizeof (uint8_t)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
rv = nvlist_add_uint8(nv, key, *(uint8_t *)value);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_BOOLEAN_ARRAY:
|
||||
rv = nvlist_add_boolean_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_INT8_ARRAY:
|
||||
rv = nvlist_add_int8_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
case DATA_TYPE_UINT8_ARRAY:
|
||||
rv = nvlist_add_uint8_array(nv, key, value, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
lzbe_remove_pair(void *ptr, const char *key)
|
||||
{
|
||||
|
||||
return (nvlist_remove_all(ptr, key));
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2020 Toomas Soome <tsoome@me.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzfsbootenv.h>
|
||||
|
||||
/*
|
||||
* Output bootenv information.
|
||||
*/
|
||||
int
|
||||
lzbe_bootenv_print(const char *pool, const char *nvlist, FILE *of)
|
||||
{
|
||||
nvlist_t *nv;
|
||||
int rv = -1;
|
||||
|
||||
if (pool == NULL || *pool == '\0' || of == NULL)
|
||||
return (rv);
|
||||
|
||||
rv = lzbe_nvlist_get(pool, nvlist, (void **)&nv);
|
||||
if (rv == 0) {
|
||||
nvlist_print(of, nv);
|
||||
nvlist_free(nv);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
@@ -7,6 +7,13 @@ VPATH = \
|
||||
$(top_srcdir)/module/os/linux/zfs \
|
||||
$(top_srcdir)/lib/libzpool
|
||||
|
||||
if BUILD_FREEBSD
|
||||
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/freebsd/zfs
|
||||
endif
|
||||
if BUILD_LINUX
|
||||
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/linux/zfs
|
||||
endif
|
||||
|
||||
# Unconditionally enable debugging for libzpool
|
||||
AM_CPPFLAGS += -DDEBUG -UNDEBUG -DZFS_DEBUG
|
||||
|
||||
|
||||
Reference in New Issue
Block a user