Accepting request 32673 from devel:openSUSE:Factory

Copy from devel:openSUSE:Factory/grub2 based on submit request 32673 from user a_jaeger

OBS-URL: https://build.opensuse.org/request/show/32673
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=1
This commit is contained in:
OBS User autobuild 2010-02-18 14:10:48 +00:00 committed by Git OBS Bridge
parent 631218dea1
commit cc490a048e
100 changed files with 209 additions and 16119 deletions

View File

@ -1,37 +0,0 @@
From 0155e49166494624e9fb6ef113ed2c16d4accbb3 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Fri, 29 Jul 2016 17:41:27 +0800
Subject: [PATCH 1/8] misc: fix invalid character recongition in strto*l
From: Aaron Miller <aaronmiller@fb.com>
Would previously allow digits larger than the base and didn't check that
subtracting the difference from 0-9 to lowercase letters for characters
larger than 9 didn't result in a value lower than 9, which allowed the
parses: ` = 9, _ = 8, ^ = 7, ] = 6, \ = 5, and [ = 4
---
grub-core/kern/misc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index d1a54df..3a14d67 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -394,9 +394,13 @@ grub_strtoull (const char *str, char **end, int base)
if (digit > 9)
{
digit += '0' - 'a' + 10;
- if (digit >= (unsigned long) base)
+ /* digit <= 9 check is needed to keep chars larger than
+ '9' but less than 'a' from being read as numbers */
+ if (digit >= (unsigned long) base || digit <= 9)
break;
}
+ if (digit >= (unsigned long) base)
+ break;
found = 1;
--
2.6.6

View File

@ -1,360 +0,0 @@
From d17c80ca8de35f8cb06175965d428bdabbda3c19 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
Date: Mon, 30 Jun 2014 10:37:08 -0300
Subject: [PATCH 2/2] Add Virtual LAN support.
This patch adds support for virtual LAN (VLAN) tagging. VLAN tagging allows
multiple VLANs in a bridged network to share the same physical network link
but maintain isolation:
http://en.wikipedia.org/wiki/IEEE_802.1Q
---
ChangeLog | 17 ++++++++++++
grub-core/net/arp.c | 10 +++++--
grub-core/net/drivers/ieee1275/ofnet.c | 20 +++++++++++++-
grub-core/net/ethernet.c | 49 ++++++++++++++++++++++++++++++----
grub-core/net/ip.c | 31 ++++++++++++++-------
include/grub/net.h | 9 +++++++
include/grub/net/arp.h | 5 ++--
include/grub/net/ip.h | 3 ++-
8 files changed, 124 insertions(+), 20 deletions(-)
Index: grub-2.02~beta3/grub-core/net/arp.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/net/arp.c 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/grub-core/net/arp.c 2016-02-28 19:23:27.056877621 +0300
@@ -111,8 +111,8 @@
}
grub_err_t
-grub_net_arp_receive (struct grub_net_buff *nb,
- struct grub_net_card *card)
+grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card,
+ grub_uint16_t vlantag_vid)
{
struct arppkt *arp_packet = (struct arppkt *) nb->data;
grub_net_network_level_address_t sender_addr, target_addr;
@@ -138,6 +138,12 @@
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
{
+ /* Check vlantag id */
+ if (inf->card == card &&
+ ((inf->vlantag.set && vlantag_vid != inf->vlantag.vid) ||
+ (!inf->vlantag.set && vlantag_vid != 0)))
+ continue;
+
/* 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))
Index: grub-2.02~beta3/grub-core/net/drivers/ieee1275/ofnet.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/net/drivers/ieee1275/ofnet.c 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/grub-core/net/drivers/ieee1275/ofnet.c 2016-02-28 19:24:47.004878566 +0300
@@ -147,11 +147,11 @@
char *comma_char = 0;
char *equal_char = 0;
grub_size_t field_counter = 0;
-
grub_net_network_level_address_t client_addr, gateway_addr, subnet_mask;
grub_net_link_level_address_t hw_addr;
grub_net_interface_flags_t flags = 0;
struct grub_net_network_level_interface *inter = NULL;
+ grub_uint32_t vlantag = 0;
hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
@@ -169,6 +169,18 @@
*equal_char = 0;
grub_env_set_net_property ((*card)->name, args, equal_char + 1,
grub_strlen(equal_char + 1));
+
+ if ((grub_strcmp (args, "vtag") == 0) &&
+ (grub_strlen (equal_char + 1) > 4))
+ {
+ vlantag = grub_strtoul (equal_char + 1, 0, 16) & 0xffff;
+ if (grub_errno == GRUB_ERR_BAD_NUMBER)
+ {
+ vlantag = 0;
+ grub_errno = GRUB_ERR_NONE;
+ }
+ }
+
*equal_char = '=';
}
else
@@ -207,6 +219,12 @@
hw_addr.mac, sizeof(hw_addr.mac), 0);
inter = grub_net_add_addr ((*card)->name, *card, &client_addr, &hw_addr,
flags);
+ if (vlantag > 0)
+ {
+ inter->vlantag.set = 1;
+ inter->vlantag.vid = vlantag & 0xfff;
+ }
+
grub_net_add_ipv4_local (inter,
__builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4)));
}
Index: grub-2.02~beta3/grub-core/net/ethernet.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/net/ethernet.c 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/grub-core/net/ethernet.c 2016-02-28 19:23:27.056877621 +0300
@@ -18,6 +18,7 @@
#include <grub/misc.h>
#include <grub/mm.h>
+#include <grub/env.h>
#include <grub/net/ethernet.h>
#include <grub/net/ip.h>
#include <grub/net/arp.h>
@@ -56,10 +57,16 @@
{
struct etherhdr *eth;
grub_err_t err;
+ grub_uint8_t etherhdr_size;
- COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE);
+ etherhdr_size = sizeof (*eth);
+ COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE);
- err = grub_netbuff_push (nb, sizeof (*eth));
+ /* Increase ethernet header in case of vlantag */
+ if (inf->vlantag.set)
+ etherhdr_size += 4;
+
+ err = grub_netbuff_push (nb, etherhdr_size);
if (err)
return err;
eth = (struct etherhdr *) nb->data;
@@ -76,6 +83,21 @@
return err;
inf->card->opened = 1;
}
+
+ /* Check and add a vlan-tag if needed. */
+ if (inf->vlantag.set)
+ {
+ grub_uint32_t vlantag;
+ vlantag = grub_cpu_to_be32 ((VLANTAG_IDENTIFIER << 16) | inf->vlantag.vid);
+
+ /* 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, 4);
+ }
+
return inf->card->driver->send (inf->card, nb);
}
@@ -90,10 +112,26 @@
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_uint16_t vlantag_vid = 0;
+
+ /* 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) ==
+ grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER))
+ {
+ vlantag_vid = grub_be_to_cpu16 (grub_get_unaligned16 (nb->data +
+ etherhdr_size)) & 0x1fff;
+ 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 = (struct etherhdr *) nb->data;
type = grub_be_to_cpu16 (eth->type);
- err = grub_netbuff_pull (nb, sizeof (*eth));
+ err = grub_netbuff_pull (nb, etherhdr_size);
if (err)
return err;
@@ -121,13 +159,14 @@
{
/* ARP packet. */
case GRUB_NET_ETHERTYPE_ARP:
- grub_net_arp_receive (nb, card);
+ grub_net_arp_receive (nb, card, vlantag_vid);
grub_netbuff_free (nb);
return GRUB_ERR_NONE;
/* IP packet. */
case GRUB_NET_ETHERTYPE_IP:
case GRUB_NET_ETHERTYPE_IP6:
- return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress);
+ return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress,
+ vlantag_vid);
}
grub_netbuff_free (nb);
return GRUB_ERR_NONE;
Index: grub-2.02~beta3/grub-core/net/ip.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/net/ip.c 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/grub-core/net/ip.c 2016-02-28 19:23:27.056877621 +0300
@@ -228,12 +228,13 @@
grub_net_ip_protocol_t proto,
const grub_net_network_level_address_t *source,
const grub_net_network_level_address_t *dest,
+ grub_uint16_t vlantag_vid,
grub_uint8_t ttl)
{
struct grub_net_network_level_interface *inf = NULL;
grub_err_t err;
int multicast = 0;
-
+
/* DHCP needs special treatment since we don't know IP yet. */
{
struct udphdr *udph;
@@ -293,6 +294,13 @@
&& grub_net_addr_cmp (&inf->address, dest) == 0
&& grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0)
break;
+
+ /* Check vlantag id */
+ if (inf->card == card &&
+ ((inf->vlantag.set && vlantag_vid != inf->vlantag.vid) ||
+ (!inf->vlantag.set && vlantag_vid != 0)))
+ continue;
+
/* Solicited node multicast. */
if (inf->card == card
&& inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
@@ -381,7 +389,8 @@
grub_net_recv_ip4_packets (struct grub_net_buff *nb,
struct grub_net_card *card,
const grub_net_link_level_address_t *hwaddress,
- const grub_net_link_level_address_t *src_hwaddress)
+ const grub_net_link_level_address_t *src_hwaddress,
+ grub_uint16_t vlantag_vid)
{
struct iphdr *iph = (struct iphdr *) nb->data;
grub_err_t err;
@@ -456,7 +465,7 @@
dest.ipv4 = iph->dest;
return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol,
- &source, &dest, iph->ttl);
+ &source, &dest, vlantag_vid, iph->ttl);
}
for (prev = &reassembles, rsm = *prev; rsm; prev = &rsm->next, rsm = *prev)
@@ -592,7 +601,7 @@
dest.ipv4 = dst;
return handle_dgram (ret, card, src_hwaddress,
- hwaddress, proto, &source, &dest,
+ hwaddress, proto, &source, &dest, vlantag_vid,
ttl);
}
}
@@ -650,7 +659,8 @@
grub_net_recv_ip6_packets (struct grub_net_buff *nb,
struct grub_net_card *card,
const grub_net_link_level_address_t *hwaddress,
- const grub_net_link_level_address_t *src_hwaddress)
+ const grub_net_link_level_address_t *src_hwaddress,
+ grub_uint16_t vlantag_vid)
{
struct ip6hdr *iph = (struct ip6hdr *) nb->data;
grub_err_t err;
@@ -701,21 +711,24 @@
grub_memcpy (dest.ipv6, &iph->dest, sizeof (dest.ipv6));
return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol,
- &source, &dest, iph->ttl);
+ &source, &dest, vlantag_vid, iph->ttl);
}
grub_err_t
grub_net_recv_ip_packets (struct grub_net_buff *nb,
struct grub_net_card *card,
const grub_net_link_level_address_t *hwaddress,
- const grub_net_link_level_address_t *src_hwaddress)
+ const grub_net_link_level_address_t *src_hwaddress,
+ grub_uint16_t vlantag_vid)
{
struct iphdr *iph = (struct iphdr *) nb->data;
if ((iph->verhdrlen >> 4) == 4)
- return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress);
+ return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress,
+ vlantag_vid);
if ((iph->verhdrlen >> 4) == 6)
- return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress);
+ return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress,
+ vlantag_vid);
grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4));
grub_netbuff_free (nb);
return GRUB_ERR_NONE;
Index: grub-2.02~beta3/include/grub/net.h
===================================================================
--- grub-2.02~beta3.orig/include/grub/net.h 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/include/grub/net.h 2016-02-28 19:23:27.056877621 +0300
@@ -280,6 +280,12 @@
extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);
+struct grub_net_vlantag
+{
+ grub_uint8_t set;
+ grub_uint16_t vid;
+};
+
struct grub_net_network_level_interface
{
struct grub_net_network_level_interface *next;
@@ -291,6 +297,7 @@
grub_net_interface_flags_t flags;
struct grub_net_bootp_packet *dhcp_ack;
grub_size_t dhcp_acklen;
+ struct grub_net_vlantag vlantag;
void *data;
};
@@ -561,4 +568,6 @@
#define GRUB_NET_INTERVAL 400
#define GRUB_NET_INTERVAL_ADDITION 20
+#define VLANTAG_IDENTIFIER 0x8100
+
#endif /* ! GRUB_NET_HEADER */
Index: grub-2.02~beta3/include/grub/net/arp.h
===================================================================
--- grub-2.02~beta3.orig/include/grub/net/arp.h 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/include/grub/net/arp.h 2016-02-28 19:23:27.056877621 +0300
@@ -22,10 +22,11 @@
#include <grub/net.h>
extern grub_err_t grub_net_arp_receive (struct grub_net_buff *nb,
- struct grub_net_card *card);
+ struct grub_net_card *card,
+ grub_uint16_t vlantag_vid);
grub_err_t
grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
- const grub_net_network_level_address_t *proto_addr);
+ const grub_net_network_level_address_t *proto_addr);
#endif
Index: grub-2.02~beta3/include/grub/net/ip.h
===================================================================
--- grub-2.02~beta3.orig/include/grub/net/ip.h 2016-02-28 19:23:27.060877621 +0300
+++ grub-2.02~beta3/include/grub/net/ip.h 2016-02-28 19:23:27.056877621 +0300
@@ -48,7 +48,8 @@
grub_net_recv_ip_packets (struct grub_net_buff *nb,
struct grub_net_card *card,
const grub_net_link_level_address_t *hwaddress,
- const grub_net_link_level_address_t *src_hwaddress);
+ const grub_net_link_level_address_t *src_hwaddress,
+ grub_uint16_t vlantag_vid);
grub_err_t
grub_net_send_ip_packet (struct grub_net_network_level_interface *inf,

View File

@ -1,250 +0,0 @@
From 4a00be0176a459fa6e199f2709eabbe8dc0d7979 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Fri, 29 Jul 2016 17:41:38 +0800
Subject: [PATCH 2/8] net: read bracketed ipv6 addrs and port numbers
From: Aaron Miller <aaronmiller@fb.com>
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
---
grub-core/net/http.c | 21 ++++++++++---
grub-core/net/net.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++---
grub-core/net/tftp.c | 6 +++-
include/grub/net.h | 1 +
4 files changed, 104 insertions(+), 10 deletions(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index 5aa4ad3..f182d7b 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -312,12 +312,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 +358,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 +367,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 +401,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, http_err,
file);
if (!data->sock)
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 10773fc..5cc0d2f 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -437,6 +437,12 @@ 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;
@@ -475,6 +481,9 @@ 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;
@@ -1260,8 +1269,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)
{
@@ -1299,6 +1310,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)
@@ -1308,14 +1385,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;
}
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
index 7d90bf6..a0817a0 100644
--- a/grub-core/net/tftp.c
+++ b/grub-core/net/tftp.c
@@ -314,6 +314,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)
@@ -382,13 +383,16 @@ tftp_open (struct grub_file *file, const char *filename)
err = grub_net_resolve_address (file->device->net->server, &addr);
if (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);
destroy_pq (data);
grub_free (data);
return err;
}
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 2192fa1..ccc169c 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -270,6 +270,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;
--
2.6.6

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
From ca482c7c1efe5faf792bf0912a116ea8e0642e24 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Wed, 15 Apr 2015 14:48:30 +0800
Subject: [PATCH 4/8] 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 | 24 +++++++++++++----
include/grub/efi/api.h | 55 +++++++++++++++++++++++++++++++++++++-
2 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
index 5388f95..fc90415 100644
--- a/grub-core/net/drivers/efi/efinet.c
+++ b/grub-core/net/drivers/efi/efinet.c
@@ -378,11 +378,25 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
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_configure_by_dhcpv6_reply (card->name, card, 0,
+ (struct grub_net_dhcp6_packet *)
+ &pxe_mode->dhcp_ack,
+ sizeof (pxe_mode->dhcp_ack),
+ 1, device, path);
+ if (grub_errno)
+ grub_print_error ();
+ }
+ else
+ {
+ 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);
+ }
return;
}
}
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index c7c9f0e..92f9b5a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1452,14 +1452,67 @@ typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output
typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
+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_uint8_t filters;
+ grub_uint8_t ip_cnt;
+ grub_uint16_t reserved;
+ grub_efi_pxe_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_uint8_t unused[52];
+ grub_uint8_t started;
+ grub_uint8_t ipv6_available;
+ grub_uint8_t ipv6_supported;
+ grub_uint8_t using_ipv6;
+ grub_uint8_t unused[16];
+ grub_efi_pxe_ip_address_t station_ip;
+ grub_efi_pxe_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_uint32_t arp_cache_entries;
+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES];
+ grub_uint32_t route_table_entries;
+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES];
} grub_efi_pxe_mode_t;
typedef struct grub_efi_pxe
--
2.6.6

View File

@ -1,51 +0,0 @@
From 2c997c8c058b41d3a59a81f2bf654288b7cdf8f2 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Tue, 5 May 2015 14:19:24 +0800
Subject: [PATCH 5/8] 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 82f6fa4..60b4aa0 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5173,6 +5173,7 @@ See @uref{http://wiki.xen.org/wiki/XSM} for more detail.
* net_add_dns:: Add a DNS server
* net_add_route:: Add routing entry
* net_bootp:: Perform a bootp 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
@@ -5254,6 +5255,22 @@ Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_extensionspath}
@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_del_addr
@subsection net_del_addr
--
2.6.6

View File

@ -1,130 +0,0 @@
From 8191aae462f8b755972a0a801f4adbdd6ecaa66c Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 14 Jul 2016 18:45:14 +0800
Subject: [PATCH 6/8] 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 | 67 +++++++++++++++++++++++++++++++++++++++++++++++++--
include/grub/net.h | 1 +
2 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 81173b4..04f9f3d 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -207,6 +207,11 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
taglength);
break;
+ case GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER:
+ grub_env_set_net_property (name, "vendor_class_identifier", (const char *) ptr,
+ taglength);
+ break;
+
case GRUB_NET_BOOTP_EXTENSIONS_PATH:
grub_env_set_net_property (name, "extensionspath", (const char *) ptr,
taglength);
@@ -281,6 +286,66 @@ grub_net_configure_by_dhcp_ack (const char *name,
}
#endif
+ if (size > OFFSET_OF (vendor, bp))
+ {
+ char *cidvar;
+ const char *cid;
+
+ parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
+ cidvar = grub_xasprintf ("net_%s_%s", name, "vendor_class_identifier");
+ cid = grub_env_get (cidvar);
+ grub_free (cidvar);
+
+ if (cid && grub_strcmp (cid, "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;
+ }
+ }
+
if (size > OFFSET_OF (boot_file, bp))
grub_env_set_net_property (name, "boot_file", bp->boot_file,
sizeof (bp->boot_file));
@@ -342,8 +407,6 @@ grub_net_configure_by_dhcp_ack (const char *name,
**path = 0;
}
}
- if (size > OFFSET_OF (vendor, bp))
- parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
grub_net_add_ipv4_local (inter, mask);
inter->dhcp_ack = grub_malloc (size);
diff --git a/include/grub/net.h b/include/grub/net.h
index 38a3973..e4bf678 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -517,6 +517,7 @@ enum
GRUB_NET_BOOTP_DOMAIN = 0x0f,
GRUB_NET_BOOTP_ROOT_PATH = 0x11,
GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
+ GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 0x3C,
GRUB_NET_BOOTP_END = 0xff
};
--
2.6.6

View File

@ -1,389 +0,0 @@
From 369df8e3006000a4acacc674f5882d8729781811 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Sun, 10 Jul 2016 23:46:31 +0800
Subject: [PATCH 7/8] 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 | 268 +++++++++++++++++++++++++++++++++++--
include/grub/efi/api.h | 11 ++
2 files changed, 270 insertions(+), 9 deletions(-)
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
index fc90415..2d3b00f 100644
--- a/grub-core/net/drivers/efi/efinet.c
+++ b/grub-core/net/drivers/efi/efinet.c
@@ -23,6 +23,7 @@
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/i18n.h>
+#include <grub/net/netbuff.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -324,6 +325,221 @@ 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);
+ 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)
+ 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)
@@ -340,6 +556,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;
+ grub_uint8_t *packet_buf;
+ grub_size_t packet_bufsz ;
+ int ipv6;
+ struct grub_net_buff *nb = NULL;
+
if (card->driver != &efidriver)
continue;
cdp = grub_efi_get_device_path (card->efi_handle);
@@ -359,11 +580,21 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **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))
+ && 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;
@@ -375,16 +606,31 @@ 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;
- pxe_mode = pxe->mode;
+ 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;
+ }
- if (pxe_mode->using_ipv6)
+ if (ipv6)
{
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 ();
@@ -393,10 +639,14 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
{
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);
}
+
+ if (nb)
+ grub_netbuff_free (nb);
+
return;
}
}
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 92f9b5a..d5a1256 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -825,6 +825,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;
@@ -879,6 +881,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. */
--
2.6.6

View File

@ -1,340 +0,0 @@
From 0c7ae6d7527d08e54a6eeebddb6c5c697c4b37d2 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 14 Jul 2016 17:48:45 +0800
Subject: [PATCH 8/8] 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 | 76 +++++++++++++++++
2 files changed, 239 insertions(+)
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
index 2d3b00f..82a28fb 100644
--- a/grub-core/net/drivers/efi/efinet.c
+++ b/grub-core/net/drivers/efi/efinet.c
@@ -30,6 +30,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,
@@ -325,6 +327,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)
{
@@ -377,6 +498,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);
@@ -438,6 +561,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)
@@ -470,6 +612,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));
@@ -533,6 +677,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 d5a1256..99ba068 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -334,6 +334,16 @@
{ 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
}
+#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
{
grub_uint32_t signature;
@@ -1749,6 +1759,72 @@ struct grub_efi_block_io
};
typedef struct grub_efi_block_io grub_efi_block_io_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__)
--
2.6.6

View File

@ -1,59 +0,0 @@
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2011 Michal Ambroz <rebus@seznam.cz>
# Adapted for openSUSE by Andrey Borzenkov <arvidjaar@gmail.com>
#
# 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.
#
# 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 the script. If not, see <http://www.gnu.org/licenses/>.
. /usr/share/grub2/grub-mkconfig_lib
export TEXTDOMAIN=grub2
export TEXTDOMAINDIR=/usr/share/locale
# memset86+ requires the x86 real mode
# which is not available with UEFI booting.
if [ -d /sys/firmware/efi ]; then
exit 0
fi
CLASS="--class memtest86 --class gnu --class tools"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=Memtest
else
OS="${GRUB_DISTRIBUTOR} Memtest"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}"
fi
memtest=/boot/memtest.bin
if grub_file_is_not_garbage "$memtest" ; then
gettext_printf "Found memtest image: %s\n" "$memtest" >&2
basename=`basename $memtest`
dirname=`dirname $memtest`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE_BOOT}")"
printf "menuentry '%s' %s \$menuentry_id_option '%s' {\n" "${OS}" "${CLASS}" "memtest-$boot_device_id"
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
printf '%s\n' "${prepare_boot_cache}"
message="$(gettext_printf "Loading memtest ...\n" | grub_quote)"
cat << EOF
echo '$message'
linux16 ${rel_dirname}/${basename}
}
EOF
fi

View File

@ -1,10 +0,0 @@
#! /bin/sh
set -e
if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] &&
[ "x${GRUB_FS}" = "xbtrfs" ] ; then
cat <<EOF
if [ -f "/.snapshots/grub-snapshot.cfg" ]; then
source "/.snapshots/grub-snapshot.cfg"
fi
EOF
fi

View File

@ -1,6 +0,0 @@
Make sure the patches you add contain tags similar to patches in the kernel
RPM. This means, it should contain From, Subject, Patch-mainline tags and also
a description of the problem, i.e. what the patch is for.
Also, if it is not a SUSE/openSUSE-specific patch (unlikely is), post the patch to
upstream too.

View File

@ -1,59 +0,0 @@
[Disclaimer: I do not know enough (by far) about the inner workings
and secrets of these printer-consoles, so please correct me/send advice,
if there are better solutions!]
On 3215/327x things are dramatically different from everywhere else.
You'll have to live with some severe limitations:
0. Interactivity is quite limited. You'll need to "blindly" type,
most of the time, to see the effect only on "submission" ([Enter]).
In edit and shell mode it's sometimes useful to insert underlines
just to see, where the curser (AKA "point") is. (BTW, 3270 is _much_
better at displaying/refreshing grub2 screens than 3215.)
1. No cursor-movement-, alt-, meta-, and control-keys (like [ESC]).
2. To work around the lack of control-keys, the "[^][C]-sends-interrupt"-
trick is extended to translate sequences of caret followed by character
to the respective control-character. In the following this sequence
of two keystrokes is referred to as '^c' instead of that somewhat balky
[^][C]. Thus an [ESC] keypress can be generated with '^[' ("caret"
followed by "opening square bracket").
3. If a caret itself is needed, send one on it's own (i.e. a solitary [^]
followed by [Enter] -- or use '^^'.
4. No '[Enter]', because it can't be avoided on *any* input.
5. If you still need one to arrive at the application, you may either
press '[Enter]' *twice* (one empty line, sort of) or add '^j' to your
input. In menu mode '^f' works as well (see below). But using "empty
lines" does now work very reliably, so explicit control sequences
are to be preferred. This has the additional advantage, that combined
sequences can be sent, e.g. to exit from 'grub2-emu' without doing
anything, you can simply type 'cexit^j' and submit that with [Enter].
Common Substitutes:
'^j'` => [Enter] "engage"
'^[' => [ESC] "abort" / return to previous "state"
'^i' => [TAB] try completion (in edit & shell mode)
Available Keys in Menu Mode:
'^a' first entry '^e' last entry
'^p' previous entry '^n' next entry
'^g' previous page '^c' next page
'^f' boot selected entry/enter sub-menu (same as '^j')
'e' edit selected entry 'c' enter grub-shell
Available Keys in Edit Mode:
'^p' previous line '^n' next line
'^b' backward char '^f' forward char
'^a' beginning of line '^e' end of line
'^h' backspace '^d' delete
'^k' kill (to end of) line '^y' yank
'^o' open line '^l' refresh screen
'^x' boot entry '^c' enter grub-shell
Availble Keys on Command Line Mode:
'^p' previous command '^n' next command (from history)
'^a' beginning of line '^e' end of line
'^b' backward char '^f' forward char
'^h' backspace '^d' delete
'^k' kill (to end of) line '^u' discard line
'^y' yank

48
README.openSUSE Normal file
View File

@ -0,0 +1,48 @@
Using GNU GRUB 2 in openSUSE
============================
Though GRUB 2 provides various feature enhancements over previous GRUB
version (referred to as "GRUB", or "GRUB Legacy"), it did not reach its
stability and feature completness yet, and thus is not ready to replace
it for the whole user base. This package is primarily intended to
encourage testing and accelerate distribution integration.
It is generally safe to install the package. It is able to co-exist with
existing GRUB installation and adds itself to the GRUB menu upon
installation, so you'll able to select GRUB 2 from GRUB menu during
the boot.
Utilities
---------
The GRUB 2 utilities are prefixed (or postfixed) with 'grub2':
grub2-editenv
grub2-mkimage
grub2-mkelfimage
grub2-mkrescue
grub2-emu
grub2-install
grub2-mkdevicemap
grub2-probe
grub2-setup
update-grub2
Documentation
-------------
The GRUB 2 lacks documentation. While you are encouraged to contribute
the documentation, you can use the GRUB 2 Wiki [1] as primary source of
information pertaining to this development snapshot.
[1] http://grub.enbug.org/
If you intend to install grub2 as your primary boot loader refer to
the GRUB 2 Wiki for information on how to set it up.
Support channels
----------------
If you find a bug in this package, report them to the openSUSE Bugzilla [2].
[2] http://bugzilla.novell.com/

View File

@ -1,39 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIG5TCCBM2gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBpjEtMCsGA1UEAwwkU1VT
RSBMaW51eCBFbnRlcnByaXNlIFNlY3VyZSBCb290IENBMQswCQYDVQQGEwJERTES
MBAGA1UEBwwJTnVyZW1iZXJnMSEwHwYDVQQKDBhTVVNFIExpbnV4IFByb2R1Y3Rz
IEdtYkgxEzARBgNVBAsMCkJ1aWxkIFRlYW0xHDAaBgkqhkiG9w0BCQEWDWJ1aWxk
QHN1c2UuZGUwHhcNMTMwMTIyMTQyMDA4WhcNMzQxMjE4MTQyMDA4WjCBpjEtMCsG
A1UEAwwkU1VTRSBMaW51eCBFbnRlcnByaXNlIFNlY3VyZSBCb290IENBMQswCQYD
VQQGEwJERTESMBAGA1UEBwwJTnVyZW1iZXJnMSEwHwYDVQQKDBhTVVNFIExpbnV4
IFByb2R1Y3RzIEdtYkgxEzARBgNVBAsMCkJ1aWxkIFRlYW0xHDAaBgkqhkiG9w0B
CQEWDWJ1aWxkQHN1c2UuZGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQCrLYL1Uq02iIgro6x6PFESFDtUKU7xO/bJanI7+AQAroowFuLBI67BBSmoq3hR
QnH3OtQusGV8y+wvjaaunppvWMfjViZ88zssj5fKXrDr5U6BB566DJgHreWaEs2d
FD13XpKRr3Nk9zdjAJu5YsR7hI1NMXsnj1X8w71OY9HLjv+Kq9917PJwZQjOGnAJ
BQTi0ogHuLiwDqMKgg5rrYD4cJDPzoLEmEXnwHDIOSiWdD0bCzhN6GQDKldIxQ2O
d/mjUgzB+dWslIb+bUKaoJgDtyPV20W74t7Y2uwoaEVr9QkPoM3tOPttf4qsWo8B
J1TgeoF01ZeKcvSyvOXCKbfAN9sqURK2ZUTNThqZ//VPQmJP6fByrMJsbvTOSsQt
HI+fFPrg1DC2KT8SzuGtWDRscHZ7MofvUKEQolVgkGwp8u68t/RAAwDpUdqIajzi
yfp9qSDD+9uMeyiLa4rrAr2ATGohNBa0qha95slgvSepXbYKuHG5b4fWMsG7z4Uc
dqE2vK8cQma1nsAeQBaq2/89294TOHEzKyspesfCBCnKQ3q+l9xelYRdvapj1CH/
cfUZf2/6X3VHN1P88RfRrPubswmrcOCEBT41upa2WKRDJ1GS6YhL6LJnrZSTjfe+
KsfNVS1D+KqSKiK0hfk6YK6O88mMGeAKQs3Ap8WthBLf0QIDAQABo4IBGjCCARYw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPU1Az5OFOQJLHPxaEt7f6LF+dV8w
gdMGA1UdIwSByzCByIAUPU1Az5OFOQJLHPxaEt7f6LF+dV+hgaykgakwgaYxLTAr
BgNVBAMMJFNVU0UgTGludXggRW50ZXJwcmlzZSBTZWN1cmUgQm9vdCBDQTELMAkG
A1UEBhMCREUxEjAQBgNVBAcMCU51cmVtYmVyZzEhMB8GA1UECgwYU1VTRSBMaW51
eCBQcm9kdWN0cyBHbWJIMRMwEQYDVQQLDApCdWlsZCBUZWFtMRwwGgYJKoZIhvcN
AQkBFg1idWlsZEBzdXNlLmRlggEBMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0B
AQsFAAOCAgEANtdMT47CjQtuERYa5jfygIO5F+urB4fl8pYcQQ/hTPE0KtAnAtrS
1strtMrVQ1t7Wu3fVbWYA6MZMXXkcwyyNbaWfj6roaSC6G5ZqCJ69oSyzaCbyaTI
eOgzIIiVGOAj7tiM6T88Xp9qx4Xa3F6UQHF6xfwBT3nNKerGKOG01p7mBfBewwO5
Hxp7OAZmennUxV1uuT5/AsArxw9lMlawXhIAS7tRYHW+32D4tjHPDycldOw1hBjt
z5JdehBiTmxhJ6onl0HSpsX84IMSbkeFIxLfxIF0TNas1pGnSGmh8FcV+ck9js3P
yamJcNkgCstIwo3QZ2D5YdtQjOusyEuGjCIpDIQx36OMzeOo0SayOdzb2dSmcrHv
4DIkXDUELyIzu79A2R2KR7OQaGL6HGAVy6+yXHHygTbbUrb6ck2+aOG8913ChABc
ZAiSFFRKVZzzj7FeIxZNA8GBUbhd20eQB2fUXDypeAnTG6P3dtTs84xNb1qGm3VC
OAKjkWYQijLWmAOs9Q4NM/AXOeDTgXxA7iX7kWHRNeDbACirp7zM2ZOIP5ObIS6z
yMqcG9DecSVbXiH3MJDTBoB1idQTTyreqpM/l6N8xNNVjEiLJGMEM1SeYq6S1lFV
a+GcdOaLYkh7ya3I42l/tDOqH2OLIf7FEtocnc1xU6jTz8au1tZxec8=
-----END CERTIFICATE-----

