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

[Xen-devel] Re: [PATCH] pygrub: look in every partition for something to

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH] pygrub: look in every partition for something to boot
From: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Date: Thu, 15 Jul 2010 10:57:01 +0100
Delivery-date: Thu, 15 Jul 2010 02:58:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20100706104553.GN31695@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20100706104553.GN31695@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.18 (2008-05-17)
Ping?

At 11:45 +0100 on 06 Jul (1278416753), Tim Deegan wrote:
> 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>
> 
> diff -r 78b2f1e04c73 tools/pygrub/src/pygrub
> --- a/tools/pygrub/src/pygrub Tue Jul 06 11:09:36 2010 +0100
> +++ b/tools/pygrub/src/pygrub Tue Jul 06 11:38:42 2010 +0100
> @@ -50,21 +50,6 @@
>          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_GPT=0xee
>  
> -def get_fs_offset(file):
> +def get_partition_offsets(file):
>      if not is_disk_image(file):
> -        return 0
> +        # No MBR: assume whole disk filesystem, which is like a 
> +        # single partition starting at 0
> +        return [0]
>  
> -    partbuf = get_active_partition(file)
> -    if len(partbuf) == 0:
> -        raise RuntimeError, "Unable to find active partition on disk"
> +    part_offs = []
>  
> -    offset = struct.unpack("<L", partbuf[8:12])[0] * SECTOR_SIZE
> +    fd = os.open(file, os.O_RDONLY)
> +    buf = os.read(fd, 512)
> +    for poff in (446, 462, 478, 494): # partition offsets
>  
> -    type = struct.unpack("<B", partbuf[4:5])[0]
> +        # 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:
> -        offset += get_solaris_slice(file, offset)
> +        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)
> -    
> -    return offset
> +        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 = ""):
> @@ -703,17 +711,40 @@
>      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))
> +        bootfsoptions = ""
>  
> -    chosencfg = sniff_solaris(fs, incfg)
> +    # get list of offsets into file which start partitions
> +    part_offs = get_partition_offsets(file)
>  
> -    if not chosencfg["kernel"]:
> -        chosencfg = sniff_netware(fs, incfg)
> +    for offset in part_offs:
> +        try:
> +            fs = fsimage.open(file, offset, bootfsoptions)
>  
> -    if not chosencfg["kernel"]:
> -        chosencfg = run_grub(file, entry, fs, incfg["args"])
> +            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"]

-- 
Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd.  (Company #02937203, SL9 0BG)

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

<Prev in Thread] Current Thread [Next in Thread>