discover/grub: Allow to set a default index for BLS entries
authorJavier Martinez Canillas <javierm@redhat.com>
Tue, 17 Apr 2018 17:09:00 +0000 (19:09 +0200)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Wed, 18 Apr 2018 01:10:48 +0000 (11:10 +1000)
When the BLS support was added, the conclusion was that default indexes
didn't apply for BLS snippets. But for GRUB 2 the indexes refers to the
boot menu entries in memory, regardless of how these were generated.

Since in GRUB 2 is valid to set a default index even for menu entries
generated from BLS fragments, allow this to also be done in Petitboot.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
discover/grub2/blscfg.c
test/parser/Makefile.am
test/parser/test-grub2-blscfg-default-index.c [new file with mode: 0644]

index 5dadd2c6e8efde1ccf2eaf37af2893f4825c1cef..a1076b9db27b5002e2ba984779e881ae092170ad 100644 (file)
@@ -20,6 +20,7 @@
 struct bls_state {
        struct discover_boot_option *opt;
        struct grub2_script *script;
+       unsigned int idx;
        const char *filename;
        const char *title;
        const char *version;
@@ -81,19 +82,25 @@ static void bls_process_pair(struct conf_context *conf, const char *name,
        }
 }
 
-static bool option_is_default(struct grub2_script *script,
+static bool option_is_default(struct bls_state *state,
                              struct boot_option *option)
 {
+       unsigned int idx;
        const char *var;
+       char *end;
 
-       var = script_env_get(script, "default");
+       var = script_env_get(state->script, "default");
        if (!var)
                return false;
 
        if (!strcmp(var, option->id))
                return true;
 
-       return !strcmp(var, option->name);
+       if (!strcmp(var, option->name))
+               return true;
+
+       idx = strtoul(var, &end, 10);
+       return end != var && *end == '\0' && idx == state->idx;
 }
 
 static void bls_finish(struct conf_context *conf)
@@ -141,7 +148,7 @@ static void bls_finish(struct conf_context *conf)
                opt->dtb = create_grub2_resource(opt, conf->dc->device,
                                                 root, state->dtb);
 
-       option->is_default = option_is_default(state->script, option);
+       option->is_default = option_is_default(state, option);
 
        list_add_tail(&state->script->options, &opt->list);
        state->script->n_options++;
@@ -176,6 +183,7 @@ int builtin_blscfg(struct grub2_script *script,
                int argc __attribute__((unused)),
                char *argv[] __attribute__((unused)))
 {
+       unsigned int current_idx = script->n_options;
        struct discover_context *dc = script->ctx;
        struct dirent **bls_entries;
        struct conf_context *conf;
@@ -217,6 +225,7 @@ int builtin_blscfg(struct grub2_script *script,
 
                state->script = script;
                state->filename = filename;
+               state->idx = current_idx++;
                conf->parser_info = state;
 
                rc = parser_request_file(dc, dc->device, filename, &buf, &len);
index 3479d88cdb23c1a33447a525e65414fc1f44668c..6ff3972d8316a32da57d579f2015a0145883fae8 100644 (file)
@@ -41,6 +41,7 @@ parser_TESTS = \
        test/parser/test-grub2-test-file-ops \
        test/parser/test-grub2-single-yocto \
        test/parser/test-grub2-blscfg-default-filename \
+       test/parser/test-grub2-blscfg-default-index \
        test/parser/test-grub2-blscfg-default-title \
        test/parser/test-grub2-blscfg-multiple-bls \
        test/parser/test-grub2-blscfg-opts-config \
diff --git a/test/parser/test-grub2-blscfg-default-index.c b/test/parser/test-grub2-blscfg-default-index.c
new file mode 100644 (file)
index 0000000..4ef3e2e
--- /dev/null
@@ -0,0 +1,45 @@
+#include "parser-test.h"
+
+#if 0 /* PARSER_EMBEDDED_CONFIG */
+set default=2
+menuentry 'title Fedora (4.15-9-304.fc28.x86_64) 28 (Twenty Eight)' {
+       linux   /vmlinuz-4.15-9-301.fc28.x86_64
+}
+
+menuentry 'title Fedora (4.15.6-300.fc28.x86_64) 28 (Twenty Eight)' {
+       linux   /vmlinuz-4.15.6-300.fc28.x86_64
+}
+blscfg
+#endif
+
+void run_test(struct parser_test *test)
+{
+       struct discover_boot_option *opt;
+       struct discover_context *ctx;
+
+       test_add_file_string(test, test->ctx->device,
+                            "/loader/entries/6c063c8e48904f2684abde8eea303f41-4.15.2-300.fc28.x86_64.conf",
+                            "title Fedora (4.15.2-300.fc28.x86_64) 28 (Twenty Eight)\n"
+                            "linux /vmlinuz-4.15.2-300.fc28.x86_64\n"
+                            "initrd /initramfs-4.15.2-300.fc28.x86_64.img\n"
+                            "options root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root\n\n");
+
+       test_add_file_string(test, test->ctx->device,
+                            "/loader/entries/6c063c8e48904f2684abde8eea303f41-4.14.18-300.fc28.x86_64.conf",
+                            "title Fedora (4.14.18-300.fc28.x86_64) 28 (Twenty Eight)\n"
+                            "linux /vmlinuz-4.14.18-300.fc28.x86_64\n"
+                            "initrd /initramfs-4.14.18-300.fc28.x86_64.img\n"
+                            "options root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root\n");
+
+       test_read_conf_embedded(test, "/boot/grub2/grub.cfg");
+
+       test_run_parser(test, "grub2");
+
+       ctx = test->ctx;
+
+       opt = get_boot_option(ctx, 2);
+
+       check_name(opt, "Fedora (4.15.2-300.fc28.x86_64) 28 (Twenty Eight)");
+
+       check_is_default(opt);
+}