View File

@ -1,17 +0,0 @@
Index: grub-2.02~rc1/grub-core/osdep/linux/hostdisk.c
===================================================================
--- grub-2.02~rc1.orig/grub-core/osdep/linux/hostdisk.c
+++ grub-2.02~rc1/grub-core/osdep/linux/hostdisk.c
@@ -45,6 +45,12 @@
#include <errno.h>
#include <limits.h>
+#if defined(MAJOR_IN_MKDEV)
+#include <sys/mkdev.h>
+#elif defined(MAJOR_IN_SYSMACROS)
+#include <sys/sysmacros.h>
+#endif
+
# include <sys/ioctl.h> /* ioctl */
# include <sys/mount.h>
# ifndef BLKFLSBUF

17
grub-1.95-grubdir.patch Normal file
View File

@ -0,0 +1,17 @@
This should ideally be done using transformations.
Alternatively, /boot/grub may be used, no grub's files there should conflict
with grub2 and they both can share the same device.map.
Lubomir Rintel <lkundrak@v3.sk>
--- grub2.orig/include/grub/util/misc.h 2007-11-28 14:10:01.000000000 +0100
+++ grub2/include/grub/util/misc.h 2007-11-28 14:10:20.000000000 +0100
@@ -28,7 +28,7 @@
/* NetBSD uses /boot for its boot block. */
# define DEFAULT_DIRECTORY "/grub"
#else
-# define DEFAULT_DIRECTORY "/boot/grub"
+# define DEFAULT_DIRECTORY "/boot/grub2"
#endif
#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map"

3
grub-1.97.2.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:98c1d2623ce809ec25ba9136ea59c15a4580c71478d122be765e819cb06a1c49
size 1249181

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:445239e9b96d1143c194c1d37851cf4196b83701c60172e49665e9d453d80278
size 6051964

View File

@ -1,39 +1,2 @@
# If you change this file, run 'grub2-mkconfig -o /boot/grub2/grub.cfg' afterwards to update
# /boot/grub2/grub.cfg.
# Uncomment to set your own custom distributor. If you leave it unset or empty, the default
# policy is to determine the value from /etc/os-release
# GRUB_DISTRIBUTOR=""
GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""
# Uncomment to automatically save last booted menu entry in GRUB2 environment
# variable `saved_entry'
#GRUB_SAVEDEFAULT="true"
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_LINUX_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
GRUB_CMDLINE_LINUX="quiet"
GRUB_DISTRIBUTOR="openSUSE"

View File

@ -1,232 +0,0 @@
From a06004f4c668abd7c760a2818d0a8205da7568e7 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 26 Apr 2016 15:29:25 +0200
Subject: [PATCH v3] Add hidden menu entries
The menu infrastructure is quite powerful. It allows you to define menu
entries that can contain arbitrary grub commands that can do a lot more
than just boot kernel entries.
For some of these it makes sense to hide them inside the normal menu
though and instead have them available through hotkeys that get advertised
differently. My main use case is to switch to the serial console when
gfxterm is loaded.
So this patch adds support for hidden menu entries that are accessible
using hotkeys, but are not accessible in the grub menu.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- fix default entry selection
v2 -> v3:
- replace "--hidden" parameter with new command "hiddenentry"
diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
index dd9d9f1..b282c4f 100644
--- a/grub-core/commands/legacycfg.c
+++ b/grub-core/commands/legacycfg.c
@@ -133,7 +133,7 @@ legacy_file (const char *filename)
args[0] = oldname;
grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
NULL, NULL,
- entrysrc, 0);
+ entrysrc, 0, 0);
grub_free (args);
entrysrc[0] = 0;
grub_free (oldname);
@@ -186,7 +186,7 @@ legacy_file (const char *filename)
}
args[0] = entryname;
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
- NULL, NULL, entrysrc, 0);
+ NULL, NULL, entrysrc, 0, 0);
grub_free (args);
}
diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
index 58d4dad..b4d6c31 100644
--- a/grub-core/commands/menuentry.c
+++ b/grub-core/commands/menuentry.c
@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
char **classes, const char *id,
const char *users, const char *hotkey,
const char *prefix, const char *sourcecode,
- int submenu)
+ int submenu, int hidden)
{
int menu_hotkey = 0;
char **menu_args = NULL;
@@ -188,8 +188,11 @@ grub_normal_add_menu_entry (int argc, const char **args,
(*last)->args = menu_args;
(*last)->sourcecode = menu_sourcecode;
(*last)->submenu = submenu;
+ (*last)->hidden = hidden;
+
+ if (!hidden)
+ menu->size++;
- menu->size++;
return GRUB_ERR_NONE;
fail:
@@ -286,7 +289,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
users,
ctxt->state[2].arg, 0,
ctxt->state[3].arg,
- ctxt->extcmd->cmd->name[0] == 's');
+ ctxt->extcmd->cmd->name[0] == 's',
+ ctxt->extcmd->cmd->name[0] == 'h');
src = args[argc - 1];
args[argc - 1] = NULL;
@@ -303,7 +307,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
ctxt->state[0].args, ctxt->state[4].arg,
users,
ctxt->state[2].arg, prefix, src + 1,
- ctxt->extcmd->cmd->name[0] == 's');
+ ctxt->extcmd->cmd->name[0] == 's',
+ ctxt->extcmd->cmd->name[0] == 'h');
src[len - 1] = ch;
args[argc - 1] = src;
@@ -311,7 +316,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
return r;
}
-static grub_extcmd_t cmd, cmd_sub;
+static grub_extcmd_t cmd, cmd_sub, cmd_hidden;
void
grub_menu_init (void)
@@ -327,6 +332,13 @@ grub_menu_init (void)
| GRUB_COMMAND_FLAG_EXTRACTOR,
N_("BLOCK"), N_("Define a submenu."),
options);
+ cmd_hidden = grub_register_extcmd ("hiddenentry", grub_cmd_menuentry,
+ GRUB_COMMAND_FLAG_BLOCKS
+ | GRUB_COMMAND_ACCEPT_DASH
+ | GRUB_COMMAND_FLAG_EXTRACTOR,
+ N_("BLOCK"),
+ N_("Define a hidden menu entry."),
+ options);
}
void
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 719e2fb..2a151fe 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -40,6 +40,8 @@
grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
int nested) = NULL;
+#define MENU_INCLUDE_HIDDEN 0x10000
+
enum timeout_style {
TIMEOUT_STYLE_MENU,
TIMEOUT_STYLE_COUNTDOWN,
@@ -80,8 +82,20 @@ grub_menu_get_entry (grub_menu_t menu, int no)
{
grub_menu_entry_t e;
- for (e = menu->entry_list; e && no > 0; e = e->next, no--)
- ;
+ if (no & MENU_INCLUDE_HIDDEN) {
+ no &= ~MENU_INCLUDE_HIDDEN;
+
+ for (e = menu->entry_list; e && no > 0; e = e->next, no--)
+ ;
+ } else {
+ for (e = menu->entry_list; e && no > 0; e = e->next, no--) {
+ /* Skip hidden entries */
+ while (e && e->hidden)
+ e = e->next;
+ }
+ while (e && e->hidden)
+ e = e->next;
+ }
return e;
}
@@ -93,10 +107,10 @@ get_entry_index_by_hotkey (grub_menu_t menu, int hotkey)
grub_menu_entry_t entry;
int i;
- for (i = 0, entry = menu->entry_list; i < menu->size;
+ for (i = 0, entry = menu->entry_list; entry;
i++, entry = entry->next)
if (entry->hotkey == hotkey)
- return i;
+ return i | MENU_INCLUDE_HIDDEN;
return -1;
}
@@ -510,6 +524,10 @@ get_entry_number (grub_menu_t menu, const char *name)
grub_menu_entry_t e = menu->entry_list;
int i;
+ /* Skip hidden entries */
+ while (e && e->hidden)
+ e = e->next;
+
grub_errno = GRUB_ERR_NONE;
for (i = 0; e; i++)
@@ -521,6 +539,10 @@ get_entry_number (grub_menu_t menu, const char *name)
break;
}
e = e->next;
+
+ /* Skip hidden entries */
+ while (e && e->hidden)
+ e = e->next;
}
if (! e)
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
index e22bb91..4ac2d6b 100644
--- a/grub-core/normal/menu_text.c
+++ b/grub-core/normal/menu_text.c
@@ -290,6 +290,10 @@ print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
e, data);
if (e)
e = e->next;
+
+ /* Skip hidden entries */
+ while (e && e->hidden)
+ e = e->next;
}
grub_term_gotoxy (data->term,
diff --git a/include/grub/menu.h b/include/grub/menu.h
index ee2b5e9..eb8a86b 100644
--- a/include/grub/menu.h
+++ b/include/grub/menu.h
@@ -58,6 +58,8 @@ struct grub_menu_entry
int submenu;
+ int hidden;
+
/* The next element. */
struct grub_menu_entry *next;
};
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 218cbab..bcb4124 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
const char *id,
const char *users, const char *hotkey,
const char *prefix, const char *sourcecode,
- int submenu);
+ int submenu, int hidden);
grub_err_t
grub_normal_set_password (const char *user, const char *password);

View File

