mirror of
https://src.fedoraproject.org/rpms/grub2.git
synced 2024-11-24 14:32:58 +00:00
Merge branch 'f18'
This commit is contained in:
commit
2d134a261f
6 changed files with 781 additions and 4 deletions
|
@ -152,11 +152,10 @@ index b5e6eb0..c44eced 100644
|
|||
p[i++] = *s++;
|
||||
else
|
||||
p[i++] = ch;
|
||||
@@ -381,14 +402,25 @@ parse_string (const char *str,
|
||||
@@ -381,14 +402,24 @@ parse_string (const char *str,
|
||||
int escaped = 0;
|
||||
const char *optr;
|
||||
|
||||
+ grub_printf("str: \"%s\"\n", str);
|
||||
for (ptr = str; ptr && *ptr; )
|
||||
switch (*ptr)
|
||||
{
|
||||
|
|
230
grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch
Normal file
230
grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch
Normal file
|
@ -0,0 +1,230 @@
|
|||
From 3e00d82827f80461f9fe6da37acd84235c08e5a5 Mon Sep 17 00:00:00 2001
|
||||
From: Gustavo Luiz Duarte <gustavold@linux.vnet.ibm.com>
|
||||
Date: Fri, 28 Sep 2012 19:42:07 -0400
|
||||
Subject: [PATCH] Issue separate DNS queries for ipv4 and ipv6
|
||||
|
||||
Adding multiple questions on a single DNS query is not supportted by
|
||||
most DNS servers. This patch issues two separate DNS queries
|
||||
sequentially for ipv4 and then for ipv6.
|
||||
|
||||
There are 4 possible config options:
|
||||
DNS_OPTION_IPV4: issue only one ipv4 query
|
||||
DNS_OPTION_IPV6: issue only one ipv6 query
|
||||
DNS_OPTION_PREFER_IPV4: issue the ipv4 query first and fallback to ipv6
|
||||
DNS_OPTION_PREFER_IPV6: issue the ipv6 query first and fallback to ipv4
|
||||
However, there is no code yet to set such config option. The default is
|
||||
DNS_OPTION_PREFER_IPV4.
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=860829
|
||||
---
|
||||
grub-core/net/dns.c | 99 ++++++++++++++++++++++++++++++++++++-----------------
|
||||
include/grub/net.h | 9 +++++
|
||||
2 files changed, 76 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
|
||||
index 3381ea7..725725c 100644
|
||||
--- a/grub-core/net/dns.c
|
||||
+++ b/grub-core/net/dns.c
|
||||
@@ -34,6 +34,14 @@ struct dns_cache_element
|
||||
#define DNS_CACHE_SIZE 1021
|
||||
#define DNS_HASH_BASE 423
|
||||
|
||||
+typedef enum grub_dns_qtype_id
|
||||
+ {
|
||||
+ GRUB_DNS_QTYPE_A = 1,
|
||||
+ GRUB_DNS_QTYPE_AAAA = 28
|
||||
+ } grub_dns_qtype_id_t;
|
||||
+
|
||||
+static grub_dns_option_t dns_type_option = DNS_OPTION_PREFER_IPV4;
|
||||
+
|
||||
static struct dns_cache_element dns_cache[DNS_CACHE_SIZE];
|
||||
static struct grub_net_network_level_address *dns_servers;
|
||||
static grub_size_t dns_nservers, dns_servers_alloc;
|
||||
@@ -410,13 +418,13 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
-grub_err_t
|
||||
-grub_net_dns_lookup (const char *name,
|
||||
+static grub_err_t
|
||||
+grub_net_dns_lookup_qtype (const char *name,
|
||||
const struct grub_net_network_level_address *servers,
|
||||
grub_size_t n_servers,
|
||||
grub_size_t *naddresses,
|
||||
struct grub_net_network_level_address **addresses,
|
||||
- int cache)
|
||||
+ int cache, grub_dns_qtype_id_t qtype)
|
||||
{
|
||||
grub_size_t send_servers = 0;
|
||||
grub_size_t i, j;
|
||||
@@ -471,8 +479,7 @@ grub_net_dns_lookup (const char *name,
|
||||
+ GRUB_NET_MAX_LINK_HEADER_SIZE
|
||||
+ GRUB_NET_UDP_HEADER_SIZE
|
||||
+ sizeof (struct dns_header)
|
||||
- + grub_strlen (name) + 2 + 4
|
||||
- + 2 + 4);
|
||||
+ + grub_strlen (name) + 2 + 4);
|
||||
if (!nb)
|
||||
{
|
||||
grub_free (data.name);
|
||||
@@ -482,7 +489,7 @@ grub_net_dns_lookup (const char *name,
|
||||
+ GRUB_NET_MAX_LINK_HEADER_SIZE
|
||||
+ GRUB_NET_UDP_HEADER_SIZE);
|
||||
grub_netbuff_put (nb, sizeof (struct dns_header)
|
||||
- + grub_strlen (name) + 2 + 4 + 2 + 4);
|
||||
+ + grub_strlen (name) + 2 + 4);
|
||||
head = (struct dns_header *) nb->data;
|
||||
optr = (grub_uint8_t *) (head + 1);
|
||||
for (iptr = name; *iptr; )
|
||||
@@ -509,18 +516,7 @@ grub_net_dns_lookup (const char *name,
|
||||
|
||||
/* Type: A. */
|
||||
*optr++ = 0;
|
||||
- *optr++ = 1;
|
||||
-
|
||||
- /* Class. */
|
||||
- *optr++ = 0;
|
||||
- *optr++ = 1;
|
||||
-
|
||||
- /* Compressed name. */
|
||||
- *optr++ = 0xc0;
|
||||
- *optr++ = 0x0c;
|
||||
- /* Type: AAAA. */
|
||||
- *optr++ = 0;
|
||||
- *optr++ = 28;
|
||||
+ *optr++ = qtype;
|
||||
|
||||
/* Class. */
|
||||
*optr++ = 0;
|
||||
@@ -529,7 +525,7 @@ grub_net_dns_lookup (const char *name,
|
||||
head->id = data.id;
|
||||
head->flags = FLAGS_RD;
|
||||
head->ra_z_r_code = 0;
|
||||
- head->qdcount = grub_cpu_to_be16_compile_time (2);
|
||||
+ head->qdcount = grub_cpu_to_be16_compile_time (1);
|
||||
head->ancount = grub_cpu_to_be16_compile_time (0);
|
||||
head->nscount = grub_cpu_to_be16_compile_time (0);
|
||||
head->arcount = grub_cpu_to_be16_compile_time (0);
|
||||
@@ -587,16 +583,47 @@ grub_net_dns_lookup (const char *name,
|
||||
if (*data.naddresses)
|
||||
return GRUB_ERR_NONE;
|
||||
if (data.dns_err)
|
||||
- return grub_error (GRUB_ERR_NET_NO_DOMAIN,
|
||||
- N_("no DNS record found"));
|
||||
-
|
||||
+ {
|
||||
+ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n",
|
||||
+ N_("no DNS record found"), qtype, name);
|
||||
+ return GRUB_ERR_NET_NO_DOMAIN;
|
||||
+ }
|
||||
if (err)
|
||||
{
|
||||
grub_errno = err;
|
||||
return err;
|
||||
}
|
||||
- return grub_error (GRUB_ERR_TIMEOUT,
|
||||
- N_("no DNS reply received"));
|
||||
+ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n",
|
||||
+ N_("no DNS reply received"), qtype, name);
|
||||
+ return GRUB_ERR_TIMEOUT;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_net_dns_lookup (const char *name,
|
||||
+ const struct grub_net_network_level_address *servers,
|
||||
+ grub_size_t n_servers,
|
||||
+ grub_size_t *naddresses,
|
||||
+ struct grub_net_network_level_address **addresses,
|
||||
+ int cache)
|
||||
+{
|
||||
+ if (dns_type_option == DNS_OPTION_IPV6 || dns_type_option == DNS_OPTION_PREFER_IPV6)
|
||||
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
|
||||
+ addresses, cache, GRUB_DNS_QTYPE_AAAA);
|
||||
+ else
|
||||
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
|
||||
+ addresses, cache, GRUB_DNS_QTYPE_A);
|
||||
+ if (!*naddresses)
|
||||
+ {
|
||||
+ if (dns_type_option == DNS_OPTION_PREFER_IPV4)
|
||||
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
|
||||
+ addresses, cache, GRUB_DNS_QTYPE_AAAA);
|
||||
+ else if (dns_type_option == DNS_OPTION_PREFER_IPV6)
|
||||
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
|
||||
+ addresses, cache, GRUB_DNS_QTYPE_A);
|
||||
+ }
|
||||
+ if (!*naddresses)
|
||||
+ return GRUB_ERR_NET_NO_DOMAIN;
|
||||
+ return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -604,22 +631,28 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
grub_err_t err;
|
||||
- grub_size_t naddresses, i;
|
||||
+ struct grub_net_network_level_address cmd_server;
|
||||
+ struct grub_net_network_level_address *servers;
|
||||
+ grub_size_t nservers, i, naddresses = 0;
|
||||
struct grub_net_network_level_address *addresses = 0;
|
||||
if (argc != 2 && argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
|
||||
if (argc == 2)
|
||||
{
|
||||
- struct grub_net_network_level_address server;
|
||||
- err = grub_net_resolve_address (args[1], &server);
|
||||
+ err = grub_net_resolve_address (args[1], &cmd_server);
|
||||
if (err)
|
||||
return err;
|
||||
- err = grub_net_dns_lookup (args[0], &server, 1, &naddresses,
|
||||
- &addresses, 0);
|
||||
+ servers = &cmd_server;
|
||||
+ nservers = 1;
|
||||
}
|
||||
else
|
||||
- err = grub_net_dns_lookup (args[0], dns_servers, dns_nservers, &naddresses,
|
||||
- &addresses, 0);
|
||||
+ {
|
||||
+ servers = dns_servers;
|
||||
+ nservers = dns_nservers;
|
||||
+ }
|
||||
+
|
||||
+ grub_net_dns_lookup (args[0], servers, nservers, &naddresses,
|
||||
+ &addresses, 0);
|
||||
|
||||
for (i = 0; i < naddresses; i++)
|
||||
{
|
||||
@@ -628,7 +661,9 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
|
||||
grub_printf ("%s\n", buf);
|
||||
}
|
||||
grub_free (addresses);
|
||||
- return GRUB_ERR_NONE;
|
||||
+ if (naddresses)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found"));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
diff --git a/include/grub/net.h b/include/grub/net.h
|
||||
index 3877451..a7e5b2c 100644
|
||||
--- a/include/grub/net.h
|
||||
+++ b/include/grub/net.h
|
||||
@@ -505,6 +505,15 @@ grub_err_t
|
||||
grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf,
|
||||
const grub_net_network_level_address_t *proto_addr,
|
||||
grub_net_link_level_address_t *hw_addr);
|
||||
+
|
||||
+typedef enum
|
||||
+ {
|
||||
+ DNS_OPTION_IPV4,
|
||||
+ DNS_OPTION_IPV6,
|
||||
+ DNS_OPTION_PREFER_IPV4,
|
||||
+ DNS_OPTION_PREFER_IPV6
|
||||
+ } grub_dns_option_t;
|
||||
+
|
||||
grub_err_t
|
||||
grub_net_dns_lookup (const char *name,
|
||||
const struct grub_net_network_level_address *servers,
|
||||
--
|
||||
1.7.11.4
|
||||
|
174
grub-2.00-cas-reboot-support.patch
Normal file
174
grub-2.00-cas-reboot-support.patch
Normal file
|
@ -0,0 +1,174 @@
|
|||
From be9ee2df83a927d49184026154dd8d5039a8b664 Mon Sep 17 00:00:00 2001
|
||||
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
||||
Date: Thu, 20 Sep 2012 18:07:39 -0300
|
||||
Subject: [PATCH] IBM client architecture (CAS) reboot support
|
||||
|
||||
This is an implementation of IBM client architecture (CAS) reboot for GRUB.
|
||||
|
||||
There are cases where the POWER firmware must reboot in order to support
|
||||
specific features requested by a kernel. The kernel calls
|
||||
ibm,client-architecture-support and it may either return or reboot with the new
|
||||
feature set. eg:
|
||||
|
||||
Calling ibm,client-architecture-support.../
|
||||
Elapsed time since release of system processors: 70959 mins 50 secs
|
||||
Welcome to GRUB!
|
||||
|
||||
Instead of return to the GRUB menu, it will check if the flag for CAS reboot is
|
||||
set. If so, grub will automatically boot the last booted kernel using the same
|
||||
parameters
|
||||
---
|
||||
grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++
|
||||
grub-core/normal/main.c | 19 ++++++++++++
|
||||
grub-core/script/execute.c | 7 +++++
|
||||
include/grub/ieee1275/ieee1275.h | 2 ++
|
||||
4 files changed, 91 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
|
||||
index 40abaa3..c2b1bdf 100644
|
||||
--- a/grub-core/kern/ieee1275/openfw.c
|
||||
+++ b/grub-core/kern/ieee1275/openfw.c
|
||||
@@ -523,3 +523,66 @@ grub_ieee1275_canonicalise_devname (const char *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/* Check if it's a CAS reboot. If so, set the script to be executed. */
|
||||
+int
|
||||
+grub_ieee1275_cas_reboot (char *script)
|
||||
+{
|
||||
+ grub_uint32_t ibm_ca_support_reboot;
|
||||
+ grub_uint32_t ibm_fw_nbr_reboots;
|
||||
+ char property_value[10];
|
||||
+ grub_ssize_t actual;
|
||||
+ grub_ieee1275_ihandle_t options;
|
||||
+
|
||||
+ if (grub_ieee1275_finddevice ("/options", &options) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* Check two properties, one is enough to get cas reboot value */
|
||||
+ ibm_ca_support_reboot = 0;
|
||||
+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
|
||||
+ "ibm,client-architecture-support-reboot",
|
||||
+ &ibm_ca_support_reboot,
|
||||
+ sizeof (ibm_ca_support_reboot),
|
||||
+ &actual) >= 0)
|
||||
+ grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n",
|
||||
+ ibm_ca_support_reboot);
|
||||
+
|
||||
+ ibm_fw_nbr_reboots = 0;
|
||||
+ if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots",
|
||||
+ property_value, sizeof (property_value),
|
||||
+ &actual) >= 0)
|
||||
+ {
|
||||
+ property_value[sizeof (property_value) - 1] = 0;
|
||||
+ ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10);
|
||||
+ grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots);
|
||||
+ }
|
||||
+
|
||||
+ if (ibm_ca_support_reboot || ibm_fw_nbr_reboots)
|
||||
+ {
|
||||
+ if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual))
|
||||
+ {
|
||||
+ if (actual > 1024)
|
||||
+ script = grub_realloc (script, actual + 1);
|
||||
+ grub_ieee1275_get_property (options, "boot-last-label", script, actual,
|
||||
+ &actual);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_ieee1275_set_boot_last_label ("");
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int grub_ieee1275_set_boot_last_label (const char *text)
|
||||
+{
|
||||
+ grub_ieee1275_ihandle_t options;
|
||||
+ grub_ssize_t actual;
|
||||
+
|
||||
+ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text));
|
||||
+ if (! grub_ieee1275_finddevice ("/options", &options) &&
|
||||
+ options != (grub_ieee1275_ihandle_t) -1)
|
||||
+ grub_ieee1275_set_property (options, "boot-last-label", text,
|
||||
+ grub_strlen (text), &actual);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 39bb734..aa0b3e5 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/script_sh.h>
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -296,6 +299,22 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ int boot;
|
||||
+ boot = 0;
|
||||
+ char *script;
|
||||
+ script = grub_malloc (1024);
|
||||
+ if (! grub_ieee1275_cas_reboot (script))
|
||||
+ {
|
||||
+ char *dummy[1] = { NULL };
|
||||
+ if (! grub_script_execute_sourcecode (script, 0, dummy))
|
||||
+ boot = 1;
|
||||
+ }
|
||||
+ grub_free (script);
|
||||
+ if (boot)
|
||||
+ grub_command_execute ("boot", 0, 0);
|
||||
+#endif
|
||||
+
|
||||
/* Ignore any error. */
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
||||
index b5e6eb0..4397540 100644
|
||||
--- a/grub-core/script/execute.c
|
||||
+++ b/grub-core/script/execute.c
|
||||
@@ -27,6 +27,9 @@
|
||||
#include <grub/normal.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#endif
|
||||
|
||||
/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
|
||||
is sizeof (int) * 3, and one extra for a possible -ve sign. */
|
||||
@@ -820,6 +823,10 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args)
|
||||
old_scope = scope;
|
||||
scope = &new_scope;
|
||||
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ grub_ieee1275_set_boot_last_label (source);
|
||||
+#endif
|
||||
+
|
||||
while (source)
|
||||
{
|
||||
char *line;
|
||||
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
|
||||
index 38a75fd..416a544 100644
|
||||
--- a/include/grub/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/ieee1275/ieee1275.h
|
||||
@@ -208,5 +208,7 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook)
|
||||
char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path);
|
||||
char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path);
|
||||
char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path);
|
||||
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
|
||||
+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);
|
||||
|
||||
#endif /* ! GRUB_IEEE1275_HEADER */
|
||||
--
|
||||
1.7.10.4
|
||||
|
28
grub-2.00-fix-http-crash.patch
Normal file
28
grub-2.00-fix-http-crash.patch
Normal file
|
@ -0,0 +1,28 @@
|
|||
From 4414df5e72937b0bb1c4a0bb66cd1132ec2a5720 Mon Sep 17 00:00:00 2001
|
||||
From: Gustavo Luiz Duarte <gustavold@linux.vnet.ibm.com>
|
||||
Date: Tue, 25 Sep 2012 18:40:55 -0400
|
||||
Subject: [PATCH] Fix crash on http
|
||||
|
||||
Don't free file->data on receiving FIN flag since it is used all over without
|
||||
checking. http_close() will be called later to free that memory.
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=860834
|
||||
---
|
||||
grub-core/net/http.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
|
||||
index a7542d1..a5f6f31 100644
|
||||
--- a/grub-core/net/http.c
|
||||
+++ b/grub-core/net/http.c
|
||||
@@ -386,7 +386,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
|
||||
|
||||
data->sock = grub_net_tcp_open (file->device->net->server,
|
||||
HTTP_PORT, http_receive,
|
||||
- http_err, http_err,
|
||||
+ http_err, NULL,
|
||||
file);
|
||||
if (!data->sock)
|
||||
{
|
||||
--
|
||||
1.7.11.4
|
||||
|
332
grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch
Normal file
332
grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch
Normal file
|
@ -0,0 +1,332 @@
|
|||
From 4613775aee8b413ba89bfb7233d49a4288e13390 Mon Sep 17 00:00:00 2001
|
||||
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
||||
Date: Mon, 15 Oct 2012 17:21:01 -0300
|
||||
Subject: [PATCH] for ppc, include all modules in the core image
|
||||
|
||||
This patch implements the solution suggested by Gustavo Luiz Duarte
|
||||
<gustavold@linux.vnet.ibm.com>:
|
||||
|
||||
Adding more modules to be built-in to the grub core ELF is easy. It is a
|
||||
parameter passed by grub2-install to grub2-mkimage. However, there is a downside
|
||||
on adding many modules to the core ELF: they are fully initialized in the grub's
|
||||
first stage. It means you could hit a bug on a module you don't need and end up
|
||||
with a non-bootable system.
|
||||
|
||||
Another downside is that you wouldn't get updates for these built-in modules, as
|
||||
updating the grub2 package only updates the modules residing in /boot and not
|
||||
the grub core ELF in the PReP partition.
|
||||
|
||||
A proper solution would be to add to grub the ability of having built-in
|
||||
*inactive* modules which would be loaded and initialized only on demand (i.e.
|
||||
explicitly calling the insmod command).
|
||||
|
||||
This patch fix this bugzilla:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=866559
|
||||
---
|
||||
grub-core/kern/corecmd.c | 3 ++
|
||||
grub-core/kern/dl.c | 67 ++++++++++++++++++++++++++++++++++++++++---
|
||||
include/grub/dl.h | 1 +
|
||||
include/grub/kernel.h | 1 +
|
||||
include/grub/util/resolve.h | 5 ++++
|
||||
util/grub-mkimage.c | 37 +++++++++++++++++++++++-
|
||||
util/resolve.c | 57 ++++++++++++++++++++++++++++++++++++
|
||||
7 files changed, 166 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
|
||||
index 16c03df..8684139 100644
|
||||
--- a/grub-core/kern/corecmd.c
|
||||
+++ b/grub-core/kern/corecmd.c
|
||||
@@ -100,6 +100,9 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
|
||||
else
|
||||
mod = grub_dl_load (argv[0]);
|
||||
|
||||
+ if (!mod)
|
||||
+ grub_dl_load_core_by_name (argv[0]);
|
||||
+
|
||||
if (mod)
|
||||
grub_dl_ref (mod);
|
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index 5b0aa65..a498682 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/env.h>
|
||||
#include <grub/cache.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/kernel.h>
|
||||
|
||||
/* Platforms where modules are in a readonly area of memory. */
|
||||
#if defined(GRUB_MACHINE_QEMU)
|
||||
@@ -47,6 +48,7 @@
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
grub_dl_t grub_dl_head = 0;
|
||||
+char grub_use_stale_modules = 0;
|
||||
|
||||
grub_err_t
|
||||
grub_dl_add (grub_dl_t mod);
|
||||
@@ -659,6 +661,57 @@ grub_dl_load_core (void *addr, grub_size_t size)
|
||||
return mod;
|
||||
}
|
||||
|
||||
+/* Load a module from core using a symbolic name. */
|
||||
+grub_dl_t
|
||||
+grub_dl_load_core_by_name (const char *name)
|
||||
+{
|
||||
+ struct grub_module_header *header;
|
||||
+ grub_dl_t mod;
|
||||
+ char *module_addr;
|
||||
+
|
||||
+ mod = (grub_dl_t) grub_zalloc (sizeof (*mod));
|
||||
+ if (! mod)
|
||||
+ return 0;
|
||||
+
|
||||
+ grub_use_stale_modules = 1;
|
||||
+
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ /* Not an ELF module, skip. */
|
||||
+ if ((header->type != OBJ_TYPE_ELF) &&
|
||||
+ (header->type != OBJ_TYPE_ELF_STALE))
|
||||
+ continue;
|
||||
+
|
||||
+ module_addr = (char *) header + sizeof (struct grub_module_header);
|
||||
+ grub_dl_resolve_name (mod, (Elf_Ehdr *) module_addr);
|
||||
+
|
||||
+ if (grub_strcmp(name, mod->name) == 0)
|
||||
+ {
|
||||
+ grub_printf ("WARNING: You are using the built-in '%s' module!\n", name);
|
||||
+
|
||||
+ mod = grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
|
||||
+ (header->size - sizeof (struct grub_module_header)));
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ else
|
||||
+ mod = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (! mod)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ {
|
||||
+ if (grub_errno == GRUB_ERR_IO)
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_strcmp (mod->name, name) != 0)
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE, "mismatched names");
|
||||
+
|
||||
+ return mod;
|
||||
+}
|
||||
+
|
||||
/* Load a module from the file FILENAME. */
|
||||
grub_dl_t
|
||||
grub_dl_load_file (const char *filename)
|
||||
@@ -718,13 +771,19 @@ grub_dl_load (const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ /* First, try to load module from the grub directory */
|
||||
filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod",
|
||||
grub_dl_dir, name);
|
||||
- if (! filename)
|
||||
- return 0;
|
||||
+ if (filename)
|
||||
+ {
|
||||
+ mod = grub_dl_load_file (filename);
|
||||
+ grub_free (filename);
|
||||
+ }
|
||||
|
||||
- mod = grub_dl_load_file (filename);
|
||||
- grub_free (filename);
|
||||
+ /* If the module isn't loaded, check if there is a stale module available and
|
||||
+ * use it*/
|
||||
+ if (! mod && grub_use_stale_modules)
|
||||
+ mod = grub_dl_load_core_by_name (name);
|
||||
|
||||
if (! mod)
|
||||
return 0;
|
||||
diff --git a/include/grub/dl.h b/include/grub/dl.h
|
||||
index 3119978..30f12f9 100644
|
||||
--- a/include/grub/dl.h
|
||||
+++ b/include/grub/dl.h
|
||||
@@ -181,6 +181,7 @@ typedef struct grub_dl *grub_dl_t;
|
||||
grub_dl_t grub_dl_load_file (const char *filename);
|
||||
grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
|
||||
grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
|
||||
+grub_dl_t grub_dl_load_core_by_name (const char *name);
|
||||
int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
|
||||
void grub_dl_unload_unneeded (void);
|
||||
int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
|
||||
index eef4c3f..4cd2cb0 100644
|
||||
--- a/include/grub/kernel.h
|
||||
+++ b/include/grub/kernel.h
|
||||
@@ -25,6 +25,7 @@
|
||||
enum
|
||||
{
|
||||
OBJ_TYPE_ELF,
|
||||
+ OBJ_TYPE_ELF_STALE,
|
||||
OBJ_TYPE_MEMDISK,
|
||||
OBJ_TYPE_CONFIG,
|
||||
OBJ_TYPE_PREFIX
|
||||
diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h
|
||||
index f42df32..1d0252c 100644
|
||||
--- a/include/grub/util/resolve.h
|
||||
+++ b/include/grub/util/resolve.h
|
||||
@@ -32,4 +32,9 @@ grub_util_resolve_dependencies (const char *prefix,
|
||||
const char *dep_list_file,
|
||||
char *modules[]);
|
||||
|
||||
+struct grub_util_path_list *
|
||||
+grub_util_create_complementary_module_list (const char *prefix,
|
||||
+ const char *dep_list_file,
|
||||
+ struct grub_util_path_list *path_list);
|
||||
+
|
||||
#endif /* ! GRUB_UTIL_RESOLVE_HEADER */
|
||||
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
||||
index a551bbb..b06f37a 100644
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -711,7 +711,7 @@ generate_image (const char *dir, const char *prefix,
|
||||
size_t prefix_size = 0;
|
||||
char *kernel_path;
|
||||
size_t offset;
|
||||
- struct grub_util_path_list *path_list, *p, *next;
|
||||
+ struct grub_util_path_list *path_list, *path_list_comp = 0, *p, *next;
|
||||
grub_size_t bss_size;
|
||||
grub_uint64_t start_address;
|
||||
void *rel_section = 0;
|
||||
@@ -727,6 +727,10 @@ generate_image (const char *dir, const char *prefix,
|
||||
|
||||
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
|
||||
|
||||
+ if (image_target->id == IMAGE_PPC)
|
||||
+ path_list_comp = grub_util_create_complementary_module_list (dir,
|
||||
+ "moddep.lst", path_list);
|
||||
+
|
||||
kernel_path = grub_util_get_path (dir, "kernel.img");
|
||||
|
||||
if (image_target->voidp_sizeof == 8)
|
||||
@@ -761,6 +765,10 @@ generate_image (const char *dir, const char *prefix,
|
||||
total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
|
||||
+ sizeof (struct grub_module_header));
|
||||
|
||||
+ for (p = path_list_comp; p; p = p->next)
|
||||
+ total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
|
||||
+ + sizeof (struct grub_module_header));
|
||||
+
|
||||
grub_util_info ("the total module size is 0x%llx",
|
||||
(unsigned long long) total_module_size);
|
||||
|
||||
@@ -835,6 +843,25 @@ generate_image (const char *dir, const char *prefix,
|
||||
offset += mod_size;
|
||||
}
|
||||
|
||||
+ for (p = path_list_comp; p; p = p->next)
|
||||
+ {
|
||||
+ struct grub_module_header *header;
|
||||
+ size_t mod_size, orig_size;
|
||||
+
|
||||
+ orig_size = grub_util_get_image_size (p->name);
|
||||
+ mod_size = ALIGN_ADDR (orig_size);
|
||||
+
|
||||
+ header = (struct grub_module_header *) (kernel_img + offset);
|
||||
+ memset (header, 0, sizeof (struct grub_module_header));
|
||||
+ header->type = grub_host_to_target32 (OBJ_TYPE_ELF_STALE);
|
||||
+ header->size = grub_host_to_target32 (mod_size + sizeof (*header));
|
||||
+ offset += sizeof (*header);
|
||||
+ memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);
|
||||
+
|
||||
+ grub_util_load_image (p->name, kernel_img + offset);
|
||||
+ offset += mod_size;
|
||||
+ }
|
||||
+
|
||||
if (memdisk_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
@@ -1639,6 +1666,14 @@ generate_image (const char *dir, const char *prefix,
|
||||
free (path_list);
|
||||
path_list = next;
|
||||
}
|
||||
+
|
||||
+ while (path_list_comp)
|
||||
+ {
|
||||
+ next = path_list_comp->next;
|
||||
+ free ((void *) path_list_comp->name);
|
||||
+ free (path_list_comp);
|
||||
+ path_list_comp = next;
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
diff --git a/util/resolve.c b/util/resolve.c
|
||||
index 1af24e6..997db99 100644
|
||||
--- a/util/resolve.c
|
||||
+++ b/util/resolve.c
|
||||
@@ -271,3 +271,60 @@ grub_util_resolve_dependencies (const char *prefix,
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
+
|
||||
+struct grub_util_path_list *
|
||||
+grub_util_create_complementary_module_list (const char *prefix,
|
||||
+ const char *dep_list_file,
|
||||
+ struct grub_util_path_list *path_list)
|
||||
+{
|
||||
+ char *path;
|
||||
+ FILE *fp;
|
||||
+ struct grub_util_path_list *path_list_comp = 0;
|
||||
+ struct grub_util_path_list *new_path;
|
||||
+ char skip;
|
||||
+
|
||||
+ path = grub_util_get_path (prefix, dep_list_file);
|
||||
+ fp = fopen (path, "r");
|
||||
+ if (! fp)
|
||||
+ grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
|
||||
+
|
||||
+ while (fgets (buf, sizeof (buf), fp))
|
||||
+ {
|
||||
+ char *p;
|
||||
+ struct grub_util_path_list *pl;
|
||||
+
|
||||
+ skip = 0;
|
||||
+
|
||||
+ /* Get the target name. */
|
||||
+ p = strchr (buf, ':');
|
||||
+ if (! p)
|
||||
+ grub_util_error (_("invalid line format: %s"), buf);
|
||||
+
|
||||
+ *p++ = '\0';
|
||||
+
|
||||
+ /* kernel is not a module */
|
||||
+ if (strcmp(buf, "kernel") == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Check if the module is already in the core. */
|
||||
+ for (pl = path_list; pl; pl = pl->next)
|
||||
+ {
|
||||
+ if (strcmp(buf, get_module_name(pl->name)) == 0)
|
||||
+ {
|
||||
+ skip = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (skip)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Add the new path. */
|
||||
+ new_path = (struct grub_util_path_list *) xmalloc (sizeof (*new_path));
|
||||
+ new_path->name = get_module_path (prefix, buf);
|
||||
+ new_path->next = path_list_comp;
|
||||
+ path_list_comp = new_path;
|
||||
+ }
|
||||
+
|
||||
+ return path_list_comp;
|
||||
+}
|
||||
--
|
||||
1.7.10.4
|
||||
|
18
grub2.spec
18
grub2.spec
|
@ -41,7 +41,7 @@
|
|||
Name: grub2
|
||||
Epoch: 1
|
||||
Version: 2.00
|
||||
Release: 9%{?dist}
|
||||
Release: 10%{?dist}
|
||||
Summary: Bootloader with support for Linux, Multiboot and more
|
||||
|
||||
Group: System Environment/Base
|
||||
|
@ -68,6 +68,10 @@ Patch24: grub-2.00-no-insmod-on-sb.patch
|
|||
Patch25: grub-2.00-efidisk-ahci-workaround.patch
|
||||
Patch26: grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch
|
||||
Patch27: grub-2.00-Handle-escapes-in-labels.patch
|
||||
Patch28: grub-2.00-fix-http-crash.patch
|
||||
Patch29: grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch
|
||||
Patch30: grub-2.00-cas-reboot-support.patch
|
||||
Patch31: grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
|
@ -86,7 +90,7 @@ BuildRequires: freetype-devel gettext-devel git
|
|||
BuildRequires: texinfo
|
||||
BuildRequires: dejavu-sans-fonts
|
||||
%ifarch %{efiarchs}
|
||||
BuildRequires: pesign >= 0.10-3
|
||||
BuildRequires: pesign >= 0.99-8
|
||||
%endif
|
||||
|
||||
Requires: gettext os-prober which file system-logos
|
||||
|
@ -421,6 +425,16 @@ fi
|
|||
%doc grub-%{tarversion}/themes/starfield/COPYING.CC-BY-SA-3.0
|
||||
|
||||
%changelog
|
||||
* Mon Oct 22 2012 Peter Jones <pjones@redhat.com> - 2.00-10
|
||||
- Rebuild with newer pesign so we'll get signed with the final signing keys.
|
||||
|
||||
* Thu Oct 18 2012 Peter Jones <pjones@redhat.com> - 2.00-10
|
||||
- Various PPC fixes.
|
||||
- Fix crash fetching from http (gustavold, #860834)
|
||||
- Issue separate dns queries for ipv4 and ipv6 (gustavold, #860829)
|
||||
- Support IBM CAS reboot (pfsmorigo, #859223)
|
||||
- Include all modules in the core image on ppc (pfsmorigo, #866559)
|
||||
|
||||
* Mon Oct 01 2012 Peter Jones <pjones@redhat.com> - 1:2.00-9
|
||||
- Work around bug with using "\x20" in linux command line.
|
||||
Related: rhbz#855849
|
||||
|
|
Loading…
Reference in a new issue