diff --git a/0001-Add-grub_envblk_buf-helper-function.patch b/0001-Add-grub_envblk_buf-helper-function.patch new file mode 100644 index 0000000..21655a7 --- /dev/null +++ b/0001-Add-grub_envblk_buf-helper-function.patch @@ -0,0 +1,68 @@ +From a326e486bdcf99e6be973ba54c0abfb6d2d95b73 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + #include + ++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 + diff --git a/0002-Add-grub_disk_write_tail-helper-function.patch b/0002-Add-grub_disk_write_tail-helper-function.patch new file mode 100644 index 0000000..c8b6190 --- /dev/null +++ b/0002-Add-grub_disk_write_tail-helper-function.patch @@ -0,0 +1,60 @@ +From c0d00403a297d6023eab6189ba87dc8a3f6d1e85 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + diff --git a/0003-grub-install-support-prep-environment-block.patch b/0003-grub-install-support-prep-environment-block.patch new file mode 100644 index 0000000..9a27092 --- /dev/null +++ b/0003-grub-install-support-prep-environment-block.patch @@ -0,0 +1,97 @@ +From c31fc5aa0ded9ce1e774d0a3526cfee19be1b77f Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 ++#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 + #include + #include ++#include + + #include + +@@ -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 + diff --git a/0004-Introduce-prep_load_env-command.patch b/0004-Introduce-prep_load_env-command.patch new file mode 100644 index 0000000..ac6c87f --- /dev/null +++ b/0004-Introduce-prep_load_env-command.patch @@ -0,0 +1,269 @@ +From 3cf4fdf8d17423dea4e5913ab14fb6305f3c2571 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 + diff --git a/0005-export-environment-at-start-up.patch b/0005-export-environment-at-start-up.patch new file mode 100644 index 0000000..767a429 --- /dev/null +++ b/0005-export-environment-at-start-up.patch @@ -0,0 +1,177 @@ +From 496b6b20cbce3fc27228d1d8290089fb7107b8de Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + #include + #include ++#include + + 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 + diff --git a/grub2.changes b/grub2.changes index bcb2f2c..db92f8b 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Fri Mar 4 03:37:40 UTC 2022 - Michael Chang + +- 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 diff --git a/grub2.spec b/grub2.spec index 4f0e222..d6a640d 100644 --- a/grub2.spec +++ b/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}"