@ -1,46 +0,0 @@
From 6225854682a736e4312ce15b34c90fff03b002db Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Fri, 6 Jul 2012 15:55:18 +0800
Subject: [PATCH] add GRUB_CMDLINE_LINUX_RECOVERY for recovery mode
References: [openSUSE-factory] Has FailSafe or Safe Mode been removed
permanently from 12.2?
Patch-Mainline: no
We adapt the script a bit in order to support openSUSE's failsafe
booting mode. We don't use single user mode but with specific kernel
command line options decided in YaST. These command line could be
applied to grub2's recovery mode via the new setting
GRUB_CMDLINE_LINUX_RECOVERY.
---
util/grub-mkconfig.in | 3 ++-
util/grub.d/10_linux.in | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -227,7 +227,8 @@ export GRUB_DEFAULT \
GRUB_ENABLE_CRYPTODISK \
GRUB_BADRAM \
GRUB_OS_PROBER_SKIP_LIST \
- GRUB_DISABLE_SUBMENU
+ GRUB_DISABLE_SUBMENU \
+ GRUB_CMDLINE_LINUX_RECOVERY
if test "x${grub_cfg}" != "x"; then
rm -f "${grub_cfg}.new"
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -240,7 +240,7 @@ while [ "x$list" != "x" ] ; do
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" recovery \
- "single ${GRUB_CMDLINE_LINUX}"
+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_RECOVERY}"
fi
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`

View File

@ -1,68 +0,0 @@
From f6be3d41e24e685846dfc90ac1ca447501813687 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 26 Apr 2016 15:59:03 +0200
Subject: [PATCH] SUSE: Add the "t" hotkey
While graphical output is fancy and nice, in some environments (EFI) we can
only have fancy graphical on frame buffer _or_ ugly serial on any output.
To give the user a nicely graphical screen in the default case, but still
allow them to get their boot menu on the serial console, let's add a new
hidden option "t" that switches the output device back to the firmware default.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2
- use hiddenentry instead of --hidden
diff --git a/Makefile.util.def b/Makefile.util.def
index f9caccb..d94de92 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -504,6 +504,12 @@ script = {
installdir = grubconf;
};
+script = {
+ name = '95_textmode';
+ common = util/grub.d/95_textmode.in;
+ installdir = grubconf;
+};
+
program = {
mansection = 1;
name = grub-mkrescue;
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
index 93a9023..b6ec7e2 100644
--- a/util/grub.d/00_header.in
+++ b/util/grub.d/00_header.in
@@ -184,6 +184,9 @@ EOF
fi
fi
+ if [ -d /sys/firmware/efi ]; then
+ echo 'echo "Please press 't' to show the boot menu on this console"'
+ fi
cat << EOF
set gfxmode=${GRUB_GFXMODE}
load_video
diff --git a/util/grub.d/95_textmode.in b/util/grub.d/95_textmode.in
new file mode 100644
index 0000000..fa48cf9
--- /dev/null
+++ b/util/grub.d/95_textmode.in
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+if [ -d /sys/firmware/efi ]; then
+ echo "
+ # On EFI systems we can only have graphics *or* serial, so allow the user
+ # to switch between the two
+ hiddenentry 'Text mode' --hotkey 't' {
+ set textmode=true
+ terminal_output console
+ }"
+fi

View File

@ -1,22 +0,0 @@
Accept empty modules
For the Xen platform the all_video.mod module is empty.
With old binutils the .symtab section remained (containing
only section symbols), so the check didn't trigger, but starting
with binutils 2.27 not even a .symtab remains. As there are
also no relocations that's no problem (and that is checked
independendly).
Index: grub-2.02~rc1/util/grub-module-verifierXX.c
===================================================================
--- grub-2.02~rc1.orig/util/grub-module-verifierXX.c
+++ grub-2.02~rc1/util/grub-module-verifierXX.c
@@ -224,7 +224,8 @@ check_symbols (const struct grub_module_
s = find_section (arch, e, ".moddeps");
if (!s)
- grub_util_error ("no symbol table and no .moddeps section");
+ /*grub_util_error ("no symbol table and no .moddeps section");*/
+ return; /* An empty module happens for all_video.module for Xen */
if (!s->sh_size)
grub_util_error ("no symbol table and empty .moddeps section");

View File

@ -1,696 +0,0 @@
From: Jeff Mahoney <jeffm@suse.com>
Subject: 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 | 529 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 518 insertions(+), 11 deletions(-)
Index: grub-2.02~beta2/grub-core/fs/btrfs.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/fs/btrfs.c
+++ grub-2.02~beta2/grub-core/fs/btrfs.c
@@ -29,6 +29,9 @@
#include <minilzo.h>
#include <grub/i18n.h>
#include <grub/btrfs.h>
+#include <grub/command.h>
+#include <grub/env.h>
+#include <grub/extcmd.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -64,9 +67,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];
@@ -105,6 +110,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
@@ -171,6 +177,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;
@@ -215,6 +229,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
};
@@ -830,6 +852,62 @@ grub_btrfs_read_logical (struct grub_btr
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)
{
@@ -865,6 +943,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;
}
@@ -1226,6 +1311,91 @@ get_root (struct grub_btrfs_data *data,
}
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,
grub_uint64_t *tree, grub_uint8_t *type)
@@ -1243,14 +1413,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] == '/')
@@ -1423,9 +1605,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;
}
@@ -1666,6 +1860,20 @@ grub_btrfs_read (grub_file_t file, char
data->tree, file->offset, buf, len);
}
+static char *
+btrfs_unparse_uuid(struct grub_btrfs_data *data)
+{
+ 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]),
+ grub_be_to_cpu16 (data->sblock.uuid[3]),
+ grub_be_to_cpu16 (data->sblock.uuid[4]),
+ 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)
{
@@ -1677,15 +1885,7 @@ grub_btrfs_uuid (grub_device_t device, c
if (!data)
return grub_errno;
- *uuid = 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]),
- grub_be_to_cpu16 (data->sblock.uuid[3]),
- grub_be_to_cpu16 (data->sblock.uuid[4]),
- grub_be_to_cpu16 (data->sblock.uuid[5]),
- grub_be_to_cpu16 (data->sblock.uuid[6]),
- grub_be_to_cpu16 (data->sblock.uuid[7]));
+ *uuid = btrfs_unparse_uuid(data);
grub_btrfs_unmount (data);
@@ -1742,6 +1942,242 @@ grub_btrfs_embed (grub_device_t device _
}
#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",
.dir = grub_btrfs_dir,
@@ -1757,12 +2193,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:
Index: grub-2.02~beta2/include/grub/btrfs.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/btrfs.h
+++ grub-2.02~beta2/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
};

View File

@ -1,21 +0,0 @@
From: Michael Chang <mchang@suse.com>
Subject: 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>
Index: grub-2.00/grub-core/fs/btrfs.c
===================================================================
--- grub-2.00.orig/grub-core/fs/btrfs.c
+++ grub-2.00/grub-core/fs/btrfs.c
@@ -2252,6 +2252,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)

View File

@ -1,187 +0,0 @@
Index: grub-2.02~beta2/grub-core/fs/btrfs.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/fs/btrfs.c
+++ grub-2.02~beta2/grub-core/fs/btrfs.c
@@ -913,6 +913,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)
{
@@ -943,11 +944,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;
@@ -1407,24 +1411,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
{
@@ -1435,15 +1454,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)
{
@@ -1454,7 +1481,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] == '.')
@@ -1485,8 +1514,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;
}
@@ -1555,7 +1585,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;
@@ -1605,14 +1637,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
{
@@ -2268,6 +2312,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)

View File

@ -1,160 +0,0 @@
Index: grub-2.02~rc1/grub-core/osdep/unix/config.c
===================================================================
--- grub-2.02~rc1.orig/grub-core/osdep/unix/config.c
+++ grub-2.02~rc1/grub-core/osdep/unix/config.c
@@ -219,6 +219,19 @@ grub_util_load_config (struct grub_util_
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;
@@ -242,8 +255,8 @@ grub_util_load_config (struct grub_util_
*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';
Index: grub-2.02~rc1/include/grub/emu/config.h
===================================================================
--- grub-2.02~rc1.orig/include/grub/emu/config.h
+++ grub-2.02~rc1/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
Index: grub-2.02~rc1/util/config.c
===================================================================
--- grub-2.02~rc1.orig/util/config.c
+++ grub-2.02~rc1/util/config.c
@@ -42,6 +42,16 @@ grub_util_parse_config (FILE *f, struct
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)
{
Index: grub-2.02~rc1/util/grub-install.c
===================================================================
--- grub-2.02~rc1.orig/util/grub-install.c
+++ grub-2.02~rc1/util/grub-install.c
@@ -828,6 +828,8 @@ fill_core_services (const char *core_ser
free (sysv_plist);
}
+extern int use_relative_path_on_btrfs;
+
int
main (int argc, char *argv[])
{
@@ -861,6 +863,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;
@@ -1347,6 +1352,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;
Index: grub-2.02~rc1/grub-core/osdep/linux/getroot.c
===================================================================
--- grub-2.02~rc1.orig/grub-core/osdep/linux/getroot.c
+++ grub-2.02~rc1/grub-core/osdep/linux/getroot.c
@@ -376,6 +376,7 @@ get_btrfs_fs_prefix (const char *mount_p
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)
{
Index: grub-2.02~rc1/util/grub-mkrelpath.c
===================================================================
--- grub-2.02~rc1.orig/util/grub-mkrelpath.c
+++ grub-2.02~rc1/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
switch (key)
{
+ case 'r':
+ use_relative_path_on_btrfs = 1;
+ break;
case ARGP_KEY_ARG:
if (state->arg_num == 0)
arguments->pathname = xstrdup (arg);

View File

@ -1,136 +0,0 @@
---
util/grub-mkconfig.in | 3 ++-
util/grub-mkconfig_lib.in | 4 ++++
util/grub.d/00_header.in | 23 ++++++++++++++++++++++-
util/grub.d/10_linux.in | 11 ++++++++++-
util/grub.d/20_linux_xen.in | 4 ++++
5 files changed, 42 insertions(+), 3 deletions(-)
Index: grub-2.02~beta2/util/grub-mkconfig_lib.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig_lib.in
+++ grub-2.02~beta2/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 ()
Index: grub-2.02~beta2/util/grub.d/00_header.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/00_header.in
+++ grub-2.02~beta2/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
@@ -43,7 +51,9 @@ if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved
if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi
cat << EOF
-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
@@ -367,3 +377,15 @@ fi
if [ "x${GRUB_BADRAM}" != "x" ] ; then
echo "badram ${GRUB_BADRAM}"
fi
+
+if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "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
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -262,7 +262,8 @@ export GRUB_DEFAULT \
GRUB_OS_PROBER_SKIP_LIST \
GRUB_DISABLE_SUBMENU \
GRUB_CMDLINE_LINUX_RECOVERY \
- GRUB_USE_LINUXEFI
+ GRUB_USE_LINUXEFI \
+ SUSE_BTRFS_SNAPSHOT_BOOTING
if test "x${grub_cfg}" != "x"; then
rm -f "${grub_cfg}.new"
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -57,10 +57,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`
@@ -236,7 +240,12 @@ while [ "x$list" != "x" ] ; do
if [ $PLATFORM != "emu" ]; then
hotkey=0
else
- rel_dirname=$dirname
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] &&
+ [ "x${GRUB_FS}" = "xbtrfs" ] ; then
+ rel_dirname="\${btrfs_subvol}$dirname"
+ else
+ rel_dirname="$dirname"
+ fi
fi
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -71,10 +71,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`

View File

@ -1,512 +0,0 @@
Index: grub-2.02~rc1/grub-core/fs/btrfs.c
===================================================================
--- grub-2.02~rc1.orig/grub-core/fs/btrfs.c
+++ grub-2.02~rc1/grub-core/fs/btrfs.c
@@ -32,6 +32,7 @@
#include <grub/command.h>
#include <grub/env.h>
#include <grub/extcmd.h>
+#include <grub/list.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -245,6 +246,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)
@@ -887,9 +894,26 @@ lookup_root_by_name(struct grub_btrfs_da
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);
@@ -1758,11 +1782,20 @@ grub_btrfs_dir (grub_device_t device, co
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);
@@ -1864,11 +1897,21 @@ grub_btrfs_open (struct grub_file *file,
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);
@@ -2039,6 +2082,150 @@ grub_cmd_btrfs_info (grub_command_t cmd
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,
@@ -2245,6 +2432,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 *
@@ -2308,6 +2496,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",
Index: grub-2.02~rc1/grub-core/osdep/linux/getroot.c
===================================================================
--- grub-2.02~rc1.orig/grub-core/osdep/linux/getroot.c
+++ grub-2.02~rc1/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_p
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)
@@ -1144,6 +1258,34 @@ grub_util_get_grub_dev_os (const char *o
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)
{
Index: grub-2.02~rc1/util/grub-install.c
===================================================================
--- grub-2.02~rc1.orig/util/grub-install.c
+++ grub-2.02~rc1/util/grub-install.c
@@ -1560,6 +1560,42 @@ 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;
+
+ if (!load_cfg_f)
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ have_load_cfg = 1;
+
+ 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 (grub_strcmp (subvol, def_subvol) != 0)
+ fprintf (load_cfg_f, "btrfs-mount-subvol ($root) %s %s\n", mount_path, subvol);
+ free (def_subvol);
+ }
+ }
+
+ if (subvol)
+ free (subvol);
+ if (mount_path)
+ free (mount_path);
+ }
+
+#endif
+
char mkimage_target[200];
const char *core_name = NULL;
Index: grub-2.02~rc1/include/grub/emu/getroot.h
===================================================================
--- grub-2.02~rc1.orig/include/grub/emu/getroot.h
+++ grub-2.02~rc1/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);

View File

@ -1,46 +0,0 @@
Index: grub-2.02~beta3/grub-core/fs/btrfs.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/fs/btrfs.c
+++ grub-2.02~beta3/grub-core/fs/btrfs.c
@@ -925,10 +925,40 @@ lookup_root_by_name(struct grub_btrfs_da
}
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);

View File

@ -1,58 +0,0 @@
Index: grub-2.02~beta2/grub-core/normal/menu.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/normal/menu.c
+++ grub-2.02~beta2/grub-core/normal/menu.c
@@ -575,6 +575,44 @@ print_countdown (struct grub_term_coordi
grub_refresh ();
}
+/* bsc#956046 - The first entry titled 'Bootable snapshot #$NUM' is inserted on
+ top at runtime to display current snapshot information. If default entry is
+ using number as key to index the entry, the result will be shifted so here we
+ add specical handling to shift it back. We apply this workaround until a better
+ solution can be found. */
+static void
+workaround_snapshot_menu_default_entry (grub_menu_t menu, const char *name, int *default_entry)
+{
+ grub_menu_entry_t entry;
+
+ if ((entry = grub_menu_get_entry (menu, 0))
+ && entry->submenu
+ && grub_strncmp (entry->title, "Bootable snapshot", sizeof("Bootable snapshot") - 1) == 0)
+ {
+ const char *val;
+
+ if (*default_entry == -1 && menu->size > 1)
+ {
+ *default_entry = 1;
+ return;
+ }
+
+ val = grub_env_get (name);
+
+ grub_error_push ();
+
+ if (val)
+ grub_strtoul (val, 0, 0);
+
+ if (*default_entry < (menu->size - 1) && grub_errno == GRUB_ERR_NONE)
+ ++(*default_entry);
+
+ grub_error_pop ();
+ }
+
+ return;
+}
+
#define GRUB_MENU_PAGE_SIZE 10
/* Show the menu and handle menu entry selection. Returns the menu entry
@@ -593,6 +631,8 @@ run_menu (grub_menu_t menu, int nested,
default_entry = get_entry_number (menu, "default");
+ workaround_snapshot_menu_default_entry (menu, "default", &default_entry);
+
/* If DEFAULT_ENTRY is not within the menu entries, fall back to
the first entry. */
if (default_entry < 0 || default_entry >= menu->size)

View File

@ -1,475 +0,0 @@
Index: grub-2.02~beta3/grub-core/kern/fs.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/kern/fs.c
+++ grub-2.02~beta3/grub-core/kern/fs.c
@@ -27,6 +27,7 @@
#include <grub/mm.h>
#include <grub/term.h>
#include <grub/i18n.h>
+#include <grub/partition.h>
grub_fs_t grub_fs_list = 0;
@@ -228,6 +229,13 @@ grub_fs_blocklist_read (grub_file_t file
size, buf) != GRUB_ERR_NONE)
return -1;
+ if (file->read_hook)
+ {
+ grub_disk_addr_t part_start;
+
+ part_start = grub_partition_get_start (file->device->disk->partition);
+ file->read_hook (p->offset + sector + part_start, (unsigned)offset, (unsigned)size, file->read_hook_data);
+ }
ret += size;
len -= size;
sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS);
Index: grub-2.02~beta3/util/grub-editenv.c
===================================================================
--- grub-2.02~beta3.orig/util/grub-editenv.c
+++ grub-2.02~beta3/util/grub-editenv.c
@@ -23,8 +23,11 @@
#include <grub/util/misc.h>
#include <grub/lib/envblk.h>
#include <grub/i18n.h>
-#include <grub/emu/hostfile.h>
+#include <grub/emu/hostdisk.h>
#include <grub/util/install.h>
+#include <grub/emu/getroot.h>
+#include <grub/fs.h>
+#include <grub/crypto.h>
#include <stdio.h>
#include <unistd.h>
@@ -120,6 +123,140 @@ block, use `rm %s'."),
NULL, help_filter, NULL
};
+struct fs_envblk_spec {
+ const char *fs_name;
+ int offset;
+ int size;
+} fs_envblk_spec[] = {
+ { "btrfs", 256 * 1024, GRUB_DISK_SECTOR_SIZE },
+ { NULL, 0, 0 }
+};
+
+struct fs_envblk {
+ struct fs_envblk_spec *spec;
+ const char *dev;
+};
+
+typedef struct fs_envblk_spec *fs_envblk_spec_t;
+typedef struct fs_envblk *fs_envblk_t;
+
+fs_envblk_t fs_envblk = NULL;
+
+static int
+read_envblk_fs (const char *varname, const char *value, void *hook_data)
+{
+ grub_envblk_t *p_envblk = (grub_envblk_t *)hook_data;
+
+ if (!p_envblk || !fs_envblk)
+ return 0;
+
+ if (strcmp (varname, "env_block") == 0)
+ {
+ int off, sz;
+ char *p;
+
+ off = strtol (value, &p, 10);
+ if (*p == '+')
+ sz = strtol (p+1, &p, 10);
+
+ if (*p == '\0')
+ {
+ FILE *fp;
+ char *buf;
+
+ off <<= GRUB_DISK_SECTOR_BITS;
+ sz <<= GRUB_DISK_SECTOR_BITS;
+
+ fp = grub_util_fopen (fs_envblk->dev, "rb");
+ if (! fp)
+ grub_util_error (_("cannot open `%s': %s"), fs_envblk->dev,
+ strerror (errno));
+
+
+ if (fseek (fp, off, SEEK_SET) < 0)
+ grub_util_error (_("cannot seek `%s': %s"), fs_envblk->dev,
+ strerror (errno));
+
+ buf = xmalloc (sz);
+ if ((fread (buf, 1, sz, fp)) != sz)
+ grub_util_error (_("cannot read `%s': %s"), fs_envblk->dev,
+ strerror (errno));
+
+ fclose (fp);
+
+ *p_envblk = grub_envblk_open (buf, sz);
+ }
+ }
+
+ return 0;
+}
+
+static void
+create_envblk_fs (void)
+{
+ FILE *fp;
+ char *buf;
+ const char *device;
+ int offset, size;
+
+ if (!fs_envblk)
+ return;
+
+ device = fs_envblk->dev;
+ offset = fs_envblk->spec->offset;
+ size = fs_envblk->spec->size;
+
+ fp = grub_util_fopen (device, "r+b");
+ if (! fp)
+ grub_util_error (_("cannot open `%s': %s"), device, strerror (errno));
+
+ buf = xmalloc (size);
+ memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
+ memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
+
+ if (fseek (fp, offset, SEEK_SET) < 0)
+ grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
+
+ if (fwrite (buf, 1, size, fp) != size)
+ grub_util_error (_("cannot write to `%s': %s"), device, strerror (errno));
+
+ grub_util_file_sync (fp);
+ free (buf);
+ fclose (fp);
+}
+
+static grub_envblk_t
+open_envblk_fs (grub_envblk_t envblk)
+{
+ grub_envblk_t envblk_fs = NULL;
+ char *val;
+ int offset, size;
+
+ if (!fs_envblk)
+ return NULL;
+
+ offset = fs_envblk->spec->offset;
+ size = fs_envblk->spec->size;
+
+ grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs);
+
+ if (envblk_fs && grub_envblk_size (envblk_fs) == size)
+ return envblk_fs;
+
+ create_envblk_fs ();
+
+ offset = offset >> GRUB_DISK_SECTOR_BITS;
+ size = (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS;
+
+ val = xasprintf ("%d+%d", offset, size);
+ if (! grub_envblk_set (envblk, "env_block", val))
+ grub_util_error ("%s", _("environment block too small"));
+ grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs);
+ free (val);
+
+ return envblk_fs;
+}
+
static grub_envblk_t
open_envblk_file (const char *name)
{
@@ -176,10 +313,17 @@ static void
list_variables (const char *name)
{
grub_envblk_t envblk;
+ grub_envblk_t envblk_fs = NULL;
envblk = open_envblk_file (name);
+ grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs);
grub_envblk_iterate (envblk, NULL, print_var);
grub_envblk_close (envblk);
+ if (envblk_fs)
+ {
+ grub_envblk_iterate (envblk_fs, NULL, print_var);
+ grub_envblk_close (envblk_fs);
+ }
}
static void
@@ -202,6 +346,38 @@ write_envblk (const char *name, grub_env
}
static void
+write_envblk_fs (grub_envblk_t envblk)
+{
+ FILE *fp;
+ const char *device;
+ int offset, size;
+
+ if (!fs_envblk)
+ return;
+
+ device = fs_envblk->dev;
+ offset = fs_envblk->spec->offset;
+ size = fs_envblk->spec->size;
+
+ if (grub_envblk_size (envblk) > size)
+ grub_util_error ("%s", _("environment block too small"));
+
+ fp = grub_util_fopen (device, "r+b");
+
+ if (! fp)
+ grub_util_error (_("cannot open `%s': %s"), device, strerror (errno));
+
+ if (fseek (fp, offset, SEEK_SET) < 0)
+ grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
+
+ if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp) != grub_envblk_size (envblk))
+ grub_util_error (_("cannot write to `%s': %s"), device, strerror (errno));
+
+ grub_util_file_sync (fp);
+ fclose (fp);
+}
+
+static void
set_variables (const char *name, int argc, char *argv[])
{
grub_envblk_t envblk;
@@ -217,8 +393,26 @@ set_variables (const char *name, int arg
*(p++) = 0;
- if (! grub_envblk_set (envblk, argv[0], p))
- grub_util_error ("%s", _("environment block too small"));
+ if (strcmp (argv[0], "next_entry") == 0 && fs_envblk)
+ {
+ grub_envblk_t envblk_fs;
+ envblk_fs = open_envblk_fs (envblk);
+ if (!envblk_fs)
+ grub_util_error ("%s", _("can't open fs environment block"));
+ if (! grub_envblk_set (envblk_fs, argv[0], p))
+ grub_util_error ("%s", _("environment block too small"));
+ write_envblk_fs (envblk_fs);
+ grub_envblk_close (envblk_fs);
+ }
+ else if (strcmp (argv[0], "env_block") == 0)
+ {
+ grub_util_warn ("can't set env_block as it's read-only");
+ }
+ else
+ {
+ if (! grub_envblk_set (envblk, argv[0], p))
+ grub_util_error ("%s", _("environment block too small"));
+ }
argc--;
argv++;
@@ -226,26 +420,158 @@ set_variables (const char *name, int arg
write_envblk (name, envblk);
grub_envblk_close (envblk);
+
}
static void
unset_variables (const char *name, int argc, char *argv[])
{
grub_envblk_t envblk;
+ grub_envblk_t envblk_fs;
envblk = open_envblk_file (name);
+
+ envblk_fs = NULL;
+ if (fs_envblk)
+ envblk_fs = open_envblk_fs (envblk);
+
while (argc)
{
grub_envblk_delete (envblk, argv[0]);
+ if (envblk_fs)
+ grub_envblk_delete (envblk_fs, argv[0]);
+
argc--;
argv++;
}
write_envblk (name, envblk);
grub_envblk_close (envblk);
+
+ if (envblk_fs)
+ {
+ write_envblk_fs (envblk_fs);
+ grub_envblk_close (envblk_fs);
+ }
+}
+
+int have_abstraction = 0;
+static void
+probe_abstraction (grub_disk_t disk)
+{
+ if (disk->partition == NULL)
+ grub_util_info ("no partition map found for %s", disk->name);
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID ||
+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ {
+ have_abstraction = 1;
+ }
}
+static fs_envblk_t
+probe_fs_envblk (fs_envblk_spec_t spec)
+{
+ char **grub_devices;
+ char **curdev, **curdrive;
+ size_t ndev = 0;
+ char **grub_drives;
+ grub_device_t grub_dev = NULL;
+ grub_fs_t grub_fs;
+ const char *fs_envblk_device;
+
+#ifdef __s390x__
+ return NULL;
+#endif
+
+ grub_util_biosdisk_init (DEFAULT_DEVICE_MAP);
+ grub_init_all ();
+ grub_gcry_init_all ();
+
+ grub_lvm_fini ();
+ grub_mdraid09_fini ();
+ grub_mdraid1x_fini ();
+ grub_diskfilter_fini ();
+ grub_diskfilter_init ();
+ grub_mdraid09_init ();
+ grub_mdraid1x_init ();
+ grub_lvm_init ();
+
+ grub_devices = grub_guess_root_devices (DEFAULT_DIRECTORY);
+
+ if (!grub_devices || !grub_devices[0])
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), DEFAULT_DIRECTORY);
+
+ fs_envblk_device = grub_devices[0];
+
+ for (curdev = grub_devices; *curdev; curdev++)
+ {
+ grub_util_pull_device (*curdev);
+ ndev++;
+ }
+
+ grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1));
+
+ for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
+ curdrive++)
+ {
+ *curdrive = grub_util_get_grub_dev (*curdev);
+ if (! *curdrive)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ *curdev);
+ }
+ *curdrive = 0;
+
+ grub_dev = grub_device_open (grub_drives[0]);
+ if (! grub_dev)
+ grub_util_error ("%s", grub_errmsg);
+
+ grub_fs = grub_fs_probe (grub_dev);
+ if (! grub_fs)
+ grub_util_error ("%s", grub_errmsg);
+
+ if (grub_dev->disk)
+ {
+ probe_abstraction (grub_dev->disk);
+ }
+ for (curdrive = grub_drives + 1; *curdrive; curdrive++)
+ {
+ grub_device_t dev = grub_device_open (*curdrive);
+ if (!dev)
+ continue;
+ if (dev->disk)
+ probe_abstraction (dev->disk);
+ grub_device_close (dev);
+ }
+
+ free (grub_drives);
+ grub_device_close (grub_dev);
+ grub_gcry_fini_all ();
+ grub_fini_all ();
+ grub_util_biosdisk_fini ();
+
+ fs_envblk_spec_t p;
+
+ for (p = spec; p->fs_name; p++)
+ {
+ if (strcmp (grub_fs->name, p->fs_name) == 0 && !have_abstraction)
+ {
+ if (p->offset % GRUB_DISK_SECTOR_SIZE == 0 &&
+ p->size % GRUB_DISK_SECTOR_SIZE == 0)
+ {
+ fs_envblk = xmalloc (sizeof (fs_envblk_t));
+ fs_envblk->spec = p;
+ fs_envblk->dev = strdup(fs_envblk_device);
+ return fs_envblk;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
int
main (int argc, char *argv[])
{
@@ -277,6 +603,9 @@ main (int argc, char *argv[])
command = argv[curindex++];
}
+ if (strcmp (filename, DEFAULT_ENVBLK_PATH) == 0)
+ fs_envblk = probe_fs_envblk (fs_envblk_spec);
+
if (strcmp (command, "create") == 0)
grub_util_create_envblk_file (filename);
else if (strcmp (command, "list") == 0)
Index: grub-2.02~beta3/util/grub.d/00_header.in
===================================================================
--- grub-2.02~beta3.orig/util/grub.d/00_header.in
+++ grub-2.02~beta3/util/grub.d/00_header.in
@@ -46,6 +46,11 @@ cat << EOF
if [ -s \$prefix/grubenv ]; then
load_env
fi
+
+if [ "\${env_block}" ] ; then
+ load_env -f "\${env_block}"
+fi
+
EOF
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
@@ -55,6 +60,9 @@ elif [ "\${next_entry}" ] ; then
set default="\${next_entry}"
set next_entry=
save_env next_entry
+ if [ "\${env_block}" ] ; then
+ save_env -f "\${env_block}" next_entry
+ fi
set boot_once=true
else
set default="${GRUB_DEFAULT}"
@@ -66,6 +74,9 @@ if [ "\${next_entry}" ] ; then
set default="\${next_entry}"
set next_entry=
save_env next_entry
+ if [ "\${env_block}" ] ; then
+ save_env -f "\${env_block}" next_entry
+ fi
set boot_once=true
else
set default="${GRUB_DEFAULT}"

View File

@ -1,70 +0,0 @@
From: Raymund Will <rw@suse.com>
Subject: Introduce a 'read_file' sub-command.
References: bsc#892852, bsc#891946
Patch-Mainline: not yet
Needed to allow s390x-emu to be telecontrolled via LOADPARM.
---
grub-core/commands/read.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
--- a/grub-core/commands/read.c
+++ b/grub-core/commands/read.c
@@ -20,6 +20,7 @@
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
+#include <grub/normal.h>
#include <grub/env.h>
#include <grub/term.h>
#include <grub/types.h>
@@ -77,16 +78,49 @@ grub_cmd_read (grub_command_t cmd __attr
return 0;
}
+static grub_err_t
+grub_cmd_read_from_file (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
+{
+ char *line;
+ int i = 0;
+ grub_file_t file;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("file name expected"));
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable name expected"));
+ file = grub_file_open (args[i++]);
+ if (! file)
+ return grub_errno;
+ while ( i < argc )
+ {
+ line = grub_file_getline (file);
+ if ( !line )
+ break;
+ grub_env_set (args[i++], line);
+ grub_free (line);
+ }
+ grub_file_close (file);
+ if (i != argc)
+ return GRUB_ERR_OUT_OF_RANGE;
+ return 0;
+}
+
static grub_command_t cmd;
+static grub_command_t cme;
GRUB_MOD_INIT(read)
{
cmd = grub_register_command ("read", grub_cmd_read,
N_("[ENVVAR]"),
N_("Set variable with user input."));
+ cme = grub_register_command ("read_file", grub_cmd_read_from_file,
+ N_("FILE ENVVAR [...]"),
+ N_("Set variable(s) with line(s) from FILE."));
}
GRUB_MOD_FINI(read)
{
grub_unregister_command (cmd);
+ grub_unregister_command (cme);
}

View File

@ -1,200 +0,0 @@
Index: grub-2.02~beta3/grub-core/osdep/unix/config.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/osdep/unix/config.c
+++ grub-2.02~beta3/grub-core/osdep/unix/config.c
@@ -61,6 +61,143 @@ grub_util_get_localedir (void)
return LOCALEDIR;
}
+#ifdef __linux__
+static char *
+os_release_get_val (const char *buf, const char *key)
+{
+ const char *ptr = buf;
+ char *ret;
+
+ while (*ptr && grub_isspace(*ptr))
+ ptr++;
+
+ if (*ptr == '#')
+ return NULL;
+
+ if (grub_strncmp (ptr, key, grub_strlen (key)) != 0)
+ return NULL;
+
+ ptr += grub_strlen (key);
+ if (*ptr++ != '=' || *ptr == '\0')
+ return NULL;
+
+ if (*ptr == '"' || *ptr == '\'')
+ {
+ char c = *ptr;
+ int i = 0;
+ char *tmp, *ptmp;
+
+ if (*++ptr == '\0')
+ return NULL;
+
+ tmp = grub_strdup (ptr);
+ if ((ptmp = grub_strrchr (tmp, c)))
+ *ptmp = '\0';
+
+ ret = malloc (grub_strlen (tmp) + 1);
+ ptmp = tmp;
+ while (*ptmp)
+ {
+ if (*ptmp != '\\' || *(ptmp + 1) != c)
+ ret[i++] = *ptmp;
+ ++ptmp;
+ }
+
+ grub_free (tmp);
+ ret[i] = '\0';
+ }
+ else
+ {
+ char *pret;
+
+ ret = grub_strdup (ptr);
+ if ((pret = grub_strchr (ret, ' ')))
+ *pret = '\0';
+ }
+
+ return ret;
+}
+
+static char*
+grub_util_default_distributor (void)
+{
+ char *cfgfile;
+ char buf[1024];
+ FILE *fp = NULL;
+ char *os_pretty_name = NULL;
+ char *os_name = NULL;
+ char *os_version = NULL;
+
+ cfgfile = grub_util_path_concat (2, GRUB_SYSCONFDIR, "os-release");
+ if (!grub_util_is_regular (cfgfile))
+ {
+ grub_free (cfgfile);
+ return NULL;
+ }
+
+ fp = grub_util_fopen (cfgfile, "r");
+
+ if (!fp)
+ {
+ grub_util_warn (_("cannot open configuration file `%s': %s"),
+ cfgfile, strerror (errno));
+ grub_free (cfgfile);
+ return NULL;
+ }
+
+ grub_free (cfgfile);
+
+ while (fgets (buf, sizeof (buf), fp))
+ {
+ if (buf[grub_strlen(buf) - 1] == '\n')
+ buf[grub_strlen(buf) - 1] = '\0';
+
+ if (!os_pretty_name
+ && (os_pretty_name = os_release_get_val (buf, "PRETTY_NAME")))
+ continue;
+ if (!os_name
+ && (os_name = os_release_get_val (buf, "NAME")))
+ continue;
+ if (!os_version
+ && (os_version = os_release_get_val (buf, "VERSION")))
+ continue;
+ if (os_pretty_name && os_name && os_version)
+ break;
+ }
+
+ fclose (fp);
+
+ if (os_name && grub_strncmp (os_name, "openSUSE Tumbleweed", sizeof ("openSUSE Tumbleweed") - 1) == 0)
+ {
+ grub_free (os_name);
+ if (os_version)
+ grub_free (os_version);
+
+ return os_pretty_name;
+ }
+ else if (os_name && os_version)
+ {
+ char *os_name_version;
+
+ os_name_version = grub_xasprintf ("%s %s", os_name, os_version);
+
+ grub_free (os_name);
+ grub_free (os_version);
+ if (os_pretty_name)
+ grub_free (os_pretty_name);
+
+ return os_name_version;
+ }
+
+ if (os_pretty_name)
+ grub_free (os_pretty_name);
+ if (os_version)
+ grub_free (os_version);
+
+ return os_name;
+}
+#endif
+
void
grub_util_load_config (struct grub_util_config *cfg)
{
@@ -125,7 +262,17 @@ grub_util_load_config (struct grub_util_
waitpid (pid, NULL, 0);
}
if (f)
- return;
+ {
+#ifdef __linux__
+ if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0')
+ {
+ if (cfg->grub_distributor)
+ grub_free (cfg->grub_distributor);
+ cfg->grub_distributor = grub_util_default_distributor ();
+ }
+#endif
+ return;
+ }
f = grub_util_fopen (cfgfile, "r");
if (f)
@@ -136,4 +283,13 @@ grub_util_load_config (struct grub_util_
else
grub_util_warn (_("cannot open configuration file `%s': %s"),
cfgfile, strerror (errno));
+
+#ifdef __linux__
+ if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0')
+ {
+ if (cfg->grub_distributor)
+ grub_free (cfg->grub_distributor);
+ cfg->grub_distributor = grub_util_default_distributor ();
+ }
+#endif
}
Index: grub-2.02~beta3/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta3.orig/util/grub-mkconfig.in
+++ grub-2.02~beta3/util/grub-mkconfig.in
@@ -206,6 +206,14 @@ GRUB_ACTUAL_DEFAULT="$GRUB_DEFAULT"
if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub_editenv}" - list | sed -n '/^saved_entry=/ s,^saved_entry=,,p'`" ; fi
+if [ x"${GRUB_DISTRIBUTOR}" = x ] && [ -f "${sysconfdir}/os-release" ] ; then
+ . "${sysconfdir}/os-release"
+ if echo "$NAME" | grep -q "^openSUSE Tumbleweed" ; then
+ GRUB_DISTRIBUTOR="${PRETTY_NAME}"
+ else
+ GRUB_DISTRIBUTOR="${NAME} ${VERSION}"
+ fi
+fi
# These are defined in this script, export them here so that user can
# override them.

30
grub2-dlsym-v4.patch Normal file
View File

@ -0,0 +1,30 @@
2008-05-07: Lubomir Rintel <lkundrak@fedoraproject.org>
* kern/dl.c (grub_dl_resolve_symbols): Let the
grub_gdb_trapvec symbol be resolved correctly (instead of 0).
--- grub2/kern/dl.c 2008-01-26 21:34:58.000000000 +0100
+++ grub2-gdb/kern/dl.c 2008-05-07 09:27:08.000000000 +0200
@@ -352,16 +352,18 @@ grub_dl_resolve_symbols (grub_dl_t mod,
{
case STT_NOTYPE:
/* Resolve a global symbol. */
- if (sym->st_name != 0 && sym->st_shndx == 0)
+ if (sym->st_name == 0)
+ break;
+
+ if (sym->st_shndx == 0) /* external */
{
sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
if (! sym->st_value)
return grub_error (GRUB_ERR_BAD_MODULE,
"the symbol `%s' not found", name);
- }
- else
- sym->st_value = 0;
break;
+ }
+ /* nonexternal, same as STT_OBJECT */
case STT_OBJECT:
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,

View File

@ -1,36 +0,0 @@
Index: grub-2.02~beta2/util/editenv.c
===================================================================
--- grub-2.02~beta2.orig/util/editenv.c
+++ grub-2.02~beta2/util/editenv.c
@@ -30,12 +30,14 @@
#include <string.h>
#define DEFAULT_ENVBLK_SIZE 1024
+#define GRUB_ENVBLK_MESSAGE "# WARNING: Do not edit this file other than by grub2-editenv\n"
void
grub_util_create_envblk_file (const char *name)
{
FILE *fp;
char *buf;
+ char *pbuf;
char *namenew;
buf = xmalloc (DEFAULT_ENVBLK_SIZE);
@@ -46,9 +48,13 @@ grub_util_create_envblk_file (const char
grub_util_error (_("cannot open `%s': %s"), namenew,
strerror (errno));
- memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
- memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#',
- DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
+ pbuf = buf;
+ memcpy (pbuf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
+ pbuf += sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+ memcpy (pbuf, GRUB_ENVBLK_MESSAGE, sizeof (GRUB_ENVBLK_MESSAGE) - 1);
+ pbuf += sizeof (GRUB_ENVBLK_MESSAGE) - 1;
+ memset (pbuf , '#',
+ DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) - sizeof (GRUB_ENVBLK_MESSAGE) + 2);
if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE)
grub_util_error (_("cannot write to `%s': %s"), namenew,

View File

@ -1,88 +0,0 @@
From 0c5fbc745846a53cc04ac1052cfbd35c699394c5 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Thu, 19 May 2016 15:01:06 +0200
Subject: [PATCH] efi: Free malloc regions on exit
When we exit grub, we don't free all the memory that we allocated earlier
for our heap region. This can cause problems with setups where you try
to descend the boot order using "exit" entries, such as PXE -> HD boot
scenarios.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
grub-core/kern/efi/init.c | 1 +
grub-core/kern/efi/mm.c | 24 ++++++++++++++++++++++++
include/grub/efi/efi.h | 1 +
3 files changed, 26 insertions(+)
Index: grub-2.02~beta3/grub-core/kern/efi/init.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/kern/efi/init.c
+++ grub-2.02~beta3/grub-core/kern/efi/init.c
@@ -167,4 +167,5 @@ grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_console_fini ();
+ grub_efi_memory_fini ();
}
Index: grub-2.02~beta3/grub-core/kern/efi/mm.c
===================================================================
--- grub-2.02~beta3.orig/grub-core/kern/efi/mm.c
+++ grub-2.02~beta3/grub-core/kern/efi/mm.c
@@ -49,6 +49,12 @@ static grub_efi_uintn_t finish_desc_size
static grub_efi_uint32_t finish_desc_version;
int grub_efi_is_finished = 0;
+struct efi_allocation {
+ grub_uint64_t start_addr;
+ grub_uint64_t pages;
+} efi_allocated_memory[16];
+unsigned int efi_allocated_memory_idx = 0;
+
/* Allocate pages below a specified address */
void *
grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
@@ -440,6 +446,13 @@ add_memory_regions (grub_efi_memory_desc
(void *) ((grub_addr_t) start),
(unsigned) pages);
+ /* Track up to 16 regions that we allocate from */
+ if (efi_allocated_memory_idx < ARRAY_SIZE(efi_allocated_memory)) {
+ efi_allocated_memory[efi_allocated_memory_idx].start_addr = start;
+ efi_allocated_memory[efi_allocated_memory_idx].pages = pages;
+ efi_allocated_memory_idx++;
+ }
+
grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
required_pages -= pages;
@@ -451,6 +464,17 @@ add_memory_regions (grub_efi_memory_desc
grub_fatal ("too little memory");
}
+void
+grub_efi_memory_fini (void)
+{
+ unsigned int i;
+
+ for (i = 0; i < efi_allocated_memory_idx; i++) {
+ grub_efi_free_pages (efi_allocated_memory[i].start_addr,
+ efi_allocated_memory[i].pages);
+ }
+}
+
#if 0
/* Print the memory map. */
static void
Index: grub-2.02~beta3/include/grub/efi/efi.h
===================================================================
--- grub-2.02~beta3.orig/include/grub/efi/efi.h
+++ grub-2.02~beta3/include/grub/efi/efi.h
@@ -51,6 +51,7 @@ EXPORT_FUNC(grub_efi_get_memory_map) (gr
grub_efi_uintn_t *map_key,
grub_efi_uintn_t *descriptor_size,
grub_efi_uint32_t *descriptor_version);
+void grub_efi_memory_fini (void);
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);

View File

@ -1,93 +0,0 @@
Index: grub-2.02~beta2/grub-core/kern/efi/init.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/efi/init.c
+++ grub-2.02~beta2/grub-core/kern/efi/init.c
@@ -25,6 +25,7 @@
#include <grub/env.h>
#include <grub/mm.h>
#include <grub/kernel.h>
+#include <grub/file.h>
grub_addr_t grub_modbase;
@@ -48,6 +49,67 @@ grub_efi_init (void)
void (*grub_efi_net_config) (grub_efi_handle_t hnd,
char **device,
char **path);
+static char *
+workaround_efi_firmware_path (const char *device, const char *path)
+{
+ char *config = NULL;;
+ char *config_upper = NULL;
+ char *path_upper = NULL;
+ char *ret_path = NULL;
+ grub_file_t config_fd = NULL;
+ char *s;
+
+ if (!device || !path)
+ return NULL;
+
+ /* only workaround if booting off from cd device */
+ if (grub_strncmp (device, "cd", 2) != 0)
+ goto quit;
+
+ config = grub_xasprintf ("(%s)%s/grub.cfg", device, path);
+ config_fd = grub_file_open (config);
+
+ /* everything's fine, so quit the workaround */
+ if (config_fd)
+ goto quit;
+
+ /* reset grub error state because noone else does... */
+ grub_errno = GRUB_ERR_NONE;
+
+ /* try again, this time upper case path */
+ path_upper = grub_strdup (path);
+ if (! path_upper)
+ goto quit;
+
+ s = path_upper;
+ for (; *s; s++) *s = grub_toupper(*s);
+
+ config_upper = grub_xasprintf ("(%s)%s/grub.cfg", device, path_upper);
+ if (! config_upper)
+ goto quit;
+
+ config_fd = grub_file_open (config_upper);
+
+ /* if config can be found by the upper case path, return it */
+ if (config_fd)
+ ret_path = grub_strdup (path_upper);
+
+quit:
+
+ if (config_fd)
+ grub_file_close (config_fd);
+
+ if (grub_errno)
+ grub_errno = GRUB_ERR_NONE;
+
+ if (config)
+ grub_free (config);
+
+ if (config_upper)
+ grub_free (config_upper);
+
+ return ret_path;
+}
void
grub_machine_get_bootlocation (char **device, char **path)
@@ -69,6 +131,12 @@ grub_machine_get_bootlocation (char **de
p = grub_strrchr (*path, '/');
if (p)
*p = '\0';
+
+ if ((p = workaround_efi_firmware_path (*device, *path)))
+ {
+ grub_free (*path);
+ *path = p;
+ }
}
}

View File

@ -1,103 +0,0 @@
---
grub-core/loader/efi/chainloader.c | 62 +++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 26 deletions(-)
Index: grub-2.02~beta2/grub-core/loader/efi/chainloader.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/loader/efi/chainloader.c
+++ grub-2.02~beta2/grub-core/loader/efi/chainloader.c
@@ -326,40 +326,41 @@ grub_secure_mode (void)
static grub_efi_boolean_t
read_header (void *data, grub_efi_uint32_t size, pe_coff_loader_image_context_t *context)
{
- grub_efi_guid_t guid = SHIM_LOCK_GUID;
- grub_efi_shim_lock_t *shim_lock;
- grub_efi_status_t status;
-
- shim_lock = grub_efi_locate_protocol (&guid, NULL);
+ char *msdos = (char *)data;
+ struct grub_pe32_header_no_msdos_stub *pe32 = (struct grub_pe32_header_no_msdos_stub *)data;
- if (!shim_lock)
+ if (size < sizeof (*pe32))
{
- grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol");
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid image");
return 0;
}
- status = shim_lock->context (data, size, context);
-
- if (status == GRUB_EFI_SUCCESS)
+ if (grub_memcmp (msdos, "MZ", 2) == 0)
{
- grub_dprintf ("chain", "context success\n");
- return 1;
+ grub_uint32_t off = *((grub_uint32_t *) (msdos + 0x3c));
+ pe32 = (struct grub_pe32_header_no_msdos_stub *) ((char *)data + off);
}
- switch (status)
+ if (grub_memcmp (pe32->signature, "PE\0\0", 4) != 0 ||
+ pe32->coff_header.machine != GRUB_PE32_MACHINE_X86_64 ||
+ pe32->optional_header.magic != GRUB_PE32_PE64_MAGIC)
{
- case GRUB_EFI_UNSUPPORTED:
- grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported");
- break;
- case GRUB_EFI_INVALID_PARAMETER:
- grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter");
- break;
- default:
- grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code");
- break;
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Not supported image");
+ return 0;
}
- return 0;
+ context->number_of_rva_and_sizes = pe32->optional_header.num_data_directories;
+ context->size_of_headers = pe32->optional_header.header_size;
+ context->image_size = pe32->optional_header.image_size;
+ context->image_address = pe32->optional_header.image_base;
+ context->entry_point = pe32->optional_header.entry_addr;
+ context->reloc_dir = &pe32->optional_header.base_relocation_table;
+ context->sec_dir = &pe32->optional_header.certificate_table;
+ context->number_of_sections = pe32->coff_header.num_sections;
+ context->pe_hdr = pe32;
+ context->first_section = (struct grub_pe32_section_table *)((char *)(&pe32->optional_header) + pe32->coff_header.optional_header_size);
+
+ return 1;
}
static void*
@@ -623,6 +624,9 @@ error_exit:
if (buffer)
efi_call_1 (b->free_pool, buffer);
+ if (grub_errno)
+ grub_print_error ();
+
return 0;
}
@@ -845,6 +849,19 @@ grub_cmd_chainloader (grub_command_t cmd
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
boot_image, fsize,
&image_handle);
+#ifdef SUPPORT_SECURE_BOOT
+ if (status == GRUB_EFI_SECURITY_VIOLATION && !grub_secure_mode())
+ {
+ /* If it failed with security violation while not in secure boot mode,
+ the firmware might be broken. We try to workaround on that by forcing
+ the SB method! (bsc#887793) */
+ grub_dprintf ("chain", "Possible firmware flaw! Security violation while not in secure boot mode.\n");
+ grub_file_close (file);
+ grub_loader_set (grub_secureboot_chainloader_boot,
+ grub_secureboot_chainloader_unload, 0);
+ return 0;
+ }
+#endif
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)

View File

@ -1,39 +0,0 @@
From: Raymund Will <rw@suse.com>
Subject: Use device part of chainloader target, if present.
References: bnc#871857, bnc#880177
Patch-Mainline: no
Otherwise chainloading is restricted to '$root', which might not even
be readable by EFI!
v1. use grub_file_get_device_name() to get device name
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/loader/efi/chainloader.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
Index: grub-2.02~beta2/grub-core/loader/efi/chainloader.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/loader/efi/chainloader.c
+++ grub-2.02~beta2/grub-core/loader/efi/chainloader.c
@@ -706,12 +706,16 @@ grub_cmd_chainloader (grub_command_t cmd
*(--p16) = 0;
}
+ grub_dprintf ("chain", "cmd='%s'\n", filename);
file = grub_file_open (filename);
if (! file)
goto fail;
- /* Get the root device's device path. */
- dev = grub_device_open (0);
+ /* Get the device path from filename. */
+ char *devname = grub_file_get_device_name (filename);
+ dev = grub_device_open (devname);
+ if (devname)
+ grub_free (devname);
if (! dev)
goto fail;

View File

