|
|
d9d99f |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
d9d99f |
From: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
d9d99f |
Date: Wed, 18 Jul 2018 08:08:02 +0200
|
|
|
d9d99f |
Subject: [PATCH] blscfg: Expand the BLS options field instead of showing its
|
|
|
d9d99f |
variables
|
|
|
d9d99f |
|
|
|
d9d99f |
The values of the BLS fragment fields can either be string literals or
|
|
|
d9d99f |
grub2 environment variables, the latter will be expanded by grub2 when
|
|
|
d9d99f |
the boot entry is selected.
|
|
|
d9d99f |
|
|
|
d9d99f |
But from a usability point of view, is much more convenient if the BLS
|
|
|
d9d99f |
parse code expand any variables that are present in the options field.
|
|
|
d9d99f |
|
|
|
d9d99f |
That will allow users to select an entry in the menu by pressing the e
|
|
|
d9d99f |
key and edit the kernel command line parameters. So for example instead
|
|
|
d9d99f |
of showing the following:
|
|
|
d9d99f |
|
|
|
d9d99f |
kernel /boot/vmlinuz-4.17.0 $kernelopts
|
|
|
d9d99f |
|
|
|
d9d99f |
It would show something like the following:
|
|
|
d9d99f |
|
|
|
d9d99f |
kernel /boot/vmlinuz-4.17.0 root=UUID=cec677c9-c890-4103-b94a-bcc191642935
|
|
|
d9d99f |
|
|
|
d9d99f |
Suggested-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
d9d99f |
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
d9d99f |
---
|
|
|
d9d99f |
grub-core/commands/blscfg.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
d9d99f |
1 file changed, 68 insertions(+), 1 deletion(-)
|
|
|
d9d99f |
|
|
|
d9d99f |
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
|
|
d9d99f |
index c6addc4dc12..80d8814fc3f 100644
|
|
|
d9d99f |
--- a/grub-core/commands/blscfg.c
|
|
|
d9d99f |
+++ b/grub-core/commands/blscfg.c
|
|
|
d9d99f |
@@ -32,6 +32,8 @@
|
|
|
d9d99f |
#include <grub/normal.h>
|
|
|
d9d99f |
#include <grub/lib/envblk.h>
|
|
|
d9d99f |
|
|
|
d9d99f |
+#include <stdbool.h>
|
|
|
d9d99f |
+
|
|
|
d9d99f |
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
d9d99f |
|
|
|
d9d99f |
#include "loadenv.h"
|
|
|
d9d99f |
@@ -506,6 +508,70 @@ static char **bls_make_list (struct bls_entry *entry, const char *key, int *num)
|
|
|
d9d99f |
return list;
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
+static char *field_append(bool is_var, char *buffer, char *start, char *end)
|
|
|
d9d99f |
+{
|
|
|
d9d99f |
+ char *temp = grub_strndup(start, end - start + 1);
|
|
|
d9d99f |
+ const char *field = temp;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (is_var) {
|
|
|
d9d99f |
+ field = grub_env_get (temp);
|
|
|
d9d99f |
+ if (!field)
|
|
|
d9d99f |
+ return buffer;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (!buffer) {
|
|
|
d9d99f |
+ buffer = grub_strdup(field);
|
|
|
d9d99f |
+ if (!buffer)
|
|
|
d9d99f |
+ return NULL;
|
|
|
d9d99f |
+ } else {
|
|
|
d9d99f |
+ buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field));
|
|
|
d9d99f |
+ if (!buffer)
|
|
|
d9d99f |
+ return NULL;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ grub_stpcpy (buffer + grub_strlen(buffer), field);
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ return buffer;
|
|
|
d9d99f |
+}
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+static char *expand_val(char *value)
|
|
|
d9d99f |
+{
|
|
|
d9d99f |
+ char *buffer = NULL;
|
|
|
d9d99f |
+ char *start = value;
|
|
|
d9d99f |
+ char *end = value;
|
|
|
d9d99f |
+ bool is_var = false;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ while (*value) {
|
|
|
d9d99f |
+ if (*value == '$') {
|
|
|
d9d99f |
+ if (start != end) {
|
|
|
d9d99f |
+ buffer = field_append(is_var, buffer, start, end);
|
|
|
d9d99f |
+ if (!buffer)
|
|
|
d9d99f |
+ return NULL;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ is_var = true;
|
|
|
d9d99f |
+ start = value + 1;
|
|
|
d9d99f |
+ } else if (is_var) {
|
|
|
d9d99f |
+ if (!grub_isalnum(*value) && *value != '_') {
|
|
|
d9d99f |
+ buffer = field_append(is_var, buffer, start, end);
|
|
|
d9d99f |
+ is_var = false;
|
|
|
d9d99f |
+ start = value;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ end = value;
|
|
|
d9d99f |
+ value++;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (start != end) {
|
|
|
d9d99f |
+ buffer = field_append(is_var, buffer, start, end);
|
|
|
d9d99f |
+ if (!buffer)
|
|
|
d9d99f |
+ return NULL;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ return buffer;
|
|
|
d9d99f |
+}
|
|
|
d9d99f |
+
|
|
|
d9d99f |
static void create_entry (struct bls_entry *entry)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
int argc = 0;
|
|
|
d9d99f |
@@ -536,7 +602,7 @@ static void create_entry (struct bls_entry *entry)
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
title = bls_get_val (entry, "title", NULL);
|
|
|
d9d99f |
- options = bls_get_val (entry, "options", NULL);
|
|
|
d9d99f |
+ options = expand_val (bls_get_val (entry, "options", NULL));
|
|
|
d9d99f |
initrds = bls_make_list (entry, "initrd", NULL);
|
|
|
d9d99f |
|
|
|
d9d99f |
hotkey = bls_get_val (entry, "grub_hotkey", NULL);
|
|
|
d9d99f |
@@ -594,6 +660,7 @@ static void create_entry (struct bls_entry *entry)
|
|
|
d9d99f |
finish:
|
|
|
d9d99f |
grub_free (initrd);
|
|
|
d9d99f |
grub_free (initrds);
|
|
|
d9d99f |
+ grub_free (options);
|
|
|
d9d99f |
grub_free (classes);
|
|
|
d9d99f |
grub_free (args);
|
|
|
d9d99f |
grub_free (argv);
|