From ee23f22ae6e748800362c0b84c8342d382a25d0b Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 27 Nov 2025 14:20:00 +1100 Subject: [PATCH] bootenv: reorganise and document In 99d7453b43 I split out the "OS-specific" zfs_bootenv_os.h for userspace, added a placeholder "posix" vendor and set BOOTENV_OS to use it by default. This turned out to be the wrong thing to do. BOOTENV_OS is not actually OS-specific but rather, part of a protocol coordinating behaviour between libzfsbootenv and the bootloader. So, all bootenv keys now get prefixed with posix:, and their respective loaders can no longer find them[1]. Reverting would have been straightforward, however, I am more interested in trying to reorganise libzfsbootenv and surrounds to provide all the pieces a loader, its support tools and the kernel module need in order to have agreement on how to communicate with each other. This commit is attempting that rework. The two goals here are: - it should be possible to set and get the loader prefix in libzfsbootenv at run time, allowing the possibility for the library to work on loader prefixes other than the one it was compiled with. - a loader is a constrained environment, and so should be able to get all the config it needs from a single header that libzfsbootenv and the kernel at least default to using. FreeBSD (and illumos, which borrows heavily from it) is the only system out there that currently has this tight integration between loader, kernel and tools, so it is the obvious target to focus on here, but I'm also trying to clearly draw the lines for future systems. First, we remove sys/zfs_bootenv.h and the various sys/zfs_bootenv_os.h. This is not really a public API, and as discussed, is not the proper way to target a loader anyway. The important macros for a consumer have been moved to fs/zfs.h as public and supported names. These are the minimum necessary to use libzfsbootenv (actually lzc_get_bootenv/lzc_set_bootenv) effectively anyway, and since they live in headers, a standalone loader can make use of them. Here we have macros nvlist keys for "known" loaders, and for common/known bootenv vars. Worth noting that only "bootonce" is currently used in libzfsbootenv proper, but listing them out at least makes sure they're documented and we can encourage future systems to do it the same way. libzfsbootenv gains an internal notion of the current loader, just the string prefix. Two new functions are added, lzbe_set_loader() and lzbe_get_loader(), allowing runtime changes. By compiler define, we set the default on FreeBSD and illumos to the matching macro from fs/zfs.h, and "unknown" otherwise. This should keep existing consumers working without change. The rest is simple cleanup. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris 1. https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291211 --- include/Makefile.am | 1 - include/libzfsbootenv.h | 3 ++ include/os/freebsd/Makefile.am | 1 - include/os/freebsd/zfs/sys/zfs_bootenv_os.h | 30 ----------- include/os/linux/Makefile.am | 1 - include/os/linux/zfs/sys/zfs_bootenv_os.h | 30 ----------- include/sys/fs/zfs.h | 36 ++++++++++++++ include/sys/vdev_impl.h | 20 -------- include/sys/zfs_bootenv.h | 55 --------------------- lib/libzfsbootenv/Makefile.am | 4 +- lib/libzfsbootenv/libzfsbootenv.abi | 12 +++++ lib/libzfsbootenv/lzbe_device.c | 47 +++++++++++------- lib/libzfsbootenv/lzbe_loader.c | 55 +++++++++++++++++++++ lib/libzfsbootenv/lzbe_pair.c | 15 +++--- lib/libzpool/include/Makefile.am | 1 - lib/libzpool/include/sys/zfs_bootenv_os.h | 39 --------------- module/zfs/vdev_label.c | 39 ++++++++++----- module/zfs/zfs_ioctl.c | 5 +- tests/zfs-tests/cmd/libzfs_input_check.c | 5 +- 19 files changed, 177 insertions(+), 222 deletions(-) delete mode 100644 include/os/freebsd/zfs/sys/zfs_bootenv_os.h delete mode 100644 include/os/linux/zfs/sys/zfs_bootenv_os.h delete mode 100644 include/sys/zfs_bootenv.h create mode 100644 lib/libzfsbootenv/lzbe_loader.c delete mode 100644 lib/libzpool/include/sys/zfs_bootenv_os.h diff --git a/include/Makefile.am b/include/Makefile.am index cc79c1a3ddb2..f7f59eb61a7e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -123,7 +123,6 @@ COMMON_H = \ sys/zcp_set.h \ sys/zfeature.h \ sys/zfs_acl.h \ - sys/zfs_bootenv.h \ sys/zfs_chksum.h \ sys/zfs_context.h \ sys/zfs_debug.h \ diff --git a/include/libzfsbootenv.h b/include/libzfsbootenv.h index 978bf440efb3..511bb2b8fdfb 100644 --- a/include/libzfsbootenv.h +++ b/include/libzfsbootenv.h @@ -12,6 +12,7 @@ /* * Copyright 2020 Toomas Soome + * Copyright (c) 2025, Rob Norris */ #ifndef _LIBZFSBOOTENV_H @@ -36,6 +37,8 @@ _LIBZFSBOOTENV_H int lzbe_set_boot_device(const char *, lzbe_flags_t, const char *); _LIBZFSBOOTENV_H int lzbe_get_boot_device(const char *, char **); _LIBZFSBOOTENV_H int lzbe_bootenv_print(const char *, const char *, FILE *); +_LIBZFSBOOTENV_H const char *lzbe_loader_get(void); +_LIBZFSBOOTENV_H int lzbe_loader_set(const char *, size_t); #ifdef __cplusplus } diff --git a/include/os/freebsd/Makefile.am b/include/os/freebsd/Makefile.am index 47cf6756ab7d..fced1fff697f 100644 --- a/include/os/freebsd/Makefile.am +++ b/include/os/freebsd/Makefile.am @@ -82,7 +82,6 @@ noinst_HEADERS = \ %D%/zfs/sys/freebsd_event.h \ %D%/zfs/sys/trace_zfs.h \ %D%/zfs/sys/vdev_os.h \ - %D%/zfs/sys/zfs_bootenv_os.h \ %D%/zfs/sys/zfs_context_os.h \ %D%/zfs/sys/zfs_ctldir.h \ %D%/zfs/sys/zfs_debug_os.h \ diff --git a/include/os/freebsd/zfs/sys/zfs_bootenv_os.h b/include/os/freebsd/zfs/sys/zfs_bootenv_os.h deleted file mode 100644 index eaa07328a846..000000000000 --- a/include/os/freebsd/zfs/sys/zfs_bootenv_os.h +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * 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 - */ - -#ifndef _ZFS_BOOTENV_OS_H -#define _ZFS_BOOTENV_OS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BOOTENV_OS BE_FREEBSD_VENDOR - -#ifdef __cplusplus -} -#endif - -#endif /* _ZFS_BOOTENV_OS_H */ diff --git a/include/os/linux/Makefile.am b/include/os/linux/Makefile.am index 9188a974cc22..589b562deaa4 100644 --- a/include/os/linux/Makefile.am +++ b/include/os/linux/Makefile.am @@ -38,7 +38,6 @@ kernel_sys_HEADERS = \ %D%/zfs/sys/trace_zil.h \ %D%/zfs/sys/trace_zio.h \ %D%/zfs/sys/trace_zrlock.h \ - %D%/zfs/sys/zfs_bootenv_os.h \ %D%/zfs/sys/zfs_context_os.h \ %D%/zfs/sys/zfs_ctldir.h \ %D%/zfs/sys/zfs_debug_os.h \ diff --git a/include/os/linux/zfs/sys/zfs_bootenv_os.h b/include/os/linux/zfs/sys/zfs_bootenv_os.h deleted file mode 100644 index 4f90b72c80f7..000000000000 --- a/include/os/linux/zfs/sys/zfs_bootenv_os.h +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * 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 - */ - -#ifndef _ZFS_BOOTENV_OS_H -#define _ZFS_BOOTENV_OS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BOOTENV_OS BE_LINUX_VENDOR - -#ifdef __cplusplus -} -#endif - -#endif /* _ZFS_BOOTENV_OS_H */ diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index 830c8455bb1a..0fce6fbe0df5 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -32,6 +32,7 @@ * Copyright (c) 2021, Colm Buckley * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. * Copyright (c) 2024, Klara, Inc. + * Copyright (c) 2025, Rob Norris */ #ifndef _SYS_FS_ZFS_H @@ -2003,6 +2004,41 @@ enum zio_encrypt { ZFS_XA_NS_PREFIX_MATCH(LINUX_TRUSTED, name) || \ ZFS_XA_NS_PREFIX_MATCH(LINUX_USER, name)) + +/* + * Boot environment support. The vdev environment block is accessed with the + * ZFS_IOC_GET_BOOTENV and ZFS_IOC_SET_BOOTENV calls. libzfsbootenv uses these + * internally, and is the preferred way to work with boot environments, but + * these defines are provided here to assist bootloaders and tools that want to + * do their own thing. + */ + +#define ZFS_BE_VERSION "version" +enum zfs_bootenv_version { + ZFS_BE_VERSION_GRUBENV = 0, /* GRUB "grubenv" file */ + ZFS_BE_VERSION_NVLIST = 1, /* arbitrary packed nvlist */ +}; + +/* nvlist key for GRUB "grubenv" string */ +#define ZFS_BE_GRUB_ENVMAP "grub:envmap" + +/* + * Keys in NVLIST bootenvs should be prefixed with a loader-specific string, + * allowing the envblock to support multiple loaders. + * + * This is the list of known loader prefixes. + */ +#define ZFS_BE_LOADER_FREEBSD "freebsd" +#define ZFS_BE_LOADER_ILLUMOS "illumos" + +/* + * Common bootenv keys, to be combined with the loader prefix. New loaders are + * encouraged to use these where appropriate to assist cross-platform interop. + */ +#define ZFS_BE_BOOTONCE "bootonce" +#define ZFS_BE_BOOTONCE_USED "bootonce-used" +#define ZFS_BE_NVSTORE "nvstore" + #ifdef __cplusplus } #endif diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h index afaa401343d9..0036f565b7d6 100644 --- a/include/sys/vdev_impl.h +++ b/include/sys/vdev_impl.h @@ -503,26 +503,6 @@ typedef struct vdev_phys { zio_eck_t vp_zbt; } vdev_phys_t; -typedef enum vbe_vers { - /* - * The bootenv file is stored as ascii text in the envblock. - * It is used by the GRUB bootloader used on Linux to store the - * contents of the grubenv file. The file is stored as raw ASCII, - * and is protected by an embedded checksum. By default, GRUB will - * check if the boot filesystem supports storing the environment data - * in a special location, and if so, will invoke filesystem specific - * logic to retrieve it. This can be overridden by a variable, should - * the user so desire. - */ - VB_RAW = 0, - - /* - * The bootenv file is converted to an nvlist and then packed into the - * envblock. - */ - VB_NVLIST = 1 -} vbe_vers_t; - typedef struct vdev_boot_envblock { uint64_t vbe_version; char vbe_bootenv[VDEV_PAD_SIZE - sizeof (uint64_t) - diff --git a/include/sys/zfs_bootenv.h b/include/sys/zfs_bootenv.h deleted file mode 100644 index 4c4b2ab1ab1b..000000000000 --- a/include/sys/zfs_bootenv.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * 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 - */ - -#ifndef _ZFS_BOOTENV_H -#define _ZFS_BOOTENV_H - -/* - * Define macros for label bootenv nvlist pair keys. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define BOOTENV_VERSION "version" - -#define BE_ILLUMOS_VENDOR "illumos" -#define BE_FREEBSD_VENDOR "freebsd" -#define BE_GRUB_VENDOR "grub" -#define BE_LINUX_VENDOR "linux" -#define BE_POSIX_VENDOR "posix" - -#include - -#define GRUB_ENVMAP BE_GRUB_VENDOR ":" "envmap" - -#define FREEBSD_BOOTONCE BE_FREEBSD_VENDOR ":" "bootonce" -#define FREEBSD_BOOTONCE_USED BE_FREEBSD_VENDOR ":" "bootonce-used" -#define FREEBSD_NVSTORE BE_FREEBSD_VENDOR ":" "nvstore" -#define ILLUMOS_BOOTONCE BE_ILLUMOS_VENDOR ":" "bootonce" -#define ILLUMOS_BOOTONCE_USED BE_ILLUMOS_VENDOR ":" "bootonce-used" -#define ILLUMOS_NVSTORE BE_ILLUMOS_VENDOR ":" "nvstore" - -#define OS_BOOTONCE BOOTENV_OS ":" "bootonce" -#define OS_BOOTONCE_USED BOOTENV_OS ":" "bootonce-used" -#define OS_NVSTORE BOOTENV_OS ":" "nvstore" - -#ifdef __cplusplus -} -#endif - -#endif /* _ZFS_BOOTENV_H */ diff --git a/lib/libzfsbootenv/Makefile.am b/lib/libzfsbootenv/Makefile.am index 118f154821fc..da879c0053d2 100644 --- a/lib/libzfsbootenv/Makefile.am +++ b/lib/libzfsbootenv/Makefile.am @@ -5,10 +5,10 @@ lib_LTLIBRARIES += libzfsbootenv.la CPPCHECKTARGETS += libzfsbootenv.la libzfsbootenv_la_CPPFLAGS = $(AM_CPPFLAGS) -libzfsbootenv_la_CPPFLAGS += -I$(srcdir)/include/os/@ac_system_l@/zfs dist_libzfsbootenv_la_SOURCES = \ %D%/lzbe_device.c \ + %D%/lzbe_loader.c \ %D%/lzbe_pair.c \ %D%/lzbe_util.c @@ -22,7 +22,7 @@ if !ASAN_ENABLED libzfsbootenv_la_LDFLAGS += -Wl,-z,defs endif -libzfsbootenv_la_LDFLAGS += -version-info 1:0:0 +libzfsbootenv_la_LDFLAGS += -version-info 2:0:1 pkgconfig_DATA += %D%/libzfsbootenv.pc diff --git a/lib/libzfsbootenv/libzfsbootenv.abi b/lib/libzfsbootenv/libzfsbootenv.abi index e2b492a0780d..2a9180784ca5 100644 --- a/lib/libzfsbootenv/libzfsbootenv.abi +++ b/lib/libzfsbootenv/libzfsbootenv.abi @@ -8,6 +8,8 @@ + + @@ -225,6 +227,9 @@ + + + @@ -314,6 +319,13 @@ + + + + + + + diff --git a/lib/libzfsbootenv/lzbe_device.c b/lib/libzfsbootenv/lzbe_device.c index f155960bfea0..dc8952f445f5 100644 --- a/lib/libzfsbootenv/lzbe_device.c +++ b/lib/libzfsbootenv/lzbe_device.c @@ -11,14 +11,14 @@ */ /* * Copyright 2020 Toomas Soome + * Copyright (c) 2025, Rob Norris */ #include #include #include #include -#include -#include +#include /* * Store device name to zpool label bootenv area. @@ -31,7 +31,7 @@ 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; + char *bootonce = NULL, *descriptor; uint64_t version; int rv = -1; @@ -53,12 +53,12 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device) if (rv == 0) { /* * We got the nvlist, check for version. - * if version is missing or is not VB_NVLIST, - * create new list. + * if version is missing or is not + * ZFS_BE_VERSION_NVLIST, create new list. */ - rv = nvlist_lookup_uint64(nv, BOOTENV_VERSION, + rv = nvlist_lookup_uint64(nv, ZFS_BE_VERSION, &version); - if (rv == 0 && version == VB_NVLIST) + if (rv == 0 && version == ZFS_BE_VERSION_NVLIST) break; /* Drop this nvlist */ @@ -73,25 +73,28 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device) } /* version is mandatory */ - fnvlist_add_uint64(nv, BOOTENV_VERSION, VB_NVLIST); + fnvlist_add_uint64(nv, ZFS_BE_VERSION, ZFS_BE_VERSION_NVLIST); rv = 0; - /* - * 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); + if (asprintf(&bootonce, "%s:" ZFS_BE_BOOTONCE, + lzbe_loader_get()) == -1) { + rv = ENOMEM; + } else if ((device == NULL || *device == '\0')) { + /* + * If device name is empty, remove boot device configuration. + */ + if (nvlist_exists(nv, bootonce)) + fnvlist_remove(nv, bootonce); } else { /* * Use device name directly if it does start with * prefix "zfs:". Otherwise, add prefix and suffix. */ if (strncmp(device, "zfs:", 4) == 0) { - fnvlist_add_string(nv, OS_BOOTONCE, device); + fnvlist_add_string(nv, bootonce, device); } else { if (asprintf(&descriptor, "zfs:%s:", device) > 0) { - fnvlist_add_string(nv, OS_BOOTONCE, descriptor); + fnvlist_add_string(nv, bootonce, descriptor); free(descriptor); } else rv = ENOMEM; @@ -102,6 +105,9 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device) if (rv != 0) fprintf(stderr, "%s\n", libzfs_error_description(hdl)); + if (bootonce != NULL) + free(bootonce); + fnvlist_free(nv); zpool_close(zphdl); libzfs_fini(hdl); @@ -118,6 +124,7 @@ lzbe_get_boot_device(const char *pool, char **device) zpool_handle_t *zphdl; nvlist_t *nv; const char *val; + char *bootonce = NULL; int rv = -1; if (pool == NULL || *pool == '\0' || device == NULL) @@ -134,7 +141,12 @@ lzbe_get_boot_device(const char *pool, char **device) rv = zpool_get_bootenv(zphdl, &nv); if (rv == 0) { - rv = nvlist_lookup_string(nv, OS_BOOTONCE, &val); + if (asprintf(&bootonce, "%s:" ZFS_BE_BOOTONCE, + lzbe_loader_get()) == -1) + rv = ENOMEM; + } + if (rv == 0) { + rv = nvlist_lookup_string(nv, bootonce, &val); if (rv == 0) { /* * zfs device descriptor is in form of "zfs:dataset:", @@ -156,6 +168,7 @@ lzbe_get_boot_device(const char *pool, char **device) } } nvlist_free(nv); + free(bootonce); } zpool_close(zphdl); diff --git a/lib/libzfsbootenv/lzbe_loader.c b/lib/libzfsbootenv/lzbe_loader.c new file mode 100644 index 000000000000..e6c4287feebf --- /dev/null +++ b/lib/libzfsbootenv/lzbe_loader.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * 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 (c) 2025, Rob Norris + */ + +#include +#include +#include +#include +#include + +/* + * Set a "default" loader name for the target platform. This is the traditional + * behaviour of libzfsbootenv for these platforms that have a dedicated loader + * and integrated tooling. + * + * For anything else, just use "unknown". The application should be setting + * a name to match the loader it is setting up environment for, and if not, at + * least those won't trample anything. + */ +#if defined(__FreeBSD__) +#define LOADER_DEFAULT ZFS_BE_LOADER_FREEBSD +#elif defined(__illumos__) +#define LOADER_DEFAULT ZFS_BE_LOADER_ILLUMOS +#else +#define LOADER_DEFAULT "unknown" +#endif + +#define LOADER_MAXLEN (32) +static char lzbe_loader[LOADER_MAXLEN+1] = LOADER_DEFAULT; + +const char * +lzbe_loader_get(void) +{ + return (lzbe_loader); +} + +int +lzbe_loader_set(const char *loader, size_t len) +{ + if (len > LOADER_MAXLEN) + return (ENAMETOOLONG); + stpncpy(lzbe_loader, loader, LOADER_MAXLEN); + return (0); +} diff --git a/lib/libzfsbootenv/lzbe_pair.c b/lib/libzfsbootenv/lzbe_pair.c index 3f576a569f28..2ef97562e74f 100644 --- a/lib/libzfsbootenv/lzbe_pair.c +++ b/lib/libzfsbootenv/lzbe_pair.c @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include /* * Get or create nvlist. If key is not NULL, get nvlist from bootenv, @@ -98,18 +97,18 @@ lzbe_nvlist_set(const char *pool, const char *key, void *ptr) if (rv == 0) { /* * We got the nvlist, check for version. - * if version is missing or is not VB_NVLIST, - * create new list. + * if version is missing or is not + * ZFS_BE_VERSION_NVLIST, create new list. */ - rv = nvlist_lookup_uint64(nv, BOOTENV_VERSION, + rv = nvlist_lookup_uint64(nv, ZFS_BE_VERSION, &version); - if (rv != 0 || version != VB_NVLIST) { + if (rv != 0 || version != ZFS_BE_VERSION_NVLIST) { /* Drop this nvlist */ fnvlist_free(nv); /* Create and prepare new nvlist */ nv = fnvlist_alloc(); - fnvlist_add_uint64(nv, BOOTENV_VERSION, - VB_NVLIST); + fnvlist_add_uint64(nv, ZFS_BE_VERSION, + ZFS_BE_VERSION_NVLIST); } rv = nvlist_add_nvlist(nv, key, ptr); if (rv == 0) diff --git a/lib/libzpool/include/Makefile.am b/lib/libzpool/include/Makefile.am index 6cfa2d5ce089..420b6f64666b 100644 --- a/lib/libzpool/include/Makefile.am +++ b/lib/libzpool/include/Makefile.am @@ -3,6 +3,5 @@ libzpool_sys_HEADERS = \ %D%/sys/abd_os.h \ %D%/sys/abd_impl_os.h \ %D%/sys/trace_zfs.h \ - %D%/sys/zfs_bootenv_os.h \ %D%/sys/zfs_context_os.h \ %D%/sys/zfs_debug_os.h diff --git a/lib/libzpool/include/sys/zfs_bootenv_os.h b/lib/libzpool/include/sys/zfs_bootenv_os.h deleted file mode 100644 index 44afbb6f5b6b..000000000000 --- a/lib/libzpool/include/sys/zfs_bootenv_os.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2025, Rob Norris - */ - -#ifndef _ZFS_BOOTENV_OS_H -#define _ZFS_BOOTENV_OS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BOOTENV_OS BE_POSIX_VENDOR - -#ifdef __cplusplus -} -#endif - -#endif /* _ZFS_BOOTENV_OS_H */ diff --git a/module/zfs/vdev_label.c b/module/zfs/vdev_label.c index 7e222eac5edc..094f6f7cf169 100644 --- a/module/zfs/vdev_label.c +++ b/module/zfs/vdev_label.c @@ -153,7 +153,6 @@ #include #include #include -#include /* * Basic routines to read and write from a vdev label. @@ -1343,18 +1342,19 @@ vdev_label_read_bootenv(vdev_t *rvd, nvlist_t *bootenv) vbe->vbe_version = ntohll(vbe->vbe_version); switch (vbe->vbe_version) { - case VB_RAW: + case ZFS_BE_VERSION_GRUBENV: /* * if we have textual data in vbe_bootenv, create nvlist * with key "envmap". */ - fnvlist_add_uint64(bootenv, BOOTENV_VERSION, VB_RAW); + fnvlist_add_uint64(bootenv, ZFS_BE_VERSION, + ZFS_BE_VERSION_GRUBENV); vbe->vbe_bootenv[sizeof (vbe->vbe_bootenv) - 1] = '\0'; - fnvlist_add_string(bootenv, GRUB_ENVMAP, + fnvlist_add_string(bootenv, ZFS_BE_GRUB_ENVMAP, vbe->vbe_bootenv); break; - case VB_NVLIST: + case ZFS_BE_VERSION_NVLIST: err = nvlist_unpack(vbe->vbe_bootenv, sizeof (vbe->vbe_bootenv), &config, 0); if (err == 0) { @@ -1367,11 +1367,12 @@ vdev_label_read_bootenv(vdev_t *rvd, nvlist_t *bootenv) /* Check for FreeBSD zfs bootonce command string */ buf = abd_to_buf(abd); if (*buf == '\0') { - fnvlist_add_uint64(bootenv, BOOTENV_VERSION, - VB_NVLIST); + fnvlist_add_uint64(bootenv, ZFS_BE_VERSION, + ZFS_BE_VERSION_NVLIST); break; } - fnvlist_add_string(bootenv, FREEBSD_BOOTONCE, buf); + fnvlist_add_string(bootenv, + ZFS_BE_LOADER_FREEBSD ":" ZFS_BE_BOOTONCE, buf); } /* @@ -1435,16 +1436,30 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env) nvbuf = bootenv->vbe_bootenv; nvsize = sizeof (bootenv->vbe_bootenv); - bootenv->vbe_version = fnvlist_lookup_uint64(env, BOOTENV_VERSION); + bootenv->vbe_version = fnvlist_lookup_uint64(env, ZFS_BE_VERSION); switch (bootenv->vbe_version) { - case VB_RAW: - if (nvlist_lookup_string(env, GRUB_ENVMAP, &tmp) == 0) { + case ZFS_BE_VERSION_GRUBENV: + /* + * The bootenv file is stored as ascii text in the envblock. + * It is used by the GRUB bootloader used on Linux to store the + * contents of the grubenv file. The file is stored as raw + * ASCII, and is protected by an embedded checksum. By default, + * GRUB will check if the boot filesystem supports storing the + * environment data in a special location, and if so, will + * invoke filesystem specific logic to retrieve it. This can be + * overridden by a variable, should the user so desire. + */ + if (nvlist_lookup_string(env, ZFS_BE_GRUB_ENVMAP, &tmp) == 0) { (void) strlcpy(bootenv->vbe_bootenv, tmp, nvsize); } error = 0; break; - case VB_NVLIST: + case ZFS_BE_VERSION_NVLIST: + /* + * The bootenv file is converted to an nvlist and then packed + * into the envblock. + */ error = nvlist_pack(env, &nvbuf, &nvsize, NV_ENCODE_XDR, KM_SLEEP); break; diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 1b2392aeaa85..cbd67d838c25 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -3924,8 +3924,9 @@ zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) * The data is stored as nvlist data stream, and is protected by * an embedded checksum. * The version can have two possible values: - * VB_RAW: nvlist should have key GRUB_ENVMAP, value DATA_TYPE_STRING. - * VB_NVLIST: nvlist with arbitrary pairs. + * ZFS_BE_VERSION_GRUBENV: nvlist should have key ZFS_BE_GRUB_ENVMAP, + * value DATA_TYPE_STRING. + * ZFS_BE_VERSION_NVLIST: nvlist with arbitrary pairs. */ static const zfs_ioc_key_t zfs_keys_set_bootenv[] = { {"version", DATA_TYPE_UINT64, 0}, diff --git a/tests/zfs-tests/cmd/libzfs_input_check.c b/tests/zfs-tests/cmd/libzfs_input_check.c index 4ef249bbd4a1..60348bc93dd4 100644 --- a/tests/zfs-tests/cmd/libzfs_input_check.c +++ b/tests/zfs-tests/cmd/libzfs_input_check.c @@ -27,7 +27,6 @@ #include #include #include -#include #include /* @@ -783,8 +782,8 @@ test_set_bootenv(const char *pool) { nvlist_t *required = fnvlist_alloc(); - fnvlist_add_uint64(required, "version", VB_RAW); - fnvlist_add_string(required, GRUB_ENVMAP, "test"); + fnvlist_add_uint64(required, "version", ZFS_BE_VERSION_GRUBENV); + fnvlist_add_string(required, ZFS_BE_GRUB_ENVMAP, "test"); IOC_INPUT_TEST_WILD(ZFS_IOC_SET_BOOTENV, pool, required, NULL, 0);