@ -1,35 +0,0 @@
Index: grub-2.02~beta2/grub-core/Makefile.core.def
===================================================================
--- grub-2.02~beta2.orig/grub-core/Makefile.core.def
+++ grub-2.02~beta2/grub-core/Makefile.core.def
@@ -1921,13 +1921,13 @@ module = {
module = {
name = video_cirrus;
x86 = video/cirrus.c;
- enable = x86;
+ enable = x86_noefi;
};
module = {
name = video_bochs;
x86 = video/bochs.c;
- enable = x86;
+ enable = x86_noefi;
};
module = {
Index: grub-2.02~beta2/gentpl.py
===================================================================
--- grub-2.02~beta2.orig/gentpl.py
+++ grub-2.02~beta2/gentpl.py
@@ -80,6 +80,10 @@ GROUPS["fdt"] = [ "arm64_efi", "arm_uboo
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
+# x86 without efi
+GROUPS["x86_noefi"] = GROUPS["x86"][:]
+GROUPS["x86_noefi"].remove("i386_efi"); GROUPS["x86_noefi"].remove("x86_64_efi");
+
#
# Create platform => groups reverse map, where groups covering that
# platform are ordered by their sizes

View File

@ -1,59 +0,0 @@
From dc56925653819582777ddc5c761a56f52dddd8f1 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Wed, 1 Feb 2017 23:10:45 +0100
Subject: [PATCH] grub-core/video/efi_gop.c: Add support for BLT_ONLY adapters
EFI GOP has support for multiple different bitness types of frame buffers
and for a special "BLT only" type which is always defined to be RGBx.
Because grub2 doesn't ever directly access the frame buffer but instead
only renders graphics via the BLT interface anyway, we can easily support
these adapters.
The reason this has come up now is the emerging support for virtio-gpu
in OVMF. That adapter does not have the notion of a memory mapped frame
buffer and thus is BLT only.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
grub-core/video/efi_gop.c | 2 ++
include/grub/efi/graphics_output.h | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
index 7f9d1c2..c9e40e8 100644
--- a/grub-core/video/efi_gop.c
+++ b/grub-core/video/efi_gop.c
@@ -121,6 +121,7 @@ grub_video_gop_get_bpp (struct grub_efi_gop_mode_info *in)
{
case GRUB_EFI_GOT_BGRA8:
case GRUB_EFI_GOT_RGBA8:
+ case GRUB_EFI_GOT_BLT_ONLY:
return 32;
case GRUB_EFI_GOT_BITMASK:
@@ -187,6 +188,7 @@ grub_video_gop_fill_real_mode_info (unsigned mode,
switch (in->pixel_format)
{
case GRUB_EFI_GOT_RGBA8:
+ case GRUB_EFI_GOT_BLT_ONLY:
out->red_mask_size = 8;
out->red_field_pos = 0;
out->green_mask_size = 8;
diff --git a/include/grub/efi/graphics_output.h b/include/grub/efi/graphics_output.h
index 1297774..e438812 100644
--- a/include/grub/efi/graphics_output.h
+++ b/include/grub/efi/graphics_output.h
@@ -28,7 +28,8 @@ typedef enum
{
GRUB_EFI_GOT_RGBA8,
GRUB_EFI_GOT_BGRA8,
- GRUB_EFI_GOT_BITMASK
+ GRUB_EFI_GOT_BITMASK,
+ GRUB_EFI_GOT_BLT_ONLY,
}
grub_efi_gop_pixel_format_t;
--
1.8.5.6

View File

@ -1,166 +0,0 @@
From: Raymund Will <rw@suse.com>
Subject: Use chainloader to boot xen.efi under UEFI.
References: bnc#871857, bnc#879148
Patch-Mainline: no
As XEN on SLE12 is not multiboot2 ready, some very dirty hacking
is necessary to boot via xen.efi and separate configfile snippets
(as done in SLE11SP3 secureboot).
To that end said configfile snippets, xen efi-binaries, kernels and initrds
need to copied to the EFI system partition during 'grub2-mkconfig'!
V0:
- first, somewhat fragile version, without any sort of cleanup for ESP.
V1:
- add missing whitespace. (bnc879148)
V2:
- second, much less fragile version, using only one config file per
XEN hypervisor version with sections for different kernels, avoiding
useless duplicates for sym-linked hypervisors. and removing previously
installed files from ESP.
---
util/grub.d/20_linux_xen.in | 88 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 2 deletions(-)
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -21,6 +21,8 @@ prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
+ME=$(basename $0)
+
. "$pkgdatadir/grub-mkconfig_lib"
export TEXTDOMAIN=@PACKAGE@
@@ -36,9 +38,11 @@ CLASS="--class gnu-linux --class gnu --c
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
+ os=linux
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}"
+ os="$(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1)"
+ CLASS="--class ${os} ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
@@ -85,6 +89,31 @@ esac
title_correction_code=
+if [ -d /sys/firmware/efi ]; then
+ is_efi=true
+ err_msg=""
+ efi_dir="/boot/efi/efi/${os}"
+ grub_dir=/boot/@PACKAGE@
+ xen_dir=/usr/lib64/efi
+ for d in $grub_dir $efi_dir $xen_dir; do
+ [ ! -d "$d" ] || continue
+ err_msg="${err_msg}$ME: Essential directory '$d' not found!\n"
+ done
+ if ! [ -d "$efi_dir" -a -d "$grub_dir" -a -d "$xen_dir" ]; then
+ err_msg="${err_msg}$ME: XEN configuration skipped!\n"
+ else
+ rm -f $grub_dir/xen*.cfg
+ if [ -s $efi_dir/grub.xen-files ]; then
+ for f in $(sort $efi_dir/grub.xen-files| uniq); do
+ rm -f $efi_dir/$f
+ done
+ : > $efi_dir/grub.xen-files
+ fi
+ fi
+else
+ is_efi=false
+fi
+
linux_entry ()
{
os="$1"
@@ -122,6 +151,40 @@ linux_entry ()
save_default_entry | grub_add_tab | sed "s/^/$submenu_indentation/"
fi
+ if $is_efi; then
+ xen_cfg=${xen_basename/.efi/.cfg}
+ if [ "$section_count" = 0 ]; then
+ cat <<-EOF > $grub_dir/$xen_cfg
+ # disclaimer
+ [global]
+ #default=
+ EOF
+ fi
+ section_count=$(expr $section_count + 1)
+ if [ x$type != xrecovery ] ; then
+ section="config.$section_count"
+ else
+ section="failsafe.$section_count"
+ fi
+ cat <<-EOF >> $grub_dir/$xen_cfg
+
+ [$section]
+ options=${xen_args}
+ kernel=${basename} root=${linux_root_device_thisversion} ${args}
+ ramdisk=${initrd}
+ EOF
+ message="$(gettext_printf "Loading Xen %s with Linux %s ..." ${xen_version} ${version})"
+ sed "s/^/$submenu_indentation/" <<-EOF
+ echo '$(echo "$message" | grub_quote)'
+ chainloader \$cmdpath/${xen_basename} ${xen_basename} $section
+ }
+ EOF
+ for f in ${grub_dir}/$xen_cfg ${xen_dir}/${xen_basename} ${dirname}/${basename} ${dirname}/${initrd}; do
+ cp --preserve=timestamps $f $efi_dir
+ echo $(basename $f) >> $efi_dir/grub.xen-files
+ done
+ return
+ fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
fi
@@ -219,6 +282,24 @@ while [ "x${xen_list}" != "x" ] ; do
xen_dirname=`dirname ${current_xen}`
rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname`
xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"`
+ xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '`
+ if $is_efi; then
+ xen_basename=${xen_basename/.gz/.efi}
+ if ! [ -f ${xen_dir}/${xen_basename} ]; then
+ echo "Skip missing hypervisor $xen_dir/$xen_basename" >&2
+ continue
+ elif [ -L ${xen_dir}/${xen_basename} ]; then
+ xen_target=$(basename $(readlink -e ${xen_dir}/${xen_basename}))
+ if [ -f ${efi_dir}/${xen_target} ]; then
+ echo "Skip duplicate $xen_dir/$xen_basename for $xen_target" >&2
+ continue
+ fi
+ elif [ -n "$err_msg" ]; then
+ break
+ fi
+ gettext_printf "Found hypervisor: %s\n" "$current_xen" >&2
+ section_count=0
+ fi
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
@@ -283,7 +364,6 @@ while [ "x${xen_list}" != "x" ] ; do
if [ x"$is_top_level" != xtrue ]; then
echo ' }'
fi
- xen_list=`echo $xen_list | tr ' ' '\n' | fgrep -vx "$current_xen" | tr '\n' ' '`
done
# If at least one kernel was found, then we need to
@@ -293,3 +373,7 @@ if [ x"$is_top_level" != xtrue ]; then
fi
echo "$title_correction_code"
+
+if [ -n "$err_msg" ]; then
+ echo -en "$err_msg" >&2
+fi

View File

@ -1,27 +0,0 @@
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -260,7 +260,8 @@ export GRUB_DEFAULT \
GRUB_DISABLE_SUBMENU \
GRUB_CMDLINE_LINUX_RECOVERY \
GRUB_USE_LINUXEFI \
- SUSE_BTRFS_SNAPSHOT_BOOTING
+ SUSE_BTRFS_SNAPSHOT_BOOTING \
+ SUSE_CMDLINE_XENEFI
if test "x${grub_cfg}" != "x"; then
rm -f "${grub_cfg}.new"
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -176,7 +176,7 @@ linux_entry ()
message="$(gettext_printf "Loading Xen %s with Linux %s ..." ${xen_version} ${version})"
sed "s/^/$submenu_indentation/" <<-EOF
echo '$(echo "$message" | grub_quote)'
- chainloader \$cmdpath/${xen_basename} ${xen_basename} $section
+ chainloader \$cmdpath/${xen_basename} ${xen_basename} ${SUSE_CMDLINE_XENEFI} $section
}
EOF
for f in ${grub_dir}/$xen_cfg ${xen_dir}/${xen_basename} ${dirname}/${basename} ${dirname}/${initrd}; do

View File

@ -1,39 +0,0 @@
---
grub-core/video/efi_gop.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
--- a/grub-core/video/efi_gop.c
+++ b/grub-core/video/efi_gop.c
@@ -358,6 +358,7 @@ grub_video_gop_setup (unsigned int width
grub_err_t err;
unsigned bpp;
int found = 0;
+ int avoid_low_resolution = 1;
unsigned long long best_volume = 0;
unsigned int preferred_width = 0, preferred_height = 0;
grub_uint8_t *buffer;
@@ -376,8 +377,11 @@ grub_video_gop_setup (unsigned int width
}
}
+again:
/* Keep current mode if possible. */
- if (gop->mode->info)
+ if (gop->mode->info &&
+ (!avoid_low_resolution ||
+ (gop->mode->info->width >= 800 && gop->mode->info->height >= 600)))
{
bpp = grub_video_gop_get_bpp (gop->mode->info);
if (bpp && ((width == gop->mode->info->width
@@ -450,6 +454,11 @@ grub_video_gop_setup (unsigned int width
if (!found)
{
+ if (avoid_low_resolution && gop->mode->info)
+ {
+ avoid_low_resolution = 0;
+ goto again;
+ }
grub_dprintf ("video", "GOP: no mode found\n");
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
}

View File

@ -1,170 +0,0 @@
---
Makefile.util.def | 10 +++++-----
configure.ac | 1 +
grub-core/Makefile.core.def | 14 +++++---------
grub-core/osdep/unix/emuconsole.c | 5 +++--
4 files changed, 14 insertions(+), 16 deletions(-)
Index: grub-2.02~rc1/Makefile.util.def
===================================================================
--- grub-2.02~rc1.orig/Makefile.util.def
+++ grub-2.02~rc1/Makefile.util.def
@@ -352,7 +352,7 @@ program = {
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup';
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
program = {
@@ -373,7 +373,7 @@ program = {
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup';
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
program = {
@@ -389,7 +389,7 @@ program = {
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
program = {
@@ -420,7 +420,7 @@ program = {
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
data = {
@@ -1345,7 +1345,7 @@ program = {
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
program = {
Index: grub-2.02~rc1/grub-core/Makefile.core.def
===================================================================
--- grub-2.02~rc1.orig/grub-core/Makefile.core.def
+++ grub-2.02~rc1/grub-core/Makefile.core.def
@@ -1057,7 +1057,7 @@ module = {
module = {
name = videotest;
common = commands/videotest.c;
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
module = {
@@ -1470,7 +1470,7 @@ module = {
common = gfxmenu/gui_progress_bar.c;
common = gfxmenu/gui_util.c;
common = gfxmenu/gui_string_util.c;
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
module = {
@@ -1886,13 +1886,13 @@ module = {
name = gfxterm;
common = term/gfxterm.c;
enable = videomodules;
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
module = {
name = gfxterm_background;
common = term/gfxterm_background.c;
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
module = {
@@ -2005,9 +2005,7 @@ module = {
enable = i386_pc;
enable = i386_efi;
enable = x86_64_efi;
- enable = emu;
enable = xen;
- emu_condition = COND_NOT_s390x;
};
module = {
@@ -2054,7 +2052,7 @@ module = {
module = {
name = gfxterm_menu;
common = tests/gfxterm_menu.c;
- emu_condition = COND_NOT_s390x;
+ emu_condition = COND_NOT_emu;
};
module = {
@@ -2205,9 +2203,7 @@ module = {
enable = i386_pc;
enable = i386_efi;
enable = x86_64_efi;
- enable = emu;
enable = xen;
- emu_condition = COND_NOT_s390x;
};
module = {
Index: grub-2.02~rc1/configure.ac
===================================================================
--- grub-2.02~rc1.orig/configure.ac
+++ grub-2.02~rc1/configure.ac
@@ -1884,6 +1884,7 @@ AC_SUBST(BUILD_LIBM)
AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone])
AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
+AM_CONDITIONAL([COND_NOT_emu], [test x$platform != xemu])
AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi])
Index: grub-2.02~rc1/grub-core/osdep/unix/emuconsole.c
===================================================================
--- grub-2.02~rc1.orig/grub-core/osdep/unix/emuconsole.c
+++ grub-2.02~rc1/grub-core/osdep/unix/emuconsole.c
@@ -50,13 +50,12 @@ static struct termios new_tty;
static int console_mode = 0;
#define MAX_LEN 1023
-#if defined(__s390x__)
+
static int
dummy (void)
{
return 0;
}
-#endif
#if 0
static char msg[MAX_LEN+1];
static void
@@ -128,6 +127,7 @@ readkey (struct grub_term_input *term)
return -1;
}
+#if defined(__s390x__)
#define NO_KEY ((grub_uint8_t)-1)
static int
readkey_dumb (struct grub_term_input *term)
@@ -158,6 +158,7 @@ readkey_dumb (struct grub_term_input *te
p = c;
return c;
}
+#endif
static void
grub_dumb_putchar (struct grub_term_output *term,

View File

@ -1,33 +0,0 @@
From e2e0fe44cf2a03744e96f886f95ab2c2a8aed331 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Wed, 18 Jul 2012 14:54:32 +0800
Subject: [PATCH] fix error: terminal 'gfxterm' isn't found
References: bnc#771393
Patch-Mainline: no
If set GRUB_TERMINAL="gfxterm", the error message "terminal
'gfxterm' isn't found" will be logged to screen. This is caused
by GRUB_TERMINAL_INPUT erroneously set to gfxterm. This patch
fixes the issue by not setting it.
---
util/grub-mkconfig.in | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -150,7 +150,11 @@ fi
# XXX: should this be deprecated at some point?
if [ "x${GRUB_TERMINAL}" != "x" ] ; then
- GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
+# bnc#771393 - fix error: terminal 'gfxterm' isn't found.
+# by not specifying 'gfxterm' to GRUB_TERMINAL_INPUT
+ if [ "x${GRUB_TERMINAL}" != "xgfxterm" ]; then
+ GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
+ fi
GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
fi

View File

@ -1,37 +0,0 @@
From e7500166b343874447e6abf385a791998c77f4c4 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Wed, 26 Sep 2012 15:55:44 +0800
Subject: [PATCH] Silence error messages when translations are unavailable
From: Colin Watson <cjwatson@ubuntu.com>
References: bnc#771393
https://savannah.gnu.org/bugs/?35880
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/gettext/gettext.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
Index: grub-2.00/grub-core/gettext/gettext.c
===================================================================
--- grub-2.00.orig/grub-core/gettext/gettext.c
+++ grub-2.00/grub-core/gettext/gettext.c
@@ -424,9 +424,13 @@ grub_gettext_init_ext (struct grub_gette
grub_free (lang);
}
- if (locale[0] == 'e' && locale[1] == 'n'
- && (locale[2] == '\0' || locale[2] == '_'))
- grub_errno = err = GRUB_ERR_NONE;
+ /* If no translations are available, fall back to untranslated text. */
+ if (err == GRUB_ERR_FILE_NOT_FOUND)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+
return err;
}

View File

@ -1,130 +0,0 @@
From b411dc88b46890400a2e1ba0aa8650e00f738c23 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 19 Jul 2012 18:43:55 +0800
Subject: [PATCH] fix menu in xen host server
References: bnc#771689, bnc#757895
Patch-Mainline: no
When system is configred as "Xen Virtual Machines Host Server", the
grub2 menu is not well organized. We could see some issues on it.
- Many duplicated xen entries generated by links to xen hypervisor
- Non bootable kernel entries trying to boot xen kernel natively
- The -dbg xen hypervisor takes precedence over release version
This patch fixes above three issues.
v2:
References: bnc#877040
Create only hypervisor pointed by /boot/xen.gz symlink to not clutter
the menu with multiple versions and also not include -dbg. Use custom.cfg
if you need any other custom entries.
---
util/grub-mkconfig_lib.in | 5 +++++
util/grub.d/10_linux.in | 12 ++++++++++--
util/grub.d/20_linux_xen.in | 6 ++++--
3 files changed, 19 insertions(+), 4 deletions(-)
Index: grub-2.02~beta2/util/grub-mkconfig_lib.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig_lib.in
+++ grub-2.02~beta2/util/grub-mkconfig_lib.in
@@ -248,6 +248,11 @@ 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 ;;
+# bnc#757895 - Grub2 menu items incorrect when "Xen Virtual Machines Host Server" selected
+# The dbg version should be placed after release version
+ dbg-*:dbg-*) ;;
+ dbg-*:*) version_test_gt_a="" ;;
+ *:dbg-*) version_test_gt_b="" ;;
esac
version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
return "$?"
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -26,6 +26,12 @@ datarootdir="@datarootdir@"
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
+if [ ! -e /proc/xen/xsd_port -a -e /proc/xen ]; then
+# we're running on xen domU guest
+# prevent setting up nested virt on HVM or PV domU guest
+ exit 0
+fi
+
CLASS="--class gnu-linux --class gnu --class os --class xen"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
@@ -166,10 +172,18 @@ file_is_not_sym () {
esac
}
-xen_list=
-for i in /boot/xen*; do
- if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then xen_list="$xen_list $i" ; fi
-done
+# bnc#877040 - Duplicate entries for boot menu created
+# only create /boot/xen.gz symlink boot entry
+if test -L /boot/xen.gz; then
+ xen_list=`readlink -f /boot/xen.gz`
+else
+ # bnc#757895 - Grub2 menu items incorrect when "Xen Virtual Machines Host Server" selected
+ # wildcard expasion with correct suffix (.gz) for not generating many duplicated menu entries
+ xen_list=
+ for i in /boot/xen*.gz; do
+ if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then xen_list="$xen_list $i" ; fi
+ done
+fi
prepare_boot_cache=
boot_device_id=
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -209,6 +209,40 @@ while [ "x$list" != "x" ] ; do
fi
done
+ # try to get the kernel config if $linux is a symlink
+ if test -z "${config}" ; then
+ lnk_version=`basename \`readlink -f $linux\` | sed -e "s,^[^0-9]*-,,g"`
+ if (test -n ${lnk_version} && test -e "${dirname}/config-${lnk_version}") ; then
+ config="${dirname}/config-${lnk_version}"
+ fi
+ fi
+
+ # check if we are in xen domU
+ if [ ! -e /proc/xen/xsd_port -a -e /proc/xen ]; then
+ # we're running on xen domU guest
+ dmi=/sys/class/dmi/id
+ if [ -r "${dmi}/product_name" -a -r "${dmi}/sys_vendor" ]; then
+ product_name=`cat ${dmi}/product_name`
+ sys_vendor=`cat ${dmi}/sys_vendor`
+ if test "${sys_vendor}" = "Xen" -a "${product_name}" = "HVM domU"; then
+ # xen HVM guest
+ xen_pv_domU=false
+ fi
+ fi
+ else
+ # we're running on baremetal or xen dom0
+ xen_pv_domU=false
+ fi
+
+ if test "$xen_pv_domU" = "false" ; then
+ # prevent xen kernel without pv_opt support from booting
+ if (grep -qx "CONFIG_XEN=y" "${config}" 2> /dev/null && ! grep -qx "CONFIG_PARAVIRT=y" "${config}" 2> /dev/null); then
+ echo "Skip xenlinux kernel $linux" >&2
+ list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
+ continue
+ fi
+ fi
+
initramfs=
if test -n "${config}" ; then
initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`

View File

@ -1,44 +0,0 @@
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -45,12 +45,14 @@ esac
# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
-if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
- || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
+ || uses_abstraction "${GRUB_DEVICE}" lvm ) && test -e "${GRUB_DEVICE}"; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
- LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
+ if [ "x${GRUB_DEVICE_UUID}" != "x" ]; then
+ LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
+ fi
fi
if [ "x$GRUB_CONMODE" != "x" ]; then
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -55,12 +55,14 @@ esac
# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
-if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
- || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
+ || uses_abstraction "${GRUB_DEVICE}" lvm ) && test -e "${GRUB_DEVICE}"; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
- LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
+ if [ "x${GRUB_DEVICE_UUID}" != "x" ]; then
+ LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
+ fi
fi
# Allow overriding GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT.

View File

@ -1,68 +0,0 @@
From: Michael Chang <mchang@suse.com>
Subject: treat mdadm ddf fakeraid as simple device
References: bnc#872360
Patch-Mainline: no
Index: grub-2.02~beta2/grub-core/osdep/linux/getroot.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/osdep/linux/getroot.c
+++ grub-2.02~beta2/grub-core/osdep/linux/getroot.c
@@ -117,7 +117,7 @@ struct btrfs_ioctl_search_args {
struct btrfs_ioctl_fs_info_args)
static int
-grub_util_is_imsm (const char *os_dev);
+grub_util_is_imsm_or_ddf (const char *os_dev);
#define ESCAPED_PATH_MAX (4 * PATH_MAX)
@@ -603,10 +603,10 @@ out:
}
static int
-grub_util_is_imsm (const char *os_dev)
+grub_util_is_imsm_or_ddf (const char *os_dev)
{
int retry;
- int is_imsm = 0;
+ int is_imsm_or_ddf = 0;
int container_seen = 0;
const char *dev = os_dev;
@@ -667,10 +667,17 @@ grub_util_is_imsm (const char *os_dev)
if (strncmp (buf, "MD_METADATA=imsm",
sizeof ("MD_METADATA=imsm") - 1) == 0)
{
- is_imsm = 1;
+ is_imsm_or_ddf = 1;
grub_util_info ("%s is imsm", dev);
break;
}
+ if (strncmp (buf, "MD_METADATA=ddf",
+ sizeof ("MD_METADATA=ddf") - 1) == 0)
+ {
+ is_imsm_or_ddf = 1;
+ grub_util_info ("%s is ddf", dev);
+ break;
+ }
}
free (buf);
@@ -681,7 +688,7 @@ grub_util_is_imsm (const char *os_dev)
if (dev != os_dev)
free ((void *) dev);
- return is_imsm;
+ return is_imsm_or_ddf;
}
char *
@@ -1018,7 +1025,7 @@ grub_util_get_dev_abstraction_os (const
/* Check for RAID. */
if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev)
- && !grub_util_is_imsm (os_dev))
+ && !grub_util_is_imsm_or_ddf (os_dev))
return GRUB_DEV_ABSTRACTION_RAID;
return GRUB_DEV_ABSTRACTION_NONE;
}

View File

@ -1,48 +0,0 @@
From: Michael Chang <mchang@suse.com>
The same as in the previous patch, add a support for installing grub
into an extended partition.
Here, we do not ignore extended partitions anymore. Instead we call a
hook that makes sure we have the partition when installing.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
References: https://bugzilla.novell.com/show_bug.cgi?id=750897
From: Andrey Borzenkov <arvidjaar@gmail.com>
Apply this logic only to primary extended partition. Ignore extended
partitions that are used to link together logical partitions.
References: https://bugzilla.novell.com/show_bug.cgi?id=785341
---
Index: grub-2.00/grub-core/partmap/msdos.c
===================================================================
--- grub-2.00.orig/grub-core/partmap/msdos.c
+++ grub-2.00/grub-core/partmap/msdos.c
@@ -188,13 +188,20 @@ grub_partition_msdos_iterate (grub_disk_
(unsigned long long) p.len);
/* If this partition is a normal one, call the hook. */
- if (! grub_msdos_partition_is_empty (e->type)
- && ! grub_msdos_partition_is_extended (e->type))
+ if (! grub_msdos_partition_is_empty (e->type))
{
- p.number++;
+ if (!grub_msdos_partition_is_extended (e->type) || p.number < 3)
+ {
+ p.number++;
- if (hook (disk, &p, hook_data))
- return grub_errno;
+ /* prevent someone doing mkfs or mkswap on an
+ extended partition, but leave room for LILO */
+ if (grub_msdos_partition_is_extended (e->type))
+ p.len = 2;
+
+ if (hook (disk, &p, hook_data))
+ return grub_errno;
+ }
}
else if (p.number < 3)
/* If this partition is a logical one, shouldn't increase the

View File

@ -1,21 +0,0 @@
From: Andrey Borzenkov <arvidjaar@gmail.com>
Subject: disable rsync to make it possible to use in RPM build
We need to create po/LINGUAS to generate message catalogs. Use
linguas.sh to ensure we always use the same rules as upstream, but
disable rsync.
Index: grub-2.02~beta2/linguas.sh
===================================================================
--- grub-2.02~beta2.orig/linguas.sh 2015-11-02 20:47:03.471686784 +0300
+++ grub-2.02~beta2/linguas.sh 2015-11-02 20:48:15.707687638 +0300
@@ -1,8 +1,8 @@
#!/bin/sh
-rsync -Lrtvz --exclude=ko.po translationproject.org::tp/latest/grub/ po
+#rsync -Lrtvz --exclude=ko.po translationproject.org::tp/latest/grub/ po
-autogenerated="en@quot en@hebrew de@hebrew en@cyrillic en@greek en@arabic en@piglatin de_CH"
+autogenerated="en@quot" # en@hebrew de@hebrew en@cyrillic en@greek en@arabic en@piglatin de_CH"
for x in $autogenerated; do

View File

@ -1,44 +1,13 @@
Index: grub-2.02~beta2/util/grub.d/10_linux.in
Index: util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -31,7 +31,7 @@ CLASS="--class gnu-linux --class gnu --c
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
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
@@ -129,7 +129,7 @@ linux_entry ()
message="$(gettext_printf "Loading Linux %s ..." ${version})"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
+ linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ${args}
--- util/grub.d/10_linux.in.orig
+++ util/grub.d/10_linux.in
@@ -49,7 +49,7 @@ menuentry "$1" {
EOF
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
cat << EOF
- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro $2
+ linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} $2
EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -31,7 +31,7 @@ CLASS="--class gnu-linux --class gnu --c
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
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
@@ -122,7 +122,7 @@ linux_entry ()
fi
multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts}
echo '$(echo "$lmessage" | grub_quote)'
- module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
+ module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ${args}
EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
cat << EOF

View File

@ -1,23 +0,0 @@
Index: grub-2.02~beta2/grub-core/normal/menu.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/normal/menu.c
+++ grub-2.02~beta2/grub-core/normal/menu.c
@@ -213,7 +213,17 @@ grub_menu_execute_entry(grub_menu_entry_
grub_size_t sz = 0;
if (entry->restricted)
- err = grub_auth_check_authentication (entry->users);
+ {
+ int auth_check = 1;
+ if (entry->users && entry->users[0] == 0)
+ {
+ const char *unr = grub_env_get ("unrestricted_menu");
+ if (unr && (unr[0] == '1' || unr[0] == 'y'))
+ auth_check = 0;
+ }
+ if (auth_check)
+ err = grub_auth_check_authentication (entry->users);
+ }
if (err)
{

View File

@ -1,14 +0,0 @@
grub-mkonfig: Look for Image-* on aarch64
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -190,6 +190,7 @@ EOF
machine=`uname -m`
case "x$machine" in
xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;;
+ xaarch64) klist="/boot/Image-* /Image-* /boot/kernel-*" ;;
xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;;
*) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \
/boot/kernel-*" ;;

View File

@ -1,12 +0,0 @@
Index: grub-2.02~beta3/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta3.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta3/util/grub.d/10_linux.in
@@ -193,6 +193,7 @@ machine=`uname -m`
case "x$machine" in
xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;;
xaarch64) klist="/boot/Image-* /Image-* /boot/kernel-*" ;;
+ xarm*) klist="/boot/zImage-* /zImage-* /boot/kernel-*" ;;
xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;;
*) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \
/boot/kernel-*" ;;

View File

@ -1,291 +0,0 @@
#!/usr/bin/perl
#
# (C) 2014 mchang@suse.com
#
# 2014-02-20 jw@suse.de
use strict;
my $grub2_dir;
my $grub2_reboot;
my $grub2_editenv;
my $show_mapped;
my $id_name;
my @menuentry;
my @enumentry;
my %E;
sub dPrint($) {
#print( STDERR @_[0]);
}
sub sh_test($) {
my ( $exp ) = @_;
dPrint( "?? '$exp' ");
$exp .= " ]" if ( $exp =~ m{^\[.*[^\]]\s*$} ); # gnaaa
#my $t = qx{set -x; $exp};
my $t = qx{$exp};
my $ret = $? >> 8;
$ret = ($ret == 0) ? 1 : 0;
dPrint("=> $ret ($t)\n");
return $ret;
}
sub read_cfg($$) {
my ($dir, $cfg) = @_;
my $fh;
my $m = "";
my $state = 1; # 1 == normal, 010 == if-false, 011 == if-true, 110 == else-false, 111 == else-true
my @State = ();
if ($dir) {
%E = ( "config_directory" => $dir );
dPrint("# VE: 'cd'='$dir'\n");
$dir .= "/";
if ($> == 0) {
open($fh, "$grub2_editenv - list |") || die "cannot read grub2 environment: $!\n";
while (<$fh>) {
chomp;
if ( m{^([^\s=]+?)=(.*)$} ) {
my ($k, $v) = ($1, $2);
$v =~ s{^"([^"]*)"$}{$1};
dPrint("# VE: '$k'='$v'\n");
$E{$k} = $v;
}
}
close($fh);
}
}
dPrint("# open($dir$cfg)\n");
open($fh, "<$dir$cfg") || die "cannot read $cfg in $dir: $!\n";
LINE: while ( <$fh> ) {
s{^#.*$}{}; # get rid of trailing comments,
s{\s+$}{}; # trailing whitespace
s{\s*;$}{}; # including semicolons
next if (m{^\s*$}); # and empty lines.
s{^\s*}{ }; # force leading whitespace to one
dPrint(sprintf("#%d: '%s' [%s]%04b\n", $., $_, join(",",@State), $state));
if ( m{^ fi$} ) {
$state = pop( @State);
$m .= "$_\n";
dPrint(sprintf(">FI: [%s]0b%04b\n", join(",",@State), $state));
next;
}
if ($state & 0b10) { # {if,else}-*
if ( m{^ elif\s+(.*?)\s*; then$} && !($state & 0b1000)) {
if ($state & 0b1) {
$state = 0b110; # else-false
} else {
$state = 0b010 + sh_test( $1); # if-?
dPrint(sprintf("=EI: 0b%03b\n", $state));
$m .= "$_\n";
next;
}
} elsif ( m{^ else$} && !($state & 0b1000)) {
if (($state & 0b111) == 0b010) { # in 'if' but neither 'else' nor 'true'
$state = 0b111; # else-true
} else {
$state = 0b110; # else-false
}
$m .= "$_\n";
dPrint(sprintf("=EL: 0b%03b\n", $state));
next;
}
}
if ($state & 0b1) { # *-true or normal
dPrint("-I1: $_\n");
} else { # *-false
dPrint("-I0: $_\n");
if ( m{^ if (.*?)\s*; then$} ) {
push( @State, $state);
$state = 0b1000;
$m .= "$_\n";
}
next;
}
while ( m'(?:[^\\])(\$(?:{([^}]+?)}|([A-Za-z0-9_]+)))' ) {
my ($s, $k1, $k2) = ($1, $2, $3);
my $k = (defined($k1)) ? $k1 : $k2;
dPrint("# VT: '$k'\n");
if (exists( $E{$k})) {
$s =~ s{([\$\{\}\"])}{\\$1}g;
dPrint("# VB: '$_'\n");
s{$s}{$E{$k}} || die;
dPrint("# VR: '$_'\n");
} else {
$s =~ s{([\$\{\}\"])}{\\$1}g;
s{$s}{} || die;
dPrint("# VR: '$_'\n");
}
}
if ( m{^ if (.*?)\s*; then$} ) {
push( @State, $state);
$state = 0b010 + sh_test( $1);
dPrint(sprintf("<IF: 0b%03b [%s]\n", $state, join (",", @State)));
} elsif ( m{^ (?:set\s+)?([^\s=]+?)=(.*)$} ) {
my ($k, $v) = ($1, $2);
$v =~ s{^"([^"]*)"$}{$1};
dPrint("# VA: '$k'='$v'\n");
$E{$k} = $v;
} elsif ( m{^ source\s+(\S+)$} ) {
my $f = $1;
$f =~ s{^"([^"]+)"$}{$1} &&
dPrint("# f='$f'\n");
if ( -r $f ) {
$m .= read_cfg("", $f);
}
next;
}
$m .= "$_\n";
}
close ($fh);
return ($m);
}
sub parse_menuentry($$$) {
my ($parent, $pId, $menu) = @_;
my $c = 0;
my @m = $menu =~ /(submenu|menuentry) \s+ (.*?) ( \{ (?: [^{}]* | (?3))* \} )/sxg;
for (my $i = 0; $i <= $#m; $i += 3) {
my $type = $m[$i];
my $title = `printf "%s\n" $m[$i+1] | head -1 | tr -d '\n'`;
my $data = $m[$i+2];
my $name = ($parent) ? "$parent>$title" : "$title";
my $eId = (($pId ne "") ? "$pId>" : "") . $c++;
if ($type eq "menuentry") {
push @menuentry, $name;
push @enumentry, [$name, $eId];
} elsif ($type eq "submenu") {
parse_menuentry ($name, $eId, $data);
}
}
}
# Enable restore grubenv service (bnc#892358)
# Restore grubenv settings for booting default entry to workaround the grub2-once cannot
# work and function properly on lvm, md and s390.
sub enable_restore_grubenv_service {
my $systemctl="/usr/bin/systemctl";
if (-x $systemctl) {
system "$systemctl --no-reload enable grub2-once >/dev/null 2>&1";
}
}
$id_name = "";
if (@ARGV == 2 && ($ARGV[0] eq "--show-mapped")) {
$show_mapped = 1;
$id_name = $ARGV[1];
} elsif (@ARGV == 1) {
$show_mapped = 0;
$id_name = $ARGV[0];
}
die "wrong command line options, try --help\n" if ($id_name eq "");
open(SYSCONF, "</etc/sysconfig/bootloader") || die "cannot read bootloader sysconfig: $!\n";
$grub2_dir = "";
while (<SYSCONF>) {
if (/^#/) {
next
};
if (/LOADER_TYPE="(.*)"/) {
my $bl = $1;
if ($bl eq "grub2" || $bl eq "grub2-efi") {
$grub2_dir = "/boot/grub2";
$grub2_reboot = "/usr/sbin/grub2-reboot";
$grub2_editenv = "/usr/bin/grub2-editenv";
}
last;
}
}
close (SYSCONF);
if ($id_name eq "--help" or $id_name eq "-h")
{
print "Usage: grub2-once [--show-mapped ID | --list | ID | NAME_SUBSTRING ]\n";
system "$grub2_reboot \"--help\"";
exit 0;
}
die "no grub2_dir" if ($grub2_dir eq "");
my $m = read_cfg( $grub2_dir, "grub.cfg");
# Note: only *one* top-level call to parse_menuentry() is possible
# or else it will start again with 0 (and no parent)!
parse_menuentry ("", "", $m);
my $ret = "";
my $name = "";
my $id = -1;
if ($id_name eq '--enum') {
foreach my $e (@enumentry) {
printf "%-7s %s\n", $e->[1], $e->[0];
}
exit 0;
}
if ($id_name eq '--list')
{
my $c = 0;
foreach my $e (@menuentry)
{
printf "%6d %s\n", $c, $e;
$c++;
}
exit 0;
}
if ($id_name =~ m!^[0-9]+$!) {
if ($id_name < @menuentry) {
$id = $id_name;
$name = $menuentry[$id];
$ret = $name;
}
} else {
my $i = -1;
my $c = 0;
$name = $id_name;
foreach my $e (@menuentry) {
if ($e =~ qr!\Q$name\E!) {
$i = $c;
last;
}
} continue {
++$c;
}
if ($i >= 0) {
$id = $i;
$name = $menuentry[$id];
$ret = "$id";
}
}
if ($show_mapped > 0) {
print $ret;
} else {
system "$grub2_reboot \"$name\"";
enable_restore_grubenv_service;
}

View File

@ -1,16 +0,0 @@
[Unit]
Description=Restore grubenv
DefaultDependencies=no
After=local-fs.target
Before=sysinit.target shutdown.target
Conflicts=shutdown.target
ConditionPathIsReadWrite=/boot/grub2/grubenv
[Service]
Type=oneshot
ExecStart=-/usr/bin/grub2-editenv /boot/grub2/grubenv unset next_entry
ExecStartPost=-/usr/bin/systemctl disable grub2-once.service
StandardOutput=syslog
[Install]
WantedBy=sysinit.target

View File

@ -1,131 +0,0 @@
From 340fd0c8717c2bf33163a18bfec72243b0e51862 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 30 Aug 2012 15:43:17 +0800
Subject: [PATCH] Pass corret root= for nfsroot
References: bnc#774548
Patch-Mainline: no
Fix / is mounted on nfs. The fix is to pass kernel parameters
with correct root= for nfs. However since grub2 doesn't support
nfs file system module, the /boot on nfs is not possible and
grub2-probe not work in probing nfs mounted path. The fix is merely
on the script level and not use grub2-probe for above reasons.
---
util/grub-mkconfig.in | 37 ++++++++++++++++++++++++++++++-------
1 files changed, 30 insertions(+), 7 deletions(-)
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -128,22 +128,47 @@ else
exit 1
fi
-# Device containing our userland. Typically used for root= parameter.
-GRUB_DEVICE="`${grub_probe} --target=device /`"
-GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
+probe_nfsroot_device () {
+ while read line ; do
+ part1=`echo $line | sed -e 's! - .*$!!'`
+ part2=`echo $line | sed -n -e 's! - \(.*\)$!\n\1!p' | sed 1d`
-# Device containing our /boot partition. Usually the same as GRUB_DEVICE.
-GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
-GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
+ set -- $part1
+ path=$5
+
+ set -- $part2
+ fstype=$1
+ device=$2
+
+ if [ "x${path}" = "x/" ] &&
+ [ "x${fstype}" = "xnfs" -o "x${fstype}" = "xnfs4" ] ; then
+ echo "${fstype}:$device"
+ return
+ fi
+ done
+} </proc/self/mountinfo
+
+NFSROOT_DEVICE="`probe_nfsroot_device`"
-# Filesystem for the device containing our userland. Used for stuff like
-# choosing Hurd filesystem module.
-GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`"
+if [ "x${NFSROOT_DEVICE}" != "x" ]; then
+ GRUB_DEVICE=""
+ GRUB_DEVICE_UUID=""
+ GRUB_FS="unknown"
+else
+ # Device containing our userland. Typically used for root= parameter.
+ GRUB_DEVICE="`${grub_probe} --target=device /`"
+ GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
-if [ x"$GRUB_FS" = xunknown ]; then
- GRUB_FS="$(stat -f --printf=%T / || echo unknown)"
+
+ if [ x"$GRUB_FS" = x ] || [ x"$GRUB_FS" = xunknown ]; then
+ GRUB_FS="$(stat -f --printf=%T / || echo unknown)"
+ fi
fi
+# Device containing our /boot partition. Usually the same as GRUB_DEVICE.
+GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
+GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
+
if test -f ${sysconfdir}/default/grub ; then
. ${sysconfdir}/default/grub
fi
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -74,6 +74,12 @@ linux_entry ()
type="$3"
args="$4"
+ if [ -n "${linux_root_device_thisversion}" ]; then
+ root_device="root=${linux_root_device_thisversion}"
+ else
+ root_device=""
+ fi
+
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
@@ -129,7 +135,7 @@ linux_entry ()
message="$(gettext_printf "Loading Linux %s ..." ${version})"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ${args}
+ linux ${rel_dirname}/${basename} ${root_device} ${args}
EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -89,6 +89,11 @@ linux_entry ()
type="$4"
args="$5"
xen_args="$6"
+ if [ -n "${linux_root_device_thisversion}" ]; then
+ root_device="root=${linux_root_device_thisversion}"
+ else
+ root_device=""
+ fi
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
@@ -128,7 +133,7 @@ linux_entry ()
fi
multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts}
echo '$(echo "$lmessage" | grub_quote)'
- module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ${args}
+ module ${rel_dirname}/${basename} placeholder ${root_device} ${args}
EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.

View File

@ -1,151 +0,0 @@
From e263907f50e496e602edd9bd846ccb6e0565a085 Mon Sep 17 00:00:00 2001
From: Mark Hamzy <hamzy@us.ibm.com>
Date: Wed, 28 Mar 2012 14:46:41 -0500
Subject: [PATCH] Migrate PPC from Yaboot to Grub2
Add configuration support for serial terminal consoles. This will set the
maximum screen size so that text is not overwritten.
---
Makefile.util.def | 7 +++
util/grub.d/20_ppc_terminfo.in | 114 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+), 0 deletions(-)
create mode 100644 util/grub.d/20_ppc_terminfo.in
Index: grub-2.02~beta2/Makefile.util.def
===================================================================
--- grub-2.02~beta2.orig/Makefile.util.def
+++ grub-2.02~beta2/Makefile.util.def
@@ -485,6 +485,13 @@ script = {
};
script = {
+ name = '20_ppc_terminfo';
+ common = util/grub.d/20_ppc_terminfo.in;
+ installdir = grubconf;
+ condition = COND_HOST_LINUX;
+};
+
+script = {
name = '30_os-prober';
common = util/grub.d/30_os-prober.in;
installdir = grubconf;
Index: grub-2.02~beta2/util/grub.d/20_ppc_terminfo.in
===================================================================
--- /dev/null
+++ grub-2.02~beta2/util/grub.d/20_ppc_terminfo.in
@@ -0,0 +1,114 @@
+#! /bin/sh
+set -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2006,2007,2008,2009,2010 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/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+libdir=@libdir@
+. "@datadir@/@PACKAGE@/grub-mkconfig_lib"
+
+export TEXTDOMAIN=@PACKAGE@
+export TEXTDOMAINDIR=@localedir@
+
+X=80
+Y=24
+TERMINAL=ofconsole
+
+argument () {
+ opt=$1
+ shift
+
+ if test $# -eq 0; then
+ echo "$0: option requires an argument -- '$opt'" 1>&2
+ exit 1
+ fi
+ echo $1
+}
+
+check_terminfo () {
+
+ while test $# -gt 0
+ do
+ option=$1
+ shift
+
+ case "$option" in
+ terminfo | TERMINFO)
+ ;;
+
+ -g)
+ NEWXY=`argument $option "$@"`
+ NEWX=`echo $NEWXY | cut -d x -f 1`
+ NEWY=`echo $NEWXY | cut -d x -f 2`
+
+ if [ ${NEWX} -ge 80 ] ; then
+ X=${NEWX}
+ else
+ echo "Warning: ${NEWX} is less than the minimum size of 80"
+ fi
+
+ if [ ${NEWY} -ge 24 ] ; then
+ Y=${NEWY}
+ else
+ echo "Warning: ${NEWY} is less than the minimum size of 24"
+ fi
+
+ shift
+ ;;
+
+ *)
+# # accept console or ofconsole
+# if [ "$option" != "console" -a "$option" != "ofconsole" ] ; then
+# echo "Error: GRUB_TERMINFO unknown console: $option"
+# exit 1
+# fi
+# # perfer console
+# TERMINAL=console
+ # accept ofconsole
+ if [ "$option" != "ofconsole" ] ; then
+ echo "Error: GRUB_TERMINFO unknown console: $option"
+ exit 1
+ fi
+ # perfer console
+ TERMINAL=ofconsole
+ ;;
+ esac
+
+ done
+
+}
+
+if ! uname -m | grep -q ppc ; then
+ exit 0
+fi
+
+if [ "x${GRUB_TERMINFO}" != "x" ] ; then
+ F1=`echo ${GRUB_TERMINFO} | cut -d " " -f 1`
+
+ if [ "${F1}" != "terminfo" ] ; then
+ echo "Error: GRUB_TERMINFO is set to \"${GRUB_TERMINFO}\" The first word should be terminfo."
+ exit 1
+ fi
+
+ check_terminfo ${GRUB_TERMINFO}
+fi
+
+cat << EOF
+ terminfo -g ${X}x${Y} ${TERMINAL}
+EOF

View File

@ -1,170 +0,0 @@
From 9d1411ffa7290c1cbdc9ee95bb5fcc5506e63e0f 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 096/152] 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 | 62 ++++++++++++++++++++++++++++++++++++++++
grub-core/normal/main.c | 19 ++++++++++++
grub-core/script/execute.c | 7 +++++
include/grub/ieee1275/ieee1275.h | 2 ++
4 files changed, 90 insertions(+)
Index: grub-2.02~beta2/grub-core/kern/ieee1275/openfw.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/ieee1275/openfw.c 2016-01-29 23:08:47.560532720 +0300
+++ grub-2.02~beta2/grub-core/kern/ieee1275/openfw.c 2016-01-29 23:08:47.556532720 +0300
@@ -590,3 +590,65 @@
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: %" PRIxGRUB_SIZE ")\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;
+}
Index: grub-2.02~beta2/grub-core/normal/main.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/normal/main.c 2016-01-29 23:08:47.560532720 +0300
+++ grub-2.02~beta2/grub-core/normal/main.c 2016-01-29 23:09:59.812533575 +0300
@@ -33,6 +33,9 @@
#include <grub/charset.h>
#include <grub/script_sh.h>
#include <grub/bufio.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif
GRUB_MOD_LICENSE ("GPLv3+");
@@ -275,6 +278,21 @@
{
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))
+ {
+ if (! grub_script_execute_sourcecode (script))
+ boot = 1;
+ }
+ grub_free (script);
+ if (boot)
+ grub_command_execute ("boot", 0, 0);
+#endif
+
/* Ignore any error. */
grub_errno = GRUB_ERR_NONE;
}
Index: grub-2.02~beta2/grub-core/script/execute.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/script/execute.c 2016-01-29 23:08:47.560532720 +0300
+++ grub-2.02~beta2/grub-core/script/execute.c 2016-01-29 23:08:47.560532720 +0300
@@ -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. */
@@ -877,6 +880,10 @@
grub_err_t ret = 0;
struct grub_script *parsed_script;
+#ifdef GRUB_MACHINE_IEEE1275
+ grub_ieee1275_set_boot_last_label (source);
+#endif
+
while (source)
{
char *line;
Index: grub-2.02~beta2/include/grub/ieee1275/ieee1275.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/ieee1275/ieee1275.h 2016-01-29 23:08:47.560532720 +0300
+++ grub-2.02~beta2/include/grub/ieee1275/ieee1275.h 2016-01-29 23:08:47.560532720 +0300
@@ -242,6 +242,8 @@
void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias);
void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath,
struct grub_ieee1275_devalias *alias);
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);
#define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));)

View File

@ -1,49 +0,0 @@
Index: grub-2.02~beta2/grub-core/kern/ieee1275/cmain.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/ieee1275/cmain.c
+++ grub-2.02~beta2/grub-core/kern/ieee1275/cmain.c
@@ -90,7 +90,10 @@ grub_ieee1275_find_options (void)
}
if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0)
- grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS);
+ {
+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS);
+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT);
+ }
/* Old Macs have no key repeat, newer ones have fully working one.
The ones inbetween when repeated key generates an escaoe sequence
Index: grub-2.02~beta2/grub-core/video/ieee1275.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/video/ieee1275.c
+++ grub-2.02~beta2/grub-core/video/ieee1275.c
@@ -351,9 +351,12 @@ static struct grub_video_adapter grub_vi
GRUB_MOD_INIT(ieee1275_fb)
{
- find_display ();
- if (display)
- grub_video_register (&grub_video_ieee1275_adapter);
+ if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT))
+ {
+ find_display ();
+ if (display)
+ grub_video_register (&grub_video_ieee1275_adapter);
+ }
}
GRUB_MOD_FINI(ieee1275_fb)
Index: grub-2.02~beta2/include/grub/ieee1275/ieee1275.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/ieee1275/ieee1275.h
+++ grub-2.02~beta2/include/grub/ieee1275/ieee1275.h
@@ -145,6 +145,8 @@ enum grub_ieee1275_flag
GRUB_IEEE1275_FLAG_BROKEN_REPEAT,
GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN,
+
+ GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT
};
extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);

View File

@ -1,84 +0,0 @@
Index: grub-2.02~beta2/grub-core/kern/ieee1275/openfw.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/ieee1275/openfw.c
+++ grub-2.02~beta2/grub-core/kern/ieee1275/openfw.c
@@ -302,6 +302,34 @@ grub_ieee1275_map (grub_addr_t phys, gru
return args.catch_result;
}
+/* Preallocate IEEE1275_MAX_MAP_RESOURCE map tracks to track the
+ * map regions allocated to us by the firmware. Cannot
+ * dynamically allocate them, since the heap is not set
+ * yet.
+ */
+struct grub_map_track grub_map_track[IEEE1275_MAX_MAP_RESOURCE];
+int grub_map_track_index=0;
+
+void
+grub_releasemap ()
+{
+ int i=0;
+ for (i=grub_map_track_index-1; i >= 0; i--)
+ grub_ieee1275_release(grub_map_track[i].addr, grub_map_track[i].size);
+ grub_map_track_index = 0;
+ return;
+}
+
+static void
+grub_track_map (grub_addr_t addr, grub_size_t size)
+{
+ if (grub_map_track_index >= IEEE1275_MAX_MAP_RESOURCE)
+ return;
+ grub_map_track[grub_map_track_index].addr = addr;
+ grub_map_track[grub_map_track_index++].size = size;
+ return;
+}
+
grub_err_t
grub_claimmap (grub_addr_t addr, grub_size_t size)
{
@@ -317,6 +345,7 @@ grub_claimmap (grub_addr_t addr, grub_si
return grub_errno;
}
+ grub_track_map (addr, size);
return GRUB_ERR_NONE;
}
Index: grub-2.02~beta2/include/grub/ieee1275/ieee1275.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/ieee1275/ieee1275.h
+++ grub-2.02~beta2/include/grub/ieee1275/ieee1275.h
@@ -30,6 +30,12 @@ struct grub_ieee1275_mem_region
unsigned int size;
};
+#define IEEE1275_MAX_MAP_RESOURCE 10
+struct grub_map_track {
+ grub_addr_t addr;
+ grub_size_t size;
+};
+
#define IEEE1275_MAX_PROP_LEN 8192
#define IEEE1275_MAX_PATH_LEN 256
@@ -214,6 +220,7 @@ int EXPORT_FUNC(grub_ieee1275_millisecon
grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
+void EXPORT_FUNC(grub_releasemap) (void);
int
EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt,
Index: grub-2.02~beta2/grub-core/kern/ieee1275/init.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/ieee1275/init.c
+++ grub-2.02~beta2/grub-core/kern/ieee1275/init.c
@@ -62,6 +62,7 @@ grub_addr_t grub_ieee1275_original_stack
void
grub_exit (void)
{
+ grub_releasemap();
grub_ieee1275_exit ();
}

View File

@ -1,304 +0,0 @@
From f38ada424e7d991a0121253ba1abc430b86a990b Mon Sep 17 00:00:00 2001
From: John Jolly <jjolly@suse.de>
Date: Wed, 22 Jan 2014 01:18:10 -0700
Subject: [PATCH 1/3] - Changes made and files added in order to allow s390x
build
---
grub-core/kern/emu/cache_s.S | 1 +
grub-core/kern/emu/lite.c | 2 ++
grub-core/kern/s390x/dl.c | 37 +++++++++++++++++++++++++++++++++++
grub-core/lib/s390x/setjmp.S | 46 ++++++++++++++++++++++++++++++++++++++++++++
grub-core/lib/setjmp.S | 2 ++
include/grub/cache.h | 2 +-
include/grub/s390x/setjmp.h | 29 ++++++++++++++++++++++++++++
include/grub/s390x/time.h | 27 ++++++++++++++++++++++++++
include/grub/s390x/types.h | 32 ++++++++++++++++++++++++++++++
9 files changed, 177 insertions(+), 1 deletion(-)
create mode 100644 grub-core/kern/s390x/dl.c
create mode 100644 grub-core/lib/s390x/setjmp.S
create mode 100644 include/grub/s390x/setjmp.h
create mode 100644 include/grub/s390x/time.h
create mode 100644 include/grub/s390x/types.h
Index: grub-2.02~beta2/grub-core/kern/emu/cache_s.S
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/emu/cache_s.S
+++ grub-2.02~beta2/grub-core/kern/emu/cache_s.S
@@ -9,6 +9,7 @@
#elif defined(__powerpc__)
#include "../powerpc/cache.S"
#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__)
+#elif defined(__s390x__)
#else
#error "No target cpu type is defined"
#endif
Index: grub-2.02~beta2/grub-core/kern/emu/lite.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/emu/lite.c
+++ grub-2.02~beta2/grub-core/kern/emu/lite.c
@@ -24,6 +24,8 @@
#elif defined(__aarch64__)
#include "../arm64/dl_helper.c"
#include "../arm64/dl.c"
+#elif defined(__s390x__)
+#include "../s390x/dl.c"
#else
#error "No target cpu type is defined"
#endif
Index: grub-2.02~beta2/grub-core/kern/dl.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/dl.c
+++ grub-2.02~beta2/grub-core/kern/dl.c
@@ -229,7 +229,7 @@ grub_dl_load_segments (grub_dl_t mod, co
unsigned i;
const Elf_Shdr *s;
grub_size_t tsize = 0, talign = 1;
-#if !defined (__i386__) && !defined (__x86_64__)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined (__s390x__)
grub_size_t tramp;
grub_size_t got;
grub_err_t err;
@@ -245,7 +245,7 @@ grub_dl_load_segments (grub_dl_t mod, co
talign = s->sh_addralign;
}
-#if !defined (__i386__) && !defined (__x86_64__)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined (__s390x__)
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
if (err)
return err;
@@ -308,7 +308,7 @@ grub_dl_load_segments (grub_dl_t mod, co
mod->segment = seg;
}
}
-#if !defined (__i386__) && !defined (__x86_64__)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined (__s390x__)
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
mod->tramp = ptr;
mod->trampptr = ptr;
Index: grub-2.02~beta2/grub-core/kern/s390x/dl.c
===================================================================
--- /dev/null
+++ grub-2.02~beta2/grub-core/kern/s390x/dl.c
@@ -0,0 +1,40 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2004,2005,2007,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/dl.h>
+
+/* Check if EHDR is a valid ELF header. */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+ (void)(ehdr);
+ return GRUB_ERR_BUG;
+}
+
+/* Relocate symbols. */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ Elf_Shdr *s, grub_dl_segment_t seg)
+{
+ (void)(mod);
+ (void)(ehdr);
+ (void)(s);
+ (void)(seg);
+ return GRUB_ERR_BUG;
+}
Index: grub-2.02~beta2/grub-core/lib/s390x/setjmp.S
===================================================================
--- /dev/null
+++ grub-2.02~beta2/grub-core/lib/s390x/setjmp.S
@@ -0,0 +1,46 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005,2007,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/symbol.h>
+#include <grub/dl.h>
+
+ .file "setjmp.S"
+
+GRUB_MOD_LICENSE "GPLv3+"
+
+ .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+ stmg %r11,%r15,0(%r2)
+ lghi %r2,0
+ br %r14
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+ chi %r3,0
+ jne .L2
+ lghi %r3,1
+.L2:
+ lmg %r11,%r15,0(%r2)
+ lgr %r2,%r3
+ br %r14
Index: grub-2.02~beta2/grub-core/lib/setjmp.S
===================================================================
--- grub-2.02~beta2.orig/grub-core/lib/setjmp.S
+++ grub-2.02~beta2/grub-core/lib/setjmp.S
@@ -15,6 +15,8 @@
#include "./arm/setjmp.S"
#elif defined(__aarch64__)
#include "./arm64/setjmp.S"
+#elif defined(__s390x__)
+#include "./s390x/setjmp.S"
#else
#error "Unknown target cpu type"
#endif
Index: grub-2.02~beta2/include/grub/cache.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/cache.h
+++ grub-2.02~beta2/include/grub/cache.h
@@ -23,7 +23,7 @@
#include <grub/symbol.h>
#include <grub/types.h>
-#if defined (__i386__) || defined (__x86_64__)
+#if defined (__i386__) || defined (__x86_64__) || defined (__s390x__)
static inline void
grub_arch_sync_caches (void *address __attribute__ ((unused)),
grub_size_t len __attribute__ ((unused)))
Index: grub-2.02~beta2/include/grub/s390x/setjmp.h
===================================================================
--- /dev/null
+++ grub-2.02~beta2/include/grub/s390x/setjmp.h
@@ -0,0 +1,29 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2004,2006,2007,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/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+#include <grub/types.h>
+
+typedef grub_uint64_t grub_jmp_buf[5];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
Index: grub-2.02~beta2/include/grub/s390x/time.h
===================================================================
--- /dev/null
+++ grub-2.02~beta2/include/grub/s390x/time.h
@@ -0,0 +1,27 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 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 KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
Index: grub-2.02~beta2/include/grub/s390x/types.h
===================================================================
--- /dev/null
+++ grub-2.02~beta2/include/grub/s390x/types.h
@@ -0,0 +1,32 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2004,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_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER 1
+
+/* The size of void *. */
+#define GRUB_TARGET_SIZEOF_VOID_P 8
+
+/* The size of long. */
+#define GRUB_TARGET_SIZEOF_LONG 8
+
+/* s390x is big-endian. */
+#define GRUB_TARGET_WORDS_BIGENDIAN 1
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */

View File

@ -1,342 +0,0 @@
---
grub-core/Makefile.am | 1
grub-core/Makefile.core.def | 2
grub-core/kern/emu/main.c | 4
grub-core/kern/emu/misc.c | 18 ++++
grub-core/loader/emu/linux.c | 173 +++++++++++++++++++++++++++++++++++++++++++
include/grub/emu/exec.h | 4
include/grub/emu/hostfile.h | 3
include/grub/emu/misc.h | 3
8 files changed, 204 insertions(+), 4 deletions(-)
Index: grub-2.02~beta2/grub-core/Makefile.core.def
===================================================================
--- grub-2.02~beta2.orig/grub-core/Makefile.core.def 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/grub-core/Makefile.core.def 2016-01-29 22:59:52.240526390 +0300
@@ -1667,9 +1667,9 @@
ia64_efi = loader/ia64/efi/linux.c;
arm = loader/arm/linux.c;
arm64 = loader/arm64/linux.c;
+ emu = loader/emu/linux.c;
common = loader/linux.c;
common = lib/cmdline.c;
- enable = noemu;
};
module = {
Index: grub-2.02~beta2/grub-core/loader/emu/linux.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ grub-2.02~beta2/grub-core/loader/emu/linux.c 2016-01-29 22:59:52.240526390 +0300
@@ -0,0 +1,173 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008,2009,2010 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/loader.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/time.h>
+
+#include <grub/emu/exec.h>
+#include <grub/emu/hostfile.h>
+#include <grub/emu/misc.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_dl_t my_mod;
+
+static char *kernel_path;
+static char *initrd_path;
+static char *boot_cmdline;
+
+static grub_err_t
+grub_linux_boot (void)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+ char *initrd_param;
+ const char *kexec[] = { "kexec", "-l", kernel_path, boot_cmdline, NULL, NULL };
+ const char *systemctl[] = { "systemctl", "kexec", NULL };
+ int kexecute = grub_util_get_kexecute();
+
+ if (initrd_path) {
+ initrd_param = grub_xasprintf("--initrd=%s", initrd_path);
+ kexec[3] = initrd_param;
+ kexec[4] = boot_cmdline;
+ } else {
+ initrd_param = grub_xasprintf("%s", "");
+ //return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("initrd required!"));
+ }
+
+ grub_printf("%serforming 'kexec -l %s %s %s'\n",
+ (kexecute) ? "P" : "Not p",
+ kernel_path, initrd_param, boot_cmdline);
+
+ if (kexecute)
+ rc = grub_util_exec(kexec);
+
+ grub_free(initrd_param);
+
+ if (rc != GRUB_ERR_NONE) {
+ grub_error (rc, N_("Error trying to perform kexec load operation."));
+ grub_sleep (3);
+ return rc;
+ }
+ if (kexecute < 1)
+ grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart."));
+
+ grub_printf("Performing 'systemctl kexec' (%s) ",
+ (kexecute==1) ? "do-or-die" : "just-in-case");
+ rc = grub_util_exec (systemctl);
+
+ if (kexecute == 1)
+ grub_fatal (N_("Error trying to perform 'systemctl kexec'"));
+
+ /* need to check read-only root before resetting hard!? */
+ grub_printf("Performing 'kexec -e'");
+ kexec[1] = "-e";
+ kexec[2] = NULL;
+ rc = grub_util_exec(kexec);
+ if ( rc != GRUB_ERR_NONE )
+ grub_fatal (N_("Error trying to directly perform 'kexec -e'."));
+
+ return rc;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+ grub_dl_unref (my_mod);
+ if ( boot_cmdline != NULL )
+ grub_free (boot_cmdline);
+ boot_cmdline = NULL;
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[])
+{
+ int i;
+ char *tempstr;
+
+ grub_dl_ref (my_mod);
+
+ if (argc == 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+
+ if ( !grub_util_is_regular(argv[0]) )
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find kernel file %s"), argv[0]);
+
+ if ( kernel_path != NULL )
+ grub_free(kernel_path);
+
+ kernel_path = grub_xasprintf("%s", argv[0]);
+
+ if ( boot_cmdline != NULL ) {
+ grub_free(boot_cmdline);
+ boot_cmdline = NULL;
+ }
+
+ if ( argc > 1 )
+ {
+ boot_cmdline = grub_xasprintf("--command-line=%s", argv[1]);
+ for ( i = 2; i < argc; i++ ) {
+ tempstr = grub_xasprintf("%s %s", boot_cmdline, argv[i]);
+ grub_free(boot_cmdline);
+ boot_cmdline = tempstr;
+ }
+ }
+
+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[])
+{
+ if (argc == 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+
+ if ( !grub_util_is_regular(argv[0]) )
+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find initrd file %s"), argv[0]);
+
+ if ( initrd_path != NULL )
+ grub_free(initrd_path);
+
+ initrd_path = grub_xasprintf("%s", argv[0]);
+
+ grub_dl_unref (my_mod);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+ cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, N_("Load Linux."));
+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0, N_("Load initrd."));
+ my_mod = mod;
+ kernel_path = NULL;
+ initrd_path = NULL;
+ boot_cmdline = NULL;
+}
+
+GRUB_MOD_FINI(linux)
+{
+ grub_unregister_command (cmd_linux);
+ grub_unregister_command (cmd_initrd);
+}
Index: grub-2.02~beta2/include/grub/emu/hostfile.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/emu/hostfile.h 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/include/grub/emu/hostfile.h 2016-01-29 22:59:52.240526390 +0300
@@ -22,6 +22,7 @@
#include <grub/disk.h>
#include <grub/partition.h>
#include <sys/types.h>
+#include <grub/symbol.h>
#include <grub/osdep/hostfile.h>
int
@@ -29,7 +30,7 @@
int
grub_util_is_special_file (const char *path);
int
-grub_util_is_regular (const char *path);
+EXPORT_FUNC(grub_util_is_regular) (const char *path);
char *
grub_util_path_concat (size_t n, ...);
Index: grub-2.02~beta2/include/grub/emu/exec.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/emu/exec.h 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/include/grub/emu/exec.h 2016-01-29 22:59:52.240526390 +0300
@@ -23,6 +23,8 @@
#include <stdarg.h>
#include <sys/types.h>
+#include <grub/symbol.h>
+
pid_t
grub_util_exec_pipe (const char *const *argv, int *fd);
pid_t
@@ -32,7 +34,7 @@
grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file,
const char *stdout_file, const char *stderr_file);
int
-grub_util_exec (const char *const *argv);
+EXPORT_FUNC(grub_util_exec) (const char *const *argv);
int
grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
const char *stdout_file);
Index: grub-2.02~beta2/grub-core/Makefile.am
===================================================================
--- grub-2.02~beta2.orig/grub-core/Makefile.am 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/grub-core/Makefile.am 2016-01-29 22:59:52.240526390 +0300
@@ -258,6 +258,7 @@
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/exec.h
if COND_GRUB_EMU_SDL
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h
endif
Index: grub-2.02~beta2/grub-core/kern/emu/main.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/emu/main.c 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/grub-core/kern/emu/main.c 2016-01-29 22:59:52.240526390 +0300
@@ -106,6 +106,7 @@
N_("use GRUB files in the directory DIR [default=%s]"), 0},
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
{"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL, N_("wait until a debugger will attach"), 0},
+ {"kexec", 'X', 0, 0, N_("try the untryable."), 0},
{ 0, 0, 0, 0, 0, 0 }
};
@@ -163,6 +164,9 @@
case 'v':
verbosity++;
break;
+ case 'X':
+ grub_util_set_kexecute();
+ break;
case ARGP_KEY_ARG:
{
Index: grub-2.02~beta2/grub-core/kern/emu/misc.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/emu/misc.c 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/grub-core/kern/emu/misc.c 2016-01-29 22:59:52.240526390 +0300
@@ -37,6 +37,7 @@
#include <grub/emu/misc.h>
int verbosity;
+int kexecute;
void
grub_util_warn (const char *fmt, ...)
@@ -80,7 +81,7 @@
vfprintf (stderr, fmt, ap);
va_end (ap);
fprintf (stderr, ".\n");
- exit (1);
+ grub_exit ();
}
void *
@@ -138,6 +139,9 @@
void
grub_exit (void)
{
+#if defined (GRUB_KERNEL)
+ grub_reboot();
+#endif
exit (1);
}
#endif
@@ -199,3 +203,15 @@
fclose (fp);
}
+
+void
+grub_util_set_kexecute(void)
+{
+ kexecute++;
+}
+
+int
+grub_util_get_kexecute(void)
+{
+ return kexecute;
+}
Index: grub-2.02~beta2/include/grub/emu/misc.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/emu/misc.h 2016-01-29 22:59:52.244526390 +0300
+++ grub-2.02~beta2/include/grub/emu/misc.h 2016-01-29 22:59:52.240526390 +0300
@@ -60,6 +60,9 @@
void EXPORT_FUNC(grub_util_info) (const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2)));
void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2), noreturn));
+void EXPORT_FUNC(grub_util_set_kexecute) (void);
+int EXPORT_FUNC(grub_util_get_kexecute) (void) WARN_UNUSED_RESULT;
+
grub_uint64_t EXPORT_FUNC (grub_util_get_cpu_time_ms) (void);
#ifdef HAVE_DEVICE_MAPPER

