From e068e8634ca2042246f4577ab7c42a7c1f19f7d9 Mon Sep 17 00:00:00 2001 From: Robert Fairley Date: Thu, 14 Feb 2019 16:18:01 -0500 Subject: [PATCH] Add sysroot.bootloader repo config key The sysroot.bootloader key is used to configure the bootloader that OSTree uses when deploying a sysroot. Having this key allows specifying behavior not to use the default bootloader backend code, which is preferable when creating a first deployment from the sysroot (#1774). As of now, the key can take the values "auto" or "none". If the key is not given, the value defaults to "auto". "auto" causes _ostree_sysroot_query_bootloader() to be used when writing a new deployment, which is the original behavior that dynamically detects which bootloader to use. "none" avoids querying the bootloader dynamically. The BLS config fragments are still written to sysroot/boot/loader/entries for use by higher-level software. More values can be supported in future to specify a single bootloader, different behavior for the bootloader code, or a list of bootloaders to try. Resolves: #1774 --- src/libostree/ostree-repo-private.h | 1 + src/libostree/ostree-repo.c | 50 +++++++++++++++++++++++++++ src/libostree/ostree-repo.h | 3 ++ src/libostree/ostree-sysroot-deploy.c | 29 ++++++++++++++-- 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 40be72633d..6bc74c2d23 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -169,6 +169,7 @@ struct OstreeRepo { guint64 payload_link_threshold; gint fs_support_reflink; /* The underlying filesystem has support for ioctl (FICLONE..) */ gchar **repo_finders; + gchar *bootloader; /* Configure which bootloader to use. */ OstreeRepo *parent_repo; }; diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 37a6cdf0d2..418fbe1c0c 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3113,6 +3113,36 @@ reload_remote_config (OstreeRepo *self, return TRUE; } +static gboolean +reload_sysroot_config (OstreeRepo *self, + GCancellable *cancellable, + GError **error) +{ + { g_autofree char *bootloader = NULL; + + if (!ot_keyfile_get_value_with_default (self->config, "sysroot", + "bootloader", "auto", + &bootloader, error)) + return FALSE; + + if (bootloader == NULL) + return glnx_throw (error, "Invalid empty bootloader configuration"); + + /* Can later add support for specifying a single bootloader e.g. + * "grub", "sd-boot", "rpi" here too. See: + * https://github.com/ostreedev/ostree/issues/1719 + * https://github.com/ostreedev/ostree/issues/1801 + */ + if (strcmp (bootloader, "auto") != 0 && + strcmp (bootloader, "none") != 0) + return glnx_throw (error, "Invalid configured bootloader '%s'", bootloader); + + self->bootloader = g_steal_pointer (&bootloader); + } + + return TRUE; +} + /** * ostree_repo_reload_config: * @self: repo @@ -3131,6 +3161,8 @@ ostree_repo_reload_config (OstreeRepo *self, return FALSE; if (!reload_remote_config (self, cancellable, error)) return FALSE; + if (!reload_sysroot_config (self, cancellable, error)) + return FALSE; return TRUE; } @@ -6060,3 +6092,21 @@ ostree_repo_get_default_repo_finders (OstreeRepo *self) return (const gchar * const *)self->repo_finders; } + +/** + * ostree_repo_get_bootloader: + * @self: an #OstreeRepo + * + * Get the bootloader configured. See the documentation for the + * "sysroot.bootloader" config key. + * + * Returns: bootloader configuration for the sysroot + * Since: 2019.3 + */ +const gchar * +ostree_repo_get_bootloader (OstreeRepo *self) +{ + g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); + + return self->bootloader; +} diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 6e325b8b30..7eb983cfa0 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -115,6 +115,9 @@ gboolean ostree_repo_set_collection_id (OstreeRepo *self, _OSTREE_PUBLIC const gchar * const * ostree_repo_get_default_repo_finders (OstreeRepo *self); +_OSTREE_PUBLIC +const gchar * ostree_repo_get_bootloader (OstreeRepo *self); + _OSTREE_PUBLIC GFile * ostree_repo_get_path (OstreeRepo *self); diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index b16f65b334..ce7e3a6208 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -2077,6 +2077,7 @@ write_deployments_bootswap (OstreeSysroot *self, cancellable, error)) return FALSE; + // TODO: move this to ostree_sysroot_write_deployments_with_options? /* Need the repo to try and extract the versions for deployments. * But this is a "nice-to-have" for the bootloader UI, so failure * here is not fatal to the whole operation. We just gracefully @@ -2310,6 +2311,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, gboolean bootloader_is_atomic = FALSE; SyncStats syncstats = { 0, }; g_autoptr(OstreeBootloader) bootloader = NULL; + g_autofree const char *bootloader_config = NULL; if (!requires_new_bootversion) { if (!create_new_bootlinks (self, self->bootversion, @@ -2342,8 +2344,30 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, return glnx_throw_errno_prefix (error, "Remounting /boot read-write"); } - if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error)) - return FALSE; + g_autoptr(OstreeRepo) repo = NULL; + if (!ostree_sysroot_get_repo (self, &repo, cancellable, error)) + { + return glnx_throw (error, "Getting repo config"); + } + + bootloader_config = ostree_repo_get_bootloader (repo); + + g_debug ("Using bootloader configuration: %s", bootloader_config); + + if (g_strcmp0 (bootloader_config, "auto") == 0) + { + if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error)) + return FALSE; + } + else if (g_strcmp0 (bootloader_config, "none") == 0) + { + /* No bootloader specified; do not query bootloaders to run. */ + } + else + { + return glnx_throw (error, "Invalid configured bootloader '%s'", bootloader_config); + } + bootloader_is_atomic = bootloader != NULL && _ostree_bootloader_is_atomic (bootloader); /* Note equivalent of try/finally here */ @@ -2375,6 +2399,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_COMPLETE_ID), "MESSAGE=%s", msg, "OSTREE_BOOTLOADER=%s", bootloader ? _ostree_bootloader_get_name (bootloader) : "none", + "OSTREE_BOOTLOADER_CONFIG=%s", bootloader_config, "OSTREE_BOOTLOADER_ATOMIC=%s", bootloader_is_atomic ? "yes" : "no", "OSTREE_DID_BOOTSWAP=%s", requires_new_bootversion ? "yes" : "no", "OSTREE_N_DEPLOYMENTS=%u", new_deployments->len,