>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@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@xxxxxxxxxx> 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@localhost ~]#