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