View File

@ -1,530 +0,0 @@
Vn:
* recognize 'dev/sclp_line0' as 3215-look-alike. [bnc#876743]
Vn+1:
* revamp readkey_dumb().
Vn+2:
* support hotkeys on all line-mode terminals, not only 3215. [bnc#885668]
---
grub-core/kern/emu/main.c | 8 +
grub-core/normal/menu_text.c | 54 +++++++-
grub-core/normal/term.c | 2
grub-core/osdep/unix/emuconsole.c | 238 +++++++++++++++++++++++++++++++++++++-
include/grub/term.h | 4
5 files changed, 294 insertions(+), 12 deletions(-)
--- a/grub-core/osdep/unix/emuconsole.c
+++ b/grub-core/osdep/unix/emuconsole.c
@@ -39,17 +39,61 @@
#include <grub/emu/console.h>
+#include <stdio.h>
+#include <errno.h>
+
extern struct grub_terminfo_output_state grub_console_terminfo_output;
static int original_fl;
static int saved_orig;
static struct termios orig_tty;
static struct termios new_tty;
+static int console_mode = 0;
+
+#define MAX_LEN 1023
+#if defined(__s390x__)
+static int
+dummy (void)
+{
+ return 0;
+}
+#endif
+#if 0
+static char msg[MAX_LEN+1];
+static void
+dprint (int len)
+{
+ if (len < 0)
+ return;
+ if (len > MAX_LEN)
+ len = MAX_LEN;
+ write (2, msg, len);
+}
+#define dprintf(fmt, vargs...) dprint(snprintf(msg, MAX_LEN, fmt, ## vargs))
+#else
+#define dprintf(fmt, vargs...) {}
+#endif
static void
-put (struct grub_term_output *term __attribute__ ((unused)), const int c)
+put (struct grub_term_output *term, const int c)
{
char chr = c;
ssize_t actual;
+ struct grub_terminfo_output_state *data
+ = (struct grub_terminfo_output_state *) term->data;
+
+ if (term->flags & GRUB_TERM_DUMB) {
+ if (c == '\n') {
+ data->pos.y++;
+ data->pos.x = 0;
+ } else {
+ data->pos.x++;
+ }
+ if (0) {
+ if (c == ' ') chr = '_';
+ if (c == GRUB_TERM_BACKSPACE) chr = '{';
+ if (c == '\b') chr = '<';
+ }
+ }
actual = write (STDOUT_FILENO, &chr, 1);
if (actual < 1)
@@ -60,17 +104,152 @@ put (struct grub_term_output *term __att
}
static int
-readkey (struct grub_term_input *term __attribute__ ((unused)))
+readkey (struct grub_term_input *term)
{
grub_uint8_t c;
ssize_t actual;
+ fd_set readfds;
+ struct timeval timeout;
+ int sel;
+ FD_SET (0, &readfds);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500000;
+ if ((sel=select (1, &readfds, (fd_set *)0, (fd_set *)0, &timeout)) <= 0)
+ {
+ if (sel < 0 && errno == EINTR)
+ return 0x03; /* '^C' */
+ return -1;
+ }
+
actual = read (STDIN_FILENO, &c, 1);
if (actual > 0)
return c;
return -1;
}
+#define NO_KEY ((grub_uint8_t)-1)
+static int
+readkey_dumb (struct grub_term_input *term)
+{
+ grub_uint8_t c;
+ static grub_uint8_t p = NO_KEY;
+
+ c = readkey (term);
+ if (c == NO_KEY)
+ return -1;
+ if ((p == '^' || p == '\n') && c == '\n') /* solitary '^' or '\n'? */
+ {
+ c = p; /* use immediately! */
+ p = '\n';
+ }
+ else if ((c == '\n' || c == '^') && p != c) /* non-duplicate specials? */
+ {
+ p = c; /* remember! */
+ c = NO_KEY;
+ }
+ else if (p == '^')
+ {
+ if (c != '^')
+ c &= 0x1F;
+ p = NO_KEY;
+ }
+ else
+ p = c;
+ return c;
+}
+
+static void
+grub_dumb_putchar (struct grub_term_output *term,
+ const struct grub_unicode_glyph *c)
+{
+ unsigned i;
+
+ /* For now, do not try to use a surrogate pair. */
+ if (c->base > 0xffff)
+ put (term, '?');
+ else
+ put (term, (c->base & 0xffff));
+
+ if (0) {
+ for (i = 0; i < c->ncomb; i++)
+ if (c->base < 0xffff)
+ put (term, grub_unicode_get_comb (c)[i].code);
+ }
+}
+
+static struct grub_term_coordinate
+grub_dumb_getxy (struct grub_term_output *term)
+{
+ struct grub_terminfo_output_state *data
+ = (struct grub_terminfo_output_state *) term->data;
+
+ dprintf ("<%d,%d>", data->pos.x, data->pos.y);
+ return data->pos;
+}
+
+static struct grub_term_coordinate
+grub_dumb_getwh (struct grub_term_output *term)
+{
+ static int once = 0;
+ struct grub_terminfo_output_state *data
+ = (struct grub_terminfo_output_state *) term->data;
+
+ if (!once++)
+ dprintf ("dumb_getwh: w=%d h=%d\n", data->size.x, data->size.y);
+ return data->size;
+}
+
+static void
+grub_dumb_gotoxy (struct grub_term_output *term,
+ struct grub_term_coordinate pos)
+{
+ struct grub_terminfo_output_state *data
+ = (struct grub_terminfo_output_state *) term->data;
+
+ if (pos.x > grub_term_width (term) || pos.y > grub_term_height (term))
+ {
+ grub_error (GRUB_ERR_BUG, "invalid point (%u,%u)", pos.x, pos.y);
+ return;
+ }
+
+ dprintf("goto(%d,%d)", pos.x, pos.y);
+ if (pos.x > (grub_term_width (term) - 4)) {
+ dprintf (" really?");
+ //return;
+ }
+
+ if (data->gotoxy)
+ {
+ int i;
+ dprintf ("data-gotoxy");
+ if (data->pos.y != pos.y) {
+ put (term, '\n');
+
+ for (i = 1; i < pos.x; i++ )
+ put (term, ' ');
+ }
+ }
+ else
+ {
+ int i = 0;
+ if (data->pos.y != pos.y || data->pos.x > pos.x) {
+ if (data->pos.y >= pos.y) data->pos.y = pos.y - 1;
+ if (pos.y - data->pos.y > 3) data->pos.y = pos.y - 2;
+ dprintf (" <%dnl>+%d", (pos.y - data->pos.y), pos.x);
+ for (i = data->pos.y; i < pos.y; i++ )
+ put (term, '\n');
+ }
+ for (i = data->pos.x; i < pos.x; i++ )
+ put (term, ' ');
+ dprintf ("#%d", i);
+ grub_dumb_getxy (term);
+ }
+
+ dprintf ("\n");
+ data->pos = pos;
+}
+
static grub_err_t
grub_console_init_input (struct grub_term_input *term)
{
@@ -105,7 +284,8 @@ static grub_err_t
grub_console_init_output (struct grub_term_output *term)
{
struct winsize size;
- if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0)
+ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0 &&
+ size.ws_col > 0 && size.ws_row > 0)
{
grub_console_terminfo_output.size.x = size.ws_col;
grub_console_terminfo_output.size.y = size.ws_row;
@@ -115,6 +295,8 @@ grub_console_init_output (struct grub_te
grub_console_terminfo_output.size.x = 80;
grub_console_terminfo_output.size.y = 24;
}
+ if (console_mode == 3215)
+ grub_console_terminfo_output.size.x -= 1;
grub_terminfo_output_init (term);
@@ -161,24 +343,72 @@ static struct grub_term_output grub_cons
void
grub_console_init (void)
{
+#if ! defined(__s390x__)
const char *cs = nl_langinfo (CODESET);
if (cs && grub_strcasecmp (cs, "UTF-8"))
grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL;
else
grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII;
+#else
+ char link[MAX_LEN+1];
+ ssize_t len = readlink ("/proc/self/fd/0", link, MAX_LEN);
+
+ if (len > 0)
+ link[len] = 0;
+ else
+ link[0] = 0;
+ if (grub_strncmp ("/dev/ttyS", link, 9) == 0 )
+ console_mode = 3215;
+ else if (grub_strncmp ("/dev/3270/tty", link, 13) == 0 )
+ console_mode = 3270;
+ else if (grub_strncmp ("/dev/sclp_line", link, 14) == 0 )
+ console_mode = 3215;
+ grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII;
+ switch (console_mode)
+ {
+ case 3215:
+ grub_console_term_output.flags |= GRUB_TERM_DUMB;
+ /* FALLTHROUGH */
+ case 3270:
+ grub_console_term_output.flags |= GRUB_TERM_LINE;
+ grub_console_term_output.flags |= GRUB_TERM_NO_ECHO;
+ grub_console_terminfo_input.readkey = readkey_dumb;
+ break;
+ default:
+ break;
+ }
+#endif
+ if (grub_console_term_output.flags & GRUB_TERM_DUMB)
+ {
+ grub_console_term_output.putchar = grub_dumb_putchar,
+ grub_console_term_output.getxy = grub_dumb_getxy;
+ grub_console_term_output.getwh = grub_dumb_getwh;
+ grub_console_term_output.gotoxy = grub_dumb_gotoxy;
+ grub_console_term_output.cls = (void *) dummy;
+ grub_console_term_output.setcolorstate = (void *) dummy;
+ grub_console_term_output.setcursor = (void *) dummy;
+ grub_console_term_output.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE;
+ }
grub_term_register_input ("console", &grub_console_term_input);
grub_term_register_output ("console", &grub_console_term_output);
grub_terminfo_init ();
- grub_terminfo_output_register (&grub_console_term_output, "vt100-color");
+ grub_terminfo_output_register (&grub_console_term_output,
+ (grub_console_term_output.flags & GRUB_TERM_DUMB) ? "dumb":"vt100-color");
}
void
grub_console_fini (void)
{
+ dprintf( "grub_console_fini: %d\n", grub_console_term_output.flags & GRUB_TERM_DUMB);
if (saved_orig)
{
fcntl (STDIN_FILENO, F_SETFL, original_fl);
tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty);
}
+ if (!(grub_console_term_output.flags & GRUB_TERM_DUMB))
+ {
+ const char clear[] = { 0x1b, 'c', 0 };
+ write (STDOUT_FILENO, clear, 2);
+ }
saved_orig = 0;
}
--- a/grub-core/normal/menu_text.c
+++ b/grub-core/normal/menu_text.c
@@ -113,6 +113,7 @@ draw_border (struct grub_term_output *te
{
int i;
+ if (! (term->flags & GRUB_TERM_DUMB)) {
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
@@ -142,7 +143,7 @@ draw_border (struct grub_term_output *te
grub_putcode (GRUB_UNICODE_CORNER_LR, term);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-
+ }
grub_term_gotoxy (term,
(struct grub_term_coordinate) { geo->first_entry_x - 1,
(geo->first_entry_y - 1 + geo->num_entries
@@ -155,6 +156,15 @@ print_message (int nested, int edit, str
int ret = 0;
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+ if (edit && (term->flags & GRUB_TERM_LINE))
+ {
+ ret += grub_print_message_indented_real
+ (_("Minimum Emacs-like screen editing is supported. '^i' lists "
+ "completions. Type '^x' to boot, '^c' for a command-line "
+ "or '^[' to discard edits and return to the GRUB menu."),
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
+ }
+ else
if (edit)
{
ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \
@@ -165,10 +175,15 @@ command-line or ESC to discard edits and
}
else
{
+#if defined(__s390x__hotkey)
+ ret += grub_print_message_indented_real
+ (_("Select a menu option by pressing the hotkey specified. "),
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
+#else
char *msg_translated;
msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
- "entry is highlighted."),
+ "entry is highlighted. "),
GRUB_UNICODE_UPARROW,
GRUB_UNICODE_DOWNARROW);
if (!msg_translated)
@@ -177,6 +192,7 @@ command-line or ESC to discard edits and
STANDARD_MARGIN, term, dry_run);
grub_free (msg_translated);
+#endif
if (nested)
{
@@ -211,6 +227,10 @@ print_entry (int y, int highlight, grub_
title = entry ? entry->title : "";
title_len = grub_strlen (title);
+
+ if ((data->term->flags & GRUB_TERM_DUMB) && title[0] == '\0')
+ return;
+
unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
if (! unicode_title)
/* XXX How to show this error? */
@@ -244,6 +264,14 @@ print_entry (int y, int highlight, grub_
if (data->geo.num_entries > 1)
grub_putcode (highlight ? '*' : ' ', data->term);
+ if ((data->term->flags & GRUB_TERM_LINE) && title[0] != '\0') {
+ grub_putcode('(', data->term);
+ grub_putcode((entry && entry->hotkey >= '0' && entry->hotkey <= 'z') ?
+ entry->hotkey : ' ', data->term);
+ grub_putcode(')', data->term);
+ grub_putcode(' ', data->term);
+ }
+
grub_print_ucs4_menu (unicode_title,
unicode_title + len,
0,
@@ -413,6 +441,8 @@ grub_menu_init_page (int nested, int edi
grub_term_highlight_color = old_color_highlight;
geo->timeout_y = geo->first_entry_y + geo->num_entries
+ geo->border + empty_lines;
+ if (term->flags & GRUB_TERM_DUMB)
+ geo->timeout_y = 1;
if (bottom_message)
{
grub_term_gotoxy (term,
@@ -422,6 +452,8 @@ grub_menu_init_page (int nested, int edi
print_message (nested, edit, term, 0);
geo->timeout_y += msg_num_lines;
}
+ if (term->flags & GRUB_TERM_DUMB)
+ geo->timeout_y = 1;
geo->right_margin = grub_term_width (term)
- geo->first_entry_x
- geo->entry_width - 1;
@@ -433,12 +465,19 @@ menu_text_print_timeout (int timeout, vo
struct menu_viewer_data *data = dataptr;
char *msg_translated = 0;
- grub_term_gotoxy (data->term,
+ if (data->geo.timeout_y)
+ grub_term_gotoxy (data->term,
(struct grub_term_coordinate) { 0, data->geo.timeout_y });
+ if (data->term->flags & GRUB_TERM_DUMB)
+ {
+ if (! data->geo.timeout_y)
+ data->timeout_msg = TIMEOUT_TERSE;
+ data->geo.timeout_y = 0;
+ }
if (data->timeout_msg == TIMEOUT_TERSE
|| data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN)
- msg_translated = grub_xasprintf (_("%ds"), timeout);
+ msg_translated = grub_xasprintf (_(" %ds"), timeout);
else
msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout);
if (!msg_translated)
@@ -468,6 +507,8 @@ menu_text_print_timeout (int timeout, vo
data->term);
grub_free (msg_translated);
+ if (data->term->flags & GRUB_TERM_DUMB)
+ return;
grub_term_gotoxy (data->term,
(struct grub_term_coordinate) {
grub_term_cursor_x (&data->geo),
@@ -495,7 +536,7 @@ menu_text_set_chosen_entry (int entry, v
data->first = entry;
complete_redraw = 1;
}
- if (complete_redraw)
+ if (complete_redraw || (data->term->flags & GRUB_TERM_DUMB))
print_entries (data->menu, data);
else
{
@@ -525,6 +566,9 @@ menu_text_clear_timeout (void *dataptr)
struct menu_viewer_data *data = dataptr;
int i;
+ if ((data->term->flags & GRUB_TERM_DUMB))
+ return;
+
for (i = 0; i < data->geo.timeout_lines;i++)
{
grub_term_gotoxy (data->term, (struct grub_term_coordinate) {
--- a/grub-core/normal/term.c
+++ b/grub-core/normal/term.c
@@ -981,7 +981,7 @@ grub_print_ucs4_menu (const grub_uint32_
{
print_ucs4_real (str, last_position, margin_left, margin_right,
term, 0, 0, 1, skip_lines, max_lines,
- contchar, 1, pos);
+ contchar, (term->flags & GRUB_TERM_DUMB)? 0 : 1, pos);
}
void
--- a/grub-core/kern/emu/main.c
+++ b/grub-core/kern/emu/main.c
@@ -174,6 +174,12 @@ static struct argp argp = {
NULL, help_filter, NULL
};
+void
+ignore (int num __attribute__ ((unused)))
+{
+ return;
+}
+
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
@@ -212,7 +218,7 @@ main (int argc, char *argv[])
sleep (1);
}
- signal (SIGINT, SIG_IGN);
+ signal (SIGINT, (sighandler_t) &ignore);
grub_console_init ();
grub_host_init ();
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -99,8 +99,10 @@ grub_term_color_state;
#define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2)
+/* Set when the terminal is line oriented. */
+#define GRUB_TERM_LINE (1 << 3)
/* Which encoding does terminal expect stream to be. */
-#define GRUB_TERM_CODE_TYPE_SHIFT 3
+#define GRUB_TERM_CODE_TYPE_SHIFT 4
#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Only ASCII characters accepted. */
#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT)

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +0,0 @@
From: Raymund Will <rw@suse.com>
Subject: Enable grub2-mkconfig for s390x-emu
References: fate#314213, bnc#868909
Patch-Mainline: no
V2:
* omit subvolume-prefix for platform "emu"
V3:
* add 'conmode=' to command-line if GRUB_CONMODE exists. [bnc#868909]
V4:
* remove 's' from possible hot-keys for "bootable snapshots". [bnc#885668]
---
util/grub.d/10_linux.in | 63 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 12 deletions(-)
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -51,6 +51,10 @@ else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
+if [ "x$GRUB_CONMODE" != "x" ]; then
+ GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}"
+fi
+
case x"$GRUB_FS" in
xbtrfs)
rootsubvol="`make_system_path_relative_to_its_root /`"
@@ -67,6 +71,21 @@ esac
title_correction_code=
+hotkey=1
+incr_hotkey()
+{
+ [ -z "$hotkey" ] && return
+ expr $hotkey + 1
+}
+print_hotkey()
+{
+ keys="123456789abdfgijklmnoprtuvwyz"
+ if [ -z "$hotkey" ]||[ $hotkey -eq 0 ]||[ $hotkey -gt 30 ]; then
+ return
+ fi
+ echo "--hotkey=$(expr substr $keys $hotkey 1)"
+}
+
linux_entry ()
{
os="$1"
@@ -96,9 +115,11 @@ linux_entry ()
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/"
+ echo "menuentry '$(echo "$title" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
+ hotkey=$(incr_hotkey)
else
- echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
+ echo "menuentry '$(echo "$os" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
+ hotkey=$(incr_hotkey)
fi
if [ x$type != xrecovery ] ; then
save_default_entry | grub_add_tab
@@ -121,6 +142,7 @@ linux_entry ()
echo " insmod gzio" | sed "s/^/$submenu_indentation/"
+ if [ $PLATFORM != emu ]; then # 'search' does not work for now
if [ x$dirname = x/ ]; then
if [ -z "${prepare_root_cache}" ]; then
prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
@@ -132,6 +154,7 @@ linux_entry ()
fi
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
+ fi
message="$(gettext_printf "Loading Linux %s ..." ${version})"
if [ -d /sys/firmware/efi ] && [ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
sed "s/^/$submenu_indentation/" << EOF
@@ -166,17 +189,15 @@ EOF
machine=`uname -m`
case "x$machine" in
- xi?86 | xx86_64)
- list=
- for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
- if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
- done ;;
- *)
- list=
- for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
- if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
- done ;;
+ xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;;
+ xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;;
+ *) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \
+ /boot/kernel-*" ;;
esac
+list=
+for i in $klist ; do
+ if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
+done
case "$machine" in
i?86) GENKERNEL_ARCH="x86" ;;
@@ -186,6 +207,15 @@ case "$machine" in
*) GENKERNEL_ARCH="$machine" ;;
esac
+PLATFORM="native"
+if [ -d /sys/firmware/efi ]&&[ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
+ PLATFORM="efi"
+else
+ case "$machine" in
+ s390*) PLATFORM="emu" ;;
+ esac
+fi
+
prepare_boot_cache=
prepare_root_cache=
boot_device_id=
@@ -202,6 +232,11 @@ while [ "x$list" != "x" ] ; do
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
+ if [ $PLATFORM != "emu" ]; then
+ hotkey=0
+ else
+ rel_dirname=$dirname
+ fi
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
@@ -286,7 +321,8 @@ while [ "x$list" != "x" ] ; do
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
# TRANSLATORS: %s is replaced with an OS name
- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
+ echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' $(print_hotkey) \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
+ hotkey=$(incr_hotkey)
is_top_level=false
fi

View File

@ -1,47 +0,0 @@
From: Raymund Will <rw@suse.com>
Subject: Allow s390x-emu to telecontrolled by LOADPARM
References: bsc#892852, bsc#891946
Patch-Mainline: no
---
util/grub.d/00_header.in | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
Index: grub-2.02~beta3/util/grub.d/00_header.in
===================================================================
--- grub-2.02~beta3.orig/util/grub.d/00_header.in
+++ grub-2.02~beta3/util/grub.d/00_header.in
@@ -52,6 +52,33 @@ if [ "\${env_block}" ] ; then
fi
EOF
+if [ "`uname -m`" = "s390x" ]; then
+ cat <<EOF
+if [ ! "\$sys_loadparm" ]; then
+ set sys_loadparm=/sys/firmware/ipl/loadparm
+fi
+while [ -f "\$sys_loadparm" ]; do
+ unset loadparm
+ read_file "\$sys_loadparm" loadparm
+ if [ ! "\${loadparm}" ]; then break; fi
+ unset z_gp # extract grub part
+ regexp -s 2:z_gp '^([^Gg]*)[Gg](.+)$' "\$loadparm"
+ if [ ! "\$z_gp" ]; then break; fi
+ while true; do
+ unset z_1
+ unset z_2 # remap zIPL-compatible "." to grub's '>'
+ regexp -s 1:z_1 -s 2:z_2 '^([0-9][0-9>]*)\.([0-9][0-9.]*)$' "\$z_gp"
+ if [ ! "\$z_1" -o ! "\$z_2" ]; then break; fi
+ set z_gp="\$z_1>\$z_2"
+ done
+ if [ ! "\$z_gp" ]; then break; fi
+ set next_entry="\$z_gp"
+ unset z_gp
+ unset loadparm
+ break
+done
+EOF
+fi
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then

View File

@ -1,41 +0,0 @@
--- grub-2.02~beta2.orig/util/s390x/zipl2grub.pl.in 2015-09-15 07:29:51.473202000 -0600
+++ grub-2.02~beta2/util/s390x/zipl2grub.pl.in 2015-09-15 07:34:12.559142000 -0600
@@ -7,6 +7,9 @@ my $in = '@sysconfdir@/default/zipl2grub
my $default = '@sysconfdir@/default/grub';
my $fallback = '@sysconfdir@/zipl.conf';
my $sysconfbl = '@sysconfdir@/sysconfig/bootloader';
+my $defimage = "/boot/image";
+my $definitrd = "/boot/initrd";
+my $Image = "$defimage";
my $zipldir = "";
my $running = "";
my $refresh = 1; # needs to default to "on" until most bugs are shaken out!
@@ -166,7 +169,7 @@ sub Usage($) {
my $msg = "";
$msg .= sprintf( "%s: %s\n", $C, $cat[$_[0]]) if ($_[0] > 0);
- $msg .= "Usage: $C [-v] [-d] [-f] [-T template] [-z ZIPLDIR]\n";
+ $msg .= "Usage: $C [-v] [-d] [-f] [-T template] [-z ZIPLDIR] [-i imagepath]\n";
Panic( $_[0], $msg . "\n");
}
@@ -184,6 +187,7 @@ while ( $#ARGV >= 0 ) {
(/^--?help/ || /^-h/) && (Usage(0));
(/^--zipldir$/ || /^-z$/) && ($zipldir = shift || Usage(2), next);
(/^--template$/ || /^-T$/) && ($in = shift || Usage(3), next);
+ (/^--image$/ || /^-i$/) && ($Image = shift || Usage(5), $force = 1, next);
(/^-/) && (Usage(1));
Usage(1);
}
@@ -379,11 +383,8 @@ if ( ! $debug ) {
}
# copy out kernel and initrd
-my $defimage = "/boot/image";
-my $definitrd = "/boot/initrd";
my $ziplimage = "$zipldir/image";
my $ziplinitrd = "$zipldir/initrd";
-my $Image = "$defimage";
if ( ! $running && ! $force ) {
chomp( $running = qx{uname -r});

View File

@ -1,15 +0,0 @@
Index: grub-2.02~beta2/grub-core/osdep/linux/getroot.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/osdep/linux/getroot.c
+++ grub-2.02~beta2/grub-core/osdep/linux/getroot.c
@@ -713,6 +713,10 @@ grub_util_part_to_disk (const char *os_d
if (! realpath (os_dev, path))
return NULL;
+#ifdef __s390x__
+ return path;
+#endif
+
if (strncmp ("/dev/", path, 5) == 0)
{
char *p = path + 5;

View File

@ -1,481 +0,0 @@
From: Matthew Garrett <mjg@redhat.com>
Date: 2012-07-10 11:58:52 EDT
Subject: [PATCH] Add support for linuxefi
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/Makefile.core.def | 8 +
grub-core/kern/efi/mm.c | 32 ++++
grub-core/loader/i386/efi/linux.c | 371 +++++++++++++++++++++++++++++++++++++
include/grub/efi/efi.h | 3 +
include/grub/i386/linux.h | 1 +
5 files changed, 415 insertions(+), 0 deletions(-)
create mode 100644 grub-core/loader/i386/efi/linux.c
Index: grub-2.02~beta2/grub-core/Makefile.core.def
===================================================================
--- grub-2.02~beta2.orig/grub-core/Makefile.core.def
+++ grub-2.02~beta2/grub-core/Makefile.core.def
@@ -1691,6 +1691,14 @@ module = {
};
module = {
+ name = linuxefi;
+ efi = loader/i386/efi/linux.c;
+ efi = lib/cmdline.c;
+ enable = i386_efi;
+ enable = x86_64_efi;
+};
+
+module = {
name = chain;
efi = loader/efi/chainloader.c;
i386_pc = loader/i386/pc/chainloader.c;
Index: grub-2.02~beta2/grub-core/kern/efi/mm.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/efi/mm.c
+++ grub-2.02~beta2/grub-core/kern/efi/mm.c
@@ -49,6 +49,38 @@ static grub_efi_uintn_t finish_desc_size
static grub_efi_uint32_t finish_desc_version;
int grub_efi_is_finished = 0;
+/* Allocate pages below a specified address */
+void *
+grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
+ grub_efi_uintn_t pages)
+{
+ grub_efi_status_t status;
+ grub_efi_boot_services_t *b;
+ grub_efi_physical_address_t address = max;
+
+ if (max > 0xffffffff)
+ return 0;
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
+
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+
+ if (address == 0)
+ {
+ /* Uggh, the address 0 was allocated... This is too annoying,
+ so reallocate another one. */
+ address = max;
+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
+ grub_efi_free_pages (0, pages);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+ }
+
+ return (void *) ((grub_addr_t) address);
+}
+
/* Allocate pages. Return the pointer to the first of allocated pages. */
void *
grub_efi_allocate_pages (grub_efi_physical_address_t address,
Index: grub-2.02~beta2/grub-core/loader/i386/efi/linux.c
===================================================================
--- /dev/null
+++ grub-2.02~beta2/grub-core/loader/i386/efi/linux.c
@@ -0,0 +1,371 @@
+/*
+ * 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/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/cpu/linux.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/lib/cmdline.h>
+#include <grub/efi/efi.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+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 grub_uint32_t handover_offset;
+struct linux_kernel_params *params;
+static char *linux_cmdline;
+
+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
+
+#define SHIM_LOCK_GUID \
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
+
+struct grub_efi_shim_lock
+{
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
+};
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+
+static grub_efi_boolean_t
+grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
+{
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_efi_shim_lock_t *shim_lock;
+
+ shim_lock = grub_efi_locate_protocol(&guid, NULL);
+
+ if (!shim_lock)
+ return 1;
+
+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
+ return 1;
+
+ return 0;
+}
+
+typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
+
+static grub_err_t
+grub_linuxefi_boot (void)
+{
+ handover_func hf;
+ int offset = 0;
+
+#ifdef __x86_64__
+ offset = 512;
+#endif
+
+ hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
+
+ asm volatile ("cli");
+
+ hf (grub_efi_image_handle, grub_efi_system_table, params);
+
+ /* Not reached */
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+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));
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_file_t *files = 0;
+ int i, nfiles = 0;
+ grub_size_t size = 0;
+ grub_uint8_t *ptr;
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+ goto fail;
+ }
+
+ if (!loaded)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
+ goto fail;
+ }
+
+ files = grub_zalloc (argc * sizeof (files[0]));
+ if (!files)
+ goto fail;
+
+ for (i = 0; i < argc; i++)
+ {
+ grub_file_filter_disable_compression ();
+ files[i] = grub_file_open (argv[i]);
+ if (! files[i])
+ goto fail;
+ nfiles++;
+ size += ALIGN_UP (grub_file_size (files[i]), 4);
+ }
+
+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
+
+ if (!initrd_mem)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
+ goto fail;
+ }
+
+ params->ramdisk_size = size;
+ params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem;
+
+ ptr = initrd_mem;
+
+ 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 (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ argv[i]);
+ goto fail;
+ }
+ ptr += cursize;
+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
+ ptr += ALIGN_UP_OVERHEAD (cursize, 4);
+ }
+
+ params->ramdisk_size = size;
+
+ fail:
+ for (i = 0; i < nfiles; i++)
+ grub_file_close (files[i]);
+ grub_free (files);
+
+ if (initrd_mem && grub_errno)
+ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size));
+
+ return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_file_t file = 0;
+ struct linux_kernel_header lh;
+ grub_ssize_t len, start, filelen;
+ void *kernel;
+
+ grub_dl_ref (my_mod);
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+ goto fail;
+ }
+
+ file = grub_file_open (argv[0]);
+ if (! file)
+ goto fail;
+
+ filelen = grub_file_size (file);
+
+ kernel = grub_malloc(filelen);
+
+ if (!kernel)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
+ goto fail;
+ }
+
+ if (grub_file_read (file, kernel, filelen) != filelen)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
+ goto fail;
+ }
+
+ if (! grub_linuxefi_secure_validate (kernel, filelen))
+ {
+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
+ grub_free (kernel);
+ goto fail;
+ }
+
+ grub_file_seek (file, 0);
+
+ grub_free(kernel);
+
+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
+
+ if (! params)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
+ goto fail;
+ }
+
+ grub_memset (params, 0, 16384);
+
+ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ goto fail;
+ }
+
+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
+ goto fail;
+ }
+
+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
+ goto fail;
+ }
+
+ if (lh.version < grub_cpu_to_le16 (0x020b))
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
+ goto fail;
+ }
+
+ if (!lh.handover_offset)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
+ goto fail;
+ }
+
+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
+ 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_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
+ grub_create_loader_cmdline (argc, argv,
+ linux_cmdline + sizeof (LINUX_IMAGE) - 1,
+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1));
+
+ lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline;
+
+ handover_offset = lh.handover_offset;
+
+ start = (lh.setup_sects + 1) * 512;
+ len = grub_file_size(file) - start;
+
+ kernel_mem = grub_efi_allocate_pages(lh.pref_address,
+ BYTES_TO_PAGES(lh.init_size));
+
+ if (!kernel_mem)
+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
+ BYTES_TO_PAGES(lh.init_size));
+
+ if (!kernel_mem)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
+ goto fail;
+ }
+
+ if (grub_file_seek (file, start) == (grub_off_t) -1)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ goto fail;
+ }
+
+ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ }
+
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
+ loaded = 1;
+ lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem;
+ }
+
+ grub_memcpy(params, &lh, 2 * 512);
+
+ params->type_of_loader = 0x21;
+
+ fail:
+
+ if (file)
+ grub_file_close (file);
+
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_dl_unref (my_mod);
+ loaded = 0;
+ }
+
+ if (linux_cmdline && !loaded)
+ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(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));
+
+ return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linuxefi)
+{
+ cmd_linux =
+ grub_register_command ("linuxefi", grub_cmd_linux,
+ 0, N_("Load Linux."));
+ cmd_initrd =
+ grub_register_command ("initrdefi", grub_cmd_initrd,
+ 0, N_("Load initrd."));
+ my_mod = mod;
+}
+
+GRUB_MOD_FINI(linuxefi)
+{
+ grub_unregister_command (cmd_linux);
+ grub_unregister_command (cmd_initrd);
+}
Index: grub-2.02~beta2/include/grub/efi/efi.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/efi/efi.h
+++ grub-2.02~beta2/include/grub/efi/efi.h
@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_e
void *
EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
+void *
+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max,
+ grub_efi_uintn_t pages);
void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
int
Index: grub-2.02~beta2/include/grub/i386/linux.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/i386/linux.h
+++ grub-2.02~beta2/include/grub/i386/linux.h
@@ -139,6 +139,7 @@ struct linux_kernel_header
grub_uint64_t setup_data;
grub_uint64_t pref_address;
grub_uint32_t init_size;
+ grub_uint32_t handover_offset;
} GRUB_PACKED;
/* Boot parameters for Linux based on 2.6.12. This is used by the setup

View File

@ -1,690 +0,0 @@
From 06ff1079788fedac5e3f1f12ed7bbe69228a7ae0 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Tue, 18 Dec 2012 16:54:03 +0800
Subject: [PATCH] Add secureboot support on efi chainloader
References: fate#314485
Patch-Mainline: no
Expand the chainloader to be able to verify the image by means of shim
lock protocol. The PE/COFF image is loaded and relocated by the
chainloader instead of calling LoadImage and StartImage UEFI boot
Service as they require positive verification result from keys enrolled
in KEK or DB. The shim will use MOK in addition to firmware enrolled
keys to verify the image.
The chainloader module could be used to load other UEFI bootloaders,
such as xen.efi, and could be signed by any of MOK, KEK or DB.
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/loader/efi/chainloader.c | 538 +++++++++++++++++++++++++++++++++--
1 files changed, 507 insertions(+), 31 deletions(-)
Index: grub-2.02~beta2/grub-core/loader/efi/chainloader.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/loader/efi/chainloader.c
+++ grub-2.02~beta2/grub-core/loader/efi/chainloader.c
@@ -40,15 +40,31 @@
#include <grub/i386/macho.h>
#endif
+#ifdef __x86_64__
+#define SUPPORT_SECURE_BOOT
+#endif
+
+#ifdef SUPPORT_SECURE_BOOT
+#include <grub/efi/pe32.h>
+#endif
+
GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
static grub_efi_physical_address_t address;
static grub_efi_uintn_t pages;
+static grub_ssize_t fsize;
static grub_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
static grub_efi_char16_t *cmdline;
+static grub_ssize_t cmdline_len;
+static grub_efi_handle_t dev_handle;
+
+#ifdef SUPPORT_SECURE_BOOT
+static grub_efi_boolean_t debug_secureboot = 0;
+static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
+#endif
static grub_err_t
grub_chainloader_unload (void)
@@ -63,6 +79,7 @@ grub_chainloader_unload (void)
grub_free (cmdline);
cmdline = 0;
file_path = 0;
+ dev_handle = 0;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
@@ -187,12 +204,460 @@ make_file_path (grub_efi_device_path_t *
return file_path;
}
+#ifdef SUPPORT_SECURE_BOOT
+#define SHIM_LOCK_GUID \
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
+
+struct grub_pe32_header_no_msdos_stub
+{
+ char signature[GRUB_PE32_SIGNATURE_SIZE];
+ struct grub_pe32_coff_header coff_header;
+ struct grub_pe64_optional_header optional_header;
+};
+
+struct pe_coff_loader_image_context
+{
+ grub_efi_uint64_t image_address;
+ grub_efi_uint64_t image_size;
+ grub_efi_uint64_t entry_point;
+ grub_efi_uintn_t size_of_headers;
+ grub_efi_uint16_t image_type;
+ grub_efi_uint16_t number_of_sections;
+ struct grub_pe32_section_table *first_section;
+ struct grub_pe32_data_directory *reloc_dir;
+ struct grub_pe32_data_directory *sec_dir;
+ grub_efi_uint64_t number_of_rva_and_sizes;
+ struct grub_pe32_header_no_msdos_stub *pe_hdr;
+};
+
+typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t;
+
+struct grub_efi_shim_lock
+{
+ grub_efi_status_t (*verify)(void *buffer,
+ grub_efi_uint32_t size);
+ grub_efi_status_t (*hash)(void *data,
+ grub_efi_int32_t datasize,
+ pe_coff_loader_image_context_t *context,
+ grub_efi_uint8_t *sha256hash,
+ grub_efi_uint8_t *sha1hash);
+ grub_efi_status_t (*context)(void *data,
+ grub_efi_uint32_t size,
+ pe_coff_loader_image_context_t *context);
+};
+
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+
+static grub_efi_boolean_t
+grub_secure_validate (void *data, grub_efi_uint32_t size)
+{
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_efi_shim_lock_t *shim_lock;
+
+ shim_lock = grub_efi_locate_protocol (&guid, NULL);
+
+ if (!shim_lock)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol");
+ return 0;
+ }
+
+ if (shim_lock->verify (data, size) == GRUB_EFI_SUCCESS)
+ {
+ grub_dprintf ("chain", "verify success\n");
+ return 1;
+ }
+
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "verify failed");
+ return 0;
+}
+
+static grub_efi_boolean_t
+grub_secure_mode (void)
+{
+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ grub_uint8_t *data;
+ grub_size_t datasize;
+
+ data = grub_efi_get_variable ("SecureBoot", &efi_var_guid, &datasize);
+
+ if (data)
+ {
+ grub_dprintf ("chain", "SecureBoot: %d, datasize %d\n", (int)*data, (int)datasize);
+ }
+
+ if (data && (datasize == 1))
+ {
+ if (*data != 1)
+ {
+ grub_dprintf ("chain", "secure boot not enabled\n");
+ return 0;
+ }
+ }
+ else
+ {
+ grub_dprintf ("chain", "unknown secure boot status\n");
+ return 0;
+ }
+
+ grub_free (data);
+
+ data = grub_efi_get_variable ("SetupMode", &efi_var_guid, &datasize);
+
+ if (data)
+ {
+ grub_dprintf ("chain", "SetupMode: %d, datasize %d\n", (int)*data, (int)datasize);
+ }
+
+ if (data && (datasize == 1))
+ {
+ if (*data == 1)
+ {
+ grub_dprintf ("chain", "platform in setup mode\n");
+ return 0;
+ }
+ }
+
+ grub_free (data);
+
+ return 1;
+}
+
+static grub_efi_boolean_t
+read_header (void *data, grub_efi_uint32_t size, pe_coff_loader_image_context_t *context)
+{
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_efi_shim_lock_t *shim_lock;
+ grub_efi_status_t status;
+
+ shim_lock = grub_efi_locate_protocol (&guid, NULL);
+
+ if (!shim_lock)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol");
+ return 0;
+ }
+
+ status = shim_lock->context (data, size, context);
+
+ if (status == GRUB_EFI_SUCCESS)
+ {
+ grub_dprintf ("chain", "context success\n");
+ return 1;
+ }
+
+ switch (status)
+ {
+ case GRUB_EFI_UNSUPPORTED:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported");
+ break;
+ case GRUB_EFI_INVALID_PARAMETER:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter");
+ break;
+ default:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code");
+ break;
+ }
+
+ return 0;
+}
+
+static void*
+image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr)
+{
+ if (adr > sz)
+ return NULL;
+
+ return ((grub_uint8_t*)image + adr);
+}
+
+static grub_efi_status_t
+relocate_coff (pe_coff_loader_image_context_t *context, void *data)
+{
+ struct grub_pe32_data_directory *reloc_base, *reloc_base_end;
+ grub_efi_uint64_t adjust;
+ grub_efi_uint16_t *reloc, *reloc_end;
+ char *fixup, *fixup_base, *fixup_data = NULL;
+ grub_efi_uint16_t *fixup_16;
+ grub_efi_uint32_t *fixup_32;
+ grub_efi_uint64_t *fixup_64;
+
+ grub_efi_uint64_t size = context->image_size;
+ void *image_end = (char *)data + size;
+
+ context->pe_hdr->optional_header.image_base = (grub_uint64_t)data;
+
+ if (context->number_of_rva_and_sizes <= 5 || context->reloc_dir->size == 0)
+ {
+ grub_dprintf ("chain", "no need to reloc, we are done\n");
+ return GRUB_EFI_SUCCESS;
+ }
+
+ reloc_base = image_address (data, size, context->reloc_dir->rva);
+ reloc_base_end = image_address (data, size, context->reloc_dir->rva + context->reloc_dir->size -1);
+
+ grub_dprintf ("chain", "reloc_base %p reloc_base_end %p\n", reloc_base, reloc_base_end);
+
+ if (!reloc_base || !reloc_base_end)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ adjust = (grub_uint64_t)data - context->image_address;
+
+ while (reloc_base < reloc_base_end)
+ {
+ reloc = (grub_uint16_t *)((char*)reloc_base + sizeof (struct grub_pe32_data_directory));
+ reloc_end = (grub_uint16_t *)((char*)reloc_base + reloc_base->size);
+
+ if ((void *)reloc_end < data || (void *)reloc_end > image_end)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ fixup_base = image_address(data, size, reloc_base->rva);
+
+ if (!fixup_base)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid fixupbase");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ while (reloc < reloc_end)
+ {
+ fixup = fixup_base + (*reloc & 0xFFF);
+ switch ((*reloc) >> 12)
+ {
+ case GRUB_PE32_REL_BASED_ABSOLUTE:
+ break;
+ case GRUB_PE32_REL_BASED_HIGH:
+ fixup_16 = (grub_uint16_t *)fixup;
+ *fixup_16 = (grub_uint16_t) (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16)));
+ if (fixup_data != NULL)
+ {
+ *(grub_uint16_t *) fixup_data = *fixup_16;
+ fixup_data = fixup_data + sizeof (grub_uint16_t);
+ }
+ break;
+ case GRUB_PE32_REL_BASED_LOW:
+ fixup_16 = (grub_uint16_t *)fixup;
+ *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust );
+ if (fixup_data != NULL)
+ {
+ *(grub_uint16_t *) fixup_data = *fixup_16;
+ fixup_data = fixup_data + sizeof (grub_uint16_t);
+ }
+ break;
+ case GRUB_PE32_REL_BASED_HIGHLOW:
+ fixup_32 = (grub_uint32_t *)fixup;
+ *fixup_32 = *fixup_32 + (grub_uint32_t)adjust;
+ if (fixup_data != NULL)
+ {
+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t));
+ *(grub_uint32_t *) fixup_data = *fixup_32;
+ fixup_data += sizeof (grub_uint32_t);
+ }
+ break;
+ case GRUB_PE32_REL_BASED_DIR64:
+ fixup_64 = (grub_uint64_t *)fixup;
+ *fixup_64 = *fixup_64 + (grub_uint64_t)adjust;
+ if (fixup_data != NULL)
+ {
+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t));
+ *(grub_uint64_t *) fixup_data = *fixup_64;
+ fixup_data += sizeof (grub_uint64_t);
+ }
+ break;
+ default:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocation");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+ reloc += 1;
+ }
+ reloc_base = (struct grub_pe32_data_directory *)reloc_end;
+ }
+
+ return GRUB_EFI_SUCCESS;
+}
+
+static grub_efi_device_path_t *
+grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
+{
+ while (1)
+ {
+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+
+ if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
+ break;
+ else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+ && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
+ return dp;
+
+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
+ }
+
+ return NULL;
+}
+
+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;
+ char *buffer_aligned = NULL;
+ grub_efi_uint32_t i, size;
+ struct grub_pe32_section_table *section;
+ char *base, *end;
+ pe_coff_loader_image_context_t context;
+ grub_uint32_t section_alignment;
+ grub_uint32_t buffer_size;
+
+ b = grub_efi_system_table->boot_services;
+
+ if (read_header (data, datasize, &context))
+ {
+ grub_dprintf ("chain", "Succeed to read header\n");
+ }
+ else
+ {
+ grub_dprintf ("chain", "Failed to read header\n");
+ goto error_exit;
+ }
+
+ section_alignment = context.pe_hdr->optional_header.section_alignment;
+ buffer_size = context.image_size + section_alignment;
+
+ efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
+ buffer_size, &buffer);
+
+ if (efi_status != GRUB_EFI_SUCCESS)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ goto error_exit;
+ }
+
+ buffer_aligned = (char *)ALIGN_UP ((grub_addr_t)buffer, section_alignment);
+
+ grub_memcpy (buffer_aligned, data, context.size_of_headers);
+
+ section = context.first_section;
+ for (i = 0; i < context.number_of_sections; i++)
+ {
+ size = section->virtual_size;
+ if (size > section->raw_data_size)
+ size = section->raw_data_size;
+
+ base = image_address (buffer_aligned, context.image_size, section->virtual_address);
+ end = image_address (buffer_aligned, context.image_size, section->virtual_address + size - 1);
+
+ if (!base || !end)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size");
+ goto error_exit;
+ }
+
+ if (section->raw_data_size > 0)
+ grub_memcpy (base, (grub_efi_uint8_t*)data + section->raw_data_offset, size);
+
+ if (size < section->virtual_size)
+ grub_memset (base + size, 0, section->virtual_size - size);
+
+ grub_dprintf ("chain", "copied section %s\n", section->name);
+ section += 1;
+ }
+
+ efi_status = relocate_coff (&context, buffer_aligned);
+
+ if (efi_status != GRUB_EFI_SUCCESS)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed");
+ goto error_exit;
+ }
+
+ entry_point = image_address (buffer_aligned, context.image_size, context.entry_point);
+
+ if (!entry_point)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point");
+ goto error_exit;
+ }
+
+ li = grub_efi_get_loaded_image (grub_efi_image_handle);
+ if (!li)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available");
+ goto error_exit;
+ }
+
+ grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t));
+ li->image_base = buffer_aligned;
+ li->image_size = context.image_size;
+ li->load_options = cmdline;
+ li->load_options_size = cmdline_len;
+ li->file_path = grub_efi_get_media_file_path (file_path);
+ li->device_handle = dev_handle;
+ if (li->file_path)
+ {
+ grub_printf ("file path: ");
+ grub_efi_print_device_path (li->file_path);
+ }
+ else
+ {
+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
+ goto error_exit;
+ }
+
+ efi_status = efi_call_2 (entry_point, grub_efi_image_handle, grub_efi_system_table);
+
+ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t));
+ efi_status = efi_call_1 (b->free_pool, buffer);
+
+ return 1;
+
+error_exit:
+ if (buffer)
+ efi_call_1 (b->free_pool, buffer);
+
+ return 0;
+
+}
+
+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_free (file_path);
+ grub_free (cmdline);
+ cmdline = 0;
+ file_path = 0;
+ dev_handle = 0;
+
+ grub_dl_unref (my_mod);
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_secureboot_chainloader_boot (void)
+{
+ handle_image ((void *)address, fsize);
+ grub_loader_unset ();
+ return grub_errno;
+}
+#endif
+
static grub_err_t
grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_file_t file = 0;
- grub_ssize_t size;
grub_efi_status_t status;
grub_efi_boot_services_t *b;
grub_device_t dev = 0;
@@ -200,7 +665,6 @@ grub_cmd_chainloader (grub_command_t cmd
grub_efi_loaded_image_t *loaded_image;
char *filename;
void *boot_image = 0;
- grub_efi_handle_t dev_handle = 0;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -212,9 +676,36 @@ grub_cmd_chainloader (grub_command_t cmd
address = 0;
image_handle = 0;
file_path = 0;
+ dev_handle = 0;
b = grub_efi_system_table->boot_services;
+ if (argc > 1)
+ {
+ int i;
+ grub_efi_char16_t *p16;
+
+ for (i = 1, cmdline_len = 0; i < argc; i++)
+ cmdline_len += grub_strlen (argv[i]) + 1;
+
+ cmdline_len *= sizeof (grub_efi_char16_t);
+ cmdline = p16 = grub_malloc (cmdline_len);
+ if (! cmdline)
+ goto fail;
+
+ for (i = 1; i < argc; i++)
+ {
+ char *p8;
+
+ p8 = argv[i];
+ while (*p8)
+ *(p16++) = *(p8++);
+
+ *(p16++) = ' ';
+ }
+ *(--p16) = 0;
+ }
+
file = grub_file_open (filename);
if (! file)
goto fail;
@@ -260,14 +751,14 @@ grub_cmd_chainloader (grub_command_t cmd
grub_printf ("file path: ");
grub_efi_print_device_path (file_path);
- size = grub_file_size (file);
- if (!size)
+ fsize = grub_file_size (file);
+ if (!fsize)
{
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
filename);
goto fail;
}
- pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
+ pages = (((grub_efi_uintn_t) fsize + ((1 << 12) - 1)) >> 12);
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
GRUB_EFI_LOADER_CODE,
@@ -281,7 +772,7 @@ grub_cmd_chainloader (grub_command_t cmd
}
boot_image = (void *) ((grub_addr_t) address);
- if (grub_file_read (file, boot_image, size) != size)
+ if (grub_file_read (file, boot_image, fsize) != fsize)
{
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -291,7 +782,7 @@ grub_cmd_chainloader (grub_command_t cmd
}
#if defined (__i386__) || defined (__x86_64__)
- if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
+ if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
{
struct grub_macho_fat_header *head = boot_image;
if (head->magic
@@ -314,20 +805,30 @@ grub_cmd_chainloader (grub_command_t cmd
> ~grub_cpu_to_le32 (archs[i].size)
|| grub_cpu_to_le32 (archs[i].offset)
+ grub_cpu_to_le32 (archs[i].size)
- > (grub_size_t) size)
+ > (grub_size_t) fsize)
{
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
filename);
goto fail;
}
boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset);
- size = grub_cpu_to_le32 (archs[i].size);
+ fsize = grub_cpu_to_le32 (archs[i].size);
}
}
#endif
+#ifdef SUPPORT_SECURE_BOOT
+ /* FIXME is secure boot possible also with universal binaries? */
+ if (debug_secureboot || (grub_secure_mode() && grub_secure_validate ((void *)address, fsize)))
+ {
+ grub_file_close (file);
+ grub_loader_set (grub_secureboot_chainloader_boot, grub_secureboot_chainloader_unload, 0);
+ return 0;
+ }
+#endif
+
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
- boot_image, size,
+ boot_image, fsize,
&image_handle);
if (status != GRUB_EFI_SUCCESS)
{
@@ -350,33 +851,10 @@ grub_cmd_chainloader (grub_command_t cmd
}
loaded_image->device_handle = dev_handle;
- if (argc > 1)
+ if (cmdline)
{
- int i, len;
- grub_efi_char16_t *p16;
-
- for (i = 1, len = 0; i < argc; i++)
- len += grub_strlen (argv[i]) + 1;
-
- len *= sizeof (grub_efi_char16_t);
- cmdline = p16 = grub_malloc (len);
- if (! cmdline)
- goto fail;
-
- for (i = 1; i < argc; i++)
- {
- char *p8;
-
- p8 = argv[i];
- while (*p8)
- *(p16++) = *(p8++);
-
- *(p16++) = ' ';
- }
- *(--p16) = 0;
-
loaded_image->load_options = cmdline;
- loaded_image->load_options_size = len;
+ loaded_image->load_options_size = cmdline_len;
}
grub_file_close (file);
@@ -398,6 +876,9 @@ grub_cmd_chainloader (grub_command_t cmd
if (address)
efi_call_2 (b->free_pages, address, pages);
+ if (cmdline)
+ grub_free (cmdline);
+
grub_dl_unref (my_mod);
return grub_errno;

View File

@ -1,101 +0,0 @@
From 29c89e27805f7a6a22bce11ed9bb430e19c972a9 Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@ubuntu.com>
Date: Tue, 23 Oct 2012 10:40:49 -0400
Subject: [PATCH 449/482] Don't allow insmod when secure boot is enabled.
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/kern/dl.c | 17 +++++++++++++++++
grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++
include/grub/efi/efi.h | 1 +
3 files changed, 46 insertions(+)
Index: grub-2.02~beta2/grub-core/kern/dl.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/dl.c
+++ grub-2.02~beta2/grub-core/kern/dl.c
@@ -38,6 +38,10 @@
#define GRUB_MODULES_MACHINE_READONLY
#endif
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
+
#pragma GCC diagnostic ignored "-Wcast-align"
@@ -682,6 +686,19 @@ grub_dl_load_file (const char *filename)
grub_boot_time ("Loading module %s", filename);
+#ifdef GRUB_MACHINE_EFI
+ if (grub_efi_secure_boot ())
+ {
+#if 0
+ /* This is an error, but grub2-mkconfig still generates a pile of
+ * insmod commands, so emitting it would be mostly just obnoxious. */
+ grub_error (GRUB_ERR_ACCESS_DENIED,
+ "Secure Boot forbids loading module from %s", filename);
+#endif
+ return 0;
+ }
+#endif
+
file = grub_file_open (filename);
if (! file)
return 0;
Index: grub-2.02~beta2/grub-core/kern/efi/efi.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/kern/efi/efi.c
+++ grub-2.02~beta2/grub-core/kern/efi/efi.c
@@ -259,6 +259,34 @@ grub_efi_get_variable (const char *var,
return NULL;
}
+grub_efi_boolean_t
+grub_efi_secure_boot (void)
+{
+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ grub_size_t datasize;
+ char *secure_boot = NULL;
+ char *setup_mode = NULL;
+ grub_efi_boolean_t ret = 0;
+
+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
+
+ if (datasize != 1 || !secure_boot)
+ goto out;
+
+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
+
+ if (datasize != 1 || !setup_mode)
+ goto out;
+
+ if (*secure_boot && !*setup_mode)
+ ret = 1;
+
+ out:
+ grub_free (secure_boot);
+ grub_free (setup_mode);
+ return ret;
+}
+
#pragma GCC diagnostic ignored "-Wcast-align"
/* Search the mods section from the PE32/PE32+ image. This code uses
Index: grub-2.02~beta2/include/grub/efi/efi.h
===================================================================
--- grub-2.02~beta2.orig/include/grub/efi/efi.h
+++ grub-2.02~beta2/include/grub/efi/efi.h
@@ -72,6 +72,7 @@ EXPORT_FUNC (grub_efi_set_variable) (con
const grub_efi_guid_t *guid,
void *data,
grub_size_t datasize);
+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void);
int
EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
const grub_efi_device_path_t *dp2);

View File

@ -1,63 +0,0 @@
From 795ac61cba9674376d745813efdab395e35cff41 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Mon, 26 Nov 2012 15:38:54 +0800
Subject: [PATCH] provide option in config to enable linuxefi
References: fate#314485
Patch-Mainline: no
As linuxefi module requires kernel 3.6 or later which supports EFI
handover protocol, it may not be able to load kernels without that
supports in place.
In case that things would break, and the linuxefi is really too young to
take over the position of "linux" kernel loader module, we introduce a
option GRUB_USE_LINUXEFI in the config and only explicit set it to true
will enable it. Example usage is
GRUB_USE_LINUXEFI=true grub2-mkconfig -o /boot/efi/EFI/opensuse/grub.cfg
This will output a grub.cfg which uses linuxefi in replace of linux and
enable verification of kernel signature if in secureboot enabled and
has shim exported protocols available.
---
util/grub-mkconfig.in | 3 ++-
util/grub.d/10_linux.in | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -254,7 +254,8 @@ export GRUB_DEFAULT \
GRUB_BADRAM \
GRUB_OS_PROBER_SKIP_LIST \
GRUB_DISABLE_SUBMENU \
- GRUB_CMDLINE_LINUX_RECOVERY
+ GRUB_CMDLINE_LINUX_RECOVERY \
+ GRUB_USE_LINUXEFI
if test "x${grub_cfg}" != "x"; then
rm -f "${grub_cfg}.new"
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -133,7 +133,7 @@ linux_entry ()
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
message="$(gettext_printf "Loading Linux %s ..." ${version})"
- if [ -d /sys/firmware/efi ]; then
+ if [ -d /sys/firmware/efi ] && [ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
linuxefi ${rel_dirname}/${basename} ${root_device} ${args}
@@ -147,7 +147,7 @@ EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
- if [ -d /sys/firmware/efi ]; then
+ if [ -d /sys/firmware/efi ] && [ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
initrdefi ${rel_dirname}/${initrd}

View File

@ -1,54 +0,0 @@
From: Andrey Borzenkov <arvidjaar@gmail.com>
Subject: use linuxefi/initrdefi for Linux in 30_os-prober if secure boot is enabled
Reference: bnc#810912
Emit linuxefi/initrdefi for os-prober detected Linux installations if
secure boot is enabled.
Index: grub-2.02~beta2/util/grub.d/30_os-prober.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/30_os-prober.in
+++ grub-2.02~beta2/util/grub.d/30_os-prober.in
@@ -41,6 +41,15 @@ if [ -z "${OSPROBED}" ] ; then
exit 0
fi
+# If secure boot is enabled, use linuxefi/initrdefi for Linux (bnc#810912)
+if [ -d /sys/firmware/efi ] && [ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
+ LINUX_LOADER_CMD=linuxefi
+ LINUX_INITRD_CMD=initrdefi
+else
+ LINUX_LOADER_CMD=linux
+ LINUX_INITRD_CMD=initrd
+fi
+
osx_entry() {
if [ x$2 = x32 ]; then
# TRANSLATORS: it refers to kernel architecture (32-bit)
@@ -234,11 +243,11 @@ EOF
save_default_entry | grub_add_tab
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
- linux ${LKERNEL} ${LPARAMS}
+ ${LINUX_LOADER_CMD} ${LKERNEL} ${LPARAMS}
EOF
if [ -n "${LINITRD}" ] ; then
cat << EOF
- initrd ${LINITRD}
+ ${LINUX_INITRD_CMD} ${LINITRD}
EOF
fi
cat << EOF
@@ -254,11 +263,11 @@ EOF
save_default_entry | sed -e "s/^/$grub_tab$grub_tab/"
printf '%s\n' "${prepare_boot_cache}" | grub_add_tab
cat << EOF
- linux ${LKERNEL} ${LPARAMS}
+ ${LINUX_LOADER_CMD} ${LKERNEL} ${LPARAMS}
EOF
if [ -n "${LINITRD}" ] ; then
cat << EOF
- initrd ${LINITRD}
+ ${LINUX_INITRD_CMD} ${LINITRD}
EOF
fi
cat << EOF

View File

@ -1,51 +0,0 @@
From 151b1691fe0cf885df101c6e6a7cb1defc50428b Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 16 Jul 2012 18:57:11 -0400
Subject: [PATCH] Use "linuxefi" and "initrdefi" where appropriate
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
util/grub.d/10_linux.in | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -133,17 +133,31 @@ linux_entry ()
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
message="$(gettext_printf "Loading Linux %s ..." ${version})"
- sed "s/^/$submenu_indentation/" << EOF
+ if [ -d /sys/firmware/efi ]; then
+ sed "s/^/$submenu_indentation/" << EOF
+ echo '$(echo "$message" | grub_quote)'
+ linuxefi ${rel_dirname}/${basename} ${root_device} ${args}
+EOF
+ else
+ sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
linux ${rel_dirname}/${basename} ${root_device} ${args}
EOF
+ fi
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
- sed "s/^/$submenu_indentation/" << EOF
+ if [ -d /sys/firmware/efi ]; then
+ sed "s/^/$submenu_indentation/" << EOF
+ echo '$(echo "$message" | grub_quote)'
+ initrdefi ${rel_dirname}/${initrd}
+EOF
+ else
+ sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
initrd ${rel_dirname}/${initrd}
EOF
+ fi
fi
sed "s/^/$submenu_indentation/" << EOF
}

View File

@ -1,58 +0,0 @@
Index: grub-2.02~beta2/util/setup.c
===================================================================
--- grub-2.02~beta2.orig/util/setup.c
+++ grub-2.02~beta2/util/setup.c
@@ -501,8 +501,42 @@ SETUP (const char *dir,
err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors);
else if (ctx.dest_partmap)
- err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
- GRUB_EMBED_PCBIOS, &sectors);
+ {
+ err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
+ GRUB_EMBED_PCBIOS, &sectors);
+#ifdef GRUB_SETUP_BIOS
+ if (err == GRUB_ERR_OUT_OF_RANGE
+ && dest_dev->disk->id == root_dev->disk->id
+ && dest_dev->disk->dev->id == root_dev->disk->dev->id)
+ {
+ grub_fs_t root_fs;
+
+ root_fs = grub_fs_probe (root_dev);
+ if (root_fs && root_fs->embed)
+ {
+ grub_disk_addr_t *fs_sectors;
+ unsigned int fs_nsec;
+
+ fs_sectors = NULL;
+ fs_nsec = core_sectors;
+ err = root_fs->embed (root_dev, &fs_nsec, maxsec,
+ GRUB_EMBED_PCBIOS, &fs_sectors);
+ if (!err && fs_nsec >= core_sectors)
+ {
+ sectors = fs_sectors;
+ nsec = fs_nsec;
+ ctx.container = root_dev->disk->partition;
+ core_dev = root_dev;
+ }
+ else
+ {
+ if (fs_sectors)
+ grub_free (fs_sectors);
+ }
+ }
+ }
+#endif
+ }
else
err = fs->embed (dest_dev, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors);
@@ -584,7 +618,7 @@ SETUP (const char *dir,
/* Write the core image onto the disk. */
for (i = 0; i < nsec; i++)
- grub_disk_write (dest_dev->disk, sectors[i], 0,
+ grub_disk_write (core_dev->disk, sectors[i], 0,
GRUB_DISK_SECTOR_SIZE,
core_img + i * GRUB_DISK_SECTOR_SIZE);

View File

@ -1,281 +0,0 @@
#!/bin/sh
set -e
# Copyright (C) 2006,2007,2008,2009,2010 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/>.
grub_mkconfig="/usr/sbin/grub2-mkconfig"
grub_mkrelpath="/usr/bin/grub2-mkrelpath"
grub_script_check="/usr/bin/grub2-script-check"
grub_setting="/etc/default/grub"
grub_cfg="/boot/grub2/grub.cfg"
grub_snapshot_cfg="/boot/grub2/snapshot_submenu.cfg"
snapper_snapshot_path="/.snapshots"
snapshot_submenu_name="grub-snapshot.cfg"
snapper_snapshots_cfg="${snapper_snapshot_path}/${snapshot_submenu_name}"
# add hotkeys for s390. (bnc#885668)
hotkey=
incr_hotkey()
{
[ -n "$hotkey" ] || return
expr $hotkey + 1
}
print_hotkey()
{
keys="123456789abdfgijklmnoprstuvwyz"
if [ -z "$hotkey" ]||[ $hotkey -eq 0 ]||[ $hotkey -gt 30 ]; then
return
fi
echo "--hotkey=$(expr substr $keys $hotkey 1)"
}
snapshot_submenu () {
s_dir="$1"
snapshot="${s_dir}/snapshot"
num="`basename $s_dir`"
# bnc#864842 Important snapshots are not marked as such in grub2 menu
# the format is "important distribution version (kernel_version, timestamp, pre/post)"
date=`xmllint --xpath '/snapshot/date/text()' "${s_dir}/info.xml" || echo ""`
date=`echo $date | sed 's/\(.*\) \(.*\):.*/\1T\2/'`
important=`xmllint --xpath "/snapshot/userdata[key='important']/value/text()" "${s_dir}/info.xml" 2>/dev/null || echo ""`
stype=`xmllint --xpath '/snapshot/type/text()' "${s_dir}/info.xml" || echo ""`
kernel_ver=`readlink ${snapshot}/boot/vmlinuz | sed -e 's/^vmlinuz-//' -e 's/-default$//'`
if [ -z "$kernel_ver" -a -L ${snapshot}/boot/image ]; then
kernel_ver=`readlink ${snapshot}/boot/image | sed -e 's/^image-//' -e 's/-default$//'`
fi
eval `cat ${snapshot}/etc/os-release`
# bsc#934252 - Replace SLES 12.1 with SLES12-SP1 for the list of snapshots
if test "${NAME}" = "SLES" -o "${NAME}" = "SLED"; then
VERSION=`echo ${VERSION} | sed -e 's!^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\)$!\1-SP\2!'`
fi
# FATE#318101
# Show user defined comments in grub2 menu for snapshots
# Use userdata tag "bootloader=[user defined text]"
full_desc=`xmllint --xpath "/snapshot/userdata[key='bootloader']/value/text()" "${s_dir}/info.xml" 2>/dev/null || echo ""`
test -z "$full_desc" && desc=`xmllint --xpath '/snapshot/description/text()' "${s_dir}/info.xml" 2>/dev/null || echo ""`
# FATE#317972
# If we have a post entry and the description field is empty,
# we should use the "Pre" number and add that description to the post entry.
if test -z "$full_desc" -a -z "$desc" -a "$stype" = "post"; then
pre_num=`xmllint --xpath '/snapshot/pre_num/text()' "${s_dir}/info.xml" 2>/dev/null || echo ""`
if test -n "$pre_num"; then
if test -f "${snapper_snapshot_path}/${pre_num}/info.xml" ; then
desc=`xmllint --xpath '/snapshot/description/text()' "${snapper_snapshot_path}/${pre_num}/info.xml" 2>/dev/null || echo ""`
fi
fi
fi
test "$important" = "yes" && important="*" || important=" "
test "$stype" = "single" && stype=""
test -z "$stype" || stype=",$stype"
test -z "$desc" || desc=",$desc"
test -z "$full_desc" && full_desc="$kernel_ver,$date$stype$desc"
if test "${NAME}" = "SLES" -o "${NAME}" = "SLED"; then
title="${important}${NAME}${VERSION} ($full_desc)"
else
title="${important}${NAME} ${VERSION} ($full_desc)"
fi
if test "$s390" = "1"; then
subvol="\$2"
else
subvol="\$3"
fi
cat <<EOF
if [ -f "${snapper_snapshot_path}/$num/snapshot/boot/grub2/grub.cfg" ]; then
snapshot_found=true
saved_subvol=\$btrfs_subvol
menuentry `print_hotkey` "$title" "${snapper_snapshot_path}/$num/snapshot" "`$grub_mkrelpath ${snapper_snapshot_path}/${num}/snapshot`" {
btrfs_subvol="$subvol"
extra_cmdline="rootflags=subvol=\$3"
export extra_cmdline
snapshot_num=$num
export snapshot_num
configfile "\$2/boot/grub2/grub.cfg"
btrfs_subvol=\$saved_subvol
}
fi
EOF
hotkey=`incr_hotkey`
return 0
}
snapper_snapshots_cfg_refresh () {
if [ ! -d "$snapper_snapshot_path" ]; then
return
fi
cs=
for s_dir in ${snapper_snapshot_path}/*; do
snapshot="${s_dir}/snapshot"
# list only read-only snapshot (bnc#878528)
if [ ! -d ${s_dir} -o -w "$snapshot" ]; then
continue
fi
if [ -r "${s_dir}/info.xml" -a -r "${s_dir}/snapshot/boot/grub2/grub.cfg" ]; then
cs="${s_dir}
${cs}"
else
# cleanup any grub-snapshot.cfg without associated snapshot info
snapper_cfg="${s_dir}/${snapshot_submenu_name}"
if [ -f "$snapper_cfg" ]; then
rm -f "$snapper_cfg"
rmdir "$s_dir" 2>/dev/null || true
fi
continue
fi
done
hk=""
[ -z "$hotkey" ] || hk="--hotkey=s"
for c in $(printf '%s' "${cs}" | sort -Vr); do
if ! snapshot_submenu "$c" > "${c}/${snapshot_submenu_name}"; then
rm -f "${c}/${snapshot_submenu_name}"
continue
fi
snapshot_cfg="${snapshot_cfg}
if [ -f \"$c/${snapshot_submenu_name}\" ]; then
source \"$c/${snapshot_submenu_name}\"
fi"
done
cat <<EOF >"${snapper_snapshots_cfg}.new"
if [ -z "\$extra_cmdline" ]; then
submenu $hk "Start bootloader from a read-only snapshot" {${snapshot_cfg}
if [ x\$snapshot_found != xtrue ]; then
submenu "Not Found" { true; }
fi
}
fi
EOF
if ${grub_script_check} "${snapper_snapshots_cfg}.new"; then
mv -f "${snapper_snapshots_cfg}.new" "${snapper_snapshots_cfg}"
fi
}
snapshot_submenu_clean () {
for s_dir in ${snapper_snapshot_path}/*; do
snapper_cfg="${s_dir}/${snapshot_submenu_name}"
if [ -f "$snapper_cfg" ]; then
rm -f "$snapper_cfg"
rmdir "$s_dir" 2>/dev/null || true
fi
done
if [ -f "${snapper_snapshot_path}/${snapshot_submenu_name}" ]; then
rm -f "${snapper_snapshot_path}/${snapshot_submenu_name}"
fi
}
set_grub_setting () {
name=$1
val=$2
if grep -q "$name" "$grub_setting"; then
sed -i -e "s!.*\($name\)=.*!\1=\"$val\"!" "$grub_setting"
else
echo "$name=\"$val\"" >> "$grub_setting"
fi
}
enable_grub_settings () {
set_grub_setting SUSE_BTRFS_SNAPSHOT_BOOTING "true"
}
disable_grub_settings () {
set_grub_setting SUSE_BTRFS_SNAPSHOT_BOOTING "false"
}
update_grub () {
"${grub_mkconfig}" -o "${grub_cfg}"
}
machine=`uname -m`
case "$machine" in
(s390|s390x)
hotkey=1
s390=1
;;
esac
cmdline="$0 $* hotkey='$hotkey'"
# Check the arguments.
while test $# -gt 0
do
option=$1
shift
case "$option" in
-e | --enable)
opt_enable=true
;;
-d | --disable)
opt_enable=false
;;
-r | --refresh)
opt_refresh=true
;;
-c | --clean)
opt_clean=true
;;
-*)
;;
esac
done
if [ "x${opt_enable}" = "xtrue" ]; then
#enable_grub_settings
#update_grub
snapper_snapshots_cfg_refresh
elif [ "x${opt_enable}" = "xfalse" ]; then
#disable_grub_settings
update_grub
snapshot_submenu_clean
fi
if [ x${opt_refresh} = "xtrue" ]; then
snapper_snapshots_cfg_refresh
fi
if [ x${opt_clean} = "xtrue" ]; then
snapshot_submenu_clean
fi

View File

@ -1,83 +0,0 @@
Index: grub-2.02~beta2/util/grub-mkconfig.in
===================================================================
--- grub-2.02~beta2.orig/util/grub-mkconfig.in
+++ grub-2.02~beta2/util/grub-mkconfig.in
@@ -261,7 +261,8 @@ export GRUB_DEFAULT \
GRUB_CMDLINE_LINUX_RECOVERY \
GRUB_USE_LINUXEFI \
SUSE_BTRFS_SNAPSHOT_BOOTING \
- SUSE_CMDLINE_XENEFI
+ SUSE_CMDLINE_XENEFI \
+ SUSE_REMOVE_LINUX_ROOT_PARAM
if test "x${grub_cfg}" != "x"; then
rm -f "${grub_cfg}.new"
Index: grub-2.02~beta2/util/grub.d/10_linux.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/10_linux.in
+++ grub-2.02~beta2/util/grub.d/10_linux.in
@@ -66,7 +66,7 @@ case x"$GRUB_FS" in
else
rootsubvol="`make_system_path_relative_to_its_root /`"
rootsubvol="${rootsubvol#/}"
- if [ "x${rootsubvol}" != x ]; then
+ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
fi
fi;;
@@ -77,6 +77,10 @@ case x"$GRUB_FS" in
;;
esac
+if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
+ LINUX_ROOT_DEVICE=""
+fi
+
title_correction_code=
hotkey=1
Index: grub-2.02~beta2/util/grub.d/20_linux_xen.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/20_linux_xen.in
+++ grub-2.02~beta2/util/grub.d/20_linux_xen.in
@@ -80,7 +80,7 @@ case x"$GRUB_FS" in
else
rootsubvol="`make_system_path_relative_to_its_root /`"
rootsubvol="${rootsubvol#/}"
- if [ "x${rootsubvol}" != x ]; then
+ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
fi
fi;;
@@ -91,6 +91,10 @@ case x"$GRUB_FS" in
;;
esac
+if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
+ LINUX_ROOT_DEVICE=""
+fi
+
title_correction_code=
if [ -d /sys/firmware/efi ]; then
Index: grub-2.02~beta2/util/s390x/zipl2grub.pl.in
===================================================================
--- grub-2.02~beta2.orig/util/s390x/zipl2grub.pl.in
+++ grub-2.02~beta2/util/s390x/zipl2grub.pl.in
@@ -361,9 +361,13 @@ while ( <IN> ) {
} else {
$v = "";
}
- if ($k eq "GRUB_DEVICE" && $v !~ /^UUID/ && ! -e $v) {
- s{root=\@$k\@}{}g;
- next;
+ if ($k eq "GRUB_DEVICE") {
+ if (($v !~ /^UUID/ && ! -e $v) ||
+ (exists( $C{SUSE_REMOVE_LINUX_ROOT_PARAM}) &&
+ $C{SUSE_REMOVE_LINUX_ROOT_PARAM} eq "true")) {
+ s{root=\@$k\@}{}g;
+ next;
+ }
}
s{\@$k\@}{$v}g;
}

View File

@ -1,216 +0,0 @@
#!/bin/bash
#
# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
set -e
GRUB_ONCE="/usr/sbin/grub2-once"
GRUB_ENV="/boot/grub2/grubenv"
GRUB_EDITENV="/usr/bin/grub2-editenv"
GRUB_CONF="/boot/grub2/grub.cfg"
BLKID="/usr/sbin/blkid"
error_quit()
{
echo "$1" >&2
exit 1
}
check-system()
{
[ -x "${GRUB_ONCE}" ] || error_quit "ERROR: cannot find or execute ${GRUB_ONCE}"
[ -x "${GRUB_EDITENV}" ] || error_quit "ERROR: cannot find or execute ${GRUB_EDITENV}"
[ -x "${BLKID}" ] || error_quit "ERROR: cannot find or execute ${BLKID}"
[ -r "${GRUB_CONF}" ] || error_quit "ERROR: cannot find or read ${GRUB_CONF}"
}
#####################################################################
# gets a list of available kernels from /boot/grub2/grub.cfg
# kernels are in the array $KERNELS
get-kernels()
{
local I DUMMY MNT ROOTDEV
declare -i I=0
# we need the root partition later to decide if this is the kernel to select
while read ROOTDEV MNT DUMMY; do
[ "$ROOTDEV" = "rootfs" ] && continue # not what we are searching for
if [ "$MNT" = "/" ]; then
break
fi
done < /proc/mounts
while read -r LINE; do
case $LINE in
menuentry\ *)
local PATTERN="^\\s*menuentry\\s\\+\\(.\\+\\)\\s*{.*\$"
MENUENTRY_OPTS=`echo "$LINE" | sed -n -e "s/${PATTERN}/\\1/p"`
MENU_ENTRIES[$I]=`eval "printf \"%s\n\" $MENUENTRY_OPTS | head -1"`
;;
set\ default*)
local DEFAULT=${LINE#*default=}
if echo $DEFAULT | grep -q saved_entry ; then
local SAVED=`$GRUB_EDITENV $GRUB_ENV list | sed -n s/^saved_entry=//p`
if [ -n "$SAVED" ]; then
DEFAULT_BOOT=$($GRUB_ONCE --show-mapped "$SAVED")
fi
fi
;;
linux*noresume*|module*xen*noresume*)
echo " Skipping ${MENU_ENTRIES[$I]}, because it has the noresume option" >&2
;;
linux*root=*|module*xen*root=*)
local ROOT
ROOT=${LINE#*root=}
DUMMY=($ROOT)
ROOT=${DUMMY[0]}
if [ x"${ROOT:0:5}" = "xUUID=" ]; then
UUID=${ROOT#UUID=}
if [ -n "$UUID" ]; then
ROOT=$($BLKID -U $UUID || true)
if [ -z "$ROOT" ]; then
echo " Skipping ${MENU_ENTRIES[$I]}, because its root device $UUID is not found" >&2
continue
fi
fi
fi
if [ "$(stat -Lc '%t:%T' $ROOT || true)" != "$(stat -Lc '%t:%T' $ROOTDEV || true)" ]; then
echo " Skipping ${MENU_ENTRIES[$I]}, because its root= parameter ($ROOT)" >&2
echo " does not match the current root device ($ROOTDEV)." >&2
continue
fi
DUMMY=($LINE) # kernel (hd0,1)/boot/vmlinuz-ABC root=/dev/hda2
KERNELS[$I]=${DUMMY[1]##*/} # vmlinuz-ABC
# DEBUG "Found kernel entry #${I}: '${DUMMY[1]##*/}'" INFO
let ++I
;;
linux*|module*xen*)
# a kernel without "root="? We better skip that one...
echo " Skipping ${MENU_ENTRIES[$I]}, because it has no root= option" >&2
;;
*) ;;
esac
done < "$GRUB_CONF"
}
#############################################################
# restore grub default after (eventually failed) resume
grub-once-restore()
{
echo "INFO: Running grub-once-restore .."
check-system
$GRUB_EDITENV $GRUB_ENV unset next_entry
echo "INFO: Done."
}
#############################################################################
# try to find a kernel image that matches the actually running kernel.
# We need this, if more than one kernel is installed. This works reasonably
# well with grub, if all kernels are named "vmlinuz-`uname -r`" and are
# located in /boot. If they are not, good luck ;-)
find-kernel-entry()
{
NEXT_BOOT=""
ARCH=`uname -m`
declare -i I=0
# DEBUG "running kernel: $RUNNING" DIAG
while [ -n "${KERNELS[$I]}" ]; do
BOOTING="${KERNELS[$I]}"
if IMAGE=`readlink /boot/$BOOTING` && [ -e "/boot/${IMAGE##*/}" ]; then
# DEBUG "Found kernel symlink $BOOTING => $IMAGE" INFO
BOOTING=$IMAGE
fi
case $ARCH in
ppc*) BOOTING="${BOOTING#*vmlinux-}" ;;
*) BOOTING="${BOOTING#*vmlinuz-}" ;;
esac
if [ "$RUNNING" == "$BOOTING" -a -n "${MENU_ENTRIES[$I]}" ]; then
NEXT_BOOT="${MENU_ENTRIES[$I]}"
echo " running kernel is grub menu entry $NEXT_BOOT (${KERNELS[$I]})"
break
fi
let ++I
done
# if we have not found a kernel, issue a warning.
# if we have found a kernel, we'll do "grub-once" later, after
# prepare_suspend finished.
if [ -z "$NEXT_BOOT" ]; then
echo "WARNING: no kernelfile matching the running kernel found"
fi
}
#############################################################################
# if we did not find a kernel (or BOOT_LOADER is not GRUB) check,
# if the running kernel is still the one that will (probably) be booted for
# resume (default entry in menu.lst or, if there is none, the kernel file
# /boot/vmlinuz points to.)
# This will only work, if you use "original" SUSE kernels.
# you can always override with the config variable set to "yes"
prepare-grub()
{
echo "INFO: Running prepare-grub .."
check-system
get-kernels
RUNNING=`uname -r`
find-kernel-entry
if [ -z "$NEXT_BOOT" ]; then
# which kernel is booted with the default entry?
BOOTING="${KERNELS[$DEFAULT_BOOT]}"
# if there is no default entry (no menu.lst?) we fall back to
# the default of /boot/vmlinuz.
[ -z "$BOOTING" ] && BOOTING="vmlinuz"
if IMAGE=`readlink /boot/$BOOTING` && [ -e "/boot/${IMAGE##*/}" ]; then
BOOTING=$IMAGE
fi
BOOTING="${BOOTING#*vmlinuz-}"
echo "running kernel: '$RUNNING', probably booting kernel: '$BOOTING'"
if [ "$BOOTING" != "$RUNNING" ]; then
error_quit "ERROR: kernel version mismatch, cannot suspend to disk"
fi
else
# set the bootloader to the running kernel
echo " preparing boot-loader: selecting entry $NEXT_BOOT, kernel /boot/$BOOTING"
T1=`date +"%s%N"`
sync; sync; sync # this is needed to speed up grub-once on reiserfs
T2=`date +"%s%N"`
echo " running $GRUB_ONCE \"${NEXT_BOOT}\""
${GRUB_ONCE} "$NEXT_BOOT"
T3=`date +"%s%N"`
S=$(((T2-T1)/100000000)); S="$((S/10)).${S:0-1}"
G=$(((T3-T2)/100000000)); G="$((G/10)).${G:0-1}"
echo " time needed for sync: $S seconds, time needed for grub: $G seconds."
fi
echo "INFO: Done."
}
###### main()
eval `grep LOADER_TYPE= /etc/sysconfig/bootloader`
if [ x"$LOADER_TYPE" != "xgrub2" -a x"$LOADER_TYPE" != "xgrub2-efi" ]; then
echo "INFO: Skip running $0 for bootloader: $LOADER_TYPE"
exit 0
fi
if [ "$2" = suspend ]; then
echo "INFO: Skip running $0 for $2"
exit 0
else
echo "INFO: running $0 for $2"
fi
if [ "$1" = pre ] ; then
prepare-grub
fi
if [ "$1" = post ] ; then
grub-once-restore
fi

