]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
use new standard option 'pve-startup-order'
[qemu-server.git] / PVE / QemuServer.pm
CommitLineData
1e3baf05
DM
1package PVE::QemuServer;
2
3use strict;
990fc5e2 4use warnings;
1e3baf05
DM
5use POSIX;
6use IO::Handle;
7use IO::Select;
8use IO::File;
9use IO::Dir;
10use IO::Socket::UNIX;
11use File::Basename;
12use File::Path;
13use File::stat;
14use Getopt::Long;
fc1ddcdc 15use Digest::SHA;
1e3baf05
DM
16use Fcntl ':flock';
17use Cwd 'abs_path';
18use IPC::Open3;
c971c4f2 19use JSON;
1e3baf05
DM
20use Fcntl;
21use PVE::SafeSyslog;
22use Storable qw(dclone);
23use PVE::Exception qw(raise raise_param_exc);
24use PVE::Storage;
4543ecf0 25use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach);
b7ba6b79 26use PVE::JSONSchema qw(get_standard_option);
1e3baf05
DM
27use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
28use PVE::INotify;
29use PVE::ProcFSTools;
26f11676 30use PVE::QMPClient;
91bd6c90 31use PVE::RPCEnvironment;
6b64503e 32use Time::HiRes qw(gettimeofday);
1e3baf05 33
7f0b5beb 34my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
1e3baf05 35
19672434 36# Note about locking: we use flock on the config file protect
1e3baf05
DM
37# against concurent actions.
38# Aditionaly, we have a 'lock' setting in the config file. This
22c377f0 39# can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
1e3baf05
DM
40# allowed when such lock is set. But you can ignore this kind of
41# lock with the --skiplock flag.
42
97d62eb7 43cfs_register_file('/qemu-server/',
1858638f
DM
44 \&parse_vm_config,
45 \&write_vm_config);
1e3baf05 46
3ea94c60
DM
47PVE::JSONSchema::register_standard_option('skiplock', {
48 description => "Ignore locks - only root is allowed to use this option.",
afdb31d5 49 type => 'boolean',
3ea94c60
DM
50 optional => 1,
51});
52
53PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
54 description => "Some command save/restore state from this location.",
55 type => 'string',
56 maxLength => 128,
57 optional => 1,
58});
59
8abd398b
DM
60PVE::JSONSchema::register_standard_option('pve-snapshot-name', {
61 description => "The name of the snapshot.",
62 type => 'string', format => 'pve-configid',
63 maxLength => 40,
64});
65
1e3baf05
DM
66#no warnings 'redefine';
67
68unless(defined(&_VZSYSCALLS_H_)) {
69 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_);
70 require 'sys/syscall.ph';
71 if(defined(&__x86_64__)) {
72 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus);
73 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod);
74 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod);
75 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt);
76 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr);
77 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate);
78 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid);
79 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit);
80 }
81 elsif(defined( &__i386__) ) {
82 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod);
83 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod);
84 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt);
85 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr);
86 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate);
87 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus);
88 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid);
89 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit);
90 } else {
91 die("no fairsched syscall for this arch");
92 }
93 require 'asm/ioctl.ph';
94 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION);
95}
96
97sub fairsched_mknod {
98 my ($parent, $weight, $desired) = @_;
99
6b64503e 100 return syscall(&__NR_fairsched_mknod, int($parent), int($weight), int($desired));
1e3baf05
DM
101}
102
103sub fairsched_rmnod {
104 my ($id) = @_;
105
6b64503e 106 return syscall(&__NR_fairsched_rmnod, int($id));
1e3baf05
DM
107}
108
109sub fairsched_mvpr {
110 my ($pid, $newid) = @_;
111
6b64503e 112 return syscall(&__NR_fairsched_mvpr, int($pid), int($newid));
1e3baf05
DM
113}
114
115sub fairsched_vcpus {
116 my ($id, $vcpus) = @_;
117
6b64503e 118 return syscall(&__NR_fairsched_vcpus, int($id), int($vcpus));
1e3baf05
DM
119}
120
121sub fairsched_rate {
122 my ($id, $op, $rate) = @_;
123
6b64503e 124 return syscall(&__NR_fairsched_rate, int($id), int($op), int($rate));
1e3baf05
DM
125}
126
127use constant FAIRSCHED_SET_RATE => 0;
128use constant FAIRSCHED_DROP_RATE => 1;
129use constant FAIRSCHED_GET_RATE => 2;
130
131sub fairsched_cpulimit {
132 my ($id, $limit) = @_;
133
6b64503e 134 my $cpulim1024 = int($limit * 1024 / 100);
1e3baf05
DM
135 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE : FAIRSCHED_DROP_RATE;
136
6b64503e 137 return fairsched_rate($id, $op, $cpulim1024);
1e3baf05
DM
138}
139
140my $nodename = PVE::INotify::nodename();
141
142mkdir "/etc/pve/nodes/$nodename";
143my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
144mkdir $confdir;
145
146my $var_run_tmpdir = "/var/run/qemu-server";
147mkdir $var_run_tmpdir;
148
149my $lock_dir = "/var/lock/qemu-server";
150mkdir $lock_dir;
151
152my $pcisysfs = "/sys/bus/pci";
153
1e3baf05
DM
154my $confdesc = {
155 onboot => {
156 optional => 1,
157 type => 'boolean',
158 description => "Specifies whether a VM will be started during system bootup.",
159 default => 0,
160 },
161 autostart => {
162 optional => 1,
163 type => 'boolean',
164 description => "Automatic restart after crash (currently ignored).",
165 default => 0,
166 },
2ff09f52
DA
167 hotplug => {
168 optional => 1,
b3c2bdd1
DM
169 type => 'string', format => 'pve-hotplug-features',
170 description => "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.",
171 default => 'network,disk,usb',
2ff09f52 172 },
1e3baf05
DM
173 reboot => {
174 optional => 1,
175 type => 'boolean',
176 description => "Allow reboot. If set to '0' the VM exit on reboot.",
177 default => 1,
178 },
179 lock => {
180 optional => 1,
181 type => 'string',
182 description => "Lock/unlock the VM.",
22c377f0 183 enum => [qw(migrate backup snapshot rollback)],
1e3baf05
DM
184 },
185 cpulimit => {
186 optional => 1,
187 type => 'integer',
188 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.",
189 minimum => 0,
190 default => 0,
191 },
192 cpuunits => {
193 optional => 1,
194 type => 'integer',
195 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.",
196 minimum => 0,
197 maximum => 500000,
198 default => 1000,
199 },
200 memory => {
201 optional => 1,
202 type => 'integer',
7878afeb 203 description => "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
1e3baf05
DM
204 minimum => 16,
205 default => 512,
206 },
13a48620
DA
207 balloon => {
208 optional => 1,
209 type => 'integer',
8b1accf7
DM
210 description => "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.",
211 minimum => 0,
212 },
213 shares => {
214 optional => 1,
215 type => 'integer',
216 description => "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning",
217 minimum => 0,
218 maximum => 50000,
219 default => 1000,
13a48620 220 },
1e3baf05
DM
221 keyboard => {
222 optional => 1,
223 type => 'string',
224 description => "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
e95fe75f 225 enum => PVE::Tools::kvmkeymaplist(),
1e3baf05
DM
226 default => 'en-us',
227 },
228 name => {
229 optional => 1,
7fabe17d 230 type => 'string', format => 'dns-name',
1e3baf05
DM
231 description => "Set a name for the VM. Only used on the configuration web interface.",
232 },
cdd20088
AD
233 scsihw => {
234 optional => 1,
235 type => 'string',
236 description => "scsi controller model",
6731a4cf 237 enum => [qw(lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi)],
cdd20088
AD
238 default => 'lsi',
239 },
1e3baf05
DM
240 description => {
241 optional => 1,
242 type => 'string',
0581fe4f 243 description => "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
1e3baf05
DM
244 },
245 ostype => {
246 optional => 1,
247 type => 'string',
6b9d84cf 248 enum => [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 l24 l26 solaris)],
1e3baf05
DM
249 description => <<EODESC,
250Used to enable special optimization/features for specific
251operating systems:
252
253other => unspecified OS
254wxp => Microsoft Windows XP
255w2k => Microsoft Windows 2000
256w2k3 => Microsoft Windows 2003
257w2k8 => Microsoft Windows 2008
258wvista => Microsoft Windows Vista
259win7 => Microsoft Windows 7
a70ebde3 260win8 => Microsoft Windows 8/2012
1e3baf05
DM
261l24 => Linux 2.4 Kernel
262l26 => Linux 2.6/3.X Kernel
6b9d84cf 263solaris => solaris/opensolaris/openindiania kernel
1e3baf05 264
6b9d84cf 265other|l24|l26|solaris ... no special behaviour
a70ebde3 266wxp|w2k|w2k3|w2k8|wvista|win7|win8 ... use --localtime switch
1e3baf05
DM
267EODESC
268 },
269 boot => {
270 optional => 1,
271 type => 'string',
272 description => "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
273 pattern => '[acdn]{1,4}',
32baffb4 274 default => 'cdn',
1e3baf05
DM
275 },
276 bootdisk => {
277 optional => 1,
278 type => 'string', format => 'pve-qm-bootdisk',
279 description => "Enable booting from specified disk.",
03e480fc 280 pattern => '(ide|sata|scsi|virtio)\d+',
1e3baf05
DM
281 },
282 smp => {
283 optional => 1,
284 type => 'integer',
285 description => "The number of CPUs. Please use option -sockets instead.",
286 minimum => 1,
287 default => 1,
288 },
289 sockets => {
290 optional => 1,
291 type => 'integer',
292 description => "The number of CPU sockets.",
293 minimum => 1,
294 default => 1,
295 },
296 cores => {
297 optional => 1,
298 type => 'integer',
299 description => "The number of cores per socket.",
300 minimum => 1,
301 default => 1,
302 },
8a010eae
AD
303 numa => {
304 optional => 1,
305 type => 'boolean',
306 description => "Enable/disable Numa.",
307 default => 0,
308 },
de9d1e55 309 vcpus => {
3bd18e48
AD
310 optional => 1,
311 type => 'integer',
de9d1e55 312 description => "Number of hotplugged vcpus.",
3bd18e48 313 minimum => 1,
de9d1e55 314 default => 0,
3bd18e48 315 },
1e3baf05
DM
316 acpi => {
317 optional => 1,
318 type => 'boolean',
319 description => "Enable/disable ACPI.",
320 default => 1,
321 },
bc84dcca 322 agent => {
ab6a046f
AD
323 optional => 1,
324 type => 'boolean',
325 description => "Enable/disable Qemu GuestAgent.",
be79c214 326 default => 0,
ab6a046f 327 },
1e3baf05
DM
328 kvm => {
329 optional => 1,
330 type => 'boolean',
331 description => "Enable/disable KVM hardware virtualization.",
332 default => 1,
333 },
334 tdf => {
335 optional => 1,
336 type => 'boolean',
8c559505
DM
337 description => "Enable/disable time drift fix.",
338 default => 0,
1e3baf05 339 },
19672434 340 localtime => {
1e3baf05
DM
341 optional => 1,
342 type => 'boolean',
343 description => "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
344 },
345 freeze => {
346 optional => 1,
347 type => 'boolean',
348 description => "Freeze CPU at startup (use 'c' monitor command to start execution).",
349 },
350 vga => {
351 optional => 1,
352 type => 'string',
ef5e2be2 353 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 win8/win7/w2k8, and 'cirrur' for other OS types. Option 'qxl' enables the SPICE display sever. You can also run without any graphic card using a serial devive as terminal.",
2fa3151e 354 enum => [qw(std cirrus vmware qxl serial0 serial1 serial2 serial3 qxl2 qxl3 qxl4)],
1e3baf05 355 },
0ea9541d
DM
356 watchdog => {
357 optional => 1,
358 type => 'string', format => 'pve-qm-watchdog',
359 typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
360 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)",
361 },
1e3baf05
DM
362 startdate => {
363 optional => 1,
19672434 364 type => 'string',
1e3baf05
DM
365 typetext => "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
366 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'.",
367 pattern => '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
368 default => 'now',
369 },
43574f73 370 startup => get_standard_option('pve-startup-order'),
68eda3ab
AD
371 template => {
372 optional => 1,
373 type => 'boolean',
374 description => "Enable/disable Template.",
375 default => 0,
376 },
1e3baf05
DM
377 args => {
378 optional => 1,
379 type => 'string',
380 description => <<EODESCR,
381Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
382
383args: -no-reboot -no-hpet
384EODESCR
385 },
386 tablet => {
387 optional => 1,
388 type => 'boolean',
389 default => 1,
5acbfe9e 390 description => "Enable/disable the usb tablet device. This device is usually needed to allow absolute mouse positioning with VNC. 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. This is turned of by default if you use spice (vga=qxl).",
1e3baf05
DM
391 },
392 migrate_speed => {
393 optional => 1,
394 type => 'integer',
395 description => "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
396 minimum => 0,
397 default => 0,
398 },
399 migrate_downtime => {
400 optional => 1,
04432191 401 type => 'number',
1e3baf05
DM
402 description => "Set maximum tolerated downtime (in seconds) for migrations.",
403 minimum => 0,
04432191 404 default => 0.1,
1e3baf05
DM
405 },
406 cdrom => {
407 optional => 1,
408 type => 'string', format => 'pve-qm-drive',
409 typetext => 'volume',
410 description => "This is an alias for option -ide2",
411 },
412 cpu => {
413 optional => 1,
414 description => "Emulated CPU type.",
415 type => 'string',
8bb5e28d 416 enum => [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom Conroe Penryn Nehalem Westmere SandyBridge IvyBridge Haswell Broadwell Opteron_G1 Opteron_G2 Opteron_G3 Opteron_G4 Opteron_G5 host) ],
eac6899d 417 default => 'kvm64',
1e3baf05 418 },
b7ba6b79
DM
419 parent => get_standard_option('pve-snapshot-name', {
420 optional => 1,
421 description => "Parent snapshot name. This is used internally, and should not be modified.",
422 }),
982c7f12
DM
423 snaptime => {
424 optional => 1,
425 description => "Timestamp for snapshots.",
426 type => 'integer',
427 minimum => 0,
428 },
18bfb361
DM
429 vmstate => {
430 optional => 1,
431 type => 'string', format => 'pve-volume-id',
432 description => "Reference to a volume which stores the VM state. This is used internally for snapshots.",
433 },
3bafc510
DM
434 machine => {
435 description => "Specific the Qemu machine type.",
436 type => 'string',
437 pattern => '(pc|pc(-i440fx)?-\d+\.\d+|q35|pc-q35-\d+\.\d+)',
438 maxLength => 40,
439 optional => 1,
440 },
2796e7d5
DM
441 smbios1 => {
442 description => "Specify SMBIOS type 1 fields.",
443 type => 'string', format => 'pve-qm-smbios1',
444 typetext => "[manufacturer=str][,product=str][,version=str][,serial=str] [,uuid=uuid][,sku=str][,family=str]",
445 maxLength => 256,
446 optional => 1,
447 },
1e3baf05
DM
448};
449
450# what about other qemu settings ?
451#cpu => 'string',
452#machine => 'string',
453#fda => 'file',
454#fdb => 'file',
455#mtdblock => 'file',
456#sd => 'file',
457#pflash => 'file',
458#snapshot => 'bool',
459#bootp => 'file',
460##tftp => 'dir',
461##smb => 'dir',
462#kernel => 'file',
463#append => 'string',
464#initrd => 'file',
465##soundhw => 'string',
466
467while (my ($k, $v) = each %$confdesc) {
468 PVE::JSONSchema::register_standard_option("pve-qm-$k", $v);
469}
470
471my $MAX_IDE_DISKS = 4;
f62db2a4 472my $MAX_SCSI_DISKS = 14;
a2650619 473my $MAX_VIRTIO_DISKS = 16;
cdb0931f 474my $MAX_SATA_DISKS = 6;
1e3baf05 475my $MAX_USB_DEVICES = 5;
5bdcf937 476my $MAX_NETS = 32;
1e3baf05 477my $MAX_UNUSED_DISKS = 8;
5cffb2d2 478my $MAX_HOSTPCI_DEVICES = 4;
bae179aa 479my $MAX_SERIAL_PORTS = 4;
1989a89c 480my $MAX_PARALLEL_PORTS = 3;
2ed5d572 481my $MAX_NUMA = 8;
4d3f29ed
AD
482my $MAX_MEM = 4194304;
483my $STATICMEM = 1024;
2ed5d572
AD
484
485my $numadesc = {
486 optional => 1,
487 type => 'string', format => 'pve-qm-numanode',
25088687 488 typetext => "cpus=<id[-id],memory=<mb>[[,hostnodes=<id[-id]>] [,policy=<preferred|bind|interleave>]]",
2ed5d572
AD
489 description => "numa topology",
490};
491PVE::JSONSchema::register_standard_option("pve-qm-numanode", $numadesc);
492
493for (my $i = 0; $i < $MAX_NUMA; $i++) {
494 $confdesc->{"numa$i"} = $numadesc;
495}
1e3baf05
DM
496
497my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
55034103
KT
498 'ne2k_isa', 'i82551', 'i82557b', 'i82559er', 'vmxnet3',
499 'e1000-82540em', 'e1000-82544gc', 'e1000-82545em'];
6b64503e 500my $nic_model_list_txt = join(' ', sort @$nic_model_list);
1e3baf05 501
1e3baf05
DM
502my $netdesc = {
503 optional => 1,
504 type => 'string', format => 'pve-qm-net',
25088687 505 typetext => "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,queues=<nbqueues>][,rate=<mbps>] [,tag=<vlanid>][,firewall=0|1],link_down=0|1]",
1e3baf05 506 description => <<EODESCR,
19672434 507Specify network devices.
1e3baf05
DM
508
509MODEL is one of: $nic_model_list_txt
510
19672434 511XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
1e3baf05
DM
512automatically generated if not specified.
513
514The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
515
516Option 'rate' is used to limit traffic bandwidth from and to this interface. It is specified as floating point number, unit is 'Megabytes per second'.
517
518If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
519
52010.0.2.2 Gateway
52110.0.2.3 DNS Server
52210.0.2.4 SMB Server
523
524The DHCP server assign addresses to the guest starting from 10.0.2.15.
525
526EODESCR
527};
528PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
529
530for (my $i = 0; $i < $MAX_NETS; $i++) {
531 $confdesc->{"net$i"} = $netdesc;
532}
533
534my $drivename_hash;
19672434 535
1e3baf05
DM
536my $idedesc = {
537 optional => 1,
538 type => 'string', format => 'pve-qm-drive',
8d87f8aa 539 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] [,discard=ignore|on]',
3c770faa 540 description => "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
1e3baf05
DM
541};
542PVE::JSONSchema::register_standard_option("pve-qm-ide", $idedesc);
543
544my $scsidesc = {
545 optional => 1,
546 type => 'string', format => 'pve-qm-drive',
6e11f143 547 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] [,discard=ignore|on] [,iothread=on] [,queues=<nbqueues>]',
3c770faa 548 description => "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
1e3baf05
DM
549};
550PVE::JSONSchema::register_standard_option("pve-qm-scsi", $scsidesc);
551
cdb0931f
DA
552my $satadesc = {
553 optional => 1,
554 type => 'string', format => 'pve-qm-drive',
8d87f8aa 555 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] [,discard=ignore|on]',
3c770faa 556 description => "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
cdb0931f
DA
557};
558PVE::JSONSchema::register_standard_option("pve-qm-sata", $satadesc);
559
1e3baf05
DM
560my $virtiodesc = {
561 optional => 1,
562 type => 'string', format => 'pve-qm-drive',
51f492cd 563 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] [,discard=ignore|on] [,iothread=on]',
3c770faa 564 description => "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
1e3baf05
DM
565};
566PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
567
568my $usbdesc = {
569 optional => 1,
570 type => 'string', format => 'pve-qm-usb-device',
80401dd8 571 typetext => 'host=HOSTUSBDEVICE|spice',
1e3baf05 572 description => <<EODESCR,
2fe1a152 573Configure an USB device (n is 0 to 4). This can be used to
1e3baf05
DM
574pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
575
19672434 576'bus-port(.port)*' (decimal numbers) or
1e3baf05
DM
577'vendor_id:product_id' (hexadeciaml numbers)
578
19672434 579You can use the 'lsusb -t' command to list existing usb devices.
1e3baf05
DM
580
581Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
582
80401dd8
DM
583The value 'spice' can be used to add a usb redirection devices for spice.
584
1e3baf05
DM
585EODESCR
586};
587PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
588
040b06b7
DA
589my $hostpcidesc = {
590 optional => 1,
591 type => 'string', format => 'pve-qm-hostpci',
2e3b7e2a 592 typetext => "[host=]HOSTPCIDEVICE [,driver=kvm|vfio] [,rombar=on|off] [,pcie=0|1] [,x-vga=on|off]",
040b06b7
DA
593 description => <<EODESCR,
594Map host pci devices. HOSTPCIDEVICE syntax is:
595
596'bus:dev.func' (hexadecimal numbers)
597
598You can us the 'lspci' command to list existing pci devices.
599
0cea6a01
DM
600The 'rombar' option determines whether or not the device's ROM will be visible in the guest's memory map (default is 'on').
601
040b06b7
DA
602Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
603
604Experimental: user reported problems with this option.
605EODESCR
606};
607PVE::JSONSchema::register_standard_option("pve-qm-hostpci", $hostpcidesc);
608
bae179aa
DA
609my $serialdesc = {
610 optional => 1,
ca0cef26 611 type => 'string',
1b0b51ed 612 pattern => '(/dev/.+|socket)',
bae179aa 613 description => <<EODESCR,
1b0b51ed 614Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device (i.e. /dev/ttyS0), or create a unix socket on the host side (use 'qm terminal' to open a terminal connection).
bae179aa
DA
615
616Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
617
618Experimental: user reported problems with this option.
619EODESCR
620};
bae179aa 621
1989a89c
DA
622my $paralleldesc= {
623 optional => 1,
ca0cef26 624 type => 'string',
9ecc8431 625 pattern => '/dev/parport\d+|/dev/usb/lp\d+',
1989a89c 626 description => <<EODESCR,
19672434 627Map host parallel devices (n is 0 to 2).
1989a89c
DA
628
629Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
630
631Experimental: user reported problems with this option.
632EODESCR
633};
1989a89c
DA
634
635for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
636 $confdesc->{"parallel$i"} = $paralleldesc;
637}
638
bae179aa
DA
639for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
640 $confdesc->{"serial$i"} = $serialdesc;
641}
642
040b06b7
DA
643for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
644 $confdesc->{"hostpci$i"} = $hostpcidesc;
645}
1e3baf05
DM
646
647for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
648 $drivename_hash->{"ide$i"} = 1;
649 $confdesc->{"ide$i"} = $idedesc;
650}
651
cdb0931f
DA
652for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
653 $drivename_hash->{"sata$i"} = 1;
654 $confdesc->{"sata$i"} = $satadesc;
655}
656
1e3baf05
DM
657for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
658 $drivename_hash->{"scsi$i"} = 1;
659 $confdesc->{"scsi$i"} = $scsidesc ;
660}
661
662for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
663 $drivename_hash->{"virtio$i"} = 1;
664 $confdesc->{"virtio$i"} = $virtiodesc;
665}
666
667for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
668 $confdesc->{"usb$i"} = $usbdesc;
669}
670
671my $unuseddesc = {
672 optional => 1,
673 type => 'string', format => 'pve-volume-id',
674 description => "Reference to unused volumes.",
675};
676
677for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
678 $confdesc->{"unused$i"} = $unuseddesc;
679}
680
681my $kvm_api_version = 0;
682
683sub kvm_version {
684
685 return $kvm_api_version if $kvm_api_version;
686
6b64503e 687 my $fh = IO::File->new("</dev/kvm") ||
1e3baf05
DM
688 return 0;
689
6b64503e 690 if (my $v = $fh->ioctl(KVM_GET_API_VERSION(), 0)) {
1e3baf05
DM
691 $kvm_api_version = $v;
692 }
693
694 $fh->close();
695
696 return $kvm_api_version;
697}
698
699my $kvm_user_version;
700
701sub kvm_user_version {
702
703 return $kvm_user_version if $kvm_user_version;
704
705 $kvm_user_version = 'unknown';
706
707 my $tmp = `kvm -help 2>/dev/null`;
19672434 708
fa7ae705 709 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?)[,\s]/) {
1e3baf05
DM
710 $kvm_user_version = $2;
711 }
712
713 return $kvm_user_version;
714
715}
716
717my $kernel_has_vhost_net = -c '/dev/vhost-net';
718
719sub disknames {
720 # order is important - used to autoselect boot disk
19672434 721 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
1e3baf05 722 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
cdb0931f
DA
723 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
724 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
1e3baf05
DM
725}
726
727sub valid_drivename {
728 my $dev = shift;
729
6b64503e 730 return defined($drivename_hash->{$dev});
1e3baf05
DM
731}
732
733sub option_exists {
734 my $key = shift;
735 return defined($confdesc->{$key});
19672434 736}
1e3baf05
DM
737
738sub nic_models {
739 return $nic_model_list;
740}
741
742sub os_list_description {
743
744 return {
745 other => 'Other',
746 wxp => 'Windows XP',
747 w2k => 'Windows 2000',
748 w2k3 =>, 'Windows 2003',
749 w2k8 => 'Windows 2008',
750 wvista => 'Windows Vista',
751 win7 => 'Windows 7',
a70ebde3 752 win8 => 'Windows 8/2012',
1e3baf05
DM
753 l24 => 'Linux 2.4',
754 l26 => 'Linux 2.6',
19672434 755 };
1e3baf05
DM
756}
757
1e3baf05
DM
758my $cdrom_path;
759
760sub get_cdrom_path {
761
762 return $cdrom_path if $cdrom_path;
763
764 return $cdrom_path = "/dev/cdrom" if -l "/dev/cdrom";
765 return $cdrom_path = "/dev/cdrom1" if -l "/dev/cdrom1";
766 return $cdrom_path = "/dev/cdrom2" if -l "/dev/cdrom2";
767}
768
769sub get_iso_path {
770 my ($storecfg, $vmid, $cdrom) = @_;
771
772 if ($cdrom eq 'cdrom') {
773 return get_cdrom_path();
774 } elsif ($cdrom eq 'none') {
775 return '';
776 } elsif ($cdrom =~ m|^/|) {
777 return $cdrom;
778 } else {
6b64503e 779 return PVE::Storage::path($storecfg, $cdrom);
1e3baf05
DM
780 }
781}
782
783# try to convert old style file names to volume IDs
784sub filename_to_volume_id {
785 my ($vmid, $file, $media) = @_;
786
787 if (!($file eq 'none' || $file eq 'cdrom' ||
788 $file =~ m|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
19672434 789
1e3baf05 790 return undef if $file =~ m|/|;
19672434 791
1e3baf05
DM
792 if ($media && $media eq 'cdrom') {
793 $file = "local:iso/$file";
794 } else {
795 $file = "local:$vmid/$file";
796 }
797 }
798
799 return $file;
800}
801
802sub verify_media_type {
803 my ($opt, $vtype, $media) = @_;
804
805 return if !$media;
806
807 my $etype;
808 if ($media eq 'disk') {
a125592c 809 $etype = 'images';
1e3baf05
DM
810 } elsif ($media eq 'cdrom') {
811 $etype = 'iso';
812 } else {
813 die "internal error";
814 }
815
816 return if ($vtype eq $etype);
19672434 817
1e3baf05
DM
818 raise_param_exc({ $opt => "unexpected media type ($vtype != $etype)" });
819}
820
821sub cleanup_drive_path {
822 my ($opt, $storecfg, $drive) = @_;
823
824 # try to convert filesystem paths to volume IDs
825
826 if (($drive->{file} !~ m/^(cdrom|none)$/) &&
827 ($drive->{file} !~ m|^/dev/.+|) &&
828 ($drive->{file} !~ m/^([^:]+):(.+)$/) &&
19672434 829 ($drive->{file} !~ m/^\d+$/)) {
1e3baf05
DM
830 my ($vtype, $volid) = PVE::Storage::path_to_volume_id($storecfg, $drive->{file});
831 raise_param_exc({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
832 $drive->{media} = 'cdrom' if !$drive->{media} && $vtype eq 'iso';
833 verify_media_type($opt, $vtype, $drive->{media});
834 $drive->{file} = $volid;
835 }
836
837 $drive->{media} = 'cdrom' if !$drive->{media} && $drive->{file} =~ m/^(cdrom|none)$/;
838}
839
840sub create_conf_nolock {
841 my ($vmid, $settings) = @_;
842
6b64503e 843 my $filename = config_file($vmid);
1e3baf05
DM
844
845 die "configuration file '$filename' already exists\n" if -f $filename;
19672434 846
1e3baf05
DM
847 my $defaults = load_defaults();
848
849 $settings->{name} = "vm$vmid" if !$settings->{name};
850 $settings->{memory} = $defaults->{memory} if !$settings->{memory};
851
852 my $data = '';
853 foreach my $opt (keys %$settings) {
854 next if !$confdesc->{$opt};
855
856 my $value = $settings->{$opt};
857 next if !$value;
858
859 $data .= "$opt: $value\n";
860 }
861
862 PVE::Tools::file_set_contents($filename, $data);
863}
864
b3c2bdd1
DM
865sub parse_hotplug_features {
866 my ($data) = @_;
867
868 my $res = {};
869
870 return $res if $data eq '0';
a1b7d579 871
b3c2bdd1
DM
872 $data = $confdesc->{hotplug}->{default} if $data eq '1';
873
45827685 874 foreach my $feature (PVE::Tools::split_list($data)) {
b3c2bdd1
DM
875 if ($feature =~ m/^(network|disk|cpu|memory|usb)$/) {
876 $res->{$1} = 1;
877 } else {
878 warn "ignoring unknown hotplug feature '$feature'\n";
879 }
880 }
881 return $res;
882}
883
884PVE::JSONSchema::register_format('pve-hotplug-features', \&pve_verify_hotplug_features);
885sub pve_verify_hotplug_features {
886 my ($value, $noerr) = @_;
887
888 return $value if parse_hotplug_features($value);
889
890 return undef if $noerr;
891
892 die "unable to parse hotplug option\n";
893}
894
f36ed4f4
DM
895my $parse_size = sub {
896 my ($value) = @_;
897
9bf371a6 898 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
f36ed4f4
DM
899 my ($size, $unit) = ($1, $3);
900 if ($unit) {
901 if ($unit eq 'K') {
902 $size = $size * 1024;
903 } elsif ($unit eq 'M') {
904 $size = $size * 1024 * 1024;
905 } elsif ($unit eq 'G') {
906 $size = $size * 1024 * 1024 * 1024;
907 }
908 }
909 return int($size);
910};
911
912my $format_size = sub {
913 my ($size) = @_;
914
915 $size = int($size);
916
917 my $kb = int($size/1024);
918 return $size if $kb*1024 != $size;
919
920 my $mb = int($kb/1024);
921 return "${kb}K" if $mb*1024 != $kb;
922
923 my $gb = int($mb/1024);
924 return "${mb}M" if $gb*1024 != $mb;
925
926 return "${gb}G";
927};
928
1e3baf05
DM
929# ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
930# [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
036e0e2b 931# [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
51f492cd 932# [,aio=native|threads][,discard=ignore|on][,iothread=on]
1e3baf05
DM
933
934sub parse_drive {
935 my ($key, $data) = @_;
936
937 my $res = {};
19672434 938
1e3baf05
DM
939 # $key may be undefined - used to verify JSON parameters
940 if (!defined($key)) {
941 $res->{interface} = 'unknown'; # should not harm when used to verify parameters
942 $res->{index} = 0;
943 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
944 $res->{interface} = $1;
945 $res->{index} = $2;
946 } else {
947 return undef;
948 }
949
950 foreach my $p (split (/,/, $data)) {
951 next if $p =~ m/^\s*$/;
952
6e11f143 953 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|mbps|mbps_max|bps_rd|mbps_rd|mbps_rd_max|bps_wr|mbps_wr|mbps_wr_max|iops|iops_max|iops_rd|iops_rd_max|iops_wr|iops_wr_max|size|discard|iothread|queues)=(.+)$/) {
1e3baf05
DM
954 my ($k, $v) = ($1, $2);
955
956 $k = 'file' if $k eq 'volume';
957
958 return undef if defined $res->{$k};
19672434 959
9bf371a6
DM
960 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
961 return undef if !$v || $v !~ m/^\d+/;
962 $k = "m$k";
963 $v = sprintf("%.3f", $v / (1024*1024));
964 }
1e3baf05
DM
965 $res->{$k} = $v;
966 } else {
967 if (!$res->{file} && $p !~ m/=/) {
968 $res->{file} = $p;
969 } else {
970 return undef;
971 }
972 }
973 }
974
975 return undef if !$res->{file};
976
bdf3f362
AD
977 if($res->{file} =~ m/\.(raw|cow|qcow|qcow2|vmdk|cloop)$/){
978 $res->{format} = $1;
979 }
980
19672434 981 return undef if $res->{cache} &&
e482cec3 982 $res->{cache} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
1e3baf05
DM
983 return undef if $res->{snapshot} && $res->{snapshot} !~ m/^(on|off)$/;
984 return undef if $res->{cyls} && $res->{cyls} !~ m/^\d+$/;
985 return undef if $res->{heads} && $res->{heads} !~ m/^\d+$/;
986 return undef if $res->{secs} && $res->{secs} !~ m/^\d+$/;
987 return undef if $res->{media} && $res->{media} !~ m/^(disk|cdrom)$/;
988 return undef if $res->{trans} && $res->{trans} !~ m/^(none|lba|auto)$/;
989 return undef if $res->{format} && $res->{format} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
990 return undef if $res->{rerror} && $res->{rerror} !~ m/^(ignore|report|stop)$/;
991 return undef if $res->{werror} && $res->{werror} !~ m/^(enospc|ignore|report|stop)$/;
992 return undef if $res->{backup} && $res->{backup} !~ m/^(yes|no)$/;
993 return undef if $res->{aio} && $res->{aio} !~ m/^(native|threads)$/;
8d87f8aa 994 return undef if $res->{discard} && $res->{discard} !~ m/^(ignore|on)$/;
51f492cd 995 return undef if $res->{iothread} && $res->{iothread} !~ m/^(on)$/;
6e11f143 996 return undef if $res->{queues} && ($res->{queues} !~ m/^\d+$/ || $res->{queues} < 2);
be190583 997
9bf371a6
DM
998 return undef if $res->{mbps_rd} && $res->{mbps};
999 return undef if $res->{mbps_wr} && $res->{mbps};
1000
1001 return undef if $res->{mbps} && $res->{mbps} !~ m/^\d+(\.\d+)?$/;
74edd76b 1002 return undef if $res->{mbps_max} && $res->{mbps_max} !~ m/^\d+(\.\d+)?$/;
9bf371a6 1003 return undef if $res->{mbps_rd} && $res->{mbps_rd} !~ m/^\d+(\.\d+)?$/;
74edd76b 1004 return undef if $res->{mbps_rd_max} && $res->{mbps_rd_max} !~ m/^\d+(\.\d+)?$/;
9bf371a6 1005 return undef if $res->{mbps_wr} && $res->{mbps_wr} !~ m/^\d+(\.\d+)?$/;
74edd76b 1006 return undef if $res->{mbps_wr_max} && $res->{mbps_wr_max} !~ m/^\d+(\.\d+)?$/;
9bf371a6 1007
affd2f88
AD
1008 return undef if $res->{iops_rd} && $res->{iops};
1009 return undef if $res->{iops_wr} && $res->{iops};
74edd76b
AD
1010
1011
affd2f88 1012 return undef if $res->{iops} && $res->{iops} !~ m/^\d+$/;
74edd76b 1013 return undef if $res->{iops_max} && $res->{iops_max} !~ m/^\d+$/;
affd2f88 1014 return undef if $res->{iops_rd} && $res->{iops_rd} !~ m/^\d+$/;
74edd76b 1015 return undef if $res->{iops_rd_max} && $res->{iops_rd_max} !~ m/^\d+$/;
affd2f88 1016 return undef if $res->{iops_wr} && $res->{iops_wr} !~ m/^\d+$/;
74edd76b 1017 return undef if $res->{iops_wr_max} && $res->{iops_wr_max} !~ m/^\d+$/;
affd2f88
AD
1018
1019
24afaca0 1020 if ($res->{size}) {
be190583 1021 return undef if !defined($res->{size} = &$parse_size($res->{size}));
24afaca0
DM
1022 }
1023
1e3baf05
DM
1024 if ($res->{media} && ($res->{media} eq 'cdrom')) {
1025 return undef if $res->{snapshot} || $res->{trans} || $res->{format};
19672434 1026 return undef if $res->{heads} || $res->{secs} || $res->{cyls};
1e3baf05
DM
1027 return undef if $res->{interface} eq 'virtio';
1028 }
1029
1030 # rerror does not work with scsi drives
1031 if ($res->{rerror}) {
1032 return undef if $res->{interface} eq 'scsi';
1033 }
1034
1035 return $res;
1036}
1037
74edd76b 1038my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio discard iops iops_rd iops_wr iops_max iops_rd_max iops_wr_max);
1e3baf05
DM
1039
1040sub print_drive {
1041 my ($vmid, $drive) = @_;
1042
1043 my $opts = '';
6e11f143 1044 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'mbps_max', 'mbps_rd_max', 'mbps_wr_max', 'backup', 'iothread', 'queues') {
1e3baf05
DM
1045 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1046 }
1047
24afaca0
DM
1048 if ($drive->{size}) {
1049 $opts .= ",size=" . &$format_size($drive->{size});
1050 }
1051
1e3baf05
DM
1052 return "$drive->{file}$opts";
1053}
1054
28ef82d3
DM
1055sub scsi_inquiry {
1056 my($fh, $noerr) = @_;
1057
1058 my $SG_IO = 0x2285;
1059 my $SG_GET_VERSION_NUM = 0x2282;
1060
1061 my $versionbuf = "\x00" x 8;
1062 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
1063 if (!$ret) {
1064 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
1065 return undef;
1066 }
97d62eb7 1067 my $version = unpack("I", $versionbuf);
28ef82d3
DM
1068 if ($version < 30000) {
1069 die "scsi generic interface too old\n" if !$noerr;
1070 return undef;
1071 }
97d62eb7 1072
28ef82d3
DM
1073 my $buf = "\x00" x 36;
1074 my $sensebuf = "\x00" x 8;
f334aa3e 1075 my $cmd = pack("C x3 C x1", 0x12, 36);
97d62eb7 1076
28ef82d3
DM
1077 # see /usr/include/scsi/sg.h
1078 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";
1079
97d62eb7
DM
1080 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
1081 length($sensebuf), 0, length($buf), $buf,
28ef82d3
DM
1082 $cmd, $sensebuf, 6000);
1083
1084 $ret = ioctl($fh, $SG_IO, $packet);
1085 if (!$ret) {
1086 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
1087 return undef;
1088 }
97d62eb7 1089
28ef82d3
DM
1090 my @res = unpack($sg_io_hdr_t, $packet);
1091 if ($res[17] || $res[18]) {
1092 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
1093 return undef;
1094 }
1095
1096 my $res = {};
09984754 1097 (my $byte0, my $byte1, $res->{vendor},
28ef82d3
DM
1098 $res->{product}, $res->{revision}) = unpack("C C x6 A8 A16 A4", $buf);
1099
09984754
DM
1100 $res->{removable} = $byte1 & 128 ? 1 : 0;
1101 $res->{type} = $byte0 & 31;
1102
28ef82d3
DM
1103 return $res;
1104}
1105
1106sub path_is_scsi {
1107 my ($path) = @_;
1108
1109 my $fh = IO::File->new("+<$path") || return undef;
1110 my $res = scsi_inquiry($fh, 1);
1111 close($fh);
1112
1113 return $res;
1114}
1115
db656e5f
DM
1116sub machine_type_is_q35 {
1117 my ($conf) = @_;
b467f79a 1118
db656e5f
DM
1119 return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
1120}
1121
1122sub print_tabletdevice_full {
1123 my ($conf) = @_;
b467f79a 1124
db656e5f
DM
1125 my $q35 = machine_type_is_q35($conf);
1126
1127 # we use uhci for old VMs because tablet driver was buggy in older qemu
1128 my $usbbus = $q35 ? "ehci" : "uhci";
b467f79a 1129
db656e5f
DM
1130 return "usb-tablet,id=tablet,bus=$usbbus.0,port=1";
1131}
1132
ca916ecc 1133sub print_drivedevice_full {
5bdcf937 1134 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
ca916ecc
DA
1135
1136 my $device = '';
1137 my $maxdev = 0;
19672434 1138
ca916ecc 1139 if ($drive->{interface} eq 'virtio') {
5bdcf937 1140 my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}", $bridges);
2ed36a41 1141 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
51f492cd 1142 $device .= ",iothread=iothread-$drive->{interface}$drive->{index}" if $drive->{iothread};
2ed36a41 1143 } elsif ($drive->{interface} eq 'scsi') {
6731a4cf 1144
ee034f5c 1145 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
2ed36a41
DM
1146 my $unit = $drive->{index} % $maxdev;
1147 my $devicetype = 'hd';
231f2e13
DA
1148 my $path = '';
1149 if (drive_is_cdrom($drive)) {
1150 $devicetype = 'cd';
29b19529 1151 } else {
231f2e13
DA
1152 if ($drive->{file} =~ m|^/|) {
1153 $path = $drive->{file};
1154 } else {
1155 $path = PVE::Storage::path($storecfg, $drive->{file});
1156 }
d454d040
AD
1157
1158 if($path =~ m/^iscsi\:\/\//){
29b19529
DM
1159 $devicetype = 'generic';
1160 } else {
09984754
DM
1161 if (my $info = path_is_scsi($path)) {
1162 if ($info->{type} == 0) {
1163 $devicetype = 'block';
1164 } elsif ($info->{type} == 1) { # tape
1165 $devicetype = 'generic';
1166 }
1167 }
d454d040 1168 }
231f2e13 1169 }
ca916ecc 1170
5b952ff5 1171 if (!$conf->{scsihw} || ($conf->{scsihw} =~ m/^lsi/)){
6731a4cf 1172 $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdd20088 1173 } else {
6731a4cf 1174 $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,channel=0,scsi-id=0,lun=$drive->{index},drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdd20088
AD
1175 }
1176
2ed36a41
DM
1177 } elsif ($drive->{interface} eq 'ide'){
1178 $maxdev = 2;
1179 my $controller = int($drive->{index} / $maxdev);
1180 my $unit = $drive->{index} % $maxdev;
1181 my $devicetype = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
1182
7ebe888a 1183 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdb0931f
DA
1184 } elsif ($drive->{interface} eq 'sata'){
1185 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1186 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1187 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
2ed36a41
DM
1188 } elsif ($drive->{interface} eq 'usb') {
1189 die "implement me";
1190 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1191 } else {
1192 die "unsupported interface type";
ca916ecc
DA
1193 }
1194
3b408e82
DM
1195 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex};
1196
ca916ecc
DA
1197 return $device;
1198}
1199
15b21acc 1200sub get_initiator_name {
46f58b5f 1201 my $initiator;
15b21acc 1202
46f58b5f
DM
1203 my $fh = IO::File->new('/etc/iscsi/initiatorname.iscsi') || return undef;
1204 while (defined(my $line = <$fh>)) {
1205 next if $line !~ m/^\s*InitiatorName\s*=\s*([\.\-:\w]+)/;
15b21acc
MR
1206 $initiator = $1;
1207 last;
1208 }
46f58b5f
DM
1209 $fh->close();
1210
15b21acc
MR
1211 return $initiator;
1212}
1213
1e3baf05
DM
1214sub print_drive_full {
1215 my ($storecfg, $vmid, $drive) = @_;
1216
1217 my $opts = '';
1218 foreach my $o (@qemu_drive_options) {
3b408e82 1219 next if $o eq 'bootindex';
1e3baf05 1220 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
19672434 1221 }
1e3baf05 1222
9bf371a6
DM
1223 foreach my $o (qw(bps bps_rd bps_wr)) {
1224 my $v = $drive->{"m$o"};
1225 $opts .= ",$o=" . int($v*1024*1024) if $v;
1226 }
1227
3f548708
AD
1228 # aio native works only with O_DIRECT
1229 if (!$drive->{aio}) {
1230 if(!$drive->{cache} || $drive->{cache} eq 'none' || $drive->{cache} eq 'directsync') {
1231 $opts .= ",aio=native";
1232 } else {
1233 $opts .= ",aio=threads";
1234 }
1235 }
1236
1e3baf05
DM
1237
1238 my $path;
1239 my $volid = $drive->{file};
6b64503e
DM
1240 if (drive_is_cdrom($drive)) {
1241 $path = get_iso_path($storecfg, $vmid, $volid);
1e3baf05
DM
1242 } else {
1243 if ($volid =~ m|^/|) {
1244 $path = $volid;
1245 } else {
6b64503e 1246 $path = PVE::Storage::path($storecfg, $volid);
1e3baf05
DM
1247 }
1248 }
1249
ef86170e 1250 $opts .= ",cache=none" if !$drive->{cache} && !drive_is_cdrom($drive);
11490cf2 1251
f1e05305
AD
1252 my $detectzeroes = $drive->{discard} ? "unmap" : "on";
1253 $opts .= ",detect-zeroes=$detectzeroes" if !drive_is_cdrom($drive);
1254
1e3baf05
DM
1255 my $pathinfo = $path ? "file=$path," : '';
1256
3ebfcc86 1257 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1e3baf05
DM
1258}
1259
cc4d6182 1260sub print_netdevice_full {
5bdcf937 1261 my ($vmid, $conf, $net, $netid, $bridges) = @_;
cc4d6182
DA
1262
1263 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
1264
1265 my $device = $net->{model};
1266 if ($net->{model} eq 'virtio') {
1267 $device = 'virtio-net-pci';
1268 };
1269
5bdcf937 1270 my $pciaddr = print_pci_addr("$netid", $bridges);
5e2068d2 1271 my $tmpstr = "$device,mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
a9410357
AD
1272 if ($net->{queues} && $net->{queues} > 1 && $net->{model} eq 'virtio'){
1273 #Consider we have N queues, the number of vectors needed is 2*N + 2 (plus one config interrupt and control vq)
1274 my $vectors = $net->{queues} * 2 + 2;
1275 $tmpstr .= ",vectors=$vectors,mq=on";
1276 }
cc4d6182
DA
1277 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex} ;
1278 return $tmpstr;
1279}
1280
1281sub print_netdev_full {
1282 my ($vmid, $conf, $net, $netid) = @_;
1283
1284 my $i = '';
1285 if ($netid =~ m/^net(\d+)$/) {
1286 $i = int($1);
1287 }
1288
1289 die "got strange net id '$i'\n" if $i >= ${MAX_NETS};
1290
1291 my $ifname = "tap${vmid}i$i";
1292
1293 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1294 die "interface name '$ifname' is too long (max 15 character)\n"
1295 if length($ifname) >= 16;
1296
1297 my $vhostparam = '';
1298 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model} eq 'virtio';
1299
1300 my $vmname = $conf->{name} || "vm$vmid";
1301
a9410357
AD
1302 my $netdev = "";
1303
cc4d6182 1304 if ($net->{bridge}) {
a9410357 1305 $netdev = "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown$vhostparam";
cc4d6182 1306 } else {
a9410357 1307 $netdev = "type=user,id=$netid,hostname=$vmname";
cc4d6182 1308 }
a9410357
AD
1309
1310 $netdev .= ",queues=$net->{queues}" if ($net->{queues} && $net->{model} eq 'virtio');
1311
1312 return $netdev;
cc4d6182 1313}
1e3baf05
DM
1314
1315sub drive_is_cdrom {
1316 my ($drive) = @_;
1317
1318 return $drive && $drive->{media} && ($drive->{media} eq 'cdrom');
1319
1320}
1321
2ed5d572
AD
1322sub parse_numa {
1323 my ($data) = @_;
1324
1325 my $res = {};
1326
1327 foreach my $kvp (split(/,/, $data)) {
1328
1329 if ($kvp =~ m/^memory=(\S+)$/) {
1330 $res->{memory} = $1;
1331 } elsif ($kvp =~ m/^policy=(preferred|bind|interleave)$/) {
1332 $res->{policy} = $1;
1333 } elsif ($kvp =~ m/^cpus=(\d+)(-(\d+))?$/) {
1334 $res->{cpus}->{start} = $1;
1335 $res->{cpus}->{end} = $3;
1336 } elsif ($kvp =~ m/^hostnodes=(\d+)(-(\d+))?$/) {
1337 $res->{hostnodes}->{start} = $1;
1338 $res->{hostnodes}->{end} = $3;
1339 } else {
1340 return undef;
1341 }
1342 }
1343
1344 return $res;
1345}
1346
040b06b7
DA
1347sub parse_hostpci {
1348 my ($value) = @_;
1349
1350 return undef if !$value;
1351
0cea6a01
DM
1352
1353 my @list = split(/,/, $value);
1354 my $found;
1355
040b06b7 1356 my $res = {};
0cea6a01 1357 foreach my $kv (@list) {
040b06b7 1358
4543ecf0 1359 if ($kv =~ m/^(host=)?([a-f0-9]{2}:[a-f0-9]{2})(\.([a-f0-9]))?$/) {
0cea6a01 1360 $found = 1;
4543ecf0
AD
1361 if(defined($4)){
1362 push @{$res->{pciid}}, { id => $2 , function => $4};
1363
1364 }else{
1365 my $pcidevices = lspci($2);
1366 $res->{pciid} = $pcidevices->{$2};
1367 }
0cea6a01
DM
1368 } elsif ($kv =~ m/^driver=(kvm|vfio)$/) {
1369 $res->{driver} = $1;
1370 } elsif ($kv =~ m/^rombar=(on|off)$/) {
1371 $res->{rombar} = $1;
2e3b7e2a
AD
1372 } elsif ($kv =~ m/^x-vga=(on|off)$/) {
1373 $res->{'x-vga'} = $1;
1374 } elsif ($kv =~ m/^pcie=(\d+)$/) {
1375 $res->{pcie} = 1 if $1 == 1;
0cea6a01
DM
1376 } else {
1377 warn "unknown hostpci setting '$kv'\n";
1378 }
040b06b7
DA
1379 }
1380
0cea6a01
DM
1381 return undef if !$found;
1382
040b06b7
DA
1383 return $res;
1384}
1385
1e3baf05
DM
1386# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1387sub parse_net {
1388 my ($data) = @_;
1389
1390 my $res = {};
1391
6b64503e 1392 foreach my $kvp (split(/,/, $data)) {
1e3baf05 1393
55034103 1394 if ($kvp =~ m/^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er|vmxnet3)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
6b64503e 1395 my $model = lc($1);
92f0fedc 1396 my $mac = defined($3) ? uc($3) : PVE::Tools::random_ether_addr();
1e3baf05
DM
1397 $res->{model} = $model;
1398 $res->{macaddr} = $mac;
1399 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1400 $res->{bridge} = $1;
a9410357
AD
1401 } elsif ($kvp =~ m/^queues=(\d+)$/) {
1402 $res->{queues} = $1;
1e3baf05
DM
1403 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1404 $res->{rate} = $1;
5070f384
DA
1405 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1406 $res->{tag} = $1;
25088687 1407 } elsif ($kvp =~ m/^firewall=([01])$/) {
2dd4aa4c 1408 $res->{firewall} = $1;
25088687
DM
1409 } elsif ($kvp =~ m/^link_down=([01])$/) {
1410 $res->{link_down} = $1;
1e3baf05
DM
1411 } else {
1412 return undef;
1413 }
19672434 1414
1e3baf05
DM
1415 }
1416
1417 return undef if !$res->{model};
1418
1419 return $res;
1420}
1421
1422sub print_net {
1423 my $net = shift;
1424
1425 my $res = "$net->{model}";
1426 $res .= "=$net->{macaddr}" if $net->{macaddr};
1427 $res .= ",bridge=$net->{bridge}" if $net->{bridge};
1428 $res .= ",rate=$net->{rate}" if $net->{rate};
18744ba3 1429 $res .= ",tag=$net->{tag}" if $net->{tag};
25088687
DM
1430 $res .= ",firewall=1" if $net->{firewall};
1431 $res .= ",link_down=1" if $net->{link_down};
8b6c5579 1432 $res .= ",queues=$net->{queues}" if $net->{queues};
1e3baf05
DM
1433
1434 return $res;
1435}
1436
1437sub add_random_macs {
1438 my ($settings) = @_;
1439
1440 foreach my $opt (keys %$settings) {
1441 next if $opt !~ m/^net(\d+)$/;
1442 my $net = parse_net($settings->{$opt});
1443 next if !$net;
1444 $settings->{$opt} = print_net($net);
1445 }
1446}
1447
1448sub add_unused_volume {
1858638f 1449 my ($config, $volid) = @_;
1e3baf05
DM
1450
1451 my $key;
1452 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1453 my $test = "unused$ind";
1454 if (my $vid = $config->{$test}) {
1455 return if $vid eq $volid; # do not add duplicates
1456 } else {
1457 $key = $test;
19672434 1458 }
1e3baf05
DM
1459 }
1460
1461 die "To many unused volume - please delete them first.\n" if !$key;
97d62eb7 1462
1858638f 1463 $config->{$key} = $volid;
1e3baf05 1464
1858638f 1465 return $key;
1e3baf05
DM
1466}
1467
055d554d
DM
1468sub vm_is_volid_owner {
1469 my ($storecfg, $vmid, $volid) = @_;
1470
1471 if ($volid !~ m|^/|) {
1472 my ($path, $owner);
1473 eval { ($path, $owner) = PVE::Storage::path($storecfg, $volid); };
1474 if ($owner && ($owner == $vmid)) {
1475 return 1;
1476 }
1477 }
1478
1479 return undef;
1480}
1481
1482sub vmconfig_delete_pending_option {
1483 my ($conf, $key) = @_;
1484
1485 delete $conf->{pending}->{$key};
1486 my $pending_delete_hash = { $key => 1 };
1487 foreach my $opt (PVE::Tools::split_list($conf->{pending}->{delete})) {
1488 $pending_delete_hash->{$opt} = 1;
1489 }
1490 $conf->{pending}->{delete} = join(',', keys %$pending_delete_hash);
1491}
1492
1493sub vmconfig_undelete_pending_option {
1494 my ($conf, $key) = @_;
1495
1496 my $pending_delete_hash = {};
1497 foreach my $opt (PVE::Tools::split_list($conf->{pending}->{delete})) {
1498 $pending_delete_hash->{$opt} = 1;
1499 }
1500 delete $pending_delete_hash->{$key};
1501
1502 my @keylist = keys %$pending_delete_hash;
1503 if (scalar(@keylist)) {
1504 $conf->{pending}->{delete} = join(',', @keylist);
1505 } else {
1506 delete $conf->{pending}->{delete};
1507 }
1508}
1509
1510sub vmconfig_register_unused_drive {
1511 my ($storecfg, $vmid, $conf, $drive) = @_;
1512
1513 if (!drive_is_cdrom($drive)) {
1514 my $volid = $drive->{file};
1515 if (vm_is_volid_owner($storecfg, $vmid, $volid)) {
1516 add_unused_volume($conf, $volid, $vmid);
1517 }
1518 }
1519}
1520
c750e90a
DM
1521sub vmconfig_cleanup_pending {
1522 my ($conf) = @_;
1523
1524 # remove pending changes when nothing changed
1525 my $changes;
1526 foreach my $opt (keys %{$conf->{pending}}) {
1527 if (defined($conf->{$opt}) && ($conf->{pending}->{$opt} eq $conf->{$opt})) {
1528 $changes = 1;
1529 delete $conf->{pending}->{$opt};
1530 }
1531 }
1532
1533 # remove delete if option is not set
1534 my $pending_delete_hash = {};
1535 foreach my $opt (PVE::Tools::split_list($conf->{pending}->{delete})) {
1536 if (defined($conf->{$opt})) {
1537 $pending_delete_hash->{$opt} = 1;
1538 } else {
1539 $changes = 1;
1540 }
1541 }
1542
1543 my @keylist = keys %$pending_delete_hash;
1544 if (scalar(@keylist)) {
1545 $conf->{pending}->{delete} = join(',', @keylist);
1546 } else {
1547 delete $conf->{pending}->{delete};
1548 }
1549
1550 return $changes;
1551}
1552
2796e7d5
DM
1553my $valid_smbios1_options = {
1554 manufacturer => '\S+',
1555 product => '\S+',
1556 version => '\S+',
1557 serial => '\S+',
1558 uuid => '[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}',
1559 sku => '\S+',
1560 family => '\S+',
1561};
1562
1563# smbios: [manufacturer=str][,product=str][,version=str][,serial=str][,uuid=uuid][,sku=str][,family=str]
1564sub parse_smbios1 {
1565 my ($data) = @_;
1566
1567 my $res = {};
1568
1569 foreach my $kvp (split(/,/, $data)) {
1570 return undef if $kvp !~ m/^(\S+)=(.+)$/;
1571 my ($k, $v) = split(/=/, $kvp);
1572 return undef if !defined($k) || !defined($v);
1573 return undef if !$valid_smbios1_options->{$k};
1574 return undef if $v !~ m/^$valid_smbios1_options->{$k}$/;
1575 $res->{$k} = $v;
1576 }
1577
1578 return $res;
1579}
1580
cd11416f
DM
1581sub print_smbios1 {
1582 my ($smbios1) = @_;
1583
1584 my $data = '';
1585 foreach my $k (keys %$smbios1) {
1586 next if !defined($smbios1->{$k});
1587 next if !$valid_smbios1_options->{$k};
1588 $data .= ',' if $data;
1589 $data .= "$k=$smbios1->{$k}";
1590 }
1591 return $data;
1592}
1593
2796e7d5
DM
1594PVE::JSONSchema::register_format('pve-qm-smbios1', \&verify_smbios1);
1595sub verify_smbios1 {
1596 my ($value, $noerr) = @_;
1597
1598 return $value if parse_smbios1($value);
1599
1600 return undef if $noerr;
1601
1602 die "unable to parse smbios (type 1) options\n";
1603}
1604
1e3baf05
DM
1605PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1606sub verify_bootdisk {
1607 my ($value, $noerr) = @_;
1608
19672434 1609 return $value if valid_drivename($value);
1e3baf05
DM
1610
1611 return undef if $noerr;
1612
1613 die "invalid boot disk '$value'\n";
1614}
1615
2ed5d572
AD
1616PVE::JSONSchema::register_format('pve-qm-numanode', \&verify_numa);
1617sub verify_numa {
1618 my ($value, $noerr) = @_;
1619
1620 return $value if parse_numa($value);
1621
1622 return undef if $noerr;
1623
1624 die "unable to parse numa options\n";
1625}
1626
1e3baf05
DM
1627PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1628sub verify_net {
1629 my ($value, $noerr) = @_;
1630
1631 return $value if parse_net($value);
1632
1633 return undef if $noerr;
19672434 1634
1e3baf05
DM
1635 die "unable to parse network options\n";
1636}
1637
1638PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1639sub verify_drive {
1640 my ($value, $noerr) = @_;
1641
6b64503e 1642 return $value if parse_drive(undef, $value);
1e3baf05
DM
1643
1644 return undef if $noerr;
19672434 1645
1e3baf05
DM
1646 die "unable to parse drive options\n";
1647}
1648
1649PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1650sub verify_hostpci {
1651 my ($value, $noerr) = @_;
1652
040b06b7
DA
1653 return $value if parse_hostpci($value);
1654
1655 return undef if $noerr;
1656
1657 die "unable to parse pci id\n";
1e3baf05
DM
1658}
1659
0ea9541d
DM
1660PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1661sub verify_watchdog {
1662 my ($value, $noerr) = @_;
1663
1664 return $value if parse_watchdog($value);
1665
1666 return undef if $noerr;
19672434 1667
0ea9541d
DM
1668 die "unable to parse watchdog options\n";
1669}
1670
1671sub parse_watchdog {
1672 my ($value) = @_;
1673
1674 return undef if !$value;
1675
1676 my $res = {};
1677
6b64503e 1678 foreach my $p (split(/,/, $value)) {
0ea9541d
DM
1679 next if $p =~ m/^\s*$/;
1680
1681 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1682 $res->{model} = $2;
1683 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1684 $res->{action} = $2;
1685 } else {
1686 return undef;
1687 }
1688 }
1689
1690 return $res;
1691}
1692
1e3baf05
DM
1693sub parse_usb_device {
1694 my ($value) = @_;
1695
1696 return undef if !$value;
1697
6b64503e 1698 my @dl = split(/,/, $value);
1e3baf05
DM
1699 my $found;
1700
1701 my $res = {};
1702 foreach my $v (@dl) {
036e0e2b 1703 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1e3baf05 1704 $found = 1;
036e0e2b
DM
1705 $res->{vendorid} = $2;
1706 $res->{productid} = $4;
1e3baf05
DM
1707 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1708 $found = 1;
1709 $res->{hostbus} = $1;
1710 $res->{hostport} = $2;
80401dd8
DM
1711 } elsif ($v =~ m/^spice$/) {
1712 $found = 1;
1713 $res->{spice} = 1;
1e3baf05
DM
1714 } else {
1715 return undef;
1716 }
1717 }
1718 return undef if !$found;
1719
1720 return $res;
1721}
19672434 1722
1e3baf05
DM
1723PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1724sub verify_usb_device {
1725 my ($value, $noerr) = @_;
1726
1727 return $value if parse_usb_device($value);
1728
1729 return undef if $noerr;
19672434 1730
1e3baf05
DM
1731 die "unable to parse usb device\n";
1732}
1733
1e3baf05
DM
1734# add JSON properties for create and set function
1735sub json_config_properties {
1736 my $prop = shift;
1737
1738 foreach my $opt (keys %$confdesc) {
18bfb361 1739 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1e3baf05
DM
1740 $prop->{$opt} = $confdesc->{$opt};
1741 }
1742
1743 return $prop;
1744}
1745
1746sub check_type {
1747 my ($key, $value) = @_;
1748
1749 die "unknown setting '$key'\n" if !$confdesc->{$key};
1750
1751 my $type = $confdesc->{$key}->{type};
1752
6b64503e 1753 if (!defined($value)) {
1e3baf05
DM
1754 die "got undefined value\n";
1755 }
1756
1757 if ($value =~ m/[\n\r]/) {
1758 die "property contains a line feed\n";
1759 }
1760
1761 if ($type eq 'boolean') {
19672434
DM
1762 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1763 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1764 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1765 } elsif ($type eq 'integer') {
1766 return int($1) if $value =~ m/^(\d+)$/;
1767 die "type check ('integer') failed - got '$value'\n";
04432191
AD
1768 } elsif ($type eq 'number') {
1769 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
1770 die "type check ('number') failed - got '$value'\n";
1e3baf05
DM
1771 } elsif ($type eq 'string') {
1772 if (my $fmt = $confdesc->{$key}->{format}) {
1773 if ($fmt eq 'pve-qm-drive') {
1774 # special case - we need to pass $key to parse_drive()
6b64503e 1775 my $drive = parse_drive($key, $value);
1e3baf05
DM
1776 return $value if $drive;
1777 die "unable to parse drive options\n";
1778 }
1779 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1780 return $value;
1781 }
1e3baf05 1782 $value =~ s/^\"(.*)\"$/$1/;
19672434 1783 return $value;
1e3baf05
DM
1784 } else {
1785 die "internal error"
1786 }
1787}
1788
191435c6
DM
1789sub lock_config_full {
1790 my ($vmid, $timeout, $code, @param) = @_;
1e3baf05 1791
6b64503e 1792 my $filename = config_file_lock($vmid);
1e3baf05 1793
191435c6 1794 my $res = lock_file($filename, $timeout, $code, @param);
1e3baf05
DM
1795
1796 die $@ if $@;
5fdbe4f0
DM
1797
1798 return $res;
1e3baf05
DM
1799}
1800
4e4f83fe
DM
1801sub lock_config_mode {
1802 my ($vmid, $timeout, $shared, $code, @param) = @_;
6116f729
DM
1803
1804 my $filename = config_file_lock($vmid);
1805
4e4f83fe 1806 my $res = lock_file_full($filename, $timeout, $shared, $code, @param);
6116f729
DM
1807
1808 die $@ if $@;
1809
1810 return $res;
1811}
1812
191435c6
DM
1813sub lock_config {
1814 my ($vmid, $code, @param) = @_;
1815
1816 return lock_config_full($vmid, 10, $code, @param);
1817}
1818
1e3baf05 1819sub cfs_config_path {
a78ccf26 1820 my ($vmid, $node) = @_;
1e3baf05 1821
a78ccf26
DM
1822 $node = $nodename if !$node;
1823 return "nodes/$node/qemu-server/$vmid.conf";
1e3baf05
DM
1824}
1825
040b06b7
DA
1826sub check_iommu_support{
1827 #fixme : need to check IOMMU support
1828 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1829
1830 my $iommu=1;
1831 return $iommu;
1832
1833}
1834
1e3baf05 1835sub config_file {
a78ccf26 1836 my ($vmid, $node) = @_;
1e3baf05 1837
a78ccf26 1838 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1839 return "/etc/pve/$cfspath";
1840}
1841
1842sub config_file_lock {
1843 my ($vmid) = @_;
1844
1845 return "$lock_dir/lock-$vmid.conf";
1846}
1847
1848sub touch_config {
1849 my ($vmid) = @_;
1850
6b64503e 1851 my $conf = config_file($vmid);
1e3baf05
DM
1852 utime undef, undef, $conf;
1853}
1854
1e3baf05 1855sub destroy_vm {
a6af7b3e 1856 my ($storecfg, $vmid, $keep_empty_config) = @_;
1e3baf05 1857
6b64503e 1858 my $conffile = config_file($vmid);
1e3baf05 1859
6b64503e 1860 my $conf = load_config($vmid);
1e3baf05 1861
6b64503e 1862 check_lock($conf);
1e3baf05 1863
19672434 1864 # only remove disks owned by this VM
1e3baf05
DM
1865 foreach_drive($conf, sub {
1866 my ($ds, $drive) = @_;
1867
6b64503e 1868 return if drive_is_cdrom($drive);
1e3baf05
DM
1869
1870 my $volid = $drive->{file};
ed221350 1871
ff1a2432 1872 return if !$volid || $volid =~ m|^/|;
1e3baf05 1873
6b64503e 1874 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
ff1a2432 1875 return if !$path || !$owner || ($owner != $vmid);
1e3baf05 1876
6b64503e 1877 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1878 });
19672434 1879
a6af7b3e 1880 if ($keep_empty_config) {
9c502e26 1881 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
a6af7b3e
DM
1882 } else {
1883 unlink $conffile;
1884 }
1e3baf05
DM
1885
1886 # also remove unused disk
1887 eval {
6b64503e 1888 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
1889
1890 eval {
6b64503e 1891 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 1892 my ($volid, $sid, $volname, $d) = @_;
6b64503e 1893 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
1894 });
1895 };
1896 warn $@ if $@;
1897
1898 };
1899 warn $@ if $@;
1900}
1901
1e3baf05 1902sub load_config {
7e8dcf2c 1903 my ($vmid, $node) = @_;
1e3baf05 1904
7e8dcf2c 1905 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1906
1907 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1908
1909 die "no such VM ('$vmid')\n" if !defined($conf);
1910
1911 return $conf;
19672434 1912}
1e3baf05
DM
1913
1914sub parse_vm_config {
1915 my ($filename, $raw) = @_;
1916
1917 return undef if !defined($raw);
1918
554ac7e7 1919 my $res = {
fc1ddcdc 1920 digest => Digest::SHA::sha1_hex($raw),
0d18dcfc 1921 snapshots => {},
0d732d16 1922 pending => {},
554ac7e7 1923 };
1e3baf05 1924
19672434 1925 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1926 || die "got strange filename '$filename'";
1927
1928 my $vmid = $1;
1929
0d18dcfc 1930 my $conf = $res;
0581fe4f 1931 my $descr = '';
e297c490 1932 my $section = '';
0581fe4f 1933
0d18dcfc
DM
1934 my @lines = split(/\n/, $raw);
1935 foreach my $line (@lines) {
1e3baf05 1936 next if $line =~ m/^\s*$/;
be190583 1937
eab09f4e 1938 if ($line =~ m/^\[PENDING\]\s*$/i) {
e297c490 1939 $section = 'pending';
0d732d16
DM
1940 $conf->{description} = $descr if $descr;
1941 $descr = '';
e297c490 1942 $conf = $res->{$section} = {};
eab09f4e
AD
1943 next;
1944
0d732d16 1945 } elsif ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
e297c490 1946 $section = $1;
0d18dcfc 1947 $conf->{description} = $descr if $descr;
782f4f75 1948 $descr = '';
e297c490 1949 $conf = $res->{snapshots}->{$section} = {};
0d18dcfc
DM
1950 next;
1951 }
1e3baf05 1952
0581fe4f
DM
1953 if ($line =~ m/^\#(.*)\s*$/) {
1954 $descr .= PVE::Tools::decode_text($1) . "\n";
1955 next;
1956 }
1957
1e3baf05 1958 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
0581fe4f 1959 $descr .= PVE::Tools::decode_text($2);
0d18dcfc
DM
1960 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1961 $conf->{snapstate} = $1;
1e3baf05
DM
1962 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1963 my $key = $1;
1964 my $value = $2;
0d18dcfc 1965 $conf->{$key} = $value;
ef824322 1966 } elsif ($line =~ m/^delete:\s*(.*\S)\s*$/) {
e297c490 1967 my $value = $1;
ef824322
DM
1968 if ($section eq 'pending') {
1969 $conf->{delete} = $value; # we parse this later
1970 } else {
1971 warn "vm $vmid - propertry 'delete' is only allowed in [PENDING]\n";
eab09f4e 1972 }
1e3baf05
DM
1973 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1974 my $key = $1;
1975 my $value = $2;
1976 eval { $value = check_type($key, $value); };
1977 if ($@) {
1978 warn "vm $vmid - unable to parse value of '$key' - $@";
1979 } else {
1980 my $fmt = $confdesc->{$key}->{format};
1981 if ($fmt && $fmt eq 'pve-qm-drive') {
1982 my $v = parse_drive($key, $value);
1983 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1984 $v->{file} = $volid;
6b64503e 1985 $value = print_drive($vmid, $v);
1e3baf05
DM
1986 } else {
1987 warn "vm $vmid - unable to parse value of '$key'\n";
1988 next;
1989 }
1990 }
1991
1992 if ($key eq 'cdrom') {
0d18dcfc 1993 $conf->{ide2} = $value;
1e3baf05 1994 } else {
0d18dcfc 1995 $conf->{$key} = $value;
1e3baf05
DM
1996 }
1997 }
1998 }
1999 }
2000
0d18dcfc 2001 $conf->{description} = $descr if $descr;
0581fe4f 2002
0d18dcfc 2003 delete $res->{snapstate}; # just to be sure
1e3baf05
DM
2004
2005 return $res;
2006}
2007
1858638f
DM
2008sub write_vm_config {
2009 my ($filename, $conf) = @_;
1e3baf05 2010
0d18dcfc
DM
2011 delete $conf->{snapstate}; # just to be sure
2012
1858638f
DM
2013 if ($conf->{cdrom}) {
2014 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
2015 $conf->{ide2} = $conf->{cdrom};
2016 delete $conf->{cdrom};
2017 }
1e3baf05
DM
2018
2019 # we do not use 'smp' any longer
1858638f
DM
2020 if ($conf->{sockets}) {
2021 delete $conf->{smp};
2022 } elsif ($conf->{smp}) {
2023 $conf->{sockets} = $conf->{smp};
2024 delete $conf->{cores};
2025 delete $conf->{smp};
1e3baf05
DM
2026 }
2027
ee2f90b1 2028 my $used_volids = {};
0d18dcfc 2029
ee2f90b1 2030 my $cleanup_config = sub {
ef824322 2031 my ($cref, $pending, $snapname) = @_;
1858638f 2032
ee2f90b1
DM
2033 foreach my $key (keys %$cref) {
2034 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
ef824322 2035 $key eq 'snapstate' || $key eq 'pending';
ee2f90b1 2036 my $value = $cref->{$key};
ef824322
DM
2037 if ($key eq 'delete') {
2038 die "propertry 'delete' is only allowed in [PENDING]\n"
2039 if !$pending;
2040 # fixme: check syntax?
2041 next;
2042 }
ee2f90b1
DM
2043 eval { $value = check_type($key, $value); };
2044 die "unable to parse value of '$key' - $@" if $@;
1858638f 2045
ee2f90b1
DM
2046 $cref->{$key} = $value;
2047
a8e2f942 2048 if (!$snapname && valid_drivename($key)) {
ed221350 2049 my $drive = parse_drive($key, $value);
ee2f90b1
DM
2050 $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
2051 }
1e3baf05 2052 }
ee2f90b1
DM
2053 };
2054
2055 &$cleanup_config($conf);
ef824322
DM
2056
2057 &$cleanup_config($conf->{pending}, 1);
2058
ee2f90b1 2059 foreach my $snapname (keys %{$conf->{snapshots}}) {
ef824322
DM
2060 die "internal error" if $snapname eq 'pending';
2061 &$cleanup_config($conf->{snapshots}->{$snapname}, undef, $snapname);
1e3baf05
DM
2062 }
2063
1858638f
DM
2064 # remove 'unusedX' settings if we re-add a volume
2065 foreach my $key (keys %$conf) {
2066 my $value = $conf->{$key};
ee2f90b1 2067 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1858638f 2068 delete $conf->{$key};
1e3baf05 2069 }
1858638f 2070 }
be190583 2071
0d18dcfc
DM
2072 my $generate_raw_config = sub {
2073 my ($conf) = @_;
0581fe4f 2074
0d18dcfc
DM
2075 my $raw = '';
2076
2077 # add description as comment to top of file
2078 my $descr = $conf->{description} || '';
2079 foreach my $cl (split(/\n/, $descr)) {
2080 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
2081 }
2082
2083 foreach my $key (sort keys %$conf) {
ef824322 2084 next if $key eq 'digest' || $key eq 'description' || $key eq 'pending' || $key eq 'snapshots';
0d18dcfc
DM
2085 $raw .= "$key: $conf->{$key}\n";
2086 }
2087 return $raw;
2088 };
0581fe4f 2089
0d18dcfc 2090 my $raw = &$generate_raw_config($conf);
ef824322
DM
2091
2092 if (scalar(keys %{$conf->{pending}})){
2093 $raw .= "\n[PENDING]\n";
2094 $raw .= &$generate_raw_config($conf->{pending});
2095 }
2096
0d18dcfc
DM
2097 foreach my $snapname (sort keys %{$conf->{snapshots}}) {
2098 $raw .= "\n[$snapname]\n";
2099 $raw .= &$generate_raw_config($conf->{snapshots}->{$snapname});
1858638f 2100 }
1e3baf05 2101
1858638f
DM
2102 return $raw;
2103}
1e3baf05 2104
1858638f
DM
2105sub update_config_nolock {
2106 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 2107
1858638f 2108 check_lock($conf) if !$skiplock;
97d62eb7 2109
1858638f 2110 my $cfspath = cfs_config_path($vmid);
1e3baf05 2111
1858638f
DM
2112 PVE::Cluster::cfs_write_file($cfspath, $conf);
2113}
1e3baf05 2114
1858638f
DM
2115sub update_config {
2116 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 2117
1858638f 2118 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1e3baf05
DM
2119}
2120
19672434 2121sub load_defaults {
1e3baf05
DM
2122
2123 my $res = {};
2124
2125 # we use static defaults from our JSON schema configuration
2126 foreach my $key (keys %$confdesc) {
2127 if (defined(my $default = $confdesc->{$key}->{default})) {
2128 $res->{$key} = $default;
2129 }
2130 }
19672434 2131
1e3baf05
DM
2132 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
2133 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
2134
2135 return $res;
2136}
2137
2138sub config_list {
2139 my $vmlist = PVE::Cluster::get_vmlist();
2140 my $res = {};
2141 return $res if !$vmlist || !$vmlist->{ids};
2142 my $ids = $vmlist->{ids};
2143
1e3baf05
DM
2144 foreach my $vmid (keys %$ids) {
2145 my $d = $ids->{$vmid};
2146 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 2147 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
2148 $res->{$vmid}->{exists} = 1;
2149 }
2150 return $res;
2151}
2152
64e13401
DM
2153# test if VM uses local resources (to prevent migration)
2154sub check_local_resources {
2155 my ($conf, $noerr) = @_;
2156
2157 my $loc_res = 0;
19672434 2158
e0ab7331
DM
2159 $loc_res = 1 if $conf->{hostusb}; # old syntax
2160 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 2161
0d29ab3b 2162 foreach my $k (keys %$conf) {
49ca581d 2163 next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice');
2fe1a152 2164 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
2165 }
2166
2167 die "VM uses local resources\n" if $loc_res && !$noerr;
2168
2169 return $loc_res;
2170}
2171
719893a9 2172# check if used storages are available on all nodes (use by migrate)
47152e2e
DM
2173sub check_storage_availability {
2174 my ($storecfg, $conf, $node) = @_;
2175
2176 foreach_drive($conf, sub {
2177 my ($ds, $drive) = @_;
2178
2179 my $volid = $drive->{file};
2180 return if !$volid;
2181
2182 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
2183 return if !$sid;
2184
2185 # check if storage is available on both nodes
2186 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
2187 PVE::Storage::storage_check_node($storecfg, $sid, $node);
2188 });
2189}
2190
719893a9
DM
2191# list nodes where all VM images are available (used by has_feature API)
2192sub shared_nodes {
2193 my ($conf, $storecfg) = @_;
2194
2195 my $nodelist = PVE::Cluster::get_nodelist();
2196 my $nodehash = { map { $_ => 1 } @$nodelist };
2197 my $nodename = PVE::INotify::nodename();
be190583 2198
719893a9
DM
2199 foreach_drive($conf, sub {
2200 my ($ds, $drive) = @_;
2201
2202 my $volid = $drive->{file};
2203 return if !$volid;
2204
2205 my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
2206 if ($storeid) {
2207 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
2208 if ($scfg->{disable}) {
2209 $nodehash = {};
2210 } elsif (my $avail = $scfg->{nodes}) {
2211 foreach my $node (keys %$nodehash) {
2212 delete $nodehash->{$node} if !$avail->{$node};
2213 }
2214 } elsif (!$scfg->{shared}) {
2215 foreach my $node (keys %$nodehash) {
2216 delete $nodehash->{$node} if $node ne $nodename
2217 }
2218 }
2219 }
2220 });
2221
2222 return $nodehash
2223}
2224
1e3baf05
DM
2225sub check_lock {
2226 my ($conf) = @_;
2227
2228 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
2229}
2230
2231sub check_cmdline {
2232 my ($pidfile, $pid) = @_;
2233
6b64503e
DM
2234 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
2235 if (defined($fh)) {
1e3baf05
DM
2236 my $line = <$fh>;
2237 $fh->close;
2238 return undef if !$line;
6b64503e 2239 my @param = split(/\0/, $line);
1e3baf05
DM
2240
2241 my $cmd = $param[0];
06094efd 2242 return if !$cmd || ($cmd !~ m|kvm$| && $cmd !~ m|qemu-system-x86_64$|);
1e3baf05
DM
2243
2244 for (my $i = 0; $i < scalar (@param); $i++) {
2245 my $p = $param[$i];
2246 next if !$p;
2247 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
2248 my $p = $param[$i+1];
2249 return 1 if $p && ($p eq $pidfile);
2250 return undef;
2251 }
2252 }
2253 }
2254 return undef;
2255}
2256
2257sub check_running {
7e8dcf2c 2258 my ($vmid, $nocheck, $node) = @_;
1e3baf05 2259
7e8dcf2c 2260 my $filename = config_file($vmid, $node);
1e3baf05
DM
2261
2262 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 2263 if !$nocheck && ! -f $filename;
1e3baf05 2264
e6c3b671 2265 my $pidfile = pidfile_name($vmid);
1e3baf05 2266
e6c3b671
DM
2267 if (my $fd = IO::File->new("<$pidfile")) {
2268 my $st = stat($fd);
1e3baf05 2269 my $line = <$fd>;
6b64503e 2270 close($fd);
1e3baf05
DM
2271
2272 my $mtime = $st->mtime;
2273 if ($mtime > time()) {
2274 warn "file '$filename' modified in future\n";
2275 }
2276
2277 if ($line =~ m/^(\d+)$/) {
2278 my $pid = $1;
e6c3b671
DM
2279 if (check_cmdline($pidfile, $pid)) {
2280 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
2281 return $pid;
2282 }
2283 }
1e3baf05
DM
2284 }
2285 }
2286
2287 return undef;
2288}
2289
2290sub vzlist {
19672434 2291
1e3baf05
DM
2292 my $vzlist = config_list();
2293
6b64503e 2294 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 2295
19672434 2296 while (defined(my $de = $fd->read)) {
1e3baf05
DM
2297 next if $de !~ m/^(\d+)\.pid$/;
2298 my $vmid = $1;
6b64503e
DM
2299 next if !defined($vzlist->{$vmid});
2300 if (my $pid = check_running($vmid)) {
1e3baf05
DM
2301 $vzlist->{$vmid}->{pid} = $pid;
2302 }
2303 }
2304
2305 return $vzlist;
2306}
2307
1e3baf05
DM
2308sub disksize {
2309 my ($storecfg, $conf) = @_;
2310
2311 my $bootdisk = $conf->{bootdisk};
2312 return undef if !$bootdisk;
2313 return undef if !valid_drivename($bootdisk);
2314
2315 return undef if !$conf->{$bootdisk};
2316
2317 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
2318 return undef if !defined($drive);
2319
2320 return undef if drive_is_cdrom($drive);
2321
2322 my $volid = $drive->{file};
2323 return undef if !$volid;
2324
24afaca0 2325 return $drive->{size};
1e3baf05
DM
2326}
2327
2328my $last_proc_pid_stat;
2329
03a33f30
DM
2330# get VM status information
2331# This must be fast and should not block ($full == false)
2332# We only query KVM using QMP if $full == true (this can be slow)
1e3baf05 2333sub vmstatus {
03a33f30 2334 my ($opt_vmid, $full) = @_;
1e3baf05
DM
2335
2336 my $res = {};
2337
19672434 2338 my $storecfg = PVE::Storage::config();
1e3baf05
DM
2339
2340 my $list = vzlist();
694fcad4 2341 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 2342
ae4915a2
DM
2343 my $cpucount = $cpuinfo->{cpus} || 1;
2344
1e3baf05
DM
2345 foreach my $vmid (keys %$list) {
2346 next if $opt_vmid && ($vmid ne $opt_vmid);
2347
2348 my $cfspath = cfs_config_path($vmid);
2349 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
2350
2351 my $d = {};
2352 $d->{pid} = $list->{$vmid}->{pid};
2353
2354 # fixme: better status?
2355 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
2356
af990afe
DM
2357 my $size = disksize($storecfg, $conf);
2358 if (defined($size)) {
2359 $d->{disk} = 0; # no info available
1e3baf05
DM
2360 $d->{maxdisk} = $size;
2361 } else {
2362 $d->{disk} = 0;
2363 $d->{maxdisk} = 0;
2364 }
2365
2366 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2 2367 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
d7c8364b 2368 $d->{cpus} = $conf->{vcpus} if $conf->{vcpus};
ae4915a2 2369
1e3baf05 2370 $d->{name} = $conf->{name} || "VM $vmid";
19672434 2371 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 2372
8b1accf7 2373 if ($conf->{balloon}) {
4bdb0514 2374 $d->{balloon_min} = $conf->{balloon}*(1024*1024);
074e01c8 2375 $d->{shares} = defined($conf->{shares}) ? $conf->{shares} : 1000;
8b1accf7
DM
2376 }
2377
1e3baf05
DM
2378 $d->{uptime} = 0;
2379 $d->{cpu} = 0;
1e3baf05
DM
2380 $d->{mem} = 0;
2381
2382 $d->{netout} = 0;
2383 $d->{netin} = 0;
2384
2385 $d->{diskread} = 0;
2386 $d->{diskwrite} = 0;
2387
4d8c851b
AD
2388 $d->{template} = is_template($conf);
2389
1e3baf05
DM
2390 $res->{$vmid} = $d;
2391 }
2392
2393 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
2394 foreach my $dev (keys %$netdev) {
2395 next if $dev !~ m/^tap([1-9]\d*)i/;
2396 my $vmid = $1;
2397 my $d = $res->{$vmid};
2398 next if !$d;
19672434 2399
1e3baf05
DM
2400 $d->{netout} += $netdev->{$dev}->{receive};
2401 $d->{netin} += $netdev->{$dev}->{transmit};
2402 }
2403
1e3baf05
DM
2404 my $ctime = gettimeofday;
2405
2406 foreach my $vmid (keys %$list) {
2407
2408 my $d = $res->{$vmid};
2409 my $pid = $d->{pid};
2410 next if !$pid;
2411
694fcad4
DM
2412 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
2413 next if !$pstat; # not running
19672434 2414
694fcad4 2415 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 2416
694fcad4 2417 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 2418
694fcad4 2419 if ($pstat->{vsize}) {
6b64503e 2420 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
2421 }
2422
2423 my $old = $last_proc_pid_stat->{$pid};
2424 if (!$old) {
19672434
DM
2425 $last_proc_pid_stat->{$pid} = {
2426 time => $ctime,
1e3baf05
DM
2427 used => $used,
2428 cpu => 0,
1e3baf05
DM
2429 };
2430 next;
2431 }
2432
7f0b5beb 2433 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
2434
2435 if ($dtime > 1000) {
2436 my $dutime = $used - $old->{used};
2437
ae4915a2 2438 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 2439 $last_proc_pid_stat->{$pid} = {
19672434 2440 time => $ctime,
1e3baf05
DM
2441 used => $used,
2442 cpu => $d->{cpu},
1e3baf05
DM
2443 };
2444 } else {
2445 $d->{cpu} = $old->{cpu};
1e3baf05
DM
2446 }
2447 }
2448
f5eb281a 2449 return $res if !$full;
03a33f30
DM
2450
2451 my $qmpclient = PVE::QMPClient->new();
2452
64e7fcf2
DM
2453 my $ballooncb = sub {
2454 my ($vmid, $resp) = @_;
2455
2456 my $info = $resp->{'return'};
38babf81
DM
2457 return if !$info->{max_mem};
2458
64e7fcf2
DM
2459 my $d = $res->{$vmid};
2460
38babf81
DM
2461 # use memory assigned to VM
2462 $d->{maxmem} = $info->{max_mem};
2463 $d->{balloon} = $info->{actual};
2464
2465 if (defined($info->{total_mem}) && defined($info->{free_mem})) {
2466 $d->{mem} = $info->{total_mem} - $info->{free_mem};
2467 $d->{freemem} = $info->{free_mem};
64e7fcf2
DM
2468 }
2469
2470 };
2471
03a33f30
DM
2472 my $blockstatscb = sub {
2473 my ($vmid, $resp) = @_;
2474 my $data = $resp->{'return'} || [];
2475 my $totalrdbytes = 0;
2476 my $totalwrbytes = 0;
2477 for my $blockstat (@$data) {
2478 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
2479 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
2480 }
2481 $res->{$vmid}->{diskread} = $totalrdbytes;
2482 $res->{$vmid}->{diskwrite} = $totalwrbytes;
2483 };
2484
2485 my $statuscb = sub {
2486 my ($vmid, $resp) = @_;
64e7fcf2 2487
03a33f30 2488 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
64e7fcf2
DM
2489 # this fails if ballon driver is not loaded, so this must be
2490 # the last commnand (following command are aborted if this fails).
38babf81 2491 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
03a33f30
DM
2492
2493 my $status = 'unknown';
2494 if (!defined($status = $resp->{'return'}->{status})) {
2495 warn "unable to get VM status\n";
2496 return;
2497 }
2498
2499 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2500 };
2501
2502 foreach my $vmid (keys %$list) {
2503 next if $opt_vmid && ($vmid ne $opt_vmid);
2504 next if !$res->{$vmid}->{pid}; # not running
2505 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2506 }
2507
c8125172 2508 $qmpclient->queue_execute(undef, 1);
03a33f30
DM
2509
2510 foreach my $vmid (keys %$list) {
2511 next if $opt_vmid && ($vmid ne $opt_vmid);
2512 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2513 }
2514
1e3baf05
DM
2515 return $res;
2516}
2517
e059fb4d
AD
2518sub foreach_dimm {
2519 my ($conf, $vmid, $memory, $sockets, $func) = @_;
2520
2521 my $dimm_id = 0;
2522 my $current_size = 1024;
2523 my $dimm_size = 512;
2524 return if $current_size == $memory;
2525
2526 for (my $j = 0; $j < 8; $j++) {
2527 for (my $i = 0; $i < 32; $i++) {
2528 my $name = "dimm${dimm_id}";
2529 $dimm_id++;
2530 my $numanode = $i % $sockets;
2531 $current_size += $dimm_size;
2532 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
2533 return $current_size if $current_size >= $memory;
2534 }
2535 $dimm_size *= 2;
2536 }
2537}
2538
1e3baf05
DM
2539sub foreach_drive {
2540 my ($conf, $func) = @_;
2541
2542 foreach my $ds (keys %$conf) {
2543 next if !valid_drivename($ds);
2544
6b64503e 2545 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2546 next if !$drive;
2547
2548 &$func($ds, $drive);
2549 }
2550}
2551
d5769dc2
DM
2552sub foreach_volid {
2553 my ($conf, $func) = @_;
be190583 2554
d5769dc2
DM
2555 my $volhash = {};
2556
2557 my $test_volid = sub {
2558 my ($volid, $is_cdrom) = @_;
2559
2560 return if !$volid;
be190583 2561
d5769dc2
DM
2562 $volhash->{$volid} = $is_cdrom || 0;
2563 };
2564
ed221350 2565 foreach_drive($conf, sub {
d5769dc2
DM
2566 my ($ds, $drive) = @_;
2567 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2568 });
2569
2570 foreach my $snapname (keys %{$conf->{snapshots}}) {
2571 my $snap = $conf->{snapshots}->{$snapname};
2572 &$test_volid($snap->{vmstate}, 0);
ed221350 2573 foreach_drive($snap, sub {
d5769dc2
DM
2574 my ($ds, $drive) = @_;
2575 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2576 });
2577 }
2578
2579 foreach my $volid (keys %$volhash) {
be190583 2580 &$func($volid, $volhash->{$volid});
d5769dc2
DM
2581 }
2582}
2583
86b8228b
DM
2584sub vga_conf_has_spice {
2585 my ($vga) = @_;
2586
590e698c
DM
2587 return 0 if !$vga || $vga !~ m/^qxl([234])?$/;
2588
2589 return $1 || 1;
86b8228b
DM
2590}
2591
1e3baf05 2592sub config_to_command {
952958bc 2593 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
1e3baf05
DM
2594
2595 my $cmd = [];
8c559505
DM
2596 my $globalFlags = [];
2597 my $machineFlags = [];
2598 my $rtcFlags = [];
519ed28c 2599 my $cpuFlags = [];
5bdcf937 2600 my $devices = [];
b78ebef7 2601 my $pciaddr = '';
5bdcf937 2602 my $bridges = {};
1e3baf05
DM
2603 my $kvmver = kvm_user_version();
2604 my $vernum = 0; # unknown
a3c52213
DM
2605 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2606 $vernum = $1*1000000+$2*1000;
2607 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2608 $vernum = $1*1000000+$2*1000+$3;
2609 }
2610
a3c52213 2611 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2612
2613 my $have_ovz = -f '/proc/vz/vestat';
2614
db656e5f 2615 my $q35 = machine_type_is_q35($conf);
4d3f29ed 2616 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
23f73120 2617 my $machine_type = $forcemachine || $conf->{machine};
db656e5f 2618
1e3baf05
DM
2619 push @$cmd, '/usr/bin/kvm';
2620
2621 push @$cmd, '-id', $vmid;
2622
2623 my $use_virtio = 0;
2624
c971c4f2
AD
2625 my $qmpsocket = qmp_socket($vmid);
2626 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2627 push @$cmd, '-mon', "chardev=qmp,mode=control";
2628
7b7c6d1b 2629 my $socket = vnc_socket($vmid);
1e3baf05
DM
2630 push @$cmd, '-vnc', "unix:$socket,x509,password";
2631
6b64503e 2632 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2633
1e3baf05
DM
2634 push @$cmd, '-daemonize';
2635
2796e7d5
DM
2636 if ($conf->{smbios1}) {
2637 push @$cmd, '-smbios', "type=1,$conf->{smbios1}";
2638 }
2639
db656e5f 2640 if ($q35) {
b467f79a 2641 # the q35 chipset support native usb2, so we enable usb controller
db656e5f 2642 # by default for this machine type
f8e83f05 2643 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
db656e5f 2644 } else {
f8e83f05
AD
2645 $pciaddr = print_pci_addr("piix3", $bridges);
2646 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
24f0d39a 2647
f8e83f05 2648 my $use_usb2 = 0;
db656e5f
DM
2649 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2650 next if !$conf->{"usb$i"};
2651 $use_usb2 = 1;
2652 }
2653 # include usb device config
2654 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
fcc573ab 2655 }
19672434 2656
5acbfe9e 2657 my $vga = $conf->{vga};
2fa3151e 2658
590e698c
DM
2659 my $qxlnum = vga_conf_has_spice($vga);
2660 $vga = 'qxl' if $qxlnum;
2fa3151e 2661
5acbfe9e 2662 if (!$vga) {
264e519f
DM
2663 if ($conf->{ostype} && ($conf->{ostype} eq 'win8' ||
2664 $conf->{ostype} eq 'win7' ||
5acbfe9e
DM
2665 $conf->{ostype} eq 'w2k8')) {
2666 $vga = 'std';
2667 } else {
2668 $vga = 'cirrus';
2669 }
2670 }
2671
1e3baf05 2672 # enable absolute mouse coordinates (needed by vnc)
5acbfe9e
DM
2673 my $tablet;
2674 if (defined($conf->{tablet})) {
2675 $tablet = $conf->{tablet};
2676 } else {
2677 $tablet = $defaults->{tablet};
590e698c 2678 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
ef5e2be2 2679 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
5acbfe9e
DM
2680 }
2681
db656e5f 2682 push @$devices, '-device', print_tabletdevice_full($conf) if $tablet;
b467f79a 2683
1e3baf05 2684 # host pci devices
040b06b7 2685 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2e3b7e2a
AD
2686 my $d = parse_hostpci($conf->{"hostpci$i"});
2687 next if !$d;
2688
2689 my $pcie = $d->{pcie};
2690 if($pcie){
2691 die "q35 machine model is not enabled" if !$q35;
2692 $pciaddr = print_pcie_addr("hostpci$i");
2693 }else{
2694 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2695 }
2696
2697 my $rombar = $d->{rombar} && $d->{rombar} eq 'off' ? ",rombar=0" : "";
2698 my $driver = $d->{driver} && $d->{driver} eq 'vfio' ? "vfio-pci" : "pci-assign";
2699 my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ? ",x-vga=on" : "";
137483c0
AD
2700 if ($xvga && $xvga ne '') {
2701 push @$cpuFlags, 'kvm=off';
2702 $vga = 'none';
2703 }
2e3b7e2a 2704 $driver = "vfio-pci" if $xvga ne '';
4543ecf0
AD
2705 my $pcidevices = $d->{pciid};
2706 my $multifunction = 1 if @$pcidevices > 1;
2e3b7e2a 2707
4543ecf0
AD
2708 my $j=0;
2709 foreach my $pcidevice (@$pcidevices) {
2e3b7e2a 2710
4543ecf0
AD
2711 my $id = "hostpci$i";
2712 $id .= ".$j" if $multifunction;
2713 my $addr = $pciaddr;
2714 $addr .= ".$j" if $multifunction;
2715 my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
2716
2717 if($j == 0){
2718 $devicestr .= "$rombar$xvga";
2719 $devicestr .= ",multifunction=on" if $multifunction;
2720 }
2721
2722 push @$devices, '-device', $devicestr;
2723 $j++;
2724 }
1e3baf05
DM
2725 }
2726
2727 # usb devices
2728 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2729 my $d = parse_usb_device($conf->{"usb$i"});
2730 next if !$d;
2731 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2732 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2733 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2734 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
80401dd8
DM
2735 } elsif ($d->{spice}) {
2736 # usb redir support for spice
2737 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2738 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
1e3baf05
DM
2739 }
2740 }
2741
1e3baf05 2742 # serial devices
bae179aa 2743 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2744 if (my $path = $conf->{"serial$i"}) {
9f9d2fb2
DM
2745 if ($path eq 'socket') {
2746 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2747 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2748 push @$devices, '-device', "isa-serial,chardev=serial$i";
2749 } else {
2750 die "no such serial device\n" if ! -c $path;
2751 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2752 push @$devices, '-device', "isa-serial,chardev=serial$i";
2753 }
34978be3 2754 }
1e3baf05
DM
2755 }
2756
2757 # parallel devices
1989a89c 2758 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2759 if (my $path = $conf->{"parallel$i"}) {
19672434 2760 die "no such parallel device\n" if ! -c $path;
32e69805 2761 my $devtype = $path =~ m!^/dev/usb/lp! ? 'tty' : 'parport';
4c5dbaf6 2762 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
5bdcf937 2763 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2764 }
1e3baf05
DM
2765 }
2766
2767 my $vmname = $conf->{name} || "vm$vmid";
2768
2769 push @$cmd, '-name', $vmname;
19672434 2770
1e3baf05
DM
2771 my $sockets = 1;
2772 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2773 $sockets = $conf->{sockets} if $conf->{sockets};
2774
2775 my $cores = $conf->{cores} || 1;
3bd18e48 2776
de9d1e55 2777 my $maxcpus = $sockets * $cores;
76267728 2778
de9d1e55 2779 my $vcpus = $conf->{vcpus} ? $conf->{vcpus} : $maxcpus;
76267728 2780
de9d1e55
AD
2781 my $allowed_vcpus = $cpuinfo->{cpus};
2782
2783 die "MAX $maxcpus vcpus allowed per VM on this node\n"
2784 if ($allowed_vcpus < $maxcpus);
2785
2786 push @$cmd, '-smp', "$vcpus,sockets=$sockets,cores=$cores,maxcpus=$maxcpus";
1e3baf05 2787
1e3baf05
DM
2788 push @$cmd, '-nodefaults';
2789
32baffb4 2790 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2791
0888fdce
DM
2792 my $bootindex_hash = {};
2793 my $i = 1;
2794 foreach my $o (split(//, $bootorder)) {
2795 $bootindex_hash->{$o} = $i*100;
2796 $i++;
afdb31d5 2797 }
3b408e82 2798
cf71f776 2799 push @$cmd, '-boot', "menu=on,strict=on,reboot-timeout=1000";
1e3baf05 2800
6b64503e 2801 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2802
6b64503e 2803 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05 2804
ef5e2be2 2805 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
1e3baf05
DM
2806
2807 # time drift fix
6b64503e 2808 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2809
6b64503e 2810 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2811 my $useLocaltime = $conf->{localtime};
1e3baf05
DM
2812
2813 if (my $ost = $conf->{ostype}) {
6b9d84cf 2814 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
1e3baf05
DM
2815
2816 if ($ost =~ m/^w/) { # windows
8c559505 2817 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2818
8c559505 2819 # use time drift fix when acpi is enabled
6b64503e 2820 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2821 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2822 }
2823 }
2824
be190583 2825 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
a70ebde3 2826 $ost eq 'wvista') {
8c559505 2827 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf 2828 push @$cmd, '-no-hpet';
8f3f959d
AD
2829 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2830 push @$cpuFlags , 'hv_spinlocks=0x1fff' if !$nokvm;
8a054ffd 2831 push @$cpuFlags , 'hv_vapic' if !$nokvm;
cfac0be4 2832 push @$cpuFlags , 'hv_time' if !$nokvm;
8a054ffd 2833
a1b7d579 2834 } else {
8f3f959d
AD
2835 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2836 }
462e8d19
AD
2837 }
2838
2839 if ($ost eq 'win7' || $ost eq 'win8') {
2840 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
b7e0c8bf 2841 }
1e3baf05
DM
2842 }
2843
8c559505
DM
2844 push @$rtcFlags, 'driftfix=slew' if $tdf;
2845
7f0b5beb 2846 if ($nokvm) {
8c559505 2847 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2848 } else {
2849 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2850 }
1e3baf05 2851
952958bc
DM
2852 if ($machine_type) {
2853 push @$machineFlags, "type=${machine_type}";
3bafc510
DM
2854 }
2855
8c559505
DM
2856 if ($conf->{startdate}) {
2857 push @$rtcFlags, "base=$conf->{startdate}";
2858 } elsif ($useLocaltime) {
2859 push @$rtcFlags, 'base=localtime';
2860 }
1e3baf05 2861
519ed28c
AD
2862 my $cpu = $nokvm ? "qemu64" : "kvm64";
2863 $cpu = $conf->{cpu} if $conf->{cpu};
2864
4dc339e7
AD
2865 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2866
6b9d84cf
AD
2867 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype} ne 'solaris';
2868
2869 push @$cpuFlags , '-x2apic' if $conf->{ostype} eq 'solaris';
519ed28c 2870
2e1a5389
AD
2871 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2872
117a0414
AD
2873 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2874
2875 push @$cpuFlags , '+kvm_pv_unhalt' if !$nokvm;
0da5a08c 2876 push @$cpuFlags , '+kvm_pv_eoi' if !$nokvm;
117a0414
AD
2877 }
2878
be190583 2879 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c 2880
6a33d44a 2881 push @$cmd, '-cpu', "$cpu,enforce";
519ed28c 2882
4d3f29ed
AD
2883 my $memory = $conf->{memory} || $defaults->{memory};
2884 my $static_memory = 0;
2885 my $dimm_memory = 0;
2886
2887 if ($hotplug_features->{memory}) {
996635e5
DM
2888 die "Numa need to be enabled for memory hotplug\n" if !$conf->{numa};
2889 die "Total memory is bigger than ${MAX_MEM}MB\n" if $memory > $MAX_MEM;
4d3f29ed 2890 $static_memory = $STATICMEM;
996635e5 2891 die "minimum memory must be ${static_memory}MB\n" if($memory < $static_memory);
4d3f29ed 2892 $dimm_memory = $memory - $static_memory;
996635e5 2893 push @$cmd, '-m', "size=${static_memory},slots=255,maxmem=${MAX_MEM}M";
4d3f29ed
AD
2894
2895 } else {
2896
2897 $static_memory = $memory;
2898 push @$cmd, '-m', $static_memory;
2899 }
8a010eae 2900
67fb9de6 2901 if ($conf->{numa}) {
8a010eae 2902
2ed5d572
AD
2903 my $numa_totalmemory = undef;
2904 for (my $i = 0; $i < $MAX_NUMA; $i++) {
2905 next if !$conf->{"numa$i"};
2906 my $numa = parse_numa($conf->{"numa$i"});
2907 next if !$numa;
67fb9de6
DM
2908 # memory
2909 die "missing numa node$i memory value\n" if !$numa->{memory};
2ed5d572
AD
2910 my $numa_memory = $numa->{memory};
2911 $numa_totalmemory += $numa_memory;
996635e5 2912 my $numa_object = "memory-backend-ram,id=ram-node$i,size=${numa_memory}M";
2ed5d572 2913
67fb9de6 2914 # cpus
2ed5d572 2915 my $cpus_start = $numa->{cpus}->{start};
67fb9de6 2916 die "missing numa node$i cpus\n" if !defined($cpus_start);
2ed5d572
AD
2917 my $cpus_end = $numa->{cpus}->{end} if defined($numa->{cpus}->{end});
2918 my $cpus = $cpus_start;
2919 if (defined($cpus_end)) {
2920 $cpus .= "-$cpus_end";
67fb9de6 2921 die "numa node$i : cpu range $cpus is incorrect\n" if $cpus_end <= $cpus_start;
2ed5d572 2922 }
8a010eae 2923
67fb9de6 2924 # hostnodes
2ed5d572
AD
2925 my $hostnodes_start = $numa->{hostnodes}->{start};
2926 if (defined($hostnodes_start)) {
2927 my $hostnodes_end = $numa->{hostnodes}->{end} if defined($numa->{hostnodes}->{end});
2928 my $hostnodes = $hostnodes_start;
2929 if (defined($hostnodes_end)) {
2930 $hostnodes .= "-$hostnodes_end";
67fb9de6 2931 die "host node $hostnodes range is incorrect\n" if $hostnodes_end <= $hostnodes_start;
2ed5d572 2932 }
8a010eae 2933
2ed5d572
AD
2934 my $hostnodes_end_range = defined($hostnodes_end) ? $hostnodes_end : $hostnodes_start;
2935 for (my $i = $hostnodes_start; $i <= $hostnodes_end_range; $i++ ) {
67fb9de6 2936 die "host numa node$i don't exist\n" if ! -d "/sys/devices/system/node/node$i/";
2ed5d572 2937 }
8a010eae 2938
67fb9de6 2939 # policy
2ed5d572 2940 my $policy = $numa->{policy};
67fb9de6
DM
2941 die "you need to define a policy for hostnode $hostnodes\n" if !$policy;
2942 $numa_object .= ",host-nodes=$hostnodes,policy=$policy";
2ed5d572
AD
2943 }
2944
2945 push @$cmd, '-object', $numa_object;
8a010eae
AD
2946 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2947 }
67fb9de6 2948
4d3f29ed
AD
2949 die "total memory for NUMA nodes must be equal to vm static memory\n"
2950 if $numa_totalmemory && $numa_totalmemory != $static_memory;
2ed5d572
AD
2951
2952 #if no custom tology, we split memory and cores across numa nodes
2953 if(!$numa_totalmemory) {
2954
4d3f29ed 2955 my $numa_memory = ($static_memory / $sockets) . "M";
2ed5d572
AD
2956
2957 for (my $i = 0; $i < $sockets; $i++) {
2958
2959 my $cpustart = ($cores * $i);
2960 my $cpuend = ($cpustart + $cores - 1) if $cores && $cores > 1;
2961 my $cpus = $cpustart;
2962 $cpus .= "-$cpuend" if $cpuend;
2963
2964 push @$cmd, '-object', "memory-backend-ram,size=$numa_memory,id=ram-node$i";
2965 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2966 }
2967 }
8a010eae
AD
2968 }
2969
4d3f29ed 2970 if ($hotplug_features->{memory}) {
e059fb4d
AD
2971 foreach_dimm($conf, $vmid, $memory, $sockets, sub {
2972 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
996635e5 2973 push @$cmd, "-object" , "memory-backend-ram,id=mem-$name,size=${dimm_size}M";
e059fb4d
AD
2974 push @$cmd, "-device", "pc-dimm,id=$name,memdev=mem-$name,node=$numanode";
2975
2976 #if dimm_memory is not aligned to dimm map
2977 if($current_size > $memory) {
2978 $conf->{memory} = $current_size;
2979 update_config_nolock($vmid, $conf, 1);
2980 }
2981 });
4d3f29ed
AD
2982 }
2983
1e3baf05
DM
2984 push @$cmd, '-S' if $conf->{freeze};
2985
2986 # set keyboard layout
2987 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2988 push @$cmd, '-k', $kb if $kb;
2989
2990 # enable sound
2991 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2992 #push @$cmd, '-soundhw', 'es1370';
2993 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2994
bc84dcca 2995 if($conf->{agent}) {
7a6c2150 2996 my $qgasocket = qmp_socket($vmid, 1);
ab6a046f
AD
2997 my $pciaddr = print_pci_addr("qga0", $bridges);
2998 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2999 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
3000 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
3001 }
3002
1d794448 3003 my $spice_port;
2fa3151e 3004
590e698c
DM
3005 if ($qxlnum) {
3006 if ($qxlnum > 1) {
3007 if ($conf->{ostype} && $conf->{ostype} =~ m/^w/){
3008 for(my $i = 1; $i < $qxlnum; $i++){
3009 my $pciaddr = print_pci_addr("vga$i", $bridges);
3010 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
3011 }
3012 } else {
3013 # assume other OS works like Linux
3014 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
3015 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2fa3151e
AD
3016 }
3017 }
3018
1011b570 3019 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 3020
cd339d1f 3021 $spice_port = PVE::Tools::next_spice_port();
943340a6 3022
d2da6d9b 3023 push @$devices, '-spice', "tls-port=${spice_port},addr=127.0.0.1,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 3024
d2da6d9b
AD
3025 push @$devices, '-device', "virtio-serial,id=spice$pciaddr";
3026 push @$devices, '-chardev', "spicevmc,id=vdagent,name=vdagent";
3027 push @$devices, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
1011b570
DM
3028 }
3029
8d9ae0d2
DM
3030 # enable balloon by default, unless explicitly disabled
3031 if (!defined($conf->{balloon}) || $conf->{balloon}) {
3032 $pciaddr = print_pci_addr("balloon0", $bridges);
3033 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
3034 }
1e3baf05 3035
0ea9541d
DM
3036 if ($conf->{watchdog}) {
3037 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 3038 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 3039 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
3040 push @$devices, '-device', "$watchdog$pciaddr";
3041 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
3042 }
3043
1e3baf05 3044 my $vollist = [];
941e0c42 3045 my $scsicontroller = {};
26ee04b6 3046 my $ahcicontroller = {};
cdd20088 3047 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05 3048
5881b913
DM
3049 # Add iscsi initiator name if available
3050 if (my $initiator = get_initiator_name()) {
3051 push @$devices, '-iscsi', "initiator-name=$initiator";
3052 }
3053
1e3baf05
DM
3054 foreach_drive($conf, sub {
3055 my ($ds, $drive) = @_;
3056
ff1a2432 3057 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 3058 push @$vollist, $drive->{file};
ff1a2432 3059 }
afdb31d5 3060
1e3baf05 3061 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
3062
3063 if (drive_is_cdrom ($drive)) {
3064 if ($bootindex_hash->{d}) {
3065 $drive->{bootindex} = $bootindex_hash->{d};
3066 $bootindex_hash->{d} += 1;
3067 }
3068 } else {
3069 if ($bootindex_hash->{c}) {
3070 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
3071 $bootindex_hash->{c} += 1;
3072 }
3073 }
3074
51f492cd
AD
3075 if($drive->{interface} eq 'virtio'){
3076 push @$cmd, '-object', "iothread,id=iothread-$ds" if $drive->{iothread};
3077 }
3078
941e0c42 3079 if ($drive->{interface} eq 'scsi') {
cdd20088 3080
ee034f5c 3081 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
6731a4cf 3082
6731a4cf 3083 $pciaddr = print_pci_addr("$controller_prefix$controller", $bridges);
a1b7d579 3084 my $scsihw_type = $scsihw =~ m/^virtio-scsi-single/ ? "virtio-scsi-pci" : $scsihw;
fc8b40fd
AD
3085
3086 my $iothread = '';
3087 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{iothread}){
3088 $iothread .= ",iothread=iothread-$controller_prefix$controller";
3089 push @$cmd, '-object', "iothread,id=iothread-$controller_prefix$controller";
3090 }
3091
6e11f143
AD
3092 my $queues = '';
3093 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{queues}){
3094 $queues = ",num_queues=$drive->{queues}";
3095 }
3096
3097 push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread$queues" if !$scsicontroller->{$controller};
cdd20088 3098 $scsicontroller->{$controller}=1;
941e0c42 3099 }
3b408e82 3100
26ee04b6
DA
3101 if ($drive->{interface} eq 'sata') {
3102 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
3103 $pciaddr = print_pci_addr("ahci$controller", $bridges);
3104 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
3105 $ahcicontroller->{$controller}=1;
3106 }
46f58b5f 3107
15b21acc
MR
3108 my $drive_cmd = print_drive_full($storecfg, $vmid, $drive);
3109 push @$devices, '-drive',$drive_cmd;
46f58b5f 3110 push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
3111 });
3112
cc4d6182 3113 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 3114 next if !$conf->{"net$i"};
cc4d6182
DA
3115 my $d = parse_net($conf->{"net$i"});
3116 next if !$d;
1e3baf05 3117
cc4d6182 3118 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 3119
cc4d6182
DA
3120 if ($bootindex_hash->{n}) {
3121 $d->{bootindex} = $bootindex_hash->{n};
3122 $bootindex_hash->{n} += 1;
3123 }
1e3baf05 3124
cc4d6182 3125 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
3126 push @$devices, '-netdev', $netdevfull;
3127
3128 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
3129 push @$devices, '-device', $netdevicefull;
3130 }
1e3baf05 3131
db656e5f
DM
3132 if (!$q35) {
3133 # add pci bridges
fc79e813
AD
3134 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
3135 $bridges->{1} = 1;
3136 $bridges->{2} = 1;
3137 }
3138
6731a4cf
AD
3139 $bridges->{3} = 1 if $scsihw =~ m/^virtio-scsi-single/;
3140
f8e83f05
AD
3141 while (my ($k, $v) = each %$bridges) {
3142 $pciaddr = print_pci_addr("pci.$k");
3143 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
3144 }
19672434
DM
3145 }
3146
1e3baf05
DM
3147 # hack: virtio with fairsched is unreliable, so we do not use fairsched
3148 # when the VM uses virtio devices.
19672434
DM
3149 if (!$use_virtio && $have_ovz) {
3150
6b64503e 3151 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
3152 $conf->{cpuunits} : $defaults->{cpuunits};
3153
3154 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
3155
3156 # fixme: cpulimit is currently ignored
3157 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
3158 }
3159
3160 # add custom args
3161 if ($conf->{args}) {
3ada46c9 3162 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
3163 push @$cmd, @$aa;
3164 }
3165
5bdcf937 3166 push @$cmd, @$devices;
be190583 3167 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 3168 if scalar(@$rtcFlags);
be190583 3169 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
3170 if scalar(@$machineFlags);
3171 push @$cmd, '-global', join(',', @$globalFlags)
3172 if scalar(@$globalFlags);
3173
1d794448 3174 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 3175}
19672434 3176
1e3baf05
DM
3177sub vnc_socket {
3178 my ($vmid) = @_;
3179 return "${var_run_tmpdir}/$vmid.vnc";
3180}
3181
943340a6 3182sub spice_port {
1011b570 3183 my ($vmid) = @_;
943340a6 3184
1d794448 3185 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
3186
3187 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
3188}
3189
c971c4f2 3190sub qmp_socket {
693d12a2
AD
3191 my ($vmid, $qga) = @_;
3192 my $sockettype = $qga ? 'qga' : 'qmp';
3193 return "${var_run_tmpdir}/$vmid.$sockettype";
c971c4f2
AD
3194}
3195
1e3baf05
DM
3196sub pidfile_name {
3197 my ($vmid) = @_;
3198 return "${var_run_tmpdir}/$vmid.pid";
3199}
3200
86fdcfb2
DA
3201sub vm_devices_list {
3202 my ($vmid) = @_;
3203
ceea9078 3204 my $res = vm_mon_cmd($vmid, 'query-pci');
ceea9078
DM
3205 my $devices = {};
3206 foreach my $pcibus (@$res) {
3207 foreach my $device (@{$pcibus->{devices}}) {
6e62a21f 3208 next if !$device->{'qdev_id'};
200644a7 3209 if ($device->{'pci_bridge'}) {
200644a7
AD
3210 $devices->{$device->{'qdev_id'}} = 1;
3211 foreach my $bridge_device (@{$device->{'pci_bridge'}->{devices}}) {
3212 next if !$bridge_device->{'qdev_id'};
3213 $devices->{$bridge_device->{'qdev_id'}} = 1;
3214 $devices->{$device->{'qdev_id'}}++;
3215 }
3216 } else {
200644a7
AD
3217 $devices->{$device->{'qdev_id'}} = 1;
3218 }
f78cc802
AD
3219 }
3220 }
3221
3222 my $resblock = vm_mon_cmd($vmid, 'query-block');
3223 foreach my $block (@$resblock) {
3224 if($block->{device} =~ m/^drive-(\S+)/){
3225 $devices->{$1} = 1;
1dc4f496
DM
3226 }
3227 }
86fdcfb2 3228
3d7389fe
DM
3229 my $resmice = vm_mon_cmd($vmid, 'query-mice');
3230 foreach my $mice (@$resmice) {
3231 if ($mice->{name} eq 'QEMU HID Tablet') {
3232 $devices->{tablet} = 1;
3233 last;
3234 }
3235 }
3236
1dc4f496 3237 return $devices;
86fdcfb2
DA
3238}
3239
ec21aa11 3240sub vm_deviceplug {
f19d1c47 3241 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 3242
db656e5f
DM
3243 my $q35 = machine_type_is_q35($conf);
3244
95d6343b
DA
3245 my $devices_list = vm_devices_list($vmid);
3246 return 1 if defined($devices_list->{$deviceid});
3247
fee46675
DM
3248 qemu_add_pci_bridge($storecfg, $conf, $vmid, $deviceid); # add PCI bridge if we need it for the device
3249
3d7389fe 3250 if ($deviceid eq 'tablet') {
fee46675 3251
3d7389fe 3252 qemu_deviceadd($vmid, print_tabletdevice_full($conf));
3d7389fe 3253
fee46675 3254 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
40f28a9f 3255
22de899a
AD
3256 qemu_iothread_add($vmid, $deviceid, $device);
3257
fee46675 3258 qemu_driveadd($storecfg, $vmid, $device);
cdd20088 3259 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
fee46675 3260
5e5dcb73 3261 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3262 eval { qemu_deviceaddverify($vmid, $deviceid); };
3263 if (my $err = $@) {
63c2da2f
DM
3264 eval { qemu_drivedel($vmid, $deviceid); };
3265 warn $@ if $@;
fee46675 3266 die $err;
5e5dcb73 3267 }
cfc817c7 3268
2733141c 3269 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
fee46675 3270
fc8b40fd 3271
cdd20088 3272 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 3273 my $pciaddr = print_pci_addr($deviceid);
a1b7d579 3274 my $scsihw_type = $scsihw eq 'virtio-scsi-single' ? "virtio-scsi-pci" : $scsihw;
2733141c
AD
3275
3276 my $devicefull = "$scsihw_type,id=$deviceid$pciaddr";
fee46675 3277
fc8b40fd
AD
3278 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{iothread}) {
3279 qemu_iothread_add($vmid, $deviceid, $device);
3280 $devicefull .= ",iothread=iothread-$deviceid";
3281 }
3282
6e11f143
AD
3283 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{queues}) {
3284 $devicefull .= ",num_queues=$device->{queues}";
3285 }
3286
cfc817c7 3287 qemu_deviceadd($vmid, $devicefull);
fee46675 3288 qemu_deviceaddverify($vmid, $deviceid);
cfc817c7 3289
fee46675
DM
3290 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3291
3292 qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
3293 qemu_driveadd($storecfg, $vmid, $device);
a1b7d579 3294
fee46675
DM
3295 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
3296 eval { qemu_deviceadd($vmid, $devicefull); };
3297 if (my $err = $@) {
63c2da2f
DM
3298 eval { qemu_drivedel($vmid, $deviceid); };
3299 warn $@ if $@;
fee46675 3300 die $err;
a4f091a0 3301 }
a4f091a0 3302
fee46675
DM
3303 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3304
2630d2a9
DA
3305 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
3306 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
3307 qemu_deviceadd($vmid, $netdevicefull);
fee46675
DM
3308 eval { qemu_deviceaddverify($vmid, $deviceid); };
3309 if (my $err = $@) {
3310 eval { qemu_netdevdel($vmid, $deviceid); };
3311 warn $@ if $@;
3312 die $err;
2630d2a9 3313 }
2630d2a9 3314
fee46675 3315 } elsif (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
b467f79a 3316
40f28a9f
AD
3317 my $bridgeid = $2;
3318 my $pciaddr = print_pci_addr($deviceid);
3319 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
a1b7d579 3320
40f28a9f 3321 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3322 qemu_deviceaddverify($vmid, $deviceid);
3323
3324 } else {
a1b7d579 3325 die "can't hotplug device '$deviceid'\n";
40f28a9f
AD
3326 }
3327
5e5dcb73 3328 return 1;
a4dea331
DA
3329}
3330
3eec5767 3331# fixme: this should raise exceptions on error!
ec21aa11 3332sub vm_deviceunplug {
f19d1c47 3333 my ($vmid, $conf, $deviceid) = @_;
873c2d69 3334
95d6343b
DA
3335 my $devices_list = vm_devices_list($vmid);
3336 return 1 if !defined($devices_list->{$deviceid});
3337
63c2da2f
DM
3338 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
3339
3d7389fe 3340 if ($deviceid eq 'tablet') {
63c2da2f 3341
3d7389fe 3342 qemu_devicedel($vmid, $deviceid);
3d7389fe 3343
63c2da2f 3344 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
f19d1c47 3345
5e5dcb73 3346 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3347 qemu_devicedelverify($vmid, $deviceid);
3348 qemu_drivedel($vmid, $deviceid);
22de899a
AD
3349 qemu_iothread_del($conf, $vmid, $deviceid);
3350
2733141c 3351 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
a1b7d579 3352
63c2da2f 3353 qemu_devicedel($vmid, $deviceid);
8ce30dde 3354 qemu_devicedelverify($vmid, $deviceid);
fc8b40fd 3355 qemu_iothread_del($conf, $vmid, $deviceid);
a1b7d579 3356
63c2da2f 3357 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
cfc817c7 3358
8bcf3068
AD
3359 #qemu 2.3 segfault on drive_del with virtioscsi + iothread
3360 my $device = parse_drive($deviceid, $conf->{$deviceid});
3361 die "virtioscsi with iothread is not hot-unplugglable currently" if $device->{iothread};
3362
63c2da2f
DM
3363 qemu_devicedel($vmid, $deviceid);
3364 qemu_drivedel($vmid, $deviceid);
a1b7d579 3365 qemu_deletescsihw($conf, $vmid, $deviceid);
8ce30dde 3366
63c2da2f 3367 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
a4f091a0 3368
2630d2a9 3369 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3370 qemu_devicedelverify($vmid, $deviceid);
3371 qemu_netdevdel($vmid, $deviceid);
3372
3373 } else {
3374 die "can't unplug device '$deviceid'\n";
2630d2a9
DA
3375 }
3376
5e5dcb73
DA
3377 return 1;
3378}
3379
3380sub qemu_deviceadd {
3381 my ($vmid, $devicefull) = @_;
873c2d69 3382
d695b5b7
AD
3383 $devicefull = "driver=".$devicefull;
3384 my %options = split(/[=,]/, $devicefull);
f19d1c47 3385
d695b5b7 3386 vm_mon_cmd($vmid, "device_add" , %options);
5e5dcb73 3387}
afdb31d5 3388
5e5dcb73 3389sub qemu_devicedel {
fee46675 3390 my ($vmid, $deviceid) = @_;
63c2da2f 3391
5a77d8c1 3392 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
5e5dcb73
DA
3393}
3394
22de899a
AD
3395sub qemu_iothread_add {
3396 my($vmid, $deviceid, $device) = @_;
3397
3398 if ($device->{iothread}) {
3399 my $iothreads = vm_iothreads_list($vmid);
3400 qemu_objectadd($vmid, "iothread-$deviceid", "iothread") if !$iothreads->{"iothread-$deviceid"};
3401 }
3402}
3403
3404sub qemu_iothread_del {
3405 my($conf, $vmid, $deviceid) = @_;
3406
3407 my $device = parse_drive($deviceid, $conf->{$deviceid});
3408 if ($device->{iothread}) {
3409 my $iothreads = vm_iothreads_list($vmid);
3410 qemu_objectdel($vmid, "iothread-$deviceid") if $iothreads->{"iothread-$deviceid"};
3411 }
3412}
3413
4d3f29ed
AD
3414sub qemu_objectadd {
3415 my($vmid, $objectid, $qomtype) = @_;
3416
3417 vm_mon_cmd($vmid, "object-add", id => $objectid, "qom-type" => $qomtype);
3418
3419 return 1;
3420}
3421
3422sub qemu_objectdel {
3423 my($vmid, $objectid) = @_;
3424
3425 vm_mon_cmd($vmid, "object-del", id => $objectid);
3426
3427 return 1;
3428}
3429
5e5dcb73 3430sub qemu_driveadd {
fee46675 3431 my ($storecfg, $vmid, $device) = @_;
5e5dcb73
DA
3432
3433 my $drive = print_drive_full($storecfg, $vmid, $device);
7a69fc3c 3434 $drive =~ s/\\/\\\\/g;
8ead5ec7 3435 my $ret = vm_human_monitor_command($vmid, "drive_add auto \"$drive\"");
fee46675 3436
5e5dcb73 3437 # If the command succeeds qemu prints: "OK"
fee46675
DM
3438 return 1 if $ret =~ m/OK/s;
3439
3440 die "adding drive failed: $ret\n";
5e5dcb73 3441}
afdb31d5 3442
5e5dcb73
DA
3443sub qemu_drivedel {
3444 my($vmid, $deviceid) = @_;
873c2d69 3445
7b7c6d1b 3446 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73 3447 $ret =~ s/^\s+//;
a1b7d579 3448
63c2da2f 3449 return 1 if $ret eq "";
a1b7d579 3450
63c2da2f 3451 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
a1b7d579
DM
3452 return 1 if $ret =~ m/Device \'.*?\' not found/s;
3453
63c2da2f 3454 die "deleting drive $deviceid failed : $ret\n";
5e5dcb73 3455}
f19d1c47 3456
5e5dcb73 3457sub qemu_deviceaddverify {
fee46675 3458 my ($vmid, $deviceid) = @_;
873c2d69 3459
5e5dcb73
DA
3460 for (my $i = 0; $i <= 5; $i++) {
3461 my $devices_list = vm_devices_list($vmid);
3462 return 1 if defined($devices_list->{$deviceid});
3463 sleep 1;
afdb31d5 3464 }
fee46675
DM
3465
3466 die "error on hotplug device '$deviceid'\n";
5e5dcb73 3467}
afdb31d5 3468
5e5dcb73
DA
3469
3470sub qemu_devicedelverify {
63c2da2f
DM
3471 my ($vmid, $deviceid) = @_;
3472
a1b7d579 3473 # need to verify that the device is correctly removed as device_del
63c2da2f 3474 # is async and empty return is not reliable
5e5dcb73 3475
5e5dcb73
DA
3476 for (my $i = 0; $i <= 5; $i++) {
3477 my $devices_list = vm_devices_list($vmid);
3478 return 1 if !defined($devices_list->{$deviceid});
3479 sleep 1;
afdb31d5 3480 }
63c2da2f
DM
3481
3482 die "error on hot-unplugging device '$deviceid'\n";
873c2d69
DA
3483}
3484
cdd20088 3485sub qemu_findorcreatescsihw {
cfc817c7
DA
3486 my ($storecfg, $conf, $vmid, $device) = @_;
3487
ee034f5c 3488 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
2733141c
AD
3489
3490 my $scsihwid="$controller_prefix$controller";
cfc817c7
DA
3491 my $devices_list = vm_devices_list($vmid);
3492
cdd20088 3493 if(!defined($devices_list->{$scsihwid})) {
fc8b40fd 3494 vm_deviceplug($storecfg, $conf, $vmid, $scsihwid, $device);
cfc817c7 3495 }
fee46675 3496
cfc817c7
DA
3497 return 1;
3498}
3499
8ce30dde
AD
3500sub qemu_deletescsihw {
3501 my ($conf, $vmid, $opt) = @_;
3502
3503 my $device = parse_drive($opt, $conf->{$opt});
3504
a1511b3c 3505 if ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
2733141c
AD
3506 vm_deviceunplug($vmid, $conf, "virtioscsi$device->{index}");
3507 return 1;
3508 }
3509
ee034f5c 3510 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
8ce30dde
AD
3511
3512 my $devices_list = vm_devices_list($vmid);
3513 foreach my $opt (keys %{$devices_list}) {
3514 if (PVE::QemuServer::valid_drivename($opt)) {
3515 my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
3516 if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) {
3517 return 1;
3518 }
3519 }
3520 }
3521
3522 my $scsihwid="scsihw$controller";
3523
3524 vm_deviceunplug($vmid, $conf, $scsihwid);
3525
3526 return 1;
3527}
3528
281fedb3 3529sub qemu_add_pci_bridge {
40f28a9f
AD
3530 my ($storecfg, $conf, $vmid, $device) = @_;
3531
3532 my $bridges = {};
281fedb3
DM
3533
3534 my $bridgeid;
3535
40f28a9f
AD
3536 print_pci_addr($device, $bridges);
3537
3538 while (my ($k, $v) = each %$bridges) {
3539 $bridgeid = $k;
3540 }
fee46675 3541 return 1 if !defined($bridgeid) || $bridgeid < 1;
281fedb3 3542
40f28a9f
AD
3543 my $bridge = "pci.$bridgeid";
3544 my $devices_list = vm_devices_list($vmid);
3545
281fedb3 3546 if (!defined($devices_list->{$bridge})) {
fee46675 3547 vm_deviceplug($storecfg, $conf, $vmid, $bridge);
40f28a9f 3548 }
281fedb3 3549
40f28a9f
AD
3550 return 1;
3551}
3552
25088687
DM
3553sub qemu_set_link_status {
3554 my ($vmid, $device, $up) = @_;
3555
a1b7d579 3556 vm_mon_cmd($vmid, "set_link", name => $device,
25088687
DM
3557 up => $up ? JSON::true : JSON::false);
3558}
3559
2630d2a9
DA
3560sub qemu_netdevadd {
3561 my ($vmid, $conf, $device, $deviceid) = @_;
3562
3563 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
73aa03b8 3564 my %options = split(/[=,]/, $netdev);
2630d2a9 3565
73aa03b8
AD
3566 vm_mon_cmd($vmid, "netdev_add", %options);
3567 return 1;
2630d2a9
DA
3568}
3569
3570sub qemu_netdevdel {
3571 my ($vmid, $deviceid) = @_;
3572
89c1e0f4 3573 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2630d2a9
DA
3574}
3575
838776ab 3576sub qemu_cpu_hotplug {
8edc9c08 3577 my ($vmid, $conf, $vcpus) = @_;
838776ab 3578
8edc9c08
AD
3579 my $sockets = 1;
3580 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
3581 $sockets = $conf->{sockets} if $conf->{sockets};
3582 my $cores = $conf->{cores} || 1;
3583 my $maxcpus = $sockets * $cores;
838776ab 3584
8edc9c08 3585 $vcpus = $maxcpus if !$vcpus;
3a11fadb 3586
8edc9c08
AD
3587 die "you can't add more vcpus than maxcpus\n"
3588 if $vcpus > $maxcpus;
3a11fadb 3589
8edc9c08 3590 my $currentvcpus = $conf->{vcpus} || $maxcpus;
3a11fadb 3591 die "online cpu unplug is not yet possible\n"
8edc9c08 3592 if $vcpus < $currentvcpus;
838776ab 3593
8edc9c08
AD
3594 my $currentrunningvcpus = vm_mon_cmd($vmid, "query-cpus");
3595 die "vcpus in running vm is different than configuration\n"
3596 if scalar(@{$currentrunningvcpus}) != $currentvcpus;
838776ab 3597
8edc9c08 3598 for (my $i = $currentvcpus; $i < $vcpus; $i++) {
838776ab
AD
3599 vm_mon_cmd($vmid, "cpu-add", id => int($i));
3600 }
3601}
3602
4d3f29ed
AD
3603sub qemu_memory_hotplug {
3604 my ($vmid, $conf, $defaults, $opt, $value) = @_;
3605
3606 return $value if !check_running($vmid);
a1b7d579 3607
4d3f29ed 3608 my $memory = $conf->{memory} || $defaults->{memory};
a1b7d579 3609 $value = $defaults->{memory} if !$value;
4d3f29ed
AD
3610 return $value if $value == $memory;
3611
3612 my $static_memory = $STATICMEM;
3613 my $dimm_memory = $memory - $static_memory;
3614
3615 die "memory can't be lower than $static_memory MB" if $value < $static_memory;
3616 die "memory unplug is not yet available" if $value < $memory;
4d3f29ed
AD
3617 die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM;
3618
3619
3620 my $sockets = 1;
3621 $sockets = $conf->{sockets} if $conf->{sockets};
3622
e059fb4d
AD
3623 foreach_dimm($conf, $vmid, $value, $sockets, sub {
3624 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
3625
3626 return if $current_size <= $conf->{memory};
4d3f29ed
AD
3627
3628 eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) };
3629 if (my $err = $@) {
3630 eval { qemu_objectdel($vmid, "mem-$name"); };
3631 die $err;
3632 }
3633
3634 eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) };
3635 if (my $err = $@) {
3636 eval { qemu_objectdel($vmid, "mem-$name"); };
3637 die $err;
3638 }
3639 #update conf after each succesful module hotplug
e059fb4d 3640 $conf->{memory} = $current_size;
4d3f29ed 3641 update_config_nolock($vmid, $conf, 1);
e059fb4d 3642 });
4d3f29ed
AD
3643}
3644
affd2f88
AD
3645sub qemu_block_set_io_throttle {
3646 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
3647
f3f323a3
AD
3648 return if !check_running($vmid) ;
3649
f3f323a3
AD
3650 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));
3651
affd2f88
AD
3652}
3653
f5eb281a 3654# old code, only used to shutdown old VM after update
dab36e1e
DM
3655sub __read_avail {
3656 my ($fh, $timeout) = @_;
3657
3658 my $sel = new IO::Select;
3659 $sel->add($fh);
3660
3661 my $res = '';
3662 my $buf;
3663
3664 my @ready;
3665 while (scalar (@ready = $sel->can_read($timeout))) {
3666 my $count;
3667 if ($count = $fh->sysread($buf, 8192)) {
3668 if ($buf =~ /^(.*)\(qemu\) $/s) {
3669 $res .= $1;
3670 last;
3671 } else {
3672 $res .= $buf;
3673 }
3674 } else {
3675 if (!defined($count)) {
3676 die "$!\n";
3677 }
3678 last;
3679 }
3680 }
3681
3682 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 3683
dab36e1e
DM
3684 return $res;
3685}
3686
f5eb281a 3687# old code, only used to shutdown old VM after update
dab36e1e
DM
3688sub vm_monitor_command {
3689 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 3690
dab36e1e
DM
3691 my $res;
3692
3693 eval {
3694 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
3695
3696 my $sname = "${var_run_tmpdir}/$vmid.mon";
3697
3698 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
3699 die "unable to connect to VM $vmid socket - $!\n";
3700
3701 my $timeout = 3;
3702
3703 # hack: migrate sometime blocks the monitor (when migrate_downtime
3704 # is set)
3705 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3706 $timeout = 60*60; # 1 hour
3707 }
3708
3709 # read banner;
3710 my $data = __read_avail($sock, $timeout);
3711
3712 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3713 die "got unexpected qemu monitor banner\n";
3714 }
3715
3716 my $sel = new IO::Select;
3717 $sel->add($sock);
3718
3719 if (!scalar(my @ready = $sel->can_write($timeout))) {
3720 die "monitor write error - timeout";
3721 }
3722
3723 my $fullcmd = "$cmdstr\r";
3724
3725 # syslog('info', "VM $vmid monitor command: $cmdstr");
3726
3727 my $b;
3728 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3729 die "monitor write error - $!";
3730 }
3731
3732 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3733
3734 $timeout = 20;
3735
3736 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3737 $timeout = 60*60; # 1 hour
3738 } elsif ($cmdstr =~ m/^(eject|change)/) {
3739 $timeout = 60; # note: cdrom mount command is slow
3740 }
3741 if ($res = __read_avail($sock, $timeout)) {
3742
3743 my @lines = split("\r?\n", $res);
f5eb281a 3744
dab36e1e 3745 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 3746
dab36e1e
DM
3747 $res = join("\n", @lines);
3748 $res .= "\n";
3749 }
3750 };
3751
3752 my $err = $@;
3753
3754 if ($err) {
3755 syslog("err", "VM $vmid monitor command failed - $err");
3756 die $err;
3757 }
f5eb281a 3758
dab36e1e
DM
3759 return $res;
3760}
3761
c1175c92
AD
3762sub qemu_block_resize {
3763 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3764
ed221350 3765 my $running = check_running($vmid);
c1175c92
AD
3766
3767 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3768
3769 return if !$running;
3770
3771 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3772
3773}
3774
1ab0057c
AD
3775sub qemu_volume_snapshot {
3776 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3777
ed221350 3778 my $running = check_running($vmid);
1ab0057c
AD
3779
3780 return if !PVE::Storage::volume_snapshot($storecfg, $volid, $snap, $running);
3781
3782 return if !$running;
3783
3784 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3785
3786}
3787
fc46aff9
AD
3788sub qemu_volume_snapshot_delete {
3789 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3790
ed221350 3791 my $running = check_running($vmid);
fc46aff9
AD
3792
3793 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3794
3795 return if !$running;
3796
18bfb361 3797 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3798}
3799
264e519f
DM
3800sub set_migration_caps {
3801 my ($vmid) = @_;
a89fded1 3802
8b8345f3 3803 my $cap_ref = [];
a89fded1
AD
3804
3805 my $enabled_cap = {
8b8345f3
DM
3806 "auto-converge" => 1,
3807 "xbzrle" => 0,
3808 "x-rdma-pin-all" => 0,
3809 "zero-blocks" => 0,
a89fded1
AD
3810 };
3811
8b8345f3 3812 my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities");
a89fded1 3813
8b8345f3 3814 for my $supported_capability (@$supported_capabilities) {
b463a3ce
SP
3815 push @$cap_ref, {
3816 capability => $supported_capability->{capability},
22430fa2
DM
3817 state => $enabled_cap->{$supported_capability->{capability}} ? JSON::true : JSON::false,
3818 };
a89fded1
AD
3819 }
3820
8b8345f3
DM
3821 vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => $cap_ref);
3822}
a89fded1 3823
81d95ae1 3824my $fast_plug_option = {
7498eb64 3825 'lock' => 1,
81d95ae1 3826 'name' => 1,
a1b7d579 3827 'onboot' => 1,
81d95ae1
DM
3828 'shares' => 1,
3829 'startup' => 1,
3830};
3831
3a11fadb
DM
3832# hotplug changes in [PENDING]
3833# $selection hash can be used to only apply specified options, for
3834# example: { cores => 1 } (only apply changed 'cores')
3835# $errors ref is used to return error messages
c427973b 3836sub vmconfig_hotplug_pending {
3a11fadb 3837 my ($vmid, $conf, $storecfg, $selection, $errors) = @_;
c427973b 3838
8e90138a 3839 my $defaults = load_defaults();
c427973b
DM
3840
3841 # commit values which do not have any impact on running VM first
3a11fadb
DM
3842 # Note: those option cannot raise errors, we we do not care about
3843 # $selection and always apply them.
3844
3845 my $add_error = sub {
3846 my ($opt, $msg) = @_;
3847 $errors->{$opt} = "hotplug problem - $msg";
3848 };
c427973b
DM
3849
3850 my $changes = 0;
3851 foreach my $opt (keys %{$conf->{pending}}) { # add/change
81d95ae1 3852 if ($fast_plug_option->{$opt}) {
c427973b
DM
3853 $conf->{$opt} = $conf->{pending}->{$opt};
3854 delete $conf->{pending}->{$opt};
3855 $changes = 1;
3856 }
3857 }
3858
3859 if ($changes) {
3860 update_config_nolock($vmid, $conf, 1);
3861 $conf = load_config($vmid); # update/reload
3862 }
3863
b3c2bdd1 3864 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
c427973b 3865
3d7389fe
DM
3866 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3867 foreach my $opt (@delete) {
3a11fadb 3868 next if $selection && !$selection->{$opt};
3a11fadb 3869 eval {
51a6f637
AD
3870 if ($opt eq 'hotplug') {
3871 die "skip\n" if ($conf->{hotplug} =~ /memory/);
3872 } elsif ($opt eq 'tablet') {
b3c2bdd1 3873 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3874 if ($defaults->{tablet}) {
3875 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3876 } else {
3877 vm_deviceunplug($vmid, $conf, $opt);
3878 }
8edc9c08 3879 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3880 die "skip\n" if !$hotplug_features->{cpu};
8edc9c08 3881 qemu_cpu_hotplug($vmid, $conf, undef);
9c2f7069 3882 } elsif ($opt eq 'balloon') {
81d95ae1
DM
3883 # enable balloon device is not hotpluggable
3884 die "skip\n" if !defined($conf->{balloon}) || $conf->{balloon};
3885 } elsif ($fast_plug_option->{$opt}) {
3886 # do nothing
3eec5767 3887 } elsif ($opt =~ m/^net(\d+)$/) {
b3c2bdd1 3888 die "skip\n" if !$hotplug_features->{network};
3eec5767 3889 vm_deviceunplug($vmid, $conf, $opt);
a05cff86 3890 } elsif (valid_drivename($opt)) {
b3c2bdd1 3891 die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
19120f99
AD
3892 vm_deviceunplug($vmid, $conf, $opt);
3893 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
4d3f29ed
AD
3894 } elsif ($opt =~ m/^memory$/) {
3895 die "skip\n" if !$hotplug_features->{memory};
3896 qemu_memory_hotplug($vmid, $conf, $defaults, $opt);
3d7389fe 3897 } else {
e56beeda 3898 die "skip\n";
3d7389fe 3899 }
3a11fadb
DM
3900 };
3901 if (my $err = $@) {
e56beeda
DM
3902 &$add_error($opt, $err) if $err ne "skip\n";
3903 } else {
3a11fadb
DM
3904 # save new config if hotplug was successful
3905 delete $conf->{$opt};
3906 vmconfig_undelete_pending_option($conf, $opt);
3907 update_config_nolock($vmid, $conf, 1);
3908 $conf = load_config($vmid); # update/reload
3d7389fe 3909 }
3d7389fe
DM
3910 }
3911
3912 foreach my $opt (keys %{$conf->{pending}}) {
3a11fadb 3913 next if $selection && !$selection->{$opt};
3d7389fe 3914 my $value = $conf->{pending}->{$opt};
3a11fadb 3915 eval {
51a6f637
AD
3916 if ($opt eq 'hotplug') {
3917 die "skip\n" if ($value =~ /memory/) || ($value !~ /memory/ && $conf->{hotplug} =~ /memory/);
3918 } elsif ($opt eq 'tablet') {
b3c2bdd1 3919 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3920 if ($value == 1) {
3921 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3922 } elsif ($value == 0) {
3923 vm_deviceunplug($vmid, $conf, $opt);
3924 }
8edc9c08 3925 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3926 die "skip\n" if !$hotplug_features->{cpu};
3a11fadb
DM
3927 qemu_cpu_hotplug($vmid, $conf, $value);
3928 } elsif ($opt eq 'balloon') {
81d95ae1 3929 # enable/disable balloning device is not hotpluggable
8fe689e7 3930 my $old_balloon_enabled = !!(!defined($conf->{balloon}) || $conf->{balloon});
a1b7d579 3931 my $new_balloon_enabled = !!(!defined($conf->{pending}->{balloon}) || $conf->{pending}->{balloon});
81d95ae1
DM
3932 die "skip\n" if $old_balloon_enabled != $new_balloon_enabled;
3933
3a11fadb 3934 # allow manual ballooning if shares is set to zero
4cc1efa6 3935 if ((defined($conf->{shares}) && ($conf->{shares} == 0))) {
9c2f7069
AD
3936 my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
3937 vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
3938 }
a1b7d579 3939 } elsif ($opt =~ m/^net(\d+)$/) {
3eec5767 3940 # some changes can be done without hotplug
a1b7d579 3941 vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
b3c2bdd1 3942 $vmid, $opt, $value);
a05cff86
DM
3943 } elsif (valid_drivename($opt)) {
3944 # some changes can be done without hotplug
b3c2bdd1
DM
3945 vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk},
3946 $vmid, $opt, $value, 1);
4d3f29ed
AD
3947 } elsif ($opt =~ m/^memory$/) { #dimms
3948 die "skip\n" if !$hotplug_features->{memory};
3949 $value = qemu_memory_hotplug($vmid, $conf, $defaults, $opt, $value);
3a11fadb 3950 } else {
e56beeda 3951 die "skip\n"; # skip non-hot-pluggable options
3d7389fe 3952 }
3a11fadb
DM
3953 };
3954 if (my $err = $@) {
e56beeda
DM
3955 &$add_error($opt, $err) if $err ne "skip\n";
3956 } else {
3a11fadb
DM
3957 # save new config if hotplug was successful
3958 $conf->{$opt} = $value;
3959 delete $conf->{pending}->{$opt};
3960 update_config_nolock($vmid, $conf, 1);
3961 $conf = load_config($vmid); # update/reload
3d7389fe 3962 }
3d7389fe 3963 }
c427973b 3964}
055d554d
DM
3965
3966sub vmconfig_apply_pending {
3a11fadb 3967 my ($vmid, $conf, $storecfg) = @_;
c427973b
DM
3968
3969 # cold plug
055d554d
DM
3970
3971 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3972 foreach my $opt (@delete) { # delete
3973 die "internal error" if $opt =~ m/^unused/;
3974 $conf = load_config($vmid); # update/reload
3975 if (!defined($conf->{$opt})) {
3976 vmconfig_undelete_pending_option($conf, $opt);
3977 update_config_nolock($vmid, $conf, 1);
3978 } elsif (valid_drivename($opt)) {
3979 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
3980 vmconfig_undelete_pending_option($conf, $opt);
3981 delete $conf->{$opt};
3982 update_config_nolock($vmid, $conf, 1);
3983 } else {
3984 vmconfig_undelete_pending_option($conf, $opt);
3985 delete $conf->{$opt};
3986 update_config_nolock($vmid, $conf, 1);
3987 }
3988 }
3989
3990 $conf = load_config($vmid); # update/reload
3991
3992 foreach my $opt (keys %{$conf->{pending}}) { # add/change
3993 $conf = load_config($vmid); # update/reload
3994
3995 if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) {
3996 # skip if nothing changed
3997 } elsif (valid_drivename($opt)) {
3998 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
3999 if defined($conf->{$opt});
4000 $conf->{$opt} = $conf->{pending}->{$opt};
4001 } else {
4002 $conf->{$opt} = $conf->{pending}->{$opt};
4003 }
4004
4005 delete $conf->{pending}->{$opt};
4006 update_config_nolock($vmid, $conf, 1);
4007 }
4008}
4009
3eec5767
DM
4010my $safe_num_ne = sub {
4011 my ($a, $b) = @_;
4012
4013 return 0 if !defined($a) && !defined($b);
4014 return 1 if !defined($a);
4015 return 1 if !defined($b);
4016
4017 return $a != $b;
4018};
4019
4020my $safe_string_ne = sub {
4021 my ($a, $b) = @_;
4022
4023 return 0 if !defined($a) && !defined($b);
4024 return 1 if !defined($a);
4025 return 1 if !defined($b);
4026
4027 return $a ne $b;
4028};
4029
4030sub vmconfig_update_net {
b3c2bdd1 4031 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value) = @_;
3eec5767
DM
4032
4033 my $newnet = parse_net($value);
4034
4035 if ($conf->{$opt}) {
4036 my $oldnet = parse_net($conf->{$opt});
4037
4038 if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
4039 &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
4040 &$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
4041 !($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
4042
4043 # for non online change, we try to hot-unplug
7196b757 4044 die "skip\n" if !$hotplug;
3eec5767
DM
4045 vm_deviceunplug($vmid, $conf, $opt);
4046 } else {
4047
4048 die "internal error" if $opt !~ m/net(\d+)/;
4049 my $iface = "tap${vmid}i$1";
a1b7d579 4050
3eec5767
DM
4051 if (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
4052 PVE::Network::tap_rate_limit($iface, $newnet->{rate});
4053 }
4054
25088687
DM
4055 if (&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) ||
4056 &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) ||
4057 &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})) {
3eec5767
DM
4058 PVE::Network::tap_unplug($iface);
4059 PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
4060 }
38c590d9 4061
25088687
DM
4062 if (&$safe_string_ne($oldnet->{link_down}, $newnet->{link_down})) {
4063 qemu_set_link_status($vmid, $opt, !$newnet->{link_down});
4064 }
4065
38c590d9 4066 return 1;
3eec5767
DM
4067 }
4068 }
a1b7d579 4069
7196b757 4070 if ($hotplug) {
38c590d9
DM
4071 vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
4072 } else {
4073 die "skip\n";
4074 }
3eec5767
DM
4075}
4076
a05cff86 4077sub vmconfig_update_disk {
b3c2bdd1 4078 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $force) = @_;
a05cff86
DM
4079
4080 # fixme: do we need force?
4081
4082 my $drive = parse_drive($opt, $value);
4083
4084 if ($conf->{$opt}) {
4085
4086 if (my $old_drive = parse_drive($opt, $conf->{$opt})) {
4087
4088 my $media = $drive->{media} || 'disk';
4089 my $oldmedia = $old_drive->{media} || 'disk';
4090 die "unable to change media type\n" if $media ne $oldmedia;
4091
4092 if (!drive_is_cdrom($old_drive)) {
4093
a1b7d579 4094 if ($drive->{file} ne $old_drive->{file}) {
a05cff86 4095
7196b757 4096 die "skip\n" if !$hotplug;
a05cff86
DM
4097
4098 # unplug and register as unused
4099 vm_deviceunplug($vmid, $conf, $opt);
4100 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
a1b7d579 4101
a05cff86
DM
4102 } else {
4103 # update existing disk
4104
4105 # skip non hotpluggable value
a1b7d579 4106 if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) ||
22de899a 4107 &$safe_string_ne($drive->{iothread}, $old_drive->{iothread}) ||
6e11f143 4108 &$safe_string_ne($drive->{queues}, $old_drive->{queues}) ||
a05cff86
DM
4109 &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
4110 die "skip\n";
4111 }
4112
4113 # apply throttle
4114 if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
4115 &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
4116 &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
4117 &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
4118 &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
4119 &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
4120 &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
4121 &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
4122 &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
4123 &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
4124 &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
4125 &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
a1b7d579 4126
a05cff86
DM
4127 qemu_block_set_io_throttle($vmid,"drive-$opt",
4128 ($drive->{mbps} || 0)*1024*1024,
4129 ($drive->{mbps_rd} || 0)*1024*1024,
4130 ($drive->{mbps_wr} || 0)*1024*1024,
4131 $drive->{iops} || 0,
4132 $drive->{iops_rd} || 0,
4133 $drive->{iops_wr} || 0,
4134 ($drive->{mbps_max} || 0)*1024*1024,
4135 ($drive->{mbps_rd_max} || 0)*1024*1024,
4136 ($drive->{mbps_wr_max} || 0)*1024*1024,
4137 $drive->{iops_max} || 0,
4138 $drive->{iops_rd_max} || 0,
4139 $drive->{iops_wr_max} || 0);
4140
4141 }
a1b7d579 4142
a05cff86
DM
4143 return 1;
4144 }
4de1bb25
DM
4145
4146 } else { # cdrom
a1b7d579 4147
4de1bb25
DM
4148 if ($drive->{file} eq 'none') {
4149 vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
4150 } else {
4151 my $path = get_iso_path($storecfg, $vmid, $drive->{file});
4152 vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
4153 vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
4154 }
a1b7d579 4155
34758d66 4156 return 1;
a05cff86
DM
4157 }
4158 }
4159 }
4160
a1b7d579 4161 die "skip\n" if !$hotplug || $opt =~ m/(ide|sata)(\d+)/;
4de1bb25
DM
4162 # hotplug new disks
4163 vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
a05cff86
DM
4164}
4165
1e3baf05 4166sub vm_start {
1d794448 4167 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
1e3baf05 4168
6b64503e 4169 lock_config($vmid, sub {
7e8dcf2c 4170 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 4171
8b43bc11 4172 die "you can't start a vm if it's a template\n" if is_template($conf);
3dcb98d5 4173
6b64503e 4174 check_lock($conf) if !$skiplock;
1e3baf05 4175
7e8dcf2c 4176 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 4177
055d554d 4178 if (!$statefile && scalar(keys %{$conf->{pending}})) {
3a11fadb 4179 vmconfig_apply_pending($vmid, $conf, $storecfg);
055d554d
DM
4180 $conf = load_config($vmid); # update/reload
4181 }
4182
6c47d546
DM
4183 my $defaults = load_defaults();
4184
4185 # set environment variable useful inside network script
4186 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
4187
1d794448 4188 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 4189
1e3baf05 4190 my $migrate_port = 0;
5bc1e039 4191 my $migrate_uri;
1e3baf05
DM
4192 if ($statefile) {
4193 if ($statefile eq 'tcp') {
5bc1e039
SP
4194 my $localip = "localhost";
4195 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
4196 if ($datacenterconf->{migration_unsecure}) {
4197 my $nodename = PVE::INotify::nodename();
4198 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
4199 }
f9a971e0 4200 $migrate_port = PVE::Tools::next_migrate_port();
5bc1e039 4201 $migrate_uri = "tcp:${localip}:${migrate_port}";
6c47d546
DM
4202 push @$cmd, '-incoming', $migrate_uri;
4203 push @$cmd, '-S';
1e3baf05 4204 } else {
6c47d546 4205 push @$cmd, '-loadstate', $statefile;
1e3baf05 4206 }
91bd6c90
DM
4207 } elsif ($paused) {
4208 push @$cmd, '-S';
1e3baf05
DM
4209 }
4210
1e3baf05 4211 # host pci devices
040b06b7
DA
4212 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
4213 my $d = parse_hostpci($conf->{"hostpci$i"});
4214 next if !$d;
b1f72af6
AD
4215 my $pcidevices = $d->{pciid};
4216 foreach my $pcidevice (@$pcidevices) {
4217 my $pciid = $pcidevice->{id}.".".$pcidevice->{function};
000fc0a2 4218
b1f72af6
AD
4219 my $info = pci_device_info("0000:$pciid");
4220 die "IOMMU not present\n" if !check_iommu_support();
4221 die "no pci device info for device '$pciid'\n" if !$info;
000fc0a2 4222
b1f72af6
AD
4223 if ($d->{driver} && $d->{driver} eq "vfio") {
4224 die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid);
4225 } else {
4226 die "can't unbind/bind to stub pci device '$pciid'\n" if !pci_dev_bind_to_stub($info);
4227 }
4228
8f3e88af 4229 die "can't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info);
b1f72af6 4230 }
040b06b7 4231 }
1e3baf05
DM
4232
4233 PVE::Storage::activate_volumes($storecfg, $vollist);
4234
585b6e28
DM
4235 eval { run_command($cmd, timeout => $statefile ? undef : 30,
4236 umask => 0077); };
1e3baf05 4237 my $err = $@;
ff1a2432 4238 die "start failed: $err" if $err;
1e3baf05 4239
5bc1e039 4240 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 4241
8c609afd 4242 if ($statefile && $statefile ne 'tcp') {
95381ce0 4243 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 4244 warn $@ if $@;
62de2cbd
DM
4245 }
4246
1d794448 4247 if ($migratedfrom) {
a89fded1
AD
4248
4249 eval {
8e90138a 4250 set_migration_caps($vmid);
a89fded1 4251 };
1d794448 4252 warn $@ if $@;
a89fded1 4253
1d794448
DM
4254 if ($spice_port) {
4255 print "spice listens on port $spice_port\n";
4256 if ($spice_ticket) {
8e90138a
DM
4257 vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
4258 vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
4259 }
4260 }
4261
1d794448 4262 } else {
4ec05c4c 4263
15b1fc93 4264 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 4265 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 4266 if $conf->{balloon};
4ec05c4c 4267 }
25088687
DM
4268
4269 foreach my $opt (keys %$conf) {
4270 next if $opt !~ m/^net\d+$/;
4271 my $nicconf = parse_net($conf->{$opt});
4272 qemu_set_link_status($vmid, $opt, 0) if $nicconf->{link_down};
4273 }
e18b0b99 4274 }
a1b7d579 4275
eb065317
AD
4276 vm_mon_cmd_nocheck($vmid, 'qom-set',
4277 path => "machine/peripheral/balloon0",
4278 property => "guest-stats-polling-interval",
4279 value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
4280
1e3baf05
DM
4281 });
4282}
4283
0eedc444
AD
4284sub vm_mon_cmd {
4285 my ($vmid, $execute, %params) = @_;
4286
26f11676
DM
4287 my $cmd = { execute => $execute, arguments => \%params };
4288 vm_qmp_command($vmid, $cmd);
0eedc444
AD
4289}
4290
4291sub vm_mon_cmd_nocheck {
4292 my ($vmid, $execute, %params) = @_;
4293
26f11676
DM
4294 my $cmd = { execute => $execute, arguments => \%params };
4295 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
4296}
4297
c971c4f2 4298sub vm_qmp_command {
c5a07de5 4299 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 4300
c971c4f2 4301 my $res;
26f11676 4302
14db5366
DM
4303 my $timeout;
4304 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
4305 $timeout = $cmd->{arguments}->{timeout};
4306 delete $cmd->{arguments}->{timeout};
4307 }
be190583 4308
c971c4f2
AD
4309 eval {
4310 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
7a6c2150
DM
4311 my $sname = qmp_socket($vmid);
4312 if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga
c5a07de5 4313 my $qmpclient = PVE::QMPClient->new();
dab36e1e 4314
14db5366 4315 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
c5a07de5 4316 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
dab36e1e
DM
4317 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
4318 if scalar(%{$cmd->{arguments}});
4319 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
4320 } else {
4321 die "unable to open monitor socket\n";
4322 }
c971c4f2 4323 };
26f11676 4324 if (my $err = $@) {
c971c4f2
AD
4325 syslog("err", "VM $vmid qmp command failed - $err");
4326 die $err;
4327 }
4328
4329 return $res;
4330}
4331
9df5cbcc
DM
4332sub vm_human_monitor_command {
4333 my ($vmid, $cmdline) = @_;
4334
4335 my $res;
4336
f5eb281a 4337 my $cmd = {
9df5cbcc
DM
4338 execute => 'human-monitor-command',
4339 arguments => { 'command-line' => $cmdline},
4340 };
4341
4342 return vm_qmp_command($vmid, $cmd);
4343}
4344
1e3baf05
DM
4345sub vm_commandline {
4346 my ($storecfg, $vmid) = @_;
4347
6b64503e 4348 my $conf = load_config($vmid);
1e3baf05
DM
4349
4350 my $defaults = load_defaults();
4351
6b64503e 4352 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 4353
6b64503e 4354 return join(' ', @$cmd);
1e3baf05
DM
4355}
4356
4357sub vm_reset {
4358 my ($vmid, $skiplock) = @_;
4359
6b64503e 4360 lock_config($vmid, sub {
1e3baf05 4361
6b64503e 4362 my $conf = load_config($vmid);
1e3baf05 4363
6b64503e 4364 check_lock($conf) if !$skiplock;
1e3baf05 4365
816e2c4a 4366 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
4367 });
4368}
4369
4370sub get_vm_volumes {
4371 my ($conf) = @_;
1e3baf05 4372
ff1a2432 4373 my $vollist = [];
d5769dc2
DM
4374 foreach_volid($conf, sub {
4375 my ($volid, $is_cdrom) = @_;
ff1a2432 4376
d5769dc2 4377 return if $volid =~ m|^/|;
ff1a2432 4378
d5769dc2
DM
4379 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
4380 return if !$sid;
ff1a2432
DM
4381
4382 push @$vollist, $volid;
1e3baf05 4383 });
ff1a2432
DM
4384
4385 return $vollist;
4386}
4387
4388sub vm_stop_cleanup {
70b04821 4389 my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
ff1a2432 4390
745fed70
DM
4391 eval {
4392 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 4393
254575e9
DM
4394 if (!$keepActive) {
4395 my $vollist = get_vm_volumes($conf);
4396 PVE::Storage::deactivate_volumes($storecfg, $vollist);
4397 }
a1b7d579 4398
ab6a046f 4399 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
4400 unlink "/var/run/qemu-server/${vmid}.$ext";
4401 }
a1b7d579 4402
70b04821 4403 vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
745fed70
DM
4404 };
4405 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
4406}
4407
e6c3b671 4408# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
4409# We need that when migration VMs to other nodes (files already moved)
4410# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 4411sub vm_stop {
af30308f 4412 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 4413
9269013a 4414 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 4415
af30308f
DM
4416 if ($migratedfrom){
4417 my $pid = check_running($vmid, $nocheck, $migratedfrom);
4418 kill 15, $pid if $pid;
4419 my $conf = load_config($vmid, $migratedfrom);
70b04821 4420 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 0);
af30308f
DM
4421 return;
4422 }
4423
e6c3b671 4424 lock_config($vmid, sub {
1e3baf05 4425
e6c3b671 4426 my $pid = check_running($vmid, $nocheck);
ff1a2432 4427 return if !$pid;
1e3baf05 4428
ff1a2432 4429 my $conf;
e6c3b671 4430 if (!$nocheck) {
ff1a2432 4431 $conf = load_config($vmid);
e6c3b671 4432 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
4433 if (!defined($timeout) && $shutdown && $conf->{startup}) {
4434 my $opts = parse_startup($conf->{startup});
4435 $timeout = $opts->{down} if $opts->{down};
4436 }
e6c3b671 4437 }
19672434 4438
7f4a5b5a 4439 $timeout = 60 if !defined($timeout);
67fb9de6 4440
9269013a
DM
4441 eval {
4442 if ($shutdown) {
fbda7965 4443 if (defined($conf) && $conf->{agent}) {
2ea54503 4444 vm_qmp_command($vmid, { execute => "guest-shutdown" }, $nocheck);
1c0c1c17 4445 } else {
2ea54503 4446 vm_qmp_command($vmid, { execute => "system_powerdown" }, $nocheck);
1c0c1c17 4447 }
9269013a 4448 } else {
2ea54503 4449 vm_qmp_command($vmid, { execute => "quit" }, $nocheck);
afdb31d5 4450 }
9269013a 4451 };
1e3baf05
DM
4452 my $err = $@;
4453
4454 if (!$err) {
1e3baf05 4455 my $count = 0;
e6c3b671 4456 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4457 $count++;
4458 sleep 1;
4459 }
4460
4461 if ($count >= $timeout) {
9269013a
DM
4462 if ($force) {
4463 warn "VM still running - terminating now with SIGTERM\n";
4464 kill 15, $pid;
4465 } else {
4466 die "VM quit/powerdown failed - got timeout\n";
4467 }
4468 } else {
70b04821 4469 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
9269013a 4470 return;
1e3baf05
DM
4471 }
4472 } else {
9269013a
DM
4473 if ($force) {
4474 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
4475 kill 15, $pid;
4476 } else {
afdb31d5 4477 die "VM quit/powerdown failed\n";
9269013a 4478 }
1e3baf05
DM
4479 }
4480
4481 # wait again
ff1a2432 4482 $timeout = 10;
1e3baf05
DM
4483
4484 my $count = 0;
e6c3b671 4485 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4486 $count++;
4487 sleep 1;
4488 }
4489
4490 if ($count >= $timeout) {
ff1a2432 4491 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 4492 kill 9, $pid;
ff1a2432 4493 sleep 1;
1e3baf05
DM
4494 }
4495
70b04821 4496 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
ff1a2432 4497 });
1e3baf05
DM
4498}
4499
4500sub vm_suspend {
4501 my ($vmid, $skiplock) = @_;
4502
6b64503e 4503 lock_config($vmid, sub {
1e3baf05 4504
6b64503e 4505 my $conf = load_config($vmid);
1e3baf05 4506
051347aa 4507 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
bcb7c9cf 4508
f77f91f3 4509 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
4510 });
4511}
4512
4513sub vm_resume {
4514 my ($vmid, $skiplock) = @_;
4515
6b64503e 4516 lock_config($vmid, sub {
1e3baf05 4517
6b64503e 4518 my $conf = load_config($vmid);
1e3baf05 4519
051347aa 4520 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
1e3baf05 4521
12060fe8 4522 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
4523 });
4524}
4525
5fdbe4f0
DM
4526sub vm_sendkey {
4527 my ($vmid, $skiplock, $key) = @_;
1e3baf05 4528
6b64503e 4529 lock_config($vmid, sub {
1e3baf05 4530
6b64503e 4531 my $conf = load_config($vmid);
f5eb281a 4532
7b7c6d1b
DM
4533 # there is no qmp command, so we use the human monitor command
4534 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
4535 });
4536}
4537
4538sub vm_destroy {
4539 my ($storecfg, $vmid, $skiplock) = @_;
4540
6b64503e 4541 lock_config($vmid, sub {
1e3baf05 4542
6b64503e 4543 my $conf = load_config($vmid);
1e3baf05 4544
6b64503e 4545 check_lock($conf) if !$skiplock;
1e3baf05 4546
ff1a2432
DM
4547 if (!check_running($vmid)) {
4548 fairsched_rmnod($vmid); # try to destroy group
4549 destroy_vm($storecfg, $vmid);
4550 } else {
4551 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
4552 }
4553 });
4554}
4555
1e3baf05
DM
4556# pci helpers
4557
4558sub file_write {
4559 my ($filename, $buf) = @_;
4560
6b64503e 4561 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
4562 return undef if !$fh;
4563
4564 my $res = print $fh $buf;
4565
4566 $fh->close();
4567
4568 return $res;
4569}
4570
4571sub pci_device_info {
4572 my ($name) = @_;
4573
4574 my $res;
4575
4576 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
4577 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
4578
4579 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
4580 return undef if !defined($irq) || $irq !~ m/^\d+$/;
4581
4582 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
4583 return undef if !defined($vendor) || $vendor !~ s/^0x//;
4584
4585 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
4586 return undef if !defined($product) || $product !~ s/^0x//;
4587
4588 $res = {
4589 name => $name,
4590 vendor => $vendor,
4591 product => $product,
4592 domain => $domain,
4593 bus => $bus,
4594 slot => $slot,
4595 func => $func,
4596 irq => $irq,
4597 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
4598 };
4599
4600 return $res;
4601}
4602
4603sub pci_dev_reset {
4604 my ($dev) = @_;
4605
4606 my $name = $dev->{name};
4607
4608 my $fn = "$pcisysfs/devices/$name/reset";
4609
6b64503e 4610 return file_write($fn, "1");
1e3baf05
DM
4611}
4612
4613sub pci_dev_bind_to_stub {
4614 my ($dev) = @_;
4615
4616 my $name = $dev->{name};
4617
4618 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
4619 return 1 if -d $testdir;
4620
4621 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 4622 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
4623
4624 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 4625 if (!file_write($fn, $name)) {
1e3baf05
DM
4626 return undef if -f $fn;
4627 }
4628
4629 $fn = "$pcisysfs/drivers/pci-stub/bind";
4630 if (! -d $testdir) {
6b64503e 4631 return undef if !file_write($fn, $name);
1e3baf05
DM
4632 }
4633
4634 return -d $testdir;
4635}
4636
000fc0a2
SP
4637sub pci_dev_bind_to_vfio {
4638 my ($dev) = @_;
4639
4640 my $name = $dev->{name};
4641
4642 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4643
4644 if (!-d $vfio_basedir) {
4645 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4646 }
4647 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4648
4649 my $testdir = "$vfio_basedir/$name";
4650 return 1 if -d $testdir;
4651
4652 my $data = "$dev->{vendor} $dev->{product}";
4653 return undef if !file_write("$vfio_basedir/new_id", $data);
4654
4655 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4656 if (!file_write($fn, $name)) {
4657 return undef if -f $fn;
4658 }
4659
4660 $fn = "$vfio_basedir/bind";
4661 if (! -d $testdir) {
4662 return undef if !file_write($fn, $name);
4663 }
4664
4665 return -d $testdir;
4666}
4667
4668sub pci_dev_group_bind_to_vfio {
4669 my ($pciid) = @_;
4670
4671 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4672
4673 if (!-d $vfio_basedir) {
4674 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4675 }
4676 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4677
4678 # get IOMMU group devices
4679 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
4680 my @devs = grep /^0000:/, readdir($D);
4681 closedir($D);
4682
4683 foreach my $pciid (@devs) {
4684 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
f8fa2ed7
SP
4685
4686 # pci bridges, switches or root ports are not supported
4687 # they have a pci_bus subdirectory so skip them
4688 next if (-e "$pcisysfs/devices/$pciid/pci_bus");
4689
000fc0a2
SP
4690 my $info = pci_device_info($1);
4691 pci_dev_bind_to_vfio($info) || die "Cannot bind $pciid to vfio\n";
4692 }
4693
4694 return 1;
4695}
4696
afdb31d5 4697sub print_pci_addr {
5bdcf937 4698 my ($id, $bridges) = @_;
6b64503e 4699
72a063e4 4700 my $res = '';
6b64503e 4701 my $devices = {
24f0d39a 4702 piix3 => { bus => 0, addr => 1 },
e5f7f8ed 4703 #addr2 : first videocard
13b5a753 4704 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 4705 watchdog => { bus => 0, addr => 4 },
a1b7d579 4706 scsihw0 => { bus => 0, addr => 5 },
6731a4cf 4707 'pci.3' => { bus => 0, addr => 5 }, #can also be used for virtio-scsi-single bridge
cdd20088 4708 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 4709 ahci0 => { bus => 0, addr => 7 },
ab6a046f 4710 qga0 => { bus => 0, addr => 8 },
1011b570 4711 spice => { bus => 0, addr => 9 },
6b64503e
DM
4712 virtio0 => { bus => 0, addr => 10 },
4713 virtio1 => { bus => 0, addr => 11 },
4714 virtio2 => { bus => 0, addr => 12 },
4715 virtio3 => { bus => 0, addr => 13 },
4716 virtio4 => { bus => 0, addr => 14 },
4717 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
4718 hostpci0 => { bus => 0, addr => 16 },
4719 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
4720 net0 => { bus => 0, addr => 18 },
4721 net1 => { bus => 0, addr => 19 },
4722 net2 => { bus => 0, addr => 20 },
4723 net3 => { bus => 0, addr => 21 },
4724 net4 => { bus => 0, addr => 22 },
4725 net5 => { bus => 0, addr => 23 },
2fa3151e
AD
4726 vga1 => { bus => 0, addr => 24 },
4727 vga2 => { bus => 0, addr => 25 },
4728 vga3 => { bus => 0, addr => 26 },
5cffb2d2
AD
4729 hostpci2 => { bus => 0, addr => 27 },
4730 hostpci3 => { bus => 0, addr => 28 },
e5f7f8ed 4731 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
4732 'pci.1' => { bus => 0, addr => 30 },
4733 'pci.2' => { bus => 0, addr => 31 },
4734 'net6' => { bus => 1, addr => 1 },
4735 'net7' => { bus => 1, addr => 2 },
4736 'net8' => { bus => 1, addr => 3 },
4737 'net9' => { bus => 1, addr => 4 },
4738 'net10' => { bus => 1, addr => 5 },
4739 'net11' => { bus => 1, addr => 6 },
4740 'net12' => { bus => 1, addr => 7 },
4741 'net13' => { bus => 1, addr => 8 },
4742 'net14' => { bus => 1, addr => 9 },
4743 'net15' => { bus => 1, addr => 10 },
4744 'net16' => { bus => 1, addr => 11 },
4745 'net17' => { bus => 1, addr => 12 },
4746 'net18' => { bus => 1, addr => 13 },
4747 'net19' => { bus => 1, addr => 14 },
4748 'net20' => { bus => 1, addr => 15 },
4749 'net21' => { bus => 1, addr => 16 },
4750 'net22' => { bus => 1, addr => 17 },
4751 'net23' => { bus => 1, addr => 18 },
4752 'net24' => { bus => 1, addr => 19 },
4753 'net25' => { bus => 1, addr => 20 },
4754 'net26' => { bus => 1, addr => 21 },
4755 'net27' => { bus => 1, addr => 22 },
4756 'net28' => { bus => 1, addr => 23 },
4757 'net29' => { bus => 1, addr => 24 },
4758 'net30' => { bus => 1, addr => 25 },
4759 'net31' => { bus => 1, addr => 26 },
4760 'virtio6' => { bus => 2, addr => 1 },
4761 'virtio7' => { bus => 2, addr => 2 },
4762 'virtio8' => { bus => 2, addr => 3 },
4763 'virtio9' => { bus => 2, addr => 4 },
4764 'virtio10' => { bus => 2, addr => 5 },
4765 'virtio11' => { bus => 2, addr => 6 },
4766 'virtio12' => { bus => 2, addr => 7 },
4767 'virtio13' => { bus => 2, addr => 8 },
4768 'virtio14' => { bus => 2, addr => 9 },
4769 'virtio15' => { bus => 2, addr => 10 },
6731a4cf
AD
4770 'virtioscsi0' => { bus => 3, addr => 1 },
4771 'virtioscsi1' => { bus => 3, addr => 2 },
4772 'virtioscsi2' => { bus => 3, addr => 3 },
4773 'virtioscsi3' => { bus => 3, addr => 4 },
4774 'virtioscsi4' => { bus => 3, addr => 5 },
4775 'virtioscsi5' => { bus => 3, addr => 6 },
4776 'virtioscsi6' => { bus => 3, addr => 7 },
4777 'virtioscsi7' => { bus => 3, addr => 8 },
4778 'virtioscsi8' => { bus => 3, addr => 9 },
4779 'virtioscsi9' => { bus => 3, addr => 10 },
4780 'virtioscsi10' => { bus => 3, addr => 11 },
4781 'virtioscsi11' => { bus => 3, addr => 12 },
4782 'virtioscsi12' => { bus => 3, addr => 13 },
4783 'virtioscsi13' => { bus => 3, addr => 14 },
4784 'virtioscsi14' => { bus => 3, addr => 15 },
4785 'virtioscsi15' => { bus => 3, addr => 16 },
4786 'virtioscsi16' => { bus => 3, addr => 17 },
4787 'virtioscsi17' => { bus => 3, addr => 18 },
4788 'virtioscsi18' => { bus => 3, addr => 19 },
4789 'virtioscsi19' => { bus => 3, addr => 20 },
4790 'virtioscsi20' => { bus => 3, addr => 21 },
4791 'virtioscsi21' => { bus => 3, addr => 22 },
4792 'virtioscsi22' => { bus => 3, addr => 23 },
4793 'virtioscsi23' => { bus => 3, addr => 24 },
4794 'virtioscsi24' => { bus => 3, addr => 25 },
4795 'virtioscsi25' => { bus => 3, addr => 26 },
4796 'virtioscsi26' => { bus => 3, addr => 27 },
4797 'virtioscsi27' => { bus => 3, addr => 28 },
4798 'virtioscsi28' => { bus => 3, addr => 29 },
4799 'virtioscsi29' => { bus => 3, addr => 30 },
4800 'virtioscsi30' => { bus => 3, addr => 31 },
4801
6b64503e
DM
4802 };
4803
4804 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 4805 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
4806 my $bus = $devices->{$id}->{bus};
4807 $res = ",bus=pci.$bus,addr=$addr";
98627641 4808 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
4809 }
4810 return $res;
4811
4812}
4813
2e3b7e2a
AD
4814sub print_pcie_addr {
4815 my ($id) = @_;
4816
4817 my $res = '';
4818 my $devices = {
4819 hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 },
4820 hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 },
4821 hostpci2 => { bus => "ich9-pcie-port-3", addr => 0 },
4822 hostpci3 => { bus => "ich9-pcie-port-4", addr => 0 },
4823 };
4824
4825 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
4826 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
4827 my $bus = $devices->{$id}->{bus};
4828 $res = ",bus=$bus,addr=$addr";
4829 }
4830 return $res;
4831
4832}
4833
3e16d5fc
DM
4834# vzdump restore implementaion
4835
ed221350 4836sub tar_archive_read_firstfile {
3e16d5fc 4837 my $archive = shift;
afdb31d5 4838
3e16d5fc
DM
4839 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
4840
4841 # try to detect archive type first
4842 my $pid = open (TMP, "tar tf '$archive'|") ||
4843 die "unable to open file '$archive'\n";
4844 my $firstfile = <TMP>;
4845 kill 15, $pid;
4846 close TMP;
4847
4848 die "ERROR: archive contaions no data\n" if !$firstfile;
4849 chomp $firstfile;
4850
4851 return $firstfile;
4852}
4853
ed221350
DM
4854sub tar_restore_cleanup {
4855 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
4856
4857 print STDERR "starting cleanup\n";
4858
4859 if (my $fd = IO::File->new($statfile, "r")) {
4860 while (defined(my $line = <$fd>)) {
4861 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4862 my $volid = $2;
4863 eval {
4864 if ($volid =~ m|^/|) {
4865 unlink $volid || die 'unlink failed\n';
4866 } else {
ed221350 4867 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 4868 }
afdb31d5 4869 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
4870 };
4871 print STDERR "unable to cleanup '$volid' - $@" if $@;
4872 } else {
4873 print STDERR "unable to parse line in statfile - $line";
afdb31d5 4874 }
3e16d5fc
DM
4875 }
4876 $fd->close();
4877 }
4878}
4879
4880sub restore_archive {
a0d1b1a2 4881 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 4882
91bd6c90
DM
4883 my $format = $opts->{format};
4884 my $comp;
4885
4886 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
4887 $format = 'tar' if !$format;
4888 $comp = 'gzip';
4889 } elsif ($archive =~ m/\.tar$/) {
4890 $format = 'tar' if !$format;
4891 } elsif ($archive =~ m/.tar.lzo$/) {
4892 $format = 'tar' if !$format;
4893 $comp = 'lzop';
4894 } elsif ($archive =~ m/\.vma$/) {
4895 $format = 'vma' if !$format;
4896 } elsif ($archive =~ m/\.vma\.gz$/) {
4897 $format = 'vma' if !$format;
4898 $comp = 'gzip';
4899 } elsif ($archive =~ m/\.vma\.lzo$/) {
4900 $format = 'vma' if !$format;
4901 $comp = 'lzop';
4902 } else {
4903 $format = 'vma' if !$format; # default
4904 }
4905
4906 # try to detect archive format
4907 if ($format eq 'tar') {
4908 return restore_tar_archive($archive, $vmid, $user, $opts);
4909 } else {
4910 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
4911 }
4912}
4913
4914sub restore_update_config_line {
4915 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
4916
4917 return if $line =~ m/^\#qmdump\#/;
4918 return if $line =~ m/^\#vzdump\#/;
4919 return if $line =~ m/^lock:/;
4920 return if $line =~ m/^unused\d+:/;
4921 return if $line =~ m/^parent:/;
ca3e4fa4 4922 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
4923
4924 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
4925 # try to convert old 1.X settings
4926 my ($id, $ind, $ethcfg) = ($1, $2, $3);
4927 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
4928 my ($model, $macaddr) = split(/\=/, $devconfig);
4929 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
4930 my $net = {
4931 model => $model,
4932 bridge => "vmbr$ind",
4933 macaddr => $macaddr,
4934 };
4935 my $netstr = print_net($net);
4936
4937 print $outfd "net$cookie->{netcount}: $netstr\n";
4938 $cookie->{netcount}++;
4939 }
4940 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
4941 my ($id, $netstr) = ($1, $2);
4942 my $net = parse_net($netstr);
4943 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
4944 $netstr = print_net($net);
4945 print $outfd "$id: $netstr\n";
4946 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
4947 my $virtdev = $1;
907ea891 4948 my $value = $3;
91bd6c90
DM
4949 if ($line =~ m/backup=no/) {
4950 print $outfd "#$line";
4951 } elsif ($virtdev && $map->{$virtdev}) {
ed221350 4952 my $di = parse_drive($virtdev, $value);
8fd57431 4953 delete $di->{format}; # format can change on restore
91bd6c90 4954 $di->{file} = $map->{$virtdev};
ed221350 4955 $value = print_drive($vmid, $di);
91bd6c90
DM
4956 print $outfd "$virtdev: $value\n";
4957 } else {
4958 print $outfd $line;
4959 }
4960 } else {
4961 print $outfd $line;
4962 }
4963}
4964
4965sub scan_volids {
4966 my ($cfg, $vmid) = @_;
4967
4968 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
4969
4970 my $volid_hash = {};
4971 foreach my $storeid (keys %$info) {
4972 foreach my $item (@{$info->{$storeid}}) {
4973 next if !($item->{volid} && $item->{size});
5996a936 4974 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
4975 $volid_hash->{$item->{volid}} = $item;
4976 }
4977 }
4978
4979 return $volid_hash;
4980}
4981
a8e2f942
DM
4982sub get_used_paths {
4983 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
4984
4985 my $used_path = {};
4986
4987 my $scan_config = sub {
4988 my ($cref, $snapname) = @_;
4989
4990 foreach my $key (keys %$cref) {
4991 my $value = $cref->{$key};
4992 if (valid_drivename($key)) {
4993 next if $skip_drive && $key eq $skip_drive;
4994 my $drive = parse_drive($key, $value);
4995 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
4996 if ($drive->{file} =~ m!^/!) {
4997 $used_path->{$drive->{file}}++; # = 1;
4998 } else {
4999 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
5000 next if !$storeid;
5001 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
5002 next if !$scfg;
5003 my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
5004 $used_path->{$path}++; # = 1;
5005 }
5006 }
5007 }
5008 };
5009
5010 &$scan_config($conf);
5011
5012 undef $skip_drive;
5013
5014 if ($scan_snapshots) {
5015 foreach my $snapname (keys %{$conf->{snapshots}}) {
5016 &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
5017 }
5018 }
5019
5020 return $used_path;
5021}
5022
91bd6c90
DM
5023sub update_disksize {
5024 my ($vmid, $conf, $volid_hash) = @_;
be190583 5025
91bd6c90
DM
5026 my $changes;
5027
5028 my $used = {};
5029
5996a936
DM
5030 # Note: it is allowed to define multiple storages with same path (alias), so
5031 # we need to check both 'volid' and real 'path' (two different volid can point
5032 # to the same path).
5033
5034 my $usedpath = {};
be190583 5035
91bd6c90
DM
5036 # update size info
5037 foreach my $opt (keys %$conf) {
ed221350
DM
5038 if (valid_drivename($opt)) {
5039 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
5040 my $volid = $drive->{file};
5041 next if !$volid;
5042
5043 $used->{$volid} = 1;
be190583 5044 if ($volid_hash->{$volid} &&
5996a936
DM
5045 (my $path = $volid_hash->{$volid}->{path})) {
5046 $usedpath->{$path} = 1;
5047 }
91bd6c90 5048
ed221350 5049 next if drive_is_cdrom($drive);
91bd6c90
DM
5050 next if !$volid_hash->{$volid};
5051
5052 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
5053 my $new = print_drive($vmid, $drive);
5054 if ($new ne $conf->{$opt}) {
5055 $changes = 1;
5056 $conf->{$opt} = $new;
5057 }
91bd6c90
DM
5058 }
5059 }
5060
5996a936
DM
5061 # remove 'unusedX' entry if volume is used
5062 foreach my $opt (keys %$conf) {
5063 next if $opt !~ m/^unused\d+$/;
5064 my $volid = $conf->{$opt};
5065 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 5066 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
5067 $changes = 1;
5068 delete $conf->{$opt};
5069 }
5070 }
5071
91bd6c90
DM
5072 foreach my $volid (sort keys %$volid_hash) {
5073 next if $volid =~ m/vm-$vmid-state-/;
5074 next if $used->{$volid};
5996a936
DM
5075 my $path = $volid_hash->{$volid}->{path};
5076 next if !$path; # just to be sure
5077 next if $usedpath->{$path};
91bd6c90 5078 $changes = 1;
ed221350 5079 add_unused_volume($conf, $volid);
05937a14 5080 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
5081 }
5082
5083 return $changes;
5084}
5085
5086sub rescan {
5087 my ($vmid, $nolock) = @_;
5088
5089 my $cfg = PVE::Cluster::cfs_read_file("storage.cfg");
5090
5091 my $volid_hash = scan_volids($cfg, $vmid);
5092
5093 my $updatefn = sub {
5094 my ($vmid) = @_;
5095
ed221350 5096 my $conf = load_config($vmid);
be190583 5097
ed221350 5098 check_lock($conf);
91bd6c90 5099
03da3f0d
DM
5100 my $vm_volids = {};
5101 foreach my $volid (keys %$volid_hash) {
5102 my $info = $volid_hash->{$volid};
5103 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
5104 }
5105
5106 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 5107
ed221350 5108 update_config_nolock($vmid, $conf, 1) if $changes;
91bd6c90
DM
5109 };
5110
5111 if (defined($vmid)) {
5112 if ($nolock) {
5113 &$updatefn($vmid);
5114 } else {
ed221350 5115 lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
5116 }
5117 } else {
5118 my $vmlist = config_list();
5119 foreach my $vmid (keys %$vmlist) {
5120 if ($nolock) {
5121 &$updatefn($vmid);
5122 } else {
ed221350 5123 lock_config($vmid, $updatefn, $vmid);
be190583 5124 }
91bd6c90
DM
5125 }
5126 }
5127}
5128
5129sub restore_vma_archive {
5130 my ($archive, $vmid, $user, $opts, $comp) = @_;
5131
5132 my $input = $archive eq '-' ? "<&STDIN" : undef;
5133 my $readfrom = $archive;
5134
5135 my $uncomp = '';
5136 if ($comp) {
5137 $readfrom = '-';
5138 my $qarchive = PVE::Tools::shellquote($archive);
5139 if ($comp eq 'gzip') {
5140 $uncomp = "zcat $qarchive|";
5141 } elsif ($comp eq 'lzop') {
5142 $uncomp = "lzop -d -c $qarchive|";
5143 } else {
5144 die "unknown compression method '$comp'\n";
5145 }
be190583 5146
91bd6c90
DM
5147 }
5148
5149 my $tmpdir = "/var/tmp/vzdumptmp$$";
5150 rmtree $tmpdir;
5151
5152 # disable interrupts (always do cleanups)
5153 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5154 warn "got interrupt - ignored\n";
5155 };
5156
5157 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
5158 POSIX::mkfifo($mapfifo, 0600);
5159 my $fifofh;
5160
5161 my $openfifo = sub {
5162 open($fifofh, '>', $mapfifo) || die $!;
5163 };
5164
5165 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
5166
5167 my $oldtimeout;
5168 my $timeout = 5;
5169
5170 my $devinfo = {};
5171
5172 my $rpcenv = PVE::RPCEnvironment::get();
5173
ed221350 5174 my $conffile = config_file($vmid);
91bd6c90
DM
5175 my $tmpfn = "$conffile.$$.tmp";
5176
ed221350
DM
5177 # Note: $oldconf is undef if VM does not exists
5178 my $oldconf = PVE::Cluster::cfs_read_file(cfs_config_path($vmid));
5179
91bd6c90
DM
5180 my $print_devmap = sub {
5181 my $virtdev_hash = {};
5182
5183 my $cfgfn = "$tmpdir/qemu-server.conf";
5184
5185 # we can read the config - that is already extracted
5186 my $fh = IO::File->new($cfgfn, "r") ||
5187 "unable to read qemu-server.conf - $!\n";
5188
5189 while (defined(my $line = <$fh>)) {
5190 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
5191 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
5192 die "archive does not contain data for drive '$virtdev'\n"
5193 if !$devinfo->{$devname};
5194 if (defined($opts->{storage})) {
5195 $storeid = $opts->{storage} || 'local';
5196 } elsif (!$storeid) {
5197 $storeid = 'local';
5198 }
5199 $format = 'raw' if !$format;
5200 $devinfo->{$devname}->{devname} = $devname;
5201 $devinfo->{$devname}->{virtdev} = $virtdev;
5202 $devinfo->{$devname}->{format} = $format;
5203 $devinfo->{$devname}->{storeid} = $storeid;
5204
be190583 5205 # check permission on storage
91bd6c90
DM
5206 my $pool = $opts->{pool}; # todo: do we need that?
5207 if ($user ne 'root@pam') {
5208 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
5209 }
5210
5211 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
5212 }
5213 }
5214
5215 foreach my $devname (keys %$devinfo) {
be190583
DM
5216 die "found no device mapping information for device '$devname'\n"
5217 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
5218 }
5219
91bd6c90 5220 my $cfg = cfs_read_file('storage.cfg');
ed221350
DM
5221
5222 # create empty/temp config
be190583 5223 if ($oldconf) {
ed221350
DM
5224 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
5225 foreach_drive($oldconf, sub {
5226 my ($ds, $drive) = @_;
5227
5228 return if drive_is_cdrom($drive);
5229
5230 my $volid = $drive->{file};
5231
5232 return if !$volid || $volid =~ m|^/|;
5233
5234 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
5235 return if !$path || !$owner || ($owner != $vmid);
5236
5237 # Note: only delete disk we want to restore
5238 # other volumes will become unused
5239 if ($virtdev_hash->{$ds}) {
5240 PVE::Storage::vdisk_free($cfg, $volid);
5241 }
5242 });
5243 }
5244
5245 my $map = {};
91bd6c90
DM
5246 foreach my $virtdev (sort keys %$virtdev_hash) {
5247 my $d = $virtdev_hash->{$virtdev};
5248 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
5249 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
5250
5251 # test if requested format is supported
5252 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
5253 my $supported = grep { $_ eq $d->{format} } @$validFormats;
5254 $d->{format} = $defFormat if !$supported;
5255
91bd6c90
DM
5256 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
5257 $d->{format}, undef, $alloc_size);
5258 print STDERR "new volume ID is '$volid'\n";
5259 $d->{volid} = $volid;
5260 my $path = PVE::Storage::path($cfg, $volid);
5261
5262 my $write_zeros = 1;
5263 # fixme: what other storages types initialize volumes with zero?
244f2577 5264 if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' || $scfg->{type} eq 'glusterfs' ||
013d5275 5265 $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
91bd6c90
DM
5266 $write_zeros = 0;
5267 }
5268
5269 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
5270
5271 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
5272 $map->{$virtdev} = $volid;
5273 }
5274
5275 $fh->seek(0, 0) || die "seek failed - $!\n";
5276
5277 my $outfd = new IO::File ($tmpfn, "w") ||
5278 die "unable to write config for VM $vmid\n";
5279
5280 my $cookie = { netcount => 0 };
5281 while (defined(my $line = <$fh>)) {
be190583 5282 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
5283 }
5284
5285 $fh->close();
5286 $outfd->close();
5287 };
5288
5289 eval {
5290 # enable interrupts
5291 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5292 die "interrupted by signal\n";
5293 };
5294 local $SIG{ALRM} = sub { die "got timeout\n"; };
5295
5296 $oldtimeout = alarm($timeout);
5297
5298 my $parser = sub {
5299 my $line = shift;
5300
5301 print "$line\n";
5302
5303 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
5304 my ($dev_id, $size, $devname) = ($1, $2, $3);
5305 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
5306 } elsif ($line =~ m/^CTIME: /) {
46f58b5f 5307 # we correctly received the vma config, so we can disable
3cf90d7a
DM
5308 # the timeout now for disk allocation (set to 10 minutes, so
5309 # that we always timeout if something goes wrong)
5310 alarm(600);
91bd6c90
DM
5311 &$print_devmap();
5312 print $fifofh "done\n";
5313 my $tmp = $oldtimeout || 0;
5314 $oldtimeout = undef;
5315 alarm($tmp);
5316 close($fifofh);
5317 }
5318 };
be190583 5319
91bd6c90
DM
5320 print "restore vma archive: $cmd\n";
5321 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
5322 };
5323 my $err = $@;
5324
5325 alarm($oldtimeout) if $oldtimeout;
5326
5327 unlink $mapfifo;
5328
5329 if ($err) {
5330 rmtree $tmpdir;
5331 unlink $tmpfn;
5332
5333 my $cfg = cfs_read_file('storage.cfg');
5334 foreach my $devname (keys %$devinfo) {
5335 my $volid = $devinfo->{$devname}->{volid};
5336 next if !$volid;
5337 eval {
5338 if ($volid =~ m|^/|) {
5339 unlink $volid || die 'unlink failed\n';
5340 } else {
5341 PVE::Storage::vdisk_free($cfg, $volid);
5342 }
5343 print STDERR "temporary volume '$volid' sucessfuly removed\n";
5344 };
5345 print STDERR "unable to cleanup '$volid' - $@" if $@;
5346 }
5347 die $err;
5348 }
5349
5350 rmtree $tmpdir;
ed221350
DM
5351
5352 rename($tmpfn, $conffile) ||
91bd6c90
DM
5353 die "unable to commit configuration file '$conffile'\n";
5354
ed221350
DM
5355 PVE::Cluster::cfs_update(); # make sure we read new file
5356
91bd6c90
DM
5357 eval { rescan($vmid, 1); };
5358 warn $@ if $@;
5359}
5360
5361sub restore_tar_archive {
5362 my ($archive, $vmid, $user, $opts) = @_;
5363
9c502e26 5364 if ($archive ne '-') {
ed221350 5365 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
5366 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
5367 if $firstfile ne 'qemu-server.conf';
5368 }
3e16d5fc 5369
ed221350 5370 my $storecfg = cfs_read_file('storage.cfg');
ebb55558 5371
ed221350 5372 # destroy existing data - keep empty config
8e90138a 5373 my $vmcfgfn = config_file($vmid);
ebb55558 5374 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 5375
3e16d5fc
DM
5376 my $tocmd = "/usr/lib/qemu-server/qmextract";
5377
2415a446 5378 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 5379 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
5380 $tocmd .= ' --prealloc' if $opts->{prealloc};
5381 $tocmd .= ' --info' if $opts->{info};
5382
a0d1b1a2 5383 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 5384 # so we pipe to zcat
2415a446
DM
5385 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
5386 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
5387
5388 my $tmpdir = "/var/tmp/vzdumptmp$$";
5389 mkpath $tmpdir;
5390
5391 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
5392 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 5393 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 5394
ed221350 5395 my $conffile = config_file($vmid);
3e16d5fc
DM
5396 my $tmpfn = "$conffile.$$.tmp";
5397
5398 # disable interrupts (always do cleanups)
5399 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5400 print STDERR "got interrupt - ignored\n";
5401 };
5402
afdb31d5 5403 eval {
3e16d5fc
DM
5404 # enable interrupts
5405 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5406 die "interrupted by signal\n";
5407 };
5408
9c502e26
DM
5409 if ($archive eq '-') {
5410 print "extracting archive from STDIN\n";
5411 run_command($cmd, input => "<&STDIN");
5412 } else {
5413 print "extracting archive '$archive'\n";
5414 run_command($cmd);
5415 }
3e16d5fc
DM
5416
5417 return if $opts->{info};
5418
5419 # read new mapping
5420 my $map = {};
5421 my $statfile = "$tmpdir/qmrestore.stat";
5422 if (my $fd = IO::File->new($statfile, "r")) {
5423 while (defined (my $line = <$fd>)) {
5424 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
5425 $map->{$1} = $2 if $1;
5426 } else {
5427 print STDERR "unable to parse line in statfile - $line\n";
5428 }
5429 }
5430 $fd->close();
5431 }
5432
5433 my $confsrc = "$tmpdir/qemu-server.conf";
5434
5435 my $srcfd = new IO::File($confsrc, "r") ||
5436 die "unable to open file '$confsrc'\n";
5437
5438 my $outfd = new IO::File ($tmpfn, "w") ||
5439 die "unable to write config for VM $vmid\n";
5440
91bd6c90 5441 my $cookie = { netcount => 0 };
3e16d5fc 5442 while (defined (my $line = <$srcfd>)) {
be190583 5443 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
5444 }
5445
5446 $srcfd->close();
5447 $outfd->close();
5448 };
5449 my $err = $@;
5450
afdb31d5 5451 if ($err) {
3e16d5fc
DM
5452
5453 unlink $tmpfn;
5454
ed221350 5455 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 5456
3e16d5fc 5457 die $err;
afdb31d5 5458 }
3e16d5fc
DM
5459
5460 rmtree $tmpdir;
5461
5462 rename $tmpfn, $conffile ||
5463 die "unable to commit configuration file '$conffile'\n";
91bd6c90 5464
ed221350
DM
5465 PVE::Cluster::cfs_update(); # make sure we read new file
5466
91bd6c90
DM
5467 eval { rescan($vmid, 1); };
5468 warn $@ if $@;
3e16d5fc
DM
5469};
5470
0d18dcfc
DM
5471
5472# Internal snapshots
5473
5474# NOTE: Snapshot create/delete involves several non-atomic
5475# action, and can take a long time.
5476# So we try to avoid locking the file and use 'lock' variable
5477# inside the config file instead.
5478
ef59d1ca
DM
5479my $snapshot_copy_config = sub {
5480 my ($source, $dest) = @_;
5481
5482 foreach my $k (keys %$source) {
5483 next if $k eq 'snapshots';
982c7f12
DM
5484 next if $k eq 'snapstate';
5485 next if $k eq 'snaptime';
18bfb361 5486 next if $k eq 'vmstate';
ef59d1ca
DM
5487 next if $k eq 'lock';
5488 next if $k eq 'digest';
db7c26e5 5489 next if $k eq 'description';
ef59d1ca 5490 next if $k =~ m/^unused\d+$/;
be190583 5491
ef59d1ca
DM
5492 $dest->{$k} = $source->{$k};
5493 }
5494};
5495
5496my $snapshot_apply_config = sub {
5497 my ($conf, $snap) = @_;
5498
5499 # copy snapshot list
5500 my $newconf = {
5501 snapshots => $conf->{snapshots},
5502 };
5503
db7c26e5 5504 # keep description and list of unused disks
ef59d1ca 5505 foreach my $k (keys %$conf) {
db7c26e5 5506 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
5507 $newconf->{$k} = $conf->{$k};
5508 }
5509
5510 &$snapshot_copy_config($snap, $newconf);
5511
5512 return $newconf;
5513};
5514
18bfb361
DM
5515sub foreach_writable_storage {
5516 my ($conf, $func) = @_;
5517
5518 my $sidhash = {};
5519
5520 foreach my $ds (keys %$conf) {
5521 next if !valid_drivename($ds);
5522
5523 my $drive = parse_drive($ds, $conf->{$ds});
5524 next if !$drive;
5525 next if drive_is_cdrom($drive);
5526
5527 my $volid = $drive->{file};
5528
5529 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 5530 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
5531 }
5532
5533 foreach my $sid (sort keys %$sidhash) {
5534 &$func($sid);
5535 }
5536}
5537
5538my $alloc_vmstate_volid = sub {
5539 my ($storecfg, $vmid, $conf, $snapname) = @_;
be190583 5540
18bfb361
DM
5541 # Note: we try to be smart when selecting a $target storage
5542
5543 my $target;
5544
5545 # search shared storage first
5546 foreach_writable_storage($conf, sub {
5547 my ($sid) = @_;
5548 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5549 return if !$scfg->{shared};
5550
5551 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
5552 });
5553
5554 if (!$target) {
5555 # now search local storage
5556 foreach_writable_storage($conf, sub {
5557 my ($sid) = @_;
5558 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5559 return if $scfg->{shared};
5560
5561 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
5562 });
5563 }
5564
5565 $target = 'local' if !$target;
5566
fe6249f4
DM
5567 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
5568 # we abort live save after $conf->{memory}, so we need at max twice that space
5569 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
5570
5571 my $name = "vm-$vmid-state-$snapname";
5572 my $scfg = PVE::Storage::storage_config($storecfg, $target);
5573 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
5574 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
5575
5576 return $volid;
5577};
5578
0d18dcfc 5579my $snapshot_prepare = sub {
18bfb361 5580 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
5581
5582 my $snap;
0d18dcfc
DM
5583
5584 my $updatefn = sub {
5585
5586 my $conf = load_config($vmid);
5587
be190583 5588 die "you can't take a snapshot if it's a template\n"
5295b23d
DM
5589 if is_template($conf);
5590
0d18dcfc
DM
5591 check_lock($conf);
5592
22c377f0
DM
5593 $conf->{lock} = 'snapshot';
5594
be190583
DM
5595 die "snapshot name '$snapname' already used\n"
5596 if defined($conf->{snapshots}->{$snapname});
0d18dcfc 5597
ee2f90b1 5598 my $storecfg = PVE::Storage::config();
7ea975ef 5599 die "snapshot feature is not available" if !has_feature('snapshot', $conf, $storecfg);
18bfb361 5600
782f4f75 5601 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 5602
18bfb361
DM
5603 if ($save_vmstate && check_running($vmid)) {
5604 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
5605 }
5606
ef59d1ca 5607 &$snapshot_copy_config($conf, $snap);
0d18dcfc 5608
782f4f75
DM
5609 $snap->{snapstate} = "prepare";
5610 $snap->{snaptime} = time();
5611 $snap->{description} = $comment if $comment;
5612
4b15803d
DM
5613 # always overwrite machine if we save vmstate. This makes sure we
5614 # can restore it later using correct machine type
5615 $snap->{machine} = get_current_qemu_machine($vmid) if $snap->{vmstate};
5616
0d18dcfc
DM
5617 update_config_nolock($vmid, $conf, 1);
5618 };
5619
5620 lock_config($vmid, $updatefn);
22c377f0
DM
5621
5622 return $snap;
0d18dcfc
DM
5623};
5624
5625my $snapshot_commit = sub {
5626 my ($vmid, $snapname) = @_;
5627
5628 my $updatefn = sub {
5629
5630 my $conf = load_config($vmid);
5631
be190583
DM
5632 die "missing snapshot lock\n"
5633 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
0d18dcfc 5634
7946e0fa
DM
5635 my $has_machine_config = defined($conf->{machine});
5636
0d18dcfc
DM
5637 my $snap = $conf->{snapshots}->{$snapname};
5638
be190583
DM
5639 die "snapshot '$snapname' does not exist\n" if !defined($snap);
5640
5641 die "wrong snapshot state\n"
5642 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
0d18dcfc 5643
0d18dcfc 5644 delete $snap->{snapstate};
ee2f90b1 5645 delete $conf->{lock};
0d18dcfc 5646
ef59d1ca 5647 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 5648
7946e0fa
DM
5649 delete $newconf->{machine} if !$has_machine_config;
5650
05e5ad3f
DM
5651 $newconf->{parent} = $snapname;
5652
0d18dcfc
DM
5653 update_config_nolock($vmid, $newconf, 1);
5654 };
5655
5656 lock_config($vmid, $updatefn);
5657};
5658
22c377f0
DM
5659sub snapshot_rollback {
5660 my ($vmid, $snapname) = @_;
5661
22c377f0
DM
5662 my $prepare = 1;
5663
a3222b91 5664 my $storecfg = PVE::Storage::config();
be190583 5665
ba4eea15 5666 my $conf = load_config($vmid);
22c377f0 5667
ba4eea15 5668 my $get_snapshot_config = sub {
22c377f0 5669
8b43bc11 5670 die "you can't rollback if vm is a template\n" if is_template($conf);
90b0c6b3 5671
ba4eea15 5672 my $res = $conf->{snapshots}->{$snapname};
ab33a7c2 5673
ba4eea15
WL
5674 die "snapshot '$snapname' does not exist\n" if !defined($res);
5675
5676 return $res;
5677 };
5678
5679 my $snap = &$get_snapshot_config();
5680
5681 foreach_drive($snap, sub {
5682 my ($ds, $drive) = @_;
5683
5684 return if drive_is_cdrom($drive);
5685
5686 my $volid = $drive->{file};
5687
5688 PVE::Storage::volume_rollback_is_possible($storecfg, $volid, $snapname);
5689 });
5690
5691 my $updatefn = sub {
5692
5693 $conf = load_config($vmid);
5694
5695 $snap = &$get_snapshot_config();
ab33a7c2 5696
be190583 5697 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
ab33a7c2
DM
5698 if $snap->{snapstate};
5699
a3222b91
DM
5700 if ($prepare) {
5701 check_lock($conf);
5702 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
5703 }
22c377f0
DM
5704
5705 die "unable to rollback vm $vmid: vm is running\n"
5706 if check_running($vmid);
5707
5708 if ($prepare) {
5709 $conf->{lock} = 'rollback';
5710 } else {
5711 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
5712 delete $conf->{lock};
5713 }
5714
4b15803d
DM
5715 my $forcemachine;
5716
22c377f0 5717 if (!$prepare) {
4b15803d
DM
5718 my $has_machine_config = defined($conf->{machine});
5719
22c377f0 5720 # copy snapshot config to current config
ef59d1ca
DM
5721 $conf = &$snapshot_apply_config($conf, $snap);
5722 $conf->{parent} = $snapname;
4b15803d 5723
d8b916fd
DM
5724 # Note: old code did not store 'machine', so we try to be smart
5725 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
5726 $forcemachine = $conf->{machine} || 'pc-i440fx-1.4';
be190583 5727 # we remove the 'machine' configuration if not explicitly specified
4b15803d
DM
5728 # in the original config.
5729 delete $conf->{machine} if $snap->{vmstate} && !$has_machine_config;
22c377f0
DM
5730 }
5731
5732 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
5733
5734 if (!$prepare && $snap->{vmstate}) {
5735 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
4b15803d 5736 vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
a3222b91 5737 }
22c377f0
DM
5738 };
5739
5740 lock_config($vmid, $updatefn);
be190583 5741
22c377f0
DM
5742 foreach_drive($snap, sub {
5743 my ($ds, $drive) = @_;
5744
5745 return if drive_is_cdrom($drive);
5746
5747 my $volid = $drive->{file};
5748 my $device = "drive-$ds";
5749
79e57b29 5750 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
5751 });
5752
5753 $prepare = 0;
5754 lock_config($vmid, $updatefn);
5755}
5756
9dcf4909
DM
5757my $savevm_wait = sub {
5758 my ($vmid) = @_;
5759
5760 for(;;) {
ed221350 5761 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
9dcf4909
DM
5762 if (!$stat->{status}) {
5763 die "savevm not active\n";
5764 } elsif ($stat->{status} eq 'active') {
5765 sleep(1);
5766 next;
5767 } elsif ($stat->{status} eq 'completed') {
5768 last;
5769 } else {
5770 die "query-savevm returned status '$stat->{status}'\n";
5771 }
5772 }
5773};
5774
0d18dcfc 5775sub snapshot_create {
af9110dd 5776 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
0d18dcfc 5777
18bfb361 5778 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 5779
af9110dd 5780 $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
18bfb361 5781
67fb9de6
DM
5782 my $config = load_config($vmid);
5783
af9110dd
WL
5784 my $running = check_running($vmid);
5785
67fb9de6 5786 my $freezefs = $running && $config->{agent};
af9110dd
WL
5787 $freezefs = 0 if $snap->{vmstate}; # not needed if we save RAM
5788
5789 my $drivehash = {};
5790
5791 if ($freezefs) {
65994ad7
WL
5792 eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); };
5793 warn "guest-fsfreeze-freeze problems - $@" if $@;
5794 }
67fb9de6 5795
0d18dcfc
DM
5796 eval {
5797 # create internal snapshots of all drives
22c377f0
DM
5798
5799 my $storecfg = PVE::Storage::config();
a3222b91
DM
5800
5801 if ($running) {
5802 if ($snap->{vmstate}) {
be190583 5803 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
5804 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
5805 &$savevm_wait($vmid);
a3222b91 5806 } else {
9dcf4909 5807 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
5808 }
5809 };
5810
22c377f0
DM
5811 foreach_drive($snap, sub {
5812 my ($ds, $drive) = @_;
5813
5814 return if drive_is_cdrom($drive);
0d18dcfc 5815
22c377f0
DM
5816 my $volid = $drive->{file};
5817 my $device = "drive-$ds";
5818
5819 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 5820 $drivehash->{$ds} = 1;
22c377f0 5821 });
0d18dcfc 5822 };
22c377f0
DM
5823 my $err = $@;
5824
65994ad7
WL
5825 if ($running) {
5826 eval { vm_mon_cmd($vmid, "savevm-end") };
5827 warn $@ if $@;
22c377f0 5828
af9110dd 5829 if ($freezefs) {
67fb9de6 5830 eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); };
65994ad7
WL
5831 warn "guest-fsfreeze-thaw problems - $@" if $@;
5832 }
22c377f0 5833
65994ad7 5834 # savevm-end is async, we need to wait
f34ebd52 5835 for (;;) {
2c9e8036
AD
5836 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
5837 if (!$stat->{bytes}) {
5838 last;
5839 } else {
5840 print "savevm not yet finished\n";
5841 sleep(1);
5842 next;
5843 }
5844 }
5845 }
5846
22c377f0 5847 if ($err) {
0d18dcfc 5848 warn "snapshot create failed: starting cleanup\n";
3ee28e38 5849 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
5850 warn $@ if $@;
5851 die $err;
5852 }
5853
5854 &$snapshot_commit($vmid, $snapname);
5855}
5856
3ee28e38 5857# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 5858sub snapshot_delete {
3ee28e38 5859 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
5860
5861 my $prepare = 1;
5862
22c377f0 5863 my $snap;
ee2f90b1 5864 my $unused = [];
0d18dcfc 5865
6cb1a8cf
DM
5866 my $unlink_parent = sub {
5867 my ($confref, $new_parent) = @_;
5868
5869 if ($confref->{parent} && $confref->{parent} eq $snapname) {
5870 if ($new_parent) {
5871 $confref->{parent} = $new_parent;
5872 } else {
5873 delete $confref->{parent};
5874 }
5875 }
5876 };
be190583 5877
0d18dcfc 5878 my $updatefn = sub {
2009f324 5879 my ($remove_drive) = @_;
0d18dcfc 5880
22c377f0 5881 my $conf = load_config($vmid);
0d18dcfc 5882
5295b23d
DM
5883 if (!$drivehash) {
5884 check_lock($conf);
be190583 5885 die "you can't delete a snapshot if vm is a template\n"
5295b23d
DM
5886 if is_template($conf);
5887 }
0d18dcfc 5888
22c377f0 5889 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc 5890
be190583 5891 die "snapshot '$snapname' does not exist\n" if !defined($snap);
0d18dcfc
DM
5892
5893 # remove parent refs
8fd882a4
SP
5894 if (!$prepare) {
5895 &$unlink_parent($conf, $snap->{parent});
5896 foreach my $sn (keys %{$conf->{snapshots}}) {
5897 next if $sn eq $snapname;
5898 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
5899 }
0d18dcfc
DM
5900 }
5901
2009f324 5902 if ($remove_drive) {
18bfb361
DM
5903 if ($remove_drive eq 'vmstate') {
5904 delete $snap->{$remove_drive};
5905 } else {
5906 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
5907 my $volid = $drive->{file};
5908 delete $snap->{$remove_drive};
5909 add_unused_volume($conf, $volid);
5910 }
2009f324
DM
5911 }
5912
0d18dcfc
DM
5913 if ($prepare) {
5914 $snap->{snapstate} = 'delete';
5915 } else {
5916 delete $conf->{snapshots}->{$snapname};
3ee28e38 5917 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
5918 foreach my $volid (@$unused) {
5919 add_unused_volume($conf, $volid);
5920 }
0d18dcfc
DM
5921 }
5922
5923 update_config_nolock($vmid, $conf, 1);
5924 };
5925
5926 lock_config($vmid, $updatefn);
5927
18bfb361 5928 # now remove vmstate file
0d18dcfc 5929
22c377f0
DM
5930 my $storecfg = PVE::Storage::config();
5931
18bfb361
DM
5932 if ($snap->{vmstate}) {
5933 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
5934 if (my $err = $@) {
5935 die $err if !$force;
5936 warn $err;
5937 }
5938 # save changes (remove vmstate from snapshot)
5939 lock_config($vmid, $updatefn, 'vmstate') if !$force;
5940 };
5941
5942 # now remove all internal snapshots
5943 foreach_drive($snap, sub {
22c377f0
DM
5944 my ($ds, $drive) = @_;
5945
5946 return if drive_is_cdrom($drive);
3ee28e38 5947
22c377f0
DM
5948 my $volid = $drive->{file};
5949 my $device = "drive-$ds";
5950
2009f324
DM
5951 if (!$drivehash || $drivehash->{$ds}) {
5952 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
5953 if (my $err = $@) {
5954 die $err if !$force;
5955 warn $err;
5956 }
3ee28e38 5957 }
2009f324
DM
5958
5959 # save changes (remove drive fron snapshot)
5960 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 5961 push @$unused, $volid;
22c377f0 5962 });
0d18dcfc
DM
5963
5964 # now cleanup config
5965 $prepare = 0;
5966 lock_config($vmid, $updatefn);
5967}
5968
9cd07842 5969sub has_feature {
7ea975ef
AD
5970 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
5971
719893a9 5972 my $err;
7ea975ef
AD
5973 foreach_drive($conf, sub {
5974 my ($ds, $drive) = @_;
5975
5976 return if drive_is_cdrom($drive);
5977 my $volid = $drive->{file};
5978 $err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
5979 });
5980
719893a9 5981 return $err ? 0 : 1;
7ea975ef 5982}
04a69bb4
AD
5983
5984sub template_create {
5985 my ($vmid, $conf, $disk) = @_;
5986
04a69bb4 5987 my $storecfg = PVE::Storage::config();
04a69bb4 5988
9cd07842
DM
5989 foreach_drive($conf, sub {
5990 my ($ds, $drive) = @_;
5991
5992 return if drive_is_cdrom($drive);
5993 return if $disk && $ds ne $disk;
5994
5995 my $volid = $drive->{file};
bbd56097 5996 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 5997
04a69bb4
AD
5998 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
5999 $drive->{file} = $voliddst;
152fe752
DM
6000 $conf->{$ds} = print_drive($vmid, $drive);
6001 update_config_nolock($vmid, $conf, 1);
04a69bb4 6002 });
04a69bb4
AD
6003}
6004
624361b3
AD
6005sub is_template {
6006 my ($conf) = @_;
6007
96d695c0 6008 return 1 if defined $conf->{template} && $conf->{template} == 1;
624361b3
AD
6009}
6010
5133de42
AD
6011sub qemu_img_convert {
6012 my ($src_volid, $dst_volid, $size, $snapname) = @_;
6013
6014 my $storecfg = PVE::Storage::config();
6015 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
6016 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
6017
6018 if ($src_storeid && $dst_storeid) {
6019 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
6020 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
6021
6022 my $src_format = qemu_img_format($src_scfg, $src_volname);
6023 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
6024
6025 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
6026 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
6027
6028 my $cmd = [];
71ddbff9 6029 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5133de42
AD
6030 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
6031 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
6032
6033 my $parser = sub {
6034 my $line = shift;
6035 if($line =~ m/\((\S+)\/100\%\)/){
6036 my $percent = $1;
6037 my $transferred = int($size * $percent / 100);
6038 my $remaining = $size - $transferred;
6039
6040 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
6041 }
6042
6043 };
6044
6045 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
6046 my $err = $@;
6047 die "copy failed: $err" if $err;
6048 }
6049}
6050
6051sub qemu_img_format {
6052 my ($scfg, $volname) = @_;
6053
ccb5c001 6054 if ($scfg->{path} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
5133de42 6055 return $1;
ccb5c001 6056 } elsif ($scfg->{type} eq 'iscsi') {
5133de42 6057 return "host_device";
be190583 6058 } else {
5133de42 6059 return "raw";
5133de42
AD
6060 }
6061}
6062
cfad42af 6063sub qemu_drive_mirror {
ab6ecffe 6064 my ($vmid, $drive, $dst_volid, $vmiddst) = @_;
cfad42af 6065
ab6ecffe 6066 my $count = 0;
cfad42af
AD
6067 my $old_len = 0;
6068 my $frozen = undef;
ab6ecffe 6069 my $maxwait = 120;
cfad42af
AD
6070
6071 my $storecfg = PVE::Storage::config();
08ac653f 6072 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid);
152fe752 6073
08ac653f 6074 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
cfad42af 6075
08ac653f
DM
6076 my $format;
6077 if ($dst_volname =~ m/\.(raw|qcow2)$/){
6078 $format = $1;
6079 }
21ccdb50 6080
08ac653f 6081 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
21ccdb50 6082
88383920
DM
6083 my $opts = { timeout => 10, device => "drive-$drive", mode => "existing", sync => "full", target => $dst_path };
6084 $opts->{format} = $format if $format;
6085
6086 #fixme : sometime drive-mirror timeout, but works fine after.
6087 # (I have see the problem with big volume > 200GB), so we need to eval
f34ebd52 6088 eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); };
88383920 6089 # ignore errors here
21ccdb50 6090
08ac653f
DM
6091 eval {
6092 while (1) {
6093 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6094 my $stat = @$stats[0];
6095 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
6096 die "error job is not mirroring" if $stat->{type} ne "mirror";
6097
08ac653f
DM
6098 my $busy = $stat->{busy};
6099
6f708643
DM
6100 if (my $total = $stat->{len}) {
6101 my $transferred = $stat->{offset} || 0;
6102 my $remaining = $total - $transferred;
6103 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
67fb9de6 6104
6f708643
DM
6105 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy\n";
6106 }
f34ebd52 6107
08ac653f
DM
6108 if ($stat->{len} == $stat->{offset}) {
6109 if ($busy eq 'false') {
6110
6111 last if $vmiddst != $vmid;
f34ebd52 6112
08ac653f
DM
6113 # try to switch the disk if source and destination are on the same guest
6114 eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") };
6115 last if !$@;
6116 die $@ if $@ !~ m/cannot be completed/;
cfad42af 6117 }
b467f79a 6118
08ac653f
DM
6119 if ($count > $maxwait) {
6120 # if too much writes to disk occurs at the end of migration
6121 #the disk needs to be freezed to be able to complete the migration
6122 vm_suspend($vmid,1);
6123 $frozen = 1;
bcc87408 6124 }
08ac653f
DM
6125 $count ++
6126 }
6127 $old_len = $stat->{offset};
6128 sleep 1;
cfad42af
AD
6129 }
6130
08ac653f
DM
6131 vm_resume($vmid, 1) if $frozen;
6132
6133 };
88383920 6134 my $err = $@;
08ac653f 6135
88383920 6136 my $cancel_job = sub {
08ac653f
DM
6137 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
6138 while (1) {
6139 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6140 my $stat = @$stats[0];
6141 last if !$stat;
6142 sleep 1;
cfad42af 6143 }
88383920
DM
6144 };
6145
6146 if ($err) {
f34ebd52 6147 eval { &$cancel_job(); };
88383920
DM
6148 die "mirroring error: $err";
6149 }
6150
6151 if ($vmiddst != $vmid) {
6152 # if we clone a disk for a new target vm, we don't switch the disk
6153 &$cancel_job(); # so we call block-job-cancel
cfad42af
AD
6154 }
6155}
6156
152fe752 6157sub clone_disk {
be190583 6158 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
6159 $newvmid, $storage, $format, $full, $newvollist) = @_;
6160
6161 my $newvolid;
6162
6163 if (!$full) {
6164 print "create linked clone of drive $drivename ($drive->{file})\n";
258e646c 6165 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid, $snapname);
152fe752
DM
6166 push @$newvollist, $newvolid;
6167 } else {
6168 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
6169 $storeid = $storage if $storage;
6170
1377d7b0
DM
6171 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
6172 if (!$format) {
6173 $format = $drive->{format} || $defFormat;
152fe752
DM
6174 }
6175
1377d7b0
DM
6176 # test if requested format is supported - else use default
6177 my $supported = grep { $_ eq $format } @$validFormats;
6178 $format = $defFormat if !$supported;
6179
152fe752
DM
6180 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
6181
6182 print "create full clone of drive $drivename ($drive->{file})\n";
6183 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
6184 push @$newvollist, $newvolid;
6185
6186 if (!$running || $snapname) {
6187 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname);
6188 } else {
6189 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid);
be190583 6190 }
152fe752
DM
6191 }
6192
6193 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
6194
6195 my $disk = $drive;
6196 $disk->{format} = undef;
6197 $disk->{file} = $newvolid;
6198 $disk->{size} = $size;
6199
6200 return $disk;
6201}
6202
ff556cf2
DM
6203# this only works if VM is running
6204sub get_current_qemu_machine {
6205 my ($vmid) = @_;
6206
6207 my $cmd = { execute => 'query-machines', arguments => {} };
8e90138a 6208 my $res = vm_qmp_command($vmid, $cmd);
ff556cf2
DM
6209
6210 my ($current, $default);
6211 foreach my $e (@$res) {
6212 $default = $e->{name} if $e->{'is-default'};
6213 $current = $e->{name} if $e->{'is-current'};
6214 }
6215
6216 # fallback to the default machine if current is not supported by qemu
6217 return $current || $default || 'pc';
6218}
6219
23f73120
AD
6220sub qemu_machine_feature_enabled {
6221 my ($machine, $kvmver, $version_major, $version_minor) = @_;
6222
6223 my $current_major;
6224 my $current_minor;
6225
6226 if ($machine && $machine =~ m/^(pc(-i440fx|-q35)?-(\d+)\.(\d+))/) {
6227
6228 $current_major = $3;
6229 $current_minor = $4;
6230
6231 } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
6232
6233 $current_major = $1;
6234 $current_minor = $2;
6235 }
6236
6237 return 1 if $current_major >= $version_major && $current_minor >= $version_minor;
6238
6239
6240}
6241
4543ecf0
AD
6242sub lspci {
6243
6244 my $devices = {};
6245
6246 dir_glob_foreach("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
6247 my (undef, $id, $function) = @_;
6248 my $res = { id => $id, function => $function};
6249 push @{$devices->{$id}}, $res;
6250 });
6251
6252 return $devices;
6253}
6254
22de899a
AD
6255sub vm_iothreads_list {
6256 my ($vmid) = @_;
6257
6258 my $res = vm_mon_cmd($vmid, 'query-iothreads');
6259
6260 my $iothreads = {};
6261 foreach my $iothread (@$res) {
6262 $iothreads->{ $iothread->{id} } = $iothread->{"thread-id"};
6263 }
6264
6265 return $iothreads;
6266}
6267
ee034f5c
AD
6268sub scsihw_infos {
6269 my ($conf, $drive) = @_;
6270
6271 my $maxdev = 0;
6272
6273 if ($conf->{scsihw} && ($conf->{scsihw} =~ m/^lsi/)) {
6274 $maxdev = 7;
a1511b3c 6275 } elsif ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
ee034f5c
AD
6276 $maxdev = 1;
6277 } else {
6278 $maxdev = 256;
6279 }
6280
6281 my $controller = int($drive->{index} / $maxdev);
a1511b3c 6282 my $controller_prefix = ($conf->{scsihw} && $conf->{scsihw} eq 'virtio-scsi-single') ? "virtioscsi" : "scsihw";
ee034f5c
AD
6283
6284 return ($maxdev, $controller, $controller_prefix);
6285}
a1511b3c 6286
1e3baf05 62871;