aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pygrub
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-01-12 14:42:07 +0000
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-01-12 14:42:07 +0000
commitce9e6668ac8c0c6188026d2374d15b37dee6186c (patch)
tree9e84e523b94a720df6fe80f0d1d7b2fd064d47c0 /tools/pygrub
parenta84893ee09eceb7f9c6625e51be2e5c25c014e7a (diff)
downloadxen-ce9e6668ac8c0c6188026d2374d15b37dee6186c.tar.gz
xen-ce9e6668ac8c0c6188026d2374d15b37dee6186c.tar.bz2
xen-ce9e6668ac8c0c6188026d2374d15b37dee6186c.zip
Parse Solaris VTOCs in pygrub.
Signed-off-by: John Levon <john.levon@sun.com>
Diffstat (limited to 'tools/pygrub')
-rw-r--r--tools/pygrub/src/pygrub61
1 files changed, 47 insertions, 14 deletions
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index ab8a20f31b..13b05d9a67 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -48,8 +48,7 @@ def is_disk_image(file):
return True
return False
-SECTOR_SIZE=512
-def get_active_offset(file):
+def get_active_partition(file):
"""Find the offset for the start of the first active partition "
"in the disk image file."""
@@ -58,22 +57,56 @@ def get_active_offset(file):
for poff in (446, 462, 478, 494): # partition offsets
# active partition has 0x80 as the first byte
if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
- return struct.unpack("<L",
- buf[poff+8:poff+12])[0] * SECTOR_SIZE
+ return buf[poff:poff+16]
# if there's not a partition marked as active, fall back to
# the first partition
- P1 = 446
- return struct.unpack("<L", buf[P1+8:P1+12])[0] * SECTOR_SIZE
+ return buf[446:446+16]
+
+SECTOR_SIZE=512
+DK_LABEL_LOC=1
+DKL_MAGIC=0xdabe
+V_ROOT=0x2
+
+def get_solaris_slice(file, offset):
+ """Find the root slice in a Solaris VTOC."""
+
+ fd = os.open(file, os.O_RDONLY)
+ os.lseek(fd, offset + (DK_LABEL_LOC * SECTOR_SIZE), 0)
+ buf = os.read(fd, 512)
+ if struct.unpack("<H", buf[508:510])[0] != DKL_MAGIC:
+ raise RuntimeError, "Invalid disklabel magic"
+
+ nslices = struct.unpack("<H", buf[30:32])[0]
+
+ for i in range(nslices):
+ sliceoff = 72 + 12 * i
+ slicetag = struct.unpack("<H", buf[sliceoff:sliceoff+2])[0]
+ slicesect = struct.unpack("<L", buf[sliceoff+4:sliceoff+8])[0]
+ if slicetag == V_ROOT:
+ return slicesect * SECTOR_SIZE
+
+ raise RuntimeError, "No root slice found"
+
+FDISK_PART_SOLARIS=0xbf
+FDISK_PART_SOLARIS_OLD=0x82
+
+def get_fs_offset(file):
+ if not is_disk_image(file):
+ return 0
+
+ partbuf = get_active_partition(file)
+ if len(partbuf) == 0:
+ raise RuntimeError, "Unable to find active partition on disk"
+
+ offset = struct.unpack("<L", partbuf[8:12])[0] * SECTOR_SIZE
+
+ type = struct.unpack("<B", partbuf[4:5])[0]
-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"
+ if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
+ offset += get_solaris_slice(file, offset)
- return fsimage.open(file, offset)
+ return offset
class GrubLineEditor(curses.textpad.Textbox):
def __init__(self, screen, startx, starty, line = ""):
@@ -571,7 +604,7 @@ if __name__ == "__main__":
print " args: %s" % chosencfg["args"]
sys.exit(0)
- fs = open_fs(file)
+ fs = fsimage.open(file, get_fs_offset(file))
chosencfg = sniff_solaris(fs, incfg)