ia64/xen-unstable

changeset 13406:7bf03e7ad6d0

Parse Solaris VTOCs in pygrub.

Signed-off-by: John Levon <john.levon@sun.com>
author kfraser@localhost.localdomain
date Fri Jan 12 14:42:07 2007 +0000 (2007-01-12)
parents c6cea93d3cd9
children d2505c4ca32b
files tools/pygrub/src/pygrub
line diff
     1.1 --- a/tools/pygrub/src/pygrub	Fri Jan 12 14:40:13 2007 +0000
     1.2 +++ b/tools/pygrub/src/pygrub	Fri Jan 12 14:42:07 2007 +0000
     1.3 @@ -48,8 +48,7 @@ def is_disk_image(file):
     1.4          return True
     1.5      return False
     1.6  
     1.7 -SECTOR_SIZE=512
     1.8 -def get_active_offset(file):
     1.9 +def get_active_partition(file):
    1.10      """Find the offset for the start of the first active partition "
    1.11      "in the disk image file."""
    1.12  
    1.13 @@ -58,22 +57,56 @@ def get_active_offset(file):
    1.14      for poff in (446, 462, 478, 494): # partition offsets
    1.15          # active partition has 0x80 as the first byte
    1.16          if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
    1.17 -            return struct.unpack("<L",
    1.18 -                                 buf[poff+8:poff+12])[0] * SECTOR_SIZE
    1.19 +            return buf[poff:poff+16]
    1.20  
    1.21      # if there's not a partition marked as active, fall back to
    1.22      # the first partition
    1.23 -    P1 = 446
    1.24 -    return struct.unpack("<L", buf[P1+8:P1+12])[0] * SECTOR_SIZE
    1.25 +    return buf[446:446+16]
    1.26 +
    1.27 +SECTOR_SIZE=512
    1.28 +DK_LABEL_LOC=1
    1.29 +DKL_MAGIC=0xdabe
    1.30 +V_ROOT=0x2
    1.31 +
    1.32 +def get_solaris_slice(file, offset):
    1.33 +    """Find the root slice in a Solaris VTOC."""
    1.34 +
    1.35 +    fd = os.open(file, os.O_RDONLY)
    1.36 +    os.lseek(fd, offset + (DK_LABEL_LOC * SECTOR_SIZE), 0)
    1.37 +    buf = os.read(fd, 512)
    1.38 +    if struct.unpack("<H", buf[508:510])[0] != DKL_MAGIC:
    1.39 +        raise RuntimeError, "Invalid disklabel magic"
    1.40 +
    1.41 +    nslices = struct.unpack("<H", buf[30:32])[0]
    1.42  
    1.43 -def open_fs(file):
    1.44 -    offset = 0
    1.45 -    if is_disk_image(file):
    1.46 -        offset = get_active_offset(file)
    1.47 -        if offset == -1:
    1.48 -            raise RuntimeError, "Unable to find active partition on disk"
    1.49 +    for i in range(nslices):
    1.50 +        sliceoff = 72 + 12 * i
    1.51 +        slicetag = struct.unpack("<H", buf[sliceoff:sliceoff+2])[0]
    1.52 +        slicesect = struct.unpack("<L", buf[sliceoff+4:sliceoff+8])[0]
    1.53 +        if slicetag == V_ROOT:
    1.54 +            return slicesect * SECTOR_SIZE
    1.55 +
    1.56 +    raise RuntimeError, "No root slice found"      
    1.57 +
    1.58 +FDISK_PART_SOLARIS=0xbf
    1.59 +FDISK_PART_SOLARIS_OLD=0x82
    1.60  
    1.61 -    return fsimage.open(file, offset)
    1.62 +def get_fs_offset(file):
    1.63 +    if not is_disk_image(file):
    1.64 +        return 0
    1.65 +
    1.66 +    partbuf = get_active_partition(file)
    1.67 +    if len(partbuf) == 0:
    1.68 +        raise RuntimeError, "Unable to find active partition on disk"
    1.69 +
    1.70 +    offset = struct.unpack("<L", partbuf[8:12])[0] * SECTOR_SIZE
    1.71 +
    1.72 +    type = struct.unpack("<B", partbuf[4:5])[0]
    1.73 +
    1.74 +    if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
    1.75 +        offset += get_solaris_slice(file, offset)
    1.76 +
    1.77 +    return offset
    1.78  
    1.79  class GrubLineEditor(curses.textpad.Textbox):
    1.80      def __init__(self, screen, startx, starty, line = ""):
    1.81 @@ -571,7 +604,7 @@ if __name__ == "__main__":
    1.82          print "  args: %s" % chosencfg["args"]
    1.83          sys.exit(0)
    1.84  
    1.85 -    fs = open_fs(file)
    1.86 +    fs = fsimage.open(file, get_fs_offset(file))
    1.87  
    1.88      chosencfg = sniff_solaris(fs, incfg)
    1.89