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