2019-02-04 18:19:28 +00:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
|
Date: Wed, 30 Jan 2019 15:08:22 +0100
|
|
|
|
Subject: [PATCH] blscfg: add support for prepend early initrds to the BLS
|
|
|
|
entries
|
|
|
|
|
|
|
|
There are cases where is needed one or more initramfs besides the one that
|
|
|
|
is defined in the BLS entry. For example, a user may want to add an early
|
|
|
|
initramfs to override some ACPI tables, load CPU microcode, firmware, etc.
|
|
|
|
|
|
|
|
Add support to preprend initrds if they are defined as an early_initrd var
|
|
|
|
in grubenv. Also honor GRUB_EARLY_INITRD_LINUX_CUSTOM in /etc/default/grub
|
|
|
|
and use that value to set the early_initrd var when running grub2-mkconfig.
|
|
|
|
|
|
|
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
|
---
|
2019-02-13 12:16:17 +00:00
|
|
|
grub-core/commands/blscfg.c | 79 +++++++++++++++++++++++++++++++++++++++++++--
|
2019-02-04 18:19:28 +00:00
|
|
|
util/grub.d/10_linux.in | 3 ++
|
|
|
|
util/grub.d/10_linux_bls.in | 3 ++
|
2019-02-13 12:16:17 +00:00
|
|
|
3 files changed, 83 insertions(+), 2 deletions(-)
|
2019-02-04 18:19:28 +00:00
|
|
|
|
|
|
|
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
2019-02-13 12:16:17 +00:00
|
|
|
index aa5bf0d3220..1ef2ae06cff 100644
|
2019-02-04 18:19:28 +00:00
|
|
|
--- a/grub-core/commands/blscfg.c
|
|
|
|
+++ b/grub-core/commands/blscfg.c
|
|
|
|
@@ -660,6 +660,33 @@ static char *expand_val(char *value)
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static char **early_initrd_list (const char *initrd)
|
|
|
|
+{
|
|
|
|
+ int nlist = 0;
|
|
|
|
+ char **list = NULL;
|
|
|
|
+ char *separator;
|
|
|
|
+
|
|
|
|
+ while ((separator = grub_strchr (initrd, ' ')))
|
|
|
|
+ {
|
|
|
|
+ list = grub_realloc (list, (nlist + 2) * sizeof (char *));
|
|
|
|
+ if (!list)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ list[nlist++] = grub_strndup(initrd, separator - initrd);
|
|
|
|
+ list[nlist] = NULL;
|
|
|
|
+ initrd = separator + 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ list = grub_realloc (list, (nlist + 2) * sizeof (char *));
|
|
|
|
+ if (!list)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ list[nlist++] = grub_strndup(initrd, grub_strlen(initrd));
|
|
|
|
+ list[nlist] = NULL;
|
|
|
|
+
|
|
|
|
+ return list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static void create_entry (struct bls_entry *entry)
|
|
|
|
{
|
|
|
|
int argc = 0;
|
|
|
|
@@ -670,6 +697,9 @@ static void create_entry (struct bls_entry *entry)
|
|
|
|
char *options = NULL;
|
|
|
|
char **initrds = NULL;
|
|
|
|
char *initrd = NULL;
|
|
|
|
+ const char *early_initrd = NULL;
|
|
|
|
+ char **early_initrds = NULL;
|
|
|
|
+ char *initrd_prefix = NULL;
|
|
|
|
char *id = entry->filename;
|
|
|
|
char *dotconf = id;
|
|
|
|
char *hotkey = NULL;
|
|
|
|
@@ -716,13 +746,47 @@ static void create_entry (struct bls_entry *entry)
|
|
|
|
argv[i] = args[i-1];
|
|
|
|
argv[argc] = NULL;
|
|
|
|
|
|
|
|
+ early_initrd = grub_env_get("early_initrd");
|
|
|
|
+
|
|
|
|
grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n",
|
|
|
|
title, id);
|
|
|
|
- if (initrds)
|
|
|
|
+ if (early_initrd)
|
|
|
|
+ {
|
|
|
|
+ early_initrds = early_initrd_list(early_initrd);
|
|
|
|
+ if (!early_initrds)
|
|
|
|
+ {
|
|
|
|
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
|
|
|
+ goto finish;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (initrds != NULL && initrds[0] != NULL)
|
|
|
|
+ {
|
|
|
|
+ initrd_prefix = grub_strrchr (initrds[0], '/');
|
|
|
|
+ initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ initrd_prefix = grub_strrchr (clinux, '/');
|
|
|
|
+ initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!initrd_prefix)
|
|
|
|
+ {
|
|
|
|
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
|
|
|
+ goto finish;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (early_initrds || initrds)
|
|
|
|
{
|
|
|
|
int initrd_size = sizeof ("initrd");
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
+ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
|
|
|
+ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
|
|
|
|
+ + grub_strlen(initrd_prefix) \
|
|
|
|
+ + grub_strlen (early_initrds[i]) + 1;
|
|
|
|
+
|
|
|
|
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
|
|
|
initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
|
|
|
|
+ grub_strlen (initrds[i]) + 1;
|
2019-02-13 12:16:17 +00:00
|
|
|
@@ -736,7 +800,16 @@ static void create_entry (struct bls_entry *entry)
|
2019-02-04 18:19:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- tmp = grub_stpcpy(initrd, "initrd ");
|
|
|
|
+ tmp = grub_stpcpy(initrd, "initrd");
|
|
|
|
+ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
|
|
|
+ {
|
|
|
|
+ grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
|
|
|
|
+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
|
|
|
+ tmp = grub_stpcpy (tmp, initrd_prefix);
|
|
|
|
+ tmp = grub_stpcpy (tmp, early_initrds[i]);
|
|
|
|
+ grub_free(early_initrds[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
|
2019-02-13 12:16:17 +00:00
|
|
|
@@ -759,6 +832,8 @@ static void create_entry (struct bls_entry *entry)
|
2019-02-04 18:19:28 +00:00
|
|
|
|
|
|
|
finish:
|
|
|
|
grub_free (initrd);
|
|
|
|
+ grub_free (initrd_prefix);
|
|
|
|
+ grub_free (early_initrds);
|
|
|
|
grub_free (initrds);
|
|
|
|
grub_free (options);
|
|
|
|
grub_free (classes);
|
|
|
|
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
|
|
|
index da2992ac9f1..9c240f92625 100644
|
|
|
|
--- a/util/grub.d/10_linux.in
|
|
|
|
+++ b/util/grub.d/10_linux.in
|
|
|
|
@@ -167,6 +167,9 @@ EOF
|
|
|
|
|
|
|
|
if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
|
|
|
|
${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro ${args}"
|
|
|
|
+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
|
|
|
|
+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
|
|
|
|
+ fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
exit 0
|
|
|
|
diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
|
|
|
|
index 175bedd0763..b14951daf82 100644
|
|
|
|
--- a/util/grub.d/10_linux_bls.in
|
|
|
|
+++ b/util/grub.d/10_linux_bls.in
|
|
|
|
@@ -227,6 +227,9 @@ linux_entry ()
|
|
|
|
|
|
|
|
if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
|
|
|
|
${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro ${args}"
|
|
|
|
+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
|
|
|
|
+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
|
|
|
|
+ fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
exit 0
|