ia64/xen-unstable

changeset 5956:0301cccd14f1

The attached patch adds the support that was only stubbed in to be able
to support having reading the boot loader config when you're using a
whole disk (eg, file:/root/disk.img,xvda,w) as opposed to just a
partition.

This reads the partition table in the MBR to find the active partition
and then passes that offset down into the filesystem reading code.

Signed-off-by: Jeremy Katz <katzj@redhat.com>
author smh22@firebug.cl.cam.ac.uk
date Tue Aug 02 09:31:47 2005 +0000 (2005-08-02)
parents 706733e1ecdf
children d18f732c0a5f
files tools/pygrub/setup.py tools/pygrub/src/fsys/ext2/__init__.py tools/pygrub/src/fsys/ext2/ext2module.c tools/pygrub/src/pygrub
line diff
     1.1 --- a/tools/pygrub/setup.py	Tue Aug 02 09:29:56 2005 +0000
     1.2 +++ b/tools/pygrub/setup.py	Tue Aug 02 09:31:47 2005 +0000
     1.3 @@ -23,7 +23,7 @@ if os.path.exists("/usr/include/reiserfs
     1.4      fsys_pkgs.append("grub.fsys.reiser")
     1.5  
     1.6  setup(name='pygrub',
     1.7 -      version='0.2',
     1.8 +      version='0.3',
     1.9        description='Boot loader that looks a lot like grub for Xen',
    1.10        author='Jeremy Katz',
    1.11        author_email='katzj@redhat.com',
     2.1 --- a/tools/pygrub/src/fsys/ext2/__init__.py	Tue Aug 02 09:29:56 2005 +0000
     2.2 +++ b/tools/pygrub/src/fsys/ext2/__init__.py	Tue Aug 02 09:31:47 2005 +0000
     2.3 @@ -32,7 +32,7 @@ class Ext2FileSystemType(FileSystemType)
     2.4      def open_fs(self, fn, offset = 0):
     2.5          if not self.sniff_magic(fn, offset):
     2.6              raise ValueError, "Not an ext2 filesystem"
     2.7 -        return Ext2Fs(fn)
     2.8 +        return Ext2Fs(fn, offset = offset)
     2.9  
    2.10  register_fstype(Ext2FileSystemType())
    2.11  
     3.1 --- a/tools/pygrub/src/fsys/ext2/ext2module.c	Tue Aug 02 09:29:56 2005 +0000
     3.2 +++ b/tools/pygrub/src/fsys/ext2/ext2module.c	Tue Aug 02 09:31:47 2005 +0000
     3.3 @@ -208,22 +208,28 @@ static PyObject *
     3.4  ext2_fs_open (Ext2Fs *fs, PyObject *args, PyObject *kwargs)
     3.5  {
     3.6      static char *kwlist[] = { "name", "flags", "superblock", 
     3.7 -                              "block_size", NULL };
     3.8 +                              "block_size", "offset", NULL };
     3.9      char * name;
    3.10 -    int flags = 0, superblock = 0, err;
    3.11 +    int flags = 0, superblock = 0, offset = 0, err;
    3.12      unsigned int block_size = 0;
    3.13      ext2_filsys efs;
    3.14 +    char offsetopt[30];
    3.15  
    3.16 -    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, 
    3.17 -                                     &name, &flags, &superblock, &block_size))
    3.18 -                                     return NULL;
    3.19 +    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iiii", kwlist, 
    3.20 +                                     &name, &flags, &superblock, 
    3.21 +                                     &block_size, &offset))
    3.22 +        return NULL;
    3.23  
    3.24      if (fs->fs != NULL) {
    3.25          PyErr_SetString(PyExc_ValueError, "already have an fs object");
    3.26          return NULL;
    3.27      }
    3.28  
    3.29 -    err = ext2fs_open(name, flags, superblock, block_size, 
    3.30 +    if (offset != 0) {
    3.31 +        snprintf(offsetopt, 29, "offset=%d", offset);
    3.32 +    }
    3.33 +
    3.34 +    err = ext2fs_open2(name, offsetopt, flags, superblock, block_size, 
    3.35                        unix_io_manager, &efs);
    3.36      if (err) {
    3.37          PyErr_SetString(PyExc_ValueError, "unable to open file");
    3.38 @@ -323,14 +329,15 @@ static PyObject *
    3.39  ext2_fs_new(PyObject *o, PyObject *args, PyObject *kwargs) 
    3.40  {
    3.41      static char *kwlist[] = { "name", "flags", "superblock", 
    3.42 -                              "block_size", NULL };
    3.43 +                              "block_size", "offset", NULL };
    3.44      char * name;
    3.45 -    int flags = 0, superblock = 0;
    3.46 +    int flags = 0, superblock = 0, offset;
    3.47      unsigned int block_size = 0;
    3.48      Ext2Fs *pfs;
    3.49  
    3.50 -    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, 
    3.51 -                                     &name, &flags, &superblock, &block_size))
    3.52 +    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iiii", kwlist, 
    3.53 +                                     &name, &flags, &superblock, &block_size,
    3.54 +                                     &offset))
    3.55          return NULL;
    3.56  
    3.57      pfs = (Ext2Fs *) PyObject_NEW(Ext2Fs, &Ext2FsType);
    3.58 @@ -339,8 +346,8 @@ ext2_fs_new(PyObject *o, PyObject *args,
    3.59      pfs->fs = NULL;
    3.60  
    3.61      if (!ext2_fs_open(pfs, 
    3.62 -                      Py_BuildValue("siii", name, flags, superblock, block_size),
    3.63 -                      NULL))
    3.64 +                      Py_BuildValue("siiii", name, flags, superblock, 
    3.65 +                                    block_size, offset), NULL))
    3.66          return NULL;
    3.67  
    3.68      return (PyObject *)pfs;
     4.1 --- a/tools/pygrub/src/pygrub	Tue Aug 02 09:29:56 2005 +0000
     4.2 +++ b/tools/pygrub/src/pygrub	Tue Aug 02 09:31:47 2005 +0000
     4.3 @@ -24,7 +24,7 @@ sys.path = [ '/usr/lib/python' ] + sys.p
     4.4  import grub.GrubConf
     4.5  import grub.fsys
     4.6  
     4.7 -PYGRUB_VER = 0.02
     4.8 +PYGRUB_VER = 0.3
     4.9  
    4.10  
    4.11  def draw_window():
    4.12 @@ -77,24 +77,39 @@ def is_disk_image(file):
    4.13      buf = os.read(fd, 512)
    4.14      os.close(fd)
    4.15  
    4.16 -    if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaaff):
    4.17 +    if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,):
    4.18          return True
    4.19      return False
    4.20  
    4.21 +SECTOR_SIZE=512
    4.22 +def get_active_offset(file):
    4.23 +    """Find the offset for the start of the first active partition in the
    4.24 +    disk image file."""
    4.25 +    fd = os.open(file, os.O_RDONLY)
    4.26 +    buf = os.read(fd, 512)
    4.27 +    for poff in (446, 462, 478, 494): # partition offsets
    4.28 +        # active partition has 0x80 as the first byte
    4.29 +        if struct.unpack("<c", buf[p:p+1]) == ('\x80',):
    4.30 +            return struct.unpack("<", buf[p+8:p+12])[0] * SECTOR_SIZE
    4.31 +    return -1
    4.32 +
    4.33  def get_config(fn):
    4.34      if not os.access(fn, os.R_OK):
    4.35          raise RuntimeError, "Unable to access %s" %(fn,)
    4.36  
    4.37      cf = grub.GrubConf.GrubConfigFile()
    4.38  
    4.39 +    offset = 0
    4.40      if is_disk_image(fn):
    4.41 -        raise RuntimeError, "appears to be a full disk image... unable to handle this yet"
    4.42 +        offset = get_active_offset(fn)
    4.43 +        if offset == -1:
    4.44 +            raise RuntimeError, "Unable to find active partition on disk"
    4.45  
    4.46      # open the image and read the grub config
    4.47      fs = None
    4.48      for fstype in grub.fsys.fstypes.values():
    4.49 -        if fstype.sniff_magic(fn):
    4.50 -            fs = fstype.open_fs(fn)
    4.51 +        if fstype.sniff_magic(fn, offset):
    4.52 +            fs = fstype.open_fs(fn, offset)
    4.53              break
    4.54  
    4.55      if fs is not None:
    4.56 @@ -244,14 +259,17 @@ if __name__ == "__main__":
    4.57      if img.initrd:
    4.58          print "  initrd: %s" %(img.initrd[1],)
    4.59  
    4.60 +    offset = 0
    4.61      if is_disk_image(file):
    4.62 -        raise RuntimeError, "unable to handle full disk images yet"
    4.63 +        offset = get_active_offset(fn)
    4.64 +        if offset == -1:
    4.65 +            raise RuntimeError, "Unable to find active partition on disk"
    4.66  
    4.67      # read the kernel and initrd onto the hostfs
    4.68      fs = None
    4.69      for fstype in grub.fsys.fstypes.values():
    4.70 -        if fstype.sniff_magic(file):
    4.71 -            fs = fstype.open_fs(file)
    4.72 +        if fstype.sniff_magic(file, offset):
    4.73 +            fs = fstype.open_fs(file, offset)
    4.74              break
    4.75  
    4.76      if fs is None: