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
* 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));