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] [PATCH 3/7] Auto-load Solaris via bootloader

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 3/7] Auto-load Solaris via bootloader
From: John Levon <levon@xxxxxxxxxxxxxxxxx>
Date: Fri, 5 Jan 2007 16:52:11 +0000
Delivery-date: Fri, 05 Jan 2007 08:51:08 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20070105165017.GA29771@xxxxxxxxxxxxxxxxxxxxxxx>
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: <20070105165017.GA29771@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.9i
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
@@ -13,7 +13,7 @@
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 #
 
-import os, sys, string, struct, tempfile
+import os, sys, string, struct, tempfile, re
 import copy
 import logging
 
@@ -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,57 @@ 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"
+        cfg["ramdisk"] = "/platform/i86pc/boot_archive"
+        if longmode:
+            cfg["kernel"] = "/platform/i86xen/kernel/amd64/unix"
+            cfg["ramdisk"] = "/platform/i86pc/amd64/boot_archive"
+
+    # Unpleasant. Typically we'll have 'root=foo -k' or 'root=foo /kernel -k',
+    # and we need to maintain Xen properties (root= and ip=) and the kernel
+    # before any user args.
+    
+    xenargs = ""
+    userargs = ""
+    
+    if not cfg["args"]:
+        cfg["args"] = cfg["kernel"]
+    else:
+        for arg in cfg["args"].split():
+            if re.match("^root=", arg) or re.match("^ip=", arg):
+                xenargs += arg + " "
+            elif arg != cfg["kernel"]:
+                userargs += arg + " "
+        cfg["args"] = xenargs + " " + cfg["kernel"] + " " + userargs
+
+    return cfg
+ 
 if __name__ == "__main__":
     sel = None
     
@@ -497,11 +530,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 +557,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.",

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