[Fedora-xen] pygrub failed

Jun OKAJIMA okajima at digitalinfra.co.jp
Sun Apr 2 16:40:01 UTC 2006


>I believe the error "Error: Error creating domain: The privileged  
>domain did not balloon!" happens when you don't have enough available  
>memory for the domU to boot.  The xenguest-install.py script tells  
>you to restart the domain by running "xm create -c xxxx', but I think  
>the error message is just a generic one that is printed if the script  
>crashes out, and it it is the wrong thing to do in this case.
>
>When I had the same problem, I had to allocate less memory to dom0  
>and re-run the xenguest-install script.  I see you have about 196MB  
>of RAM.  Since the FC5 script needs 256MB of RAM, I don't think  
>you'll be able to install it unless you increase the amount of RAM  
>you have.  But since the machine is a virtual one in VMWare, this  
>shouldn't be too difficult.
>


Thank you for replying.
Unfortunately, I tried same stuff with 512MB mem but failed.
What I suspect now is, a disk image would have to be formatted.
xenguest-install.py just makes plain empty sparse file, but is this
enough? I suspect it should be formatted and partitioned and so on.
You succeeded to do an install on FC5? How you did it?

Check the code of pygrub.
See this:
   116      fs = None
   117      for fstype in grub.fsys.fstypes.values():
   118          if fstype.sniff_magic(fn, offset):
   119              fs = fstype.open_fs(fn, offset)
   120              break
   121
   122      if fs is not None:
(snip)
   138      else:
   139          raise RuntimeError, "Unable to read filesystem"

What happened here is, in short, like this:

   # Check diskimage formatted as described in grub config
   117      for fstype in grub.fsys.fstypes.values():
   118          if fstype.sniff_magic(fn, offset):
   # If not formatted properly, raise error.
   138      else:
   139          raise RuntimeError, "Unable to read filesystem"

                                --- Okajima, Jun. Tokyo, Japan.


