lib/bootconfig: Add support for multiple initrd keys

Prep for actually teaching the rest of the codebase about this.

We keep the primary initrd in the `options` hash table for backwards
compatibility.
This commit is contained in:
Jonathan Lebon 2020-08-17 09:48:16 -04:00
parent a5f9651dab
commit f7500bb703
4 changed files with 81 additions and 2 deletions

View File

@ -37,6 +37,8 @@ ostree_bootconfig_parser_write
ostree_bootconfig_parser_write_at ostree_bootconfig_parser_write_at
ostree_bootconfig_parser_set ostree_bootconfig_parser_set
ostree_bootconfig_parser_get ostree_bootconfig_parser_get
ostree_bootconfig_parser_set_overlay_initrds
ostree_bootconfig_parser_get_overlay_initrds
<SUBSECTION Standard> <SUBSECTION Standard>
OSTREE_BOOTCONFIG_PARSER OSTREE_BOOTCONFIG_PARSER
OSTREE_IS_BOOTCONFIG_PARSER OSTREE_IS_BOOTCONFIG_PARSER

View File

@ -24,6 +24,8 @@ global:
*/ */
ostree_repo_static_delta_execute_offline_with_signature; ostree_repo_static_delta_execute_offline_with_signature;
ostree_repo_static_delta_verify_signature; ostree_repo_static_delta_verify_signature;
ostree_bootconfig_parser_get_overlay_initrds;
ostree_bootconfig_parser_set_overlay_initrds;
} LIBOSTREE_2020.4; } LIBOSTREE_2020.4;
/* Stub section for the stable release *after* this development one; don't /* Stub section for the stable release *after* this development one; don't

View File

@ -30,6 +30,9 @@ struct _OstreeBootconfigParser
const char *separators; const char *separators;
GHashTable *options; GHashTable *options;
/* Additional initrds; the primary initrd is in options. */
char **overlay_initrds;
}; };
typedef GObjectClass OstreeBootconfigParserClass; typedef GObjectClass OstreeBootconfigParserClass;
@ -50,6 +53,8 @@ ostree_bootconfig_parser_clone (OstreeBootconfigParser *self)
GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v)
g_hash_table_replace (parser->options, g_strdup (k), g_strdup (v)); g_hash_table_replace (parser->options, g_strdup (k), g_strdup (v));
parser->overlay_initrds = g_strdupv (self->overlay_initrds);
return parser; return parser;
} }
@ -76,6 +81,8 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
if (!contents) if (!contents)
return FALSE; return FALSE;
g_autoptr(GPtrArray) overlay_initrds = NULL;
g_auto(GStrv) lines = g_strsplit (contents, "\n", -1); g_auto(GStrv) lines = g_strsplit (contents, "\n", -1);
for (char **iter = lines; *iter; iter++) for (char **iter = lines; *iter; iter++)
{ {
@ -86,9 +93,20 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
char **items = NULL; char **items = NULL;
items = g_strsplit_set (line, self->separators, 2); items = g_strsplit_set (line, self->separators, 2);
if (g_strv_length (items) == 2 && items[0][0] != '\0') if (g_strv_length (items) == 2 && items[0][0] != '\0')
{
if (g_str_equal (items[0], "initrd") &&
g_hash_table_contains (self->options, "initrd"))
{
if (!overlay_initrds)
overlay_initrds = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (overlay_initrds, items[1]);
g_free (items[0]);
}
else
{ {
g_hash_table_insert (self->options, items[0], items[1]); g_hash_table_insert (self->options, items[0], items[1]);
g_free (items); /* Transfer ownership */ }
g_free (items); /* Free container; we stole the elements */
} }
else else
{ {
@ -97,6 +115,12 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
} }
} }
if (overlay_initrds)
{
g_ptr_array_add (overlay_initrds, NULL);
self->overlay_initrds = (char**)g_ptr_array_free (g_steal_pointer (&overlay_initrds), FALSE);
}
self->parsed = TRUE; self->parsed = TRUE;
return TRUE; return TRUE;
@ -127,6 +151,41 @@ ostree_bootconfig_parser_get (OstreeBootconfigParser *self,
return g_hash_table_lookup (self->options, key); return g_hash_table_lookup (self->options, key);
} }
/**
* ostree_bootconfig_parser_set_overlay_initrds:
* @self: Parser
* @initrds: (array zero-terminated=1) (transfer none) (allow-none): Array of overlay
* initrds or %NULL to unset.
*
* These are rendered as additional `initrd` keys in the final bootloader configs. The
* base initrd is part of the primary keys.
*
* Since: 2020.7
*/
void
ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self,
char **initrds)
{
g_assert (g_hash_table_contains (self->options, "initrd"));
g_strfreev (self->overlay_initrds);
self->overlay_initrds = g_strdupv (initrds);
}
/**
* ostree_bootconfig_parser_get_overlay_initrds:
* @self: Parser
*
* Returns: (array zero-terminated=1) (transfer none) (nullable): Array of initrds or %NULL
* if none are set.
*
* Since: 2020.7
*/
char**
ostree_bootconfig_parser_get_overlay_initrds (OstreeBootconfigParser *self)
{
return self->overlay_initrds;
}
static void static void
write_key (OstreeBootconfigParser *self, write_key (OstreeBootconfigParser *self,
GString *buf, GString *buf,
@ -165,6 +224,15 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
} }
} }
/* Write overlay initrds */
if (self->overlay_initrds && (g_strv_length (self->overlay_initrds) > 0))
{
/* we should've written the primary initrd already */
g_assert (g_hash_table_contains (keys_written, "initrd"));
for (char **it = self->overlay_initrds; it && *it; it++)
write_key (self, buf, "initrd", *it);
}
/* Write unknown fields */ /* Write unknown fields */
GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v)
{ {
@ -197,6 +265,7 @@ ostree_bootconfig_parser_finalize (GObject *object)
{ {
OstreeBootconfigParser *self = OSTREE_BOOTCONFIG_PARSER (object); OstreeBootconfigParser *self = OSTREE_BOOTCONFIG_PARSER (object);
g_strfreev (self->overlay_initrds);
g_hash_table_unref (self->options); g_hash_table_unref (self->options);
G_OBJECT_CLASS (ostree_bootconfig_parser_parent_class)->finalize (object); G_OBJECT_CLASS (ostree_bootconfig_parser_parent_class)->finalize (object);

View File

@ -73,5 +73,11 @@ _OSTREE_PUBLIC
const char *ostree_bootconfig_parser_get (OstreeBootconfigParser *self, const char *ostree_bootconfig_parser_get (OstreeBootconfigParser *self,
const char *key); const char *key);
_OSTREE_PUBLIC
void ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self,
char **initrds);
_OSTREE_PUBLIC
char** ostree_bootconfig_parser_get_overlay_initrds (OstreeBootconfigParser *self);
G_END_DECLS G_END_DECLS