Skip to content

Commit

Permalink
lib/bootconfig-parser: Write BLS fragment fields in a deterministic o…
Browse files Browse the repository at this point in the history
…rder

Currently the BLS fragments fields write is non-determinisitc. The order
of the fields will depend on how the iterator of the options GHashTable
iterates over the key/value pairs.

But some bootloaders expect the fields to be written in a certain order.
For example the zipl bootloader (used in the s390x architecture) fails to
parse BLS files if the first field is not the 'title' field, since that's
used to name the zipl boot sections that are created from the BLS files.

Write the fields in a deterministic order, following what is used in the
example file of the BootLoaderspec document:

https://systemd.io/BOOT_LOADER_SPECIFICATION

Related: #1888

Closes: #1904
Approved by: cgwalters
  • Loading branch information
martinezjavier authored and rh-atomic-bot committed Aug 29, 2019
1 parent f82f825 commit 2ca2b88
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/libostree/ostree-bootconfig-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,32 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
GCancellable *cancellable,
GError **error)
{
/* Write the fields in a deterministic order, following what is used
* in the bootconfig example of the BootLoaderspec document:
* https://systemd.io/BOOT_LOADER_SPECIFICATION
*/
const char *fields[] = { "title", "version", "options", "devicetree", "linux", "initrd" };
g_autoptr(GHashTable) keys_written = g_hash_table_new (g_str_hash, g_str_equal);
g_autoptr(GString) buf = g_string_new ("");

for (guint i = 0; i < G_N_ELEMENTS (fields); i++)
{
const char *key = fields[i];
const char *value = g_hash_table_lookup (self->options, key);
if (value != NULL)
{
write_key (self, buf, key, value);
g_hash_table_add (keys_written, (gpointer)key);
}
}

/* Write unknown fields */
GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v)
write_key (self, buf, k, v);
{
if (g_hash_table_lookup (keys_written, k))
continue;
write_key (self, buf, k, v);
}

if (!glnx_file_replace_contents_at (dfd, path, (guint8*)buf->str, buf->len,
GLNX_FILE_REPLACE_NODATASYNC,
Expand Down

0 comments on commit 2ca2b88

Please sign in to comment.