diff mbox series

[XEN,1/3] set default kernel from grubenv next_entry or saved_entry

Message ID 30a4fb6bb023348af867a253f6ff1e80efc7e232.1572038720.git.m.a.young@durham.ac.uk (mailing list archive)
State New, archived
Headers show
Series read grubenv and set default from it | expand

Commit Message

Michael Young Oct. 25, 2019, 10:52 p.m. UTC
This patch reads the contents of a grubenv file if available, and
uses the value of next_entry (in preference) or of saved_entry to
set the default kernel if there is a matching title or if it is a
number.  If either next_entry or saved_entry is set and neither is
used then the default is set to 0.

Signed-off-by: Michael Young <m.a.young@durham.ac.uk>
---
 tools/pygrub/src/GrubConf.py | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

Comments

Ian Jackson Oct. 28, 2019, 4:38 p.m. UTC | #1
YOUNG, MICHAEL A. writes ("[XEN PATCH 1/3] set default kernel from grubenv next_entry or saved_entry"):
> This patch reads the contents of a grubenv file if available, and
> uses the value of next_entry (in preference) or of saved_entry to
> set the default kernel if there is a matching title or if it is a
> number.  If either next_entry or saved_entry is set and neither is
> used then the default is set to 0.

Are you sure the grubenv file has a compatible enough syntax with the
grub.cfg file ?  I had a look at grub_split and AFIACT from the
confusing way it is expressed, it splits on the earliest of = ' ' '\t'
which I guess is right ...

Is it deliberate that your implementation strategy would honour
`next_entry' and `saved_entry' commands in grub.cfg ?

Are you sure it is correct that your implementation strategy would
honour `title' etc. if it occurred in grubenv ?  My reading of the
documentation is that grubenv may be less trusted.

Despite these misgivings, I think this patch is probably better than
nothing.

So:
  Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

But I think depending on the answer to my questions above we may want
a health warning of some kind in the release notes, or a followup.

Ian.
diff mbox series

Patch

diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
index 73f1bbed2f..1fc68cadb2 100644
--- a/tools/pygrub/src/GrubConf.py
+++ b/tools/pygrub/src/GrubConf.py
@@ -368,7 +368,7 @@  class Grub2ConfigFile(_GrubConfigFile):
     def new_image(self, title, lines):
         return Grub2Image(title, lines)
  
-    def parse(self, buf = None):
+    def parse(self, buf = None, grubenv = None):
         if buf is None:
             if self.filename is None:
                 raise ValueError("No config file defined to parse!")
@@ -379,10 +379,17 @@  class Grub2ConfigFile(_GrubConfigFile):
         else:
             lines = buf.split("\n")
 
+        if grubenv is not None:
+            lines = grubenv.split("\n") + lines
+
         in_function = False
         img = None
         title = ""
         menu_level=0
+        img_count=0
+        saved_entry = ""
+        next_entry = ""
+        entry_matched = False
         for l in lines:
             l = l.strip()
             # skip blank lines
@@ -408,6 +415,13 @@  class Grub2ConfigFile(_GrubConfigFile):
                     raise RuntimeError("syntax error: cannot nest menuentry (%d %s)" % (len(img),img))
                 img = []
                 title = title_match.group(1)
+                if title == next_entry:
+                    setattr(self, 'default', img_count)
+                    entry_matched = True
+                if title == saved_entry and not entry_matched:
+                    setattr(self, 'default', img_count)
+                    entry_matched = True
+                img_count += 1
                 continue
 
             if l.startswith("submenu"):
@@ -432,6 +446,14 @@  class Grub2ConfigFile(_GrubConfigFile):
 
             (com, arg) = grub_exact_split(l, 2)
         
+            if com == "next_entry":
+                next_entry = arg
+                continue
+
+            if com == "saved_entry":
+                saved_entry = arg
+                continue
+
             if com == "set":
                 (com,arg) = grub2_handle_set(arg)
                 
@@ -448,6 +470,13 @@  class Grub2ConfigFile(_GrubConfigFile):
                 pass
             else:
                 logging.warning("Unknown directive %s" %(com,))
+
+        if next_entry.isdigit():
+            setattr(self, 'default', next_entry)
+        elif saved_entry.isdigit() and not entry_matched:
+            setattr(self, 'default', saved_entry)
+        elif (next_entry != "" or saved_entry != "") and not entry_matched:
+            setattr(self, 'default', 0)
             
         if img is not None:
             raise RuntimeError("syntax error: end of file with open menuentry(%d %s)" % (len(img),img))