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