kvm: qemu: simulate edge-triggered interrupt in master PIC for time-drift-fix
[kvm-userspace.git] / kvm
blob0374fbc17debf3857e4b6a421c68ac2f85d76cec
1 #!/usr/bin/python
3 import sys, os, time, re
4 import optparse, commands
5 import ConfigParser, StringIO
7 class ShellConfigParser(ConfigParser.ConfigParser):
8 def read(self, filename):
9 try:
10 text = open(filename).read()
11 except IOError:
12 pass
13 else:
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',
28 dest = 'reload',
29 default = privileged,
32 optparser.add_option('--install',
33 help = 'start up guest in installer boot cd',
34 action = 'store_true',
35 default = False,
38 optparser.add_option('-m', '--memory',
39 help = 'guest memory in MB',
40 type = 'int',
41 default = 384,
42 dest = 'memory',
45 optparser.add_option('--debugger',
46 help = 'wait for gdb',
47 action = 'store_true',
48 default = False,
51 optparser.add_option('--no-tap',
52 help = 'run the guest without tap netif',
53 action = 'store_true',
54 dest = 'notap',
55 default = not privileged,
58 optparser.add_option('--mac',
59 help = 'use this specific mac addr',
60 dest = 'mac',
61 default = None,
64 optparser.add_option('--vnc',
65 help = 'use VNC rather than SDL',
66 dest = 'vnc',
67 default = None,
70 optparser.add_option('--no-kvm',
71 help = 'use standard qemu, without kvm',
72 action = 'store_false',
73 dest = 'kvm',
74 default = True,
76 optparser.add_option('--image',
77 help = 'select disk image',
78 dest = 'image',
79 default = '/tmp/disk',
81 optparser.add_option('--cdrom',
82 help = 'select cdrom image',
83 dest = 'cdrom',
84 default = None,
87 optparser.add_option('--hdb',
88 help = 'secondary hard disk image',
89 dest = 'hdb',
90 default = None,
93 optparser.add_option('--loadvm',
94 help = 'select saved vm-image',
95 dest = 'saved_image',
96 default = None,
99 optparser.add_option('--monitor',
100 help = 'redirect monitor (currently only stdio or tcp)',
101 dest = 'monitor',
102 default = None,
105 optparser.add_option('--stopped',
106 help = 'start image in stopped mode',
107 action = 'store_true',
108 default = False,
111 optparser.add_option('-s', '--smp',
112 type = 'int',
113 default = 1,
114 dest = 'vcpus',
115 help = 'define number of vcpus',
118 optparser.add_option('--no-kvm-irqchip',
119 action = 'store_false',
120 default = True,
121 dest = 'irqchip',
122 help = 'avoid using in-kernel irqchip',
125 optparser.add_option('-n', '--dry-run',
126 help = "just print the qemu command line; don't run it",
127 action = 'store_true',
128 dest = 'dry_run',
129 default = False,
133 (options, args) = optparser.parse_args()
135 if len(args) > 0:
136 options.image = args[0]
138 if len(args) > 1:
139 options.cdrom = args[1]
141 def remove_module(module):
142 module = module.replace('-', '_')
143 lines = commands.getoutput('/sbin/lsmod').split('\n')
144 for x in lines:
145 if x.startswith(module + ' '):
146 if os.spawnl(os.P_WAIT, '/sbin/rmmod', 'rmmod', module) != 0:
147 raise Exception('failed to remove %s module' % (module,))
149 def insert_module(module):
150 if os.spawnl(os.P_WAIT, '/sbin/insmod', 'insmod',
151 'kernel/%s.ko' % (module,)) != 0:
152 raise Exception('failed to load kvm module')
154 def probe_module(module):
155 if os.spawnl(os.P_WAIT, '/sbin/modprobe', 'modprobe', module) != 0:
156 raise Exception('failed to load kvm module')
158 def vendor():
159 for x in file('/proc/cpuinfo').readlines():
160 m = re.match(r'vendor_id[ \t]*: *([a-zA-Z]+),*', x)
161 if m:
162 return m.group(1)
163 return unknown
165 vendor_module = {
166 'GenuineIntel': 'kvm-intel',
167 'AuthenticAMD': 'kvm-amd',
168 }[vendor()]
170 if options.kvm and options.reload:
171 for module in [vendor_module, 'kvm']:
172 remove_module(module)
173 if external_module:
174 insmod = insert_module
175 else:
176 insmod = probe_module
177 for module in ['kvm', vendor_module]:
178 insmod(module)
179 commands.getstatusoutput('/sbin/udevsettle')
180 if not os.access('/dev/kvm', os.F_OK):
181 print '/dev/kvm not present'
183 disk = options.image
184 if options.install:
185 (status, output) = commands.getstatusoutput(
186 'qemu/qemu-img create -f qcow2 "%s" 30G' % disk)
187 if status:
188 raise Exception, output
190 bootdisk = 'c'
191 if options.install:
192 bootdisk = 'd'
194 arch = 'x86_64'
196 if arch == 'x86_64':
197 cmd = 'qemu-system-' + arch
198 else:
199 cmd = 'qemu'
201 local_cmd = 'qemu/' + arch + '-softmmu/' + cmd
202 if os.access(local_cmd, os.F_OK):
203 cmd = local_cmd
204 else:
205 cmd = '/usr/bin/kvm'
207 qemu_args = (cmd, '-boot', bootdisk,
208 '-hda', disk, '-m', str(options.memory),
209 '-serial', 'file:/tmp/serial.log',
210 '-smp', str(options.vcpus),
211 #'-usbdevice', 'tablet',
214 if options.cdrom:
215 qemu_args += ('-cdrom', options.cdrom,)
217 if options.hdb:
218 qemu_args += ('-hdb', options.hdb,)
220 if not options.kvm:
221 qemu_args += ('-no-kvm',)
223 if options.debugger:
224 qemu_args += ('-s',)
226 if not options.irqchip:
227 qemu_args += ('-no-kvm-irqchip',)
229 if not options.notap:
230 mac = options.mac
231 if not mac:
232 for line in commands.getoutput('/sbin/ip link show eth0').splitlines():
233 m = re.match(r'.*link/ether (..:..:..:..:..:..).*', line)
234 if m:
235 mac = m.group(1)
236 if not mac:
237 raise Exception, 'Unable to determine eth0 mac address'
238 mac_components = mac.split(':')
239 mac_components[0] = 'a0'
240 mac = ':'.join(mac_components)
242 qemu_args += ('-net', 'nic,macaddr=%s,model=rtl8139' % (mac,),
243 '-net', 'tap,script=/etc/kvm/qemu-ifup',)
245 if options.vnc:
246 qemu_args += ('-vnc', str(options.vnc))
248 if options.saved_image:
249 qemu_args += ('-loadvm' , options.saved_image, )
251 if options.monitor:
252 if options.monitor == 'stdio':
253 qemu_args += ('-monitor' , 'stdio', )
254 elif options.monitor == 'tcp':
255 qemu_args += ('-monitor' , 'tcp:0:5555,server,nowait', )
256 else:
257 raise Exception('illegal monitor option %s' % option.monitor)
259 if options.stopped:
260 qemu_args += ('-S',)
262 if options.dry_run:
263 def concat_func(x,y): return x + ' ' + y
264 print reduce(concat_func, qemu_args)
265 sys.exit(0)
267 os.execvp(cmd, qemu_args)