git: b765cfa380a4 - main - stand/zfs: Refactor zfs_get_bootonce
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 01 May 2023 21:04:15 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=b765cfa380a47de2b77cbf8a6249e226b0de2275
commit b765cfa380a47de2b77cbf8a6249e226b0de2275
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2023-05-01 15:27:06 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-05-01 21:02:53 +0000
stand/zfs: Refactor zfs_get_bootonce
Lookup the spa and pass it into zfs_get_bootonce_spa to process the boot
once protocol.
Sponsored by: Netflix
Reviewed by: tsoome, kevans
Differential Revision: https://reviews.freebsd.org/D39411
---
stand/libsa/zfs/zfs.c | 23 ++++-------------------
stand/libsa/zfs/zfsimpl.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/stand/libsa/zfs/zfs.c b/stand/libsa/zfs/zfs.c
index 7cdfa1a06df9..8ddd6de8623d 100644
--- a/stand/libsa/zfs/zfs.c
+++ b/stand/libsa/zfs/zfs.c
@@ -827,27 +827,12 @@ zfs_set_bootenv(void *vdev, nvlist_t *benv)
int
zfs_get_bootonce(void *vdev, const char *key, char *buf, size_t size)
{
- nvlist_t *benv;
- char *result = NULL;
- int result_size, rv;
-
- if ((rv = zfs_get_bootenv(vdev, &benv)) != 0)
- return (rv);
+ spa_t *spa;
- if ((rv = nvlist_find(benv, key, DATA_TYPE_STRING, NULL,
- &result, &result_size)) == 0) {
- if (result_size == 0) {
- /* ignore empty string */
- rv = ENOENT;
- } else {
- size = MIN((size_t)result_size + 1, size);
- strlcpy(buf, result, size);
- }
- (void) nvlist_remove(benv, key, DATA_TYPE_STRING);
- (void) zfs_set_bootenv(vdev, benv);
- }
+ if ((spa = spa_find_by_dev((struct zfs_devdesc *)vdev)) == NULL)
+ return (ENXIO);
- return (rv);
+ return (zfs_get_bootonce_spa(spa, key, buf, size));
}
/*
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index 3b093dea3c41..996245b92c45 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -3899,3 +3899,36 @@ zfs_set_bootenv_spa(spa_t *spa, nvlist_t *benv)
spa->spa_bootenv = benv;
return (0);
}
+
+/*
+ * Get bootonce value by key. The bootonce <key, value> pair is removed from the
+ * bootenv nvlist and the remaining nvlist is committed back to disk. This process
+ * the bootonce flag since we've reached the point in the boot that we've 'used'
+ * the BE. For chained boot scenarios, we may reach this point multiple times (but
+ * only remove it and return 0 the first time).
+ */
+static int
+zfs_get_bootonce_spa(spa_t *spa, const char *key, char *buf, size_t size)
+{
+ nvlist_t *benv;
+ char *result = NULL;
+ int result_size, rv;
+
+ if ((rv = zfs_get_bootenv_spa(spa, &benv)) != 0)
+ return (rv);
+
+ if ((rv = nvlist_find(benv, key, DATA_TYPE_STRING, NULL,
+ &result, &result_size)) == 0) {
+ if (result_size == 0) {
+ /* ignore empty string */
+ rv = ENOENT;
+ } else if (buf != NULL) {
+ size = MIN((size_t)result_size + 1, size);
+ strlcpy(buf, result, size);
+ }
+ (void)nvlist_remove(benv, key, DATA_TYPE_STRING);
+ (void)zfs_set_bootenv_spa(spa, benv);
+ }
+
+ return (rv);
+}