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