* [PATCH] pygrub: look in every partition for something to boot
@ 2010-07-06 10:45 Tim Deegan
2010-07-06 10:47 ` David Markey
2010-07-15 9:57 ` Tim Deegan
0 siblings, 2 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-06 10:45 UTC (permalink / raw)
To: xen-devel
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@citrix.com>
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"]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] pygrub: look in every partition for something to boot
2010-07-06 10:45 [PATCH] pygrub: look in every partition for something to boot Tim Deegan
@ 2010-07-06 10:47 ` David Markey
2010-07-15 9:57 ` Tim Deegan
1 sibling, 0 replies; 3+ messages in thread
From: David Markey @ 2010-07-06 10:47 UTC (permalink / raw)
To: Tim Deegan; +Cc: xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 5239 bytes --]
Good job. I've come across this problem before.
On 6 July 2010 11:45, Tim Deegan <Tim.Deegan@citrix.com> 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@citrix.com>
>
> 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"]
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>
[-- Attachment #1.2: Type: text/html, Size: 6421 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] pygrub: look in every partition for something to boot
2010-07-06 10:45 [PATCH] pygrub: look in every partition for something to boot Tim Deegan
2010-07-06 10:47 ` David Markey
@ 2010-07-15 9:57 ` Tim Deegan
1 sibling, 0 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-15 9:57 UTC (permalink / raw)
To: xen-devel@lists.xensource.com
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@citrix.com>
>
> 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@citrix.com>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-07-15 9:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-06 10:45 [PATCH] pygrub: look in every partition for something to boot Tim Deegan
2010-07-06 10:47 ` David Markey
2010-07-15 9:57 ` Tim Deegan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).