View File

@ -1,15 +0,0 @@
DejaVu Sans is proportional font and looks pretty bad in terminal
window. Use GNU Unifont instead.
Index: grub-2.02~beta2/themes/starfield/theme.txt
===================================================================
--- grub-2.02~beta2.orig/themes/starfield/theme.txt
+++ grub-2.02~beta2/themes/starfield/theme.txt
@@ -25,7 +25,7 @@ message-font: "DejaVu Sans Regular 12"
message-color: "#000"
message-bg-color: "#fff"
terminal-box: "terminal_box_*.png"
-terminal-font: "DejaVu Sans Regular 12"
+terminal-font: "Gnu Unifont Mono Regular 16"
desktop-image: "starfield.png"
#help bar at the bottom

View File

@ -1,12 +0,0 @@
diff -urN grub-2.02~beta2.old/util/grub-mkconfig_lib.in grub-2.02~beta2/util/grub-mkconfig_lib.in
--- grub-2.02~beta2.old/util/grub-mkconfig_lib.in 2014-04-11 15:20:42.451394845 +0200
+++ grub-2.02~beta2/util/grub-mkconfig_lib.in 2014-04-11 15:58:02.940618803 +0200
@@ -229,7 +229,7 @@
version_test_numeric_a="$version_test_numeric_b"
version_test_numeric_b="$version_test_numeric_c"
fi
- if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
+ if [ "`printf '%s\n' "$version_test_gt_a" "$version_test_gt_b" | /usr/lib/rpm/rpmsort -r | head -n1`" = "$version_test_gt_a" ] ; then
return 0
else
return 1

