3 import sys
, os
, time
, re
4 import optparse
, commands
5 import ConfigParser
, StringIO
7 class ShellConfigParser(ConfigParser
.ConfigParser
):
8 def read(self
, filename
):
10 text
= open(filename
).read()
14 file = StringIO
.StringIO("[shell]\n" + text
)
15 self
.readfp(file, filename
)
17 config
= ShellConfigParser()
18 config
.read('config.mak')
20 external_module
= config
.get('shell', 'want_module')
21 privileged
= os
.getuid() == 0
23 optparser
= optparse
.OptionParser()
25 optparser
.add_option('--no-reload-module',
26 help = 'do not reload kvm module',
27 action
= 'store_false',
32 optparser
.add_option('--install',
33 help = 'start up guest in installer boot cd',
34 action
= 'store_true',
38 optparser
.add_option('-m', '--memory',
39 help = 'guest memory in MB',
45 optparser
.add_option('--debugger',
46 help = 'wait for gdb',
47 action
= 'store_true',
51 optparser
.add_option('--no-tap',
52 help = 'run the guest without tap netif',
53 action
= 'store_true',
55 default
= not privileged
,
58 optparser
.add_option('--nictype',
59 help = 'use this specific nic type (vendor)',
64 optparser
.add_option('--mac',
65 help = 'use this specific mac addr',
70 optparser
.add_option('--vnc',
71 help = 'use VNC rather than SDL',
76 optparser
.add_option('--no-kvm',
77 help = 'use standard qemu, without kvm',
78 action
= 'store_false',
82 optparser
.add_option('--image',
83 help = 'select disk image',
85 default
= '/tmp/disk',
87 optparser
.add_option('--cdrom',
88 help = 'select cdrom image',
93 optparser
.add_option('--hdb',
94 help = 'secondary hard disk image',
99 optparser
.add_option('--loadvm',
100 help = 'select saved vm-image',
101 dest
= 'saved_image',
105 optparser
.add_option('--monitor',
106 help = 'redirect monitor (currently only stdio or tcp)',
111 optparser
.add_option('--stopped',
112 help = 'start image in stopped mode',
113 action
= 'store_true',
117 optparser
.add_option('-s', '--smp',
121 help = 'define number of vcpus',
124 optparser
.add_option('--no-kvm-irqchip',
125 action
= 'store_false',
128 help = 'avoid using in-kernel irqchip',
131 optparser
.add_option('-n', '--dry-run',
132 help = "just print the qemu command line; don't run it",
133 action
= 'store_true',
139 (options
, args
) = optparser
.parse_args()
142 options
.image
= args
[0]
145 options
.cdrom
= args
[1]
147 def remove_module(module
):
148 module
= module
.replace('-', '_')
149 lines
= commands
.getoutput('/sbin/lsmod').split('\n')
151 if x
.startswith(module
+ ' '):
152 if os
.spawnl(os
.P_WAIT
, '/sbin/rmmod', 'rmmod', module
) != 0:
153 raise Exception('failed to remove %s module' % (module
,))
155 def insert_module(module
):
156 if os
.spawnl(os
.P_WAIT
, '/sbin/insmod', 'insmod',
157 'kernel/%s.ko' % (module
,)) != 0:
158 raise Exception('failed to load kvm module')
160 def probe_module(module
):
161 if os
.spawnl(os
.P_WAIT
, '/sbin/modprobe', 'modprobe', module
) != 0:
162 raise Exception('failed to load kvm module')
165 for x
in file('/proc/cpuinfo').readlines():
166 m
= re
.match(r
'vendor_id[ \t]*: *([a-zA-Z]+),*', x
)
172 'GenuineIntel': 'kvm-intel',
173 'AuthenticAMD': 'kvm-amd',
176 if options
.kvm
and options
.reload:
177 for module
in [vendor_module
, 'kvm']:
178 remove_module(module
)
180 insmod
= insert_module
182 insmod
= probe_module
183 for module
in ['kvm', vendor_module
]:
185 commands
.getstatusoutput('/sbin/udevsettle')
186 if not os
.access('/dev/kvm', os
.F_OK
):
187 print '/dev/kvm not present'
191 (status
, output
) = commands
.getstatusoutput(
192 'qemu/qemu-img create -f qcow2 "%s" 30G' % disk
)
194 raise Exception, output
203 cmd
= 'qemu-system-' + arch
207 local_cmd
= 'qemu/' + arch
+ '-softmmu/' + cmd
208 if os
.access(local_cmd
, os
.F_OK
):
213 qemu_args
= (cmd
, '-boot', bootdisk
,
214 '-hda', disk
, '-m', str(options
.memory
),
215 '-serial', 'file:/tmp/serial.log',
216 '-smp', str(options
.vcpus
),
217 #'-usbdevice', 'tablet',
221 qemu_args
+= ('-cdrom', options
.cdrom
,)
224 qemu_args
+= ('-hdb', options
.hdb
,)
227 qemu_args
+= ('-no-kvm',)
232 if not options
.irqchip
:
233 qemu_args
+= ('-no-kvm-irqchip',)
235 if not options
.notap
:
238 for line
in commands
.getoutput('/sbin/ip link show eth0').splitlines():
239 m
= re
.match(r
'.*link/ether (..:..:..:..:..:..).*', line
)
243 raise Exception, 'Unable to determine eth0 mac address'
244 mac_components
= mac
.split(':')
245 mac_components
[0] = 'a0'
246 mac
= ':'.join(mac_components
)
248 qemu_args
+= ('-net', 'nic,macaddr=%s,model=%s' % (mac
,options
.nictype
,),
249 '-net', 'tap,script=/etc/kvm/qemu-ifup',)
252 qemu_args
+= ('-vnc', str(options
.vnc
))
254 if options
.saved_image
:
255 qemu_args
+= ('-loadvm' , options
.saved_image
, )
258 if options
.monitor
== 'stdio':
259 qemu_args
+= ('-monitor' , 'stdio', )
260 elif options
.monitor
== 'tcp':
261 qemu_args
+= ('-monitor' , 'tcp:0:5555,server,nowait', )
263 raise Exception('illegal monitor option %s' % option
.monitor
)
269 def concat_func(x
,y
): return x
+ ' ' + y
270 print reduce(concat_func
, qemu_args
)
273 os
.execvp(cmd
, qemu_args
)