-------------
[root at localhost ~]# cat -n /usr/bin/pygrub
     1  #!/usr/bin/python
     2  #
     3  # pygrub - simple python-based bootloader for Xen
     4  #
     5  # Copyright 2005 Red Hat, Inc.
     6  # Jeremy Katz <katzj at redhat.com>
     7  #
     8  # This software may be freely redistributed under the terms of the GNU
     9  # general public license.
    10  #
    11  # You should have received a copy of the GNU General Public License
    12  # along with this program; if not, write to the Free Software
    13  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    14  #
    15
    16  import os, sys, string, struct, tempfile
    17  import logging
    18
    19  import curses, _curses, curses.wrapper
    20  import getopt
    21
    22  sys.path = [ '/usr/lib/python' ] + sys.path
    23
    24  import grub.GrubConf
    25  import grub.fsys
    26
    27  PYGRUB_VER = 0.3
    28
    29
    30  def draw_window():
    31      stdscr = curses.initscr()
    32      if hasattr(curses, 'use_default_colors'):
    33          curses.use_default_colors()
    34      try:
    35          curses.curs_set(0)
    36      except _curses.error:
    37          pass
    38
    39      stdscr.addstr(1, 4, "pyGRUB  version %s" %(PYGRUB_VER,))
    40
    41      win = curses.newwin(10, 74, 2, 1)
    42      win.box()
    43      win.refresh()
    44
    45      stdscr.addstr(12, 5, "Use the U and D keys to select which entry is highlighted.")
    46      stdscr.addstr(13, 5, "Press enter to boot the selected OS. 'e' to edit the")
    47      stdscr.addstr(14, 5, "commands before booting, 'a' to modify the kernel arguments ")
    48      stdscr.addstr(15, 5, "before booting, or 'c' for a command line.")
    49      stdscr.addch(12, 13, curses.ACS_UARROW)
    50      stdscr.addch(12, 19, curses.ACS_DARROW)
    51      (y, x) = stdscr.getmaxyx()
    52      stdscr.move(y - 1, x - 1)
    53
    54      stdscr.refresh()
    55      return (stdscr, win)
    56
    57  def fill_entries(win, cfg, selected):
    58      y = 0
    59
    60      for i in cfg.images:
    61          if (0, y) > win.getmaxyx():
    62              break
    63          if y == selected:
    64              attr = curses.A_REVERSE
    65          else:
    66              attr = 0
    67          win.addstr(y + 1, 2, i.title.ljust(70), attr)
    68          y += 1
    69      win.refresh()
    70
    71  def select(win, line):
    72      win.attron(curses.A_REVERSE)
    73      win.redrawln(line + 1, 1)
    74      win.refresh()
    75
    76  def is_disk_image(file):
    77      fd = os.open(file, os.O_RDONLY)
    78      buf = os.read(fd, 512)
    79      os.close(fd)
    80
    81      if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,):
    82          return True
    83      return False
    84
    85  SECTOR_SIZE=512
    86  def get_active_offset(file):
    87      """Find the offset for the start of the first active partition in the
    88      disk image file."""
    89      fd = os.open(file, os.O_RDONLY)
    90      buf = os.read(fd, 512)
    91      for poff in (446, 462, 478, 494): # partition offsets
    92          # active partition has 0x80 as the first byte
    93          if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
    94              return struct.unpack("<L", buf[poff+8:poff+12])[0] * SECTOR_SIZE
    95      return -1
    96
    97  def get_config(fn, isconfig = False):
    98      if not os.access(fn, os.R_OK):
    99          raise RuntimeError, "Unable to access %s" %(fn,)
   100
   101      cf = grub.GrubConf.GrubConfigFile()
   102
   103      if isconfig:
   104          # set the config file and parse it
   105          cf.filename = fn
   106          cf.parse()
   107          return cf
   108
   109      offset = 0
   110      if is_disk_image(fn):
   111          offset = get_active_offset(fn)
   112          if offset == -1:
   113              raise RuntimeError, "Unable to find active partition on disk"
   114
   115      # open the image and read the grub config
   116      fs = None
   117      for fstype in grub.fsys.fstypes.values():
   118          if fstype.sniff_magic(fn, offset):
   119              fs = fstype.open_fs(fn, offset)
   120              break
   121
   122      if fs is not None:
   123          grubfile = None
   124          for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
   125                    "/grub/menu.lst", "/grub/grub.conf"):
   126              if fs.file_exist(f):
   127                  grubfile = f
   128                  break
   129          if grubfile is None:
   130              raise RuntimeError, "we couldn't find /boot/grub{menu.lst,grub.conf} " + \
   131                                  "in the image provided. halt!"
   132          f = fs.open_file(grubfile)
   133          buf = f.read()
   134          f.close()
   135          fs.close()
   136          # then parse the grub config
   137          cf.parse(buf)
   138      else:
   139          raise RuntimeError, "Unable to read filesystem"
   140
   141      return cf
   142
   143  def get_entry_idx(cf, entry):
   144      # first, see if the given entry is numeric
   145      try:
   146          idx = string.atoi(entry)
   147          return idx
   148      except ValueError:
   149          pass
   150
   151      # it's not, now check the labels for a match
   152      for i in range(len(cf.images)):
   153          if entry == cf.images[i].title:
   154              return i
   155
   156      return None
   157
   158  def main(cf = None):
   159      mytime = 0
   160      timeout = int(cf.timeout)
   161
   162      (stdscr, win) = draw_window()
   163      stdscr.timeout(1000)
   164      selected = cf.default
   165
   166      while (timeout == -1 or mytime < int(timeout)):
   167          if timeout != -1 and mytime != -1:
   168              stdscr.addstr(20, 5, "Will boot selected entry in %2d seconds"
   169                            %(int(timeout) - mytime))
   170          else:
   171              stdscr.addstr(20, 5, " " * 80)
   172
   173          fill_entries(win, cf, selected)
   174          c = stdscr.getch()
   175          if mytime != -1:
   176              mytime += 1
   177  #        if c == ord('q'):
   178  #            selected = -1
   179  #            break
   180          if c == ord('c'):
   181              # FIXME: needs to go to command line mode
   182              continue
   183          elif c == ord('a'):
   184              # FIXME: needs to go to append mode
   185              continue
   186          elif c == ord('e'):
   187              # FIXME: needs to go to edit mode
   188              continue
   189          elif c in (curses.KEY_ENTER, ord('\n'), ord('\r')):
   190              break
   191          elif c == curses.KEY_UP:
   192              mytime = -1
   193              selected -= 1
   194          elif c == curses.KEY_DOWN:
   195              mytime = -1
   196              selected += 1
   197          else:
   198              pass
   199
   200          # bound at the top and bottom
   201          if selected < 0:
   202              selected = 0
   203          elif selected >= len(cf.images):
   204              selected = len(cf.images) - 1
   205
   206      if selected >= 0:
   207          return selected
   208
   209  if __name__ == "__main__":
   210      sel = None
   211
   212      def run_main(scr, *args):
   213          global sel
   214          sel = main(cf)
   215
   216      def usage():
   217          print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--entry=] <image>" %
