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 <javierm@redhat.com>
This commit is contained in:
parent
5699af497f
commit
11b49b804e
@ -7,26 +7,151 @@ Subject: [PATCH] Make grub_strtoul "end" pointer have the right
|
|||||||
Related: rhbz#1640979
|
Related: rhbz#1640979
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
---
|
---
|
||||||
grub-core/kern/fs.c | 2 +-
|
grub-core/commands/date.c | 5 +++--
|
||||||
grub-core/kern/misc.c | 8 ++++----
|
grub-core/commands/password_pbkdf2.c | 2 +-
|
||||||
grub-core/kern/partition.c | 2 +-
|
grub-core/commands/regexp.c | 2 +-
|
||||||
grub-core/lib/legacy_parse.c | 2 +-
|
grub-core/commands/videoinfo.c | 2 +-
|
||||||
grub-core/lib/syslinux_parse.c | 6 +++---
|
grub-core/disk/diskfilter.c | 3 ++-
|
||||||
grub-core/loader/i386/xen_fileXX.c | 2 +-
|
grub-core/disk/lvm.c | 9 +++++----
|
||||||
grub-core/net/efi/ip4_config.c | 2 +-
|
grub-core/kern/fs.c | 2 +-
|
||||||
grub-core/net/efi/ip6_config.c | 2 +-
|
grub-core/kern/misc.c | 8 ++++----
|
||||||
grub-core/net/efi/net.c | 4 ++--
|
grub-core/kern/partition.c | 2 +-
|
||||||
grub-core/net/efi/pxe.c | 6 +++---
|
grub-core/lib/arg.c | 2 +-
|
||||||
grub-core/net/http.c | 4 ++--
|
grub-core/lib/legacy_parse.c | 2 +-
|
||||||
grub-core/net/net.c | 8 ++++----
|
grub-core/lib/syslinux_parse.c | 6 +++---
|
||||||
grub-core/net/url.c | 2 +-
|
grub-core/loader/i386/xen_fileXX.c | 2 +-
|
||||||
grub-core/script/execute.c | 6 +++---
|
grub-core/net/efi/ip4_config.c | 2 +-
|
||||||
grub-core/term/serial.c | 2 +-
|
grub-core/net/efi/ip6_config.c | 2 +-
|
||||||
grub-core/term/terminfo.c | 2 +-
|
grub-core/net/efi/net.c | 4 ++--
|
||||||
grub-core/tests/strtoull_test.c | 2 +-
|
grub-core/net/efi/pxe.c | 6 +++---
|
||||||
include/grub/misc.h | 6 +++---
|
grub-core/net/http.c | 4 ++--
|
||||||
18 files changed, 34 insertions(+), 34 deletions(-)
|
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
|
diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c
|
||||||
index 9085895b6fe..1bd748be83b 100644
|
index 9085895b6fe..1bd748be83b 100644
|
||||||
--- a/grub-core/kern/fs.c
|
--- a/grub-core/kern/fs.c
|
||||||
@ -92,6 +217,19 @@ index e499147cbcb..2c401b866c4 100644
|
|||||||
|
|
||||||
curpart = 0;
|
curpart = 0;
|
||||||
/* Use the first partition map type found. */
|
/* 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
|
diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c
|
||||||
index ef56150ac77..05719ab2ccb 100644
|
index ef56150ac77..05719ab2ccb 100644
|
||||||
--- a/grub-core/lib/legacy_parse.c
|
--- a/grub-core/lib/legacy_parse.c
|
||||||
@ -300,6 +438,19 @@ index 146858284cd..d9d2fc9a9dc 100644
|
|||||||
*port_end = c;
|
*port_end = c;
|
||||||
#ifdef URL_TEST
|
#ifdef URL_TEST
|
||||||
if (portul == ULONG_MAX && errno == ERANGE)
|
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
|
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
||||||
index 93965777138..7d327f59d92 100644
|
index 93965777138..7d327f59d92 100644
|
||||||
--- a/grub-core/script/execute.c
|
--- a/grub-core/script/execute.c
|
||||||
@ -370,6 +521,56 @@ index 7da615ff33e..5488ab26b43 100644
|
|||||||
unsigned long long value;
|
unsigned long long value;
|
||||||
grub_errno = 0;
|
grub_errno = 0;
|
||||||
value = grub_strtoull(input, &output, base);
|
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 <grub/types.h>
|
||||||
|
#include <grub/device.h>
|
||||||
|
|
||||||
|
@@ -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
|
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||||
index de9016ab709..1258ec6bbf3 100644
|
index de9016ab709..1258ec6bbf3 100644
|
||||||
--- a/include/grub/misc.h
|
--- a/include/grub/misc.h
|
||||||
|
360
0273-Add-efi-export-env-and-efi-load-env-commands.patch
Normal file
360
0273-Add-efi-export-env-and-efi-load-env-commands.patch
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
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 <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
+ */
|
||||||
|
+#include <grub/dl.h>
|
||||||
|
+#include <grub/mm.h>
|
||||||
|
+#include <grub/misc.h>
|
||||||
|
+#include <grub/types.h>
|
||||||
|
+#include <grub/mm.h>
|
||||||
|
+#include <grub/misc.h>
|
||||||
|
+#include <grub/efi/api.h>
|
||||||
|
+#include <grub/efi/efi.h>
|
||||||
|
+#include <grub/env.h>
|
||||||
|
+#include <grub/lib/envblk.h>
|
||||||
|
+#include <grub/command.h>
|
||||||
|
+
|
||||||
|
+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 <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
-#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 <config-util.h> /* For *_DIR_NAME defines */
|
||||||
|
#include <grub/types.h>
|
||||||
|
+#include <grub/err.h>
|
||||||
|
#include <grub/lib/envblk.h> /* For GRUB_ENVBLK_DEFCFG define */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
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 <grub/dl.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
|
||||||
|
+#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,
|
@ -0,0 +1,45 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
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 <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
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;
|
@ -0,0 +1,44 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
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 <javierm@redhat.com>
|
||||||
|
---
|
||||||
|
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);
|
||||||
|
|
590
0276-blscfg-store-the-BLS-entries-in-a-sorted-linked-list.patch
Normal file
590
0276-blscfg-store-the-BLS-entries-in-a-sorted-linked-list.patch
Normal file
@ -0,0 +1,590 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
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 <javierm@redhat.com>
|
||||||
|
---
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include <grub/list.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-/* 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 <grub/types.h>
|
||||||
|
-#include <grub/misc.h>
|
||||||
|
-#include <grub/mm.h>
|
||||||
|
-
|
||||||
|
-#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;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
532
0277-blscfg-add-more-options-to-blscfg-command-to-make-it.patch
Normal file
532
0277-blscfg-add-more-options-to-blscfg-command-to-make-it.patch
Normal file
@ -0,0 +1,532 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
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 <javierm@redhat.com>
|
||||||
|
---
|
||||||
|
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 <grub/kernel.h>
|
||||||
|
#include <grub/normal.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
+#include <grub/menu.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
@@ -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);
|
179
0278-blscfg-add-support-for-prepend-early-initrds-to-the-.patch
Normal file
179
0278-blscfg-add-support-for-prepend-early-initrds-to-the-.patch
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Date: Wed, 30 Jan 2019 15:08:22 +0100
|
||||||
|
Subject: [PATCH] blscfg: add support for prepend early initrds to the BLS
|
||||||
|
entries
|
||||||
|
|
||||||
|
There are cases where is needed one or more initramfs besides the one that
|
||||||
|
is defined in the BLS entry. For example, a user may want to add an early
|
||||||
|
initramfs to override some ACPI tables, load CPU microcode, firmware, etc.
|
||||||
|
|
||||||
|
Add support to preprend initrds if they are defined as an early_initrd var
|
||||||
|
in grubenv. Also honor GRUB_EARLY_INITRD_LINUX_CUSTOM in /etc/default/grub
|
||||||
|
and use that value to set the early_initrd var when running grub2-mkconfig.
|
||||||
|
|
||||||
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
@ -0,0 +1,42 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||||
|
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;
|
39
0280-Try-to-set-fPIE-and-friends-on-libgnu.a.patch
Normal file
39
0280-Try-to-set-fPIE-and-friends-on-libgnu.a.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
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 <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
|
|
||||||
%global efi_only aarch64 %{arm}
|
%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}
|
%ifarch %{efi_arch}
|
||||||
%global with_efi_arch 1
|
%global with_efi_arch 1
|
||||||
%else
|
%else
|
||||||
|
@ -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
|
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
|
Patch0271: 0271-Fix-get_entry_number-wrongly-dereferencing-the-tail-.patch
|
||||||
Patch0272: 0272-Make-grub2-mkconfig-to-honour-GRUB_CMDLINE_LINUX-in-.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
|
||||||
|
11
grub2.spec
11
grub2.spec
@ -7,7 +7,7 @@
|
|||||||
Name: grub2
|
Name: grub2
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Version: 2.02
|
Version: 2.02
|
||||||
Release: 67%{?dist}
|
Release: 68%{?dist}
|
||||||
Summary: Bootloader with support for Linux, Multiboot and more
|
Summary: Bootloader with support for Linux, Multiboot and more
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
URL: http://www.gnu.org/software/grub/
|
URL: http://www.gnu.org/software/grub/
|
||||||
@ -473,6 +473,15 @@ rm -r /boot/grub2.tmp/ || :
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Feb 04 2019 Javier Martinez Canillas <javierm@redhat.com> - 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 <releng@fedoraproject.org>
|
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org>
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user