View File

@ -1,32 +0,0 @@
From: Jeff Mahoney <jeffm@suse.com>
Subject: grub2: use stat instead of udevadm for partition lookup
References: bnc#883635
sysfs_partition_path calls udevadm to resolve the sysfs path for
a block device. That can be accomplished by stating the device node
and using the major/minor to follow the symlinks in /sys/dev/block/.
This cuts the execution time of grub2-mkconfig from 10s to 2s on
my system.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
grub-core/osdep/linux/hostdisk.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/grub-core/osdep/linux/hostdisk.c
+++ b/grub-core/osdep/linux/hostdisk.c
@@ -105,6 +106,13 @@ sysfs_partition_path (const char *dev, c
char *buf = NULL;
size_t len = 0;
char *path = NULL;
+ struct stat st;
+ int ret;
+
+ ret = stat(dev, &st);
+ if (ret == 0 && S_ISBLK(st.st_mode))
+ return xasprintf ("/sys/dev/block/%u:%u/%s",
+ major (st.st_rdev), minor (st.st_rdev), entry);
argv[0] = "udevadm";
argv[1] = "info";

View File

@ -1,20 +0,0 @@
Index: grub-2.02~beta2/grub-core/video/i386/pc/vbe.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/video/i386/pc/vbe.c
+++ grub-2.02~beta2/grub-core/video/i386/pc/vbe.c
@@ -1053,6 +1053,15 @@ grub_video_vbe_setup (unsigned int width
|| vbe_mode_info.y_resolution > height)
/* Resolution exceeds that of preferred mode. */
continue;
+
+ /* Blacklist 1440x900x32 from preferred mode handling until a
+ better solution is available. This mode causes problems on
+ many Thinkpads.
+ */
+ if (vbe_mode_info.x_resolution == 1440 &&
+ vbe_mode_info.y_resolution == 900 &&
+ vbe_mode_info.bits_per_pixel == 32)
+ continue;
}
else
{

View File

@ -1,31 +0,0 @@
Index: grub-2.02~beta2/grub-core/loader/i386/xen.c
===================================================================
--- grub-2.02~beta2.orig/grub-core/loader/i386/xen.c
+++ grub-2.02~beta2/grub-core/loader/i386/xen.c
@@ -688,7 +688,7 @@ fail:
return grub_errno;
}
-static grub_command_t cmd_xen, cmd_initrd, cmd_module, cmd_multiboot;
+static grub_command_t cmd_xen, cmd_initrd, cmd_module, cmd_multiboot, cmd_xen16, cmd_initrd16;
GRUB_MOD_INIT (xen)
{
@@ -700,6 +700,10 @@ GRUB_MOD_INIT (xen)
0, N_("Load initrd."));
cmd_module = grub_register_command ("module", grub_cmd_module,
0, N_("Load module."));
+ cmd_xen16 = grub_register_command ("linux16", grub_cmd_xen,
+ 0, N_("Load Linux."));
+ cmd_initrd16 = grub_register_command ("initrd16", grub_cmd_initrd,
+ 0, N_("Load initrd."));
my_mod = mod;
}
@@ -709,4 +713,6 @@ GRUB_MOD_FINI (xen)
grub_unregister_command (cmd_initrd);
grub_unregister_command (cmd_multiboot);
grub_unregister_command (cmd_module);
+ grub_unregister_command (cmd_xen16);
+ grub_unregister_command (cmd_initrd16);
}

