git: 5086b6ec32d5 - main - libbe: handle destroying/renaming temporary/bootonce boot environments
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 29 Jan 2024 15:08:25 UTC
The branch main has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=5086b6ec32d5c82c3d0894eb7bd74a9b81480644 commit 5086b6ec32d5c82c3d0894eb7bd74a9b81480644 Author: R. Christian McDonald <rcm@FreeBSD.org> AuthorDate: 2024-01-26 16:39:38 +0000 Commit: R. Christian McDonald <rcm@FreeBSD.org> CommitDate: 2024-01-29 15:07:49 +0000 libbe: handle destroying/renaming temporary/bootonce boot environments When a temporary/bootonce boot environment is renamed, we need to also update the bootenv nvlist on-disk to reflect the new name. Additionally, when a temporary/bootonce boot environment is destroyed, we also need to clear out the on-disk state. Reviewed by: kevans Approved by: kp MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43591 --- lib/libbe/be.c | 23 ++++++++-- lib/libbe/be_impl.h | 1 + lib/libbe/be_info.c | 7 +-- sbin/bectl/tests/bectl_test.sh | 102 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 113 insertions(+), 20 deletions(-) diff --git a/lib/libbe/be.c b/lib/libbe/be.c index c74ec9b0f3dc..e61cfc9d68ae 100644 --- a/lib/libbe/be.c +++ b/lib/libbe/be.c @@ -175,6 +175,9 @@ libbe_init(const char *root) strcmp(altroot, "-") != 0) lbh->altroot_len = strlen(altroot); + (void) lzbe_get_boot_device(zpool_get_name(lbh->active_phandle), + &lbh->bootonce); + return (lbh); err: if (lbh != NULL) { @@ -199,6 +202,8 @@ libbe_close(libbe_handle_t *lbh) if (lbh->active_phandle != NULL) zpool_close(lbh->active_phandle); libzfs_fini(lbh->lzh); + + free(lbh->bootonce); free(lbh); } @@ -443,6 +448,12 @@ be_destroy_internal(libbe_handle_t *lbh, const char *name, int options, return (set_error(lbh, BE_ERR_DESTROYMNT)); } } + + /* Handle destroying bootonce */ + if (lbh->bootonce != NULL && + strcmp(path, lbh->bootonce) == 0) + (void) lzbe_set_boot_device( + zpool_get_name(lbh->active_phandle), lzbe_add, NULL); } else { /* * If we're initially destroying a snapshot, origin options do @@ -1021,11 +1032,17 @@ be_rename(libbe_handle_t *lbh, const char *old, const char *new) .nounmount = 1, }; err = zfs_rename(zfs_hdl, full_new, flags); + if (err != 0) + goto error; + + /* handle renaming bootonce */ + if (lbh->bootonce != NULL && + strcmp(full_old, lbh->bootonce) == 0) + err = be_activate(lbh, new, true); +error: zfs_close(zfs_hdl); - if (err != 0) - return (set_error(lbh, BE_ERR_UNKNOWN)); - return (0); + return (set_error(lbh, err)); } diff --git a/lib/libbe/be_impl.h b/lib/libbe/be_impl.h index d5fd26c4f072..0327f8abaa0a 100644 --- a/lib/libbe/be_impl.h +++ b/lib/libbe/be_impl.h @@ -36,6 +36,7 @@ struct libbe_handle { char root[BE_MAXPATHLEN]; char rootfs[BE_MAXPATHLEN]; char bootfs[BE_MAXPATHLEN]; + char *bootonce; size_t altroot_len; zpool_handle_t *active_phandle; libzfs_handle_t *lzh; diff --git a/lib/libbe/be_info.c b/lib/libbe/be_info.c index 88a9b17bf421..509b56cb8cf5 100644 --- a/lib/libbe/be_info.c +++ b/lib/libbe/be_info.c @@ -181,8 +181,8 @@ prop_list_builder_cb(zfs_handle_t *zfs_hdl, void *data_p) dataset = zfs_get_name(zfs_hdl); nvlist_add_string(props, "dataset", dataset); - if (data->bootonce != NULL && - strcmp(dataset, data->bootonce) == 0) + if (data->lbh->bootonce != NULL && + strcmp(dataset, data->lbh->bootonce) == 0) nvlist_add_boolean_value(props, "bootonce", true); name = strrchr(dataset, '/') + 1; @@ -252,9 +252,6 @@ be_proplist_update(prop_data_t *data) ZFS_TYPE_FILESYSTEM)) == NULL) return (BE_ERR_ZFSOPEN); - (void) lzbe_get_boot_device(zpool_get_name(data->lbh->active_phandle), - &data->bootonce); - /* XXX TODO: some error checking here */ zfs_iter_filesystems(root_hdl, prop_list_builder_cb, data); diff --git a/sbin/bectl/tests/bectl_test.sh b/sbin/bectl/tests/bectl_test.sh index 0f167829cf46..00c71e11de09 100755 --- a/sbin/bectl/tests/bectl_test.sh +++ b/sbin/bectl/tests/bectl_test.sh @@ -93,7 +93,6 @@ bectl_cleanup() atf_test_case bectl_create cleanup bectl_create_head() { - atf_set "descr" "Check the various forms of bectl create" atf_set "require.user" root } @@ -157,7 +156,6 @@ bectl_create_cleanup() atf_test_case bectl_destroy cleanup bectl_destroy_head() { - atf_set "descr" "Check bectl destroy" atf_set "require.user" root } @@ -240,14 +238,12 @@ bectl_destroy_body() } bectl_destroy_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_export_import cleanup bectl_export_import_head() { - atf_set "descr" "Check bectl export and import" atf_set "require.user" root } @@ -278,14 +274,12 @@ bectl_export_import_body() } bectl_export_import_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_list cleanup bectl_list_head() { - atf_set "descr" "Check bectl list" atf_set "require.user" root } @@ -323,14 +317,12 @@ bectl_list_body() } bectl_list_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_mount cleanup bectl_mount_head() { - atf_set "descr" "Check bectl mount/unmount" atf_set "require.user" root } @@ -367,14 +359,12 @@ bectl_mount_body() } bectl_mount_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_rename cleanup bectl_rename_head() { - atf_set "descr" "Check bectl rename" atf_set "require.user" root } @@ -403,14 +393,12 @@ bectl_rename_body() } bectl_rename_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_jail cleanup bectl_jail_head() { - atf_set "descr" "Check bectl rename" atf_set "require.user" root atf_set "require.progs" jail @@ -577,6 +565,94 @@ bectl_promotion_cleanup() bectl_cleanup $(get_zpool_name) } +atf_test_case bectl_destroy_bootonce cleanup +bectl_destroy_bootonce_head() +{ + atf_set "descr" "Check bectl destroy (bootonce)" + atf_set "require.user" root +} +bectl_destroy_bootonce_body() +{ + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "i386" ]; then + atf_skip "https://bugs.freebsd.org/249055" + fi + + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "armv7" ]; then + atf_skip "https://bugs.freebsd.org/249229" + fi + + cwd=$(realpath .) + zpool=$(make_zpool_name) + disk=${cwd}/disk.img + mount=${cwd}/mnt + root=${mount}/root + + be=default2 + + bectl_create_setup ${zpool} ${disk} ${mount} + atf_check -s exit:0 -o empty bectl -r ${zpool}/ROOT create -e default ${be} + + # Create boot environment and bootonce activate it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT activate -t ${be} + atf_check -s exit:0 -o inline:"zfs:${zpool}/ROOT/${be}:\n" zfsbootcfg -z ${zpool} + + # Destroy it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT destroy ${be} + + # Should be empty + atf_check -s exit:0 -o empty zfsbootcfg -z ${zpool} +} +bectl_destroy_bootonce_cleanup() +{ + bectl_cleanup $(get_zpool_name) +} + +atf_test_case bectl_rename_bootonce cleanup +bectl_rename_bootonce_head() +{ + atf_set "descr" "Check bectl destroy (bootonce)" + atf_set "require.user" root +} +bectl_rename_bootonce_body() +{ + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "i386" ]; then + atf_skip "https://bugs.freebsd.org/249055" + fi + + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "armv7" ]; then + atf_skip "https://bugs.freebsd.org/249229" + fi + + cwd=$(realpath .) + zpool=$(make_zpool_name) + disk=${cwd}/disk.img + mount=${cwd}/mnt + root=${mount}/root + + be=default2 + + bectl_create_setup ${zpool} ${disk} ${mount} + atf_check -s exit:0 -o empty bectl -r ${zpool}/ROOT create -e default ${be} + + # Create boot environment and bootonce activate it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT activate -t ${be} + atf_check -s exit:0 -o inline:"zfs:${zpool}/ROOT/${be}:\n" zfsbootcfg -z ${zpool} + + # Rename it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT rename ${be} ${be}_renamed + + # Should be renamed + atf_check -s exit:0 -o inline:"zfs:${zpool}/ROOT/${be}_renamed:\n" zfsbootcfg -z ${zpool} +} +bectl_rename_bootonce_cleanup() +{ + bectl_cleanup $(get_zpool_name) +} + atf_init_test_cases() { atf_add_test_case bectl_create @@ -587,4 +663,6 @@ atf_init_test_cases() atf_add_test_case bectl_rename atf_add_test_case bectl_jail atf_add_test_case bectl_promotion + atf_add_test_case bectl_destroy_bootonce + atf_add_test_case bectl_rename_bootonce }