# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1168349081 0
# Node ID ac626903f46b31aa8812d6c4e332a448136cdd4f
# Parent 6638763ee12ce579d299b5b525905e6c8077eb1e
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>
---
tools/pygrub/src/pygrub | 160 +++++++++++++++++++++++++++++-------------------
1 files changed, 97 insertions(+), 63 deletions(-)
diff -r 6638763ee12c -r ac626903f46b tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub Tue Jan 09 13:24:40 2007 +0000
+++ b/tools/pygrub/src/pygrub Tue Jan 09 13:24:41 2007 +0000
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|