From bf36bf56fa8fc16dfbc925ace0c188d04a2bdac4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 30 Nov 2023 18:16:33 -0500 Subject: [PATCH] bootloader/zipl: Run in target deployment as container if needed xref https://issues.redhat.com/browse/MGMT-16303 Basically the OCP Assisted installer has now grown code to try to do OS updates offline post-install, and this means we need to handle the case of running zipl from the target root. --- src/libostree/ostree-bootloader-zipl.c | 39 +++++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c index 42cae8241d..02dce42350 100644 --- a/src/libostree/ostree-bootloader-zipl.c +++ b/src/libostree/ostree-bootloader-zipl.c @@ -434,10 +434,19 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, int bootver if (getuid () != 0) return TRUE; - /* Note that unlike the grub2-mkconfig backend, we make no attempt to - * chroot(). - */ - g_assert (self->sysroot->booted_deployment); + // If we're in a booted deployment, we don't need to spawn a container. + // Also avoid containerizing if there's no deployments to target, which shouldn't + // generally happen. + OstreeDeployment *target_deployment; + if (self->sysroot->booted_deployment || self->sysroot->deployments->len == 0) + { + target_deployment = NULL; + } + else + { + g_assert_cmpint (self->sysroot->deployments->len, >, 0); + target_deployment = self->sysroot->deployments->pdata[0]; + } if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, zipl_requires_execute_path, NULL, 0, error)) @@ -467,9 +476,25 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, int bootver const char *const zipl_argv[] = { "zipl", "--secure", (sb_enabled == TRUE) ? "1" : "auto", "-V", NULL }; int estatus; - if (!g_spawn_sync (NULL, (char **)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, - &estatus, error)) - return FALSE; + if (target_deployment != NULL) + { + g_debug ("executing zipl in deployment root"); + g_autofree char *deployment_path + = ostree_sysroot_get_deployment_dirpath (self->sysroot, target_deployment); + glnx_autofd int deployment_dfd = -1; + if (!glnx_opendirat (self->sysroot->sysroot_fd, deployment_path, TRUE, &deployment_dfd, + error)) + return FALSE; + if (!_ostree_sysroot_run_in_deployment (deployment_dfd, zipl_argv, &estatus, NULL, error)) + return glnx_prefix_error (error, "Failed to invoke zipl"); + } + else + { + g_debug ("executing zipl from booted system"); + if (!g_spawn_sync (NULL, (char **)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, + NULL, &estatus, error)) + return FALSE; + } if (!g_spawn_check_exit_status (estatus, error)) return FALSE; if (!glnx_unlinkat (self->sysroot->sysroot_fd, zipl_requires_execute_path, 0, error))