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