Device-assignment: free device if hotplug fails
[qemu-kvm/fedora.git] / kvm / kvm
blobcb9ecf83b1b8b0d3c8849576f15704180948333a
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')
22 arch = config.get('shell', 'arch')
23 p = re.compile("^i\d86$")
24 if len(p.findall(arch)):
25 arch = 'x86_64'
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',
36 dest = 'reload',
37 default = privileged,
40 optparser.add_option('--install',
41 help = 'start up guest in installer boot cd',
42 action = 'store_true',
43 default = False,
46 optparser.add_option('-m', '--memory',
47 help = 'guest memory in MB',
48 type = 'int',
49 default = 384,
50 dest = 'memory',
53 optparser.add_option('--debugger',
54 help = 'wait for gdb',
55 action = 'store_true',
56 default = False,
59 optparser.add_option('--no-tap',
60 help = 'run the guest without tap netif',
61 action = 'store_true',
62 dest = 'notap',
63 default = not privileged,
66 optparser.add_option('--nictype',
67 help = 'use this specific nic type (vendor)',
68 dest = 'nictype',
69 default = 'rtl8139',
72 optparser.add_option('--mac',
73 help = 'use this specific mac addr',
74 dest = 'mac',
75 default = None,
78 optparser.add_option('--vnc',
79 help = 'use VNC rather than SDL',
80 dest = 'vnc',
81 default = None,
84 optparser.add_option('--no-kvm',
85 help = 'use standard qemu, without kvm',
86 action = 'store_false',
87 dest = 'kvm',
88 default = True,
90 optparser.add_option('--image',
91 help = 'select disk image',
92 dest = 'image',
93 default = '/tmp/disk',
95 optparser.add_option('--cdrom',
96 help = 'select cdrom image',
97 dest = 'cdrom',
98 default = None,
101 optparser.add_option('--hdb',
102 help = 'secondary hard disk image',
103 dest = 'hdb',
104 default = None,
107 optparser.add_option('--loadvm',
108 help = 'select saved vm-image',
109 dest = 'saved_image',
110 default = None,
113 optparser.add_option('--monitor',
114 help = 'redirect monitor (currently only stdio or tcp)',
115 dest = 'monitor',
116 default = None,
119 optparser.add_option('--stopped',
120 help = 'start image in stopped mode',
121 action = 'store_true',
122 default = False,
125 optparser.add_option('-s', '--smp',
126 type = 'int',
127 default = 1,
128 dest = 'vcpus',
129 help = 'define number of vcpus',
132 optparser.add_option('--no-kvm-irqchip',
133 action = 'store_false',
134 default = True,
135 dest = 'irqchip',
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',
142 dest = 'dry_run',
143 default = False,
147 (options, args) = optparser.parse_args()
149 if len(args) > 0:
150 options.image = args[0]
152 if len(args) > 1:
153 options.cdrom = args[1]
155 def remove_module(module):
156 module = module.replace('-', '_')
157 lines = commands.getoutput('/sbin/lsmod').split('\n')
158 for x in lines:
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):
164 if arch == 'x86_64':
165 archdir = 'x86'
166 elif arch == 'ia64':
167 archdir = 'ia64'
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')
176 def vendor():
177 for x in file('/proc/cpuinfo').readlines():
178 m = re.match(r'vendor_id[ \t]*: *([a-zA-Z]+),*', x)
179 if m:
180 return m.group(1)
181 return unknown
183 vendor_module = {
184 'GenuineIntel': 'kvm-intel',
185 'AuthenticAMD': 'kvm-amd',
186 }[vendor()]
188 if options.kvm and options.reload:
189 for module in [vendor_module, 'kvm']:
190 remove_module(module)
191 if external_module:
192 insmod = insert_module
193 else:
194 insmod = probe_module
195 for module in ['kvm', vendor_module]:
196 insmod(module)
197 commands.getstatusoutput('/sbin/udevsettle')
198 if not os.access('/dev/kvm', os.F_OK):
199 print '/dev/kvm not present'
201 disk = options.image
202 if options.install:
203 (status, output) = commands.getstatusoutput(
204 'qemu/qemu-img create -f qcow2 "%s" 30G' % disk)
205 if status:
206 raise Exception, output
208 bootdisk = 'c'
209 if options.install:
210 bootdisk = 'd'
212 if arch == 'x86_64':
213 cmd = 'qemu-system-' + arch
214 else:
215 cmd = 'qemu'
217 local_cmd = 'qemu/' + arch + '-softmmu/' + cmd
218 if os.access(local_cmd, os.F_OK):
219 cmd = local_cmd
220 else:
221 cmd = '/usr/bin/kvm'
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',
230 if options.cdrom:
231 qemu_args += ('-cdrom', options.cdrom,)
233 if options.hdb:
234 qemu_args += ('-hdb', options.hdb,)
236 if not options.kvm:
237 qemu_args += ('-no-kvm',)
239 if options.debugger:
240 qemu_args += ('-s',)
242 if not options.irqchip:
243 qemu_args += ('-no-kvm-irqchip',)
245 if not options.notap:
246 mac = options.mac
247 if not mac:
248 for line in commands.getoutput('/sbin/ip link show eth0').splitlines():
249 m = re.match(r'.*link/ether (..:..:..:..:..:..).*', line)
250 if m:
251 mac = m.group(1)
252 if not mac:
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',)
261 if options.vnc:
262 qemu_args += ('-vnc', str(options.vnc))
264 if options.saved_image:
265 qemu_args += ('-loadvm' , options.saved_image, )
267 if options.monitor:
268 if options.monitor == 'stdio':
269 qemu_args += ('-monitor' , 'stdio', )
270 elif options.monitor == 'tcp':
271 qemu_args += ('-monitor' , 'tcp:0:5555,server,nowait', )
272 else:
273 raise Exception('illegal monitor option %s' % option.monitor)
275 if options.stopped:
276 qemu_args += ('-S',)
278 if options.dry_run:
279 def concat_func(x,y): return x + ' ' + y
280 print reduce(concat_func, qemu_args)
281 sys.exit(0)
283 os.execvp(cmd, qemu_args)