WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [RFC] bootloader improvements - pygrub-solaris

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [RFC] bootloader improvements - pygrub-solaris
From: John Levon <levon@xxxxxxxxxxxxxxxxx>
Date: Thu, 9 Nov 2006 19:23:24 +0000
Delivery-date: Thu, 09 Nov 2006 11:24:06 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20061109192017.GA16487@xxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20061109192017.GA16487@xxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.9i
# HG changeset patch
# User john.levon@xxxxxxx
# Date 1163095817 28800
# Node ID 6d2a4f2c5d6c23e1c5a096eef0112303047b2c78
# Parent  aebe98c33a6bc0cd633d915b9e0bad40718c29d6
Sniff for Solaris if not specified. This allows Solaris domU's to automatically
boot correctly without fiddling with domain configs.

Signed-off-by: John Levon <john.levon@xxxxxxx>

diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -65,6 +65,15 @@ def get_active_offset(file):
     # the first partition
     P1 = 446
     return struct.unpack("<L", buf[P1+8:P1+12])[0] * SECTOR_SIZE
+
+def open_fs(file):
+    offset = 0
+    if is_disk_image(file):
+        offset = get_active_offset(file)
+        if offset == -1:
+            raise RuntimeError, "Unable to find active partition on disk"
+
+    return fsimage.open(file, offset)
 
 class GrubLineEditor(curses.textpad.Textbox):
     def __init__(self, screen, startx, starty, line = ""):
@@ -143,12 +152,12 @@ class GrubLineEditor(curses.textpad.Text
         
 
 class Grub:
-    def __init__(self, file, isconfig = False):
+    def __init__(self, file, fs = None):
         self.screen = None
         self.entry_win = None
         self.text_win = None
         if file:
-            self.read_config(file, isconfig)
+            self.read_config(file, fs)
 
     def draw_main_windows(self):
         if self.screen is None: #only init stuff once
@@ -295,8 +304,8 @@ class Grub:
             # else, we cancelled and should just go back
             break
 
-    def read_config(self, fn, isConfig = False):
-        """Read the given file to parse the config.  If isconfig, then
+    def read_config(self, fn, fs = None):
+        """Read the given file to parse the config.  If fs = None, then
         we're being given a raw config file rather than a disk image."""
         
         if not os.access(fn, os.R_OK):
@@ -304,38 +313,25 @@ class Grub:
 
         self.cf = grub.GrubConf.GrubConfigFile()
 
-        if isConfig:
+        if not fs:
             # set the config file and parse it
             self.cf.filename = fn
             self.cf.parse()
             return
 
-        offset = 0
-        if is_disk_image(fn):
-            offset = get_active_offset(fn)
-            if offset == -1:
-                raise RuntimeError, "Unable to find active partition on disk"
-
-        # open the image and read the grub config
-        fs = fsimage.open(fn, offset)
-
-        if fs is not None:
-            grubfile = None
-            for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
-                      "/grub/menu.lst", "/grub/grub.conf"):
-                if fs.file_exists(f):
-                    grubfile = f
-                    break
-            if grubfile is None:
-                raise RuntimeError, "we couldn't find grub config file in the 
image provided."
-            f = fs.open_file(grubfile)
-            buf = f.read()
-            del f
-            del fs
-            # then parse the grub config
-            self.cf.parse(buf)
-        else:
-            raise RuntimeError, "Unable to read filesystem" 
+        grubfile = None
+        for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
+                  "/grub/menu.lst", "/grub/grub.conf"):
+            if fs.file_exists(f):
+                grubfile = f
+                break
+        if grubfile is None:
+            raise RuntimeError, "we couldn't find grub config file in the 
image provided."
+        f = fs.open_file(grubfile)
+        buf = f.read()
+        del f
+        # then parse the grub config
+        self.cf.parse(buf)
 
     def run(self):
         timeout = int(self.cf.timeout)
@@ -431,15 +427,16 @@ def get_entry_idx(cf, entry):
 
     return None
 
-def run_grub(file, isconfig, entry):
+def run_grub(file, entry, fs):
     global g
+    global sel
 
     def run_main(scr, *args):
         global sel
         global g
         sel = g.run()
 
-    g = Grub(file, isconfig)
+    g = Grub(file, fs)
     if interactive:
         curses.wrapper(run_main)
     else:
@@ -457,21 +454,48 @@ def run_grub(file, isconfig, entry):
 
     img = g.cf.images[sel]
 
+    grubcfg = { "kernel": None, "ramdisk": None, "args": None }
+
     grubcfg["kernel"] = img.kernel[1]
-    grubcfg["ramdisk"] = img.initrd[1]
-    grubcfg["args"] = img.args[1]
-
-    print "Going to boot %s" %(img.title)
-    print "  kernel: %s" % grubcfg["kernel"]
     if img.initrd:
-        print "  initrd: %s" % grubcfg["ramdisk"]
-
-    if isconfig:
-        print "  args: %s" % grubcfg["args"]
-        sys.exit(0)
-        
+        grubcfg["ramdisk"] = img.initrd[1]
+    if img.args:
+        grubcfg["args"] = img.args
+
     return grubcfg
 
+# If nothing has been specified, look for a Solaris domU. If found, perform the
+# necessary tweaks.
+def sniff_solaris(fs, cfg):
+    if not fs.file_exists("/platform/i86xen/kernel/unix"):
+        return cfg
+    
+    # darned python
+    longmode = (sys.maxint != 2147483647L)
+    if not longmode:
+        longmode = os.uname()[4] == "x86_64"
+    if not longmode:
+        if (os.access("/usr/bin/isainfo", os.R_OK) and
+            os.popen("/usr/bin/isainfo -b").read() == "64\n"):
+            longmode = True
+
+    if not cfg["kernel"]:
+        cfg["kernel"] = "/platform/i86xen/kernel/unix";
+        if longmode:
+            cfg["kernel"] = "/platform/i86xen/kernel/amd64/unix";
+        cfg["ramdisk"] = "/platform/i86pc/boot_archive"
+
+    # we need to pass the path to the kernel as the first argument, but only if
+    # it's not present in args already.
+    args = cfg["args"]
+    cfg["args"] = cfg["kernel"] + " "
+    if args:
+        if string.split(args)[0] == cfg["kernel"]:
+            cfg["args"] = ""
+        cfg["args"] += args
+
+    return cfg
+ 
 if __name__ == "__main__":
     sel = None
     
@@ -497,11 +521,11 @@ if __name__ == "__main__":
     isconfig = False
 
     # what was passed in
-    incfg = { "kernel": None, "ramdisk": None, "args": None };
-    # what grub chose
-    chosencfg = { "kernel": None, "ramdisk": None, "args": None };
+    incfg = { "kernel": None, "ramdisk": None, "args": None }
+    # what grub or sniffing chose
+    chosencfg = { "kernel": None, "ramdisk": None, "args": None }
     # what to boot
-    bootcfg = { "kernel": None, "ramdisk": None, "args": None };
+    bootcfg = { "kernel": None, "ramdisk": None, "args": None }
 
     for o, a in opts:
         if o in ("-q", "--quiet"):
@@ -524,25 +548,26 @@ if __name__ == "__main__":
         elif o in ("--isconfig",):
             isconfig = True
 
-
     if output is None or output == "-":
         fd = sys.stdout.fileno()
     else:
         fd = os.open(output, os.O_WRONLY)
 
-    if not incfg["kernel"]:
-        chosencfg = run_grub(file, isconfig, entry)
-    else:
-        chosencfg = incfg
-     
-    offset = 0
-    if is_disk_image(file):
-        offset = get_active_offset(file)
-        if offset == -1:
-            raise RuntimeError, "Unable to find active partition on disk"
-
-    # read the kernel and initrd onto the hostfs
-    fs = fsimage.open(file, offset)
+    # debug
+    if isconfig:
+        chosencfg = run_grub(file, entry)
+        print "  kernel: %s" % chosencfg["kernel"]
+        if img.initrd:
+            print "  initrd: %s" % chosencfg["ramdisk"]
+        print "  args: %s" % chosencfg["args"]
+        sys.exit(0)
+
+    fs = open_fs(file)
+
+    chosencfg = sniff_solaris(fs, incfg)
+
+    if not chosencfg["kernel"]:
+        chosencfg = run_grub(file, entry, fs)
 
     data = fs.open_file(chosencfg["kernel"]).read()
     (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.", 
dir="/var/lib/xen")

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel