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 ~]#