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