On Thu, 15 Aug 2019, Steven Haigh wrote:

> Having a bit of a look here....
>
> My test system grubenv file has:
> # GRUB Environment Block
> saved_entry=0
> kernelopts=root=UUID=5346b4d9-885f-4673-8aff-04a16bf1971a ro 
> rootflags=subvol=root selinux=0 rhgb quiet
> boot_success=1
> #################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################

I have attached a revision of the first patch which should handle a 
numeric saved_entry.

        Michael Young
From 51a9dce9de3ea159011928e2db8541f3c7e8383a Mon Sep 17 00:00:00 2001
From: Michael Young <m.a.yo...@durham.ac.uk>
Date: Thu, 15 Aug 2019 19:55:30 +0100
Subject: [PATCH] read grubenv and set default from saved_entry or next_entry

This patch looks for a grubenv file in the same directory as the
grub.cfg file and includes it at front of the grub.cfg file when passed
to parse()

As the grubenv file consists of variable=value lines padded by hashes these
are treated as commands in parse() where it uses the value of saved_entry
or next_entry (if set) to set the default entry if a title matches or is
a number.
---
 tools/pygrub/src/GrubConf.py | 11 +++++++++++
 tools/pygrub/src/pygrub      | 13 ++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
index 594139bac7..22e0948da2 100644
--- a/tools/pygrub/src/GrubConf.py
+++ b/tools/pygrub/src/GrubConf.py
@@ -383,6 +383,8 @@ class Grub2ConfigFile(_GrubConfigFile):
         img = None
         title = ""
         menu_level=0
+        img_count=0
+        default_title=""
         for l in lines:
             l = l.strip()
             # skip blank lines
@@ -408,6 +410,9 @@ class Grub2ConfigFile(_GrubConfigFile):
                     raise RuntimeError("syntax error: cannot nest menuentry 
(%d %s)" % (len(img),img))
                 img = []
                 title = title_match.group(1)
+                if title == default_title:
+                    setattr(self, 'default', img_count)
+                img_count += 1
                 continue
 
             if l.startswith("submenu"):
@@ -432,6 +437,10 @@ class Grub2ConfigFile(_GrubConfigFile):
 
             (com, arg) = grub_exact_split(l, 2)
         
+            if com == "saved_entry" or com == "next_entry":
+                default_title = arg
+                continue
+
             if com == "set":
                 (com,arg) = grub2_handle_set(arg)
                 
@@ -449,6 +458,8 @@ class Grub2ConfigFile(_GrubConfigFile):
             else:
                 logging.warning("Unknown directive %s" %(com,))
             
+        if default_title.isdigit():
+            setattr(self, 'default', default_title)
         if img is not None:
             raise RuntimeError("syntax error: end of file with open 
menuentry(%d %s)" % (len(img),img))
 
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index ce7ab0eb8c..267788795b 100755
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -454,8 +454,19 @@ class Grub:
         if self.__dict__.get('cf', None) is None:
             raise RuntimeError("couldn't find bootloader config file in the 
image provided.")
         f = fs.open_file(self.cf.filename)
+        fenv = self.cf.filename.replace("grub.cfg","grubenv")
+        if fenv != self.cf.filename and fs.file_exists(fenv):
+            # if grubenv file exists next to grub.cfg prepend it
+            fenvf = fs.open_file(fenv)
+            if sys.version_info[0] < 3:
+                fsep = "\n"
+            else:
+                fsep = b"\n"
+            buf = fsep.join((fenvf.read(FS_READ_MAX),f.read(FS_READ_MAX)))
+            del fenvf
         # limit read size to avoid pathological cases
-        buf = f.read(FS_READ_MAX)
+        else:
+            buf = f.read(FS_READ_MAX)
         del f
         if sys.version_info[0] < 3:
             self.cf.parse(buf)
-- 
2.21.0

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Reply via email to