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