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')
22 arch
= config
.get('shell', 'arch')
23 p
= re
.compile("^i\d86$")
24 if len(p
.findall(arch
)):
26 if arch
!= 'x86_64' and arch
!= 'ia64':
27 raise Exception('unsupported architecture %s' % arch
)
29 privileged
= os
.getuid() == 0
31 optparser
= optparse
.OptionParser()
33 optparser
.add_option('--no-reload-module',
34 help = 'do not reload kvm module',
35 action
= 'store_false',
40 optparser
.add_option('--install',
41 help = 'start up guest in installer boot cd',
42 action
= 'store_true',
46 optparser
.add_option('-m', '--memory',
47 help = 'guest memory in MB',
53 optparser
.add_option('--debugger',
54 help = 'wait for gdb',
55 action
= 'store_true',
59 optparser
.add_option('--no-tap',
60 help = 'run the guest without tap netif',
61 action
= 'store_true',
63 default
= not privileged
,
66 optparser
.add_option('--nictype',
67 help = 'use this specific nic type (vendor)',
72 optparser
.add_option('--mac',
73 help = 'use this specific mac addr',
78 optparser
.add_option('--vnc',
79 help = 'use VNC rather than SDL',
84 optparser
.add_option('--no-kvm',
85 help = 'use standard qemu, without kvm',
86 action
= 'store_false',
90 optparser
.add_option('--image',
91 help = 'select disk image',
93 default
= '/tmp/disk',
95 optparser
.add_option('--cdrom',
96 help = 'select cdrom image',
101 optparser
.add_option('--hdb',
102 help = 'secondary hard disk image',
107 optparser
.add_option('--loadvm',
108 help = 'select saved vm-image',
109 dest
= 'saved_image',
113 optparser
.add_option('--monitor',
114 help = 'redirect monitor (currently only stdio or tcp)',
119 optparser
.add_option('--stopped',
120 help = 'start image in stopped mode',
121 action
= 'store_true',
125 optparser
.add_option('-s', '--smp',
129 help = 'define number of vcpus',
132 optparser
.add_option('--no-kvm-irqchip',
133 action
= 'store_false',
136 help = 'avoid using in-kernel irqchip',
139 optparser
.add_option('-n', '--dry-run',
140 help = "just print the qemu command line; don't run it",
141 action
= 'store_true',
147 (options
, args
) = optparser
.parse_args()
150 options
.image
= args
[0]
153 options
.cdrom
= args
[1]
155 def remove_module(module
):
156 module
= module
.replace('-', '_')
157 lines
= commands
.getoutput('/sbin/lsmod').split('\n')
159 if x
.startswith(module
+ ' '):
160 if os
.spawnl(os
.P_WAIT
, '/sbin/rmmod', 'rmmod', module
) != 0:
161 raise Exception('failed to remove %s module' % (module
,))
163 def insert_module(module
):
168 if os
.spawnl(os
.P_WAIT
, '/sbin/insmod', 'insmod',
169 'kernel/' + archdir
+ '/%s.ko' % (module
,)) != 0:
170 raise Exception('failed to load kvm module')
172 def probe_module(module
):
173 if os
.spawnl(os
.P_WAIT
, '/sbin/modprobe', 'modprobe', module
) != 0:
174 raise Exception('failed to load kvm module')
177 for x
in file('/proc/cpuinfo').readlines():
178 m
= re
.match(r
'vendor_id[ \t]*: *([a-zA-Z]+),*', x
)
184 'GenuineIntel': 'kvm-intel',
185 'AuthenticAMD': 'kvm-amd',
188 if options
.kvm
and options
.reload:
189 for module
in [vendor_module
, 'kvm']:
190 remove_module(module
)
192 insmod
= insert_module
194 insmod
= probe_module
195 for module
in ['kvm', vendor_module
]:
197 commands
.getstatusoutput('/sbin/udevsettle')
198 if not os
.access('/dev/kvm', os
.F_OK
):
199 print '/dev/kvm not present'
203 (status
, output
) = commands
.getstatusoutput(
204 'qemu/qemu-img create -f qcow2 "%s" 30G' % disk
)
206 raise Exception, output
213 cmd
= 'qemu-system-' + arch
217 local_cmd
= 'qemu/' + arch
+ '-softmmu/' + cmd
218 if os
.access(local_cmd
, os
.F_OK
):
223 qemu_args
= (cmd
, '-boot', bootdisk
,
224 '-hda', disk
, '-m', str(options
.memory
),
225 '-serial', 'file:/tmp/serial.log',
226 '-smp', str(options
.vcpus
),
227 #'-usbdevice', 'tablet',
231 qemu_args
+= ('-cdrom', options
.cdrom
,)
234 qemu_args
+= ('-hdb', options
.hdb
,)
237 qemu_args
+= ('-no-kvm',)
242 if not options
.irqchip
:
243 qemu_args
+= ('-no-kvm-irqchip',)
245 if not options
.notap
:
248 for line
in commands
.getoutput('/sbin/ip link show eth0').splitlines():
249 m
= re
.match(r
'.*link/ether (..:..:..:..:..:..).*', line
)
253 raise Exception, 'Unable to determine eth0 mac address'
254 mac_components
= mac
.split(':')
255 mac_components
[0] = 'a0'
256 mac
= ':'.join(mac_components
)
258 qemu_args
+= ('-net', 'nic,macaddr=%s,model=%s' % (mac
,options
.nictype
,),
259 '-net', 'tap,script=/etc/kvm/qemu-ifup',)
262 qemu_args
+= ('-vnc', str(options
.vnc
))
264 if options
.saved_image
:
265 qemu_args
+= ('-loadvm' , options
.saved_image
, )
268 if options
.monitor
== 'stdio':
269 qemu_args
+= ('-monitor' , 'stdio', )
270 elif options
.monitor
== 'tcp':
271 qemu_args
+= ('-monitor' , 'tcp:0:5555,server,nowait', )
273 raise Exception('illegal monitor option %s' % option
.monitor
)
279 def concat_func(x
,y
): return x
+ ' ' + y
280 print reduce(concat_func
, qemu_args
)
283 os
.execvp(cmd
, qemu_args
)