summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--discover/grub2/blscfg.c85
-rw-r--r--test/parser/test-grub2-blscfg-multiple-bls.c5
-rw-r--r--test/parser/test-grub2-blscfg-opts-grubenv.c4
3 files changed, 74 insertions, 20 deletions
diff --git a/discover/grub2/blscfg.c b/discover/grub2/blscfg.c
index a381306..d4754aa 100644
--- a/discover/grub2/blscfg.c
+++ b/discover/grub2/blscfg.c
@@ -2,6 +2,7 @@
#define _GNU_SOURCE
#include <assert.h>
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
@@ -34,54 +35,106 @@ struct bls_state {
const char *dtb;
};
+static char *field_append(struct bls_state *state, int type, char *buffer,
+ char *start, char *end)
+{
+ char *temp = talloc_strndup(state, start, end - start + 1);
+ const char *field = temp;
+
+ if (type == GRUB2_WORD_VAR) {
+ field = script_env_get(state->script, temp);
+ if (!field)
+ return buffer;
+ }
+
+ if (!buffer)
+ buffer = talloc_strdup(state->opt, field);
+ else
+ buffer = talloc_asprintf_append(buffer, "%s", field);
+
+ return buffer;
+}
+
+static char *expand_field(struct bls_state *state, char *value)
+{
+ char *buffer = NULL;
+ char *start = value;
+ char *end = value;
+ int type = GRUB2_WORD_TEXT;
+
+ while (*value) {
+ if (*value == '$') {
+ if (start != end) {
+ buffer = field_append(state, type, buffer,
+ start, end);
+ if (!buffer)
+ return NULL;
+ }
+
+ type = GRUB2_WORD_VAR;
+ start = value + 1;
+ } else if (type == GRUB2_WORD_VAR) {
+ if (!isalnum(*value) && *value != '_') {
+ buffer = field_append(state, type, buffer,
+ start, end);
+ type = GRUB2_WORD_TEXT;
+ start = value;
+ }
+ }
+
+ end = value;
+ value++;
+ }
+
+ if (start != end) {
+ buffer = field_append(state, type, buffer,
+ start, end);
+ if (!buffer)
+ return NULL;
+ }
+
+ return buffer;
+}
+
static void bls_process_pair(struct conf_context *conf, const char *name,
char *value)
{
struct bls_state *state = conf->parser_info;
struct discover_boot_option *opt = state->opt;
struct boot_option *option = opt->option;
- const char *boot_args;
if (streq(name, "title")) {
- state->title = talloc_strdup(state, value);
+ state->title = expand_field(state, value);
return;
}
if (streq(name, "version")) {
- state->version = talloc_strdup(state, value);
+ state->version = expand_field(state, value);
return;
}
if (streq(name, "machine-id")) {
- state->machine_id = talloc_strdup(state, value);
+ state->machine_id = expand_field(state, value);
return;
}
if (streq(name, "linux")) {
- state->image = talloc_strdup(state, value);
+ state->image = expand_field(state, value);
return;
}
if (streq(name, "initrd")) {
- state->initrd = talloc_strdup(state, value);
+ state->initrd = expand_field(state, value);
return;
}
if (streq(name, "devicetree")) {
- state->dtb = talloc_strdup(state, value);
+ state->dtb = expand_field(state, value);
return;
}
if (streq(name, "options")) {
- if (value[0] == '$') {
- boot_args = script_env_get(state->script, value + 1);
- if (!boot_args)
- return;
-
- option->boot_args = talloc_strdup(opt, boot_args);
- } else {
- option->boot_args = talloc_strdup(opt, value);
- }
+ option->boot_args = expand_field(state, value);
return;
}
}
diff --git a/test/parser/test-grub2-blscfg-multiple-bls.c b/test/parser/test-grub2-blscfg-multiple-bls.c
index 94f40d1..d15fb24 100644
--- a/test/parser/test-grub2-blscfg-multiple-bls.c
+++ b/test/parser/test-grub2-blscfg-multiple-bls.c
@@ -1,6 +1,7 @@
#include "parser-test.h"
#if 0 /* PARSER_EMBEDDED_CONFIG */
+set os_name=Fedora
blscfg
#endif
@@ -13,14 +14,14 @@ void run_test(struct parser_test *test)
test_add_file_string(test, test->ctx->device,
"/loader/entries/6c063c8e48904f2684abde8eea303f41-4.15.2-302.fc28.x86_64.conf",
- "title Fedora (4.15.2-302.fc28.x86_64) 28 (Twenty Eight)\n"
+ "title $os_name (4.15.2-302.fc28.x86_64) 28 (Twenty Eight)\n"
"linux /vmlinuz-4.15.2-302.fc28.x86_64\n"
"initrd /initramfs-4.15.2-302.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"
+ "title $os_name (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");
diff --git a/test/parser/test-grub2-blscfg-opts-grubenv.c b/test/parser/test-grub2-blscfg-opts-grubenv.c
index 544a5de..2dffd1b 100644
--- a/test/parser/test-grub2-blscfg-opts-grubenv.c
+++ b/test/parser/test-grub2-blscfg-opts-grubenv.c
@@ -22,7 +22,7 @@ void run_test(struct parser_test *test)
"title Fedora (4.15.2-302.fc28.x86_64) 28 (Twenty Eight)\n"
"linux /vmlinuz-4.15.2-302.fc28.x86_64\n"
"initrd /initramfs-4.15.2-302.fc28.x86_64.img\n"
- "options $kernelopts\n");
+ "options $kernelopts debug\n");
test_read_conf_embedded(test, "/boot/grub2/grub.cfg");
@@ -32,5 +32,5 @@ void run_test(struct parser_test *test)
opt = get_boot_option(ctx, 0);
- check_args(opt, "root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root");
+ check_args(opt, "root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root debug");
}
OpenPOWER on IntegriCloud