(sys.argv[0],)
   218
   219      try:
   220          opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::',
   221                                     ["quiet", "help", "output=", "entry=",
   222                                      "isconfig"])
   223      except getopt.GetoptError:
   224          usage()
   225          sys.exit(1)
   226
   227      if len(args) < 1:
   228          usage()
   229          sys.exit(1)
   230      file = args[0]
   231
   232      output = None
   233      entry = None
   234      interactive = True
   235      isconfig = False
   236      for o, a in opts:
   237          if o in ("-q", "--quiet"):
   238              interactive = False
   239          elif o in ("-h", "--help"):
   240              usage()
   241              sys.exit()
   242          elif o in ("--output",):
   243              output = a
   244          elif o in ("--entry",):
   245              entry = a
   246              # specifying the entry to boot implies non-interactive
   247              interactive = False
   248          elif o in ("--isconfig",):
   249              isconfig = True
   250
   251      if output is None or output == "-":
   252          fd = sys.stdout.fileno()
   253      else:
   254          fd = os.open(output, os.O_WRONLY)
   255
   256      cf = get_config(file, isconfig)
   257      if interactive:
   258          curses.wrapper(run_main)
   259      else:
   260          sel = cf.default
   261
   262      # set the entry to boot as requested
   263      if entry is not None:
   264          idx = get_entry_idx(cf, entry)
   265          if idx is not None and idx > 0 and idx < len(cf.images):
   266              sel = idx
   267
   268      img = cf.images[sel]
   269      print "Going to boot %s" %(img.title)
   270      print "  kernel: %s" %(img.kernel[1],)
   271      if img.initrd:
   272          print "  initrd: %s" %(img.initrd[1],)
   273
   274      offset = 0
   275      if is_disk_image(file):
   276          offset = get_active_offset(file)
   277          if offset == -1:
   278              raise RuntimeError, "Unable to find active partition on disk"
   279
   280      # read the kernel and initrd onto the hostfs
   281      fs = None
   282      for fstype in grub.fsys.fstypes.values():
   283          if fstype.sniff_magic(file, offset):
   284              fs = fstype.open_fs(file, offset)
   285              break
   286
   287      if fs is None:
   288          raise RuntimeError, "Unable to open filesystem"
   289
   290      kernel = fs.open_file(img.kernel[1],).read()
   291      (tfd, fn) = tempfile.mkstemp(prefix="vmlinuz.", dir="/var/lib/xen")
   292      os.write(tfd, kernel)
   293      os.close(tfd)
   294      sxp = "linux (kernel %s)" %(fn,)
   295
   296      if img.initrd:
   297          initrd = fs.open_file(img.initrd[1],).read()
   298          (tfd, fn) = tempfile.mkstemp(prefix="initrd.", dir="/var/lib/xen")
   299          os.write(tfd, initrd)
   300          os.close(tfd)
   301          sxp += "(ramdisk %s)" %(fn,)
   302      else:
   303          initrd = None
   304      sxp += "(args '%s')" %(img.args,)
   305
   306      sys.stdout.flush()
   307      os.write(fd, sxp)
   308
[root at localhost ~]#




More information about the Fedora-xen mailing list