]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
convert migrate_set_downtime monitor command to qmp
[qemu-server.git] / PVE / QemuServer.pm
CommitLineData
1e3baf05
DM
1package PVE::QemuServer;
2
3use strict;
4use POSIX;
5use IO::Handle;
6use IO::Select;
7use IO::File;
8use IO::Dir;
9use IO::Socket::UNIX;
10use File::Basename;
11use File::Path;
12use File::stat;
13use Getopt::Long;
fc1ddcdc 14use Digest::SHA;
1e3baf05
DM
15use Fcntl ':flock';
16use Cwd 'abs_path';
17use IPC::Open3;
c971c4f2 18use JSON;
1e3baf05
DM
19use Fcntl;
20use PVE::SafeSyslog;
21use Storable qw(dclone);
22use PVE::Exception qw(raise raise_param_exc);
23use PVE::Storage;
24use PVE::Tools qw(run_command lock_file file_read_firstline);
25use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
26use PVE::INotify;
27use PVE::ProcFSTools;
6b64503e 28use Time::HiRes qw(gettimeofday);
1e3baf05 29
7f0b5beb 30my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
1e3baf05 31
19672434 32# Note about locking: we use flock on the config file protect
1e3baf05
DM
33# against concurent actions.
34# Aditionaly, we have a 'lock' setting in the config file. This
35# can be set to 'migrate' or 'backup'. Most actions are not
36# allowed when such lock is set. But you can ignore this kind of
37# lock with the --skiplock flag.
38
97d62eb7 39cfs_register_file('/qemu-server/',
1858638f
DM
40 \&parse_vm_config,
41 \&write_vm_config);
1e3baf05 42
3ea94c60
DM
43PVE::JSONSchema::register_standard_option('skiplock', {
44 description => "Ignore locks - only root is allowed to use this option.",
afdb31d5 45 type => 'boolean',
3ea94c60
DM
46 optional => 1,
47});
48
49PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
50 description => "Some command save/restore state from this location.",
51 type => 'string',
52 maxLength => 128,
53 optional => 1,
54});
55
1e3baf05
DM
56#no warnings 'redefine';
57
58unless(defined(&_VZSYSCALLS_H_)) {
59 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_);
60 require 'sys/syscall.ph';
61 if(defined(&__x86_64__)) {
62 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus);
63 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod);
64 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod);
65 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt);
66 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr);
67 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate);
68 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid);
69 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit);
70 }
71 elsif(defined( &__i386__) ) {
72 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod);
73 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod);
74 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt);
75 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr);
76 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate);
77 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus);
78 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid);
79 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit);
80 } else {
81 die("no fairsched syscall for this arch");
82 }
83 require 'asm/ioctl.ph';
84 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION);
85}
86
87sub fairsched_mknod {
88 my ($parent, $weight, $desired) = @_;
89
6b64503e 90 return syscall(&__NR_fairsched_mknod, int($parent), int($weight), int($desired));
1e3baf05
DM
91}
92
93sub fairsched_rmnod {
94 my ($id) = @_;
95
6b64503e 96 return syscall(&__NR_fairsched_rmnod, int($id));
1e3baf05
DM
97}
98
99sub fairsched_mvpr {
100 my ($pid, $newid) = @_;
101
6b64503e 102 return syscall(&__NR_fairsched_mvpr, int($pid), int($newid));
1e3baf05
DM
103}
104
105sub fairsched_vcpus {
106 my ($id, $vcpus) = @_;
107
6b64503e 108 return syscall(&__NR_fairsched_vcpus, int($id), int($vcpus));
1e3baf05
DM
109}
110
111sub fairsched_rate {
112 my ($id, $op, $rate) = @_;
113
6b64503e 114 return syscall(&__NR_fairsched_rate, int($id), int($op), int($rate));
1e3baf05
DM
115}
116
117use constant FAIRSCHED_SET_RATE => 0;
118use constant FAIRSCHED_DROP_RATE => 1;
119use constant FAIRSCHED_GET_RATE => 2;
120
121sub fairsched_cpulimit {
122 my ($id, $limit) = @_;
123
6b64503e 124 my $cpulim1024 = int($limit * 1024 / 100);
1e3baf05
DM
125 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE : FAIRSCHED_DROP_RATE;
126
6b64503e 127 return fairsched_rate($id, $op, $cpulim1024);
1e3baf05
DM
128}
129
130my $nodename = PVE::INotify::nodename();
131
132mkdir "/etc/pve/nodes/$nodename";
133my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
134mkdir $confdir;
135
136my $var_run_tmpdir = "/var/run/qemu-server";
137mkdir $var_run_tmpdir;
138
139my $lock_dir = "/var/lock/qemu-server";
140mkdir $lock_dir;
141
142my $pcisysfs = "/sys/bus/pci";
143
1e3baf05
DM
144my $confdesc = {
145 onboot => {
146 optional => 1,
147 type => 'boolean',
148 description => "Specifies whether a VM will be started during system bootup.",
149 default => 0,
150 },
151 autostart => {
152 optional => 1,
153 type => 'boolean',
154 description => "Automatic restart after crash (currently ignored).",
155 default => 0,
156 },
2ff09f52
DA
157 hotplug => {
158 optional => 1,
e8b9c17c 159 type => 'boolean',
2ff09f52
DA
160 description => "Activate hotplug for disk and network device",
161 default => 0,
162 },
1e3baf05
DM
163 reboot => {
164 optional => 1,
165 type => 'boolean',
166 description => "Allow reboot. If set to '0' the VM exit on reboot.",
167 default => 1,
168 },
169 lock => {
170 optional => 1,
171 type => 'string',
172 description => "Lock/unlock the VM.",
173 enum => [qw(migrate backup)],
174 },
175 cpulimit => {
176 optional => 1,
177 type => 'integer',
178 description => "Limit of CPU usage in per cent. Note if the computer has 2 CPUs, it has total of 200% CPU time. Value '0' indicates no CPU limit.\n\nNOTE: This option is currently ignored.",
179 minimum => 0,
180 default => 0,
181 },
182 cpuunits => {
183 optional => 1,
184 type => 'integer',
185 description => "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.",
186 minimum => 0,
187 maximum => 500000,
188 default => 1000,
189 },
190 memory => {
191 optional => 1,
192 type => 'integer',
7878afeb 193 description => "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
1e3baf05
DM
194 minimum => 16,
195 default => 512,
196 },
13a48620
DA
197 balloon => {
198 optional => 1,
199 type => 'integer',
200 description => "Amount of target RAM for the VM in MB.",
7878afeb 201 minimum => 16,
13a48620 202 },
1e3baf05
DM
203 keyboard => {
204 optional => 1,
205 type => 'string',
206 description => "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
e95fe75f 207 enum => PVE::Tools::kvmkeymaplist(),
1e3baf05
DM
208 default => 'en-us',
209 },
210 name => {
211 optional => 1,
7fabe17d 212 type => 'string', format => 'dns-name',
1e3baf05
DM
213 description => "Set a name for the VM. Only used on the configuration web interface.",
214 },
215 description => {
216 optional => 1,
217 type => 'string',
0581fe4f 218 description => "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
1e3baf05
DM
219 },
220 ostype => {
221 optional => 1,
222 type => 'string',
223 enum => [qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26)],
224 description => <<EODESC,
225Used to enable special optimization/features for specific
226operating systems:
227
228other => unspecified OS
229wxp => Microsoft Windows XP
230w2k => Microsoft Windows 2000
231w2k3 => Microsoft Windows 2003
232w2k8 => Microsoft Windows 2008
233wvista => Microsoft Windows Vista
234win7 => Microsoft Windows 7
235l24 => Linux 2.4 Kernel
236l26 => Linux 2.6/3.X Kernel
237
238other|l24|l26 ... no special behaviour
239wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
240EODESC
241 },
242 boot => {
243 optional => 1,
244 type => 'string',
245 description => "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
246 pattern => '[acdn]{1,4}',
32baffb4 247 default => 'cdn',
1e3baf05
DM
248 },
249 bootdisk => {
250 optional => 1,
251 type => 'string', format => 'pve-qm-bootdisk',
252 description => "Enable booting from specified disk.",
253 pattern => '(ide|scsi|virtio)\d+',
254 },
255 smp => {
256 optional => 1,
257 type => 'integer',
258 description => "The number of CPUs. Please use option -sockets instead.",
259 minimum => 1,
260 default => 1,
261 },
262 sockets => {
263 optional => 1,
264 type => 'integer',
265 description => "The number of CPU sockets.",
266 minimum => 1,
267 default => 1,
268 },
269 cores => {
270 optional => 1,
271 type => 'integer',
272 description => "The number of cores per socket.",
273 minimum => 1,
274 default => 1,
275 },
276 acpi => {
277 optional => 1,
278 type => 'boolean',
279 description => "Enable/disable ACPI.",
280 default => 1,
281 },
282 kvm => {
283 optional => 1,
284 type => 'boolean',
285 description => "Enable/disable KVM hardware virtualization.",
286 default => 1,
287 },
288 tdf => {
289 optional => 1,
290 type => 'boolean',
da21653b 291 description => "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
1e3baf05
DM
292 default => 1,
293 },
19672434 294 localtime => {
1e3baf05
DM
295 optional => 1,
296 type => 'boolean',
297 description => "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
298 },
299 freeze => {
300 optional => 1,
301 type => 'boolean',
302 description => "Freeze CPU at startup (use 'c' monitor command to start execution).",
303 },
304 vga => {
305 optional => 1,
306 type => 'string',
307 description => "Select VGA type. If you want to use high resolution modes (>= 1280x1024x16) then you should use option 'std' or 'vmware'. Default is 'std' for win7/w2k8, and 'cirrur' for other OS types",
308 enum => [qw(std cirrus vmware)],
309 },
0ea9541d
DM
310 watchdog => {
311 optional => 1,
312 type => 'string', format => 'pve-qm-watchdog',
313 typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
314 description => "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the guest will be restarted (or execute the action specified)",
315 },
1e3baf05
DM
316 startdate => {
317 optional => 1,
19672434 318 type => 'string',
1e3baf05
DM
319 typetext => "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
320 description => "Set the initial date of the real time clock. Valid format for date are: 'now' or '2006-06-17T16:01:21' or '2006-06-17'.",
321 pattern => '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
322 default => 'now',
323 },
59411c4e
DM
324 startup => {
325 optional => 1,
326 type => 'string', format => 'pve-qm-startup',
327 typetext => '[[order=]\d+] [,up=\d+] [,down=\d+] ',
328 description => "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.",
329 },
1e3baf05
DM
330 args => {
331 optional => 1,
332 type => 'string',
333 description => <<EODESCR,
334Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
335
336args: -no-reboot -no-hpet
337EODESCR
338 },
339 tablet => {
340 optional => 1,
341 type => 'boolean',
342 default => 1,
343 description => "Enable/disable the usb tablet device. This device is usually needed to allow absolute mouse positioning. Else the mouse runs out of sync with normal vnc clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches.",
344 },
345 migrate_speed => {
346 optional => 1,
347 type => 'integer',
348 description => "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
349 minimum => 0,
350 default => 0,
351 },
352 migrate_downtime => {
353 optional => 1,
354 type => 'integer',
355 description => "Set maximum tolerated downtime (in seconds) for migrations.",
356 minimum => 0,
357 default => 1,
358 },
359 cdrom => {
360 optional => 1,
361 type => 'string', format => 'pve-qm-drive',
362 typetext => 'volume',
363 description => "This is an alias for option -ide2",
364 },
365 cpu => {
366 optional => 1,
367 description => "Emulated CPU type.",
368 type => 'string',
5b805e50 369 enum => [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom cpu64-rhel6 cpu64-rhel5 Conroe Penryn Nehalem Westmere Opteron_G1 Opteron_G2 Opteron_G3 host) ],
1e3baf05
DM
370 default => 'qemu64',
371 },
372};
373
374# what about other qemu settings ?
375#cpu => 'string',
376#machine => 'string',
377#fda => 'file',
378#fdb => 'file',
379#mtdblock => 'file',
380#sd => 'file',
381#pflash => 'file',
382#snapshot => 'bool',
383#bootp => 'file',
384##tftp => 'dir',
385##smb => 'dir',
386#kernel => 'file',
387#append => 'string',
388#initrd => 'file',
389##soundhw => 'string',
390
391while (my ($k, $v) = each %$confdesc) {
392 PVE::JSONSchema::register_standard_option("pve-qm-$k", $v);
393}
394
395my $MAX_IDE_DISKS = 4;
f62db2a4
DA
396my $MAX_SCSI_DISKS = 14;
397my $MAX_VIRTIO_DISKS = 6;
cdb0931f 398my $MAX_SATA_DISKS = 6;
1e3baf05 399my $MAX_USB_DEVICES = 5;
f62db2a4 400my $MAX_NETS = 6;
1e3baf05 401my $MAX_UNUSED_DISKS = 8;
040b06b7 402my $MAX_HOSTPCI_DEVICES = 2;
bae179aa 403my $MAX_SERIAL_PORTS = 4;
1989a89c 404my $MAX_PARALLEL_PORTS = 3;
1e3baf05
DM
405
406my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
407 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
6b64503e 408my $nic_model_list_txt = join(' ', sort @$nic_model_list);
1e3baf05
DM
409
410# fixme:
411my $netdesc = {
412 optional => 1,
413 type => 'string', format => 'pve-qm-net',
5070f384 414 typetext => "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
1e3baf05 415 description => <<EODESCR,
19672434 416Specify network devices.
1e3baf05
DM
417
418MODEL is one of: $nic_model_list_txt
419
19672434 420XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
1e3baf05
DM
421automatically generated if not specified.
422
423The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
424
425Option 'rate' is used to limit traffic bandwidth from and to this interface. It is specified as floating point number, unit is 'Megabytes per second'.
426
427If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
428
42910.0.2.2 Gateway
43010.0.2.3 DNS Server
43110.0.2.4 SMB Server
432
433The DHCP server assign addresses to the guest starting from 10.0.2.15.
434
435EODESCR
436};
437PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
438
439for (my $i = 0; $i < $MAX_NETS; $i++) {
440 $confdesc->{"net$i"} = $netdesc;
441}
442
443my $drivename_hash;
19672434 444
1e3baf05
DM
445my $idedesc = {
446 optional => 1,
447 type => 'string', format => 'pve-qm-drive',
e482cec3 448 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
1e3baf05
DM
449 description => "Use volume as IDE hard disk or CD-ROM (n is 0 to 3).",
450};
451PVE::JSONSchema::register_standard_option("pve-qm-ide", $idedesc);
452
453my $scsidesc = {
454 optional => 1,
455 type => 'string', format => 'pve-qm-drive',
e482cec3 456 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
2fe1a152 457 description => "Use volume as SCSI hard disk or CD-ROM (n is 0 to 13).",
1e3baf05
DM
458};
459PVE::JSONSchema::register_standard_option("pve-qm-scsi", $scsidesc);
460
cdb0931f
DA
461my $satadesc = {
462 optional => 1,
463 type => 'string', format => 'pve-qm-drive',
e482cec3 464 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
cdb0931f
DA
465 description => "Use volume as SATA hard disk or CD-ROM (n is 0 to 5).",
466};
467PVE::JSONSchema::register_standard_option("pve-qm-sata", $satadesc);
468
1e3baf05
DM
469my $virtiodesc = {
470 optional => 1,
471 type => 'string', format => 'pve-qm-drive',
e482cec3 472 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
2fe1a152 473 description => "Use volume as VIRTIO hard disk (n is 0 to 5).",
1e3baf05
DM
474};
475PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
476
477my $usbdesc = {
478 optional => 1,
479 type => 'string', format => 'pve-qm-usb-device',
480 typetext => 'host=HOSTUSBDEVICE',
481 description => <<EODESCR,
2fe1a152 482Configure an USB device (n is 0 to 4). This can be used to
1e3baf05
DM
483pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
484
19672434 485'bus-port(.port)*' (decimal numbers) or
1e3baf05
DM
486'vendor_id:product_id' (hexadeciaml numbers)
487
19672434 488You can use the 'lsusb -t' command to list existing usb devices.
1e3baf05
DM
489
490Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
491
492EODESCR
493};
494PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
495
040b06b7
DA
496my $hostpcidesc = {
497 optional => 1,
498 type => 'string', format => 'pve-qm-hostpci',
499 typetext => "HOSTPCIDEVICE",
500 description => <<EODESCR,
501Map host pci devices. HOSTPCIDEVICE syntax is:
502
503'bus:dev.func' (hexadecimal numbers)
504
505You can us the 'lspci' command to list existing pci devices.
506
507Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
508
509Experimental: user reported problems with this option.
510EODESCR
511};
512PVE::JSONSchema::register_standard_option("pve-qm-hostpci", $hostpcidesc);
513
bae179aa
DA
514my $serialdesc = {
515 optional => 1,
ca0cef26 516 type => 'string',
2fe1a152 517 pattern => '/dev/ttyS\d+',
bae179aa 518 description => <<EODESCR,
19672434 519Map host serial devices (n is 0 to 3).
bae179aa
DA
520
521Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
522
523Experimental: user reported problems with this option.
524EODESCR
525};
bae179aa 526
1989a89c
DA
527my $paralleldesc= {
528 optional => 1,
ca0cef26 529 type => 'string',
2fe1a152 530 pattern => '/dev/parport\d+',
1989a89c 531 description => <<EODESCR,
19672434 532Map host parallel devices (n is 0 to 2).
1989a89c
DA
533
534Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
535
536Experimental: user reported problems with this option.
537EODESCR
538};
1989a89c
DA
539
540for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
541 $confdesc->{"parallel$i"} = $paralleldesc;
542}
543
bae179aa
DA
544for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
545 $confdesc->{"serial$i"} = $serialdesc;
546}
547
040b06b7
DA
548for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
549 $confdesc->{"hostpci$i"} = $hostpcidesc;
550}
1e3baf05
DM
551
552for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
553 $drivename_hash->{"ide$i"} = 1;
554 $confdesc->{"ide$i"} = $idedesc;
555}
556
cdb0931f
DA
557for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
558 $drivename_hash->{"sata$i"} = 1;
559 $confdesc->{"sata$i"} = $satadesc;
560}
561
1e3baf05
DM
562for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
563 $drivename_hash->{"scsi$i"} = 1;
564 $confdesc->{"scsi$i"} = $scsidesc ;
565}
566
567for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
568 $drivename_hash->{"virtio$i"} = 1;
569 $confdesc->{"virtio$i"} = $virtiodesc;
570}
571
572for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
573 $confdesc->{"usb$i"} = $usbdesc;
574}
575
576my $unuseddesc = {
577 optional => 1,
578 type => 'string', format => 'pve-volume-id',
579 description => "Reference to unused volumes.",
580};
581
582for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
583 $confdesc->{"unused$i"} = $unuseddesc;
584}
585
586my $kvm_api_version = 0;
587
588sub kvm_version {
589
590 return $kvm_api_version if $kvm_api_version;
591
6b64503e 592 my $fh = IO::File->new("</dev/kvm") ||
1e3baf05
DM
593 return 0;
594
6b64503e 595 if (my $v = $fh->ioctl(KVM_GET_API_VERSION(), 0)) {
1e3baf05
DM
596 $kvm_api_version = $v;
597 }
598
599 $fh->close();
600
601 return $kvm_api_version;
602}
603
604my $kvm_user_version;
605
606sub kvm_user_version {
607
608 return $kvm_user_version if $kvm_user_version;
609
610 $kvm_user_version = 'unknown';
611
612 my $tmp = `kvm -help 2>/dev/null`;
19672434 613
a3c52213 614 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
1e3baf05
DM
615 $kvm_user_version = $2;
616 }
617
618 return $kvm_user_version;
619
620}
621
622my $kernel_has_vhost_net = -c '/dev/vhost-net';
623
624sub disknames {
625 # order is important - used to autoselect boot disk
19672434 626 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
1e3baf05 627 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
cdb0931f
DA
628 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
629 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
1e3baf05
DM
630}
631
632sub valid_drivename {
633 my $dev = shift;
634
6b64503e 635 return defined($drivename_hash->{$dev});
1e3baf05
DM
636}
637
638sub option_exists {
639 my $key = shift;
640 return defined($confdesc->{$key});
19672434 641}
1e3baf05
DM
642
643sub nic_models {
644 return $nic_model_list;
645}
646
647sub os_list_description {
648
649 return {
650 other => 'Other',
651 wxp => 'Windows XP',
652 w2k => 'Windows 2000',
653 w2k3 =>, 'Windows 2003',
654 w2k8 => 'Windows 2008',
655 wvista => 'Windows Vista',
656 win7 => 'Windows 7',
657 l24 => 'Linux 2.4',
658 l26 => 'Linux 2.6',
19672434 659 };
1e3baf05
DM
660}
661
1e3baf05
DM
662sub disk_devive_info {
663 my $dev = shift;
664
665 die "unknown disk device format '$dev'" if $dev !~ m/^(ide|scsi|virtio)(\d+)$/;
666
667 my $bus = $1;
668 my $index = $2;
669 my $maxdev = 1024;
670
671 if ($bus eq 'ide') {
672 $maxdev = 2;
673 } elsif ($bus eq 'scsi') {
f62db2a4 674 $maxdev = 7;
1e3baf05
DM
675 }
676
6b64503e 677 my $controller = int($index / $maxdev);
1e3baf05
DM
678 my $unit = $index % $maxdev;
679
680
681 return { bus => $bus, desc => uc($bus) . " $controller:$unit",
682 controller => $controller, unit => $unit, index => $index };
683
684}
685
686sub qemu_drive_name {
19672434 687 my ($dev, $media) = @_;
1e3baf05 688
6b64503e 689 my $info = disk_devive_info($dev);
1e3baf05
DM
690 my $mediastr = '';
691
692 if (($info->{bus} eq 'ide') || ($info->{bus} eq 'scsi')) {
693 $mediastr = ($media eq 'cdrom') ? "-cd" : "-hd";
19672434 694 return sprintf("%s%i%s%i", $info->{bus}, $info->{controller},
1e3baf05
DM
695 $mediastr, $info->{unit});
696 } else {
19672434 697 return sprintf("%s%i", $info->{bus}, $info->{index});
1e3baf05
DM
698 }
699}
700
701my $cdrom_path;
702
703sub get_cdrom_path {
704
705 return $cdrom_path if $cdrom_path;
706
707 return $cdrom_path = "/dev/cdrom" if -l "/dev/cdrom";
708 return $cdrom_path = "/dev/cdrom1" if -l "/dev/cdrom1";
709 return $cdrom_path = "/dev/cdrom2" if -l "/dev/cdrom2";
710}
711
712sub get_iso_path {
713 my ($storecfg, $vmid, $cdrom) = @_;
714
715 if ($cdrom eq 'cdrom') {
716 return get_cdrom_path();
717 } elsif ($cdrom eq 'none') {
718 return '';
719 } elsif ($cdrom =~ m|^/|) {
720 return $cdrom;
721 } else {
6b64503e 722 return PVE::Storage::path($storecfg, $cdrom);
1e3baf05
DM
723 }
724}
725
726# try to convert old style file names to volume IDs
727sub filename_to_volume_id {
728 my ($vmid, $file, $media) = @_;
729
730 if (!($file eq 'none' || $file eq 'cdrom' ||
731 $file =~ m|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
19672434 732
1e3baf05 733 return undef if $file =~ m|/|;
19672434 734
1e3baf05
DM
735 if ($media && $media eq 'cdrom') {
736 $file = "local:iso/$file";
737 } else {
738 $file = "local:$vmid/$file";
739 }
740 }
741
742 return $file;
743}
744
745sub verify_media_type {
746 my ($opt, $vtype, $media) = @_;
747
748 return if !$media;
749
750 my $etype;
751 if ($media eq 'disk') {
a125592c 752 $etype = 'images';
1e3baf05
DM
753 } elsif ($media eq 'cdrom') {
754 $etype = 'iso';
755 } else {
756 die "internal error";
757 }
758
759 return if ($vtype eq $etype);
19672434 760
1e3baf05
DM
761 raise_param_exc({ $opt => "unexpected media type ($vtype != $etype)" });
762}
763
764sub cleanup_drive_path {
765 my ($opt, $storecfg, $drive) = @_;
766
767 # try to convert filesystem paths to volume IDs
768
769 if (($drive->{file} !~ m/^(cdrom|none)$/) &&
770 ($drive->{file} !~ m|^/dev/.+|) &&
771 ($drive->{file} !~ m/^([^:]+):(.+)$/) &&
19672434 772 ($drive->{file} !~ m/^\d+$/)) {
1e3baf05
DM
773 my ($vtype, $volid) = PVE::Storage::path_to_volume_id($storecfg, $drive->{file});
774 raise_param_exc({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
775 $drive->{media} = 'cdrom' if !$drive->{media} && $vtype eq 'iso';
776 verify_media_type($opt, $vtype, $drive->{media});
777 $drive->{file} = $volid;
778 }
779
780 $drive->{media} = 'cdrom' if !$drive->{media} && $drive->{file} =~ m/^(cdrom|none)$/;
781}
782
783sub create_conf_nolock {
784 my ($vmid, $settings) = @_;
785
6b64503e 786 my $filename = config_file($vmid);
1e3baf05
DM
787
788 die "configuration file '$filename' already exists\n" if -f $filename;
19672434 789
1e3baf05
DM
790 my $defaults = load_defaults();
791
792 $settings->{name} = "vm$vmid" if !$settings->{name};
793 $settings->{memory} = $defaults->{memory} if !$settings->{memory};
794
795 my $data = '';
796 foreach my $opt (keys %$settings) {
797 next if !$confdesc->{$opt};
798
799 my $value = $settings->{$opt};
800 next if !$value;
801
802 $data .= "$opt: $value\n";
803 }
804
805 PVE::Tools::file_set_contents($filename, $data);
806}
807
808# ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
809# [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
036e0e2b 810# [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
1e3baf05
DM
811# [,aio=native|threads]
812
813sub parse_drive {
814 my ($key, $data) = @_;
815
816 my $res = {};
19672434 817
1e3baf05
DM
818 # $key may be undefined - used to verify JSON parameters
819 if (!defined($key)) {
820 $res->{interface} = 'unknown'; # should not harm when used to verify parameters
821 $res->{index} = 0;
822 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
823 $res->{interface} = $1;
824 $res->{index} = $2;
825 } else {
826 return undef;
827 }
828
829 foreach my $p (split (/,/, $data)) {
830 next if $p =~ m/^\s*$/;
831
affd2f88 832 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|bps_rd|bps_wr|iops|iops_rd|iops_wr)=(.+)$/) {
1e3baf05
DM
833 my ($k, $v) = ($1, $2);
834
835 $k = 'file' if $k eq 'volume';
836
837 return undef if defined $res->{$k};
19672434 838
1e3baf05
DM
839 $res->{$k} = $v;
840 } else {
841 if (!$res->{file} && $p !~ m/=/) {
842 $res->{file} = $p;
843 } else {
844 return undef;
845 }
846 }
847 }
848
849 return undef if !$res->{file};
850
19672434 851 return undef if $res->{cache} &&
e482cec3 852 $res->{cache} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
1e3baf05
DM
853 return undef if $res->{snapshot} && $res->{snapshot} !~ m/^(on|off)$/;
854 return undef if $res->{cyls} && $res->{cyls} !~ m/^\d+$/;
855 return undef if $res->{heads} && $res->{heads} !~ m/^\d+$/;
856 return undef if $res->{secs} && $res->{secs} !~ m/^\d+$/;
857 return undef if $res->{media} && $res->{media} !~ m/^(disk|cdrom)$/;
858 return undef if $res->{trans} && $res->{trans} !~ m/^(none|lba|auto)$/;
859 return undef if $res->{format} && $res->{format} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
860 return undef if $res->{rerror} && $res->{rerror} !~ m/^(ignore|report|stop)$/;
861 return undef if $res->{werror} && $res->{werror} !~ m/^(enospc|ignore|report|stop)$/;
862 return undef if $res->{backup} && $res->{backup} !~ m/^(yes|no)$/;
863 return undef if $res->{aio} && $res->{aio} !~ m/^(native|threads)$/;
864
affd2f88
AD
865 return undef if $res->{bps_rd} && $res->{bps};
866 return undef if $res->{bps_wr} && $res->{bps};
867 return undef if $res->{iops_rd} && $res->{iops};
868 return undef if $res->{iops_wr} && $res->{iops};
869
870 return undef if $res->{bps} && $res->{bps} !~ m/^\d+$/;
871 return undef if $res->{bps_rd} && $res->{bps_rd} !~ m/^\d+$/;
872 return undef if $res->{bps_wr} && $res->{bps_wr} !~ m/^\d+$/;
873 return undef if $res->{iops} && $res->{iops} !~ m/^\d+$/;
874 return undef if $res->{iops_rd} && $res->{iops_rd} !~ m/^\d+$/;
875 return undef if $res->{iops_wr} && $res->{iops_wr} !~ m/^\d+$/;
876
877
1e3baf05
DM
878 if ($res->{media} && ($res->{media} eq 'cdrom')) {
879 return undef if $res->{snapshot} || $res->{trans} || $res->{format};
19672434 880 return undef if $res->{heads} || $res->{secs} || $res->{cyls};
1e3baf05
DM
881 return undef if $res->{interface} eq 'virtio';
882 }
883
884 # rerror does not work with scsi drives
885 if ($res->{rerror}) {
886 return undef if $res->{interface} eq 'scsi';
887 }
888
889 return $res;
890}
891
affd2f88 892my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio bps bps_rd bps_wr iops iops_rd iops_wr);
1e3baf05
DM
893
894sub print_drive {
895 my ($vmid, $drive) = @_;
896
897 my $opts = '';
898 foreach my $o (@qemu_drive_options, 'backup') {
899 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
900 }
901
902 return "$drive->{file}$opts";
903}
904
28ef82d3
DM
905sub scsi_inquiry {
906 my($fh, $noerr) = @_;
907
908 my $SG_IO = 0x2285;
909 my $SG_GET_VERSION_NUM = 0x2282;
910
911 my $versionbuf = "\x00" x 8;
912 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
913 if (!$ret) {
914 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
915 return undef;
916 }
97d62eb7 917 my $version = unpack("I", $versionbuf);
28ef82d3
DM
918 if ($version < 30000) {
919 die "scsi generic interface too old\n" if !$noerr;
920 return undef;
921 }
97d62eb7 922
28ef82d3
DM
923 my $buf = "\x00" x 36;
924 my $sensebuf = "\x00" x 8;
925 my $cmd = pack("C x3 C x11", 0x12, 36);
97d62eb7 926
28ef82d3
DM
927 # see /usr/include/scsi/sg.h
928 my $sg_io_hdr_t = "i i C C s I P P P I I i P C C C C S S i I I";
929
97d62eb7
DM
930 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
931 length($sensebuf), 0, length($buf), $buf,
28ef82d3
DM
932 $cmd, $sensebuf, 6000);
933
934 $ret = ioctl($fh, $SG_IO, $packet);
935 if (!$ret) {
936 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
937 return undef;
938 }
97d62eb7 939
28ef82d3
DM
940 my @res = unpack($sg_io_hdr_t, $packet);
941 if ($res[17] || $res[18]) {
942 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
943 return undef;
944 }
945
946 my $res = {};
947 ($res->{device}, $res->{removable}, $res->{venodor},
948 $res->{product}, $res->{revision}) = unpack("C C x6 A8 A16 A4", $buf);
949
950 return $res;
951}
952
953sub path_is_scsi {
954 my ($path) = @_;
955
956 my $fh = IO::File->new("+<$path") || return undef;
957 my $res = scsi_inquiry($fh, 1);
958 close($fh);
959
960 return $res;
961}
962
ca916ecc
DA
963sub print_drivedevice_full {
964 my ($storecfg, $vmid, $drive) = @_;
965
966 my $device = '';
967 my $maxdev = 0;
19672434 968
ca916ecc 969 if ($drive->{interface} eq 'virtio') {
2ed36a41
DM
970 my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}");
971 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
972 } elsif ($drive->{interface} eq 'scsi') {
973 $maxdev = 7;
974 my $controller = int($drive->{index} / $maxdev);
975 my $unit = $drive->{index} % $maxdev;
976 my $devicetype = 'hd';
231f2e13
DA
977 my $path = '';
978 if (drive_is_cdrom($drive)) {
979 $devicetype = 'cd';
980 } else {
981 if ($drive->{file} =~ m|^/|) {
982 $path = $drive->{file};
983 } else {
984 $path = PVE::Storage::path($storecfg, $drive->{file});
985 }
28ef82d3 986 $devicetype = 'block' if path_is_scsi($path);
231f2e13 987 }
ca916ecc 988
7ebe888a 989 $device = "scsi-$devicetype,bus=lsi$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
2ed36a41
DM
990 } elsif ($drive->{interface} eq 'ide'){
991 $maxdev = 2;
992 my $controller = int($drive->{index} / $maxdev);
993 my $unit = $drive->{index} % $maxdev;
994 my $devicetype = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
995
7ebe888a 996 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdb0931f
DA
997 } elsif ($drive->{interface} eq 'sata'){
998 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
999 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1000 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
2ed36a41
DM
1001 } elsif ($drive->{interface} eq 'usb') {
1002 die "implement me";
1003 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1004 } else {
1005 die "unsupported interface type";
ca916ecc
DA
1006 }
1007
3b408e82
DM
1008 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex};
1009
ca916ecc
DA
1010 return $device;
1011}
1012
1e3baf05
DM
1013sub print_drive_full {
1014 my ($storecfg, $vmid, $drive) = @_;
1015
1016 my $opts = '';
1017 foreach my $o (@qemu_drive_options) {
3b408e82 1018 next if $o eq 'bootindex';
1e3baf05 1019 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
19672434 1020 }
1e3baf05
DM
1021
1022 # use linux-aio by default (qemu default is threads)
19672434 1023 $opts .= ",aio=native" if !$drive->{aio};
1e3baf05
DM
1024
1025 my $path;
1026 my $volid = $drive->{file};
6b64503e
DM
1027 if (drive_is_cdrom($drive)) {
1028 $path = get_iso_path($storecfg, $vmid, $volid);
1e3baf05
DM
1029 } else {
1030 if ($volid =~ m|^/|) {
1031 $path = $volid;
1032 } else {
6b64503e 1033 $path = PVE::Storage::path($storecfg, $volid);
1e3baf05 1034 }
2b556977
DM
1035 if (!$drive->{cache} && ($path =~ m|^/dev/| || $path =~ m|\.raw$|)) {
1036 $opts .= ",cache=none";
1037 }
1e3baf05
DM
1038 }
1039
1040 my $pathinfo = $path ? "file=$path," : '';
1041
3ebfcc86 1042 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1e3baf05
DM
1043}
1044
cc4d6182
DA
1045sub print_netdevice_full {
1046 my ($vmid, $conf, $net, $netid) = @_;
1047
1048 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
1049
1050 my $device = $net->{model};
1051 if ($net->{model} eq 'virtio') {
1052 $device = 'virtio-net-pci';
1053 };
1054
1055 # qemu > 0.15 always try to boot from network - we disable that by
1056 # not loading the pxe rom file
1057 my $extra = ($bootorder !~ m/n/) ? "romfile=," : '';
1058 my $pciaddr = print_pci_addr("$netid");
1059 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1060 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex} ;
1061 return $tmpstr;
1062}
1063
1064sub print_netdev_full {
1065 my ($vmid, $conf, $net, $netid) = @_;
1066
1067 my $i = '';
1068 if ($netid =~ m/^net(\d+)$/) {
1069 $i = int($1);
1070 }
1071
1072 die "got strange net id '$i'\n" if $i >= ${MAX_NETS};
1073
1074 my $ifname = "tap${vmid}i$i";
1075
1076 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1077 die "interface name '$ifname' is too long (max 15 character)\n"
1078 if length($ifname) >= 16;
1079
1080 my $vhostparam = '';
1081 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model} eq 'virtio';
1082
1083 my $vmname = $conf->{name} || "vm$vmid";
1084
1085 if ($net->{bridge}) {
1086 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1087 } else {
1088 return "type=user,id=$netid,hostname=$vmname";
1089 }
1090}
1e3baf05
DM
1091
1092sub drive_is_cdrom {
1093 my ($drive) = @_;
1094
1095 return $drive && $drive->{media} && ($drive->{media} eq 'cdrom');
1096
1097}
1098
040b06b7
DA
1099sub parse_hostpci {
1100 my ($value) = @_;
1101
1102 return undef if !$value;
1103
1104 my $res = {};
1105
1106 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1107 $res->{pciid} = $value;
1108 } else {
1109 return undef;
1110 }
1111
1112 return $res;
1113}
1114
1e3baf05
DM
1115# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1116sub parse_net {
1117 my ($data) = @_;
1118
1119 my $res = {};
1120
6b64503e 1121 foreach my $kvp (split(/,/, $data)) {
1e3baf05
DM
1122
1123 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
6b64503e 1124 my $model = lc($1);
9f91ff02 1125 my $mac = uc($3) || PVE::Tools::random_ether_addr();
1e3baf05
DM
1126 $res->{model} = $model;
1127 $res->{macaddr} = $mac;
1128 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1129 $res->{bridge} = $1;
1130 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1131 $res->{rate} = $1;
5070f384
DA
1132 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1133 $res->{tag} = $1;
1e3baf05
DM
1134 } else {
1135 return undef;
1136 }
19672434 1137
1e3baf05
DM
1138 }
1139
1140 return undef if !$res->{model};
1141
1142 return $res;
1143}
1144
1145sub print_net {
1146 my $net = shift;
1147
1148 my $res = "$net->{model}";
1149 $res .= "=$net->{macaddr}" if $net->{macaddr};
1150 $res .= ",bridge=$net->{bridge}" if $net->{bridge};
1151 $res .= ",rate=$net->{rate}" if $net->{rate};
18744ba3 1152 $res .= ",tag=$net->{tag}" if $net->{tag};
1e3baf05
DM
1153
1154 return $res;
1155}
1156
1157sub add_random_macs {
1158 my ($settings) = @_;
1159
1160 foreach my $opt (keys %$settings) {
1161 next if $opt !~ m/^net(\d+)$/;
1162 my $net = parse_net($settings->{$opt});
1163 next if !$net;
1164 $settings->{$opt} = print_net($net);
1165 }
1166}
1167
1168sub add_unused_volume {
1858638f 1169 my ($config, $volid) = @_;
1e3baf05
DM
1170
1171 my $key;
1172 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1173 my $test = "unused$ind";
1174 if (my $vid = $config->{$test}) {
1175 return if $vid eq $volid; # do not add duplicates
1176 } else {
1177 $key = $test;
19672434 1178 }
1e3baf05
DM
1179 }
1180
1181 die "To many unused volume - please delete them first.\n" if !$key;
97d62eb7 1182
1858638f 1183 $config->{$key} = $volid;
1e3baf05 1184
1858638f 1185 return $key;
1e3baf05
DM
1186}
1187
1188# fixme: remove all thos $noerr parameters?
1189
1190PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1191sub verify_bootdisk {
1192 my ($value, $noerr) = @_;
1193
19672434 1194 return $value if valid_drivename($value);
1e3baf05
DM
1195
1196 return undef if $noerr;
1197
1198 die "invalid boot disk '$value'\n";
1199}
1200
1201PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1202sub verify_net {
1203 my ($value, $noerr) = @_;
1204
1205 return $value if parse_net($value);
1206
1207 return undef if $noerr;
19672434 1208
1e3baf05
DM
1209 die "unable to parse network options\n";
1210}
1211
1212PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1213sub verify_drive {
1214 my ($value, $noerr) = @_;
1215
6b64503e 1216 return $value if parse_drive(undef, $value);
1e3baf05
DM
1217
1218 return undef if $noerr;
19672434 1219
1e3baf05
DM
1220 die "unable to parse drive options\n";
1221}
1222
1223PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1224sub verify_hostpci {
1225 my ($value, $noerr) = @_;
1226
040b06b7
DA
1227 return $value if parse_hostpci($value);
1228
1229 return undef if $noerr;
1230
1231 die "unable to parse pci id\n";
1e3baf05
DM
1232}
1233
0ea9541d
DM
1234PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1235sub verify_watchdog {
1236 my ($value, $noerr) = @_;
1237
1238 return $value if parse_watchdog($value);
1239
1240 return undef if $noerr;
19672434 1241
0ea9541d
DM
1242 die "unable to parse watchdog options\n";
1243}
1244
1245sub parse_watchdog {
1246 my ($value) = @_;
1247
1248 return undef if !$value;
1249
1250 my $res = {};
1251
6b64503e 1252 foreach my $p (split(/,/, $value)) {
0ea9541d
DM
1253 next if $p =~ m/^\s*$/;
1254
1255 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1256 $res->{model} = $2;
1257 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1258 $res->{action} = $2;
1259 } else {
1260 return undef;
1261 }
1262 }
1263
1264 return $res;
1265}
1266
59411c4e
DM
1267PVE::JSONSchema::register_format('pve-qm-startup', \&verify_startup);
1268sub verify_startup {
1269 my ($value, $noerr) = @_;
1270
1271 return $value if parse_startup($value);
1272
1273 return undef if $noerr;
1274
1275 die "unable to parse startup options\n";
1276}
1277
1278sub parse_startup {
1279 my ($value) = @_;
1280
1281 return undef if !$value;
1282
1283 my $res = {};
1284
1285 foreach my $p (split(/,/, $value)) {
1286 next if $p =~ m/^\s*$/;
1287
1288 if ($p =~ m/^(order=)?(\d+)$/) {
1289 $res->{order} = $2;
1290 } elsif ($p =~ m/^up=(\d+)$/) {
1291 $res->{up} = $1;
1292 } elsif ($p =~ m/^down=(\d+)$/) {
1293 $res->{down} = $1;
1294 } else {
1295 return undef;
1296 }
1297 }
1298
1299 return $res;
1300}
1301
1e3baf05
DM
1302sub parse_usb_device {
1303 my ($value) = @_;
1304
1305 return undef if !$value;
1306
6b64503e 1307 my @dl = split(/,/, $value);
1e3baf05
DM
1308 my $found;
1309
1310 my $res = {};
1311 foreach my $v (@dl) {
036e0e2b 1312 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1e3baf05 1313 $found = 1;
036e0e2b
DM
1314 $res->{vendorid} = $2;
1315 $res->{productid} = $4;
1e3baf05
DM
1316 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1317 $found = 1;
1318 $res->{hostbus} = $1;
1319 $res->{hostport} = $2;
1320 } else {
1321 return undef;
1322 }
1323 }
1324 return undef if !$found;
1325
1326 return $res;
1327}
19672434 1328
1e3baf05
DM
1329PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1330sub verify_usb_device {
1331 my ($value, $noerr) = @_;
1332
1333 return $value if parse_usb_device($value);
1334
1335 return undef if $noerr;
19672434 1336
1e3baf05
DM
1337 die "unable to parse usb device\n";
1338}
1339
1e3baf05
DM
1340# add JSON properties for create and set function
1341sub json_config_properties {
1342 my $prop = shift;
1343
1344 foreach my $opt (keys %$confdesc) {
1345 $prop->{$opt} = $confdesc->{$opt};
1346 }
1347
1348 return $prop;
1349}
1350
1351sub check_type {
1352 my ($key, $value) = @_;
1353
1354 die "unknown setting '$key'\n" if !$confdesc->{$key};
1355
1356 my $type = $confdesc->{$key}->{type};
1357
6b64503e 1358 if (!defined($value)) {
1e3baf05
DM
1359 die "got undefined value\n";
1360 }
1361
1362 if ($value =~ m/[\n\r]/) {
1363 die "property contains a line feed\n";
1364 }
1365
1366 if ($type eq 'boolean') {
19672434
DM
1367 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1368 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1369 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1370 } elsif ($type eq 'integer') {
1371 return int($1) if $value =~ m/^(\d+)$/;
1372 die "type check ('integer') failed - got '$value'\n";
1373 } elsif ($type eq 'string') {
1374 if (my $fmt = $confdesc->{$key}->{format}) {
1375 if ($fmt eq 'pve-qm-drive') {
1376 # special case - we need to pass $key to parse_drive()
6b64503e 1377 my $drive = parse_drive($key, $value);
1e3baf05
DM
1378 return $value if $drive;
1379 die "unable to parse drive options\n";
1380 }
1381 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1382 return $value;
1383 }
1e3baf05 1384 $value =~ s/^\"(.*)\"$/$1/;
19672434 1385 return $value;
1e3baf05
DM
1386 } else {
1387 die "internal error"
1388 }
1389}
1390
191435c6
DM
1391sub lock_config_full {
1392 my ($vmid, $timeout, $code, @param) = @_;
1e3baf05 1393
6b64503e 1394 my $filename = config_file_lock($vmid);
1e3baf05 1395
191435c6 1396 my $res = lock_file($filename, $timeout, $code, @param);
1e3baf05
DM
1397
1398 die $@ if $@;
5fdbe4f0
DM
1399
1400 return $res;
1e3baf05
DM
1401}
1402
191435c6
DM
1403sub lock_config {
1404 my ($vmid, $code, @param) = @_;
1405
1406 return lock_config_full($vmid, 10, $code, @param);
1407}
1408
1e3baf05 1409sub cfs_config_path {
a78ccf26 1410 my ($vmid, $node) = @_;
1e3baf05 1411
a78ccf26
DM
1412 $node = $nodename if !$node;
1413 return "nodes/$node/qemu-server/$vmid.conf";
1e3baf05
DM
1414}
1415
040b06b7
DA
1416sub check_iommu_support{
1417 #fixme : need to check IOMMU support
1418 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1419
1420 my $iommu=1;
1421 return $iommu;
1422
1423}
1424
1e3baf05 1425sub config_file {
a78ccf26 1426 my ($vmid, $node) = @_;
1e3baf05 1427
a78ccf26 1428 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1429 return "/etc/pve/$cfspath";
1430}
1431
1432sub config_file_lock {
1433 my ($vmid) = @_;
1434
1435 return "$lock_dir/lock-$vmid.conf";
1436}
1437
1438sub touch_config {
1439 my ($vmid) = @_;
1440
6b64503e 1441 my $conf = config_file($vmid);
1e3baf05
DM
1442 utime undef, undef, $conf;
1443}
1444
1e3baf05 1445sub destroy_vm {
a6af7b3e 1446 my ($storecfg, $vmid, $keep_empty_config) = @_;
1e3baf05 1447
6b64503e 1448 my $conffile = config_file($vmid);
1e3baf05 1449
6b64503e 1450 my $conf = load_config($vmid);
1e3baf05 1451
6b64503e 1452 check_lock($conf);
1e3baf05 1453
19672434 1454 # only remove disks owned by this VM
1e3baf05
DM
1455 foreach_drive($conf, sub {
1456 my ($ds, $drive) = @_;
1457
6b64503e 1458 return if drive_is_cdrom($drive);
1e3baf05
DM
1459
1460 my $volid = $drive->{file};
ff1a2432 1461 return if !$volid || $volid =~ m|^/|;
1e3baf05 1462
6b64503e 1463 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
ff1a2432 1464 return if !$path || !$owner || ($owner != $vmid);
1e3baf05 1465
6b64503e 1466 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1467 });
19672434 1468
a6af7b3e 1469 if ($keep_empty_config) {
9c502e26 1470 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
a6af7b3e
DM
1471 } else {
1472 unlink $conffile;
1473 }
1e3baf05
DM
1474
1475 # also remove unused disk
1476 eval {
6b64503e 1477 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
1478
1479 eval {
6b64503e 1480 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 1481 my ($volid, $sid, $volname, $d) = @_;
6b64503e 1482 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
1483 });
1484 };
1485 warn $@ if $@;
1486
1487 };
1488 warn $@ if $@;
1489}
1490
1491# fixme: remove?
1492sub load_diskinfo_old {
1493 my ($storecfg, $vmid, $conf) = @_;
1494
1495 my $info = {};
1496 my $res = {};
1497 my $vollist;
1498
1499 foreach_drive($conf, sub {
1500 my ($ds, $di) = @_;
1501
1502 $res->{$ds} = $di;
1503
6b64503e 1504 return if drive_is_cdrom($di);
1e3baf05
DM
1505
1506 if ($di->{file} =~ m|^/dev/.+|) {
6b64503e 1507 $info->{$di->{file}}->{size} = PVE::Storage::file_size_info($di->{file});
1e3baf05
DM
1508 } else {
1509 push @$vollist, $di->{file};
1510 }
1511 });
1512
1513 eval {
6b64503e 1514 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid, $vollist);
1e3baf05 1515
6b64503e 1516 PVE::Storage::foreach_volid($dl, sub {
1e3baf05
DM
1517 my ($volid, $sid, $volname, $d) = @_;
1518 $info->{$volid} = $d;
1519 });
1520 };
1521 warn $@ if $@;
1522
1523 foreach my $ds (keys %$res) {
1524 my $di = $res->{$ds};
1525
19672434 1526 $res->{$ds}->{disksize} = $info->{$di->{file}} ?
1e3baf05
DM
1527 $info->{$di->{file}}->{size} / (1024*1024) : 0;
1528 }
1529
1530 return $res;
1531}
1532
1533sub load_config {
1534 my ($vmid) = @_;
1535
1536 my $cfspath = cfs_config_path($vmid);
1537
1538 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1539
1540 die "no such VM ('$vmid')\n" if !defined($conf);
1541
1542 return $conf;
19672434 1543}
1e3baf05
DM
1544
1545sub parse_vm_config {
1546 my ($filename, $raw) = @_;
1547
1548 return undef if !defined($raw);
1549
554ac7e7 1550 my $res = {
fc1ddcdc 1551 digest => Digest::SHA::sha1_hex($raw),
554ac7e7 1552 };
1e3baf05 1553
19672434 1554 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1555 || die "got strange filename '$filename'";
1556
1557 my $vmid = $1;
1558
0581fe4f
DM
1559 my $descr = '';
1560
1e3baf05
DM
1561 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1562 my $line = $1;
19672434 1563
1e3baf05
DM
1564 next if $line =~ m/^\s*$/;
1565
0581fe4f
DM
1566 if ($line =~ m/^\#(.*)\s*$/) {
1567 $descr .= PVE::Tools::decode_text($1) . "\n";
1568 next;
1569 }
1570
1e3baf05 1571 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
0581fe4f 1572 $descr .= PVE::Tools::decode_text($2);
1e3baf05
DM
1573 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1574 my $key = $1;
1575 my $value = $2;
1576 $res->{$key} = $value;
1577 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1578 my $key = $1;
1579 my $value = $2;
1580 eval { $value = check_type($key, $value); };
1581 if ($@) {
1582 warn "vm $vmid - unable to parse value of '$key' - $@";
1583 } else {
1584 my $fmt = $confdesc->{$key}->{format};
1585 if ($fmt && $fmt eq 'pve-qm-drive') {
1586 my $v = parse_drive($key, $value);
1587 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1588 $v->{file} = $volid;
6b64503e 1589 $value = print_drive($vmid, $v);
1e3baf05
DM
1590 } else {
1591 warn "vm $vmid - unable to parse value of '$key'\n";
1592 next;
1593 }
1594 }
1595
1596 if ($key eq 'cdrom') {
1597 $res->{ide2} = $value;
1598 } else {
1599 $res->{$key} = $value;
1600 }
1601 }
1602 }
1603 }
1604
0581fe4f
DM
1605 $res->{description} = $descr if $descr;
1606
1e3baf05
DM
1607 # convert old smp to sockets
1608 if ($res->{smp} && !$res->{sockets}) {
1609 $res->{sockets} = $res->{smp};
19672434 1610 }
1e3baf05
DM
1611 delete $res->{smp};
1612
1613 return $res;
1614}
1615
1858638f
DM
1616sub write_vm_config {
1617 my ($filename, $conf) = @_;
1e3baf05 1618
1858638f
DM
1619 if ($conf->{cdrom}) {
1620 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
1621 $conf->{ide2} = $conf->{cdrom};
1622 delete $conf->{cdrom};
1623 }
1e3baf05
DM
1624
1625 # we do not use 'smp' any longer
1858638f
DM
1626 if ($conf->{sockets}) {
1627 delete $conf->{smp};
1628 } elsif ($conf->{smp}) {
1629 $conf->{sockets} = $conf->{smp};
1630 delete $conf->{cores};
1631 delete $conf->{smp};
1e3baf05
DM
1632 }
1633
1634 my $new_volids = {};
1858638f 1635 foreach my $key (keys %$conf) {
0581fe4f 1636 next if $key eq 'digest' || $key eq 'description';
1858638f 1637 my $value = $conf->{$key};
1e3baf05
DM
1638 eval { $value = check_type($key, $value); };
1639 die "unable to parse value of '$key' - $@" if $@;
1858638f
DM
1640
1641 $conf->{$key} = $value;
1642
1e3baf05
DM
1643 if (valid_drivename($key)) {
1644 my $drive = PVE::QemuServer::parse_drive($key, $value);
1645 $new_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
1646 }
1647 }
1648
1858638f
DM
1649 # remove 'unusedX' settings if we re-add a volume
1650 foreach my $key (keys %$conf) {
1651 my $value = $conf->{$key};
1652 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1653 delete $conf->{$key};
1e3baf05 1654 }
1858638f 1655 }
1e3baf05 1656
1858638f
DM
1657 # gererate RAW data
1658 my $raw = '';
0581fe4f
DM
1659
1660 # add description as comment to top of file
1661 my $descr = $conf->{description} || '';
1662 foreach my $cl (split(/\n/, $descr)) {
1663 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
1664 }
1665
1858638f 1666 foreach my $key (sort keys %$conf) {
0581fe4f 1667 next if $key eq 'digest' || $key eq 'description';
1858638f
DM
1668 $raw .= "$key: $conf->{$key}\n";
1669 }
1e3baf05 1670
1858638f
DM
1671 return $raw;
1672}
1e3baf05 1673
1858638f
DM
1674sub update_config_nolock {
1675 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1676
1858638f 1677 check_lock($conf) if !$skiplock;
97d62eb7 1678
1858638f 1679 my $cfspath = cfs_config_path($vmid);
1e3baf05 1680
1858638f
DM
1681 PVE::Cluster::cfs_write_file($cfspath, $conf);
1682}
1e3baf05 1683
1858638f
DM
1684sub update_config {
1685 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1686
1858638f 1687 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1e3baf05
DM
1688}
1689
19672434 1690sub load_defaults {
1e3baf05
DM
1691
1692 my $res = {};
1693
1694 # we use static defaults from our JSON schema configuration
1695 foreach my $key (keys %$confdesc) {
1696 if (defined(my $default = $confdesc->{$key}->{default})) {
1697 $res->{$key} = $default;
1698 }
1699 }
19672434 1700
1e3baf05
DM
1701 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
1702 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
1703
1704 return $res;
1705}
1706
1707sub config_list {
1708 my $vmlist = PVE::Cluster::get_vmlist();
1709 my $res = {};
1710 return $res if !$vmlist || !$vmlist->{ids};
1711 my $ids = $vmlist->{ids};
1712
1e3baf05
DM
1713 foreach my $vmid (keys %$ids) {
1714 my $d = $ids->{$vmid};
1715 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 1716 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
1717 $res->{$vmid}->{exists} = 1;
1718 }
1719 return $res;
1720}
1721
64e13401
DM
1722# test if VM uses local resources (to prevent migration)
1723sub check_local_resources {
1724 my ($conf, $noerr) = @_;
1725
1726 my $loc_res = 0;
19672434 1727
e0ab7331
DM
1728 $loc_res = 1 if $conf->{hostusb}; # old syntax
1729 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 1730
0d29ab3b 1731 foreach my $k (keys %$conf) {
2fe1a152 1732 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
1733 }
1734
1735 die "VM uses local resources\n" if $loc_res && !$noerr;
1736
1737 return $loc_res;
1738}
1739
47152e2e
DM
1740# check is used storages are available on all nodes (use by migrate)
1741sub check_storage_availability {
1742 my ($storecfg, $conf, $node) = @_;
1743
1744 foreach_drive($conf, sub {
1745 my ($ds, $drive) = @_;
1746
1747 my $volid = $drive->{file};
1748 return if !$volid;
1749
1750 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
1751 return if !$sid;
1752
1753 # check if storage is available on both nodes
1754 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
1755 PVE::Storage::storage_check_node($storecfg, $sid, $node);
1756 });
1757}
1758
1e3baf05
DM
1759sub check_lock {
1760 my ($conf) = @_;
1761
1762 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1763}
1764
1765sub check_cmdline {
1766 my ($pidfile, $pid) = @_;
1767
6b64503e
DM
1768 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
1769 if (defined($fh)) {
1e3baf05
DM
1770 my $line = <$fh>;
1771 $fh->close;
1772 return undef if !$line;
6b64503e 1773 my @param = split(/\0/, $line);
1e3baf05
DM
1774
1775 my $cmd = $param[0];
1776 return if !$cmd || ($cmd !~ m|kvm$|);
1777
1778 for (my $i = 0; $i < scalar (@param); $i++) {
1779 my $p = $param[$i];
1780 next if !$p;
1781 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1782 my $p = $param[$i+1];
1783 return 1 if $p && ($p eq $pidfile);
1784 return undef;
1785 }
1786 }
1787 }
1788 return undef;
1789}
1790
1791sub check_running {
e6c3b671 1792 my ($vmid, $nocheck) = @_;
1e3baf05 1793
e6c3b671 1794 my $filename = config_file($vmid);
1e3baf05
DM
1795
1796 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 1797 if !$nocheck && ! -f $filename;
1e3baf05 1798
e6c3b671 1799 my $pidfile = pidfile_name($vmid);
1e3baf05 1800
e6c3b671
DM
1801 if (my $fd = IO::File->new("<$pidfile")) {
1802 my $st = stat($fd);
1e3baf05 1803 my $line = <$fd>;
6b64503e 1804 close($fd);
1e3baf05
DM
1805
1806 my $mtime = $st->mtime;
1807 if ($mtime > time()) {
1808 warn "file '$filename' modified in future\n";
1809 }
1810
1811 if ($line =~ m/^(\d+)$/) {
1812 my $pid = $1;
e6c3b671
DM
1813 if (check_cmdline($pidfile, $pid)) {
1814 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
1815 return $pid;
1816 }
1817 }
1e3baf05
DM
1818 }
1819 }
1820
1821 return undef;
1822}
1823
1824sub vzlist {
19672434 1825
1e3baf05
DM
1826 my $vzlist = config_list();
1827
6b64503e 1828 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 1829
19672434 1830 while (defined(my $de = $fd->read)) {
1e3baf05
DM
1831 next if $de !~ m/^(\d+)\.pid$/;
1832 my $vmid = $1;
6b64503e
DM
1833 next if !defined($vzlist->{$vmid});
1834 if (my $pid = check_running($vmid)) {
1e3baf05
DM
1835 $vzlist->{$vmid}->{pid} = $pid;
1836 }
1837 }
1838
1839 return $vzlist;
1840}
1841
1842my $storage_timeout_hash = {};
1843
1844sub disksize {
1845 my ($storecfg, $conf) = @_;
1846
1847 my $bootdisk = $conf->{bootdisk};
1848 return undef if !$bootdisk;
1849 return undef if !valid_drivename($bootdisk);
1850
1851 return undef if !$conf->{$bootdisk};
1852
1853 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
1854 return undef if !defined($drive);
1855
1856 return undef if drive_is_cdrom($drive);
1857
1858 my $volid = $drive->{file};
1859 return undef if !$volid;
1860
1861 my $path;
1862 my $storeid;
1863 my $timeoutid;
1864
1865 if ($volid =~ m|^/|) {
1866 $path = $timeoutid = $volid;
1867 } else {
f0cab979
DM
1868 eval {
1869 $storeid = $timeoutid = PVE::Storage::parse_volume_id($volid);
1870 $path = PVE::Storage::path($storecfg, $volid);
1871 };
1872 if (my $err = $@) {
1873 warn $err;
1874 return undef;
1875 }
1e3baf05
DM
1876 }
1877
1878 my $last_timeout = $storage_timeout_hash->{$timeoutid};
1879 if ($last_timeout) {
1880 if ((time() - $last_timeout) < 30) {
1881 # skip storage with errors
1882 return undef ;
1883 }
1884 delete $storage_timeout_hash->{$timeoutid};
1885 }
1886
1887 my ($size, $format, $used);
1888
1889 ($size, $format, $used) = PVE::Storage::file_size_info($path, 1);
1890
1891 if (!defined($format)) {
1892 # got timeout
1893 $storage_timeout_hash->{$timeoutid} = time();
1894 return undef;
1895 }
1896
1897 return wantarray ? ($size, $used) : $size;
1898}
1899
1900my $last_proc_pid_stat;
1901
1902sub vmstatus {
1903 my ($opt_vmid) = @_;
1904
1905 my $res = {};
1906
19672434 1907 my $storecfg = PVE::Storage::config();
1e3baf05
DM
1908
1909 my $list = vzlist();
694fcad4 1910 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 1911
ae4915a2
DM
1912 my $cpucount = $cpuinfo->{cpus} || 1;
1913
1e3baf05
DM
1914 foreach my $vmid (keys %$list) {
1915 next if $opt_vmid && ($vmid ne $opt_vmid);
1916
1917 my $cfspath = cfs_config_path($vmid);
1918 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
1919
1920 my $d = {};
1921 $d->{pid} = $list->{$vmid}->{pid};
1922
1923 # fixme: better status?
1924 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
1925
1926 my ($size, $used) = disksize($storecfg, $conf);
1927 if (defined($size) && defined($used)) {
1928 $d->{disk} = $used;
1929 $d->{maxdisk} = $size;
1930 } else {
1931 $d->{disk} = 0;
1932 $d->{maxdisk} = 0;
1933 }
1934
1935 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2
DM
1936 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
1937
1e3baf05 1938 $d->{name} = $conf->{name} || "VM $vmid";
19672434 1939 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 1940
1e3baf05
DM
1941 $d->{uptime} = 0;
1942 $d->{cpu} = 0;
1e3baf05
DM
1943 $d->{mem} = 0;
1944
1945 $d->{netout} = 0;
1946 $d->{netin} = 0;
1947
1948 $d->{diskread} = 0;
1949 $d->{diskwrite} = 0;
1950
1951 $res->{$vmid} = $d;
1952 }
1953
1954 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
1955 foreach my $dev (keys %$netdev) {
1956 next if $dev !~ m/^tap([1-9]\d*)i/;
1957 my $vmid = $1;
1958 my $d = $res->{$vmid};
1959 next if !$d;
19672434 1960
1e3baf05
DM
1961 $d->{netout} += $netdev->{$dev}->{receive};
1962 $d->{netin} += $netdev->{$dev}->{transmit};
1963 }
1964
1e3baf05
DM
1965 my $ctime = gettimeofday;
1966
1967 foreach my $vmid (keys %$list) {
1968
1969 my $d = $res->{$vmid};
1970 my $pid = $d->{pid};
1971 next if !$pid;
1972
1973 if (my $fh = IO::File->new("/proc/$pid/io", "r")) {
1974 my $data = {};
6b64503e 1975 while (defined(my $line = <$fh>)) {
1e3baf05
DM
1976 if ($line =~ m/^([rw]char):\s+(\d+)$/) {
1977 $data->{$1} = $2;
1978 }
1979 }
1980 close($fh);
1981 $d->{diskread} = $data->{rchar} || 0;
1982 $d->{diskwrite} = $data->{wchar} || 0;
1983 }
1984
694fcad4
DM
1985 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
1986 next if !$pstat; # not running
19672434 1987
694fcad4 1988 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 1989
694fcad4 1990 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 1991
694fcad4 1992 if ($pstat->{vsize}) {
6b64503e 1993 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
1994 }
1995
1996 my $old = $last_proc_pid_stat->{$pid};
1997 if (!$old) {
19672434
DM
1998 $last_proc_pid_stat->{$pid} = {
1999 time => $ctime,
1e3baf05
DM
2000 used => $used,
2001 cpu => 0,
1e3baf05
DM
2002 };
2003 next;
2004 }
2005
7f0b5beb 2006 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
2007
2008 if ($dtime > 1000) {
2009 my $dutime = $used - $old->{used};
2010
ae4915a2 2011 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 2012 $last_proc_pid_stat->{$pid} = {
19672434 2013 time => $ctime,
1e3baf05
DM
2014 used => $used,
2015 cpu => $d->{cpu},
1e3baf05
DM
2016 };
2017 } else {
2018 $d->{cpu} = $old->{cpu};
1e3baf05
DM
2019 }
2020 }
2021
2022 return $res;
2023}
2024
2025sub foreach_drive {
2026 my ($conf, $func) = @_;
2027
2028 foreach my $ds (keys %$conf) {
2029 next if !valid_drivename($ds);
2030
6b64503e 2031 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2032 next if !$drive;
2033
2034 &$func($ds, $drive);
2035 }
2036}
2037
2038sub config_to_command {
2039 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2040
2041 my $cmd = [];
b78ebef7 2042 my $pciaddr = '';
1e3baf05
DM
2043 my $kvmver = kvm_user_version();
2044 my $vernum = 0; # unknown
a3c52213
DM
2045 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2046 $vernum = $1*1000000+$2*1000;
2047 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2048 $vernum = $1*1000000+$2*1000+$3;
2049 }
2050
a3c52213 2051 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2052
2053 my $have_ovz = -f '/proc/vz/vestat';
2054
2055 push @$cmd, '/usr/bin/kvm';
2056
2057 push @$cmd, '-id', $vmid;
2058
2059 my $use_virtio = 0;
2060
6b64503e 2061 my $socket = monitor_socket($vmid);
abb39b66
DA
2062 push @$cmd, '-chardev', "socket,id=monitor,path=$socket,server,nowait";
2063 push @$cmd, '-mon', "chardev=monitor,mode=readline";
1e3baf05 2064
c971c4f2
AD
2065 my $qmpsocket = qmp_socket($vmid);
2066 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2067 push @$cmd, '-mon', "chardev=qmp,mode=control";
2068
6b64503e 2069 $socket = vnc_socket($vmid);
1e3baf05
DM
2070 push @$cmd, '-vnc', "unix:$socket,x509,password";
2071
6b64503e 2072 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2073
1e3baf05
DM
2074 push @$cmd, '-daemonize';
2075
2076 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2077
1c060867
DM
2078 my $use_usb2 = 0;
2079 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2080 next if !$conf->{"usb$i"};
2081 $use_usb2 = 1;
2082 }
1e3baf05 2083 # include usb device config
1c060867 2084 push @$cmd, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
19672434 2085
1e3baf05 2086 # enable absolute mouse coordinates (needed by vnc)
6b64503e 2087 my $tablet = defined($conf->{tablet}) ? $conf->{tablet} : $defaults->{tablet};
1c060867
DM
2088 if ($tablet) {
2089 if ($use_usb2) {
2090 push @$cmd, '-device', 'usb-tablet,bus=ehci.0,port=6';
2091 } else {
2092 push @$cmd, '-usbdevice', 'tablet';
2093 }
2094 }
1e3baf05
DM
2095
2096 # host pci devices
040b06b7
DA
2097 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2098 my $d = parse_hostpci($conf->{"hostpci$i"});
2099 next if !$d;
b78ebef7
DA
2100 $pciaddr = print_pci_addr("hostpci$i");
2101 push @$cmd, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
1e3baf05
DM
2102 }
2103
2104 # usb devices
2105 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2106 my $d = parse_usb_device($conf->{"usb$i"});
2107 next if !$d;
2108 if ($d->{vendorid} && $d->{productid}) {
036e0e2b 2109 push @$cmd, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05
DM
2110 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
2111 push @$cmd, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2112 }
2113 }
2114
1e3baf05 2115 # serial devices
bae179aa 2116 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2117 if (my $path = $conf->{"serial$i"}) {
19672434 2118 die "no such serial device\n" if ! -c $path;
34978be3
DM
2119 push @$cmd, '-chardev', "tty,id=serial$i,path=$path";
2120 push @$cmd, '-device', "isa-serial,chardev=serial$i";
2121 }
1e3baf05
DM
2122 }
2123
2124 # parallel devices
1989a89c 2125 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2126 if (my $path = $conf->{"parallel$i"}) {
19672434 2127 die "no such parallel device\n" if ! -c $path;
34978be3
DM
2128 push @$cmd, '-chardev', "parport,id=parallel$i,path=$path";
2129 push @$cmd, '-device', "isa-parallel,chardev=parallel$i";
2130 }
1e3baf05
DM
2131 }
2132
2133 my $vmname = $conf->{name} || "vm$vmid";
2134
2135 push @$cmd, '-name', $vmname;
19672434 2136
1e3baf05
DM
2137 my $sockets = 1;
2138 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2139 $sockets = $conf->{sockets} if $conf->{sockets};
2140
2141 my $cores = $conf->{cores} || 1;
2142
1e3baf05
DM
2143 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2144
2145 push @$cmd, '-cpu', $conf->{cpu} if $conf->{cpu};
2146
1e3baf05
DM
2147 push @$cmd, '-nodefaults';
2148
32baffb4 2149 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2150
0888fdce
DM
2151 my $bootindex_hash = {};
2152 my $i = 1;
2153 foreach my $o (split(//, $bootorder)) {
2154 $bootindex_hash->{$o} = $i*100;
2155 $i++;
afdb31d5 2156 }
3b408e82
DM
2157
2158 push @$cmd, '-boot', "menu=on";
1e3baf05 2159
6b64503e 2160 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2161
6b64503e 2162 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05
DM
2163
2164 my $vga = $conf->{vga};
2165 if (!$vga) {
2166 if ($conf->{ostype} && ($conf->{ostype} eq 'win7' || $conf->{ostype} eq 'w2k8')) {
2167 $vga = 'std';
2168 } else {
2169 $vga = 'cirrus';
2170 }
2171 }
19672434 2172
1e3baf05
DM
2173 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2174
2175 # time drift fix
6b64503e 2176 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
da21653b
DM
2177 # ignore - no longer supported by newer kvm
2178 # push @$cmd, '-tdf' if $tdf;
1e3baf05 2179
6b64503e 2180 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
1e3baf05
DM
2181
2182 if (my $ost = $conf->{ostype}) {
2183 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2184
2185 if ($ost =~ m/^w/) { # windows
6b64503e 2186 push @$cmd, '-localtime' if !defined($conf->{localtime});
1e3baf05
DM
2187
2188 # use rtc-td-hack when acpi is enabled
6b64503e 2189 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
1e3baf05
DM
2190 push @$cmd, '-rtc-td-hack';
2191 }
2192 }
2193
b7e0c8bf
DM
2194 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2195 push @$cmd, '-no-kvm-pit-reinjection';
2196 push @$cmd, '-no-hpet';
2197 }
2198
1e3baf05 2199 # -tdf ?
19672434
DM
2200 # -no-acpi
2201 # -no-kvm
1e3baf05
DM
2202 # -win2k-hack ?
2203 }
2204
7f0b5beb
DM
2205 if ($nokvm) {
2206 push @$cmd, '-no-kvm';
2207 } else {
2208 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2209 }
1e3baf05
DM
2210
2211 push @$cmd, '-localtime' if $conf->{localtime};
2212
2213 push @$cmd, '-startdate', $conf->{startdate} if $conf->{startdate};
2214
2215 push @$cmd, '-S' if $conf->{freeze};
2216
2217 # set keyboard layout
2218 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2219 push @$cmd, '-k', $kb if $kb;
2220
2221 # enable sound
2222 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2223 #push @$cmd, '-soundhw', 'es1370';
2224 #push @$cmd, '-soundhw', $soundhw if $soundhw;
b78ebef7 2225 $pciaddr = print_pci_addr("balloon0");
13b5a753 2226 push @$cmd, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon};
1e3baf05 2227
0ea9541d
DM
2228 if ($conf->{watchdog}) {
2229 my $wdopts = parse_watchdog($conf->{watchdog});
0a40e8ea
DA
2230 $pciaddr = print_pci_addr("watchdog");
2231 my $watchdog = $wdopts->{model} || 'i6300esb';
2232 push @$cmd, '-device', "$watchdog$pciaddr";
0ea9541d
DM
2233 push @$cmd, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
2234 }
2235
1e3baf05 2236 my $vollist = [];
941e0c42 2237 my $scsicontroller = {};
26ee04b6 2238 my $ahcicontroller = {};
1e3baf05
DM
2239
2240 foreach_drive($conf, sub {
2241 my ($ds, $drive) = @_;
2242
ff1a2432 2243 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 2244 push @$vollist, $drive->{file};
ff1a2432 2245 }
afdb31d5 2246
1e3baf05 2247 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
2248
2249 if (drive_is_cdrom ($drive)) {
2250 if ($bootindex_hash->{d}) {
2251 $drive->{bootindex} = $bootindex_hash->{d};
2252 $bootindex_hash->{d} += 1;
2253 }
2254 } else {
2255 if ($bootindex_hash->{c}) {
2256 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2257 $bootindex_hash->{c} += 1;
2258 }
2259 }
2260
941e0c42
DA
2261 if ($drive->{interface} eq 'scsi') {
2262 my $maxdev = 7;
6b64503e 2263 my $controller = int($drive->{index} / $maxdev);
69b6ae0c
DA
2264 $pciaddr = print_pci_addr("lsi$controller");
2265 push @$cmd, '-device', "lsi,id=lsi$controller$pciaddr" if !$scsicontroller->{$controller};
58dc808d 2266 $scsicontroller->{$controller}=1;
941e0c42 2267 }
3b408e82 2268
26ee04b6
DA
2269 if ($drive->{interface} eq 'sata') {
2270 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2271 $pciaddr = print_pci_addr("ahci$controller");
2272 push @$cmd, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2273 $ahcicontroller->{$controller}=1;
2274 }
2275
2276 push @$cmd, '-drive',print_drive_full($storecfg, $vmid, $drive);
6b64503e 2277 push @$cmd, '-device',print_drivedevice_full($storecfg,$vmid, $drive);
1e3baf05
DM
2278 });
2279
2280 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2281
cc4d6182 2282 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 2283 next if !$conf->{"net$i"};
cc4d6182
DA
2284 my $d = parse_net($conf->{"net$i"});
2285 next if !$d;
1e3baf05 2286
cc4d6182 2287 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 2288
cc4d6182
DA
2289 if ($bootindex_hash->{n}) {
2290 $d->{bootindex} = $bootindex_hash->{n};
2291 $bootindex_hash->{n} += 1;
2292 }
1e3baf05 2293
cc4d6182
DA
2294 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
2295 push @$cmd, '-netdev', $netdevfull;
1e3baf05 2296
cc4d6182
DA
2297 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i");
2298 push @$cmd, '-device', $netdevicefull;
19672434
DM
2299 }
2300
1e3baf05
DM
2301
2302 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2303 # when the VM uses virtio devices.
19672434
DM
2304 if (!$use_virtio && $have_ovz) {
2305
6b64503e 2306 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2307 $conf->{cpuunits} : $defaults->{cpuunits};
2308
2309 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2310
2311 # fixme: cpulimit is currently ignored
2312 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2313 }
2314
2315 # add custom args
2316 if ($conf->{args}) {
3ada46c9 2317 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
2318 push @$cmd, @$aa;
2319 }
2320
2321 return wantarray ? ($cmd, $vollist) : $cmd;
2322}
19672434 2323
1e3baf05
DM
2324sub vnc_socket {
2325 my ($vmid) = @_;
2326 return "${var_run_tmpdir}/$vmid.vnc";
2327}
2328
2329sub monitor_socket {
2330 my ($vmid) = @_;
2331 return "${var_run_tmpdir}/$vmid.mon";
2332}
2333
c971c4f2
AD
2334sub qmp_socket {
2335 my ($vmid) = @_;
2336 return "${var_run_tmpdir}/$vmid.qmp";
2337}
2338
1e3baf05
DM
2339sub pidfile_name {
2340 my ($vmid) = @_;
2341 return "${var_run_tmpdir}/$vmid.pid";
2342}
2343
1e3baf05
DM
2344sub next_migrate_port {
2345
2346 for (my $p = 60000; $p < 60010; $p++) {
2347
6b64503e
DM
2348 my $sock = IO::Socket::INET->new(Listen => 5,
2349 LocalAddr => 'localhost',
2350 LocalPort => $p,
2351 ReuseAddr => 1,
2352 Proto => 0);
1e3baf05
DM
2353
2354 if ($sock) {
6b64503e 2355 close($sock);
1e3baf05
DM
2356 return $p;
2357 }
2358 }
2359
2360 die "unable to find free migration port";
2361}
2362
86fdcfb2
DA
2363sub vm_devices_list {
2364 my ($vmid) = @_;
2365
ff1a2432 2366 my $res = vm_monitor_command ($vmid, "info pci");
1dc4f496
DM
2367
2368 my @lines = split ("\n", $res);
2369 my $devices;
2370 my $bus;
2371 my $addr;
2372 my $id;
afdb31d5 2373
1dc4f496
DM
2374 foreach my $line (@lines) {
2375 $line =~ s/^\s+//;
2376 if ($line =~ m/^Bus (\d+), device (\d+), function (\d+):$/) {
2377 $bus=$1;
2378 $addr=$2;
2379 }
2380 if ($line =~ m/^id "([a-z][a-z_\-]*\d*)"$/) {
86fdcfb2
DA
2381 $id=$1;
2382 $devices->{$id}->{bus}=$bus;
2383 $devices->{$id}->{addr}=$addr;
1dc4f496
DM
2384 }
2385 }
86fdcfb2 2386
1dc4f496 2387 return $devices;
86fdcfb2
DA
2388}
2389
ec21aa11 2390sub vm_deviceplug {
f19d1c47 2391 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 2392
2630d2a9 2393 return 1 if !check_running($vmid) || !$conf->{hotplug};
afdb31d5 2394
95d6343b
DA
2395 my $devices_list = vm_devices_list($vmid);
2396 return 1 if defined($devices_list->{$deviceid});
2397
5e5dcb73
DA
2398 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2399 return undef if !qemu_driveadd($storecfg, $vmid, $device);
1dc4f496 2400 my $devicefull = print_drivedevice_full($storecfg, $vmid, $device);
5e5dcb73
DA
2401 qemu_deviceadd($vmid, $devicefull);
2402 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2403 qemu_drivedel($vmid, $deviceid);
2404 return undef;
2405 }
f19d1c47 2406 }
cfc817c7
DA
2407
2408 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2409 my $pciaddr = print_pci_addr($deviceid);
2410 my $devicefull = "lsi,id=$deviceid$pciaddr";
2411 qemu_deviceadd($vmid, $devicefull);
2412 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2413 }
2414
a4f091a0
DA
2415 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2416 return undef if !qemu_findorcreatelsi($storecfg,$conf, $vmid, $device);
2417 return undef if !qemu_driveadd($storecfg, $vmid, $device);
2418 my $devicefull = print_drivedevice_full($storecfg, $vmid, $device);
2419 if(!qemu_deviceadd($vmid, $devicefull)) {
2420 qemu_drivedel($vmid, $deviceid);
2421 return undef;
2422 }
2423 }
2424
2630d2a9
DA
2425 if ($deviceid =~ m/^(net)(\d+)$/) {
2426 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2427 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2428 qemu_deviceadd($vmid, $netdevicefull);
2429 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2430 qemu_netdevdel($vmid, $deviceid);
2431 return undef;
2432 }
2433 }
2434
5e5dcb73 2435 return 1;
a4dea331
DA
2436}
2437
ec21aa11 2438sub vm_deviceunplug {
f19d1c47 2439 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2440
5e5dcb73 2441 return 1 if !check_running ($vmid) || !$conf->{hotplug};
873c2d69 2442
95d6343b
DA
2443 my $devices_list = vm_devices_list($vmid);
2444 return 1 if !defined($devices_list->{$deviceid});
2445
ae57f6b3 2446 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
f19d1c47 2447
5e5dcb73
DA
2448 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2449 return undef if !qemu_drivedel($vmid, $deviceid);
2450 qemu_devicedel($vmid, $deviceid);
2451 return undef if !qemu_devicedelverify($vmid, $deviceid);
2452 }
cfc817c7
DA
2453
2454 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2455 return undef if !qemu_devicedel($vmid, $deviceid);
2456 }
2457
a4f091a0
DA
2458 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2459 return undef if !qemu_devicedel($vmid, $deviceid);
2460 return undef if !qemu_drivedel($vmid, $deviceid);
2461 }
2462
2630d2a9
DA
2463 if ($deviceid =~ m/^(net)(\d+)$/) {
2464 return undef if !qemu_netdevdel($vmid, $deviceid);
2465 qemu_devicedel($vmid, $deviceid);
2466 return undef if !qemu_devicedelverify($vmid, $deviceid);
2467 }
2468
5e5dcb73
DA
2469 return 1;
2470}
2471
2472sub qemu_deviceadd {
2473 my ($vmid, $devicefull) = @_;
873c2d69 2474
5e5dcb73
DA
2475 my $ret = vm_monitor_command($vmid, "device_add $devicefull");
2476 $ret =~ s/^\s+//;
afdb31d5 2477 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
5e5dcb73
DA
2478 return 1 if $ret eq "";
2479 syslog("err", "error on hotplug device : $ret");
2480 return undef;
f19d1c47 2481
5e5dcb73 2482}
afdb31d5 2483
5e5dcb73
DA
2484sub qemu_devicedel {
2485 my($vmid, $deviceid) = @_;
f19d1c47 2486
5e5dcb73
DA
2487 my $ret = vm_monitor_command($vmid, "device_del $deviceid");
2488 $ret =~ s/^\s+//;
2489 return 1 if $ret eq "";
2490 syslog("err", "detaching device $deviceid failed : $ret");
2491 return undef;
2492}
2493
2494sub qemu_driveadd {
2495 my($storecfg, $vmid, $device) = @_;
2496
2497 my $drive = print_drive_full($storecfg, $vmid, $device);
2498 my $ret = vm_monitor_command($vmid, "drive_add auto $drive");
2499 # If the command succeeds qemu prints: "OK"
2500 if ($ret !~ m/OK/s) {
2501 syslog("err", "adding drive failed: $ret");
2502 return undef;
f19d1c47 2503 }
5e5dcb73
DA
2504 return 1;
2505}
afdb31d5 2506
5e5dcb73
DA
2507sub qemu_drivedel {
2508 my($vmid, $deviceid) = @_;
873c2d69 2509
5e5dcb73
DA
2510 my $ret = vm_monitor_command($vmid, "drive_del drive-$deviceid");
2511 $ret =~ s/^\s+//;
2512 if ($ret =~ m/Device \'.*?\' not found/s) {
afdb31d5 2513 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
5e5dcb73
DA
2514 }
2515 elsif ($ret ne "") {
2516 syslog("err", "deleting drive $deviceid failed : $ret");
2517 return undef;
873c2d69 2518 }
5e5dcb73
DA
2519 return 1;
2520}
f19d1c47 2521
5e5dcb73
DA
2522sub qemu_deviceaddverify {
2523 my ($vmid,$deviceid) = @_;
873c2d69 2524
5e5dcb73
DA
2525 for (my $i = 0; $i <= 5; $i++) {
2526 my $devices_list = vm_devices_list($vmid);
2527 return 1 if defined($devices_list->{$deviceid});
2528 sleep 1;
afdb31d5 2529 }
5e5dcb73
DA
2530 syslog("err", "error on hotplug device $deviceid");
2531 return undef;
2532}
afdb31d5 2533
5e5dcb73
DA
2534
2535sub qemu_devicedelverify {
2536 my ($vmid,$deviceid) = @_;
2537
2538 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2539 for (my $i = 0; $i <= 5; $i++) {
2540 my $devices_list = vm_devices_list($vmid);
2541 return 1 if !defined($devices_list->{$deviceid});
2542 sleep 1;
afdb31d5 2543 }
5e5dcb73
DA
2544 syslog("err", "error on hot-unplugging device $deviceid");
2545 return undef;
873c2d69
DA
2546}
2547
cfc817c7
DA
2548sub qemu_findorcreatelsi {
2549 my ($storecfg, $conf, $vmid, $device) = @_;
2550
2551 my $maxdev = 7;
2552 my $controller = int($device->{index} / $maxdev);
2553 my $lsiid="lsi$controller";
2554 my $devices_list = vm_devices_list($vmid);
2555
2556 if(!defined($devices_list->{$lsiid})) {
2557 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $lsiid);
2558 }
2559 return 1;
2560}
2561
2630d2a9
DA
2562sub qemu_netdevadd {
2563 my ($vmid, $conf, $device, $deviceid) = @_;
2564
2565 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
2566 my $ret = vm_monitor_command($vmid, "netdev_add $netdev");
2567 $ret =~ s/^\s+//;
2568
97d62eb7 2569 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2570 return 1 if $ret eq "";
2571 syslog("err", "adding netdev failed: $ret");
2572 return undef;
2573}
2574
2575sub qemu_netdevdel {
2576 my ($vmid, $deviceid) = @_;
2577
2578 my $ret = vm_monitor_command($vmid, "netdev_del $deviceid");
2579 $ret =~ s/^\s+//;
97d62eb7 2580 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2581 return 1 if $ret eq "";
2582 syslog("err", "deleting netdev failed: $ret");
2583 return undef;
2584}
2585
affd2f88
AD
2586sub qemu_block_set_io_throttle {
2587 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2588
2589 $bps = 0 if !$bps;
2590 $bps_rd = 0 if !$bps_rd;
2591 $bps_wr = 0 if !$bps_wr;
2592 $iops = 0 if !$iops;
2593 $iops_rd = 0 if !$iops_rd;
2594 $iops_wr = 0 if !$iops_wr;
2595
6f1dbbea 2596 my $ret = vm_mon_cmd($vmid, "block_set_io_throttle", device => $deviceid, bps => $bps, bps_rd => $bps_rd, bps_wr => $bps_wr, iops => $iops, iops_rd => $iops_rd, iops_wr => $iops_wr);
affd2f88
AD
2597 $ret =~ s/^\s+//;
2598 return 1 if $ret eq "";
2599 syslog("err", "error setting block_set_io_throttle: $ret");
2600 return undef;
2601}
2602
1e3baf05
DM
2603sub vm_start {
2604 my ($storecfg, $vmid, $statefile, $skiplock) = @_;
2605
6b64503e
DM
2606 lock_config($vmid, sub {
2607 my $conf = load_config($vmid);
1e3baf05 2608
6b64503e 2609 check_lock($conf) if !$skiplock;
1e3baf05 2610
ff1a2432 2611 die "VM $vmid already running\n" if check_running($vmid);
1e3baf05
DM
2612
2613 my $migrate_uri;
2614 my $migrate_port = 0;
2615
2616 if ($statefile) {
2617 if ($statefile eq 'tcp') {
2618 $migrate_port = next_migrate_port();
2619 $migrate_uri = "tcp:localhost:${migrate_port}";
2620 } else {
2621 if (-f $statefile) {
2622 $migrate_uri = "exec:cat $statefile";
2623 } else {
2624 warn "state file '$statefile' does not exist - doing normal startup\n";
2625 }
2626 }
2627 }
2628
2629 my $defaults = load_defaults();
2630
e6c3b671 2631 my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults, $migrate_uri);
1e3baf05 2632 # host pci devices
040b06b7
DA
2633 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2634 my $d = parse_hostpci($conf->{"hostpci$i"});
2635 next if !$d;
2636 my $info = pci_device_info("0000:$d->{pciid}");
2637 die "IOMMU not present\n" if !check_iommu_support();
2638 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2639 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
2640 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
2641 }
1e3baf05
DM
2642
2643 PVE::Storage::activate_volumes($storecfg, $vollist);
2644
6b64503e 2645 eval { run_command($cmd, timeout => $migrate_uri ? undef : 30); };
1e3baf05 2646 my $err = $@;
ff1a2432 2647 die "start failed: $err" if $err;
1e3baf05
DM
2648
2649 if ($statefile) {
2650
2651 if ($statefile eq 'tcp') {
2652 print "migration listens on port $migrate_port\n";
2653 } else {
2654 unlink $statefile;
2655 # fixme: send resume - is that necessary ?
ff1a2432 2656 eval { vm_monitor_command($vmid, "cont"); };
1e3baf05
DM
2657 }
2658 }
afdb31d5 2659
48e1a963
DM
2660 # always set migrate speed (overwrite kvm default of 32m)
2661 # we set a very hight default of 8192m which is basically unlimited
2662 my $migrate_speed = $defaults->{migrate_speed} || 8192;
2663 $migrate_speed = $conf->{migrate_speed} || $migrate_speed;
2f674c7a 2664 $migrate_speed = $migrate_speed * 1048576;
afdb31d5 2665 eval {
2f674c7a 2666 vm_mon_cmd($vmid, "migrate_set_speed", value => $migrate_speed);
48e1a963 2667 };
1e3baf05 2668
71c11a83
DM
2669 my $migrate_downtime = $defaults->{migrate_downtime};
2670 $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime});
2671 if (defined($migrate_downtime)) {
ec843725 2672 eval { vm_mon_cmd($vmid, "migrate_set_downtime",value => $migrate_downtime); };
1e3baf05 2673 }
e6c3b671 2674
7878afeb 2675 vm_balloonset($vmid, $conf->{balloon}) if $conf->{balloon};
ce332eeb 2676
1e3baf05
DM
2677 });
2678}
2679
97d62eb7 2680my $qmp_read_avail = sub {
c971c4f2
AD
2681 my ($fh, $timeout) = @_;
2682
2683 my $sel = new IO::Select;
2684 $sel->add($fh);
2685
2686 my $res = '';
2687 my $buf;
2688
2689 my @ready;
2690 while (scalar (@ready = $sel->can_read($timeout))) {
2691 my $count;
2692 if ($count = $fh->sysread($buf, 8192)) {
2693 $res .= $buf;
2694 last;
2695 } else {
2696 if (!defined($count)) {
2697 die "$!\n";
2698 }
2699 last;
2700 }
2701 }
2702
2703 die "qmp read timeout\n" if !scalar(@ready);
f667373f
AD
2704
2705 my @jsons = split("\n", $res);
2706 my $obj = {};
2707 my $event = {};
2708 my $return = {};
2709 foreach my $json (@jsons) {
2710 $obj = from_json($json);
2711 $event = $obj->{event} if exists $obj->{event};
2712 $return = $obj->{QMP} if exists $obj->{QMP};
2713 $return = $obj->{"return"} if exists $obj->{"return"};
2714 die $obj->{error}->{desc} if exists $obj->{error}->{desc} && $obj->{error}->{desc} !~ m/Connection can not be completed immediately/;
2715 }
2716
2717 return ($return,$event);
97d62eb7 2718};
c971c4f2 2719
1e3baf05
DM
2720sub __read_avail {
2721 my ($fh, $timeout) = @_;
2722
2723 my $sel = new IO::Select;
6b64503e 2724 $sel->add($fh);
1e3baf05
DM
2725
2726 my $res = '';
2727 my $buf;
2728
2729 my @ready;
6b64503e 2730 while (scalar (@ready = $sel->can_read($timeout))) {
1e3baf05 2731 my $count;
6b64503e 2732 if ($count = $fh->sysread($buf, 8192)) {
1e3baf05
DM
2733 if ($buf =~ /^(.*)\(qemu\) $/s) {
2734 $res .= $1;
2735 last;
2736 } else {
2737 $res .= $buf;
2738 }
2739 } else {
6b64503e 2740 if (!defined($count)) {
1e3baf05
DM
2741 die "$!\n";
2742 }
2743 last;
2744 }
2745 }
2746
6b64503e 2747 die "monitor read timeout\n" if !scalar(@ready);
1e3baf05
DM
2748
2749 return $res;
2750}
2751
2752sub vm_monitor_command {
ff1a2432 2753 my ($vmid, $cmdstr, $nocheck) = @_;
1e3baf05
DM
2754
2755 my $res;
2756
1e3baf05 2757 eval {
ff1a2432 2758 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
1e3baf05 2759
e6c3b671 2760 my $sname = monitor_socket($vmid);
1e3baf05 2761
6b64503e 2762 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
1e3baf05
DM
2763 die "unable to connect to VM $vmid socket - $!\n";
2764
2765 my $timeout = 3;
2766
19672434 2767 # hack: migrate sometime blocks the monitor (when migrate_downtime
1e3baf05
DM
2768 # is set)
2769 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2770 $timeout = 60*60; # 1 hour
2771 }
2772
2773 # read banner;
6b64503e 2774 my $data = __read_avail($sock, $timeout);
19672434 2775
1e3baf05
DM
2776 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2777 die "got unexpected qemu monitor banner\n";
2778 }
2779
2780 my $sel = new IO::Select;
6b64503e 2781 $sel->add($sock);
1e3baf05 2782
6b64503e 2783 if (!scalar(my @ready = $sel->can_write($timeout))) {
1e3baf05
DM
2784 die "monitor write error - timeout";
2785 }
2786
2787 my $fullcmd = "$cmdstr\r";
2788
ae57f6b3
DM
2789 # syslog('info', "VM $vmid monitor command: $cmdstr");
2790
1e3baf05 2791 my $b;
6b64503e 2792 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
1e3baf05
DM
2793 die "monitor write error - $!";
2794 }
2795
2796 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2797
19672434 2798 $timeout = 20;
1e3baf05
DM
2799
2800 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2801 $timeout = 60*60; # 1 hour
2802 } elsif ($cmdstr =~ m/^(eject|change)/) {
2803 $timeout = 60; # note: cdrom mount command is slow
2804 }
6b64503e 2805 if ($res = __read_avail($sock, $timeout)) {
19672434 2806
6b64503e 2807 my @lines = split("\r?\n", $res);
1e3baf05
DM
2808
2809 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
19672434 2810
6b64503e 2811 $res = join("\n", @lines);
1e3baf05
DM
2812 $res .= "\n";
2813 }
2814 };
2815
2816 my $err = $@;
2817
2818 if ($err) {
6b64503e 2819 syslog("err", "VM $vmid monitor command failed - $err");
1e3baf05
DM
2820 die $err;
2821 }
2822
2823 return $res;
2824}
2825
0eedc444
AD
2826sub vm_mon_cmd {
2827 my ($vmid, $execute, %params) = @_;
2828
2829 my $cmd = {};
2830 $cmd->{execute} = $execute;
2831 $cmd->{arguments} = \%params;
2832 vm_qmp_command($vmid,$cmd);
2833}
2834
2835sub vm_mon_cmd_nocheck {
2836 my ($vmid, $execute, %params) = @_;
2837
2838 my $cmd = {};
2839 $cmd->{execute} = $execute;
2840 $cmd->{arguments} = \%params;
2841 vm_qmp_command($vmid,$cmd,1);
2842}
2843
c971c4f2 2844sub vm_qmp_command {
d967756b 2845 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 2846
c971c4f2
AD
2847 #http://git.qemu.org/?p=qemu.git;a=blob;f=qmp-commands.hx;h=db980fa811325aeca8ad43472ba468702d4a25a2;hb=HEAD
2848 my $res;
d967756b 2849 my $event;
c971c4f2
AD
2850 eval {
2851 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2852
2853 my $sname = qmp_socket($vmid);
2854 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2855 die "unable to connect to VM $vmid socket - $!\n";
2856
c971c4f2 2857 my $timeout = 3;
97d62eb7
DM
2858
2859 # maybe this works with qmp, need to be tested
c971c4f2
AD
2860
2861 # hack: migrate sometime blocks the monitor (when migrate_downtime
2862 # is set)
d967756b
AD
2863
2864 $timeout = 60*60 if ($cmd->{execute} =~ m/(migrate)$/);
2865
c971c4f2
AD
2866
2867 # read banner;
97d62eb7 2868 my $data = &$qmp_read_avail($sock, $timeout);
c971c4f2 2869 # '{"QMP": {"version": {"qemu": {"micro": 93, "minor": 0, "major": 1}, "package": " (qemu-kvm-devel)"}, "capabilities": []}} ';
d967756b 2870 die "got unexpected qemu qmp banner\n" if !$data;
c971c4f2
AD
2871
2872 my $sel = new IO::Select;
2873 $sel->add($sock);
2874
2875 #negociation
2876 my $negociation = '{ "execute": "qmp_capabilities" }';
97d62eb7 2877
c971c4f2
AD
2878 if (!scalar(my @ready = $sel->can_write($timeout))) {
2879 die "monitor write error - timeout";
2880 }
2881
2882 my $b;
2883 if (!($b = $sock->syswrite($negociation)) || ($b != length($negociation))) {
2884 die "monitor write error - $!";
2885 }
2886
97d62eb7 2887 $res = &$qmp_read_avail($sock, $timeout);
c971c4f2 2888 # res = '{"return": {}}
d967756b 2889 die "qmp negociation error\n" if !$res;
c971c4f2 2890
c971c4f2
AD
2891 $timeout = 20;
2892
d967756b
AD
2893 my $cmdjson;
2894
97d62eb7 2895 #generate json from hash for complex cmd
d967756b 2896 $cmdjson = to_json($cmd);
c971c4f2 2897
d967756b
AD
2898 if ($cmd->{execute} =~ m/(migrate)$/) {
2899 $timeout = 60*60; # 1 hour
2900 } elsif ($cmd->{execute} =~ m/^(eject|change)/) {
2901 $timeout = 60; # note: cdrom mount command is slow
c971c4f2 2902 }
d967756b 2903
97d62eb7 2904
d967756b 2905 if (!($b = $sock->syswrite($cmdjson)) || ($b != length($cmdjson))) {
c971c4f2
AD
2906 die "monitor write error - $!";
2907 }
d967756b
AD
2908
2909
2910 return if ($cmd->{execute} eq 'q') || ($cmd->{execute} eq 'quit');
c971c4f2 2911
c971c4f2 2912
d967756b 2913 ($res,$event) = &$qmp_read_avail($sock, $timeout);
c971c4f2
AD
2914 };
2915
2916 my $err = $@;
2917
2918 if ($err) {
2919 syslog("err", "VM $vmid qmp command failed - $err");
2920 die $err;
2921 }
2922
2923 return $res;
2924}
2925
1e3baf05
DM
2926sub vm_commandline {
2927 my ($storecfg, $vmid) = @_;
2928
6b64503e 2929 my $conf = load_config($vmid);
1e3baf05
DM
2930
2931 my $defaults = load_defaults();
2932
6b64503e 2933 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 2934
6b64503e 2935 return join(' ', @$cmd);
1e3baf05
DM
2936}
2937
2938sub vm_reset {
2939 my ($vmid, $skiplock) = @_;
2940
6b64503e 2941 lock_config($vmid, sub {
1e3baf05 2942
6b64503e 2943 my $conf = load_config($vmid);
1e3baf05 2944
6b64503e 2945 check_lock($conf) if !$skiplock;
1e3baf05 2946
816e2c4a 2947 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
2948 });
2949}
2950
2951sub get_vm_volumes {
2952 my ($conf) = @_;
1e3baf05 2953
ff1a2432
DM
2954 my $vollist = [];
2955 foreach_drive($conf, sub {
2956 my ($ds, $drive) = @_;
2957
2958 my ($sid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
2959 return if !$sid;
2960
2961 my $volid = $drive->{file};
2962 return if !$volid || $volid =~ m|^/|;
2963
2964 push @$vollist, $volid;
1e3baf05 2965 });
ff1a2432
DM
2966
2967 return $vollist;
2968}
2969
2970sub vm_stop_cleanup {
254575e9 2971 my ($storecfg, $vmid, $conf, $keepActive) = @_;
ff1a2432 2972
745fed70
DM
2973 eval {
2974 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 2975
254575e9
DM
2976 if (!$keepActive) {
2977 my $vollist = get_vm_volumes($conf);
2978 PVE::Storage::deactivate_volumes($storecfg, $vollist);
2979 }
961bfcb2
DM
2980
2981 foreach my $ext (qw(mon pid vnc)) {
2982 unlink "/var/run/qemu-server/${vmid}.$ext";
2983 }
745fed70
DM
2984 };
2985 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
2986}
2987
e6c3b671 2988# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
2989# We need that when migration VMs to other nodes (files already moved)
2990# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 2991sub vm_stop {
254575e9 2992 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive) = @_;
9269013a
DM
2993
2994 $timeout = 60 if !defined($timeout);
ff1a2432 2995
9269013a 2996 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 2997
e6c3b671 2998 lock_config($vmid, sub {
1e3baf05 2999
e6c3b671 3000 my $pid = check_running($vmid, $nocheck);
ff1a2432 3001 return if !$pid;
1e3baf05 3002
ff1a2432 3003 my $conf;
e6c3b671 3004 if (!$nocheck) {
ff1a2432 3005 $conf = load_config($vmid);
e6c3b671
DM
3006 check_lock($conf) if !$skiplock;
3007 }
19672434 3008
9269013a
DM
3009 eval {
3010 if ($shutdown) {
988903ca
AD
3011 $nocheck ? vm_mon_cmd_nocheck($vmid, "system_powerdown") : vm_mon_cmd($vmid, "system_powerdown");
3012
9269013a 3013 } else {
988903ca 3014 $nocheck ? vm_mon_cmd_nocheck($vmid, "quit") : vm_mon_cmd($vmid, "quit");
afdb31d5 3015 }
9269013a 3016 };
1e3baf05
DM
3017 my $err = $@;
3018
3019 if (!$err) {
1e3baf05 3020 my $count = 0;
e6c3b671 3021 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3022 $count++;
3023 sleep 1;
3024 }
3025
3026 if ($count >= $timeout) {
9269013a
DM
3027 if ($force) {
3028 warn "VM still running - terminating now with SIGTERM\n";
3029 kill 15, $pid;
3030 } else {
3031 die "VM quit/powerdown failed - got timeout\n";
3032 }
3033 } else {
254575e9 3034 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
9269013a 3035 return;
1e3baf05
DM
3036 }
3037 } else {
9269013a
DM
3038 if ($force) {
3039 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3040 kill 15, $pid;
3041 } else {
afdb31d5 3042 die "VM quit/powerdown failed\n";
9269013a 3043 }
1e3baf05
DM
3044 }
3045
3046 # wait again
ff1a2432 3047 $timeout = 10;
1e3baf05
DM
3048
3049 my $count = 0;
e6c3b671 3050 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3051 $count++;
3052 sleep 1;
3053 }
3054
3055 if ($count >= $timeout) {
ff1a2432 3056 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 3057 kill 9, $pid;
ff1a2432 3058 sleep 1;
1e3baf05
DM
3059 }
3060
254575e9 3061 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
ff1a2432 3062 });
1e3baf05
DM
3063}
3064
3065sub vm_suspend {
3066 my ($vmid, $skiplock) = @_;
3067
6b64503e 3068 lock_config($vmid, sub {
1e3baf05 3069
6b64503e 3070 my $conf = load_config($vmid);
1e3baf05 3071
6b64503e 3072 check_lock($conf) if !$skiplock;
f77f91f3
AD
3073
3074 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
3075 });
3076}
3077
3078sub vm_resume {
3079 my ($vmid, $skiplock) = @_;
3080
6b64503e 3081 lock_config($vmid, sub {
1e3baf05 3082
6b64503e 3083 my $conf = load_config($vmid);
1e3baf05 3084
6b64503e 3085 check_lock($conf) if !$skiplock;
1e3baf05 3086
12060fe8 3087 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
3088 });
3089}
3090
5fdbe4f0
DM
3091sub vm_sendkey {
3092 my ($vmid, $skiplock, $key) = @_;
1e3baf05 3093
6b64503e 3094 lock_config($vmid, sub {
1e3baf05 3095
6b64503e 3096 my $conf = load_config($vmid);
1e3baf05 3097
ff1a2432 3098 vm_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
3099 });
3100}
3101
3102sub vm_destroy {
3103 my ($storecfg, $vmid, $skiplock) = @_;
3104
6b64503e 3105 lock_config($vmid, sub {
1e3baf05 3106
6b64503e 3107 my $conf = load_config($vmid);
1e3baf05 3108
6b64503e 3109 check_lock($conf) if !$skiplock;
1e3baf05 3110
ff1a2432
DM
3111 if (!check_running($vmid)) {
3112 fairsched_rmnod($vmid); # try to destroy group
3113 destroy_vm($storecfg, $vmid);
3114 } else {
3115 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
3116 }
3117 });
3118}
3119
1e3baf05
DM
3120# pci helpers
3121
3122sub file_write {
3123 my ($filename, $buf) = @_;
3124
6b64503e 3125 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
3126 return undef if !$fh;
3127
3128 my $res = print $fh $buf;
3129
3130 $fh->close();
3131
3132 return $res;
3133}
3134
3135sub pci_device_info {
3136 my ($name) = @_;
3137
3138 my $res;
3139
3140 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3141 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3142
3143 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
3144 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3145
3146 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
3147 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3148
3149 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
3150 return undef if !defined($product) || $product !~ s/^0x//;
3151
3152 $res = {
3153 name => $name,
3154 vendor => $vendor,
3155 product => $product,
3156 domain => $domain,
3157 bus => $bus,
3158 slot => $slot,
3159 func => $func,
3160 irq => $irq,
3161 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
3162 };
3163
3164 return $res;
3165}
3166
3167sub pci_dev_reset {
3168 my ($dev) = @_;
3169
3170 my $name = $dev->{name};
3171
3172 my $fn = "$pcisysfs/devices/$name/reset";
3173
6b64503e 3174 return file_write($fn, "1");
1e3baf05
DM
3175}
3176
3177sub pci_dev_bind_to_stub {
3178 my ($dev) = @_;
3179
3180 my $name = $dev->{name};
3181
3182 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3183 return 1 if -d $testdir;
3184
3185 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 3186 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
3187
3188 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 3189 if (!file_write($fn, $name)) {
1e3baf05
DM
3190 return undef if -f $fn;
3191 }
3192
3193 $fn = "$pcisysfs/drivers/pci-stub/bind";
3194 if (! -d $testdir) {
6b64503e 3195 return undef if !file_write($fn, $name);
1e3baf05
DM
3196 }
3197
3198 return -d $testdir;
3199}
3200
afdb31d5 3201sub print_pci_addr {
72a063e4 3202 my ($id) = @_;
6b64503e 3203
72a063e4 3204 my $res = '';
6b64503e 3205 my $devices = {
e5f7f8ed
DA
3206 #addr1 : ide,parallel,serial (motherboard)
3207 #addr2 : first videocard
13b5a753 3208 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 3209 watchdog => { bus => 0, addr => 4 },
69b6ae0c
DA
3210 lsi0 => { bus => 0, addr => 5 },
3211 lsi1 => { bus => 0, addr => 6 },
26ee04b6 3212 ahci0 => { bus => 0, addr => 7 },
6b64503e
DM
3213 virtio0 => { bus => 0, addr => 10 },
3214 virtio1 => { bus => 0, addr => 11 },
3215 virtio2 => { bus => 0, addr => 12 },
3216 virtio3 => { bus => 0, addr => 13 },
3217 virtio4 => { bus => 0, addr => 14 },
3218 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
3219 hostpci0 => { bus => 0, addr => 16 },
3220 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
3221 net0 => { bus => 0, addr => 18 },
3222 net1 => { bus => 0, addr => 19 },
3223 net2 => { bus => 0, addr => 20 },
3224 net3 => { bus => 0, addr => 21 },
3225 net4 => { bus => 0, addr => 22 },
3226 net5 => { bus => 0, addr => 23 },
e5f7f8ed 3227 #addr29 : usb-host (pve-usb.cfg)
6b64503e
DM
3228 };
3229
3230 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4
DA
3231 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
3232 $res = ",bus=pci.$devices->{$id}->{bus},addr=$addr";
3233 }
3234 return $res;
3235
3236}
3237
13a48620 3238sub vm_balloonset {
7878afeb 3239 my ($vmid, $value) = @_;
13a48620 3240
2d23ddc5 3241 vm_mon_cmd($vmid, "balloon", value => $value);
13a48620
DA
3242}
3243
3e16d5fc
DM
3244# vzdump restore implementaion
3245
3246sub archive_read_firstfile {
3247 my $archive = shift;
afdb31d5 3248
3e16d5fc
DM
3249 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
3250
3251 # try to detect archive type first
3252 my $pid = open (TMP, "tar tf '$archive'|") ||
3253 die "unable to open file '$archive'\n";
3254 my $firstfile = <TMP>;
3255 kill 15, $pid;
3256 close TMP;
3257
3258 die "ERROR: archive contaions no data\n" if !$firstfile;
3259 chomp $firstfile;
3260
3261 return $firstfile;
3262}
3263
3264sub restore_cleanup {
3265 my $statfile = shift;
3266
3267 print STDERR "starting cleanup\n";
3268
3269 if (my $fd = IO::File->new($statfile, "r")) {
3270 while (defined(my $line = <$fd>)) {
3271 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3272 my $volid = $2;
3273 eval {
3274 if ($volid =~ m|^/|) {
3275 unlink $volid || die 'unlink failed\n';
3276 } else {
3277 my $cfg = cfs_read_file('storage.cfg');
3278 PVE::Storage::vdisk_free($cfg, $volid);
3279 }
afdb31d5 3280 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
3281 };
3282 print STDERR "unable to cleanup '$volid' - $@" if $@;
3283 } else {
3284 print STDERR "unable to parse line in statfile - $line";
afdb31d5 3285 }
3e16d5fc
DM
3286 }
3287 $fd->close();
3288 }
3289}
3290
3291sub restore_archive {
a0d1b1a2 3292 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 3293
9c502e26
DM
3294 if ($archive ne '-') {
3295 my $firstfile = archive_read_firstfile($archive);
3296 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3297 if $firstfile ne 'qemu-server.conf';
3298 }
3e16d5fc
DM
3299
3300 my $tocmd = "/usr/lib/qemu-server/qmextract";
3301
2415a446 3302 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 3303 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
3304 $tocmd .= ' --prealloc' if $opts->{prealloc};
3305 $tocmd .= ' --info' if $opts->{info};
3306
a0d1b1a2 3307 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 3308 # so we pipe to zcat
2415a446
DM
3309 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
3310 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
3311
3312 my $tmpdir = "/var/tmp/vzdumptmp$$";
3313 mkpath $tmpdir;
3314
3315 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
3316 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 3317 local $ENV{VZDUMP_USER} = $user;
3e16d5fc
DM
3318
3319 my $conffile = PVE::QemuServer::config_file($vmid);
3320 my $tmpfn = "$conffile.$$.tmp";
3321
3322 # disable interrupts (always do cleanups)
3323 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3324 print STDERR "got interrupt - ignored\n";
3325 };
3326
afdb31d5 3327 eval {
3e16d5fc
DM
3328 # enable interrupts
3329 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
3330 die "interrupted by signal\n";
3331 };
3332
9c502e26
DM
3333 if ($archive eq '-') {
3334 print "extracting archive from STDIN\n";
3335 run_command($cmd, input => "<&STDIN");
3336 } else {
3337 print "extracting archive '$archive'\n";
3338 run_command($cmd);
3339 }
3e16d5fc
DM
3340
3341 return if $opts->{info};
3342
3343 # read new mapping
3344 my $map = {};
3345 my $statfile = "$tmpdir/qmrestore.stat";
3346 if (my $fd = IO::File->new($statfile, "r")) {
3347 while (defined (my $line = <$fd>)) {
3348 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3349 $map->{$1} = $2 if $1;
3350 } else {
3351 print STDERR "unable to parse line in statfile - $line\n";
3352 }
3353 }
3354 $fd->close();
3355 }
3356
3357 my $confsrc = "$tmpdir/qemu-server.conf";
3358
3359 my $srcfd = new IO::File($confsrc, "r") ||
3360 die "unable to open file '$confsrc'\n";
3361
3362 my $outfd = new IO::File ($tmpfn, "w") ||
3363 die "unable to write config for VM $vmid\n";
3364
51586c3a
DM
3365 my $netcount = 0;
3366
3e16d5fc
DM
3367 while (defined (my $line = <$srcfd>)) {
3368 next if $line =~ m/^\#vzdump\#/;
3369 next if $line =~ m/^lock:/;
3370 next if $line =~ m/^unused\d+:/;
3371
51586c3a
DM
3372 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3373 # try to convert old 1.X settings
3374 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3375 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3376 my ($model, $macaddr) = split(/\=/, $devconfig);
3377 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $opts->{unique};
3378 my $net = {
3379 model => $model,
3380 bridge => "vmbr$ind",
3381 macaddr => $macaddr,
3382 };
3383 my $netstr = print_net($net);
3384 print $outfd "net${netcount}: $netstr\n";
3385 $netcount++;
3386 }
3387 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique})) {
3388 my ($id, $netstr) = ($1, $2);
3389 my $net = parse_net($netstr);
3390 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3391 $netstr = print_net($net);
afdb31d5 3392 print $outfd "$id: $netstr\n";
51586c3a 3393 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3e16d5fc
DM
3394 my $virtdev = $1;
3395 my $value = $2;
3396 if ($line =~ m/backup=no/) {
3397 print $outfd "#$line";
3398 } elsif ($virtdev && $map->{$virtdev}) {
3399 my $di = PVE::QemuServer::parse_drive($virtdev, $value);
3400 $di->{file} = $map->{$virtdev};
3401 $value = PVE::QemuServer::print_drive($vmid, $di);
3402 print $outfd "$virtdev: $value\n";
3403 } else {
3404 print $outfd $line;
3405 }
3406 } else {
3407 print $outfd $line;
3408 }
3409 }
3410
3411 $srcfd->close();
3412 $outfd->close();
3413 };
3414 my $err = $@;
3415
afdb31d5 3416 if ($err) {
3e16d5fc
DM
3417
3418 unlink $tmpfn;
3419
3420 restore_cleanup("$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 3421
3e16d5fc 3422 die $err;
afdb31d5 3423 }
3e16d5fc
DM
3424
3425 rmtree $tmpdir;
3426
3427 rename $tmpfn, $conffile ||
3428 die "unable to commit configuration file '$conffile'\n";
3429};
3430
1e3baf05 34311;