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-changelog

[Xen-changelog] [xen-unstable] pygrub: look in every partition for somet

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] pygrub: look in every partition for something to boot
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 16 Jul 2010 06:06:33 -0700
Delivery-date: Fri, 16 Jul 2010 06:13:06 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
# Date 1279214296 -3600
# Node ID c4a83e3cc6b435cc559450bbcd8b2ba7a801964f
# Parent  6fdb00dc93a5d4d8a29b2af52053f3e65b645c93
pygrub: look in every partition for something to boot

pygrub: look in every partition for something to boot, in case
the OS installer (SLES 10 sp1 in particular) forgets to mark the
boot partition as active.

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Acked-by: David Markey <admin@xxxxxxxxxxx>
---
 tools/pygrub/src/pygrub |  113 +++++++++++++++++++++++++++++-------------------
 1 files changed, 70 insertions(+), 43 deletions(-)

diff -r 6fdb00dc93a5 -r c4a83e3cc6b4 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Thu Jul 15 16:32:50 2010 +0100
+++ b/tools/pygrub/src/pygrub   Thu Jul 15 18:18:16 2010 +0100
@@ -50,21 +50,6 @@ def is_disk_image(file):
         return True
     return False
 
-def get_active_partition(file):
-    """Find the offset for the start of the first active partition "
-    "in the disk image file."""
-
-    fd = os.open(file, os.O_RDONLY)
-    buf = os.read(fd, 512)
-    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 buf[poff:poff+16]
-
-    # if there's not a partition marked as active, fall back to
-    # the first partition
-    return buf[446:446+16]
-
 SECTOR_SIZE=512
 DK_LABEL_LOC=1
 DKL_MAGIC=0xdabe
@@ -101,25 +86,44 @@ FDISK_PART_SOLARIS_OLD=0x82
 FDISK_PART_SOLARIS_OLD=0x82
 FDISK_PART_GPT=0xee
 
-def get_fs_offset(file):
+def get_partition_offsets(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]
-
-    if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
-        offset += get_solaris_slice(file, offset)
-
-    if type == FDISK_PART_GPT:
-        offset = get_fs_offset_gpt(file)
-    
-    return offset
+        # No MBR: assume whole disk filesystem, which is like a 
+        # single partition starting at 0
+        return [0]
+
+    part_offs = []
+
+    fd = os.open(file, os.O_RDONLY)
+    buf = os.read(fd, 512)
+    for poff in (446, 462, 478, 494): # partition offsets
+
+        # MBR contains a 16 byte descriptor per partition
+        partbuf = buf[poff:poff+16]
+        offset  = struct.unpack("<L", partbuf[8:12])[0] * SECTOR_SIZE
+        type    = struct.unpack("<B", partbuf[4:5])[0]
+        
+        # offset == 0 implies this partition is not enabled
+        if offset == 0:
+            continue
+
+        if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
+            try:
+                offset += get_solaris_slice(file, offset)
+            except RuntimeError:
+                continue # no solaris magic at that offset, ignore partition
+
+        if type == FDISK_PART_GPT:
+            offset = get_fs_offset_gpt(file)
+
+        # Active partition has 0x80 as the first byte.
+        # If active, prepend to front of list, otherwise append to back.
+        if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
+            part_offs.insert(0, offset)
+        else:
+            part_offs.append(offset)
+
+    return part_offs
 
 class GrubLineEditor(curses.textpad.Textbox):
     def __init__(self, screen, startx, starty, line = ""):
@@ -734,17 +738,40 @@ if __name__ == "__main__":
     bootfsargs = '"%s"' % incfg["args"]
     bootfsgroup = re.findall('zfs-bootfs=(.*?)[\s\,\"]', bootfsargs)
     if bootfsgroup:
-        fs = fsimage.open(file, get_fs_offset(file), bootfsgroup[0])
+        bootfsoptions = bootfsgroup[0]
     else:
-        fs = fsimage.open(file, get_fs_offset(file))
-
-    chosencfg = sniff_solaris(fs, incfg)
-
-    if not chosencfg["kernel"]:
-        chosencfg = sniff_netware(fs, incfg)
-
-    if not chosencfg["kernel"]:
-        chosencfg = run_grub(file, entry, fs, incfg["args"])
+        bootfsoptions = ""
+
+    # get list of offsets into file which start partitions
+    part_offs = get_partition_offsets(file)
+
+    for offset in part_offs:
+        try:
+            fs = fsimage.open(file, offset, bootfsoptions)
+
+            chosencfg = sniff_solaris(fs, incfg)
+
+            if not chosencfg["kernel"]:
+                chosencfg = sniff_netware(fs, incfg)
+
+            if not chosencfg["kernel"]:
+                chosencfg = run_grub(file, entry, fs, incfg["args"])
+
+            # Break as soon as we've found the kernel so that we continue
+            # to use this fsimage object
+            if chosencfg["kernel"]:
+                break
+            fs = None
+
+        except:
+            # IOErrors raised by fsimage.open
+            # RuntimeErrors raised by run_grub if no menu.lst present
+            fs = None
+            continue
+
+    # Did looping through partitions find us a kernel?
+    if not fs:
+        raise RuntimeError, "Unable to find partition containing kernel"
 
     if not_really:
         bootcfg["kernel"] = "<kernel:%s>" % chosencfg["kernel"]

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] pygrub: look in every partition for something to boot, Xen patchbot-unstable <=