From 11b49b804e344f280c91409ba155c7a74eed7446 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Feb 04 2019 18:28:49 +0000 Subject: BLS support enhancements and some fixes - Don't build the grub2-efi-ia32-* packages on i686 (pjones) - Add efi-export-env and efi-load-env commands (pjones) - Make it possible to subtract conditions from debug= (pjones) - Try to set -fPIE and friends on libgnu.a (pjones) - Add more options to blscfg command to make it more flexible - Add support for prepend early initrds to the BLS entries - Fix grub.cfg-XXX look up when booting over TFTP Signed-off-by: Javier Martinez Canillas --- diff --git a/0262-Make-grub_strtoul-end-pointer-have-the-right-constif.patch b/0262-Make-grub_strtoul-end-pointer-have-the-right-constif.patch index 99787bd..3358f64 100644 --- a/0262-Make-grub_strtoul-end-pointer-have-the-right-constif.patch +++ b/0262-Make-grub_strtoul-end-pointer-have-the-right-constif.patch @@ -7,26 +7,151 @@ Subject: [PATCH] Make grub_strtoul "end" pointer have the right Related: rhbz#1640979 Signed-off-by: Peter Jones --- - grub-core/kern/fs.c | 2 +- - grub-core/kern/misc.c | 8 ++++---- - grub-core/kern/partition.c | 2 +- - grub-core/lib/legacy_parse.c | 2 +- - grub-core/lib/syslinux_parse.c | 6 +++--- - grub-core/loader/i386/xen_fileXX.c | 2 +- - grub-core/net/efi/ip4_config.c | 2 +- - grub-core/net/efi/ip6_config.c | 2 +- - grub-core/net/efi/net.c | 4 ++-- - grub-core/net/efi/pxe.c | 6 +++--- - grub-core/net/http.c | 4 ++-- - grub-core/net/net.c | 8 ++++---- - grub-core/net/url.c | 2 +- - grub-core/script/execute.c | 6 +++--- - grub-core/term/serial.c | 2 +- - grub-core/term/terminfo.c | 2 +- - grub-core/tests/strtoull_test.c | 2 +- - include/grub/misc.h | 6 +++--- - 18 files changed, 34 insertions(+), 34 deletions(-) + grub-core/commands/date.c | 5 +++-- + grub-core/commands/password_pbkdf2.c | 2 +- + grub-core/commands/regexp.c | 2 +- + grub-core/commands/videoinfo.c | 2 +- + grub-core/disk/diskfilter.c | 3 ++- + grub-core/disk/lvm.c | 9 +++++---- + grub-core/kern/fs.c | 2 +- + grub-core/kern/misc.c | 8 ++++---- + grub-core/kern/partition.c | 2 +- + grub-core/lib/arg.c | 2 +- + grub-core/lib/legacy_parse.c | 2 +- + grub-core/lib/syslinux_parse.c | 6 +++--- + grub-core/loader/i386/xen_fileXX.c | 2 +- + grub-core/net/efi/ip4_config.c | 2 +- + grub-core/net/efi/ip6_config.c | 2 +- + grub-core/net/efi/net.c | 4 ++-- + grub-core/net/efi/pxe.c | 6 +++--- + grub-core/net/http.c | 4 ++-- + grub-core/net/net.c | 8 ++++---- + grub-core/net/url.c | 2 +- + grub-core/osdep/devmapper/hostdisk.c | 2 +- + grub-core/script/execute.c | 6 +++--- + grub-core/term/serial.c | 2 +- + grub-core/term/terminfo.c | 2 +- + grub-core/tests/strtoull_test.c | 2 +- + util/grub-fstest.c | 2 +- + include/grub/emu/getroot.h | 4 ++++ + include/grub/emu/misc.h | 3 +++ + include/grub/misc.h | 6 +++--- + 29 files changed, 57 insertions(+), 47 deletions(-) +diff --git a/grub-core/commands/date.c b/grub-core/commands/date.c +index 8e1f41f141b..0ff0f132c28 100644 +--- a/grub-core/commands/date.c ++++ b/grub-core/commands/date.c +@@ -35,7 +35,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + static grub_err_t + grub_cmd_date (grub_command_t cmd __attribute__ ((unused)), +- int argc, char **args) ++ int argc, char ** args) + { + struct grub_datetime datetime; + int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, 59}}; +@@ -59,7 +59,8 @@ grub_cmd_date (grub_command_t cmd __attribute__ ((unused)), + + for (; argc; argc--, args++) + { +- char *p, c; ++ const char *p; ++ char c; + int m1, ofs, n, cur_mask; + + p = args[0]; +diff --git a/grub-core/commands/password_pbkdf2.c b/grub-core/commands/password_pbkdf2.c +index da636e6217a..ab845d25eb3 100644 +--- a/grub-core/commands/password_pbkdf2.c ++++ b/grub-core/commands/password_pbkdf2.c +@@ -86,7 +86,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) + { + grub_err_t err; +- char *ptr, *ptr2; ++ const char *ptr, *ptr2; + grub_uint8_t *ptro; + struct pbkdf2_password *pass; + +diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c +index f00b184c81e..7c5c72fe460 100644 +--- a/grub-core/commands/regexp.c ++++ b/grub-core/commands/regexp.c +@@ -64,7 +64,7 @@ set_matches (char **varnames, char *str, grub_size_t nmatches, + { + int i; + char *p; +- char *q; ++ const char * q; + grub_err_t err; + unsigned long j; + +diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c +index 4be8107d553..016a4d81835 100644 +--- a/grub-core/commands/videoinfo.c ++++ b/grub-core/commands/videoinfo.c +@@ -136,7 +136,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), + ctx.height = ctx.width = ctx.depth = 0; + if (argc) + { +- char *ptr; ++ const char *ptr; + ptr = args[0]; + ctx.width = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index 66f6b992604..5447e04e702 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -971,7 +971,8 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg) + for (p = vgp->lvs; p; p = p->next) + { + int cur_num; +- char *num, *end; ++ char *num; ++ const char *end; + if (!p->fullname) + continue; + if (grub_strncmp (p->fullname, lv->fullname, len) != 0) +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 7b265c780c3..0cbd0dd1629 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -38,7 +38,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); + at the number. In case STR is not found, *P will be NULL and the + return value will be 0. */ + static grub_uint64_t +-grub_lvm_getvalue (char **p, const char *str) ++grub_lvm_getvalue (const char ** const p, const char *str) + { + *p = grub_strstr (*p, str); + if (! *p) +@@ -63,12 +63,12 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl) + #endif + + static int +-grub_lvm_check_flag (char *p, const char *str, const char *flag) ++grub_lvm_check_flag (const char *p, const char *str, const char *flag) + { + grub_size_t len_str = grub_strlen (str), len_flag = grub_strlen (flag); + while (1) + { +- char *q; ++ const char *q; + p = grub_strstr (p, str); + if (! p) + return 0; +@@ -105,7 +105,8 @@ grub_lvm_detect (grub_disk_t disk, + char buf[GRUB_LVM_LABEL_SIZE]; + char vg_id[GRUB_LVM_ID_STRLEN+1]; + char pv_id[GRUB_LVM_ID_STRLEN+1]; +- char *metadatabuf, *p, *q, *vgname; ++ char *metadatabuf, *vgname; ++ const char *p, *q; + struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf; + struct grub_lvm_pv_header *pvh; + struct grub_lvm_disk_locn *dlocn; diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c index 9085895b6fe..1bd748be83b 100644 --- a/grub-core/kern/fs.c @@ -92,6 +217,19 @@ index e499147cbcb..2c401b866c4 100644 curpart = 0; /* Use the first partition map type found. */ +diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c +index fd7744a6ff6..ccc185017ee 100644 +--- a/grub-core/lib/arg.c ++++ b/grub-core/lib/arg.c +@@ -375,7 +375,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, + + case ARG_TYPE_INT: + { +- char *tail; ++ const char * tail; + + grub_strtoull (option, &tail, 0); + if (tail == 0 || tail == option || *tail != '\0' || grub_errno) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index ef56150ac77..05719ab2ccb 100644 --- a/grub-core/lib/legacy_parse.c @@ -300,6 +438,19 @@ index 146858284cd..d9d2fc9a9dc 100644 *port_end = c; #ifdef URL_TEST if (portul == ULONG_MAX && errno == ERANGE) +diff --git a/grub-core/osdep/devmapper/hostdisk.c b/grub-core/osdep/devmapper/hostdisk.c +index a697bcb4d8d..a8afc0c9408 100644 +--- a/grub-core/osdep/devmapper/hostdisk.c ++++ b/grub-core/osdep/devmapper/hostdisk.c +@@ -113,7 +113,7 @@ grub_util_get_dm_node_linear_info (dev_t dev, + void *next = NULL; + uint64_t length, start; + char *target, *params; +- char *ptr; ++ const char *ptr; + int major = 0, minor = 0; + int first = 1; + grub_disk_addr_t partstart = 0; diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 93965777138..7d327f59d92 100644 --- a/grub-core/script/execute.c @@ -370,6 +521,56 @@ index 7da615ff33e..5488ab26b43 100644 unsigned long long value; grub_errno = 0; value = grub_strtoull(input, &output, base); +diff --git a/util/grub-fstest.c b/util/grub-fstest.c +index f82f9504054..5095fa8356c 100644 +--- a/util/grub-fstest.c ++++ b/util/grub-fstest.c +@@ -538,7 +538,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + static error_t + argp_parser (int key, char *arg, struct argp_state *state) + { +- char *p; ++ const char *p; + + switch (key) + { +diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h +index 9c642ae3fe3..80b96b972d0 100644 +--- a/include/grub/emu/getroot.h ++++ b/include/grub/emu/getroot.h +@@ -19,6 +19,8 @@ + #ifndef GRUB_UTIL_GETROOT_HEADER + #define GRUB_UTIL_GETROOT_HEADER 1 + ++#define NEED_GRUB_MAKE_SYSTEM_PATH_RELATIVE ++ + #include + #include + +@@ -37,7 +39,9 @@ char *grub_find_device (const char *dir, dev_t dev); + void grub_util_pull_device (const char *osname); + char **grub_guess_root_devices (const char *dir); + int grub_util_get_dev_abstraction (const char *os_dev); ++#ifndef NEED_GRUB_MAKE_SYSTEM_PATH_RELATIVE + char *grub_make_system_path_relative_to_its_root (const char *path); ++#endif + char * + grub_make_system_path_relative_to_its_root_os (const char *path); + char *grub_util_get_grub_dev (const char *os_dev); +diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h +index a653132e36a..1ca4c78de97 100644 +--- a/include/grub/emu/misc.h ++++ b/include/grub/emu/misc.h +@@ -40,6 +40,9 @@ void grub_find_zpool_from_dir (const char *dir, + + char *grub_make_system_path_relative_to_its_root (const char *path) + WARN_UNUSED_RESULT; ++#ifdef NEED_GRUB_MAKE_SYSTEM_PATH_RELATIVE ++#undef NEED_GRUB_MAKE_SYSTEM_PATH_RELATIVE ++#endif + int + grub_util_device_is_mapped (const char *dev); + diff --git a/include/grub/misc.h b/include/grub/misc.h index de9016ab709..1258ec6bbf3 100644 --- a/include/grub/misc.h diff --git a/0273-Add-efi-export-env-and-efi-load-env-commands.patch b/0273-Add-efi-export-env-and-efi-load-env-commands.patch new file mode 100644 index 0000000..58e8e1e --- /dev/null +++ b/0273-Add-efi-export-env-and-efi-load-env-commands.patch @@ -0,0 +1,360 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 16 Jan 2019 13:21:46 -0500 +Subject: [PATCH] Add efi-export-env and efi-load-env commands + +This adds "efi-export-env VARIABLE" and "efi-load-env", which manipulate the +environment block stored in the EFI variable +GRUB_ENV-91376aff-cba6-42be-949d-06fde81128e8. + +Signed-off-by: Peter Jones +--- + grub-core/Makefile.core.def | 6 ++ + grub-core/commands/efi/env.c | 168 +++++++++++++++++++++++++++++++++++++++++++ + grub-core/kern/efi/efi.c | 3 + + grub-core/kern/efi/init.c | 5 -- + grub-core/lib/envblk.c | 43 +++++++++++ + util/editenv.c | 2 - + util/grub-set-bootflag.c | 1 + + include/grub/efi/efi.h | 5 ++ + include/grub/lib/envblk.h | 3 + + 9 files changed, 229 insertions(+), 7 deletions(-) + create mode 100644 grub-core/commands/efi/env.c + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 826e27af900..017080bd599 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -776,6 +776,12 @@ module = { + enable = efi; + }; + ++module = { ++ name = efienv; ++ common = commands/efi/env.c; ++ enable = efi; ++}; ++ + module = { + name = efifwsetup; + efi = commands/efi/efifwsetup.c; +diff --git a/grub-core/commands/efi/env.c b/grub-core/commands/efi/env.c +new file mode 100644 +index 00000000000..a69079786aa +--- /dev/null ++++ b/grub-core/commands/efi/env.c +@@ -0,0 +1,168 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2012 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static const grub_efi_guid_t grub_env_guid = GRUB_EFI_GRUB_VARIABLE_GUID; ++ ++static grub_err_t ++grub_efi_export_env(grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ const char *value; ++ char *old_value; ++ struct grub_envblk envblk_s = { NULL, 0 }; ++ grub_envblk_t envblk = &envblk_s; ++ grub_err_t err; ++ int changed = 1; ++ grub_efi_status_t status; ++ ++ grub_dprintf ("efienv", "argc:%d\n", argc); ++ for (int i = 0; i < argc; i++) ++ grub_dprintf ("efienv", "argv[%d]: %s\n", i, argv[i]); ++ ++ if (argc != 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable name expected")); ++ ++ envblk_s.buf = grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, ++ &envblk_s.size); ++ if (!envblk_s.buf || envblk_s.size < 1) ++ { ++ char *buf = grub_malloc (1025); ++ if (!buf) ++ return grub_errno; ++ ++ grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); ++ grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', ++ DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); ++ buf[1024] = '\0'; ++ ++ envblk_s.buf = buf; ++ envblk_s.size = 1024; ++ } ++ else ++ { ++ char *buf = grub_realloc (envblk_s.buf, envblk_s.size + 1); ++ if (!buf) ++ return grub_errno; ++ ++ envblk_s.buf = buf; ++ envblk_s.buf[envblk_s.size] = '\0'; ++ } ++ ++ err = grub_envblk_get(envblk, argv[0], &old_value); ++ if (err != GRUB_ERR_NONE) ++ { ++ grub_dprintf ("efienv", "grub_envblk_get returned %d\n", err); ++ return err; ++ } ++ ++ value = grub_env_get(argv[0]); ++ if ((!value && !old_value) || ++ (value && old_value && !grub_strcmp(old_value, value))) ++ changed = 0; ++ ++ if (old_value) ++ grub_free(old_value); ++ ++ if (changed == 0) ++ { ++ grub_dprintf ("efienv", "No changes necessary\n"); ++ return 0; ++ } ++ ++ if (value) ++ { ++ grub_dprintf ("efienv", "setting \"%s\" to \"%s\"\n", argv[0], value); ++ grub_envblk_set(envblk, argv[0], value); ++ } ++ else ++ { ++ grub_dprintf ("efienv", "deleting \"%s\" from envblk\n", argv[0]); ++ grub_envblk_delete(envblk, argv[0]); ++ } ++ ++ grub_dprintf ("efienv", "envblk is %lu bytes:\n\"%s\"\n", envblk_s.size, envblk_s.buf); ++ ++ grub_dprintf ("efienv", "removing GRUB_ENV\n"); ++ status = grub_efi_set_variable ("GRUB_ENV", &grub_env_guid, NULL, 0); ++ if (status != GRUB_EFI_SUCCESS) ++ grub_dprintf ("efienv", "removal returned %ld\n", status); ++ ++ grub_dprintf ("efienv", "setting GRUB_ENV\n"); ++ status = grub_efi_set_variable ("GRUB_ENV", &grub_env_guid, ++ envblk_s.buf, envblk_s.size); ++ if (status != GRUB_EFI_SUCCESS) ++ grub_dprintf ("efienv", "setting GRUB_ENV returned %ld\n", status); ++ ++ return 0; ++} ++ ++static int ++set_var (const char *name, const char *value, ++ void *whitelist __attribute__((__unused__))) ++{ ++ grub_env_set (name, value); ++ return 0; ++} ++ ++static grub_err_t ++grub_efi_load_env(grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[] __attribute__((__unused__))) ++{ ++ struct grub_envblk envblk_s = { NULL, 0 }; ++ grub_envblk_t envblk = &envblk_s; ++ ++ envblk_s.buf = grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, ++ &envblk_s.size); ++ if (!envblk_s.buf || envblk_s.size < 1) ++ return 0; ++ ++ if (argc > 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected argument")); ++ ++ grub_envblk_iterate (envblk, NULL, set_var); ++ grub_free (envblk_s.buf); ++} ++ ++static grub_command_t export_cmd, loadenv_cmd; ++ ++GRUB_MOD_INIT(lsefi) ++{ ++ export_cmd = grub_register_command ("efi-export-env", grub_efi_export_env, ++ N_("VARIABLE_NAME"), N_("Export environment variable to UEFI.")); ++ loadenv_cmd = grub_register_command ("efi-load-env", grub_efi_load_env, ++ NULL, N_("Load the grub environment from UEFI.")); ++} ++ ++GRUB_MOD_FINI(lsefi) ++{ ++ grub_unregister_command (export_cmd); ++ grub_unregister_command (loadenv_cmd); ++} +diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c +index 4d36fe31177..1079ac74a47 100644 +--- a/grub-core/kern/efi/efi.c ++++ b/grub-core/kern/efi/efi.c +@@ -224,6 +224,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + ++ if (status == GRUB_EFI_NOT_FOUND && datasize == 0) ++ return GRUB_ERR_NONE; ++ + return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); + } + +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c +index e6183a4c44d..d1afa3af11e 100644 +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -29,11 +29,6 @@ + + grub_addr_t grub_modbase; + +-#define GRUB_EFI_GRUB_VARIABLE_GUID \ +- { 0x91376aff, 0xcba6, 0x42be, \ +- { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ +- } +- + /* Helper for grub_efi_env_init */ + static int + set_var (const char *name, const char *value, +diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c +index 230e0e9d9ab..f89d86d4e8d 100644 +--- a/grub-core/lib/envblk.c ++++ b/grub-core/lib/envblk.c +@@ -223,6 +223,49 @@ grub_envblk_delete (grub_envblk_t envblk, const char *name) + } + } + ++struct get_var_state { ++ const char * const name; ++ char * value; ++ int found; ++}; ++ ++static int ++get_var (const char * const name, const char * const value, void *statep) ++{ ++ struct get_var_state *state = (struct get_var_state *)statep; ++ ++ if (!grub_strcmp(state->name, name)) ++ { ++ state->found = 1; ++ state->value = grub_strdup(value); ++ if (!state->value) ++ grub_errno = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++grub_err_t ++grub_envblk_get (grub_envblk_t envblk, const char * const name, char ** const value) ++{ ++ struct get_var_state state = { ++ .name = name, ++ .value = NULL, ++ .found = 0, ++ }; ++ ++ grub_envblk_iterate(envblk, (void *)&state, get_var); ++ ++ *value = state.value; ++ ++ if (state.found && !state.value) ++ return grub_errno; ++ ++ return GRUB_ERR_NONE; ++} ++ + void + grub_envblk_iterate (grub_envblk_t envblk, + void *hook_data, +diff --git a/util/editenv.c b/util/editenv.c +index 41bc7cb1c9a..844a14d90da 100644 +--- a/util/editenv.c ++++ b/util/editenv.c +@@ -30,8 +30,6 @@ + #include + #include + +-#define DEFAULT_ENVBLK_SIZE 1024 +- + void + grub_util_create_envblk_file (const char *name) + { +diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c +index f8dc310909a..20062fe802b 100644 +--- a/util/grub-set-bootflag.c ++++ b/util/grub-set-bootflag.c +@@ -25,6 +25,7 @@ + + #include /* For *_DIR_NAME defines */ + #include ++#include + #include /* For GRUB_ENVBLK_DEFCFG define */ + #include + #include +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index 570a69361a5..2778b95df17 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -24,6 +24,11 @@ + #include + #include + ++#define GRUB_EFI_GRUB_VARIABLE_GUID \ ++ { 0x91376aff, 0xcba6, 0x42be, \ ++ { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ ++ } ++ + /* Variables. */ + extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); + extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); +diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h +index c3e65592170..ab969af2461 100644 +--- a/include/grub/lib/envblk.h ++++ b/include/grub/lib/envblk.h +@@ -22,6 +22,8 @@ + #define GRUB_ENVBLK_SIGNATURE "# GRUB Environment Block\n" + #define GRUB_ENVBLK_DEFCFG "grubenv" + ++#define DEFAULT_ENVBLK_SIZE 1024 ++ + #ifndef ASM_FILE + + struct grub_envblk +@@ -33,6 +35,7 @@ typedef struct grub_envblk *grub_envblk_t; + + 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); ++grub_err_t grub_envblk_get (grub_envblk_t envblk, const char * const name, char ** const value); + void grub_envblk_delete (grub_envblk_t envblk, const char *name); + void grub_envblk_iterate (grub_envblk_t envblk, + void *hook_data, diff --git a/0274-Make-it-possible-to-subtract-conditions-from-debug.patch b/0274-Make-it-possible-to-subtract-conditions-from-debug.patch new file mode 100644 index 0000000..24cc724 --- /dev/null +++ b/0274-Make-it-possible-to-subtract-conditions-from-debug.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 17 Jan 2019 13:10:39 -0500 +Subject: [PATCH] Make it possible to subtract conditions from debug= + +This makes it so you can do set debug to "all,-scripting,-lexer" and get the +obvious outcome. Any negation present will take preference over that +conditional, so "all,-scripting,scripting" is the same thing as +"all,-scripting". + +Signed-off-by: Peter Jones +--- + grub-core/kern/misc.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index aaae9aa0ab7..f6eaa7b4df8 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -163,12 +163,24 @@ int + grub_debug_enabled (const char * condition) + { + const char *debug; ++ char *negcond; ++ int negated = 0; + + debug = grub_env_get ("debug"); + if (!debug) + return 0; + +- if (grub_strword (debug, "all") || grub_strword (debug, condition)) ++ negcond = grub_zalloc (grub_strlen (condition) + 2); ++ if (negcond) ++ { ++ grub_strcpy (negcond, "-"); ++ grub_strcpy (negcond+1, condition); ++ negated = grub_strword (debug, negcond); ++ grub_free (negcond); ++ } ++ ++ if (!negated && ++ (grub_strword (debug, "all") || grub_strword (debug, condition))) + return 1; + + return 0; diff --git a/0275-Export-all-variables-from-the-initial-context-when-c.patch b/0275-Export-all-variables-from-the-initial-context-when-c.patch new file mode 100644 index 0000000..24e3580 --- /dev/null +++ b/0275-Export-all-variables-from-the-initial-context-when-c.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 22 Jan 2019 15:40:25 +0100 +Subject: [PATCH] Export all variables from the initial context when creating a + submenu + +When a submenu is created, only the exported variables are copied to the +new menu context. But we want the variables to be global, so export lets +export all variables to the new created submenu. + +Also, don't unset the default variable when a new submenu is created. + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/normal/context.c | 2 +- + grub-core/normal/menu.c | 2 -- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c +index ee53d4a68e5..87edd254c44 100644 +--- a/grub-core/normal/context.c ++++ b/grub-core/normal/context.c +@@ -99,7 +99,7 @@ grub_env_new_context (int export_all) + grub_err_t + grub_env_context_open (void) + { +- return grub_env_new_context (0); ++ return grub_env_new_context (1); + } + + int grub_extractor_level = 0; +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index 7e32c498aa8..d087153f276 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -376,8 +376,6 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) + + if (ptr && ptr[0] && ptr[1]) + grub_env_set ("default", ptr + 1); +- else +- grub_env_unset ("default"); + + grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args); + diff --git a/0276-blscfg-store-the-BLS-entries-in-a-sorted-linked-list.patch b/0276-blscfg-store-the-BLS-entries-in-a-sorted-linked-list.patch new file mode 100644 index 0000000..dfd0686 --- /dev/null +++ b/0276-blscfg-store-the-BLS-entries-in-a-sorted-linked-list.patch @@ -0,0 +1,590 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Mon, 21 Jan 2019 17:33:13 +0100 +Subject: [PATCH] blscfg: store the BLS entries in a sorted linked list + +The parsed BLS entries are stored in an array, that it's sorted +using the quick sort algorithm before populating the boot menu. + +This works on the assumption that all BLS entries are parsed at +the same time and that are displayed just after being retrieved. + +But the support could be made more flexible, and have different +commands to load and display the entries. Keeping the BLS in a +sorted link simplify the code considerably, while not making it +much less efficient. + +While being there, mark entries that have been used to populate +the boot menu so multiple calls to the blscfg command don't add +duplicated entries. + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/Makefile.core.def | 1 - + grub-core/commands/blscfg.c | 177 ++++++++++++---------------- + grub-core/commands/bls_qsort.h | 255 ----------------------------------------- + 3 files changed, 71 insertions(+), 362 deletions(-) + delete mode 100644 grub-core/commands/bls_qsort.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 017080bd599..8a00c6177e1 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -796,7 +796,6 @@ module = { + module = { + name = blscfg; + common = commands/blscfg.c; +- common = commands/bls_qsort.h; + common = commands/loadenv.h; + enable = powerpc_ieee1275; + enable = efi; +diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c +index c432c6ba27a..304d73908ae 100644 +--- a/grub-core/commands/blscfg.c ++++ b/grub-core/commands/blscfg.c +@@ -19,6 +19,7 @@ + * along with GRUB. If not, see . + */ + ++#include + #include + #include + #include +@@ -36,7 +37,6 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-#include "bls_qsort.h" + #include "loadenv.h" + + #define GRUB_BLS_CONFIG_PATH "/loader/entries/" +@@ -54,45 +54,17 @@ struct keyval + + struct bls_entry + { ++ struct bls_entry *next; ++ struct bls_entry **prev; + struct keyval **keyvals; + int nkeyvals; + char *filename; ++ bool visible; + }; + +-static struct bls_entry **entries; +-static int nentries; ++static struct bls_entry *entries = NULL; + +-static struct bls_entry *bls_new_entry(void) +-{ +- struct bls_entry **new_entries; +- struct bls_entry *entry; +- int new_n = nentries + 1; +- +- new_entries = grub_realloc (entries, new_n * sizeof (struct bls_entry *)); +- if (!new_entries) +- { +- grub_error (GRUB_ERR_OUT_OF_MEMORY, +- "couldn't find space for BLS entry list"); +- return NULL; +- } +- +- entries = new_entries; +- +- entry = grub_malloc (sizeof (*entry)); +- if (!entry) +- { +- grub_error (GRUB_ERR_OUT_OF_MEMORY, +- "couldn't find space for BLS entry list"); +- return NULL; +- } +- +- grub_memset (entry, 0, sizeof (*entry)); +- entries[nentries] = entry; +- +- nentries = new_n; +- +- return entry; +-} ++#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) + + static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) + { +@@ -138,24 +110,6 @@ static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) + return 0; + } + +-static void bls_free_entry(struct bls_entry *entry) +-{ +- int i; +- +- for (i = 0; i < entry->nkeyvals; i++) +- { +- struct keyval *kv = entry->keyvals[i]; +- grub_free ((void *)kv->key); +- grub_free (kv->val); +- grub_free (kv); +- } +- +- grub_free (entry->keyvals); +- grub_free (entry->filename); +- grub_memset (entry, 0, sizeof (*entry)); +- grub_free (entry); +-} +- + /* Find they value of the key named by keyname. If there are allowed to be + * more than one, pass a pointer to an int set to -1 the first time, and pass + * the same pointer through each time after, and it'll return them in sorted +@@ -387,43 +341,17 @@ split_cmp(char *nvr0, char *nvr1, int has_name) + return ret; + } + +-/* return 1: p0 is newer than p1 */ +-/* 0: p0 and p1 are the same version */ +-/* -1: p1 is newer than p0 */ +-static int bls_cmp(const void *p0, const void *p1, void *state) ++/* return 1: e0 is newer than e1 */ ++/* 0: e0 and e1 are the same version */ ++/* -1: e1 is newer than e0 */ ++static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1) + { +- struct bls_entry * e0 = *(struct bls_entry **)p0; +- struct bls_entry * e1 = *(struct bls_entry **)p1; +- bool use_version = *(bool *)state; +- char *v0, *v1; + char *id0, *id1; +- int l, r; +- +- if (use_version) +- { +- v0 = grub_strdup(bls_get_val(e0, "version", NULL)); +- v1 = grub_strdup(bls_get_val(e1, "version", NULL)); +- +- r = split_cmp(v0, v1, 0); +- +- grub_free(v0); +- grub_free(v1); +- +- if (r != 0) +- return r; +- } ++ int r; + + id0 = grub_strdup(e0->filename); + id1 = grub_strdup(e1->filename); + +- l = grub_strlen(id0); +- if (l > 5 && grub_strcmp(id0 + l - 5, ".conf")) +- id0[l-5] = '\0'; +- +- l = grub_strlen(id1); +- if (l > 5 && grub_strcmp(id1 + l - 5, ".conf")) +- id1[l-5] = '\0'; +- + r = split_cmp(id0, id1, 1); + + grub_free(id0); +@@ -432,6 +360,53 @@ static int bls_cmp(const void *p0, const void *p1, void *state) + return r; + } + ++static void list_add_tail(grub_list_t head, grub_list_t item) ++{ ++ item->next = head; ++ if (head->prev) ++ (*head->prev)->next = item; ++ item->prev = head->prev; ++ head->prev = &item; ++} ++ ++static int bls_add_entry(struct bls_entry *entry) ++{ ++ struct bls_entry *e, *last = NULL; ++ int rc; ++ ++ if (!entries) { ++ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); ++ entries = entry; ++ return 0; ++ } ++ ++ FOR_BLS_ENTRIES(e) { ++ rc = bls_cmp(entry, e); ++ ++ if (!rc) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ if (rc == 1) { ++ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); ++ list_add_tail (GRUB_AS_LIST (e), GRUB_AS_LIST (entry)); ++ if (e == entries) { ++ entries = entry; ++ entry->prev = NULL; ++ } ++ return 0; ++ } ++ last = e; ++ } ++ ++ if (last) { ++ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); ++ last->next = entry; ++ entry->prev = &last; ++ } ++ ++ return 0; ++} ++ + struct read_entry_info { + const char *devid; + const char *dirname; +@@ -442,6 +417,7 @@ static int read_entry ( + const struct grub_dirhook_info *dirhook_info UNUSED, + void *data) + { ++ int rc = 0; + grub_size_t n; + char *p; + grub_file_t f = NULL; +@@ -471,7 +447,7 @@ static int read_entry ( + if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024) + goto finish; + +- entry = bls_new_entry(); ++ entry = grub_zalloc (sizeof (*entry)); + if (!entry) + goto finish; + +@@ -485,7 +461,6 @@ static int read_entry ( + { + char *buf; + char *separator; +- int rc; + + buf = grub_file_getline (f); + if (!buf) +@@ -519,6 +494,9 @@ static int read_entry ( + break; + } + ++ if (!rc) ++ bls_add_entry(entry); ++ + finish: + grub_free (p); + +@@ -779,10 +757,10 @@ struct find_entry_info { + static int find_entry (struct find_entry_info *info) + { + struct read_entry_info read_entry_info; ++ struct bls_entry *entry = NULL; + grub_fs_t blsdir_fs = NULL; + grub_device_t blsdir_dev = NULL; + const char *blsdir = NULL; +- bool use_version = true; + int fallback = 0; + int r = 0; + +@@ -810,7 +788,7 @@ read_fallback: + } while (e); + } + +- if (!nentries && !fallback) { ++ if (!entries && !fallback) { + read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; + grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", + blsdir, read_entry_info.dirname); +@@ -818,27 +796,14 @@ read_fallback: + goto read_fallback; + } + +- grub_dprintf ("blscfg", "Sorting %d entries\n", nentries); ++ grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); ++ FOR_BLS_ENTRIES(entry) { ++ if (entry->visible) ++ continue; + +- for (r = 0; r < nentries && use_version; r++) { +- if (!bls_get_val(entries[r], "version", NULL)) +- use_version = false; ++ create_entry(entry); ++ entry->visible = true; + } +- +- bls_qsort(&entries[0], nentries, sizeof (struct bls_entry *), bls_cmp, &use_version); +- +- grub_dprintf ("blscfg", "%s Creating %d entries from bls\n", __func__, nentries); +- for (r = nentries - 1; r >= 0; r--) +- create_entry(entries[r]); +- +- for (r = 0; r < nentries; r++) +- bls_free_entry (entries[r]); +- +- nentries = 0; +- +- grub_free (entries); +- entries = NULL; +- + return 0; + } + +diff --git a/grub-core/commands/bls_qsort.h b/grub-core/commands/bls_qsort.h +deleted file mode 100644 +index 572765fa3f2..00000000000 +--- a/grub-core/commands/bls_qsort.h ++++ /dev/null +@@ -1,255 +0,0 @@ +-/* quicksort +- * This file from the GNU C Library. +- * Copyright (C) 1991-2016 Free Software Foundation, Inc. +- * Written by Douglas C. Schmidt (schmidt@ics.uci.edu). +- * +- * GRUB -- GRand Unified Bootloader +- * +- * GRUB is free software: you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * GRUB is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with GRUB. If not, see . +- */ +- +-/* If you consider tuning this algorithm, you should consult first: +- Engineering a sort function; Jon Bentley and M. Douglas McIlroy; +- Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ +- +-#include +-#include +-#include +- +-#define CHAR_BIT 8 +- +-/* Byte-wise swap two items of size SIZE. */ +-#define SWAP(a, b, size) \ +- do \ +- { \ +- grub_size_t __size = (size); \ +- char *__a = (a), *__b = (b); \ +- do \ +- { \ +- char __tmp = *__a; \ +- *__a++ = *__b; \ +- *__b++ = __tmp; \ +- } while (--__size > 0); \ +- } while (0) +- +-/* Discontinue quicksort algorithm when partition gets below this size. +- This particular magic number was chosen to work best on a Sun 4/260. */ +-#define MAX_THRESH 4 +- +-/* Stack node declarations used to store unfulfilled partition obligations. */ +-typedef struct +- { +- char *lo; +- char *hi; +- } stack_node; +- +-/* The next 4 #defines implement a very fast in-line stack abstraction. */ +-/* The stack needs log (total_elements) entries (we could even subtract +- log(MAX_THRESH)). Since total_elements has type grub_size_t, we get as +- upper bound for log (total_elements): +- bits per byte (CHAR_BIT) * sizeof(grub_size_t). */ +-#define STACK_SIZE (CHAR_BIT * sizeof(grub_size_t)) +-#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +-#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +-#define STACK_NOT_EMPTY (stack < top) +- +-typedef int (*grub_compar_d_fn_t) (const void *p0, const void *p1, void *state); +- +-/* Order size using quicksort. This implementation incorporates +- four optimizations discussed in Sedgewick: +- +- 1. Non-recursive, using an explicit stack of pointer that store the +- next array partition to sort. To save time, this maximum amount +- of space required to store an array of SIZE_MAX is allocated on the +- stack. Assuming a 32-bit (64 bit) integer for grub_size_t, this needs +- only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). +- Pretty cheap, actually. +- +- 2. Chose the pivot element using a median-of-three decision tree. +- This reduces the probability of selecting a bad pivot value and +- eliminates certain extraneous comparisons. +- +- 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving +- insertion sort to order the MAX_THRESH items within each partition. +- This is a big win, since insertion sort is faster for small, mostly +- sorted array segments. +- +- 4. The larger of the two sub-partitions is always pushed onto the +- stack first, with the algorithm then concentrating on the +- smaller partition. This *guarantees* no more than log (total_elems) +- stack size is needed (actually O(1) in this case)! */ +- +-static inline void UNUSED +-bls_qsort (void *const pbase, grub_size_t total_elems, grub_size_t size, +- grub_compar_d_fn_t cmp, void *arg) +-{ +- char *base_ptr = (char *) pbase; +- +- const grub_size_t max_thresh = MAX_THRESH * size; +- +- if (total_elems == 0) +- /* Avoid lossage with unsigned arithmetic below. */ +- return; +- +- if (total_elems > MAX_THRESH) +- { +- char *lo = base_ptr; +- char *hi = &lo[size * (total_elems - 1)]; +- stack_node stack[STACK_SIZE]; +- stack_node *top = stack; +- +- PUSH (NULL, NULL); +- +- while (STACK_NOT_EMPTY) +- { +- char *left_ptr; +- char *right_ptr; +- +- /* Select median value from among LO, MID, and HI. Rearrange +- LO and HI so the three values are sorted. This lowers the +- probability of picking a pathological pivot value and +- skips a comparison for both the LEFT_PTR and RIGHT_PTR in +- the while loops. */ +- +- char *mid = lo + size * ((hi - lo) / size >> 1); +- +- if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) +- SWAP (mid, lo, size); +- if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) +- SWAP (mid, hi, size); +- else +- goto jump_over; +- if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) +- SWAP (mid, lo, size); +- jump_over:; +- +- left_ptr = lo + size; +- right_ptr = hi - size; +- +- /* Here's the famous ``collapse the walls'' section of quicksort. +- Gotta like those tight inner loops! They are the main reason +- that this algorithm runs much faster than others. */ +- do +- { +- while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) +- left_ptr += size; +- +- while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) +- right_ptr -= size; +- +- if (left_ptr < right_ptr) +- { +- SWAP (left_ptr, right_ptr, size); +- if (mid == left_ptr) +- mid = right_ptr; +- else if (mid == right_ptr) +- mid = left_ptr; +- left_ptr += size; +- right_ptr -= size; +- } +- else if (left_ptr == right_ptr) +- { +- left_ptr += size; +- right_ptr -= size; +- break; +- } +- } +- while (left_ptr <= right_ptr); +- +- /* Set up pointers for next iteration. First determine whether +- left and right partitions are below the threshold size. If so, +- ignore one or both. Otherwise, push the larger partition's +- bounds on the stack and continue sorting the smaller one. */ +- +- if ((grub_size_t) (right_ptr - lo) <= max_thresh) +- { +- if ((grub_size_t) (hi - left_ptr) <= max_thresh) +- /* Ignore both small partitions. */ +- POP (lo, hi); +- else +- /* Ignore small left partition. */ +- lo = left_ptr; +- } +- else if ((grub_size_t) (hi - left_ptr) <= max_thresh) +- /* Ignore small right partition. */ +- hi = right_ptr; +- else if ((right_ptr - lo) > (hi - left_ptr)) +- { +- /* Push larger left partition indices. */ +- PUSH (lo, right_ptr); +- lo = left_ptr; +- } +- else +- { +- /* Push larger right partition indices. */ +- PUSH (left_ptr, hi); +- hi = right_ptr; +- } +- } +- } +- +- /* Once the BASE_PTR array is partially sorted by quicksort the rest +- is completely sorted using insertion sort, since this is efficient +- for partitions below MAX_THRESH size. BASE_PTR points to the beginning +- of the array to sort, and END_PTR points at the very last element in +- the array (*not* one beyond it!). */ +- +-#define min(x, y) ((x) < (y) ? (x) : (y)) +- +- { +- char *const end_ptr = &base_ptr[size * (total_elems - 1)]; +- char *tmp_ptr = base_ptr; +- char *thresh = min(end_ptr, base_ptr + max_thresh); +- char *run_ptr; +- +- /* Find smallest element in first threshold and place it at the +- array's beginning. This is the smallest array element, +- and the operation speeds up insertion sort's inner loop. */ +- +- for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) +- if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) +- tmp_ptr = run_ptr; +- +- if (tmp_ptr != base_ptr) +- SWAP (tmp_ptr, base_ptr, size); +- +- /* Insertion sort, running from left-hand-side up to right-hand-side. */ +- +- run_ptr = base_ptr + size; +- while ((run_ptr += size) <= end_ptr) +- { +- tmp_ptr = run_ptr - size; +- while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) +- tmp_ptr -= size; +- +- tmp_ptr += size; +- if (tmp_ptr != run_ptr) +- { +- char *trav; +- +- trav = run_ptr + size; +- while (--trav >= run_ptr) +- { +- char c = *trav; +- char *hi, *lo; +- +- for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) +- *hi = *lo; +- *hi = c; +- } +- } +- } +- } +-} +- diff --git a/0277-blscfg-add-more-options-to-blscfg-command-to-make-it.patch b/0277-blscfg-add-more-options-to-blscfg-command-to-make-it.patch new file mode 100644 index 0000000..91947ec --- /dev/null +++ b/0277-blscfg-add-more-options-to-blscfg-command-to-make-it.patch @@ -0,0 +1,532 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 23 Jan 2019 16:33:32 +0100 +Subject: [PATCH] blscfg: add more options to blscfg command to make it more + flexible + +Currently the blscfg command is not flexible, it just loads all the BLS +entries from a predefined path and populate the menu entries at the same +time. But a user might want more control over what BLS snippets are used +to populate the entries and in which order. + +So lets make the BLS support more flexible by allowing to blscfg command +to populate only the default entry, the non-default entries or choose a +custom path to a BLS snippet or a BLS directory to load the entries from. + +The blscfg command now supports the following arguments: + +blscfg default +blscfg non-default +blscfg (hd0,gpt2)/boot/loader/entries/ +blscfg (hd0,gpt2)/boot/loader/entries/custom_entry.conf + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/commands/blscfg.c | 241 +++++++++++++++++++++++++++++++---------- + grub-core/commands/legacycfg.c | 5 +- + grub-core/commands/menuentry.c | 8 +- + grub-core/normal/main.c | 6 + + include/grub/menu.h | 13 +++ + include/grub/normal.h | 2 +- + 6 files changed, 213 insertions(+), 62 deletions(-) + +diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c +index 304d73908ae..aa5bf0d3220 100644 +--- a/grub-core/commands/blscfg.c ++++ b/grub-core/commands/blscfg.c +@@ -52,16 +52,6 @@ struct keyval + char *val; + }; + +-struct bls_entry +-{ +- struct bls_entry *next; +- struct bls_entry **prev; +- struct keyval **keyvals; +- int nkeyvals; +- char *filename; +- bool visible; +-}; +- + static struct bls_entry *entries = NULL; + + #define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) +@@ -410,6 +400,7 @@ static int bls_add_entry(struct bls_entry *entry) + struct read_entry_info { + const char *devid; + const char *dirname; ++ grub_file_t file; + }; + + static int read_entry ( +@@ -417,9 +408,9 @@ static int read_entry ( + const struct grub_dirhook_info *dirhook_info UNUSED, + void *data) + { ++ grub_size_t m = 0, n, clip = 0; + int rc = 0; +- grub_size_t n; +- char *p; ++ char *p = NULL; + grub_file_t f = NULL; + grub_off_t sz; + struct bls_entry *entry; +@@ -427,21 +418,29 @@ static int read_entry ( + + grub_dprintf ("blscfg", "filename: \"%s\"\n", filename); + +- if (filename[0] == '.') +- return 0; +- + n = grub_strlen (filename); +- if (n <= 5) +- return 0; + +- if (grub_strcmp (filename + n - 5, ".conf") != 0) +- return 0; ++ if (info->file) ++ { ++ f = info->file; ++ } ++ else ++ { ++ if (filename[0] == '.') ++ return 0; + +- p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); ++ if (n <= 5) ++ return 0; + +- f = grub_file_open (p); +- if (!f) +- goto finish; ++ if (grub_strcmp (filename + n - 5, ".conf") != 0) ++ return 0; ++ ++ p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); ++ ++ f = grub_file_open (p); ++ if (!f) ++ goto finish; ++ } + + sz = grub_file_size (f); + if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024) +@@ -451,7 +450,30 @@ static int read_entry ( + if (!entry) + goto finish; + +- entry->filename = grub_strndup(filename, n - 5); ++ if (info->file) ++ { ++ char *slash; ++ ++ if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0) ++ clip = 5; ++ ++ slash = grub_strrchr (filename, '/'); ++ if (!slash) ++ slash = grub_strrchr (filename, '\\'); ++ ++ while (*slash == '/' || *slash == '\\') ++ slash++; ++ ++ m = slash ? slash - filename : 0; ++ } ++ else ++ { ++ m = 0; ++ clip = 5; ++ } ++ n -= m; ++ ++ entry->filename = grub_strndup(filename + m, n - clip); + if (!entry->filename) + goto finish; + +@@ -498,7 +520,8 @@ static int read_entry ( + bls_add_entry(entry); + + finish: +- grub_free (p); ++ if (p) ++ grub_free (p); + + if (f) + grub_file_close (f); +@@ -731,7 +754,7 @@ static void create_entry (struct bls_entry *entry) + GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", + initrd ? initrd : ""); + +- grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index); ++ grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry); + grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); + + finish: +@@ -745,10 +768,10 @@ finish: + } + + struct find_entry_info { ++ const char *dirname; + const char *devid; + grub_device_t dev; + grub_fs_t fs; +- int platform; + }; + + /* +@@ -757,20 +780,22 @@ struct find_entry_info { + static int find_entry (struct find_entry_info *info) + { + struct read_entry_info read_entry_info; +- struct bls_entry *entry = NULL; + grub_fs_t blsdir_fs = NULL; + grub_device_t blsdir_dev = NULL; +- const char *blsdir = NULL; ++ const char *blsdir = info->dirname; + int fallback = 0; + int r = 0; + +- blsdir = grub_env_get ("blsdir"); +- if (!blsdir) +- blsdir = GRUB_BLS_CONFIG_PATH; ++ if (!blsdir) { ++ blsdir = grub_env_get ("blsdir"); ++ if (!blsdir) ++ blsdir = GRUB_BLS_CONFIG_PATH; ++ } + ++ read_entry_info.file = NULL; + read_entry_info.dirname = blsdir; + +- grub_dprintf ("blscfg", "scanning blsdir: %s\n", GRUB_BLS_CONFIG_PATH); ++ grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir); + + blsdir_dev = info->dev; + blsdir_fs = info->fs; +@@ -788,7 +813,7 @@ read_fallback: + } while (e); + } + +- if (!entries && !fallback) { ++ if (r && !info->dirname && !fallback) { + read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; + grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", + blsdir, read_entry_info.dirname); +@@ -796,45 +821,62 @@ read_fallback: + goto read_fallback; + } + +- grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); +- FOR_BLS_ENTRIES(entry) { +- if (entry->visible) +- continue; +- +- create_entry(entry); +- entry->visible = true; +- } + return 0; + } + + static grub_err_t +-grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, +- int argc UNUSED, +- char **args UNUSED) ++bls_load_entries (const char *path) + { ++ grub_size_t len; + grub_fs_t fs; + grub_device_t dev; + static grub_err_t r; +- const char *devid; +- struct find_entry_info info = +- { ++ const char *devid = NULL; ++ char *blsdir = NULL; ++ struct find_entry_info info = { + .dev = NULL, + .fs = NULL, +- }; ++ .dirname = NULL, ++ }; ++ struct read_entry_info rei = { ++ .devid = NULL, ++ .dirname = NULL, ++ }; + ++ if (path) { ++ len = grub_strlen (path); ++ if (grub_strcmp (path + len - 5, ".conf") == 0) { ++ rei.file = grub_file_open (path); ++ if (!rei.file) ++ return grub_errno; ++ /* ++ * read_entry() closes the file ++ */ ++ return read_entry(path, NULL, &rei); ++ } else if (path[0] == '(') { ++ devid = path + 1; + +- grub_dprintf ("blscfg", "finding boot\n"); ++ blsdir = grub_strchr (path, ')'); ++ if (!blsdir) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct")); + ++ *blsdir = '\0'; ++ blsdir = blsdir + 1; ++ } ++ } ++ ++ if (!devid) { + #ifdef GRUB_MACHINE_EMU +- devid = "host"; ++ devid = "host"; + #elif defined(GRUB_MACHINE_EFI) +- devid = grub_env_get ("root"); ++ devid = grub_env_get ("root"); + #else +- devid = grub_env_get ("boot"); ++ devid = grub_env_get ("boot"); + #endif +- if (!devid) +- return grub_error (GRUB_ERR_FILE_NOT_FOUND, +- N_("variable `%s' isn't set"), "boot"); ++ if (!devid) ++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, ++ N_("variable `%s' isn't set"), "boot"); ++ } + + grub_dprintf ("blscfg", "opening %s\n", devid); + dev = grub_device_open (devid); +@@ -849,6 +891,7 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, + goto finish; + } + ++ info.dirname = blsdir; + info.devid = devid; + info.dev = dev; + info.fs = fs; +@@ -861,6 +904,92 @@ finish: + return r; + } + ++static bool ++is_default_entry(const char *def_entry, struct bls_entry *entry, int idx) ++{ ++ const char *title; ++ int def_idx; ++ ++ if (!def_entry) ++ return false; ++ ++ if (grub_strcmp(def_entry, entry->filename) == 0) ++ return true; ++ ++ title = bls_get_val(entry, "title", NULL); ++ ++ if (title && grub_strcmp(def_entry, title) == 0) ++ return true; ++ ++ def_idx = (int)grub_strtol(def_entry, NULL, 0); ++ if (grub_errno == GRUB_ERR_BAD_NUMBER) ++ return false; ++ ++ if (def_idx == idx) ++ return true; ++ ++ return false; ++} ++ ++static grub_err_t ++bls_create_entries (bool show_default, bool show_non_default, char *entry_id) ++{ ++ const char *def_entry = NULL; ++ struct bls_entry *entry = NULL; ++ int idx = 0; ++ ++ def_entry = grub_env_get("default"); ++ ++ grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); ++ FOR_BLS_ENTRIES(entry) { ++ if (entry->visible) { ++ idx++; ++ continue; ++ } ++ ++ if ((show_default && is_default_entry(def_entry, entry, idx)) || ++ (show_non_default && !is_default_entry(def_entry, entry, idx)) || ++ (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) { ++ create_entry(entry); ++ entry->visible = 1; ++ } ++ idx++; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, ++ int argc, char **args) ++{ ++ grub_err_t r; ++ char *path = NULL; ++ char *entry_id = NULL; ++ bool show_default = true; ++ bool show_non_default = true; ++ ++ if (argc == 1) { ++ if (grub_strcmp (args[0], "default") == 0) { ++ show_non_default = false; ++ } else if (grub_strcmp (args[0], "non-default") == 0) { ++ show_default = false; ++ } else if (args[0][0] == '(') { ++ path = args[0]; ++ } else { ++ entry_id = args[0]; ++ show_default = false; ++ show_non_default = false; ++ } ++ } ++ ++ r = bls_load_entries(path); ++ if (r) ++ return r; ++ ++ return bls_create_entries(show_default, show_non_default, entry_id); ++} ++ + static grub_extcmd_t cmd; + static grub_extcmd_t oldcmd; + +diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c +index f9d7627bdc3..ef8dd74c589 100644 +--- a/grub-core/commands/legacycfg.c ++++ b/grub-core/commands/legacycfg.c +@@ -133,7 +133,7 @@ legacy_file (const char *filename) + args[0] = oldname; + grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", + NULL, NULL, +- entrysrc, 0, NULL); ++ entrysrc, 0, NULL, NULL); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); +@@ -186,7 +186,8 @@ legacy_file (const char *filename) + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, +- NULL, NULL, entrysrc, 0, NULL); ++ NULL, NULL, entrysrc, 0, NULL, ++ NULL); + grub_free (args); + } + +diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c +index 7004e08ce78..29736f5cd03 100644 +--- a/grub-core/commands/menuentry.c ++++ b/grub-core/commands/menuentry.c +@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args, + char **classes, const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu, int *index) ++ int submenu, int *index, struct bls_entry *bls) + { + int menu_hotkey = 0; + char **menu_args = NULL; +@@ -195,6 +195,7 @@ grub_normal_add_menu_entry (int argc, const char **args, + (*last)->args = menu_args; + (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; ++ (*last)->bls = bls; + + menu->size++; + if (index) +@@ -296,7 +297,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + ctxt->state[2].arg, 0, + ctxt->state[3].arg, + ctxt->extcmd->cmd->name[0] == 's', +- NULL); ++ NULL, NULL); + + src = args[argc - 1]; + args[argc - 1] = NULL; +@@ -313,7 +314,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + ctxt->state[0].args, ctxt->state[4].arg, + users, + ctxt->state[2].arg, prefix, src + 1, +- ctxt->extcmd->cmd->name[0] == 's', NULL); ++ ctxt->extcmd->cmd->name[0] == 's', NULL, ++ NULL); + + src[len - 1] = ch; + args[argc - 1] = src; +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 04ae9ed02f6..4117317c4c4 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -70,6 +71,11 @@ grub_normal_free_menu (grub_menu_t menu) + grub_free (entry->args); + } + ++ if (entry->bls) ++ { ++ entry->bls->visible = 0; ++ } ++ + grub_free ((void *) entry->id); + grub_free ((void *) entry->users); + grub_free ((void *) entry->title); +diff --git a/include/grub/menu.h b/include/grub/menu.h +index ee2b5e91045..eea493f74b1 100644 +--- a/include/grub/menu.h ++++ b/include/grub/menu.h +@@ -20,6 +20,16 @@ + #ifndef GRUB_MENU_HEADER + #define GRUB_MENU_HEADER 1 + ++struct bls_entry ++{ ++ struct bls_entry *next; ++ struct bls_entry **prev; ++ struct keyval **keyvals; ++ int nkeyvals; ++ char *filename; ++ int visible; ++}; ++ + struct grub_menu_entry_class + { + char *name; +@@ -60,6 +70,9 @@ struct grub_menu_entry + + /* The next element. */ + struct grub_menu_entry *next; ++ ++ /* BLS used to populate the entry */ ++ struct bls_entry *bls; + }; + typedef struct grub_menu_entry *grub_menu_entry_t; + +diff --git a/include/grub/normal.h b/include/grub/normal.h +index cb9901f41b3..8839ad85a19 100644 +--- a/include/grub/normal.h ++++ b/include/grub/normal.h +@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu, int *index); ++ int submenu, int *index, struct bls_entry *bls); + + grub_err_t + grub_normal_set_password (const char *user, const char *password); diff --git a/0278-blscfg-add-support-for-prepend-early-initrds-to-the-.patch b/0278-blscfg-add-support-for-prepend-early-initrds-to-the-.patch new file mode 100644 index 0000000..77ea562 --- /dev/null +++ b/0278-blscfg-add-support-for-prepend-early-initrds-to-the-.patch @@ -0,0 +1,179 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +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 +--- + grub-core/commands/blscfg.c | 80 +++++++++++++++++++++++++++++++++++++++++++-- + util/grub.d/10_linux.in | 3 ++ + util/grub.d/10_linux_bls.in | 3 ++ + 3 files changed, 84 insertions(+), 2 deletions(-) + +diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c +index aa5bf0d3220..5dcd68b401e 100644 +--- 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; +@@ -736,12 +800,22 @@ static void create_entry (struct bls_entry *entry) + } + + +- 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]); + tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); + tmp = grub_stpcpy (tmp, initrds[i]); ++ grub_free(initrds[i]); + } + tmp = grub_stpcpy (tmp, "\n"); + } +@@ -759,6 +833,8 @@ static void create_entry (struct bls_entry *entry) + + 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 diff --git a/0279-Fix-the-looking-up-grub.cfg-XXX-while-tftp-booting.patch b/0279-Fix-the-looking-up-grub.cfg-XXX-while-tftp-booting.patch new file mode 100644 index 0000000..3469f7a --- /dev/null +++ b/0279-Fix-the-looking-up-grub.cfg-XXX-while-tftp-booting.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Masayoshi Mizuma +Date: Tue, 18 Dec 2018 21:27:45 -0500 +Subject: [PATCH] Fix the looking up grub.cfg-XXX while tftp booting. + +Currently, grub doesn't look up grub.cfg-UUID, grub.cfg-MAC and grub.cfg-IP +while the boot is from tftp. That is because the uuid size is got by +grub_snprintf(, 0, ,), but the grub_snprintf() always returns 0, +so grub judges there's no available uuid in the client and give up +the looking up grub.cfg-XXX. + +This issue can be fixed by changing grub_snprintf(, 0, ,) behaivior +to like as snprintf() from glibc, however, somewhere may expect +such argument as the error, so it's risky. + +Let's use sizeof() and grub_strlen() to calculate the uuid size +instead of grub_snprintf(). + +Resolves: rhbz#1658500 +--- + grub-core/net/net.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index a011b940100..19ff2d486a1 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1942,11 +1942,9 @@ grub_net_search_configfile (char *config) + char *client_uuid_var; + grub_size_t client_uuid_var_size; + +- client_uuid_var_size = grub_snprintf (NULL, 0, +- "net_%s_clientuuid", inf->name); +- if (client_uuid_var_size <= 0) +- continue; +- client_uuid_var_size += 1; ++ client_uuid_var_size = sizeof ("net_") + grub_strlen (inf->name) + ++ sizeof ("_clientuuid") + 1; ++ + client_uuid_var = grub_malloc(client_uuid_var_size); + if (!client_uuid_var) + continue; diff --git a/0280-Try-to-set-fPIE-and-friends-on-libgnu.a.patch b/0280-Try-to-set-fPIE-and-friends-on-libgnu.a.patch new file mode 100644 index 0000000..17f5179 --- /dev/null +++ b/0280-Try-to-set-fPIE-and-friends-on-libgnu.a.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 15 Jan 2019 14:57:25 -0500 +Subject: [PATCH] Try to set -fPIE and friends on libgnu.a + +In order to make sure UTIL_CFLAGS and UTIL_LDFLAGS can correctly get +-Wl,-z,relro,-z,now , we need everything going in them to be built with at +least -fPIC (and preferably -fPIE) wherever we can, or else we get relocations +in some component object that can't be used with the link type that's being +used for the final ELF object. + +So this makes sure libgnu.a gets built with HOST_CFLAGS and HOST_LDFLAGS, +which are what is later used to define UTIL_CFLAGS and UTIL_LDFLAGS, and +includes -fPIE. + +Fixes an rpmdiff check. + +Related: rhbz#1658500 + +Signed-off-by: Peter Jones +--- + grub-core/gnulib/Makefile.am | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/gnulib/Makefile.am b/grub-core/gnulib/Makefile.am +index b7c5e60e1c3..bd3621930ff 100644 +--- a/grub-core/gnulib/Makefile.am ++++ b/grub-core/gnulib/Makefile.am +@@ -38,8 +38,8 @@ CLEANFILES = + DISTCLEANFILES = + MAINTAINERCLEANFILES = + +-AM_CPPFLAGS = +-AM_CFLAGS = ++AM_CPPFLAGS = $(HOST_CPPFLAGS) ++AM_CFLAGS = $(HOST_CFLAGS) + + noinst_LIBRARIES += libgnu.a + diff --git a/grub.macros b/grub.macros index d15bd25..598f247 100644 --- a/grub.macros +++ b/grub.macros @@ -74,7 +74,7 @@ %global efi_only aarch64 %{arm} -%global efi_arch x86_64 %{ix86} ia64 %{efi_only} +%global efi_arch x86_64 ia64 %{efi_only} %ifarch %{efi_arch} %global with_efi_arch 1 %else diff --git a/grub.patches b/grub.patches index f0fbd01..801c422 100644 --- a/grub.patches +++ b/grub.patches @@ -270,3 +270,11 @@ Patch0269: 0269-Fix-menu-entry-selection-based-on-title.patch Patch0270: 0270-BLS-files-should-only-be-copied-by-grub-switch-to-bl.patch Patch0271: 0271-Fix-get_entry_number-wrongly-dereferencing-the-tail-.patch Patch0272: 0272-Make-grub2-mkconfig-to-honour-GRUB_CMDLINE_LINUX-in-.patch +Patch0273: 0273-Add-efi-export-env-and-efi-load-env-commands.patch +Patch0274: 0274-Make-it-possible-to-subtract-conditions-from-debug.patch +Patch0275: 0275-Export-all-variables-from-the-initial-context-when-c.patch +Patch0276: 0276-blscfg-store-the-BLS-entries-in-a-sorted-linked-list.patch +Patch0277: 0277-blscfg-add-more-options-to-blscfg-command-to-make-it.patch +Patch0278: 0278-blscfg-add-support-for-prepend-early-initrds-to-the-.patch +Patch0279: 0279-Fix-the-looking-up-grub.cfg-XXX-while-tftp-booting.patch +Patch0280: 0280-Try-to-set-fPIE-and-friends-on-libgnu.a.patch diff --git a/grub2.spec b/grub2.spec index fe8f450..9b243bb 100644 --- a/grub2.spec +++ b/grub2.spec @@ -7,7 +7,7 @@ Name: grub2 Epoch: 1 Version: 2.02 -Release: 67%{?dist} +Release: 68%{?dist} Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -473,6 +473,15 @@ rm -r /boot/grub2.tmp/ || : %endif %changelog +* Mon Feb 04 2019 Javier Martinez Canillas - 2.02-68 +- Don't build the grub2-efi-ia32-* packages on i686 (pjones) +- Add efi-export-env and efi-load-env commands (pjones) +- Make it possible to subtract conditions from debug= (pjones) +- Try to set -fPIE and friends on libgnu.a (pjones) +- Add more options to blscfg command to make it more flexible +- Add support for prepend early initrds to the BLS entries +- Fix grub.cfg-XXX look up when booting over TFTP + * Fri Feb 01 2019 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild