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