ia64/xen-unstable

changeset 13337:ac626903f46b

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@sun.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Tue Jan 09 13:24:41 2007 +0000 (2007-01-09)
parents 6638763ee12c
children 8966444e69fa
files tools/pygrub/src/pygrub
line diff
     1.1 --- a/tools/pygrub/src/pygrub	Tue Jan 09 13:24:40 2007 +0000
     1.2 +++ b/tools/pygrub/src/pygrub	Tue Jan 09 13:24:41 2007 +0000
     1.3 @@ -13,7 +13,7 @@
     1.4  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     1.5  #
     1.6  
     1.7 -import os, sys, string, struct, tempfile
     1.8 +import os, sys, string, struct, tempfile, re
     1.9  import copy
    1.10  import logging
    1.11  
    1.12 @@ -66,6 +66,15 @@ def get_active_offset(file):
    1.13      P1 = 446
    1.14      return struct.unpack("<L", buf[P1+8:P1+12])[0] * SECTOR_SIZE
    1.15  
    1.16 +def open_fs(file):
    1.17 +    offset = 0
    1.18 +    if is_disk_image(file):
    1.19 +        offset = get_active_offset(file)
    1.20 +        if offset == -1:
    1.21 +            raise RuntimeError, "Unable to find active partition on disk"
    1.22 +
    1.23 +    return fsimage.open(file, offset)
    1.24 +
    1.25  class GrubLineEditor(curses.textpad.Textbox):
    1.26      def __init__(self, screen, startx, starty, line = ""):
    1.27          screen.addstr(startx, starty, "> ")
    1.28 @@ -143,12 +152,12 @@ class GrubLineEditor(curses.textpad.Text
    1.29          
    1.30  
    1.31  class Grub:
    1.32 -    def __init__(self, file, isconfig = False):
    1.33 +    def __init__(self, file, fs = None):
    1.34          self.screen = None
    1.35          self.entry_win = None
    1.36          self.text_win = None
    1.37          if file:
    1.38 -            self.read_config(file, isconfig)
    1.39 +            self.read_config(file, fs)
    1.40  
    1.41      def draw_main_windows(self):
    1.42          if self.screen is None: #only init stuff once
    1.43 @@ -295,8 +304,8 @@ class Grub:
    1.44              # else, we cancelled and should just go back
    1.45              break
    1.46  
    1.47 -    def read_config(self, fn, isConfig = False):
    1.48 -        """Read the given file to parse the config.  If isconfig, then
    1.49 +    def read_config(self, fn, fs = None):
    1.50 +        """Read the given file to parse the config.  If fs = None, then
    1.51          we're being given a raw config file rather than a disk image."""
    1.52          
    1.53          if not os.access(fn, os.R_OK):
    1.54 @@ -304,38 +313,25 @@ class Grub:
    1.55  
    1.56          self.cf = grub.GrubConf.GrubConfigFile()
    1.57  
    1.58 -        if isConfig:
    1.59 +        if not fs:
    1.60              # set the config file and parse it
    1.61              self.cf.filename = fn
    1.62              self.cf.parse()
    1.63              return
    1.64  
    1.65 -        offset = 0
    1.66 -        if is_disk_image(fn):
    1.67 -            offset = get_active_offset(fn)
    1.68 -            if offset == -1:
    1.69 -                raise RuntimeError, "Unable to find active partition on disk"
    1.70 -
    1.71 -        # open the image and read the grub config
    1.72 -        fs = fsimage.open(fn, offset)
    1.73 -
    1.74 -        if fs is not None:
    1.75 -            grubfile = None
    1.76 -            for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
    1.77 -                      "/grub/menu.lst", "/grub/grub.conf"):
    1.78 -                if fs.file_exists(f):
    1.79 -                    grubfile = f
    1.80 -                    break
    1.81 -            if grubfile is None:
    1.82 -                raise RuntimeError, "we couldn't find grub config file in the image provided."
    1.83 -            f = fs.open_file(grubfile)
    1.84 -            buf = f.read()
    1.85 -            del f
    1.86 -            del fs
    1.87 -            # then parse the grub config
    1.88 -            self.cf.parse(buf)
    1.89 -        else:
    1.90 -            raise RuntimeError, "Unable to read filesystem" 
    1.91 +        grubfile = None
    1.92 +        for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
    1.93 +                  "/grub/menu.lst", "/grub/grub.conf"):
    1.94 +            if fs.file_exists(f):
    1.95 +                grubfile = f
    1.96 +                break
    1.97 +        if grubfile is None:
    1.98 +            raise RuntimeError, "we couldn't find grub config file in the image provided."
    1.99 +        f = fs.open_file(grubfile)
   1.100 +        buf = f.read()
   1.101 +        del f
   1.102 +        # then parse the grub config
   1.103 +        self.cf.parse(buf)
   1.104  
   1.105      def run(self):
   1.106          timeout = int(self.cf.timeout)
   1.107 @@ -431,15 +427,16 @@ def get_entry_idx(cf, entry):
   1.108  
   1.109      return None
   1.110  
   1.111 -def run_grub(file, isconfig, entry):
   1.112 +def run_grub(file, entry, fs):
   1.113      global g
   1.114 +    global sel
   1.115  
   1.116      def run_main(scr, *args):
   1.117          global sel
   1.118          global g
   1.119          sel = g.run()
   1.120  
   1.121 -    g = Grub(file, isconfig)
   1.122 +    g = Grub(file, fs)
   1.123      if interactive:
   1.124          curses.wrapper(run_main)
   1.125      else:
   1.126 @@ -457,21 +454,57 @@ def run_grub(file, isconfig, entry):
   1.127  
   1.128      img = g.cf.images[sel]
   1.129  
   1.130 +    grubcfg = { "kernel": None, "ramdisk": None, "args": None }
   1.131 +
   1.132      grubcfg["kernel"] = img.kernel[1]
   1.133 -    grubcfg["ramdisk"] = img.initrd[1]
   1.134 -    grubcfg["args"] = img.args[1]
   1.135 -
   1.136 -    print "Going to boot %s" %(img.title)
   1.137 -    print "  kernel: %s" % grubcfg["kernel"]
   1.138      if img.initrd:
   1.139 -        print "  initrd: %s" % grubcfg["ramdisk"]
   1.140 +        grubcfg["ramdisk"] = img.initrd[1]
   1.141 +    if img.args:
   1.142 +        grubcfg["args"] = img.args
   1.143  
   1.144 -    if isconfig:
   1.145 -        print "  args: %s" % grubcfg["args"]
   1.146 -        sys.exit(0)
   1.147 -        
   1.148      return grubcfg
   1.149  
   1.150 +# If nothing has been specified, look for a Solaris domU. If found, perform the
   1.151 +# necessary tweaks.
   1.152 +def sniff_solaris(fs, cfg):
   1.153 +    if not fs.file_exists("/platform/i86xen/kernel/unix"):
   1.154 +        return cfg
   1.155 +    
   1.156 +    # darned python
   1.157 +    longmode = (sys.maxint != 2147483647L)
   1.158 +    if not longmode:
   1.159 +        longmode = os.uname()[4] == "x86_64"
   1.160 +    if not longmode:
   1.161 +        if (os.access("/usr/bin/isainfo", os.R_OK) and
   1.162 +            os.popen("/usr/bin/isainfo -b").read() == "64\n"):
   1.163 +            longmode = True
   1.164 +
   1.165 +    if not cfg["kernel"]:
   1.166 +        cfg["kernel"] = "/platform/i86xen/kernel/unix"
   1.167 +        cfg["ramdisk"] = "/platform/i86pc/boot_archive"
   1.168 +        if longmode:
   1.169 +            cfg["kernel"] = "/platform/i86xen/kernel/amd64/unix"
   1.170 +            cfg["ramdisk"] = "/platform/i86pc/amd64/boot_archive"
   1.171 +
   1.172 +    # Unpleasant. Typically we'll have 'root=foo -k' or 'root=foo /kernel -k',
   1.173 +    # and we need to maintain Xen properties (root= and ip=) and the kernel
   1.174 +    # before any user args.
   1.175 +    
   1.176 +    xenargs = ""
   1.177 +    userargs = ""
   1.178 +    
   1.179 +    if not cfg["args"]:
   1.180 +        cfg["args"] = cfg["kernel"]
   1.181 +    else:
   1.182 +        for arg in cfg["args"].split():
   1.183 +            if re.match("^root=", arg) or re.match("^ip=", arg):
   1.184 +                xenargs += arg + " "
   1.185 +            elif arg != cfg["kernel"]:
   1.186 +                userargs += arg + " "
   1.187 +        cfg["args"] = xenargs + " " + cfg["kernel"] + " " + userargs
   1.188 +
   1.189 +    return cfg
   1.190 + 
   1.191  if __name__ == "__main__":
   1.192      sel = None
   1.193      
   1.194 @@ -497,11 +530,11 @@ if __name__ == "__main__":
   1.195      isconfig = False
   1.196  
   1.197      # what was passed in
   1.198 -    incfg = { "kernel": None, "ramdisk": None, "args": None };
   1.199 -    # what grub chose
   1.200 -    chosencfg = { "kernel": None, "ramdisk": None, "args": None };
   1.201 +    incfg = { "kernel": None, "ramdisk": None, "args": None }
   1.202 +    # what grub or sniffing chose
   1.203 +    chosencfg = { "kernel": None, "ramdisk": None, "args": None }
   1.204      # what to boot
   1.205 -    bootcfg = { "kernel": None, "ramdisk": None, "args": None };
   1.206 +    bootcfg = { "kernel": None, "ramdisk": None, "args": None }
   1.207  
   1.208      for o, a in opts:
   1.209          if o in ("-q", "--quiet"):
   1.210 @@ -524,25 +557,26 @@ if __name__ == "__main__":
   1.211          elif o in ("--isconfig",):
   1.212              isconfig = True
   1.213  
   1.214 -
   1.215      if output is None or output == "-":
   1.216          fd = sys.stdout.fileno()
   1.217      else:
   1.218          fd = os.open(output, os.O_WRONLY)
   1.219  
   1.220 -    if not incfg["kernel"]:
   1.221 -        chosencfg = run_grub(file, isconfig, entry)
   1.222 -    else:
   1.223 -        chosencfg = incfg
   1.224 -     
   1.225 -    offset = 0
   1.226 -    if is_disk_image(file):
   1.227 -        offset = get_active_offset(file)
   1.228 -        if offset == -1:
   1.229 -            raise RuntimeError, "Unable to find active partition on disk"
   1.230 +    # debug
   1.231 +    if isconfig:
   1.232 +        chosencfg = run_grub(file, entry)
   1.233 +        print "  kernel: %s" % chosencfg["kernel"]
   1.234 +        if img.initrd:
   1.235 +            print "  initrd: %s" % chosencfg["ramdisk"]
   1.236 +        print "  args: %s" % chosencfg["args"]
   1.237 +        sys.exit(0)
   1.238  
   1.239 -    # read the kernel and initrd onto the hostfs
   1.240 -    fs = fsimage.open(file, offset)
   1.241 +    fs = open_fs(file)
   1.242 +
   1.243 +    chosencfg = sniff_solaris(fs, incfg)
   1.244 +
   1.245 +    if not chosencfg["kernel"]:
   1.246 +        chosencfg = run_grub(file, entry, fs)
   1.247  
   1.248      data = fs.open_file(chosencfg["kernel"]).read()
   1.249      (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.",