Toshaan Bharvani
4 days ago
343 changed files with 58844 additions and 362 deletions
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 28 Oct 2013 10:09:27 -0400 |
||||
Subject: [PATCH] Enable pager by default. (#985860) |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub.d/00_header.in | 2 ++ |
||||
1 file changed, 2 insertions(+) |
||||
|
||||
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in |
||||
index 93a90233ea..858b526c92 100644 |
||||
--- a/util/grub.d/00_header.in |
||||
+++ b/util/grub.d/00_header.in |
||||
@@ -43,6 +43,8 @@ if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_ |
||||
if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi |
||||
|
||||
cat << EOF |
||||
+set pager=1 |
||||
+ |
||||
if [ -s \$prefix/grubenv ]; then |
||||
load_env |
||||
fi |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 14 Mar 2011 14:27:42 -0400 |
||||
Subject: [PATCH] Don't say "GNU/Linux" in generated menus. |
||||
|
||||
[rharwood: say it even less] |
||||
--- |
||||
grub-core/normal/main.c | 2 +- |
||||
tests/util/grub-shell-tester.in | 2 +- |
||||
tests/util/grub-shell.in | 2 +- |
||||
util/grub.d/10_linux.in | 4 ++-- |
||||
util/grub.d/20_linux_xen.in | 4 ++-- |
||||
5 files changed, 7 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c |
||||
index 7ca2e5400b..98372217ad 100644 |
||||
--- a/grub-core/normal/main.c |
||||
+++ b/grub-core/normal/main.c |
||||
@@ -218,7 +218,7 @@ grub_normal_init_page (struct grub_term_output *term, |
||||
|
||||
grub_term_cls (term); |
||||
|
||||
- msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION); |
||||
+ msg_formatted = grub_xasprintf (_("GRUB version %s"), PACKAGE_VERSION); |
||||
if (!msg_formatted) |
||||
return; |
||||
|
||||
diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in |
||||
index 8a87109b15..9a4319d4f4 100644 |
||||
--- a/tests/util/grub-shell-tester.in |
||||
+++ b/tests/util/grub-shell-tester.in |
||||
@@ -56,7 +56,7 @@ for option in "$@"; do |
||||
usage |
||||
exit 0 ;; |
||||
-v | --version) |
||||
- echo "$0 (GNU GRUB ${PACKAGE_VERSION})" |
||||
+ echo "$0 (GRUB ${PACKAGE_VERSION})" |
||||
exit 0 ;; |
||||
--modules=*) |
||||
ms=`echo "$option" | sed -e 's/--modules=//'` |
||||
diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in |
||||
index 93e9f51484..ec1182bf93 100644 |
||||
--- a/tests/util/grub-shell.in |
||||
+++ b/tests/util/grub-shell.in |
||||
@@ -209,7 +209,7 @@ for option in "$@"; do |
||||
usage |
||||
exit 0 ;; |
||||
-v | --version) |
||||
- echo "$0 (GNU GRUB ${PACKAGE_VERSION})" |
||||
+ echo "$0 (GRUB ${PACKAGE_VERSION})" |
||||
exit 0 ;; |
||||
--trim) |
||||
trim=1 |
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index dc75a1c30b..4a499c53a6 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" |
||||
CLASS="--class gnu-linux --class gnu --class os" |
||||
|
||||
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then |
||||
- OS=GNU/Linux |
||||
+ OS="$(sed 's, release .*$,,g' /etc/system-release)" |
||||
else |
||||
- OS="${GRUB_DISTRIBUTOR} GNU/Linux" |
||||
+ OS="${GRUB_DISTRIBUTOR}" |
||||
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" |
||||
fi |
||||
|
||||
diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in |
||||
index 3b1f470492..ada20775a1 100644 |
||||
--- a/util/grub.d/20_linux_xen.in |
||||
+++ b/util/grub.d/20_linux_xen.in |
||||
@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" |
||||
CLASS="--class gnu-linux --class gnu --class os --class xen" |
||||
|
||||
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then |
||||
- OS=GNU/Linux |
||||
+ OS="$(sed 's, release .*$,,g' /etc/system-release)" |
||||
else |
||||
- OS="${GRUB_DISTRIBUTOR} GNU/Linux" |
||||
+ OS="${GRUB_DISTRIBUTOR}" |
||||
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" |
||||
fi |
||||
|
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Fedora Ninjas <grub2-owner@fedoraproject.org> |
||||
Date: Mon, 13 Jan 2014 21:50:59 -0500 |
||||
Subject: [PATCH] Add .eh_frame to list of relocations stripped |
||||
|
||||
--- |
||||
conf/Makefile.common | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/conf/Makefile.common b/conf/Makefile.common |
||||
index 2a1a886f6d..191b1a70c6 100644 |
||||
--- a/conf/Makefile.common |
||||
+++ b/conf/Makefile.common |
||||
@@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding |
||||
LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) |
||||
CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 |
||||
CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) |
||||
-STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx |
||||
+STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx |
||||
|
||||
CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding |
||||
LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 11 Feb 2014 11:14:50 -0500 |
||||
Subject: [PATCH] Don't require a password to boot entries generated by |
||||
grub-mkconfig. |
||||
|
||||
When we set a password, we just want that to mean you can't /edit/ an entry. |
||||
|
||||
Resolves: rhbz#1030176 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub.d/10_linux.in | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index 4a499c53a6..cf8d118698 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -26,7 +26,7 @@ datarootdir="@datarootdir@" |
||||
export TEXTDOMAIN=@PACKAGE@ |
||||
export TEXTDOMAINDIR="@localedir@" |
||||
|
||||
-CLASS="--class gnu-linux --class gnu --class os" |
||||
+CLASS="--class gnu-linux --class gnu --class os --unrestricted" |
||||
|
||||
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then |
||||
OS="$(sed 's, release .*$,,g' /etc/system-release)" |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Fedora Ninjas <grub2-owner@fedoraproject.org> |
||||
Date: Wed, 19 Feb 2014 15:58:43 -0500 |
||||
Subject: [PATCH] use fw_path prefix when fallback searching for grub config |
||||
|
||||
When PXE booting via UEFI firmware, grub was searching for grub.cfg |
||||
in the fw_path directory where the grub application was found. If |
||||
that didn't exist, a fallback search would look for config file names |
||||
based on MAC and IP address. However, the search would look in the |
||||
prefix directory which may not be the same fw_path. This patch |
||||
changes that behavior to use the fw_path directory for the fallback |
||||
search. Only if fw_path is NULL will the prefix directory be searched. |
||||
|
||||
Signed-off-by: Mark Salter <msalter@redhat.com> |
||||
--- |
||||
grub-core/normal/main.c | 5 +++-- |
||||
1 file changed, 3 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c |
||||
index 98372217ad..bf24e65713 100644 |
||||
--- a/grub-core/normal/main.c |
||||
+++ b/grub-core/normal/main.c |
||||
@@ -347,7 +347,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), |
||||
char *config; |
||||
const char *prefix, *fw_path; |
||||
|
||||
- fw_path = grub_env_get ("fw_path"); |
||||
+ prefix = fw_path = grub_env_get ("fw_path"); |
||||
if (fw_path) |
||||
{ |
||||
config = grub_xasprintf ("%s/grub.cfg", fw_path); |
||||
@@ -370,7 +370,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), |
||||
} |
||||
} |
||||
|
||||
- prefix = grub_env_get ("prefix"); |
||||
+ if (! prefix) |
||||
+ prefix = grub_env_get ("prefix"); |
||||
if (prefix) |
||||
{ |
||||
grub_size_t config_len; |
@ -0,0 +1,127 @@
@@ -0,0 +1,127 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 8 Jul 2019 17:33:22 +0200 |
||||
Subject: [PATCH] Try mac/guid/etc before grub.cfg on tftp config files. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/normal/main.c | 97 ++++++++++++++++++++++++++----------------------- |
||||
1 file changed, 51 insertions(+), 46 deletions(-) |
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c |
||||
index bf24e65713..0a99768f75 100644 |
||||
--- a/grub-core/normal/main.c |
||||
+++ b/grub-core/normal/main.c |
||||
@@ -345,61 +345,66 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), |
||||
/* Guess the config filename. It is necessary to make CONFIG static, |
||||
so that it won't get broken by longjmp. */ |
||||
char *config; |
||||
- const char *prefix, *fw_path; |
||||
- |
||||
- prefix = fw_path = grub_env_get ("fw_path"); |
||||
- if (fw_path) |
||||
- { |
||||
- config = grub_xasprintf ("%s/grub.cfg", fw_path); |
||||
- if (config) |
||||
- { |
||||
- grub_file_t file; |
||||
- |
||||
- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); |
||||
- if (file) |
||||
- { |
||||
- grub_file_close (file); |
||||
- grub_enter_normal_mode (config); |
||||
- } |
||||
- else |
||||
- { |
||||
- /* Ignore all errors. */ |
||||
- grub_errno = 0; |
||||
- } |
||||
- grub_free (config); |
||||
- } |
||||
- } |
||||
+ const char *prefix; |
||||
+ const char *net_search_cfg; |
||||
+ int disable_net_search = 0; |
||||
|
||||
+ prefix = grub_env_get ("fw_path"); |
||||
if (! prefix) |
||||
prefix = grub_env_get ("prefix"); |
||||
+ |
||||
+ net_search_cfg = grub_env_get ("feature_net_search_cfg"); |
||||
+ if (net_search_cfg && net_search_cfg[0] == 'n') |
||||
+ disable_net_search = 1; |
||||
+ |
||||
if (prefix) |
||||
{ |
||||
- grub_size_t config_len; |
||||
- int disable_net_search = 0; |
||||
- const char *net_search_cfg; |
||||
- |
||||
- config_len = grub_strlen (prefix) + |
||||
- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); |
||||
- config = grub_malloc (config_len); |
||||
- |
||||
- if (!config) |
||||
- goto quit; |
||||
- |
||||
- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); |
||||
- |
||||
- net_search_cfg = grub_env_get ("feature_net_search_cfg"); |
||||
- if (net_search_cfg && net_search_cfg[0] == 'n') |
||||
- disable_net_search = 1; |
||||
- |
||||
if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && |
||||
!disable_net_search) |
||||
- grub_net_search_config_file (config); |
||||
+ { |
||||
+ grub_size_t config_len; |
||||
+ config_len = grub_strlen (prefix) + |
||||
+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); |
||||
+ config = grub_malloc (config_len); |
||||
|
||||
- grub_enter_normal_mode (config); |
||||
- grub_free (config); |
||||
- } |
||||
+ if (! config) |
||||
+ goto quit; |
||||
+ |
||||
+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); |
||||
+ |
||||
+ grub_net_search_configfile (config); |
||||
+ |
||||
+ grub_enter_normal_mode (config); |
||||
+ grub_free (config); |
||||
+ config = NULL; |
||||
+ } |
||||
+ |
||||
+ if (!config) |
||||
+ { |
||||
+ config = grub_xasprintf ("%s/grub.cfg", prefix); |
||||
+ if (config) |
||||
+ { |
||||
+ grub_file_t file; |
||||
+ |
||||
+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); |
||||
+ if (file) |
||||
+ { |
||||
+ grub_file_close (file); |
||||
+ grub_enter_normal_mode (config); |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ /* Ignore all errors. */ |
||||
+ grub_errno = 0; |
||||
+ } |
||||
+ grub_free (config); |
||||
+ } |
||||
+ } |
||||
+ } |
||||
else |
||||
- grub_enter_normal_mode (0); |
||||
+ { |
||||
+ grub_enter_normal_mode (0); |
||||
+ } |
||||
} |
||||
else |
||||
grub_enter_normal_mode (argv[0]); |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 4 Sep 2014 14:23:23 -0400 |
||||
Subject: [PATCH] Generate OS and CLASS in 10_linux from /etc/os-release |
||||
|
||||
This makes us use pretty names in the titles we generate in |
||||
grub2-mkconfig when GRUB_DISTRIBUTOR isn't set. |
||||
|
||||
Resolves: rhbz#996794 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub.d/10_linux.in | 3 ++- |
||||
1 file changed, 2 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index cf8d118698..5f6d3c8d52 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -29,7 +29,8 @@ export TEXTDOMAINDIR="@localedir@" |
||||
CLASS="--class gnu-linux --class gnu --class os --unrestricted" |
||||
|
||||
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then |
||||
- OS="$(sed 's, release .*$,,g' /etc/system-release)" |
||||
+ OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})" |
||||
+ CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n "${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}" |
||||
else |
||||
OS="${GRUB_DISTRIBUTOR}" |
||||
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 4 Sep 2014 15:52:08 -0400 |
||||
Subject: [PATCH] Minimize the sort ordering for .debug and -rescue- kernels. |
||||
|
||||
Resolves: rhbz#1065360 |
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub-mkconfig_lib.in | 8 ++++++++ |
||||
1 file changed, 8 insertions(+) |
||||
|
||||
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in |
||||
index 301d1ac229..0f6505bf3b 100644 |
||||
--- a/util/grub-mkconfig_lib.in |
||||
+++ b/util/grub-mkconfig_lib.in |
||||
@@ -253,6 +253,14 @@ version_test_gt () |
||||
*.old:*.old) ;; |
||||
*.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; |
||||
*:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; |
||||
+ *-rescue*:*-rescue*) ;; |
||||
+ *?debug:*?debug) ;; |
||||
+ *-rescue*:*?debug) return 1 ;; |
||||
+ *?debug:*-rescue*) return 0 ;; |
||||
+ *-rescue*:*) return 1 ;; |
||||
+ *:*-rescue*) return 0 ;; |
||||
+ *?debug:*) return 1 ;; |
||||
+ *:*?debug) return 0 ;; |
||||
esac |
||||
version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" |
||||
return "$?" |
@ -0,0 +1,222 @@
@@ -0,0 +1,222 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 9 Jul 2019 10:35:16 +0200 |
||||
Subject: [PATCH] Try $prefix if $fw_path doesn't work. |
||||
|
||||
Related: rhbz#1148652 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/ieee1275/init.c | 28 +++++---- |
||||
grub-core/net/net.c | 2 +- |
||||
grub-core/normal/main.c | 134 ++++++++++++++++++++--------------------- |
||||
3 files changed, 82 insertions(+), 82 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c |
||||
index e71d158416..0cd2a62723 100644 |
||||
--- a/grub-core/kern/ieee1275/init.c |
||||
+++ b/grub-core/kern/ieee1275/init.c |
||||
@@ -127,23 +127,25 @@ grub_machine_get_bootlocation (char **device, char **path) |
||||
grub_free (canon); |
||||
} |
||||
else |
||||
- *device = grub_ieee1275_encode_devname (bootpath); |
||||
- grub_free (type); |
||||
- |
||||
- filename = grub_ieee1275_get_filename (bootpath); |
||||
- if (filename) |
||||
{ |
||||
- char *lastslash = grub_strrchr (filename, '\\'); |
||||
- |
||||
- /* Truncate at last directory. */ |
||||
- if (lastslash) |
||||
+ filename = grub_ieee1275_get_filename (bootpath); |
||||
+ if (filename) |
||||
{ |
||||
- *lastslash = '\0'; |
||||
- grub_translate_ieee1275_path (filename); |
||||
+ char *lastslash = grub_strrchr (filename, '\\'); |
||||
|
||||
- *path = filename; |
||||
- } |
||||
+ /* Truncate at last directory. */ |
||||
+ if (lastslash) |
||||
+ { |
||||
+ *lastslash = '\0'; |
||||
+ grub_translate_ieee1275_path (filename); |
||||
+ |
||||
+ *path = filename; |
||||
+ } |
||||
+ } |
||||
+ *device = grub_ieee1275_encode_devname (bootpath); |
||||
} |
||||
+ |
||||
+ grub_free (type); |
||||
grub_free (bootpath); |
||||
} |
||||
|
||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c |
||||
index 4d3eb5c1a5..0ef148f4ad 100644 |
||||
--- a/grub-core/net/net.c |
||||
+++ b/grub-core/net/net.c |
||||
@@ -1869,7 +1869,7 @@ grub_net_search_config_file (char *config) |
||||
/* Remove the remaining minus sign at the end. */ |
||||
config[config_len] = '\0'; |
||||
|
||||
- return GRUB_ERR_NONE; |
||||
+ return GRUB_ERR_FILE_NOT_FOUND; |
||||
} |
||||
|
||||
static struct grub_preboot *fini_hnd; |
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c |
||||
index 0a99768f75..55558cc0b9 100644 |
||||
--- a/grub-core/normal/main.c |
||||
+++ b/grub-core/normal/main.c |
||||
@@ -335,81 +335,79 @@ grub_enter_normal_mode (const char *config) |
||||
grub_boot_time ("Exiting normal mode"); |
||||
} |
||||
|
||||
+static grub_err_t |
||||
+grub_try_normal (const char *variable) |
||||
+{ |
||||
+ char *config; |
||||
+ const char *prefix; |
||||
+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; |
||||
+ const char *net_search_cfg; |
||||
+ int disable_net_search = 0; |
||||
+ |
||||
+ prefix = grub_env_get (variable); |
||||
+ if (!prefix) |
||||
+ return GRUB_ERR_FILE_NOT_FOUND; |
||||
+ |
||||
+ net_search_cfg = grub_env_get ("feature_net_search_cfg"); |
||||
+ if (net_search_cfg && net_search_cfg[0] == 'n') |
||||
+ disable_net_search = 1; |
||||
+ |
||||
+ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && |
||||
+ !disable_net_search) |
||||
+ { |
||||
+ grub_size_t config_len; |
||||
+ config_len = grub_strlen (prefix) + |
||||
+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); |
||||
+ config = grub_malloc (config_len); |
||||
+ |
||||
+ if (! config) |
||||
+ return GRUB_ERR_FILE_NOT_FOUND; |
||||
+ |
||||
+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); |
||||
+ err = grub_net_search_config_file (config); |
||||
+ } |
||||
+ |
||||
+ if (err != GRUB_ERR_NONE) |
||||
+ { |
||||
+ config = grub_xasprintf ("%s/grub.cfg", prefix); |
||||
+ if (config) |
||||
+ { |
||||
+ grub_file_t file; |
||||
+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); |
||||
+ if (file) |
||||
+ { |
||||
+ grub_file_close (file); |
||||
+ err = GRUB_ERR_NONE; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (err == GRUB_ERR_NONE) |
||||
+ grub_enter_normal_mode (config); |
||||
+ |
||||
+ grub_errno = 0; |
||||
+ grub_free (config); |
||||
+ return err; |
||||
+} |
||||
+ |
||||
/* Enter normal mode from rescue mode. */ |
||||
static grub_err_t |
||||
grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), |
||||
int argc, char *argv[]) |
||||
{ |
||||
- if (argc == 0) |
||||
- { |
||||
- /* Guess the config filename. It is necessary to make CONFIG static, |
||||
- so that it won't get broken by longjmp. */ |
||||
- char *config; |
||||
- const char *prefix; |
||||
- const char *net_search_cfg; |
||||
- int disable_net_search = 0; |
||||
- |
||||
- prefix = grub_env_get ("fw_path"); |
||||
- if (! prefix) |
||||
- prefix = grub_env_get ("prefix"); |
||||
- |
||||
- net_search_cfg = grub_env_get ("feature_net_search_cfg"); |
||||
- if (net_search_cfg && net_search_cfg[0] == 'n') |
||||
- disable_net_search = 1; |
||||
- |
||||
- if (prefix) |
||||
- { |
||||
- if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && |
||||
- !disable_net_search) |
||||
- { |
||||
- grub_size_t config_len; |
||||
- config_len = grub_strlen (prefix) + |
||||
- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); |
||||
- config = grub_malloc (config_len); |
||||
- |
||||
- if (! config) |
||||
- goto quit; |
||||
- |
||||
- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); |
||||
- |
||||
- grub_net_search_configfile (config); |
||||
- |
||||
- grub_enter_normal_mode (config); |
||||
- grub_free (config); |
||||
- config = NULL; |
||||
- } |
||||
- |
||||
- if (!config) |
||||
- { |
||||
- config = grub_xasprintf ("%s/grub.cfg", prefix); |
||||
- if (config) |
||||
- { |
||||
- grub_file_t file; |
||||
- |
||||
- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); |
||||
- if (file) |
||||
- { |
||||
- grub_file_close (file); |
||||
- grub_enter_normal_mode (config); |
||||
- } |
||||
- else |
||||
- { |
||||
- /* Ignore all errors. */ |
||||
- grub_errno = 0; |
||||
- } |
||||
- grub_free (config); |
||||
- } |
||||
- } |
||||
- } |
||||
- else |
||||
- { |
||||
- grub_enter_normal_mode (0); |
||||
- } |
||||
- } |
||||
- else |
||||
+ if (argc) |
||||
grub_enter_normal_mode (argv[0]); |
||||
+ else |
||||
+ { |
||||
+ /* Guess the config filename. */ |
||||
+ grub_err_t err; |
||||
+ err = grub_try_normal ("fw_path"); |
||||
+ if (err == GRUB_ERR_FILE_NOT_FOUND) |
||||
+ err = grub_try_normal ("prefix"); |
||||
+ if (err == GRUB_ERR_FILE_NOT_FOUND) |
||||
+ grub_enter_normal_mode (0); |
||||
+ } |
||||
|
||||
-quit: |
||||
return 0; |
||||
} |
||||
|
@ -0,0 +1,69 @@
@@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 28 Apr 2015 11:15:03 -0400 |
||||
Subject: [PATCH] Make grub2-mkconfig construct titles that look like the ones |
||||
we want elsewhere. |
||||
|
||||
Resolves: rhbz#1215839 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++------- |
||||
1 file changed, 27 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index 5f6d3c8d52..786dbabb4a 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -78,6 +78,32 @@ case x"$GRUB_FS" in |
||||
;; |
||||
esac |
||||
|
||||
+mktitle () |
||||
+{ |
||||
+ local title_type |
||||
+ local version |
||||
+ local OS_NAME |
||||
+ local OS_VERS |
||||
+ |
||||
+ title_type=$1 && shift |
||||
+ version=$1 && shift |
||||
+ |
||||
+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" |
||||
+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" |
||||
+ |
||||
+ case $title_type in |
||||
+ recovery) |
||||
+ title=$(printf '%s (%s) %s (recovery mode)' \ |
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}") |
||||
+ ;; |
||||
+ *) |
||||
+ title=$(printf '%s (%s) %s' \ |
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}") |
||||
+ ;; |
||||
+ esac |
||||
+ echo -n ${title} |
||||
+} |
||||
+ |
||||
title_correction_code= |
||||
|
||||
linux_entry () |
||||
@@ -91,17 +117,11 @@ linux_entry () |
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" |
||||
fi |
||||
if [ x$type != xsimple ] ; then |
||||
- case $type in |
||||
- recovery) |
||||
- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; |
||||
- *) |
||||
- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; |
||||
- esac |
||||
+ title=$(mktitle "$type" "$version") |
||||
if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then |
||||
replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" |
||||
quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" |
||||
title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" |
||||
- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" |
||||
fi |
||||
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" |
||||
else |
@ -0,0 +1,245 @@
@@ -0,0 +1,245 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Robert Marshall <rmarshall@redhat.com> |
||||
Date: Thu, 25 Jun 2015 11:13:11 -0400 |
||||
Subject: [PATCH] Add friendly grub2 password config tool (#985962) |
||||
|
||||
Provided a tool for users to reset the grub2 root user password |
||||
without having to alter the grub.cfg. The hashed password now |
||||
lives in a root-only-readable configuration file. |
||||
|
||||
Resolves: rhbz#985962 |
||||
|
||||
Signed-off-by: Robert Marshall <rmarshall@redhat.com> |
||||
[pjones: fix the efidir in grub-setpassword and rename tool] |
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[luto: fix grub-setpassword -o's output path] |
||||
Signed-off-by: Andy Lutomirski <luto@kernel.org> |
||||
[rharwood: migrate man page to h2m, context] |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
configure.ac | 1 + |
||||
Makefile.util.def | 13 +++++ |
||||
docs/man/grub-set-password.h2m | 2 + |
||||
util/grub-mkconfig.in | 2 + |
||||
util/grub-set-password.in | 128 +++++++++++++++++++++++++++++++++++++++++ |
||||
util/grub.d/01_users.in | 11 ++++ |
||||
6 files changed, 157 insertions(+) |
||||
create mode 100644 docs/man/grub-set-password.h2m |
||||
create mode 100644 util/grub-set-password.in |
||||
create mode 100644 util/grub.d/01_users.in |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 8331f95b64..7f59ad788f 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -72,6 +72,7 @@ grub_TRANSFORM([grub-mkrelpath]) |
||||
grub_TRANSFORM([grub-mkrescue]) |
||||
grub_TRANSFORM([grub-probe]) |
||||
grub_TRANSFORM([grub-reboot]) |
||||
+grub_TRANSFORM([grub-set-password]) |
||||
grub_TRANSFORM([grub-script-check]) |
||||
grub_TRANSFORM([grub-set-default]) |
||||
grub_TRANSFORM([grub-sparc64-setup]) |
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index 2c9b283a23..4ee22c5daa 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -452,6 +452,12 @@ script = { |
||||
installdir = grubconf; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = '01_users'; |
||||
+ common = util/grub.d/01_users.in; |
||||
+ installdir = grubconf; |
||||
+}; |
||||
+ |
||||
script = { |
||||
name = '10_windows'; |
||||
common = util/grub.d/10_windows.in; |
||||
@@ -724,6 +730,13 @@ script = { |
||||
installdir = sbin; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = grub-set-password; |
||||
+ common = util/grub-set-password.in; |
||||
+ mansection = 8; |
||||
+ installdir = sbin; |
||||
+}; |
||||
+ |
||||
script = { |
||||
name = grub-mkconfig_lib; |
||||
common = util/grub-mkconfig_lib.in; |
||||
diff --git a/docs/man/grub-set-password.h2m b/docs/man/grub-set-password.h2m |
||||
new file mode 100644 |
||||
index 0000000000..10ee82f4d5 |
||||
--- /dev/null |
||||
+++ b/docs/man/grub-set-password.h2m |
||||
@@ -0,0 +1,2 @@ |
||||
+[NAME] |
||||
+grub-set-password \- generate the user.cfg file containing the hashed grub bootloader password |
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in |
||||
index 8ea2315ebc..ba14cf6261 100644 |
||||
--- a/util/grub-mkconfig.in |
||||
+++ b/util/grub-mkconfig.in |
||||
@@ -276,6 +276,8 @@ for i in "${grub_mkconfig_dir}"/* ; do |
||||
*~) ;; |
||||
# emacsen autosave files. FIXME: support other editors |
||||
*/\#*\#) ;; |
||||
+ # rpm config files of yore. |
||||
+ *.rpmsave|*.rpmnew|*.rpmorig) ;; |
||||
*) |
||||
if grub_file_is_not_garbage "$i" && test -x "$i" ; then |
||||
echo |
||||
diff --git a/util/grub-set-password.in b/util/grub-set-password.in |
||||
new file mode 100644 |
||||
index 0000000000..5ebf50576d |
||||
--- /dev/null |
||||
+++ b/util/grub-set-password.in |
||||
@@ -0,0 +1,128 @@ |
||||
+#!/bin/sh -e |
||||
+ |
||||
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/') |
||||
+if [ -d /sys/firmware/efi/efivars/ ]; then |
||||
+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` |
||||
+else |
||||
+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` |
||||
+fi |
||||
+ |
||||
+PACKAGE_VERSION="@PACKAGE_VERSION@" |
||||
+PACKAGE_NAME="@PACKAGE_NAME@" |
||||
+self=`basename $0` |
||||
+bindir="@bindir@" |
||||
+grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" |
||||
+ |
||||
+# Usage: usage |
||||
+# Print the usage. |
||||
+usage () { |
||||
+ cat <<EOF |
||||
+Usage: $0 [OPTION] |
||||
+$0 prompts the user to set a password on the grub bootloader. The password |
||||
+is written to a file named user.cfg which lives in the GRUB directory |
||||
+located by default at ${grubdir}. |
||||
+ |
||||
+ -h, --help print this message and exit |
||||
+ -v, --version print the version information and exit |
||||
+ -o, --output_path <DIRECTORY> put user.cfg in a user-selected directory |
||||
+ |
||||
+Report bugs at https://bugzilla.redhat.com. |
||||
+EOF |
||||
+} |
||||
+ |
||||
+argument () { |
||||
+ opt=$1 |
||||
+ shift |
||||
+ |
||||
+ if test $# -eq 0; then |
||||
+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 |
||||
+ exit 1 |
||||
+ fi |
||||
+ echo $1 |
||||
+} |
||||
+ |
||||
+# Ensure that it's the root user running this script |
||||
+if [ "${EUID}" -ne 0 ]; then |
||||
+ echo "The grub bootloader password may only be set by root." |
||||
+ usage |
||||
+ exit 2 |
||||
+fi |
||||
+ |
||||
+# Check the arguments. |
||||
+while test $# -gt 0 |
||||
+do |
||||
+ option=$1 |
||||
+ shift |
||||
+ |
||||
+ case "$option" in |
||||
+ -h | --help) |
||||
+ usage |
||||
+ exit 0 ;; |
||||
+ -v | --version) |
||||
+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" |
||||
+ exit 0 ;; |
||||
+ -o | --output) |
||||
+ OUTPUT_PATH=`argument $option "$@"`; shift ;; |
||||
+ --output=*) |
||||
+ OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; |
||||
+ -o=*) |
||||
+ OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; |
||||
+ esac |
||||
+done |
||||
+ |
||||
+# set user input or default path for user.cfg file |
||||
+if [ -z "${OUTPUT_PATH}" ]; then |
||||
+ OUTPUT_PATH="${grubdir}" |
||||
+fi |
||||
+ |
||||
+if [ ! -d "${OUTPUT_PATH}" ]; then |
||||
+ echo "${OUTPUT_PATH} does not exist." |
||||
+ usage |
||||
+ exit 2; |
||||
+fi |
||||
+ |
||||
+ttyopt=$(stty -g) |
||||
+fixtty() { |
||||
+ stty ${ttyopt} |
||||
+} |
||||
+ |
||||
+trap fixtty EXIT |
||||
+stty -echo |
||||
+ |
||||
+# prompt & confirm new grub2 root user password |
||||
+echo -n "Enter password: " |
||||
+read PASSWORD |
||||
+echo |
||||
+echo -n "Confirm password: " |
||||
+read PASSWORD_CONFIRM |
||||
+echo |
||||
+stty ${ttyopt} |
||||
+ |
||||
+getpass() { |
||||
+ local P0 |
||||
+ local P1 |
||||
+ P0="$1" && shift |
||||
+ P1="$1" && shift |
||||
+ |
||||
+ ( echo ${P0} ; echo ${P1} ) | \ |
||||
+ LC_ALL=C ${grub_mkpasswd} | \ |
||||
+ grep -v '[eE]nter password:' | \ |
||||
+ sed -e "s/PBKDF2 hash of your password is //" |
||||
+} |
||||
+ |
||||
+MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" |
||||
+if [ -z "${MYPASS}" ]; then |
||||
+ echo "${self}: error: empty password" 1>&2 |
||||
+ exit 1 |
||||
+fi |
||||
+ |
||||
+# on the ESP, these will fail to set the permissions, but it's okay because |
||||
+# the directory is protected. |
||||
+install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : |
||||
+chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : |
||||
+echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg" |
||||
+ |
||||
+if ! grep -q "^### BEGIN /etc/grub.d/01_users ###$" "${OUTPUT_PATH}/grub.cfg"; then |
||||
+ echo "WARNING: The current configuration lacks password support!" |
||||
+ echo "Update your configuration with @grub_mkconfig@ to support this feature." |
||||
+fi |
||||
diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in |
||||
new file mode 100644 |
||||
index 0000000000..db2f44bfb7 |
||||
--- /dev/null |
||||
+++ b/util/grub.d/01_users.in |
||||
@@ -0,0 +1,11 @@ |
||||
+#!/bin/sh -e |
||||
+cat << EOF |
||||
+if [ -f \${prefix}/user.cfg ]; then |
||||
+ source \${prefix}/user.cfg |
||||
+ if [ -n "\${GRUB2_PASSWORD}" ]; then |
||||
+ set superusers="root" |
||||
+ export superusers |
||||
+ password_pbkdf2 root \${GRUB2_PASSWORD} |
||||
+ fi |
||||
+fi |
||||
+EOF |
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Josef Bacik <jbacik@fb.com> |
||||
Date: Wed, 12 Aug 2015 08:57:55 -0700 |
||||
Subject: [PATCH] tcp: add window scaling support |
||||
|
||||
Sometimes we have to provision boxes across regions, such as California to |
||||
Sweden. The http server has a 10 minute timeout, so if we can't get our 250mb |
||||
image transferred fast enough our provisioning fails, which is not ideal. So |
||||
add tcp window scaling on open connections and set the window size to 1mb. With |
||||
this change we're able to get higher sustained transfers between regions and can |
||||
transfer our image in well below 10 minutes. Without this patch we'd time out |
||||
every time halfway through the transfer. Thanks, |
||||
|
||||
Signed-off-by: Josef Bacik <jbacik@fb.com> |
||||
--- |
||||
grub-core/net/tcp.c | 42 +++++++++++++++++++++++++++++------------- |
||||
1 file changed, 29 insertions(+), 13 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c |
||||
index e8ad34b84d..7d4b822626 100644 |
||||
--- a/grub-core/net/tcp.c |
||||
+++ b/grub-core/net/tcp.c |
||||
@@ -106,6 +106,18 @@ struct tcphdr |
||||
grub_uint16_t urgent; |
||||
} GRUB_PACKED; |
||||
|
||||
+struct tcp_scale_opt { |
||||
+ grub_uint8_t kind; |
||||
+ grub_uint8_t length; |
||||
+ grub_uint8_t scale; |
||||
+} GRUB_PACKED; |
||||
+ |
||||
+struct tcp_synhdr { |
||||
+ struct tcphdr tcphdr; |
||||
+ struct tcp_scale_opt scale_opt; |
||||
+ grub_uint8_t padding; |
||||
+}; |
||||
+ |
||||
struct tcp_pseudohdr |
||||
{ |
||||
grub_uint32_t src; |
||||
@@ -566,7 +578,7 @@ grub_net_tcp_open (char *server, |
||||
grub_net_tcp_socket_t socket; |
||||
static grub_uint16_t in_port = 21550; |
||||
struct grub_net_buff *nb; |
||||
- struct tcphdr *tcph; |
||||
+ struct tcp_synhdr *tcph; |
||||
int i; |
||||
grub_uint8_t *nbd; |
||||
grub_net_link_level_address_t ll_target_addr; |
||||
@@ -635,20 +647,24 @@ grub_net_tcp_open (char *server, |
||||
} |
||||
|
||||
tcph = (void *) nb->data; |
||||
+ grub_memset(tcph, 0, sizeof (*tcph)); |
||||
socket->my_start_seq = grub_get_time_ms (); |
||||
socket->my_cur_seq = socket->my_start_seq + 1; |
||||
- socket->my_window = 8192; |
||||
- tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq); |
||||
- tcph->ack = grub_cpu_to_be32_compile_time (0); |
||||
- tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN); |
||||
- tcph->window = grub_cpu_to_be16 (socket->my_window); |
||||
- tcph->urgent = 0; |
||||
- tcph->src = grub_cpu_to_be16 (socket->in_port); |
||||
- tcph->dst = grub_cpu_to_be16 (socket->out_port); |
||||
- tcph->checksum = 0; |
||||
- tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, |
||||
- &socket->inf->address, |
||||
- &socket->out_nla); |
||||
+ socket->my_window = 32768; |
||||
+ tcph->tcphdr.seqnr = grub_cpu_to_be32 (socket->my_start_seq); |
||||
+ tcph->tcphdr.ack = grub_cpu_to_be32_compile_time (0); |
||||
+ tcph->tcphdr.flags = grub_cpu_to_be16_compile_time ((6 << 12) | TCP_SYN); |
||||
+ tcph->tcphdr.window = grub_cpu_to_be16 (socket->my_window); |
||||
+ tcph->tcphdr.urgent = 0; |
||||
+ tcph->tcphdr.src = grub_cpu_to_be16 (socket->in_port); |
||||
+ tcph->tcphdr.dst = grub_cpu_to_be16 (socket->out_port); |
||||
+ tcph->tcphdr.checksum = 0; |
||||
+ tcph->scale_opt.kind = 3; |
||||
+ tcph->scale_opt.length = 3; |
||||
+ tcph->scale_opt.scale = 5; |
||||
+ tcph->tcphdr.checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, |
||||
+ &socket->inf->address, |
||||
+ &socket->out_nla); |
||||
|
||||
tcp_socket_register (socket); |
||||
|
@ -0,0 +1,651 @@
@@ -0,0 +1,651 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 9 Jul 2019 11:47:37 +0200 |
||||
Subject: [PATCH] efinet and bootp: add support for dhcpv6 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/net/bootp.c | 173 +++++++++++++++++++++++++++++++++++++ |
||||
grub-core/net/drivers/efi/efinet.c | 53 ++++++++++-- |
||||
grub-core/net/net.c | 72 +++++++++++++++ |
||||
grub-core/net/tftp.c | 4 + |
||||
include/grub/efi/api.h | 129 +++++++++++++++++++++++++-- |
||||
include/grub/net.h | 60 +++++++++++++ |
||||
6 files changed, 477 insertions(+), 14 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c |
||||
index 6fb5627025..e28fb6a09f 100644 |
||||
--- a/grub-core/net/bootp.c |
||||
+++ b/grub-core/net/bootp.c |
||||
@@ -902,6 +902,179 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), |
||||
|
||||
static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; |
||||
|
||||
+struct grub_net_network_level_interface * |
||||
+grub_net_configure_by_dhcpv6_ack (const char *name, |
||||
+ struct grub_net_card *card, |
||||
+ grub_net_interface_flags_t flags |
||||
+ __attribute__((__unused__)), |
||||
+ const grub_net_link_level_address_t *hwaddr, |
||||
+ const struct grub_net_dhcpv6_packet *packet, |
||||
+ int is_def, char **device, char **path) |
||||
+{ |
||||
+ struct grub_net_network_level_interface *inter = NULL; |
||||
+ struct grub_net_network_level_address addr; |
||||
+ int mask = -1; |
||||
+ |
||||
+ if (!device || !path) |
||||
+ return NULL; |
||||
+ |
||||
+ *device = 0; |
||||
+ *path = 0; |
||||
+ |
||||
+ grub_dprintf ("net", "mac address is %02x:%02x:%02x:%02x:%02x:%02x\n", |
||||
+ hwaddr->mac[0], hwaddr->mac[1], hwaddr->mac[2], |
||||
+ hwaddr->mac[3], hwaddr->mac[4], hwaddr->mac[5]); |
||||
+ |
||||
+ if (is_def) |
||||
+ grub_net_default_server = 0; |
||||
+ |
||||
+ if (is_def && !grub_net_default_server && packet) |
||||
+ { |
||||
+ const grub_uint8_t *options = packet->dhcp_options; |
||||
+ unsigned int option_max = 1024 - OFFSET_OF (dhcp_options, packet); |
||||
+ unsigned int i; |
||||
+ |
||||
+ for (i = 0; i < option_max - sizeof (grub_net_dhcpv6_option_t); ) |
||||
+ { |
||||
+ grub_uint16_t num, len; |
||||
+ grub_net_dhcpv6_option_t *opt = |
||||
+ (grub_net_dhcpv6_option_t *)(options + i); |
||||
+ |
||||
+ num = grub_be_to_cpu16(opt->option_num); |
||||
+ len = grub_be_to_cpu16(opt->option_len); |
||||
+ |
||||
+ grub_dprintf ("net", "got dhcpv6 option %d len %d\n", num, len); |
||||
+ |
||||
+ if (len == 0) |
||||
+ break; |
||||
+ |
||||
+ if (len + i > 1024) |
||||
+ break; |
||||
+ |
||||
+ if (num == GRUB_NET_DHCP6_BOOTFILE_URL) |
||||
+ { |
||||
+ char *scheme, *userinfo, *host, *file; |
||||
+ char *tmp; |
||||
+ int hostlen; |
||||
+ int port; |
||||
+ int rc = extract_url_info ((const char *)opt->option_data, |
||||
+ (grub_size_t)len, |
||||
+ &scheme, &userinfo, &host, &port, |
||||
+ &file); |
||||
+ if (rc < 0) |
||||
+ continue; |
||||
+ |
||||
+ /* right now this only handles tftp. */ |
||||
+ if (grub_strcmp("tftp", scheme)) |
||||
+ { |
||||
+ grub_free (scheme); |
||||
+ grub_free (userinfo); |
||||
+ grub_free (host); |
||||
+ grub_free (file); |
||||
+ continue; |
||||
+ } |
||||
+ grub_free (userinfo); |
||||
+ |
||||
+ hostlen = grub_strlen (host); |
||||
+ if (hostlen > 2 && host[0] == '[' && host[hostlen-1] == ']') |
||||
+ { |
||||
+ tmp = host+1; |
||||
+ host[hostlen-1] = '\0'; |
||||
+ } |
||||
+ else |
||||
+ tmp = host; |
||||
+ |
||||
+ *device = grub_xasprintf ("%s,%s", scheme, tmp); |
||||
+ grub_free (scheme); |
||||
+ grub_free (host); |
||||
+ |
||||
+ if (file && *file) |
||||
+ { |
||||
+ tmp = grub_strrchr (file, '/'); |
||||
+ if (tmp) |
||||
+ *(tmp+1) = '\0'; |
||||
+ else |
||||
+ file[0] = '\0'; |
||||
+ } |
||||
+ else if (!file) |
||||
+ file = grub_strdup (""); |
||||
+ |
||||
+ if (file[0] == '/') |
||||
+ { |
||||
+ *path = grub_strdup (file+1); |
||||
+ grub_free (file); |
||||
+ } |
||||
+ else |
||||
+ *path = file; |
||||
+ } |
||||
+ else if (num == GRUB_NET_DHCP6_IA_NA) |
||||
+ { |
||||
+ const grub_net_dhcpv6_option_t *ia_na_opt; |
||||
+ const grub_net_dhcpv6_opt_ia_na_t *ia_na = |
||||
+ (const grub_net_dhcpv6_opt_ia_na_t *)opt; |
||||
+ unsigned int left = len - OFFSET_OF (options, ia_na); |
||||
+ unsigned int j; |
||||
+ |
||||
+ if ((grub_uint8_t *)ia_na + left > |
||||
+ (grub_uint8_t *)options + option_max) |
||||
+ left -= ((grub_uint8_t *)ia_na + left) |
||||
+ - ((grub_uint8_t *)options + option_max); |
||||
+ |
||||
+ if (len < OFFSET_OF (option_data, opt) |
||||
+ + sizeof (grub_net_dhcpv6_option_t)) |
||||
+ { |
||||
+ grub_dprintf ("net", |
||||
+ "found dhcpv6 ia_na option with no address\n"); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ for (j = 0; left > sizeof (grub_net_dhcpv6_option_t); ) |
||||
+ { |
||||
+ ia_na_opt = (const grub_net_dhcpv6_option_t *) |
||||
+ (ia_na->options + j); |
||||
+ grub_uint16_t ia_na_opt_num, ia_na_opt_len; |
||||
+ |
||||
+ ia_na_opt_num = grub_be_to_cpu16 (ia_na_opt->option_num); |
||||
+ ia_na_opt_len = grub_be_to_cpu16 (ia_na_opt->option_len); |
||||
+ if (ia_na_opt_len == 0) |
||||
+ break; |
||||
+ if (j + ia_na_opt_len > left) |
||||
+ break; |
||||
+ if (ia_na_opt_num == GRUB_NET_DHCP6_IA_ADDRESS) |
||||
+ { |
||||
+ const grub_net_dhcpv6_opt_ia_address_t *ia_addr; |
||||
+ |
||||
+ ia_addr = (const grub_net_dhcpv6_opt_ia_address_t *) |
||||
+ ia_na_opt; |
||||
+ addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; |
||||
+ grub_memcpy(addr.ipv6, ia_addr->ipv6_address, |
||||
+ sizeof (ia_addr->ipv6_address)); |
||||
+ inter = grub_net_add_addr (name, card, &addr, hwaddr, 0); |
||||
+ } |
||||
+ |
||||
+ j += ia_na_opt_len; |
||||
+ left -= ia_na_opt_len; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ i += len + 4; |
||||
+ } |
||||
+ |
||||
+ grub_print_error (); |
||||
+ } |
||||
+ |
||||
+ if (is_def) |
||||
+ { |
||||
+ grub_env_set ("net_default_interface", name); |
||||
+ grub_env_export ("net_default_interface"); |
||||
+ } |
||||
+ |
||||
+ if (inter) |
||||
+ grub_net_add_ipv6_local (inter, mask); |
||||
+ return inter; |
||||
+} |
||||
+ |
||||
+ |
||||
void |
||||
grub_bootp_init (void) |
||||
{ |
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
||||
index 5388f952ba..173fb63153 100644 |
||||
--- a/grub-core/net/drivers/efi/efinet.c |
||||
+++ b/grub-core/net/drivers/efi/efinet.c |
||||
@@ -18,11 +18,14 @@ |
||||
|
||||
#include <grub/net/netbuff.h> |
||||
#include <grub/dl.h> |
||||
+#include <grub/env.h> |
||||
#include <grub/net.h> |
||||
#include <grub/time.h> |
||||
#include <grub/efi/api.h> |
||||
#include <grub/efi/efi.h> |
||||
#include <grub/i18n.h> |
||||
+#include <grub/lib/hexdump.h> |
||||
+#include <grub/types.h> |
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+"); |
||||
|
||||
@@ -329,7 +332,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
char **path) |
||||
{ |
||||
struct grub_net_card *card; |
||||
- grub_efi_device_path_t *dp; |
||||
+ grub_efi_device_path_t *dp, *ldp = NULL; |
||||
|
||||
dp = grub_efi_get_device_path (hnd); |
||||
if (! dp) |
||||
@@ -340,14 +343,19 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
grub_efi_device_path_t *cdp; |
||||
struct grub_efi_pxe *pxe; |
||||
struct grub_efi_pxe_mode *pxe_mode; |
||||
+ |
||||
if (card->driver != &efidriver) |
||||
continue; |
||||
+ |
||||
cdp = grub_efi_get_device_path (card->efi_handle); |
||||
if (! cdp) |
||||
continue; |
||||
+ |
||||
+ ldp = grub_efi_find_last_device_path (dp); |
||||
+ |
||||
if (grub_efi_compare_device_paths (dp, cdp) != 0) |
||||
{ |
||||
- grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp; |
||||
+ grub_efi_device_path_t *dup_dp, *dup_ldp; |
||||
int match; |
||||
|
||||
/* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6 |
||||
@@ -356,7 +364,6 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
devices. We skip them when enumerating cards, so here we need to |
||||
find matching MAC device. |
||||
*/ |
||||
- ldp = grub_efi_find_last_device_path (dp); |
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE |
||||
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE |
||||
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) |
||||
@@ -373,16 +380,46 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
if (!match) |
||||
continue; |
||||
} |
||||
+ |
||||
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, |
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
||||
if (! pxe) |
||||
continue; |
||||
+ |
||||
pxe_mode = pxe->mode; |
||||
- grub_net_configure_by_dhcp_ack (card->name, card, 0, |
||||
- (struct grub_net_bootp_packet *) |
||||
- &pxe_mode->dhcp_ack, |
||||
- sizeof (pxe_mode->dhcp_ack), |
||||
- 1, device, path); |
||||
+ if (pxe_mode->using_ipv6) |
||||
+ { |
||||
+ grub_net_link_level_address_t hwaddr; |
||||
+ struct grub_net_network_level_interface *intf; |
||||
+ |
||||
+ grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); |
||||
+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", |
||||
+ pxe_mode->dhcp_ack_received ? "yes" : "no", |
||||
+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); |
||||
+ if (!pxe_mode->dhcp_ack_received) |
||||
+ continue; |
||||
+ |
||||
+ hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
+ grub_memcpy (hwaddr.mac, |
||||
+ card->efi_net->mode->current_address, |
||||
+ sizeof (hwaddr.mac)); |
||||
+ |
||||
+ intf = grub_net_configure_by_dhcpv6_ack (card->name, card, 0, &hwaddr, |
||||
+ (const struct grub_net_dhcpv6_packet *)&pxe_mode->dhcp_ack.dhcpv6, |
||||
+ 1, device, path); |
||||
+ if (intf && device && path) |
||||
+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ grub_dprintf ("efinet", "using ipv4 and dhcp\n"); |
||||
+ grub_net_configure_by_dhcp_ack (card->name, card, 0, |
||||
+ (struct grub_net_bootp_packet *) |
||||
+ &pxe_mode->dhcp_ack, |
||||
+ sizeof (pxe_mode->dhcp_ack), |
||||
+ 1, device, path); |
||||
+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); |
||||
+ } |
||||
return; |
||||
} |
||||
} |
||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c |
||||
index 0ef148f4ad..22f2689aae 100644 |
||||
--- a/grub-core/net/net.c |
||||
+++ b/grub-core/net/net.c |
||||
@@ -960,6 +960,78 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa |
||||
grub_net_network_level_interfaces = inter; |
||||
} |
||||
|
||||
+int |
||||
+grub_ipv6_get_masksize (grub_uint16_t be_mask[8]) |
||||
+{ |
||||
+ grub_uint8_t *mask; |
||||
+ grub_uint16_t mask16[8]; |
||||
+ int x, y; |
||||
+ int ret = 128; |
||||
+ |
||||
+ grub_memcpy (mask16, be_mask, sizeof (mask16)); |
||||
+ for (x = 0; x < 8; x++) |
||||
+ mask16[x] = grub_be_to_cpu16 (mask16[x]); |
||||
+ |
||||
+ mask = (grub_uint8_t *)mask16; |
||||
+ |
||||
+ for (x = 15; x >= 0; x--) |
||||
+ { |
||||
+ grub_uint8_t octet = mask[x]; |
||||
+ if (!octet) |
||||
+ { |
||||
+ ret -= 8; |
||||
+ continue; |
||||
+ } |
||||
+ for (y = 0; y < 8; y++) |
||||
+ { |
||||
+ if (octet & (1 << y)) |
||||
+ break; |
||||
+ else |
||||
+ ret--; |
||||
+ } |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
+grub_err_t |
||||
+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inter, |
||||
+ int mask) |
||||
+{ |
||||
+ struct grub_net_route *route; |
||||
+ |
||||
+ if (inter->address.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6) |
||||
+ return 0; |
||||
+ |
||||
+ if (mask == -1) |
||||
+ mask = grub_ipv6_get_masksize ((grub_uint16_t *)inter->address.ipv6); |
||||
+ |
||||
+ if (mask == -1) |
||||
+ return 0; |
||||
+ |
||||
+ route = grub_zalloc (sizeof (*route)); |
||||
+ if (!route) |
||||
+ return grub_errno; |
||||
+ |
||||
+ route->name = grub_xasprintf ("%s:local", inter->name); |
||||
+ if (!route->name) |
||||
+ { |
||||
+ grub_free (route); |
||||
+ return grub_errno; |
||||
+ } |
||||
+ |
||||
+ route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; |
||||
+ grub_memcpy (route->target.ipv6.base, inter->address.ipv6, |
||||
+ sizeof (inter->address.ipv6)); |
||||
+ route->target.ipv6.masksize = mask; |
||||
+ route->is_gateway = 0; |
||||
+ route->interface = inter; |
||||
+ |
||||
+ grub_net_route_register (route); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
|
||||
grub_err_t |
||||
grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter, |
||||
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c |
||||
index 7f44b30f52..4ab2f5c735 100644 |
||||
--- a/grub-core/net/tftp.c |
||||
+++ b/grub-core/net/tftp.c |
||||
@@ -358,18 +358,22 @@ tftp_open (struct grub_file *file, const char *filename) |
||||
file->not_easily_seekable = 1; |
||||
file->data = data; |
||||
|
||||
+ grub_dprintf("tftp", "resolving address for %s\n", file->device->net->server); |
||||
err = grub_net_resolve_address (file->device->net->server, &addr); |
||||
if (err) |
||||
{ |
||||
+ grub_dprintf("tftp", "Address resolution failed: %d\n", err); |
||||
grub_free (data); |
||||
return err; |
||||
} |
||||
|
||||
+ grub_dprintf("tftp", "opening connection\n"); |
||||
data->sock = grub_net_udp_open (addr, |
||||
TFTP_SERVER_PORT, tftp_receive, |
||||
file); |
||||
if (!data->sock) |
||||
{ |
||||
+ grub_dprintf("tftp", "connection failed\n"); |
||||
grub_free (data); |
||||
return grub_errno; |
||||
} |
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h |
||||
index f1a52210c0..117469450d 100644 |
||||
--- a/include/grub/efi/api.h |
||||
+++ b/include/grub/efi/api.h |
||||
@@ -592,10 +592,16 @@ typedef void *grub_efi_handle_t; |
||||
typedef void *grub_efi_event_t; |
||||
typedef grub_efi_uint64_t grub_efi_lba_t; |
||||
typedef grub_efi_uintn_t grub_efi_tpl_t; |
||||
-typedef grub_uint8_t grub_efi_mac_address_t[32]; |
||||
-typedef grub_uint8_t grub_efi_ipv4_address_t[4]; |
||||
-typedef grub_uint16_t grub_efi_ipv6_address_t[8]; |
||||
-typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); |
||||
+typedef grub_efi_uint8_t grub_efi_mac_address_t[32]; |
||||
+typedef grub_efi_uint8_t grub_efi_ipv4_address_t[4]; |
||||
+typedef grub_efi_uint8_t grub_efi_ipv6_address_t[16]; |
||||
+typedef union |
||||
+{ |
||||
+ grub_efi_uint32_t addr[4]; |
||||
+ grub_efi_ipv4_address_t v4; |
||||
+ grub_efi_ipv6_address_t v6; |
||||
+} grub_efi_ip_address_t __attribute__ ((aligned(4))); |
||||
+ |
||||
typedef grub_efi_uint64_t grub_efi_physical_address_t; |
||||
typedef grub_efi_uint64_t grub_efi_virtual_address_t; |
||||
|
||||
@@ -1474,16 +1480,127 @@ struct grub_efi_simple_text_output_interface |
||||
}; |
||||
typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; |
||||
|
||||
-typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; |
||||
+typedef struct grub_efi_pxe_dhcpv4_packet |
||||
+{ |
||||
+ grub_efi_uint8_t bootp_opcode; |
||||
+ grub_efi_uint8_t bootp_hwtype; |
||||
+ grub_efi_uint8_t bootp_hwaddr_len; |
||||
+ grub_efi_uint8_t bootp_gate_hops; |
||||
+ grub_efi_uint32_t bootp_ident; |
||||
+ grub_efi_uint16_t bootp_seconds; |
||||
+ grub_efi_uint16_t bootp_flags; |
||||
+ grub_efi_uint8_t bootp_ci_addr[4]; |
||||
+ grub_efi_uint8_t bootp_yi_addr[4]; |
||||
+ grub_efi_uint8_t bootp_si_addr[4]; |
||||
+ grub_efi_uint8_t bootp_gi_addr[4]; |
||||
+ grub_efi_uint8_t bootp_hw_addr[16]; |
||||
+ grub_efi_uint8_t bootp_srv_name[64]; |
||||
+ grub_efi_uint8_t bootp_boot_file[128]; |
||||
+ grub_efi_uint32_t dhcp_magik; |
||||
+ grub_efi_uint8_t dhcp_options[56]; |
||||
+} grub_efi_pxe_dhcpv4_packet_t; |
||||
+ |
||||
+struct grub_efi_pxe_dhcpv6_packet |
||||
+{ |
||||
+ grub_efi_uint32_t message_type:8; |
||||
+ grub_efi_uint32_t transaction_id:24; |
||||
+ grub_efi_uint8_t dhcp_options[1024]; |
||||
+} GRUB_PACKED; |
||||
+typedef struct grub_efi_pxe_dhcpv6_packet grub_efi_pxe_dhcpv6_packet_t; |
||||
+ |
||||
+typedef union |
||||
+{ |
||||
+ grub_efi_uint8_t raw[1472]; |
||||
+ grub_efi_pxe_dhcpv4_packet_t dhcpv4; |
||||
+ grub_efi_pxe_dhcpv6_packet_t dhcpv6; |
||||
+} grub_efi_pxe_packet_t; |
||||
+ |
||||
+#define GRUB_EFI_PXE_MAX_IPCNT 8 |
||||
+#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 |
||||
+#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 |
||||
+ |
||||
+typedef struct grub_efi_pxe_ip_filter |
||||
+{ |
||||
+ grub_efi_uint8_t filters; |
||||
+ grub_efi_uint8_t ip_count; |
||||
+ grub_efi_uint8_t reserved; |
||||
+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; |
||||
+} grub_efi_pxe_ip_filter_t; |
||||
+ |
||||
+typedef struct grub_efi_pxe_arp_entry |
||||
+{ |
||||
+ grub_efi_ip_address_t ip_addr; |
||||
+ grub_efi_mac_address_t mac_addr; |
||||
+} grub_efi_pxe_arp_entry_t; |
||||
+ |
||||
+typedef struct grub_efi_pxe_route_entry |
||||
+{ |
||||
+ grub_efi_ip_address_t ip_addr; |
||||
+ grub_efi_ip_address_t subnet_mask; |
||||
+ grub_efi_ip_address_t gateway_addr; |
||||
+} grub_efi_pxe_route_entry_t; |
||||
+ |
||||
+typedef struct grub_efi_pxe_icmp_error |
||||
+{ |
||||
+ grub_efi_uint8_t type; |
||||
+ grub_efi_uint8_t code; |
||||
+ grub_efi_uint16_t checksum; |
||||
+ union |
||||
+ { |
||||
+ grub_efi_uint32_t reserved; |
||||
+ grub_efi_uint32_t mtu; |
||||
+ grub_efi_uint32_t pointer; |
||||
+ struct |
||||
+ { |
||||
+ grub_efi_uint16_t identifier; |
||||
+ grub_efi_uint16_t sequence; |
||||
+ } echo; |
||||
+ } u; |
||||
+ grub_efi_uint8_t data[494]; |
||||
+} grub_efi_pxe_icmp_error_t; |
||||
+ |
||||
+typedef struct grub_efi_pxe_tftp_error |
||||
+{ |
||||
+ grub_efi_uint8_t error_code; |
||||
+ grub_efi_char8_t error_string[127]; |
||||
+} grub_efi_pxe_tftp_error_t; |
||||
|
||||
typedef struct grub_efi_pxe_mode |
||||
{ |
||||
- grub_uint8_t unused[52]; |
||||
+ grub_efi_boolean_t started; |
||||
+ grub_efi_boolean_t ipv6_available; |
||||
+ grub_efi_boolean_t ipv6_supported; |
||||
+ grub_efi_boolean_t using_ipv6; |
||||
+ grub_efi_boolean_t bis_supported; |
||||
+ grub_efi_boolean_t bis_detected; |
||||
+ grub_efi_boolean_t auto_arp; |
||||
+ grub_efi_boolean_t send_guid; |
||||
+ grub_efi_boolean_t dhcp_discover_valid; |
||||
+ grub_efi_boolean_t dhcp_ack_received; |
||||
+ grub_efi_boolean_t proxy_offer_received; |
||||
+ grub_efi_boolean_t pxe_discover_valid; |
||||
+ grub_efi_boolean_t pxe_reply_received; |
||||
+ grub_efi_boolean_t pxe_bis_reply_received; |
||||
+ grub_efi_boolean_t icmp_error_received; |
||||
+ grub_efi_boolean_t tftp_error_received; |
||||
+ grub_efi_boolean_t make_callbacks; |
||||
+ grub_efi_uint8_t ttl; |
||||
+ grub_efi_uint8_t tos; |
||||
+ grub_efi_ip_address_t station_ip; |
||||
+ grub_efi_ip_address_t subnet_mask; |
||||
grub_efi_pxe_packet_t dhcp_discover; |
||||
grub_efi_pxe_packet_t dhcp_ack; |
||||
grub_efi_pxe_packet_t proxy_offer; |
||||
grub_efi_pxe_packet_t pxe_discover; |
||||
grub_efi_pxe_packet_t pxe_reply; |
||||
+ grub_efi_pxe_packet_t pxe_bis_reply; |
||||
+ grub_efi_pxe_ip_filter_t ip_filter; |
||||
+ grub_efi_uint32_t arp_cache_entries; |
||||
+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; |
||||
+ grub_efi_uint32_t route_table_entries; |
||||
+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; |
||||
+ grub_efi_pxe_icmp_error_t icmp_error; |
||||
+ grub_efi_pxe_tftp_error_t tftp_error; |
||||
} grub_efi_pxe_mode_t; |
||||
|
||||
typedef struct grub_efi_pxe |
||||
diff --git a/include/grub/net.h b/include/grub/net.h |
||||
index 7ae4b6bd80..8a05ec4fe7 100644 |
||||
--- a/include/grub/net.h |
||||
+++ b/include/grub/net.h |
||||
@@ -447,6 +447,51 @@ struct grub_net_bootp_packet |
||||
grub_uint8_t vendor[0]; |
||||
} GRUB_PACKED; |
||||
|
||||
+enum |
||||
+ { |
||||
+ GRUB_NET_DHCP6_IA_NA = 3, |
||||
+ GRUB_NET_DHCP6_IA_ADDRESS = 5, |
||||
+ GRUB_NET_DHCP6_BOOTFILE_URL = 59, |
||||
+ }; |
||||
+ |
||||
+struct grub_net_dhcpv6_option |
||||
+{ |
||||
+ grub_uint16_t option_num; |
||||
+ grub_uint16_t option_len; |
||||
+ grub_uint8_t option_data[]; |
||||
+} GRUB_PACKED; |
||||
+typedef struct grub_net_dhcpv6_option grub_net_dhcpv6_option_t; |
||||
+ |
||||
+struct grub_net_dhcpv6_opt_ia_na |
||||
+{ |
||||
+ grub_uint16_t option_num; |
||||
+ grub_uint16_t option_len; |
||||
+ grub_uint32_t iaid; |
||||
+ grub_uint32_t t1; |
||||
+ grub_uint32_t t2; |
||||
+ grub_uint8_t options[]; |
||||
+} GRUB_PACKED; |
||||
+typedef struct grub_net_dhcpv6_opt_ia_na grub_net_dhcpv6_opt_ia_na_t; |
||||
+ |
||||
+struct grub_net_dhcpv6_opt_ia_address |
||||
+{ |
||||
+ grub_uint16_t option_num; |
||||
+ grub_uint16_t option_len; |
||||
+ grub_uint64_t ipv6_address[2]; |
||||
+ grub_uint32_t preferred_lifetime; |
||||
+ grub_uint32_t valid_lifetime; |
||||
+ grub_uint8_t options[]; |
||||
+} GRUB_PACKED; |
||||
+typedef struct grub_net_dhcpv6_opt_ia_address grub_net_dhcpv6_opt_ia_address_t; |
||||
+ |
||||
+struct grub_net_dhcpv6_packet |
||||
+{ |
||||
+ grub_uint32_t message_type:8; |
||||
+ grub_uint32_t transaction_id:24; |
||||
+ grub_uint8_t dhcp_options[1024]; |
||||
+} GRUB_PACKED; |
||||
+typedef struct grub_net_dhcpv6_packet grub_net_dhcpv6_packet_t; |
||||
+ |
||||
#define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 |
||||
#define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 |
||||
#define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 |
||||
@@ -482,6 +527,21 @@ grub_net_configure_by_dhcp_ack (const char *name, |
||||
grub_size_t size, |
||||
int is_def, char **device, char **path); |
||||
|
||||
+struct grub_net_network_level_interface * |
||||
+grub_net_configure_by_dhcpv6_ack (const char *name, |
||||
+ struct grub_net_card *card, |
||||
+ grub_net_interface_flags_t flags, |
||||
+ const grub_net_link_level_address_t *hwaddr, |
||||
+ const struct grub_net_dhcpv6_packet *packet, |
||||
+ int is_def, char **device, char **path); |
||||
+ |
||||
+int |
||||
+grub_ipv6_get_masksize(grub_uint16_t *mask); |
||||
+ |
||||
+grub_err_t |
||||
+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inf, |
||||
+ int mask); |
||||
+ |
||||
grub_err_t |
||||
grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, |
||||
int mask); |
@ -0,0 +1,271 @@
@@ -0,0 +1,271 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 23 Jun 2016 11:01:39 -0400 |
||||
Subject: [PATCH] Add grub-get-kernel-settings and use it in 10_linux |
||||
|
||||
This patch adds grub-get-kernel-settings, which reads the system kernel |
||||
installation configuration from /etc/sysconfig/kernel, and outputs |
||||
${GRUB_...} variables suitable for evaluation by grub-mkconfig. Those |
||||
variables are then used by 10_linux to choose whether or not to create |
||||
debug stanzas. |
||||
|
||||
Resolves: rhbz#1226325 |
||||
[rharwood: migrate man page to h2m] |
||||
--- |
||||
configure.ac | 1 + |
||||
Makefile.util.def | 7 ++ |
||||
docs/man/grub-get-kernel-settings.h2m | 2 + |
||||
util/bash-completion.d/grub-completion.bash.in | 22 +++++++ |
||||
util/grub-get-kernel-settings.in | 88 ++++++++++++++++++++++++++ |
||||
util/grub-mkconfig.in | 3 + |
||||
util/grub.d/10_linux.in | 23 +++++-- |
||||
7 files changed, 141 insertions(+), 5 deletions(-) |
||||
create mode 100644 docs/man/grub-get-kernel-settings.h2m |
||||
create mode 100644 util/grub-get-kernel-settings.in |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 7f59ad788f..0d0e6782a1 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-install]) |
||||
grub_TRANSFORM([grub-mkconfig]) |
||||
grub_TRANSFORM([grub-mkfont]) |
||||
grub_TRANSFORM([grub-mkimage]) |
||||
+grub_TRANSFORM([grub-get-kernel-settings]) |
||||
grub_TRANSFORM([grub-glue-efi]) |
||||
grub_TRANSFORM([grub-mklayout]) |
||||
grub_TRANSFORM([grub-mkpasswd-pbkdf2]) |
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index 4ee22c5daa..18a9242776 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -716,6 +716,13 @@ script = { |
||||
installdir = sbin; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = grub-get-kernel-settings; |
||||
+ common = util/grub-get-kernel-settings.in; |
||||
+ mansection = 3; |
||||
+ installdir = sbin; |
||||
+}; |
||||
+ |
||||
script = { |
||||
name = grub-set-default; |
||||
common = util/grub-set-default.in; |
||||
diff --git a/docs/man/grub-get-kernel-settings.h2m b/docs/man/grub-get-kernel-settings.h2m |
||||
new file mode 100644 |
||||
index 0000000000..b8051f01f3 |
||||
--- /dev/null |
||||
+++ b/docs/man/grub-get-kernel-settings.h2m |
||||
@@ -0,0 +1,2 @@ |
||||
+[NAME] |
||||
+grub-get-kernel-settings \- Evaluate the system's kernel installation settings for use while making a grub configuration file |
||||
diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in |
||||
index 44bf135b9f..5c4acd496d 100644 |
||||
--- a/util/bash-completion.d/grub-completion.bash.in |
||||
+++ b/util/bash-completion.d/grub-completion.bash.in |
||||
@@ -264,6 +264,28 @@ have ${__grub_sparc64_setup_program} && \ |
||||
unset __grub_sparc64_setup_program |
||||
|
||||
|
||||
+# |
||||
+# grub-get-kernel-settings |
||||
+# |
||||
+_grub_get_kernel_settings () { |
||||
+ local cur |
||||
+ |
||||
+ COMPREPLY=() |
||||
+ cur=`_get_cword` |
||||
+ |
||||
+ if [[ "$cur" == -* ]]; then |
||||
+ __grubcomp "$(__grub_get_options_from_help)" |
||||
+ else |
||||
+ # Default complete with a filename |
||||
+ _filedir |
||||
+ fi |
||||
+} |
||||
+__grub_get_kernel_settings_program="@grub_get_kernel_settings@" |
||||
+have ${__grub_get_kernel_settings_program} && \ |
||||
+ complete -F _grub_get_kernel_settings -o filenames ${__grub_get_kernel_settings_program} |
||||
+unset __grub_get_kernel_settings_program |
||||
+ |
||||
+ |
||||
# |
||||
# grub-install |
||||
# |
||||
diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in |
||||
new file mode 100644 |
||||
index 0000000000..7e87dfccc0 |
||||
--- /dev/null |
||||
+++ b/util/grub-get-kernel-settings.in |
||||
@@ -0,0 +1,88 @@ |
||||
+#!/bin/sh |
||||
+set -e |
||||
+ |
||||
+# Evaluate new-kernel-pkg's configuration file. |
||||
+# Copyright (C) 2016 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/>. |
||||
+ |
||||
+PACKAGE_NAME=@PACKAGE_NAME@ |
||||
+PACKAGE_VERSION=@PACKAGE_VERSION@ |
||||
+datadir="@datadir@" |
||||
+if [ "x$pkgdatadir" = x ]; then |
||||
+ pkgdatadir="${datadir}/@PACKAGE@" |
||||
+fi |
||||
+ |
||||
+self=`basename $0` |
||||
+ |
||||
+export TEXTDOMAIN=@PACKAGE@ |
||||
+export TEXTDOMAINDIR="@localedir@" |
||||
+ |
||||
+. "${pkgdatadir}/grub-mkconfig_lib" |
||||
+ |
||||
+# Usage: usage |
||||
+# Print the usage. |
||||
+usage () { |
||||
+ gettext_printf "Usage: %s [OPTION]\n" "$self" |
||||
+ gettext "Evaluate new-kernel-pkg configuration"; echo |
||||
+ echo |
||||
+ print_option_help "-h, --help" "$(gettext "print this message and exit")" |
||||
+ print_option_help "-v, --version" "$(gettext "print the version information and exit")" |
||||
+ echo |
||||
+} |
||||
+ |
||||
+# Check the arguments. |
||||
+while test $# -gt 0 |
||||
+do |
||||
+ option=$1 |
||||
+ shift |
||||
+ |
||||
+ case "$option" in |
||||
+ -h | --help) |
||||
+ usage |
||||
+ exit 0 ;; |
||||
+ -v | --version) |
||||
+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" |
||||
+ exit 0 ;; |
||||
+ -*) |
||||
+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 |
||||
+ usage |
||||
+ exit 1 |
||||
+ ;; |
||||
+ # Explicitly ignore non-option arguments, for compatibility. |
||||
+ esac |
||||
+done |
||||
+ |
||||
+if test -f /etc/sysconfig/kernel ; then |
||||
+ . /etc/sysconfig/kernel |
||||
+fi |
||||
+ |
||||
+if [ "$MAKEDEBUG" = "yes" ]; then |
||||
+ echo GRUB_LINUX_MAKE_DEBUG=true |
||||
+ echo export GRUB_LINUX_MAKE_DEBUG |
||||
+ echo GRUB_CMDLINE_LINUX_DEBUG=\"systemd.log_level=debug systemd.log_target=kmsg\" |
||||
+ echo export GRUB_CMDLINE_LINUX_DEBUG |
||||
+ echo GRUB_LINUX_DEBUG_TITLE_POSTFIX=\" with debugging\" |
||||
+ echo export GRUB_LINUX_DEBUG_TITLE_POSTFIX |
||||
+fi |
||||
+if [ "$DEFAULTDEBUG" = "yes" ]; then |
||||
+ echo GRUB_DEFAULT_TO_DEBUG=true |
||||
+else |
||||
+ echo GRUB_DEFAULT_TO_DEBUG=false |
||||
+fi |
||||
+echo export GRUB_DEFAULT_TO_DEBUG |
||||
+if [ "$UPDATEDEFAULT" = "yes" ]; then |
||||
+ echo GRUB_UPDATE_DEFAULT_KERNEL=true |
||||
+ echo export GRUB_UPDATE_DEFAULT_KERNEL |
||||
+fi |
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in |
||||
index ba14cf6261..005f093809 100644 |
||||
--- a/util/grub-mkconfig.in |
||||
+++ b/util/grub-mkconfig.in |
||||
@@ -45,6 +45,7 @@ grub_probe="${sbindir}/@grub_probe@" |
||||
grub_file="${bindir}/@grub_file@" |
||||
grub_editenv="${bindir}/@grub_editenv@" |
||||
grub_script_check="${bindir}/@grub_script_check@" |
||||
+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" |
||||
|
||||
export TEXTDOMAIN=@PACKAGE@ |
||||
export TEXTDOMAINDIR="@localedir@" |
||||
@@ -158,6 +159,8 @@ if test -f ${sysconfdir}/default/grub ; then |
||||
. ${sysconfdir}/default/grub |
||||
fi |
||||
|
||||
+eval "$("${grub_get_kernel_settings}")" || true |
||||
+ |
||||
if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then |
||||
if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then |
||||
GRUB_DISABLE_LINUX_UUID="true" |
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index 786dbabb4a..292e333324 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -111,7 +111,8 @@ linux_entry () |
||||
os="$1" |
||||
version="$2" |
||||
type="$3" |
||||
- args="$4" |
||||
+ isdebug="$4" |
||||
+ args="$5" |
||||
|
||||
if [ -z "$boot_device_id" ]; then |
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" |
||||
@@ -123,6 +124,9 @@ linux_entry () |
||||
quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" |
||||
title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" |
||||
fi |
||||
+ if [ x$isdebug = xdebug ]; then |
||||
+ title="$title${GRUB_LINUX_DEBUG_TITLE_POSTFIX}" |
||||
+ fi |
||||
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" |
||||
else |
||||
echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" |
||||
@@ -306,11 +310,15 @@ while [ "x$list" != "x" ] ; do |
||||
fi |
||||
|
||||
if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then |
||||
- linux_entry "${OS}" "${version}" simple \ |
||||
+ linux_entry "${OS}" "${version}" simple standard \ |
||||
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" |
||||
+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then |
||||
+ linux_entry "${OS}" "${version}" simple debug \ |
||||
+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" |
||||
+ fi |
||||
|
||||
submenu_indentation="$grub_tab" |
||||
- |
||||
+ |
||||
if [ -z "$boot_device_id" ]; then |
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" |
||||
fi |
||||
@@ -319,10 +327,15 @@ while [ "x$list" != "x" ] ; do |
||||
is_top_level=false |
||||
fi |
||||
|
||||
- linux_entry "${OS}" "${version}" advanced \ |
||||
+ linux_entry "${OS}" "${version}" advanced standard \ |
||||
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" |
||||
+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then |
||||
+ linux_entry "${OS}" "${version}" advanced debug \ |
||||
+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" |
||||
+ fi |
||||
+ |
||||
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then |
||||
- linux_entry "${OS}" "${version}" recovery \ |
||||
+ linux_entry "${OS}" "${version}" recovery standard \ |
||||
"single ${GRUB_CMDLINE_LINUX}" |
||||
fi |
||||
|
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Masahiro Matsuya <mmatsuya@redhat.com> |
||||
Date: Sat, 29 Oct 2016 08:35:26 +0900 |
||||
Subject: [PATCH] bz1374141 fix incorrect mask for ppc64 |
||||
|
||||
The netmask configured in firmware is not respected on ppc64 (big endian). |
||||
When 255.255.252.0 is set as netmask in firmware, the following is the value of bootpath string in grub_ieee1275_parse_bootpath(). |
||||
|
||||
/vdevice/l-lan@30000002:speed=auto,duplex=auto,192.168.88.10,,192.168.89.113,192.168.88.1,5,5,255.255.252.0,512 |
||||
|
||||
The netmask in this bootpath is no problem, since it's a value specified in firmware. But, |
||||
The value of 'subnet_mask.ipv4' was set with 0xfffffc00, and __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4)) returned 16 (not 22). |
||||
As a result, 16 was used for netmask wrongly. |
||||
|
||||
1111 1111 1111 1111 1111 1100 0000 0000 # subnet_mask.ipv4 (=0xfffffc00) |
||||
0000 0000 1111 1100 1111 1111 1111 1111 # grub_le_to_cpu32 (subnet_mask.ipv4) |
||||
1111 1111 0000 0011 0000 0000 0000 0000 # ~grub_le_to_cpu32 (subnet_mask.ipv4) |
||||
|
||||
And, the count of zero with __builtin_ctz can be 16. |
||||
This patch changes it as below. |
||||
|
||||
1111 1111 1111 1111 1111 1100 0000 0000 # subnet_mask.ipv4 (=0xfffffc00) |
||||
0000 0000 1111 1100 1111 1111 1111 1111 # grub_le_to_cpu32 (subnet_mask.ipv4) |
||||
1111 1111 1111 1111 1111 1100 0000 0000 # grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)) |
||||
0000 0000 0000 0000 0000 0011 1111 1111 # ~grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)) |
||||
|
||||
The count of zero with __builtin_clz can be 22. (clz counts the number of one bits preceding the most significant zero bit) |
||||
|
||||
Signed-off-by: Masahiro Matsuya <mmatsuya@redhat.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/net/drivers/ieee1275/ofnet.c | 3 +-- |
||||
1 file changed, 1 insertion(+), 2 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c |
||||
index ac4e62a95c..3860b6f78d 100644 |
||||
--- a/grub-core/net/drivers/ieee1275/ofnet.c |
||||
+++ b/grub-core/net/drivers/ieee1275/ofnet.c |
||||
@@ -220,8 +220,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, |
||||
flags); |
||||
inter->vlantag = vlantag; |
||||
grub_net_add_ipv4_local (inter, |
||||
- __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4))); |
||||
- |
||||
+ __builtin_clz (~grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)))); |
||||
} |
||||
|
||||
if (gateway_addr.ipv4 != 0) |
@ -0,0 +1,172 @@
@@ -0,0 +1,172 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Wed, 27 Jan 2016 09:22:42 -0500 |
||||
Subject: [PATCH] Make grub_fatal() also backtrace. |
||||
|
||||
--- |
||||
grub-core/Makefile.core.def | 3 ++ |
||||
grub-core/kern/misc.c | 8 +++++- |
||||
grub-core/lib/arm64/backtrace.c | 62 +++++++++++++++++++++++++++++++++++++++++ |
||||
grub-core/lib/backtrace.c | 2 ++ |
||||
grub-core/lib/i386/backtrace.c | 14 +++++++++- |
||||
5 files changed, 87 insertions(+), 2 deletions(-) |
||||
create mode 100644 grub-core/lib/arm64/backtrace.c |
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
||||
index c15e91943b..058c88ac3a 100644 |
||||
--- a/grub-core/Makefile.core.def |
||||
+++ b/grub-core/Makefile.core.def |
||||
@@ -188,6 +188,9 @@ kernel = { |
||||
|
||||
softdiv = lib/division.c; |
||||
|
||||
+ x86 = lib/i386/backtrace.c; |
||||
+ x86 = lib/backtrace.c; |
||||
+ |
||||
i386 = kern/i386/dl.c; |
||||
i386_xen = kern/i386/dl.c; |
||||
i386_xen_pvh = kern/i386/dl.c; |
||||
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c |
||||
index 63b586d09c..a3e215155b 100644 |
||||
--- a/grub-core/kern/misc.c |
||||
+++ b/grub-core/kern/misc.c |
||||
@@ -24,6 +24,7 @@ |
||||
#include <grub/term.h> |
||||
#include <grub/env.h> |
||||
#include <grub/i18n.h> |
||||
+#include <grub/backtrace.h> |
||||
|
||||
union printf_arg |
||||
{ |
||||
@@ -1199,8 +1200,13 @@ grub_printf_fmt_check (const char *fmt, const char *fmt_expected) |
||||
static void __attribute__ ((noreturn)) |
||||
grub_abort (void) |
||||
{ |
||||
+#ifndef GRUB_UTIL |
||||
+#if defined(__i386__) || defined(__x86_64__) |
||||
+ grub_backtrace(); |
||||
+#endif |
||||
+#endif |
||||
grub_printf ("\nAborted."); |
||||
- |
||||
+ |
||||
#ifndef GRUB_UTIL |
||||
if (grub_term_inputs) |
||||
#endif |
||||
diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c |
||||
new file mode 100644 |
||||
index 0000000000..1079b5380e |
||||
--- /dev/null |
||||
+++ b/grub-core/lib/arm64/backtrace.c |
||||
@@ -0,0 +1,62 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2009 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/misc.h> |
||||
+#include <grub/command.h> |
||||
+#include <grub/err.h> |
||||
+#include <grub/dl.h> |
||||
+#include <grub/mm.h> |
||||
+#include <grub/term.h> |
||||
+#include <grub/backtrace.h> |
||||
+ |
||||
+#define MAX_STACK_FRAME 102400 |
||||
+ |
||||
+void |
||||
+grub_backtrace_pointer (int frame) |
||||
+{ |
||||
+ while (1) |
||||
+ { |
||||
+ void *lp = __builtin_return_address (frame); |
||||
+ if (!lp) |
||||
+ break; |
||||
+ |
||||
+ lp = __builtin_extract_return_addr (lp); |
||||
+ |
||||
+ grub_printf ("%p: ", lp); |
||||
+ grub_backtrace_print_address (lp); |
||||
+ grub_printf (" ("); |
||||
+ for (i = 0; i < 2; i++) |
||||
+ grub_printf ("%p,", ((void **)ptr) [i + 2]); |
||||
+ grub_printf ("%p)\n", ((void **)ptr) [i + 2]); |
||||
+ nptr = *(void **)ptr; |
||||
+ if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME |
||||
+ || nptr == ptr) |
||||
+ { |
||||
+ grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); |
||||
+ break; |
||||
+ } |
||||
+ ptr = nptr; |
||||
+ } |
||||
+} |
||||
+ |
||||
+void |
||||
+grub_backtrace (void) |
||||
+{ |
||||
+ grub_backtrace_pointer (1); |
||||
+} |
||||
+ |
||||
diff --git a/grub-core/lib/backtrace.c b/grub-core/lib/backtrace.c |
||||
index 825a8800e2..c0ad6ab8be 100644 |
||||
--- a/grub-core/lib/backtrace.c |
||||
+++ b/grub-core/lib/backtrace.c |
||||
@@ -29,6 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); |
||||
void |
||||
grub_backtrace_print_address (void *addr) |
||||
{ |
||||
+#ifndef GRUB_UTIL |
||||
grub_dl_t mod; |
||||
|
||||
FOR_DL_MODULES (mod) |
||||
@@ -44,6 +45,7 @@ grub_backtrace_print_address (void *addr) |
||||
} |
||||
} |
||||
|
||||
+#endif |
||||
grub_printf ("%p", addr); |
||||
} |
||||
|
||||
diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c |
||||
index c3e03c7275..c67273db3a 100644 |
||||
--- a/grub-core/lib/i386/backtrace.c |
||||
+++ b/grub-core/lib/i386/backtrace.c |
||||
@@ -15,11 +15,23 @@ |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>. |
||||
*/ |
||||
+#include <config.h> |
||||
+#ifdef GRUB_UTIL |
||||
+#define REALLY_GRUB_UTIL GRUB_UTIL |
||||
+#undef GRUB_UTIL |
||||
+#endif |
||||
+ |
||||
+#include <grub/symbol.h> |
||||
+#include <grub/dl.h> |
||||
+ |
||||
+#ifdef REALLY_GRUB_UTIL |
||||
+#define GRUB_UTIL REALLY_GRUB_UTIL |
||||
+#undef REALLY_GRUB_UTIL |
||||
+#endif |
||||
|
||||
#include <grub/misc.h> |
||||
#include <grub/command.h> |
||||
#include <grub/err.h> |
||||
-#include <grub/dl.h> |
||||
#include <grub/mm.h> |
||||
#include <grub/term.h> |
||||
#include <grub/backtrace.h> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Wed, 24 May 2017 12:42:32 -0400 |
||||
Subject: [PATCH] macos: just build chainloader entries, don't try any xnu xnu. |
||||
|
||||
Since our bugs tell us that the xnu boot entries really just don't work |
||||
most of the time, and they create piles of extra boot entries, because |
||||
they can't quite figure out 32-vs-64 and other stuff like that. |
||||
|
||||
It's rediculous, and we should just boot their bootloader through the |
||||
chainloader instead. |
||||
|
||||
So this patch does that. |
||||
|
||||
Resolves: rhbz#893179 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub.d/30_os-prober.in | 78 +++++++++++---------------------------------- |
||||
1 file changed, 18 insertions(+), 60 deletions(-) |
||||
|
||||
diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in |
||||
index 1b91c102f3..4b27bd2015 100644 |
||||
--- a/util/grub.d/30_os-prober.in |
||||
+++ b/util/grub.d/30_os-prober.in |
||||
@@ -42,68 +42,25 @@ if [ -z "${OSPROBED}" ] ; then |
||||
fi |
||||
|
||||
osx_entry() { |
||||
- if [ x$2 = x32 ]; then |
||||
- # TRANSLATORS: it refers to kernel architecture (32-bit) |
||||
- bitstr="$(gettext "(32-bit)")" |
||||
- else |
||||
- # TRANSLATORS: it refers to kernel architecture (64-bit) |
||||
- bitstr="$(gettext "(64-bit)")" |
||||
- fi |
||||
# TRANSLATORS: it refers on the OS residing on device %s |
||||
onstr="$(gettext_printf "(on %s)" "${DEVICE}")" |
||||
- cat << EOF |
||||
-menuentry '$(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' { |
||||
+ hints="" |
||||
+ for hint in `"${grub_probe}" --device ${device} --target=efi_hints 2> /dev/null` ; do |
||||
+ hints="${hints} --hint=${hint}" |
||||
+ done |
||||
+ cat << EOF |
||||
+menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' { |
||||
EOF |
||||
save_default_entry | grub_add_tab |
||||
prepare_grub_to_access_device ${DEVICE} | grub_add_tab |
||||
cat << EOF |
||||
+ set gfxpayload=keep |
||||
load_video |
||||
- set do_resume=0 |
||||
- if [ /var/vm/sleepimage -nt10 / ]; then |
||||
- if xnu_resume /var/vm/sleepimage; then |
||||
- set do_resume=1 |
||||
- fi |
||||
- fi |
||||
- if [ \$do_resume = 0 ]; then |
||||
- xnu_uuid ${OSXUUID} uuid |
||||
- if [ -f /Extra/DSDT.aml ]; then |
||||
- acpi -e /Extra/DSDT.aml |
||||
- fi |
||||
- if [ /kernelcache -nt /System/Library/Extensions ]; then |
||||
- $1 /kernelcache boot-uuid=\${uuid} rd=*uuid |
||||
- elif [ -f /System/Library/Kernels/kernel ]; then |
||||
- $1 /System/Library/Kernels/kernel boot-uuid=\${uuid} rd=*uuid |
||||
- xnu_kextdir /System/Library/Extensions |
||||
- else |
||||
- $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid |
||||
- if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then |
||||
- xnu_mkext /System/Library/Extensions.mkext |
||||
- else |
||||
- xnu_kextdir /System/Library/Extensions |
||||
- fi |
||||
- fi |
||||
- if [ -f /Extra/Extensions.mkext ]; then |
||||
- xnu_mkext /Extra/Extensions.mkext |
||||
- fi |
||||
- if [ -d /Extra/Extensions ]; then |
||||
- xnu_kextdir /Extra/Extensions |
||||
- fi |
||||
- if [ -f /Extra/devprop.bin ]; then |
||||
- xnu_devprop_load /Extra/devprop.bin |
||||
- fi |
||||
- if [ -f /Extra/splash.jpg ]; then |
||||
- insmod jpeg |
||||
- xnu_splash /Extra/splash.jpg |
||||
- fi |
||||
- if [ -f /Extra/splash.png ]; then |
||||
- insmod png |
||||
- xnu_splash /Extra/splash.png |
||||
- fi |
||||
- if [ -f /Extra/splash.tga ]; then |
||||
- insmod tga |
||||
- xnu_splash /Extra/splash.tga |
||||
- fi |
||||
- fi |
||||
+ insmod part_gpt |
||||
+ insmod hfsplus |
||||
+ search --no-floppy --fs-uuid --set=root ${hints} $(grub_get_device_id "${DEVICE}") |
||||
+ chainloader (\$root)/System/Library/CoreServices/boot.efi |
||||
+ boot |
||||
} |
||||
EOF |
||||
} |
||||
@@ -292,11 +249,12 @@ EOF |
||||
echo "$title_correction_code" |
||||
;; |
||||
macosx) |
||||
- if [ "${UUID}" ]; then |
||||
- OSXUUID="${UUID}" |
||||
- osx_entry xnu_kernel 32 |
||||
- osx_entry xnu_kernel64 64 |
||||
- fi |
||||
+ for subdevice in ${DEVICE%[[:digit:]]*}* ; do |
||||
+ parttype="`"${grub_probe}" --device ${device} --target=gpt_parttype "${subdevice}" 2> /dev/null`" |
||||
+ if [[ "$parttype" = "426f6f74-0000-11aa-aa11-00306543ecac" ]]; then |
||||
+ DEVICE="${subdevice}" osx_entry |
||||
+ fi |
||||
+ done |
||||
;; |
||||
hurd) |
||||
onstr="$(gettext_printf "(on %s)" "${DEVICE}")" |
@ -0,0 +1,703 @@
@@ -0,0 +1,703 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Jeff Mahoney <jeffm@suse.com> |
||||
Date: Tue, 9 Jul 2019 13:39:45 +0200 |
||||
Subject: [PATCH] grub2/btrfs: Add ability to boot from subvolumes |
||||
|
||||
This patch adds the ability to specify a different root on a btrfs |
||||
filesystem too boot from other than the default one. |
||||
|
||||
btrfs-list-snapshots <dev> will list the subvolumes available on the |
||||
filesystem. |
||||
|
||||
set btrfs_subvol=<path> and set btrfs_subvolid=<subvolid> will specify |
||||
which subvolume to use and any pathnames provided with either of those |
||||
variables set will start using that root. If the subvolume or subvolume id |
||||
doesn't exist, then an error case will result. |
||||
|
||||
It is possible to boot into a separate GRUB instance by exporting the |
||||
variable and loading the config file from the subvolume. |
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com> |
||||
--- |
||||
grub-core/fs/btrfs.c | 552 +++++++++++++++++++++++++++++++++++++++++++++++++-- |
||||
include/grub/btrfs.h | 1 + |
||||
2 files changed, 533 insertions(+), 20 deletions(-) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index 63203034df..f1fff7385b 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -38,6 +38,9 @@ |
||||
#include <zstd.h> |
||||
#include <grub/i18n.h> |
||||
#include <grub/btrfs.h> |
||||
+#include <grub/command.h> |
||||
+#include <grub/env.h> |
||||
+#include <grub/extcmd.h> |
||||
#include <grub/crypto.h> |
||||
#include <grub/diskfilter.h> |
||||
#include <grub/safemath.h> |
||||
@@ -79,9 +82,11 @@ struct grub_btrfs_superblock |
||||
grub_uint64_t generation; |
||||
grub_uint64_t root_tree; |
||||
grub_uint64_t chunk_tree; |
||||
- grub_uint8_t dummy2[0x20]; |
||||
+ grub_uint8_t dummy2[0x18]; |
||||
+ grub_uint64_t bytes_used; |
||||
grub_uint64_t root_dir_objectid; |
||||
- grub_uint8_t dummy3[0x41]; |
||||
+ grub_uint64_t num_devices; |
||||
+ grub_uint8_t dummy3[0x39]; |
||||
struct grub_btrfs_device this_device; |
||||
char label[0x100]; |
||||
grub_uint8_t dummy4[0x100]; |
||||
@@ -121,6 +126,7 @@ struct grub_btrfs_data |
||||
grub_uint64_t exttree; |
||||
grub_size_t extsize; |
||||
struct grub_btrfs_extent_data *extent; |
||||
+ grub_uint64_t fs_tree; |
||||
}; |
||||
|
||||
struct grub_btrfs_chunk_item |
||||
@@ -191,6 +197,14 @@ struct grub_btrfs_leaf_descriptor |
||||
} *data; |
||||
}; |
||||
|
||||
+struct grub_btrfs_root_ref |
||||
+{ |
||||
+ grub_uint64_t dirid; |
||||
+ grub_uint64_t sequence; |
||||
+ grub_uint16_t name_len; |
||||
+ const char name[0]; |
||||
+} __attribute__ ((packed)); |
||||
+ |
||||
struct grub_btrfs_time |
||||
{ |
||||
grub_int64_t sec; |
||||
@@ -236,6 +250,14 @@ struct grub_btrfs_extent_data |
||||
|
||||
#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 |
||||
|
||||
+#define GRUB_BTRFS_ROOT_TREE_OBJECTID 1ULL |
||||
+#define GRUB_BTRFS_FS_TREE_OBJECTID 5ULL |
||||
+#define GRUB_BTRFS_ROOT_REF_KEY 156 |
||||
+#define GRUB_BTRFS_ROOT_ITEM_KEY 132 |
||||
+ |
||||
+static grub_uint64_t btrfs_default_subvolid = 0; |
||||
+static char *btrfs_default_subvol = NULL; |
||||
+ |
||||
static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, |
||||
256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 |
||||
}; |
||||
@@ -1173,6 +1195,62 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, |
||||
return GRUB_ERR_NONE; |
||||
} |
||||
|
||||
+static grub_err_t |
||||
+get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, |
||||
+ grub_uint64_t objectid, grub_uint64_t offset, |
||||
+ grub_uint64_t *fs_root); |
||||
+ |
||||
+static grub_err_t |
||||
+lookup_root_by_id(struct grub_btrfs_data *data, grub_uint64_t id) |
||||
+{ |
||||
+ grub_err_t err; |
||||
+ grub_uint64_t tree; |
||||
+ |
||||
+ err = get_fs_root(data, data->sblock.root_tree, id, -1, &tree); |
||||
+ if (!err) |
||||
+ data->fs_tree = tree; |
||||
+ return err; |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+find_path (struct grub_btrfs_data *data, |
||||
+ const char *path, struct grub_btrfs_key *key, |
||||
+ grub_uint64_t *tree, grub_uint8_t *type); |
||||
+ |
||||
+static grub_err_t |
||||
+lookup_root_by_name(struct grub_btrfs_data *data, const char *path) |
||||
+{ |
||||
+ grub_err_t err; |
||||
+ grub_uint64_t tree = 0; |
||||
+ grub_uint8_t type; |
||||
+ struct grub_btrfs_key key; |
||||
+ |
||||
+ err = find_path (data, path, &key, &tree, &type); |
||||
+ if (err) |
||||
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); |
||||
+ |
||||
+ if (key.object_id != grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK) || tree == 0) |
||||
+ return grub_error(GRUB_ERR_BAD_FILE_TYPE, "%s: not a subvolume\n", path); |
||||
+ |
||||
+ data->fs_tree = tree; |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+btrfs_handle_subvol(struct grub_btrfs_data *data __attribute__ ((unused))) |
||||
+{ |
||||
+ if (btrfs_default_subvol) |
||||
+ return lookup_root_by_name(data, btrfs_default_subvol); |
||||
+ |
||||
+ if (btrfs_default_subvolid) |
||||
+ return lookup_root_by_id(data, btrfs_default_subvolid); |
||||
+ |
||||
+ data->fs_tree = 0; |
||||
+ |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
+ |
||||
static struct grub_btrfs_data * |
||||
grub_btrfs_mount (grub_device_t dev) |
||||
{ |
||||
@@ -1208,6 +1286,13 @@ grub_btrfs_mount (grub_device_t dev) |
||||
data->devices_attached[0].dev = dev; |
||||
data->devices_attached[0].id = data->sblock.this_device.device_id; |
||||
|
||||
+ err = btrfs_handle_subvol (data); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (data); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
return data; |
||||
} |
||||
|
||||
@@ -1673,6 +1758,91 @@ get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, |
||||
return GRUB_ERR_NONE; |
||||
} |
||||
|
||||
+static grub_err_t |
||||
+find_pathname(struct grub_btrfs_data *data, grub_uint64_t objectid, |
||||
+ grub_uint64_t fs_root, const char *name, char **pathname) |
||||
+{ |
||||
+ grub_err_t err; |
||||
+ struct grub_btrfs_key key = { |
||||
+ .object_id = objectid, |
||||
+ .type = GRUB_BTRFS_ITEM_TYPE_INODE_REF, |
||||
+ .offset = 0, |
||||
+ }; |
||||
+ struct grub_btrfs_key key_out; |
||||
+ struct grub_btrfs_leaf_descriptor desc; |
||||
+ char *p = grub_strdup (name); |
||||
+ grub_disk_addr_t elemaddr; |
||||
+ grub_size_t elemsize; |
||||
+ grub_size_t alloc = grub_strlen(name) + 1; |
||||
+ |
||||
+ err = lower_bound(data, &key, &key_out, fs_root, |
||||
+ &elemaddr, &elemsize, &desc, 0); |
||||
+ if (err) |
||||
+ return grub_error(err, "lower_bound caught %d\n", err); |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF) |
||||
+ next(data, &desc, &elemaddr, &elemsize, &key_out); |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF) |
||||
+ { |
||||
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, |
||||
+ "Can't find inode ref for {%"PRIuGRUB_UINT64_T |
||||
+ ", %u, %"PRIuGRUB_UINT64_T"} %"PRIuGRUB_UINT64_T |
||||
+ "/%"PRIuGRUB_SIZE"\n", |
||||
+ key_out.object_id, key_out.type, |
||||
+ key_out.offset, elemaddr, elemsize); |
||||
+ } |
||||
+ |
||||
+ |
||||
+ while (key_out.type == GRUB_BTRFS_ITEM_TYPE_INODE_REF && |
||||
+ key_out.object_id != key_out.offset) { |
||||
+ struct grub_btrfs_inode_ref *inode_ref; |
||||
+ char *new; |
||||
+ |
||||
+ inode_ref = grub_malloc(elemsize + 1); |
||||
+ if (!inode_ref) |
||||
+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, |
||||
+ "couldn't allocate memory for inode_ref (%"PRIuGRUB_SIZE")\n", elemsize); |
||||
+ |
||||
+ err = grub_btrfs_read_logical(data, elemaddr, inode_ref, elemsize, 0); |
||||
+ if (err) |
||||
+ return grub_error(err, "read_logical caught %d\n", err); |
||||
+ |
||||
+ alloc += grub_le_to_cpu16 (inode_ref->n) + 2; |
||||
+ new = grub_malloc(alloc); |
||||
+ if (!new) |
||||
+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, |
||||
+ "couldn't allocate memory for name (%"PRIuGRUB_SIZE")\n", alloc); |
||||
+ |
||||
+ grub_memcpy(new, inode_ref->name, grub_le_to_cpu16 (inode_ref->n)); |
||||
+ if (p) |
||||
+ { |
||||
+ new[grub_le_to_cpu16 (inode_ref->n)] = '/'; |
||||
+ grub_strcpy (new + grub_le_to_cpu16 (inode_ref->n) + 1, p); |
||||
+ grub_free(p); |
||||
+ } |
||||
+ else |
||||
+ new[grub_le_to_cpu16 (inode_ref->n)] = 0; |
||||
+ grub_free(inode_ref); |
||||
+ |
||||
+ p = new; |
||||
+ |
||||
+ key.object_id = key_out.offset; |
||||
+ |
||||
+ err = lower_bound(data, &key, &key_out, fs_root, &elemaddr, |
||||
+ &elemsize, &desc, 0); |
||||
+ if (err) |
||||
+ return grub_error(err, "lower_bound caught %d\n", err); |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF) |
||||
+ next(data, &desc, &elemaddr, &elemsize, &key_out); |
||||
+ |
||||
+ } |
||||
+ |
||||
+ *pathname = p; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
static grub_err_t |
||||
find_path (struct grub_btrfs_data *data, |
||||
const char *path, struct grub_btrfs_key *key, |
||||
@@ -1691,14 +1861,26 @@ find_path (struct grub_btrfs_data *data, |
||||
char *origpath = NULL; |
||||
unsigned symlinks_max = 32; |
||||
|
||||
- err = get_root (data, key, tree, type); |
||||
- if (err) |
||||
- return err; |
||||
- |
||||
origpath = grub_strdup (path); |
||||
if (!origpath) |
||||
return grub_errno; |
||||
|
||||
+ if (data->fs_tree) |
||||
+ { |
||||
+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
+ *tree = data->fs_tree; |
||||
+ /* This is a tree root, so everything starts at objectid 256 */ |
||||
+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); |
||||
+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key->offset = 0; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ err = get_root (data, key, tree, type); |
||||
+ if (err) |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
while (1) |
||||
{ |
||||
while (path[0] == '/') |
||||
@@ -1871,9 +2053,21 @@ find_path (struct grub_btrfs_data *data, |
||||
path = path_alloc = tmp; |
||||
if (path[0] == '/') |
||||
{ |
||||
- err = get_root (data, key, tree, type); |
||||
- if (err) |
||||
- return err; |
||||
+ if (data->fs_tree) |
||||
+ { |
||||
+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
+ *tree = data->fs_tree; |
||||
+ /* This is a tree root, so everything starts at objectid 256 */ |
||||
+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); |
||||
+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key->offset = 0; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ err = get_root (data, key, tree, type); |
||||
+ if (err) |
||||
+ return err; |
||||
+ } |
||||
} |
||||
continue; |
||||
} |
||||
@@ -2114,18 +2308,10 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) |
||||
data->tree, file->offset, buf, len); |
||||
} |
||||
|
||||
-static grub_err_t |
||||
-grub_btrfs_uuid (grub_device_t device, char **uuid) |
||||
+static char * |
||||
+btrfs_unparse_uuid(struct grub_btrfs_data *data) |
||||
{ |
||||
- struct grub_btrfs_data *data; |
||||
- |
||||
- *uuid = NULL; |
||||
- |
||||
- data = grub_btrfs_mount (device); |
||||
- if (!data) |
||||
- return grub_errno; |
||||
- |
||||
- *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", |
||||
+ return grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", |
||||
grub_be_to_cpu16 (data->sblock.uuid[0]), |
||||
grub_be_to_cpu16 (data->sblock.uuid[1]), |
||||
grub_be_to_cpu16 (data->sblock.uuid[2]), |
||||
@@ -2134,6 +2320,20 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) |
||||
grub_be_to_cpu16 (data->sblock.uuid[5]), |
||||
grub_be_to_cpu16 (data->sblock.uuid[6]), |
||||
grub_be_to_cpu16 (data->sblock.uuid[7])); |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+grub_btrfs_uuid (grub_device_t device, char **uuid) |
||||
+{ |
||||
+ struct grub_btrfs_data *data; |
||||
+ |
||||
+ *uuid = NULL; |
||||
+ |
||||
+ data = grub_btrfs_mount (device); |
||||
+ if (!data) |
||||
+ return grub_errno; |
||||
+ |
||||
+ *uuid = btrfs_unparse_uuid(data); |
||||
|
||||
grub_btrfs_unmount (data); |
||||
|
||||
@@ -2190,6 +2390,242 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), |
||||
} |
||||
#endif |
||||
|
||||
+static grub_err_t |
||||
+grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc, |
||||
+ char **argv) |
||||
+{ |
||||
+ grub_device_t dev; |
||||
+ char *devname; |
||||
+ struct grub_btrfs_data *data; |
||||
+ char *uuid; |
||||
+ |
||||
+ if (argc < 1) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); |
||||
+ |
||||
+ devname = grub_file_get_device_name(argv[0]); |
||||
+ |
||||
+ if (!devname) |
||||
+ return grub_errno; |
||||
+ |
||||
+ dev = grub_device_open (devname); |
||||
+ grub_free (devname); |
||||
+ if (!dev) |
||||
+ return grub_errno; |
||||
+ |
||||
+ data = grub_btrfs_mount (dev); |
||||
+ if (!data) |
||||
+ { |
||||
+ grub_device_close(dev); |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to open fs"); |
||||
+ } |
||||
+ |
||||
+ if (data->sblock.label) |
||||
+ grub_printf("Label: '%s' ", data->sblock.label); |
||||
+ else |
||||
+ grub_printf("Label: none "); |
||||
+ |
||||
+ uuid = btrfs_unparse_uuid(data); |
||||
+ |
||||
+ grub_printf(" uuid: %s\n\tTotal devices %" PRIuGRUB_UINT64_T |
||||
+ " FS bytes used %" PRIuGRUB_UINT64_T "\n", |
||||
+ uuid, grub_cpu_to_le64(data->sblock.num_devices), |
||||
+ grub_cpu_to_le64(data->sblock.bytes_used)); |
||||
+ |
||||
+ grub_btrfs_unmount (data); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, |
||||
+ grub_uint64_t objectid, grub_uint64_t offset, |
||||
+ grub_uint64_t *fs_root) |
||||
+{ |
||||
+ grub_err_t err; |
||||
+ struct grub_btrfs_key key_in = { |
||||
+ .object_id = objectid, |
||||
+ .type = GRUB_BTRFS_ROOT_ITEM_KEY, |
||||
+ .offset = offset, |
||||
+ }, key_out; |
||||
+ struct grub_btrfs_leaf_descriptor desc; |
||||
+ grub_disk_addr_t elemaddr; |
||||
+ grub_size_t elemsize; |
||||
+ struct grub_btrfs_root_item ri; |
||||
+ |
||||
+ err = lower_bound(data, &key_in, &key_out, tree, |
||||
+ &elemaddr, &elemsize, &desc, 0); |
||||
+ |
||||
+ if (err) |
||||
+ return err; |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM || elemaddr == 0) |
||||
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, |
||||
+ N_("can't find fs root for subvol %"PRIuGRUB_UINT64_T"\n"), |
||||
+ key_in.object_id); |
||||
+ |
||||
+ err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri), 0); |
||||
+ if (err) |
||||
+ return err; |
||||
+ |
||||
+ *fs_root = ri.tree; |
||||
+ |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
+static const struct grub_arg_option options[] = { |
||||
+ {"output", 'o', 0, N_("Output to a variable instead of the console."), |
||||
+ N_("VARNAME"), ARG_TYPE_STRING}, |
||||
+ {"path-only", 'p', 0, N_("Show only the path of the subvolume."), 0, 0}, |
||||
+ {"id-only", 'i', 0, N_("Show only the id of the subvolume."), 0, 0}, |
||||
+ {0, 0, 0, 0, 0, 0} |
||||
+}; |
||||
+ |
||||
+static grub_err_t |
||||
+grub_cmd_btrfs_list_subvols (struct grub_extcmd_context *ctxt, |
||||
+ int argc, char **argv) |
||||
+{ |
||||
+ struct grub_btrfs_data *data; |
||||
+ grub_device_t dev; |
||||
+ char *devname; |
||||
+ grub_uint64_t tree; |
||||
+ struct grub_btrfs_key key_in = { |
||||
+ .object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_FS_TREE_OBJECTID), |
||||
+ .type = GRUB_BTRFS_ROOT_REF_KEY, |
||||
+ .offset = 0, |
||||
+ }, key_out; |
||||
+ struct grub_btrfs_leaf_descriptor desc; |
||||
+ grub_disk_addr_t elemaddr; |
||||
+ grub_uint64_t fs_root = 0; |
||||
+ grub_size_t elemsize; |
||||
+ grub_size_t allocated = 0; |
||||
+ int r = 0; |
||||
+ grub_err_t err; |
||||
+ char *buf = NULL; |
||||
+ int print = 1; |
||||
+ int path_only = ctxt->state[1].set; |
||||
+ int num_only = ctxt->state[2].set; |
||||
+ char *varname = NULL; |
||||
+ char *output = NULL; |
||||
+ |
||||
+ if (ctxt->state[0].set) { |
||||
+ varname = ctxt->state[0].arg; |
||||
+ print = 0; |
||||
+ } |
||||
+ |
||||
+ if (argc < 1) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); |
||||
+ |
||||
+ devname = grub_file_get_device_name(argv[0]); |
||||
+ if (!devname) |
||||
+ return grub_errno; |
||||
+ |
||||
+ dev = grub_device_open (devname); |
||||
+ grub_free (devname); |
||||
+ if (!dev) |
||||
+ return grub_errno; |
||||
+ |
||||
+ data = grub_btrfs_mount(dev); |
||||
+ if (!data) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "could not open device"); |
||||
+ |
||||
+ tree = data->sblock.root_tree; |
||||
+ err = get_fs_root(data, tree, grub_cpu_to_le64_compile_time (GRUB_BTRFS_FS_TREE_OBJECTID), |
||||
+ 0, &fs_root); |
||||
+ if (err) |
||||
+ goto out; |
||||
+ |
||||
+ err = lower_bound(data, &key_in, &key_out, tree, |
||||
+ &elemaddr, &elemsize, &desc, 0); |
||||
+ |
||||
+ if (err) |
||||
+ { |
||||
+ grub_btrfs_unmount(data); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF || elemaddr == 0) |
||||
+ { |
||||
+ r = next(data, &desc, &elemaddr, &elemsize, &key_out); |
||||
+ } |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF) { |
||||
+ err = GRUB_ERR_FILE_NOT_FOUND; |
||||
+ grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root refs")); |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ do |
||||
+ { |
||||
+ struct grub_btrfs_root_ref *ref; |
||||
+ char *p = NULL; |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF) |
||||
+ { |
||||
+ r = 0; |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ if (elemsize > allocated) |
||||
+ { |
||||
+ grub_free(buf); |
||||
+ allocated = 2 * elemsize; |
||||
+ buf = grub_malloc(allocated + 1); |
||||
+ if (!buf) |
||||
+ { |
||||
+ r = -grub_errno; |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ ref = (struct grub_btrfs_root_ref *)buf; |
||||
+ |
||||
+ err = grub_btrfs_read_logical(data, elemaddr, buf, elemsize, 0); |
||||
+ if (err) |
||||
+ { |
||||
+ r = -err; |
||||
+ break; |
||||
+ } |
||||
+ buf[elemsize] = 0; |
||||
+ |
||||
+ find_pathname(data, ref->dirid, fs_root, ref->name, &p); |
||||
+ |
||||
+ if (print) |
||||
+ { |
||||
+ if (num_only) |
||||
+ grub_printf("ID %"PRIuGRUB_UINT64_T"\n", key_out.offset); |
||||
+ else if (path_only) |
||||
+ grub_printf("%s\n", p); |
||||
+ else |
||||
+ grub_printf("ID %"PRIuGRUB_UINT64_T" path %s\n", key_out.offset, p); |
||||
+ } else { |
||||
+ char *old = output; |
||||
+ if (num_only) |
||||
+ output = grub_xasprintf("%s%"PRIuGRUB_UINT64_T"\n", |
||||
+ old ?: "", key_out.offset); |
||||
+ else if (path_only) |
||||
+ output = grub_xasprintf("%s%s\n", old ?: "", p); |
||||
+ else |
||||
+ output = grub_xasprintf("%sID %"PRIuGRUB_UINT64_T" path %s\n", |
||||
+ old ?: "", key_out.offset, p); |
||||
+ |
||||
+ if (old) |
||||
+ grub_free(old); |
||||
+ } |
||||
+ |
||||
+ r = next(data, &desc, &elemaddr, &elemsize, &key_out); |
||||
+ } while(r > 0); |
||||
+ |
||||
+ if (output) |
||||
+ grub_env_set(varname, output); |
||||
+ |
||||
+out: |
||||
+ free_iterator(&desc); |
||||
+ grub_btrfs_unmount(data); |
||||
+ |
||||
+ grub_device_close (dev); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
static struct grub_fs grub_btrfs_fs = { |
||||
.name = "btrfs", |
||||
.fs_dir = grub_btrfs_dir, |
||||
@@ -2205,12 +2641,88 @@ static struct grub_fs grub_btrfs_fs = { |
||||
#endif |
||||
}; |
||||
|
||||
+static grub_command_t cmd_info; |
||||
+static grub_extcmd_t cmd_list_subvols; |
||||
+ |
||||
+static char * |
||||
+subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)), |
||||
+ const char *val) |
||||
+{ |
||||
+ unsigned long long result = 0; |
||||
+ |
||||
+ grub_errno = GRUB_ERR_NONE; |
||||
+ if (*val) |
||||
+ { |
||||
+ result = grub_strtoull(val, NULL, 10); |
||||
+ if (grub_errno) |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ grub_free (btrfs_default_subvol); |
||||
+ btrfs_default_subvol = NULL; |
||||
+ btrfs_default_subvolid = result; |
||||
+ return grub_strdup(val); |
||||
+} |
||||
+ |
||||
+static const char * |
||||
+subvolid_get_env (struct grub_env_var *var __attribute__ ((unused)), |
||||
+ const char *val __attribute__ ((unused))) |
||||
+{ |
||||
+ if (btrfs_default_subvol) |
||||
+ return grub_xasprintf("subvol:%s", btrfs_default_subvol); |
||||
+ else if (btrfs_default_subvolid) |
||||
+ return grub_xasprintf("%"PRIuGRUB_UINT64_T, btrfs_default_subvolid); |
||||
+ else |
||||
+ return ""; |
||||
+} |
||||
+ |
||||
+static char * |
||||
+subvol_set_env (struct grub_env_var *var __attribute__ ((unused)), |
||||
+ const char *val) |
||||
+{ |
||||
+ grub_free (btrfs_default_subvol); |
||||
+ btrfs_default_subvol = grub_strdup (val); |
||||
+ btrfs_default_subvolid = 0; |
||||
+ return grub_strdup(val); |
||||
+} |
||||
+ |
||||
+static const char * |
||||
+subvol_get_env (struct grub_env_var *var __attribute__ ((unused)), |
||||
+ const char *val __attribute__ ((unused))) |
||||
+{ |
||||
+ if (btrfs_default_subvol) |
||||
+ return btrfs_default_subvol; |
||||
+ else if (btrfs_default_subvolid) |
||||
+ return grub_xasprintf("subvolid:%" PRIuGRUB_UINT64_T, |
||||
+ btrfs_default_subvolid); |
||||
+ else |
||||
+ return ""; |
||||
+} |
||||
+ |
||||
GRUB_MOD_INIT (btrfs) |
||||
{ |
||||
grub_fs_register (&grub_btrfs_fs); |
||||
+ cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info, |
||||
+ "DEVICE", |
||||
+ "Print BtrFS info about DEVICE."); |
||||
+ cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols", |
||||
+ grub_cmd_btrfs_list_subvols, 0, |
||||
+ "[-p|-n] [-o var] DEVICE", |
||||
+ "Print list of BtrFS subvolumes on " |
||||
+ "DEVICE.", options); |
||||
+ grub_register_variable_hook ("btrfs_subvol", subvol_get_env, |
||||
+ subvol_set_env); |
||||
+ grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, |
||||
+ subvolid_set_env); |
||||
} |
||||
|
||||
GRUB_MOD_FINI (btrfs) |
||||
{ |
||||
+ grub_register_variable_hook ("btrfs_subvol", NULL, NULL); |
||||
+ grub_register_variable_hook ("btrfs_subvolid", NULL, NULL); |
||||
+ grub_unregister_command (cmd_info); |
||||
+ grub_unregister_extcmd (cmd_list_subvols); |
||||
grub_fs_unregister (&grub_btrfs_fs); |
||||
} |
||||
+ |
||||
+// vim: si et sw=2: |
||||
diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h |
||||
index 9d93fb6c18..234ad97677 100644 |
||||
--- a/include/grub/btrfs.h |
||||
+++ b/include/grub/btrfs.h |
||||
@@ -29,6 +29,7 @@ enum |
||||
GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84, |
||||
GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90, |
||||
GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8, |
||||
+ GRUB_BTRFS_ITEM_TYPE_ROOT_REF = 0x9c, |
||||
GRUB_BTRFS_ITEM_TYPE_CHUNK = 0xe4 |
||||
}; |
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Wed, 18 Dec 2013 09:57:04 +0000 |
||||
Subject: [PATCH] export btrfs_subvol and btrfs_subvolid |
||||
|
||||
We should export btrfs_subvol and btrfs_subvolid to have both visible |
||||
to subsidiary configuration files loaded using configfile. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
--- |
||||
grub-core/fs/btrfs.c | 2 ++ |
||||
1 file changed, 2 insertions(+) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index f1fff7385b..ad1b56b716 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -2714,6 +2714,8 @@ GRUB_MOD_INIT (btrfs) |
||||
subvol_set_env); |
||||
grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, |
||||
subvolid_set_env); |
||||
+ grub_env_export ("btrfs_subvol"); |
||||
+ grub_env_export ("btrfs_subvolid"); |
||||
} |
||||
|
||||
GRUB_MOD_FINI (btrfs) |
@ -0,0 +1,198 @@
@@ -0,0 +1,198 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Thu, 21 Aug 2014 03:39:11 +0000 |
||||
Subject: [PATCH] grub2-btrfs-03-follow_default |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/fs/btrfs.c | 107 ++++++++++++++++++++++++++++++++++++--------------- |
||||
1 file changed, 76 insertions(+), 31 deletions(-) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index ad1b56b716..113c1f746c 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -1256,6 +1256,7 @@ grub_btrfs_mount (grub_device_t dev) |
||||
{ |
||||
struct grub_btrfs_data *data; |
||||
grub_err_t err; |
||||
+ const char *relpath = grub_env_get ("btrfs_relative_path"); |
||||
|
||||
if (!dev->disk) |
||||
{ |
||||
@@ -1286,11 +1287,14 @@ grub_btrfs_mount (grub_device_t dev) |
||||
data->devices_attached[0].dev = dev; |
||||
data->devices_attached[0].id = data->sblock.this_device.device_id; |
||||
|
||||
- err = btrfs_handle_subvol (data); |
||||
- if (err) |
||||
+ if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) |
||||
{ |
||||
- grub_free (data); |
||||
- return NULL; |
||||
+ err = btrfs_handle_subvol (data); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (data); |
||||
+ return NULL; |
||||
+ } |
||||
} |
||||
|
||||
return data; |
||||
@@ -1855,24 +1859,39 @@ find_path (struct grub_btrfs_data *data, |
||||
grub_size_t allocated = 0; |
||||
struct grub_btrfs_dir_item *direl = NULL; |
||||
struct grub_btrfs_key key_out; |
||||
+ int follow_default; |
||||
const char *ctoken; |
||||
grub_size_t ctokenlen; |
||||
char *path_alloc = NULL; |
||||
char *origpath = NULL; |
||||
unsigned symlinks_max = 32; |
||||
+ const char *relpath = grub_env_get ("btrfs_relative_path"); |
||||
|
||||
+ follow_default = 0; |
||||
origpath = grub_strdup (path); |
||||
if (!origpath) |
||||
return grub_errno; |
||||
|
||||
- if (data->fs_tree) |
||||
+ if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) |
||||
{ |
||||
- *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
- *tree = data->fs_tree; |
||||
- /* This is a tree root, so everything starts at objectid 256 */ |
||||
- key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); |
||||
- key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
- key->offset = 0; |
||||
+ if (data->fs_tree) |
||||
+ { |
||||
+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
+ *tree = data->fs_tree; |
||||
+ /* This is a tree root, so everything starts at objectid 256 */ |
||||
+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); |
||||
+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key->offset = 0; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
+ *tree = data->sblock.root_tree; |
||||
+ key->object_id = data->sblock.root_dir_objectid; |
||||
+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key->offset = 0; |
||||
+ follow_default = 1; |
||||
+ } |
||||
} |
||||
else |
||||
{ |
||||
@@ -1883,15 +1902,23 @@ find_path (struct grub_btrfs_data *data, |
||||
|
||||
while (1) |
||||
{ |
||||
- while (path[0] == '/') |
||||
- path++; |
||||
- if (!path[0]) |
||||
- break; |
||||
- slash = grub_strchr (path, '/'); |
||||
- if (!slash) |
||||
- slash = path + grub_strlen (path); |
||||
- ctoken = path; |
||||
- ctokenlen = slash - path; |
||||
+ if (!follow_default) |
||||
+ { |
||||
+ while (path[0] == '/') |
||||
+ path++; |
||||
+ if (!path[0]) |
||||
+ break; |
||||
+ slash = grub_strchr (path, '/'); |
||||
+ if (!slash) |
||||
+ slash = path + grub_strlen (path); |
||||
+ ctoken = path; |
||||
+ ctokenlen = slash - path; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ ctoken = "default"; |
||||
+ ctokenlen = sizeof ("default") - 1; |
||||
+ } |
||||
|
||||
if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) |
||||
{ |
||||
@@ -1902,7 +1929,9 @@ find_path (struct grub_btrfs_data *data, |
||||
|
||||
if (ctokenlen == 1 && ctoken[0] == '.') |
||||
{ |
||||
- path = slash; |
||||
+ if (!follow_default) |
||||
+ path = slash; |
||||
+ follow_default = 0; |
||||
continue; |
||||
} |
||||
if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.') |
||||
@@ -1933,8 +1962,9 @@ find_path (struct grub_btrfs_data *data, |
||||
*type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
key->object_id = key_out.offset; |
||||
|
||||
- path = slash; |
||||
- |
||||
+ if (!follow_default) |
||||
+ path = slash; |
||||
+ follow_default = 0; |
||||
continue; |
||||
} |
||||
|
||||
@@ -2003,7 +2033,9 @@ find_path (struct grub_btrfs_data *data, |
||||
return err; |
||||
} |
||||
|
||||
- path = slash; |
||||
+ if (!follow_default) |
||||
+ path = slash; |
||||
+ follow_default = 0; |
||||
if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) |
||||
{ |
||||
struct grub_btrfs_inode inode; |
||||
@@ -2053,14 +2085,26 @@ find_path (struct grub_btrfs_data *data, |
||||
path = path_alloc = tmp; |
||||
if (path[0] == '/') |
||||
{ |
||||
- if (data->fs_tree) |
||||
+ if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) |
||||
{ |
||||
- *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
- *tree = data->fs_tree; |
||||
- /* This is a tree root, so everything starts at objectid 256 */ |
||||
- key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); |
||||
- key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
- key->offset = 0; |
||||
+ if (data->fs_tree) |
||||
+ { |
||||
+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
+ *tree = data->fs_tree; |
||||
+ /* This is a tree root, so everything starts at objectid 256 */ |
||||
+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); |
||||
+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key->offset = 0; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; |
||||
+ *tree = data->sblock.root_tree; |
||||
+ key->object_id = data->sblock.root_dir_objectid; |
||||
+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key->offset = 0; |
||||
+ follow_default = 1; |
||||
+ } |
||||
} |
||||
else |
||||
{ |
||||
@@ -2716,6 +2760,7 @@ GRUB_MOD_INIT (btrfs) |
||||
subvolid_set_env); |
||||
grub_env_export ("btrfs_subvol"); |
||||
grub_env_export ("btrfs_subvolid"); |
||||
+ grub_env_export ("btrfs_relative_path"); |
||||
} |
||||
|
||||
GRUB_MOD_FINI (btrfs) |
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Thu, 21 Aug 2014 03:39:11 +0000 |
||||
Subject: [PATCH] grub2-btrfs-04-grub2-install |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/osdep/linux/getroot.c | 7 +++++++ |
||||
grub-core/osdep/unix/config.c | 17 +++++++++++++++-- |
||||
util/config.c | 10 ++++++++++ |
||||
util/grub-install.c | 15 +++++++++++++++ |
||||
util/grub-mkrelpath.c | 6 ++++++ |
||||
include/grub/emu/config.h | 1 + |
||||
6 files changed, 54 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c |
||||
index 001b818fe5..caf9b1ccd3 100644 |
||||
--- a/grub-core/osdep/linux/getroot.c |
||||
+++ b/grub-core/osdep/linux/getroot.c |
||||
@@ -376,6 +376,7 @@ get_btrfs_fs_prefix (const char *mount_path) |
||||
return NULL; |
||||
} |
||||
|
||||
+int use_relative_path_on_btrfs = 0; |
||||
|
||||
char ** |
||||
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) |
||||
@@ -519,6 +520,12 @@ again: |
||||
{ |
||||
ret = grub_find_root_devices_from_btrfs (dir); |
||||
fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); |
||||
+ if (use_relative_path_on_btrfs) |
||||
+ { |
||||
+ if (fs_prefix) |
||||
+ free (fs_prefix); |
||||
+ fs_prefix = xstrdup ("/"); |
||||
+ } |
||||
} |
||||
else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) |
||||
{ |
||||
diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c |
||||
index 7d6325138c..46a881530c 100644 |
||||
--- a/grub-core/osdep/unix/config.c |
||||
+++ b/grub-core/osdep/unix/config.c |
||||
@@ -82,6 +82,19 @@ grub_util_load_config (struct grub_util_config *cfg) |
||||
if (v) |
||||
cfg->grub_distributor = xstrdup (v); |
||||
|
||||
+ v = getenv ("SUSE_BTRFS_SNAPSHOT_BOOTING"); |
||||
+ if (v) |
||||
+ { |
||||
+ if (grub_strncmp(v, "true", sizeof ("true") - 1) == 0) |
||||
+ { |
||||
+ cfg->is_suse_btrfs_snapshot_enabled = 1; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ cfg->is_suse_btrfs_snapshot_enabled = 0; |
||||
+ } |
||||
+ } |
||||
+ |
||||
cfgfile = grub_util_get_config_filename (); |
||||
if (!grub_util_is_regular (cfgfile)) |
||||
return; |
||||
@@ -105,8 +118,8 @@ grub_util_load_config (struct grub_util_config *cfg) |
||||
*ptr++ = *iptr; |
||||
} |
||||
|
||||
- strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" " |
||||
- "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\""); |
||||
+ strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\nSUSE_BTRFS_SNAPSHOT_BOOTING=%s\\n\" " |
||||
+ "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\" \"$SUSE_BTRFS_SNAPSHOT_BOOTING\""); |
||||
|
||||
argv[2] = script; |
||||
argv[3] = '\0'; |
||||
diff --git a/util/config.c b/util/config.c |
||||
index ebcdd8f5e2..f044a880a7 100644 |
||||
--- a/util/config.c |
||||
+++ b/util/config.c |
||||
@@ -42,6 +42,16 @@ grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple) |
||||
cfg->is_cryptodisk_enabled = 1; |
||||
continue; |
||||
} |
||||
+ if (grub_strncmp (ptr, "SUSE_BTRFS_SNAPSHOT_BOOTING=", |
||||
+ sizeof ("SUSE_BTRFS_SNAPSHOT_BOOTING=") - 1) == 0) |
||||
+ { |
||||
+ ptr += sizeof ("SUSE_BTRFS_SNAPSHOT_BOOTING=") - 1; |
||||
+ if (*ptr == '"' || *ptr == '\'') |
||||
+ ptr++; |
||||
+ if (grub_strncmp(ptr, "true", sizeof ("true") - 1) == 0) |
||||
+ cfg->is_suse_btrfs_snapshot_enabled = 1; |
||||
+ continue; |
||||
+ } |
||||
if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=", |
||||
sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0) |
||||
{ |
||||
diff --git a/util/grub-install.c b/util/grub-install.c |
||||
index 0fbe7f78c6..0f66f36d23 100644 |
||||
--- a/util/grub-install.c |
||||
+++ b/util/grub-install.c |
||||
@@ -827,6 +827,8 @@ fill_core_services (const char *core_services) |
||||
free (sysv_plist); |
||||
} |
||||
|
||||
+extern int use_relative_path_on_btrfs; |
||||
+ |
||||
int |
||||
main (int argc, char *argv[]) |
||||
{ |
||||
@@ -860,6 +862,9 @@ main (int argc, char *argv[]) |
||||
|
||||
grub_util_load_config (&config); |
||||
|
||||
+ if (config.is_suse_btrfs_snapshot_enabled) |
||||
+ use_relative_path_on_btrfs = 1; |
||||
+ |
||||
if (!bootloader_id && config.grub_distributor) |
||||
{ |
||||
char *ptr; |
||||
@@ -1352,6 +1357,16 @@ main (int argc, char *argv[]) |
||||
fprintf (load_cfg_f, "set debug='%s'\n", |
||||
debug_image); |
||||
} |
||||
+ |
||||
+ if (config.is_suse_btrfs_snapshot_enabled |
||||
+ && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0) |
||||
+ { |
||||
+ if (!load_cfg_f) |
||||
+ load_cfg_f = grub_util_fopen (load_cfg, "wb"); |
||||
+ have_load_cfg = 1; |
||||
+ fprintf (load_cfg_f, "set btrfs_relative_path='y'\n"); |
||||
+ } |
||||
+ |
||||
char *prefix_drive = NULL; |
||||
char *install_drive = NULL; |
||||
|
||||
diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c |
||||
index 47a241a391..5db7a9a7d9 100644 |
||||
--- a/util/grub-mkrelpath.c |
||||
+++ b/util/grub-mkrelpath.c |
||||
@@ -40,9 +40,12 @@ struct arguments |
||||
}; |
||||
|
||||
static struct argp_option options[] = { |
||||
+ {"relative", 'r', 0, 0, "use relative path on btrfs", 0}, |
||||
{ 0, 0, 0, 0, 0, 0 } |
||||
}; |
||||
|
||||
+extern int use_relative_path_on_btrfs; |
||||
+ |
||||
static error_t |
||||
argp_parser (int key, char *arg, struct argp_state *state) |
||||
{ |
||||
@@ -52,6 +55,9 @@ argp_parser (int key, char *arg, struct argp_state *state) |
||||
|
||||
switch (key) |
||||
{ |
||||
+ case 'r': |
||||
+ use_relative_path_on_btrfs = 1; |
||||
+ break; |
||||
case ARGP_KEY_ARG: |
||||
if (state->arg_num == 0) |
||||
arguments->pathname = xstrdup (arg); |
||||
diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h |
||||
index 875d5896ce..c9a7e5f4ad 100644 |
||||
--- a/include/grub/emu/config.h |
||||
+++ b/include/grub/emu/config.h |
||||
@@ -37,6 +37,7 @@ struct grub_util_config |
||||
{ |
||||
int is_cryptodisk_enabled; |
||||
char *grub_distributor; |
||||
+ int is_suse_btrfs_snapshot_enabled; |
||||
}; |
||||
|
||||
void |
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Thu, 21 Aug 2014 03:39:11 +0000 |
||||
Subject: [PATCH] grub2-btrfs-05-grub2-mkconfig |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
--- |
||||
util/grub-mkconfig.in | 3 ++- |
||||
util/grub-mkconfig_lib.in | 4 ++++ |
||||
util/grub.d/00_header.in | 25 ++++++++++++++++++++++++- |
||||
util/grub.d/10_linux.in | 4 ++++ |
||||
util/grub.d/20_linux_xen.in | 4 ++++ |
||||
5 files changed, 38 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in |
||||
index 005f093809..535c0f0249 100644 |
||||
--- a/util/grub-mkconfig.in |
||||
+++ b/util/grub-mkconfig.in |
||||
@@ -252,7 +252,8 @@ export GRUB_DEFAULT \ |
||||
GRUB_BADRAM \ |
||||
GRUB_OS_PROBER_SKIP_LIST \ |
||||
GRUB_DISABLE_SUBMENU \ |
||||
- GRUB_DEFAULT_DTB |
||||
+ GRUB_DEFAULT_DTB \ |
||||
+ SUSE_BTRFS_SNAPSHOT_BOOTING |
||||
|
||||
if test "x${grub_cfg}" != "x"; then |
||||
rm -f "${grub_cfg}.new" |
||||
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in |
||||
index 0f6505bf3b..5e96f6cc5d 100644 |
||||
--- a/util/grub-mkconfig_lib.in |
||||
+++ b/util/grub-mkconfig_lib.in |
||||
@@ -49,7 +49,11 @@ grub_warn () |
||||
|
||||
make_system_path_relative_to_its_root () |
||||
{ |
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] ; then |
||||
+ "${grub_mkrelpath}" -r "$1" |
||||
+ else |
||||
"${grub_mkrelpath}" "$1" |
||||
+ fi |
||||
} |
||||
|
||||
is_path_readable_by_grub () |
||||
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in |
||||
index 858b526c92..de727e6ee6 100644 |
||||
--- a/util/grub.d/00_header.in |
||||
+++ b/util/grub.d/00_header.in |
||||
@@ -27,6 +27,14 @@ export TEXTDOMAINDIR="@localedir@" |
||||
|
||||
. "$pkgdatadir/grub-mkconfig_lib" |
||||
|
||||
+if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] && |
||||
+ [ "x${GRUB_FS}" = "xbtrfs" ] ; then |
||||
+ cat <<EOF |
||||
+set btrfs_relative_path="y" |
||||
+export btrfs_relative_path |
||||
+EOF |
||||
+fi |
||||
+ |
||||
# Do this as early as possible, since other commands might depend on it. |
||||
# (e.g. the `loadfont' command might need lvm or raid modules) |
||||
for i in ${GRUB_PRELOAD_MODULES} ; do |
||||
@@ -45,7 +53,9 @@ if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT |
||||
cat << EOF |
||||
set pager=1 |
||||
|
||||
-if [ -s \$prefix/grubenv ]; then |
||||
+if [ -f \${config_directory}/grubenv ]; then |
||||
+ load_env -f \${config_directory}/grubenv |
||||
+elif [ -s \$prefix/grubenv ]; then |
||||
load_env |
||||
fi |
||||
EOF |
||||
@@ -356,3 +366,16 @@ fi |
||||
if [ "x${GRUB_BADRAM}" != "x" ] ; then |
||||
echo "badram ${GRUB_BADRAM}" |
||||
fi |
||||
+ |
||||
+if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] && |
||||
+ [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ] && |
||||
+ [ "x${GRUB_FS}" = "xbtrfs" ] ; then |
||||
+ # Note: No $snapshot_num on *read-only* rollback! (bsc#901487) |
||||
+ cat <<EOF |
||||
+if [ -n "\$extra_cmdline" ]; then |
||||
+ submenu "Bootable snapshot #\$snapshot_num" { |
||||
+ menuentry "If OK, run 'snapper rollback' and reboot." { true; } |
||||
+ } |
||||
+fi |
||||
+EOF |
||||
+fi |
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index 292e333324..7bb3a211a7 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -66,10 +66,14 @@ fi |
||||
|
||||
case x"$GRUB_FS" in |
||||
xbtrfs) |
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ]; then |
||||
+ GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} \${extra_cmdline}" |
||||
+ else |
||||
rootsubvol="`make_system_path_relative_to_its_root /`" |
||||
rootsubvol="${rootsubvol#/}" |
||||
if [ "x${rootsubvol}" != x ]; then |
||||
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" |
||||
+ fi |
||||
fi;; |
||||
xzfs) |
||||
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true` |
||||
diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in |
||||
index ada20775a1..e9e73b815f 100644 |
||||
--- a/util/grub.d/20_linux_xen.in |
||||
+++ b/util/grub.d/20_linux_xen.in |
||||
@@ -73,10 +73,14 @@ fi |
||||
|
||||
case x"$GRUB_FS" in |
||||
xbtrfs) |
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ]; then |
||||
+ GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} \${extra_cmdline}" |
||||
+ else |
||||
rootsubvol="`make_system_path_relative_to_its_root /`" |
||||
rootsubvol="${rootsubvol#/}" |
||||
if [ "x${rootsubvol}" != x ]; then |
||||
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" |
||||
+ fi |
||||
fi;; |
||||
xzfs) |
||||
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true` |
@ -0,0 +1,539 @@
@@ -0,0 +1,539 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Tue, 9 Jul 2019 13:56:16 +0200 |
||||
Subject: [PATCH] grub2-btrfs-06-subvol-mount |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/fs/btrfs.c | 195 +++++++++++++++++++++++++++++++++++++++- |
||||
grub-core/osdep/linux/getroot.c | 148 +++++++++++++++++++++++++++++- |
||||
util/grub-install.c | 49 ++++++++++ |
||||
include/grub/emu/getroot.h | 5 ++ |
||||
4 files changed, 392 insertions(+), 5 deletions(-) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index 113c1f746c..d323746ecf 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -41,6 +41,7 @@ |
||||
#include <grub/command.h> |
||||
#include <grub/env.h> |
||||
#include <grub/extcmd.h> |
||||
+#include <grub/list.h> |
||||
#include <grub/crypto.h> |
||||
#include <grub/diskfilter.h> |
||||
#include <grub/safemath.h> |
||||
@@ -266,6 +267,12 @@ static grub_err_t |
||||
grub_btrfs_read_logical (struct grub_btrfs_data *data, |
||||
grub_disk_addr_t addr, void *buf, grub_size_t size, |
||||
int recursion_depth); |
||||
+static grub_err_t |
||||
+get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, |
||||
+ grub_uint64_t *tree, grub_uint8_t *type); |
||||
+ |
||||
+grub_uint64_t |
||||
+find_mtab_subvol_tree (const char *path, char **path_in_subvol); |
||||
|
||||
static grub_err_t |
||||
read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) |
||||
@@ -1223,9 +1230,26 @@ lookup_root_by_name(struct grub_btrfs_data *data, const char *path) |
||||
grub_err_t err; |
||||
grub_uint64_t tree = 0; |
||||
grub_uint8_t type; |
||||
+ grub_uint64_t saved_tree; |
||||
struct grub_btrfs_key key; |
||||
|
||||
+ if (path[0] == '\0') |
||||
+ { |
||||
+ data->fs_tree = 0; |
||||
+ return GRUB_ERR_NONE; |
||||
+ } |
||||
+ |
||||
+ err = get_root (data, &key, &tree, &type); |
||||
+ if (err) |
||||
+ return err; |
||||
+ |
||||
+ saved_tree = data->fs_tree; |
||||
+ data->fs_tree = tree; |
||||
+ |
||||
err = find_path (data, path, &key, &tree, &type); |
||||
+ |
||||
+ data->fs_tree = saved_tree; |
||||
+ |
||||
if (err) |
||||
return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); |
||||
|
||||
@@ -2199,11 +2223,20 @@ grub_btrfs_dir (grub_device_t device, const char *path, |
||||
int r = 0; |
||||
grub_uint64_t tree; |
||||
grub_uint8_t type; |
||||
+ char *new_path = NULL; |
||||
|
||||
if (!data) |
||||
return grub_errno; |
||||
|
||||
- err = find_path (data, path, &key_in, &tree, &type); |
||||
+ tree = find_mtab_subvol_tree (path, &new_path); |
||||
+ |
||||
+ if (tree) |
||||
+ data->fs_tree = tree; |
||||
+ |
||||
+ err = find_path (data, new_path ? new_path : path, &key_in, &tree, &type); |
||||
+ if (new_path) |
||||
+ grub_free (new_path); |
||||
+ |
||||
if (err) |
||||
{ |
||||
grub_btrfs_unmount (data); |
||||
@@ -2305,11 +2338,21 @@ grub_btrfs_open (struct grub_file *file, const char *name) |
||||
struct grub_btrfs_inode inode; |
||||
grub_uint8_t type; |
||||
struct grub_btrfs_key key_in; |
||||
+ grub_uint64_t tree; |
||||
+ char *new_path = NULL; |
||||
|
||||
if (!data) |
||||
return grub_errno; |
||||
|
||||
- err = find_path (data, name, &key_in, &data->tree, &type); |
||||
+ tree = find_mtab_subvol_tree (name, &new_path); |
||||
+ |
||||
+ if (tree) |
||||
+ data->fs_tree = tree; |
||||
+ |
||||
+ err = find_path (data, new_path ? new_path : name, &key_in, &data->tree, &type); |
||||
+ if (new_path) |
||||
+ grub_free (new_path); |
||||
+ |
||||
if (err) |
||||
{ |
||||
grub_btrfs_unmount (data); |
||||
@@ -2480,6 +2523,150 @@ grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc, |
||||
return 0; |
||||
} |
||||
|
||||
+struct grub_btrfs_mtab |
||||
+{ |
||||
+ struct grub_btrfs_mtab *next; |
||||
+ struct grub_btrfs_mtab **prev; |
||||
+ char *path; |
||||
+ char *subvol; |
||||
+ grub_uint64_t tree; |
||||
+}; |
||||
+ |
||||
+typedef struct grub_btrfs_mtab* grub_btrfs_mtab_t; |
||||
+ |
||||
+static struct grub_btrfs_mtab *btrfs_mtab; |
||||
+ |
||||
+#define FOR_GRUB_MTAB(var) FOR_LIST_ELEMENTS (var, btrfs_mtab) |
||||
+#define FOR_GRUB_MTAB_SAFE(var, next) FOR_LIST_ELEMENTS_SAFE((var), (next), btrfs_mtab) |
||||
+ |
||||
+static void |
||||
+add_mountpoint (const char *path, const char *subvol, grub_uint64_t tree) |
||||
+{ |
||||
+ grub_btrfs_mtab_t m = grub_malloc (sizeof (*m)); |
||||
+ |
||||
+ m->path = grub_strdup (path); |
||||
+ m->subvol = grub_strdup (subvol); |
||||
+ m->tree = tree; |
||||
+ grub_list_push (GRUB_AS_LIST_P (&btrfs_mtab), GRUB_AS_LIST (m)); |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+grub_cmd_btrfs_mount_subvol (grub_command_t cmd __attribute__ ((unused)), int argc, |
||||
+ char **argv) |
||||
+{ |
||||
+ char *devname, *dirname, *subvol; |
||||
+ struct grub_btrfs_key key_in; |
||||
+ grub_uint8_t type; |
||||
+ grub_uint64_t tree; |
||||
+ grub_uint64_t saved_tree; |
||||
+ grub_err_t err; |
||||
+ struct grub_btrfs_data *data = NULL; |
||||
+ grub_device_t dev = NULL; |
||||
+ |
||||
+ if (argc < 3) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "required <dev> <dir> and <subvol>"); |
||||
+ |
||||
+ devname = grub_file_get_device_name(argv[0]); |
||||
+ dev = grub_device_open (devname); |
||||
+ grub_free (devname); |
||||
+ |
||||
+ if (!dev) |
||||
+ { |
||||
+ err = grub_errno; |
||||
+ goto err_out; |
||||
+ } |
||||
+ |
||||
+ dirname = argv[1]; |
||||
+ subvol = argv[2]; |
||||
+ |
||||
+ data = grub_btrfs_mount (dev); |
||||
+ if (!data) |
||||
+ { |
||||
+ err = grub_errno; |
||||
+ goto err_out; |
||||
+ } |
||||
+ |
||||
+ err = find_path (data, dirname, &key_in, &tree, &type); |
||||
+ if (err) |
||||
+ goto err_out; |
||||
+ |
||||
+ if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) |
||||
+ { |
||||
+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); |
||||
+ goto err_out; |
||||
+ } |
||||
+ |
||||
+ err = get_root (data, &key_in, &tree, &type); |
||||
+ |
||||
+ if (err) |
||||
+ goto err_out; |
||||
+ |
||||
+ saved_tree = data->fs_tree; |
||||
+ data->fs_tree = tree; |
||||
+ err = find_path (data, subvol, &key_in, &tree, &type); |
||||
+ data->fs_tree = saved_tree; |
||||
+ |
||||
+ if (err) |
||||
+ goto err_out; |
||||
+ |
||||
+ if (key_in.object_id != grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK) || tree == 0) |
||||
+ { |
||||
+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "%s: not a subvolume\n", subvol); |
||||
+ goto err_out; |
||||
+ } |
||||
+ |
||||
+ grub_btrfs_unmount (data); |
||||
+ grub_device_close (dev); |
||||
+ add_mountpoint (dirname, subvol, tree); |
||||
+ |
||||
+ return GRUB_ERR_NONE; |
||||
+ |
||||
+err_out: |
||||
+ |
||||
+ if (data) |
||||
+ grub_btrfs_unmount (data); |
||||
+ |
||||
+ if (dev) |
||||
+ grub_device_close (dev); |
||||
+ |
||||
+ return err; |
||||
+} |
||||
+ |
||||
+grub_uint64_t |
||||
+find_mtab_subvol_tree (const char *path, char **path_in_subvol) |
||||
+{ |
||||
+ grub_btrfs_mtab_t m, cm; |
||||
+ grub_uint64_t tree; |
||||
+ |
||||
+ if (!path || !path_in_subvol) |
||||
+ return 0; |
||||
+ |
||||
+ *path_in_subvol = NULL; |
||||
+ tree = 0; |
||||
+ cm = NULL; |
||||
+ |
||||
+ FOR_GRUB_MTAB (m) |
||||
+ { |
||||
+ if (grub_strncmp (path, m->path, grub_strlen (m->path)) == 0) |
||||
+ { |
||||
+ if (!cm) |
||||
+ cm = m; |
||||
+ else |
||||
+ if (grub_strcmp (m->path, cm->path) > 0) |
||||
+ cm = m; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (cm) |
||||
+ { |
||||
+ const char *s = path + grub_strlen (cm->path); |
||||
+ *path_in_subvol = (s[0] == '\0') ? grub_strdup ("/") : grub_strdup (s); |
||||
+ tree = cm->tree; |
||||
+ } |
||||
+ |
||||
+ return tree; |
||||
+} |
||||
+ |
||||
static grub_err_t |
||||
get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, |
||||
grub_uint64_t objectid, grub_uint64_t offset, |
||||
@@ -2686,6 +2873,7 @@ static struct grub_fs grub_btrfs_fs = { |
||||
}; |
||||
|
||||
static grub_command_t cmd_info; |
||||
+static grub_command_t cmd_mount_subvol; |
||||
static grub_extcmd_t cmd_list_subvols; |
||||
|
||||
static char * |
||||
@@ -2749,6 +2937,9 @@ GRUB_MOD_INIT (btrfs) |
||||
cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info, |
||||
"DEVICE", |
||||
"Print BtrFS info about DEVICE."); |
||||
+ cmd_mount_subvol = grub_register_command("btrfs-mount-subvol", grub_cmd_btrfs_mount_subvol, |
||||
+ "DEVICE DIRECTORY SUBVOL", |
||||
+ "Set btrfs DEVICE the DIRECTORY a mountpoint of SUBVOL."); |
||||
cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols", |
||||
grub_cmd_btrfs_list_subvols, 0, |
||||
"[-p|-n] [-o var] DEVICE", |
||||
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c |
||||
index caf9b1ccd3..28790307e0 100644 |
||||
--- a/grub-core/osdep/linux/getroot.c |
||||
+++ b/grub-core/osdep/linux/getroot.c |
||||
@@ -107,6 +107,14 @@ struct btrfs_ioctl_search_key |
||||
grub_uint32_t unused[9]; |
||||
}; |
||||
|
||||
+struct btrfs_ioctl_search_header { |
||||
+ grub_uint64_t transid; |
||||
+ grub_uint64_t objectid; |
||||
+ grub_uint64_t offset; |
||||
+ grub_uint32_t type; |
||||
+ grub_uint32_t len; |
||||
+}; |
||||
+ |
||||
struct btrfs_ioctl_search_args { |
||||
struct btrfs_ioctl_search_key key; |
||||
grub_uint64_t buf[(4096 - sizeof(struct btrfs_ioctl_search_key)) |
||||
@@ -378,6 +386,109 @@ get_btrfs_fs_prefix (const char *mount_path) |
||||
|
||||
int use_relative_path_on_btrfs = 0; |
||||
|
||||
+static char * |
||||
+get_btrfs_subvol (const char *path) |
||||
+{ |
||||
+ struct btrfs_ioctl_ino_lookup_args args; |
||||
+ grub_uint64_t tree_id; |
||||
+ int fd = -1; |
||||
+ char *ret = NULL; |
||||
+ |
||||
+ fd = open (path, O_RDONLY); |
||||
+ |
||||
+ if (fd < 0) |
||||
+ return NULL; |
||||
+ |
||||
+ memset (&args, 0, sizeof(args)); |
||||
+ args.objectid = GRUB_BTRFS_TREE_ROOT_OBJECTID; |
||||
+ |
||||
+ if (ioctl (fd, BTRFS_IOC_INO_LOOKUP, &args) < 0) |
||||
+ goto error; |
||||
+ |
||||
+ tree_id = args.treeid; |
||||
+ |
||||
+ while (tree_id != GRUB_BTRFS_ROOT_VOL_OBJECTID) |
||||
+ { |
||||
+ struct btrfs_ioctl_search_args sargs; |
||||
+ struct grub_btrfs_root_backref *br; |
||||
+ struct btrfs_ioctl_search_header *search_header; |
||||
+ char *old; |
||||
+ grub_uint16_t len; |
||||
+ grub_uint64_t inode_id; |
||||
+ |
||||
+ memset (&sargs, 0, sizeof(sargs)); |
||||
+ |
||||
+ sargs.key.tree_id = 1; |
||||
+ sargs.key.min_objectid = tree_id; |
||||
+ sargs.key.max_objectid = tree_id; |
||||
+ |
||||
+ sargs.key.min_offset = 0; |
||||
+ sargs.key.max_offset = ~0ULL; |
||||
+ sargs.key.min_transid = 0; |
||||
+ sargs.key.max_transid = ~0ULL; |
||||
+ sargs.key.min_type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF; |
||||
+ sargs.key.max_type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF; |
||||
+ |
||||
+ sargs.key.nr_items = 1; |
||||
+ |
||||
+ if (ioctl (fd, BTRFS_IOC_TREE_SEARCH, &sargs) < 0) |
||||
+ goto error; |
||||
+ |
||||
+ if (sargs.key.nr_items == 0) |
||||
+ goto error; |
||||
+ |
||||
+ search_header = (struct btrfs_ioctl_search_header *)sargs.buf; |
||||
+ br = (struct grub_btrfs_root_backref *) (search_header + 1); |
||||
+ |
||||
+ len = grub_le_to_cpu16 (br->n); |
||||
+ inode_id = grub_le_to_cpu64 (br->inode_id); |
||||
+ tree_id = search_header->offset; |
||||
+ |
||||
+ old = ret; |
||||
+ ret = malloc (len + 1); |
||||
+ memcpy (ret, br->name, len); |
||||
+ ret[len] = '\0'; |
||||
+ |
||||
+ if (inode_id != GRUB_BTRFS_TREE_ROOT_OBJECTID) |
||||
+ { |
||||
+ char *s; |
||||
+ |
||||
+ memset(&args, 0, sizeof(args)); |
||||
+ args.treeid = search_header->offset; |
||||
+ args.objectid = inode_id; |
||||
+ |
||||
+ if (ioctl (fd, BTRFS_IOC_INO_LOOKUP, &args) < 0) |
||||
+ goto error; |
||||
+ |
||||
+ s = xasprintf ("%s%s", args.name, ret); |
||||
+ free (ret); |
||||
+ ret = s; |
||||
+ } |
||||
+ |
||||
+ if (old) |
||||
+ { |
||||
+ char *s = xasprintf ("%s/%s", ret, old); |
||||
+ free (ret); |
||||
+ free (old); |
||||
+ ret = s; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ close (fd); |
||||
+ return ret; |
||||
+ |
||||
+error: |
||||
+ |
||||
+ if (fd >= 0) |
||||
+ close (fd); |
||||
+ if (ret) |
||||
+ free (ret); |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+void (*grub_find_root_btrfs_mount_path_hook)(const char *mount_path); |
||||
+ |
||||
char ** |
||||
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) |
||||
{ |
||||
@@ -519,12 +630,15 @@ again: |
||||
else if (grub_strcmp (entries[i].fstype, "btrfs") == 0) |
||||
{ |
||||
ret = grub_find_root_devices_from_btrfs (dir); |
||||
- fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); |
||||
if (use_relative_path_on_btrfs) |
||||
{ |
||||
- if (fs_prefix) |
||||
- free (fs_prefix); |
||||
fs_prefix = xstrdup ("/"); |
||||
+ if (grub_find_root_btrfs_mount_path_hook) |
||||
+ grub_find_root_btrfs_mount_path_hook (entries[i].enc_path); |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); |
||||
} |
||||
} |
||||
else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) |
||||
@@ -1150,6 +1264,34 @@ grub_util_get_grub_dev_os (const char *os_dev) |
||||
return grub_dev; |
||||
} |
||||
|
||||
+ |
||||
+char * |
||||
+grub_util_get_btrfs_subvol (const char *path, char **mount_path) |
||||
+{ |
||||
+ char *mp = NULL; |
||||
+ |
||||
+ if (mount_path) |
||||
+ *mount_path = NULL; |
||||
+ |
||||
+ auto void |
||||
+ mount_path_hook (const char *m) |
||||
+ { |
||||
+ mp = strdup (m); |
||||
+ } |
||||
+ |
||||
+ grub_find_root_btrfs_mount_path_hook = mount_path_hook; |
||||
+ grub_free (grub_find_root_devices_from_mountinfo (path, NULL)); |
||||
+ grub_find_root_btrfs_mount_path_hook = NULL; |
||||
+ |
||||
+ if (!mp) |
||||
+ return NULL; |
||||
+ |
||||
+ if (mount_path) |
||||
+ *mount_path = mp; |
||||
+ |
||||
+ return get_btrfs_subvol (mp); |
||||
+} |
||||
+ |
||||
char * |
||||
grub_make_system_path_relative_to_its_root_os (const char *path) |
||||
{ |
||||
diff --git a/util/grub-install.c b/util/grub-install.c |
||||
index 0f66f36d23..84ed6e88ec 100644 |
||||
--- a/util/grub-install.c |
||||
+++ b/util/grub-install.c |
||||
@@ -1569,6 +1569,55 @@ main (int argc, char *argv[]) |
||||
prefix_drive = xasprintf ("(%s)", grub_drives[0]); |
||||
} |
||||
|
||||
+#ifdef __linux__ |
||||
+ |
||||
+ if (config.is_suse_btrfs_snapshot_enabled |
||||
+ && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0) |
||||
+ { |
||||
+ char *subvol = NULL; |
||||
+ char *mount_path = NULL; |
||||
+ char **rootdir_devices = NULL; |
||||
+ char *rootdir_path = grub_util_path_concat (2, "/", rootdir); |
||||
+ |
||||
+ if (grub_util_is_directory (rootdir_path)) |
||||
+ rootdir_devices = grub_guess_root_devices (rootdir_path); |
||||
+ |
||||
+ free (rootdir_path); |
||||
+ |
||||
+ if (rootdir_devices && rootdir_devices[0]) |
||||
+ if (grub_strcmp (rootdir_devices[0], grub_devices[0]) == 0) |
||||
+ subvol = grub_util_get_btrfs_subvol (platdir, &mount_path); |
||||
+ |
||||
+ if (subvol && mount_path) |
||||
+ { |
||||
+ char *def_subvol; |
||||
+ |
||||
+ def_subvol = grub_util_get_btrfs_subvol ("/", NULL); |
||||
+ |
||||
+ if (def_subvol) |
||||
+ { |
||||
+ if (!load_cfg_f) |
||||
+ load_cfg_f = grub_util_fopen (load_cfg, "wb"); |
||||
+ have_load_cfg = 1; |
||||
+ |
||||
+ if (grub_strcmp (subvol, def_subvol) != 0) |
||||
+ fprintf (load_cfg_f, "btrfs-mount-subvol ($root) %s %s\n", mount_path, subvol); |
||||
+ free (def_subvol); |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ for (curdev = rootdir_devices; *curdev; curdev++) |
||||
+ free (*curdev); |
||||
+ if (rootdir_devices) |
||||
+ free (rootdir_devices); |
||||
+ if (subvol) |
||||
+ free (subvol); |
||||
+ if (mount_path) |
||||
+ free (mount_path); |
||||
+ } |
||||
+ |
||||
+#endif |
||||
+ |
||||
char mkimage_target[200]; |
||||
const char *core_name = NULL; |
||||
|
||||
diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h |
||||
index 73fa2d34ab..9c642ae3fe 100644 |
||||
--- a/include/grub/emu/getroot.h |
||||
+++ b/include/grub/emu/getroot.h |
||||
@@ -53,6 +53,11 @@ char ** |
||||
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot); |
||||
#endif |
||||
|
||||
+#ifdef __linux__ |
||||
+char * |
||||
+grub_util_get_btrfs_subvol (const char *path, char **mount_path); |
||||
+#endif |
||||
+ |
||||
/* Devmapper functions provided by getroot_devmapper.c. */ |
||||
void |
||||
grub_util_pull_devmapper (const char *os_dev); |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Andrei Borzenkov <arvidjaar@gmail.com> |
||||
Date: Tue, 21 Jun 2016 16:44:17 +0000 |
||||
Subject: [PATCH] Fallback to old subvol name scheme to support old snapshot |
||||
config |
||||
|
||||
Ref: bsc#953538 |
||||
--- |
||||
grub-core/fs/btrfs.c | 32 +++++++++++++++++++++++++++++++- |
||||
1 file changed, 31 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index d323746ecf..673ded0352 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -1260,11 +1260,41 @@ lookup_root_by_name(struct grub_btrfs_data *data, const char *path) |
||||
return GRUB_ERR_NONE; |
||||
} |
||||
|
||||
+static grub_err_t |
||||
+lookup_root_by_name_fallback(struct grub_btrfs_data *data, const char *path) |
||||
+{ |
||||
+ grub_err_t err; |
||||
+ grub_uint64_t tree = 0; |
||||
+ grub_uint8_t type; |
||||
+ struct grub_btrfs_key key; |
||||
+ |
||||
+ err = find_path (data, path, &key, &tree, &type); |
||||
+ if (err) |
||||
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); |
||||
+ |
||||
+ if (key.object_id != grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK) || tree == 0) |
||||
+ return grub_error(GRUB_ERR_BAD_FILE_TYPE, "%s: not a subvolume\n", path); |
||||
+ |
||||
+ data->fs_tree = tree; |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
static grub_err_t |
||||
btrfs_handle_subvol(struct grub_btrfs_data *data __attribute__ ((unused))) |
||||
{ |
||||
if (btrfs_default_subvol) |
||||
- return lookup_root_by_name(data, btrfs_default_subvol); |
||||
+ { |
||||
+ grub_err_t err; |
||||
+ err = lookup_root_by_name(data, btrfs_default_subvol); |
||||
+ |
||||
+ /* Fallback to old schemes */ |
||||
+ if (err == GRUB_ERR_FILE_NOT_FOUND) |
||||
+ { |
||||
+ err = GRUB_ERR_NONE; |
||||
+ return lookup_root_by_name_fallback(data, btrfs_default_subvol); |
||||
+ } |
||||
+ return err; |
||||
+ } |
||||
|
||||
if (btrfs_default_subvolid) |
||||
return lookup_root_by_id(data, btrfs_default_subvolid); |
@ -0,0 +1,274 @@
@@ -0,0 +1,274 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Thu, 11 May 2017 08:56:57 +0000 |
||||
Subject: [PATCH] Grub not working correctly with btrfs snapshots (bsc#1026511) |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/fs/btrfs.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
||||
1 file changed, 238 insertions(+) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index 673ded0352..2b21cbaa67 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -2887,6 +2887,238 @@ out: |
||||
return 0; |
||||
} |
||||
|
||||
+static grub_err_t |
||||
+grub_btrfs_get_parent_subvol_path (struct grub_btrfs_data *data, |
||||
+ grub_uint64_t child_id, |
||||
+ const char *child_path, |
||||
+ grub_uint64_t *parent_id, |
||||
+ char **path_out) |
||||
+{ |
||||
+ grub_uint64_t fs_root = 0; |
||||
+ struct grub_btrfs_key key_in = { |
||||
+ .object_id = child_id, |
||||
+ .type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF, |
||||
+ .offset = 0, |
||||
+ }, key_out; |
||||
+ struct grub_btrfs_root_ref *ref; |
||||
+ char *buf; |
||||
+ struct grub_btrfs_leaf_descriptor desc; |
||||
+ grub_size_t elemsize; |
||||
+ grub_disk_addr_t elemaddr; |
||||
+ grub_err_t err; |
||||
+ char *parent_path; |
||||
+ |
||||
+ *parent_id = 0; |
||||
+ *path_out = 0; |
||||
+ |
||||
+ err = lower_bound(data, &key_in, &key_out, data->sblock.root_tree, |
||||
+ &elemaddr, &elemsize, &desc, 0); |
||||
+ if (err) |
||||
+ return err; |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF || elemaddr == 0) |
||||
+ next(data, &desc, &elemaddr, &elemsize, &key_out); |
||||
+ |
||||
+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF) |
||||
+ { |
||||
+ free_iterator(&desc); |
||||
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root backrefs")); |
||||
+ } |
||||
+ |
||||
+ buf = grub_malloc(elemsize + 1); |
||||
+ if (!buf) |
||||
+ { |
||||
+ free_iterator(&desc); |
||||
+ return grub_errno; |
||||
+ } |
||||
+ |
||||
+ err = grub_btrfs_read_logical(data, elemaddr, buf, elemsize, 0); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free(buf); |
||||
+ free_iterator(&desc); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ buf[elemsize] = 0; |
||||
+ ref = (struct grub_btrfs_root_ref *)buf; |
||||
+ |
||||
+ err = get_fs_root(data, data->sblock.root_tree, grub_le_to_cpu64 (key_out.offset), |
||||
+ 0, &fs_root); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free(buf); |
||||
+ free_iterator(&desc); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ find_pathname(data, grub_le_to_cpu64 (ref->dirid), fs_root, ref->name, &parent_path); |
||||
+ |
||||
+ if (child_path) |
||||
+ { |
||||
+ *path_out = grub_xasprintf ("%s/%s", parent_path, child_path); |
||||
+ grub_free (parent_path); |
||||
+ } |
||||
+ else |
||||
+ *path_out = parent_path; |
||||
+ |
||||
+ *parent_id = grub_le_to_cpu64 (key_out.offset); |
||||
+ |
||||
+ grub_free(buf); |
||||
+ free_iterator(&desc); |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+grub_btrfs_get_default_subvolume_id (struct grub_btrfs_data *data, grub_uint64_t *id) |
||||
+{ |
||||
+ grub_err_t err; |
||||
+ grub_disk_addr_t elemaddr; |
||||
+ grub_size_t elemsize; |
||||
+ struct grub_btrfs_key key, key_out; |
||||
+ struct grub_btrfs_dir_item *direl = NULL; |
||||
+ const char *ctoken = "default"; |
||||
+ grub_size_t ctokenlen = sizeof ("default") - 1; |
||||
+ |
||||
+ *id = 0; |
||||
+ key.object_id = data->sblock.root_dir_objectid; |
||||
+ key.type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; |
||||
+ key.offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); |
||||
+ err = lower_bound (data, &key, &key_out, data->sblock.root_tree, &elemaddr, &elemsize, |
||||
+ NULL, 0); |
||||
+ if (err) |
||||
+ return err; |
||||
+ |
||||
+ if (key_cmp (&key, &key_out) != 0) |
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); |
||||
+ |
||||
+ struct grub_btrfs_dir_item *cdirel; |
||||
+ direl = grub_malloc (elemsize + 1); |
||||
+ err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (direl); |
||||
+ return err; |
||||
+ } |
||||
+ for (cdirel = direl; |
||||
+ (grub_uint8_t *) cdirel - (grub_uint8_t *) direl |
||||
+ < (grub_ssize_t) elemsize; |
||||
+ cdirel = (void *) ((grub_uint8_t *) (direl + 1) |
||||
+ + grub_le_to_cpu16 (cdirel->n) |
||||
+ + grub_le_to_cpu16 (cdirel->m))) |
||||
+ { |
||||
+ if (ctokenlen == grub_le_to_cpu16 (cdirel->n) |
||||
+ && grub_memcmp (cdirel->name, ctoken, ctokenlen) == 0) |
||||
+ break; |
||||
+ } |
||||
+ if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl |
||||
+ >= (grub_ssize_t) elemsize) |
||||
+ { |
||||
+ grub_free (direl); |
||||
+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ if (cdirel->key.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM) |
||||
+ { |
||||
+ grub_free (direl); |
||||
+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ *id = grub_le_to_cpu64 (cdirel->key.object_id); |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt, |
||||
+ int argc, char **argv) |
||||
+{ |
||||
+ char *devname; |
||||
+ grub_device_t dev; |
||||
+ struct grub_btrfs_data *data; |
||||
+ grub_err_t err; |
||||
+ grub_uint64_t id; |
||||
+ char *subvol = NULL; |
||||
+ grub_uint64_t subvolid = 0; |
||||
+ char *varname = NULL; |
||||
+ char *output = NULL; |
||||
+ int path_only = ctxt->state[1].set; |
||||
+ int num_only = ctxt->state[2].set; |
||||
+ |
||||
+ if (ctxt->state[0].set) |
||||
+ varname = ctxt->state[0].arg; |
||||
+ |
||||
+ if (argc < 1) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); |
||||
+ |
||||
+ devname = grub_file_get_device_name(argv[0]); |
||||
+ if (!devname) |
||||
+ return grub_errno; |
||||
+ |
||||
+ dev = grub_device_open (devname); |
||||
+ grub_free (devname); |
||||
+ if (!dev) |
||||
+ return grub_errno; |
||||
+ |
||||
+ data = grub_btrfs_mount(dev); |
||||
+ if (!data) |
||||
+ { |
||||
+ grub_device_close (dev); |
||||
+ grub_dprintf ("btrfs", "failed to open fs\n"); |
||||
+ grub_errno = GRUB_ERR_NONE; |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
+ err = grub_btrfs_get_default_subvolume_id (data, &subvolid); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_btrfs_unmount (data); |
||||
+ grub_device_close (dev); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ id = subvolid; |
||||
+ while (id != GRUB_BTRFS_ROOT_VOL_OBJECTID) |
||||
+ { |
||||
+ grub_uint64_t parent_id; |
||||
+ char *path_out; |
||||
+ |
||||
+ err = grub_btrfs_get_parent_subvol_path (data, grub_cpu_to_le64 (id), subvol, &parent_id, &path_out); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_btrfs_unmount (data); |
||||
+ grub_device_close (dev); |
||||
+ return err; |
||||
+ } |
||||
+ |
||||
+ if (subvol) |
||||
+ grub_free (subvol); |
||||
+ subvol = path_out; |
||||
+ id = parent_id; |
||||
+ } |
||||
+ |
||||
+ if (num_only && path_only) |
||||
+ output = grub_xasprintf ("%"PRIuGRUB_UINT64_T" /%s", subvolid, subvol); |
||||
+ else if (num_only) |
||||
+ output = grub_xasprintf ("%"PRIuGRUB_UINT64_T, subvolid); |
||||
+ else |
||||
+ output = grub_xasprintf ("/%s", subvol); |
||||
+ |
||||
+ if (varname) |
||||
+ grub_env_set(varname, output); |
||||
+ else |
||||
+ grub_printf ("%s\n", output); |
||||
+ |
||||
+ grub_free (output); |
||||
+ grub_free (subvol); |
||||
+ |
||||
+ grub_btrfs_unmount (data); |
||||
+ grub_device_close (dev); |
||||
+ |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
static struct grub_fs grub_btrfs_fs = { |
||||
.name = "btrfs", |
||||
.fs_dir = grub_btrfs_dir, |
||||
@@ -2905,6 +3137,7 @@ static struct grub_fs grub_btrfs_fs = { |
||||
static grub_command_t cmd_info; |
||||
static grub_command_t cmd_mount_subvol; |
||||
static grub_extcmd_t cmd_list_subvols; |
||||
+static grub_extcmd_t cmd_get_default_subvol; |
||||
|
||||
static char * |
||||
subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)), |
||||
@@ -2975,6 +3208,11 @@ GRUB_MOD_INIT (btrfs) |
||||
"[-p|-n] [-o var] DEVICE", |
||||
"Print list of BtrFS subvolumes on " |
||||
"DEVICE.", options); |
||||
+ cmd_get_default_subvol = grub_register_extcmd("btrfs-get-default-subvol", |
||||
+ grub_cmd_btrfs_get_default_subvol, 0, |
||||
+ "[-p|-n] [-o var] DEVICE", |
||||
+ "Print default BtrFS subvolume on " |
||||
+ "DEVICE.", options); |
||||
grub_register_variable_hook ("btrfs_subvol", subvol_get_env, |
||||
subvol_set_env); |
||||
grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, |
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 1 Jun 2017 09:59:56 -0400 |
||||
Subject: [PATCH] Add grub_efi_allocate_pool() and grub_efi_free_pool() |
||||
wrappers. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
include/grub/efi/efi.h | 36 ++++++++++++++++++++++++++++++++---- |
||||
1 file changed, 32 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
||||
index 585fa6662b..03f9a9d011 100644 |
||||
--- a/include/grub/efi/efi.h |
||||
+++ b/include/grub/efi/efi.h |
||||
@@ -24,6 +24,10 @@ |
||||
#include <grub/dl.h> |
||||
#include <grub/efi/api.h> |
||||
|
||||
+/* Variables. */ |
||||
+extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); |
||||
+extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); |
||||
+ |
||||
/* Functions. */ |
||||
void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol, |
||||
void *registration); |
||||
@@ -60,6 +64,33 @@ EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, |
||||
grub_efi_uintn_t *descriptor_size, |
||||
grub_efi_uint32_t *descriptor_version); |
||||
void grub_efi_memory_fini (void); |
||||
+ |
||||
+static inline grub_efi_status_t |
||||
+__attribute__((__unused__)) |
||||
+grub_efi_allocate_pool (grub_efi_memory_type_t pool_type, |
||||
+ grub_efi_uintn_t buffer_size, |
||||
+ void **buffer) |
||||
+{ |
||||
+ grub_efi_boot_services_t *b; |
||||
+ grub_efi_status_t status; |
||||
+ |
||||
+ b = grub_efi_system_table->boot_services; |
||||
+ status = efi_call_3 (b->allocate_pool, pool_type, buffer_size, buffer); |
||||
+ return status; |
||||
+} |
||||
+ |
||||
+static inline grub_efi_status_t |
||||
+__attribute__((__unused__)) |
||||
+grub_efi_free_pool (void *buffer) |
||||
+{ |
||||
+ grub_efi_boot_services_t *b; |
||||
+ grub_efi_status_t status; |
||||
+ |
||||
+ b = grub_efi_system_table->boot_services; |
||||
+ status = efi_call_1 (b->free_pool, buffer); |
||||
+ return status; |
||||
+} |
||||
+ |
||||
grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); |
||||
void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); |
||||
char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); |
||||
@@ -115,10 +146,7 @@ void grub_efi_init (void); |
||||
void grub_efi_fini (void); |
||||
void grub_efi_set_prefix (void); |
||||
|
||||
-/* Variables. */ |
||||
-extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); |
||||
-extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); |
||||
- |
||||
+/* More variables. */ |
||||
extern int EXPORT_VAR(grub_efi_is_finished); |
||||
|
||||
struct grub_net_card; |
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 1 Jun 2017 10:06:38 -0400 |
||||
Subject: [PATCH] Use grub_efi_...() memory helpers where reasonable. |
||||
|
||||
This uses grub_efi_allocate_pool(), grub_efi_free_pool(), and |
||||
grub_efi_free_pages() instead of open-coded efi_call_N() calls, so we |
||||
get more reasonable type checking. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/loader/efi/chainloader.c | 24 +++++++++--------------- |
||||
1 file changed, 9 insertions(+), 15 deletions(-) |
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c |
||||
index 07c4937898..89ac84cc66 100644 |
||||
--- a/grub-core/loader/efi/chainloader.c |
||||
+++ b/grub-core/loader/efi/chainloader.c |
||||
@@ -65,7 +65,7 @@ grub_chainloader_unload (void) |
||||
|
||||
b = grub_efi_system_table->boot_services; |
||||
efi_call_1 (b->unload_image, image_handle); |
||||
- efi_call_2 (b->free_pages, address, pages); |
||||
+ grub_efi_free_pages (address, pages); |
||||
|
||||
grub_free (file_path); |
||||
grub_free (cmdline); |
||||
@@ -108,7 +108,7 @@ grub_chainloader_boot (void) |
||||
} |
||||
|
||||
if (exit_data) |
||||
- efi_call_1 (b->free_pool, exit_data); |
||||
+ grub_efi_free_pool (exit_data); |
||||
|
||||
grub_loader_unset (); |
||||
|
||||
@@ -527,10 +527,9 @@ grub_efi_get_media_file_path (grub_efi_device_path_t *dp) |
||||
static grub_efi_boolean_t |
||||
handle_image (void *data, grub_efi_uint32_t datasize) |
||||
{ |
||||
- grub_efi_boot_services_t *b; |
||||
grub_efi_loaded_image_t *li, li_bak; |
||||
grub_efi_status_t efi_status; |
||||
- char *buffer = NULL; |
||||
+ void *buffer = NULL; |
||||
char *buffer_aligned = NULL; |
||||
grub_efi_uint32_t i; |
||||
struct grub_pe32_section_table *section; |
||||
@@ -541,8 +540,6 @@ handle_image (void *data, grub_efi_uint32_t datasize) |
||||
int found_entry_point = 0; |
||||
int rc; |
||||
|
||||
- b = grub_efi_system_table->boot_services; |
||||
- |
||||
rc = read_header (data, datasize, &context); |
||||
if (rc < 0) |
||||
{ |
||||
@@ -582,8 +579,8 @@ handle_image (void *data, grub_efi_uint32_t datasize) |
||||
grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n", |
||||
context.image_size, datasize); |
||||
|
||||
- efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, |
||||
- buffer_size, &buffer); |
||||
+ efi_status = grub_efi_allocate_pool (GRUB_EFI_LOADER_DATA, buffer_size, |
||||
+ &buffer); |
||||
|
||||
if (efi_status != GRUB_EFI_SUCCESS) |
||||
{ |
||||
@@ -815,14 +812,14 @@ handle_image (void *data, grub_efi_uint32_t datasize) |
||||
|
||||
grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); |
||||
grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); |
||||
- efi_status = efi_call_1 (b->free_pool, buffer); |
||||
+ efi_status = grub_efi_free_pool (buffer); |
||||
|
||||
return 1; |
||||
|
||||
error_exit: |
||||
grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno); |
||||
if (buffer) |
||||
- efi_call_1 (b->free_pool, buffer); |
||||
+ grub_efi_free_pool (buffer); |
||||
|
||||
return 0; |
||||
} |
||||
@@ -830,10 +827,7 @@ error_exit: |
||||
static grub_err_t |
||||
grub_secureboot_chainloader_unload (void) |
||||
{ |
||||
- grub_efi_boot_services_t *b; |
||||
- |
||||
- b = grub_efi_system_table->boot_services; |
||||
- efi_call_2 (b->free_pages, address, pages); |
||||
+ grub_efi_free_pages (address, pages); |
||||
grub_free (file_path); |
||||
grub_free (cmdline); |
||||
cmdline = 0; |
||||
@@ -1100,7 +1094,7 @@ fail: |
||||
grub_free (file_path); |
||||
|
||||
if (address) |
||||
- efi_call_2 (b->free_pages, address, pages); |
||||
+ grub_efi_free_pages (address, pages); |
||||
|
||||
if (cmdline) |
||||
grub_free (cmdline); |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 1 Jun 2017 10:07:50 -0400 |
||||
Subject: [PATCH] Add PRIxGRUB_EFI_STATUS and use it. |
||||
|
||||
This avoids syntax checkers getting confused about if it's llx or lx. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/loader/efi/chainloader.c | 3 ++- |
||||
include/grub/efi/api.h | 9 +++++++++ |
||||
2 files changed, 11 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c |
||||
index 89ac84cc66..ac8dfd40c6 100644 |
||||
--- a/grub-core/loader/efi/chainloader.c |
||||
+++ b/grub-core/loader/efi/chainloader.c |
||||
@@ -810,7 +810,8 @@ handle_image (void *data, grub_efi_uint32_t datasize) |
||||
efi_status = efi_call_2 (entry_point, grub_efi_image_handle, |
||||
grub_efi_system_table); |
||||
|
||||
- grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); |
||||
+ grub_dprintf ("chain", "entry_point returned 0x%"PRIxGRUB_EFI_STATUS"\n", |
||||
+ efi_status); |
||||
grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); |
||||
efi_status = grub_efi_free_pool (buffer); |
||||
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h |
||||
index 117469450d..9962880147 100644 |
||||
--- a/include/grub/efi/api.h |
||||
+++ b/include/grub/efi/api.h |
||||
@@ -546,7 +546,16 @@ typedef grub_uint64_t grub_efi_uint64_t; |
||||
typedef grub_uint8_t grub_efi_char8_t; |
||||
typedef grub_uint16_t grub_efi_char16_t; |
||||
|
||||
+ |
||||
typedef grub_efi_uintn_t grub_efi_status_t; |
||||
+/* Make grub_efi_status_t reasonably printable. */ |
||||
+#if GRUB_CPU_SIZEOF_VOID_P == 8 |
||||
+#define PRIxGRUB_EFI_STATUS "lx" |
||||
+#define PRIdGRUB_EFI_STATUS "ld" |
||||
+#else |
||||
+#define PRIxGRUB_EFI_STATUS "llx" |
||||
+#define PRIdGRUB_EFI_STATUS "lld" |
||||
+#endif |
||||
|
||||
#define GRUB_EFI_ERROR_CODE(value) \ |
||||
((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 26 Jun 2017 12:44:59 -0400 |
||||
Subject: [PATCH] don't use int for efi status |
||||
|
||||
--- |
||||
grub-core/kern/efi/efi.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c |
||||
index 05d8237a9b..ae9885edb8 100644 |
||||
--- a/grub-core/kern/efi/efi.c |
||||
+++ b/grub-core/kern/efi/efi.c |
||||
@@ -167,7 +167,7 @@ grub_reboot (void) |
||||
void |
||||
grub_exit (int retval) |
||||
{ |
||||
- int rc = GRUB_EFI_LOAD_ERROR; |
||||
+ grub_efi_status_t rc = GRUB_EFI_LOAD_ERROR; |
||||
|
||||
if (retval == 0) |
||||
rc = GRUB_EFI_SUCCESS; |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 26 Jun 2017 12:46:23 -0400 |
||||
Subject: [PATCH] make GRUB_MOD_INIT() declare its function prototypes. |
||||
|
||||
--- |
||||
include/grub/dl.h | 2 ++ |
||||
1 file changed, 2 insertions(+) |
||||
|
||||
diff --git a/include/grub/dl.h b/include/grub/dl.h |
||||
index b3753c9ca2..91933b85f2 100644 |
||||
--- a/include/grub/dl.h |
||||
+++ b/include/grub/dl.h |
||||
@@ -54,6 +54,7 @@ grub_mod_fini (void) |
||||
|
||||
#define GRUB_MOD_INIT(name) \ |
||||
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ |
||||
+extern void grub_##name##_init (void); \ |
||||
void \ |
||||
grub_##name##_init (void) { grub_mod_init (0); } \ |
||||
static void \ |
||||
@@ -61,6 +62,7 @@ grub_mod_init (grub_dl_t mod __attribute__ ((unused))) |
||||
|
||||
#define GRUB_MOD_FINI(name) \ |
||||
static void grub_mod_fini (void) __attribute__ ((used)); \ |
||||
+extern void grub_##name##_fini (void); \ |
||||
void \ |
||||
grub_##name##_fini (void) { grub_mod_fini (); } \ |
||||
static void \ |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 20 Apr 2017 13:29:06 -0400 |
||||
Subject: [PATCH] Don't guess /boot/efi/ as HFS+ on ppc machines in |
||||
grub-install |
||||
|
||||
This should never be trying this, and since we've consolidated the |
||||
grubenv to always be on /boot/efi/EFI/fedora/, this code causes it to |
||||
always make the wrong decision. |
||||
|
||||
Resolves: rhbz#1484474 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub-install.c | 12 +----------- |
||||
1 file changed, 1 insertion(+), 11 deletions(-) |
||||
|
||||
diff --git a/util/grub-install.c b/util/grub-install.c |
||||
index 84ed6e88ec..a2bec7446c 100644 |
||||
--- a/util/grub-install.c |
||||
+++ b/util/grub-install.c |
||||
@@ -1190,18 +1190,8 @@ main (int argc, char *argv[]) |
||||
char *d; |
||||
|
||||
is_guess = 1; |
||||
- d = grub_util_path_concat (2, bootdir, "macppc"); |
||||
- if (!grub_util_is_directory (d)) |
||||
- { |
||||
- free (d); |
||||
- d = grub_util_path_concat (2, bootdir, "efi"); |
||||
- } |
||||
/* Find the Mac HFS(+) System Partition. */ |
||||
- if (!grub_util_is_directory (d)) |
||||
- { |
||||
- free (d); |
||||
- d = grub_util_path_concat (2, bootdir, "EFI"); |
||||
- } |
||||
+ d = grub_util_path_concat (2, bootdir, "macppc"); |
||||
if (!grub_util_is_directory (d)) |
||||
{ |
||||
free (d); |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 9 Jul 2019 14:31:19 +0200 |
||||
Subject: [PATCH] 20_linux_xen: load xen or multiboot{,2} modules as needed. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub.d/20_linux_xen.in | 5 +++++ |
||||
1 file changed, 5 insertions(+) |
||||
|
||||
diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in |
||||
index e9e73b815f..c23b064be6 100644 |
||||
--- a/util/grub.d/20_linux_xen.in |
||||
+++ b/util/grub.d/20_linux_xen.in |
||||
@@ -153,6 +153,7 @@ linux_entry_xsm () |
||||
else |
||||
xen_rm_opts="no-real-mode edd=off" |
||||
fi |
||||
+ insmod ${xen_module} |
||||
${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} |
||||
echo '$(echo "$lmessage" | grub_quote)' |
||||
${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} |
||||
@@ -166,6 +167,7 @@ EOF |
||||
done |
||||
sed "s/^/$submenu_indentation/" << EOF |
||||
echo '$(echo "$message" | grub_quote)' |
||||
+ insmod ${xen_module} |
||||
${module_loader} --nounzip $(echo $initrd_path) |
||||
EOF |
||||
fi |
||||
@@ -253,13 +255,16 @@ while [ "x${xen_list}" != "x" ] ; do |
||||
echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {" |
||||
fi |
||||
if ($grub_file --is-arm64-efi $current_xen); then |
||||
+ xen_module="xen_boot" |
||||
xen_loader="xen_hypervisor" |
||||
module_loader="xen_module" |
||||
else |
||||
if ($grub_file --is-x86-multiboot2 $current_xen); then |
||||
+ xen_module="multiboot2" |
||||
xen_loader="multiboot2" |
||||
module_loader="module2" |
||||
else |
||||
+ xen_module="multiboot" |
||||
xen_loader="multiboot" |
||||
module_loader="module" |
||||
fi |
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 7 Nov 2017 17:12:17 -0500 |
||||
Subject: [PATCH] Make pmtimer tsc calibration not take 51 seconds to fail. |
||||
|
||||
On my laptop running at 2.4GHz, if I run a VM where tsc calibration |
||||
using pmtimer will fail presuming a broken pmtimer, it takes ~51 seconds |
||||
to do so (as measured with the stopwatch on my phone), with a tsc delta |
||||
of 0x1cd1c85300, or around 125 billion cycles. |
||||
|
||||
If instead of trying to wait for 5-200ms to show up on the pmtimer, we try |
||||
to wait for 5-200us, it decides it's broken in ~0x2626aa0 TSCs, aka ~2.4 |
||||
million cycles, or more or less instantly. |
||||
|
||||
Additionally, this reading the pmtimer was returning 0xffffffff anyway, |
||||
and that's obviously an invalid return. I've added a check for that and |
||||
0 so we don't bother waiting for the test if what we're seeing is dead |
||||
pins with no response at all. |
||||
|
||||
If "debug" is includes "pmtimer", you will see one of the following |
||||
three outcomes. If pmtimer gives all 0 or all 1 bits, you will see: |
||||
|
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 1 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 2 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 3 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 4 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 5 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 6 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 7 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 8 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 9 |
||||
kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 10 |
||||
kern/i386/tsc_pmtimer.c:78: timer is broken; giving up. |
||||
|
||||
This outcome was tested using qemu+kvm with UEFI (OVMF) firmware and |
||||
these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX |
||||
|
||||
If pmtimer gives any other bit patterns but is not actually marching |
||||
forward fast enough to use for clock calibration, you will see: |
||||
|
||||
kern/i386/tsc_pmtimer.c:121: pmtimer delta is 0x0 (1904 iterations) |
||||
kern/i386/tsc_pmtimer.c:124: tsc delta is implausible: 0x2626aa0 |
||||
|
||||
This outcome was tested using grub compiled with GRUB_PMTIMER_IGNORE_BAD_READS |
||||
defined (so as not to trip the bad read test) using qemu+kvm with UEFI |
||||
(OVMF) firmware, and these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX |
||||
|
||||
If pmtimer actually works, you'll see something like: |
||||
|
||||
kern/i386/tsc_pmtimer.c:121: pmtimer delta is 0x0 (1904 iterations) |
||||
kern/i386/tsc_pmtimer.c:124: tsc delta is implausible: 0x2626aa0 |
||||
|
||||
This outcome was tested using qemu+kvm with UEFI (OVMF) firmware, and |
||||
these options: -machine pc-i440fx-2.4 -cpu Broadwell-noTSX |
||||
|
||||
I've also tested this outcome on a real Intel Xeon E3-1275v3 on an Intel |
||||
Server Board S1200V3RPS using the SDV.RP.B8 "Release" build here: |
||||
https://firmware.intel.com/sites/default/files/UEFIDevKit_S1200RP_vB8.zip |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/i386/tsc_pmtimer.c | 109 +++++++++++++++++++++++++++++++------- |
||||
1 file changed, 89 insertions(+), 20 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c |
||||
index c9c3616997..ca15c3aacd 100644 |
||||
--- a/grub-core/kern/i386/tsc_pmtimer.c |
||||
+++ b/grub-core/kern/i386/tsc_pmtimer.c |
||||
@@ -28,40 +28,101 @@ |
||||
#include <grub/acpi.h> |
||||
#include <grub/cpu/io.h> |
||||
|
||||
+/* |
||||
+ * Define GRUB_PMTIMER_IGNORE_BAD_READS if you're trying to test a timer that's |
||||
+ * present but doesn't keep time well. |
||||
+ */ |
||||
+// #define GRUB_PMTIMER_IGNORE_BAD_READS |
||||
+ |
||||
grub_uint64_t |
||||
grub_pmtimer_wait_count_tsc (grub_port_t pmtimer, |
||||
grub_uint16_t num_pm_ticks) |
||||
{ |
||||
grub_uint32_t start; |
||||
- grub_uint32_t last; |
||||
- grub_uint32_t cur, end; |
||||
+ grub_uint64_t cur, end; |
||||
grub_uint64_t start_tsc; |
||||
grub_uint64_t end_tsc; |
||||
- int num_iter = 0; |
||||
+ unsigned int num_iter = 0; |
||||
+#ifndef GRUB_PMTIMER_IGNORE_BAD_READS |
||||
+ int bad_reads = 0; |
||||
+#endif |
||||
|
||||
- start = grub_inl (pmtimer) & 0xffffff; |
||||
- last = start; |
||||
+ /* |
||||
+ * Some timers are 24-bit and some are 32-bit, but it doesn't make much |
||||
+ * difference to us. Caring which one we have isn't really worth it since |
||||
+ * the low-order digits will give us enough data to calibrate TSC. So just |
||||
+ * mask the top-order byte off. |
||||
+ */ |
||||
+ cur = start = grub_inl (pmtimer) & 0xffffffUL; |
||||
end = start + num_pm_ticks; |
||||
start_tsc = grub_get_tsc (); |
||||
while (1) |
||||
{ |
||||
- cur = grub_inl (pmtimer) & 0xffffff; |
||||
- if (cur < last) |
||||
- cur |= 0x1000000; |
||||
- num_iter++; |
||||
+ cur &= 0xffffffffff000000ULL; |
||||
+ cur |= grub_inl (pmtimer) & 0xffffffUL; |
||||
+ |
||||
+ end_tsc = grub_get_tsc(); |
||||
+ |
||||
+#ifndef GRUB_PMTIMER_IGNORE_BAD_READS |
||||
+ /* |
||||
+ * If we get 10 reads in a row that are obviously dead pins, there's no |
||||
+ * reason to do this thousands of times. |
||||
+ */ |
||||
+ if (cur == 0xffffffUL || cur == 0) |
||||
+ { |
||||
+ bad_reads++; |
||||
+ grub_dprintf ("pmtimer", |
||||
+ "pmtimer: 0x%"PRIxGRUB_UINT64_T" bad_reads: %d\n", |
||||
+ cur, bad_reads); |
||||
+ grub_dprintf ("pmtimer", "timer is broken; giving up.\n"); |
||||
+ |
||||
+ if (bad_reads == 10) |
||||
+ return 0; |
||||
+ } |
||||
+#endif |
||||
+ |
||||
+ if (cur < start) |
||||
+ cur += 0x1000000; |
||||
+ |
||||
if (cur >= end) |
||||
{ |
||||
- end_tsc = grub_get_tsc (); |
||||
+ grub_dprintf ("pmtimer", "pmtimer delta is 0x%"PRIxGRUB_UINT64_T"\n", |
||||
+ cur - start); |
||||
+ grub_dprintf ("pmtimer", "tsc delta is 0x%"PRIxGRUB_UINT64_T"\n", |
||||
+ end_tsc - start_tsc); |
||||
return end_tsc - start_tsc; |
||||
} |
||||
- /* Check for broken PM timer. |
||||
- 50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz) |
||||
- if after this time we still don't have 1 ms on pmtimer, then |
||||
- pmtimer is broken. |
||||
+ |
||||
+ /* |
||||
+ * Check for broken PM timer. 1ms at 10GHz should be 1E+7 TSCs; at |
||||
+ * 250MHz it should be 2.5E6. So if after 4E+7 TSCs on a 10GHz machine, |
||||
+ * we should have seen pmtimer show 4ms of change (i.e. cur =~ |
||||
+ * start+14320); on a 250MHz machine that should be 16ms (start+57280). |
||||
+ * If after this a time we still don't have 1ms on pmtimer, then pmtimer |
||||
+ * is broken. |
||||
+ * |
||||
+ * Likewise, if our code is perfectly efficient and introduces no delays |
||||
+ * whatsoever, on a 10GHz system we should see a TSC delta of 3580 in |
||||
+ * ~3580 iterations. On a 250MHz machine that should be ~900 iterations. |
||||
+ * |
||||
+ * With those factors in mind, there are two limits here. There's a hard |
||||
+ * limit here at 8x our desired pm timer delta, picked as an arbitrarily |
||||
+ * large value that's still not a lot of time to humans, because if we |
||||
+ * get that far this is either an implausibly fast machine or the pmtimer |
||||
+ * is not running. And there's another limit on 4x our 10GHz tsc delta |
||||
+ * without seeing cur converge on our target value. |
||||
*/ |
||||
- if ((num_iter & 0xffffff) == 0 && grub_get_tsc () - start_tsc > 5000000) { |
||||
- return 0; |
||||
- } |
||||
+ if ((++num_iter > (grub_uint32_t)num_pm_ticks << 3UL) || |
||||
+ end_tsc - start_tsc > 40000000) |
||||
+ { |
||||
+ grub_dprintf ("pmtimer", |
||||
+ "pmtimer delta is 0x%"PRIxGRUB_UINT64_T" (%u iterations)\n", |
||||
+ cur - start, num_iter); |
||||
+ grub_dprintf ("pmtimer", |
||||
+ "tsc delta is implausible: 0x%"PRIxGRUB_UINT64_T"\n", |
||||
+ end_tsc - start_tsc); |
||||
+ return 0; |
||||
+ } |
||||
} |
||||
} |
||||
|
||||
@@ -74,12 +135,20 @@ grub_tsc_calibrate_from_pmtimer (void) |
||||
|
||||
fadt = grub_acpi_find_fadt (); |
||||
if (!fadt) |
||||
- return 0; |
||||
+ { |
||||
+ grub_dprintf ("pmtimer", "No FADT found; not using pmtimer.\n"); |
||||
+ return 0; |
||||
+ } |
||||
pmtimer = fadt->pmtimer; |
||||
if (!pmtimer) |
||||
- return 0; |
||||
+ { |
||||
+ grub_dprintf ("pmtimer", "FADT does not specify pmtimer; skipping.\n"); |
||||
+ return 0; |
||||
+ } |
||||
|
||||
- /* It's 3.579545 MHz clock. Wait 1 ms. */ |
||||
+ /* |
||||
+ * It's 3.579545 MHz clock. Wait 1 ms. |
||||
+ */ |
||||
tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580); |
||||
if (tsc_diff == 0) |
||||
return 0; |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 27 Feb 2018 13:55:35 -0500 |
||||
Subject: [PATCH] align struct efi_variable better... |
||||
|
||||
--- |
||||
include/grub/efiemu/runtime.h | 2 +- |
||||
include/grub/types.h | 1 + |
||||
2 files changed, 2 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h |
||||
index 36d2dedf47..9d93ba88ba 100644 |
||||
--- a/include/grub/efiemu/runtime.h |
||||
+++ b/include/grub/efiemu/runtime.h |
||||
@@ -33,5 +33,5 @@ struct efi_variable |
||||
grub_uint32_t namelen; |
||||
grub_uint32_t size; |
||||
grub_efi_uint32_t attributes; |
||||
-} GRUB_PACKED; |
||||
+} GRUB_PACKED GRUB_ALIGNED(8); |
||||
#endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */ |
||||
diff --git a/include/grub/types.h b/include/grub/types.h |
||||
index 0a3ff15913..ba446d9904 100644 |
||||
--- a/include/grub/types.h |
||||
+++ b/include/grub/types.h |
||||
@@ -29,6 +29,7 @@ |
||||
#else |
||||
#define GRUB_PACKED __attribute__ ((packed)) |
||||
#endif |
||||
+#define GRUB_ALIGNED(x) __attribute__((aligned (x))) |
||||
|
||||
#ifdef GRUB_BUILD |
||||
# define GRUB_CPU_SIZEOF_VOID_P BUILD_SIZEOF_VOID_P |
@ -0,0 +1,382 @@
@@ -0,0 +1,382 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Fri, 9 Dec 2016 15:40:29 -0500 |
||||
Subject: [PATCH] Add BLS support to grub-mkconfig |
||||
|
||||
GRUB now has BootLoaderSpec support, the user can choose to use this by |
||||
setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup, |
||||
the boot menu entries are not added to the grub.cfg, instead BLS config |
||||
files are parsed by blscfg command and the entries created dynamically. |
||||
|
||||
A 10_linux_bls grub.d snippet to generate menu entries from BLS files |
||||
is also added that can be used on platforms where the bootloader doesn't |
||||
have BLS support and only can parse a normal grub configuration file. |
||||
|
||||
Portions of the 10_linux_bls were taken from the ostree-grub-generator |
||||
script that's included in the OSTree project. |
||||
|
||||
Fixes to support multi-devices and generate a BLS section even if no |
||||
kernels are found in the boot directory were proposed by Yclept Nemo |
||||
and Tom Gundersen respectively. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[javierm: remove outdated URL for BLS document] |
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
[iwienand@redhat.com: skip machine ID check when updating entries] |
||||
Signed-off-by: Ian Wienand <iwienand@redhat.com> |
||||
[rharwood: use sort(1), commit message composits, drop man pages] |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
util/grub-mkconfig.in | 9 +- |
||||
util/grub-mkconfig_lib.in | 22 ++++- |
||||
util/grub.d/10_linux.in | 218 +++++++++++++++++++++++++++++++++++++++++++++- |
||||
3 files changed, 243 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in |
||||
index 535c0f0249..f55339a3f6 100644 |
||||
--- a/util/grub-mkconfig.in |
||||
+++ b/util/grub-mkconfig.in |
||||
@@ -50,6 +50,8 @@ grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" |
||||
export TEXTDOMAIN=@PACKAGE@ |
||||
export TEXTDOMAINDIR="@localedir@" |
||||
|
||||
+export GRUB_GRUBENV_UPDATE="yes" |
||||
+ |
||||
. "${pkgdatadir}/grub-mkconfig_lib" |
||||
|
||||
# Usage: usage |
||||
@@ -59,6 +61,7 @@ usage () { |
||||
gettext "Generate a grub config file"; echo |
||||
echo |
||||
print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")" |
||||
+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")" |
||||
print_option_help "-h, --help" "$(gettext "print this message and exit")" |
||||
print_option_help "-V, --version" "$(gettext "print the version information and exit")" |
||||
echo |
||||
@@ -94,6 +97,9 @@ do |
||||
--output=*) |
||||
grub_cfg=`echo "$option" | sed 's/--output=//'` |
||||
;; |
||||
+ --no-grubenv-update) |
||||
+ GRUB_GRUBENV_UPDATE="no" |
||||
+ ;; |
||||
-*) |
||||
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 |
||||
usage |
||||
@@ -253,7 +259,8 @@ export GRUB_DEFAULT \ |
||||
GRUB_OS_PROBER_SKIP_LIST \ |
||||
GRUB_DISABLE_SUBMENU \ |
||||
GRUB_DEFAULT_DTB \ |
||||
- SUSE_BTRFS_SNAPSHOT_BOOTING |
||||
+ SUSE_BTRFS_SNAPSHOT_BOOTING \ |
||||
+ GRUB_ENABLE_BLSCFG |
||||
|
||||
if test "x${grub_cfg}" != "x"; then |
||||
rm -f "${grub_cfg}.new" |
||||
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in |
||||
index 5e96f6cc5d..301d8a8a1e 100644 |
||||
--- a/util/grub-mkconfig_lib.in |
||||
+++ b/util/grub-mkconfig_lib.in |
||||
@@ -30,6 +30,9 @@ fi |
||||
if test "x$grub_file" = x; then |
||||
grub_file="${bindir}/@grub_file@" |
||||
fi |
||||
+if test "x$grub_editenv" = x; then |
||||
+ grub_editenv="${bindir}/@grub_editenv@" |
||||
+fi |
||||
if test "x$grub_mkrelpath" = x; then |
||||
grub_mkrelpath="${bindir}/@grub_mkrelpath@" |
||||
fi |
||||
@@ -122,8 +125,19 @@ EOF |
||||
fi |
||||
} |
||||
|
||||
+prepare_grub_to_access_device_with_variable () |
||||
+{ |
||||
+ device_variable="$1" |
||||
+ shift |
||||
+ prepare_grub_to_access_device "$@" |
||||
+ unset "device_variable" |
||||
+} |
||||
+ |
||||
prepare_grub_to_access_device () |
||||
{ |
||||
+ if [ -z "$device_variable" ]; then |
||||
+ device_variable="root" |
||||
+ fi |
||||
old_ifs="$IFS" |
||||
IFS=' |
||||
' |
||||
@@ -158,18 +172,18 @@ prepare_grub_to_access_device () |
||||
# otherwise set root as per value in device.map. |
||||
fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" |
||||
if [ "x$fs_hint" != x ]; then |
||||
- echo "set root='$fs_hint'" |
||||
+ echo "set ${device_variable}='$fs_hint'" |
||||
fi |
||||
if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then |
||||
hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= |
||||
if [ "x$hints" != x ]; then |
||||
echo "if [ x\$feature_platform_search_hint = xy ]; then" |
||||
- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" |
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}" |
||||
echo "else" |
||||
- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" |
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" |
||||
echo "fi" |
||||
else |
||||
- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" |
||||
+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" |
||||
fi |
||||
fi |
||||
IFS="$old_ifs" |
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index 7bb3a211a7..2851952659 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -82,6 +82,218 @@ case x"$GRUB_FS" in |
||||
;; |
||||
esac |
||||
|
||||
+populate_header_warn() |
||||
+{ |
||||
+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then |
||||
+ bls_parser="10_linux script" |
||||
+else |
||||
+ bls_parser="blscfg command" |
||||
+fi |
||||
+cat <<EOF |
||||
+ |
||||
+# This section was generated by a script. Do not modify the generated file - all changes |
||||
+# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files. |
||||
+# |
||||
+# The $bls_parser parses the BootLoaderSpec files stored in /boot/loader/entries and |
||||
+# populates the boot menu. Please refer to the Boot Loader Specification documentation |
||||
+# for the files format: https://systemd.io/BOOT_LOADER_SPECIFICATION/. |
||||
+ |
||||
+EOF |
||||
+} |
||||
+ |
||||
+read_config() |
||||
+{ |
||||
+ config_file=${1} |
||||
+ title="" |
||||
+ initrd="" |
||||
+ options="" |
||||
+ linux="" |
||||
+ grub_arg="" |
||||
+ |
||||
+ while read -r line |
||||
+ do |
||||
+ record=$(echo ${line} | cut -f 1 -d ' ') |
||||
+ value=$(echo ${line} | cut -s -f2- -d ' ') |
||||
+ case "${record}" in |
||||
+ "title") |
||||
+ title=${value} |
||||
+ ;; |
||||
+ "initrd") |
||||
+ initrd=${value} |
||||
+ ;; |
||||
+ "linux") |
||||
+ linux=${value} |
||||
+ ;; |
||||
+ "options") |
||||
+ options=${value} |
||||
+ ;; |
||||
+ "grub_arg") |
||||
+ grub_arg=${value} |
||||
+ ;; |
||||
+ esac |
||||
+ done < ${config_file} |
||||
+} |
||||
+ |
||||
+blsdir="/boot/loader/entries" |
||||
+ |
||||
+get_sorted_bls() |
||||
+{ |
||||
+ if ! [ -d "${blsdir}" ]; then |
||||
+ return |
||||
+ fi |
||||
+ |
||||
+ local IFS=$'\n' |
||||
+ |
||||
+ files=($(for bls in ${blsdir}/*.conf; do |
||||
+ if ! [[ -e "${bls}" ]] ; then |
||||
+ continue |
||||
+ fi |
||||
+ bls="${bls%.conf}" |
||||
+ bls="${bls##*/}" |
||||
+ echo "${bls}" |
||||
+ done | sort -Vr 2>/dev/null)) || : |
||||
+ |
||||
+ echo "${files[@]}" |
||||
+} |
||||
+ |
||||
+update_bls_cmdline() |
||||
+{ |
||||
+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" |
||||
+ local -a files=($(get_sorted_bls)) |
||||
+ |
||||
+ for bls in "${files[@]}"; do |
||||
+ local options="${cmdline}" |
||||
+ if [ -z "${bls##*debug*}" ]; then |
||||
+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}" |
||||
+ fi |
||||
+ options="$(echo "${options}" | sed -e 's/\//\\\//g')" |
||||
+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf" |
||||
+ done |
||||
+} |
||||
+ |
||||
+populate_menu() |
||||
+{ |
||||
+ local -a files=($(get_sorted_bls)) |
||||
+ |
||||
+ gettext_printf "Generating boot entries from BLS files...\n" >&2 |
||||
+ |
||||
+ for bls in "${files[@]}"; do |
||||
+ read_config "${blsdir}/${bls}.conf" |
||||
+ |
||||
+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n" |
||||
+ menu="${menu}\t linux ${linux} ${options}\n" |
||||
+ if [ -n "${initrd}" ] ; then |
||||
+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n" |
||||
+ fi |
||||
+ menu="${menu}}\n\n" |
||||
+ done |
||||
+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation |
||||
+ printf "$menu" |
||||
+} |
||||
+ |
||||
+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. |
||||
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then |
||||
+ GRUB_ENABLE_BLSCFG="true" |
||||
+fi |
||||
+ |
||||
+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then |
||||
+ if [ x$dirname = x/ ]; then |
||||
+ if [ -z "${prepare_root_cache}" ]; then |
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE} |
||||
+ fi |
||||
+ else |
||||
+ if [ -z "${prepare_boot_cache}" ]; then |
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} |
||||
+ fi |
||||
+ fi |
||||
+ |
||||
+ if [ -d /sys/firmware/efi ]; then |
||||
+ bootefi_device="`${grub_probe} --target=device /boot/efi/`" |
||||
+ prepare_grub_to_access_device_with_variable boot ${bootefi_device} |
||||
+ else |
||||
+ boot_device="`${grub_probe} --target=device /boot/`" |
||||
+ prepare_grub_to_access_device_with_variable boot ${boot_device} |
||||
+ fi |
||||
+ |
||||
+ arch="$(uname -m)" |
||||
+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then |
||||
+ |
||||
+ BLS_POPULATE_MENU="true" |
||||
+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" |
||||
+ |
||||
+ if test -e ${petitboot_path}; then |
||||
+ read -r -d '' petitboot_version < ${petitboot_path} |
||||
+ petitboot_version="$(echo ${petitboot_version//v})" |
||||
+ |
||||
+ if test -n ${petitboot_version}; then |
||||
+ major_version="$(echo ${petitboot_version} | cut -d . -f1)" |
||||
+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)" |
||||
+ |
||||
+ re='^[0-9]+$' |
||||
+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && |
||||
+ ([[ ${major_version} -gt 1 ]] || |
||||
+ [[ ${major_version} -eq 1 && |
||||
+ ${minor_version} -ge 8 ]]); then |
||||
+ BLS_POPULATE_MENU="false" |
||||
+ fi |
||||
+ fi |
||||
+ fi |
||||
+ fi |
||||
+ |
||||
+ populate_header_warn |
||||
+ |
||||
+ cat << EOF |
||||
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu |
||||
+# entries populated from BootLoaderSpec files that use this variable work correctly even |
||||
+# without a grubenv file, define a fallback kernelopts variable if this has not been set. |
||||
+# |
||||
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by |
||||
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX |
||||
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both |
||||
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable. |
||||
+if [ -z "\${kernelopts}" ]; then |
||||
+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" |
||||
+fi |
||||
+EOF |
||||
+ |
||||
+ update_bls_cmdline |
||||
+ |
||||
+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then |
||||
+ populate_menu |
||||
+ else |
||||
+ cat << EOF |
||||
+ |
||||
+insmod blscfg |
||||
+blscfg |
||||
+EOF |
||||
+ fi |
||||
+ |
||||
+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then |
||||
+ blsdir="/boot/loader/entries" |
||||
+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})" |
||||
+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then |
||||
+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}") |
||||
+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then |
||||
+ ${grub_editenv} - set blsdir="${blsdir}" |
||||
+ fi |
||||
+ fi |
||||
+ |
||||
+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then |
||||
+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}" |
||||
+ fi |
||||
+ |
||||
+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then |
||||
+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}" |
||||
+ fi |
||||
+ |
||||
+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then |
||||
+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}" |
||||
+ fi |
||||
+ fi |
||||
+ |
||||
+ exit 0 |
||||
+fi |
||||
+ |
||||
mktitle () |
||||
{ |
||||
local title_type |
||||
@@ -121,6 +333,7 @@ linux_entry () |
||||
if [ -z "$boot_device_id" ]; then |
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" |
||||
fi |
||||
+ |
||||
if [ x$type != xsimple ] ; then |
||||
title=$(mktitle "$type" "$version") |
||||
if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then |
||||
@@ -231,6 +444,7 @@ is_top_level=true |
||||
while [ "x$list" != "x" ] ; do |
||||
linux=`version_find_latest $list` |
||||
gettext_printf "Found linux image: %s\n" "$linux" >&2 |
||||
+ |
||||
basename=`basename $linux` |
||||
dirname=`dirname $linux` |
||||
rel_dirname=`make_system_path_relative_to_its_root $dirname` |
||||
@@ -269,7 +483,9 @@ while [ "x$list" != "x" ] ; do |
||||
for i in ${initrd}; do |
||||
initrd_display="${initrd_display} ${dirname}/${i}" |
||||
done |
||||
- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 |
||||
+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then |
||||
+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 |
||||
+ fi |
||||
fi |
||||
|
||||
fdt= |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Javier Martinez Canillas <javierm@redhat.com> |
||||
Date: Tue, 6 Feb 2018 11:16:28 +0100 |
||||
Subject: [PATCH] Don't attempt to backtrace on grub_abort() for grub-emu |
||||
|
||||
The emu platform doesn't have a grub_backtrace() implementation, so this |
||||
causes a build error. Don't attempt to call this when building grub-emu. |
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
--- |
||||
grub-core/kern/misc.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c |
||||
index a3e215155b..c60601b699 100644 |
||||
--- a/grub-core/kern/misc.c |
||||
+++ b/grub-core/kern/misc.c |
||||
@@ -1201,7 +1201,7 @@ static void __attribute__ ((noreturn)) |
||||
grub_abort (void) |
||||
{ |
||||
#ifndef GRUB_UTIL |
||||
-#if defined(__i386__) || defined(__x86_64__) |
||||
+#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU) |
||||
grub_backtrace(); |
||||
#endif |
||||
#endif |
@ -0,0 +1,395 @@
@@ -0,0 +1,395 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 15 Mar 2018 14:12:40 -0400 |
||||
Subject: [PATCH] Add grub2-switch-to-blscfg |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub] |
||||
Signed-off-by: Jan Hlavac <jhlavac@redhat.com> |
||||
[rharwood: skip on ostree installations, migrate man to h2m] |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
Makefile.util.def | 7 + |
||||
docs/man/grub-switch-to-blscfg.h2m | 2 + |
||||
util/grub-set-password.in | 2 +- |
||||
util/grub-switch-to-blscfg.in | 317 +++++++++++++++++++++++++++++++++++++ |
||||
util/grub.d/10_linux.in | 2 +- |
||||
5 files changed, 328 insertions(+), 2 deletions(-) |
||||
create mode 100644 docs/man/grub-switch-to-blscfg.h2m |
||||
create mode 100644 util/grub-switch-to-blscfg.in |
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index 18a9242776..88f55e35c4 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -1348,6 +1348,13 @@ program = { |
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = grub-switch-to-blscfg; |
||||
+ common = util/grub-switch-to-blscfg.in; |
||||
+ mansection = 8; |
||||
+ installdir = sbin; |
||||
+}; |
||||
+ |
||||
program = { |
||||
name = grub-glue-efi; |
||||
mansection = 1; |
||||
diff --git a/docs/man/grub-switch-to-blscfg.h2m b/docs/man/grub-switch-to-blscfg.h2m |
||||
new file mode 100644 |
||||
index 0000000000..fa341426a5 |
||||
--- /dev/null |
||||
+++ b/docs/man/grub-switch-to-blscfg.h2m |
||||
@@ -0,0 +1,2 @@ |
||||
+[NAME] |
||||
+grub-switch-to-blscfg \- switch to using BLS config files |
||||
diff --git a/util/grub-set-password.in b/util/grub-set-password.in |
||||
index 5ebf50576d..c0b5ebbfdc 100644 |
||||
--- a/util/grub-set-password.in |
||||
+++ b/util/grub-set-password.in |
||||
@@ -1,6 +1,6 @@ |
||||
#!/bin/sh -e |
||||
|
||||
-EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/') |
||||
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') |
||||
if [ -d /sys/firmware/efi/efivars/ ]; then |
||||
grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` |
||||
else |
||||
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in |
||||
new file mode 100644 |
||||
index 0000000000..a851424beb |
||||
--- /dev/null |
||||
+++ b/util/grub-switch-to-blscfg.in |
||||
@@ -0,0 +1,317 @@ |
||||
+#! /bin/sh |
||||
+# |
||||
+# Set a default boot entry for GRUB. |
||||
+# Copyright (C) 2004,2009 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/>. |
||||
+ |
||||
+#set -eu |
||||
+ |
||||
+# Initialize some variables. |
||||
+prefix=@prefix@ |
||||
+exec_prefix=@exec_prefix@ |
||||
+sbindir=@sbindir@ |
||||
+bindir=@bindir@ |
||||
+sysconfdir="@sysconfdir@" |
||||
+PACKAGE_NAME=@PACKAGE_NAME@ |
||||
+PACKAGE_VERSION=@PACKAGE_VERSION@ |
||||
+datarootdir="@datarootdir@" |
||||
+datadir="@datadir@" |
||||
+if [ ! -v pkgdatadir ]; then |
||||
+ pkgdatadir="${datadir}/@PACKAGE@" |
||||
+fi |
||||
+ |
||||
+self=`basename $0` |
||||
+ |
||||
+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" |
||||
+grub_editenv=${bindir}/@grub_editenv@ |
||||
+etcdefaultgrub=/etc/default/grub |
||||
+ |
||||
+eval "$("${grub_get_kernel_settings}")" || true |
||||
+ |
||||
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') |
||||
+if [ -d /sys/firmware/efi/efivars/ ]; then |
||||
+ startlink=/etc/grub2-efi.cfg |
||||
+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` |
||||
+else |
||||
+ startlink=/etc/grub2.cfg |
||||
+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` |
||||
+fi |
||||
+ |
||||
+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'` |
||||
+ |
||||
+backupsuffix=.bak |
||||
+ |
||||
+arch="$(uname -m)" |
||||
+ |
||||
+export TEXTDOMAIN=@PACKAGE@ |
||||
+export TEXTDOMAINDIR="@localedir@" |
||||
+ |
||||
+. "${pkgdatadir}/grub-mkconfig_lib" |
||||
+ |
||||
+# Usage: usage |
||||
+# Print the usage. |
||||
+usage () { |
||||
+ gettext_printf "Usage: %s\n" "$self" |
||||
+ gettext "Switch to BLS config files.\n"; echo |
||||
+ echo |
||||
+ print_option_help "-h, --help" "$(gettext "print this message and exit")" |
||||
+ print_option_help "-V, --version" "$(gettext "print the version information and exit")" |
||||
+ echo |
||||
+ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix" |
||||
+ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir" |
||||
+ print_option_help "--config-file=$(gettext "FILE")" "$startlink" |
||||
+ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub" |
||||
+ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir" |
||||
+ # echo |
||||
+ # gettext "Report bugs to <bug-grub@gnu.org>."; echo |
||||
+} |
||||
+ |
||||
+argument () { |
||||
+ opt=$1 |
||||
+ shift |
||||
+ |
||||
+ if test $# -eq 0; then |
||||
+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 |
||||
+ exit 1 |
||||
+ fi |
||||
+ echo $1 |
||||
+} |
||||
+ |
||||
+# Check the arguments. |
||||
+while test $# -gt 0 |
||||
+do |
||||
+ option=$1 |
||||
+ shift |
||||
+ |
||||
+ case "$option" in |
||||
+ -h | --help) |
||||
+ usage |
||||
+ exit 0 ;; |
||||
+ -V | --version) |
||||
+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" |
||||
+ exit 0 ;; |
||||
+ |
||||
+ --backup-suffix) |
||||
+ backupsuffix=`argument $option "$@"` |
||||
+ shift |
||||
+ ;; |
||||
+ --backup-suffix=*) |
||||
+ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'` |
||||
+ ;; |
||||
+ |
||||
+ --bls-directory) |
||||
+ blsdir=`argument $option "$@"` |
||||
+ shift |
||||
+ ;; |
||||
+ --bls-directory=*) |
||||
+ blsdir=`echo "$option" | sed 's/--bls-directory=//'` |
||||
+ ;; |
||||
+ |
||||
+ --config-file) |
||||
+ startlink=`argument $option "$@"` |
||||
+ shift |
||||
+ ;; |
||||
+ --config-file=*) |
||||
+ startlink=`echo "$option" | sed 's/--config-file=//'` |
||||
+ ;; |
||||
+ |
||||
+ --grub-defaults) |
||||
+ etcdefaultgrub=`argument $option "$@"` |
||||
+ shift |
||||
+ ;; |
||||
+ --grub-defaults=*) |
||||
+ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'` |
||||
+ ;; |
||||
+ |
||||
+ --grub-directory) |
||||
+ grubdir=`argument $option "$@"` |
||||
+ shift |
||||
+ ;; |
||||
+ --grub-directory=*) |
||||
+ grubdir=`echo "$option" | sed 's/--grub-directory=//'` |
||||
+ ;; |
||||
+ |
||||
+ *) |
||||
+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 |
||||
+ usage |
||||
+ exit 1 |
||||
+ ;; |
||||
+ esac |
||||
+done |
||||
+ |
||||
+find_grub_cfg() { |
||||
+ local candidate="" |
||||
+ while [ -e "${candidate}" -o $# -gt 0 ] |
||||
+ do |
||||
+ if [ ! -e "${candidate}" ] ; then |
||||
+ candidate="$1" |
||||
+ shift |
||||
+ fi |
||||
+ |
||||
+ if [ -L "${candidate}" ]; then |
||||
+ candidate="$(realpath "${candidate}")" |
||||
+ fi |
||||
+ |
||||
+ if [ -f "${candidate}" ]; then |
||||
+ export GRUB_CONFIG_FILE="${candidate}" |
||||
+ return 0 |
||||
+ fi |
||||
+ done |
||||
+ return 1 |
||||
+} |
||||
+ |
||||
+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then |
||||
+ gettext_printf "Couldn't find config file\n" 1>&2 |
||||
+ exit 1 |
||||
+fi |
||||
+ |
||||
+if [ ! -d "${blsdir}" ]; then |
||||
+ install -m 700 -d "${blsdir}" |
||||
+fi |
||||
+ |
||||
+if [ -f /etc/machine-id ]; then |
||||
+ MACHINE_ID=$(cat /etc/machine-id) |
||||
+else |
||||
+ MACHINE_ID=$(dmesg | sha256sum) |
||||
+fi |
||||
+ |
||||
+mkbls() { |
||||
+ local kernelver=$1 && shift |
||||
+ local datetime=$1 && shift |
||||
+ local kernelopts=$1 && shift |
||||
+ |
||||
+ local debugname="" |
||||
+ local debugid="" |
||||
+ local flavor="" |
||||
+ |
||||
+ if [ "$kernelver" == *\+* ] ; then |
||||
+ local flavor=-"${kernelver##*+}" |
||||
+ if [ "${flavor}" == "-debug" ]; then |
||||
+ local debugname=" with debugging" |
||||
+ local debugid="-debug" |
||||
+ fi |
||||
+ fi |
||||
+ ( |
||||
+ source /etc/os-release |
||||
+ |
||||
+ cat <<EOF |
||||
+title ${NAME} (${kernelver}) ${VERSION}${debugname} |
||||
+version ${kernelver}${debugid} |
||||
+linux /vmlinuz-${kernelver} |
||||
+initrd /initramfs-${kernelver}.img |
||||
+options ${kernelopts} |
||||
+grub_users \$grub_users |
||||
+grub_arg --unrestricted |
||||
+grub_class kernel${flavor} |
||||
+EOF |
||||
+ ) | cat |
||||
+} |
||||
+ |
||||
+copy_bls() { |
||||
+ for kernelver in $(cd /lib/modules/ ; ls -1) "" ; do |
||||
+ bls_target="${blsdir}/${MACHINE_ID}-${kernelver}.conf" |
||||
+ linux="/vmlinuz-${kernelver}" |
||||
+ linux_path="/boot${linux}" |
||||
+ kernel_dir="/lib/modules/${kernelver}" |
||||
+ |
||||
+ if [ ! -d "${kernel_dir}" ] ; then |
||||
+ continue |
||||
+ fi |
||||
+ if [ ! -f "${linux_path}" ]; then |
||||
+ continue |
||||
+ fi |
||||
+ |
||||
+ linux_relpath="$("${grub_mkrelpath}" "${linux_path}")" |
||||
+ bootprefix="${linux_relpath%%"${linux}"}" |
||||
+ cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" |
||||
+ |
||||
+ mkbls "${kernelver}" \ |
||||
+ "$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \ |
||||
+ "${bootprefix}" "${cmdline}" >"${bls_target}" |
||||
+ |
||||
+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then |
||||
+ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")" |
||||
+ cp -aT "${bls_target}" "${bls_debug}" |
||||
+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')" |
||||
+ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')" |
||||
+ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}" |
||||
+ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}" |
||||
+ fi |
||||
+ done |
||||
+ |
||||
+ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then |
||||
+ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf" |
||||
+ fi |
||||
+} |
||||
+ |
||||
+# The grub2 EFI binary is not copied to the ESP as a part of an ostree |
||||
+# transaction. Make sure a grub2 version with BLS support is installed |
||||
+# but only do this if the blsdir is not set, to make sure that the BLS |
||||
+# parsing module will search for the BLS snippets in the default path. |
||||
+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \ |
||||
+ ! ${grub_editenv} - list | grep -q blsdir && \ |
||||
+ mountpoint -q /boot; then |
||||
+ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)" |
||||
+ install -m 700 ${grub_binary} ${grubdir} || exit 1 |
||||
+ # Create a hidden file to indicate that grub2 now has BLS support. |
||||
+ touch /boot/grub2/.grub2-blscfg-supported |
||||
+fi |
||||
+ |
||||
+GENERATE=0 |
||||
+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ |
||||
+ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then |
||||
+ if ! sed -i"${backupsuffix}" \ |
||||
+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \ |
||||
+ "${etcdefaultgrub}" ; then |
||||
+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" |
||||
+ exit 1 |
||||
+ fi |
||||
+ GENERATE=1 |
||||
+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then |
||||
+ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then |
||||
+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" |
||||
+ exit 1 |
||||
+ fi |
||||
+ GENERATE=1 |
||||
+fi |
||||
+ |
||||
+if [ "${GENERATE}" -eq 1 ] ; then |
||||
+ copy_bls |
||||
+ |
||||
+ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then |
||||
+ mod_dir="i386-pc" |
||||
+ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then |
||||
+ mod_dir="powerpc-ieee1275" |
||||
+ fi |
||||
+ |
||||
+ if [ -n "${mod_dir}" ]; then |
||||
+ for mod in blscfg increment; do |
||||
+ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1 |
||||
+ done |
||||
+ fi |
||||
+ |
||||
+ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}" |
||||
+ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then |
||||
+ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}" |
||||
+ sed -i"${backupsuffix}" \ |
||||
+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \ |
||||
+ "${etcdefaultgrub}" |
||||
+ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}" |
||||
+ exit 1 |
||||
+ fi |
||||
+fi |
||||
+ |
||||
+# Bye. |
||||
+exit 0 |
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in |
||||
index 2851952659..e490e1a43a 100644 |
||||
--- a/util/grub.d/10_linux.in |
||||
+++ b/util/grub.d/10_linux.in |
||||
@@ -138,7 +138,7 @@ blsdir="/boot/loader/entries" |
||||
|
||||
get_sorted_bls() |
||||
{ |
||||
- if ! [ -d "${blsdir}" ]; then |
||||
+ if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ] || [ -d /ostree/repo ]; then |
||||
return |
||||
fi |
||||
|
@ -0,0 +1,910 @@
@@ -0,0 +1,910 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 9 Jul 2019 17:05:03 +0200 |
||||
Subject: [PATCH] make better backtraces |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
Makefile.util.def | 6 ++ |
||||
grub-core/Makefile.core.def | 16 ++-- |
||||
grub-core/{lib => commands}/backtrace.c | 2 +- |
||||
grub-core/gdb/cstub.c | 1 - |
||||
grub-core/kern/arm64/backtrace.c | 94 ++++++++++++++++++++++++ |
||||
grub-core/kern/backtrace.c | 97 +++++++++++++++++++++++++ |
||||
grub-core/kern/dl.c | 45 ++++++++++++ |
||||
grub-core/kern/i386/backtrace.c | 125 ++++++++++++++++++++++++++++++++ |
||||
grub-core/kern/i386/pc/init.c | 4 +- |
||||
grub-core/kern/ieee1275/init.c | 1 - |
||||
grub-core/kern/misc.c | 13 ++-- |
||||
grub-core/kern/mm.c | 6 +- |
||||
grub-core/lib/arm64/backtrace.c | 62 ---------------- |
||||
grub-core/lib/i386/backtrace.c | 78 -------------------- |
||||
include/grub/backtrace.h | 10 ++- |
||||
include/grub/dl.h | 2 + |
||||
include/grub/kernel.h | 3 + |
||||
grub-core/kern/arm/efi/startup.S | 2 + |
||||
grub-core/kern/arm/startup.S | 2 + |
||||
grub-core/kern/arm64/efi/startup.S | 2 + |
||||
grub-core/kern/i386/qemu/startup.S | 3 +- |
||||
grub-core/kern/ia64/efi/startup.S | 3 +- |
||||
grub-core/kern/sparc64/ieee1275/crt0.S | 3 +- |
||||
grub-core/Makefile.am | 1 + |
||||
24 files changed, 414 insertions(+), 167 deletions(-) |
||||
rename grub-core/{lib => commands}/backtrace.c (98%) |
||||
create mode 100644 grub-core/kern/arm64/backtrace.c |
||||
create mode 100644 grub-core/kern/backtrace.c |
||||
create mode 100644 grub-core/kern/i386/backtrace.c |
||||
delete mode 100644 grub-core/lib/arm64/backtrace.c |
||||
delete mode 100644 grub-core/lib/i386/backtrace.c |
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index 88f55e35c4..bda9fd1211 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -51,6 +51,12 @@ library = { |
||||
common = grub-core/partmap/msdos.c; |
||||
common = grub-core/fs/proc.c; |
||||
common = grub-core/fs/archelp.c; |
||||
+ common = grub-core/kern/backtrace.c; |
||||
+ |
||||
+ x86 = grub-core/kern/i386/backtrace.c; |
||||
+ i386_xen = grub-core/kern/i386/backtrace.c; |
||||
+ x86_64_xen = grub-core/kern/i386/backtrace.c; |
||||
+ arm64 = grub-core/kern/arm64/backtrace.c; |
||||
}; |
||||
|
||||
library = { |
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
||||
index 058c88ac3a..52ec0fafcd 100644 |
||||
--- a/grub-core/Makefile.core.def |
||||
+++ b/grub-core/Makefile.core.def |
||||
@@ -142,6 +142,12 @@ kernel = { |
||||
common = kern/rescue_reader.c; |
||||
common = kern/term.c; |
||||
common = kern/verifiers.c; |
||||
+ common = kern/backtrace.c; |
||||
+ |
||||
+ x86 = kern/i386/backtrace.c; |
||||
+ i386_xen = kern/i386/backtrace.c; |
||||
+ x86_64_xen = kern/i386/backtrace.c; |
||||
+ arm64 = kern/arm64/backtrace.c; |
||||
|
||||
noemu = kern/compiler-rt.c; |
||||
noemu = kern/mm.c; |
||||
@@ -188,9 +194,6 @@ kernel = { |
||||
|
||||
softdiv = lib/division.c; |
||||
|
||||
- x86 = lib/i386/backtrace.c; |
||||
- x86 = lib/backtrace.c; |
||||
- |
||||
i386 = kern/i386/dl.c; |
||||
i386_xen = kern/i386/dl.c; |
||||
i386_xen_pvh = kern/i386/dl.c; |
||||
@@ -2399,15 +2402,12 @@ module = { |
||||
|
||||
module = { |
||||
name = backtrace; |
||||
- x86 = lib/i386/backtrace.c; |
||||
- i386_xen_pvh = lib/i386/backtrace.c; |
||||
- i386_xen = lib/i386/backtrace.c; |
||||
- x86_64_xen = lib/i386/backtrace.c; |
||||
- common = lib/backtrace.c; |
||||
+ common = commands/backtrace.c; |
||||
enable = x86; |
||||
enable = i386_xen_pvh; |
||||
enable = i386_xen; |
||||
enable = x86_64_xen; |
||||
+ enable = arm64; |
||||
}; |
||||
|
||||
module = { |
||||
diff --git a/grub-core/lib/backtrace.c b/grub-core/commands/backtrace.c |
||||
similarity index 98% |
||||
rename from grub-core/lib/backtrace.c |
||||
rename to grub-core/commands/backtrace.c |
||||
index c0ad6ab8be..8b5ec3913b 100644 |
||||
--- a/grub-core/lib/backtrace.c |
||||
+++ b/grub-core/commands/backtrace.c |
||||
@@ -54,7 +54,7 @@ grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)), |
||||
int argc __attribute__ ((unused)), |
||||
char **args __attribute__ ((unused))) |
||||
{ |
||||
- grub_backtrace (); |
||||
+ grub_backtrace (1); |
||||
return 0; |
||||
} |
||||
|
||||
diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c |
||||
index b64acd70fe..99281472d3 100644 |
||||
--- a/grub-core/gdb/cstub.c |
||||
+++ b/grub-core/gdb/cstub.c |
||||
@@ -215,7 +215,6 @@ grub_gdb_trap (int trap_no) |
||||
grub_printf ("Unhandled exception 0x%x at ", trap_no); |
||||
grub_backtrace_print_address ((void *) grub_gdb_regs[PC]); |
||||
grub_printf ("\n"); |
||||
- grub_backtrace_pointer ((void *) grub_gdb_regs[EBP]); |
||||
grub_fatal ("Unhandled exception"); |
||||
} |
||||
|
||||
diff --git a/grub-core/kern/arm64/backtrace.c b/grub-core/kern/arm64/backtrace.c |
||||
new file mode 100644 |
||||
index 0000000000..019c6fdfef |
||||
--- /dev/null |
||||
+++ b/grub-core/kern/arm64/backtrace.c |
||||
@@ -0,0 +1,94 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2009 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/misc.h> |
||||
+#include <grub/command.h> |
||||
+#include <grub/err.h> |
||||
+#include <grub/dl.h> |
||||
+#include <grub/mm.h> |
||||
+#include <grub/term.h> |
||||
+#include <grub/backtrace.h> |
||||
+ |
||||
+#define MAX_STACK_FRAME 102400 |
||||
+ |
||||
+struct fplr |
||||
+{ |
||||
+ void *lr; |
||||
+ struct fplr *fp; |
||||
+}; |
||||
+ |
||||
+void |
||||
+grub_backtrace_pointer (void *frame, unsigned int skip) |
||||
+{ |
||||
+ unsigned int x = 0; |
||||
+ struct fplr *fplr = (struct fplr *)frame; |
||||
+ |
||||
+ while (fplr) |
||||
+ { |
||||
+ const char *name = NULL; |
||||
+ char *addr = NULL; |
||||
+ |
||||
+ grub_dprintf("backtrace", "fp is %p next_fp is %p\n", |
||||
+ fplr, fplr->fp); |
||||
+ |
||||
+ if (x >= skip) |
||||
+ { |
||||
+ name = grub_get_symbol_by_addr (fplr->lr, 1); |
||||
+ if (name) |
||||
+ addr = grub_resolve_symbol (name); |
||||
+ grub_backtrace_print_address (fplr->lr); |
||||
+ |
||||
+ if (addr && addr != fplr->lr) |
||||
+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr, |
||||
+ (void *)((grub_uint64_t)fplr->lr - (grub_uint64_t)addr)); |
||||
+ else |
||||
+ grub_printf(" %s() %p \n", name ? name : "unknown", addr); |
||||
+ |
||||
+ } |
||||
+ |
||||
+ x += 1; |
||||
+ |
||||
+ if (fplr->fp < fplr || |
||||
+ (grub_uint64_t)fplr->fp - (grub_uint64_t)fplr > MAX_STACK_FRAME || |
||||
+ fplr->fp == fplr) |
||||
+ { |
||||
+ break; |
||||
+ } |
||||
+ fplr = fplr->fp; |
||||
+ } |
||||
+} |
||||
+ |
||||
+asm ("\t.global \"_text\"\n" |
||||
+ "_text:\n" |
||||
+ "\t.quad .text\n" |
||||
+ "\t.global \"_data\"\n" |
||||
+ "_data:\n" |
||||
+ "\t.quad .data\n" |
||||
+ ); |
||||
+ |
||||
+extern grub_uint64_t _text; |
||||
+extern grub_uint64_t _data; |
||||
+ |
||||
+void |
||||
+grub_backtrace_arch (unsigned int skip) |
||||
+{ |
||||
+ grub_printf ("Backtrace (.text %p .data %p):\n", |
||||
+ (void *)_text, (void *)_data); |
||||
+ skip += 1; |
||||
+ grub_backtrace_pointer(__builtin_frame_address(0), skip); |
||||
+} |
||||
diff --git a/grub-core/kern/backtrace.c b/grub-core/kern/backtrace.c |
||||
new file mode 100644 |
||||
index 0000000000..4a82e865cc |
||||
--- /dev/null |
||||
+++ b/grub-core/kern/backtrace.c |
||||
@@ -0,0 +1,97 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2009 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/misc.h> |
||||
+#include <grub/command.h> |
||||
+#include <grub/err.h> |
||||
+#include <grub/dl.h> |
||||
+#include <grub/mm.h> |
||||
+#include <grub/term.h> |
||||
+#include <grub/backtrace.h> |
||||
+ |
||||
+GRUB_MOD_LICENSE ("GPLv3+"); |
||||
+ |
||||
+static void |
||||
+grub_backtrace_print_address_default (void *addr) |
||||
+{ |
||||
+#ifndef GRUB_UTIL |
||||
+ grub_dl_t mod; |
||||
+ void *start_addr; |
||||
+ |
||||
+ FOR_DL_MODULES (mod) |
||||
+ { |
||||
+ grub_dl_segment_t segment; |
||||
+ for (segment = mod->segment; segment; segment = segment->next) |
||||
+ if (segment->addr <= addr && (grub_uint8_t *) segment->addr |
||||
+ + segment->size > (grub_uint8_t *) addr) |
||||
+ { |
||||
+ grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name, |
||||
+ segment->section, |
||||
+ (grub_size_t) |
||||
+ ((grub_uint8_t *)addr - (grub_uint8_t *)segment->addr)); |
||||
+ return; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ start_addr = grub_resolve_symbol ("_start"); |
||||
+ if (start_addr && start_addr < addr) |
||||
+ grub_printf ("kernel+%" PRIxGRUB_SIZE, |
||||
+ (grub_size_t) |
||||
+ ((grub_uint8_t *)addr - (grub_uint8_t *)start_addr)); |
||||
+ else |
||||
+#endif |
||||
+ grub_printf ("%p", addr); |
||||
+} |
||||
+ |
||||
+static void |
||||
+grub_backtrace_pointer_default (void *frame __attribute__((__unused__)), |
||||
+ unsigned int skip __attribute__((__unused__))) |
||||
+{ |
||||
+ return; |
||||
+} |
||||
+ |
||||
+void |
||||
+grub_backtrace_pointer (void *frame, unsigned int skip) |
||||
+ __attribute__((__weak__, |
||||
+ __alias__(("grub_backtrace_pointer_default")))); |
||||
+ |
||||
+void |
||||
+grub_backtrace_print_address (void *addr) |
||||
+ __attribute__((__weak__, |
||||
+ __alias__(("grub_backtrace_print_address_default")))); |
||||
+ |
||||
+static void |
||||
+grub_backtrace_arch_default(unsigned int skip) |
||||
+{ |
||||
+ grub_backtrace_pointer(__builtin_frame_address(0), skip + 1); |
||||
+} |
||||
+ |
||||
+void grub_backtrace_arch (unsigned int skip) |
||||
+ __attribute__((__weak__, __alias__(("grub_backtrace_arch_default")))); |
||||
+ |
||||
+void grub_backtrace (unsigned int skip) |
||||
+{ |
||||
+ grub_backtrace_arch(skip + 1); |
||||
+} |
||||
+ |
||||
+void grub_debug_backtrace (const char * const debug, |
||||
+ unsigned int skip) |
||||
+{ |
||||
+ if (grub_debug_enabled (debug)) |
||||
+ grub_backtrace (skip + 1); |
||||
+} |
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c |
||||
index 7afb9e6f72..88d2077709 100644 |
||||
--- a/grub-core/kern/dl.c |
||||
+++ b/grub-core/kern/dl.c |
||||
@@ -124,6 +124,50 @@ grub_dl_resolve_symbol (const char *name) |
||||
return 0; |
||||
} |
||||
|
||||
+void * |
||||
+grub_resolve_symbol (const char *name) |
||||
+{ |
||||
+ grub_symbol_t sym; |
||||
+ |
||||
+ sym = grub_dl_resolve_symbol (name); |
||||
+ if (sym) |
||||
+ return sym->addr; |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+const char * |
||||
+grub_get_symbol_by_addr(const void *addr, int isfunc) |
||||
+{ |
||||
+ unsigned int i; |
||||
+ grub_symbol_t before = NULL, after = NULL; |
||||
+ for (i = 0; i < GRUB_SYMTAB_SIZE; i++) |
||||
+ { |
||||
+ grub_symbol_t sym; |
||||
+ for (sym = grub_symtab[i]; sym; sym = sym->next) |
||||
+ { |
||||
+ //grub_printf ("addr 0x%08llx symbol %s\n", (unsigned long long)sym->addr, sym->name); |
||||
+ if (sym->addr > addr) |
||||
+ { |
||||
+ if (!after || sym->addr > after->addr) |
||||
+ after = sym; |
||||
+ } |
||||
+ |
||||
+ if (isfunc != sym->isfunc) |
||||
+ continue; |
||||
+ if (sym->addr > addr) |
||||
+ continue; |
||||
+ |
||||
+ if ((!before && sym->addr <= addr) || (before && before->addr <= sym->addr)) |
||||
+ before = sym; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (before && addr < after->addr) |
||||
+ return before->name; |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
/* Register a symbol with the name NAME and the address ADDR. */ |
||||
grub_err_t |
||||
grub_dl_register_symbol (const char *name, void *addr, int isfunc, |
||||
@@ -336,6 +380,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) |
||||
const char *str; |
||||
Elf_Word size, entsize; |
||||
|
||||
+ grub_dprintf ("modules", "Resolving symbols for \"%s\"\n", mod->name); |
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); |
||||
i < e->e_shnum; |
||||
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) |
||||
diff --git a/grub-core/kern/i386/backtrace.c b/grub-core/kern/i386/backtrace.c |
||||
new file mode 100644 |
||||
index 0000000000..2413f9a57d |
||||
--- /dev/null |
||||
+++ b/grub-core/kern/i386/backtrace.c |
||||
@@ -0,0 +1,125 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2009 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/misc.h> |
||||
+#include <grub/command.h> |
||||
+#include <grub/err.h> |
||||
+#include <grub/dl.h> |
||||
+#include <grub/mm.h> |
||||
+#include <grub/term.h> |
||||
+#include <grub/backtrace.h> |
||||
+ |
||||
+#define MAX_STACK_FRAME 102400 |
||||
+ |
||||
+void |
||||
+grub_backtrace_pointer (void *frame, unsigned int skip) |
||||
+{ |
||||
+ void **ebp = (void **)frame; |
||||
+ unsigned long x = 0; |
||||
+ |
||||
+ while (ebp) |
||||
+ { |
||||
+ void **next_ebp = (void **)ebp[0]; |
||||
+ const char *name = NULL; |
||||
+ char *addr = NULL; |
||||
+ |
||||
+ grub_dprintf("backtrace", "ebp is %p next_ebp is %p\n", ebp, next_ebp); |
||||
+ |
||||
+ if (x >= skip) |
||||
+ { |
||||
+ name = grub_get_symbol_by_addr (ebp[1], 1); |
||||
+ if (name) |
||||
+ addr = grub_resolve_symbol (name); |
||||
+ grub_backtrace_print_address (ebp[1]); |
||||
+ |
||||
+ if (addr && addr != ebp[1]) |
||||
+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr, |
||||
+ (char *)((char *)ebp[1] - addr)); |
||||
+ else |
||||
+ grub_printf(" %s() %p \n", name ? name : "unknown", addr); |
||||
+ |
||||
+#if 0 |
||||
+ grub_printf ("("); |
||||
+ for (i = 0, arg = ebp[2]; arg != next_ebp && i < 12; arg++, i++) |
||||
+ grub_printf ("%p,", arg); |
||||
+ grub_printf (")\n"); |
||||
+#endif |
||||
+ } |
||||
+ |
||||
+ x += 1; |
||||
+ |
||||
+ if (next_ebp < ebp || next_ebp - ebp > MAX_STACK_FRAME || next_ebp == ebp) |
||||
+ { |
||||
+ //grub_printf ("Invalid stack frame at %p (%p)\n", ebp, next_ebp); |
||||
+ break; |
||||
+ } |
||||
+ ebp = next_ebp; |
||||
+ } |
||||
+} |
||||
+ |
||||
+#if defined (__x86_64__) |
||||
+asm ("\t.global \"_text\"\n" |
||||
+ "_text:\n" |
||||
+ "\t.quad .text\n" |
||||
+ "\t.global \"_data\"\n" |
||||
+ "_data:\n" |
||||
+ "\t.quad .data\n" |
||||
+ ); |
||||
+#elif defined(__i386__) |
||||
+asm ("\t.global \"_text\"\n" |
||||
+ "_text:\n" |
||||
+ "\t.long .text\n" |
||||
+ "\t.global \"_data\"\n" |
||||
+ "_data:\n" |
||||
+ "\t.long .data\n" |
||||
+ ); |
||||
+#else |
||||
+#warning I dunno... |
||||
+#endif |
||||
+ |
||||
+extern unsigned long _text; |
||||
+extern unsigned long _data; |
||||
+ |
||||
+#ifdef GRUB_UTIL |
||||
+#define EXT_C(x) x |
||||
+#endif |
||||
+ |
||||
+void |
||||
+grub_backtrace_arch (unsigned int skip) |
||||
+{ |
||||
+ grub_printf ("Backtrace (.text %p .data %p):\n", |
||||
+ (void *)_text, (void *)_data); |
||||
+ skip += 1; |
||||
+#if defined (__x86_64__) |
||||
+ asm volatile ("movq %%rbp, %%rdi\n" |
||||
+ "movq 0, %%rsi\n" |
||||
+ "movl %0, %%esi\n" |
||||
+ "call " EXT_C("grub_backtrace_pointer") |
||||
+ : |
||||
+ : "r" (skip)); |
||||
+#elif defined(__i386__) |
||||
+ asm volatile ("addl $8, %%esp\n" |
||||
+ "pushl %0\n" |
||||
+ "pushl %%ebp\n" |
||||
+ "call " EXT_C("grub_backtrace_pointer") |
||||
+ : |
||||
+ : "r" (skip)); |
||||
+#else |
||||
+ grub_backtrace_pointer(__builtin_frame_address(0), skip); |
||||
+#endif |
||||
+} |
||||
diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c |
||||
index 27bc68b8a5..b51d0abfa6 100644 |
||||
--- a/grub-core/kern/i386/pc/init.c |
||||
+++ b/grub-core/kern/i386/pc/init.c |
||||
@@ -153,7 +153,7 @@ compact_mem_regions (void) |
||||
} |
||||
|
||||
grub_addr_t grub_modbase; |
||||
-extern grub_uint8_t _start[], _edata[]; |
||||
+extern grub_uint8_t _edata[]; |
||||
|
||||
/* Helper for grub_machine_init. */ |
||||
static int |
||||
@@ -217,7 +217,7 @@ grub_machine_init (void) |
||||
/* This has to happen before any BIOS calls. */ |
||||
grub_via_workaround_init (); |
||||
|
||||
- grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); |
||||
+ grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - (grub_uint8_t *)_start); |
||||
|
||||
/* Initialize the console as early as possible. */ |
||||
grub_console_init (); |
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c |
||||
index 0cd2a62723..937c1bc44c 100644 |
||||
--- a/grub-core/kern/ieee1275/init.c |
||||
+++ b/grub-core/kern/ieee1275/init.c |
||||
@@ -63,7 +63,6 @@ |
||||
#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024) |
||||
#endif |
||||
|
||||
-extern char _start[]; |
||||
extern char _end[]; |
||||
|
||||
#ifdef __sparc__ |
||||
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c |
||||
index c60601b699..a432a6be54 100644 |
||||
--- a/grub-core/kern/misc.c |
||||
+++ b/grub-core/kern/misc.c |
||||
@@ -1197,15 +1197,15 @@ grub_printf_fmt_check (const char *fmt, const char *fmt_expected) |
||||
|
||||
|
||||
/* Abort GRUB. This function does not return. */ |
||||
-static void __attribute__ ((noreturn)) |
||||
+static inline void __attribute__ ((noreturn)) |
||||
grub_abort (void) |
||||
{ |
||||
-#ifndef GRUB_UTIL |
||||
-#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU) |
||||
- grub_backtrace(); |
||||
+#if !defined(GRUB_MACHINE_EMU) && !defined(GRUB_UTIL) |
||||
+ grub_backtrace (1); |
||||
+#else |
||||
+ grub_printf ("\n"); |
||||
#endif |
||||
-#endif |
||||
- grub_printf ("\nAborted."); |
||||
+ grub_printf ("Aborted."); |
||||
|
||||
#ifndef GRUB_UTIL |
||||
if (grub_term_inputs) |
||||
@@ -1232,6 +1232,7 @@ grub_fatal (const char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
|
||||
+ grub_printf ("\n"); |
||||
va_start (ap, fmt); |
||||
grub_vprintf (_(fmt), ap); |
||||
va_end (ap); |
||||
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c |
||||
index c070afc621..d8c8377578 100644 |
||||
--- a/grub-core/kern/mm.c |
||||
+++ b/grub-core/kern/mm.c |
||||
@@ -97,13 +97,13 @@ get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r) |
||||
break; |
||||
|
||||
if (! *r) |
||||
- grub_fatal ("out of range pointer %p", ptr); |
||||
+ grub_fatal ("out of range pointer %p\n", ptr); |
||||
|
||||
*p = (grub_mm_header_t) ptr - 1; |
||||
if ((*p)->magic == GRUB_MM_FREE_MAGIC) |
||||
- grub_fatal ("double free at %p", *p); |
||||
+ grub_fatal ("double free at %p\n", *p); |
||||
if ((*p)->magic != GRUB_MM_ALLOC_MAGIC) |
||||
- grub_fatal ("alloc magic is broken at %p: %lx", *p, |
||||
+ grub_fatal ("alloc magic is broken at %p: %lx\n", *p, |
||||
(unsigned long) (*p)->magic); |
||||
} |
||||
|
||||
diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c |
||||
deleted file mode 100644 |
||||
index 1079b5380e..0000000000 |
||||
--- a/grub-core/lib/arm64/backtrace.c |
||||
+++ /dev/null |
||||
@@ -1,62 +0,0 @@ |
||||
-/* |
||||
- * GRUB -- GRand Unified Bootloader |
||||
- * Copyright (C) 2009 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/misc.h> |
||||
-#include <grub/command.h> |
||||
-#include <grub/err.h> |
||||
-#include <grub/dl.h> |
||||
-#include <grub/mm.h> |
||||
-#include <grub/term.h> |
||||
-#include <grub/backtrace.h> |
||||
- |
||||
-#define MAX_STACK_FRAME 102400 |
||||
- |
||||
-void |
||||
-grub_backtrace_pointer (int frame) |
||||
-{ |
||||
- while (1) |
||||
- { |
||||
- void *lp = __builtin_return_address (frame); |
||||
- if (!lp) |
||||
- break; |
||||
- |
||||
- lp = __builtin_extract_return_addr (lp); |
||||
- |
||||
- grub_printf ("%p: ", lp); |
||||
- grub_backtrace_print_address (lp); |
||||
- grub_printf (" ("); |
||||
- for (i = 0; i < 2; i++) |
||||
- grub_printf ("%p,", ((void **)ptr) [i + 2]); |
||||
- grub_printf ("%p)\n", ((void **)ptr) [i + 2]); |
||||
- nptr = *(void **)ptr; |
||||
- if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME |
||||
- || nptr == ptr) |
||||
- { |
||||
- grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); |
||||
- break; |
||||
- } |
||||
- ptr = nptr; |
||||
- } |
||||
-} |
||||
- |
||||
-void |
||||
-grub_backtrace (void) |
||||
-{ |
||||
- grub_backtrace_pointer (1); |
||||
-} |
||||
- |
||||
diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c |
||||
deleted file mode 100644 |
||||
index c67273db3a..0000000000 |
||||
--- a/grub-core/lib/i386/backtrace.c |
||||
+++ /dev/null |
||||
@@ -1,78 +0,0 @@ |
||||
-/* |
||||
- * GRUB -- GRand Unified Bootloader |
||||
- * Copyright (C) 2009 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 <config.h> |
||||
-#ifdef GRUB_UTIL |
||||
-#define REALLY_GRUB_UTIL GRUB_UTIL |
||||
-#undef GRUB_UTIL |
||||
-#endif |
||||
- |
||||
-#include <grub/symbol.h> |
||||
-#include <grub/dl.h> |
||||
- |
||||
-#ifdef REALLY_GRUB_UTIL |
||||
-#define GRUB_UTIL REALLY_GRUB_UTIL |
||||
-#undef REALLY_GRUB_UTIL |
||||
-#endif |
||||
- |
||||
-#include <grub/misc.h> |
||||
-#include <grub/command.h> |
||||
-#include <grub/err.h> |
||||
-#include <grub/mm.h> |
||||
-#include <grub/term.h> |
||||
-#include <grub/backtrace.h> |
||||
- |
||||
-#define MAX_STACK_FRAME 102400 |
||||
- |
||||
-void |
||||
-grub_backtrace_pointer (void *ebp) |
||||
-{ |
||||
- void *ptr, *nptr; |
||||
- unsigned i; |
||||
- |
||||
- ptr = ebp; |
||||
- while (1) |
||||
- { |
||||
- grub_printf ("%p: ", ptr); |
||||
- grub_backtrace_print_address (((void **) ptr)[1]); |
||||
- grub_printf (" ("); |
||||
- for (i = 0; i < 2; i++) |
||||
- grub_printf ("%p,", ((void **)ptr) [i + 2]); |
||||
- grub_printf ("%p)\n", ((void **)ptr) [i + 2]); |
||||
- nptr = *(void **)ptr; |
||||
- if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME |
||||
- || nptr == ptr) |
||||
- { |
||||
- grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); |
||||
- break; |
||||
- } |
||||
- ptr = nptr; |
||||
- } |
||||
-} |
||||
- |
||||
-void |
||||
-grub_backtrace (void) |
||||
-{ |
||||
-#ifdef __x86_64__ |
||||
- asm volatile ("movq %%rbp, %%rdi\n" |
||||
- "callq *%%rax": :"a"(grub_backtrace_pointer)); |
||||
-#else |
||||
- asm volatile ("movl %%ebp, %%eax\n" |
||||
- "calll *%%ecx": :"c"(grub_backtrace_pointer)); |
||||
-#endif |
||||
-} |
||||
- |
||||
diff --git a/include/grub/backtrace.h b/include/grub/backtrace.h |
||||
index 395519762f..275cf85e2d 100644 |
||||
--- a/include/grub/backtrace.h |
||||
+++ b/include/grub/backtrace.h |
||||
@@ -19,8 +19,14 @@ |
||||
#ifndef GRUB_BACKTRACE_HEADER |
||||
#define GRUB_BACKTRACE_HEADER 1 |
||||
|
||||
-void grub_backtrace (void); |
||||
-void grub_backtrace_pointer (void *ptr); |
||||
+#include <grub/symbol.h> |
||||
+#include <grub/types.h> |
||||
+ |
||||
+void EXPORT_FUNC(grub_debug_backtrace) (const char * const debug, |
||||
+ unsigned int skip); |
||||
+void EXPORT_FUNC(grub_backtrace) (unsigned int skip); |
||||
+void grub_backtrace_arch (unsigned int skip); |
||||
+void grub_backtrace_pointer (void *ptr, unsigned int skip); |
||||
void grub_backtrace_print_address (void *addr); |
||||
|
||||
#endif |
||||
diff --git a/include/grub/dl.h b/include/grub/dl.h |
||||
index 91933b85f2..2f76e6b043 100644 |
||||
--- a/include/grub/dl.h |
||||
+++ b/include/grub/dl.h |
||||
@@ -259,6 +259,8 @@ grub_dl_is_persistent (grub_dl_t mod) |
||||
|
||||
#endif |
||||
|
||||
+void * EXPORT_FUNC(grub_resolve_symbol) (const char *name); |
||||
+const char * EXPORT_FUNC(grub_get_symbol_by_addr) (const void *addr, int isfunc); |
||||
grub_err_t grub_dl_register_symbol (const char *name, void *addr, |
||||
int isfunc, grub_dl_t mod); |
||||
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h |
||||
index abbca5ea33..300a9766cd 100644 |
||||
--- a/include/grub/kernel.h |
||||
+++ b/include/grub/kernel.h |
||||
@@ -111,6 +111,9 @@ grub_addr_t grub_modules_get_end (void); |
||||
|
||||
#endif |
||||
|
||||
+void EXPORT_FUNC(start) (void); |
||||
+void EXPORT_FUNC(_start) (void); |
||||
+ |
||||
/* The start point of the C code. */ |
||||
void grub_main (void) __attribute__ ((noreturn)); |
||||
|
||||
diff --git a/grub-core/kern/arm/efi/startup.S b/grub-core/kern/arm/efi/startup.S |
||||
index 9f8265315a..f3bc41f9d0 100644 |
||||
--- a/grub-core/kern/arm/efi/startup.S |
||||
+++ b/grub-core/kern/arm/efi/startup.S |
||||
@@ -23,6 +23,8 @@ |
||||
.file "startup.S" |
||||
.text |
||||
.arm |
||||
+ .globl start, _start |
||||
+FUNCTION(start) |
||||
FUNCTION(_start) |
||||
/* |
||||
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in r1/r0. |
||||
diff --git a/grub-core/kern/arm/startup.S b/grub-core/kern/arm/startup.S |
||||
index 3946fe8e18..5679a1d00a 100644 |
||||
--- a/grub-core/kern/arm/startup.S |
||||
+++ b/grub-core/kern/arm/startup.S |
||||
@@ -48,6 +48,8 @@ |
||||
|
||||
.text |
||||
.arm |
||||
+ .globl start, _start |
||||
+FUNCTION(start) |
||||
FUNCTION(_start) |
||||
b codestart |
||||
|
||||
diff --git a/grub-core/kern/arm64/efi/startup.S b/grub-core/kern/arm64/efi/startup.S |
||||
index 666a7ee3c9..41676bdb2b 100644 |
||||
--- a/grub-core/kern/arm64/efi/startup.S |
||||
+++ b/grub-core/kern/arm64/efi/startup.S |
||||
@@ -19,7 +19,9 @@ |
||||
#include <grub/symbol.h> |
||||
|
||||
.file "startup.S" |
||||
+ .globl start, _start |
||||
.text |
||||
+FUNCTION(start) |
||||
FUNCTION(_start) |
||||
/* |
||||
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0. |
||||
diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S |
||||
index 0d89858d9b..939f182fc7 100644 |
||||
--- a/grub-core/kern/i386/qemu/startup.S |
||||
+++ b/grub-core/kern/i386/qemu/startup.S |
||||
@@ -24,7 +24,8 @@ |
||||
|
||||
.text |
||||
.code32 |
||||
- .globl _start |
||||
+ .globl start, _start |
||||
+start: |
||||
_start: |
||||
jmp codestart |
||||
|
||||
diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S |
||||
index d75c6d7cc7..8f2a593e52 100644 |
||||
--- a/grub-core/kern/ia64/efi/startup.S |
||||
+++ b/grub-core/kern/ia64/efi/startup.S |
||||
@@ -24,8 +24,9 @@ |
||||
.psr lsb |
||||
.lsb |
||||
|
||||
- .global _start |
||||
+ .global start, _start |
||||
.proc _start |
||||
+start: |
||||
_start: |
||||
alloc loc0=ar.pfs,2,4,0,0 |
||||
mov loc1=rp |
||||
diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S |
||||
index 03b916f053..701bf63abc 100644 |
||||
--- a/grub-core/kern/sparc64/ieee1275/crt0.S |
||||
+++ b/grub-core/kern/sparc64/ieee1275/crt0.S |
||||
@@ -22,7 +22,8 @@ |
||||
|
||||
.text |
||||
.align 4 |
||||
- .globl _start |
||||
+ .globl start, _start |
||||
+start: |
||||
_start: |
||||
ba codestart |
||||
mov %o4, %o0 |
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am |
||||
index ee88e44e97..bfd29a3bf0 100644 |
||||
--- a/grub-core/Makefile.am |
||||
+++ b/grub-core/Makefile.am |
||||
@@ -66,6 +66,7 @@ CLEANFILES += grub_script.yy.c grub_script.yy.h |
||||
|
||||
include $(srcdir)/Makefile.core.am |
||||
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/backtrace.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 9 Nov 2017 15:58:52 -0500 |
||||
Subject: [PATCH] normal: don't draw our startup message if debug is set |
||||
|
||||
--- |
||||
grub-core/normal/main.c | 3 +++ |
||||
1 file changed, 3 insertions(+) |
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c |
||||
index 55558cc0b9..af9792c963 100644 |
||||
--- a/grub-core/normal/main.c |
||||
+++ b/grub-core/normal/main.c |
||||
@@ -430,6 +430,9 @@ grub_normal_reader_init (int nested) |
||||
const char *msg_esc = _("ESC at any time exits."); |
||||
char *msg_formatted; |
||||
|
||||
+ if (grub_env_get ("debug") != NULL) |
||||
+ return 0; |
||||
+ |
||||
msg_formatted = grub_xasprintf (_("Minimal BASH-like line editing is supported. For " |
||||
"the first word, TAB lists possible command completions. Anywhere " |
||||
"else TAB lists possible device or file completions. %s"), |
@ -0,0 +1,137 @@
@@ -0,0 +1,137 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Fri, 16 Mar 2018 13:28:57 -0400 |
||||
Subject: [PATCH] Work around some minor include path weirdnesses |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
include/grub/arm/efi/console.h | 24 ++++++++++++++++++++++++ |
||||
include/grub/arm64/efi/console.h | 24 ++++++++++++++++++++++++ |
||||
include/grub/i386/efi/console.h | 24 ++++++++++++++++++++++++ |
||||
include/grub/x86_64/efi/console.h | 24 ++++++++++++++++++++++++ |
||||
4 files changed, 96 insertions(+) |
||||
create mode 100644 include/grub/arm/efi/console.h |
||||
create mode 100644 include/grub/arm64/efi/console.h |
||||
create mode 100644 include/grub/i386/efi/console.h |
||||
create mode 100644 include/grub/x86_64/efi/console.h |
||||
|
||||
diff --git a/include/grub/arm/efi/console.h b/include/grub/arm/efi/console.h |
||||
new file mode 100644 |
||||
index 0000000000..1592f6f76b |
||||
--- /dev/null |
||||
+++ b/include/grub/arm/efi/console.h |
||||
@@ -0,0 +1,24 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2002,2005,2006,2007 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/>. |
||||
+ */ |
||||
+ |
||||
+#ifndef GRUB_ARM_EFI_CONSOLE_H |
||||
+#define GRUB_ARM_EFI_CONSOLE_H |
||||
+ |
||||
+#include <efi/console.h> |
||||
+ |
||||
+#endif /* ! GRUB_ARM_EFI_CONSOLE_H */ |
||||
diff --git a/include/grub/arm64/efi/console.h b/include/grub/arm64/efi/console.h |
||||
new file mode 100644 |
||||
index 0000000000..9568933938 |
||||
--- /dev/null |
||||
+++ b/include/grub/arm64/efi/console.h |
||||
@@ -0,0 +1,24 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2002,2005,2006,2007 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/>. |
||||
+ */ |
||||
+ |
||||
+#ifndef GRUB_ARM64_EFI_CONSOLE_H |
||||
+#define GRUB_ARM64_EFI_CONSOLE_H |
||||
+ |
||||
+#include <efi/console.h> |
||||
+ |
||||
+#endif /* ! GRUB_ARM64_EFI_CONSOLE_H */ |
||||
diff --git a/include/grub/i386/efi/console.h b/include/grub/i386/efi/console.h |
||||
new file mode 100644 |
||||
index 0000000000..9231375cb0 |
||||
--- /dev/null |
||||
+++ b/include/grub/i386/efi/console.h |
||||
@@ -0,0 +1,24 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2002,2005,2006,2007 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/>. |
||||
+ */ |
||||
+ |
||||
+#ifndef GRUB_I386_EFI_CONSOLE_H |
||||
+#define GRUB_I386_EFI_CONSOLE_H |
||||
+ |
||||
+#include <efi/console.h> |
||||
+ |
||||
+#endif /* ! GRUB_I386_EFI_CONSOLE_H */ |
||||
diff --git a/include/grub/x86_64/efi/console.h b/include/grub/x86_64/efi/console.h |
||||
new file mode 100644 |
||||
index 0000000000..dba9d8678d |
||||
--- /dev/null |
||||
+++ b/include/grub/x86_64/efi/console.h |
||||
@@ -0,0 +1,24 @@ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2002,2005,2006,2007 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/>. |
||||
+ */ |
||||
+ |
||||
+#ifndef GRUB_X86_64_EFI_CONSOLE_H |
||||
+#define GRUB_X86_64_EFI_CONSOLE_H |
||||
+ |
||||
+#include <efi/console.h> |
||||
+ |
||||
+#endif /* ! GRUB_X86_64_EFI_CONSOLE_H */ |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 25 Jun 2015 15:41:06 -0400 |
||||
Subject: [PATCH] Make it possible to enabled --build-id=sha1 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
configure.ac | 8 ++++++++ |
||||
acinclude.m4 | 19 +++++++++++++++++++ |
||||
2 files changed, 27 insertions(+) |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 0d0e6782a1..302300711f 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -1442,7 +1442,15 @@ grub_PROG_TARGET_CC |
||||
if test "x$TARGET_APPLE_LINKER" != x1 ; then |
||||
grub_PROG_OBJCOPY_ABSOLUTE |
||||
fi |
||||
+ |
||||
+AC_ARG_ENABLE([build-id], |
||||
+ [AS_HELP_STRING([--enable-build-id], |
||||
+ [ask the linker to supply build-id notes (default=no)])]) |
||||
+if test x$enable_build_id = xyes; then |
||||
+grub_PROG_LD_BUILD_ID_SHA1 |
||||
+else |
||||
grub_PROG_LD_BUILD_ID_NONE |
||||
+fi |
||||
if test "x$target_cpu" = xi386; then |
||||
if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then |
||||
if test ! -z "$TARGET_IMG_LDSCRIPT"; then |
||||
diff --git a/acinclude.m4 b/acinclude.m4 |
||||
index 6e14bb553c..21238fcfd0 100644 |
||||
--- a/acinclude.m4 |
||||
+++ b/acinclude.m4 |
||||
@@ -136,6 +136,25 @@ if test "x$grub_cv_prog_ld_build_id_none" = xyes; then |
||||
fi |
||||
]) |
||||
|
||||
+dnl Supply --build-id=sha1 to ld if building modules. |
||||
+dnl This suppresses warnings from ld on some systems |
||||
+AC_DEFUN([grub_PROG_LD_BUILD_ID_SHA1], |
||||
+[AC_MSG_CHECKING([whether linker accepts --build-id=sha1]) |
||||
+AC_CACHE_VAL(grub_cv_prog_ld_build_id_sha1, |
||||
+[save_LDFLAGS="$LDFLAGS" |
||||
+LDFLAGS="$LDFLAGS -Wl,--build-id=sha1" |
||||
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], |
||||
+ [grub_cv_prog_ld_build_id_sha1=yes], |
||||
+ [grub_cv_prog_ld_build_id_sha1=no]) |
||||
+LDFLAGS="$save_LDFLAGS" |
||||
+]) |
||||
+AC_MSG_RESULT([$grub_cv_prog_ld_build_id_sha1]) |
||||
+ |
||||
+if test "x$grub_cv_prog_ld_build_id_sha1" = xyes; then |
||||
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,--build-id=sha1" |
||||
+fi |
||||
+]) |
||||
+ |
||||
dnl Check nm |
||||
AC_DEFUN([grub_PROG_NM_WORKS], |
||||
[AC_MSG_CHECKING([whether nm works]) |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Sun, 28 Jun 2015 13:09:58 -0400 |
||||
Subject: [PATCH] Add grub_qdprintf() - grub_dprintf() without the file+line |
||||
number. |
||||
|
||||
This just makes copy+paste of our debug loading info easier. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/misc.c | 18 ++++++++++++++++++ |
||||
include/grub/misc.h | 2 ++ |
||||
2 files changed, 20 insertions(+) |
||||
|
||||
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c |
||||
index a432a6be54..9a2fae6398 100644 |
||||
--- a/grub-core/kern/misc.c |
||||
+++ b/grub-core/kern/misc.c |
||||
@@ -191,6 +191,24 @@ grub_real_dprintf (const char *file, const int line, const char *condition, |
||||
} |
||||
} |
||||
|
||||
+void |
||||
+grub_qdprintf (const char *condition, const char *fmt, ...) |
||||
+{ |
||||
+ va_list args; |
||||
+ const char *debug = grub_env_get ("debug"); |
||||
+ |
||||
+ if (! debug) |
||||
+ return; |
||||
+ |
||||
+ if (grub_strword (debug, "all") || grub_strword (debug, condition)) |
||||
+ { |
||||
+ va_start (args, fmt); |
||||
+ grub_vprintf (fmt, args); |
||||
+ va_end (args); |
||||
+ grub_refresh (); |
||||
+ } |
||||
+} |
||||
+ |
||||
#define PREALLOC_SIZE 255 |
||||
|
||||
int |
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h |
||||
index fd18e6320b..3adc4036e3 100644 |
||||
--- a/include/grub/misc.h |
||||
+++ b/include/grub/misc.h |
||||
@@ -345,6 +345,8 @@ void EXPORT_FUNC(grub_real_dprintf) (const char *file, |
||||
const int line, |
||||
const char *condition, |
||||
const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); |
||||
+void EXPORT_FUNC(grub_qdprintf) (const char *condition, |
||||
+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 2, 3))); |
||||
int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); |
||||
int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) |
||||
__attribute__ ((format (GNU_PRINTF, 3, 4))); |
@ -0,0 +1,178 @@
@@ -0,0 +1,178 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 25 Jun 2015 15:11:36 -0400 |
||||
Subject: [PATCH] Make a "gdb" dprintf that tells us load addresses. |
||||
|
||||
This makes a grub_dprintf() call during platform init and during module |
||||
loading that tells us the virtual addresses of the .text and .data |
||||
sections of grub-core/kernel.exec and any modules it loads. |
||||
|
||||
Specifically, it displays them in the gdb "add-symbol-file" syntax, with |
||||
the presumption that there's a variable $grubdir that reflects the path |
||||
to any such binaries. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/dl.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ |
||||
grub-core/kern/efi/efi.c | 4 ++-- |
||||
grub-core/kern/efi/init.c | 26 +++++++++++++++++++++++- |
||||
include/grub/efi/efi.h | 2 +- |
||||
4 files changed, 78 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c |
||||
index 88d2077709..9557254035 100644 |
||||
--- a/grub-core/kern/dl.c |
||||
+++ b/grub-core/kern/dl.c |
||||
@@ -501,6 +501,23 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name) |
||||
return s; |
||||
return NULL; |
||||
} |
||||
+static long |
||||
+grub_dl_find_section_index (Elf_Ehdr *e, const char *name) |
||||
+{ |
||||
+ Elf_Shdr *s; |
||||
+ const char *str; |
||||
+ unsigned i; |
||||
+ |
||||
+ s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); |
||||
+ str = (char *) e + s->sh_offset; |
||||
+ |
||||
+ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); |
||||
+ i < e->e_shnum; |
||||
+ i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) |
||||
+ if (grub_strcmp (str + s->sh_name, name) == 0) |
||||
+ return (long)i; |
||||
+ return -1; |
||||
+} |
||||
|
||||
/* Me, Vladimir Serbinenko, hereby I add this module check as per new |
||||
GNU module policy. Note that this license check is informative only. |
||||
@@ -653,6 +670,37 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) |
||||
|
||||
return GRUB_ERR_NONE; |
||||
} |
||||
+static void |
||||
+grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e) |
||||
+{ |
||||
+ void *text, *data = NULL; |
||||
+ long idx; |
||||
+ |
||||
+ idx = grub_dl_find_section_index (e, ".text"); |
||||
+ if (idx < 0) |
||||
+ return; |
||||
+ |
||||
+ text = grub_dl_get_section_addr (mod, idx); |
||||
+ if (!text) |
||||
+ return; |
||||
+ |
||||
+ idx = grub_dl_find_section_index (e, ".data"); |
||||
+ if (idx >= 0) |
||||
+ data = grub_dl_get_section_addr (mod, idx); |
||||
+ |
||||
+ if (data) |
||||
+ grub_qdprintf ("gdb", "add-symbol-file \\\n" |
||||
+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug " |
||||
+ "\\\n %p -s .data %p\n", |
||||
+ GRUB_TARGET_CPU, GRUB_PLATFORM, |
||||
+ mod->name, text, data); |
||||
+ else |
||||
+ grub_qdprintf ("gdb", "add-symbol-file \\\n" |
||||
+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug " |
||||
+ "\\\n%p\n", |
||||
+ GRUB_TARGET_CPU, GRUB_PLATFORM, |
||||
+ mod->name, text); |
||||
+} |
||||
|
||||
/* Load a module from core memory. */ |
||||
grub_dl_t |
||||
@@ -712,6 +760,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) |
||||
grub_dprintf ("modules", "module name: %s\n", mod->name); |
||||
grub_dprintf ("modules", "init function: %p\n", mod->init); |
||||
|
||||
+ grub_dl_print_gdb_info (mod, e); |
||||
+ |
||||
if (grub_dl_add (mod)) |
||||
{ |
||||
grub_dl_unload (mod); |
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c |
||||
index ae9885edb8..d6a2fb5778 100644 |
||||
--- a/grub-core/kern/efi/efi.c |
||||
+++ b/grub-core/kern/efi/efi.c |
||||
@@ -296,7 +296,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, |
||||
/* Search the mods section from the PE32/PE32+ image. This code uses |
||||
a PE32 header, but should work with PE32+ as well. */ |
||||
grub_addr_t |
||||
-grub_efi_modules_addr (void) |
||||
+grub_efi_section_addr (const char *section_name) |
||||
{ |
||||
grub_efi_loaded_image_t *image; |
||||
struct grub_pe32_header *header; |
||||
@@ -321,7 +321,7 @@ grub_efi_modules_addr (void) |
||||
i < coff_header->num_sections; |
||||
i++, section++) |
||||
{ |
||||
- if (grub_strcmp (section->name, "mods") == 0) |
||||
+ if (grub_strcmp (section->name, section_name) == 0) |
||||
break; |
||||
} |
||||
|
||||
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c |
||||
index 6d39bd3ad2..2d12e6188f 100644 |
||||
--- a/grub-core/kern/efi/init.c |
||||
+++ b/grub-core/kern/efi/init.c |
||||
@@ -115,10 +115,33 @@ grub_efi_env_init (void) |
||||
grub_free (envblk_s.buf); |
||||
} |
||||
|
||||
+static void |
||||
+grub_efi_print_gdb_info (void) |
||||
+{ |
||||
+ grub_addr_t text; |
||||
+ grub_addr_t data; |
||||
+ |
||||
+ text = grub_efi_section_addr (".text"); |
||||
+ if (!text) |
||||
+ return; |
||||
+ |
||||
+ data = grub_efi_section_addr (".data"); |
||||
+ if (data) |
||||
+ grub_qdprintf ("gdb", |
||||
+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/" |
||||
+ "kernel.exec %p -s .data %p\n", |
||||
+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text, (void *)data); |
||||
+ else |
||||
+ grub_qdprintf ("gdb", |
||||
+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/" |
||||
+ "kernel.exec %p\n", |
||||
+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text); |
||||
+} |
||||
+ |
||||
void |
||||
grub_efi_init (void) |
||||
{ |
||||
- grub_modbase = grub_efi_modules_addr (); |
||||
+ grub_modbase = grub_efi_section_addr ("mods"); |
||||
/* First of all, initialize the console so that GRUB can display |
||||
messages. */ |
||||
grub_console_init (); |
||||
@@ -142,6 +165,7 @@ grub_efi_init (void) |
||||
0, 0, 0, NULL); |
||||
|
||||
grub_efi_env_init (); |
||||
+ grub_efi_print_gdb_info (); |
||||
grub_efidisk_init (); |
||||
} |
||||
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
||||
index 03f9a9d011..2e0691454b 100644 |
||||
--- a/include/grub/efi/efi.h |
||||
+++ b/include/grub/efi/efi.h |
||||
@@ -138,7 +138,7 @@ grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); |
||||
grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); |
||||
#endif |
||||
|
||||
-grub_addr_t grub_efi_modules_addr (void); |
||||
+grub_addr_t grub_efi_section_addr (const char *section); |
||||
|
||||
void grub_efi_mm_init (void); |
||||
void grub_efi_mm_fini (void); |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 10 May 2018 13:40:19 -0400 |
||||
Subject: [PATCH] Fixup for newer compiler |
||||
|
||||
--- |
||||
grub-core/fs/btrfs.c | 2 +- |
||||
include/grub/gpt_partition.h | 2 +- |
||||
2 files changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c |
||||
index 2b21cbaa67..4cc86e9b79 100644 |
||||
--- a/grub-core/fs/btrfs.c |
||||
+++ b/grub-core/fs/btrfs.c |
||||
@@ -218,7 +218,7 @@ struct grub_btrfs_inode |
||||
grub_uint64_t size; |
||||
grub_uint8_t dummy2[0x70]; |
||||
struct grub_btrfs_time mtime; |
||||
-} GRUB_PACKED; |
||||
+} GRUB_PACKED __attribute__ ((aligned(8))); |
||||
|
||||
struct grub_btrfs_extent_data |
||||
{ |
||||
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h |
||||
index 7a93f43291..8212697bf6 100644 |
||||
--- a/include/grub/gpt_partition.h |
||||
+++ b/include/grub/gpt_partition.h |
||||
@@ -76,7 +76,7 @@ struct grub_gpt_partentry |
||||
grub_uint64_t end; |
||||
grub_uint64_t attrib; |
||||
char name[72]; |
||||
-} GRUB_PACKED; |
||||
+} GRUB_PACKED __attribute__ ((aligned(8))); |
||||
|
||||
grub_err_t |
||||
grub_gpt_partition_map_iterate (grub_disk_t disk, |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Javier Martinez Canillas <javierm@redhat.com> |
||||
Date: Sat, 12 May 2018 11:29:07 +0200 |
||||
Subject: [PATCH] Don't attempt to export the start and _start symbols for |
||||
grub-emu |
||||
|
||||
Commit 318ee04aadc ("make better backtraces") reworked the backtrace logic |
||||
but the changes lead to the following build error on the grub-emu platform: |
||||
|
||||
grub_emu_lite-symlist.o:(.data+0xf08): undefined reference to `start' |
||||
collect2: error: ld returned 1 exit status |
||||
make[3]: *** [Makefile:25959: grub-emu-lite] Error 1 |
||||
make[3]: *** Waiting for unfinished jobs.... |
||||
cat kernel_syms.input | grep -v '^#' | sed -n \ |
||||
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '""'\1/;p;}' \ |
||||
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '""'\1/;p;}' \ |
||||
| sort -u >kernel_syms.lst |
||||
|
||||
The problem is that start and _start symbols are exported unconditionally, |
||||
but these aren't defined for grub-emu since is an emultaed platform so it |
||||
doesn't have a startup logic. Don't attempt to export those for grub-emu. |
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
--- |
||||
include/grub/kernel.h | 2 ++ |
||||
1 file changed, 2 insertions(+) |
||||
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h |
||||
index 300a9766cd..55849777ea 100644 |
||||
--- a/include/grub/kernel.h |
||||
+++ b/include/grub/kernel.h |
||||
@@ -111,8 +111,10 @@ grub_addr_t grub_modules_get_end (void); |
||||
|
||||
#endif |
||||
|
||||
+#if !defined(GRUB_MACHINE_EMU) |
||||
void EXPORT_FUNC(start) (void); |
||||
void EXPORT_FUNC(_start) (void); |
||||
+#endif |
||||
|
||||
/* The start point of the C code. */ |
||||
void grub_main (void) __attribute__ ((noreturn)); |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 10 May 2018 13:40:19 -0400 |
||||
Subject: [PATCH] Fixup for newer compiler |
||||
|
||||
--- |
||||
conf/Makefile.common | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/conf/Makefile.common b/conf/Makefile.common |
||||
index 191b1a70c6..5f0ef96985 100644 |
||||
--- a/conf/Makefile.common |
||||
+++ b/conf/Makefile.common |
||||
@@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding |
||||
LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) |
||||
CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 |
||||
CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) |
||||
-STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx |
||||
+STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -R .note.gnu.property -R .gnu.build.attributes |
||||
|
||||
CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding |
||||
LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d |
@ -0,0 +1,766 @@
@@ -0,0 +1,766 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Andrzej Kacprowski <andrzej.kacprowski@intel.com> |
||||
Date: Wed, 10 Jul 2019 15:22:29 +0200 |
||||
Subject: [PATCH] Add support for non-Ethernet network cards |
||||
|
||||
This patch replaces fixed 6-byte link layer address with |
||||
up to 32-byte variable sized address. |
||||
This allows supporting Infiniband and Omni-Path fabric |
||||
which use 20-byte address, but other network card types |
||||
can also take advantage of this change. |
||||
The network card driver is responsible for replacing L2 |
||||
header provided by grub2 if needed. |
||||
This approach is compatible with UEFI network stack which |
||||
also allows up to 32-byte variable size link address. |
||||
|
||||
The BOOTP/DHCP packet format is limited to 16 byte client |
||||
hardware address, if link address is more that 16-bytes |
||||
then chaddr field in BOOTP it will be set to 0 as per rfc4390. |
||||
|
||||
Resolves: rhbz#1370642 |
||||
|
||||
Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@intel.com> |
||||
[msalter: Fix max string calculation in grub_net_hwaddr_to_str] |
||||
Signed-off-by: Mark Salter <msalter@redhat.com> |
||||
--- |
||||
grub-core/net/arp.c | 155 ++++++++++++++++++++++----------- |
||||
grub-core/net/bootp.c | 15 ++-- |
||||
grub-core/net/drivers/efi/efinet.c | 8 +- |
||||
grub-core/net/drivers/emu/emunet.c | 1 + |
||||
grub-core/net/drivers/i386/pc/pxe.c | 13 +-- |
||||
grub-core/net/drivers/ieee1275/ofnet.c | 2 + |
||||
grub-core/net/drivers/uboot/ubootnet.c | 1 + |
||||
grub-core/net/ethernet.c | 88 +++++++++---------- |
||||
grub-core/net/icmp6.c | 15 ++-- |
||||
grub-core/net/ip.c | 4 +- |
||||
grub-core/net/net.c | 50 ++++++----- |
||||
include/grub/net.h | 19 ++-- |
||||
12 files changed, 219 insertions(+), 152 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c |
||||
index 54306e3b16..67b409a8ac 100644 |
||||
--- a/grub-core/net/arp.c |
||||
+++ b/grub-core/net/arp.c |
||||
@@ -31,22 +31,12 @@ enum |
||||
ARP_REPLY = 2 |
||||
}; |
||||
|
||||
-enum |
||||
- { |
||||
- /* IANA ARP constant to define hardware type as ethernet. */ |
||||
- GRUB_NET_ARPHRD_ETHERNET = 1 |
||||
- }; |
||||
- |
||||
-struct arppkt { |
||||
+struct arphdr { |
||||
grub_uint16_t hrd; |
||||
grub_uint16_t pro; |
||||
grub_uint8_t hln; |
||||
grub_uint8_t pln; |
||||
grub_uint16_t op; |
||||
- grub_uint8_t sender_mac[6]; |
||||
- grub_uint32_t sender_ip; |
||||
- grub_uint8_t recv_mac[6]; |
||||
- grub_uint32_t recv_ip; |
||||
} GRUB_PACKED; |
||||
|
||||
static int have_pending; |
||||
@@ -57,12 +47,16 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, |
||||
const grub_net_network_level_address_t *proto_addr) |
||||
{ |
||||
struct grub_net_buff nb; |
||||
- struct arppkt *arp_packet; |
||||
+ struct arphdr *arp_header; |
||||
grub_net_link_level_address_t target_mac_addr; |
||||
grub_err_t err; |
||||
int i; |
||||
grub_uint8_t *nbd; |
||||
grub_uint8_t arp_data[128]; |
||||
+ grub_uint8_t hln; |
||||
+ grub_uint8_t pln; |
||||
+ grub_uint8_t arp_packet_len; |
||||
+ grub_uint8_t *tmp_ptr; |
||||
|
||||
if (proto_addr->type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) |
||||
return grub_error (GRUB_ERR_BUG, "unsupported address family"); |
||||
@@ -73,23 +67,39 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, |
||||
grub_netbuff_clear (&nb); |
||||
grub_netbuff_reserve (&nb, 128); |
||||
|
||||
- err = grub_netbuff_push (&nb, sizeof (*arp_packet)); |
||||
+ hln = inf->card->default_address.len; |
||||
+ pln = sizeof (proto_addr->ipv4); |
||||
+ arp_packet_len = sizeof (*arp_header) + 2 * (hln + pln); |
||||
+ |
||||
+ err = grub_netbuff_push (&nb, arp_packet_len); |
||||
if (err) |
||||
return err; |
||||
|
||||
- arp_packet = (struct arppkt *) nb.data; |
||||
- arp_packet->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); |
||||
- arp_packet->hln = 6; |
||||
- arp_packet->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); |
||||
- arp_packet->pln = 4; |
||||
- arp_packet->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); |
||||
- /* Sender hardware address. */ |
||||
- grub_memcpy (arp_packet->sender_mac, &inf->hwaddress.mac, 6); |
||||
- arp_packet->sender_ip = inf->address.ipv4; |
||||
- grub_memset (arp_packet->recv_mac, 0, 6); |
||||
- arp_packet->recv_ip = proto_addr->ipv4; |
||||
- /* Target protocol address */ |
||||
- grub_memset (&target_mac_addr.mac, 0xff, 6); |
||||
+ arp_header = (struct arphdr *) nb.data; |
||||
+ arp_header->hrd = grub_cpu_to_be16 (inf->card->default_address.type); |
||||
+ arp_header->hln = hln; |
||||
+ arp_header->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); |
||||
+ arp_header->pln = pln; |
||||
+ arp_header->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); |
||||
+ tmp_ptr = nb.data + sizeof (*arp_header); |
||||
+ |
||||
+ /* The source hardware address. */ |
||||
+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln); |
||||
+ tmp_ptr += hln; |
||||
+ |
||||
+ /* The source protocol address. */ |
||||
+ grub_memcpy (tmp_ptr, &inf->address.ipv4, pln); |
||||
+ tmp_ptr += pln; |
||||
+ |
||||
+ /* The target hardware address. */ |
||||
+ grub_memset (tmp_ptr, 0, hln); |
||||
+ tmp_ptr += hln; |
||||
+ |
||||
+ /* The target protocol address */ |
||||
+ grub_memcpy (tmp_ptr, &proto_addr->ipv4, pln); |
||||
+ tmp_ptr += pln; |
||||
+ |
||||
+ grub_memset (&target_mac_addr.mac, 0xff, hln); |
||||
|
||||
nbd = nb.data; |
||||
send_ethernet_packet (inf, &nb, target_mac_addr, GRUB_NET_ETHERTYPE_ARP); |
||||
@@ -114,28 +124,53 @@ grub_err_t |
||||
grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, |
||||
grub_uint16_t *vlantag) |
||||
{ |
||||
- struct arppkt *arp_packet = (struct arppkt *) nb->data; |
||||
+ struct arphdr *arp_header = (struct arphdr *) nb->data; |
||||
grub_net_network_level_address_t sender_addr, target_addr; |
||||
grub_net_link_level_address_t sender_mac_addr; |
||||
struct grub_net_network_level_interface *inf; |
||||
+ grub_uint16_t hw_type; |
||||
+ grub_uint8_t hln; |
||||
+ grub_uint8_t pln; |
||||
+ grub_uint8_t arp_packet_len; |
||||
+ grub_uint8_t *tmp_ptr; |
||||
|
||||
- if (arp_packet->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) |
||||
- || arp_packet->pln != 4 || arp_packet->hln != 6 |
||||
- || nb->tail - nb->data < (int) sizeof (*arp_packet)) |
||||
+ hw_type = card->default_address.type; |
||||
+ hln = card->default_address.len; |
||||
+ pln = sizeof(sender_addr.ipv4); |
||||
+ arp_packet_len = sizeof (*arp_header) + 2 * (pln + hln); |
||||
+ |
||||
+ if (arp_header->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) |
||||
+ || arp_header->hrd != grub_cpu_to_be16 (hw_type) |
||||
+ || arp_header->hln != hln || arp_header->pln != pln |
||||
+ || nb->tail - nb->data < (int) arp_packet_len) { |
||||
return GRUB_ERR_NONE; |
||||
+ } |
||||
|
||||
+ tmp_ptr = nb->data + sizeof (*arp_header); |
||||
+ |
||||
+ /* The source hardware address. */ |
||||
+ sender_mac_addr.type = hw_type; |
||||
+ sender_mac_addr.len = hln; |
||||
+ grub_memcpy (sender_mac_addr.mac, tmp_ptr, hln); |
||||
+ tmp_ptr += hln; |
||||
+ |
||||
+ /* The source protocol address. */ |
||||
sender_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; |
||||
+ grub_memcpy(&sender_addr.ipv4, tmp_ptr, pln); |
||||
+ tmp_ptr += pln; |
||||
+ |
||||
+ grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); |
||||
+ |
||||
+ /* The target hardware address. */ |
||||
+ tmp_ptr += hln; |
||||
+ |
||||
+ /* The target protocol address. */ |
||||
target_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; |
||||
- sender_addr.ipv4 = arp_packet->sender_ip; |
||||
- target_addr.ipv4 = arp_packet->recv_ip; |
||||
- if (arp_packet->sender_ip == pending_req) |
||||
+ grub_memcpy(&target_addr.ipv4, tmp_ptr, pln); |
||||
+ |
||||
+ if (sender_addr.ipv4 == pending_req) |
||||
have_pending = 1; |
||||
|
||||
- sender_mac_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (sender_mac_addr.mac, arp_packet->sender_mac, |
||||
- sizeof (sender_mac_addr.mac)); |
||||
- grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); |
||||
- |
||||
FOR_NET_NETWORK_LEVEL_INTERFACES (inf) |
||||
{ |
||||
/* Verify vlantag id */ |
||||
@@ -148,11 +183,11 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, |
||||
|
||||
/* Am I the protocol address target? */ |
||||
if (grub_net_addr_cmp (&inf->address, &target_addr) == 0 |
||||
- && arp_packet->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) |
||||
+ && arp_header->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) |
||||
{ |
||||
grub_net_link_level_address_t target; |
||||
struct grub_net_buff nb_reply; |
||||
- struct arppkt *arp_reply; |
||||
+ struct arphdr *arp_reply; |
||||
grub_uint8_t arp_data[128]; |
||||
grub_err_t err; |
||||
|
||||
@@ -161,25 +196,39 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, |
||||
grub_netbuff_clear (&nb_reply); |
||||
grub_netbuff_reserve (&nb_reply, 128); |
||||
|
||||
- err = grub_netbuff_push (&nb_reply, sizeof (*arp_packet)); |
||||
+ err = grub_netbuff_push (&nb_reply, arp_packet_len); |
||||
if (err) |
||||
return err; |
||||
|
||||
- arp_reply = (struct arppkt *) nb_reply.data; |
||||
+ arp_reply = (struct arphdr *) nb_reply.data; |
||||
|
||||
- arp_reply->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); |
||||
+ arp_reply->hrd = grub_cpu_to_be16 (hw_type); |
||||
arp_reply->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); |
||||
- arp_reply->pln = 4; |
||||
- arp_reply->hln = 6; |
||||
+ arp_reply->pln = pln; |
||||
+ arp_reply->hln = hln; |
||||
arp_reply->op = grub_cpu_to_be16_compile_time (ARP_REPLY); |
||||
- arp_reply->sender_ip = arp_packet->recv_ip; |
||||
- arp_reply->recv_ip = arp_packet->sender_ip; |
||||
- arp_reply->hln = 6; |
||||
- |
||||
- target.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (target.mac, arp_packet->sender_mac, 6); |
||||
- grub_memcpy (arp_reply->sender_mac, inf->hwaddress.mac, 6); |
||||
- grub_memcpy (arp_reply->recv_mac, arp_packet->sender_mac, 6); |
||||
+ |
||||
+ tmp_ptr = nb_reply.data + sizeof (*arp_reply); |
||||
+ |
||||
+ /* The source hardware address. */ |
||||
+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln); |
||||
+ tmp_ptr += hln; |
||||
+ |
||||
+ /* The source protocol address. */ |
||||
+ grub_memcpy (tmp_ptr, &target_addr.ipv4, pln); |
||||
+ tmp_ptr += pln; |
||||
+ |
||||
+ /* The target hardware address. */ |
||||
+ grub_memcpy (tmp_ptr, sender_mac_addr.mac, hln); |
||||
+ tmp_ptr += hln; |
||||
+ |
||||
+ /* The target protocol address */ |
||||
+ grub_memcpy (tmp_ptr, &sender_addr.ipv4, pln); |
||||
+ tmp_ptr += pln; |
||||
+ |
||||
+ target.type = hw_type; |
||||
+ target.len = hln; |
||||
+ grub_memcpy (target.mac, sender_mac_addr.mac, hln); |
||||
|
||||
/* Change operation to REPLY and send packet */ |
||||
send_ethernet_packet (inf, &nb_reply, target, GRUB_NET_ETHERTYPE_ARP); |
||||
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c |
||||
index e28fb6a09f..08b6b2b5d6 100644 |
||||
--- a/grub-core/net/bootp.c |
||||
+++ b/grub-core/net/bootp.c |
||||
@@ -233,7 +233,6 @@ grub_net_configure_by_dhcp_ack (const char *name, |
||||
int is_def, char **device, char **path) |
||||
{ |
||||
grub_net_network_level_address_t addr; |
||||
- grub_net_link_level_address_t hwaddr; |
||||
struct grub_net_network_level_interface *inter; |
||||
int mask = -1; |
||||
char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; |
||||
@@ -250,12 +249,8 @@ grub_net_configure_by_dhcp_ack (const char *name, |
||||
if (path) |
||||
*path = 0; |
||||
|
||||
- grub_memcpy (hwaddr.mac, bp->mac_addr, |
||||
- bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len |
||||
- : sizeof (hwaddr.mac)); |
||||
- hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- |
||||
- inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); |
||||
+ grub_dprintf("dhcp", "configuring dhcp for %s\n", name); |
||||
+ inter = grub_net_add_addr (name, card, &addr, &card->default_address, flags); |
||||
if (!inter) |
||||
return 0; |
||||
|
||||
@@ -567,7 +562,9 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) |
||||
grub_memset (pack, 0, sizeof (*pack)); |
||||
pack->opcode = 1; |
||||
pack->hw_type = 1; |
||||
- pack->hw_len = 6; |
||||
+ pack->hw_len = iface->hwaddress.len > 16 ? 0 |
||||
+ : iface->hwaddress.len; |
||||
+ |
||||
err = grub_get_datetime (&date); |
||||
if (err || !grub_datetime2unixtime (&date, &t)) |
||||
{ |
||||
@@ -580,7 +577,7 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) |
||||
else |
||||
pack->ident = iface->xid; |
||||
|
||||
- grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); |
||||
+ grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, pack->hw_len); |
||||
|
||||
grub_netbuff_push (nb, sizeof (*udph)); |
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
||||
index 173fb63153..a673bea807 100644 |
||||
--- a/grub-core/net/drivers/efi/efinet.c |
||||
+++ b/grub-core/net/drivers/efi/efinet.c |
||||
@@ -279,6 +279,9 @@ grub_efinet_findcards (void) |
||||
/* This should not happen... Why? */ |
||||
continue; |
||||
|
||||
+ if (net->mode->hwaddr_size > GRUB_NET_MAX_LINK_ADDRESS_SIZE) |
||||
+ continue; |
||||
+ |
||||
if (net->mode->state == GRUB_EFI_NETWORK_STOPPED |
||||
&& efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) |
||||
continue; |
||||
@@ -315,10 +318,11 @@ grub_efinet_findcards (void) |
||||
card->name = grub_xasprintf ("efinet%d", i++); |
||||
card->driver = &efidriver; |
||||
card->flags = 0; |
||||
- card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
+ card->default_address.type = net->mode->if_type; |
||||
+ card->default_address.len = net->mode->hwaddr_size; |
||||
grub_memcpy (card->default_address.mac, |
||||
net->mode->current_address, |
||||
- sizeof (card->default_address.mac)); |
||||
+ net->mode->hwaddr_size); |
||||
card->efi_net = net; |
||||
card->efi_handle = *handle; |
||||
|
||||
diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c |
||||
index b194920861..5b6c5e16a6 100644 |
||||
--- a/grub-core/net/drivers/emu/emunet.c |
||||
+++ b/grub-core/net/drivers/emu/emunet.c |
||||
@@ -46,6 +46,7 @@ static struct grub_net_card emucard = |
||||
.mtu = 1500, |
||||
.default_address = { |
||||
.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, |
||||
+ . len = 6, |
||||
{.mac = {0, 1, 2, 3, 4, 5}} |
||||
}, |
||||
.flags = 0 |
||||
diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c |
||||
index 3f4152d036..9f8fb4b6d2 100644 |
||||
--- a/grub-core/net/drivers/i386/pc/pxe.c |
||||
+++ b/grub-core/net/drivers/i386/pc/pxe.c |
||||
@@ -386,20 +386,21 @@ GRUB_MOD_INIT(pxe) |
||||
grub_memset (ui, 0, sizeof (*ui)); |
||||
grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry); |
||||
|
||||
+ grub_pxe_card.default_address.len = 6; |
||||
grub_memcpy (grub_pxe_card.default_address.mac, ui->current_addr, |
||||
- sizeof (grub_pxe_card.default_address.mac)); |
||||
- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) |
||||
+ grub_pxe_card.default_address.len); |
||||
+ for (i = 0; i < grub_pxe_card.default_address.len; i++) |
||||
if (grub_pxe_card.default_address.mac[i] != 0) |
||||
break; |
||||
- if (i != sizeof (grub_pxe_card.default_address.mac)) |
||||
+ if (i != grub_pxe_card.default_address.len) |
||||
{ |
||||
- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) |
||||
+ for (i = 0; i < grub_pxe_card.default_address.len; i++) |
||||
if (grub_pxe_card.default_address.mac[i] != 0xff) |
||||
break; |
||||
} |
||||
- if (i == sizeof (grub_pxe_card.default_address.mac)) |
||||
+ if (i == grub_pxe_card.default_address.len) |
||||
grub_memcpy (grub_pxe_card.default_address.mac, ui->permanent_addr, |
||||
- sizeof (grub_pxe_card.default_address.mac)); |
||||
+ grub_pxe_card.default_address.len); |
||||
grub_pxe_card.mtu = ui->mtu; |
||||
|
||||
grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c |
||||
index 3860b6f78d..bcb3f9ea02 100644 |
||||
--- a/grub-core/net/drivers/ieee1275/ofnet.c |
||||
+++ b/grub-core/net/drivers/ieee1275/ofnet.c |
||||
@@ -160,6 +160,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, |
||||
grub_uint16_t vlantag = 0; |
||||
|
||||
hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
+ hw_addr.len = 6; |
||||
|
||||
args = bootpath + grub_strlen (devpath) + 1; |
||||
do |
||||
@@ -503,6 +504,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias) |
||||
grub_memcpy (&lla.mac, pprop, 6); |
||||
|
||||
lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
+ lla.len = 6; |
||||
card->default_address = lla; |
||||
|
||||
card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; |
||||
diff --git a/grub-core/net/drivers/uboot/ubootnet.c b/grub-core/net/drivers/uboot/ubootnet.c |
||||
index 056052e40d..22ebcbf211 100644 |
||||
--- a/grub-core/net/drivers/uboot/ubootnet.c |
||||
+++ b/grub-core/net/drivers/uboot/ubootnet.c |
||||
@@ -131,6 +131,7 @@ GRUB_MOD_INIT (ubootnet) |
||||
|
||||
grub_memcpy (&(card->default_address.mac), &devinfo->di_net.hwaddr, 6); |
||||
card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
+ card->default_address.len = 6; |
||||
|
||||
card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; |
||||
card->txbuf = grub_zalloc (card->txbufsize); |
||||
diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c |
||||
index 4d7ceed6f9..9aae83a5eb 100644 |
||||
--- a/grub-core/net/ethernet.c |
||||
+++ b/grub-core/net/ethernet.c |
||||
@@ -29,13 +29,6 @@ |
||||
|
||||
#define LLCADDRMASK 0x7f |
||||
|
||||
-struct etherhdr |
||||
-{ |
||||
- grub_uint8_t dst[6]; |
||||
- grub_uint8_t src[6]; |
||||
- grub_uint16_t type; |
||||
-} GRUB_PACKED; |
||||
- |
||||
struct llchdr |
||||
{ |
||||
grub_uint8_t dsap; |
||||
@@ -55,13 +48,15 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, |
||||
grub_net_link_level_address_t target_addr, |
||||
grub_net_ethertype_t ethertype) |
||||
{ |
||||
- struct etherhdr *eth; |
||||
+ grub_uint8_t *eth; |
||||
grub_err_t err; |
||||
- grub_uint8_t etherhdr_size; |
||||
- grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; |
||||
+ grub_uint32_t vlantag = 0; |
||||
+ grub_uint8_t hw_addr_len = inf->card->default_address.len; |
||||
+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2; |
||||
|
||||
- etherhdr_size = sizeof (*eth); |
||||
- COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); |
||||
+ /* Source and destination link addresses + ethertype + vlan tag */ |
||||
+ COMPILE_TIME_ASSERT ((GRUB_NET_MAX_LINK_ADDRESS_SIZE * 2 + 2 + 4) < |
||||
+ GRUB_NET_MAX_LINK_HEADER_SIZE); |
||||
|
||||
/* Increase ethernet header in case of vlantag */ |
||||
if (inf->vlantag != 0) |
||||
@@ -70,11 +65,22 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, |
||||
err = grub_netbuff_push (nb, etherhdr_size); |
||||
if (err) |
||||
return err; |
||||
- eth = (struct etherhdr *) nb->data; |
||||
- grub_memcpy (eth->dst, target_addr.mac, 6); |
||||
- grub_memcpy (eth->src, inf->hwaddress.mac, 6); |
||||
+ eth = nb->data; |
||||
+ grub_memcpy (eth, target_addr.mac, hw_addr_len); |
||||
+ eth += hw_addr_len; |
||||
+ grub_memcpy (eth, inf->hwaddress.mac, hw_addr_len); |
||||
+ eth += hw_addr_len; |
||||
+ |
||||
+ /* Check if a vlan-tag is present. */ |
||||
+ if (vlantag != 0) |
||||
+ { |
||||
+ *((grub_uint32_t *)eth) = grub_cpu_to_be32 (vlantag); |
||||
+ eth += sizeof (vlantag); |
||||
+ } |
||||
+ |
||||
+ /* Write ethertype */ |
||||
+ *((grub_uint16_t*) eth) = grub_cpu_to_be16 (ethertype); |
||||
|
||||
- eth->type = grub_cpu_to_be16 (ethertype); |
||||
if (!inf->card->opened) |
||||
{ |
||||
err = GRUB_ERR_NONE; |
||||
@@ -85,18 +91,6 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, |
||||
inf->card->opened = 1; |
||||
} |
||||
|
||||
- /* Check and add a vlan-tag if needed. */ |
||||
- if (inf->vlantag != 0) |
||||
- { |
||||
- /* Move eth type to the right */ |
||||
- grub_memcpy ((char *) nb->data + etherhdr_size - 2, |
||||
- (char *) nb->data + etherhdr_size - 6, 2); |
||||
- |
||||
- /* Add the tag in the middle */ |
||||
- grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); |
||||
- grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2); |
||||
- } |
||||
- |
||||
return inf->card->driver->send (inf->card, nb); |
||||
} |
||||
|
||||
@@ -104,31 +98,40 @@ grub_err_t |
||||
grub_net_recv_ethernet_packet (struct grub_net_buff *nb, |
||||
struct grub_net_card *card) |
||||
{ |
||||
- struct etherhdr *eth; |
||||
+ grub_uint8_t *eth; |
||||
struct llchdr *llch; |
||||
struct snaphdr *snaph; |
||||
grub_net_ethertype_t type; |
||||
grub_net_link_level_address_t hwaddress; |
||||
grub_net_link_level_address_t src_hwaddress; |
||||
grub_err_t err; |
||||
- grub_uint8_t etherhdr_size = sizeof (*eth); |
||||
+ grub_uint8_t hw_addr_len = card->default_address.len; |
||||
+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2; |
||||
grub_uint16_t vlantag = 0; |
||||
|
||||
+ eth = nb->data; |
||||
|
||||
- /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ |
||||
- /* longer than the original one. The vlantag id is extracted and the header */ |
||||
- /* is reseted to the original size. */ |
||||
- if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER) |
||||
+ hwaddress.type = card->default_address.type; |
||||
+ hwaddress.len = hw_addr_len; |
||||
+ grub_memcpy (hwaddress.mac, eth, hw_addr_len); |
||||
+ eth += hw_addr_len; |
||||
+ |
||||
+ src_hwaddress.type = card->default_address.type; |
||||
+ src_hwaddress.len = hw_addr_len; |
||||
+ grub_memcpy (src_hwaddress.mac, eth, hw_addr_len); |
||||
+ eth += hw_addr_len; |
||||
+ |
||||
+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); |
||||
+ if (type == VLANTAG_IDENTIFIER) |
||||
{ |
||||
- vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); |
||||
+ /* Skip vlan tag */ |
||||
+ eth += 2; |
||||
+ vlantag = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); |
||||
etherhdr_size += 4; |
||||
- /* Move eth type to the original position */ |
||||
- grub_memcpy((char *) nb->data + etherhdr_size - 6, |
||||
- (char *) nb->data + etherhdr_size - 2, 2); |
||||
+ eth += 2; |
||||
+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); |
||||
} |
||||
|
||||
- eth = (struct etherhdr *) nb->data; |
||||
- type = grub_be_to_cpu16 (eth->type); |
||||
err = grub_netbuff_pull (nb, etherhdr_size); |
||||
if (err) |
||||
return err; |
||||
@@ -148,11 +151,6 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, |
||||
} |
||||
} |
||||
|
||||
- hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); |
||||
- src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac)); |
||||
- |
||||
switch (type) |
||||
{ |
||||
/* ARP packet. */ |
||||
diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c |
||||
index 2cbd95dce2..56a3ec5c8e 100644 |
||||
--- a/grub-core/net/icmp6.c |
||||
+++ b/grub-core/net/icmp6.c |
||||
@@ -231,8 +231,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, |
||||
&& ohdr->len == 1) |
||||
{ |
||||
grub_net_link_level_address_t ll_address; |
||||
- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); |
||||
+ ll_address.type = card->default_address.type; |
||||
+ ll_address.len = card->default_address.len; |
||||
+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); |
||||
grub_net_link_layer_add_address (card, source, &ll_address, 0); |
||||
} |
||||
} |
||||
@@ -335,8 +336,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, |
||||
&& ohdr->len == 1) |
||||
{ |
||||
grub_net_link_level_address_t ll_address; |
||||
- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); |
||||
+ ll_address.type = card->default_address.type; |
||||
+ ll_address.len = card->default_address.len; |
||||
+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); |
||||
grub_net_link_layer_add_address (card, source, &ll_address, 0); |
||||
} |
||||
} |
||||
@@ -384,8 +386,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, |
||||
&& ohdr->len == 1) |
||||
{ |
||||
grub_net_link_level_address_t ll_address; |
||||
- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); |
||||
+ ll_address.type = card->default_address.type; |
||||
+ ll_address.len = card->default_address.len; |
||||
+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); |
||||
grub_net_link_layer_add_address (card, source, &ll_address, 0); |
||||
} |
||||
if (ohdr->type == OPTION_PREFIX && ohdr->len == 4) |
||||
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c |
||||
index ea5edf8f1f..a5896f6dc2 100644 |
||||
--- a/grub-core/net/ip.c |
||||
+++ b/grub-core/net/ip.c |
||||
@@ -276,8 +276,8 @@ handle_dgram (struct grub_net_buff *nb, |
||||
if (inf->card == card |
||||
&& inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV |
||||
&& inf->hwaddress.type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET |
||||
- && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, |
||||
- sizeof (inf->hwaddress.mac)) == 0) |
||||
+ && (grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, |
||||
+ bootp->hw_len) == 0 || bootp->hw_len == 0)) |
||||
{ |
||||
grub_net_process_dhcp (nb, inf); |
||||
grub_netbuff_free (nb); |
||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c |
||||
index 22f2689aae..a46f82362e 100644 |
||||
--- a/grub-core/net/net.c |
||||
+++ b/grub-core/net/net.c |
||||
@@ -133,8 +133,9 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, |
||||
<< 48) |
||||
&& proto_addr->ipv6[1] == (grub_be_to_cpu64_compile_time (1)))) |
||||
{ |
||||
- hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
- grub_memset (hw_addr->mac, -1, 6); |
||||
+ hw_addr->type = inf->card->default_address.type; |
||||
+ hw_addr->len = inf->card->default_address.len; |
||||
+ grub_memset (hw_addr->mac, -1, hw_addr->len); |
||||
return GRUB_ERR_NONE; |
||||
} |
||||
|
||||
@@ -142,6 +143,7 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, |
||||
&& ((grub_be_to_cpu64 (proto_addr->ipv6[0]) >> 56) == 0xff)) |
||||
{ |
||||
hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
||||
+ hw_addr->len = inf->card->default_address.len; |
||||
hw_addr->mac[0] = 0x33; |
||||
hw_addr->mac[1] = 0x33; |
||||
hw_addr->mac[2] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 24) & 0xff); |
||||
@@ -762,23 +764,23 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) |
||||
void |
||||
grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) |
||||
{ |
||||
- str[0] = 0; |
||||
- switch (addr->type) |
||||
+ char *ptr; |
||||
+ unsigned i; |
||||
+ int maxstr; |
||||
+ |
||||
+ if (addr->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE) |
||||
{ |
||||
- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: |
||||
- { |
||||
- char *ptr; |
||||
- unsigned i; |
||||
- for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++) |
||||
- { |
||||
- grub_snprintf (ptr, GRUB_NET_MAX_STR_HWADDR_LEN - (ptr - str), |
||||
- "%02x:", addr->mac[i] & 0xff); |
||||
- ptr += (sizeof ("XX:") - 1); |
||||
- } |
||||
- return; |
||||
- } |
||||
+ str[0] = 0; |
||||
+ grub_printf (_("Unsupported hw address type %d len %d\n"), |
||||
+ addr->type, addr->len); |
||||
+ return; |
||||
+ } |
||||
+ maxstr = addr->len * grub_strlen ("XX:"); |
||||
+ for (ptr = str, i = 0; i < addr->len; i++) |
||||
+ { |
||||
+ ptr += grub_snprintf (ptr, maxstr - (ptr - str), |
||||
+ "%02x:", addr->mac[i] & 0xff); |
||||
} |
||||
- grub_printf (_("Unsupported hw address type %d\n"), addr->type); |
||||
} |
||||
|
||||
int |
||||
@@ -789,13 +791,17 @@ grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, |
||||
return -1; |
||||
if (a->type > b->type) |
||||
return +1; |
||||
- switch (a->type) |
||||
+ if (a->len < b->len) |
||||
+ return -1; |
||||
+ if (a->len > b->len) |
||||
+ return +1; |
||||
+ if (a->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE) |
||||
{ |
||||
- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: |
||||
- return grub_memcmp (a->mac, b->mac, sizeof (a->mac)); |
||||
+ grub_printf (_("Unsupported hw address type %d len %d\n"), |
||||
+ a->type, a->len); |
||||
+ return + 1; |
||||
} |
||||
- grub_printf (_("Unsupported hw address type %d\n"), a->type); |
||||
- return 1; |
||||
+ return grub_memcmp (a->mac, b->mac, a->len); |
||||
} |
||||
|
||||
int |
||||
diff --git a/include/grub/net.h b/include/grub/net.h |
||||
index 8a05ec4fe7..af0404db7e 100644 |
||||
--- a/include/grub/net.h |
||||
+++ b/include/grub/net.h |
||||
@@ -29,7 +29,8 @@ |
||||
|
||||
enum |
||||
{ |
||||
- GRUB_NET_MAX_LINK_HEADER_SIZE = 64, |
||||
+ GRUB_NET_MAX_LINK_HEADER_SIZE = 96, |
||||
+ GRUB_NET_MAX_LINK_ADDRESS_SIZE = 32, |
||||
GRUB_NET_UDP_HEADER_SIZE = 8, |
||||
GRUB_NET_TCP_HEADER_SIZE = 20, |
||||
GRUB_NET_OUR_IPV4_HEADER_SIZE = 20, |
||||
@@ -42,15 +43,17 @@ enum |
||||
|
||||
typedef enum grub_link_level_protocol_id |
||||
{ |
||||
- GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET |
||||
+ /* IANA ARP constant to define hardware type. */ |
||||
+ GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET = 1, |
||||
} grub_link_level_protocol_id_t; |
||||
|
||||
typedef struct grub_net_link_level_address |
||||
{ |
||||
grub_link_level_protocol_id_t type; |
||||
+ grub_uint8_t len; |
||||
union |
||||
{ |
||||
- grub_uint8_t mac[6]; |
||||
+ grub_uint8_t mac[GRUB_NET_MAX_LINK_ADDRESS_SIZE]; |
||||
}; |
||||
} grub_net_link_level_address_t; |
||||
|
||||
@@ -566,11 +569,13 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a, |
||||
#define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX") |
||||
|
||||
/* |
||||
- Currently suppoerted adresses: |
||||
- ethernet: XX:XX:XX:XX:XX:XX |
||||
+ Up to 32 byte hardware address supported, see GRUB_NET_MAX_LINK_ADDRESS_SIZE |
||||
*/ |
||||
- |
||||
-#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) |
||||
+#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof (\ |
||||
+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ |
||||
+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ |
||||
+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ |
||||
+ "XX:XX:XX:XX:XX:XX:XX:XX")) |
||||
|
||||
void |
||||
grub_net_addr_to_str (const grub_net_network_level_address_t *target, |
@ -0,0 +1,270 @@
@@ -0,0 +1,270 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Aaron Miller <aaronmiller@fb.com> |
||||
Date: Fri, 29 Jul 2016 17:41:38 +0800 |
||||
Subject: [PATCH] net: read bracketed ipv6 addrs and port numbers |
||||
|
||||
Allow specifying port numbers for http and tftp paths, and allow ipv6 addresses |
||||
to be recognized with brackets around them, which is required to specify a port |
||||
number |
||||
|
||||
Signed-off-by: Aaron Miller <aaronmiller@fb.com> |
||||
[pjones: various bug fixes] |
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/net/http.c | 25 ++++++++++++--- |
||||
grub-core/net/net.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++--- |
||||
grub-core/net/tftp.c | 8 +++-- |
||||
include/grub/net.h | 1 + |
||||
4 files changed, 109 insertions(+), 12 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/http.c b/grub-core/net/http.c |
||||
index b616cf40b1..12a2632ea5 100644 |
||||
--- a/grub-core/net/http.c |
||||
+++ b/grub-core/net/http.c |
||||
@@ -289,7 +289,9 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), |
||||
nb2 = grub_netbuff_alloc (data->chunk_rem); |
||||
if (!nb2) |
||||
return grub_errno; |
||||
- grub_netbuff_put (nb2, data->chunk_rem); |
||||
+ err = grub_netbuff_put (nb2, data->chunk_rem); |
||||
+ if (err) |
||||
+ return grub_errno; |
||||
grub_memcpy (nb2->data, nb->data, data->chunk_rem); |
||||
if (file->device->net->packs.count >= 20) |
||||
{ |
||||
@@ -312,12 +314,14 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) |
||||
int i; |
||||
struct grub_net_buff *nb; |
||||
grub_err_t err; |
||||
+ char* server = file->device->net->server; |
||||
+ int port = file->device->net->port; |
||||
|
||||
nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE |
||||
+ sizeof ("GET ") - 1 |
||||
+ grub_strlen (data->filename) |
||||
+ sizeof (" HTTP/1.1\r\nHost: ") - 1 |
||||
- + grub_strlen (file->device->net->server) |
||||
+ + grub_strlen (server) + sizeof (":XXXXXXXXXX") |
||||
+ sizeof ("\r\nUser-Agent: " PACKAGE_STRING |
||||
"\r\n") - 1 |
||||
+ sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX" |
||||
@@ -356,7 +360,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) |
||||
sizeof (" HTTP/1.1\r\nHost: ") - 1); |
||||
|
||||
ptr = nb->tail; |
||||
- err = grub_netbuff_put (nb, grub_strlen (file->device->net->server)); |
||||
+ err = grub_netbuff_put (nb, grub_strlen (server)); |
||||
if (err) |
||||
{ |
||||
grub_netbuff_free (nb); |
||||
@@ -365,6 +369,15 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) |
||||
grub_memcpy (ptr, file->device->net->server, |
||||
grub_strlen (file->device->net->server)); |
||||
|
||||
+ if (port) |
||||
+ { |
||||
+ ptr = nb->tail; |
||||
+ grub_snprintf ((char *) ptr, |
||||
+ sizeof (":XXXXXXXXXX"), |
||||
+ ":%d", |
||||
+ port); |
||||
+ } |
||||
+ |
||||
ptr = nb->tail; |
||||
err = grub_netbuff_put (nb, |
||||
sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") |
||||
@@ -390,8 +403,10 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) |
||||
grub_netbuff_put (nb, 2); |
||||
grub_memcpy (ptr, "\r\n", 2); |
||||
|
||||
- data->sock = grub_net_tcp_open (file->device->net->server, |
||||
- HTTP_PORT, http_receive, |
||||
+ grub_dprintf ("http", "opening path %s on host %s TCP port %d\n", |
||||
+ data->filename, server, port ? port : HTTP_PORT); |
||||
+ data->sock = grub_net_tcp_open (server, |
||||
+ port ? port : HTTP_PORT, http_receive, |
||||
http_err, NULL, |
||||
file); |
||||
if (!data->sock) |
||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c |
||||
index a46f82362e..0ce5e675ed 100644 |
||||
--- a/grub-core/net/net.c |
||||
+++ b/grub-core/net/net.c |
||||
@@ -444,6 +444,13 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) |
||||
grub_uint16_t newip[8]; |
||||
const char *ptr = val; |
||||
int word, quaddot = -1; |
||||
+ int bracketed = 0; |
||||
+ |
||||
+ if (ptr[0] == '[') |
||||
+ { |
||||
+ bracketed = 1; |
||||
+ ptr++; |
||||
+ } |
||||
|
||||
if (ptr[0] == ':' && ptr[1] != ':') |
||||
return 0; |
||||
@@ -482,6 +489,8 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) |
||||
grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0])); |
||||
} |
||||
grub_memcpy (ip, newip, 16); |
||||
+ if (bracketed && *ptr == ']') |
||||
+ ptr++; |
||||
if (rest) |
||||
*rest = ptr; |
||||
return 1; |
||||
@@ -1343,8 +1352,10 @@ grub_net_open_real (const char *name) |
||||
{ |
||||
grub_net_app_level_t proto; |
||||
const char *protname, *server; |
||||
+ char *host; |
||||
grub_size_t protnamelen; |
||||
int try; |
||||
+ int port = 0; |
||||
|
||||
if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) |
||||
{ |
||||
@@ -1382,6 +1393,72 @@ grub_net_open_real (const char *name) |
||||
return NULL; |
||||
} |
||||
|
||||
+ char* port_start; |
||||
+ /* ipv6 or port specified? */ |
||||
+ if ((port_start = grub_strchr (server, ':'))) |
||||
+ { |
||||
+ char* ipv6_begin; |
||||
+ if((ipv6_begin = grub_strchr (server, '['))) |
||||
+ { |
||||
+ char* ipv6_end = grub_strchr (server, ']'); |
||||
+ if(!ipv6_end) |
||||
+ { |
||||
+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, |
||||
+ N_("mismatched [ in address")); |
||||
+ return NULL; |
||||
+ } |
||||
+ /* port number after bracketed ipv6 addr */ |
||||
+ if(ipv6_end[1] == ':') |
||||
+ { |
||||
+ port = grub_strtoul (ipv6_end + 2, NULL, 10); |
||||
+ if(port > 65535) |
||||
+ { |
||||
+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, |
||||
+ N_("bad port number")); |
||||
+ return NULL; |
||||
+ } |
||||
+ } |
||||
+ host = grub_strndup (ipv6_begin, (ipv6_end - ipv6_begin) + 1); |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ if (grub_strchr (port_start + 1, ':')) |
||||
+ { |
||||
+ int iplen = grub_strlen (server); |
||||
+ /* bracket bare ipv6 addrs */ |
||||
+ host = grub_malloc (iplen + 3); |
||||
+ if(!host) |
||||
+ { |
||||
+ return NULL; |
||||
+ } |
||||
+ host[0] = '['; |
||||
+ grub_memcpy (host + 1, server, iplen); |
||||
+ host[iplen + 1] = ']'; |
||||
+ host[iplen + 2] = '\0'; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ /* hostname:port or ipv4:port */ |
||||
+ port = grub_strtol (port_start + 1, NULL, 10); |
||||
+ if(port > 65535) |
||||
+ { |
||||
+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, |
||||
+ N_("bad port number")); |
||||
+ return NULL; |
||||
+ } |
||||
+ host = grub_strndup (server, port_start - server); |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ host = grub_strdup (server); |
||||
+ } |
||||
+ if (!host) |
||||
+ { |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
for (try = 0; try < 2; try++) |
||||
{ |
||||
FOR_NET_APP_LEVEL (proto) |
||||
@@ -1391,14 +1468,13 @@ grub_net_open_real (const char *name) |
||||
{ |
||||
grub_net_t ret = grub_zalloc (sizeof (*ret)); |
||||
if (!ret) |
||||
- return NULL; |
||||
- ret->protocol = proto; |
||||
- ret->server = grub_strdup (server); |
||||
- if (!ret->server) |
||||
{ |
||||
- grub_free (ret); |
||||
+ grub_free (host); |
||||
return NULL; |
||||
} |
||||
+ ret->protocol = proto; |
||||
+ ret->port = port; |
||||
+ ret->server = host; |
||||
ret->fs = &grub_net_fs; |
||||
return ret; |
||||
} |
||||
@@ -1473,6 +1549,7 @@ grub_net_open_real (const char *name) |
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), |
||||
name); |
||||
|
||||
+ grub_free (host); |
||||
return NULL; |
||||
} |
||||
|
||||
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c |
||||
index 4ab2f5c735..d54b13f09f 100644 |
||||
--- a/grub-core/net/tftp.c |
||||
+++ b/grub-core/net/tftp.c |
||||
@@ -295,6 +295,7 @@ tftp_open (struct grub_file *file, const char *filename) |
||||
grub_err_t err; |
||||
grub_uint8_t *nbd; |
||||
grub_net_network_level_address_t addr; |
||||
+ int port = file->device->net->port; |
||||
|
||||
data = grub_zalloc (sizeof (*data)); |
||||
if (!data) |
||||
@@ -362,14 +363,17 @@ tftp_open (struct grub_file *file, const char *filename) |
||||
err = grub_net_resolve_address (file->device->net->server, &addr); |
||||
if (err) |
||||
{ |
||||
- grub_dprintf("tftp", "Address resolution failed: %d\n", err); |
||||
+ grub_dprintf ("tftp", "Address resolution failed: %d\n", err); |
||||
+ grub_dprintf ("tftp", "file_size is %llu, block_size is %llu\n", |
||||
+ (unsigned long long)data->file_size, |
||||
+ (unsigned long long)data->block_size); |
||||
grub_free (data); |
||||
return err; |
||||
} |
||||
|
||||
grub_dprintf("tftp", "opening connection\n"); |
||||
data->sock = grub_net_udp_open (addr, |
||||
- TFTP_SERVER_PORT, tftp_receive, |
||||
+ port ? port : TFTP_SERVER_PORT, tftp_receive, |
||||
file); |
||||
if (!data->sock) |
||||
{ |
||||
diff --git a/include/grub/net.h b/include/grub/net.h |
||||
index af0404db7e..d55d505a03 100644 |
||||
--- a/include/grub/net.h |
||||
+++ b/include/grub/net.h |
||||
@@ -273,6 +273,7 @@ typedef struct grub_net |
||||
{ |
||||
char *server; |
||||
char *name; |
||||
+ int port; |
||||
grub_net_app_level_t protocol; |
||||
grub_net_packets_t packs; |
||||
grub_off_t offset; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,126 @@
@@ -0,0 +1,126 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Wed, 15 Apr 2015 14:48:30 +0800 |
||||
Subject: [PATCH] efinet: UEFI IPv6 PXE support |
||||
|
||||
When grub2 image is booted from UEFI IPv6 PXE, the DHCPv6 Reply packet is |
||||
cached in firmware buffer which can be obtained by PXE Base Code protocol. The |
||||
network interface can be setup through the parameters in that obtained packet. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com> |
||||
--- |
||||
grub-core/net/drivers/efi/efinet.c | 2 ++ |
||||
include/grub/efi/api.h | 71 +++++++++++++++++++++++--------------- |
||||
2 files changed, 46 insertions(+), 27 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
||||
index 8e25680db0..014e5bf980 100644 |
||||
--- a/grub-core/net/drivers/efi/efinet.c |
||||
+++ b/grub-core/net/drivers/efi/efinet.c |
||||
@@ -409,6 +409,8 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
grub_print_error (); |
||||
if (device && path) |
||||
grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); |
||||
+ if (grub_errno) |
||||
+ grub_print_error (); |
||||
} |
||||
else |
||||
{ |
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h |
||||
index 7614b58dca..91ab528e4d 100644 |
||||
--- a/include/grub/efi/api.h |
||||
+++ b/include/grub/efi/api.h |
||||
@@ -1524,31 +1524,6 @@ typedef union |
||||
grub_efi_pxe_dhcpv6_packet_t dhcpv6; |
||||
} grub_efi_pxe_packet_t; |
||||
|
||||
-#define GRUB_EFI_PXE_MAX_IPCNT 8 |
||||
-#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 |
||||
-#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 |
||||
- |
||||
-typedef struct grub_efi_pxe_ip_filter |
||||
-{ |
||||
- grub_efi_uint8_t filters; |
||||
- grub_efi_uint8_t ip_count; |
||||
- grub_efi_uint16_t reserved; |
||||
- grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; |
||||
-} grub_efi_pxe_ip_filter_t; |
||||
- |
||||
-typedef struct grub_efi_pxe_arp_entry |
||||
-{ |
||||
- grub_efi_ip_address_t ip_addr; |
||||
- grub_efi_mac_address_t mac_addr; |
||||
-} grub_efi_pxe_arp_entry_t; |
||||
- |
||||
-typedef struct grub_efi_pxe_route_entry |
||||
-{ |
||||
- grub_efi_ip_address_t ip_addr; |
||||
- grub_efi_ip_address_t subnet_mask; |
||||
- grub_efi_ip_address_t gateway_addr; |
||||
-} grub_efi_pxe_route_entry_t; |
||||
- |
||||
typedef struct grub_efi_pxe_icmp_error |
||||
{ |
||||
grub_efi_uint8_t type; |
||||
@@ -1574,6 +1549,48 @@ typedef struct grub_efi_pxe_tftp_error |
||||
grub_efi_char8_t error_string[127]; |
||||
} grub_efi_pxe_tftp_error_t; |
||||
|
||||
+typedef struct { |
||||
+ grub_uint8_t addr[4]; |
||||
+} grub_efi_pxe_ipv4_address_t; |
||||
+ |
||||
+typedef struct { |
||||
+ grub_uint8_t addr[16]; |
||||
+} grub_efi_pxe_ipv6_address_t; |
||||
+ |
||||
+typedef struct { |
||||
+ grub_uint8_t addr[32]; |
||||
+} grub_efi_pxe_mac_address_t; |
||||
+ |
||||
+typedef union { |
||||
+ grub_uint32_t addr[4]; |
||||
+ grub_efi_pxe_ipv4_address_t v4; |
||||
+ grub_efi_pxe_ipv6_address_t v6; |
||||
+} grub_efi_pxe_ip_address_t; |
||||
+ |
||||
+#define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8 |
||||
+typedef struct grub_efi_pxe_ip_filter |
||||
+{ |
||||
+ grub_efi_uint8_t filters; |
||||
+ grub_efi_uint8_t ip_count; |
||||
+ grub_efi_uint16_t reserved; |
||||
+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT]; |
||||
+} grub_efi_pxe_ip_filter_t; |
||||
+ |
||||
+typedef struct { |
||||
+ grub_efi_pxe_ip_address_t ip_addr; |
||||
+ grub_efi_pxe_mac_address_t mac_addr; |
||||
+} grub_efi_pxe_arp_entry_t; |
||||
+ |
||||
+typedef struct { |
||||
+ grub_efi_pxe_ip_address_t ip_addr; |
||||
+ grub_efi_pxe_ip_address_t subnet_mask; |
||||
+ grub_efi_pxe_ip_address_t gw_addr; |
||||
+} grub_efi_pxe_route_entry_t; |
||||
+ |
||||
+ |
||||
+#define GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 |
||||
+#define GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 |
||||
+ |
||||
typedef struct grub_efi_pxe_mode |
||||
{ |
||||
grub_efi_boolean_t started; |
||||
@@ -1605,9 +1622,9 @@ typedef struct grub_efi_pxe_mode |
||||
grub_efi_pxe_packet_t pxe_bis_reply; |
||||
grub_efi_pxe_ip_filter_t ip_filter; |
||||
grub_efi_uint32_t arp_cache_entries; |
||||
- grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; |
||||
+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; |
||||
grub_efi_uint32_t route_table_entries; |
||||
- grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; |
||||
+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; |
||||
grub_efi_pxe_icmp_error_t icmp_error; |
||||
grub_efi_pxe_tftp_error_t tftp_error; |
||||
} grub_efi_pxe_mode_t; |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Tue, 5 May 2015 14:19:24 +0800 |
||||
Subject: [PATCH] grub.texi: Add net_bootp6 doument |
||||
|
||||
Update grub documentation for net_bootp6 command. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com> |
||||
--- |
||||
docs/grub.texi | 17 +++++++++++++++++ |
||||
1 file changed, 17 insertions(+) |
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi |
||||
index 0615d0ed97..04ed6ac1f0 100644 |
||||
--- a/docs/grub.texi |
||||
+++ b/docs/grub.texi |
||||
@@ -5487,6 +5487,7 @@ This command is only available on AArch64 systems. |
||||
* net_add_dns:: Add a DNS server |
||||
* net_add_route:: Add routing entry |
||||
* net_bootp:: Perform a bootp/DHCP autoconfiguration |
||||
+* net_bootp6:: Perform a DHCPv6 autoconfiguration |
||||
* net_del_addr:: Remove IP address from interface |
||||
* net_del_dns:: Remove a DNS server |
||||
* net_del_route:: Remove a route entry |
||||
@@ -5611,6 +5612,22 @@ Sets environment variable @samp{net_}@var{<card>}@samp{_boot_file} |
||||
|
||||
@end deffn |
||||
|
||||
+@node net_bootp6 |
||||
+@subsection net_bootp6 |
||||
+ |
||||
+@deffn Command net_bootp6 [@var{card}] |
||||
+Perform configuration of @var{card} using DHCPv6 protocol. If no card name is |
||||
+specified, try to configure all existing cards. If configuration was |
||||
+successful, interface with name @var{card}@samp{:dhcp6} and configured address |
||||
+is added to @var{card}. |
||||
+ |
||||
+@table @samp |
||||
+@item 1 (Domain Name Server) |
||||
+Adds all servers from option value to the list of servers used during name |
||||
+resolution. |
||||
+@end table |
||||
+ |
||||
+@end deffn |
||||
|
||||
@node net_get_dhcp_option |
||||
@subsection net_get_dhcp_option |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Wed, 10 Jul 2019 23:58:28 +0200 |
||||
Subject: [PATCH] bootp: Add processing DHCPACK packet from HTTP Boot |
||||
|
||||
The vendor class identifier with the string "HTTPClient" is used to denote the |
||||
packet as responding to HTTP boot request. In DHCP4 config, the filename for |
||||
HTTP boot is the URL of the boot file while for PXE boot it is the path to the |
||||
boot file. As a consequence, the next-server becomes obseleted because the HTTP |
||||
URL already contains the server address for the boot file. For DHCP6 config, |
||||
there's no difference definition in existing config as dhcp6.bootfile-url can |
||||
be used to specify URL for both HTTP and PXE boot file. |
||||
|
||||
This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK |
||||
packet by treating it as HTTP format, not as the PXE format. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com> |
||||
--- |
||||
grub-core/net/bootp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
||||
include/grub/net.h | 1 + |
||||
2 files changed, 56 insertions(+) |
||||
|
||||
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c |
||||
index fe93b80f1c..8fb8918ae7 100644 |
||||
--- a/grub-core/net/bootp.c |
||||
+++ b/grub-core/net/bootp.c |
||||
@@ -20,6 +20,7 @@ |
||||
#include <grub/env.h> |
||||
#include <grub/i18n.h> |
||||
#include <grub/command.h> |
||||
+#include <grub/net.h> |
||||
#include <grub/net/ip.h> |
||||
#include <grub/net/netbuff.h> |
||||
#include <grub/net/udp.h> |
||||
@@ -500,6 +501,60 @@ grub_net_configure_by_dhcp_ack (const char *name, |
||||
if (opt && opt_len) |
||||
grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len); |
||||
|
||||
+ opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len); |
||||
+ if (opt && opt_len) |
||||
+ { |
||||
+ grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); |
||||
+ if (opt && grub_strcmp (opt, "HTTPClient") == 0) |
||||
+ { |
||||
+ char *proto, *ip, *pa; |
||||
+ |
||||
+ if (!dissect_url (bp->boot_file, &proto, &ip, &pa)) |
||||
+ return inter; |
||||
+ |
||||
+ grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa)); |
||||
+ if (is_def) |
||||
+ { |
||||
+ grub_net_default_server = grub_strdup (ip); |
||||
+ grub_env_set ("net_default_interface", name); |
||||
+ grub_env_export ("net_default_interface"); |
||||
+ } |
||||
+ if (device && !*device) |
||||
+ { |
||||
+ *device = grub_xasprintf ("%s,%s", proto, ip); |
||||
+ grub_print_error (); |
||||
+ } |
||||
+ if (path) |
||||
+ { |
||||
+ *path = grub_strdup (pa); |
||||
+ grub_print_error (); |
||||
+ if (*path) |
||||
+ { |
||||
+ char *slash; |
||||
+ slash = grub_strrchr (*path, '/'); |
||||
+ if (slash) |
||||
+ *slash = 0; |
||||
+ else |
||||
+ **path = 0; |
||||
+ } |
||||
+ } |
||||
+ grub_net_add_ipv4_local (inter, mask); |
||||
+ inter->dhcp_ack = grub_malloc (size); |
||||
+ if (inter->dhcp_ack) |
||||
+ { |
||||
+ grub_memcpy (inter->dhcp_ack, bp, size); |
||||
+ inter->dhcp_acklen = size; |
||||
+ } |
||||
+ else |
||||
+ grub_errno = GRUB_ERR_NONE; |
||||
+ |
||||
+ grub_free (proto); |
||||
+ grub_free (ip); |
||||
+ grub_free (pa); |
||||
+ return inter; |
||||
+ } |
||||
+ } |
||||
+ |
||||
opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len); |
||||
if (opt && opt_len) |
||||
grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len); |
||||
diff --git a/include/grub/net.h b/include/grub/net.h |
||||
index 543251f727..42af7de250 100644 |
||||
--- a/include/grub/net.h |
||||
+++ b/include/grub/net.h |
||||
@@ -531,6 +531,7 @@ enum |
||||
GRUB_NET_DHCP_MESSAGE_TYPE = 53, |
||||
GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, |
||||
GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, |
||||
+ GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 60, |
||||
GRUB_NET_BOOTP_CLIENT_ID = 61, |
||||
GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, |
||||
GRUB_NET_DHCP_BOOTFILE_NAME = 67, |
@ -0,0 +1,405 @@
@@ -0,0 +1,405 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Sun, 10 Jul 2016 23:46:31 +0800 |
||||
Subject: [PATCH] efinet: Setting network from UEFI device path |
||||
|
||||
The PXE Base Code protocol used to obtain cached PXE DHCPACK packet is no |
||||
longer provided for HTTP Boot. Instead, we have to get the HTTP boot |
||||
information from the device path nodes defined in following UEFI Specification |
||||
sections. |
||||
|
||||
9.3.5.12 IPv4 Device Path |
||||
9.3.5.13 IPv6 Device Path |
||||
9.3.5.23 Uniform Resource Identifiers (URI) Device Path |
||||
|
||||
This patch basically does: |
||||
|
||||
include/grub/efi/api.h: |
||||
Add new structure of Uniform Resource Identifiers (URI) Device Path |
||||
|
||||
grub-core/net/drivers/efi/efinet.c: |
||||
Check if PXE Base Code is available, if not it will try to obtain the netboot |
||||
information from the device path where the image booted from. The DHCPACK |
||||
packet is recoverd from the information in device patch and feed into the same |
||||
DHCP packet processing functions to ensure the network interface is setting up |
||||
the same way it used to be. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com> |
||||
--- |
||||
grub-core/net/drivers/efi/efinet.c | 284 +++++++++++++++++++++++++++++++++++-- |
||||
include/grub/efi/api.h | 11 ++ |
||||
2 files changed, 280 insertions(+), 15 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
||||
index 014e5bf980..8171ecaa5e 100644 |
||||
--- a/grub-core/net/drivers/efi/efinet.c |
||||
+++ b/grub-core/net/drivers/efi/efinet.c |
||||
@@ -26,6 +26,7 @@ |
||||
#include <grub/i18n.h> |
||||
#include <grub/lib/hexdump.h> |
||||
#include <grub/types.h> |
||||
+#include <grub/net/netbuff.h> |
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+"); |
||||
|
||||
@@ -331,6 +332,227 @@ grub_efinet_findcards (void) |
||||
grub_free (handles); |
||||
} |
||||
|
||||
+static struct grub_net_buff * |
||||
+grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6) |
||||
+{ |
||||
+ grub_efi_uint16_t uri_len; |
||||
+ grub_efi_device_path_t *ldp, *ddp; |
||||
+ grub_efi_uri_device_path_t *uri_dp; |
||||
+ struct grub_net_buff *nb; |
||||
+ grub_err_t err; |
||||
+ |
||||
+ ddp = grub_efi_duplicate_device_path (dp); |
||||
+ if (!ddp) |
||||
+ return NULL; |
||||
+ |
||||
+ ldp = grub_efi_find_last_device_path (ddp); |
||||
+ |
||||
+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE |
||||
+ || GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ uri_len = GRUB_EFI_DEVICE_PATH_LENGTH (ldp) > 4 ? GRUB_EFI_DEVICE_PATH_LENGTH (ldp) - 4 : 0; |
||||
+ |
||||
+ if (!uri_len) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ uri_dp = (grub_efi_uri_device_path_t *) ldp; |
||||
+ |
||||
+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; |
||||
+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; |
||||
+ ldp->length = sizeof (*ldp); |
||||
+ |
||||
+ ldp = grub_efi_find_last_device_path (ddp); |
||||
+ |
||||
+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE |
||||
+ || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE |
||||
+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ nb = grub_netbuff_alloc (512); |
||||
+ if (!nb) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE) |
||||
+ { |
||||
+ grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp; |
||||
+ struct grub_net_bootp_packet *bp; |
||||
+ grub_uint8_t *ptr; |
||||
+ |
||||
+ bp = (struct grub_net_bootp_packet *) nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof (*bp) + 4); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ if (sizeof(bp->boot_file) < uri_len) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ grub_memcpy (bp->boot_file, uri_dp->uri, uri_len); |
||||
+ grub_memcpy (&bp->your_ip, ipv4->local_ip_address, sizeof (bp->your_ip)); |
||||
+ grub_memcpy (&bp->server_ip, ipv4->remote_ip_address, sizeof (bp->server_ip)); |
||||
+ |
||||
+ bp->vendor[0] = GRUB_NET_BOOTP_RFC1048_MAGIC_0; |
||||
+ bp->vendor[1] = GRUB_NET_BOOTP_RFC1048_MAGIC_1; |
||||
+ bp->vendor[2] = GRUB_NET_BOOTP_RFC1048_MAGIC_2; |
||||
+ bp->vendor[3] = GRUB_NET_BOOTP_RFC1048_MAGIC_3; |
||||
+ |
||||
+ ptr = nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof (ipv4->subnet_mask) + 2); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ *ptr++ = GRUB_NET_BOOTP_NETMASK; |
||||
+ *ptr++ = sizeof (ipv4->subnet_mask); |
||||
+ grub_memcpy (ptr, ipv4->subnet_mask, sizeof (ipv4->subnet_mask)); |
||||
+ |
||||
+ ptr = nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof (ipv4->gateway_ip_address) + 2); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ *ptr++ = GRUB_NET_BOOTP_ROUTER; |
||||
+ *ptr++ = sizeof (ipv4->gateway_ip_address); |
||||
+ grub_memcpy (ptr, ipv4->gateway_ip_address, sizeof (ipv4->gateway_ip_address)); |
||||
+ |
||||
+ ptr = nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof ("HTTPClient") + 1); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ *ptr++ = GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER; |
||||
+ *ptr++ = sizeof ("HTTPClient") - 1; |
||||
+ grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1); |
||||
+ |
||||
+ ptr = nb->tail; |
||||
+ err = grub_netbuff_put (nb, 1); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ *ptr = GRUB_NET_BOOTP_END; |
||||
+ *use_ipv6 = 0; |
||||
+ |
||||
+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; |
||||
+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; |
||||
+ ldp->length = sizeof (*ldp); |
||||
+ ldp = grub_efi_find_last_device_path (ddp); |
||||
+ |
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE) |
||||
+ { |
||||
+ grub_efi_mac_address_device_path_t *mac = (grub_efi_mac_address_device_path_t *) ldp; |
||||
+ bp->hw_type = mac->if_type; |
||||
+ bp->hw_len = sizeof (bp->mac_addr); |
||||
+ grub_memcpy (bp->mac_addr, mac->mac_address, bp->hw_len); |
||||
+ } |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ grub_efi_ipv6_device_path_t *ipv6 = (grub_efi_ipv6_device_path_t *) ldp; |
||||
+ |
||||
+ struct grub_net_dhcp6_packet *d6p; |
||||
+ struct grub_net_dhcp6_option *opt; |
||||
+ struct grub_net_dhcp6_option_iana *iana; |
||||
+ struct grub_net_dhcp6_option_iaaddr *iaaddr; |
||||
+ |
||||
+ d6p = (struct grub_net_dhcp6_packet *)nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof(*d6p)); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ d6p->message_type = GRUB_NET_DHCP6_REPLY; |
||||
+ |
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof(*opt)); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA); |
||||
+ opt->len = grub_cpu_to_be16_compile_time (sizeof(*iana) + sizeof(*opt) + sizeof(*iaaddr)); |
||||
+ |
||||
+ err = grub_netbuff_put (nb, sizeof(*iana)); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof(*opt)); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IAADDR); |
||||
+ opt->len = grub_cpu_to_be16_compile_time (sizeof (*iaaddr)); |
||||
+ |
||||
+ iaaddr = (struct grub_net_dhcp6_option_iaaddr *)nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof(*iaaddr)); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ grub_memcpy (iaaddr->addr, ipv6->local_ip_address, sizeof(ipv6->local_ip_address)); |
||||
+ |
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof(*opt) + uri_len); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_BOOTFILE_URL); |
||||
+ opt->len = grub_cpu_to_be16 (uri_len); |
||||
+ grub_memcpy (opt->data, uri_dp->uri, uri_len); |
||||
+ |
||||
+ *use_ipv6 = 1; |
||||
+ } |
||||
+ |
||||
+ grub_free (ddp); |
||||
+ return nb; |
||||
+} |
||||
+ |
||||
static void |
||||
grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
char **path) |
||||
@@ -346,7 +568,11 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
{ |
||||
grub_efi_device_path_t *cdp; |
||||
struct grub_efi_pxe *pxe; |
||||
- struct grub_efi_pxe_mode *pxe_mode; |
||||
+ struct grub_efi_pxe_mode *pxe_mode = NULL; |
||||
+ grub_uint8_t *packet_buf; |
||||
+ grub_size_t packet_bufsz ; |
||||
+ int ipv6; |
||||
+ struct grub_net_buff *nb = NULL; |
||||
|
||||
if (card->driver != &efidriver) |
||||
continue; |
||||
@@ -370,11 +596,21 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
*/ |
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE |
||||
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE |
||||
- && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) |
||||
+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE |
||||
+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) |
||||
continue; |
||||
dup_dp = grub_efi_duplicate_device_path (dp); |
||||
if (!dup_dp) |
||||
continue; |
||||
+ |
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) |
||||
+ { |
||||
+ dup_ldp = grub_efi_find_last_device_path (dup_dp); |
||||
+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; |
||||
+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; |
||||
+ dup_ldp->length = sizeof (*dup_ldp); |
||||
+ } |
||||
+ |
||||
dup_ldp = grub_efi_find_last_device_path (dup_dp); |
||||
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; |
||||
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; |
||||
@@ -387,23 +623,37 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
|
||||
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, |
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
||||
- if (! pxe) |
||||
- continue; |
||||
+ if (!pxe) |
||||
+ { |
||||
+ nb = grub_efinet_create_dhcp_ack_from_device_path (dp, &ipv6); |
||||
+ if (!nb) |
||||
+ { |
||||
+ grub_print_error (); |
||||
+ continue; |
||||
+ } |
||||
+ packet_buf = nb->head; |
||||
+ packet_bufsz = nb->tail - nb->head; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ pxe_mode = pxe->mode; |
||||
+ packet_buf = (grub_uint8_t *) &pxe_mode->dhcp_ack; |
||||
+ packet_bufsz = sizeof (pxe_mode->dhcp_ack); |
||||
+ ipv6 = pxe_mode->using_ipv6; |
||||
+ } |
||||
|
||||
- pxe_mode = pxe->mode; |
||||
- if (pxe_mode->using_ipv6) |
||||
+ if (ipv6) |
||||
{ |
||||
grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); |
||||
- grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", |
||||
- pxe_mode->dhcp_ack_received ? "yes" : "no", |
||||
- pxe_mode->dhcp_ack_received ? "" : " cannot continue"); |
||||
- if (!pxe_mode->dhcp_ack_received) |
||||
- continue; |
||||
+ if (pxe_mode) |
||||
+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", |
||||
+ pxe_mode->dhcp_ack_received ? "yes" : "no", |
||||
+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); |
||||
|
||||
grub_net_configure_by_dhcpv6_reply (card->name, card, 0, |
||||
(struct grub_net_dhcp6_packet *) |
||||
- &pxe_mode->dhcp_ack, |
||||
- sizeof (pxe_mode->dhcp_ack), |
||||
+ packet_buf, |
||||
+ packet_bufsz, |
||||
1, device, path); |
||||
if (grub_errno) |
||||
grub_print_error (); |
||||
@@ -417,11 +667,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
||||
grub_dprintf ("efinet", "using ipv4 and dhcp\n"); |
||||
grub_net_configure_by_dhcp_ack (card->name, card, 0, |
||||
(struct grub_net_bootp_packet *) |
||||
- &pxe_mode->dhcp_ack, |
||||
- sizeof (pxe_mode->dhcp_ack), |
||||
+ packet_buf, |
||||
+ packet_bufsz, |
||||
1, device, path); |
||||
grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); |
||||
} |
||||
+ |
||||
+ if (nb) |
||||
+ grub_netbuff_free (nb); |
||||
+ |
||||
return; |
||||
} |
||||
} |
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h |
||||
index 91ab528e4d..4a51667adb 100644 |
||||
--- a/include/grub/efi/api.h |
||||
+++ b/include/grub/efi/api.h |
||||
@@ -864,6 +864,8 @@ struct grub_efi_ipv4_device_path |
||||
grub_efi_uint16_t remote_port; |
||||
grub_efi_uint16_t protocol; |
||||
grub_efi_uint8_t static_ip_address; |
||||
+ grub_efi_ipv4_address_t gateway_ip_address; |
||||
+ grub_efi_ipv4_address_t subnet_mask; |
||||
} GRUB_PACKED; |
||||
typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; |
||||
|
||||
@@ -918,6 +920,15 @@ struct grub_efi_sata_device_path |
||||
} GRUB_PACKED; |
||||
typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; |
||||
|
||||
+#define GRUB_EFI_URI_DEVICE_PATH_SUBTYPE 24 |
||||
+ |
||||
+struct grub_efi_uri_device_path |
||||
+{ |
||||
+ grub_efi_device_path_t header; |
||||
+ grub_efi_uint8_t uri[0]; |
||||
+} GRUB_PACKED; |
||||
+typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t; |
||||
+ |
||||
#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 |
||||
|
||||
/* Media Device Path. */ |
@ -0,0 +1,336 @@
@@ -0,0 +1,336 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Michael Chang <mchang@suse.com> |
||||
Date: Thu, 14 Jul 2016 17:48:45 +0800 |
||||
Subject: [PATCH] efinet: Setting DNS server from UEFI protocol |
||||
|
||||
In the URI device path node, any name rahter than address can be used for |
||||
looking up the resources so that DNS service become needed to get answer of the |
||||
name's address. Unfortunately the DNS is not defined in any of the device path |
||||
nodes so that we use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL |
||||
to obtain it. |
||||
|
||||
These two protcols are defined the sections of UEFI specification. |
||||
|
||||
27.5 EFI IPv4 Configuration II Protocol |
||||
27.7 EFI IPv6 Configuration Protocol |
||||
|
||||
include/grub/efi/api.h: |
||||
Add new structure and protocol UUID of EFI_IP4_CONFIG2_PROTOCOL and |
||||
EFI_IP6_CONFIG_PROTOCOL. |
||||
|
||||
grub-core/net/drivers/efi/efinet.c: |
||||
Use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL to obtain the list |
||||
of DNS server address for IPv4 and IPv6 respectively. The address of DNS |
||||
servers is structured into DHCPACK packet and feed into the same DHCP packet |
||||
processing functions to ensure the network interface is setting up the same way |
||||
it used to be. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com> |
||||
--- |
||||
grub-core/net/drivers/efi/efinet.c | 163 +++++++++++++++++++++++++++++++++++++ |
||||
include/grub/efi/api.h | 75 +++++++++++++++++ |
||||
2 files changed, 238 insertions(+) |
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
||||
index 8171ecaa5e..715a6168d7 100644 |
||||
--- a/grub-core/net/drivers/efi/efinet.c |
||||
+++ b/grub-core/net/drivers/efi/efinet.c |
||||
@@ -33,6 +33,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); |
||||
/* GUID. */ |
||||
static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; |
||||
static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; |
||||
+static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; |
||||
+static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; |
||||
|
||||
static grub_err_t |
||||
send_card_buffer (struct grub_net_card *dev, |
||||
@@ -332,6 +334,125 @@ grub_efinet_findcards (void) |
||||
grub_free (handles); |
||||
} |
||||
|
||||
+static grub_efi_handle_t |
||||
+grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path, |
||||
+ grub_efi_device_path_t **r_device_path) |
||||
+{ |
||||
+ grub_efi_handle_t handle; |
||||
+ grub_efi_status_t status; |
||||
+ |
||||
+ status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path, |
||||
+ protocol, &device_path, &handle); |
||||
+ |
||||
+ if (status != GRUB_EFI_SUCCESS) |
||||
+ return 0; |
||||
+ |
||||
+ if (r_device_path) |
||||
+ *r_device_path = device_path; |
||||
+ |
||||
+ return handle; |
||||
+} |
||||
+ |
||||
+static grub_efi_ipv4_address_t * |
||||
+grub_dns_server_ip4_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns) |
||||
+{ |
||||
+ grub_efi_handle_t hnd; |
||||
+ grub_efi_status_t status; |
||||
+ grub_efi_ip4_config2_protocol_t *conf; |
||||
+ grub_efi_ipv4_address_t *addrs; |
||||
+ grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv4_address_t); |
||||
+ |
||||
+ hnd = grub_efi_locate_device_path (&ip4_config_guid, dp, NULL); |
||||
+ |
||||
+ if (!hnd) |
||||
+ return 0; |
||||
+ |
||||
+ conf = grub_efi_open_protocol (hnd, &ip4_config_guid, |
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
||||
+ |
||||
+ if (!conf) |
||||
+ return 0; |
||||
+ |
||||
+ addrs = grub_malloc (data_size); |
||||
+ if (!addrs) |
||||
+ return 0; |
||||
+ |
||||
+ status = efi_call_4 (conf->get_data, conf, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, |
||||
+ &data_size, addrs); |
||||
+ |
||||
+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) |
||||
+ { |
||||
+ grub_free (addrs); |
||||
+ addrs = grub_malloc (data_size); |
||||
+ if (!addrs) |
||||
+ return 0; |
||||
+ |
||||
+ status = efi_call_4 (conf->get_data, conf, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, |
||||
+ &data_size, addrs); |
||||
+ } |
||||
+ |
||||
+ if (status != GRUB_EFI_SUCCESS) |
||||
+ { |
||||
+ grub_free (addrs); |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
+ *num_dns = data_size / sizeof (grub_efi_ipv4_address_t); |
||||
+ return addrs; |
||||
+} |
||||
+ |
||||
+static grub_efi_ipv6_address_t * |
||||
+grub_dns_server_ip6_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns) |
||||
+{ |
||||
+ grub_efi_handle_t hnd; |
||||
+ grub_efi_status_t status; |
||||
+ grub_efi_ip6_config_protocol_t *conf; |
||||
+ grub_efi_ipv6_address_t *addrs; |
||||
+ grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv6_address_t); |
||||
+ |
||||
+ hnd = grub_efi_locate_device_path (&ip6_config_guid, dp, NULL); |
||||
+ |
||||
+ if (!hnd) |
||||
+ return 0; |
||||
+ |
||||
+ conf = grub_efi_open_protocol (hnd, &ip6_config_guid, |
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
||||
+ |
||||
+ if (!conf) |
||||
+ return 0; |
||||
+ |
||||
+ addrs = grub_malloc (data_size); |
||||
+ if (!addrs) |
||||
+ return 0; |
||||
+ |
||||
+ status = efi_call_4 (conf->get_data, conf, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, |
||||
+ &data_size, addrs); |
||||
+ |
||||
+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) |
||||
+ { |
||||
+ grub_free (addrs); |
||||
+ addrs = grub_malloc (data_size); |
||||
+ if (!addrs) |
||||
+ return 0; |
||||
+ |
||||
+ status = efi_call_4 (conf->get_data, conf, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, |
||||
+ &data_size, addrs); |
||||
+ } |
||||
+ |
||||
+ if (status != GRUB_EFI_SUCCESS) |
||||
+ { |
||||
+ grub_free (addrs); |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
+ *num_dns = data_size / sizeof (grub_efi_ipv6_address_t); |
||||
+ return addrs; |
||||
+} |
||||
+ |
||||
static struct grub_net_buff * |
||||
grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6) |
||||
{ |
||||
@@ -390,6 +511,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u |
||||
grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp; |
||||
struct grub_net_bootp_packet *bp; |
||||
grub_uint8_t *ptr; |
||||
+ grub_efi_ipv4_address_t *dns; |
||||
+ grub_efi_uintn_t num_dns; |
||||
|
||||
bp = (struct grub_net_bootp_packet *) nb->tail; |
||||
err = grub_netbuff_put (nb, sizeof (*bp) + 4); |
||||
@@ -451,6 +574,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u |
||||
*ptr++ = sizeof ("HTTPClient") - 1; |
||||
grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1); |
||||
|
||||
+ dns = grub_dns_server_ip4_address (dp, &num_dns); |
||||
+ if (dns) |
||||
+ { |
||||
+ grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns; |
||||
+ |
||||
+ ptr = nb->tail; |
||||
+ err = grub_netbuff_put (nb, size_dns + 2); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ *ptr++ = GRUB_NET_BOOTP_DNS; |
||||
+ *ptr++ = size_dns; |
||||
+ grub_memcpy (ptr, dns, size_dns); |
||||
+ grub_free (dns); |
||||
+ } |
||||
+ |
||||
ptr = nb->tail; |
||||
err = grub_netbuff_put (nb, 1); |
||||
if (err) |
||||
@@ -483,6 +625,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u |
||||
struct grub_net_dhcp6_option *opt; |
||||
struct grub_net_dhcp6_option_iana *iana; |
||||
struct grub_net_dhcp6_option_iaaddr *iaaddr; |
||||
+ grub_efi_ipv6_address_t *dns; |
||||
+ grub_efi_uintn_t num_dns; |
||||
|
||||
d6p = (struct grub_net_dhcp6_packet *)nb->tail; |
||||
err = grub_netbuff_put (nb, sizeof(*d6p)); |
||||
@@ -546,6 +690,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u |
||||
opt->len = grub_cpu_to_be16 (uri_len); |
||||
grub_memcpy (opt->data, uri_dp->uri, uri_len); |
||||
|
||||
+ dns = grub_dns_server_ip6_address (dp, &num_dns); |
||||
+ if (dns) |
||||
+ { |
||||
+ grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns; |
||||
+ |
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail; |
||||
+ err = grub_netbuff_put (nb, sizeof(*opt) + size_dns); |
||||
+ if (err) |
||||
+ { |
||||
+ grub_free (ddp); |
||||
+ grub_netbuff_free (nb); |
||||
+ return NULL; |
||||
+ } |
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_DNS_SERVERS); |
||||
+ opt->len = grub_cpu_to_be16 (size_dns); |
||||
+ grub_memcpy (opt->data, dns, size_dns); |
||||
+ grub_free (dns); |
||||
+ } |
||||
+ |
||||
*use_ipv6 = 1; |
||||
} |
||||
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h |
||||
index 4a51667adb..0b490195ad 100644 |
||||
--- a/include/grub/efi/api.h |
||||
+++ b/include/grub/efi/api.h |
||||
@@ -352,6 +352,15 @@ |
||||
#define GRUB_EFI_RNG_PROTOCOL_GUID \ |
||||
{ 0x3152bca5, 0xeade, 0x433d, \ |
||||
{ 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ |
||||
+ |
||||
+#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \ |
||||
+ { 0x5b446ed1, 0xe30b, 0x4faa, \ |
||||
+ { 0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \ |
||||
+ } |
||||
+ |
||||
+#define GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID \ |
||||
+ { 0x937fe521, 0x95ae, 0x4d1a, \ |
||||
+ { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ |
||||
} |
||||
|
||||
struct grub_efi_sal_system_table |
||||
@@ -1883,6 +1892,72 @@ struct grub_efi_rng_protocol |
||||
}; |
||||
typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; |
||||
|
||||
+enum grub_efi_ip4_config2_data_type { |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, |
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MAXIMUM |
||||
+}; |
||||
+typedef enum grub_efi_ip4_config2_data_type grub_efi_ip4_config2_data_type_t; |
||||
+ |
||||
+struct grub_efi_ip4_config2_protocol |
||||
+{ |
||||
+ grub_efi_status_t (*set_data) (struct grub_efi_ip4_config2_protocol *this, |
||||
+ grub_efi_ip4_config2_data_type_t data_type, |
||||
+ grub_efi_uintn_t data_size, |
||||
+ void *data); |
||||
+ |
||||
+ grub_efi_status_t (*get_data) (struct grub_efi_ip4_config2_protocol *this, |
||||
+ grub_efi_ip4_config2_data_type_t data_type, |
||||
+ grub_efi_uintn_t *data_size, |
||||
+ void *data); |
||||
+ |
||||
+ grub_efi_status_t (*register_data_notify) (struct grub_efi_ip4_config2_protocol *this, |
||||
+ grub_efi_ip4_config2_data_type_t data_type, |
||||
+ grub_efi_event_t event); |
||||
+ |
||||
+ grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this, |
||||
+ grub_efi_ip4_config2_data_type_t data_type, |
||||
+ grub_efi_event_t event); |
||||
+}; |
||||
+typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t; |
||||
+ |
||||
+enum grub_efi_ip6_config_data_type { |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DUP_ADDR_DETECT_TRANSMITS, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, |
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MAXIMUM |
||||
+}; |
||||
+typedef enum grub_efi_ip6_config_data_type grub_efi_ip6_config_data_type_t; |
||||
+ |
||||
+struct grub_efi_ip6_config_protocol |
||||
+{ |
||||
+ grub_efi_status_t (*set_data) (struct grub_efi_ip6_config_protocol *this, |
||||
+ grub_efi_ip6_config_data_type_t data_type, |
||||
+ grub_efi_uintn_t data_size, |
||||
+ void *data); |
||||
+ |
||||
+ grub_efi_status_t (*get_data) (struct grub_efi_ip6_config_protocol *this, |
||||
+ grub_efi_ip6_config_data_type_t data_type, |
||||
+ grub_efi_uintn_t *data_size, |
||||
+ void *data); |
||||
+ |
||||
+ grub_efi_status_t (*register_data_notify) (struct grub_efi_ip6_config_protocol *this, |
||||
+ grub_efi_ip6_config_data_type_t data_type, |
||||
+ grub_efi_event_t event); |
||||
+ |
||||
+ grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip6_config_protocol *this, |
||||
+ grub_efi_ip6_config_data_type_t data_type, |
||||
+ grub_efi_event_t event); |
||||
+}; |
||||
+typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t; |
||||
+ |
||||
#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ |
||||
|| defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ |
||||
|| defined(__riscv) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Sebastian Krahmer <krahmer@suse.com> |
||||
Date: Tue, 28 Nov 2017 17:24:38 +0800 |
||||
Subject: [PATCH] AUDIT-0: http boot tracker bug |
||||
|
||||
Fixing a memory leak in case of error, and a integer overflow, leading to a |
||||
heap overflow due to overly large chunk sizes. |
||||
|
||||
We need to check against some maximum value, otherwise values like 0xffffffff |
||||
will eventually lead in the allocation functions to small sized buffers, since |
||||
the len is rounded up to the next reasonable alignment. The following memcpy |
||||
will then smash the heap, leading to RCE. |
||||
|
||||
This is no big issue for pure http boot, since its going to execute an |
||||
untrusted kernel anyway, but it will break trusted boot scenarios, where only |
||||
signed code is allowed to be executed. |
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com> |
||||
--- |
||||
grub-core/net/efi/net.c | 4 +++- |
||||
grub-core/net/http.c | 5 ++++- |
||||
2 files changed, 7 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c |
||||
index 86bce6535d..4bb308026c 100644 |
||||
--- a/grub-core/net/efi/net.c |
||||
+++ b/grub-core/net/efi/net.c |
||||
@@ -645,8 +645,10 @@ grub_efihttp_chunk_read (grub_file_t file, char *buf, |
||||
|
||||
rd = efi_net_interface (read, file, chunk, sz); |
||||
|
||||
- if (rd <= 0) |
||||
+ if (rd <= 0) { |
||||
+ grub_free (chunk); |
||||
return rd; |
||||
+ } |
||||
|
||||
if (buf) |
||||
{ |
||||
diff --git a/grub-core/net/http.c b/grub-core/net/http.c |
||||
index 12a2632ea5..b52b558d63 100644 |
||||
--- a/grub-core/net/http.c |
||||
+++ b/grub-core/net/http.c |
||||
@@ -31,7 +31,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); |
||||
|
||||
enum |
||||
{ |
||||
- HTTP_PORT = 80 |
||||
+ HTTP_PORT = 80, |
||||
+ HTTP_MAX_CHUNK_SIZE = 0x80000000 |
||||
}; |
||||
|
||||
|
||||
@@ -78,6 +79,8 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) |
||||
if (data->in_chunk_len == 2) |
||||
{ |
||||
data->chunk_rem = grub_strtoul (ptr, 0, 16); |
||||
+ if (data->chunk_rem > HTTP_MAX_CHUNK_SIZE) |
||||
+ return GRUB_ERR_NET_PACKET_TOO_BIG; |
||||
grub_errno = GRUB_ERR_NONE; |
||||
if (data->chunk_rem == 0) |
||||
{ |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Hans de Goede <hdegoede@redhat.com> |
||||
Date: Mon, 4 Jun 2018 19:49:47 +0200 |
||||
Subject: [PATCH] grub-editenv: Add "incr" command to increment integer value |
||||
env. variables |
||||
|
||||
To be able to automatically detect if the last boot was successful, |
||||
We want to keep count of succesful / failed boots in some integer |
||||
environment variable. |
||||
|
||||
This commit adds a grub-editenvt "incr" command to increment such |
||||
integer value env. variables by 1 for use from various boot scripts. |
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
||||
--- |
||||
util/grub-editenv.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
||||
1 file changed, 50 insertions(+) |
||||
|
||||
diff --git a/util/grub-editenv.c b/util/grub-editenv.c |
||||
index db6f187cc6..948eec8a11 100644 |
||||
--- a/util/grub-editenv.c |
||||
+++ b/util/grub-editenv.c |
||||
@@ -53,6 +53,9 @@ static struct argp_option options[] = { |
||||
/* TRANSLATORS: "unset" is a keyword. It's a summary of "unset" subcommand. */ |
||||
{N_("unset [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, |
||||
N_("Delete variables."), 0}, |
||||
+ /* TRANSLATORS: "incr" is a keyword. It's a summary of "incr" subcommand. */ |
||||
+ {N_("incr [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, |
||||
+ N_("Increase value of integer variables."), 0}, |
||||
|
||||
{0, 0, 0, OPTION_DOC, N_("Options:"), -1}, |
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, |
||||
@@ -253,6 +256,51 @@ unset_variables (const char *name, int argc, char *argv[]) |
||||
grub_envblk_close (envblk); |
||||
} |
||||
|
||||
+struct get_int_value_params { |
||||
+ char *varname; |
||||
+ int value; |
||||
+}; |
||||
+ |
||||
+static int |
||||
+get_int_value (const char *varname, const char *value, void *hook_data) |
||||
+{ |
||||
+ struct get_int_value_params *params = hook_data; |
||||
+ |
||||
+ if (strcmp (varname, params->varname) == 0) { |
||||
+ params->value = strtol (value, NULL, 10); |
||||
+ return 1; |
||||
+ } |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+static void |
||||
+incr_variables (const char *name, int argc, char *argv[]) |
||||
+{ |
||||
+ grub_envblk_t envblk; |
||||
+ char buf[16]; |
||||
+ |
||||
+ envblk = open_envblk_file (name); |
||||
+ while (argc) |
||||
+ { |
||||
+ struct get_int_value_params params = { |
||||
+ .varname = argv[0], |
||||
+ .value = 0, /* Consider unset variables 0 */ |
||||
+ }; |
||||
+ |
||||
+ grub_envblk_iterate (envblk, ¶ms, get_int_value); |
||||
+ snprintf(buf, sizeof(buf), "%d", params.value + 1); |
||||
+ |
||||
+ if (! grub_envblk_set (envblk, argv[0], buf)) |
||||
+ grub_util_error ("%s", _("environment block too small")); |
||||
+ |
||||
+ argc--; |
||||
+ argv++; |
||||
+ } |
||||
+ |
||||
+ write_envblk (name, envblk); |
||||
+ grub_envblk_close (envblk); |
||||
+} |
||||
+ |
||||
int |
||||
main (int argc, char *argv[]) |
||||
{ |
||||
@@ -292,6 +340,8 @@ main (int argc, char *argv[]) |
||||
set_variables (filename, argc - curindex, argv + curindex); |
||||
else if (strcmp (command, "unset") == 0) |
||||
unset_variables (filename, argc - curindex, argv + curindex); |
||||
+ else if (strcmp (command, "incr") == 0) |
||||
+ incr_variables (filename, argc - curindex, argv + curindex); |
||||
else |
||||
{ |
||||
char *program = xstrdup(program_name); |
@ -0,0 +1,183 @@
@@ -0,0 +1,183 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Hans de Goede <hdegoede@redhat.com> |
||||
Date: Wed, 6 Jun 2018 08:44:11 +0200 |
||||
Subject: [PATCH] Add auto-hide menu support |
||||
|
||||
On single-os systems we do not want to show the menu, unless something |
||||
went wrong with the previous boot, in which case the user may need the |
||||
menu to debug/fix the problem. |
||||
|
||||
This commit adds a new grub.d/00_menu_auto_hide file which emits a |
||||
config snippet implementing this. I've chosen to do this in a separate |
||||
grub.d file because chances of this going upstream are small and this way |
||||
it will be easier to rebase. |
||||
|
||||
Since auto-hiding the menu requires detecting the previous boot was ok, |
||||
we get fastboot support (where we don't check for a key at all) for free |
||||
so this commit also adds support for this. |
||||
|
||||
The new config-file code uses the following variables: |
||||
|
||||
menu_auto_hide Set this to "1" to activate the new auto-hide feature |
||||
Set this to "2" to auto-hide the menu even when multiple |
||||
operating systems are installed. Note the menu will still |
||||
auto show after booting an other os as that won't set |
||||
boot_success. |
||||
menu_show_once Set this to "1" to force showing the menu once. |
||||
boot_success The OS sets this to "1" to indicate a successful boot. |
||||
boot_indeterminate The OS increments this integer when rebooting after e.g. |
||||
installing updates or a selinux relabel. |
||||
fastboot If set to "1" and the conditions for auto-hiding the menu |
||||
are met, the menu is not shown and all checks for keypresses |
||||
are skipped, booting the default immediately. |
||||
|
||||
30_os-prober.in changes somewhat inspired by: |
||||
https://git.launchpad.net/~ubuntu-core-dev/grub/+git/ubuntu/tree/debian/patches/quick_boot.patch |
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
||||
--- |
||||
Makefile.util.def | 6 +++++ |
||||
util/grub.d/01_menu_auto_hide.in | 48 ++++++++++++++++++++++++++++++++++++++++ |
||||
util/grub.d/30_os-prober.in | 18 +++++++++++++++ |
||||
3 files changed, 72 insertions(+) |
||||
create mode 100644 util/grub.d/01_menu_auto_hide.in |
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index bda9fd1211..cb8e3c3270 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -458,6 +458,12 @@ script = { |
||||
installdir = grubconf; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = '01_menu_auto_hide'; |
||||
+ common = util/grub.d/01_menu_auto_hide.in; |
||||
+ installdir = grubconf; |
||||
+}; |
||||
+ |
||||
script = { |
||||
name = '01_users'; |
||||
common = util/grub.d/01_users.in; |
||||
diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/01_menu_auto_hide.in |
||||
new file mode 100644 |
||||
index 0000000000..ad175870a5 |
||||
--- /dev/null |
||||
+++ b/util/grub.d/01_menu_auto_hide.in |
||||
@@ -0,0 +1,48 @@ |
||||
+#! /bin/sh |
||||
+ |
||||
+# Disable / skip generating menu-auto-hide config parts on serial terminals |
||||
+for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do |
||||
+ case "$x" in |
||||
+ serial*) |
||||
+ exit 0 |
||||
+ ;; |
||||
+ esac |
||||
+done |
||||
+ |
||||
+cat << EOF |
||||
+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then |
||||
+ set last_boot_ok=1 |
||||
+else |
||||
+ set last_boot_ok=0 |
||||
+fi |
||||
+ |
||||
+# Reset boot_indeterminate after a successful boot |
||||
+if [ "\${boot_success}" = "1" ] ; then |
||||
+ set boot_indeterminate=0 |
||||
+# Avoid boot_indeterminate causing the menu to be hidden more then once |
||||
+elif [ "\${boot_indeterminate}" = "1" ]; then |
||||
+ set boot_indeterminate=2 |
||||
+fi |
||||
+set boot_success=0 |
||||
+save_env boot_success boot_indeterminate |
||||
+ |
||||
+if [ x\$feature_timeout_style = xy ] ; then |
||||
+ if [ "\${menu_show_once}" ]; then |
||||
+ unset menu_show_once |
||||
+ save_env menu_show_once |
||||
+ set timeout_style=menu |
||||
+ set timeout=60 |
||||
+ elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then |
||||
+ set orig_timeout_style=\${timeout_style} |
||||
+ set orig_timeout=\${timeout} |
||||
+ if [ "\${fastboot}" = "1" ]; then |
||||
+ # timeout_style=menu + timeout=0 avoids the countdown code keypress check |
||||
+ set timeout_style=menu |
||||
+ set timeout=0 |
||||
+ else |
||||
+ set timeout_style=hidden |
||||
+ set timeout=1 |
||||
+ fi |
||||
+ fi |
||||
+fi |
||||
+EOF |
||||
diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in |
||||
index 4b27bd2015..3c9431cfcf 100644 |
||||
--- a/util/grub.d/30_os-prober.in |
||||
+++ b/util/grub.d/30_os-prober.in |
||||
@@ -42,6 +42,7 @@ if [ -z "${OSPROBED}" ] ; then |
||||
fi |
||||
|
||||
osx_entry() { |
||||
+ found_other_os=1 |
||||
# TRANSLATORS: it refers on the OS residing on device %s |
||||
onstr="$(gettext_printf "(on %s)" "${DEVICE}")" |
||||
hints="" |
||||
@@ -102,6 +103,7 @@ for OS in ${OSPROBED} ; do |
||||
|
||||
case ${BOOT} in |
||||
chain) |
||||
+ found_other_os=1 |
||||
|
||||
onstr="$(gettext_printf "(on %s)" "${DEVICE}")" |
||||
cat << EOF |
||||
@@ -132,6 +134,7 @@ EOF |
||||
EOF |
||||
;; |
||||
efi) |
||||
+ found_other_os=1 |
||||
|
||||
EFIPATH=${DEVICE#*@} |
||||
DEVICE=${DEVICE%@*} |
||||
@@ -176,6 +179,7 @@ EOF |
||||
LINITRD="${LINITRD#/boot}" |
||||
fi |
||||
|
||||
+ found_other_os=1 |
||||
onstr="$(gettext_printf "(on %s)" "${DEVICE}")" |
||||
recovery_params="$(echo "${LPARAMS}" | grep single)" || true |
||||
counter=1 |
||||
@@ -257,6 +261,7 @@ EOF |
||||
done |
||||
;; |
||||
hurd) |
||||
+ found_other_os=1 |
||||
onstr="$(gettext_printf "(on %s)" "${DEVICE}")" |
||||
cat << EOF |
||||
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' { |
||||
@@ -283,6 +288,7 @@ EOF |
||||
EOF |
||||
;; |
||||
minix) |
||||
+ found_other_os=1 |
||||
cat << EOF |
||||
menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" { |
||||
EOF |
||||
@@ -299,3 +305,15 @@ EOF |
||||
;; |
||||
esac |
||||
done |
||||
+ |
||||
+# We override the results of the menu_auto_hide code here, this is a bit ugly, |
||||
+# but grub-mkconfig writes out the file linearly, so this is the only way |
||||
+if [ "${found_other_os}" = "1" ]; then |
||||
+ cat << EOF |
||||
+# Other OS found, undo autohiding of menu unless menu_auto_hide=2 |
||||
+if [ "\${orig_timeout_style}" -a "\${menu_auto_hide}" != "2" ]; then |
||||
+ set timeout_style=\${orig_timeout_style} |
||||
+ set timeout=\${orig_timeout} |
||||
+fi |
||||
+EOF |
||||
+fi |
@ -0,0 +1,290 @@
@@ -0,0 +1,290 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Hans de Goede <hdegoede@redhat.com> |
||||
Date: Tue, 12 Jun 2018 13:25:16 +0200 |
||||
Subject: [PATCH] Add grub-set-bootflag utility |
||||
|
||||
This commit adds a new grub-set-bootflag utility, which can be used |
||||
to set known bootflags in the grubenv: boot_success or menu_show_once. |
||||
|
||||
grub-set-bootflag is different from grub-editenv in 2 ways: |
||||
|
||||
1) It is intended to be executed by regular users so must be installed |
||||
as suid root. As such it is written to not use any existing grubenv |
||||
related code for easy auditing. |
||||
|
||||
It can't be executed through pkexec because we want to call it under gdm |
||||
and pkexec does not work under gdm due the gdm user having /sbin/nologin |
||||
as shell. |
||||
|
||||
2) Since it can be executed by regular users it only allows setting |
||||
(assigning a value of 1 to) bootflags which it knows about. Currently |
||||
those are just boot_success and menu_show_once. |
||||
|
||||
This commit also adds a couple of example systemd and files which show |
||||
how this can be used to set boot_success from a user-session: |
||||
|
||||
docs/grub-boot-success.service |
||||
docs/grub-boot-success.timer |
||||
|
||||
The 2 grub-boot-success.systemd files should be placed in /lib/systemd/user |
||||
and a symlink to grub-boot-success.timer should be added to |
||||
/lib/systemd/user/timers.target.wants. |
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
||||
[makhomed: grub-boot-success.timer: Only run if not in a container] |
||||
Signed-off-by: Gena Makhomed <makhomed@gmail.com> |
||||
[rharwood: migrate to h2m] |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
Makefile.util.def | 7 ++ |
||||
util/grub-set-bootflag.c | 172 +++++++++++++++++++++++++++++++++++++++++ |
||||
conf/Makefile.extra-dist | 3 + |
||||
docs/grub-boot-success.service | 6 ++ |
||||
docs/grub-boot-success.timer | 7 ++ |
||||
docs/man/grub-set-bootflag.h2m | 2 + |
||||
6 files changed, 197 insertions(+) |
||||
create mode 100644 util/grub-set-bootflag.c |
||||
create mode 100644 docs/grub-boot-success.service |
||||
create mode 100644 docs/grub-boot-success.timer |
||||
create mode 100644 docs/man/grub-set-bootflag.h2m |
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index cb8e3c3270..d066652e9b 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -1429,3 +1429,10 @@ program = { |
||||
ldadd = grub-core/lib/gnulib/libgnu.a; |
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; |
||||
}; |
||||
+ |
||||
+program = { |
||||
+ name = grub-set-bootflag; |
||||
+ installdir = sbin; |
||||
+ mansection = 1; |
||||
+ common = util/grub-set-bootflag.c; |
||||
+}; |
||||
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c |
||||
new file mode 100644 |
||||
index 0000000000..d506f7e75b |
||||
--- /dev/null |
||||
+++ b/util/grub-set-bootflag.c |
||||
@@ -0,0 +1,172 @@ |
||||
+/* grub-set-bootflag.c - tool to set boot-flags in the grubenv. */ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2018 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/>. |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * NOTE this gets run by users as root (through pkexec), so this does not |
||||
+ * use any grub library / util functions to allow for easy auditing. |
||||
+ * The grub headers are only included to get certain defines. |
||||
+ */ |
||||
+ |
||||
+#include <config-util.h> /* For *_DIR_NAME defines */ |
||||
+#include <grub/types.h> |
||||
+#include <grub/lib/envblk.h> /* For GRUB_ENVBLK_DEFCFG define */ |
||||
+#include <errno.h> |
||||
+#include <stdio.h> |
||||
+#include <string.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+#include "progname.h" |
||||
+ |
||||
+#define GRUBENV "/" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME "/" GRUB_ENVBLK_DEFCFG |
||||
+#define GRUBENV_SIZE 1024 |
||||
+ |
||||
+const char *bootflags[] = { |
||||
+ "boot_success", |
||||
+ "menu_show_once", |
||||
+ NULL |
||||
+}; |
||||
+ |
||||
+static void usage(FILE *out) |
||||
+{ |
||||
+ int i; |
||||
+ |
||||
+ fprintf (out, "Usage: 'grub-set-bootflag <bootflag>', where <bootflag> is one of:\n"); |
||||
+ for (i = 0; bootflags[i]; i++) |
||||
+ fprintf (out, " %s\n", bootflags[i]); |
||||
+} |
||||
+ |
||||
+int main(int argc, char *argv[]) |
||||
+{ |
||||
+ /* NOTE buf must be at least the longest bootflag length + 4 bytes */ |
||||
+ char env[GRUBENV_SIZE + 1], buf[64], *s; |
||||
+ const char *bootflag; |
||||
+ int i, len, ret; |
||||
+ FILE *f; |
||||
+ |
||||
+ if (argc != 2) |
||||
+ { |
||||
+ usage (stderr); |
||||
+ return 1; |
||||
+ } |
||||
+ else if (!strcmp (argv[1], "--help")) |
||||
+ { |
||||
+ usage (stdout); |
||||
+ return 0; |
||||
+ } |
||||
+ else if (!strcmp (argv[1], "--version")) |
||||
+ { |
||||
+ printf ("grub-set-bootflag (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
+ for (i = 0; bootflags[i]; i++) |
||||
+ if (!strcmp (argv[1], bootflags[i])) |
||||
+ break; |
||||
+ if (!bootflags[i]) |
||||
+ { |
||||
+ fprintf (stderr, "Invalid bootflag: '%s'\n", argv[1]); |
||||
+ usage (stderr); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ bootflag = bootflags[i]; |
||||
+ len = strlen (bootflag); |
||||
+ |
||||
+ f = fopen (GRUBENV, "r"); |
||||
+ if (!f) |
||||
+ { |
||||
+ perror ("Error opening " GRUBENV " for reading"); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ ret = fread (env, 1, GRUBENV_SIZE, f); |
||||
+ fclose (f); |
||||
+ if (ret != GRUBENV_SIZE) |
||||
+ { |
||||
+ errno = EINVAL; |
||||
+ perror ("Error reading from " GRUBENV); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ /* 0 terminate env */ |
||||
+ env[GRUBENV_SIZE] = 0; |
||||
+ |
||||
+ if (strncmp (env, GRUB_ENVBLK_SIGNATURE, strlen (GRUB_ENVBLK_SIGNATURE))) |
||||
+ { |
||||
+ fprintf (stderr, "Error invalid environment block\n"); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ /* Find a pre-existing definition of the bootflag */ |
||||
+ s = strstr (env, bootflag); |
||||
+ while (s && s[len] != '=') |
||||
+ s = strstr (s + len, bootflag); |
||||
+ |
||||
+ if (s && ((s[len + 1] != '0' && s[len + 1] != '1') || s[len + 2] != '\n')) |
||||
+ { |
||||
+ fprintf (stderr, "Pre-existing bootflag '%s' has unexpected value\n", bootflag); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ /* No pre-existing bootflag? -> find free space */ |
||||
+ if (!s) |
||||
+ { |
||||
+ for (i = 0; i < (len + 3); i++) |
||||
+ buf[i] = '#'; |
||||
+ buf[i] = 0; |
||||
+ s = strstr (env, buf); |
||||
+ } |
||||
+ |
||||
+ if (!s) |
||||
+ { |
||||
+ fprintf (stderr, "No space in grubenv to store bootflag '%s'\n", bootflag); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ /* The grubenv is not 0 terminated, so memcpy the name + '=' , '1', '\n' */ |
||||
+ snprintf(buf, sizeof(buf), "%s=1\n", bootflag); |
||||
+ memcpy(s, buf, len + 3); |
||||
+ |
||||
+ /* "r+", don't truncate so that the diskspace stays reserved */ |
||||
+ f = fopen (GRUBENV, "r+"); |
||||
+ if (!f) |
||||
+ { |
||||
+ perror ("Error opening " GRUBENV " for writing"); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ ret = fwrite (env, 1, GRUBENV_SIZE, f); |
||||
+ if (ret != GRUBENV_SIZE) |
||||
+ { |
||||
+ perror ("Error writing to " GRUBENV); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ ret = fflush (f); |
||||
+ if (ret) |
||||
+ { |
||||
+ perror ("Error flushing " GRUBENV); |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ fsync (fileno (f)); |
||||
+ fclose (f); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist |
||||
index 8f1485d52a..ad235de7fc 100644 |
||||
--- a/conf/Makefile.extra-dist |
||||
+++ b/conf/Makefile.extra-dist |
||||
@@ -15,6 +15,9 @@ EXTRA_DIST += docs/man |
||||
EXTRA_DIST += docs/autoiso.cfg |
||||
EXTRA_DIST += docs/grub.cfg |
||||
EXTRA_DIST += docs/osdetect.cfg |
||||
+EXTRA_DIST += docs/org.gnu.grub.policy |
||||
+EXTRA_DIST += docs/grub-boot-success.service |
||||
+EXTRA_DIST += docs/grub-boot-success.timer |
||||
|
||||
EXTRA_DIST += conf/i386-cygwin-img-ld.sc |
||||
|
||||
diff --git a/docs/grub-boot-success.service b/docs/grub-boot-success.service |
||||
new file mode 100644 |
||||
index 0000000000..80e79584c9 |
||||
--- /dev/null |
||||
+++ b/docs/grub-boot-success.service |
||||
@@ -0,0 +1,6 @@ |
||||
+[Unit] |
||||
+Description=Mark boot as successful |
||||
+ |
||||
+[Service] |
||||
+Type=oneshot |
||||
+ExecStart=/usr/sbin/grub2-set-bootflag boot_success |
||||
diff --git a/docs/grub-boot-success.timer b/docs/grub-boot-success.timer |
||||
new file mode 100644 |
||||
index 0000000000..406f172005 |
||||
--- /dev/null |
||||
+++ b/docs/grub-boot-success.timer |
||||
@@ -0,0 +1,7 @@ |
||||
+[Unit] |
||||
+Description=Mark boot as successful after the user session has run 2 minutes |
||||
+ConditionUser=!@system |
||||
+ConditionVirtualization=!container |
||||
+ |
||||
+[Timer] |
||||
+OnActiveSec=2min |
||||
diff --git a/docs/man/grub-set-bootflag.h2m b/docs/man/grub-set-bootflag.h2m |
||||
new file mode 100644 |
||||
index 0000000000..94ec0b92ed |
||||
--- /dev/null |
||||
+++ b/docs/man/grub-set-bootflag.h2m |
||||
@@ -0,0 +1,2 @@ |
||||
+[NAME] |
||||
+grub-set-bootflag \- set a bootflag in the GRUB environment block |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Hans de Goede <hdegoede@redhat.com> |
||||
Date: Tue, 19 Jun 2018 15:20:54 +0200 |
||||
Subject: [PATCH] docs: Add grub-boot-indeterminate.service example |
||||
|
||||
This is an example service file, for use from |
||||
/lib/systemd/system/system-update.target.wants |
||||
to increment the boot_indeterminate variable when |
||||
doing offline updates. |
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
||||
--- |
||||
docs/grub-boot-indeterminate.service | 11 +++++++++++ |
||||
1 file changed, 11 insertions(+) |
||||
create mode 100644 docs/grub-boot-indeterminate.service |
||||
|
||||
diff --git a/docs/grub-boot-indeterminate.service b/docs/grub-boot-indeterminate.service |
||||
new file mode 100644 |
||||
index 0000000000..6c8dcb186b |
||||
--- /dev/null |
||||
+++ b/docs/grub-boot-indeterminate.service |
||||
@@ -0,0 +1,11 @@ |
||||
+[Unit] |
||||
+Description=Mark boot as indeterminate |
||||
+DefaultDependencies=false |
||||
+Requires=sysinit.target |
||||
+After=sysinit.target |
||||
+Wants=system-update-pre.target |
||||
+Before=system-update-pre.target |
||||
+ |
||||
+[Service] |
||||
+Type=oneshot |
||||
+ExecStart=/usr/bin/grub2-editenv - incr boot_indeterminate |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Wed, 11 Jul 2018 13:43:15 -0400 |
||||
Subject: [PATCH] gentpl: add 'disable = ' support |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
gentpl.py | 14 +++++++++++++- |
||||
1 file changed, 13 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/gentpl.py b/gentpl.py |
||||
index c86550d4f9..f3c5f84f85 100644 |
||||
--- a/gentpl.py |
||||
+++ b/gentpl.py |
||||
@@ -592,11 +592,21 @@ def platform_conditional(platform, closure): |
||||
# }; |
||||
# |
||||
def foreach_enabled_platform(defn, closure): |
||||
+ enabled = False |
||||
+ disabled = False |
||||
if 'enable' in defn: |
||||
+ enabled = True |
||||
for platform in GRUB_PLATFORMS: |
||||
if platform_tagged(defn, platform, "enable"): |
||||
platform_conditional(platform, closure) |
||||
- else: |
||||
+ |
||||
+ if 'disable' in defn: |
||||
+ disabled = True |
||||
+ for platform in GRUB_PLATFORMS: |
||||
+ if not platform_tagged(defn, platform, "disable"): |
||||
+ platform_conditional(platform, closure) |
||||
+ |
||||
+ if not enabled and not disabled: |
||||
for platform in GRUB_PLATFORMS: |
||||
platform_conditional(platform, closure) |
||||
|
||||
@@ -655,6 +665,8 @@ def first_time(defn, snippet): |
||||
def is_platform_independent(defn): |
||||
if 'enable' in defn: |
||||
return False |
||||
+ if 'disable' in defn: |
||||
+ return False |
||||
for suffix in [ "", "_nodist" ]: |
||||
template = platform_values(defn, GRUB_PLATFORMS[0], suffix) |
||||
for platform in GRUB_PLATFORMS[1:]: |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 11 Jul 2019 11:04:24 +0200 |
||||
Subject: [PATCH] gentpl: add 'pc' firmware type |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
gentpl.py | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/gentpl.py b/gentpl.py |
||||
index f3c5f84f85..f09b336869 100644 |
||||
--- a/gentpl.py |
||||
+++ b/gentpl.py |
||||
@@ -51,6 +51,7 @@ GROUPS["riscv32"] = [ "riscv32_efi" ] |
||||
GROUPS["riscv64"] = [ "riscv64_efi" ] |
||||
|
||||
# Groups based on firmware |
||||
+GROUPS["pc"] = [ "i386_pc" ] |
||||
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", |
||||
"riscv32_efi", "riscv64_efi" ] |
||||
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 30 Jul 2018 14:06:42 -0400 |
||||
Subject: [PATCH] efinet: also use the firmware acceleration for http |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/net/efi/net.c | 4 +++- |
||||
1 file changed, 3 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c |
||||
index 4bb308026c..6603cd83ed 100644 |
||||
--- a/grub-core/net/efi/net.c |
||||
+++ b/grub-core/net/efi/net.c |
||||
@@ -1324,7 +1324,9 @@ grub_efi_net_boot_from_https (void) |
||||
&& (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) |
||||
{ |
||||
grub_efi_uri_device_path_t *uri_dp = (grub_efi_uri_device_path_t *) dp; |
||||
- return (grub_strncmp ((const char*)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0) ? 1 : 0; |
||||
+ grub_dprintf ("efinet", "url:%s\n", (const char *)uri_dp->uri); |
||||
+ return (grub_strncmp ((const char *)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0 || |
||||
+ grub_strncmp ((const char *)uri_dp->uri, "http://", sizeof ("http://") - 1) == 0); |
||||
} |
||||
|
||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 30 Jul 2018 16:39:57 -0400 |
||||
Subject: [PATCH] efi/http: Make root_url reflect the protocol+hostname of our |
||||
boot url. |
||||
|
||||
This lets you write config files that don't know urls. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/net/efi/http.c | 19 +++++++++++++++++++ |
||||
1 file changed, 19 insertions(+) |
||||
|
||||
diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c |
||||
index 3f61fd2fa5..243acbaa35 100644 |
||||
--- a/grub-core/net/efi/http.c |
||||
+++ b/grub-core/net/efi/http.c |
||||
@@ -4,6 +4,7 @@ |
||||
#include <grub/misc.h> |
||||
#include <grub/net/efi.h> |
||||
#include <grub/charset.h> |
||||
+#include <grub/env.h> |
||||
|
||||
static void |
||||
http_configure (struct grub_efi_net_device *dev, int prefer_ip6) |
||||
@@ -351,6 +352,24 @@ grub_efihttp_open (struct grub_efi_net_device *dev, |
||||
grub_err_t err; |
||||
grub_off_t size; |
||||
char *buf; |
||||
+ char *root_url; |
||||
+ grub_efi_ipv6_address_t address; |
||||
+ const char *rest; |
||||
+ |
||||
+ if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0) |
||||
+ root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server); |
||||
+ else |
||||
+ root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server); |
||||
+ if (root_url) |
||||
+ { |
||||
+ grub_env_unset ("root_url"); |
||||
+ grub_env_set ("root_url", root_url); |
||||
+ grub_free (root_url); |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ return grub_errno; |
||||
+ } |
||||
|
||||
err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); |
||||
if (err != GRUB_ERR_NONE) |
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 26 Jun 2018 17:16:06 -0400 |
||||
Subject: [PATCH] Make it so we can tell configure which cflags utils are built |
||||
with |
||||
|
||||
This lets us have kernel.img be built with TARGET_CFLAGS but grub-mkimage and |
||||
friends built with HOST_CFLAGS. That in turn lets us build with an ARM compiler |
||||
that only has hard-float ABI versions of crt*.o and libgcc*, but still use soft |
||||
float for grub.efi. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
configure.ac | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- |
||||
conf/Makefile.common | 23 ++++++++++++----------- |
||||
gentpl.py | 8 ++++---- |
||||
3 files changed, 64 insertions(+), 16 deletions(-) |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 302300711f..008f6c273b 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -849,11 +849,23 @@ if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$p |
||||
TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" |
||||
fi |
||||
|
||||
+# Should grub utils get the host CFLAGS, or the target CFLAGS? |
||||
+AC_ARG_WITH([utils], |
||||
+ AS_HELP_STRING([--with-utils=host|target|build], |
||||
+ [choose which flags to build utilities with. (default=target)]), |
||||
+ [have_with_utils=y], |
||||
+ [have_with_utils=n]) |
||||
+if test x"$have_with_utils" = xy ; then |
||||
+ with_utils="$withval" |
||||
+else |
||||
+ with_utils=target |
||||
+fi |
||||
+ |
||||
# GRUB doesn't use float or doubles at all. Yet some toolchains may decide |
||||
# that floats are a good fit to run instead of what's written in the code. |
||||
# Given that floating point unit is disabled (if present to begin with) |
||||
# when GRUB is running which may result in various hard crashes. |
||||
-if test x"$platform" != xemu ; then |
||||
+if test x"$platform" != xemu -a x"$with_utils" == xtarget ; then |
||||
AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ |
||||
grub_cv_target_cc_soft_float=no |
||||
if test "x$target_cpu" = xarm64; then |
||||
@@ -1954,6 +1966,41 @@ HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" |
||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" |
||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" |
||||
|
||||
+case "$with_utils" in |
||||
+ host) |
||||
+ UTILS_CFLAGS=$HOST_CFLAGS |
||||
+ UTILS_CPPFLAGS=$HOST_CPPFLAGS |
||||
+ UTILS_CCASFLAGS=$HOST_CCASFLAGS |
||||
+ UTILS_LDFLAGS=$HOST_LDFLAGS |
||||
+ ;; |
||||
+ target) |
||||
+ UTILS_CFLAGS=$TARGET_CFLAGS |
||||
+ UTILS_CPPFLAGS=$TARGET_CPPFLAGS |
||||
+ UTILS_CCASFLAGS=$TARGET_CCASFLAGS |
||||
+ UTILS_LDFLAGS=$TARGET_LDFLAGS |
||||
+ ;; |
||||
+ build) |
||||
+ UTILS_CFLAGS=$BUILD_CFLAGS |
||||
+ UTILS_CPPFLAGS=$BUILD_CPPFLAGS |
||||
+ UTILS_CCASFLAGS=$BUILD_CCASFLAGS |
||||
+ UTILS_LDFLAGS=$BUILD_LDFLAGS |
||||
+ ;; |
||||
+ *) |
||||
+ AC_MSG_ERROR([--with-utils must be either host, target, or build]) |
||||
+ ;; |
||||
+esac |
||||
+AC_MSG_NOTICE([Using $with_utils flags for utilities.]) |
||||
+ |
||||
+unset CFLAGS |
||||
+unset CPPFLAGS |
||||
+unset CCASFLAGS |
||||
+unset LDFLAGS |
||||
+ |
||||
+AC_SUBST(UTILS_CFLAGS) |
||||
+AC_SUBST(UTILS_CPPFLAGS) |
||||
+AC_SUBST(UTILS_CCASFLAGS) |
||||
+AC_SUBST(UTILS_LDFLAGS) |
||||
+ |
||||
GRUB_TARGET_CPU="${target_cpu}" |
||||
GRUB_PLATFORM="${platform}" |
||||
|
||||
diff --git a/conf/Makefile.common b/conf/Makefile.common |
||||
index 5f0ef96985..2ff9b39357 100644 |
||||
--- a/conf/Makefile.common |
||||
+++ b/conf/Makefile.common |
||||
@@ -40,24 +40,25 @@ CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 |
||||
CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) |
||||
STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -R .note.gnu.property -R .gnu.build.attributes |
||||
|
||||
-CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding |
||||
-LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d |
||||
-CPPFLAGS_MODULE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) |
||||
-CCASFLAGS_MODULE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) |
||||
+CFLAGS_MODULE = $(TARGET_CFLAGS) $(CFLAGS_PLATFORM) -ffreestanding |
||||
+LDFLAGS_MODULE = $(TARGET_LDFLAGS) $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d |
||||
+CPPFLAGS_MODULE = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) |
||||
+CCASFLAGS_MODULE = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) |
||||
|
||||
CFLAGS_IMAGE = $(CFLAGS_PLATFORM) -fno-builtin |
||||
LDFLAGS_IMAGE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-S |
||||
CPPFLAGS_IMAGE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) |
||||
CCASFLAGS_IMAGE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) |
||||
|
||||
-CFLAGS_PROGRAM = |
||||
-LDFLAGS_PROGRAM = |
||||
-CPPFLAGS_PROGRAM = |
||||
-CCASFLAGS_PROGRAM = |
||||
+CFLAGS_PROGRAM = $(UTILS_CFLAGS) |
||||
+LDFLAGS_PROGRAM = $(UTILS_LDFLAGS) |
||||
+CPPFLAGS_PROGRAM = $(UTILS_CPPFLAGS) |
||||
+CCASFLAGS_PROGRAM = $(UTILS_CCASFLAGS) |
||||
|
||||
-CFLAGS_LIBRARY = |
||||
-CPPFLAGS_LIBRARY = |
||||
-CCASFLAGS_LIBRARY = |
||||
+CFLAGS_LIBRARY = $(UTILS_CFLAGS) |
||||
+LDFLAGS_LIBRARY = $(UTILS_LDFLAGS) |
||||
+CPPFLAGS_LIBRARY = $(UTILS_CPPFLAGS) |
||||
+CCASFLAGS_LIBRARY = $(UTILS_CCASFLAGS) |
||||
|
||||
# Other variables |
||||
|
||||
diff --git a/gentpl.py b/gentpl.py |
||||
index f09b336869..0e62e14666 100644 |
||||
--- a/gentpl.py |
||||
+++ b/gentpl.py |
||||
@@ -697,10 +697,10 @@ def module(defn, platform): |
||||
var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") |
||||
var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") |
||||
var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) |
||||
- var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) |
||||
- var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) |
||||
- var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) |
||||
- var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) |
||||
+ var_set(cname(defn) + "_CFLAGS", "$(CFLAGS_MODULE) " + platform_cflags(defn, platform)) |
||||
+ var_set(cname(defn) + "_LDFLAGS", "$(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) |
||||
+ var_set(cname(defn) + "_CPPFLAGS", "$(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) |
||||
+ var_set(cname(defn) + "_CCASFLAGS", "$(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) |
||||
var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) |
||||
|
||||
gvar_add("dist_noinst_DATA", extra_dist(defn)) |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Wed, 1 Aug 2018 10:24:52 -0400 |
||||
Subject: [PATCH] module-verifier: make it possible to run checkers on |
||||
grub-module-verifierxx.c |
||||
|
||||
This makes it so you can treat grub-module-verifierxx.c as a file you can |
||||
build directly, so syntax checkers like vim's "syntastic" plugin, which uses |
||||
"gcc -x c -fsyntax-only" to build it, will work. |
||||
|
||||
One still has to do whatever setup is required to make it pick the right |
||||
include dirs, which -W options we use, etc., but this makes it so you can do |
||||
the checking on the file you're editing, rather than on a different file. |
||||
|
||||
v2: fix the typo in the #else clause in util/grub-module-verifierXX.c |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
util/grub-module-verifier32.c | 2 ++ |
||||
util/grub-module-verifier64.c | 2 ++ |
||||
util/grub-module-verifierXX.c | 9 +++++++++ |
||||
3 files changed, 13 insertions(+) |
||||
|
||||
diff --git a/util/grub-module-verifier32.c b/util/grub-module-verifier32.c |
||||
index 257229f8f0..ba7d41aafe 100644 |
||||
--- a/util/grub-module-verifier32.c |
||||
+++ b/util/grub-module-verifier32.c |
||||
@@ -1,2 +1,4 @@ |
||||
#define MODULEVERIFIER_ELF32 1 |
||||
+#ifndef GRUB_MODULE_VERIFIERXX |
||||
#include "grub-module-verifierXX.c" |
||||
+#endif |
||||
diff --git a/util/grub-module-verifier64.c b/util/grub-module-verifier64.c |
||||
index 4db6b4bedd..fc23ef800b 100644 |
||||
--- a/util/grub-module-verifier64.c |
||||
+++ b/util/grub-module-verifier64.c |
||||
@@ -1,2 +1,4 @@ |
||||
#define MODULEVERIFIER_ELF64 1 |
||||
+#ifndef GRUB_MODULE_VERIFIERXX |
||||
#include "grub-module-verifierXX.c" |
||||
+#endif |
||||
diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c |
||||
index ceb24309ae..a98e2f9b1a 100644 |
||||
--- a/util/grub-module-verifierXX.c |
||||
+++ b/util/grub-module-verifierXX.c |
||||
@@ -1,3 +1,12 @@ |
||||
+#define GRUB_MODULE_VERIFIERXX |
||||
+#if !defined(MODULEVERIFIER_ELF32) && !defined(MODULEVERIFIER_ELF64) |
||||
+#if __SIZEOF_POINTER__ == 8 |
||||
+#include "grub-module-verifier64.c" |
||||
+#else |
||||
+#include "grub-module-verifier32.c" |
||||
+#endif |
||||
+#endif |
||||
+ |
||||
#include <string.h> |
||||
|
||||
#include <grub/elf.h> |
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 11 Jul 2019 13:01:41 +0200 |
||||
Subject: [PATCH] Rework how the fdt command builds. |
||||
|
||||
Trying to avoid all variants of: |
||||
cat syminfo.lst | sort | gawk -f ../../grub-core/genmoddep.awk > moddep.lst || (rm -f moddep.lst; exit 1) |
||||
grub_fdt_install in linux is not defined |
||||
grub_fdt_load in linux is not defined |
||||
grub_fdt_unload in linux is not defined |
||||
grub_fdt_install in xen_boot is not defined |
||||
grub_fdt_load in xen_boot is not defined |
||||
grub_fdt_unload in xen_boot is not defined |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[javierm: Fix build with platform emu, aarch64, and risc-v] |
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/Makefile.core.def | 5 ++--- |
||||
grub-core/lib/fdt.c | 2 -- |
||||
grub-core/loader/efi/fdt.c | 2 ++ |
||||
include/grub/fdt.h | 6 ++++++ |
||||
grub-core/Makefile.am | 1 + |
||||
5 files changed, 11 insertions(+), 5 deletions(-) |
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
||||
index 12797336c9..4e7d90da76 100644 |
||||
--- a/grub-core/Makefile.core.def |
||||
+++ b/grub-core/Makefile.core.def |
||||
@@ -177,7 +177,6 @@ kernel = { |
||||
arm_coreboot = kern/arm/coreboot/init.c; |
||||
arm_coreboot = kern/arm/coreboot/timer.c; |
||||
arm_coreboot = kern/arm/coreboot/coreboot.S; |
||||
- arm_coreboot = lib/fdt.c; |
||||
arm_coreboot = bus/fdt.c; |
||||
arm_coreboot = term/ps2.c; |
||||
arm_coreboot = term/arm/pl050.c; |
||||
@@ -351,6 +350,8 @@ kernel = { |
||||
riscv64 = kern/riscv/cache_flush.S; |
||||
riscv64 = kern/riscv/dl.c; |
||||
|
||||
+ fdt = lib/fdt.c; |
||||
+ |
||||
emu = disk/host.c; |
||||
emu = kern/emu/cache_s.S; |
||||
emu = kern/emu/hostdisk.c; |
||||
@@ -1825,7 +1826,6 @@ module = { |
||||
riscv32 = loader/riscv/linux.c; |
||||
riscv64 = loader/riscv/linux.c; |
||||
emu = loader/emu/linux.c; |
||||
- fdt = lib/fdt.c; |
||||
|
||||
common = loader/linux.c; |
||||
common = lib/cmdline.c; |
||||
@@ -1837,7 +1837,6 @@ module = { |
||||
module = { |
||||
name = fdt; |
||||
efi = loader/efi/fdt.c; |
||||
- common = lib/fdt.c; |
||||
enable = fdt; |
||||
}; |
||||
|
||||
diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c |
||||
index 0d371c5633..37e04bd69e 100644 |
||||
--- a/grub-core/lib/fdt.c |
||||
+++ b/grub-core/lib/fdt.c |
||||
@@ -21,8 +21,6 @@ |
||||
#include <grub/mm.h> |
||||
#include <grub/dl.h> |
||||
|
||||
-GRUB_MOD_LICENSE ("GPLv3+"); |
||||
- |
||||
#define FDT_SUPPORTED_VERSION 17 |
||||
|
||||
#define FDT_BEGIN_NODE 0x00000001 |
||||
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c |
||||
index c86f283d75..c572415d38 100644 |
||||
--- a/grub-core/loader/efi/fdt.c |
||||
+++ b/grub-core/loader/efi/fdt.c |
||||
@@ -27,6 +27,8 @@ |
||||
#include <grub/efi/memory.h> |
||||
#include <grub/cpu/efi/memory.h> |
||||
|
||||
+GRUB_MOD_LICENSE ("GPLv3+"); |
||||
+ |
||||
static void *loaded_fdt; |
||||
static void *fdt; |
||||
|
||||
diff --git a/include/grub/fdt.h b/include/grub/fdt.h |
||||
index e609c7e411..3514aa4a5b 100644 |
||||
--- a/include/grub/fdt.h |
||||
+++ b/include/grub/fdt.h |
||||
@@ -19,6 +19,9 @@ |
||||
#ifndef GRUB_FDT_HEADER |
||||
#define GRUB_FDT_HEADER 1 |
||||
|
||||
+#if !defined(GRUB_MACHINE_EMU) && \ |
||||
+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) |
||||
+ |
||||
#include <grub/types.h> |
||||
#include <grub/symbol.h> |
||||
|
||||
@@ -144,4 +147,7 @@ int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const ch |
||||
grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \ |
||||
}) |
||||
|
||||
+#endif /* !defined(GRUB_MACHINE_EMU) && \ |
||||
+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) */ |
||||
+ |
||||
#endif /* ! GRUB_FDT_HEADER */ |
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am |
||||
index bfd29a3bf0..c2e8a82bce 100644 |
||||
--- a/grub-core/Makefile.am |
||||
+++ b/grub-core/Makefile.am |
||||
@@ -76,6 +76,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/sb.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h |
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h |
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 2 Aug 2018 10:56:38 -0400 |
||||
Subject: [PATCH] Disable non-wordsize allocations on arm |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
configure.ac | 20 ++++++++++++++++++++ |
||||
1 file changed, 20 insertions(+) |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 008f6c273b..54462e0892 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -1260,6 +1260,26 @@ if test "x$target_cpu" = xarm; then |
||||
done |
||||
]) |
||||
|
||||
+ AC_CACHE_CHECK([for options to disable movt and movw relocations], |
||||
+ grub_cv_target_cc_mword_relocations, |
||||
+ [grub_cv_target_cc_mword_relocations=no |
||||
+ for cand in "-mword-relocations" ; do |
||||
+ if test x"$grub_cv_target_cc_mword_relocations" != xno ; then |
||||
+ break |
||||
+ fi |
||||
+ CFLAGS="$TARGET_CFLAGS $cand -Werror" |
||||
+ CPPFLAGS="$TARGET_CPPFLAGS" |
||||
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], |
||||
+ [grub_cv_target_cc_mword_relocations="$cand"], |
||||
+ []) |
||||
+ done |
||||
+ ]) |
||||
+ if test x"$grub_cv_target_cc_mword_relocations" = xno ; then |
||||
+ AC_MSG_ERROR(["your compiler doesn't support disabling movw/movt relocations"]) |
||||
+ else |
||||
+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mword_relocations" |
||||
+ fi |
||||
+ |
||||
if test x"$grub_cv_target_cc_mno_movt" != xno ; then |
||||
# A trick so that clang doesn't see it on link stage |
||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt" |
@ -0,0 +1,152 @@
@@ -0,0 +1,152 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Stephen Benjamin <stephen@redhat.com> |
||||
Date: Thu, 16 Aug 2018 16:58:51 -0400 |
||||
Subject: [PATCH] Prepend prefix when HTTP path is relative |
||||
|
||||
This sets a couple of variables. With the url http://www.example.com/foo/bar : |
||||
http_path: /foo/bar |
||||
http_url: http://www.example.com/foo/bar |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
Signed-off-by: Stephen Benjamin <stephen@redhat.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/kern/main.c | 10 +++++- |
||||
grub-core/net/efi/http.c | 82 ++++++++++++++++++++++++++++++++++++------------ |
||||
2 files changed, 71 insertions(+), 21 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c |
||||
index d1de9fa687..1c540fc8c2 100644 |
||||
--- a/grub-core/kern/main.c |
||||
+++ b/grub-core/kern/main.c |
||||
@@ -131,11 +131,19 @@ grub_set_prefix_and_root (void) |
||||
if (fwdevice && fwpath) |
||||
{ |
||||
char *fw_path; |
||||
+ char separator[3] = ")"; |
||||
|
||||
- fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); |
||||
+ grub_dprintf ("fw_path", "\n"); |
||||
+ grub_dprintf ("fw_path", "fwdevice:\"%s\" fwpath:\"%s\"\n", fwdevice, fwpath); |
||||
+ |
||||
+ if (!grub_strncmp(fwdevice, "http", 4) && fwpath[0] != '/') |
||||
+ grub_strcpy(separator, ")/"); |
||||
+ |
||||
+ fw_path = grub_xasprintf ("(%s%s%s", fwdevice, separator, fwpath); |
||||
if (fw_path) |
||||
{ |
||||
grub_env_set ("fw_path", fw_path); |
||||
+ grub_dprintf ("fw_path", "fw_path:\"%s\"\n", fw_path); |
||||
grub_free (fw_path); |
||||
} |
||||
} |
||||
diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c |
||||
index 243acbaa35..de351b2cd0 100644 |
||||
--- a/grub-core/net/efi/http.c |
||||
+++ b/grub-core/net/efi/http.c |
||||
@@ -9,10 +9,52 @@ |
||||
static void |
||||
http_configure (struct grub_efi_net_device *dev, int prefer_ip6) |
||||
{ |
||||
+ grub_efi_ipv6_address_t address; |
||||
grub_efi_http_config_data_t http_config; |
||||
grub_efi_httpv4_access_point_t httpv4_node; |
||||
grub_efi_httpv6_access_point_t httpv6_node; |
||||
grub_efi_status_t status; |
||||
+ int https; |
||||
+ char *http_url; |
||||
+ const char *rest, *http_server, *http_path = NULL; |
||||
+ |
||||
+ http_server = grub_env_get ("root"); |
||||
+ https = (grub_strncmp (http_server, "https", 5) == 0) ? 1 : 0; |
||||
+ |
||||
+ /* extract http server + port */ |
||||
+ if (http_server) |
||||
+ { |
||||
+ http_server = grub_strchr (http_server, ','); |
||||
+ if (http_server) |
||||
+ http_server++; |
||||
+ } |
||||
+ |
||||
+ /* fw_path is like (http,192.168.1.1:8000)/httpboot, extract path part */ |
||||
+ http_path = grub_env_get ("fw_path"); |
||||
+ if (http_path) |
||||
+ { |
||||
+ http_path = grub_strchr (http_path, ')'); |
||||
+ if (http_path) |
||||
+ { |
||||
+ http_path++; |
||||
+ grub_env_unset ("http_path"); |
||||
+ grub_env_set ("http_path", http_path); |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (http_server && http_path) |
||||
+ { |
||||
+ if (grub_efi_string_to_ip6_address (http_server, &address, &rest) && *rest == 0) |
||||
+ http_url = grub_xasprintf ("%s://[%s]%s", https ? "https" : "http", http_server, http_path); |
||||
+ else |
||||
+ http_url = grub_xasprintf ("%s://%s%s", https ? "https" : "http", http_server, http_path); |
||||
+ if (http_url) |
||||
+ { |
||||
+ grub_env_unset ("http_url"); |
||||
+ grub_env_set ("http_url", http_url); |
||||
+ grub_free (http_url); |
||||
+ } |
||||
+ } |
||||
|
||||
grub_efi_http_t *http = dev->http; |
||||
|
||||
@@ -352,32 +394,32 @@ grub_efihttp_open (struct grub_efi_net_device *dev, |
||||
grub_err_t err; |
||||
grub_off_t size; |
||||
char *buf; |
||||
- char *root_url; |
||||
- grub_efi_ipv6_address_t address; |
||||
- const char *rest; |
||||
+ char *file_name = NULL; |
||||
+ const char *http_path; |
||||
|
||||
- if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0) |
||||
- root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server); |
||||
- else |
||||
- root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server); |
||||
- if (root_url) |
||||
- { |
||||
- grub_env_unset ("root_url"); |
||||
- grub_env_set ("root_url", root_url); |
||||
- grub_free (root_url); |
||||
- } |
||||
- else |
||||
- { |
||||
+ /* If path is relative, prepend http_path */ |
||||
+ http_path = grub_env_get ("http_path"); |
||||
+ if (http_path && file->device->net->name[0] != '/') { |
||||
+ file_name = grub_xasprintf ("%s/%s", http_path, file->device->net->name); |
||||
+ if (!file_name) |
||||
return grub_errno; |
||||
- } |
||||
+ } |
||||
|
||||
- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); |
||||
+ err = efihttp_request (dev->http, file->device->net->server, |
||||
+ file_name ? file_name : file->device->net->name, type, 1, 0); |
||||
if (err != GRUB_ERR_NONE) |
||||
- return err; |
||||
+ { |
||||
+ grub_free (file_name); |
||||
+ return err; |
||||
+ } |
||||
|
||||
- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 0, &size); |
||||
+ err = efihttp_request (dev->http, file->device->net->server, |
||||
+ file_name ? file_name : file->device->net->name, type, 0, &size); |
||||
+ grub_free (file_name); |
||||
if (err != GRUB_ERR_NONE) |
||||
- return err; |
||||
+ { |
||||
+ return err; |
||||
+ } |
||||
|
||||
buf = grub_malloc (size); |
||||
efihttp_read (dev, buf, size); |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Mon, 27 Aug 2018 13:14:06 -0400 |
||||
Subject: [PATCH] Make grub_error() more verbose |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/err.c | 13 +++++++++++-- |
||||
include/grub/err.h | 8 ++++++-- |
||||
2 files changed, 17 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c |
||||
index 53c734de70..aebfe0cf83 100644 |
||||
--- a/grub-core/kern/err.c |
||||
+++ b/grub-core/kern/err.c |
||||
@@ -33,15 +33,24 @@ static struct grub_error_saved grub_error_stack_items[GRUB_ERROR_STACK_SIZE]; |
||||
static int grub_error_stack_pos; |
||||
static int grub_error_stack_assert; |
||||
|
||||
+#ifdef grub_error |
||||
+#undef grub_error |
||||
+#endif |
||||
+ |
||||
grub_err_t |
||||
-grub_error (grub_err_t n, const char *fmt, ...) |
||||
+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
+ int m; |
||||
|
||||
grub_errno = n; |
||||
|
||||
+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line); |
||||
+ if (m < 0) |
||||
+ m = 0; |
||||
+ |
||||
va_start (ap, fmt); |
||||
- grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap); |
||||
+ grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap); |
||||
va_end (ap); |
||||
|
||||
return n; |
||||
diff --git a/include/grub/err.h b/include/grub/err.h |
||||
index b08d5d0de4..c0f90ef07c 100644 |
||||
--- a/include/grub/err.h |
||||
+++ b/include/grub/err.h |
||||
@@ -85,8 +85,12 @@ struct grub_error_saved |
||||
extern grub_err_t EXPORT_VAR(grub_errno); |
||||
extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG]; |
||||
|
||||
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...) |
||||
- __attribute__ ((format (GNU_PRINTF, 2, 3))); |
||||
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...) |
||||
+ __attribute__ ((format (GNU_PRINTF, 4, 5))); |
||||
+ |
||||
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__) |
||||
+ |
||||
+ |
||||
void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); |
||||
void EXPORT_FUNC(grub_error_push) (void); |
||||
int EXPORT_FUNC(grub_error_pop) (void); |
@ -0,0 +1,134 @@
@@ -0,0 +1,134 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 11 Sep 2018 14:20:37 -0400 |
||||
Subject: [PATCH] Add a "version" command |
||||
|
||||
This adds a command that shows you info about grub's version, the grub |
||||
target platform, the compiler version, and if you built with |
||||
--with-rpm-version=<string>, the rpm package version. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[rharwood: don't say GNU, commit message cleanup] |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
configure.ac | 13 ++++++++++ |
||||
grub-core/Makefile.core.def | 5 ++++ |
||||
grub-core/commands/version.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ |
||||
config.h.in | 1 + |
||||
4 files changed, 75 insertions(+) |
||||
create mode 100644 grub-core/commands/version.c |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 54462e0892..7b4e1854d3 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -284,6 +284,19 @@ AC_SUBST(target_cpu) |
||||
AC_SUBST(platform) |
||||
|
||||
# Define default variables |
||||
+have_with_rpm_version=n |
||||
+AC_ARG_WITH([rpm_version], |
||||
+ AS_HELP_STRING([--with-rpm-version=VERSION], |
||||
+ [set the rpm package version [[guessed]]]), |
||||
+ [have_with_rpm_version=y], |
||||
+ [have_with_rpm_version=n]) |
||||
+if test x$have_with_rpm_version = xy; then |
||||
+ rpm_version="$with_rpm_version" |
||||
+else |
||||
+ rpm_version="" |
||||
+fi |
||||
+GRUB_RPM_VERSION="$rpm_version" |
||||
+AC_SUBST(GRUB_RPM_VERSION) |
||||
|
||||
have_with_bootdir=n |
||||
AC_ARG_WITH([bootdir], |
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
||||
index 4e7d90da76..4f203533f5 100644 |
||||
--- a/grub-core/Makefile.core.def |
||||
+++ b/grub-core/Makefile.core.def |
||||
@@ -579,6 +579,11 @@ image = { |
||||
enable = mips_loongson; |
||||
}; |
||||
|
||||
+module = { |
||||
+ name = version; |
||||
+ common = commands/version.c; |
||||
+}; |
||||
+ |
||||
module = { |
||||
name = disk; |
||||
common = lib/disk.c; |
||||
diff --git a/grub-core/commands/version.c b/grub-core/commands/version.c |
||||
new file mode 100644 |
||||
index 0000000000..de0acb07ba |
||||
--- /dev/null |
||||
+++ b/grub-core/commands/version.c |
||||
@@ -0,0 +1,56 @@ |
||||
+/* version.c - Command to print the grub version and build info. */ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2006,2007,2008 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/term.h> |
||||
+#include <grub/time.h> |
||||
+#include <grub/types.h> |
||||
+#include <grub/misc.h> |
||||
+#include <grub/extcmd.h> |
||||
+#include <grub/i18n.h> |
||||
+ |
||||
+GRUB_MOD_LICENSE ("GPLv3+"); |
||||
+ |
||||
+static grub_err_t |
||||
+grub_cmd_version (grub_command_t cmd UNUSED, int argc, char **args UNUSED) |
||||
+{ |
||||
+ if (argc != 0) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("no arguments expected")); |
||||
+ |
||||
+ grub_printf (_("GRUB version %s\n"), PACKAGE_VERSION); |
||||
+ grub_printf (_("Platform %s-%s\n"), GRUB_TARGET_CPU, GRUB_PLATFORM); |
||||
+ if (grub_strlen(GRUB_RPM_VERSION) != 0) |
||||
+ grub_printf (_("RPM package version %s\n"), GRUB_RPM_VERSION); |
||||
+ grub_printf (_("Compiler version %s\n"), __VERSION__); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+static grub_command_t cmd; |
||||
+ |
||||
+GRUB_MOD_INIT(version) |
||||
+{ |
||||
+ cmd = grub_register_command ("version", grub_cmd_version, NULL, |
||||
+ N_("Print version and build information.")); |
||||
+} |
||||
+ |
||||
+GRUB_MOD_FINI(version) |
||||
+{ |
||||
+ grub_unregister_command (cmd); |
||||
+} |
||||
diff --git a/config.h.in b/config.h.in |
||||
index 9e8f9911b1..c7e316f0f1 100644 |
||||
--- a/config.h.in |
||||
+++ b/config.h.in |
||||
@@ -59,6 +59,7 @@ |
||||
|
||||
#define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" |
||||
#define GRUB_PLATFORM "@GRUB_PLATFORM@" |
||||
+#define GRUB_RPM_VERSION "@GRUB_RPM_VERSION@" |
||||
|
||||
#define RE_ENABLE_I18N 1 |
||||
|
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Tue, 11 Sep 2018 15:58:29 -0400 |
||||
Subject: [PATCH] Add more dprintf, and nerf dprintf in script.c |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/disk/diskfilter.c | 3 +++ |
||||
grub-core/disk/efi/efidisk.c | 1 + |
||||
grub-core/kern/device.c | 1 + |
||||
grub-core/script/script.c | 5 +++++ |
||||
4 files changed, 10 insertions(+) |
||||
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c |
||||
index 0320115662..7cdffe3ebd 100644 |
||||
--- a/grub-core/disk/diskfilter.c |
||||
+++ b/grub-core/disk/diskfilter.c |
||||
@@ -188,6 +188,8 @@ scan_disk (const char *name, int accept_diskfilter) |
||||
grub_disk_t disk; |
||||
static int scan_depth = 0; |
||||
|
||||
+ grub_dprintf ("diskfilter", "scanning %s\n", name); |
||||
+ |
||||
if (!accept_diskfilter && is_valid_diskfilter_name (name)) |
||||
return 0; |
||||
|
||||
@@ -1212,6 +1214,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, |
||||
the same. */ |
||||
if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size) |
||||
return GRUB_ERR_NONE; |
||||
+ grub_dprintf ("diskfilter", "checking %s\n", disk->name); |
||||
pv->disk = grub_disk_open (disk->name); |
||||
if (!pv->disk) |
||||
return grub_errno; |
||||
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c |
||||
index f077b5f553..fe8ba6e6c9 100644 |
||||
--- a/grub-core/disk/efi/efidisk.c |
||||
+++ b/grub-core/disk/efi/efidisk.c |
||||
@@ -855,6 +855,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) |
||||
return 0; |
||||
} |
||||
|
||||
+ grub_dprintf ("efidisk", "getting disk for %s\n", device_name); |
||||
parent = grub_disk_open (device_name); |
||||
grub_free (dup_dp); |
||||
|
||||
diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c |
||||
index 73b8ecc0c0..f58b58c89d 100644 |
||||
--- a/grub-core/kern/device.c |
||||
+++ b/grub-core/kern/device.c |
||||
@@ -34,6 +34,7 @@ grub_device_open (const char *name) |
||||
{ |
||||
grub_device_t dev = 0; |
||||
|
||||
+ grub_dprintf ("device", "opening device %s\n", name); |
||||
if (! name) |
||||
{ |
||||
name = grub_env_get ("root"); |
||||
diff --git a/grub-core/script/script.c b/grub-core/script/script.c |
||||
index ec4d4337c6..844e8343ca 100644 |
||||
--- a/grub-core/script/script.c |
||||
+++ b/grub-core/script/script.c |
||||
@@ -22,6 +22,11 @@ |
||||
#include <grub/parser.h> |
||||
#include <grub/mm.h> |
||||
|
||||
+#ifdef grub_dprintf |
||||
+#undef grub_dprintf |
||||
+#endif |
||||
+#define grub_dprintf(no, fmt, ...) |
||||
+ |
||||
/* It is not possible to deallocate the memory when a syntax error was |
||||
found. Because of that it is required to keep track of all memory |
||||
allocations. The memory is freed in case of an error, or assigned |
@ -0,0 +1,279 @@
@@ -0,0 +1,279 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 11 Jul 2019 14:38:57 +0200 |
||||
Subject: [PATCH] arm/arm64 loader: Better memory allocation and error |
||||
messages. |
||||
|
||||
On mustang, our memory map looks like: |
||||
|
||||
Type Physical start - end #Pages Size Attributes |
||||
reserved 0000004000000000-00000040001fffff 00000200 2MiB UC WC WT WB |
||||
conv-mem 0000004000200000-0000004393ffffff 00393e00 14654MiB UC WC WT WB |
||||
ldr-code 0000004394000000-00000043f7ffffff 00064000 1600MiB UC WC WT WB |
||||
BS-data 00000043f8000000-00000043f801ffff 00000020 128KiB UC WC WT WB |
||||
conv-mem 00000043f8020000-00000043fa15bfff 0000213c 34032KiB UC WC WT WB |
||||
ldr-code 00000043fa15c000-00000043fa2a1fff 00000146 1304KiB UC WC WT WB |
||||
ldr-data 00000043fa2a2000-00000043fa3e8fff 00000147 1308KiB UC WC WT WB |
||||
conv-mem 00000043fa3e9000-00000043fa3e9fff 00000001 4KiB UC WC WT WB |
||||
ldr-data 00000043fa3ea000-00000043fa3eafff 00000001 4KiB UC WC WT WB |
||||
ldr-code 00000043fa3eb000-00000043fa4affff 000000c5 788KiB UC WC WT WB |
||||
BS-code 00000043fa4b0000-00000043fa59ffff 000000f0 960KiB UC WC WT WB |
||||
RT-code 00000043fa5a0000-00000043fa5affff 00000010 64KiB RT UC WC WT WB |
||||
RT-data 00000043fa5b0000-00000043fa5bffff 00000010 64KiB RT UC WC WT WB |
||||
RT-code 00000043fa5c0000-00000043fa5cffff 00000010 64KiB RT UC WC WT WB |
||||
ldr-data 00000043fa5d0000-00000043fa5d0fff 00000001 4KiB UC WC WT WB |
||||
BS-code 00000043fa5d1000-00000043fa5ddfff 0000000d 52KiB UC WC WT WB |
||||
reserved 00000043fa5de000-00000043fa60ffff 00000032 200KiB UC WC WT WB |
||||
ACPI-rec 00000043fa610000-00000043fa6affff 000000a0 640KiB UC WC WT WB |
||||
ACPI-nvs 00000043fa6b0000-00000043fa6bffff 00000010 64KiB UC WC WT WB |
||||
ACPI-rec 00000043fa6c0000-00000043fa70ffff 00000050 320KiB UC WC WT WB |
||||
RT-code 00000043fa710000-00000043fa72ffff 00000020 128KiB RT UC WC WT WB |
||||
RT-data 00000043fa730000-00000043fa78ffff 00000060 384KiB RT UC WC WT WB |
||||
RT-code 00000043fa790000-00000043fa79ffff 00000010 64KiB RT UC WC WT WB |
||||
RT-data 00000043fa7a0000-00000043fa99ffff 00000200 2MiB RT UC WC WT WB |
||||
RT-code 00000043fa9a0000-00000043fa9affff 00000010 64KiB RT UC WC WT WB |
||||
RT-data 00000043fa9b0000-00000043fa9cffff 00000020 128KiB RT UC WC WT WB |
||||
BS-code 00000043fa9d0000-00000043fa9d9fff 0000000a 40KiB UC WC WT WB |
||||
reserved 00000043fa9da000-00000043fa9dbfff 00000002 8KiB UC WC WT WB |
||||
conv-mem 00000043fa9dc000-00000043fc29dfff 000018c2 25352KiB UC WC WT WB |
||||
BS-data 00000043fc29e000-00000043fc78afff 000004ed 5044KiB UC WC WT WB |
||||
conv-mem 00000043fc78b000-00000043fca01fff 00000277 2524KiB UC WC WT WB |
||||
BS-data 00000043fca02000-00000043fcea3fff 000004a2 4744KiB UC WC WT WB |
||||
conv-mem 00000043fcea4000-00000043fcea4fff 00000001 4KiB UC WC WT WB |
||||
BS-data 00000043fcea5000-00000043fd192fff 000002ee 3000KiB UC WC WT WB |
||||
conv-mem 00000043fd193000-00000043fd2b0fff 0000011e 1144KiB UC WC WT WB |
||||
BS-data 00000043fd2b1000-00000043ff80ffff 0000255f 38268KiB UC WC WT WB |
||||
BS-code 00000043ff810000-00000043ff99ffff 00000190 1600KiB UC WC WT WB |
||||
RT-code 00000043ff9a0000-00000043ff9affff 00000010 64KiB RT UC WC WT WB |
||||
conv-mem 00000043ff9b0000-00000043ff9bffff 00000010 64KiB UC WC WT WB |
||||
RT-data 00000043ff9c0000-00000043ff9effff 00000030 192KiB RT UC WC WT WB |
||||
conv-mem 00000043ff9f0000-00000043ffa05fff 00000016 88KiB UC WC WT WB |
||||
BS-data 00000043ffa06000-00000043ffffffff 000005fa 6120KiB UC WC WT WB |
||||
MMIO 0000000010510000-0000000010510fff 00000001 4KiB RT |
||||
MMIO 0000000010548000-0000000010549fff 00000002 8KiB RT |
||||
MMIO 0000000017000000-0000000017001fff 00000002 8KiB RT |
||||
MMIO 000000001c025000-000000001c025fff 00000001 4KiB RT |
||||
|
||||
This patch adds a requirement when we're trying to find the base of ram, that |
||||
the memory we choose is actually /allocatable/ conventional memory, not merely |
||||
write-combining. On this machine that means we wind up with an allocation |
||||
around 0x4392XXXXXX, which is a reasonable address. |
||||
|
||||
This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it |
||||
tries to allocate again starting with the same max address it did the first |
||||
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any |
||||
per-platform constraints on its given address are maintained. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/efi/mm.c | 33 +++++++++++++++----- |
||||
grub-core/loader/arm64/linux.c | 68 +++++++++++++++++++++++++++++++----------- |
||||
2 files changed, 76 insertions(+), 25 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c |
||||
index f6aef0ef64..85ad4b4494 100644 |
||||
--- a/grub-core/kern/efi/mm.c |
||||
+++ b/grub-core/kern/efi/mm.c |
||||
@@ -154,6 +154,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, |
||||
{ |
||||
grub_efi_status_t status; |
||||
grub_efi_boot_services_t *b; |
||||
+ grub_efi_physical_address_t ret = address; |
||||
|
||||
/* Limit the memory access to less than 4GB for 32-bit platforms. */ |
||||
if (address > GRUB_EFI_MAX_USABLE_ADDRESS) |
||||
@@ -170,19 +171,22 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, |
||||
} |
||||
|
||||
b = grub_efi_system_table->boot_services; |
||||
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); |
||||
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); |
||||
if (status != GRUB_EFI_SUCCESS) |
||||
{ |
||||
+ grub_dprintf ("efi", |
||||
+ "allocate_pages(%d, %d, 0x%0lx, 0x%016lx) = 0x%016lx\n", |
||||
+ alloctype, memtype, pages, address, status); |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); |
||||
return NULL; |
||||
} |
||||
|
||||
- if (address == 0) |
||||
+ if (ret == 0) |
||||
{ |
||||
/* Uggh, the address 0 was allocated... This is too annoying, |
||||
so reallocate another one. */ |
||||
- address = GRUB_EFI_MAX_USABLE_ADDRESS; |
||||
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); |
||||
+ ret = address; |
||||
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); |
||||
grub_efi_free_pages (0, pages); |
||||
if (status != GRUB_EFI_SUCCESS) |
||||
{ |
||||
@@ -191,9 +195,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, |
||||
} |
||||
} |
||||
|
||||
- grub_efi_store_alloc (address, pages); |
||||
+ grub_efi_store_alloc (ret, pages); |
||||
|
||||
- return (void *) ((grub_addr_t) address); |
||||
+ return (void *) ((grub_addr_t) ret); |
||||
} |
||||
|
||||
void * |
||||
@@ -713,8 +717,21 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) |
||||
for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; |
||||
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); |
||||
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) |
||||
- if (desc->attribute & GRUB_EFI_MEMORY_WB) |
||||
- *base_addr = grub_min (*base_addr, desc->physical_start); |
||||
+ { |
||||
+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY && |
||||
+ (desc->attribute & GRUB_EFI_MEMORY_WB)) |
||||
+ { |
||||
+ *base_addr = grub_min (*base_addr, desc->physical_start); |
||||
+ grub_dprintf ("efi", "setting base_addr=0x%016lx\n", *base_addr); |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ grub_dprintf ("efi", "ignoring address 0x%016lx\n", desc->physical_start); |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS) |
||||
+ grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr); |
||||
|
||||
grub_free(memory_map); |
||||
|
||||
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c |
||||
index 04994d5c67..70a0075ec5 100644 |
||||
--- a/grub-core/loader/arm64/linux.c |
||||
+++ b/grub-core/loader/arm64/linux.c |
||||
@@ -71,20 +71,25 @@ finalize_params_linux (void) |
||||
{ |
||||
grub_efi_loaded_image_t *loaded_image = NULL; |
||||
int node, retval, len; |
||||
- |
||||
+ grub_err_t err = GRUB_ERR_NONE; |
||||
void *fdt; |
||||
|
||||
fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); |
||||
- |
||||
if (!fdt) |
||||
- goto failure; |
||||
+ { |
||||
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT"); |
||||
+ goto failure; |
||||
+ } |
||||
|
||||
node = grub_fdt_find_subnode (fdt, 0, "chosen"); |
||||
if (node < 0) |
||||
node = grub_fdt_add_subnode (fdt, 0, "chosen"); |
||||
|
||||
if (node < 1) |
||||
- goto failure; |
||||
+ { |
||||
+ err = grub_error(grub_errno, "failed to load chosen fdt node."); |
||||
+ goto failure; |
||||
+ } |
||||
|
||||
/* Set initrd info */ |
||||
if (initrd_start && initrd_end > initrd_start) |
||||
@@ -95,15 +100,26 @@ finalize_params_linux (void) |
||||
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", |
||||
initrd_start); |
||||
if (retval) |
||||
- goto failure; |
||||
+ { |
||||
+ err = grub_error(retval, "Failed to set linux,initrd-start property"); |
||||
+ goto failure; |
||||
+ } |
||||
+ |
||||
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", |
||||
initrd_end); |
||||
if (retval) |
||||
- goto failure; |
||||
+ { |
||||
+ err = grub_error(retval, "Failed to set linux,initrd-end property"); |
||||
+ goto failure; |
||||
+ } |
||||
} |
||||
|
||||
- if (grub_fdt_install() != GRUB_ERR_NONE) |
||||
- goto failure; |
||||
+ retval = grub_fdt_install(); |
||||
+ if (retval != GRUB_ERR_NONE) |
||||
+ { |
||||
+ err = grub_error(retval, "Failed to install fdt"); |
||||
+ goto failure; |
||||
+ } |
||||
|
||||
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n", |
||||
fdt); |
||||
@@ -111,14 +127,20 @@ finalize_params_linux (void) |
||||
/* Convert command line to UCS-2 */ |
||||
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); |
||||
if (!loaded_image) |
||||
- goto failure; |
||||
+ { |
||||
+ err = grub_error(grub_errno, "Failed to install fdt"); |
||||
+ goto failure; |
||||
+ } |
||||
|
||||
loaded_image->load_options_size = len = |
||||
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t); |
||||
loaded_image->load_options = |
||||
grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); |
||||
if (!loaded_image->load_options) |
||||
- return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters"); |
||||
+ { |
||||
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters"); |
||||
+ goto failure; |
||||
+ } |
||||
|
||||
loaded_image->load_options_size = |
||||
2 * grub_utf8_to_utf16 (loaded_image->load_options, len, |
||||
@@ -128,7 +150,7 @@ finalize_params_linux (void) |
||||
|
||||
failure: |
||||
grub_fdt_unload(); |
||||
- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); |
||||
+ return err; |
||||
} |
||||
|
||||
static void |
||||
@@ -212,16 +234,28 @@ grub_linux_unload (void) |
||||
static void * |
||||
allocate_initrd_mem (int initrd_pages) |
||||
{ |
||||
- grub_addr_t max_addr; |
||||
+ grub_addr_t max_addr = 0; |
||||
+ grub_err_t err; |
||||
+ void *ret; |
||||
|
||||
- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) |
||||
- return NULL; |
||||
+ err = grub_efi_get_ram_base (&max_addr); |
||||
+ if (err != GRUB_ERR_NONE) |
||||
+ { |
||||
+ grub_error (err, "grub_efi_get_ram_base() failed"); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 0x%016llx\n", |
||||
+ max_addr, INITRD_MAX_ADDRESS_OFFSET); |
||||
|
||||
max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; |
||||
+ grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages); |
||||
|
||||
- return grub_efi_allocate_pages_real (max_addr, initrd_pages, |
||||
- GRUB_EFI_ALLOCATE_MAX_ADDRESS, |
||||
- GRUB_EFI_LOADER_DATA); |
||||
+ ret = grub_efi_allocate_pages_real (max_addr, initrd_pages, |
||||
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS, |
||||
+ GRUB_EFI_LOADER_DATA); |
||||
+ grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret); |
||||
+ return ret; |
||||
} |
||||
|
||||
static grub_err_t |
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 11 Jul 2019 17:17:02 +0200 |
||||
Subject: [PATCH] Try to pick better locations for kernel and initrd |
||||
|
||||
- Don't limit allocations on 64-bit platforms to < 0x[37f]fffffff if |
||||
we're using the "large" code model ; use __UINTPTR_MAX__. |
||||
- Get the comparison right to check the address we've allocated. |
||||
- Fix the allocation for the command line as well. |
||||
|
||||
*But*, when we did this some systems started failing badly; coudln't |
||||
parse partition tables, etc. What's going on here is the disk controller |
||||
is silently failing DMAs to addresses above 4GB, so we're trying to parse |
||||
uninitialized (or HW zeroed) ram when looking for the partition table, |
||||
etc. |
||||
|
||||
So to limit this, we make grub_malloc() pick addresses below 4GB on |
||||
x86_64, but the direct EFI page allocation functions can get addresses |
||||
above that. |
||||
|
||||
Additionally, we now try to locate kernel+initrd+cmdline+etc below |
||||
0x7fffffff, and if they're too big to fit any memory window there, then |
||||
we try a higher address. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[david.abdurachmanov: fix macro for riscv64] |
||||
Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
grub-core/kern/efi/mm.c | 8 ++++---- |
||||
grub-core/loader/i386/efi/linux.c | 24 +++++++++++++++++------- |
||||
include/grub/arm/efi/memory.h | 1 + |
||||
include/grub/arm64/efi/memory.h | 1 + |
||||
include/grub/i386/efi/memory.h | 1 + |
||||
include/grub/ia64/efi/memory.h | 1 + |
||||
include/grub/riscv64/efi/memory.h | 1 + |
||||
include/grub/x86_64/efi/memory.h | 4 +++- |
||||
8 files changed, 29 insertions(+), 12 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c |
||||
index 85ad4b4494..e84961d078 100644 |
||||
--- a/grub-core/kern/efi/mm.c |
||||
+++ b/grub-core/kern/efi/mm.c |
||||
@@ -122,7 +122,7 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max, |
||||
grub_efi_boot_services_t *b; |
||||
grub_efi_physical_address_t address = max; |
||||
|
||||
- if (max > 0xffffffff) |
||||
+ if (max > GRUB_EFI_MAX_USABLE_ADDRESS) |
||||
return 0; |
||||
|
||||
b = grub_efi_system_table->boot_services; |
||||
@@ -480,7 +480,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, |
||||
{ |
||||
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY |
||||
#if 1 |
||||
- && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS |
||||
+ && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS |
||||
#endif |
||||
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 |
||||
&& desc->num_pages != 0) |
||||
@@ -498,9 +498,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, |
||||
#if 1 |
||||
if (BYTES_TO_PAGES (filtered_desc->physical_start) |
||||
+ filtered_desc->num_pages |
||||
- > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)) |
||||
+ > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)) |
||||
filtered_desc->num_pages |
||||
- = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS) |
||||
+ = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS) |
||||
- BYTES_TO_PAGES (filtered_desc->physical_start)); |
||||
#endif |
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
||||
index 3017d0f3e5..33e981e76e 100644 |
||||
--- a/grub-core/loader/i386/efi/linux.c |
||||
+++ b/grub-core/loader/i386/efi/linux.c |
||||
@@ -27,6 +27,7 @@ |
||||
#include <grub/lib/cmdline.h> |
||||
#include <grub/efi/efi.h> |
||||
#include <grub/efi/linux.h> |
||||
+#include <grub/cpu/efi/memory.h> |
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+"); |
||||
|
||||
@@ -106,7 +107,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
size += ALIGN_UP (grub_file_size (files[i]), 4); |
||||
} |
||||
|
||||
- initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); |
||||
+ initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size)); |
||||
+ if (!initrd_mem) |
||||
+ initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size)); |
||||
if (!initrd_mem) |
||||
{ |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); |
||||
@@ -202,8 +205,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
goto fail; |
||||
} |
||||
|
||||
- params = grub_efi_allocate_pages_max (0x3fffffff, |
||||
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
BYTES_TO_PAGES(sizeof(*params))); |
||||
+ if (!params) |
||||
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
+ BYTES_TO_PAGES(sizeof(*params))); |
||||
if (! params) |
||||
{ |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
||||
@@ -273,8 +279,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
#endif |
||||
|
||||
grub_dprintf ("linux", "setting up cmdline\n"); |
||||
- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, |
||||
- BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
+ BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
+ if (!linux_cmdline) |
||||
+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
+ BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
if (!linux_cmdline) |
||||
{ |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); |
||||
@@ -301,11 +310,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
|
||||
kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, |
||||
BYTES_TO_PAGES(lh->init_size)); |
||||
- |
||||
if (!kernel_mem) |
||||
- kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, |
||||
+ kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
+ BYTES_TO_PAGES(lh->init_size)); |
||||
+ if (!kernel_mem) |
||||
+ kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
BYTES_TO_PAGES(lh->init_size)); |
||||
- |
||||
if (!kernel_mem) |
||||
{ |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); |
||||
diff --git a/include/grub/arm/efi/memory.h b/include/grub/arm/efi/memory.h |
||||
index 2c64918e3f..a4c2ec8350 100644 |
||||
--- a/include/grub/arm/efi/memory.h |
||||
+++ b/include/grub/arm/efi/memory.h |
||||
@@ -2,5 +2,6 @@ |
||||
#include <grub/efi/memory.h> |
||||
|
||||
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS |
||||
|
||||
#endif /* ! GRUB_MEMORY_CPU_HEADER */ |
||||
diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h |
||||
index c6cb324171..acb61dca44 100644 |
||||
--- a/include/grub/arm64/efi/memory.h |
||||
+++ b/include/grub/arm64/efi/memory.h |
||||
@@ -2,5 +2,6 @@ |
||||
#include <grub/efi/memory.h> |
||||
|
||||
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS |
||||
|
||||
#endif /* ! GRUB_MEMORY_CPU_HEADER */ |
||||
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h |
||||
index 2c64918e3f..a4c2ec8350 100644 |
||||
--- a/include/grub/i386/efi/memory.h |
||||
+++ b/include/grub/i386/efi/memory.h |
||||
@@ -2,5 +2,6 @@ |
||||
#include <grub/efi/memory.h> |
||||
|
||||
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS |
||||
|
||||
#endif /* ! GRUB_MEMORY_CPU_HEADER */ |
||||
diff --git a/include/grub/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h |
||||
index 2c64918e3f..a4c2ec8350 100644 |
||||
--- a/include/grub/ia64/efi/memory.h |
||||
+++ b/include/grub/ia64/efi/memory.h |
||||
@@ -2,5 +2,6 @@ |
||||
#include <grub/efi/memory.h> |
||||
|
||||
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS |
||||
|
||||
#endif /* ! GRUB_MEMORY_CPU_HEADER */ |
||||
diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h |
||||
index c6cb324171..acb61dca44 100644 |
||||
--- a/include/grub/riscv64/efi/memory.h |
||||
+++ b/include/grub/riscv64/efi/memory.h |
||||
@@ -2,5 +2,6 @@ |
||||
#include <grub/efi/memory.h> |
||||
|
||||
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS |
||||
|
||||
#endif /* ! GRUB_MEMORY_CPU_HEADER */ |
||||
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h |
||||
index 46e9145a30..e81cfb3221 100644 |
||||
--- a/include/grub/x86_64/efi/memory.h |
||||
+++ b/include/grub/x86_64/efi/memory.h |
||||
@@ -2,9 +2,11 @@ |
||||
#include <grub/efi/memory.h> |
||||
|
||||
#if defined (__code_model_large__) |
||||
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff |
||||
+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__ |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS 0x7fffffff |
||||
#else |
||||
#define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff |
||||
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS |
||||
#endif |
||||
|
||||
#endif /* ! GRUB_MEMORY_CPU_HEADER */ |
@ -0,0 +1,199 @@
@@ -0,0 +1,199 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 11 Jul 2019 18:03:25 +0200 |
||||
Subject: [PATCH] Attempt to fix up all the places -Wsign-compare=error finds. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/kern/emu/misc.c | 2 +- |
||||
grub-core/lib/reed_solomon.c | 4 ++-- |
||||
grub-core/osdep/linux/blocklist.c | 2 +- |
||||
grub-core/osdep/linux/getroot.c | 2 +- |
||||
grub-core/osdep/linux/hostdisk.c | 2 +- |
||||
util/grub-fstest.c | 2 +- |
||||
util/grub-menulst2cfg.c | 2 +- |
||||
util/grub-mkfont.c | 13 +++++++------ |
||||
util/grub-probe.c | 2 +- |
||||
util/setup.c | 2 +- |
||||
10 files changed, 17 insertions(+), 16 deletions(-) |
||||
|
||||
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c |
||||
index 0ff13bcaf8..d278c2921f 100644 |
||||
--- a/grub-core/kern/emu/misc.c |
||||
+++ b/grub-core/kern/emu/misc.c |
||||
@@ -185,7 +185,7 @@ grub_util_get_image_size (const char *path) |
||||
sz = ftello (f); |
||||
if (sz < 0) |
||||
grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); |
||||
- if (sz != (size_t) sz) |
||||
+ if (sz > (off_t)(GRUB_SIZE_MAX >> 1)) |
||||
grub_util_error (_("file `%s' is too big"), path); |
||||
ret = (size_t) sz; |
||||
|
||||
diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c |
||||
index 467305b46a..79037c093f 100644 |
||||
--- a/grub-core/lib/reed_solomon.c |
||||
+++ b/grub-core/lib/reed_solomon.c |
||||
@@ -157,7 +157,7 @@ static void |
||||
rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) |
||||
{ |
||||
gf_single_t *rs_polynomial; |
||||
- int i, j; |
||||
+ unsigned int i, j; |
||||
gf_single_t *m; |
||||
m = xcalloc (s + rs, sizeof (gf_single_t)); |
||||
grub_memcpy (m, data, s * sizeof (gf_single_t)); |
||||
@@ -324,7 +324,7 @@ static void |
||||
encode_block (gf_single_t *ptr, grub_size_t s, |
||||
gf_single_t *rptr, grub_size_t rs) |
||||
{ |
||||
- int i, j; |
||||
+ unsigned int i, j; |
||||
for (i = 0; i < SECTOR_SIZE; i++) |
||||
{ |
||||
grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; |
||||
diff --git a/grub-core/osdep/linux/blocklist.c b/grub-core/osdep/linux/blocklist.c |
||||
index c77d6085cc..42a315031f 100644 |
||||
--- a/grub-core/osdep/linux/blocklist.c |
||||
+++ b/grub-core/osdep/linux/blocklist.c |
||||
@@ -109,7 +109,7 @@ grub_install_get_blocklist (grub_device_t root_dev, |
||||
else |
||||
{ |
||||
struct fiemap *fie2; |
||||
- int i; |
||||
+ unsigned int i; |
||||
fie2 = xmalloc (sizeof (*fie2) |
||||
+ fie1.fm_mapped_extents |
||||
* sizeof (fie1.fm_extents[1])); |
||||
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c |
||||
index 28790307e0..9f730b3518 100644 |
||||
--- a/grub-core/osdep/linux/getroot.c |
||||
+++ b/grub-core/osdep/linux/getroot.c |
||||
@@ -236,7 +236,7 @@ grub_find_root_devices_from_btrfs (const char *dir) |
||||
{ |
||||
int fd; |
||||
struct btrfs_ioctl_fs_info_args fsi; |
||||
- int i, j = 0; |
||||
+ unsigned int i, j = 0; |
||||
char **ret; |
||||
|
||||
fd = open (dir, 0); |
||||
diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c |
||||
index da62f924e3..7bc99ac1c1 100644 |
||||
--- a/grub-core/osdep/linux/hostdisk.c |
||||
+++ b/grub-core/osdep/linux/hostdisk.c |
||||
@@ -83,7 +83,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec |
||||
if (sector_size & (sector_size - 1) || !sector_size) |
||||
return -1; |
||||
for (log_sector_size = 0; |
||||
- (1 << log_sector_size) < sector_size; |
||||
+ (1U << log_sector_size) < sector_size; |
||||
log_sector_size++); |
||||
|
||||
if (log_secsize) |
||||
diff --git a/util/grub-fstest.c b/util/grub-fstest.c |
||||
index 8386564200..bfcef852d8 100644 |
||||
--- a/util/grub-fstest.c |
||||
+++ b/util/grub-fstest.c |
||||
@@ -323,7 +323,7 @@ cmd_cmp (char *src, char *dest) |
||||
read_file (src, cmp_hook, ff); |
||||
|
||||
{ |
||||
- grub_uint64_t pre; |
||||
+ long long pre; |
||||
pre = ftell (ff); |
||||
fseek (ff, 0, SEEK_END); |
||||
if (pre != ftell (ff)) |
||||
diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c |
||||
index a39f869394..358d604210 100644 |
||||
--- a/util/grub-menulst2cfg.c |
||||
+++ b/util/grub-menulst2cfg.c |
||||
@@ -34,7 +34,7 @@ main (int argc, char **argv) |
||||
char *buf = NULL; |
||||
size_t bufsize = 0; |
||||
char *suffix = xstrdup (""); |
||||
- int suffixlen = 0; |
||||
+ size_t suffixlen = 0; |
||||
const char *out_fname = 0; |
||||
|
||||
grub_util_host_init (&argc, &argv); |
||||
diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c |
||||
index 0fe45a6103..3e09240b99 100644 |
||||
--- a/util/grub-mkfont.c |
||||
+++ b/util/grub-mkfont.c |
||||
@@ -138,7 +138,8 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, |
||||
int width, height; |
||||
int cuttop, cutbottom, cutleft, cutright; |
||||
grub_uint8_t *data; |
||||
- int mask, i, j, bitmap_size; |
||||
+ int mask, i, bitmap_size; |
||||
+ unsigned int j; |
||||
FT_GlyphSlot glyph; |
||||
int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; |
||||
FT_Error err; |
||||
@@ -183,7 +184,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, |
||||
cuttop = cutbottom = cutleft = cutright = 0; |
||||
else |
||||
{ |
||||
- for (cuttop = 0; cuttop < glyph->bitmap.rows; cuttop++) |
||||
+ for (cuttop = 0; cuttop < (long)glyph->bitmap.rows; cuttop++) |
||||
{ |
||||
for (j = 0; j < glyph->bitmap.width; j++) |
||||
if (glyph->bitmap.buffer[j / 8 + cuttop * glyph->bitmap.pitch] |
||||
@@ -203,10 +204,10 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, |
||||
break; |
||||
} |
||||
cutbottom = glyph->bitmap.rows - 1 - cutbottom; |
||||
- if (cutbottom + cuttop >= glyph->bitmap.rows) |
||||
+ if (cutbottom + cuttop >= (long)glyph->bitmap.rows) |
||||
cutbottom = 0; |
||||
|
||||
- for (cutleft = 0; cutleft < glyph->bitmap.width; cutleft++) |
||||
+ for (cutleft = 0; cutleft < (long)glyph->bitmap.width; cutleft++) |
||||
{ |
||||
for (j = 0; j < glyph->bitmap.rows; j++) |
||||
if (glyph->bitmap.buffer[cutleft / 8 + j * glyph->bitmap.pitch] |
||||
@@ -225,7 +226,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, |
||||
break; |
||||
} |
||||
cutright = glyph->bitmap.width - 1 - cutright; |
||||
- if (cutright + cutleft >= glyph->bitmap.width) |
||||
+ if (cutright + cutleft >= (long)glyph->bitmap.width) |
||||
cutright = 0; |
||||
} |
||||
|
||||
@@ -262,7 +263,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, |
||||
|
||||
mask = 0; |
||||
data = &glyph_info->bitmap[0] - 1; |
||||
- for (j = cuttop; j < height + cuttop; j++) |
||||
+ for (j = cuttop; j < (long)height + cuttop; j++) |
||||
for (i = cutleft; i < width + cutleft; i++) |
||||
add_pixel (&data, &mask, |
||||
glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] & |
||||
diff --git a/util/grub-probe.c b/util/grub-probe.c |
||||
index c08e46bbb4..c6fac732b4 100644 |
||||
--- a/util/grub-probe.c |
||||
+++ b/util/grub-probe.c |
||||
@@ -798,7 +798,7 @@ argp_parser (int key, char *arg, struct argp_state *state) |
||||
|
||||
case 't': |
||||
{ |
||||
- int i; |
||||
+ unsigned int i; |
||||
|
||||
for (i = PRINT_FS; i < ARRAY_SIZE (targets); i++) |
||||
if (strcmp (arg, targets[i]) == 0) |
||||
diff --git a/util/setup.c b/util/setup.c |
||||
index da5f2c07f5..8b22bb8cca 100644 |
||||
--- a/util/setup.c |
||||
+++ b/util/setup.c |
||||
@@ -406,7 +406,7 @@ SETUP (const char *dir, |
||||
int is_ldm; |
||||
grub_err_t err; |
||||
grub_disk_addr_t *sectors; |
||||
- int i; |
||||
+ unsigned int i; |
||||
grub_fs_t fs; |
||||
unsigned int nsec, maxsec; |
||||
|
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 11 Jul 2019 18:20:37 +0200 |
||||
Subject: [PATCH] Don't use -Wno-sign-compare -Wno-conversion -Wno-error, do |
||||
use -Wextra. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
configure.ac | 14 +++++++++++--- |
||||
conf/Makefile.common | 2 +- |
||||
2 files changed, 12 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 7b4e1854d3..490353713a 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -1452,11 +1452,11 @@ fi |
||||
# Set them to their new values for the tests below. |
||||
CC="$TARGET_CC" |
||||
if test x"$platform" = xemu ; then |
||||
-CFLAGS="$TARGET_CFLAGS -Wno-error" |
||||
+CFLAGS="$TARGET_CFLAGS" |
||||
elif test "x$TARGET_APPLE_LINKER" = x1 ; then |
||||
-CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" |
||||
+CFLAGS="$TARGET_CFLAGS -nostdlib -static" |
||||
else |
||||
-CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" |
||||
+CFLAGS="$TARGET_CFLAGS -nostdlib" |
||||
fi |
||||
CPPFLAGS="$TARGET_CPPFLAGS" |
||||
|
||||
@@ -1990,6 +1990,14 @@ if test x"$enable_werror" != xno ; then |
||||
HOST_CFLAGS="$HOST_CFLAGS -Werror" |
||||
fi |
||||
|
||||
+AC_ARG_ENABLE([wextra], |
||||
+ [AS_HELP_STRING([--disable-wextra], |
||||
+ [do not use -Wextra when building GRUB])]) |
||||
+if test x"$enable_wextra" != xno ; then |
||||
+ TARGET_CFLAGS="$TARGET_CFLAGS -Wextra" |
||||
+ HOST_CFLAGS="$HOST_CFLAGS -Wextra" |
||||
+fi |
||||
+ |
||||
TARGET_CPP="$TARGET_CC -E" |
||||
TARGET_CCAS=$TARGET_CC |
||||
|
||||
diff --git a/conf/Makefile.common b/conf/Makefile.common |
||||
index 2ff9b39357..35e14ff017 100644 |
||||
--- a/conf/Makefile.common |
||||
+++ b/conf/Makefile.common |
||||
@@ -66,7 +66,7 @@ grubconfdir = $(sysconfdir)/grub.d |
||||
platformdir = $(pkglibdir)/$(target_cpu)-$(platform) |
||||
starfielddir = $(pkgdatadir)/themes/starfield |
||||
|
||||
-CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion |
||||
+CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code |
||||
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib |
||||
|
||||
CFLAGS_POSIX = -fno-builtin |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Fri, 12 Jul 2019 09:53:32 +0200 |
||||
Subject: [PATCH] x86-efi: Use bounce buffers for reading to addresses > 4GB |
||||
|
||||
Lots of machines apparently can't DMA correctly above 4GB during UEFI, |
||||
so use bounce buffers for the initramfs read. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/loader/i386/efi/linux.c | 52 +++++++++++++++++++++++++++++++++------ |
||||
1 file changed, 45 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
||||
index 33e981e76e..2f0336809e 100644 |
||||
--- a/grub-core/loader/i386/efi/linux.c |
||||
+++ b/grub-core/loader/i386/efi/linux.c |
||||
@@ -35,11 +35,16 @@ static grub_dl_t my_mod; |
||||
static int loaded; |
||||
static void *kernel_mem; |
||||
static grub_uint64_t kernel_size; |
||||
-static grub_uint8_t *initrd_mem; |
||||
+static void *initrd_mem; |
||||
static grub_uint32_t handover_offset; |
||||
struct linux_kernel_params *params; |
||||
static char *linux_cmdline; |
||||
|
||||
+#define MIN(a, b) \ |
||||
+ ({ typeof (a) _a = (a); \ |
||||
+ typeof (b) _b = (b); \ |
||||
+ _a < _b ? _a : _b; }) |
||||
+ |
||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) |
||||
|
||||
static grub_err_t |
||||
@@ -73,6 +78,44 @@ grub_linuxefi_unload (void) |
||||
return GRUB_ERR_NONE; |
||||
} |
||||
|
||||
+#define BOUNCE_BUFFER_MAX 0x10000000ull |
||||
+ |
||||
+static grub_ssize_t |
||||
+read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) |
||||
+{ |
||||
+ grub_ssize_t bufpos = 0; |
||||
+ static grub_size_t bbufsz = 0; |
||||
+ static char *bbuf = NULL; |
||||
+ |
||||
+ if (bbufsz == 0) |
||||
+ bbufsz = MIN(BOUNCE_BUFFER_MAX, len); |
||||
+ |
||||
+ while (!bbuf && bbufsz) |
||||
+ { |
||||
+ bbuf = grub_malloc(bbufsz); |
||||
+ if (!bbuf) |
||||
+ bbufsz >>= 1; |
||||
+ } |
||||
+ if (!bbuf) |
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer")); |
||||
+ |
||||
+ while (bufpos < (long long)len) |
||||
+ { |
||||
+ grub_ssize_t sz; |
||||
+ |
||||
+ sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos)); |
||||
+ if (sz < 0) |
||||
+ return sz; |
||||
+ if (sz == 0) |
||||
+ break; |
||||
+ |
||||
+ grub_memcpy(bufp + bufpos, bbuf, sz); |
||||
+ bufpos += sz; |
||||
+ } |
||||
+ |
||||
+ return bufpos; |
||||
+} |
||||
+ |
||||
static grub_err_t |
||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
int argc, char *argv[]) |
||||
@@ -126,7 +169,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
for (i = 0; i < nfiles; i++) |
||||
{ |
||||
grub_ssize_t cursize = grub_file_size (files[i]); |
||||
- if (grub_file_read (files[i], ptr, cursize) != cursize) |
||||
+ if (read (files[i], ptr, cursize) != cursize) |
||||
{ |
||||
if (!grub_errno) |
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), |
||||
@@ -152,11 +195,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
return grub_errno; |
||||
} |
||||
|
||||
-#define MIN(a, b) \ |
||||
- ({ typeof (a) _a = (a); \ |
||||
- typeof (b) _b = (b); \ |
||||
- _a < _b ? _a : _b; }) |
||||
- |
||||
static grub_err_t |
||||
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
int argc, char *argv[]) |
@ -0,0 +1,133 @@
@@ -0,0 +1,133 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 13 Sep 2018 14:42:34 -0400 |
||||
Subject: [PATCH] x86-efi: Re-arrange grub_cmd_linux() a little bit. |
||||
|
||||
This just helps the next patch be easier to read. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/loader/i386/efi/linux.c | 75 +++++++++++++++++++++------------------ |
||||
1 file changed, 41 insertions(+), 34 deletions(-) |
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
||||
index 2f0336809e..5f48fa5561 100644 |
||||
--- a/grub-core/loader/i386/efi/linux.c |
||||
+++ b/grub-core/loader/i386/efi/linux.c |
||||
@@ -243,32 +243,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
goto fail; |
||||
} |
||||
|
||||
- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
- BYTES_TO_PAGES(sizeof(*params))); |
||||
- if (!params) |
||||
- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
- BYTES_TO_PAGES(sizeof(*params))); |
||||
- if (! params) |
||||
- { |
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
||||
- goto fail; |
||||
- } |
||||
+ lh = (struct linux_i386_kernel_header *)kernel; |
||||
+ grub_dprintf ("linux", "original lh is at %p\n", kernel); |
||||
|
||||
- grub_dprintf ("linux", "params = %p\n", params); |
||||
- |
||||
- grub_memset (params, 0, sizeof(*params)); |
||||
- |
||||
- setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); |
||||
- grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", |
||||
- MIN((grub_size_t)0x202+setup_header_end_offset, |
||||
- sizeof (*params)) - 0x1f1, |
||||
- (grub_uint8_t *)kernel + 0x1f1, |
||||
- (grub_uint8_t *)params + 0x1f1); |
||||
- grub_memcpy ((grub_uint8_t *)params + 0x1f1, |
||||
- (grub_uint8_t *)kernel + 0x1f1, |
||||
- MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1); |
||||
- lh = (struct linux_i386_kernel_header *)params; |
||||
- grub_dprintf ("linux", "lh is at %p\n", lh); |
||||
grub_dprintf ("linux", "checking lh->boot_flag\n"); |
||||
if (lh->boot_flag != grub_cpu_to_le16 (0xaa55)) |
||||
{ |
||||
@@ -316,6 +293,34 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
} |
||||
#endif |
||||
|
||||
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
+ BYTES_TO_PAGES(sizeof(*params))); |
||||
+ if (!params) |
||||
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
+ BYTES_TO_PAGES(sizeof(*params))); |
||||
+ if (! params) |
||||
+ { |
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
||||
+ goto fail; |
||||
+ } |
||||
+ |
||||
+ grub_dprintf ("linux", "params = %p\n", params); |
||||
+ |
||||
+ grub_memset (params, 0, sizeof(*params)); |
||||
+ |
||||
+ setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); |
||||
+ grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", |
||||
+ MIN((grub_size_t)0x202+setup_header_end_offset, |
||||
+ sizeof (*params)) - 0x1f1, |
||||
+ (grub_uint8_t *)kernel + 0x1f1, |
||||
+ (grub_uint8_t *)params + 0x1f1); |
||||
+ grub_memcpy ((grub_uint8_t *)params + 0x1f1, |
||||
+ (grub_uint8_t *)kernel + 0x1f1, |
||||
+ MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1); |
||||
+ |
||||
+ lh = (struct linux_i386_kernel_header *)params; |
||||
+ grub_dprintf ("linux", "new lh is at %p\n", lh); |
||||
+ |
||||
grub_dprintf ("linux", "setting up cmdline\n"); |
||||
linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
@@ -341,8 +346,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); |
||||
lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; |
||||
|
||||
- grub_dprintf ("linux", "computing handover offset\n"); |
||||
handover_offset = lh->handover_offset; |
||||
+ grub_dprintf("linux", "handover_offset: %08x\n", handover_offset); |
||||
|
||||
start = (lh->setup_sects + 1) * 512; |
||||
|
||||
@@ -359,26 +364,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); |
||||
goto fail; |
||||
} |
||||
- |
||||
- grub_dprintf ("linux", "kernel_mem = %lx\n", (unsigned long) kernel_mem); |
||||
+ grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); |
||||
|
||||
grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); |
||||
- loaded=1; |
||||
+ |
||||
+ loaded = 1; |
||||
+ |
||||
grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem); |
||||
lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; |
||||
|
||||
grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); |
||||
|
||||
- grub_dprintf ("linux", "setting lh->type_of_loader\n"); |
||||
lh->type_of_loader = 0x6; |
||||
+ grub_dprintf ("linux", "setting lh->type_of_loader = 0x%02x\n", |
||||
+ lh->type_of_loader); |
||||
|
||||
- grub_dprintf ("linux", "setting lh->ext_loader_{type,ver}\n"); |
||||
params->ext_loader_type = 0; |
||||
params->ext_loader_ver = 2; |
||||
- grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", |
||||
- kernel_mem, handover_offset); |
||||
+ grub_dprintf ("linux", |
||||
+ "setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n", |
||||
+ params->ext_loader_type, params->ext_loader_ver); |
||||
|
||||
- fail: |
||||
+fail: |
||||
if (file) |
||||
grub_file_close (file); |
||||
|
@ -0,0 +1,258 @@
@@ -0,0 +1,258 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Wed, 12 Sep 2018 16:03:55 -0400 |
||||
Subject: [PATCH] x86-efi: Make our own allocator for kernel stuff |
||||
|
||||
This helps enable allocations above 4GB. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/loader/i386/efi/linux.c | 167 +++++++++++++++++++++----------------- |
||||
1 file changed, 94 insertions(+), 73 deletions(-) |
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
||||
index 5f48fa5561..3e4f7ef39f 100644 |
||||
--- a/grub-core/loader/i386/efi/linux.c |
||||
+++ b/grub-core/loader/i386/efi/linux.c |
||||
@@ -47,6 +47,65 @@ static char *linux_cmdline; |
||||
|
||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) |
||||
|
||||
+struct allocation_choice { |
||||
+ grub_efi_physical_address_t addr; |
||||
+ grub_efi_allocate_type_t alloc_type; |
||||
+}; |
||||
+ |
||||
+static struct allocation_choice max_addresses[] = |
||||
+ { |
||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, |
||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, |
||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, |
||||
+ { 0, 0 } |
||||
+ }; |
||||
+ |
||||
+static inline void |
||||
+kernel_free(void *addr, grub_efi_uintn_t size) |
||||
+{ |
||||
+ if (addr && size) |
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)addr, |
||||
+ BYTES_TO_PAGES(size)); |
||||
+} |
||||
+ |
||||
+static void * |
||||
+kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) |
||||
+{ |
||||
+ void *addr = 0; |
||||
+ unsigned int i; |
||||
+ grub_efi_physical_address_t prev_max = 0; |
||||
+ |
||||
+ for (i = 0; max_addresses[i].addr != 0 && addr == 0; i++) |
||||
+ { |
||||
+ grub_uint64_t max = max_addresses[i].addr; |
||||
+ grub_efi_uintn_t pages; |
||||
+ |
||||
+ if (max == prev_max) |
||||
+ continue; |
||||
+ |
||||
+ pages = BYTES_TO_PAGES(size); |
||||
+ grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n", |
||||
+ pages, (void *)max); |
||||
+ |
||||
+ prev_max = max; |
||||
+ addr = grub_efi_allocate_pages_real (max, pages, |
||||
+ max_addresses[i].alloc_type, |
||||
+ GRUB_EFI_LOADER_DATA); |
||||
+ if (addr) |
||||
+ grub_dprintf ("linux", "Allocated at %p\n", addr); |
||||
+ } |
||||
+ |
||||
+ while (grub_error_pop ()) |
||||
+ { |
||||
+ ; |
||||
+ } |
||||
+ |
||||
+ if (addr == NULL) |
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "%s", errmsg); |
||||
+ |
||||
+ return addr; |
||||
+} |
||||
+ |
||||
static grub_err_t |
||||
grub_linuxefi_boot (void) |
||||
{ |
||||
@@ -62,19 +121,12 @@ grub_linuxefi_unload (void) |
||||
{ |
||||
grub_dl_unref (my_mod); |
||||
loaded = 0; |
||||
- if (initrd_mem) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, |
||||
- BYTES_TO_PAGES(params->ramdisk_size)); |
||||
- if (linux_cmdline) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) |
||||
- linux_cmdline, |
||||
- BYTES_TO_PAGES(params->cmdline_size + 1)); |
||||
- if (kernel_mem) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, |
||||
- BYTES_TO_PAGES(kernel_size)); |
||||
- if (params) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, |
||||
- BYTES_TO_PAGES(16384)); |
||||
+ |
||||
+ kernel_free(initrd_mem, params->ramdisk_size); |
||||
+ kernel_free(linux_cmdline, params->cmdline_size + 1); |
||||
+ kernel_free(kernel_mem, kernel_size); |
||||
+ kernel_free(params, sizeof(*params)); |
||||
+ |
||||
return GRUB_ERR_NONE; |
||||
} |
||||
|
||||
@@ -150,19 +202,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
size += ALIGN_UP (grub_file_size (files[i]), 4); |
||||
} |
||||
|
||||
- initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size)); |
||||
- if (!initrd_mem) |
||||
- initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size)); |
||||
- if (!initrd_mem) |
||||
- { |
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); |
||||
- goto fail; |
||||
- } |
||||
- |
||||
- grub_dprintf ("linux", "initrd_mem = %lx\n", (unsigned long) initrd_mem); |
||||
+ initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); |
||||
+ if (initrd_mem == NULL) |
||||
+ goto fail; |
||||
+ grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); |
||||
|
||||
params->ramdisk_size = size; |
||||
- params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; |
||||
+ params->ramdisk_image = initrd_mem; |
||||
|
||||
ptr = initrd_mem; |
||||
|
||||
@@ -221,7 +267,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
filelen = grub_file_size (file); |
||||
|
||||
kernel = grub_malloc(filelen); |
||||
- |
||||
if (!kernel) |
||||
{ |
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); |
||||
@@ -274,7 +319,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
goto fail; |
||||
} |
||||
|
||||
-#if defined(__x86_64__) || defined(__aarch64__) |
||||
+#if defined(__x86_64__) |
||||
grub_dprintf ("linux", "checking lh->xloadflags\n"); |
||||
if (!(lh->xloadflags & LINUX_XLF_KERNEL_64)) |
||||
{ |
||||
@@ -293,17 +338,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
} |
||||
#endif |
||||
|
||||
- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
- BYTES_TO_PAGES(sizeof(*params))); |
||||
+ params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); |
||||
if (!params) |
||||
- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
- BYTES_TO_PAGES(sizeof(*params))); |
||||
- if (! params) |
||||
- { |
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
||||
- goto fail; |
||||
- } |
||||
- |
||||
+ goto fail; |
||||
grub_dprintf ("linux", "params = %p\n", params); |
||||
|
||||
grub_memset (params, 0, sizeof(*params)); |
||||
@@ -322,19 +359,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
grub_dprintf ("linux", "new lh is at %p\n", lh); |
||||
|
||||
grub_dprintf ("linux", "setting up cmdline\n"); |
||||
- linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
- BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
+ linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); |
||||
if (!linux_cmdline) |
||||
- linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
- BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
- if (!linux_cmdline) |
||||
- { |
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); |
||||
- goto fail; |
||||
- } |
||||
- |
||||
- grub_dprintf ("linux", "linux_cmdline = %lx\n", |
||||
- (unsigned long)linux_cmdline); |
||||
+ goto fail; |
||||
+ grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline); |
||||
|
||||
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
||||
grub_create_loader_cmdline (argc, argv, |
||||
@@ -343,27 +371,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
GRUB_VERIFY_KERNEL_CMDLINE); |
||||
|
||||
grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); |
||||
- grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); |
||||
- lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; |
||||
+ grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", |
||||
+ linux_cmdline); |
||||
+ lh->cmd_line_ptr = linux_cmdline; |
||||
|
||||
handover_offset = lh->handover_offset; |
||||
- grub_dprintf("linux", "handover_offset: %08x\n", handover_offset); |
||||
+ grub_dprintf("linux", "handover_offset: 0x%08x\n", handover_offset); |
||||
|
||||
start = (lh->setup_sects + 1) * 512; |
||||
|
||||
- kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, |
||||
- BYTES_TO_PAGES(lh->init_size)); |
||||
- if (!kernel_mem) |
||||
- kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, |
||||
- BYTES_TO_PAGES(lh->init_size)); |
||||
- if (!kernel_mem) |
||||
- kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, |
||||
- BYTES_TO_PAGES(lh->init_size)); |
||||
- if (!kernel_mem) |
||||
+ grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address); |
||||
+ if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS) |
||||
{ |
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); |
||||
- goto fail; |
||||
+ max_addresses[0].addr = lh->pref_address; |
||||
+ max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS; |
||||
} |
||||
+ kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel")); |
||||
+ if (!kernel_mem) |
||||
+ goto fail; |
||||
grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); |
||||
|
||||
grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); |
||||
@@ -398,18 +423,14 @@ fail: |
||||
loaded = 0; |
||||
} |
||||
|
||||
- if (linux_cmdline && lh && !loaded) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) |
||||
- linux_cmdline, |
||||
- BYTES_TO_PAGES(lh->cmdline_size + 1)); |
||||
+ if (!loaded) |
||||
+ { |
||||
+ if (lh) |
||||
+ kernel_free (linux_cmdline, lh->cmdline_size + 1); |
||||
|
||||
- if (kernel_mem && !loaded) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, |
||||
- BYTES_TO_PAGES(kernel_size)); |
||||
- |
||||
- if (params && !loaded) |
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, |
||||
- BYTES_TO_PAGES(16384)); |
||||
+ kernel_free (kernel_mem, kernel_size); |
||||
+ kernel_free (params, sizeof(*params)); |
||||
+ } |
||||
|
||||
return grub_errno; |
||||
} |
@ -0,0 +1,171 @@
@@ -0,0 +1,171 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Wed, 12 Sep 2018 16:12:27 -0400 |
||||
Subject: [PATCH] x86-efi: Allow initrd+params+cmdline allocations above 4GB. |
||||
|
||||
This enables everything except the kernel itself to be above 4GB. |
||||
Putting the kernel up there still doesn't work, because of the way |
||||
params->code32_start is used. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/loader/i386/efi/linux.c | 67 +++++++++++++++++++++++++++++++++++---- |
||||
include/grub/i386/linux.h | 6 +++- |
||||
2 files changed, 65 insertions(+), 8 deletions(-) |
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
||||
index 3e4f7ef39f..6bc18d5aef 100644 |
||||
--- a/grub-core/loader/i386/efi/linux.c |
||||
+++ b/grub-core/loader/i386/efi/linux.c |
||||
@@ -52,13 +52,22 @@ struct allocation_choice { |
||||
grub_efi_allocate_type_t alloc_type; |
||||
}; |
||||
|
||||
-static struct allocation_choice max_addresses[] = |
||||
+static struct allocation_choice max_addresses[4] = |
||||
{ |
||||
+ /* the kernel overrides this one with pref_address and |
||||
+ * GRUB_EFI_ALLOCATE_ADDRESS */ |
||||
{ GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, |
||||
+ /* this one is always below 4GB, which we still *prefer* even if the flag |
||||
+ * is set. */ |
||||
{ GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, |
||||
+ /* If the flag in params is set, this one gets changed to be above 4GB. */ |
||||
{ GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, |
||||
{ 0, 0 } |
||||
}; |
||||
+static struct allocation_choice saved_addresses[4]; |
||||
+ |
||||
+#define save_addresses() grub_memcpy(saved_addresses, max_addresses, sizeof(max_addresses)) |
||||
+#define restore_addresses() grub_memcpy(max_addresses, saved_addresses, sizeof(max_addresses)) |
||||
|
||||
static inline void |
||||
kernel_free(void *addr, grub_efi_uintn_t size) |
||||
@@ -80,6 +89,11 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) |
||||
grub_uint64_t max = max_addresses[i].addr; |
||||
grub_efi_uintn_t pages; |
||||
|
||||
+ /* |
||||
+ * When we're *not* loading the kernel, or >4GB allocations aren't |
||||
+ * supported, these entries are basically all the same, so don't re-try |
||||
+ * the same parameters. |
||||
+ */ |
||||
if (max == prev_max) |
||||
continue; |
||||
|
||||
@@ -168,6 +182,9 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) |
||||
return bufpos; |
||||
} |
||||
|
||||
+#define LOW_U32(val) ((grub_uint32_t)(((grub_addr_t)(val)) & 0xffffffffull)) |
||||
+#define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) |
||||
+ |
||||
static grub_err_t |
||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
int argc, char *argv[]) |
||||
@@ -207,8 +224,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
||||
goto fail; |
||||
grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); |
||||
|
||||
- params->ramdisk_size = size; |
||||
- params->ramdisk_image = initrd_mem; |
||||
+ params->ramdisk_size = LOW_U32(size); |
||||
+ params->ramdisk_image = LOW_U32(initrd_mem); |
||||
+#if defined(__x86_64__) |
||||
+ params->ext_ramdisk_size = HIGH_U32(size); |
||||
+ params->ext_ramdisk_image = HIGH_U32(initrd_mem); |
||||
+#endif |
||||
|
||||
ptr = initrd_mem; |
||||
|
||||
@@ -338,6 +359,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
} |
||||
#endif |
||||
|
||||
+#if defined(__x86_64__) |
||||
+ if (lh->xloadflags & LINUX_XLF_CAN_BE_LOADED_ABOVE_4G) |
||||
+ { |
||||
+ grub_dprintf ("linux", "Loading kernel above 4GB is supported; enabling.\n"); |
||||
+ max_addresses[2].addr = GRUB_EFI_MAX_USABLE_ADDRESS; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ grub_dprintf ("linux", "Loading kernel above 4GB is not supported\n"); |
||||
+ } |
||||
+#endif |
||||
+ |
||||
params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); |
||||
if (!params) |
||||
goto fail; |
||||
@@ -372,21 +405,40 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
|
||||
grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); |
||||
grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", |
||||
- linux_cmdline); |
||||
- lh->cmd_line_ptr = linux_cmdline; |
||||
+ LOW_U32(linux_cmdline)); |
||||
+ lh->cmd_line_ptr = LOW_U32(linux_cmdline); |
||||
+#if defined(__x86_64__) |
||||
+ if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull) |
||||
+ { |
||||
+ grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n", |
||||
+ HIGH_U32(linux_cmdline)); |
||||
+ params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline); |
||||
+ } |
||||
+#endif |
||||
|
||||
handover_offset = lh->handover_offset; |
||||
grub_dprintf("linux", "handover_offset: 0x%08x\n", handover_offset); |
||||
|
||||
start = (lh->setup_sects + 1) * 512; |
||||
|
||||
+ /* |
||||
+ * AFAICS >4GB for kernel *cannot* work because of params->code32_start being |
||||
+ * 32-bit and getting called unconditionally in head_64.S from either entry |
||||
+ * point. |
||||
+ * |
||||
+ * so nerf that out here... |
||||
+ */ |
||||
+ save_addresses(); |
||||
grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address); |
||||
if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS) |
||||
{ |
||||
max_addresses[0].addr = lh->pref_address; |
||||
max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS; |
||||
} |
||||
+ max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; |
||||
+ max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; |
||||
kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel")); |
||||
+ restore_addresses(); |
||||
if (!kernel_mem) |
||||
goto fail; |
||||
grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); |
||||
@@ -395,8 +447,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
||||
|
||||
loaded = 1; |
||||
|
||||
- grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem); |
||||
- lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; |
||||
+ grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n", |
||||
+ LOW_U32(kernel_mem)); |
||||
+ lh->code32_start = LOW_U32(kernel_mem); |
||||
|
||||
grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); |
||||
|
||||
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h |
||||
index 25ef52c04e..fac22476cc 100644 |
||||
--- a/include/grub/i386/linux.h |
||||
+++ b/include/grub/i386/linux.h |
||||
@@ -236,7 +236,11 @@ struct linux_kernel_params |
||||
grub_uint32_t ofw_cif_handler; /* b8 */ |
||||
grub_uint32_t ofw_idt; /* bc */ |
||||
|
||||
- grub_uint8_t padding7[0x1b8 - 0xc0]; |
||||
+ grub_uint32_t ext_ramdisk_image; /* 0xc0 */ |
||||
+ grub_uint32_t ext_ramdisk_size; /* 0xc4 */ |
||||
+ grub_uint32_t ext_cmd_line_ptr; /* 0xc8 */ |
||||
+ |
||||
+ grub_uint8_t padding7[0x1b8 - 0xcc]; |
||||
|
||||
union |
||||
{ |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Fri, 28 Sep 2018 15:42:19 -0400 |
||||
Subject: [PATCH] Fix getroot.c's trampolines. |
||||
|
||||
This makes the stack executable on most of the grub utilities, which is |
||||
bad, and rpmdiff complains about it. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
grub-core/osdep/linux/getroot.c | 16 +++++++--------- |
||||
1 file changed, 7 insertions(+), 9 deletions(-) |
||||
|
||||
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c |
||||
index 9f730b3518..f0c503f43d 100644 |
||||
--- a/grub-core/osdep/linux/getroot.c |
||||
+++ b/grub-core/osdep/linux/getroot.c |
||||
@@ -1264,22 +1264,20 @@ grub_util_get_grub_dev_os (const char *os_dev) |
||||
return grub_dev; |
||||
} |
||||
|
||||
+static void *mp = NULL; |
||||
+static void |
||||
+btrfs_mount_path_hook(const char *m) |
||||
+{ |
||||
+ mp = strdup (m); |
||||
+} |
||||
|
||||
char * |
||||
grub_util_get_btrfs_subvol (const char *path, char **mount_path) |
||||
{ |
||||
- char *mp = NULL; |
||||
- |
||||
if (mount_path) |
||||
*mount_path = NULL; |
||||
|
||||
- auto void |
||||
- mount_path_hook (const char *m) |
||||
- { |
||||
- mp = strdup (m); |
||||
- } |
||||
- |
||||
- grub_find_root_btrfs_mount_path_hook = mount_path_hook; |
||||
+ grub_find_root_btrfs_mount_path_hook = btrfs_mount_path_hook; |
||||
grub_free (grub_find_root_devices_from_mountinfo (path, NULL)); |
||||
grub_find_root_btrfs_mount_path_hook = NULL; |
||||
|
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Fri, 12 Jul 2019 10:06:50 +0200 |
||||
Subject: [PATCH] Do not allow stack trampolines, anywhere. |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
--- |
||||
configure.ac | 3 +++ |
||||
conf/Makefile.common | 2 +- |
||||
2 files changed, 4 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 490353713a..a02d40a05b 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -1998,6 +1998,9 @@ if test x"$enable_wextra" != xno ; then |
||||
HOST_CFLAGS="$HOST_CFLAGS -Wextra" |
||||
fi |
||||
|
||||
+TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines" |
||||
+HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines" |
||||
+ |
||||
TARGET_CPP="$TARGET_CC -E" |
||||
TARGET_CCAS=$TARGET_CC |
||||
|
||||
diff --git a/conf/Makefile.common b/conf/Makefile.common |
||||
index 35e14ff017..0647c53b91 100644 |
||||
--- a/conf/Makefile.common |
||||
+++ b/conf/Makefile.common |
||||
@@ -66,7 +66,7 @@ grubconfdir = $(sysconfdir)/grub.d |
||||
platformdir = $(pkglibdir)/$(target_cpu)-$(platform) |
||||
starfielddir = $(pkgdatadir)/themes/starfield |
||||
|
||||
-CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code |
||||
+CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Werror=trampolines -fno-trampolines |
||||
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib |
||||
|
||||
CFLAGS_POSIX = -fno-builtin |
@ -0,0 +1,196 @@
@@ -0,0 +1,196 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Thu, 4 Oct 2018 14:22:09 -0400 |
||||
Subject: [PATCH] Reimplement boot_counter |
||||
|
||||
This adds "increment" and "decrement" commands, and uses them to maintain our |
||||
variables in 01_fallback_counter. It also simplifies the counter logic, so |
||||
that there are no nested tests that conflict with each other. |
||||
|
||||
Apparently, this *really* wasn't tested well enough. |
||||
|
||||
Resolves: rhbz#1614637 |
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[lorbus: add comments and revert logic changes in 01_fallback_counting] |
||||
Signed-off-by: Christian Glombek <lorbus@fedoraproject.org> |
||||
--- |
||||
Makefile.util.def | 6 +++ |
||||
grub-core/Makefile.core.def | 5 ++ |
||||
grub-core/commands/increment.c | 105 ++++++++++++++++++++++++++++++++++++ |
||||
util/grub.d/01_fallback_counting.in | 22 ++++++++ |
||||
4 files changed, 138 insertions(+) |
||||
create mode 100644 grub-core/commands/increment.c |
||||
create mode 100644 util/grub.d/01_fallback_counting.in |
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index d066652e9b..e10fe766d1 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -458,6 +458,12 @@ script = { |
||||
installdir = grubconf; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = '01_fallback_counting'; |
||||
+ common = util/grub.d/01_fallback_counting.in; |
||||
+ installdir = grubconf; |
||||
+}; |
||||
+ |
||||
script = { |
||||
name = '01_menu_auto_hide'; |
||||
common = util/grub.d/01_menu_auto_hide.in; |
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
||||
index 4f203533f5..ea4d59f51b 100644 |
||||
--- a/grub-core/Makefile.core.def |
||||
+++ b/grub-core/Makefile.core.def |
||||
@@ -398,6 +398,11 @@ kernel = { |
||||
extra_dist = kern/mips/cache_flush.S; |
||||
}; |
||||
|
||||
+module = { |
||||
+ name = increment; |
||||
+ common = commands/increment.c; |
||||
+}; |
||||
+ |
||||
program = { |
||||
name = grub-emu; |
||||
mansection = 1; |
||||
diff --git a/grub-core/commands/increment.c b/grub-core/commands/increment.c |
||||
new file mode 100644 |
||||
index 0000000000..79cf137656 |
||||
--- /dev/null |
||||
+++ b/grub-core/commands/increment.c |
||||
@@ -0,0 +1,105 @@ |
||||
+/* increment.c - Commands to increment and decrement variables. */ |
||||
+/* |
||||
+ * GRUB -- GRand Unified Bootloader |
||||
+ * Copyright (C) 2006,2007,2008 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/term.h> |
||||
+#include <grub/time.h> |
||||
+#include <grub/types.h> |
||||
+#include <grub/misc.h> |
||||
+#include <grub/extcmd.h> |
||||
+#include <grub/i18n.h> |
||||
+#include <grub/env.h> |
||||
+ |
||||
+GRUB_MOD_LICENSE ("GPLv3+"); |
||||
+ |
||||
+typedef enum { |
||||
+ INCREMENT, |
||||
+ DECREMENT, |
||||
+} operation; |
||||
+ |
||||
+static grub_err_t |
||||
+incr_decr(operation op, int argc, char **args) |
||||
+{ |
||||
+ const char *old; |
||||
+ char *new; |
||||
+ long value; |
||||
+ |
||||
+ if (argc < 1) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no variable specified")); |
||||
+ if (argc > 1) |
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("too many arguments")); |
||||
+ |
||||
+ old = grub_env_get (*args); |
||||
+ if (!old) |
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable \"%s\""), |
||||
+ *args); |
||||
+ |
||||
+ value = grub_strtol (old, NULL, 0); |
||||
+ if (grub_errno != GRUB_ERR_NONE) |
||||
+ return grub_errno; |
||||
+ |
||||
+ switch (op) |
||||
+ { |
||||
+ case INCREMENT: |
||||
+ value += 1; |
||||
+ break; |
||||
+ case DECREMENT: |
||||
+ value -= 1; |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ new = grub_xasprintf ("%ld", value); |
||||
+ if (!new) |
||||
+ return grub_errno; |
||||
+ |
||||
+ grub_env_set (*args, new); |
||||
+ grub_free (new); |
||||
+ |
||||
+ return GRUB_ERR_NONE; |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+grub_cmd_incr(struct grub_command *cmd UNUSED, |
||||
+ int argc, char **args) |
||||
+{ |
||||
+ return incr_decr(INCREMENT, argc, args); |
||||
+} |
||||
+ |
||||
+static grub_err_t |
||||
+grub_cmd_decr(struct grub_command *cmd UNUSED, |
||||
+ int argc, char **args) |
||||
+{ |
||||
+ return incr_decr(DECREMENT, argc, args); |
||||
+} |
||||
+ |
||||
+static grub_command_t cmd_incr, cmd_decr; |
||||
+ |
||||
+GRUB_MOD_INIT(increment) |
||||
+{ |
||||
+ cmd_incr = grub_register_command ("increment", grub_cmd_incr, N_("VARIABLE"), |
||||
+ N_("increment VARIABLE")); |
||||
+ cmd_decr = grub_register_command ("decrement", grub_cmd_decr, N_("VARIABLE"), |
||||
+ N_("decrement VARIABLE")); |
||||
+} |
||||
+ |
||||
+GRUB_MOD_FINI(increment) |
||||
+{ |
||||
+ grub_unregister_command (cmd_incr); |
||||
+ grub_unregister_command (cmd_decr); |
||||
+} |
||||
diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/01_fallback_counting.in |
||||
new file mode 100644 |
||||
index 0000000000..be0e770ea8 |
||||
--- /dev/null |
||||
+++ b/util/grub.d/01_fallback_counting.in |
||||
@@ -0,0 +1,22 @@ |
||||
+#! /bin/sh -e |
||||
+ |
||||
+# Boot Counting |
||||
+# The boot_counter env var can be used to count down boot attempts after an |
||||
+# OSTree upgrade and choose the rollback deployment when 0 is reached. Both |
||||
+# boot_counter and boot_success need to be (re-)set from userspace. |
||||
+cat << EOF |
||||
+insmod increment |
||||
+# Check if boot_counter exists and boot_success=0 to activate this behaviour. |
||||
+if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then |
||||
+ # if countdown has ended, choose to boot rollback deployment (default=1 on |
||||
+ # OSTree-based systems) |
||||
+ if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then |
||||
+ set default=1 |
||||
+ set boot_counter=-1 |
||||
+ # otherwise decrement boot_counter |
||||
+ else |
||||
+ decrement boot_counter |
||||
+ fi |
||||
+ save_env boot_counter |
||||
+fi |
||||
+EOF |
@ -0,0 +1,233 @@
@@ -0,0 +1,233 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Peter Jones <pjones@redhat.com> |
||||
Date: Fri, 19 Oct 2018 10:57:52 -0400 |
||||
Subject: [PATCH] Fix menu entry selection based on ID and title |
||||
|
||||
Currently if grub_strtoul(saved_entry_value, NULL, 0) does not return an |
||||
error, we assume the value it has produced is a correct index into our |
||||
menu entry list, and do not try to interpret the value as the "id" or |
||||
"title" . In cases where "id" or "title" start with a numeral, this |
||||
makes them impossible to use as selection criteria. |
||||
|
||||
This patch splits the search into three phases - matching id, matching |
||||
title, and only once those have been exhausted, trying to interpret the |
||||
ID as a numeral. In that case, we also require that the entire string |
||||
is numeric, not merely a string with leading numeric characters. |
||||
|
||||
Resolves: rhbz#1640979 |
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com> |
||||
[javierm: fix menu entry selection based on title] |
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
--- |
||||
grub-core/normal/menu.c | 141 ++++++++++++++++++++++++------------------------ |
||||
1 file changed, 71 insertions(+), 70 deletions(-) |
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c |
||||
index d7a222e681..4a02aadb01 100644 |
||||
--- a/grub-core/normal/menu.c |
||||
+++ b/grub-core/normal/menu.c |
||||
@@ -164,12 +164,12 @@ grub_menu_set_timeout (int timeout) |
||||
} |
||||
|
||||
static int |
||||
-menuentry_eq (const char *id, const char *spec) |
||||
+menuentry_eq (const char *id, const char *spec, int limit) |
||||
{ |
||||
const char *ptr1, *ptr2; |
||||
ptr1 = id; |
||||
ptr2 = spec; |
||||
- while (1) |
||||
+ while (limit == -1 || ptr1 - id <= limit) |
||||
{ |
||||
if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) |
||||
return ptr2 - spec; |
||||
@@ -178,7 +178,11 @@ menuentry_eq (const char *id, const char *spec) |
||||
if (*ptr2 == '>') |
||||
ptr2++; |
||||
if (*ptr1 != *ptr2) |
||||
- return 0; |
||||
+ { |
||||
+ if (limit > -1 && ptr1 - id == limit && !*ptr1 && grub_isspace(*ptr2)) |
||||
+ return ptr1 -id -1; |
||||
+ return 0; |
||||
+ } |
||||
if (*ptr1 == 0) |
||||
return ptr1 - id; |
||||
ptr1++; |
||||
@@ -187,6 +191,58 @@ menuentry_eq (const char *id, const char *spec) |
||||
return 0; |
||||
} |
||||
|
||||
+static int |
||||
+get_entry_number_helper(grub_menu_t menu, |
||||
+ const char * const val, const char ** const tail) |
||||
+{ |
||||
+ /* See if the variable matches the title of a menu entry. */ |
||||
+ int entry = -1; |
||||
+ grub_menu_entry_t e; |
||||
+ int i; |
||||
+ |
||||
+ for (i = 0, e = menu->entry_list; e; i++) |
||||
+ { |
||||
+ int l = 0; |
||||
+ while (val[l] && !grub_isspace(val[l])) |
||||
+ l++; |
||||
+ |
||||
+ if (menuentry_eq (e->id, val, l)) |
||||
+ { |
||||
+ if (tail) |
||||
+ *tail = val + l; |
||||
+ return i; |
||||
+ } |
||||
+ e = e->next; |
||||
+ } |
||||
+ |
||||
+ for (i = 0, e = menu->entry_list; e; i++) |
||||
+ { |
||||
+ |
||||
+ if (menuentry_eq (e->title, val, -1)) |
||||
+ { |
||||
+ if (tail) |
||||
+ *tail = NULL; |
||||
+ return i; |
||||
+ } |
||||
+ e = e->next; |
||||
+ } |
||||
+ |
||||
+ if (tail) |
||||
+ *tail = NULL; |
||||
+ |
||||
+ entry = (int) grub_strtoul (val, tail, 0); |
||||
+ if (grub_errno == GRUB_ERR_BAD_NUMBER || |
||||
+ (*tail && **tail && !grub_isspace(**tail))) |
||||
+ { |
||||
+ entry = -1; |
||||
+ if (tail) |
||||
+ *tail = NULL; |
||||
+ grub_errno = GRUB_ERR_NONE; |
||||
+ } |
||||
+ |
||||
+ return entry; |
||||
+} |
||||
+ |
||||
/* Get the first entry number from the value of the environment variable NAME, |
||||
which is a space-separated list of non-negative integers. The entry number |
||||
which is returned is stripped from the value of NAME. If no entry number |
||||
@@ -196,7 +252,6 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) |
||||
{ |
||||
const char *val, *tail; |
||||
int entry; |
||||
- int sz = 0; |
||||
|
||||
val = grub_env_get (name); |
||||
if (! val) |
||||
@@ -204,50 +259,24 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) |
||||
|
||||
grub_error_push (); |
||||
|
||||
- entry = (int) grub_strtoul (val, &tail, 0); |
||||
+ entry = get_entry_number_helper(menu, val, &tail); |
||||
+ if (!(*tail == 0 || grub_isspace(*tail))) |
||||
+ entry = -1; |
||||
|
||||
- if (grub_errno == GRUB_ERR_BAD_NUMBER) |
||||
+ if (entry >= 0) |
||||
{ |
||||
- /* See if the variable matches the title of a menu entry. */ |
||||
- grub_menu_entry_t e = menu->entry_list; |
||||
- int i; |
||||
- |
||||
- for (i = 0; e; i++) |
||||
- { |
||||
- sz = menuentry_eq (e->title, val); |
||||
- if (sz < 1) |
||||
- sz = menuentry_eq (e->id, val); |
||||
- |
||||
- if (sz >= 1) |
||||
- { |
||||
- entry = i; |
||||
- break; |
||||
- } |
||||
- e = e->next; |
||||
- } |
||||
- |
||||
- if (sz > 0) |
||||
- grub_errno = GRUB_ERR_NONE; |
||||
- |
||||
- if (! e) |
||||
- entry = -1; |
||||
- } |
||||
- |
||||
- if (grub_errno == GRUB_ERR_NONE) |
||||
- { |
||||
- if (sz > 0) |
||||
- tail += sz; |
||||
- |
||||
/* Skip whitespace to find the next entry. */ |
||||
while (*tail && grub_isspace (*tail)) |
||||
tail++; |
||||
- grub_env_set (name, tail); |
||||
+ if (*tail) |
||||
+ grub_env_set (name, tail); |
||||
+ else |
||||
+ grub_env_unset (name); |
||||
} |
||||
else |
||||
{ |
||||
grub_env_unset (name); |
||||
grub_errno = GRUB_ERR_NONE; |
||||
- entry = -1; |
||||
} |
||||
|
||||
grub_error_pop (); |
||||
@@ -524,6 +553,7 @@ static int |
||||
get_entry_number (grub_menu_t menu, const char *name) |
||||
{ |
||||
const char *val; |
||||
+ const char *tail; |
||||
int entry; |
||||
|
||||
val = grub_env_get (name); |
||||
@@ -531,38 +561,9 @@ get_entry_number (grub_menu_t menu, const char *name) |
||||
return -1; |
||||
|
||||
grub_error_push (); |
||||
- |
||||
- entry = (int) grub_strtoul (val, 0, 0); |
||||
- |
||||
- if (grub_errno == GRUB_ERR_BAD_NUMBER) |
||||
- { |
||||
- /* See if the variable matches the title of a menu entry. */ |
||||
- grub_menu_entry_t e = menu->entry_list; |
||||
- int i; |
||||
- |
||||
- grub_errno = GRUB_ERR_NONE; |
||||
- |
||||
- for (i = 0; e; i++) |
||||
- { |
||||
- if (menuentry_eq (e->title, val) |
||||
- || menuentry_eq (e->id, val)) |
||||
- { |
||||
- entry = i; |
||||
- break; |
||||
- } |
||||
- e = e->next; |
||||
- } |
||||
- |
||||
- if (! e) |
||||
- entry = -1; |
||||
- } |
||||
- |
||||
- if (grub_errno != GRUB_ERR_NONE) |
||||
- { |
||||
- grub_errno = GRUB_ERR_NONE; |
||||
- entry = -1; |
||||
- } |
||||
- |
||||
+ entry = get_entry_number_helper(menu, val, &tail); |
||||
+ if (tail && *tail != '\0') |
||||
+ entry = -1; |
||||
grub_error_pop (); |
||||
|
||||
return entry; |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Javier Martinez Canillas <javierm@redhat.com> |
||||
Date: Mon, 26 Nov 2018 10:06:42 +0100 |
||||
Subject: [PATCH] Make the menu entry users option argument to be optional |
||||
|
||||
The --users option is used to restrict the access to specific menu entries |
||||
only to a set of users. But the option requires an argument to either be a |
||||
constant or a variable that has been set. So for example the following: |
||||
|
||||
menuentry "May be run by superusers or users in $users" --users $users { |
||||
linux /vmlinuz |
||||
} |
||||
|
||||
Would fail if $users is not defined and grub would discard the menu entry. |
||||
Instead, allow the --users option to have an optional argument and ignore |
||||
the option if the argument was not set. |
||||
|
||||
Related: rhbz#1652434 |
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
--- |
||||
grub-core/commands/menuentry.c | 4 ++-- |
||||
1 file changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c |
||||
index b194123eb6..b175a1b43b 100644 |
||||
--- a/grub-core/commands/menuentry.c |
||||
+++ b/grub-core/commands/menuentry.c |
||||
@@ -29,7 +29,7 @@ static const struct grub_arg_option options[] = |
||||
{ |
||||
{"class", 1, GRUB_ARG_OPTION_REPEATABLE, |
||||
N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, |
||||
- {"users", 2, 0, |
||||
+ {"users", 2, GRUB_ARG_OPTION_OPTIONAL, |
||||
N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"), |
||||
ARG_TYPE_STRING}, |
||||
{"hotkey", 3, 0, |
||||
@@ -281,7 +281,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) |
||||
if (! ctxt->state[3].set && ! ctxt->script) |
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); |
||||
|
||||
- if (ctxt->state[1].set) |
||||
+ if (ctxt->state[1].set && ctxt->state[1].arg) |
||||
users = ctxt->state[1].arg; |
||||
else if (ctxt->state[5].set) |
||||
users = NULL; |
@ -0,0 +1,346 @@
@@ -0,0 +1,346 @@
|
||||
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/grub-set-bootflag.c | 1 + |
||||
include/grub/efi/efi.h | 5 ++ |
||||
include/grub/lib/envblk.h | 3 + |
||||
8 files changed, 229 insertions(+), 5 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 ea4d59f51b..dc9fea6f44 100644 |
||||
--- a/grub-core/Makefile.core.def |
||||
+++ b/grub-core/Makefile.core.def |
||||
@@ -820,6 +820,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 0000000000..cbd13e03e8 |
||||
--- /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")); |
||||
+ |
||||
+ grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, &envblk_s.size, |
||||
+ (void **) &envblk_s.buf); |
||||
+ 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; |
||||
+ |
||||
+ grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, &envblk_s.size, |
||||
+ (void **) &envblk_s.buf); |
||||
+ 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 2a446f5031..14bc10eb56 100644 |
||||
--- a/grub-core/kern/efi/efi.c |
||||
+++ b/grub-core/kern/efi/efi.c |
||||
@@ -225,6 +225,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 2d12e6188f..0574d8d621 100644 |
||||
--- a/grub-core/kern/efi/init.c |
||||
+++ b/grub-core/kern/efi/init.c |
||||
@@ -85,11 +85,6 @@ stack_protector_init (void) |
||||
|
||||
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 2e4e78b132..874506da16 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/grub-set-bootflag.c b/util/grub-set-bootflag.c |
||||
index d506f7e75b..a6ccc11383 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 <errno.h> |
||||
#include <stdio.h> |
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
||||
index 2e0691454b..8dfc89a33b 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 c3e6559217..ab969af246 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 @@
@@ -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 9a2fae6398..578bf51a5f 100644 |
||||
--- a/grub-core/kern/misc.c |
||||
+++ b/grub-core/kern/misc.c |
||||
@@ -164,12 +164,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 @@
@@ -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 ee53d4a68e..87edd254c4 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 4a02aadb01..fe2e77a43e 100644 |
||||
--- a/grub-core/normal/menu.c |
||||
+++ b/grub-core/normal/menu.c |
||||
@@ -375,8 +375,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); |
||||
|
@ -0,0 +1,168 @@
@@ -0,0 +1,168 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Christian Glombek <lorbus@fedoraproject.org> |
||||
Date: Tue, 2 Apr 2019 16:22:21 +0200 |
||||
Subject: [PATCH] grub.d: Split out boot success reset from menu auto hide |
||||
script |
||||
|
||||
Also rename fallback and menu auto hide script to be executed |
||||
before and after boot success reset script. |
||||
In menu auto hide script, rename last_boot_ok var to menu_hide_ok |
||||
|
||||
Signed-off-by: Christian Glombek <lorbus@fedoraproject.org> |
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com> |
||||
--- |
||||
Makefile.util.def | 14 ++++++++---- |
||||
...allback_counting.in => 08_fallback_counting.in} | 14 ++++++------ |
||||
util/grub.d/10_reset_boot_success.in | 25 ++++++++++++++++++++++ |
||||
.../{01_menu_auto_hide.in => 12_menu_auto_hide.in} | 23 +++++--------------- |
||||
4 files changed, 48 insertions(+), 28 deletions(-) |
||||
rename util/grub.d/{01_fallback_counting.in => 08_fallback_counting.in} (65%) |
||||
create mode 100644 util/grub.d/10_reset_boot_success.in |
||||
rename util/grub.d/{01_menu_auto_hide.in => 12_menu_auto_hide.in} (58%) |
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def |
||||
index e10fe766d1..b4ce5383b7 100644 |
||||
--- a/Makefile.util.def |
||||
+++ b/Makefile.util.def |
||||
@@ -459,14 +459,14 @@ script = { |
||||
}; |
||||
|
||||
script = { |
||||
- name = '01_fallback_counting'; |
||||
- common = util/grub.d/01_fallback_counting.in; |
||||
+ name = '08_fallback_counting'; |
||||
+ common = util/grub.d/08_fallback_counting.in; |
||||
installdir = grubconf; |
||||
}; |
||||
|
||||
script = { |
||||
- name = '01_menu_auto_hide'; |
||||
- common = util/grub.d/01_menu_auto_hide.in; |
||||
+ name = '12_menu_auto_hide'; |
||||
+ common = util/grub.d/12_menu_auto_hide.in; |
||||
installdir = grubconf; |
||||
}; |
||||
|
||||
@@ -518,6 +518,12 @@ script = { |
||||
condition = COND_HOST_LINUX; |
||||
}; |
||||
|
||||
+script = { |
||||
+ name = '10_reset_boot_success'; |
||||
+ common = util/grub.d/10_reset_boot_success.in; |
||||
+ installdir = grubconf; |
||||
+}; |
||||
+ |
||||
script = { |
||||
name = '10_xnu'; |
||||
common = util/grub.d/10_xnu.in; |
||||
diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/08_fallback_counting.in |
||||
similarity index 65% |
||||
rename from util/grub.d/01_fallback_counting.in |
||||
rename to util/grub.d/08_fallback_counting.in |
||||
index be0e770ea8..2e2c3ff7d3 100644 |
||||
--- a/util/grub.d/01_fallback_counting.in |
||||
+++ b/util/grub.d/08_fallback_counting.in |
||||
@@ -1,15 +1,17 @@ |
||||
#! /bin/sh -e |
||||
- |
||||
-# Boot Counting |
||||
+# Fallback Countdown |
||||
+# |
||||
+# This snippet depends on 10_reset_boot_success and needs to be kept in sync. |
||||
+# |
||||
# The boot_counter env var can be used to count down boot attempts after an |
||||
-# OSTree upgrade and choose the rollback deployment when 0 is reached. Both |
||||
-# boot_counter and boot_success need to be (re-)set from userspace. |
||||
+# OSTree upgrade and choose the rollback deployment when 0 is reached. |
||||
+# Both boot_counter=X and boot_success=1 need to be set from userspace. |
||||
cat << EOF |
||||
insmod increment |
||||
# Check if boot_counter exists and boot_success=0 to activate this behaviour. |
||||
if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then |
||||
- # if countdown has ended, choose to boot rollback deployment (default=1 on |
||||
- # OSTree-based systems) |
||||
+ # if countdown has ended, choose to boot rollback deployment, |
||||
+ # i.e. default=1 on OSTree-based systems. |
||||
if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then |
||||
set default=1 |
||||
set boot_counter=-1 |
||||
diff --git a/util/grub.d/10_reset_boot_success.in b/util/grub.d/10_reset_boot_success.in |
||||
new file mode 100644 |
||||
index 0000000000..6c88d933dd |
||||
--- /dev/null |
||||
+++ b/util/grub.d/10_reset_boot_success.in |
||||
@@ -0,0 +1,25 @@ |
||||
+#! /bin/sh -e |
||||
+# Reset Boot Success |
||||
+# |
||||
+# The 08_fallback_counting and 12_menu_auto_hide snippets rely on this one |
||||
+# and need to be kept in sync. |
||||
+# |
||||
+# The boot_success var needs to be set to 1 from userspace to mark a boot successful. |
||||
+cat << EOF |
||||
+insmod increment |
||||
+# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry |
||||
+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then |
||||
+ set menu_hide_ok=1 |
||||
+else |
||||
+ set menu_hide_ok=0 |
||||
+fi |
||||
+# Reset boot_indeterminate after a successful boot, increment otherwise |
||||
+if [ "\${boot_success}" = "1" ] ; then |
||||
+ set boot_indeterminate=0 |
||||
+else |
||||
+ increment boot_indeterminate |
||||
+fi |
||||
+# Reset boot_success for current boot |
||||
+set boot_success=0 |
||||
+save_env boot_success boot_indeterminate |
||||
+EOF |
||||
diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/12_menu_auto_hide.in |
||||
similarity index 58% |
||||
rename from util/grub.d/01_menu_auto_hide.in |
||||
rename to util/grub.d/12_menu_auto_hide.in |
||||
index ad175870a5..6a7c0fa0d4 100644 |
||||
--- a/util/grub.d/01_menu_auto_hide.in |
||||
+++ b/util/grub.d/12_menu_auto_hide.in |
||||
@@ -1,5 +1,8 @@ |
||||
#! /bin/sh |
||||
- |
||||
+# Menu Auto Hide |
||||
+# |
||||
+# This snippet depends on 10_reset_boot_success and needs to be kept in sync. |
||||
+# |
||||
# Disable / skip generating menu-auto-hide config parts on serial terminals |
||||
for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do |
||||
case "$x" in |
||||
@@ -10,29 +13,13 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do |
||||
done |
||||
|
||||
cat << EOF |
||||
-if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then |
||||
- set last_boot_ok=1 |
||||
-else |
||||
- set last_boot_ok=0 |
||||
-fi |
||||
- |
||||
-# Reset boot_indeterminate after a successful boot |
||||
-if [ "\${boot_success}" = "1" ] ; then |
||||
- set boot_indeterminate=0 |
||||
-# Avoid boot_indeterminate causing the menu to be hidden more then once |
||||
-elif [ "\${boot_indeterminate}" = "1" ]; then |
||||
- set boot_indeterminate=2 |
||||
-fi |
||||
-set boot_success=0 |
||||
-save_env boot_success boot_indeterminate |
||||
- |
||||
if [ x\$feature_timeout_style = xy ] ; then |
||||
if [ "\${menu_show_once}" ]; then |
||||
unset menu_show_once |
||||
save_env menu_show_once |
||||
set timeout_style=menu |
||||
set timeout=60 |
||||
- elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then |
||||
+ elif [ "\${menu_auto_hide}" -a "\${menu_hide_ok}" = "1" ]; then |
||||
set orig_timeout_style=\${timeout_style} |
||||
set orig_timeout=\${timeout} |
||||
if [ "\${fastboot}" = "1" ]; then |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Javier Martinez Canillas <javierm@redhat.com> |
||||
Date: Tue, 9 Apr 2019 13:12:40 +0200 |
||||
Subject: [PATCH] Don't assume that boot commands will only return on fail |
||||
|
||||
While it's true that for most loaders the boot command never returns, it |
||||
may be the case that it does. For example the GRUB emulator boot command |
||||
calls to systemctl kexec which in turn does an asynchonous call to kexec. |
||||
|
||||
So in this case GRUB will wrongly assume that the boot command fails and |
||||
print a "Failed to boot both default and fallback entries" even when the |
||||
kexec call later succeeds. |
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
||||
--- |
||||
grub-core/normal/menu.c | 23 +++++++++++++---------- |
||||
1 file changed, 13 insertions(+), 10 deletions(-) |
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c |
||||
index fe2e77a43e..ec0c92bade 100644 |
||||
--- a/grub-core/normal/menu.c |
||||
+++ b/grub-core/normal/menu.c |
||||
@@ -285,7 +285,7 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) |
||||
} |
||||
|
||||
/* Run a menu entry. */ |
||||
-static void |
||||
+static grub_err_t |
||||
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) |
||||
{ |
||||
grub_err_t err = GRUB_ERR_NONE; |
||||
@@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) |
||||
{ |
||||
grub_print_error (); |
||||
grub_errno = GRUB_ERR_NONE; |
||||
- return; |
||||
+ return grub_errno; |
||||
} |
||||
|
||||
errs_before = grub_err_printed_errors; |
||||
@@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) |
||||
grub_env_context_open (); |
||||
menu = grub_zalloc (sizeof (*menu)); |
||||
if (! menu) |
||||
- return; |
||||
+ return grub_errno; |
||||
grub_env_set_menu (menu); |
||||
if (auto_boot) |
||||
grub_env_set ("timeout", "0"); |
||||
@@ -385,7 +385,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) |
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) |
||||
/* Implicit execution of boot, only if something is loaded. */ |
||||
- grub_command_execute ("boot", 0, 0); |
||||
+ err = grub_command_execute ("boot", 0, 0); |
||||
|
||||
if (errs_before != grub_err_printed_errors) |
||||
grub_wait_after_message (); |
||||
@@ -408,6 +408,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) |
||||
else |
||||
grub_env_unset ("default"); |
||||
grub_env_unset ("timeout"); |
||||
+ |
||||
+ return err; |
||||
} |
||||
|
||||
/* Execute ENTRY from the menu MENU, falling back to entries specified |
||||
@@ -422,10 +424,13 @@ grub_menu_execute_with_fallback (grub_menu_t menu, |
||||
void *callback_data) |
||||
{ |
||||
int fallback_entry; |
||||
+ grub_err_t err; |
||||
|
||||
callback->notify_booting (entry, callback_data); |
||||
|
||||
- grub_menu_execute_entry (entry, 1); |
||||
+ err = grub_menu_execute_entry (entry, 1); |
||||
+ if (err == GRUB_ERR_NONE) |
||||
+ return; |
||||
|
||||
/* Deal with fallback entries. */ |
||||
while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) |
||||
@@ -436,11 +441,9 @@ grub_menu_execute_with_fallback (grub_menu_t menu, |
||||
|
||||
entry = grub_menu_get_entry (menu, fallback_entry); |
||||
callback->notify_fallback (entry, callback_data); |
||||
- grub_menu_execute_entry (entry, 1); |
||||
- /* If the function call to execute the entry returns at all, then this is |
||||
- taken to indicate a boot failure. For menu entries that do something |
||||
- other than actually boot an operating system, this could assume |
||||
- incorrectly that something failed. */ |
||||
+ err = grub_menu_execute_entry (entry, 1); |
||||
+ if (err == GRUB_ERR_NONE) |
||||
+ return; |
||||
} |
||||
|
||||
if (!autobooted) |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
||||
From: Hans de Goede <hdegoede@redhat.com> |
||||
Date: Wed, 13 Nov 2019 12:15:43 +0100 |
||||
Subject: [PATCH] grub-set-bootflag: Update comment about running as root |
||||
through pkexec |
||||
|
||||
We have stopped using pkexec for grub-set-bootflag, instead it is now |
||||
installed suid root, update the comment accordingly. |
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
||||
--- |
||||
util/grub-set-bootflag.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c |
||||
index a6ccc11383..3eb04beb5e 100644 |
||||
--- a/util/grub-set-bootflag.c |
||||
+++ b/util/grub-set-bootflag.c |
||||
@@ -18,7 +18,7 @@ |
||||
*/ |
||||
|
||||
/* |
||||
- * NOTE this gets run by users as root (through pkexec), so this does not |
||||
+ * NOTE this gets run by users as root (its suid root), so this does not |
||||
* use any grub library / util functions to allow for easy auditing. |
||||
* The grub headers are only included to get certain defines. |
||||
*/ |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue