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