forked from pool/grub2
Accepting request 959762 from home:michael-chang:branches:Base:System
- Support saving grub environment for POWER signed grub images (jsc#SLE-23854) * 0001-Add-grub_envblk_buf-helper-function.patch * 0002-Add-grub_disk_write_tail-helper-function.patch * 0003-grub-install-support-prep-environment-block.patch * 0004-Introduce-prep_load_env-command.patch * 0005-export-environment-at-start-up.patch - Use enviroment variable in early boot config to looking up root device * grub2.spec OBS-URL: https://build.opensuse.org/request/show/959762 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=406
This commit is contained in:
parent
ec47fa63cf
commit
24522d5d12
68
0001-Add-grub_envblk_buf-helper-function.patch
Normal file
68
0001-Add-grub_envblk_buf-helper-function.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From a326e486bdcf99e6be973ba54c0abfb6d2d95b73 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 17 Jan 2022 17:45:00 +0800
|
||||
Subject: [PATCH 1/5] Add grub_envblk_buf helper function
|
||||
|
||||
This helps in creation and initialization of memory buffer for
|
||||
environment block of given size.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/lib/envblk.c | 12 ++++++++++++
|
||||
include/grub/lib/envblk.h | 1 +
|
||||
util/grub-editenv.c | 4 +---
|
||||
3 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
|
||||
index 2e4e78b132..24efbe7ffa 100644
|
||||
--- a/grub-core/lib/envblk.c
|
||||
+++ b/grub-core/lib/envblk.c
|
||||
@@ -23,6 +23,18 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/lib/envblk.h>
|
||||
|
||||
+char *
|
||||
+grub_envblk_buf (grub_size_t size)
|
||||
+{
|
||||
+ char *buf;
|
||||
+
|
||||
+ buf = grub_malloc (size);
|
||||
+ grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
|
||||
+ grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
grub_envblk_t
|
||||
grub_envblk_open (char *buf, grub_size_t size)
|
||||
{
|
||||
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
|
||||
index c3e6559217..83f3fcf841 100644
|
||||
--- a/include/grub/lib/envblk.h
|
||||
+++ b/include/grub/lib/envblk.h
|
||||
@@ -31,6 +31,7 @@ struct grub_envblk
|
||||
};
|
||||
typedef struct grub_envblk *grub_envblk_t;
|
||||
|
||||
+char *grub_envblk_buf (grub_size_t size);
|
||||
grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
|
||||
int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
|
||||
void grub_envblk_delete (grub_envblk_t envblk, const char *name);
|
||||
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
|
||||
index b8219335f7..a02d3f2a63 100644
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -210,9 +210,7 @@ create_envblk_fs (void)
|
||||
if (! fp)
|
||||
grub_util_error (_("cannot open `%s': %s"), device, strerror (errno));
|
||||
|
||||
- buf = xmalloc (size);
|
||||
- memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
|
||||
- memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
|
||||
+ buf = grub_envblk_buf (size);
|
||||
|
||||
if (fseek (fp, offset, SEEK_SET) < 0)
|
||||
grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
|
||||
--
|
||||
2.34.1
|
||||
|
60
0002-Add-grub_disk_write_tail-helper-function.patch
Normal file
60
0002-Add-grub_disk_write_tail-helper-function.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From c0d00403a297d6023eab6189ba87dc8a3f6d1e85 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 7 Feb 2022 20:44:40 +0800
|
||||
Subject: [PATCH 2/5] Add grub_disk_write_tail helper function
|
||||
|
||||
This helps in writing data to partition where the end of buffer is
|
||||
aligned to end of partition.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/lib/disk.c | 18 ++++++++++++++++++
|
||||
include/grub/disk.h | 3 +++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/grub-core/lib/disk.c b/grub-core/lib/disk.c
|
||||
index b4eb064a81..08e24485f0 100644
|
||||
--- a/grub-core/lib/disk.c
|
||||
+++ b/grub-core/lib/disk.c
|
||||
@@ -51,6 +51,24 @@ grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id,
|
||||
}
|
||||
}
|
||||
|
||||
+grub_err_t
|
||||
+grub_disk_write_tail (grub_disk_t disk, grub_size_t size, const void *buf)
|
||||
+{
|
||||
+ grub_partition_t part;
|
||||
+ grub_disk_addr_t sector;
|
||||
+ grub_off_t offset;
|
||||
+
|
||||
+ if (!disk->partition)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ part = disk->partition;
|
||||
+ sector = part->len;
|
||||
+ sector -= (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS;
|
||||
+ offset = size & (GRUB_DISK_SECTOR_SIZE - 1);
|
||||
+
|
||||
+ return grub_disk_write (disk, sector, offset, size, buf);
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_off_t offset, grub_size_t size, const void *buf)
|
||||
diff --git a/include/grub/disk.h b/include/grub/disk.h
|
||||
index f95aca929a..6d656c4315 100644
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -232,6 +232,9 @@ grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
|
||||
grub_off_t offset,
|
||||
grub_size_t size,
|
||||
void *buf);
|
||||
+grub_err_t grub_disk_write_tail (grub_disk_t disk,
|
||||
+ grub_size_t size,
|
||||
+ const void *buf);
|
||||
grub_err_t grub_disk_write (grub_disk_t disk,
|
||||
grub_disk_addr_t sector,
|
||||
grub_off_t offset,
|
||||
--
|
||||
2.34.1
|
||||
|
97
0003-grub-install-support-prep-environment-block.patch
Normal file
97
0003-grub-install-support-prep-environment-block.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From c31fc5aa0ded9ce1e774d0a3526cfee19be1b77f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 7 Feb 2022 20:49:01 +0800
|
||||
Subject: [PATCH 3/5] grub-install: support prep environment block
|
||||
|
||||
The grub-install can be instructed to create environment block at end of
|
||||
PReP paritition with probed device identities and properties in
|
||||
variables to facilitate root device discovery. So far these variables
|
||||
are defined for this purpose:
|
||||
|
||||
ENV_FS_UUID - The filesystem uuid for the grub root device
|
||||
ENV_CRYPTO_UUID - The crytodisk uuid for the grub root device
|
||||
ENV_GRUB_DIR - The path to grub prefix directory
|
||||
ENV_HINT - The recommended hint string for searching root device
|
||||
|
||||
The size of environment block is defined in GRUB_ENVBLK_PREP_SIZE which
|
||||
is 4096 bytes and can be extended in the future.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
include/grub/lib/envblk.h | 3 +++
|
||||
util/grub-install.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 41 insertions(+)
|
||||
|
||||
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
|
||||
index 83f3fcf841..d01927bcf7 100644
|
||||
--- a/include/grub/lib/envblk.h
|
||||
+++ b/include/grub/lib/envblk.h
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
+#include <grub/disk.h>
|
||||
+#define GRUB_ENVBLK_PREP_SIZE (GRUB_DISK_SECTOR_SIZE << 3)
|
||||
+
|
||||
struct grub_envblk
|
||||
{
|
||||
char *buf;
|
||||
diff --git a/util/grub-install.c b/util/grub-install.c
|
||||
index 8fb5ea616b..7bc5f84378 100644
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <grub/util/ofpath.h>
|
||||
#include <grub/hfsplus.h>
|
||||
#include <grub/time.h>
|
||||
+#include <grub/lib/envblk.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -2112,6 +2113,43 @@ main (int argc, char *argv[])
|
||||
{
|
||||
grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
|
||||
}
|
||||
+
|
||||
+ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0)))
|
||||
+ {
|
||||
+ char *uuid = NULL;
|
||||
+ const char *cryptouuid = NULL;
|
||||
+ grub_envblk_t envblk = NULL;
|
||||
+ char *buf;
|
||||
+
|
||||
+ /* TODO: Add LVM/RAID on encrypted partitions */
|
||||
+ if (grub_dev->disk && grub_dev->disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ cryptouuid = grub_util_cryptodisk_get_uuid (grub_dev->disk);
|
||||
+ if (grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid))
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = 0;
|
||||
+ uuid = NULL;
|
||||
+ }
|
||||
+ buf = grub_envblk_buf (GRUB_ENVBLK_PREP_SIZE);
|
||||
+ envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
|
||||
+ if (uuid)
|
||||
+ grub_envblk_set (envblk, "ENV_FS_UUID", uuid);
|
||||
+ if (cryptouuid)
|
||||
+ grub_envblk_set (envblk, "ENV_CRYPTO_UUID", cryptouuid);
|
||||
+ if (relative_grubdir)
|
||||
+ grub_envblk_set (envblk, "ENV_GRUB_DIR", relative_grubdir);
|
||||
+ if (have_abstractions)
|
||||
+ grub_envblk_set (envblk, "ENV_HINT", grub_dev->disk->name);
|
||||
+ if (use_relative_path_on_btrfs)
|
||||
+ grub_envblk_set (envblk, "btrfs_relative_path", "1");
|
||||
+ if (envblk)
|
||||
+ {
|
||||
+ fprintf (stderr, _("Write environment block to PReP.\n"));
|
||||
+ if (grub_disk_write_tail (ins_dev->disk, envblk->size, envblk->buf))
|
||||
+ grub_util_error ("%s", _("failed to write environment block to the PReP partition"));
|
||||
+ }
|
||||
+ grub_envblk_close (envblk);
|
||||
+ }
|
||||
grub_device_close (ins_dev);
|
||||
if (update_nvram)
|
||||
grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
|
||||
--
|
||||
2.34.1
|
||||
|
269
0004-Introduce-prep_load_env-command.patch
Normal file
269
0004-Introduce-prep_load_env-command.patch
Normal file
@ -0,0 +1,269 @@
|
||||
From 3cf4fdf8d17423dea4e5913ab14fb6305f3c2571 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 18 Feb 2022 21:43:38 +0800
|
||||
Subject: [PATCH 4/5] Introduce prep_load_env command
|
||||
|
||||
This command will accept grub disk device and perform load_env for
|
||||
environment block located at end of PReP partition which belongs to that
|
||||
input disk device. All variables read from that environment block are
|
||||
exported to grub as environment variables.
|
||||
|
||||
Please note there's no support for whitelist variables and also
|
||||
--skip-sig option compared to ordinary load_env command.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 5 +
|
||||
grub-core/commands/prep_loadenv.c | 227 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 232 insertions(+)
|
||||
create mode 100644 grub-core/commands/prep_loadenv.c
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 49bdb63b69..4d529859be 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2624,3 +2624,8 @@ module = {
|
||||
common = lib/libtasn1_wrap/tests/Test_strings.c;
|
||||
common = lib/libtasn1_wrap/wrap_tests.c;
|
||||
};
|
||||
+
|
||||
+module = {
|
||||
+ name = prep_loadenv;
|
||||
+ common = commands/prep_loadenv.c;
|
||||
+};
|
||||
diff --git a/grub-core/commands/prep_loadenv.c b/grub-core/commands/prep_loadenv.c
|
||||
new file mode 100644
|
||||
index 0000000000..f4bb270a2b
|
||||
--- /dev/null
|
||||
+++ b/grub-core/commands/prep_loadenv.c
|
||||
@@ -0,0 +1,227 @@
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/disk.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/env.h>
|
||||
+#include <grub/partition.h>
|
||||
+#include <grub/lib/envblk.h>
|
||||
+#include <grub/extcmd.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/gpt_partition.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+static char *
|
||||
+match_substr (regmatch_t *match, const char *str)
|
||||
+{
|
||||
+ if (match->rm_so != -1)
|
||||
+ {
|
||||
+ char *substr;
|
||||
+ regoff_t sz = match->rm_eo - match->rm_so;
|
||||
+
|
||||
+ if (!sz)
|
||||
+ return NULL;
|
||||
+ substr = grub_malloc (1 + sz);
|
||||
+ if (!substr)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ grub_memcpy (substr, str + match->rm_so, sz);
|
||||
+ substr[sz] = '\0';
|
||||
+ return substr;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_prep_partition (grub_device_t dev)
|
||||
+{
|
||||
+ if (!dev->disk)
|
||||
+ return 0;
|
||||
+ if (!dev->disk->partition)
|
||||
+ return 0;
|
||||
+ if (grub_strcmp (dev->disk->partition->partmap->name, "msdos") == 0)
|
||||
+ return (dev->disk->partition->msdostype == 0x41);
|
||||
+
|
||||
+ if (grub_strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
|
||||
+ {
|
||||
+ struct grub_gpt_partentry gptdata;
|
||||
+ grub_partition_t p = dev->disk->partition;
|
||||
+ int ret = 0;
|
||||
+ dev->disk->partition = dev->disk->partition->parent;
|
||||
+
|
||||
+ if (grub_disk_read (dev->disk, p->offset, p->index,
|
||||
+ sizeof (gptdata), &gptdata) == 0)
|
||||
+ {
|
||||
+ const grub_gpt_part_guid_t template = {
|
||||
+ grub_cpu_to_le32_compile_time (0x9e1a2d38),
|
||||
+ grub_cpu_to_le16_compile_time (0xc612),
|
||||
+ grub_cpu_to_le16_compile_time (0x4316),
|
||||
+ { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
|
||||
+ };
|
||||
+
|
||||
+ ret = grub_memcmp (&template, &gptdata.type,
|
||||
+ sizeof (template)) == 0;
|
||||
+ }
|
||||
+ dev->disk->partition = p;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
|
||||
+{
|
||||
+ char **ret = data;
|
||||
+ char *partition_name, *devname;
|
||||
+ grub_device_t dev;
|
||||
+
|
||||
+ partition_name = grub_partition_get_name (partition);
|
||||
+ if (! partition_name)
|
||||
+ return 2;
|
||||
+
|
||||
+ devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
|
||||
+ grub_free (partition_name);
|
||||
+ if (!devname)
|
||||
+ return 2;
|
||||
+
|
||||
+ dev = grub_device_open (devname);
|
||||
+ if (!dev)
|
||||
+ {
|
||||
+ grub_free (devname);
|
||||
+ return 2;
|
||||
+ }
|
||||
+ if (is_prep_partition (dev))
|
||||
+ {
|
||||
+ *ret = devname;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ grub_free (devname);
|
||||
+ grub_device_close (dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+set_var (const char *name, const char *value,
|
||||
+ void *hook_data __attribute__ ((unused)))
|
||||
+{
|
||||
+ grub_env_set (name, value);
|
||||
+ grub_env_export (name);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+prep_read_envblk (const char *devname)
|
||||
+{
|
||||
+ char *buf = NULL;
|
||||
+ grub_device_t dev = NULL;
|
||||
+ grub_envblk_t envblk = NULL;
|
||||
+
|
||||
+ dev = grub_device_open (devname);
|
||||
+ if (!dev)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (!dev->disk || !dev->disk->partition)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ buf = grub_malloc (GRUB_ENVBLK_PREP_SIZE);
|
||||
+ if (!buf)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (grub_disk_read (dev->disk, dev->disk->partition->len - (GRUB_ENVBLK_PREP_SIZE >> GRUB_DISK_SECTOR_BITS), 0, GRUB_ENVBLK_PREP_SIZE, buf))
|
||||
+ goto fail;
|
||||
+
|
||||
+ envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
|
||||
+ if (!envblk)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ grub_envblk_iterate (envblk, NULL, set_var);
|
||||
+
|
||||
+ fail:
|
||||
+ if (envblk)
|
||||
+ grub_envblk_close (envblk);
|
||||
+ else
|
||||
+ grub_free (buf);
|
||||
+ if (dev)
|
||||
+ grub_device_close (dev);
|
||||
+ return grub_errno;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+prep_partname (const char *devname, char **prep)
|
||||
+{
|
||||
+ grub_device_t dev = NULL;
|
||||
+ grub_err_t err;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev = grub_device_open (devname);
|
||||
+ if (!dev)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ ret = grub_partition_iterate (dev->disk, part_hook, prep);
|
||||
+ if (ret == 1 && *prep)
|
||||
+ {
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (ret == 0 && grub_errno == GRUB_ERR_NONE)
|
||||
+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "no prep partition");
|
||||
+ else
|
||||
+ err = grub_errno;
|
||||
+
|
||||
+ out:
|
||||
+ grub_device_close (dev);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc,
|
||||
+ char **argv)
|
||||
+{
|
||||
+ char *devname, *prep = NULL;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (argc < 1)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
||||
+
|
||||
+ devname = grub_file_get_device_name(argv[0]);
|
||||
+ if (!devname)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ err = prep_partname (devname, &prep);
|
||||
+ if (prep == NULL || err != GRUB_ERR_NONE)
|
||||
+ goto out;
|
||||
+
|
||||
+ err = prep_read_envblk (prep);
|
||||
+
|
||||
+ out:
|
||||
+ grub_free (devname);
|
||||
+ grub_free (prep);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_command_t cmd_prep_load;
|
||||
+
|
||||
+GRUB_MOD_INIT(prep_loadenv)
|
||||
+{
|
||||
+ cmd_prep_load =
|
||||
+ grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
|
||||
+ "DEVICE",
|
||||
+ N_("Load variables from environment block file."));
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI(prep_loadenv)
|
||||
+{
|
||||
+ grub_unregister_command (cmd_prep_load);
|
||||
+}
|
||||
--
|
||||
2.34.1
|
||||
|
177
0005-export-environment-at-start-up.patch
Normal file
177
0005-export-environment-at-start-up.patch
Normal file
@ -0,0 +1,177 @@
|
||||
From 496b6b20cbce3fc27228d1d8290089fb7107b8de Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 18 Feb 2022 21:51:16 +0800
|
||||
Subject: [PATCH 5/5] export environment at start up
|
||||
|
||||
If the prep_loadenv module is built into the core image, it will read
|
||||
the environment block automatically during start up and export all
|
||||
variables. The will ease integration with those without early scripts to
|
||||
running the command.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 2 +
|
||||
grub-core/commands/prep_loadenv.c | 77 +++++++++++++++++++++++++++++++
|
||||
grub-core/kern/env.c | 2 +
|
||||
grub-core/kern/main.c | 3 ++
|
||||
include/grub/env.h | 1 +
|
||||
5 files changed, 85 insertions(+)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 4d529859be..f3140815b8 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2628,4 +2628,6 @@ module = {
|
||||
module = {
|
||||
name = prep_loadenv;
|
||||
common = commands/prep_loadenv.c;
|
||||
+ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
|
||||
+ cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
|
||||
};
|
||||
diff --git a/grub-core/commands/prep_loadenv.c b/grub-core/commands/prep_loadenv.c
|
||||
index f4bb270a2b..4f40f7e41a 100644
|
||||
--- a/grub-core/commands/prep_loadenv.c
|
||||
+++ b/grub-core/commands/prep_loadenv.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/gpt_partition.h>
|
||||
+#include <regex.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -184,6 +185,65 @@ prep_partname (const char *devname, char **prep)
|
||||
return err;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+boot_disk_prep_partname (char **name)
|
||||
+{
|
||||
+ regex_t regex;
|
||||
+ int ret;
|
||||
+ grub_size_t s;
|
||||
+ char *comperr;
|
||||
+ const char *cmdpath;
|
||||
+ regmatch_t *matches = NULL;
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+
|
||||
+ *name = NULL;
|
||||
+
|
||||
+ cmdpath = grub_env_get ("cmdpath");
|
||||
+ if (!cmdpath)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ ret = regcomp (®ex, "\\(([^,]+)(,?.*)?\\)(.*)", REG_EXTENDED);
|
||||
+ if (ret)
|
||||
+ goto fail;
|
||||
+
|
||||
+ matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches));
|
||||
+ if (! matches)
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = regexec (®ex, cmdpath, regex.re_nsub + 1, matches, 0);
|
||||
+ if (!ret)
|
||||
+ {
|
||||
+ char *devname = devname = match_substr (matches + 1, cmdpath);
|
||||
+ if (!devname)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s contains no disk name", cmdpath);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ err = prep_partname (devname, name);
|
||||
+ out:
|
||||
+ grub_free (devname);
|
||||
+ regfree (®ex);
|
||||
+ grub_free (matches);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ fail:
|
||||
+ grub_free (matches);
|
||||
+ s = regerror (ret, ®ex, 0, 0);
|
||||
+ comperr = grub_malloc (s);
|
||||
+ if (!comperr)
|
||||
+ {
|
||||
+ regfree (®ex);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+ regerror (ret, ®ex, comperr, s);
|
||||
+ err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
|
||||
+ regfree (®ex);
|
||||
+ grub_free (comperr);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc,
|
||||
@@ -211,10 +271,27 @@ grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
|
||||
return err;
|
||||
}
|
||||
|
||||
+static void
|
||||
+early_prep_loadenv (void)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+ char *prep;
|
||||
+
|
||||
+ err = boot_disk_prep_partname (&prep);
|
||||
+ if (err == GRUB_ERR_NONE && prep)
|
||||
+ err = prep_read_envblk (prep);
|
||||
+ if (err == GRUB_ERR_BAD_FILE_TYPE || err == GRUB_ERR_FILE_NOT_FOUND)
|
||||
+ grub_error_pop ();
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ grub_print_error ();
|
||||
+ grub_free (prep);
|
||||
+}
|
||||
+
|
||||
static grub_command_t cmd_prep_load;
|
||||
|
||||
GRUB_MOD_INIT(prep_loadenv)
|
||||
{
|
||||
+ early_env_hook = early_prep_loadenv;
|
||||
cmd_prep_load =
|
||||
grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
|
||||
"DEVICE",
|
||||
diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c
|
||||
index c408626423..ec0d268905 100644
|
||||
--- a/grub-core/kern/env.c
|
||||
+++ b/grub-core/kern/env.c
|
||||
@@ -28,6 +28,8 @@ static struct grub_env_context initial_context;
|
||||
/* The current context. */
|
||||
struct grub_env_context *grub_current_context = &initial_context;
|
||||
|
||||
+void (*early_env_hook) (void) = NULL;
|
||||
+
|
||||
/* Return the hash representation of the string S. */
|
||||
static unsigned int
|
||||
grub_env_hashval (const char *s)
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index c7c6d2d0b8..42ea96e39e 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -310,6 +310,9 @@ grub_main (void)
|
||||
|
||||
grub_boot_time ("Before execution of embedded config.");
|
||||
|
||||
+ if (early_env_hook != NULL)
|
||||
+ early_env_hook ();
|
||||
+
|
||||
if (load_config)
|
||||
grub_parser_execute (load_config);
|
||||
|
||||
diff --git a/include/grub/env.h b/include/grub/env.h
|
||||
index 76f832eb94..636e190a21 100644
|
||||
--- a/include/grub/env.h
|
||||
+++ b/include/grub/env.h
|
||||
@@ -68,5 +68,6 @@ grub_env_extractor_open (int source);
|
||||
grub_err_t
|
||||
grub_env_extractor_close (int source);
|
||||
|
||||
+extern void (*EXPORT_VAR (early_env_hook)) (void);
|
||||
|
||||
#endif /* ! GRUB_ENV_HEADER */
|
||||
--
|
||||
2.34.1
|
||||
|
@ -1,3 +1,15 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Mar 4 03:37:40 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Support saving grub environment for POWER signed grub images (jsc#SLE-23854)
|
||||
* 0001-Add-grub_envblk_buf-helper-function.patch
|
||||
* 0002-Add-grub_disk_write_tail-helper-function.patch
|
||||
* 0003-grub-install-support-prep-environment-block.patch
|
||||
* 0004-Introduce-prep_load_env-command.patch
|
||||
* 0005-export-environment-at-start-up.patch
|
||||
- Use enviroment variable in early boot config to looking up root device
|
||||
* grub2.spec
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Mar 1 08:55:57 UTC 2022 - Michal Suchanek <msuchanek@suse.com>
|
||||
|
||||
|
74
grub2.spec
74
grub2.spec
@ -351,6 +351,11 @@ Patch833: 0021-appended-signatures-documentation.patch
|
||||
Patch834: 0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
|
||||
Patch835: 0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch
|
||||
Patch836: 0001-grub-install-Add-SUSE-signed-image-support-for-power.patch
|
||||
Patch837: 0001-Add-grub_envblk_buf-helper-function.patch
|
||||
Patch838: 0002-Add-grub_disk_write_tail-helper-function.patch
|
||||
Patch839: 0003-grub-install-support-prep-environment-block.patch
|
||||
Patch840: 0004-Introduce-prep_load_env-command.patch
|
||||
Patch841: 0005-export-environment-at-start-up.patch
|
||||
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
@ -636,7 +641,7 @@ CD_MODULES="${CD_MODULES} linux"
|
||||
|
||||
GRUB_MODULES="${CD_MODULES} ${FS_MODULES} ${PXE_MODULES} ${CRYPTO_MODULES} mdraid09 mdraid1x lvm serial"
|
||||
%ifarch ppc ppc64 ppc64le
|
||||
GRUB_MODULES="${GRUB_MODULES} appendedsig memdisk tar regexp"
|
||||
GRUB_MODULES="${GRUB_MODULES} appendedsig memdisk tar regexp prep_loadenv"
|
||||
%endif
|
||||
|
||||
%ifarch %{efi}
|
||||
@ -743,39 +748,76 @@ echo "bdev=$bdev"
|
||||
echo "bpart=$bpart"
|
||||
echo "bpath=$bpath"
|
||||
|
||||
if [ "$btrfs_relative_path" = xy ]; then
|
||||
btrfs_relative_path=1
|
||||
fi
|
||||
|
||||
if [ "$bdev" -a "$bpart" -a "$bpath" ]; then
|
||||
hints="--hint $bdev$bpart"
|
||||
cfg_dir="$bpath"
|
||||
set hints="--hint $bdev$bpart"
|
||||
set cfg_dir="$bpath"
|
||||
elif [ "$bdev" -a "$bpart" ]; then
|
||||
hints="--hint $bdev$bpart"
|
||||
cfg_dir="/boot/grub2 /grub2"
|
||||
set hints="--hint $bdev$bpart"
|
||||
set cfg_dir="/boot/grub2 /grub2"
|
||||
set btrfs_relative_path=1
|
||||
elif [ "$bdev" ]; then
|
||||
hints="--hint ${bdev},"
|
||||
cfg_dir="/boot/grub2 /grub2"
|
||||
if [ "$ENV_HINT" ]; then
|
||||
set hints="--hint $ENV_HINT"
|
||||
else
|
||||
set hints="--hint ${bdev},"
|
||||
fi
|
||||
if [ "$ENV_GRUB_DIR" ]; then
|
||||
set cfg_dir="$ENV_GRUB_DIR"
|
||||
else
|
||||
set cfg_dir="/boot/grub2 /grub2"
|
||||
set btrfs_relative_path=1
|
||||
fi
|
||||
else
|
||||
hints=""
|
||||
cfg_dir="/boot/grub2 /grub2"
|
||||
set hints=""
|
||||
set cfg_dir="/boot/grub2 /grub2"
|
||||
set btrfs_relative_path=1
|
||||
fi
|
||||
|
||||
set prefix=""
|
||||
set root=""
|
||||
set cfg="grub.cfg"
|
||||
|
||||
if [ "$ENV_CRYPTO_UUID" ]; then
|
||||
cryptomount -u "$ENV_CRYPTO_UUID"
|
||||
fi
|
||||
|
||||
if [ "$ENV_FS_UUID" ]; then
|
||||
echo "searching for $ENV_FS_UUID with $hints"
|
||||
if search --fs-uuid --set=root "$ENV_FS_UUID" $hints; then
|
||||
echo "$ENV_FS_UUID is on $root"
|
||||
fi
|
||||
fi
|
||||
|
||||
for d in ${cfg_dir}; do
|
||||
set btrfs_relative_path=1
|
||||
echo "start searching for $d/${cfg} with $hints"
|
||||
if search --file --set=root "${d}/${cfg}" $hints; then
|
||||
if [ -z "$root" ]; then
|
||||
echo "searching for ${d}/${cfg}"
|
||||
if search --file --set=root "${d}/${cfg}" $hints; then
|
||||
echo "${d}/${cfg} is on $root"
|
||||
prefix="($root)${d}"
|
||||
fi
|
||||
elif [ -f "${d}/${cfg}" ]; then
|
||||
echo "${d}/${cfg} is on $root"
|
||||
set btrfs_relative_path=0
|
||||
prefix="($root)${d}"
|
||||
else
|
||||
echo "${d}/${cfg} not found in $root"
|
||||
fi
|
||||
|
||||
if [ "$prefix" -a x"$btrfs_relative_path" = x1 ]; then
|
||||
btrfs_relative_path=0
|
||||
if [ -f /@"${d}"/powerpc-ieee1275/command.lst ]; then
|
||||
set btrfs_relative_path=1
|
||||
btrfs_relative_path=1
|
||||
echo "mounting subvolume @${d}/powerpc-ieee1275 on ${d}/powerpc-ieee1275"
|
||||
btrfs-mount-subvol ($root) "${d}"/powerpc-ieee1275 @"${d}"/powerpc-ieee1275
|
||||
fi
|
||||
set btrfs_relative_path=1
|
||||
set prefix="($root)${d}"
|
||||
btrfs_relative_path=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo "prefix=$prefix root=$root"
|
||||
if [ -n "$prefix" ]; then
|
||||
source "${prefix}/${cfg}"
|
||||
|
Loading…
Reference in New Issue
Block a user