View File

@ -1,136 +0,0 @@
insmod part_msdos
insmod part_gpt
insmod search
insmod configfile
insmod legacy_configfile
set debian_cddev=""
set debian_cdarch=""
if [ "${grub_cpu}" = "x86_64" ]; then
debian_cdarch="amd"
fi
if [ "${grub_cpu}" = "i386" ]; then
debian_cdarch="i386"
fi
if [ -n "${debian_cdarch}" ]; then
set debian_kern="/install.${debian_cdarch}/xen/vmlinuz"
set debian_initrd="/install.${debian_cdarch}/xen/initrd.gz"
search -s debian_domUcfg -f "/install.${debian_cdarch}/xen/debian.cfg"
search -s debian_cdkern -f "${debian_kern}"
search -s debian_cdinitrd -f "${debian_initrd}"
if [ -n "${debian_domUcfg}" -a -n "${debian_cdinitrd}" -a -n "${debian_cdkern}" -a "${debian_domUcfg}" = "${debian_cdinitrd}" -a "${debian_domUcfg}" = "${debian_cdkern}" ]; then
debian_cddev="${debian_domUcfg}"
fi
fi
set fedora_cddev=""
if [ "${grub_cpu}" = "x86_64" ]; then
set fedora_kern="/images/pxeboot/vmlinuz"
set fedora_initrd="/images/pxeboot/initrd.img"
search -s fedora_cdkern -f "${fedora_kern}"
search -s fedora_cdinitrd -f "${fedora_initrd}"
if [ -n "${fedora_cdkern}" -a -n "${fedora_cdinitrd}" -a "${fedora_cdkern}" = "${fedora_cdinitrd}" ]; then
set fedora_cddev="${fedora_cdkern}"
fi
fi
set suse_cddev=""
search -s suse_cddev_content -f "/content"
search -s suse_cddev_product -f "/media.1/products"
if [ -n "${suse_cddev_content}" -a -n "${suse_cddev_product}" -a "${suse_cddev_content}" = "${suse_cddev_product}" ]; then
set suse_cddev="${suse_cddev_content}"
fi
set hdcfg_list="\
/boot/grub2/grub.cfg \
/@/boot/grub2/grub.cfg \
/@/.snapshots/1/snapshot/boot/grub2/grub.cfg \
/.snapshots/1/snapshot/boot/grub2/grub.cfg \
/grub2/grub.cfg\
"
set hdlst_list="\
/boot/grub/menu.lst \
/grub/menu.lst\
"
for c in ${hdcfg_list}; do
if search -s hddev -f "${c}"; then
menuentry "${hddev} Boot From Hard Disk (${c})" "${hddev}" "${c}" {
set root="${2}"
set cfg="${3}"
configfile "${cfg}"
}
break
fi
done
for c in ${hdlst_list}; do
if search -s hddev -f "${c}"; then
menuentry "${hddev} Boot From Hard Disk (${c})" "${hddev}" "${c}" {
set root="${2}"
set cfg="${3}"
legacy_configfile "${cfg}"
}
break
fi
done
set timeout=0
if [ -n "${debian_cddev}" ]; then
set timeout=8
menuentry "${debian_cddev} Debian Install" {
set root="${debian_cddev}"
linux "${debian_kern}" ignore_loglevel
initrd "${debian_initrd}"
}
fi
if [ -n "${fedora_cddev}" ]; then
set timeout=8
menuentry "${fedora_cddev} Fedora Install" {
set root="${fedora_cddev}"
linux "${fedora_kern}" ignore_loglevel
initrd "${fedora_initrd}"
}
menuentry "${fedora_cddev} Fedora Rescue" {
set root="${fedora_cddev}"
linux "${fedora_kern}" ignore_loglevel rescue
initrd "${fedora_initrd}"
}
fi
if [ -n "${suse_cddev}" ]; then
if [ "${grub_cpu}" = "i386" ]; then
set suse_cdarch="i586"
else
set suse_cdarch="${grub_cpu}"
fi
set timeout=8
set root="${suse_cddev}"
set suse_cdcfg="/boot/${suse_cdarch}/grub2-xen/grub.cfg"
set suse_cdkern="/boot/${suse_cdarch}/vmlinuz-xen"
set suse_cdinitrd="/boot/${suse_cdarch}/initrd-xen"
if [ -f "${suse_cdcfg}" ]; then
menuentry "${suse_cddev} SUSE Install menu" {
set root="${suse_cddev}"
configfile "${suse_cdcfg}"
}
elif [ -f "${suse_cdkern}" -a -f "$suse_cdinitrd" ]; then
menuentry "${suse_cddev} SUSE Install" {
linux "${suse_cdkern}" linemode=1 xencons=hvc0
initrd "${suse_cdinitrd}"
}
menuentry "${suse_cddev} SUSE Rescue" {
linux "${suse_cdkern}" linemode=1 xencons=hvc0 rescue=1
initrd "${suse_cdinitrd}"
}
menuentry "${suse_cddev} SUSE Upgrade" {
linux "${suse_cdkern}" linemode=1 xencons=hvc0 upgrade=1
initrd "${suse_cdinitrd}"
}
else
echo "the device ${suse_cddev} is not xen pv bootable"
fi
fi

View File

@ -1,15 +0,0 @@
Index: grub-2.02~beta2/util/s390x/zipl2grub.pl.in
===================================================================
--- grub-2.02~beta2.orig/util/s390x/zipl2grub.pl.in
+++ grub-2.02~beta2/util/s390x/zipl2grub.pl.in
@@ -361,6 +361,10 @@ while ( <IN> ) {
} else {
$v = "";
}
+ if ($k eq "GRUB_DEVICE" && $v !~ /^UUID/ && ! -e $v) {
+ s{root=\@$k\@}{}g;
+ next;
+ }
s{\@$k\@}{$v}g;
}
Info( 2, $_);

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
addFilter("zero-length /boot/grub2/grub.cfg")
addFilter("non-etc-or-var-file-marked-as-conffile /boot/grub2/grub.cfg")
addFilter("non-conffile-in-etc /etc/bash_completion.d/grub")
addFilter("non-conffile-in-etc /etc/grub.d/README")
addFilter("statically-linked-binary .*/grub2/*/kernel.img")
# We need to supply unstripped files for grub
addFilter("unstripped-binary-or-object .*/grub2/*/.*.mod")
# TODO: s390 Experts: is this sensible?!
addFilter("s390x: W: executable-stack")

1181
grub2.spec

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +0,0 @@
Index: grub-2.02~beta3/docs/grub.texi
===================================================================
--- grub-2.02~beta3.orig/docs/grub.texi
+++ grub-2.02~beta3/docs/grub.texi
@@ -32,15 +32,15 @@ Invariant Sections.
@dircategory Kernel
@direntry
-* GRUB: (grub). The GRand Unified Bootloader
-* grub-install: (grub)Invoking grub-install. Install GRUB on your drive
-* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration
-* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2.
-* grub-mkrelpath: (grub)Invoking grub-mkrelpath.
-* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image
-* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB
-* grub-probe: (grub)Invoking grub-probe. Probe device information
-* grub-script-check: (grub)Invoking grub-script-check.
+* GRUB2: (grub2). The GRand Unified Bootloader
+* grub2-install: (grub2)Invoking grub-install. Install GRUB on your drive
+* grub2-mkconfig: (grub2)Invoking grub-mkconfig. Generate GRUB configuration
+* grub2-mkpasswd-pbkdf2: (grub2)Invoking grub-mkpasswd-pbkdf2.
+* grub2-mkrelpath: (grub2)Invoking grub-mkrelpath.
+* grub2-mkrescue: (grub2)Invoking grub-mkrescue. Make a GRUB rescue image
+* grub2-mount: (grub2)Invoking grub-mount. Mount a file system using GRUB
+* grub2-probe: (grub2)Invoking grub-probe. Probe device information
+* grub2-script-check: (grub2)Invoking grub-script-check.
@end direntry
@setchapternewpage odd

View File

@ -1,31 +0,0 @@
From 78270522e8b8c0674941e0752c245dd8468e5bf8 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Wed, 1 Aug 2012 15:46:34 +0800
Subject: [PATCH] not display menu when boot once
References: bnc#771587
Patch-Mainline: no
We should prevent the menu from being displayed if boot once is
specified. This is in order to compliant with Grub1's behavior
and is better than current as it's not make any sense to bother
user to make decision when decision has been made.
---
util/grub.d/00_header.in | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
Index: grub-2.02~beta2/util/grub.d/00_header.in
===================================================================
--- grub-2.02~beta2.orig/util/grub.d/00_header.in
+++ grub-2.02~beta2/util/grub.d/00_header.in
@@ -304,7 +304,9 @@ make_timeout ()
style="menu"
fi
cat << EOF
-if [ x\$feature_timeout_style = xy ] ; then
+if [ x\${boot_once} = xtrue ]; then
+ set timeout=0
+elif [ x\$feature_timeout_style = xy ] ; then
set timeout_style=${style}
set timeout=${timeout}
EOF

View File

@ -1,26 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEdDCCA1ygAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgTEgMB4GA1UEAwwXb3Bl
blNVU0UgU2VjdXJlIEJvb3QgQ0ExCzAJBgNVBAYTAkRFMRIwEAYDVQQHDAlOdXJl
bWJlcmcxGTAXBgNVBAoMEG9wZW5TVVNFIFByb2plY3QxITAfBgkqhkiG9w0BCQEW
EmJ1aWxkQG9wZW5zdXNlLm9yZzAeFw0xMzA4MjYxNjEyMDdaFw0zNTA3MjIxNjEy
MDdaMIGBMSAwHgYDVQQDDBdvcGVuU1VTRSBTZWN1cmUgQm9vdCBDQTELMAkGA1UE
BhMCREUxEjAQBgNVBAcMCU51cmVtYmVyZzEZMBcGA1UECgwQb3BlblNVU0UgUHJv
amVjdDEhMB8GCSqGSIb3DQEJARYSYnVpbGRAb3BlbnN1c2Uub3JnMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3t9hknqk/oPRfTtoDrGn8E6Sk/xHPnAt
Tojcmp76M7Sm2w4jwQ2owdVlBIQE/zpIGE85MuTKTvkEnp8PzSBdYaunANil/yt/
vuhHwy9bAsi73o4a6UbThu//iJmQ6xCJuIs/PqgHxlV6btNf/IM8PRbtJsUTc5Kx
cB4ilcgAbCV2RvGi2dCwmGgPpy2xDWeJypRK6hLFkVV2f2x6LvkYiZ/49CRD1TVq
ywAOLu1L4l0J2BuXcJmeWm+mgaidqVh2fWlxgtO6OpZDm/DaFcZO6cgVuenLx+Rx
zuoQG2vEKnABqVK0F94AUs995P0PTQMYspAo1G/Erla8NmBJRotrCwIDAQABo4H0
MIHxMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGhCYA3iLExHfpW+I9/qlRPl
lxdiMIGuBgNVHSMEgaYwgaOAFGhCYA3iLExHfpW+I9/qlRPllxdioYGHpIGEMIGB
MSAwHgYDVQQDDBdvcGVuU1VTRSBTZWN1cmUgQm9vdCBDQTELMAkGA1UEBhMCREUx
EjAQBgNVBAcMCU51cmVtYmVyZzEZMBcGA1UECgwQb3BlblNVU0UgUHJvamVjdDEh
MB8GCSqGSIb3DQEJARYSYnVpbGRAb3BlbnN1c2Uub3JnggEBMA4GA1UdDwEB/wQE
AwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAiqOJwo7Z+YIL8zPO6RkXF6NlgM0zrgZR
Vim2OId79J38KI6q4FMSDjpgxwbYOmF2O3cI9JSkjHxHOpnYhJsXzCBiLuJ25MY2
DSbpLlM1Cvs6NZNFw5OCwQvzCOlXH1k3qdBsafto6n87r9P3WSeO1MeWc/QMCvc+
5K9sjMd6bwl59EEf428R+z5ssaB75JK3yvky9d7DsHN947OCXc3sYdz+DD7Gteds
LV2Sc//tqmqpm2aeXjptcLAxwM7fLyEQaAyH83egMzEKDxX27jKIxZpTcc0NGqEo
idC/9lasSzs2BisBxevl3HKDPZSsKIMT+8FdJ5wT9jJf9h9Ktz5Tig==
-----END CERTIFICATE-----

0
ready Normal file
View File

View File

@ -1,40 +0,0 @@
From 031abf80020b2fa75850d6e09f4489b687a5cb19 Mon Sep 17 00:00:00 2001
From: Jiri Slaby <jirislaby@gmail.com>
Date: Sun, 24 Jun 2012 15:40:40 +0200
Subject: [PATCH] rename grub info file to grub2
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
From: Andrey Borzenkov <arvidjaar@gmail.com>
Do not rename file here. quilt does not support it and creates the
whole file if patch needs refreshing. It means that to regenerate two
files - Makefile.core.am and Makefile.util.am - it may be necessary to
manually rename it.
---
Index: grub-2.02~beta3/docs/Makefile.am
===================================================================
--- grub-2.02~beta3.orig/docs/Makefile.am 2016-02-28 19:19:14.788874638 +0300
+++ grub-2.02~beta3/docs/Makefile.am 2016-02-28 19:19:14.780874638 +0300
@@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = subdir-objects
# AM_MAKEINFOFLAGS = --no-split --no-validate
-info_TEXINFOS = grub.texi grub-dev.texi
+info_TEXINFOS = grub2.texi grub-dev.texi
grub_TEXINFOS = fdl.texi
EXTRA_DIST = font_char_metrics.png font_char_metrics.txt
Index: grub-2.02~beta3/docs/grub.texi
===================================================================
--- grub-2.02~beta3.orig/docs/grub.texi 2016-02-28 19:19:14.788874638 +0300
+++ grub-2.02~beta3/docs/grub.texi 2016-02-28 19:19:14.784874638 +0300
@@ -1,7 +1,7 @@
\input texinfo
@c -*-texinfo-*-
@c %**start of header
-@setfilename grub.info
+@setfilename grub2.info
@include version.texi
@settitle GNU GRUB Manual @value{VERSION}
@c Unify all our little indices for now.

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:36885e7f4039a2634a0abeca7f8ab631c32abc5977119eb33c06c752fb3cecc5
size 516764

View File

@ -1,27 +0,0 @@
From 3729b131ef1dcaa043242e8074418249695d381b Mon Sep 17 00:00:00 2001
From: Jiri Slaby <jirislaby@gmail.com>
Date: Sun, 24 Jun 2012 20:51:52 +0200
Subject: [PATCH] use grub2 as a package name
This will ease all of the renaming of directories and all the pkgdata
hacks.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
configure | 24 ++++++++++++------------
configure.ac | 2 +-
2 files changed, 13 insertions(+), 13 deletions(-)
Index: grub-2.02~rc1/configure.ac
===================================================================
--- grub-2.02~rc1.orig/configure.ac
+++ grub-2.02~rc1/configure.ac
@@ -31,7 +31,7 @@ dnl (such as BUILD_CC, BUILD_CFLAGS, etc
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
dnl used for the target type. See INSTALL for full list of variables.
-AC_INIT([GRUB],[2.02~rc1],[bug-grub@gnu.org])
+AC_INIT([GRUB2],[2.02~rc1],[bug-grub@gnu.org])
AC_CONFIG_AUX_DIR([build-aux])