summaryrefslogtreecommitdiff
path: root/src/libostree/ostree-bootconfig-parser.c
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javierm@redhat.com>2019-08-27 02:12:29 +0200
committerAtomic Bot <atomic-devel@projectatomic.io>2019-08-29 12:58:43 +0000
commit2ca2b88f51c3131c3aa2322fe26bae2cee7e76fa (patch)
treeed2ce1d185f7fb65825beaa89c7803ee3f60b02b /src/libostree/ostree-bootconfig-parser.c
parentf82f825fed8253b24eeb9c2d5447089348993862 (diff)
downloadostree-2ca2b88f51c3131c3aa2322fe26bae2cee7e76fa.tar.gz
lib/bootconfig-parser: Write BLS fragment fields in a deterministic order
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: https://github.com/ostreedev/ostree/issues/1888 Closes: #1904 Approved by: cgwalters
Diffstat (limited to 'src/libostree/ostree-bootconfig-parser.c')
-rw-r--r--src/libostree/ostree-bootconfig-parser.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/libostree/ostree-bootconfig-parser.c b/src/libostree/ostree-bootconfig-parser.c
index 3d4944cc..67f9fb58 100644
--- a/src/libostree/ostree-bootconfig-parser.c
+++ b/src/libostree/ostree-bootconfig-parser.c
@@ -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,