]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
bump version to 4.0-85
[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$/) {
1677 push @{$res->{pciid}}, { id => $1, function => ($2//'0') };
0cea6a01 1678 } else {
1f4f447b
WB
1679 # should have been caught by parse_property_string already
1680 die "failed to parse PCI id: $id\n";
0cea6a01 1681 }
040b06b7 1682 }
040b06b7
DA
1683 return $res;
1684}
1685
1e3baf05
DM
1686# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1687sub parse_net {
1688 my ($data) = @_;
1689
cd9c34d1
WB
1690 my $res = eval { PVE::JSONSchema::parse_property_string($net_fmt, $data) };
1691 if ($@) {
1692 warn $@;
1693 return undef;
1e3baf05 1694 }
cd9c34d1 1695 $res->{macaddr} = PVE::Tools::random_ether_addr() if !defined($res->{macaddr});
1e3baf05
DM
1696 return $res;
1697}
1698
1699sub print_net {
1700 my $net = shift;
1701
cd9c34d1 1702 return PVE::JSONSchema::print_property_string($net, $net_fmt);
1e3baf05
DM
1703}
1704
1705sub add_random_macs {
1706 my ($settings) = @_;
1707
1708 foreach my $opt (keys %$settings) {
1709 next if $opt !~ m/^net(\d+)$/;
1710 my $net = parse_net($settings->{$opt});
1711 next if !$net;
1712 $settings->{$opt} = print_net($net);
1713 }
1714}
1715
055d554d
DM
1716sub vm_is_volid_owner {
1717 my ($storecfg, $vmid, $volid) = @_;
1718
1719 if ($volid !~ m|^/|) {
1720 my ($path, $owner);
1721 eval { ($path, $owner) = PVE::Storage::path($storecfg, $volid); };
1722 if ($owner && ($owner == $vmid)) {
1723 return 1;
1724 }
1725 }
1726
1727 return undef;
1728}
1729
3dc38fbb
WB
1730sub split_flagged_list {
1731 my $text = shift || '';
1732 $text =~ s/[,;]/ /g;
1733 $text =~ s/^\s+//;
1734 return { map { /^(!?)(.*)$/ && ($2, $1) } ($text =~ /\S+/g) };
1735}
1736
1737sub join_flagged_list {
1738 my ($how, $lst) = @_;
1739 join $how, map { $lst->{$_} . $_ } keys %$lst;
1740}
1741
055d554d 1742sub vmconfig_delete_pending_option {
3dc38fbb 1743 my ($conf, $key, $force) = @_;
055d554d
DM
1744
1745 delete $conf->{pending}->{$key};
3dc38fbb
WB
1746 my $pending_delete_hash = split_flagged_list($conf->{pending}->{delete});
1747 $pending_delete_hash->{$key} = $force ? '!' : '';
1748 $conf->{pending}->{delete} = join_flagged_list(',', $pending_delete_hash);
055d554d
DM
1749}
1750
1751sub vmconfig_undelete_pending_option {
1752 my ($conf, $key) = @_;
1753
3dc38fbb 1754 my $pending_delete_hash = split_flagged_list($conf->{pending}->{delete});
055d554d
DM
1755 delete $pending_delete_hash->{$key};
1756
3dc38fbb
WB
1757 if (%$pending_delete_hash) {
1758 $conf->{pending}->{delete} = join_flagged_list(',', $pending_delete_hash);
055d554d
DM
1759 } else {
1760 delete $conf->{pending}->{delete};
1761 }
1762}
1763
1764sub vmconfig_register_unused_drive {
1765 my ($storecfg, $vmid, $conf, $drive) = @_;
1766
1767 if (!drive_is_cdrom($drive)) {
1768 my $volid = $drive->{file};
1769 if (vm_is_volid_owner($storecfg, $vmid, $volid)) {
8793d495 1770 PVE::QemuConfig->add_unused_volume($conf, $volid, $vmid);
055d554d
DM
1771 }
1772 }
1773}
1774
c750e90a
DM
1775sub vmconfig_cleanup_pending {
1776 my ($conf) = @_;
1777
1778 # remove pending changes when nothing changed
1779 my $changes;
1780 foreach my $opt (keys %{$conf->{pending}}) {
1781 if (defined($conf->{$opt}) && ($conf->{pending}->{$opt} eq $conf->{$opt})) {
1782 $changes = 1;
1783 delete $conf->{pending}->{$opt};
1784 }
1785 }
1786
3dc38fbb 1787 my $current_delete_hash = split_flagged_list($conf->{pending}->{delete});
c750e90a 1788 my $pending_delete_hash = {};
3dc38fbb 1789 while (my ($opt, $force) = each %$current_delete_hash) {
c750e90a 1790 if (defined($conf->{$opt})) {
3dc38fbb 1791 $pending_delete_hash->{$opt} = $force;
c750e90a
DM
1792 } else {
1793 $changes = 1;
1794 }
1795 }
1796
3dc38fbb
WB
1797 if (%$pending_delete_hash) {
1798 $conf->{pending}->{delete} = join_flagged_list(',', $pending_delete_hash);
c750e90a
DM
1799 } else {
1800 delete $conf->{pending}->{delete};
1801 }
1802
1803 return $changes;
1804}
1805
bd27e851 1806# smbios: [manufacturer=str][,product=str][,version=str][,serial=str][,uuid=uuid][,sku=str][,family=str]
ff6ffe20 1807my $smbios1_fmt = {
bd27e851
WB
1808 uuid => {
1809 type => 'string',
1810 pattern => '[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}',
1811 format_description => 'UUID',
52261945 1812 description => "Set SMBIOS1 UUID.",
bd27e851
WB
1813 optional => 1,
1814 },
1815 version => {
1816 type => 'string',
1817 pattern => '\S+',
7f694a71 1818 format_description => 'string',
52261945 1819 description => "Set SMBIOS1 version.",
bd27e851
WB
1820 optional => 1,
1821 },
1822 serial => {
1823 type => 'string',
1824 pattern => '\S+',
7f694a71 1825 format_description => 'string',
52261945 1826 description => "Set SMBIOS1 serial number.",
bd27e851
WB
1827 optional => 1,
1828 },
1829 manufacturer => {
1830 type => 'string',
1831 pattern => '\S+',
7f694a71 1832 format_description => 'string',
52261945 1833 description => "Set SMBIOS1 manufacturer.",
bd27e851
WB
1834 optional => 1,
1835 },
1836 product => {
1837 type => 'string',
1838 pattern => '\S+',
7f694a71 1839 format_description => 'string',
52261945 1840 description => "Set SMBIOS1 product ID.",
bd27e851
WB
1841 optional => 1,
1842 },
1843 sku => {
1844 type => 'string',
1845 pattern => '\S+',
7f694a71 1846 format_description => 'string',
52261945 1847 description => "Set SMBIOS1 SKU string.",
bd27e851
WB
1848 optional => 1,
1849 },
1850 family => {
1851 type => 'string',
1852 pattern => '\S+',
7f694a71 1853 format_description => 'string',
52261945 1854 description => "Set SMBIOS1 family string.",
bd27e851
WB
1855 optional => 1,
1856 },
2796e7d5
DM
1857};
1858
2796e7d5
DM
1859sub parse_smbios1 {
1860 my ($data) = @_;
1861
ff6ffe20 1862 my $res = eval { PVE::JSONSchema::parse_property_string($smbios1_fmt, $data) };
bd27e851 1863 warn $@ if $@;
2796e7d5
DM
1864 return $res;
1865}
1866
cd11416f
DM
1867sub print_smbios1 {
1868 my ($smbios1) = @_;
ff6ffe20 1869 return PVE::JSONSchema::print_property_string($smbios1, $smbios1_fmt);
cd11416f
DM
1870}
1871
ff6ffe20 1872PVE::JSONSchema::register_format('pve-qm-smbios1', $smbios1_fmt);
2796e7d5 1873
1e3baf05
DM
1874PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1875sub verify_bootdisk {
1876 my ($value, $noerr) = @_;
1877
74479ee9 1878 return $value if is_valid_drivename($value);
1e3baf05
DM
1879
1880 return undef if $noerr;
1881
1882 die "invalid boot disk '$value'\n";
1883}
1884
0ea9541d
DM
1885sub parse_watchdog {
1886 my ($value) = @_;
1887
1888 return undef if !$value;
1889
ec3582b5
WB
1890 my $res = eval { PVE::JSONSchema::parse_property_string($watchdog_fmt, $value) };
1891 warn $@ if $@;
0ea9541d
DM
1892 return $res;
1893}
1894
1e3baf05
DM
1895PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1896sub verify_usb_device {
1897 my ($value, $noerr) = @_;
1898
1899 return $value if parse_usb_device($value);
1900
1901 return undef if $noerr;
19672434 1902
1e3baf05
DM
1903 die "unable to parse usb device\n";
1904}
1905
1e3baf05
DM
1906# add JSON properties for create and set function
1907sub json_config_properties {
1908 my $prop = shift;
1909
1910 foreach my $opt (keys %$confdesc) {
18bfb361 1911 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1e3baf05
DM
1912 $prop->{$opt} = $confdesc->{$opt};
1913 }
1914
1915 return $prop;
1916}
1917
1918sub check_type {
1919 my ($key, $value) = @_;
1920
1921 die "unknown setting '$key'\n" if !$confdesc->{$key};
1922
1923 my $type = $confdesc->{$key}->{type};
1924
6b64503e 1925 if (!defined($value)) {
1e3baf05
DM
1926 die "got undefined value\n";
1927 }
1928
1929 if ($value =~ m/[\n\r]/) {
1930 die "property contains a line feed\n";
1931 }
1932
1933 if ($type eq 'boolean') {
19672434
DM
1934 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1935 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1936 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1937 } elsif ($type eq 'integer') {
1938 return int($1) if $value =~ m/^(\d+)$/;
1939 die "type check ('integer') failed - got '$value'\n";
04432191
AD
1940 } elsif ($type eq 'number') {
1941 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
1942 die "type check ('number') failed - got '$value'\n";
1e3baf05
DM
1943 } elsif ($type eq 'string') {
1944 if (my $fmt = $confdesc->{$key}->{format}) {
1945 if ($fmt eq 'pve-qm-drive') {
1946 # special case - we need to pass $key to parse_drive()
6b64503e 1947 my $drive = parse_drive($key, $value);
1e3baf05
DM
1948 return $value if $drive;
1949 die "unable to parse drive options\n";
1950 }
1951 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1952 return $value;
1953 }
1e3baf05 1954 $value =~ s/^\"(.*)\"$/$1/;
19672434 1955 return $value;
1e3baf05
DM
1956 } else {
1957 die "internal error"
1958 }
1959}
1960
040b06b7
DA
1961sub check_iommu_support{
1962 #fixme : need to check IOMMU support
1963 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1964
1965 my $iommu=1;
1966 return $iommu;
1967
1968}
1969
1e3baf05
DM
1970sub touch_config {
1971 my ($vmid) = @_;
1972
ffda963f 1973 my $conf = PVE::QemuConfig->config_file($vmid);
1e3baf05
DM
1974 utime undef, undef, $conf;
1975}
1976
1e3baf05 1977sub destroy_vm {
15cc8784 1978 my ($storecfg, $vmid, $keep_empty_config, $skiplock) = @_;
1e3baf05 1979
ffda963f 1980 my $conffile = PVE::QemuConfig->config_file($vmid);
1e3baf05 1981
ffda963f 1982 my $conf = PVE::QemuConfig->load_config($vmid);
1e3baf05 1983
ffda963f 1984 PVE::QemuConfig->check_lock($conf) if !$skiplock;
1e3baf05 1985
19672434 1986 # only remove disks owned by this VM
1e3baf05
DM
1987 foreach_drive($conf, sub {
1988 my ($ds, $drive) = @_;
1989
6b64503e 1990 return if drive_is_cdrom($drive);
1e3baf05
DM
1991
1992 my $volid = $drive->{file};
ed221350 1993
ff1a2432 1994 return if !$volid || $volid =~ m|^/|;
1e3baf05 1995
6b64503e 1996 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
ff1a2432 1997 return if !$path || !$owner || ($owner != $vmid);
1e3baf05 1998
6b64503e 1999 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 2000 });
19672434 2001
a6af7b3e 2002 if ($keep_empty_config) {
9c502e26 2003 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
a6af7b3e
DM
2004 } else {
2005 unlink $conffile;
2006 }
1e3baf05
DM
2007
2008 # also remove unused disk
2009 eval {
6b64503e 2010 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
2011
2012 eval {
6b64503e 2013 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 2014 my ($volid, $sid, $volname, $d) = @_;
6b64503e 2015 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
2016 });
2017 };
2018 warn $@ if $@;
2019
2020 };
2021 warn $@ if $@;
2022}
2023
1e3baf05
DM
2024sub parse_vm_config {
2025 my ($filename, $raw) = @_;
2026
2027 return undef if !defined($raw);
2028
554ac7e7 2029 my $res = {
fc1ddcdc 2030 digest => Digest::SHA::sha1_hex($raw),
0d18dcfc 2031 snapshots => {},
0d732d16 2032 pending => {},
554ac7e7 2033 };
1e3baf05 2034
19672434 2035 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
2036 || die "got strange filename '$filename'";
2037
2038 my $vmid = $1;
2039
0d18dcfc 2040 my $conf = $res;
b0ec896e 2041 my $descr;
e297c490 2042 my $section = '';
0581fe4f 2043
0d18dcfc
DM
2044 my @lines = split(/\n/, $raw);
2045 foreach my $line (@lines) {
1e3baf05 2046 next if $line =~ m/^\s*$/;
be190583 2047
eab09f4e 2048 if ($line =~ m/^\[PENDING\]\s*$/i) {
e297c490 2049 $section = 'pending';
b0ec896e
DM
2050 if (defined($descr)) {
2051 $descr =~ s/\s+$//;
2052 $conf->{description} = $descr;
2053 }
2054 $descr = undef;
e297c490 2055 $conf = $res->{$section} = {};
eab09f4e
AD
2056 next;
2057
0d732d16 2058 } elsif ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
e297c490 2059 $section = $1;
b0ec896e
DM
2060 if (defined($descr)) {
2061 $descr =~ s/\s+$//;
2062 $conf->{description} = $descr;
2063 }
2064 $descr = undef;
e297c490 2065 $conf = $res->{snapshots}->{$section} = {};
0d18dcfc
DM
2066 next;
2067 }
1e3baf05 2068
0581fe4f 2069 if ($line =~ m/^\#(.*)\s*$/) {
b0ec896e 2070 $descr = '' if !defined($descr);
0581fe4f
DM
2071 $descr .= PVE::Tools::decode_text($1) . "\n";
2072 next;
2073 }
2074
1e3baf05 2075 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
b0ec896e 2076 $descr = '' if !defined($descr);
0581fe4f 2077 $descr .= PVE::Tools::decode_text($2);
0d18dcfc
DM
2078 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
2079 $conf->{snapstate} = $1;
1e3baf05
DM
2080 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
2081 my $key = $1;
2082 my $value = $2;
0d18dcfc 2083 $conf->{$key} = $value;
ef824322 2084 } elsif ($line =~ m/^delete:\s*(.*\S)\s*$/) {
e297c490 2085 my $value = $1;
ef824322
DM
2086 if ($section eq 'pending') {
2087 $conf->{delete} = $value; # we parse this later
2088 } else {
2089 warn "vm $vmid - propertry 'delete' is only allowed in [PENDING]\n";
eab09f4e 2090 }
1e3baf05
DM
2091 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
2092 my $key = $1;
2093 my $value = $2;
2094 eval { $value = check_type($key, $value); };
2095 if ($@) {
2096 warn "vm $vmid - unable to parse value of '$key' - $@";
2097 } else {
2098 my $fmt = $confdesc->{$key}->{format};
2099 if ($fmt && $fmt eq 'pve-qm-drive') {
2100 my $v = parse_drive($key, $value);
2101 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
2102 $v->{file} = $volid;
6b64503e 2103 $value = print_drive($vmid, $v);
1e3baf05
DM
2104 } else {
2105 warn "vm $vmid - unable to parse value of '$key'\n";
2106 next;
2107 }
2108 }
2109
2110 if ($key eq 'cdrom') {
0d18dcfc 2111 $conf->{ide2} = $value;
1e3baf05 2112 } else {
0d18dcfc 2113 $conf->{$key} = $value;
1e3baf05
DM
2114 }
2115 }
2116 }
2117 }
2118
b0ec896e
DM
2119 if (defined($descr)) {
2120 $descr =~ s/\s+$//;
2121 $conf->{description} = $descr;
2122 }
0d18dcfc 2123 delete $res->{snapstate}; # just to be sure
1e3baf05
DM
2124
2125 return $res;
2126}
2127
1858638f
DM
2128sub write_vm_config {
2129 my ($filename, $conf) = @_;
1e3baf05 2130
0d18dcfc
DM
2131 delete $conf->{snapstate}; # just to be sure
2132
1858638f
DM
2133 if ($conf->{cdrom}) {
2134 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
2135 $conf->{ide2} = $conf->{cdrom};
2136 delete $conf->{cdrom};
2137 }
1e3baf05
DM
2138
2139 # we do not use 'smp' any longer
1858638f
DM
2140 if ($conf->{sockets}) {
2141 delete $conf->{smp};
2142 } elsif ($conf->{smp}) {
2143 $conf->{sockets} = $conf->{smp};
2144 delete $conf->{cores};
2145 delete $conf->{smp};
1e3baf05
DM
2146 }
2147
ee2f90b1 2148 my $used_volids = {};
0d18dcfc 2149
ee2f90b1 2150 my $cleanup_config = sub {
ef824322 2151 my ($cref, $pending, $snapname) = @_;
1858638f 2152
ee2f90b1
DM
2153 foreach my $key (keys %$cref) {
2154 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
ef824322 2155 $key eq 'snapstate' || $key eq 'pending';
ee2f90b1 2156 my $value = $cref->{$key};
ef824322
DM
2157 if ($key eq 'delete') {
2158 die "propertry 'delete' is only allowed in [PENDING]\n"
2159 if !$pending;
2160 # fixme: check syntax?
2161 next;
2162 }
ee2f90b1
DM
2163 eval { $value = check_type($key, $value); };
2164 die "unable to parse value of '$key' - $@" if $@;
1858638f 2165
ee2f90b1
DM
2166 $cref->{$key} = $value;
2167
74479ee9 2168 if (!$snapname && is_valid_drivename($key)) {
ed221350 2169 my $drive = parse_drive($key, $value);
ee2f90b1
DM
2170 $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
2171 }
1e3baf05 2172 }
ee2f90b1
DM
2173 };
2174
2175 &$cleanup_config($conf);
ef824322
DM
2176
2177 &$cleanup_config($conf->{pending}, 1);
2178
ee2f90b1 2179 foreach my $snapname (keys %{$conf->{snapshots}}) {
ef824322
DM
2180 die "internal error" if $snapname eq 'pending';
2181 &$cleanup_config($conf->{snapshots}->{$snapname}, undef, $snapname);
1e3baf05
DM
2182 }
2183
1858638f
DM
2184 # remove 'unusedX' settings if we re-add a volume
2185 foreach my $key (keys %$conf) {
2186 my $value = $conf->{$key};
ee2f90b1 2187 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1858638f 2188 delete $conf->{$key};
1e3baf05 2189 }
1858638f 2190 }
be190583 2191
0d18dcfc 2192 my $generate_raw_config = sub {
b0ec896e 2193 my ($conf, $pending) = @_;
0581fe4f 2194
0d18dcfc
DM
2195 my $raw = '';
2196
2197 # add description as comment to top of file
b0ec896e
DM
2198 if (defined(my $descr = $conf->{description})) {
2199 if ($descr) {
2200 foreach my $cl (split(/\n/, $descr)) {
2201 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
2202 }
2203 } else {
2204 $raw .= "#\n" if $pending;
2205 }
0d18dcfc
DM
2206 }
2207
2208 foreach my $key (sort keys %$conf) {
ef824322 2209 next if $key eq 'digest' || $key eq 'description' || $key eq 'pending' || $key eq 'snapshots';
0d18dcfc
DM
2210 $raw .= "$key: $conf->{$key}\n";
2211 }
2212 return $raw;
2213 };
0581fe4f 2214
0d18dcfc 2215 my $raw = &$generate_raw_config($conf);
ef824322
DM
2216
2217 if (scalar(keys %{$conf->{pending}})){
2218 $raw .= "\n[PENDING]\n";
b0ec896e 2219 $raw .= &$generate_raw_config($conf->{pending}, 1);
ef824322
DM
2220 }
2221
0d18dcfc
DM
2222 foreach my $snapname (sort keys %{$conf->{snapshots}}) {
2223 $raw .= "\n[$snapname]\n";
2224 $raw .= &$generate_raw_config($conf->{snapshots}->{$snapname});
1858638f 2225 }
1e3baf05 2226
1858638f
DM
2227 return $raw;
2228}
1e3baf05 2229
19672434 2230sub load_defaults {
1e3baf05
DM
2231
2232 my $res = {};
2233
2234 # we use static defaults from our JSON schema configuration
2235 foreach my $key (keys %$confdesc) {
2236 if (defined(my $default = $confdesc->{$key}->{default})) {
2237 $res->{$key} = $default;
2238 }
2239 }
19672434 2240
1e3baf05
DM
2241 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
2242 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
2243
2244 return $res;
2245}
2246
2247sub config_list {
2248 my $vmlist = PVE::Cluster::get_vmlist();
2249 my $res = {};
2250 return $res if !$vmlist || !$vmlist->{ids};
2251 my $ids = $vmlist->{ids};
2252
1e3baf05
DM
2253 foreach my $vmid (keys %$ids) {
2254 my $d = $ids->{$vmid};
2255 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 2256 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
2257 $res->{$vmid}->{exists} = 1;
2258 }
2259 return $res;
2260}
2261
64e13401
DM
2262# test if VM uses local resources (to prevent migration)
2263sub check_local_resources {
2264 my ($conf, $noerr) = @_;
2265
2266 my $loc_res = 0;
19672434 2267
e0ab7331
DM
2268 $loc_res = 1 if $conf->{hostusb}; # old syntax
2269 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 2270
0d29ab3b 2271 foreach my $k (keys %$conf) {
49ca581d 2272 next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice');
d44712fc
EK
2273 # sockets are safe: they will recreated be on the target side post-migrate
2274 next if $k =~ m/^serial/ && ($conf->{$k} eq 'socket');
2fe1a152 2275 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
2276 }
2277
2278 die "VM uses local resources\n" if $loc_res && !$noerr;
2279
2280 return $loc_res;
2281}
2282
719893a9 2283# check if used storages are available on all nodes (use by migrate)
47152e2e
DM
2284sub check_storage_availability {
2285 my ($storecfg, $conf, $node) = @_;
2286
2287 foreach_drive($conf, sub {
2288 my ($ds, $drive) = @_;
2289
2290 my $volid = $drive->{file};
2291 return if !$volid;
2292
2293 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
2294 return if !$sid;
2295
2296 # check if storage is available on both nodes
2297 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
2298 PVE::Storage::storage_check_node($storecfg, $sid, $node);
2299 });
2300}
2301
719893a9
DM
2302# list nodes where all VM images are available (used by has_feature API)
2303sub shared_nodes {
2304 my ($conf, $storecfg) = @_;
2305
2306 my $nodelist = PVE::Cluster::get_nodelist();
2307 my $nodehash = { map { $_ => 1 } @$nodelist };
2308 my $nodename = PVE::INotify::nodename();
be190583 2309
719893a9
DM
2310 foreach_drive($conf, sub {
2311 my ($ds, $drive) = @_;
2312
2313 my $volid = $drive->{file};
2314 return if !$volid;
2315
2316 my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
2317 if ($storeid) {
2318 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
2319 if ($scfg->{disable}) {
2320 $nodehash = {};
2321 } elsif (my $avail = $scfg->{nodes}) {
2322 foreach my $node (keys %$nodehash) {
2323 delete $nodehash->{$node} if !$avail->{$node};
2324 }
2325 } elsif (!$scfg->{shared}) {
2326 foreach my $node (keys %$nodehash) {
2327 delete $nodehash->{$node} if $node ne $nodename
2328 }
2329 }
2330 }
2331 });
2332
2333 return $nodehash
2334}
2335
1e3baf05
DM
2336sub check_cmdline {
2337 my ($pidfile, $pid) = @_;
2338
6b64503e
DM
2339 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
2340 if (defined($fh)) {
1e3baf05
DM
2341 my $line = <$fh>;
2342 $fh->close;
2343 return undef if !$line;
6b64503e 2344 my @param = split(/\0/, $line);
1e3baf05
DM
2345
2346 my $cmd = $param[0];
06094efd 2347 return if !$cmd || ($cmd !~ m|kvm$| && $cmd !~ m|qemu-system-x86_64$|);
1e3baf05
DM
2348
2349 for (my $i = 0; $i < scalar (@param); $i++) {
2350 my $p = $param[$i];
2351 next if !$p;
2352 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
2353 my $p = $param[$i+1];
2354 return 1 if $p && ($p eq $pidfile);
2355 return undef;
2356 }
2357 }
2358 }
2359 return undef;
2360}
2361
2362sub check_running {
7e8dcf2c 2363 my ($vmid, $nocheck, $node) = @_;
1e3baf05 2364
ffda963f 2365 my $filename = PVE::QemuConfig->config_file($vmid, $node);
1e3baf05
DM
2366
2367 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 2368 if !$nocheck && ! -f $filename;
1e3baf05 2369
e6c3b671 2370 my $pidfile = pidfile_name($vmid);
1e3baf05 2371
e6c3b671
DM
2372 if (my $fd = IO::File->new("<$pidfile")) {
2373 my $st = stat($fd);
1e3baf05 2374 my $line = <$fd>;
6b64503e 2375 close($fd);
1e3baf05
DM
2376
2377 my $mtime = $st->mtime;
2378 if ($mtime > time()) {
2379 warn "file '$filename' modified in future\n";
2380 }
2381
2382 if ($line =~ m/^(\d+)$/) {
2383 my $pid = $1;
e6c3b671
DM
2384 if (check_cmdline($pidfile, $pid)) {
2385 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
2386 return $pid;
2387 }
2388 }
1e3baf05
DM
2389 }
2390 }
2391
2392 return undef;
2393}
2394
2395sub vzlist {
19672434 2396
1e3baf05
DM
2397 my $vzlist = config_list();
2398
6b64503e 2399 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 2400
19672434 2401 while (defined(my $de = $fd->read)) {
1e3baf05
DM
2402 next if $de !~ m/^(\d+)\.pid$/;
2403 my $vmid = $1;
6b64503e
DM
2404 next if !defined($vzlist->{$vmid});
2405 if (my $pid = check_running($vmid)) {
1e3baf05
DM
2406 $vzlist->{$vmid}->{pid} = $pid;
2407 }
2408 }
2409
2410 return $vzlist;
2411}
2412
1e3baf05
DM
2413sub disksize {
2414 my ($storecfg, $conf) = @_;
2415
2416 my $bootdisk = $conf->{bootdisk};
2417 return undef if !$bootdisk;
74479ee9 2418 return undef if !is_valid_drivename($bootdisk);
1e3baf05
DM
2419
2420 return undef if !$conf->{$bootdisk};
2421
2422 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
2423 return undef if !defined($drive);
2424
2425 return undef if drive_is_cdrom($drive);
2426
2427 my $volid = $drive->{file};
2428 return undef if !$volid;
2429
24afaca0 2430 return $drive->{size};
1e3baf05
DM
2431}
2432
2433my $last_proc_pid_stat;
2434
03a33f30
DM
2435# get VM status information
2436# This must be fast and should not block ($full == false)
2437# We only query KVM using QMP if $full == true (this can be slow)
1e3baf05 2438sub vmstatus {
03a33f30 2439 my ($opt_vmid, $full) = @_;
1e3baf05
DM
2440
2441 my $res = {};
2442
19672434 2443 my $storecfg = PVE::Storage::config();
1e3baf05
DM
2444
2445 my $list = vzlist();
694fcad4 2446 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 2447
ae4915a2
DM
2448 my $cpucount = $cpuinfo->{cpus} || 1;
2449
1e3baf05
DM
2450 foreach my $vmid (keys %$list) {
2451 next if $opt_vmid && ($vmid ne $opt_vmid);
2452
ffda963f 2453 my $cfspath = PVE::QemuConfig->cfs_config_path($vmid);
1e3baf05
DM
2454 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
2455
2456 my $d = {};
2457 $d->{pid} = $list->{$vmid}->{pid};
2458
2459 # fixme: better status?
2460 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
2461
af990afe
DM
2462 my $size = disksize($storecfg, $conf);
2463 if (defined($size)) {
2464 $d->{disk} = 0; # no info available
1e3baf05
DM
2465 $d->{maxdisk} = $size;
2466 } else {
2467 $d->{disk} = 0;
2468 $d->{maxdisk} = 0;
2469 }
2470
2471 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2 2472 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
d7c8364b 2473 $d->{cpus} = $conf->{vcpus} if $conf->{vcpus};
ae4915a2 2474
1e3baf05 2475 $d->{name} = $conf->{name} || "VM $vmid";
19672434 2476 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 2477
8b1accf7 2478 if ($conf->{balloon}) {
4bdb0514 2479 $d->{balloon_min} = $conf->{balloon}*(1024*1024);
074e01c8 2480 $d->{shares} = defined($conf->{shares}) ? $conf->{shares} : 1000;
8b1accf7
DM
2481 }
2482
1e3baf05
DM
2483 $d->{uptime} = 0;
2484 $d->{cpu} = 0;
1e3baf05
DM
2485 $d->{mem} = 0;
2486
2487 $d->{netout} = 0;
2488 $d->{netin} = 0;
2489
2490 $d->{diskread} = 0;
2491 $d->{diskwrite} = 0;
2492
ffda963f 2493 $d->{template} = PVE::QemuConfig->is_template($conf);
4d8c851b 2494
1e3baf05
DM
2495 $res->{$vmid} = $d;
2496 }
2497
2498 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
2499 foreach my $dev (keys %$netdev) {
2500 next if $dev !~ m/^tap([1-9]\d*)i/;
2501 my $vmid = $1;
2502 my $d = $res->{$vmid};
2503 next if !$d;
19672434 2504
1e3baf05
DM
2505 $d->{netout} += $netdev->{$dev}->{receive};
2506 $d->{netin} += $netdev->{$dev}->{transmit};
604ea644
AD
2507
2508 if ($full) {
2509 $d->{nics}->{$dev}->{netout} = $netdev->{$dev}->{receive};
2510 $d->{nics}->{$dev}->{netin} = $netdev->{$dev}->{transmit};
2511 }
2512
1e3baf05
DM
2513 }
2514
1e3baf05
DM
2515 my $ctime = gettimeofday;
2516
2517 foreach my $vmid (keys %$list) {
2518
2519 my $d = $res->{$vmid};
2520 my $pid = $d->{pid};
2521 next if !$pid;
2522
694fcad4
DM
2523 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
2524 next if !$pstat; # not running
19672434 2525
694fcad4 2526 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 2527
694fcad4 2528 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 2529
694fcad4 2530 if ($pstat->{vsize}) {
6b64503e 2531 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
2532 }
2533
2534 my $old = $last_proc_pid_stat->{$pid};
2535 if (!$old) {
19672434
DM
2536 $last_proc_pid_stat->{$pid} = {
2537 time => $ctime,
1e3baf05
DM
2538 used => $used,
2539 cpu => 0,
1e3baf05
DM
2540 };
2541 next;
2542 }
2543
7f0b5beb 2544 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
2545
2546 if ($dtime > 1000) {
2547 my $dutime = $used - $old->{used};
2548
ae4915a2 2549 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 2550 $last_proc_pid_stat->{$pid} = {
19672434 2551 time => $ctime,
1e3baf05
DM
2552 used => $used,
2553 cpu => $d->{cpu},
1e3baf05
DM
2554 };
2555 } else {
2556 $d->{cpu} = $old->{cpu};
1e3baf05
DM
2557 }
2558 }
2559
f5eb281a 2560 return $res if !$full;
03a33f30
DM
2561
2562 my $qmpclient = PVE::QMPClient->new();
2563
64e7fcf2
DM
2564 my $ballooncb = sub {
2565 my ($vmid, $resp) = @_;
2566
2567 my $info = $resp->{'return'};
38babf81
DM
2568 return if !$info->{max_mem};
2569
64e7fcf2
DM
2570 my $d = $res->{$vmid};
2571
38babf81
DM
2572 # use memory assigned to VM
2573 $d->{maxmem} = $info->{max_mem};
2574 $d->{balloon} = $info->{actual};
2575
2576 if (defined($info->{total_mem}) && defined($info->{free_mem})) {
2577 $d->{mem} = $info->{total_mem} - $info->{free_mem};
2578 $d->{freemem} = $info->{free_mem};
64e7fcf2
DM
2579 }
2580
604ea644 2581 $d->{ballooninfo} = $info;
64e7fcf2
DM
2582 };
2583
03a33f30
DM
2584 my $blockstatscb = sub {
2585 my ($vmid, $resp) = @_;
2586 my $data = $resp->{'return'} || [];
2587 my $totalrdbytes = 0;
2588 my $totalwrbytes = 0;
604ea644 2589
03a33f30
DM
2590 for my $blockstat (@$data) {
2591 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
2592 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
604ea644
AD
2593
2594 $blockstat->{device} =~ s/drive-//;
2595 $res->{$vmid}->{blockstat}->{$blockstat->{device}} = $blockstat->{stats};
03a33f30
DM
2596 }
2597 $res->{$vmid}->{diskread} = $totalrdbytes;
2598 $res->{$vmid}->{diskwrite} = $totalwrbytes;
2599 };
2600
2601 my $statuscb = sub {
2602 my ($vmid, $resp) = @_;
64e7fcf2 2603
03a33f30 2604 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
64e7fcf2
DM
2605 # this fails if ballon driver is not loaded, so this must be
2606 # the last commnand (following command are aborted if this fails).
38babf81 2607 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
03a33f30
DM
2608
2609 my $status = 'unknown';
2610 if (!defined($status = $resp->{'return'}->{status})) {
2611 warn "unable to get VM status\n";
2612 return;
2613 }
2614
2615 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2616 };
2617
2618 foreach my $vmid (keys %$list) {
2619 next if $opt_vmid && ($vmid ne $opt_vmid);
2620 next if !$res->{$vmid}->{pid}; # not running
2621 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2622 }
2623
c8125172 2624 $qmpclient->queue_execute(undef, 1);
03a33f30
DM
2625
2626 foreach my $vmid (keys %$list) {
2627 next if $opt_vmid && ($vmid ne $opt_vmid);
2628 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2629 }
2630
1e3baf05
DM
2631 return $res;
2632}
2633
2634sub foreach_drive {
b74ff047 2635 my ($conf, $func, @param) = @_;
1e3baf05 2636
74479ee9
FG
2637 foreach my $ds (valid_drive_names()) {
2638 next if !defined($conf->{$ds});
1e3baf05 2639
6b64503e 2640 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2641 next if !$drive;
2642
b74ff047 2643 &$func($ds, $drive, @param);
1e3baf05
DM
2644 }
2645}
2646
d5769dc2 2647sub foreach_volid {
b6adff33 2648 my ($conf, $func, @param) = @_;
be190583 2649
d5769dc2
DM
2650 my $volhash = {};
2651
2652 my $test_volid = sub {
2653 my ($volid, $is_cdrom) = @_;
2654
2655 return if !$volid;
be190583 2656
d5769dc2
DM
2657 $volhash->{$volid} = $is_cdrom || 0;
2658 };
2659
ed221350 2660 foreach_drive($conf, sub {
d5769dc2
DM
2661 my ($ds, $drive) = @_;
2662 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2663 });
2664
2665 foreach my $snapname (keys %{$conf->{snapshots}}) {
2666 my $snap = $conf->{snapshots}->{$snapname};
2667 &$test_volid($snap->{vmstate}, 0);
ed221350 2668 foreach_drive($snap, sub {
d5769dc2
DM
2669 my ($ds, $drive) = @_;
2670 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2671 });
2672 }
2673
2674 foreach my $volid (keys %$volhash) {
b6adff33 2675 &$func($volid, $volhash->{$volid}, @param);
d5769dc2
DM
2676 }
2677}
2678
86b8228b
DM
2679sub vga_conf_has_spice {
2680 my ($vga) = @_;
2681
590e698c
DM
2682 return 0 if !$vga || $vga !~ m/^qxl([234])?$/;
2683
2684 return $1 || 1;
86b8228b
DM
2685}
2686
1e3baf05 2687sub config_to_command {
67812f9c 2688 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
1e3baf05
DM
2689
2690 my $cmd = [];
8c559505
DM
2691 my $globalFlags = [];
2692 my $machineFlags = [];
2693 my $rtcFlags = [];
519ed28c 2694 my $cpuFlags = [];
5bdcf937 2695 my $devices = [];
b78ebef7 2696 my $pciaddr = '';
5bdcf937 2697 my $bridges = {};
1e3baf05
DM
2698 my $kvmver = kvm_user_version();
2699 my $vernum = 0; # unknown
b42d3cf9 2700 my $ostype = $conf->{ostype};
a3c52213
DM
2701 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2702 $vernum = $1*1000000+$2*1000;
2703 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2704 $vernum = $1*1000000+$2*1000+$3;
2705 }
2706
a3c52213 2707 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2708
2709 my $have_ovz = -f '/proc/vz/vestat';
2710
db656e5f 2711 my $q35 = machine_type_is_q35($conf);
4d3f29ed 2712 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
23f73120 2713 my $machine_type = $forcemachine || $conf->{machine};
249c4a6c
AD
2714 my $use_old_bios_files = undef;
2715 ($use_old_bios_files, $machine_type) = qemu_use_old_bios_files($machine_type);
db656e5f 2716
f08e17c7
AD
2717 my $cpuunits = defined($conf->{cpuunits}) ?
2718 $conf->{cpuunits} : $defaults->{cpuunits};
2719
1e3baf05
DM
2720 push @$cmd, '/usr/bin/kvm';
2721
2722 push @$cmd, '-id', $vmid;
2723
2724 my $use_virtio = 0;
2725
c971c4f2
AD
2726 my $qmpsocket = qmp_socket($vmid);
2727 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2728 push @$cmd, '-mon', "chardev=qmp,mode=control";
2729
1e3baf05 2730
6b64503e 2731 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2732
1e3baf05
DM
2733 push @$cmd, '-daemonize';
2734
2796e7d5
DM
2735 if ($conf->{smbios1}) {
2736 push @$cmd, '-smbios', "type=1,$conf->{smbios1}";
2737 }
2738
3edb45e7 2739 if ($conf->{bios} && $conf->{bios} eq 'ovmf') {
a783c78e
AD
2740 my $ovmfvar = "OVMF_VARS-pure-efi.fd";
2741 my $ovmfvar_src = "/usr/share/kvm/$ovmfvar";
2742 my $ovmfvar_dst = "/tmp/$vmid-$ovmfvar";
2bd70893 2743 PVE::Tools::file_copy($ovmfvar_src, $ovmfvar_dst, 256*1024);
a783c78e
AD
2744 push @$cmd, '-drive', "if=pflash,format=raw,readonly,file=/usr/share/kvm/OVMF-pure-efi.fd";
2745 push @$cmd, '-drive', "if=pflash,format=raw,file=$ovmfvar_dst";
2746 }
2747
da8b4189 2748
d40e5e18
DC
2749 # add usb controllers
2750 my @usbcontrollers = PVE::QemuServer::USB::get_usb_controllers($conf, $bridges, $q35, $usbdesc->{format}, $MAX_USB_DEVICES);
2751 push @$devices, @usbcontrollers if @usbcontrollers;
5acbfe9e 2752 my $vga = $conf->{vga};
2fa3151e 2753
590e698c
DM
2754 my $qxlnum = vga_conf_has_spice($vga);
2755 $vga = 'qxl' if $qxlnum;
2fa3151e 2756
5acbfe9e 2757 if (!$vga) {
264e519f
DM
2758 if ($conf->{ostype} && ($conf->{ostype} eq 'win8' ||
2759 $conf->{ostype} eq 'win7' ||
5acbfe9e
DM
2760 $conf->{ostype} eq 'w2k8')) {
2761 $vga = 'std';
2762 } else {
2763 $vga = 'cirrus';
2764 }
2765 }
2766
1e3baf05 2767 # enable absolute mouse coordinates (needed by vnc)
5acbfe9e
DM
2768 my $tablet;
2769 if (defined($conf->{tablet})) {
2770 $tablet = $conf->{tablet};
2771 } else {
2772 $tablet = $defaults->{tablet};
590e698c 2773 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
ef5e2be2 2774 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
5acbfe9e
DM
2775 }
2776
db656e5f 2777 push @$devices, '-device', print_tabletdevice_full($conf) if $tablet;
b467f79a 2778
16a91d65 2779 my $kvm_off = 0;
1e3baf05 2780 # host pci devices
040b06b7 2781 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2e3b7e2a
AD
2782 my $d = parse_hostpci($conf->{"hostpci$i"});
2783 next if !$d;
2784
2785 my $pcie = $d->{pcie};
2786 if($pcie){
2787 die "q35 machine model is not enabled" if !$q35;
2788 $pciaddr = print_pcie_addr("hostpci$i");
2789 }else{
2790 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2791 }
2792
1f4f447b
WB
2793 my $rombar = defined($d->{rombar}) && !$d->{rombar} ? ',rombar=0' : '';
2794 my $xvga = '';
2795 if ($d->{'x-vga'}) {
2796 $xvga = ',x-vga=on';
16a91d65 2797 $kvm_off = 1;
137483c0 2798 $vga = 'none';
b42d3cf9 2799 if ($ostype eq 'win7' || $ostype eq 'win8' || $ostype eq 'w2k8') {
bd92244c
AD
2800 push @$cpuFlags , 'hv_vendor_id=proxmox';
2801 }
230a4382
AD
2802 if ($conf->{bios} && $conf->{bios} eq 'ovmf') {
2803 $xvga = "";
2804 }
137483c0 2805 }
4543ecf0
AD
2806 my $pcidevices = $d->{pciid};
2807 my $multifunction = 1 if @$pcidevices > 1;
2e3b7e2a 2808
4543ecf0
AD
2809 my $j=0;
2810 foreach my $pcidevice (@$pcidevices) {
2e3b7e2a 2811
4543ecf0
AD
2812 my $id = "hostpci$i";
2813 $id .= ".$j" if $multifunction;
2814 my $addr = $pciaddr;
2815 $addr .= ".$j" if $multifunction;
6ea8cd3b 2816 my $devicestr = "vfio-pci,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
4543ecf0
AD
2817
2818 if($j == 0){
2819 $devicestr .= "$rombar$xvga";
2820 $devicestr .= ",multifunction=on" if $multifunction;
2821 }
2822
2823 push @$devices, '-device', $devicestr;
2824 $j++;
2825 }
1e3baf05
DM
2826 }
2827
2828 # usb devices
d40e5e18
DC
2829 my @usbdevices = PVE::QemuServer::USB::get_usb_devices($conf, $usbdesc->{format}, $MAX_USB_DEVICES);
2830 push @$devices, @usbdevices if @usbdevices;
1e3baf05 2831 # serial devices
bae179aa 2832 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2833 if (my $path = $conf->{"serial$i"}) {
9f9d2fb2
DM
2834 if ($path eq 'socket') {
2835 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2836 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2837 push @$devices, '-device', "isa-serial,chardev=serial$i";
2838 } else {
2839 die "no such serial device\n" if ! -c $path;
2840 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2841 push @$devices, '-device', "isa-serial,chardev=serial$i";
2842 }
34978be3 2843 }
1e3baf05
DM
2844 }
2845
2846 # parallel devices
1989a89c 2847 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2848 if (my $path = $conf->{"parallel$i"}) {
19672434 2849 die "no such parallel device\n" if ! -c $path;
32e69805 2850 my $devtype = $path =~ m!^/dev/usb/lp! ? 'tty' : 'parport';
4c5dbaf6 2851 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
5bdcf937 2852 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2853 }
1e3baf05
DM
2854 }
2855
2856 my $vmname = $conf->{name} || "vm$vmid";
2857
2858 push @$cmd, '-name', $vmname;
19672434 2859
1e3baf05
DM
2860 my $sockets = 1;
2861 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2862 $sockets = $conf->{sockets} if $conf->{sockets};
2863
2864 my $cores = $conf->{cores} || 1;
3bd18e48 2865
de9d1e55 2866 my $maxcpus = $sockets * $cores;
76267728 2867
de9d1e55 2868 my $vcpus = $conf->{vcpus} ? $conf->{vcpus} : $maxcpus;
76267728 2869
de9d1e55
AD
2870 my $allowed_vcpus = $cpuinfo->{cpus};
2871
6965d5d1 2872 die "MAX $allowed_vcpus vcpus allowed per VM on this node\n"
de9d1e55
AD
2873 if ($allowed_vcpus < $maxcpus);
2874
2875 push @$cmd, '-smp', "$vcpus,sockets=$sockets,cores=$cores,maxcpus=$maxcpus";
1e3baf05 2876
1e3baf05
DM
2877 push @$cmd, '-nodefaults';
2878
32baffb4 2879 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2880
0888fdce
DM
2881 my $bootindex_hash = {};
2882 my $i = 1;
2883 foreach my $o (split(//, $bootorder)) {
2884 $bootindex_hash->{$o} = $i*100;
2885 $i++;
afdb31d5 2886 }
3b408e82 2887
cf71f776 2888 push @$cmd, '-boot', "menu=on,strict=on,reboot-timeout=1000";
1e3baf05 2889
6b64503e 2890 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2891
6b64503e 2892 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05 2893
ef5e2be2 2894 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
1e3baf05 2895
b7be4ba9
AD
2896 if ($vga && $vga !~ m/^serial\d+$/ && $vga ne 'none'){
2897 my $socket = vnc_socket($vmid);
2898 push @$cmd, '-vnc', "unix:$socket,x509,password";
2899 } else {
2900 push @$cmd, '-nographic';
2901 }
2902
1e3baf05 2903 # time drift fix
6b64503e 2904 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2905
6b64503e 2906 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2907 my $useLocaltime = $conf->{localtime};
1e3baf05 2908
b42d3cf9 2909 if ($ostype) {
6b9d84cf 2910 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
1e3baf05 2911
b42d3cf9 2912 if ($ostype =~ m/^w/) { # windows
8c559505 2913 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2914
8c559505 2915 # use time drift fix when acpi is enabled
6b64503e 2916 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2917 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2918 }
2919 }
2920
b42d3cf9
DM
2921 if ($ostype eq 'win7' || $ostype eq 'win8' || $ostype eq 'w2k8' ||
2922 $ostype eq 'wvista') {
8c559505 2923 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf 2924 push @$cmd, '-no-hpet';
8f3f959d 2925 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
bd92244c
AD
2926 push @$cpuFlags , 'hv_spinlocks=0x1fff' if !$nokvm;
2927 push @$cpuFlags , 'hv_vapic' if !$nokvm;
2928 push @$cpuFlags , 'hv_time' if !$nokvm;
8a054ffd 2929
7a131888
AD
2930 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 6)) {
2931 push @$cpuFlags , 'hv_reset' if !$nokvm;
2932 push @$cpuFlags , 'hv_vpindex' if !$nokvm;
2933 push @$cpuFlags , 'hv_runtime' if !$nokvm;
2934 }
2935
a1b7d579 2936 } else {
bd92244c 2937 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
8f3f959d 2938 }
462e8d19
AD
2939 }
2940
b42d3cf9 2941 if ($ostype eq 'win7' || $ostype eq 'win8') {
bd92244c 2942 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
b7e0c8bf 2943 }
1e3baf05
DM
2944 }
2945
8c559505
DM
2946 push @$rtcFlags, 'driftfix=slew' if $tdf;
2947
7f0b5beb 2948 if ($nokvm) {
8c559505 2949 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2950 } else {
2951 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2952 }
1e3baf05 2953
952958bc
DM
2954 if ($machine_type) {
2955 push @$machineFlags, "type=${machine_type}";
3bafc510
DM
2956 }
2957
8c559505
DM
2958 if ($conf->{startdate}) {
2959 push @$rtcFlags, "base=$conf->{startdate}";
2960 } elsif ($useLocaltime) {
2961 push @$rtcFlags, 'base=localtime';
2962 }
1e3baf05 2963
519ed28c 2964 my $cpu = $nokvm ? "qemu64" : "kvm64";
16a91d65 2965 if (my $cputype = $conf->{cpu}) {
ff6ffe20 2966 my $cpuconf = PVE::JSONSchema::parse_property_string($cpu_fmt, $cputype)
16a91d65
WB
2967 or die "Cannot parse cpu description: $cputype\n";
2968 $cpu = $cpuconf->{cputype};
2969 $kvm_off = 1 if $cpuconf->{hidden};
2970 }
519ed28c 2971
4dc339e7
AD
2972 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2973
d853f40a
DM
2974 push @$cpuFlags , '-x2apic'
2975 if $conf->{ostype} && $conf->{ostype} eq 'solaris';
519ed28c 2976
2e1a5389
AD
2977 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2978
0dc48c3d
AD
2979 push @$cpuFlags, '-rdtscp' if $cpu =~ m/^Opteron/;
2980
117a0414
AD
2981 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2982
2983 push @$cpuFlags , '+kvm_pv_unhalt' if !$nokvm;
0da5a08c 2984 push @$cpuFlags , '+kvm_pv_eoi' if !$nokvm;
117a0414
AD
2985 }
2986
f1f7ea88 2987 push @$cpuFlags, 'enforce' if $cpu ne 'host' && !$nokvm;
dac7c619 2988
16a91d65
WB
2989 push @$cpuFlags, 'kvm=off' if $kvm_off;
2990
8930da74
DM
2991 my $cpu_vendor = $cpu_vendor_list->{$cpu} ||
2992 die "internal error"; # should not happen
2993
2994 push @$cpuFlags, "vendor=${cpu_vendor}"
2995 if $cpu_vendor ne 'default';
2996
be190583 2997 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c 2998
dac7c619 2999 push @$cmd, '-cpu', $cpu;
519ed28c 3000
0567a4d5
AD
3001 PVE::QemuServer::Memory::config($conf, $vmid, $sockets, $cores, $defaults, $hotplug_features, $cmd);
3002
1e3baf05
DM
3003 push @$cmd, '-S' if $conf->{freeze};
3004
3005 # set keyboard layout
3006 my $kb = $conf->{keyboard} || $defaults->{keyboard};
3007 push @$cmd, '-k', $kb if $kb;
3008
3009 # enable sound
3010 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
3011 #push @$cmd, '-soundhw', 'es1370';
3012 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 3013
bc84dcca 3014 if($conf->{agent}) {
7a6c2150 3015 my $qgasocket = qmp_socket($vmid, 1);
ab6a046f
AD
3016 my $pciaddr = print_pci_addr("qga0", $bridges);
3017 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
3018 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
3019 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
3020 }
3021
1d794448 3022 my $spice_port;
2fa3151e 3023
590e698c
DM
3024 if ($qxlnum) {
3025 if ($qxlnum > 1) {
3026 if ($conf->{ostype} && $conf->{ostype} =~ m/^w/){
3027 for(my $i = 1; $i < $qxlnum; $i++){
3028 my $pciaddr = print_pci_addr("vga$i", $bridges);
3029 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
3030 }
3031 } else {
3032 # assume other OS works like Linux
3033 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
3034 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2fa3151e
AD
3035 }
3036 }
3037
1011b570 3038 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 3039
af0eba7e
WB
3040 my $nodename = PVE::INotify::nodename();
3041 my $pfamily = PVE::Tools::get_host_address_family($nodename);
3042 $spice_port = PVE::Tools::next_spice_port($pfamily);
943340a6 3043
fd1f36ac 3044 push @$devices, '-spice', "tls-port=${spice_port},addr=localhost,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 3045
d2da6d9b
AD
3046 push @$devices, '-device', "virtio-serial,id=spice$pciaddr";
3047 push @$devices, '-chardev', "spicevmc,id=vdagent,name=vdagent";
3048 push @$devices, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
1011b570
DM
3049 }
3050
8d9ae0d2
DM
3051 # enable balloon by default, unless explicitly disabled
3052 if (!defined($conf->{balloon}) || $conf->{balloon}) {
3053 $pciaddr = print_pci_addr("balloon0", $bridges);
3054 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
3055 }
1e3baf05 3056
0ea9541d
DM
3057 if ($conf->{watchdog}) {
3058 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 3059 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 3060 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
3061 push @$devices, '-device', "$watchdog$pciaddr";
3062 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
3063 }
3064
1e3baf05 3065 my $vollist = [];
941e0c42 3066 my $scsicontroller = {};
26ee04b6 3067 my $ahcicontroller = {};
cdd20088 3068 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05 3069
5881b913
DM
3070 # Add iscsi initiator name if available
3071 if (my $initiator = get_initiator_name()) {
3072 push @$devices, '-iscsi', "initiator-name=$initiator";
3073 }
3074
1e3baf05
DM
3075 foreach_drive($conf, sub {
3076 my ($ds, $drive) = @_;
3077
ff1a2432 3078 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 3079 push @$vollist, $drive->{file};
ff1a2432 3080 }
afdb31d5 3081
1e3baf05 3082 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
3083
3084 if (drive_is_cdrom ($drive)) {
3085 if ($bootindex_hash->{d}) {
3086 $drive->{bootindex} = $bootindex_hash->{d};
3087 $bootindex_hash->{d} += 1;
3088 }
3089 } else {
3090 if ($bootindex_hash->{c}) {
3091 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
3092 $bootindex_hash->{c} += 1;
3093 }
3094 }
3095
51f492cd
AD
3096 if($drive->{interface} eq 'virtio'){
3097 push @$cmd, '-object', "iothread,id=iothread-$ds" if $drive->{iothread};
3098 }
3099
941e0c42 3100 if ($drive->{interface} eq 'scsi') {
cdd20088 3101
ee034f5c 3102 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
6731a4cf 3103
6731a4cf 3104 $pciaddr = print_pci_addr("$controller_prefix$controller", $bridges);
a1b7d579 3105 my $scsihw_type = $scsihw =~ m/^virtio-scsi-single/ ? "virtio-scsi-pci" : $scsihw;
fc8b40fd
AD
3106
3107 my $iothread = '';
3108 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{iothread}){
3109 $iothread .= ",iothread=iothread-$controller_prefix$controller";
3110 push @$cmd, '-object', "iothread,id=iothread-$controller_prefix$controller";
e7a5104d
DC
3111 } elsif ($drive->{iothread}) {
3112 warn "iothread is only valid with virtio disk or virtio-scsi-single controller, ignoring\n";
fc8b40fd
AD
3113 }
3114
6e11f143
AD
3115 my $queues = '';
3116 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{queues}){
3117 $queues = ",num_queues=$drive->{queues}";
3118 }
3119
3120 push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread$queues" if !$scsicontroller->{$controller};
cdd20088 3121 $scsicontroller->{$controller}=1;
941e0c42 3122 }
3b408e82 3123
26ee04b6
DA
3124 if ($drive->{interface} eq 'sata') {
3125 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
3126 $pciaddr = print_pci_addr("ahci$controller", $bridges);
3127 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
3128 $ahcicontroller->{$controller}=1;
3129 }
46f58b5f 3130
15b21acc
MR
3131 my $drive_cmd = print_drive_full($storecfg, $vmid, $drive);
3132 push @$devices, '-drive',$drive_cmd;
46f58b5f 3133 push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
3134 });
3135
cc4d6182 3136 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 3137 next if !$conf->{"net$i"};
cc4d6182
DA
3138 my $d = parse_net($conf->{"net$i"});
3139 next if !$d;
1e3baf05 3140
cc4d6182 3141 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 3142
cc4d6182
DA
3143 if ($bootindex_hash->{n}) {
3144 $d->{bootindex} = $bootindex_hash->{n};
3145 $bootindex_hash->{n} += 1;
3146 }
1e3baf05 3147
cc4d6182 3148 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
3149 push @$devices, '-netdev', $netdevfull;
3150
ba9e1000 3151 my $netdevicefull = print_netdevice_full($vmid, $conf, $d, "net$i", $bridges, $use_old_bios_files);
5bdcf937
AD
3152 push @$devices, '-device', $netdevicefull;
3153 }
1e3baf05 3154
db656e5f
DM
3155 if (!$q35) {
3156 # add pci bridges
fc79e813
AD
3157 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
3158 $bridges->{1} = 1;
3159 $bridges->{2} = 1;
3160 }
3161
6731a4cf
AD
3162 $bridges->{3} = 1 if $scsihw =~ m/^virtio-scsi-single/;
3163
f8e83f05
AD
3164 while (my ($k, $v) = each %$bridges) {
3165 $pciaddr = print_pci_addr("pci.$k");
3166 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
3167 }
19672434
DM
3168 }
3169
1e3baf05
DM
3170 # add custom args
3171 if ($conf->{args}) {
3ada46c9 3172 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
3173 push @$cmd, @$aa;
3174 }
3175
5bdcf937 3176 push @$cmd, @$devices;
be190583 3177 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 3178 if scalar(@$rtcFlags);
be190583 3179 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
3180 if scalar(@$machineFlags);
3181 push @$cmd, '-global', join(',', @$globalFlags)
3182 if scalar(@$globalFlags);
3183
1d794448 3184 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 3185}
19672434 3186
1e3baf05
DM
3187sub vnc_socket {
3188 my ($vmid) = @_;
3189 return "${var_run_tmpdir}/$vmid.vnc";
3190}
3191
943340a6 3192sub spice_port {
1011b570 3193 my ($vmid) = @_;
943340a6 3194
1d794448 3195 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
3196
3197 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
3198}
3199
c971c4f2 3200sub qmp_socket {
693d12a2
AD
3201 my ($vmid, $qga) = @_;
3202 my $sockettype = $qga ? 'qga' : 'qmp';
3203 return "${var_run_tmpdir}/$vmid.$sockettype";
c971c4f2
AD
3204}
3205
1e3baf05
DM
3206sub pidfile_name {
3207 my ($vmid) = @_;
3208 return "${var_run_tmpdir}/$vmid.pid";
3209}
3210
86fdcfb2
DA
3211sub vm_devices_list {
3212 my ($vmid) = @_;
3213
ceea9078 3214 my $res = vm_mon_cmd($vmid, 'query-pci');
ceea9078
DM
3215 my $devices = {};
3216 foreach my $pcibus (@$res) {
3217 foreach my $device (@{$pcibus->{devices}}) {
6e62a21f 3218 next if !$device->{'qdev_id'};
200644a7 3219 if ($device->{'pci_bridge'}) {
200644a7
AD
3220 $devices->{$device->{'qdev_id'}} = 1;
3221 foreach my $bridge_device (@{$device->{'pci_bridge'}->{devices}}) {
3222 next if !$bridge_device->{'qdev_id'};
3223 $devices->{$bridge_device->{'qdev_id'}} = 1;
3224 $devices->{$device->{'qdev_id'}}++;
3225 }
3226 } else {
200644a7
AD
3227 $devices->{$device->{'qdev_id'}} = 1;
3228 }
f78cc802
AD
3229 }
3230 }
3231
3232 my $resblock = vm_mon_cmd($vmid, 'query-block');
3233 foreach my $block (@$resblock) {
3234 if($block->{device} =~ m/^drive-(\S+)/){
3235 $devices->{$1} = 1;
1dc4f496
DM
3236 }
3237 }
86fdcfb2 3238
3d7389fe
DM
3239 my $resmice = vm_mon_cmd($vmid, 'query-mice');
3240 foreach my $mice (@$resmice) {
3241 if ($mice->{name} eq 'QEMU HID Tablet') {
3242 $devices->{tablet} = 1;
3243 last;
3244 }
3245 }
3246
deb091c5
DC
3247 # for usb devices there is no query-usb
3248 # but we can iterate over the entries in
3249 # qom-list path=/machine/peripheral
3250 my $resperipheral = vm_mon_cmd($vmid, 'qom-list', path => '/machine/peripheral');
3251 foreach my $per (@$resperipheral) {
3252 if ($per->{name} =~ m/^usb\d+$/) {
3253 $devices->{$per->{name}} = 1;
3254 }
3255 }
3256
1dc4f496 3257 return $devices;
86fdcfb2
DA
3258}
3259
ec21aa11 3260sub vm_deviceplug {
f19d1c47 3261 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 3262
db656e5f
DM
3263 my $q35 = machine_type_is_q35($conf);
3264
95d6343b
DA
3265 my $devices_list = vm_devices_list($vmid);
3266 return 1 if defined($devices_list->{$deviceid});
3267
fee46675
DM
3268 qemu_add_pci_bridge($storecfg, $conf, $vmid, $deviceid); # add PCI bridge if we need it for the device
3269
3d7389fe 3270 if ($deviceid eq 'tablet') {
fee46675 3271
3d7389fe 3272 qemu_deviceadd($vmid, print_tabletdevice_full($conf));
3d7389fe 3273
4eb68604
DC
3274 } elsif ($deviceid =~ m/^usb(\d+)$/) {
3275
f745762b
DC
3276 die "usb hotplug currently not reliable\n";
3277 # since we can't reliably hot unplug all added usb devices
3278 # and usb passthrough disables live migration
3279 # we disable usb hotplugging for now
4eb68604
DC
3280 qemu_deviceadd($vmid, PVE::QemuServer::USB::print_usbdevice_full($conf, $deviceid, $device));
3281
fee46675 3282 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
40f28a9f 3283
22de899a
AD
3284 qemu_iothread_add($vmid, $deviceid, $device);
3285
fee46675 3286 qemu_driveadd($storecfg, $vmid, $device);
cdd20088 3287 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
fee46675 3288
5e5dcb73 3289 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3290 eval { qemu_deviceaddverify($vmid, $deviceid); };
3291 if (my $err = $@) {
63c2da2f
DM
3292 eval { qemu_drivedel($vmid, $deviceid); };
3293 warn $@ if $@;
fee46675 3294 die $err;
5e5dcb73 3295 }
cfc817c7 3296
2733141c 3297 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
fee46675 3298
fc8b40fd 3299
cdd20088 3300 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 3301 my $pciaddr = print_pci_addr($deviceid);
a1b7d579 3302 my $scsihw_type = $scsihw eq 'virtio-scsi-single' ? "virtio-scsi-pci" : $scsihw;
2733141c
AD
3303
3304 my $devicefull = "$scsihw_type,id=$deviceid$pciaddr";
fee46675 3305
fc8b40fd
AD
3306 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{iothread}) {
3307 qemu_iothread_add($vmid, $deviceid, $device);
3308 $devicefull .= ",iothread=iothread-$deviceid";
3309 }
3310
6e11f143
AD
3311 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{queues}) {
3312 $devicefull .= ",num_queues=$device->{queues}";
3313 }
3314
cfc817c7 3315 qemu_deviceadd($vmid, $devicefull);
fee46675 3316 qemu_deviceaddverify($vmid, $deviceid);
cfc817c7 3317
fee46675
DM
3318 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3319
3320 qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
3321 qemu_driveadd($storecfg, $vmid, $device);
a1b7d579 3322
fee46675
DM
3323 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
3324 eval { qemu_deviceadd($vmid, $devicefull); };
3325 if (my $err = $@) {
63c2da2f
DM
3326 eval { qemu_drivedel($vmid, $deviceid); };
3327 warn $@ if $@;
fee46675 3328 die $err;
a4f091a0 3329 }
a4f091a0 3330
fee46675
DM
3331 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3332
2630d2a9 3333 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
8718099c
AD
3334
3335 my $machine_type = PVE::QemuServer::qemu_machine_pxe($vmid, $conf);
3336 my $use_old_bios_files = undef;
3337 ($use_old_bios_files, $machine_type) = qemu_use_old_bios_files($machine_type);
3338
3339 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid, undef, $use_old_bios_files);
2630d2a9 3340 qemu_deviceadd($vmid, $netdevicefull);
fee46675
DM
3341 eval { qemu_deviceaddverify($vmid, $deviceid); };
3342 if (my $err = $@) {
3343 eval { qemu_netdevdel($vmid, $deviceid); };
3344 warn $@ if $@;
3345 die $err;
2630d2a9 3346 }
2630d2a9 3347
fee46675 3348 } elsif (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
b467f79a 3349
40f28a9f
AD
3350 my $bridgeid = $2;
3351 my $pciaddr = print_pci_addr($deviceid);
3352 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
a1b7d579 3353
40f28a9f 3354 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3355 qemu_deviceaddverify($vmid, $deviceid);
3356
3357 } else {
a1b7d579 3358 die "can't hotplug device '$deviceid'\n";
40f28a9f
AD
3359 }
3360
5e5dcb73 3361 return 1;
a4dea331
DA
3362}
3363
3eec5767 3364# fixme: this should raise exceptions on error!
ec21aa11 3365sub vm_deviceunplug {
f19d1c47 3366 my ($vmid, $conf, $deviceid) = @_;
873c2d69 3367
95d6343b
DA
3368 my $devices_list = vm_devices_list($vmid);
3369 return 1 if !defined($devices_list->{$deviceid});
3370
63c2da2f
DM
3371 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
3372
3d7389fe 3373 if ($deviceid eq 'tablet') {
63c2da2f 3374
3d7389fe 3375 qemu_devicedel($vmid, $deviceid);
3d7389fe 3376
4eb68604
DC
3377 } elsif ($deviceid =~ m/^usb\d+$/) {
3378
f745762b
DC
3379 die "usb hotplug currently not reliable\n";
3380 # when unplugging usb devices this way,
3381 # there may be remaining usb controllers/hubs
3382 # so we disable it for now
4eb68604
DC
3383 qemu_devicedel($vmid, $deviceid);
3384 qemu_devicedelverify($vmid, $deviceid);
3385
63c2da2f 3386 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
f19d1c47 3387
5e5dcb73 3388 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3389 qemu_devicedelverify($vmid, $deviceid);
3390 qemu_drivedel($vmid, $deviceid);
22de899a
AD
3391 qemu_iothread_del($conf, $vmid, $deviceid);
3392
2733141c 3393 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
a1b7d579 3394
63c2da2f 3395 qemu_devicedel($vmid, $deviceid);
8ce30dde 3396 qemu_devicedelverify($vmid, $deviceid);
fc8b40fd 3397 qemu_iothread_del($conf, $vmid, $deviceid);
a1b7d579 3398
63c2da2f 3399 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
cfc817c7 3400
8bcf3068
AD
3401 #qemu 2.3 segfault on drive_del with virtioscsi + iothread
3402 my $device = parse_drive($deviceid, $conf->{$deviceid});
3403 die "virtioscsi with iothread is not hot-unplugglable currently" if $device->{iothread};
3404
63c2da2f
DM
3405 qemu_devicedel($vmid, $deviceid);
3406 qemu_drivedel($vmid, $deviceid);
a1b7d579 3407 qemu_deletescsihw($conf, $vmid, $deviceid);
8ce30dde 3408
63c2da2f 3409 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
a4f091a0 3410
2630d2a9 3411 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3412 qemu_devicedelverify($vmid, $deviceid);
3413 qemu_netdevdel($vmid, $deviceid);
3414
3415 } else {
3416 die "can't unplug device '$deviceid'\n";
2630d2a9
DA
3417 }
3418
5e5dcb73
DA
3419 return 1;
3420}
3421
3422sub qemu_deviceadd {
3423 my ($vmid, $devicefull) = @_;
873c2d69 3424
d695b5b7
AD
3425 $devicefull = "driver=".$devicefull;
3426 my %options = split(/[=,]/, $devicefull);
f19d1c47 3427
d695b5b7 3428 vm_mon_cmd($vmid, "device_add" , %options);
5e5dcb73 3429}
afdb31d5 3430
5e5dcb73 3431sub qemu_devicedel {
fee46675 3432 my ($vmid, $deviceid) = @_;
63c2da2f 3433
5a77d8c1 3434 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
5e5dcb73
DA
3435}
3436
22de899a
AD
3437sub qemu_iothread_add {
3438 my($vmid, $deviceid, $device) = @_;
3439
3440 if ($device->{iothread}) {
3441 my $iothreads = vm_iothreads_list($vmid);
3442 qemu_objectadd($vmid, "iothread-$deviceid", "iothread") if !$iothreads->{"iothread-$deviceid"};
3443 }
3444}
3445
3446sub qemu_iothread_del {
3447 my($conf, $vmid, $deviceid) = @_;
3448
3449 my $device = parse_drive($deviceid, $conf->{$deviceid});
3450 if ($device->{iothread}) {
3451 my $iothreads = vm_iothreads_list($vmid);
3452 qemu_objectdel($vmid, "iothread-$deviceid") if $iothreads->{"iothread-$deviceid"};
3453 }
3454}
3455
4d3f29ed
AD
3456sub qemu_objectadd {
3457 my($vmid, $objectid, $qomtype) = @_;
3458
3459 vm_mon_cmd($vmid, "object-add", id => $objectid, "qom-type" => $qomtype);
3460
3461 return 1;
3462}
3463
3464sub qemu_objectdel {
3465 my($vmid, $objectid) = @_;
3466
3467 vm_mon_cmd($vmid, "object-del", id => $objectid);
3468
3469 return 1;
3470}
3471
5e5dcb73 3472sub qemu_driveadd {
fee46675 3473 my ($storecfg, $vmid, $device) = @_;
5e5dcb73
DA
3474
3475 my $drive = print_drive_full($storecfg, $vmid, $device);
7a69fc3c 3476 $drive =~ s/\\/\\\\/g;
8ead5ec7 3477 my $ret = vm_human_monitor_command($vmid, "drive_add auto \"$drive\"");
fee46675 3478
5e5dcb73 3479 # If the command succeeds qemu prints: "OK"
fee46675
DM
3480 return 1 if $ret =~ m/OK/s;
3481
3482 die "adding drive failed: $ret\n";
5e5dcb73 3483}
afdb31d5 3484
5e5dcb73
DA
3485sub qemu_drivedel {
3486 my($vmid, $deviceid) = @_;
873c2d69 3487
7b7c6d1b 3488 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73 3489 $ret =~ s/^\s+//;
a1b7d579 3490
63c2da2f 3491 return 1 if $ret eq "";
a1b7d579 3492
63c2da2f 3493 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
a1b7d579
DM
3494 return 1 if $ret =~ m/Device \'.*?\' not found/s;
3495
63c2da2f 3496 die "deleting drive $deviceid failed : $ret\n";
5e5dcb73 3497}
f19d1c47 3498
5e5dcb73 3499sub qemu_deviceaddverify {
fee46675 3500 my ($vmid, $deviceid) = @_;
873c2d69 3501
5e5dcb73
DA
3502 for (my $i = 0; $i <= 5; $i++) {
3503 my $devices_list = vm_devices_list($vmid);
3504 return 1 if defined($devices_list->{$deviceid});
3505 sleep 1;
afdb31d5 3506 }
fee46675
DM
3507
3508 die "error on hotplug device '$deviceid'\n";
5e5dcb73 3509}
afdb31d5 3510
5e5dcb73
DA
3511
3512sub qemu_devicedelverify {
63c2da2f
DM
3513 my ($vmid, $deviceid) = @_;
3514
a1b7d579 3515 # need to verify that the device is correctly removed as device_del
63c2da2f 3516 # is async and empty return is not reliable
5e5dcb73 3517
5e5dcb73
DA
3518 for (my $i = 0; $i <= 5; $i++) {
3519 my $devices_list = vm_devices_list($vmid);
3520 return 1 if !defined($devices_list->{$deviceid});
3521 sleep 1;
afdb31d5 3522 }
63c2da2f
DM
3523
3524 die "error on hot-unplugging device '$deviceid'\n";
873c2d69
DA
3525}
3526
cdd20088 3527sub qemu_findorcreatescsihw {
cfc817c7
DA
3528 my ($storecfg, $conf, $vmid, $device) = @_;
3529
ee034f5c 3530 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
2733141c
AD
3531
3532 my $scsihwid="$controller_prefix$controller";
cfc817c7
DA
3533 my $devices_list = vm_devices_list($vmid);
3534
cdd20088 3535 if(!defined($devices_list->{$scsihwid})) {
fc8b40fd 3536 vm_deviceplug($storecfg, $conf, $vmid, $scsihwid, $device);
cfc817c7 3537 }
fee46675 3538
cfc817c7
DA
3539 return 1;
3540}
3541
8ce30dde
AD
3542sub qemu_deletescsihw {
3543 my ($conf, $vmid, $opt) = @_;
3544
3545 my $device = parse_drive($opt, $conf->{$opt});
3546
a1511b3c 3547 if ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
2733141c
AD
3548 vm_deviceunplug($vmid, $conf, "virtioscsi$device->{index}");
3549 return 1;
3550 }
3551
ee034f5c 3552 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
8ce30dde
AD
3553
3554 my $devices_list = vm_devices_list($vmid);
3555 foreach my $opt (keys %{$devices_list}) {
74479ee9 3556 if (PVE::QemuServer::is_valid_drivename($opt)) {
8ce30dde
AD
3557 my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
3558 if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) {
3559 return 1;
3560 }
3561 }
3562 }
3563
3564 my $scsihwid="scsihw$controller";
3565
3566 vm_deviceunplug($vmid, $conf, $scsihwid);
3567
3568 return 1;
3569}
3570
281fedb3 3571sub qemu_add_pci_bridge {
40f28a9f
AD
3572 my ($storecfg, $conf, $vmid, $device) = @_;
3573
3574 my $bridges = {};
281fedb3
DM
3575
3576 my $bridgeid;
3577
40f28a9f
AD
3578 print_pci_addr($device, $bridges);
3579
3580 while (my ($k, $v) = each %$bridges) {
3581 $bridgeid = $k;
3582 }
fee46675 3583 return 1 if !defined($bridgeid) || $bridgeid < 1;
281fedb3 3584
40f28a9f
AD
3585 my $bridge = "pci.$bridgeid";
3586 my $devices_list = vm_devices_list($vmid);
3587
281fedb3 3588 if (!defined($devices_list->{$bridge})) {
fee46675 3589 vm_deviceplug($storecfg, $conf, $vmid, $bridge);
40f28a9f 3590 }
281fedb3 3591
40f28a9f
AD
3592 return 1;
3593}
3594
25088687
DM
3595sub qemu_set_link_status {
3596 my ($vmid, $device, $up) = @_;
3597
a1b7d579 3598 vm_mon_cmd($vmid, "set_link", name => $device,
25088687
DM
3599 up => $up ? JSON::true : JSON::false);
3600}
3601
2630d2a9
DA
3602sub qemu_netdevadd {
3603 my ($vmid, $conf, $device, $deviceid) = @_;
3604
208ba94e 3605 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid, 1);
73aa03b8 3606 my %options = split(/[=,]/, $netdev);
2630d2a9 3607
73aa03b8
AD
3608 vm_mon_cmd($vmid, "netdev_add", %options);
3609 return 1;
2630d2a9
DA
3610}
3611
3612sub qemu_netdevdel {
3613 my ($vmid, $deviceid) = @_;
3614
89c1e0f4 3615 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2630d2a9
DA
3616}
3617
16521d63
DC
3618sub qemu_usb_hotplug {
3619 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
3620
3621 return if !$device;
3622
3623 # remove the old one first
3624 vm_deviceunplug($vmid, $conf, $deviceid);
3625
3626 # check if xhci controller is necessary and available
3627 if ($device->{usb3}) {
3628
3629 my $devicelist = vm_devices_list($vmid);
3630
3631 if (!$devicelist->{xhci}) {
3632 my $pciaddr = print_pci_addr("xhci");
3633 qemu_deviceadd($vmid, "nec-usb-xhci,id=xhci$pciaddr");
3634 }
3635 }
3636 my $d = parse_usb_device($device->{host});
3637 $d->{usb3} = $device->{usb3};
3638
3639 # add the new one
3640 vm_deviceplug($storecfg, $conf, $vmid, $deviceid, $d);
3641}
3642
838776ab 3643sub qemu_cpu_hotplug {
8edc9c08 3644 my ($vmid, $conf, $vcpus) = @_;
838776ab 3645
8edc9c08
AD
3646 my $sockets = 1;
3647 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
3648 $sockets = $conf->{sockets} if $conf->{sockets};
3649 my $cores = $conf->{cores} || 1;
3650 my $maxcpus = $sockets * $cores;
838776ab 3651
8edc9c08 3652 $vcpus = $maxcpus if !$vcpus;
3a11fadb 3653
8edc9c08
AD
3654 die "you can't add more vcpus than maxcpus\n"
3655 if $vcpus > $maxcpus;
3a11fadb 3656
8edc9c08 3657 my $currentvcpus = $conf->{vcpus} || $maxcpus;
3a11fadb 3658 die "online cpu unplug is not yet possible\n"
8edc9c08 3659 if $vcpus < $currentvcpus;
838776ab 3660
8edc9c08
AD
3661 my $currentrunningvcpus = vm_mon_cmd($vmid, "query-cpus");
3662 die "vcpus in running vm is different than configuration\n"
3663 if scalar(@{$currentrunningvcpus}) != $currentvcpus;
838776ab 3664
8edc9c08 3665 for (my $i = $currentvcpus; $i < $vcpus; $i++) {
838776ab
AD
3666 vm_mon_cmd($vmid, "cpu-add", id => int($i));
3667 }
3668}
3669
affd2f88 3670sub qemu_block_set_io_throttle {
277ca170
WB
3671 my ($vmid, $deviceid,
3672 $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr,
3673 $bps_max, $bps_rd_max, $bps_wr_max, $iops_max, $iops_rd_max, $iops_wr_max) = @_;
affd2f88 3674
f3f323a3
AD
3675 return if !check_running($vmid) ;
3676
277ca170
WB
3677 vm_mon_cmd($vmid, "block_set_io_throttle", device => $deviceid,
3678 bps => int($bps),
3679 bps_rd => int($bps_rd),
3680 bps_wr => int($bps_wr),
3681 iops => int($iops),
3682 iops_rd => int($iops_rd),
3683 iops_wr => int($iops_wr),
3684 bps_max => int($bps_max),
3685 bps_rd_max => int($bps_rd_max),
3686 bps_wr_max => int($bps_wr_max),
3687 iops_max => int($iops_max),
3688 iops_rd_max => int($iops_rd_max),
3689 iops_wr_max => int($iops_wr_max)
3690 );
f3f323a3 3691
affd2f88
AD
3692}
3693
f5eb281a 3694# old code, only used to shutdown old VM after update
dab36e1e
DM
3695sub __read_avail {
3696 my ($fh, $timeout) = @_;
3697
3698 my $sel = new IO::Select;
3699 $sel->add($fh);
3700
3701 my $res = '';
3702 my $buf;
3703
3704 my @ready;
3705 while (scalar (@ready = $sel->can_read($timeout))) {
3706 my $count;
3707 if ($count = $fh->sysread($buf, 8192)) {
3708 if ($buf =~ /^(.*)\(qemu\) $/s) {
3709 $res .= $1;
3710 last;
3711 } else {
3712 $res .= $buf;
3713 }
3714 } else {
3715 if (!defined($count)) {
3716 die "$!\n";
3717 }
3718 last;
3719 }
3720 }
3721
3722 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 3723
dab36e1e
DM
3724 return $res;
3725}
3726
f5eb281a 3727# old code, only used to shutdown old VM after update
dab36e1e
DM
3728sub vm_monitor_command {
3729 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 3730
dab36e1e
DM
3731 my $res;
3732
3733 eval {
3734 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
3735
3736 my $sname = "${var_run_tmpdir}/$vmid.mon";
3737
3738 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
3739 die "unable to connect to VM $vmid socket - $!\n";
3740
3741 my $timeout = 3;
3742
3743 # hack: migrate sometime blocks the monitor (when migrate_downtime
3744 # is set)
3745 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3746 $timeout = 60*60; # 1 hour
3747 }
3748
3749 # read banner;
3750 my $data = __read_avail($sock, $timeout);
3751
3752 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3753 die "got unexpected qemu monitor banner\n";
3754 }
3755
3756 my $sel = new IO::Select;
3757 $sel->add($sock);
3758
3759 if (!scalar(my @ready = $sel->can_write($timeout))) {
3760 die "monitor write error - timeout";
3761 }
3762
3763 my $fullcmd = "$cmdstr\r";
3764
3765 # syslog('info', "VM $vmid monitor command: $cmdstr");
3766
3767 my $b;
3768 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3769 die "monitor write error - $!";
3770 }
3771
3772 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3773
3774 $timeout = 20;
3775
3776 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3777 $timeout = 60*60; # 1 hour
3778 } elsif ($cmdstr =~ m/^(eject|change)/) {
3779 $timeout = 60; # note: cdrom mount command is slow
3780 }
3781 if ($res = __read_avail($sock, $timeout)) {
3782
3783 my @lines = split("\r?\n", $res);
f5eb281a 3784
dab36e1e 3785 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 3786
dab36e1e
DM
3787 $res = join("\n", @lines);
3788 $res .= "\n";
3789 }
3790 };
3791
3792 my $err = $@;
3793
3794 if ($err) {
3795 syslog("err", "VM $vmid monitor command failed - $err");
3796 die $err;
3797 }
f5eb281a 3798
dab36e1e
DM
3799 return $res;
3800}
3801
c1175c92
AD
3802sub qemu_block_resize {
3803 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3804
ed221350 3805 my $running = check_running($vmid);
c1175c92
AD
3806
3807 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3808
3809 return if !$running;
3810
3811 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3812
3813}
3814
1ab0057c
AD
3815sub qemu_volume_snapshot {
3816 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3817
ed221350 3818 my $running = check_running($vmid);
1ab0057c 3819
e5eaa028
WL
3820 if ($running && do_snapshots_with_qemu($storecfg, $volid)){
3821 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3822 } else {
3823 PVE::Storage::volume_snapshot($storecfg, $volid, $snap);
3824 }
1ab0057c
AD
3825}
3826
fc46aff9
AD
3827sub qemu_volume_snapshot_delete {
3828 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3829
ed221350 3830 my $running = check_running($vmid);
fc46aff9
AD
3831
3832 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3833
3834 return if !$running;
3835
18bfb361 3836 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3837}
3838
264e519f
DM
3839sub set_migration_caps {
3840 my ($vmid) = @_;
a89fded1 3841
8b8345f3 3842 my $cap_ref = [];
a89fded1
AD
3843
3844 my $enabled_cap = {
8b8345f3 3845 "auto-converge" => 1,
0b0a47e8 3846 "xbzrle" => 1,
8b8345f3
DM
3847 "x-rdma-pin-all" => 0,
3848 "zero-blocks" => 0,
b62532e4 3849 "compress" => 0
a89fded1
AD
3850 };
3851
8b8345f3 3852 my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities");
a89fded1 3853
8b8345f3 3854 for my $supported_capability (@$supported_capabilities) {
b463a3ce
SP
3855 push @$cap_ref, {
3856 capability => $supported_capability->{capability},
22430fa2
DM
3857 state => $enabled_cap->{$supported_capability->{capability}} ? JSON::true : JSON::false,
3858 };
a89fded1
AD
3859 }
3860
8b8345f3
DM
3861 vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => $cap_ref);
3862}
a89fded1 3863
81d95ae1 3864my $fast_plug_option = {
7498eb64 3865 'lock' => 1,
81d95ae1 3866 'name' => 1,
a1b7d579 3867 'onboot' => 1,
81d95ae1
DM
3868 'shares' => 1,
3869 'startup' => 1,
b0ec896e 3870 'description' => 1,
81d95ae1
DM
3871};
3872
3a11fadb
DM
3873# hotplug changes in [PENDING]
3874# $selection hash can be used to only apply specified options, for
3875# example: { cores => 1 } (only apply changed 'cores')
3876# $errors ref is used to return error messages
c427973b 3877sub vmconfig_hotplug_pending {
3a11fadb 3878 my ($vmid, $conf, $storecfg, $selection, $errors) = @_;
c427973b 3879
8e90138a 3880 my $defaults = load_defaults();
c427973b
DM
3881
3882 # commit values which do not have any impact on running VM first
3a11fadb
DM
3883 # Note: those option cannot raise errors, we we do not care about
3884 # $selection and always apply them.
3885
3886 my $add_error = sub {
3887 my ($opt, $msg) = @_;
3888 $errors->{$opt} = "hotplug problem - $msg";
3889 };
c427973b
DM
3890
3891 my $changes = 0;
3892 foreach my $opt (keys %{$conf->{pending}}) { # add/change
81d95ae1 3893 if ($fast_plug_option->{$opt}) {
c427973b
DM
3894 $conf->{$opt} = $conf->{pending}->{$opt};
3895 delete $conf->{pending}->{$opt};
3896 $changes = 1;
3897 }
3898 }
3899
3900 if ($changes) {
ffda963f
FG
3901 PVE::QemuConfig->write_config($vmid, $conf);
3902 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
c427973b
DM
3903 }
3904
b3c2bdd1 3905 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
c427973b 3906
3dc38fbb
WB
3907 my $pending_delete_hash = split_flagged_list($conf->{pending}->{delete});
3908 while (my ($opt, $force) = each %$pending_delete_hash) {
3a11fadb 3909 next if $selection && !$selection->{$opt};
3a11fadb 3910 eval {
51a6f637
AD
3911 if ($opt eq 'hotplug') {
3912 die "skip\n" if ($conf->{hotplug} =~ /memory/);
3913 } elsif ($opt eq 'tablet') {
b3c2bdd1 3914 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3915 if ($defaults->{tablet}) {
3916 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3917 } else {
3918 vm_deviceunplug($vmid, $conf, $opt);
3919 }
4eb68604 3920 } elsif ($opt =~ m/^usb\d+/) {
f745762b
DC
3921 die "skip\n";
3922 # since we cannot reliably hot unplug usb devices
3923 # we are disabling it
4eb68604
DC
3924 die "skip\n" if !$hotplug_features->{usb} || $conf->{$opt} =~ m/spice/i;
3925 vm_deviceunplug($vmid, $conf, $opt);
8edc9c08 3926 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3927 die "skip\n" if !$hotplug_features->{cpu};
8edc9c08 3928 qemu_cpu_hotplug($vmid, $conf, undef);
9c2f7069 3929 } elsif ($opt eq 'balloon') {
81d95ae1
DM
3930 # enable balloon device is not hotpluggable
3931 die "skip\n" if !defined($conf->{balloon}) || $conf->{balloon};
3932 } elsif ($fast_plug_option->{$opt}) {
3933 # do nothing
3eec5767 3934 } elsif ($opt =~ m/^net(\d+)$/) {
b3c2bdd1 3935 die "skip\n" if !$hotplug_features->{network};
3eec5767 3936 vm_deviceunplug($vmid, $conf, $opt);
74479ee9 3937 } elsif (is_valid_drivename($opt)) {
b3c2bdd1 3938 die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
19120f99 3939 vm_deviceunplug($vmid, $conf, $opt);
3dc38fbb 3940 vmconfig_delete_or_detach_drive($vmid, $storecfg, $conf, $opt, $force);
4d3f29ed
AD
3941 } elsif ($opt =~ m/^memory$/) {
3942 die "skip\n" if !$hotplug_features->{memory};
6779f1ac 3943 PVE::QemuServer::Memory::qemu_memory_hotplug($vmid, $conf, $defaults, $opt);
c8effec3
AD
3944 } elsif ($opt eq 'cpuunits') {
3945 cgroups_write("cpu", $vmid, "cpu.shares", $defaults->{cpuunits});
58be00f1
AD
3946 } elsif ($opt eq 'cpulimit') {
3947 cgroups_write("cpu", $vmid, "cpu.cfs_quota_us", -1);
3d7389fe 3948 } else {
e56beeda 3949 die "skip\n";
3d7389fe 3950 }
3a11fadb
DM
3951 };
3952 if (my $err = $@) {
e56beeda
DM
3953 &$add_error($opt, $err) if $err ne "skip\n";
3954 } else {
3a11fadb
DM
3955 # save new config if hotplug was successful
3956 delete $conf->{$opt};
3957 vmconfig_undelete_pending_option($conf, $opt);
ffda963f
FG
3958 PVE::QemuConfig->write_config($vmid, $conf);
3959 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
3d7389fe 3960 }
3d7389fe
DM
3961 }
3962
3963 foreach my $opt (keys %{$conf->{pending}}) {
3a11fadb 3964 next if $selection && !$selection->{$opt};
3d7389fe 3965 my $value = $conf->{pending}->{$opt};
3a11fadb 3966 eval {
51a6f637
AD
3967 if ($opt eq 'hotplug') {
3968 die "skip\n" if ($value =~ /memory/) || ($value !~ /memory/ && $conf->{hotplug} =~ /memory/);
3969 } elsif ($opt eq 'tablet') {
b3c2bdd1 3970 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3971 if ($value == 1) {
3972 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3973 } elsif ($value == 0) {
3974 vm_deviceunplug($vmid, $conf, $opt);
3975 }
4eb68604 3976 } elsif ($opt =~ m/^usb\d+$/) {
f745762b
DC
3977 die "skip\n";
3978 # since we cannot reliably hot unplug usb devices
3979 # we are disabling it
4eb68604
DC
3980 die "skip\n" if !$hotplug_features->{usb} || $value =~ m/spice/i;
3981 my $d = eval { PVE::JSONSchema::parse_property_string($usbdesc->{format}, $value) };
3982 die "skip\n" if !$d;
3983 qemu_usb_hotplug($storecfg, $conf, $vmid, $opt, $d);
8edc9c08 3984 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3985 die "skip\n" if !$hotplug_features->{cpu};
3a11fadb
DM
3986 qemu_cpu_hotplug($vmid, $conf, $value);
3987 } elsif ($opt eq 'balloon') {
81d95ae1 3988 # enable/disable balloning device is not hotpluggable
8fe689e7 3989 my $old_balloon_enabled = !!(!defined($conf->{balloon}) || $conf->{balloon});
a1b7d579 3990 my $new_balloon_enabled = !!(!defined($conf->{pending}->{balloon}) || $conf->{pending}->{balloon});
81d95ae1
DM
3991 die "skip\n" if $old_balloon_enabled != $new_balloon_enabled;
3992
3a11fadb 3993 # allow manual ballooning if shares is set to zero
4cc1efa6 3994 if ((defined($conf->{shares}) && ($conf->{shares} == 0))) {
9c2f7069
AD
3995 my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
3996 vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
3997 }
a1b7d579 3998 } elsif ($opt =~ m/^net(\d+)$/) {
3eec5767 3999 # some changes can be done without hotplug
a1b7d579 4000 vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
b3c2bdd1 4001 $vmid, $opt, $value);
74479ee9 4002 } elsif (is_valid_drivename($opt)) {
a05cff86 4003 # some changes can be done without hotplug
b3c2bdd1
DM
4004 vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk},
4005 $vmid, $opt, $value, 1);
4d3f29ed
AD
4006 } elsif ($opt =~ m/^memory$/) { #dimms
4007 die "skip\n" if !$hotplug_features->{memory};
6779f1ac 4008 $value = PVE::QemuServer::Memory::qemu_memory_hotplug($vmid, $conf, $defaults, $opt, $value);
c8effec3
AD
4009 } elsif ($opt eq 'cpuunits') {
4010 cgroups_write("cpu", $vmid, "cpu.shares", $conf->{pending}->{$opt});
58be00f1 4011 } elsif ($opt eq 'cpulimit') {
c6f773b8 4012 my $cpulimit = $conf->{pending}->{$opt} == 0 ? -1 : int($conf->{pending}->{$opt} * 100000);
58be00f1 4013 cgroups_write("cpu", $vmid, "cpu.cfs_quota_us", $cpulimit);
3a11fadb 4014 } else {
e56beeda 4015 die "skip\n"; # skip non-hot-pluggable options
3d7389fe 4016 }
3a11fadb
DM
4017 };
4018 if (my $err = $@) {
e56beeda
DM
4019 &$add_error($opt, $err) if $err ne "skip\n";
4020 } else {
3a11fadb
DM
4021 # save new config if hotplug was successful
4022 $conf->{$opt} = $value;
4023 delete $conf->{pending}->{$opt};
ffda963f
FG
4024 PVE::QemuConfig->write_config($vmid, $conf);
4025 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
3d7389fe 4026 }
3d7389fe 4027 }
c427973b 4028}
055d554d 4029
3dc38fbb
WB
4030sub try_deallocate_drive {
4031 my ($storecfg, $vmid, $conf, $key, $drive, $rpcenv, $authuser, $force) = @_;
4032
4033 if (($force || $key =~ /^unused/) && !drive_is_cdrom($drive, 1)) {
4034 my $volid = $drive->{file};
4035 if (vm_is_volid_owner($storecfg, $vmid, $volid)) {
4036 my $sid = PVE::Storage::parse_volume_id($volid);
4037 $rpcenv->check($authuser, "/storage/$sid", ['Datastore.AllocateSpace']);
cee01bcb
WB
4038
4039 # check if the disk is really unused
cee01bcb 4040 die "unable to delete '$volid' - volume is still in use (snapshot?)\n"
77019edf 4041 if is_volume_in_use($storecfg, $conf, $key, $volid);
cee01bcb 4042 PVE::Storage::vdisk_free($storecfg, $volid);
3dc38fbb 4043 return 1;
40b977f3
WL
4044 } else {
4045 # If vm is not owner of this disk remove from config
4046 return 1;
3dc38fbb
WB
4047 }
4048 }
4049
4050 return undef;
4051}
4052
4053sub vmconfig_delete_or_detach_drive {
4054 my ($vmid, $storecfg, $conf, $opt, $force) = @_;
4055
4056 my $drive = parse_drive($opt, $conf->{$opt});
4057
4058 my $rpcenv = PVE::RPCEnvironment::get();
4059 my $authuser = $rpcenv->get_user();
4060
4061 if ($force) {
4062 $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk']);
4063 try_deallocate_drive($storecfg, $vmid, $conf, $opt, $drive, $rpcenv, $authuser, $force);
4064 } else {
4065 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $drive);
4066 }
4067}
4068
055d554d 4069sub vmconfig_apply_pending {
3a11fadb 4070 my ($vmid, $conf, $storecfg) = @_;
c427973b
DM
4071
4072 # cold plug
055d554d 4073
3dc38fbb
WB
4074 my $pending_delete_hash = split_flagged_list($conf->{pending}->{delete});
4075 while (my ($opt, $force) = each %$pending_delete_hash) {
055d554d 4076 die "internal error" if $opt =~ m/^unused/;
ffda963f 4077 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
055d554d
DM
4078 if (!defined($conf->{$opt})) {
4079 vmconfig_undelete_pending_option($conf, $opt);
ffda963f 4080 PVE::QemuConfig->write_config($vmid, $conf);
74479ee9 4081 } elsif (is_valid_drivename($opt)) {
3dc38fbb 4082 vmconfig_delete_or_detach_drive($vmid, $storecfg, $conf, $opt, $force);
055d554d
DM
4083 vmconfig_undelete_pending_option($conf, $opt);
4084 delete $conf->{$opt};
ffda963f 4085 PVE::QemuConfig->write_config($vmid, $conf);
055d554d
DM
4086 } else {
4087 vmconfig_undelete_pending_option($conf, $opt);
4088 delete $conf->{$opt};
ffda963f 4089 PVE::QemuConfig->write_config($vmid, $conf);
055d554d
DM
4090 }
4091 }
4092
ffda963f 4093 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
055d554d
DM
4094
4095 foreach my $opt (keys %{$conf->{pending}}) { # add/change
ffda963f 4096 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
055d554d
DM
4097
4098 if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) {
4099 # skip if nothing changed
74479ee9 4100 } elsif (is_valid_drivename($opt)) {
055d554d
DM
4101 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
4102 if defined($conf->{$opt});
4103 $conf->{$opt} = $conf->{pending}->{$opt};
4104 } else {
4105 $conf->{$opt} = $conf->{pending}->{$opt};
4106 }
4107
4108 delete $conf->{pending}->{$opt};
ffda963f 4109 PVE::QemuConfig->write_config($vmid, $conf);
055d554d
DM
4110 }
4111}
4112
3eec5767
DM
4113my $safe_num_ne = sub {
4114 my ($a, $b) = @_;
4115
4116 return 0 if !defined($a) && !defined($b);
4117 return 1 if !defined($a);
4118 return 1 if !defined($b);
4119
4120 return $a != $b;
4121};
4122
4123my $safe_string_ne = sub {
4124 my ($a, $b) = @_;
4125
4126 return 0 if !defined($a) && !defined($b);
4127 return 1 if !defined($a);
4128 return 1 if !defined($b);
4129
4130 return $a ne $b;
4131};
4132
4133sub vmconfig_update_net {
b3c2bdd1 4134 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value) = @_;
3eec5767
DM
4135
4136 my $newnet = parse_net($value);
4137
4138 if ($conf->{$opt}) {
4139 my $oldnet = parse_net($conf->{$opt});
4140
4141 if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
4142 &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
4143 &$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
4144 !($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
4145
4146 # for non online change, we try to hot-unplug
7196b757 4147 die "skip\n" if !$hotplug;
3eec5767
DM
4148 vm_deviceunplug($vmid, $conf, $opt);
4149 } else {
4150
4151 die "internal error" if $opt !~ m/net(\d+)/;
4152 my $iface = "tap${vmid}i$1";
a1b7d579 4153
25088687
DM
4154 if (&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) ||
4155 &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) ||
16d08ecf 4156 &$safe_string_ne($oldnet->{trunks}, $newnet->{trunks}) ||
25088687 4157 &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})) {
3eec5767 4158 PVE::Network::tap_unplug($iface);
4f4fbeb0
WB
4159 PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall}, $newnet->{trunks}, $newnet->{rate});
4160 } elsif (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
4161 # Rate can be applied on its own but any change above needs to
4162 # include the rate in tap_plug since OVS resets everything.
4163 PVE::Network::tap_rate_limit($iface, $newnet->{rate});
3eec5767 4164 }
38c590d9 4165
25088687
DM
4166 if (&$safe_string_ne($oldnet->{link_down}, $newnet->{link_down})) {
4167 qemu_set_link_status($vmid, $opt, !$newnet->{link_down});
4168 }
4169
38c590d9 4170 return 1;
3eec5767
DM
4171 }
4172 }
a1b7d579 4173
7196b757 4174 if ($hotplug) {
38c590d9
DM
4175 vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
4176 } else {
4177 die "skip\n";
4178 }
3eec5767
DM
4179}
4180
a05cff86 4181sub vmconfig_update_disk {
b3c2bdd1 4182 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $force) = @_;
a05cff86
DM
4183
4184 # fixme: do we need force?
4185
4186 my $drive = parse_drive($opt, $value);
4187
4188 if ($conf->{$opt}) {
4189
4190 if (my $old_drive = parse_drive($opt, $conf->{$opt})) {
4191
4192 my $media = $drive->{media} || 'disk';
4193 my $oldmedia = $old_drive->{media} || 'disk';
4194 die "unable to change media type\n" if $media ne $oldmedia;
4195
4196 if (!drive_is_cdrom($old_drive)) {
4197
a1b7d579 4198 if ($drive->{file} ne $old_drive->{file}) {
a05cff86 4199
7196b757 4200 die "skip\n" if !$hotplug;
a05cff86
DM
4201
4202 # unplug and register as unused
4203 vm_deviceunplug($vmid, $conf, $opt);
4204 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
a1b7d579 4205
a05cff86
DM
4206 } else {
4207 # update existing disk
4208
4209 # skip non hotpluggable value
a1b7d579 4210 if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) ||
22de899a 4211 &$safe_string_ne($drive->{iothread}, $old_drive->{iothread}) ||
6e11f143 4212 &$safe_string_ne($drive->{queues}, $old_drive->{queues}) ||
a05cff86
DM
4213 &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
4214 die "skip\n";
4215 }
4216
4217 # apply throttle
4218 if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
4219 &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
4220 &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
4221 &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
4222 &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
4223 &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
4224 &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
4225 &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
4226 &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
4227 &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
4228 &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
4229 &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
a1b7d579 4230
a05cff86
DM
4231 qemu_block_set_io_throttle($vmid,"drive-$opt",
4232 ($drive->{mbps} || 0)*1024*1024,
4233 ($drive->{mbps_rd} || 0)*1024*1024,
4234 ($drive->{mbps_wr} || 0)*1024*1024,
4235 $drive->{iops} || 0,
4236 $drive->{iops_rd} || 0,
4237 $drive->{iops_wr} || 0,
4238 ($drive->{mbps_max} || 0)*1024*1024,
4239 ($drive->{mbps_rd_max} || 0)*1024*1024,
4240 ($drive->{mbps_wr_max} || 0)*1024*1024,
4241 $drive->{iops_max} || 0,
4242 $drive->{iops_rd_max} || 0,
4243 $drive->{iops_wr_max} || 0);
4244
4245 }
a1b7d579 4246
a05cff86
DM
4247 return 1;
4248 }
4de1bb25
DM
4249
4250 } else { # cdrom
a1b7d579 4251
4de1bb25
DM
4252 if ($drive->{file} eq 'none') {
4253 vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
4254 } else {
4255 my $path = get_iso_path($storecfg, $vmid, $drive->{file});
4256 vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
4257 vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
4258 }
a1b7d579 4259
34758d66 4260 return 1;
a05cff86
DM
4261 }
4262 }
4263 }
4264
a1b7d579 4265 die "skip\n" if !$hotplug || $opt =~ m/(ide|sata)(\d+)/;
4de1bb25 4266 # hotplug new disks
f7b4356f 4267 PVE::Storage::activate_volumes($storecfg, [$drive->{file}]) if $drive->{file} !~ m|^/dev/.+|;
4de1bb25 4268 vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
a05cff86
DM
4269}
4270
1e3baf05 4271sub vm_start {
ba9e1000
DM
4272 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused,
4273 $forcemachine, $spice_ticket) = @_;
1e3baf05 4274
ffda963f
FG
4275 PVE::QemuConfig->lock_config($vmid, sub {
4276 my $conf = PVE::QemuConfig->load_config($vmid, $migratedfrom);
1e3baf05 4277
ffda963f 4278 die "you can't start a vm if it's a template\n" if PVE::QemuConfig->is_template($conf);
3dcb98d5 4279
ffda963f 4280 PVE::QemuConfig->check_lock($conf) if !$skiplock;
1e3baf05 4281
7e8dcf2c 4282 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 4283
055d554d 4284 if (!$statefile && scalar(keys %{$conf->{pending}})) {
3a11fadb 4285 vmconfig_apply_pending($vmid, $conf, $storecfg);
ffda963f 4286 $conf = PVE::QemuConfig->load_config($vmid); # update/reload
055d554d
DM
4287 }
4288
6c47d546
DM
4289 my $defaults = load_defaults();
4290
4291 # set environment variable useful inside network script
4292 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
4293
67812f9c 4294 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 4295
1e3baf05 4296 my $migrate_port = 0;
5bc1e039 4297 my $migrate_uri;
1e3baf05
DM
4298 if ($statefile) {
4299 if ($statefile eq 'tcp') {
5bc1e039
SP
4300 my $localip = "localhost";
4301 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
af0eba7e 4302 my $nodename = PVE::INotify::nodename();
5bc1e039 4303 if ($datacenterconf->{migration_unsecure}) {
5bc1e039 4304 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
407e0b8b 4305 $localip = "[$localip]" if Net::IP::ip_is_ipv6($localip);
5bc1e039 4306 }
af0eba7e
WB
4307 my $pfamily = PVE::Tools::get_host_address_family($nodename);
4308 $migrate_port = PVE::Tools::next_migrate_port($pfamily);
407e0b8b 4309 $migrate_uri = "tcp:${localip}:${migrate_port}";
6c47d546
DM
4310 push @$cmd, '-incoming', $migrate_uri;
4311 push @$cmd, '-S';
1c9d54bf
TL
4312
4313 } elsif ($statefile eq 'unix') {
4314 # should be default for secure migrations as a ssh TCP forward
4315 # tunnel is not deterministic reliable ready and fails regurarly
4316 # to set up in time, so use UNIX socket forwards
54323eed
TL
4317 my $socket_addr = "/run/qemu-server/$vmid.migrate";
4318 unlink $socket_addr;
4319
4320 $migrate_uri = "unix:$socket_addr";
1c9d54bf
TL
4321
4322 push @$cmd, '-incoming', $migrate_uri;
4323 push @$cmd, '-S';
4324
1e3baf05 4325 } else {
6c47d546 4326 push @$cmd, '-loadstate', $statefile;
1e3baf05 4327 }
91bd6c90
DM
4328 } elsif ($paused) {
4329 push @$cmd, '-S';
1e3baf05
DM
4330 }
4331
1e3baf05 4332 # host pci devices
040b06b7
DA
4333 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
4334 my $d = parse_hostpci($conf->{"hostpci$i"});
4335 next if !$d;
b1f72af6
AD
4336 my $pcidevices = $d->{pciid};
4337 foreach my $pcidevice (@$pcidevices) {
4338 my $pciid = $pcidevice->{id}.".".$pcidevice->{function};
000fc0a2 4339
b1f72af6
AD
4340 my $info = pci_device_info("0000:$pciid");
4341 die "IOMMU not present\n" if !check_iommu_support();
4342 die "no pci device info for device '$pciid'\n" if !$info;
6ea8cd3b 4343 die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid);
8f3e88af 4344 die "can't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info);
b1f72af6 4345 }
040b06b7 4346 }
1e3baf05
DM
4347
4348 PVE::Storage::activate_volumes($storecfg, $vollist);
4349
2b401189
AD
4350 if (!check_running($vmid, 1) && -d "/sys/fs/cgroup/systemd/qemu.slice/$vmid.scope") {
4351 my $cmd = [];
4352 push @$cmd, '/bin/systemctl', 'stop', "$vmid.scope";
4353 eval { run_command($cmd); };
4354 }
4355
8e59d952
WB
4356 my $cpuunits = defined($conf->{cpuunits}) ? $conf->{cpuunits}
4357 : $defaults->{cpuunits};
4358
7023f3ea
AD
4359 my %run_params = (timeout => $statefile ? undef : 30, umask => 0077);
4360
4361 my %properties = (
4362 Slice => 'qemu.slice',
4363 KillMode => 'none',
4364 CPUShares => $cpuunits
4365 );
4366
4367 if (my $cpulimit = $conf->{cpulimit}) {
4368 $properties{CPUQuota} = int($cpulimit * 100);
4369 }
4370 $properties{timeout} = 10 if $statefile; # setting up the scope shoul be quick
4371
4372 if ($conf->{hugepages}) {
4373
4374 my $code = sub {
4375 my $hugepages_topology = PVE::QemuServer::Memory::hugepages_topology($conf);
4376 my $hugepages_host_topology = PVE::QemuServer::Memory::hugepages_host_topology();
4377
4378 PVE::QemuServer::Memory::hugepages_mount();
4379 PVE::QemuServer::Memory::hugepages_allocate($hugepages_topology, $hugepages_host_topology);
4380
4381 eval {
4382 PVE::Tools::enter_systemd_scope($vmid, "Proxmox VE VM $vmid", %properties);
4383 run_command($cmd, %run_params);
4384 };
4385
4386 if (my $err = $@) {
4387 PVE::QemuServer::Memory::hugepages_reset($hugepages_host_topology);
4388 die $err;
4389 }
4390
4391 PVE::QemuServer::Memory::hugepages_pre_deallocate($hugepages_topology);
4392 };
4393 eval { PVE::QemuServer::Memory::hugepages_update_locked($code); };
4394
4395 } else {
4396 eval {
4397 PVE::Tools::enter_systemd_scope($vmid, "Proxmox VE VM $vmid", %properties);
4398 run_command($cmd, %run_params);
4399 };
4400 }
77cde36b
DC
4401
4402 if (my $err = $@) {
4403 # deactivate volumes if start fails
4404 eval { PVE::Storage::deactivate_volumes($storecfg, $vollist); };
4405 die "start failed: $err";
4406 }
1e3baf05 4407
5bc1e039 4408 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 4409
8c609afd 4410 if ($statefile && $statefile ne 'tcp') {
95381ce0 4411 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 4412 warn $@ if $@;
62de2cbd
DM
4413 }
4414
1d794448 4415 if ($migratedfrom) {
a89fded1
AD
4416
4417 eval {
8e90138a 4418 set_migration_caps($vmid);
a89fded1 4419 };
1d794448 4420 warn $@ if $@;
a89fded1 4421
1d794448
DM
4422 if ($spice_port) {
4423 print "spice listens on port $spice_port\n";
4424 if ($spice_ticket) {
8e90138a
DM
4425 vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
4426 vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
4427 }
4428 }
4429
1d794448 4430 } else {
4ec05c4c 4431
15b1fc93 4432 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 4433 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 4434 if $conf->{balloon};
4ec05c4c 4435 }
25088687
DM
4436
4437 foreach my $opt (keys %$conf) {
4438 next if $opt !~ m/^net\d+$/;
4439 my $nicconf = parse_net($conf->{$opt});
4440 qemu_set_link_status($vmid, $opt, 0) if $nicconf->{link_down};
4441 }
e18b0b99 4442 }
a1b7d579 4443
eb065317
AD
4444 vm_mon_cmd_nocheck($vmid, 'qom-set',
4445 path => "machine/peripheral/balloon0",
4446 property => "guest-stats-polling-interval",
4447 value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
4448
1e3baf05
DM
4449 });
4450}
4451
0eedc444
AD
4452sub vm_mon_cmd {
4453 my ($vmid, $execute, %params) = @_;
4454
26f11676
DM
4455 my $cmd = { execute => $execute, arguments => \%params };
4456 vm_qmp_command($vmid, $cmd);
0eedc444
AD
4457}
4458
4459sub vm_mon_cmd_nocheck {
4460 my ($vmid, $execute, %params) = @_;
4461
26f11676
DM
4462 my $cmd = { execute => $execute, arguments => \%params };
4463 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
4464}
4465
c971c4f2 4466sub vm_qmp_command {
c5a07de5 4467 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 4468
c971c4f2 4469 my $res;
26f11676 4470
14db5366
DM
4471 my $timeout;
4472 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
4473 $timeout = $cmd->{arguments}->{timeout};
4474 delete $cmd->{arguments}->{timeout};
4475 }
be190583 4476
c971c4f2
AD
4477 eval {
4478 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
7a6c2150
DM
4479 my $sname = qmp_socket($vmid);
4480 if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga
c5a07de5 4481 my $qmpclient = PVE::QMPClient->new();
dab36e1e 4482
14db5366 4483 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
c5a07de5 4484 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
dab36e1e
DM
4485 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
4486 if scalar(%{$cmd->{arguments}});
4487 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
4488 } else {
4489 die "unable to open monitor socket\n";
4490 }
c971c4f2 4491 };
26f11676 4492 if (my $err = $@) {
c971c4f2
AD
4493 syslog("err", "VM $vmid qmp command failed - $err");
4494 die $err;
4495 }
4496
4497 return $res;
4498}
4499
9df5cbcc
DM
4500sub vm_human_monitor_command {
4501 my ($vmid, $cmdline) = @_;
4502
4503 my $res;
4504
f5eb281a 4505 my $cmd = {
9df5cbcc
DM
4506 execute => 'human-monitor-command',
4507 arguments => { 'command-line' => $cmdline},
4508 };
4509
4510 return vm_qmp_command($vmid, $cmd);
4511}
4512
1e3baf05
DM
4513sub vm_commandline {
4514 my ($storecfg, $vmid) = @_;
4515
ffda963f 4516 my $conf = PVE::QemuConfig->load_config($vmid);
1e3baf05
DM
4517
4518 my $defaults = load_defaults();
4519
6b64503e 4520 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 4521
6b64503e 4522 return join(' ', @$cmd);
1e3baf05
DM
4523}
4524
4525sub vm_reset {
4526 my ($vmid, $skiplock) = @_;
4527
ffda963f 4528 PVE::QemuConfig->lock_config($vmid, sub {
1e3baf05 4529
ffda963f 4530 my $conf = PVE::QemuConfig->load_config($vmid);
1e3baf05 4531
ffda963f 4532 PVE::QemuConfig->check_lock($conf) if !$skiplock;
1e3baf05 4533
816e2c4a 4534 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
4535 });
4536}
4537
4538sub get_vm_volumes {
4539 my ($conf) = @_;
1e3baf05 4540
ff1a2432 4541 my $vollist = [];
d5769dc2
DM
4542 foreach_volid($conf, sub {
4543 my ($volid, $is_cdrom) = @_;
ff1a2432 4544
d5769dc2 4545 return if $volid =~ m|^/|;
ff1a2432 4546
d5769dc2
DM
4547 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
4548 return if !$sid;
ff1a2432
DM
4549
4550 push @$vollist, $volid;
1e3baf05 4551 });
ff1a2432
DM
4552
4553 return $vollist;
4554}
4555
4556sub vm_stop_cleanup {
70b04821 4557 my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
ff1a2432 4558
745fed70 4559 eval {
ff1a2432 4560
254575e9
DM
4561 if (!$keepActive) {
4562 my $vollist = get_vm_volumes($conf);
4563 PVE::Storage::deactivate_volumes($storecfg, $vollist);
4564 }
a1b7d579 4565
ab6a046f 4566 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
4567 unlink "/var/run/qemu-server/${vmid}.$ext";
4568 }
a1b7d579 4569
70b04821 4570 vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
745fed70
DM
4571 };
4572 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
4573}
4574
e6c3b671 4575# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
4576# We need that when migration VMs to other nodes (files already moved)
4577# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 4578sub vm_stop {
af30308f 4579 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 4580
9269013a 4581 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 4582
af30308f
DM
4583 if ($migratedfrom){
4584 my $pid = check_running($vmid, $nocheck, $migratedfrom);
4585 kill 15, $pid if $pid;
ffda963f 4586 my $conf = PVE::QemuConfig->load_config($vmid, $migratedfrom);
70b04821 4587 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 0);
af30308f
DM
4588 return;
4589 }
4590
ffda963f 4591 PVE::QemuConfig->lock_config($vmid, sub {
1e3baf05 4592
e6c3b671 4593 my $pid = check_running($vmid, $nocheck);
ff1a2432 4594 return if !$pid;
1e3baf05 4595
ff1a2432 4596 my $conf;
e6c3b671 4597 if (!$nocheck) {
ffda963f
FG
4598 $conf = PVE::QemuConfig->load_config($vmid);
4599 PVE::QemuConfig->check_lock($conf) if !$skiplock;
7f4a5b5a 4600 if (!defined($timeout) && $shutdown && $conf->{startup}) {
38f7f26c 4601 my $opts = PVE::JSONSchema::pve_parse_startup_order($conf->{startup});
7f4a5b5a
DM
4602 $timeout = $opts->{down} if $opts->{down};
4603 }
e6c3b671 4604 }
19672434 4605
7f4a5b5a 4606 $timeout = 60 if !defined($timeout);
67fb9de6 4607
9269013a
DM
4608 eval {
4609 if ($shutdown) {
fbda7965 4610 if (defined($conf) && $conf->{agent}) {
2ea54503 4611 vm_qmp_command($vmid, { execute => "guest-shutdown" }, $nocheck);
1c0c1c17 4612 } else {
2ea54503 4613 vm_qmp_command($vmid, { execute => "system_powerdown" }, $nocheck);
1c0c1c17 4614 }
9269013a 4615 } else {
2ea54503 4616 vm_qmp_command($vmid, { execute => "quit" }, $nocheck);
afdb31d5 4617 }
9269013a 4618 };
1e3baf05
DM
4619 my $err = $@;
4620
4621 if (!$err) {
1e3baf05 4622 my $count = 0;
e6c3b671 4623 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4624 $count++;
4625 sleep 1;
4626 }
4627
4628 if ($count >= $timeout) {
9269013a
DM
4629 if ($force) {
4630 warn "VM still running - terminating now with SIGTERM\n";
4631 kill 15, $pid;
4632 } else {
4633 die "VM quit/powerdown failed - got timeout\n";
4634 }
4635 } else {
70b04821 4636 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
9269013a 4637 return;
1e3baf05
DM
4638 }
4639 } else {
9269013a
DM
4640 if ($force) {
4641 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
4642 kill 15, $pid;
4643 } else {
afdb31d5 4644 die "VM quit/powerdown failed\n";
9269013a 4645 }
1e3baf05
DM
4646 }
4647
4648 # wait again
ff1a2432 4649 $timeout = 10;
1e3baf05
DM
4650
4651 my $count = 0;
e6c3b671 4652 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4653 $count++;
4654 sleep 1;
4655 }
4656
4657 if ($count >= $timeout) {
ff1a2432 4658 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 4659 kill 9, $pid;
ff1a2432 4660 sleep 1;
1e3baf05
DM
4661 }
4662
70b04821 4663 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
ff1a2432 4664 });
1e3baf05
DM
4665}
4666
4667sub vm_suspend {
4668 my ($vmid, $skiplock) = @_;
4669
ffda963f 4670 PVE::QemuConfig->lock_config($vmid, sub {
1e3baf05 4671
ffda963f 4672 my $conf = PVE::QemuConfig->load_config($vmid);
1e3baf05 4673
e79706d4
FG
4674 PVE::QemuConfig->check_lock($conf)
4675 if !($skiplock || PVE::QemuConfig->has_lock($conf, 'backup'));
bcb7c9cf 4676
f77f91f3 4677 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
4678 });
4679}
4680
4681sub vm_resume {
289e0b85 4682 my ($vmid, $skiplock, $nocheck) = @_;
1e3baf05 4683
ffda963f 4684 PVE::QemuConfig->lock_config($vmid, sub {
1e3baf05 4685
289e0b85 4686 if (!$nocheck) {
1e3baf05 4687
ffda963f 4688 my $conf = PVE::QemuConfig->load_config($vmid);
1e3baf05 4689
e79706d4
FG
4690 PVE::QemuConfig->check_lock($conf)
4691 if !($skiplock || PVE::QemuConfig->has_lock($conf, 'backup'));
289e0b85
AD
4692
4693 vm_mon_cmd($vmid, "cont");
4694
4695 } else {
4696 vm_mon_cmd_nocheck($vmid, "cont");
4697 }
1e3baf05
DM
4698 });
4699}
4700
5fdbe4f0
DM
4701sub vm_sendkey {
4702 my ($vmid, $skiplock, $key) = @_;
1e3baf05 4703
ffda963f 4704 PVE::QemuConfig->lock_config($vmid, sub {
1e3baf05 4705
ffda963f 4706 my $conf = PVE::QemuConfig->load_config($vmid);
f5eb281a 4707
7b7c6d1b
DM
4708 # there is no qmp command, so we use the human monitor command
4709 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
4710 });
4711}
4712
4713sub vm_destroy {
4714 my ($storecfg, $vmid, $skiplock) = @_;
4715
ffda963f 4716 PVE::QemuConfig->lock_config($vmid, sub {
1e3baf05 4717
ffda963f 4718 my $conf = PVE::QemuConfig->load_config($vmid);
1e3baf05 4719
ff1a2432 4720 if (!check_running($vmid)) {
15cc8784 4721 destroy_vm($storecfg, $vmid, undef, $skiplock);
ff1a2432
DM
4722 } else {
4723 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
4724 }
4725 });
4726}
4727
1e3baf05
DM
4728# pci helpers
4729
4730sub file_write {
4731 my ($filename, $buf) = @_;
4732
6b64503e 4733 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
4734 return undef if !$fh;
4735
4736 my $res = print $fh $buf;
4737
4738 $fh->close();
4739
4740 return $res;
4741}
4742
4743sub pci_device_info {
4744 my ($name) = @_;
4745
4746 my $res;
4747
4748 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
4749 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
4750
4751 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
4752 return undef if !defined($irq) || $irq !~ m/^\d+$/;
4753
4754 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
4755 return undef if !defined($vendor) || $vendor !~ s/^0x//;
4756
4757 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
4758 return undef if !defined($product) || $product !~ s/^0x//;
4759
4760 $res = {
4761 name => $name,
4762 vendor => $vendor,
4763 product => $product,
4764 domain => $domain,
4765 bus => $bus,
4766 slot => $slot,
4767 func => $func,
4768 irq => $irq,
4769 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
4770 };
4771
4772 return $res;
4773}
4774
4775sub pci_dev_reset {
4776 my ($dev) = @_;
4777
4778 my $name = $dev->{name};
4779
4780 my $fn = "$pcisysfs/devices/$name/reset";
4781
6b64503e 4782 return file_write($fn, "1");
1e3baf05
DM
4783}
4784
000fc0a2
SP
4785sub pci_dev_bind_to_vfio {
4786 my ($dev) = @_;
4787
4788 my $name = $dev->{name};
4789
4790 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4791
4792 if (!-d $vfio_basedir) {
4793 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4794 }
4795 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4796
4797 my $testdir = "$vfio_basedir/$name";
4798 return 1 if -d $testdir;
4799
4800 my $data = "$dev->{vendor} $dev->{product}";
4801 return undef if !file_write("$vfio_basedir/new_id", $data);
4802
4803 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4804 if (!file_write($fn, $name)) {
4805 return undef if -f $fn;
4806 }
4807
4808 $fn = "$vfio_basedir/bind";
4809 if (! -d $testdir) {
4810 return undef if !file_write($fn, $name);
4811 }
4812
4813 return -d $testdir;
4814}
4815
4816sub pci_dev_group_bind_to_vfio {
4817 my ($pciid) = @_;
4818
4819 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4820
4821 if (!-d $vfio_basedir) {
4822 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4823 }
4824 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4825
4826 # get IOMMU group devices
4827 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
4828 my @devs = grep /^0000:/, readdir($D);
4829 closedir($D);
4830
4831 foreach my $pciid (@devs) {
4832 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
f8fa2ed7
SP
4833
4834 # pci bridges, switches or root ports are not supported
4835 # they have a pci_bus subdirectory so skip them
4836 next if (-e "$pcisysfs/devices/$pciid/pci_bus");
4837
000fc0a2
SP
4838 my $info = pci_device_info($1);
4839 pci_dev_bind_to_vfio($info) || die "Cannot bind $pciid to vfio\n";
4840 }
4841
4842 return 1;
4843}
4844
3e16d5fc
DM
4845# vzdump restore implementaion
4846
ed221350 4847sub tar_archive_read_firstfile {
3e16d5fc 4848 my $archive = shift;
afdb31d5 4849
3e16d5fc
DM
4850 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
4851
4852 # try to detect archive type first
387ba257 4853 my $pid = open (my $fh, '-|', 'tar', 'tf', $archive) ||
3e16d5fc 4854 die "unable to open file '$archive'\n";
387ba257 4855 my $firstfile = <$fh>;
3e16d5fc 4856 kill 15, $pid;
387ba257 4857 close $fh;
3e16d5fc
DM
4858
4859 die "ERROR: archive contaions no data\n" if !$firstfile;
4860 chomp $firstfile;
4861
4862 return $firstfile;
4863}
4864
ed221350
DM
4865sub tar_restore_cleanup {
4866 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
4867
4868 print STDERR "starting cleanup\n";
4869
4870 if (my $fd = IO::File->new($statfile, "r")) {
4871 while (defined(my $line = <$fd>)) {
4872 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4873 my $volid = $2;
4874 eval {
4875 if ($volid =~ m|^/|) {
4876 unlink $volid || die 'unlink failed\n';
4877 } else {
ed221350 4878 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 4879 }
afdb31d5 4880 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
4881 };
4882 print STDERR "unable to cleanup '$volid' - $@" if $@;
4883 } else {
4884 print STDERR "unable to parse line in statfile - $line";
afdb31d5 4885 }
3e16d5fc
DM
4886 }
4887 $fd->close();
4888 }
4889}
4890
4891sub restore_archive {
a0d1b1a2 4892 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 4893
91bd6c90
DM
4894 my $format = $opts->{format};
4895 my $comp;
4896
4897 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
4898 $format = 'tar' if !$format;
4899 $comp = 'gzip';
4900 } elsif ($archive =~ m/\.tar$/) {
4901 $format = 'tar' if !$format;
4902 } elsif ($archive =~ m/.tar.lzo$/) {
4903 $format = 'tar' if !$format;
4904 $comp = 'lzop';
4905 } elsif ($archive =~ m/\.vma$/) {
4906 $format = 'vma' if !$format;
4907 } elsif ($archive =~ m/\.vma\.gz$/) {
4908 $format = 'vma' if !$format;
4909 $comp = 'gzip';
4910 } elsif ($archive =~ m/\.vma\.lzo$/) {
4911 $format = 'vma' if !$format;
4912 $comp = 'lzop';
4913 } else {
4914 $format = 'vma' if !$format; # default
4915 }
4916
4917 # try to detect archive format
4918 if ($format eq 'tar') {
4919 return restore_tar_archive($archive, $vmid, $user, $opts);
4920 } else {
4921 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
4922 }
4923}
4924
4925sub restore_update_config_line {
4926 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
4927
4928 return if $line =~ m/^\#qmdump\#/;
4929 return if $line =~ m/^\#vzdump\#/;
4930 return if $line =~ m/^lock:/;
4931 return if $line =~ m/^unused\d+:/;
4932 return if $line =~ m/^parent:/;
ca3e4fa4 4933 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
4934
4935 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
4936 # try to convert old 1.X settings
4937 my ($id, $ind, $ethcfg) = ($1, $2, $3);
4938 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
4939 my ($model, $macaddr) = split(/\=/, $devconfig);
4940 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
4941 my $net = {
4942 model => $model,
4943 bridge => "vmbr$ind",
4944 macaddr => $macaddr,
4945 };
4946 my $netstr = print_net($net);
4947
4948 print $outfd "net$cookie->{netcount}: $netstr\n";
4949 $cookie->{netcount}++;
4950 }
4951 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
4952 my ($id, $netstr) = ($1, $2);
4953 my $net = parse_net($netstr);
4954 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
4955 $netstr = print_net($net);
4956 print $outfd "$id: $netstr\n";
4957 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
4958 my $virtdev = $1;
907ea891 4959 my $value = $3;
d9faf790
WB
4960 my $di = parse_drive($virtdev, $value);
4961 if (defined($di->{backup}) && !$di->{backup}) {
91bd6c90 4962 print $outfd "#$line";
c0f7406e 4963 } elsif ($map->{$virtdev}) {
8fd57431 4964 delete $di->{format}; # format can change on restore
91bd6c90 4965 $di->{file} = $map->{$virtdev};
ed221350 4966 $value = print_drive($vmid, $di);
91bd6c90
DM
4967 print $outfd "$virtdev: $value\n";
4968 } else {
4969 print $outfd $line;
4970 }
4971 } else {
4972 print $outfd $line;
4973 }
4974}
4975
4976sub scan_volids {
4977 my ($cfg, $vmid) = @_;
4978
4979 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
4980
4981 my $volid_hash = {};
4982 foreach my $storeid (keys %$info) {
4983 foreach my $item (@{$info->{$storeid}}) {
4984 next if !($item->{volid} && $item->{size});
5996a936 4985 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
4986 $volid_hash->{$item->{volid}} = $item;
4987 }
4988 }
4989
4990 return $volid_hash;
4991}
4992
77019edf
WB
4993sub is_volume_in_use {
4994 my ($storecfg, $conf, $skip_drive, $volid) = @_;
a8e2f942 4995
77019edf 4996 my $path = PVE::Storage::path($storecfg, $volid);
a8e2f942
DM
4997
4998 my $scan_config = sub {
4999 my ($cref, $snapname) = @_;
5000
5001 foreach my $key (keys %$cref) {
5002 my $value = $cref->{$key};
74479ee9 5003 if (is_valid_drivename($key)) {
a8e2f942
DM
5004 next if $skip_drive && $key eq $skip_drive;
5005 my $drive = parse_drive($key, $value);
5006 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
77019edf 5007 return 1 if $volid eq $drive->{file};
a8e2f942 5008 if ($drive->{file} =~ m!^/!) {
77019edf 5009 return 1 if $drive->{file} eq $path;
a8e2f942
DM
5010 } else {
5011 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
5012 next if !$storeid;
5013 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
5014 next if !$scfg;
77019edf 5015 return 1 if $path eq PVE::Storage::path($storecfg, $drive->{file}, $snapname);
a8e2f942
DM
5016 }
5017 }
5018 }
77019edf
WB
5019
5020 return 0;
a8e2f942
DM
5021 };
5022
77019edf 5023 return 1 if &$scan_config($conf);
a8e2f942
DM
5024
5025 undef $skip_drive;
5026
77019edf
WB
5027 foreach my $snapname (keys %{$conf->{snapshots}}) {
5028 return 1 if &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
a8e2f942
DM
5029 }
5030
77019edf 5031 return 0;
a8e2f942
DM
5032}
5033
91bd6c90
DM
5034sub update_disksize {
5035 my ($vmid, $conf, $volid_hash) = @_;
be190583 5036
91bd6c90
DM
5037 my $changes;
5038
5039 my $used = {};
5040
5996a936
DM
5041 # Note: it is allowed to define multiple storages with same path (alias), so
5042 # we need to check both 'volid' and real 'path' (two different volid can point
5043 # to the same path).
5044
5045 my $usedpath = {};
be190583 5046
91bd6c90
DM
5047 # update size info
5048 foreach my $opt (keys %$conf) {
74479ee9 5049 if (is_valid_drivename($opt)) {
ed221350 5050 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
5051 my $volid = $drive->{file};
5052 next if !$volid;
5053
5054 $used->{$volid} = 1;
be190583 5055 if ($volid_hash->{$volid} &&
5996a936
DM
5056 (my $path = $volid_hash->{$volid}->{path})) {
5057 $usedpath->{$path} = 1;
5058 }
91bd6c90 5059
ed221350 5060 next if drive_is_cdrom($drive);
91bd6c90
DM
5061 next if !$volid_hash->{$volid};
5062
5063 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
5064 my $new = print_drive($vmid, $drive);
5065 if ($new ne $conf->{$opt}) {
5066 $changes = 1;
5067 $conf->{$opt} = $new;
5068 }
91bd6c90
DM
5069 }
5070 }
5071
5996a936
DM
5072 # remove 'unusedX' entry if volume is used
5073 foreach my $opt (keys %$conf) {
5074 next if $opt !~ m/^unused\d+$/;
5075 my $volid = $conf->{$opt};
5076 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 5077 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
5078 $changes = 1;
5079 delete $conf->{$opt};
5080 }
5081 }
5082
91bd6c90
DM
5083 foreach my $volid (sort keys %$volid_hash) {
5084 next if $volid =~ m/vm-$vmid-state-/;
5085 next if $used->{$volid};
5996a936
DM
5086 my $path = $volid_hash->{$volid}->{path};
5087 next if !$path; # just to be sure
5088 next if $usedpath->{$path};
91bd6c90 5089 $changes = 1;
8793d495 5090 PVE::QemuConfig->add_unused_volume($conf, $volid);
05937a14 5091 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
5092 }
5093
5094 return $changes;
5095}
5096
5097sub rescan {
5098 my ($vmid, $nolock) = @_;
5099
20519efc 5100 my $cfg = PVE::Storage::config();
91bd6c90
DM
5101
5102 my $volid_hash = scan_volids($cfg, $vmid);
5103
5104 my $updatefn = sub {
5105 my ($vmid) = @_;
5106
ffda963f 5107 my $conf = PVE::QemuConfig->load_config($vmid);
be190583 5108
ffda963f 5109 PVE::QemuConfig->check_lock($conf);
91bd6c90 5110
03da3f0d
DM
5111 my $vm_volids = {};
5112 foreach my $volid (keys %$volid_hash) {
5113 my $info = $volid_hash->{$volid};
5114 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
5115 }
5116
5117 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 5118
ffda963f 5119 PVE::QemuConfig->write_config($vmid, $conf) if $changes;
91bd6c90
DM
5120 };
5121
5122 if (defined($vmid)) {
5123 if ($nolock) {
5124 &$updatefn($vmid);
5125 } else {
ffda963f 5126 PVE::QemuConfig->lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
5127 }
5128 } else {
5129 my $vmlist = config_list();
5130 foreach my $vmid (keys %$vmlist) {
5131 if ($nolock) {
5132 &$updatefn($vmid);
5133 } else {
ffda963f 5134 PVE::QemuConfig->lock_config($vmid, $updatefn, $vmid);
be190583 5135 }
91bd6c90
DM
5136 }
5137 }
5138}
5139
5140sub restore_vma_archive {
5141 my ($archive, $vmid, $user, $opts, $comp) = @_;
5142
5143 my $input = $archive eq '-' ? "<&STDIN" : undef;
5144 my $readfrom = $archive;
5145
5146 my $uncomp = '';
5147 if ($comp) {
5148 $readfrom = '-';
5149 my $qarchive = PVE::Tools::shellquote($archive);
5150 if ($comp eq 'gzip') {
5151 $uncomp = "zcat $qarchive|";
5152 } elsif ($comp eq 'lzop') {
5153 $uncomp = "lzop -d -c $qarchive|";
5154 } else {
5155 die "unknown compression method '$comp'\n";
5156 }
be190583 5157
91bd6c90
DM
5158 }
5159
5160 my $tmpdir = "/var/tmp/vzdumptmp$$";
5161 rmtree $tmpdir;
5162
5163 # disable interrupts (always do cleanups)
5164 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5165 warn "got interrupt - ignored\n";
5166 };
5167
5168 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
5169 POSIX::mkfifo($mapfifo, 0600);
5170 my $fifofh;
5171
5172 my $openfifo = sub {
5173 open($fifofh, '>', $mapfifo) || die $!;
5174 };
5175
5176 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
5177
5178 my $oldtimeout;
5179 my $timeout = 5;
5180
5181 my $devinfo = {};
5182
5183 my $rpcenv = PVE::RPCEnvironment::get();
5184
ffda963f 5185 my $conffile = PVE::QemuConfig->config_file($vmid);
91bd6c90
DM
5186 my $tmpfn = "$conffile.$$.tmp";
5187
ed221350 5188 # Note: $oldconf is undef if VM does not exists
ffda963f
FG
5189 my $cfs_path = PVE::QemuConfig->cfs_config_path($vmid);
5190 my $oldconf = PVE::Cluster::cfs_read_file($cfs_path);
ed221350 5191
91bd6c90
DM
5192 my $print_devmap = sub {
5193 my $virtdev_hash = {};
5194
5195 my $cfgfn = "$tmpdir/qemu-server.conf";
5196
5197 # we can read the config - that is already extracted
5198 my $fh = IO::File->new($cfgfn, "r") ||
5199 "unable to read qemu-server.conf - $!\n";
5200
6738ab9c 5201 my $fwcfgfn = "$tmpdir/qemu-server.fw";
3457d090
WL
5202 if (-f $fwcfgfn) {
5203 my $pve_firewall_dir = '/etc/pve/firewall';
5204 mkdir $pve_firewall_dir; # make sure the dir exists
5205 PVE::Tools::file_copy($fwcfgfn, "${pve_firewall_dir}/$vmid.fw");
5206 }
6738ab9c 5207
91bd6c90
DM
5208 while (defined(my $line = <$fh>)) {
5209 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
5210 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
5211 die "archive does not contain data for drive '$virtdev'\n"
5212 if !$devinfo->{$devname};
5213 if (defined($opts->{storage})) {
5214 $storeid = $opts->{storage} || 'local';
5215 } elsif (!$storeid) {
5216 $storeid = 'local';
5217 }
5218 $format = 'raw' if !$format;
5219 $devinfo->{$devname}->{devname} = $devname;
5220 $devinfo->{$devname}->{virtdev} = $virtdev;
5221 $devinfo->{$devname}->{format} = $format;
5222 $devinfo->{$devname}->{storeid} = $storeid;
5223
be190583 5224 # check permission on storage
91bd6c90
DM
5225 my $pool = $opts->{pool}; # todo: do we need that?
5226 if ($user ne 'root@pam') {
5227 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
5228 }
5229
5230 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
5231 }
5232 }
5233
5234 foreach my $devname (keys %$devinfo) {
be190583
DM
5235 die "found no device mapping information for device '$devname'\n"
5236 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
5237 }
5238
20519efc 5239 my $cfg = PVE::Storage::config();
ed221350
DM
5240
5241 # create empty/temp config
be190583 5242 if ($oldconf) {
ed221350
DM
5243 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
5244 foreach_drive($oldconf, sub {
5245 my ($ds, $drive) = @_;
5246
5247 return if drive_is_cdrom($drive);
5248
5249 my $volid = $drive->{file};
5250
5251 return if !$volid || $volid =~ m|^/|;
5252
5253 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
5254 return if !$path || !$owner || ($owner != $vmid);
5255
5256 # Note: only delete disk we want to restore
5257 # other volumes will become unused
5258 if ($virtdev_hash->{$ds}) {
5259 PVE::Storage::vdisk_free($cfg, $volid);
5260 }
5261 });
381b8fae
DC
5262
5263 # delete vmstate files
5264 # since after the restore we have no snapshots anymore
5265 foreach my $snapname (keys %{$oldconf->{snapshots}}) {
5266 my $snap = $oldconf->{snapshots}->{$snapname};
5267 if ($snap->{vmstate}) {
5268 eval { PVE::Storage::vdisk_free($cfg, $snap->{vmstate}); };
5269 if (my $err = $@) {
5270 warn $err;
5271 }
5272 }
5273 }
ed221350
DM
5274 }
5275
5276 my $map = {};
91bd6c90
DM
5277 foreach my $virtdev (sort keys %$virtdev_hash) {
5278 my $d = $virtdev_hash->{$virtdev};
5279 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
5280 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
5281
5282 # test if requested format is supported
5283 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
5284 my $supported = grep { $_ eq $d->{format} } @$validFormats;
5285 $d->{format} = $defFormat if !$supported;
5286
91bd6c90
DM
5287 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
5288 $d->{format}, undef, $alloc_size);
5289 print STDERR "new volume ID is '$volid'\n";
5290 $d->{volid} = $volid;
5291 my $path = PVE::Storage::path($cfg, $volid);
5292
5f96f4df
WL
5293 PVE::Storage::activate_volumes($cfg,[$volid]);
5294
91bd6c90 5295 my $write_zeros = 1;
88240a83 5296 if (PVE::Storage::volume_has_feature($cfg, 'sparseinit', $volid)) {
91bd6c90
DM
5297 $write_zeros = 0;
5298 }
5299
3c525055 5300 print $fifofh "format=$d->{format}:${write_zeros}:$d->{devname}=$path\n";
91bd6c90
DM
5301
5302 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
5303 $map->{$virtdev} = $volid;
5304 }
5305
5306 $fh->seek(0, 0) || die "seek failed - $!\n";
5307
5308 my $outfd = new IO::File ($tmpfn, "w") ||
5309 die "unable to write config for VM $vmid\n";
5310
5311 my $cookie = { netcount => 0 };
5312 while (defined(my $line = <$fh>)) {
be190583 5313 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
5314 }
5315
5316 $fh->close();
5317 $outfd->close();
5318 };
5319
5320 eval {
5321 # enable interrupts
5322 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5323 die "interrupted by signal\n";
5324 };
5325 local $SIG{ALRM} = sub { die "got timeout\n"; };
5326
5327 $oldtimeout = alarm($timeout);
5328
5329 my $parser = sub {
5330 my $line = shift;
5331
5332 print "$line\n";
5333
5334 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
5335 my ($dev_id, $size, $devname) = ($1, $2, $3);
5336 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
5337 } elsif ($line =~ m/^CTIME: /) {
46f58b5f 5338 # we correctly received the vma config, so we can disable
3cf90d7a
DM
5339 # the timeout now for disk allocation (set to 10 minutes, so
5340 # that we always timeout if something goes wrong)
5341 alarm(600);
91bd6c90
DM
5342 &$print_devmap();
5343 print $fifofh "done\n";
5344 my $tmp = $oldtimeout || 0;
5345 $oldtimeout = undef;
5346 alarm($tmp);
5347 close($fifofh);
5348 }
5349 };
be190583 5350
91bd6c90
DM
5351 print "restore vma archive: $cmd\n";
5352 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
5353 };
5354 my $err = $@;
5355
5356 alarm($oldtimeout) if $oldtimeout;
5357
5f96f4df
WL
5358 my $vollist = [];
5359 foreach my $devname (keys %$devinfo) {
5360 my $volid = $devinfo->{$devname}->{volid};
5361 push @$vollist, $volid if $volid;
5362 }
5363
20519efc 5364 my $cfg = PVE::Storage::config();
5f96f4df
WL
5365 PVE::Storage::deactivate_volumes($cfg, $vollist);
5366
91bd6c90
DM
5367 unlink $mapfifo;
5368
5369 if ($err) {
5370 rmtree $tmpdir;
5371 unlink $tmpfn;
5372
91bd6c90
DM
5373 foreach my $devname (keys %$devinfo) {
5374 my $volid = $devinfo->{$devname}->{volid};
5375 next if !$volid;
5376 eval {
5377 if ($volid =~ m|^/|) {
5378 unlink $volid || die 'unlink failed\n';
5379 } else {
5380 PVE::Storage::vdisk_free($cfg, $volid);
5381 }
5382 print STDERR "temporary volume '$volid' sucessfuly removed\n";
5383 };
5384 print STDERR "unable to cleanup '$volid' - $@" if $@;
5385 }
5386 die $err;
5387 }
5388
5389 rmtree $tmpdir;
ed221350
DM
5390
5391 rename($tmpfn, $conffile) ||
91bd6c90
DM
5392 die "unable to commit configuration file '$conffile'\n";
5393
ed221350
DM
5394 PVE::Cluster::cfs_update(); # make sure we read new file
5395
91bd6c90
DM
5396 eval { rescan($vmid, 1); };
5397 warn $@ if $@;
5398}
5399
5400sub restore_tar_archive {
5401 my ($archive, $vmid, $user, $opts) = @_;
5402
9c502e26 5403 if ($archive ne '-') {
ed221350 5404 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
5405 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
5406 if $firstfile ne 'qemu-server.conf';
5407 }
3e16d5fc 5408
20519efc 5409 my $storecfg = PVE::Storage::config();
ebb55558 5410
ed221350 5411 # destroy existing data - keep empty config
ffda963f 5412 my $vmcfgfn = PVE::QemuConfig->config_file($vmid);
ebb55558 5413 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 5414
3e16d5fc
DM
5415 my $tocmd = "/usr/lib/qemu-server/qmextract";
5416
2415a446 5417 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 5418 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
5419 $tocmd .= ' --prealloc' if $opts->{prealloc};
5420 $tocmd .= ' --info' if $opts->{info};
5421
a0d1b1a2 5422 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 5423 # so we pipe to zcat
2415a446
DM
5424 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
5425 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
5426
5427 my $tmpdir = "/var/tmp/vzdumptmp$$";
5428 mkpath $tmpdir;
5429
5430 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
5431 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 5432 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 5433
ffda963f 5434 my $conffile = PVE::QemuConfig->config_file($vmid);
3e16d5fc
DM
5435 my $tmpfn = "$conffile.$$.tmp";
5436
5437 # disable interrupts (always do cleanups)
5438 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5439 print STDERR "got interrupt - ignored\n";
5440 };
5441
afdb31d5 5442 eval {
3e16d5fc
DM
5443 # enable interrupts
5444 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5445 die "interrupted by signal\n";
5446 };
5447
9c502e26
DM
5448 if ($archive eq '-') {
5449 print "extracting archive from STDIN\n";
5450 run_command($cmd, input => "<&STDIN");
5451 } else {
5452 print "extracting archive '$archive'\n";
5453 run_command($cmd);
5454 }
3e16d5fc
DM
5455
5456 return if $opts->{info};
5457
5458 # read new mapping
5459 my $map = {};
5460 my $statfile = "$tmpdir/qmrestore.stat";
5461 if (my $fd = IO::File->new($statfile, "r")) {
5462 while (defined (my $line = <$fd>)) {
5463 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
5464 $map->{$1} = $2 if $1;
5465 } else {
5466 print STDERR "unable to parse line in statfile - $line\n";
5467 }
5468 }
5469 $fd->close();
5470 }
5471
5472 my $confsrc = "$tmpdir/qemu-server.conf";
5473
5474 my $srcfd = new IO::File($confsrc, "r") ||
5475 die "unable to open file '$confsrc'\n";
5476
5477 my $outfd = new IO::File ($tmpfn, "w") ||
5478 die "unable to write config for VM $vmid\n";
5479
91bd6c90 5480 my $cookie = { netcount => 0 };
3e16d5fc 5481 while (defined (my $line = <$srcfd>)) {
be190583 5482 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
5483 }
5484
5485 $srcfd->close();
5486 $outfd->close();
5487 };
5488 my $err = $@;
5489
afdb31d5 5490 if ($err) {
3e16d5fc
DM
5491
5492 unlink $tmpfn;
5493
ed221350 5494 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 5495
3e16d5fc 5496 die $err;
afdb31d5 5497 }
3e16d5fc
DM
5498
5499 rmtree $tmpdir;
5500
5501 rename $tmpfn, $conffile ||
5502 die "unable to commit configuration file '$conffile'\n";
91bd6c90 5503
ed221350
DM
5504 PVE::Cluster::cfs_update(); # make sure we read new file
5505
91bd6c90
DM
5506 eval { rescan($vmid, 1); };
5507 warn $@ if $@;
3e16d5fc
DM
5508};
5509
18bfb361
DM
5510sub foreach_writable_storage {
5511 my ($conf, $func) = @_;
5512
5513 my $sidhash = {};
5514
5515 foreach my $ds (keys %$conf) {
74479ee9 5516 next if !is_valid_drivename($ds);
18bfb361
DM
5517
5518 my $drive = parse_drive($ds, $conf->{$ds});
5519 next if !$drive;
5520 next if drive_is_cdrom($drive);
5521
5522 my $volid = $drive->{file};
5523
5524 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 5525 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
5526 }
5527
5528 foreach my $sid (sort keys %$sidhash) {
5529 &$func($sid);
5530 }
5531}
5532
e5eaa028
WL
5533sub do_snapshots_with_qemu {
5534 my ($storecfg, $volid) = @_;
5535
5536 my $storage_name = PVE::Storage::parse_volume_id($volid);
5537
116da784
WL
5538 if ($qemu_snap_storage->{$storecfg->{ids}->{$storage_name}->{type}}
5539 && !$storecfg->{ids}->{$storage_name}->{krbd}){
e5eaa028
WL
5540 return 1;
5541 }
5542
5543 if ($volid =~ m/\.(qcow2|qed)$/){
5544 return 1;
5545 }
5546
5547 return undef;
5548}
5549
4dcc780c
WL
5550sub qga_check_running {
5551 my ($vmid) = @_;
5552
5553 eval { vm_mon_cmd($vmid, "guest-ping", timeout => 3); };
5554 if ($@) {
5555 warn "Qemu Guest Agent are not running - $@";
5556 return 0;
5557 }
5558 return 1;
5559}
5560
04a69bb4
AD
5561sub template_create {
5562 my ($vmid, $conf, $disk) = @_;
5563
04a69bb4 5564 my $storecfg = PVE::Storage::config();
04a69bb4 5565
9cd07842
DM
5566 foreach_drive($conf, sub {
5567 my ($ds, $drive) = @_;
5568
5569 return if drive_is_cdrom($drive);
5570 return if $disk && $ds ne $disk;
5571
5572 my $volid = $drive->{file};
bbd56097 5573 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 5574
04a69bb4
AD
5575 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
5576 $drive->{file} = $voliddst;
152fe752 5577 $conf->{$ds} = print_drive($vmid, $drive);
ffda963f 5578 PVE::QemuConfig->write_config($vmid, $conf);
04a69bb4 5579 });
04a69bb4
AD
5580}
5581
5133de42 5582sub qemu_img_convert {
988e2714 5583 my ($src_volid, $dst_volid, $size, $snapname, $is_zero_initialized) = @_;
5133de42
AD
5584
5585 my $storecfg = PVE::Storage::config();
5586 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
5587 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
5588
5589 if ($src_storeid && $dst_storeid) {
6bb91c17
DM
5590
5591 PVE::Storage::activate_volumes($storecfg, [$src_volid], $snapname);
5592
5133de42
AD
5593 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
5594 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
5595
5596 my $src_format = qemu_img_format($src_scfg, $src_volname);
5597 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
5598
5599 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
5600 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
5601
5602 my $cmd = [];
71ddbff9 5603 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5133de42 5604 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
988e2714
WB
5605 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path;
5606 if ($is_zero_initialized) {
5607 push @$cmd, "zeroinit:$dst_path";
5608 } else {
5609 push @$cmd, $dst_path;
5610 }
5133de42
AD
5611
5612 my $parser = sub {
5613 my $line = shift;
5614 if($line =~ m/\((\S+)\/100\%\)/){
5615 my $percent = $1;
5616 my $transferred = int($size * $percent / 100);
5617 my $remaining = $size - $transferred;
5618
5619 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
5620 }
5621
5622 };
5623
5624 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
5625 my $err = $@;
5626 die "copy failed: $err" if $err;
5627 }
5628}
5629
5630sub qemu_img_format {
5631 my ($scfg, $volname) = @_;
5632
d81f0f09 5633 if ($scfg->{path} && $volname =~ m/\.(raw|cow|qcow|qcow2|qed|vmdk|cloop)$/) {
5133de42 5634 return $1;
be190583 5635 } else {
5133de42 5636 return "raw";
5133de42
AD
5637 }
5638}
5639
cfad42af 5640sub qemu_drive_mirror {
988e2714 5641 my ($vmid, $drive, $dst_volid, $vmiddst, $is_zero_initialized) = @_;
cfad42af 5642
cfad42af 5643 my $storecfg = PVE::Storage::config();
08ac653f 5644 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid);
152fe752 5645
08ac653f 5646 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
cfad42af 5647
d81f0f09 5648 my $format = qemu_img_format($dst_scfg, $dst_volname);
21ccdb50 5649
08ac653f 5650 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
21ccdb50 5651
988e2714
WB
5652 my $qemu_target = $is_zero_initialized ? "zeroinit:$dst_path" : $dst_path;
5653
5654 my $opts = { timeout => 10, device => "drive-$drive", mode => "existing", sync => "full", target => $qemu_target };
88383920
DM
5655 $opts->{format} = $format if $format;
5656
22967505 5657 print "drive mirror is starting (scanning bitmap) : this step can take some minutes/hours, depend of disk size and storage speed\n";
21ccdb50 5658
2e953867
WB
5659 my $finish_job = sub {
5660 while (1) {
5661 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
5662 my $stat = @$stats[0];
5663 last if !$stat;
5664 sleep 1;
5665 }
5666 };
5667
08ac653f 5668 eval {
22967505 5669 vm_mon_cmd($vmid, "drive-mirror", %$opts);
08ac653f
DM
5670 while (1) {
5671 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
5672 my $stat = @$stats[0];
5673 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
5674 die "error job is not mirroring" if $stat->{type} ne "mirror";
5675
08ac653f 5676 my $busy = $stat->{busy};
ad123d97 5677 my $ready = $stat->{ready};
08ac653f 5678
6f708643
DM
5679 if (my $total = $stat->{len}) {
5680 my $transferred = $stat->{offset} || 0;
5681 my $remaining = $total - $transferred;
5682 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
67fb9de6 5683
ad123d97 5684 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy ready: $ready \n";
6f708643 5685 }
f34ebd52 5686
08ac653f 5687
ad123d97 5688 if ($stat->{ready} eq 'true') {
f34ebd52 5689
ad123d97 5690 last if $vmiddst != $vmid;
b467f79a 5691
ad123d97
AD
5692 # try to switch the disk if source and destination are on the same guest
5693 eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") };
2e953867
WB
5694 if (!$@) {
5695 &$finish_job();
5696 last;
5697 }
ad123d97 5698 die $@ if $@ !~ m/cannot be completed/;
08ac653f 5699 }
08ac653f 5700 sleep 1;
cfad42af
AD
5701 }
5702
08ac653f
DM
5703
5704 };
88383920 5705 my $err = $@;
08ac653f 5706
88383920 5707 my $cancel_job = sub {
08ac653f 5708 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
2e953867 5709 &$finish_job();
88383920
DM
5710 };
5711
5712 if ($err) {
f34ebd52 5713 eval { &$cancel_job(); };
88383920
DM
5714 die "mirroring error: $err";
5715 }
5716
5717 if ($vmiddst != $vmid) {
5718 # if we clone a disk for a new target vm, we don't switch the disk
5719 &$cancel_job(); # so we call block-job-cancel
cfad42af
AD
5720 }
5721}
5722
152fe752 5723sub clone_disk {
be190583 5724 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
5725 $newvmid, $storage, $format, $full, $newvollist) = @_;
5726
5727 my $newvolid;
5728
5729 if (!$full) {
5730 print "create linked clone of drive $drivename ($drive->{file})\n";
258e646c 5731 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid, $snapname);
152fe752
DM
5732 push @$newvollist, $newvolid;
5733 } else {
5734 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
5735 $storeid = $storage if $storage;
5736
1377d7b0
DM
5737 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
5738 if (!$format) {
d81f0f09
DM
5739 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
5740 $format = qemu_img_format($scfg, $volname);
152fe752
DM
5741 }
5742
1377d7b0
DM
5743 # test if requested format is supported - else use default
5744 my $supported = grep { $_ eq $format } @$validFormats;
5745 $format = $defFormat if !$supported;
5746
152fe752
DM
5747 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
5748
5749 print "create full clone of drive $drivename ($drive->{file})\n";
5750 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
5751 push @$newvollist, $newvolid;
5752
1dbd6d30
WL
5753 PVE::Storage::activate_volumes($storecfg, $newvollist);
5754
988e2714 5755 my $sparseinit = PVE::Storage::volume_has_feature($storecfg, 'sparseinit', $newvolid);
152fe752 5756 if (!$running || $snapname) {
988e2714 5757 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname, $sparseinit);
152fe752 5758 } else {
988e2714 5759 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid, $sparseinit);
be190583 5760 }
152fe752
DM
5761 }
5762
5763 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
5764
5765 my $disk = $drive;
5766 $disk->{format} = undef;
5767 $disk->{file} = $newvolid;
5768 $disk->{size} = $size;
5769
5770 return $disk;
5771}
5772
ff556cf2
DM
5773# this only works if VM is running
5774sub get_current_qemu_machine {
5775 my ($vmid) = @_;
5776
5777 my $cmd = { execute => 'query-machines', arguments => {} };
8e90138a 5778 my $res = vm_qmp_command($vmid, $cmd);
ff556cf2
DM
5779
5780 my ($current, $default);
5781 foreach my $e (@$res) {
5782 $default = $e->{name} if $e->{'is-default'};
5783 $current = $e->{name} if $e->{'is-current'};
5784 }
5785
5786 # fallback to the default machine if current is not supported by qemu
5787 return $current || $default || 'pc';
5788}
5789
23f73120
AD
5790sub qemu_machine_feature_enabled {
5791 my ($machine, $kvmver, $version_major, $version_minor) = @_;
5792
5793 my $current_major;
5794 my $current_minor;
5795
5796 if ($machine && $machine =~ m/^(pc(-i440fx|-q35)?-(\d+)\.(\d+))/) {
5797
5798 $current_major = $3;
5799 $current_minor = $4;
5800
5801 } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
5802
5803 $current_major = $1;
5804 $current_minor = $2;
5805 }
5806
5807 return 1 if $current_major >= $version_major && $current_minor >= $version_minor;
5808
5809
5810}
5811
42dbd2ee
AD
5812sub qemu_machine_pxe {
5813 my ($vmid, $conf, $machine) = @_;
5814
5815 $machine = PVE::QemuServer::get_current_qemu_machine($vmid) if !$machine;
5816
5817 foreach my $opt (keys %$conf) {
5818 next if $opt !~ m/^net(\d+)$/;
5819 my $net = PVE::QemuServer::parse_net($conf->{$opt});
5820 next if !$net;
5821 my $romfile = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, 'qom-get', path => $opt, property => 'romfile');
5822 return $machine.".pxe" if $romfile =~ m/pxe/;
5823 last;
5824 }
5825
d1363934 5826 return $machine;
42dbd2ee
AD
5827}
5828
249c4a6c
AD
5829sub qemu_use_old_bios_files {
5830 my ($machine_type) = @_;
5831
5832 return if !$machine_type;
5833
5834 my $use_old_bios_files = undef;
5835
5836 if ($machine_type =~ m/^(\S+)\.pxe$/) {
5837 $machine_type = $1;
5838 $use_old_bios_files = 1;
5839 } else {
74cc511f 5840 my $kvmver = kvm_user_version();
249c4a6c
AD
5841 # Note: kvm version < 2.4 use non-efi pxe files, and have problems when we
5842 # load new efi bios files on migration. So this hack is required to allow
5843 # live migration from qemu-2.2 to qemu-2.4, which is sometimes used when
5844 # updrading from proxmox-ve-3.X to proxmox-ve 4.0
74cc511f 5845 $use_old_bios_files = !qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 4);
249c4a6c
AD
5846 }
5847
5848 return ($use_old_bios_files, $machine_type);
5849}
5850
4543ecf0
AD
5851sub lspci {
5852
5853 my $devices = {};
5854
5855 dir_glob_foreach("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
5856 my (undef, $id, $function) = @_;
5857 my $res = { id => $id, function => $function};
5858 push @{$devices->{$id}}, $res;
5859 });
5860
5861 return $devices;
5862}
5863
22de899a
AD
5864sub vm_iothreads_list {
5865 my ($vmid) = @_;
5866
5867 my $res = vm_mon_cmd($vmid, 'query-iothreads');
5868
5869 my $iothreads = {};
5870 foreach my $iothread (@$res) {
5871 $iothreads->{ $iothread->{id} } = $iothread->{"thread-id"};
5872 }
5873
5874 return $iothreads;
5875}
5876
ee034f5c
AD
5877sub scsihw_infos {
5878 my ($conf, $drive) = @_;
5879
5880 my $maxdev = 0;
5881
5882 if ($conf->{scsihw} && ($conf->{scsihw} =~ m/^lsi/)) {
5883 $maxdev = 7;
a1511b3c 5884 } elsif ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
ee034f5c
AD
5885 $maxdev = 1;
5886 } else {
5887 $maxdev = 256;
5888 }
5889
5890 my $controller = int($drive->{index} / $maxdev);
a1511b3c 5891 my $controller_prefix = ($conf->{scsihw} && $conf->{scsihw} eq 'virtio-scsi-single') ? "virtioscsi" : "scsihw";
ee034f5c
AD
5892
5893 return ($maxdev, $controller, $controller_prefix);
5894}
a1511b3c 5895
65e866e5
DM
5896# bash completion helper
5897
5898sub complete_backup_archives {
5899 my ($cmdname, $pname, $cvalue) = @_;
5900
5901 my $cfg = PVE::Storage::config();
5902
5903 my $storeid;
5904
5905 if ($cvalue =~ m/^([^:]+):/) {
5906 $storeid = $1;
5907 }
5908
5909 my $data = PVE::Storage::template_list($cfg, $storeid, 'backup');
5910
5911 my $res = [];
5912 foreach my $id (keys %$data) {
5913 foreach my $item (@{$data->{$id}}) {
5914 next if $item->{format} !~ m/^vma\.(gz|lzo)$/;
5915 push @$res, $item->{volid} if defined($item->{volid});
5916 }
5917 }
5918
5919 return $res;
5920}
5921
5922my $complete_vmid_full = sub {
5923 my ($running) = @_;
5924
5925 my $idlist = vmstatus();
5926
5927 my $res = [];
5928
5929 foreach my $id (keys %$idlist) {
5930 my $d = $idlist->{$id};
5931 if (defined($running)) {
5932 next if $d->{template};
5933 next if $running && $d->{status} ne 'running';
5934 next if !$running && $d->{status} eq 'running';
5935 }
5936 push @$res, $id;
5937
5938 }
5939 return $res;
5940};
5941
5942sub complete_vmid {
5943 return &$complete_vmid_full();
5944}
5945
5946sub complete_vmid_stopped {
5947 return &$complete_vmid_full(0);
5948}
5949
5950sub complete_vmid_running {
5951 return &$complete_vmid_full(1);
5952}
5953
335af808
DM
5954sub complete_storage {
5955
5956 my $cfg = PVE::Storage::config();
5957 my $ids = $cfg->{ids};
5958
5959 my $res = [];
5960 foreach my $sid (keys %$ids) {
5961 next if !PVE::Storage::storage_check_enabled($cfg, $sid, undef, 1);
c4c844ef 5962 next if !$ids->{$sid}->{content}->{images};
335af808
DM
5963 push @$res, $sid;
5964 }
5965
5966 return $res;
5967}
5968
1e3baf05 59691;