From: Colin Walters Date: Tue, 7 Jul 2026 14:59:35 +0000 (-0400) Subject: Revert "sysroot: Merge bootconfig-extra from previously staged deployment" X-Git-Tag: archive/raspbian/2026.4-1+rpi1^2~9^2~1^2~19^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=22e24c817f80de99f7cc5cfb94dd3ba3563b774e;p=ostree.git Revert "sysroot: Merge bootconfig-extra from previously staged deployment" This reverts commit 4c0d3a819033166ec9753ff8c5fdac5db1bac813. The 3-way merge of bootconfig-extra during staging breaks bootc loader-entries set-options-for-source when called multiple times on the same boot. Each call sets the desired x-options-source-* keys on the merge deployment's in-memory bootconfig, but the merge logic gives higher priority to the previously staged data, overriding the caller's updates. This corrupts the source-tracking metadata that bootc relies on to compute override_kernel_argv, causing stale kargs to persist across reboots. The scenario this commit was trying to fix (rpm-ostree re-staging after bootc on the same boot, preserving bootc's extension keys) will need a different approach that does not conflict with callers that update extension keys across multiple stagings. Signed-off-by: Colin Walters --- diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index add835fb..77b601ff 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -3795,25 +3795,14 @@ _ostree_sysroot_ensure_finalize_staged_service (GError **error) return TRUE; } -/* Merge all entries from an a{ss} GVariant into a string→string hash table. - * Used to accumulate bootconfig-extra keys from multiple sources during staging. */ -static void -merge_extra_variant_into_table (GVariant *extra, GHashTable *table) -{ - GVariantIter iter; - const char *k, *v; - g_variant_iter_init (&iter, extra); - while (g_variant_iter_next (&iter, "{&s&s}", &k, &v)) - g_hash_table_insert (table, g_strdup (k), g_strdup (v)); -} - /** * ostree_sysroot_stage_tree_with_options: * @self: Sysroot - * @osname: osname to use for merge deployment + * @osname: (allow-none): osname to use for merge deployment * @revision: Checksum to add * @origin: (allow-none): Origin to use for upgrades - * @opts: (nullable): Options + * @merge_deployment: (allow-none): Use this deployment for merge path + * @opts: Options * @out_new_deployment: (out): The new deployment path * @cancellable: Cancellable * @error: Error @@ -3899,72 +3888,27 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, const char *osname, * These are custom keys set by consumers like bootc and need to survive * the staging roundtrip so they are preserved during finalization at shutdown. * - * Extension keys can come from three sources, merged in increasing - * priority order (higher-priority sources override lower ones for - * the same key): - * - * 1. The merge deployment's bootconfig (on-disk BLS from the - * currently booted or pending deployment) — lowest priority - * 2. The previously staged deployment's bootconfig-extra (a prior - * consumer like bootc may have staged keys that would be lost - * when this new staging replaces the old staged GVariant) - * 3. The new deployment's bootconfig (caller set keys directly) - * — highest priority - * - * This merge ensures that e.g. `bootc loader-entries set-options-for-source` - * followed by `rpm-ostree kargs --append` on the same boot preserves the - * source keys that bootc wrote into the first staged deployment. + * First check the new deployment's bootconfig (in case the caller set keys + * on it directly). If none found, fall back to the merge deployment's + * bootconfig, which carries the keys from the currently deployed BLS entry. + * This ensures that x-prefixed keys are inherited across staged deployments + * even though _ostree_deployment_set_bootconfig_from_kargs() creates a fresh + * bootconfig containing only the "options" key. */ { - g_autoptr (GHashTable) merged_extra - = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - /* Priority 1 (lowest): merge deployment's bootconfig */ - if (merge_deployment) + GVariant *extra = NULL; + OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); + if (bootconfig) + extra = _ostree_bootconfig_parser_get_extra_keys_variant (bootconfig); + if (!extra && merge_deployment) { OstreeBootconfigParser *merge_bootconfig = ostree_deployment_get_bootconfig (merge_deployment); if (merge_bootconfig) - { - g_autoptr (GVariant) merge_extra - = _ostree_bootconfig_parser_get_extra_keys_variant (merge_bootconfig); - if (merge_extra) - merge_extra_variant_into_table (merge_extra, merged_extra); - } - } - - /* Priority 2: previously staged deployment's bootconfig-extra. - * The staged deployment data is already loaded and cached in the - * OstreeSysroot during ostree_sysroot_load(). */ - if (self->staged_deployment_data) - { - g_autoptr (GVariant) prev_extra = g_variant_lookup_value ( - self->staged_deployment_data, "bootconfig-extra", (GVariantType *)"a{ss}"); - if (prev_extra) - merge_extra_variant_into_table (prev_extra, merged_extra); - } - - /* Priority 3 (highest): new deployment's bootconfig */ - { - OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); - if (bootconfig) - { - g_autoptr (GVariant) new_extra - = _ostree_bootconfig_parser_get_extra_keys_variant (bootconfig); - if (new_extra) - merge_extra_variant_into_table (new_extra, merged_extra); - } - } - - if (g_hash_table_size (merged_extra) > 0) - { - g_auto (GVariantBuilder) extra_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_variant_builder_init (&extra_builder, (GVariantType *)"a{ss}"); - GLNX_HASH_TABLE_FOREACH_KV (merged_extra, const char *, k, const char *, v) - g_variant_builder_add (&extra_builder, "{ss}", k, v); - g_variant_builder_add (builder, "{sv}", "bootconfig-extra", - g_variant_builder_end (&extra_builder)); + extra = _ostree_bootconfig_parser_get_extra_keys_variant (merge_bootconfig); } + if (extra) + g_variant_builder_add (builder, "{sv}", "bootconfig-extra", extra); } const char *parent = dirname (strdupa (_OSTREE_SYSROOT_RUNSTATE_STAGED));