]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
Switch from netcat-traditional to netcat6
[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
1e3baf05
DM
2621 push @$cmd, '/usr/bin/kvm';
2622
2623 push @$cmd, '-id', $vmid;
2624
2625 my $use_virtio = 0;
2626
c971c4f2
AD
2627 my $qmpsocket = qmp_socket($vmid);
2628 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2629 push @$cmd, '-mon', "chardev=qmp,mode=control";
2630
7b7c6d1b 2631 my $socket = vnc_socket($vmid);
1e3baf05
DM
2632 push @$cmd, '-vnc', "unix:$socket,x509,password";
2633
6b64503e 2634 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2635
1e3baf05
DM
2636 push @$cmd, '-daemonize';
2637
2796e7d5
DM
2638 if ($conf->{smbios1}) {
2639 push @$cmd, '-smbios', "type=1,$conf->{smbios1}";
2640 }
2641
db656e5f 2642 if ($q35) {
b467f79a 2643 # the q35 chipset support native usb2, so we enable usb controller
db656e5f 2644 # by default for this machine type
f8e83f05 2645 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
db656e5f 2646 } else {
f8e83f05
AD
2647 $pciaddr = print_pci_addr("piix3", $bridges);
2648 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
24f0d39a 2649
f8e83f05 2650 my $use_usb2 = 0;
db656e5f
DM
2651 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2652 next if !$conf->{"usb$i"};
2653 $use_usb2 = 1;
2654 }
2655 # include usb device config
2656 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
fcc573ab 2657 }
19672434 2658
5acbfe9e 2659 my $vga = $conf->{vga};
2fa3151e 2660
590e698c
DM
2661 my $qxlnum = vga_conf_has_spice($vga);
2662 $vga = 'qxl' if $qxlnum;
2fa3151e 2663
5acbfe9e 2664 if (!$vga) {
264e519f
DM
2665 if ($conf->{ostype} && ($conf->{ostype} eq 'win8' ||
2666 $conf->{ostype} eq 'win7' ||
5acbfe9e
DM
2667 $conf->{ostype} eq 'w2k8')) {
2668 $vga = 'std';
2669 } else {
2670 $vga = 'cirrus';
2671 }
2672 }
2673
1e3baf05 2674 # enable absolute mouse coordinates (needed by vnc)
5acbfe9e
DM
2675 my $tablet;
2676 if (defined($conf->{tablet})) {
2677 $tablet = $conf->{tablet};
2678 } else {
2679 $tablet = $defaults->{tablet};
590e698c 2680 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
ef5e2be2 2681 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
5acbfe9e
DM
2682 }
2683
db656e5f 2684 push @$devices, '-device', print_tabletdevice_full($conf) if $tablet;
b467f79a 2685
1e3baf05 2686 # host pci devices
040b06b7 2687 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2e3b7e2a
AD
2688 my $d = parse_hostpci($conf->{"hostpci$i"});
2689 next if !$d;
2690
2691 my $pcie = $d->{pcie};
2692 if($pcie){
2693 die "q35 machine model is not enabled" if !$q35;
2694 $pciaddr = print_pcie_addr("hostpci$i");
2695 }else{
2696 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2697 }
2698
2699 my $rombar = $d->{rombar} && $d->{rombar} eq 'off' ? ",rombar=0" : "";
2700 my $driver = $d->{driver} && $d->{driver} eq 'vfio' ? "vfio-pci" : "pci-assign";
2701 my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ? ",x-vga=on" : "";
137483c0
AD
2702 if ($xvga && $xvga ne '') {
2703 push @$cpuFlags, 'kvm=off';
2704 $vga = 'none';
2705 }
2e3b7e2a 2706 $driver = "vfio-pci" if $xvga ne '';
4543ecf0
AD
2707 my $pcidevices = $d->{pciid};
2708 my $multifunction = 1 if @$pcidevices > 1;
2e3b7e2a 2709
4543ecf0
AD
2710 my $j=0;
2711 foreach my $pcidevice (@$pcidevices) {
2e3b7e2a 2712
4543ecf0
AD
2713 my $id = "hostpci$i";
2714 $id .= ".$j" if $multifunction;
2715 my $addr = $pciaddr;
2716 $addr .= ".$j" if $multifunction;
2717 my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
2718
2719 if($j == 0){
2720 $devicestr .= "$rombar$xvga";
2721 $devicestr .= ",multifunction=on" if $multifunction;
2722 }
2723
2724 push @$devices, '-device', $devicestr;
2725 $j++;
2726 }
1e3baf05
DM
2727 }
2728
2729 # usb devices
2730 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2731 my $d = parse_usb_device($conf->{"usb$i"});
2732 next if !$d;
2733 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2734 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2735 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2736 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
80401dd8
DM
2737 } elsif ($d->{spice}) {
2738 # usb redir support for spice
2739 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2740 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
1e3baf05
DM
2741 }
2742 }
2743
1e3baf05 2744 # serial devices
bae179aa 2745 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2746 if (my $path = $conf->{"serial$i"}) {
9f9d2fb2
DM
2747 if ($path eq 'socket') {
2748 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2749 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2750 push @$devices, '-device', "isa-serial,chardev=serial$i";
2751 } else {
2752 die "no such serial device\n" if ! -c $path;
2753 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2754 push @$devices, '-device', "isa-serial,chardev=serial$i";
2755 }
34978be3 2756 }
1e3baf05
DM
2757 }
2758
2759 # parallel devices
1989a89c 2760 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2761 if (my $path = $conf->{"parallel$i"}) {
19672434 2762 die "no such parallel device\n" if ! -c $path;
32e69805 2763 my $devtype = $path =~ m!^/dev/usb/lp! ? 'tty' : 'parport';
4c5dbaf6 2764 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
5bdcf937 2765 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2766 }
1e3baf05
DM
2767 }
2768
2769 my $vmname = $conf->{name} || "vm$vmid";
2770
2771 push @$cmd, '-name', $vmname;
19672434 2772
1e3baf05
DM
2773 my $sockets = 1;
2774 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2775 $sockets = $conf->{sockets} if $conf->{sockets};
2776
2777 my $cores = $conf->{cores} || 1;
3bd18e48 2778
de9d1e55 2779 my $maxcpus = $sockets * $cores;
76267728 2780
de9d1e55 2781 my $vcpus = $conf->{vcpus} ? $conf->{vcpus} : $maxcpus;
76267728 2782
de9d1e55
AD
2783 my $allowed_vcpus = $cpuinfo->{cpus};
2784
2785 die "MAX $maxcpus vcpus allowed per VM on this node\n"
2786 if ($allowed_vcpus < $maxcpus);
2787
2788 push @$cmd, '-smp', "$vcpus,sockets=$sockets,cores=$cores,maxcpus=$maxcpus";
1e3baf05 2789
1e3baf05
DM
2790 push @$cmd, '-nodefaults';
2791
32baffb4 2792 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2793
0888fdce
DM
2794 my $bootindex_hash = {};
2795 my $i = 1;
2796 foreach my $o (split(//, $bootorder)) {
2797 $bootindex_hash->{$o} = $i*100;
2798 $i++;
afdb31d5 2799 }
3b408e82 2800
cf71f776 2801 push @$cmd, '-boot', "menu=on,strict=on,reboot-timeout=1000";
1e3baf05 2802
6b64503e 2803 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2804
6b64503e 2805 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05 2806
ef5e2be2 2807 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
1e3baf05
DM
2808
2809 # time drift fix
6b64503e 2810 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2811
6b64503e 2812 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2813 my $useLocaltime = $conf->{localtime};
1e3baf05
DM
2814
2815 if (my $ost = $conf->{ostype}) {
6b9d84cf 2816 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
1e3baf05
DM
2817
2818 if ($ost =~ m/^w/) { # windows
8c559505 2819 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2820
8c559505 2821 # use time drift fix when acpi is enabled
6b64503e 2822 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2823 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2824 }
2825 }
2826
be190583 2827 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
a70ebde3 2828 $ost eq 'wvista') {
8c559505 2829 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf 2830 push @$cmd, '-no-hpet';
8f3f959d
AD
2831 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2832 push @$cpuFlags , 'hv_spinlocks=0x1fff' if !$nokvm;
8a054ffd 2833 push @$cpuFlags , 'hv_vapic' if !$nokvm;
cfac0be4 2834 push @$cpuFlags , 'hv_time' if !$nokvm;
8a054ffd 2835
a1b7d579 2836 } else {
8f3f959d
AD
2837 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2838 }
462e8d19
AD
2839 }
2840
2841 if ($ost eq 'win7' || $ost eq 'win8') {
2842 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
b7e0c8bf 2843 }
1e3baf05
DM
2844 }
2845
8c559505
DM
2846 push @$rtcFlags, 'driftfix=slew' if $tdf;
2847
7f0b5beb 2848 if ($nokvm) {
8c559505 2849 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2850 } else {
2851 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2852 }
1e3baf05 2853
952958bc
DM
2854 if ($machine_type) {
2855 push @$machineFlags, "type=${machine_type}";
3bafc510
DM
2856 }
2857
8c559505
DM
2858 if ($conf->{startdate}) {
2859 push @$rtcFlags, "base=$conf->{startdate}";
2860 } elsif ($useLocaltime) {
2861 push @$rtcFlags, 'base=localtime';
2862 }
1e3baf05 2863
519ed28c
AD
2864 my $cpu = $nokvm ? "qemu64" : "kvm64";
2865 $cpu = $conf->{cpu} if $conf->{cpu};
2866
4dc339e7
AD
2867 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2868
6b9d84cf
AD
2869 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype} ne 'solaris';
2870
2871 push @$cpuFlags , '-x2apic' if $conf->{ostype} eq 'solaris';
519ed28c 2872
2e1a5389
AD
2873 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2874
117a0414
AD
2875 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2876
2877 push @$cpuFlags , '+kvm_pv_unhalt' if !$nokvm;
0da5a08c 2878 push @$cpuFlags , '+kvm_pv_eoi' if !$nokvm;
117a0414
AD
2879 }
2880
be190583 2881 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c 2882
6a33d44a 2883 push @$cmd, '-cpu', "$cpu,enforce";
519ed28c 2884
4d3f29ed
AD
2885 my $memory = $conf->{memory} || $defaults->{memory};
2886 my $static_memory = 0;
2887 my $dimm_memory = 0;
2888
2889 if ($hotplug_features->{memory}) {
996635e5
DM
2890 die "Numa need to be enabled for memory hotplug\n" if !$conf->{numa};
2891 die "Total memory is bigger than ${MAX_MEM}MB\n" if $memory > $MAX_MEM;
4d3f29ed 2892 $static_memory = $STATICMEM;
996635e5 2893 die "minimum memory must be ${static_memory}MB\n" if($memory < $static_memory);
4d3f29ed 2894 $dimm_memory = $memory - $static_memory;
996635e5 2895 push @$cmd, '-m', "size=${static_memory},slots=255,maxmem=${MAX_MEM}M";
4d3f29ed
AD
2896
2897 } else {
2898
2899 $static_memory = $memory;
2900 push @$cmd, '-m', $static_memory;
2901 }
8a010eae 2902
67fb9de6 2903 if ($conf->{numa}) {
8a010eae 2904
2ed5d572
AD
2905 my $numa_totalmemory = undef;
2906 for (my $i = 0; $i < $MAX_NUMA; $i++) {
2907 next if !$conf->{"numa$i"};
2908 my $numa = parse_numa($conf->{"numa$i"});
2909 next if !$numa;
67fb9de6
DM
2910 # memory
2911 die "missing numa node$i memory value\n" if !$numa->{memory};
2ed5d572
AD
2912 my $numa_memory = $numa->{memory};
2913 $numa_totalmemory += $numa_memory;
996635e5 2914 my $numa_object = "memory-backend-ram,id=ram-node$i,size=${numa_memory}M";
2ed5d572 2915
67fb9de6 2916 # cpus
2ed5d572 2917 my $cpus_start = $numa->{cpus}->{start};
67fb9de6 2918 die "missing numa node$i cpus\n" if !defined($cpus_start);
2ed5d572
AD
2919 my $cpus_end = $numa->{cpus}->{end} if defined($numa->{cpus}->{end});
2920 my $cpus = $cpus_start;
2921 if (defined($cpus_end)) {
2922 $cpus .= "-$cpus_end";
67fb9de6 2923 die "numa node$i : cpu range $cpus is incorrect\n" if $cpus_end <= $cpus_start;
2ed5d572 2924 }
8a010eae 2925
67fb9de6 2926 # hostnodes
2ed5d572
AD
2927 my $hostnodes_start = $numa->{hostnodes}->{start};
2928 if (defined($hostnodes_start)) {
2929 my $hostnodes_end = $numa->{hostnodes}->{end} if defined($numa->{hostnodes}->{end});
2930 my $hostnodes = $hostnodes_start;
2931 if (defined($hostnodes_end)) {
2932 $hostnodes .= "-$hostnodes_end";
67fb9de6 2933 die "host node $hostnodes range is incorrect\n" if $hostnodes_end <= $hostnodes_start;
2ed5d572 2934 }
8a010eae 2935
2ed5d572
AD
2936 my $hostnodes_end_range = defined($hostnodes_end) ? $hostnodes_end : $hostnodes_start;
2937 for (my $i = $hostnodes_start; $i <= $hostnodes_end_range; $i++ ) {
67fb9de6 2938 die "host numa node$i don't exist\n" if ! -d "/sys/devices/system/node/node$i/";
2ed5d572 2939 }
8a010eae 2940
67fb9de6 2941 # policy
2ed5d572 2942 my $policy = $numa->{policy};
67fb9de6
DM
2943 die "you need to define a policy for hostnode $hostnodes\n" if !$policy;
2944 $numa_object .= ",host-nodes=$hostnodes,policy=$policy";
2ed5d572
AD
2945 }
2946
2947 push @$cmd, '-object', $numa_object;
8a010eae
AD
2948 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2949 }
67fb9de6 2950
4d3f29ed
AD
2951 die "total memory for NUMA nodes must be equal to vm static memory\n"
2952 if $numa_totalmemory && $numa_totalmemory != $static_memory;
2ed5d572
AD
2953
2954 #if no custom tology, we split memory and cores across numa nodes
2955 if(!$numa_totalmemory) {
2956
4d3f29ed 2957 my $numa_memory = ($static_memory / $sockets) . "M";
2ed5d572
AD
2958
2959 for (my $i = 0; $i < $sockets; $i++) {
2960
2961 my $cpustart = ($cores * $i);
2962 my $cpuend = ($cpustart + $cores - 1) if $cores && $cores > 1;
2963 my $cpus = $cpustart;
2964 $cpus .= "-$cpuend" if $cpuend;
2965
2966 push @$cmd, '-object', "memory-backend-ram,size=$numa_memory,id=ram-node$i";
2967 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2968 }
2969 }
8a010eae
AD
2970 }
2971
4d3f29ed 2972 if ($hotplug_features->{memory}) {
e059fb4d
AD
2973 foreach_dimm($conf, $vmid, $memory, $sockets, sub {
2974 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
996635e5 2975 push @$cmd, "-object" , "memory-backend-ram,id=mem-$name,size=${dimm_size}M";
e059fb4d
AD
2976 push @$cmd, "-device", "pc-dimm,id=$name,memdev=mem-$name,node=$numanode";
2977
2978 #if dimm_memory is not aligned to dimm map
2979 if($current_size > $memory) {
2980 $conf->{memory} = $current_size;
2981 update_config_nolock($vmid, $conf, 1);
2982 }
2983 });
4d3f29ed
AD
2984 }
2985
1e3baf05
DM
2986 push @$cmd, '-S' if $conf->{freeze};
2987
2988 # set keyboard layout
2989 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2990 push @$cmd, '-k', $kb if $kb;
2991
2992 # enable sound
2993 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2994 #push @$cmd, '-soundhw', 'es1370';
2995 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2996
bc84dcca 2997 if($conf->{agent}) {
7a6c2150 2998 my $qgasocket = qmp_socket($vmid, 1);
ab6a046f
AD
2999 my $pciaddr = print_pci_addr("qga0", $bridges);
3000 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
3001 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
3002 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
3003 }
3004
1d794448 3005 my $spice_port;
2fa3151e 3006
590e698c
DM
3007 if ($qxlnum) {
3008 if ($qxlnum > 1) {
3009 if ($conf->{ostype} && $conf->{ostype} =~ m/^w/){
3010 for(my $i = 1; $i < $qxlnum; $i++){
3011 my $pciaddr = print_pci_addr("vga$i", $bridges);
3012 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
3013 }
3014 } else {
3015 # assume other OS works like Linux
3016 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
3017 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2fa3151e
AD
3018 }
3019 }
3020
1011b570 3021 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 3022
cd339d1f 3023 $spice_port = PVE::Tools::next_spice_port();
943340a6 3024
d2da6d9b 3025 push @$devices, '-spice', "tls-port=${spice_port},addr=127.0.0.1,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 3026
d2da6d9b
AD
3027 push @$devices, '-device', "virtio-serial,id=spice$pciaddr";
3028 push @$devices, '-chardev', "spicevmc,id=vdagent,name=vdagent";
3029 push @$devices, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
1011b570
DM
3030 }
3031
8d9ae0d2
DM
3032 # enable balloon by default, unless explicitly disabled
3033 if (!defined($conf->{balloon}) || $conf->{balloon}) {
3034 $pciaddr = print_pci_addr("balloon0", $bridges);
3035 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
3036 }
1e3baf05 3037
0ea9541d
DM
3038 if ($conf->{watchdog}) {
3039 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 3040 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 3041 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
3042 push @$devices, '-device', "$watchdog$pciaddr";
3043 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
3044 }
3045
1e3baf05 3046 my $vollist = [];
941e0c42 3047 my $scsicontroller = {};
26ee04b6 3048 my $ahcicontroller = {};
cdd20088 3049 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05 3050
5881b913
DM
3051 # Add iscsi initiator name if available
3052 if (my $initiator = get_initiator_name()) {
3053 push @$devices, '-iscsi', "initiator-name=$initiator";
3054 }
3055
1e3baf05
DM
3056 foreach_drive($conf, sub {
3057 my ($ds, $drive) = @_;
3058
ff1a2432 3059 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 3060 push @$vollist, $drive->{file};
ff1a2432 3061 }
afdb31d5 3062
1e3baf05 3063 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
3064
3065 if (drive_is_cdrom ($drive)) {
3066 if ($bootindex_hash->{d}) {
3067 $drive->{bootindex} = $bootindex_hash->{d};
3068 $bootindex_hash->{d} += 1;
3069 }
3070 } else {
3071 if ($bootindex_hash->{c}) {
3072 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
3073 $bootindex_hash->{c} += 1;
3074 }
3075 }
3076
51f492cd
AD
3077 if($drive->{interface} eq 'virtio'){
3078 push @$cmd, '-object', "iothread,id=iothread-$ds" if $drive->{iothread};
3079 }
3080
941e0c42 3081 if ($drive->{interface} eq 'scsi') {
cdd20088 3082
ee034f5c 3083 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
6731a4cf 3084
6731a4cf 3085 $pciaddr = print_pci_addr("$controller_prefix$controller", $bridges);
a1b7d579 3086 my $scsihw_type = $scsihw =~ m/^virtio-scsi-single/ ? "virtio-scsi-pci" : $scsihw;
fc8b40fd
AD
3087
3088 my $iothread = '';
3089 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{iothread}){
3090 $iothread .= ",iothread=iothread-$controller_prefix$controller";
3091 push @$cmd, '-object', "iothread,id=iothread-$controller_prefix$controller";
3092 }
3093
6e11f143
AD
3094 my $queues = '';
3095 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{queues}){
3096 $queues = ",num_queues=$drive->{queues}";
3097 }
3098
3099 push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread$queues" if !$scsicontroller->{$controller};
cdd20088 3100 $scsicontroller->{$controller}=1;
941e0c42 3101 }
3b408e82 3102
26ee04b6
DA
3103 if ($drive->{interface} eq 'sata') {
3104 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
3105 $pciaddr = print_pci_addr("ahci$controller", $bridges);
3106 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
3107 $ahcicontroller->{$controller}=1;
3108 }
46f58b5f 3109
15b21acc
MR
3110 my $drive_cmd = print_drive_full($storecfg, $vmid, $drive);
3111 push @$devices, '-drive',$drive_cmd;
46f58b5f 3112 push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
3113 });
3114
cc4d6182 3115 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 3116 next if !$conf->{"net$i"};
cc4d6182
DA
3117 my $d = parse_net($conf->{"net$i"});
3118 next if !$d;
1e3baf05 3119
cc4d6182 3120 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 3121
cc4d6182
DA
3122 if ($bootindex_hash->{n}) {
3123 $d->{bootindex} = $bootindex_hash->{n};
3124 $bootindex_hash->{n} += 1;
3125 }
1e3baf05 3126
cc4d6182 3127 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
3128 push @$devices, '-netdev', $netdevfull;
3129
3130 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
3131 push @$devices, '-device', $netdevicefull;
3132 }
1e3baf05 3133
db656e5f
DM
3134 if (!$q35) {
3135 # add pci bridges
fc79e813
AD
3136 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
3137 $bridges->{1} = 1;
3138 $bridges->{2} = 1;
3139 }
3140
6731a4cf
AD
3141 $bridges->{3} = 1 if $scsihw =~ m/^virtio-scsi-single/;
3142
f8e83f05
AD
3143 while (my ($k, $v) = each %$bridges) {
3144 $pciaddr = print_pci_addr("pci.$k");
3145 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
3146 }
19672434
DM
3147 }
3148
1e3baf05
DM
3149 # hack: virtio with fairsched is unreliable, so we do not use fairsched
3150 # when the VM uses virtio devices.
19672434
DM
3151 if (!$use_virtio && $have_ovz) {
3152
6b64503e 3153 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
3154 $conf->{cpuunits} : $defaults->{cpuunits};
3155
3156 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
3157
3158 # fixme: cpulimit is currently ignored
3159 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
3160 }
3161
3162 # add custom args
3163 if ($conf->{args}) {
3ada46c9 3164 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
3165 push @$cmd, @$aa;
3166 }
3167
5bdcf937 3168 push @$cmd, @$devices;
be190583 3169 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 3170 if scalar(@$rtcFlags);
be190583 3171 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
3172 if scalar(@$machineFlags);
3173 push @$cmd, '-global', join(',', @$globalFlags)
3174 if scalar(@$globalFlags);
3175
1d794448 3176 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 3177}
19672434 3178
1e3baf05
DM
3179sub vnc_socket {
3180 my ($vmid) = @_;
3181 return "${var_run_tmpdir}/$vmid.vnc";
3182}
3183
943340a6 3184sub spice_port {
1011b570 3185 my ($vmid) = @_;
943340a6 3186
1d794448 3187 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
3188
3189 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
3190}
3191
c971c4f2 3192sub qmp_socket {
693d12a2
AD
3193 my ($vmid, $qga) = @_;
3194 my $sockettype = $qga ? 'qga' : 'qmp';
3195 return "${var_run_tmpdir}/$vmid.$sockettype";
c971c4f2
AD
3196}
3197
1e3baf05
DM
3198sub pidfile_name {
3199 my ($vmid) = @_;
3200 return "${var_run_tmpdir}/$vmid.pid";
3201}
3202
86fdcfb2
DA
3203sub vm_devices_list {
3204 my ($vmid) = @_;
3205
ceea9078 3206 my $res = vm_mon_cmd($vmid, 'query-pci');
ceea9078
DM
3207 my $devices = {};
3208 foreach my $pcibus (@$res) {
3209 foreach my $device (@{$pcibus->{devices}}) {
6e62a21f 3210 next if !$device->{'qdev_id'};
200644a7 3211 if ($device->{'pci_bridge'}) {
200644a7
AD
3212 $devices->{$device->{'qdev_id'}} = 1;
3213 foreach my $bridge_device (@{$device->{'pci_bridge'}->{devices}}) {
3214 next if !$bridge_device->{'qdev_id'};
3215 $devices->{$bridge_device->{'qdev_id'}} = 1;
3216 $devices->{$device->{'qdev_id'}}++;
3217 }
3218 } else {
200644a7
AD
3219 $devices->{$device->{'qdev_id'}} = 1;
3220 }
f78cc802
AD
3221 }
3222 }
3223
3224 my $resblock = vm_mon_cmd($vmid, 'query-block');
3225 foreach my $block (@$resblock) {
3226 if($block->{device} =~ m/^drive-(\S+)/){
3227 $devices->{$1} = 1;
1dc4f496
DM
3228 }
3229 }
86fdcfb2 3230
3d7389fe
DM
3231 my $resmice = vm_mon_cmd($vmid, 'query-mice');
3232 foreach my $mice (@$resmice) {
3233 if ($mice->{name} eq 'QEMU HID Tablet') {
3234 $devices->{tablet} = 1;
3235 last;
3236 }
3237 }
3238
1dc4f496 3239 return $devices;
86fdcfb2
DA
3240}
3241
ec21aa11 3242sub vm_deviceplug {
f19d1c47 3243 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 3244
db656e5f
DM
3245 my $q35 = machine_type_is_q35($conf);
3246
95d6343b
DA
3247 my $devices_list = vm_devices_list($vmid);
3248 return 1 if defined($devices_list->{$deviceid});
3249
fee46675
DM
3250 qemu_add_pci_bridge($storecfg, $conf, $vmid, $deviceid); # add PCI bridge if we need it for the device
3251
3d7389fe 3252 if ($deviceid eq 'tablet') {
fee46675 3253
3d7389fe 3254 qemu_deviceadd($vmid, print_tabletdevice_full($conf));
3d7389fe 3255
fee46675 3256 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
40f28a9f 3257
22de899a
AD
3258 qemu_iothread_add($vmid, $deviceid, $device);
3259
fee46675 3260 qemu_driveadd($storecfg, $vmid, $device);
cdd20088 3261 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
fee46675 3262
5e5dcb73 3263 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3264 eval { qemu_deviceaddverify($vmid, $deviceid); };
3265 if (my $err = $@) {
63c2da2f
DM
3266 eval { qemu_drivedel($vmid, $deviceid); };
3267 warn $@ if $@;
fee46675 3268 die $err;
5e5dcb73 3269 }
cfc817c7 3270
2733141c 3271 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
fee46675 3272
fc8b40fd 3273
cdd20088 3274 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 3275 my $pciaddr = print_pci_addr($deviceid);
a1b7d579 3276 my $scsihw_type = $scsihw eq 'virtio-scsi-single' ? "virtio-scsi-pci" : $scsihw;
2733141c
AD
3277
3278 my $devicefull = "$scsihw_type,id=$deviceid$pciaddr";
fee46675 3279
fc8b40fd
AD
3280 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{iothread}) {
3281 qemu_iothread_add($vmid, $deviceid, $device);
3282 $devicefull .= ",iothread=iothread-$deviceid";
3283 }
3284
6e11f143
AD
3285 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{queues}) {
3286 $devicefull .= ",num_queues=$device->{queues}";
3287 }
3288
cfc817c7 3289 qemu_deviceadd($vmid, $devicefull);
fee46675 3290 qemu_deviceaddverify($vmid, $deviceid);
cfc817c7 3291
fee46675
DM
3292 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3293
3294 qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
3295 qemu_driveadd($storecfg, $vmid, $device);
a1b7d579 3296
fee46675
DM
3297 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
3298 eval { qemu_deviceadd($vmid, $devicefull); };
3299 if (my $err = $@) {
63c2da2f
DM
3300 eval { qemu_drivedel($vmid, $deviceid); };
3301 warn $@ if $@;
fee46675 3302 die $err;
a4f091a0 3303 }
a4f091a0 3304
fee46675
DM
3305 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3306
2630d2a9
DA
3307 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
3308 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
3309 qemu_deviceadd($vmid, $netdevicefull);
fee46675
DM
3310 eval { qemu_deviceaddverify($vmid, $deviceid); };
3311 if (my $err = $@) {
3312 eval { qemu_netdevdel($vmid, $deviceid); };
3313 warn $@ if $@;
3314 die $err;
2630d2a9 3315 }
2630d2a9 3316
fee46675 3317 } elsif (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
b467f79a 3318
40f28a9f
AD
3319 my $bridgeid = $2;
3320 my $pciaddr = print_pci_addr($deviceid);
3321 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
a1b7d579 3322
40f28a9f 3323 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3324 qemu_deviceaddverify($vmid, $deviceid);
3325
3326 } else {
a1b7d579 3327 die "can't hotplug device '$deviceid'\n";
40f28a9f
AD
3328 }
3329
5e5dcb73 3330 return 1;
a4dea331
DA
3331}
3332
3eec5767 3333# fixme: this should raise exceptions on error!
ec21aa11 3334sub vm_deviceunplug {
f19d1c47 3335 my ($vmid, $conf, $deviceid) = @_;
873c2d69 3336
95d6343b
DA
3337 my $devices_list = vm_devices_list($vmid);
3338 return 1 if !defined($devices_list->{$deviceid});
3339
63c2da2f
DM
3340 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
3341
3d7389fe 3342 if ($deviceid eq 'tablet') {
63c2da2f 3343
3d7389fe 3344 qemu_devicedel($vmid, $deviceid);
3d7389fe 3345
63c2da2f 3346 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
f19d1c47 3347
5e5dcb73 3348 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3349 qemu_devicedelverify($vmid, $deviceid);
3350 qemu_drivedel($vmid, $deviceid);
22de899a
AD
3351 qemu_iothread_del($conf, $vmid, $deviceid);
3352
2733141c 3353 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
a1b7d579 3354
63c2da2f 3355 qemu_devicedel($vmid, $deviceid);
8ce30dde 3356 qemu_devicedelverify($vmid, $deviceid);
fc8b40fd 3357 qemu_iothread_del($conf, $vmid, $deviceid);
a1b7d579 3358
63c2da2f 3359 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
cfc817c7 3360
8bcf3068
AD
3361 #qemu 2.3 segfault on drive_del with virtioscsi + iothread
3362 my $device = parse_drive($deviceid, $conf->{$deviceid});
3363 die "virtioscsi with iothread is not hot-unplugglable currently" if $device->{iothread};
3364
63c2da2f
DM
3365 qemu_devicedel($vmid, $deviceid);
3366 qemu_drivedel($vmid, $deviceid);
a1b7d579 3367 qemu_deletescsihw($conf, $vmid, $deviceid);
8ce30dde 3368
63c2da2f 3369 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
a4f091a0 3370
2630d2a9 3371 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3372 qemu_devicedelverify($vmid, $deviceid);
3373 qemu_netdevdel($vmid, $deviceid);
3374
3375 } else {
3376 die "can't unplug device '$deviceid'\n";
2630d2a9
DA
3377 }
3378
5e5dcb73
DA
3379 return 1;
3380}
3381
3382sub qemu_deviceadd {
3383 my ($vmid, $devicefull) = @_;
873c2d69 3384
d695b5b7
AD
3385 $devicefull = "driver=".$devicefull;
3386 my %options = split(/[=,]/, $devicefull);
f19d1c47 3387
d695b5b7 3388 vm_mon_cmd($vmid, "device_add" , %options);
5e5dcb73 3389}
afdb31d5 3390
5e5dcb73 3391sub qemu_devicedel {
fee46675 3392 my ($vmid, $deviceid) = @_;
63c2da2f 3393
5a77d8c1 3394 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
5e5dcb73
DA
3395}
3396
22de899a
AD
3397sub qemu_iothread_add {
3398 my($vmid, $deviceid, $device) = @_;
3399
3400 if ($device->{iothread}) {
3401 my $iothreads = vm_iothreads_list($vmid);
3402 qemu_objectadd($vmid, "iothread-$deviceid", "iothread") if !$iothreads->{"iothread-$deviceid"};
3403 }
3404}
3405
3406sub qemu_iothread_del {
3407 my($conf, $vmid, $deviceid) = @_;
3408
3409 my $device = parse_drive($deviceid, $conf->{$deviceid});
3410 if ($device->{iothread}) {
3411 my $iothreads = vm_iothreads_list($vmid);
3412 qemu_objectdel($vmid, "iothread-$deviceid") if $iothreads->{"iothread-$deviceid"};
3413 }
3414}
3415
4d3f29ed
AD
3416sub qemu_objectadd {
3417 my($vmid, $objectid, $qomtype) = @_;
3418
3419 vm_mon_cmd($vmid, "object-add", id => $objectid, "qom-type" => $qomtype);
3420
3421 return 1;
3422}
3423
3424sub qemu_objectdel {
3425 my($vmid, $objectid) = @_;
3426
3427 vm_mon_cmd($vmid, "object-del", id => $objectid);
3428
3429 return 1;
3430}
3431
5e5dcb73 3432sub qemu_driveadd {
fee46675 3433 my ($storecfg, $vmid, $device) = @_;
5e5dcb73
DA
3434
3435 my $drive = print_drive_full($storecfg, $vmid, $device);
7a69fc3c 3436 $drive =~ s/\\/\\\\/g;
8ead5ec7 3437 my $ret = vm_human_monitor_command($vmid, "drive_add auto \"$drive\"");
fee46675 3438
5e5dcb73 3439 # If the command succeeds qemu prints: "OK"
fee46675
DM
3440 return 1 if $ret =~ m/OK/s;
3441
3442 die "adding drive failed: $ret\n";
5e5dcb73 3443}
afdb31d5 3444
5e5dcb73
DA
3445sub qemu_drivedel {
3446 my($vmid, $deviceid) = @_;
873c2d69 3447
7b7c6d1b 3448 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73 3449 $ret =~ s/^\s+//;
a1b7d579 3450
63c2da2f 3451 return 1 if $ret eq "";
a1b7d579 3452
63c2da2f 3453 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
a1b7d579
DM
3454 return 1 if $ret =~ m/Device \'.*?\' not found/s;
3455
63c2da2f 3456 die "deleting drive $deviceid failed : $ret\n";
5e5dcb73 3457}
f19d1c47 3458
5e5dcb73 3459sub qemu_deviceaddverify {
fee46675 3460 my ($vmid, $deviceid) = @_;
873c2d69 3461
5e5dcb73
DA
3462 for (my $i = 0; $i <= 5; $i++) {
3463 my $devices_list = vm_devices_list($vmid);
3464 return 1 if defined($devices_list->{$deviceid});
3465 sleep 1;
afdb31d5 3466 }
fee46675
DM
3467
3468 die "error on hotplug device '$deviceid'\n";
5e5dcb73 3469}
afdb31d5 3470
5e5dcb73
DA
3471
3472sub qemu_devicedelverify {
63c2da2f
DM
3473 my ($vmid, $deviceid) = @_;
3474
a1b7d579 3475 # need to verify that the device is correctly removed as device_del
63c2da2f 3476 # is async and empty return is not reliable
5e5dcb73 3477
5e5dcb73
DA
3478 for (my $i = 0; $i <= 5; $i++) {
3479 my $devices_list = vm_devices_list($vmid);
3480 return 1 if !defined($devices_list->{$deviceid});
3481 sleep 1;
afdb31d5 3482 }
63c2da2f
DM
3483
3484 die "error on hot-unplugging device '$deviceid'\n";
873c2d69
DA
3485}
3486
cdd20088 3487sub qemu_findorcreatescsihw {
cfc817c7
DA
3488 my ($storecfg, $conf, $vmid, $device) = @_;
3489
ee034f5c 3490 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
2733141c
AD
3491
3492 my $scsihwid="$controller_prefix$controller";
cfc817c7
DA
3493 my $devices_list = vm_devices_list($vmid);
3494
cdd20088 3495 if(!defined($devices_list->{$scsihwid})) {
fc8b40fd 3496 vm_deviceplug($storecfg, $conf, $vmid, $scsihwid, $device);
cfc817c7 3497 }
fee46675 3498
cfc817c7
DA
3499 return 1;
3500}
3501
8ce30dde
AD
3502sub qemu_deletescsihw {
3503 my ($conf, $vmid, $opt) = @_;
3504
3505 my $device = parse_drive($opt, $conf->{$opt});
3506
a1511b3c 3507 if ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
2733141c
AD
3508 vm_deviceunplug($vmid, $conf, "virtioscsi$device->{index}");
3509 return 1;
3510 }
3511
ee034f5c 3512 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
8ce30dde
AD
3513
3514 my $devices_list = vm_devices_list($vmid);
3515 foreach my $opt (keys %{$devices_list}) {
3516 if (PVE::QemuServer::valid_drivename($opt)) {
3517 my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
3518 if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) {
3519 return 1;
3520 }
3521 }
3522 }
3523
3524 my $scsihwid="scsihw$controller";
3525
3526 vm_deviceunplug($vmid, $conf, $scsihwid);
3527
3528 return 1;
3529}
3530
281fedb3 3531sub qemu_add_pci_bridge {
40f28a9f
AD
3532 my ($storecfg, $conf, $vmid, $device) = @_;
3533
3534 my $bridges = {};
281fedb3
DM
3535
3536 my $bridgeid;
3537
40f28a9f
AD
3538 print_pci_addr($device, $bridges);
3539
3540 while (my ($k, $v) = each %$bridges) {
3541 $bridgeid = $k;
3542 }
fee46675 3543 return 1 if !defined($bridgeid) || $bridgeid < 1;
281fedb3 3544
40f28a9f
AD
3545 my $bridge = "pci.$bridgeid";
3546 my $devices_list = vm_devices_list($vmid);
3547
281fedb3 3548 if (!defined($devices_list->{$bridge})) {
fee46675 3549 vm_deviceplug($storecfg, $conf, $vmid, $bridge);
40f28a9f 3550 }
281fedb3 3551
40f28a9f
AD
3552 return 1;
3553}
3554
25088687
DM
3555sub qemu_set_link_status {
3556 my ($vmid, $device, $up) = @_;
3557
a1b7d579 3558 vm_mon_cmd($vmid, "set_link", name => $device,
25088687
DM
3559 up => $up ? JSON::true : JSON::false);
3560}
3561
2630d2a9
DA
3562sub qemu_netdevadd {
3563 my ($vmid, $conf, $device, $deviceid) = @_;
3564
3565 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
73aa03b8 3566 my %options = split(/[=,]/, $netdev);
2630d2a9 3567
73aa03b8
AD
3568 vm_mon_cmd($vmid, "netdev_add", %options);
3569 return 1;
2630d2a9
DA
3570}
3571
3572sub qemu_netdevdel {
3573 my ($vmid, $deviceid) = @_;
3574
89c1e0f4 3575 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2630d2a9
DA
3576}
3577
838776ab 3578sub qemu_cpu_hotplug {
8edc9c08 3579 my ($vmid, $conf, $vcpus) = @_;
838776ab 3580
8edc9c08
AD
3581 my $sockets = 1;
3582 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
3583 $sockets = $conf->{sockets} if $conf->{sockets};
3584 my $cores = $conf->{cores} || 1;
3585 my $maxcpus = $sockets * $cores;
838776ab 3586
8edc9c08 3587 $vcpus = $maxcpus if !$vcpus;
3a11fadb 3588
8edc9c08
AD
3589 die "you can't add more vcpus than maxcpus\n"
3590 if $vcpus > $maxcpus;
3a11fadb 3591
8edc9c08 3592 my $currentvcpus = $conf->{vcpus} || $maxcpus;
3a11fadb 3593 die "online cpu unplug is not yet possible\n"
8edc9c08 3594 if $vcpus < $currentvcpus;
838776ab 3595
8edc9c08
AD
3596 my $currentrunningvcpus = vm_mon_cmd($vmid, "query-cpus");
3597 die "vcpus in running vm is different than configuration\n"
3598 if scalar(@{$currentrunningvcpus}) != $currentvcpus;
838776ab 3599
8edc9c08 3600 for (my $i = $currentvcpus; $i < $vcpus; $i++) {
838776ab
AD
3601 vm_mon_cmd($vmid, "cpu-add", id => int($i));
3602 }
3603}
3604
4d3f29ed
AD
3605sub qemu_memory_hotplug {
3606 my ($vmid, $conf, $defaults, $opt, $value) = @_;
3607
3608 return $value if !check_running($vmid);
a1b7d579 3609
4d3f29ed 3610 my $memory = $conf->{memory} || $defaults->{memory};
a1b7d579 3611 $value = $defaults->{memory} if !$value;
4d3f29ed
AD
3612 return $value if $value == $memory;
3613
3614 my $static_memory = $STATICMEM;
3615 my $dimm_memory = $memory - $static_memory;
3616
3617 die "memory can't be lower than $static_memory MB" if $value < $static_memory;
3618 die "memory unplug is not yet available" if $value < $memory;
4d3f29ed
AD
3619 die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM;
3620
3621
3622 my $sockets = 1;
3623 $sockets = $conf->{sockets} if $conf->{sockets};
3624
e059fb4d
AD
3625 foreach_dimm($conf, $vmid, $value, $sockets, sub {
3626 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
3627
3628 return if $current_size <= $conf->{memory};
4d3f29ed
AD
3629
3630 eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) };
3631 if (my $err = $@) {
3632 eval { qemu_objectdel($vmid, "mem-$name"); };
3633 die $err;
3634 }
3635
3636 eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) };
3637 if (my $err = $@) {
3638 eval { qemu_objectdel($vmid, "mem-$name"); };
3639 die $err;
3640 }
3641 #update conf after each succesful module hotplug
e059fb4d 3642 $conf->{memory} = $current_size;
4d3f29ed 3643 update_config_nolock($vmid, $conf, 1);
e059fb4d 3644 });
4d3f29ed
AD
3645}
3646
affd2f88
AD
3647sub qemu_block_set_io_throttle {
3648 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
3649
f3f323a3
AD
3650 return if !check_running($vmid) ;
3651
f3f323a3
AD
3652 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));
3653
affd2f88
AD
3654}
3655
f5eb281a 3656# old code, only used to shutdown old VM after update
dab36e1e
DM
3657sub __read_avail {
3658 my ($fh, $timeout) = @_;
3659
3660 my $sel = new IO::Select;
3661 $sel->add($fh);
3662
3663 my $res = '';
3664 my $buf;
3665
3666 my @ready;
3667 while (scalar (@ready = $sel->can_read($timeout))) {
3668 my $count;
3669 if ($count = $fh->sysread($buf, 8192)) {
3670 if ($buf =~ /^(.*)\(qemu\) $/s) {
3671 $res .= $1;
3672 last;
3673 } else {
3674 $res .= $buf;
3675 }
3676 } else {
3677 if (!defined($count)) {
3678 die "$!\n";
3679 }
3680 last;
3681 }
3682 }
3683
3684 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 3685
dab36e1e
DM
3686 return $res;
3687}
3688
f5eb281a 3689# old code, only used to shutdown old VM after update
dab36e1e
DM
3690sub vm_monitor_command {
3691 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 3692
dab36e1e
DM
3693 my $res;
3694
3695 eval {
3696 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
3697
3698 my $sname = "${var_run_tmpdir}/$vmid.mon";
3699
3700 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
3701 die "unable to connect to VM $vmid socket - $!\n";
3702
3703 my $timeout = 3;
3704
3705 # hack: migrate sometime blocks the monitor (when migrate_downtime
3706 # is set)
3707 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3708 $timeout = 60*60; # 1 hour
3709 }
3710
3711 # read banner;
3712 my $data = __read_avail($sock, $timeout);
3713
3714 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3715 die "got unexpected qemu monitor banner\n";
3716 }
3717
3718 my $sel = new IO::Select;
3719 $sel->add($sock);
3720
3721 if (!scalar(my @ready = $sel->can_write($timeout))) {
3722 die "monitor write error - timeout";
3723 }
3724
3725 my $fullcmd = "$cmdstr\r";
3726
3727 # syslog('info', "VM $vmid monitor command: $cmdstr");
3728
3729 my $b;
3730 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3731 die "monitor write error - $!";
3732 }
3733
3734 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3735
3736 $timeout = 20;
3737
3738 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3739 $timeout = 60*60; # 1 hour
3740 } elsif ($cmdstr =~ m/^(eject|change)/) {
3741 $timeout = 60; # note: cdrom mount command is slow
3742 }
3743 if ($res = __read_avail($sock, $timeout)) {
3744
3745 my @lines = split("\r?\n", $res);
f5eb281a 3746
dab36e1e 3747 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 3748
dab36e1e
DM
3749 $res = join("\n", @lines);
3750 $res .= "\n";
3751 }
3752 };
3753
3754 my $err = $@;
3755
3756 if ($err) {
3757 syslog("err", "VM $vmid monitor command failed - $err");
3758 die $err;
3759 }
f5eb281a 3760
dab36e1e
DM
3761 return $res;
3762}
3763
c1175c92
AD
3764sub qemu_block_resize {
3765 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3766
ed221350 3767 my $running = check_running($vmid);
c1175c92
AD
3768
3769 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3770
3771 return if !$running;
3772
3773 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3774
3775}
3776
1ab0057c
AD
3777sub qemu_volume_snapshot {
3778 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3779
ed221350 3780 my $running = check_running($vmid);
1ab0057c 3781
e5eaa028
WL
3782 if ($running && do_snapshots_with_qemu($storecfg, $volid)){
3783 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3784 } else {
3785 PVE::Storage::volume_snapshot($storecfg, $volid, $snap);
3786 }
1ab0057c
AD
3787}
3788
fc46aff9
AD
3789sub qemu_volume_snapshot_delete {
3790 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3791
ed221350 3792 my $running = check_running($vmid);
fc46aff9
AD
3793
3794 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3795
3796 return if !$running;
3797
18bfb361 3798 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3799}
3800
264e519f
DM
3801sub set_migration_caps {
3802 my ($vmid) = @_;
a89fded1 3803
8b8345f3 3804 my $cap_ref = [];
a89fded1
AD
3805
3806 my $enabled_cap = {
8b8345f3
DM
3807 "auto-converge" => 1,
3808 "xbzrle" => 0,
3809 "x-rdma-pin-all" => 0,
3810 "zero-blocks" => 0,
a89fded1
AD
3811 };
3812
8b8345f3 3813 my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities");
a89fded1 3814
8b8345f3 3815 for my $supported_capability (@$supported_capabilities) {
b463a3ce
SP
3816 push @$cap_ref, {
3817 capability => $supported_capability->{capability},
22430fa2
DM
3818 state => $enabled_cap->{$supported_capability->{capability}} ? JSON::true : JSON::false,
3819 };
a89fded1
AD
3820 }
3821
8b8345f3
DM
3822 vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => $cap_ref);
3823}
a89fded1 3824
81d95ae1 3825my $fast_plug_option = {
7498eb64 3826 'lock' => 1,
81d95ae1 3827 'name' => 1,
a1b7d579 3828 'onboot' => 1,
81d95ae1
DM
3829 'shares' => 1,
3830 'startup' => 1,
3831};
3832
3a11fadb
DM
3833# hotplug changes in [PENDING]
3834# $selection hash can be used to only apply specified options, for
3835# example: { cores => 1 } (only apply changed 'cores')
3836# $errors ref is used to return error messages
c427973b 3837sub vmconfig_hotplug_pending {
3a11fadb 3838 my ($vmid, $conf, $storecfg, $selection, $errors) = @_;
c427973b 3839
8e90138a 3840 my $defaults = load_defaults();
c427973b
DM
3841
3842 # commit values which do not have any impact on running VM first
3a11fadb
DM
3843 # Note: those option cannot raise errors, we we do not care about
3844 # $selection and always apply them.
3845
3846 my $add_error = sub {
3847 my ($opt, $msg) = @_;
3848 $errors->{$opt} = "hotplug problem - $msg";
3849 };
c427973b
DM
3850
3851 my $changes = 0;
3852 foreach my $opt (keys %{$conf->{pending}}) { # add/change
81d95ae1 3853 if ($fast_plug_option->{$opt}) {
c427973b
DM
3854 $conf->{$opt} = $conf->{pending}->{$opt};
3855 delete $conf->{pending}->{$opt};
3856 $changes = 1;
3857 }
3858 }
3859
3860 if ($changes) {
3861 update_config_nolock($vmid, $conf, 1);
3862 $conf = load_config($vmid); # update/reload
3863 }
3864
b3c2bdd1 3865 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
c427973b 3866
3d7389fe
DM
3867 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3868 foreach my $opt (@delete) {
3a11fadb 3869 next if $selection && !$selection->{$opt};
3a11fadb 3870 eval {
51a6f637
AD
3871 if ($opt eq 'hotplug') {
3872 die "skip\n" if ($conf->{hotplug} =~ /memory/);
3873 } elsif ($opt eq 'tablet') {
b3c2bdd1 3874 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3875 if ($defaults->{tablet}) {
3876 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3877 } else {
3878 vm_deviceunplug($vmid, $conf, $opt);
3879 }
8edc9c08 3880 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3881 die "skip\n" if !$hotplug_features->{cpu};
8edc9c08 3882 qemu_cpu_hotplug($vmid, $conf, undef);
9c2f7069 3883 } elsif ($opt eq 'balloon') {
81d95ae1
DM
3884 # enable balloon device is not hotpluggable
3885 die "skip\n" if !defined($conf->{balloon}) || $conf->{balloon};
3886 } elsif ($fast_plug_option->{$opt}) {
3887 # do nothing
3eec5767 3888 } elsif ($opt =~ m/^net(\d+)$/) {
b3c2bdd1 3889 die "skip\n" if !$hotplug_features->{network};
3eec5767 3890 vm_deviceunplug($vmid, $conf, $opt);
a05cff86 3891 } elsif (valid_drivename($opt)) {
b3c2bdd1 3892 die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
19120f99
AD
3893 vm_deviceunplug($vmid, $conf, $opt);
3894 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
4d3f29ed
AD
3895 } elsif ($opt =~ m/^memory$/) {
3896 die "skip\n" if !$hotplug_features->{memory};
3897 qemu_memory_hotplug($vmid, $conf, $defaults, $opt);
3d7389fe 3898 } else {
e56beeda 3899 die "skip\n";
3d7389fe 3900 }
3a11fadb
DM
3901 };
3902 if (my $err = $@) {
e56beeda
DM
3903 &$add_error($opt, $err) if $err ne "skip\n";
3904 } else {
3a11fadb
DM
3905 # save new config if hotplug was successful
3906 delete $conf->{$opt};
3907 vmconfig_undelete_pending_option($conf, $opt);
3908 update_config_nolock($vmid, $conf, 1);
3909 $conf = load_config($vmid); # update/reload
3d7389fe 3910 }
3d7389fe
DM
3911 }
3912
3913 foreach my $opt (keys %{$conf->{pending}}) {
3a11fadb 3914 next if $selection && !$selection->{$opt};
3d7389fe 3915 my $value = $conf->{pending}->{$opt};
3a11fadb 3916 eval {
51a6f637
AD
3917 if ($opt eq 'hotplug') {
3918 die "skip\n" if ($value =~ /memory/) || ($value !~ /memory/ && $conf->{hotplug} =~ /memory/);
3919 } elsif ($opt eq 'tablet') {
b3c2bdd1 3920 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3921 if ($value == 1) {
3922 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3923 } elsif ($value == 0) {
3924 vm_deviceunplug($vmid, $conf, $opt);
3925 }
8edc9c08 3926 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3927 die "skip\n" if !$hotplug_features->{cpu};
3a11fadb
DM
3928 qemu_cpu_hotplug($vmid, $conf, $value);
3929 } elsif ($opt eq 'balloon') {
81d95ae1 3930 # enable/disable balloning device is not hotpluggable
8fe689e7 3931 my $old_balloon_enabled = !!(!defined($conf->{balloon}) || $conf->{balloon});
a1b7d579 3932 my $new_balloon_enabled = !!(!defined($conf->{pending}->{balloon}) || $conf->{pending}->{balloon});
81d95ae1
DM
3933 die "skip\n" if $old_balloon_enabled != $new_balloon_enabled;
3934
3a11fadb 3935 # allow manual ballooning if shares is set to zero
4cc1efa6 3936 if ((defined($conf->{shares}) && ($conf->{shares} == 0))) {
9c2f7069
AD
3937 my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
3938 vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
3939 }
a1b7d579 3940 } elsif ($opt =~ m/^net(\d+)$/) {
3eec5767 3941 # some changes can be done without hotplug
a1b7d579 3942 vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
b3c2bdd1 3943 $vmid, $opt, $value);
a05cff86
DM
3944 } elsif (valid_drivename($opt)) {
3945 # some changes can be done without hotplug
b3c2bdd1
DM
3946 vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk},
3947 $vmid, $opt, $value, 1);
4d3f29ed
AD
3948 } elsif ($opt =~ m/^memory$/) { #dimms
3949 die "skip\n" if !$hotplug_features->{memory};
3950 $value = qemu_memory_hotplug($vmid, $conf, $defaults, $opt, $value);
3a11fadb 3951 } else {
e56beeda 3952 die "skip\n"; # skip non-hot-pluggable options
3d7389fe 3953 }
3a11fadb
DM
3954 };
3955 if (my $err = $@) {
e56beeda
DM
3956 &$add_error($opt, $err) if $err ne "skip\n";
3957 } else {
3a11fadb
DM
3958 # save new config if hotplug was successful
3959 $conf->{$opt} = $value;
3960 delete $conf->{pending}->{$opt};
3961 update_config_nolock($vmid, $conf, 1);
3962 $conf = load_config($vmid); # update/reload
3d7389fe 3963 }
3d7389fe 3964 }
c427973b 3965}
055d554d
DM
3966
3967sub vmconfig_apply_pending {
3a11fadb 3968 my ($vmid, $conf, $storecfg) = @_;
c427973b
DM
3969
3970 # cold plug
055d554d
DM
3971
3972 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3973 foreach my $opt (@delete) { # delete
3974 die "internal error" if $opt =~ m/^unused/;
3975 $conf = load_config($vmid); # update/reload
3976 if (!defined($conf->{$opt})) {
3977 vmconfig_undelete_pending_option($conf, $opt);
3978 update_config_nolock($vmid, $conf, 1);
3979 } elsif (valid_drivename($opt)) {
3980 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
3981 vmconfig_undelete_pending_option($conf, $opt);
3982 delete $conf->{$opt};
3983 update_config_nolock($vmid, $conf, 1);
3984 } else {
3985 vmconfig_undelete_pending_option($conf, $opt);
3986 delete $conf->{$opt};
3987 update_config_nolock($vmid, $conf, 1);
3988 }
3989 }
3990
3991 $conf = load_config($vmid); # update/reload
3992
3993 foreach my $opt (keys %{$conf->{pending}}) { # add/change
3994 $conf = load_config($vmid); # update/reload
3995
3996 if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) {
3997 # skip if nothing changed
3998 } elsif (valid_drivename($opt)) {
3999 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
4000 if defined($conf->{$opt});
4001 $conf->{$opt} = $conf->{pending}->{$opt};
4002 } else {
4003 $conf->{$opt} = $conf->{pending}->{$opt};
4004 }
4005
4006 delete $conf->{pending}->{$opt};
4007 update_config_nolock($vmid, $conf, 1);
4008 }
4009}
4010
3eec5767
DM
4011my $safe_num_ne = sub {
4012 my ($a, $b) = @_;
4013
4014 return 0 if !defined($a) && !defined($b);
4015 return 1 if !defined($a);
4016 return 1 if !defined($b);
4017
4018 return $a != $b;
4019};
4020
4021my $safe_string_ne = sub {
4022 my ($a, $b) = @_;
4023
4024 return 0 if !defined($a) && !defined($b);
4025 return 1 if !defined($a);
4026 return 1 if !defined($b);
4027
4028 return $a ne $b;
4029};
4030
4031sub vmconfig_update_net {
b3c2bdd1 4032 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value) = @_;
3eec5767
DM
4033
4034 my $newnet = parse_net($value);
4035
4036 if ($conf->{$opt}) {
4037 my $oldnet = parse_net($conf->{$opt});
4038
4039 if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
4040 &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
4041 &$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
4042 !($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
4043
4044 # for non online change, we try to hot-unplug
7196b757 4045 die "skip\n" if !$hotplug;
3eec5767
DM
4046 vm_deviceunplug($vmid, $conf, $opt);
4047 } else {
4048
4049 die "internal error" if $opt !~ m/net(\d+)/;
4050 my $iface = "tap${vmid}i$1";
a1b7d579 4051
3eec5767
DM
4052 if (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
4053 PVE::Network::tap_rate_limit($iface, $newnet->{rate});
4054 }
4055
25088687
DM
4056 if (&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) ||
4057 &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) ||
4058 &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})) {
3eec5767
DM
4059 PVE::Network::tap_unplug($iface);
4060 PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
4061 }
38c590d9 4062
25088687
DM
4063 if (&$safe_string_ne($oldnet->{link_down}, $newnet->{link_down})) {
4064 qemu_set_link_status($vmid, $opt, !$newnet->{link_down});
4065 }
4066
38c590d9 4067 return 1;
3eec5767
DM
4068 }
4069 }
a1b7d579 4070
7196b757 4071 if ($hotplug) {
38c590d9
DM
4072 vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
4073 } else {
4074 die "skip\n";
4075 }
3eec5767
DM
4076}
4077
a05cff86 4078sub vmconfig_update_disk {
b3c2bdd1 4079 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $force) = @_;
a05cff86
DM
4080
4081 # fixme: do we need force?
4082
4083 my $drive = parse_drive($opt, $value);
4084
4085 if ($conf->{$opt}) {
4086
4087 if (my $old_drive = parse_drive($opt, $conf->{$opt})) {
4088
4089 my $media = $drive->{media} || 'disk';
4090 my $oldmedia = $old_drive->{media} || 'disk';
4091 die "unable to change media type\n" if $media ne $oldmedia;
4092
4093 if (!drive_is_cdrom($old_drive)) {
4094
a1b7d579 4095 if ($drive->{file} ne $old_drive->{file}) {
a05cff86 4096
7196b757 4097 die "skip\n" if !$hotplug;
a05cff86
DM
4098
4099 # unplug and register as unused
4100 vm_deviceunplug($vmid, $conf, $opt);
4101 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
a1b7d579 4102
a05cff86
DM
4103 } else {
4104 # update existing disk
4105
4106 # skip non hotpluggable value
a1b7d579 4107 if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) ||
22de899a 4108 &$safe_string_ne($drive->{iothread}, $old_drive->{iothread}) ||
6e11f143 4109 &$safe_string_ne($drive->{queues}, $old_drive->{queues}) ||
a05cff86
DM
4110 &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
4111 die "skip\n";
4112 }
4113
4114 # apply throttle
4115 if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
4116 &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
4117 &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
4118 &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
4119 &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
4120 &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
4121 &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
4122 &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
4123 &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
4124 &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
4125 &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
4126 &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
a1b7d579 4127
a05cff86
DM
4128 qemu_block_set_io_throttle($vmid,"drive-$opt",
4129 ($drive->{mbps} || 0)*1024*1024,
4130 ($drive->{mbps_rd} || 0)*1024*1024,
4131 ($drive->{mbps_wr} || 0)*1024*1024,
4132 $drive->{iops} || 0,
4133 $drive->{iops_rd} || 0,
4134 $drive->{iops_wr} || 0,
4135 ($drive->{mbps_max} || 0)*1024*1024,
4136 ($drive->{mbps_rd_max} || 0)*1024*1024,
4137 ($drive->{mbps_wr_max} || 0)*1024*1024,
4138 $drive->{iops_max} || 0,
4139 $drive->{iops_rd_max} || 0,
4140 $drive->{iops_wr_max} || 0);
4141
4142 }
a1b7d579 4143
a05cff86
DM
4144 return 1;
4145 }
4de1bb25
DM
4146
4147 } else { # cdrom
a1b7d579 4148
4de1bb25
DM
4149 if ($drive->{file} eq 'none') {
4150 vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
4151 } else {
4152 my $path = get_iso_path($storecfg, $vmid, $drive->{file});
4153 vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
4154 vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
4155 }
a1b7d579 4156
34758d66 4157 return 1;
a05cff86
DM
4158 }
4159 }
4160 }
4161
a1b7d579 4162 die "skip\n" if !$hotplug || $opt =~ m/(ide|sata)(\d+)/;
4de1bb25
DM
4163 # hotplug new disks
4164 vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
a05cff86
DM
4165}
4166
1e3baf05 4167sub vm_start {
1d794448 4168 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
1e3baf05 4169
6b64503e 4170 lock_config($vmid, sub {
7e8dcf2c 4171 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 4172
8b43bc11 4173 die "you can't start a vm if it's a template\n" if is_template($conf);
3dcb98d5 4174
6b64503e 4175 check_lock($conf) if !$skiplock;
1e3baf05 4176
7e8dcf2c 4177 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 4178
055d554d 4179 if (!$statefile && scalar(keys %{$conf->{pending}})) {
3a11fadb 4180 vmconfig_apply_pending($vmid, $conf, $storecfg);
055d554d
DM
4181 $conf = load_config($vmid); # update/reload
4182 }
4183
6c47d546
DM
4184 my $defaults = load_defaults();
4185
4186 # set environment variable useful inside network script
4187 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
4188
1d794448 4189 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 4190
1e3baf05 4191 my $migrate_port = 0;
5bc1e039 4192 my $migrate_uri;
1e3baf05
DM
4193 if ($statefile) {
4194 if ($statefile eq 'tcp') {
5bc1e039
SP
4195 my $localip = "localhost";
4196 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
4197 if ($datacenterconf->{migration_unsecure}) {
4198 my $nodename = PVE::INotify::nodename();
4199 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
4200 }
f9a971e0 4201 $migrate_port = PVE::Tools::next_migrate_port();
5bc1e039 4202 $migrate_uri = "tcp:${localip}:${migrate_port}";
6c47d546
DM
4203 push @$cmd, '-incoming', $migrate_uri;
4204 push @$cmd, '-S';
1e3baf05 4205 } else {
6c47d546 4206 push @$cmd, '-loadstate', $statefile;
1e3baf05 4207 }
91bd6c90
DM
4208 } elsif ($paused) {
4209 push @$cmd, '-S';
1e3baf05
DM
4210 }
4211
1e3baf05 4212 # host pci devices
040b06b7
DA
4213 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
4214 my $d = parse_hostpci($conf->{"hostpci$i"});
4215 next if !$d;
b1f72af6
AD
4216 my $pcidevices = $d->{pciid};
4217 foreach my $pcidevice (@$pcidevices) {
4218 my $pciid = $pcidevice->{id}.".".$pcidevice->{function};
000fc0a2 4219
b1f72af6
AD
4220 my $info = pci_device_info("0000:$pciid");
4221 die "IOMMU not present\n" if !check_iommu_support();
4222 die "no pci device info for device '$pciid'\n" if !$info;
000fc0a2 4223
b1f72af6
AD
4224 if ($d->{driver} && $d->{driver} eq "vfio") {
4225 die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid);
4226 } else {
4227 die "can't unbind/bind to stub pci device '$pciid'\n" if !pci_dev_bind_to_stub($info);
4228 }
4229
8f3e88af 4230 die "can't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info);
b1f72af6 4231 }
040b06b7 4232 }
1e3baf05
DM
4233
4234 PVE::Storage::activate_volumes($storecfg, $vollist);
4235
585b6e28
DM
4236 eval { run_command($cmd, timeout => $statefile ? undef : 30,
4237 umask => 0077); };
1e3baf05 4238 my $err = $@;
ff1a2432 4239 die "start failed: $err" if $err;
1e3baf05 4240
5bc1e039 4241 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 4242
8c609afd 4243 if ($statefile && $statefile ne 'tcp') {
95381ce0 4244 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 4245 warn $@ if $@;
62de2cbd
DM
4246 }
4247
1d794448 4248 if ($migratedfrom) {
a89fded1
AD
4249
4250 eval {
8e90138a 4251 set_migration_caps($vmid);
a89fded1 4252 };
1d794448 4253 warn $@ if $@;
a89fded1 4254
1d794448
DM
4255 if ($spice_port) {
4256 print "spice listens on port $spice_port\n";
4257 if ($spice_ticket) {
8e90138a
DM
4258 vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
4259 vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
4260 }
4261 }
4262
1d794448 4263 } else {
4ec05c4c 4264
15b1fc93 4265 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 4266 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 4267 if $conf->{balloon};
4ec05c4c 4268 }
25088687
DM
4269
4270 foreach my $opt (keys %$conf) {
4271 next if $opt !~ m/^net\d+$/;
4272 my $nicconf = parse_net($conf->{$opt});
4273 qemu_set_link_status($vmid, $opt, 0) if $nicconf->{link_down};
4274 }
e18b0b99 4275 }
a1b7d579 4276
eb065317
AD
4277 vm_mon_cmd_nocheck($vmid, 'qom-set',
4278 path => "machine/peripheral/balloon0",
4279 property => "guest-stats-polling-interval",
4280 value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
4281
1e3baf05
DM
4282 });
4283}
4284
0eedc444
AD
4285sub vm_mon_cmd {
4286 my ($vmid, $execute, %params) = @_;
4287
26f11676
DM
4288 my $cmd = { execute => $execute, arguments => \%params };
4289 vm_qmp_command($vmid, $cmd);
0eedc444
AD
4290}
4291
4292sub vm_mon_cmd_nocheck {
4293 my ($vmid, $execute, %params) = @_;
4294
26f11676
DM
4295 my $cmd = { execute => $execute, arguments => \%params };
4296 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
4297}
4298
c971c4f2 4299sub vm_qmp_command {
c5a07de5 4300 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 4301
c971c4f2 4302 my $res;
26f11676 4303
14db5366
DM
4304 my $timeout;
4305 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
4306 $timeout = $cmd->{arguments}->{timeout};
4307 delete $cmd->{arguments}->{timeout};
4308 }
be190583 4309
c971c4f2
AD
4310 eval {
4311 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
7a6c2150
DM
4312 my $sname = qmp_socket($vmid);
4313 if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga
c5a07de5 4314 my $qmpclient = PVE::QMPClient->new();
dab36e1e 4315
14db5366 4316 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
c5a07de5 4317 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
dab36e1e
DM
4318 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
4319 if scalar(%{$cmd->{arguments}});
4320 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
4321 } else {
4322 die "unable to open monitor socket\n";
4323 }
c971c4f2 4324 };
26f11676 4325 if (my $err = $@) {
c971c4f2
AD
4326 syslog("err", "VM $vmid qmp command failed - $err");
4327 die $err;
4328 }
4329
4330 return $res;
4331}
4332
9df5cbcc
DM
4333sub vm_human_monitor_command {
4334 my ($vmid, $cmdline) = @_;
4335
4336 my $res;
4337
f5eb281a 4338 my $cmd = {
9df5cbcc
DM
4339 execute => 'human-monitor-command',
4340 arguments => { 'command-line' => $cmdline},
4341 };
4342
4343 return vm_qmp_command($vmid, $cmd);
4344}
4345
1e3baf05
DM
4346sub vm_commandline {
4347 my ($storecfg, $vmid) = @_;
4348
6b64503e 4349 my $conf = load_config($vmid);
1e3baf05
DM
4350
4351 my $defaults = load_defaults();
4352
6b64503e 4353 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 4354
6b64503e 4355 return join(' ', @$cmd);
1e3baf05
DM
4356}
4357
4358sub vm_reset {
4359 my ($vmid, $skiplock) = @_;
4360
6b64503e 4361 lock_config($vmid, sub {
1e3baf05 4362
6b64503e 4363 my $conf = load_config($vmid);
1e3baf05 4364
6b64503e 4365 check_lock($conf) if !$skiplock;
1e3baf05 4366
816e2c4a 4367 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
4368 });
4369}
4370
4371sub get_vm_volumes {
4372 my ($conf) = @_;
1e3baf05 4373
ff1a2432 4374 my $vollist = [];
d5769dc2
DM
4375 foreach_volid($conf, sub {
4376 my ($volid, $is_cdrom) = @_;
ff1a2432 4377
d5769dc2 4378 return if $volid =~ m|^/|;
ff1a2432 4379
d5769dc2
DM
4380 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
4381 return if !$sid;
ff1a2432
DM
4382
4383 push @$vollist, $volid;
1e3baf05 4384 });
ff1a2432
DM
4385
4386 return $vollist;
4387}
4388
4389sub vm_stop_cleanup {
70b04821 4390 my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
ff1a2432 4391
745fed70
DM
4392 eval {
4393 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 4394
254575e9
DM
4395 if (!$keepActive) {
4396 my $vollist = get_vm_volumes($conf);
4397 PVE::Storage::deactivate_volumes($storecfg, $vollist);
4398 }
a1b7d579 4399
ab6a046f 4400 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
4401 unlink "/var/run/qemu-server/${vmid}.$ext";
4402 }
a1b7d579 4403
70b04821 4404 vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
745fed70
DM
4405 };
4406 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
4407}
4408
e6c3b671 4409# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
4410# We need that when migration VMs to other nodes (files already moved)
4411# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 4412sub vm_stop {
af30308f 4413 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 4414
9269013a 4415 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 4416
af30308f
DM
4417 if ($migratedfrom){
4418 my $pid = check_running($vmid, $nocheck, $migratedfrom);
4419 kill 15, $pid if $pid;
4420 my $conf = load_config($vmid, $migratedfrom);
70b04821 4421 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 0);
af30308f
DM
4422 return;
4423 }
4424
e6c3b671 4425 lock_config($vmid, sub {
1e3baf05 4426
e6c3b671 4427 my $pid = check_running($vmid, $nocheck);
ff1a2432 4428 return if !$pid;
1e3baf05 4429
ff1a2432 4430 my $conf;
e6c3b671 4431 if (!$nocheck) {
ff1a2432 4432 $conf = load_config($vmid);
e6c3b671 4433 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
4434 if (!defined($timeout) && $shutdown && $conf->{startup}) {
4435 my $opts = parse_startup($conf->{startup});
4436 $timeout = $opts->{down} if $opts->{down};
4437 }
e6c3b671 4438 }
19672434 4439
7f4a5b5a 4440 $timeout = 60 if !defined($timeout);
67fb9de6 4441
9269013a
DM
4442 eval {
4443 if ($shutdown) {
fbda7965 4444 if (defined($conf) && $conf->{agent}) {
2ea54503 4445 vm_qmp_command($vmid, { execute => "guest-shutdown" }, $nocheck);
1c0c1c17 4446 } else {
2ea54503 4447 vm_qmp_command($vmid, { execute => "system_powerdown" }, $nocheck);
1c0c1c17 4448 }
9269013a 4449 } else {
2ea54503 4450 vm_qmp_command($vmid, { execute => "quit" }, $nocheck);
afdb31d5 4451 }
9269013a 4452 };
1e3baf05
DM
4453 my $err = $@;
4454
4455 if (!$err) {
1e3baf05 4456 my $count = 0;
e6c3b671 4457 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4458 $count++;
4459 sleep 1;
4460 }
4461
4462 if ($count >= $timeout) {
9269013a
DM
4463 if ($force) {
4464 warn "VM still running - terminating now with SIGTERM\n";
4465 kill 15, $pid;
4466 } else {
4467 die "VM quit/powerdown failed - got timeout\n";
4468 }
4469 } else {
70b04821 4470 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
9269013a 4471 return;
1e3baf05
DM
4472 }
4473 } else {
9269013a
DM
4474 if ($force) {
4475 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
4476 kill 15, $pid;
4477 } else {
afdb31d5 4478 die "VM quit/powerdown failed\n";
9269013a 4479 }
1e3baf05
DM
4480 }
4481
4482 # wait again
ff1a2432 4483 $timeout = 10;
1e3baf05
DM
4484
4485 my $count = 0;
e6c3b671 4486 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4487 $count++;
4488 sleep 1;
4489 }
4490
4491 if ($count >= $timeout) {
ff1a2432 4492 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 4493 kill 9, $pid;
ff1a2432 4494 sleep 1;
1e3baf05
DM
4495 }
4496
70b04821 4497 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
ff1a2432 4498 });
1e3baf05
DM
4499}
4500
4501sub vm_suspend {
4502 my ($vmid, $skiplock) = @_;
4503
6b64503e 4504 lock_config($vmid, sub {
1e3baf05 4505
6b64503e 4506 my $conf = load_config($vmid);
1e3baf05 4507
051347aa 4508 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
bcb7c9cf 4509
f77f91f3 4510 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
4511 });
4512}
4513
4514sub vm_resume {
4515 my ($vmid, $skiplock) = @_;
4516
6b64503e 4517 lock_config($vmid, sub {
1e3baf05 4518
6b64503e 4519 my $conf = load_config($vmid);
1e3baf05 4520
051347aa 4521 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
1e3baf05 4522
12060fe8 4523 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
4524 });
4525}
4526
5fdbe4f0
DM
4527sub vm_sendkey {
4528 my ($vmid, $skiplock, $key) = @_;
1e3baf05 4529
6b64503e 4530 lock_config($vmid, sub {
1e3baf05 4531
6b64503e 4532 my $conf = load_config($vmid);
f5eb281a 4533
7b7c6d1b
DM
4534 # there is no qmp command, so we use the human monitor command
4535 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
4536 });
4537}
4538
4539sub vm_destroy {
4540 my ($storecfg, $vmid, $skiplock) = @_;
4541
6b64503e 4542 lock_config($vmid, sub {
1e3baf05 4543
6b64503e 4544 my $conf = load_config($vmid);
1e3baf05 4545
6b64503e 4546 check_lock($conf) if !$skiplock;
1e3baf05 4547
ff1a2432
DM
4548 if (!check_running($vmid)) {
4549 fairsched_rmnod($vmid); # try to destroy group
4550 destroy_vm($storecfg, $vmid);
4551 } else {
4552 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
4553 }
4554 });
4555}
4556
1e3baf05
DM
4557# pci helpers
4558
4559sub file_write {
4560 my ($filename, $buf) = @_;
4561
6b64503e 4562 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
4563 return undef if !$fh;
4564
4565 my $res = print $fh $buf;
4566
4567 $fh->close();
4568
4569 return $res;
4570}
4571
4572sub pci_device_info {
4573 my ($name) = @_;
4574
4575 my $res;
4576
4577 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
4578 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
4579
4580 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
4581 return undef if !defined($irq) || $irq !~ m/^\d+$/;
4582
4583 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
4584 return undef if !defined($vendor) || $vendor !~ s/^0x//;
4585
4586 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
4587 return undef if !defined($product) || $product !~ s/^0x//;
4588
4589 $res = {
4590 name => $name,
4591 vendor => $vendor,
4592 product => $product,
4593 domain => $domain,
4594 bus => $bus,
4595 slot => $slot,
4596 func => $func,
4597 irq => $irq,
4598 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
4599 };
4600
4601 return $res;
4602}
4603
4604sub pci_dev_reset {
4605 my ($dev) = @_;
4606
4607 my $name = $dev->{name};
4608
4609 my $fn = "$pcisysfs/devices/$name/reset";
4610
6b64503e 4611 return file_write($fn, "1");
1e3baf05
DM
4612}
4613
4614sub pci_dev_bind_to_stub {
4615 my ($dev) = @_;
4616
4617 my $name = $dev->{name};
4618
4619 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
4620 return 1 if -d $testdir;
4621
4622 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 4623 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
4624
4625 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 4626 if (!file_write($fn, $name)) {
1e3baf05
DM
4627 return undef if -f $fn;
4628 }
4629
4630 $fn = "$pcisysfs/drivers/pci-stub/bind";
4631 if (! -d $testdir) {
6b64503e 4632 return undef if !file_write($fn, $name);
1e3baf05
DM
4633 }
4634
4635 return -d $testdir;
4636}
4637
000fc0a2
SP
4638sub pci_dev_bind_to_vfio {
4639 my ($dev) = @_;
4640
4641 my $name = $dev->{name};
4642
4643 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4644
4645 if (!-d $vfio_basedir) {
4646 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4647 }
4648 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4649
4650 my $testdir = "$vfio_basedir/$name";
4651 return 1 if -d $testdir;
4652
4653 my $data = "$dev->{vendor} $dev->{product}";
4654 return undef if !file_write("$vfio_basedir/new_id", $data);
4655
4656 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4657 if (!file_write($fn, $name)) {
4658 return undef if -f $fn;
4659 }
4660
4661 $fn = "$vfio_basedir/bind";
4662 if (! -d $testdir) {
4663 return undef if !file_write($fn, $name);
4664 }
4665
4666 return -d $testdir;
4667}
4668
4669sub pci_dev_group_bind_to_vfio {
4670 my ($pciid) = @_;
4671
4672 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4673
4674 if (!-d $vfio_basedir) {
4675 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4676 }
4677 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4678
4679 # get IOMMU group devices
4680 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
4681 my @devs = grep /^0000:/, readdir($D);
4682 closedir($D);
4683
4684 foreach my $pciid (@devs) {
4685 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
f8fa2ed7
SP
4686
4687 # pci bridges, switches or root ports are not supported
4688 # they have a pci_bus subdirectory so skip them
4689 next if (-e "$pcisysfs/devices/$pciid/pci_bus");
4690
000fc0a2
SP
4691 my $info = pci_device_info($1);
4692 pci_dev_bind_to_vfio($info) || die "Cannot bind $pciid to vfio\n";
4693 }
4694
4695 return 1;
4696}
4697
afdb31d5 4698sub print_pci_addr {
5bdcf937 4699 my ($id, $bridges) = @_;
6b64503e 4700
72a063e4 4701 my $res = '';
6b64503e 4702 my $devices = {
24f0d39a 4703 piix3 => { bus => 0, addr => 1 },
e5f7f8ed 4704 #addr2 : first videocard
13b5a753 4705 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 4706 watchdog => { bus => 0, addr => 4 },
a1b7d579 4707 scsihw0 => { bus => 0, addr => 5 },
6731a4cf 4708 'pci.3' => { bus => 0, addr => 5 }, #can also be used for virtio-scsi-single bridge
cdd20088 4709 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 4710 ahci0 => { bus => 0, addr => 7 },
ab6a046f 4711 qga0 => { bus => 0, addr => 8 },
1011b570 4712 spice => { bus => 0, addr => 9 },
6b64503e
DM
4713 virtio0 => { bus => 0, addr => 10 },
4714 virtio1 => { bus => 0, addr => 11 },
4715 virtio2 => { bus => 0, addr => 12 },
4716 virtio3 => { bus => 0, addr => 13 },
4717 virtio4 => { bus => 0, addr => 14 },
4718 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
4719 hostpci0 => { bus => 0, addr => 16 },
4720 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
4721 net0 => { bus => 0, addr => 18 },
4722 net1 => { bus => 0, addr => 19 },
4723 net2 => { bus => 0, addr => 20 },
4724 net3 => { bus => 0, addr => 21 },
4725 net4 => { bus => 0, addr => 22 },
4726 net5 => { bus => 0, addr => 23 },
2fa3151e
AD
4727 vga1 => { bus => 0, addr => 24 },
4728 vga2 => { bus => 0, addr => 25 },
4729 vga3 => { bus => 0, addr => 26 },
5cffb2d2
AD
4730 hostpci2 => { bus => 0, addr => 27 },
4731 hostpci3 => { bus => 0, addr => 28 },
e5f7f8ed 4732 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
4733 'pci.1' => { bus => 0, addr => 30 },
4734 'pci.2' => { bus => 0, addr => 31 },
4735 'net6' => { bus => 1, addr => 1 },
4736 'net7' => { bus => 1, addr => 2 },
4737 'net8' => { bus => 1, addr => 3 },
4738 'net9' => { bus => 1, addr => 4 },
4739 'net10' => { bus => 1, addr => 5 },
4740 'net11' => { bus => 1, addr => 6 },
4741 'net12' => { bus => 1, addr => 7 },
4742 'net13' => { bus => 1, addr => 8 },
4743 'net14' => { bus => 1, addr => 9 },
4744 'net15' => { bus => 1, addr => 10 },
4745 'net16' => { bus => 1, addr => 11 },
4746 'net17' => { bus => 1, addr => 12 },
4747 'net18' => { bus => 1, addr => 13 },
4748 'net19' => { bus => 1, addr => 14 },
4749 'net20' => { bus => 1, addr => 15 },
4750 'net21' => { bus => 1, addr => 16 },
4751 'net22' => { bus => 1, addr => 17 },
4752 'net23' => { bus => 1, addr => 18 },
4753 'net24' => { bus => 1, addr => 19 },
4754 'net25' => { bus => 1, addr => 20 },
4755 'net26' => { bus => 1, addr => 21 },
4756 'net27' => { bus => 1, addr => 22 },
4757 'net28' => { bus => 1, addr => 23 },
4758 'net29' => { bus => 1, addr => 24 },
4759 'net30' => { bus => 1, addr => 25 },
4760 'net31' => { bus => 1, addr => 26 },
4761 'virtio6' => { bus => 2, addr => 1 },
4762 'virtio7' => { bus => 2, addr => 2 },
4763 'virtio8' => { bus => 2, addr => 3 },
4764 'virtio9' => { bus => 2, addr => 4 },
4765 'virtio10' => { bus => 2, addr => 5 },
4766 'virtio11' => { bus => 2, addr => 6 },
4767 'virtio12' => { bus => 2, addr => 7 },
4768 'virtio13' => { bus => 2, addr => 8 },
4769 'virtio14' => { bus => 2, addr => 9 },
4770 'virtio15' => { bus => 2, addr => 10 },
6731a4cf
AD
4771 'virtioscsi0' => { bus => 3, addr => 1 },
4772 'virtioscsi1' => { bus => 3, addr => 2 },
4773 'virtioscsi2' => { bus => 3, addr => 3 },
4774 'virtioscsi3' => { bus => 3, addr => 4 },
4775 'virtioscsi4' => { bus => 3, addr => 5 },
4776 'virtioscsi5' => { bus => 3, addr => 6 },
4777 'virtioscsi6' => { bus => 3, addr => 7 },
4778 'virtioscsi7' => { bus => 3, addr => 8 },
4779 'virtioscsi8' => { bus => 3, addr => 9 },
4780 'virtioscsi9' => { bus => 3, addr => 10 },
4781 'virtioscsi10' => { bus => 3, addr => 11 },
4782 'virtioscsi11' => { bus => 3, addr => 12 },
4783 'virtioscsi12' => { bus => 3, addr => 13 },
4784 'virtioscsi13' => { bus => 3, addr => 14 },
4785 'virtioscsi14' => { bus => 3, addr => 15 },
4786 'virtioscsi15' => { bus => 3, addr => 16 },
4787 'virtioscsi16' => { bus => 3, addr => 17 },
4788 'virtioscsi17' => { bus => 3, addr => 18 },
4789 'virtioscsi18' => { bus => 3, addr => 19 },
4790 'virtioscsi19' => { bus => 3, addr => 20 },
4791 'virtioscsi20' => { bus => 3, addr => 21 },
4792 'virtioscsi21' => { bus => 3, addr => 22 },
4793 'virtioscsi22' => { bus => 3, addr => 23 },
4794 'virtioscsi23' => { bus => 3, addr => 24 },
4795 'virtioscsi24' => { bus => 3, addr => 25 },
4796 'virtioscsi25' => { bus => 3, addr => 26 },
4797 'virtioscsi26' => { bus => 3, addr => 27 },
4798 'virtioscsi27' => { bus => 3, addr => 28 },
4799 'virtioscsi28' => { bus => 3, addr => 29 },
4800 'virtioscsi29' => { bus => 3, addr => 30 },
4801 'virtioscsi30' => { bus => 3, addr => 31 },
4802
6b64503e
DM
4803 };
4804
4805 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 4806 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
4807 my $bus = $devices->{$id}->{bus};
4808 $res = ",bus=pci.$bus,addr=$addr";
98627641 4809 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
4810 }
4811 return $res;
4812
4813}
4814
2e3b7e2a
AD
4815sub print_pcie_addr {
4816 my ($id) = @_;
4817
4818 my $res = '';
4819 my $devices = {
4820 hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 },
4821 hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 },
4822 hostpci2 => { bus => "ich9-pcie-port-3", addr => 0 },
4823 hostpci3 => { bus => "ich9-pcie-port-4", addr => 0 },
4824 };
4825
4826 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
4827 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
4828 my $bus = $devices->{$id}->{bus};
4829 $res = ",bus=$bus,addr=$addr";
4830 }
4831 return $res;
4832
4833}
4834
3e16d5fc
DM
4835# vzdump restore implementaion
4836
ed221350 4837sub tar_archive_read_firstfile {
3e16d5fc 4838 my $archive = shift;
afdb31d5 4839
3e16d5fc
DM
4840 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
4841
4842 # try to detect archive type first
4843 my $pid = open (TMP, "tar tf '$archive'|") ||
4844 die "unable to open file '$archive'\n";
4845 my $firstfile = <TMP>;
4846 kill 15, $pid;
4847 close TMP;
4848
4849 die "ERROR: archive contaions no data\n" if !$firstfile;
4850 chomp $firstfile;
4851
4852 return $firstfile;
4853}
4854
ed221350
DM
4855sub tar_restore_cleanup {
4856 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
4857
4858 print STDERR "starting cleanup\n";
4859
4860 if (my $fd = IO::File->new($statfile, "r")) {
4861 while (defined(my $line = <$fd>)) {
4862 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4863 my $volid = $2;
4864 eval {
4865 if ($volid =~ m|^/|) {
4866 unlink $volid || die 'unlink failed\n';
4867 } else {
ed221350 4868 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 4869 }
afdb31d5 4870 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
4871 };
4872 print STDERR "unable to cleanup '$volid' - $@" if $@;
4873 } else {
4874 print STDERR "unable to parse line in statfile - $line";
afdb31d5 4875 }
3e16d5fc
DM
4876 }
4877 $fd->close();
4878 }
4879}
4880
4881sub restore_archive {
a0d1b1a2 4882 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 4883
91bd6c90
DM
4884 my $format = $opts->{format};
4885 my $comp;
4886
4887 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
4888 $format = 'tar' if !$format;
4889 $comp = 'gzip';
4890 } elsif ($archive =~ m/\.tar$/) {
4891 $format = 'tar' if !$format;
4892 } elsif ($archive =~ m/.tar.lzo$/) {
4893 $format = 'tar' if !$format;
4894 $comp = 'lzop';
4895 } elsif ($archive =~ m/\.vma$/) {
4896 $format = 'vma' if !$format;
4897 } elsif ($archive =~ m/\.vma\.gz$/) {
4898 $format = 'vma' if !$format;
4899 $comp = 'gzip';
4900 } elsif ($archive =~ m/\.vma\.lzo$/) {
4901 $format = 'vma' if !$format;
4902 $comp = 'lzop';
4903 } else {
4904 $format = 'vma' if !$format; # default
4905 }
4906
4907 # try to detect archive format
4908 if ($format eq 'tar') {
4909 return restore_tar_archive($archive, $vmid, $user, $opts);
4910 } else {
4911 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
4912 }
4913}
4914
4915sub restore_update_config_line {
4916 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
4917
4918 return if $line =~ m/^\#qmdump\#/;
4919 return if $line =~ m/^\#vzdump\#/;
4920 return if $line =~ m/^lock:/;
4921 return if $line =~ m/^unused\d+:/;
4922 return if $line =~ m/^parent:/;
ca3e4fa4 4923 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
4924
4925 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
4926 # try to convert old 1.X settings
4927 my ($id, $ind, $ethcfg) = ($1, $2, $3);
4928 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
4929 my ($model, $macaddr) = split(/\=/, $devconfig);
4930 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
4931 my $net = {
4932 model => $model,
4933 bridge => "vmbr$ind",
4934 macaddr => $macaddr,
4935 };
4936 my $netstr = print_net($net);
4937
4938 print $outfd "net$cookie->{netcount}: $netstr\n";
4939 $cookie->{netcount}++;
4940 }
4941 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
4942 my ($id, $netstr) = ($1, $2);
4943 my $net = parse_net($netstr);
4944 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
4945 $netstr = print_net($net);
4946 print $outfd "$id: $netstr\n";
4947 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
4948 my $virtdev = $1;
907ea891 4949 my $value = $3;
91bd6c90
DM
4950 if ($line =~ m/backup=no/) {
4951 print $outfd "#$line";
4952 } elsif ($virtdev && $map->{$virtdev}) {
ed221350 4953 my $di = parse_drive($virtdev, $value);
8fd57431 4954 delete $di->{format}; # format can change on restore
91bd6c90 4955 $di->{file} = $map->{$virtdev};
ed221350 4956 $value = print_drive($vmid, $di);
91bd6c90
DM
4957 print $outfd "$virtdev: $value\n";
4958 } else {
4959 print $outfd $line;
4960 }
4961 } else {
4962 print $outfd $line;
4963 }
4964}
4965
4966sub scan_volids {
4967 my ($cfg, $vmid) = @_;
4968
4969 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
4970
4971 my $volid_hash = {};
4972 foreach my $storeid (keys %$info) {
4973 foreach my $item (@{$info->{$storeid}}) {
4974 next if !($item->{volid} && $item->{size});
5996a936 4975 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
4976 $volid_hash->{$item->{volid}} = $item;
4977 }
4978 }
4979
4980 return $volid_hash;
4981}
4982
a8e2f942
DM
4983sub get_used_paths {
4984 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
4985
4986 my $used_path = {};
4987
4988 my $scan_config = sub {
4989 my ($cref, $snapname) = @_;
4990
4991 foreach my $key (keys %$cref) {
4992 my $value = $cref->{$key};
4993 if (valid_drivename($key)) {
4994 next if $skip_drive && $key eq $skip_drive;
4995 my $drive = parse_drive($key, $value);
4996 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
4997 if ($drive->{file} =~ m!^/!) {
4998 $used_path->{$drive->{file}}++; # = 1;
4999 } else {
5000 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
5001 next if !$storeid;
5002 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
5003 next if !$scfg;
5004 my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
5005 $used_path->{$path}++; # = 1;
5006 }
5007 }
5008 }
5009 };
5010
5011 &$scan_config($conf);
5012
5013 undef $skip_drive;
5014
5015 if ($scan_snapshots) {
5016 foreach my $snapname (keys %{$conf->{snapshots}}) {
5017 &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
5018 }
5019 }
5020
5021 return $used_path;
5022}
5023
91bd6c90
DM
5024sub update_disksize {
5025 my ($vmid, $conf, $volid_hash) = @_;
be190583 5026
91bd6c90
DM
5027 my $changes;
5028
5029 my $used = {};
5030
5996a936
DM
5031 # Note: it is allowed to define multiple storages with same path (alias), so
5032 # we need to check both 'volid' and real 'path' (two different volid can point
5033 # to the same path).
5034
5035 my $usedpath = {};
be190583 5036
91bd6c90
DM
5037 # update size info
5038 foreach my $opt (keys %$conf) {
ed221350
DM
5039 if (valid_drivename($opt)) {
5040 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
5041 my $volid = $drive->{file};
5042 next if !$volid;
5043
5044 $used->{$volid} = 1;
be190583 5045 if ($volid_hash->{$volid} &&
5996a936
DM
5046 (my $path = $volid_hash->{$volid}->{path})) {
5047 $usedpath->{$path} = 1;
5048 }
91bd6c90 5049
ed221350 5050 next if drive_is_cdrom($drive);
91bd6c90
DM
5051 next if !$volid_hash->{$volid};
5052
5053 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
5054 my $new = print_drive($vmid, $drive);
5055 if ($new ne $conf->{$opt}) {
5056 $changes = 1;
5057 $conf->{$opt} = $new;
5058 }
91bd6c90
DM
5059 }
5060 }
5061
5996a936
DM
5062 # remove 'unusedX' entry if volume is used
5063 foreach my $opt (keys %$conf) {
5064 next if $opt !~ m/^unused\d+$/;
5065 my $volid = $conf->{$opt};
5066 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 5067 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
5068 $changes = 1;
5069 delete $conf->{$opt};
5070 }
5071 }
5072
91bd6c90
DM
5073 foreach my $volid (sort keys %$volid_hash) {
5074 next if $volid =~ m/vm-$vmid-state-/;
5075 next if $used->{$volid};
5996a936
DM
5076 my $path = $volid_hash->{$volid}->{path};
5077 next if !$path; # just to be sure
5078 next if $usedpath->{$path};
91bd6c90 5079 $changes = 1;
ed221350 5080 add_unused_volume($conf, $volid);
05937a14 5081 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
5082 }
5083
5084 return $changes;
5085}
5086
5087sub rescan {
5088 my ($vmid, $nolock) = @_;
5089
5090 my $cfg = PVE::Cluster::cfs_read_file("storage.cfg");
5091
5092 my $volid_hash = scan_volids($cfg, $vmid);
5093
5094 my $updatefn = sub {
5095 my ($vmid) = @_;
5096
ed221350 5097 my $conf = load_config($vmid);
be190583 5098
ed221350 5099 check_lock($conf);
91bd6c90 5100
03da3f0d
DM
5101 my $vm_volids = {};
5102 foreach my $volid (keys %$volid_hash) {
5103 my $info = $volid_hash->{$volid};
5104 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
5105 }
5106
5107 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 5108
ed221350 5109 update_config_nolock($vmid, $conf, 1) if $changes;
91bd6c90
DM
5110 };
5111
5112 if (defined($vmid)) {
5113 if ($nolock) {
5114 &$updatefn($vmid);
5115 } else {
ed221350 5116 lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
5117 }
5118 } else {
5119 my $vmlist = config_list();
5120 foreach my $vmid (keys %$vmlist) {
5121 if ($nolock) {
5122 &$updatefn($vmid);
5123 } else {
ed221350 5124 lock_config($vmid, $updatefn, $vmid);
be190583 5125 }
91bd6c90
DM
5126 }
5127 }
5128}
5129
5130sub restore_vma_archive {
5131 my ($archive, $vmid, $user, $opts, $comp) = @_;
5132
5133 my $input = $archive eq '-' ? "<&STDIN" : undef;
5134 my $readfrom = $archive;
5135
5136 my $uncomp = '';
5137 if ($comp) {
5138 $readfrom = '-';
5139 my $qarchive = PVE::Tools::shellquote($archive);
5140 if ($comp eq 'gzip') {
5141 $uncomp = "zcat $qarchive|";
5142 } elsif ($comp eq 'lzop') {
5143 $uncomp = "lzop -d -c $qarchive|";
5144 } else {
5145 die "unknown compression method '$comp'\n";
5146 }
be190583 5147
91bd6c90
DM
5148 }
5149
5150 my $tmpdir = "/var/tmp/vzdumptmp$$";
5151 rmtree $tmpdir;
5152
5153 # disable interrupts (always do cleanups)
5154 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5155 warn "got interrupt - ignored\n";
5156 };
5157
5158 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
5159 POSIX::mkfifo($mapfifo, 0600);
5160 my $fifofh;
5161
5162 my $openfifo = sub {
5163 open($fifofh, '>', $mapfifo) || die $!;
5164 };
5165
5166 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
5167
5168 my $oldtimeout;
5169 my $timeout = 5;
5170
5171 my $devinfo = {};
5172
5173 my $rpcenv = PVE::RPCEnvironment::get();
5174
ed221350 5175 my $conffile = config_file($vmid);
91bd6c90
DM
5176 my $tmpfn = "$conffile.$$.tmp";
5177
ed221350
DM
5178 # Note: $oldconf is undef if VM does not exists
5179 my $oldconf = PVE::Cluster::cfs_read_file(cfs_config_path($vmid));
5180
91bd6c90
DM
5181 my $print_devmap = sub {
5182 my $virtdev_hash = {};
5183
5184 my $cfgfn = "$tmpdir/qemu-server.conf";
5185
5186 # we can read the config - that is already extracted
5187 my $fh = IO::File->new($cfgfn, "r") ||
5188 "unable to read qemu-server.conf - $!\n";
5189
5190 while (defined(my $line = <$fh>)) {
5191 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
5192 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
5193 die "archive does not contain data for drive '$virtdev'\n"
5194 if !$devinfo->{$devname};
5195 if (defined($opts->{storage})) {
5196 $storeid = $opts->{storage} || 'local';
5197 } elsif (!$storeid) {
5198 $storeid = 'local';
5199 }
5200 $format = 'raw' if !$format;
5201 $devinfo->{$devname}->{devname} = $devname;
5202 $devinfo->{$devname}->{virtdev} = $virtdev;
5203 $devinfo->{$devname}->{format} = $format;
5204 $devinfo->{$devname}->{storeid} = $storeid;
5205
be190583 5206 # check permission on storage
91bd6c90
DM
5207 my $pool = $opts->{pool}; # todo: do we need that?
5208 if ($user ne 'root@pam') {
5209 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
5210 }
5211
5212 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
5213 }
5214 }
5215
5216 foreach my $devname (keys %$devinfo) {
be190583
DM
5217 die "found no device mapping information for device '$devname'\n"
5218 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
5219 }
5220
91bd6c90 5221 my $cfg = cfs_read_file('storage.cfg');
ed221350
DM
5222
5223 # create empty/temp config
be190583 5224 if ($oldconf) {
ed221350
DM
5225 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
5226 foreach_drive($oldconf, sub {
5227 my ($ds, $drive) = @_;
5228
5229 return if drive_is_cdrom($drive);
5230
5231 my $volid = $drive->{file};
5232
5233 return if !$volid || $volid =~ m|^/|;
5234
5235 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
5236 return if !$path || !$owner || ($owner != $vmid);
5237
5238 # Note: only delete disk we want to restore
5239 # other volumes will become unused
5240 if ($virtdev_hash->{$ds}) {
5241 PVE::Storage::vdisk_free($cfg, $volid);
5242 }
5243 });
5244 }
5245
5246 my $map = {};
91bd6c90
DM
5247 foreach my $virtdev (sort keys %$virtdev_hash) {
5248 my $d = $virtdev_hash->{$virtdev};
5249 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
5250 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
5251
5252 # test if requested format is supported
5253 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
5254 my $supported = grep { $_ eq $d->{format} } @$validFormats;
5255 $d->{format} = $defFormat if !$supported;
5256
91bd6c90
DM
5257 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
5258 $d->{format}, undef, $alloc_size);
5259 print STDERR "new volume ID is '$volid'\n";
5260 $d->{volid} = $volid;
5261 my $path = PVE::Storage::path($cfg, $volid);
5262
5263 my $write_zeros = 1;
5264 # fixme: what other storages types initialize volumes with zero?
244f2577 5265 if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' || $scfg->{type} eq 'glusterfs' ||
013d5275 5266 $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
91bd6c90
DM
5267 $write_zeros = 0;
5268 }
5269
5270 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
5271
5272 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
5273 $map->{$virtdev} = $volid;
5274 }
5275
5276 $fh->seek(0, 0) || die "seek failed - $!\n";
5277
5278 my $outfd = new IO::File ($tmpfn, "w") ||
5279 die "unable to write config for VM $vmid\n";
5280
5281 my $cookie = { netcount => 0 };
5282 while (defined(my $line = <$fh>)) {
be190583 5283 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
5284 }
5285
5286 $fh->close();
5287 $outfd->close();
5288 };
5289
5290 eval {
5291 # enable interrupts
5292 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5293 die "interrupted by signal\n";
5294 };
5295 local $SIG{ALRM} = sub { die "got timeout\n"; };
5296
5297 $oldtimeout = alarm($timeout);
5298
5299 my $parser = sub {
5300 my $line = shift;
5301
5302 print "$line\n";
5303
5304 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
5305 my ($dev_id, $size, $devname) = ($1, $2, $3);
5306 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
5307 } elsif ($line =~ m/^CTIME: /) {
46f58b5f 5308 # we correctly received the vma config, so we can disable
3cf90d7a
DM
5309 # the timeout now for disk allocation (set to 10 minutes, so
5310 # that we always timeout if something goes wrong)
5311 alarm(600);
91bd6c90
DM
5312 &$print_devmap();
5313 print $fifofh "done\n";
5314 my $tmp = $oldtimeout || 0;
5315 $oldtimeout = undef;
5316 alarm($tmp);
5317 close($fifofh);
5318 }
5319 };
be190583 5320
91bd6c90
DM
5321 print "restore vma archive: $cmd\n";
5322 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
5323 };
5324 my $err = $@;
5325
5326 alarm($oldtimeout) if $oldtimeout;
5327
5328 unlink $mapfifo;
5329
5330 if ($err) {
5331 rmtree $tmpdir;
5332 unlink $tmpfn;
5333
5334 my $cfg = cfs_read_file('storage.cfg');
5335 foreach my $devname (keys %$devinfo) {
5336 my $volid = $devinfo->{$devname}->{volid};
5337 next if !$volid;
5338 eval {
5339 if ($volid =~ m|^/|) {
5340 unlink $volid || die 'unlink failed\n';
5341 } else {
5342 PVE::Storage::vdisk_free($cfg, $volid);
5343 }
5344 print STDERR "temporary volume '$volid' sucessfuly removed\n";
5345 };
5346 print STDERR "unable to cleanup '$volid' - $@" if $@;
5347 }
5348 die $err;
5349 }
5350
5351 rmtree $tmpdir;
ed221350
DM
5352
5353 rename($tmpfn, $conffile) ||
91bd6c90
DM
5354 die "unable to commit configuration file '$conffile'\n";
5355
ed221350
DM
5356 PVE::Cluster::cfs_update(); # make sure we read new file
5357
91bd6c90
DM
5358 eval { rescan($vmid, 1); };
5359 warn $@ if $@;
5360}
5361
5362sub restore_tar_archive {
5363 my ($archive, $vmid, $user, $opts) = @_;
5364
9c502e26 5365 if ($archive ne '-') {
ed221350 5366 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
5367 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
5368 if $firstfile ne 'qemu-server.conf';
5369 }
3e16d5fc 5370
ed221350 5371 my $storecfg = cfs_read_file('storage.cfg');
ebb55558 5372
ed221350 5373 # destroy existing data - keep empty config
8e90138a 5374 my $vmcfgfn = config_file($vmid);
ebb55558 5375 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 5376
3e16d5fc
DM
5377 my $tocmd = "/usr/lib/qemu-server/qmextract";
5378
2415a446 5379 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 5380 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
5381 $tocmd .= ' --prealloc' if $opts->{prealloc};
5382 $tocmd .= ' --info' if $opts->{info};
5383
a0d1b1a2 5384 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 5385 # so we pipe to zcat
2415a446
DM
5386 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
5387 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
5388
5389 my $tmpdir = "/var/tmp/vzdumptmp$$";
5390 mkpath $tmpdir;
5391
5392 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
5393 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 5394 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 5395
ed221350 5396 my $conffile = config_file($vmid);
3e16d5fc
DM
5397 my $tmpfn = "$conffile.$$.tmp";
5398
5399 # disable interrupts (always do cleanups)
5400 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5401 print STDERR "got interrupt - ignored\n";
5402 };
5403
afdb31d5 5404 eval {
3e16d5fc
DM
5405 # enable interrupts
5406 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5407 die "interrupted by signal\n";
5408 };
5409
9c502e26
DM
5410 if ($archive eq '-') {
5411 print "extracting archive from STDIN\n";
5412 run_command($cmd, input => "<&STDIN");
5413 } else {
5414 print "extracting archive '$archive'\n";
5415 run_command($cmd);
5416 }
3e16d5fc
DM
5417
5418 return if $opts->{info};
5419
5420 # read new mapping
5421 my $map = {};
5422 my $statfile = "$tmpdir/qmrestore.stat";
5423 if (my $fd = IO::File->new($statfile, "r")) {
5424 while (defined (my $line = <$fd>)) {
5425 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
5426 $map->{$1} = $2 if $1;
5427 } else {
5428 print STDERR "unable to parse line in statfile - $line\n";
5429 }
5430 }
5431 $fd->close();
5432 }
5433
5434 my $confsrc = "$tmpdir/qemu-server.conf";
5435
5436 my $srcfd = new IO::File($confsrc, "r") ||
5437 die "unable to open file '$confsrc'\n";
5438
5439 my $outfd = new IO::File ($tmpfn, "w") ||
5440 die "unable to write config for VM $vmid\n";
5441
91bd6c90 5442 my $cookie = { netcount => 0 };
3e16d5fc 5443 while (defined (my $line = <$srcfd>)) {
be190583 5444 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
5445 }
5446
5447 $srcfd->close();
5448 $outfd->close();
5449 };
5450 my $err = $@;
5451
afdb31d5 5452 if ($err) {
3e16d5fc
DM
5453
5454 unlink $tmpfn;
5455
ed221350 5456 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 5457
3e16d5fc 5458 die $err;
afdb31d5 5459 }
3e16d5fc
DM
5460
5461 rmtree $tmpdir;
5462
5463 rename $tmpfn, $conffile ||
5464 die "unable to commit configuration file '$conffile'\n";
91bd6c90 5465
ed221350
DM
5466 PVE::Cluster::cfs_update(); # make sure we read new file
5467
91bd6c90
DM
5468 eval { rescan($vmid, 1); };
5469 warn $@ if $@;
3e16d5fc
DM
5470};
5471
0d18dcfc
DM
5472
5473# Internal snapshots
5474
5475# NOTE: Snapshot create/delete involves several non-atomic
5476# action, and can take a long time.
5477# So we try to avoid locking the file and use 'lock' variable
5478# inside the config file instead.
5479
ef59d1ca
DM
5480my $snapshot_copy_config = sub {
5481 my ($source, $dest) = @_;
5482
5483 foreach my $k (keys %$source) {
5484 next if $k eq 'snapshots';
982c7f12
DM
5485 next if $k eq 'snapstate';
5486 next if $k eq 'snaptime';
18bfb361 5487 next if $k eq 'vmstate';
ef59d1ca
DM
5488 next if $k eq 'lock';
5489 next if $k eq 'digest';
db7c26e5 5490 next if $k eq 'description';
ef59d1ca 5491 next if $k =~ m/^unused\d+$/;
be190583 5492
ef59d1ca
DM
5493 $dest->{$k} = $source->{$k};
5494 }
5495};
5496
5497my $snapshot_apply_config = sub {
5498 my ($conf, $snap) = @_;
5499
5500 # copy snapshot list
5501 my $newconf = {
5502 snapshots => $conf->{snapshots},
5503 };
5504
db7c26e5 5505 # keep description and list of unused disks
ef59d1ca 5506 foreach my $k (keys %$conf) {
db7c26e5 5507 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
5508 $newconf->{$k} = $conf->{$k};
5509 }
5510
5511 &$snapshot_copy_config($snap, $newconf);
5512
5513 return $newconf;
5514};
5515
18bfb361
DM
5516sub foreach_writable_storage {
5517 my ($conf, $func) = @_;
5518
5519 my $sidhash = {};
5520
5521 foreach my $ds (keys %$conf) {
5522 next if !valid_drivename($ds);
5523
5524 my $drive = parse_drive($ds, $conf->{$ds});
5525 next if !$drive;
5526 next if drive_is_cdrom($drive);
5527
5528 my $volid = $drive->{file};
5529
5530 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 5531 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
5532 }
5533
5534 foreach my $sid (sort keys %$sidhash) {
5535 &$func($sid);
5536 }
5537}
5538
5539my $alloc_vmstate_volid = sub {
5540 my ($storecfg, $vmid, $conf, $snapname) = @_;
be190583 5541
18bfb361
DM
5542 # Note: we try to be smart when selecting a $target storage
5543
5544 my $target;
5545
5546 # search shared storage first
5547 foreach_writable_storage($conf, sub {
5548 my ($sid) = @_;
5549 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5550 return if !$scfg->{shared};
5551
5552 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
5553 });
5554
5555 if (!$target) {
5556 # now search local storage
5557 foreach_writable_storage($conf, sub {
5558 my ($sid) = @_;
5559 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5560 return if $scfg->{shared};
5561
5562 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
5563 });
5564 }
5565
5566 $target = 'local' if !$target;
5567
fe6249f4
DM
5568 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
5569 # we abort live save after $conf->{memory}, so we need at max twice that space
5570 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
5571
5572 my $name = "vm-$vmid-state-$snapname";
5573 my $scfg = PVE::Storage::storage_config($storecfg, $target);
5574 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
5575 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
5576
5577 return $volid;
5578};
5579
0d18dcfc 5580my $snapshot_prepare = sub {
18bfb361 5581 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
5582
5583 my $snap;
0d18dcfc
DM
5584
5585 my $updatefn = sub {
5586
5587 my $conf = load_config($vmid);
5588
be190583 5589 die "you can't take a snapshot if it's a template\n"
5295b23d
DM
5590 if is_template($conf);
5591
0d18dcfc
DM
5592 check_lock($conf);
5593
22c377f0
DM
5594 $conf->{lock} = 'snapshot';
5595
be190583
DM
5596 die "snapshot name '$snapname' already used\n"
5597 if defined($conf->{snapshots}->{$snapname});
0d18dcfc 5598
ee2f90b1 5599 my $storecfg = PVE::Storage::config();
7ea975ef 5600 die "snapshot feature is not available" if !has_feature('snapshot', $conf, $storecfg);
18bfb361 5601
782f4f75 5602 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 5603
18bfb361
DM
5604 if ($save_vmstate && check_running($vmid)) {
5605 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
5606 }
5607
ef59d1ca 5608 &$snapshot_copy_config($conf, $snap);
0d18dcfc 5609
782f4f75
DM
5610 $snap->{snapstate} = "prepare";
5611 $snap->{snaptime} = time();
5612 $snap->{description} = $comment if $comment;
5613
4b15803d
DM
5614 # always overwrite machine if we save vmstate. This makes sure we
5615 # can restore it later using correct machine type
5616 $snap->{machine} = get_current_qemu_machine($vmid) if $snap->{vmstate};
5617
0d18dcfc
DM
5618 update_config_nolock($vmid, $conf, 1);
5619 };
5620
5621 lock_config($vmid, $updatefn);
22c377f0
DM
5622
5623 return $snap;
0d18dcfc
DM
5624};
5625
5626my $snapshot_commit = sub {
5627 my ($vmid, $snapname) = @_;
5628
5629 my $updatefn = sub {
5630
5631 my $conf = load_config($vmid);
5632
be190583
DM
5633 die "missing snapshot lock\n"
5634 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
0d18dcfc 5635
7946e0fa
DM
5636 my $has_machine_config = defined($conf->{machine});
5637
0d18dcfc
DM
5638 my $snap = $conf->{snapshots}->{$snapname};
5639
be190583
DM
5640 die "snapshot '$snapname' does not exist\n" if !defined($snap);
5641
5642 die "wrong snapshot state\n"
5643 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
0d18dcfc 5644
0d18dcfc 5645 delete $snap->{snapstate};
ee2f90b1 5646 delete $conf->{lock};
0d18dcfc 5647
ef59d1ca 5648 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 5649
7946e0fa
DM
5650 delete $newconf->{machine} if !$has_machine_config;
5651
05e5ad3f
DM
5652 $newconf->{parent} = $snapname;
5653
0d18dcfc
DM
5654 update_config_nolock($vmid, $newconf, 1);
5655 };
5656
5657 lock_config($vmid, $updatefn);
5658};
5659
22c377f0
DM
5660sub snapshot_rollback {
5661 my ($vmid, $snapname) = @_;
5662
22c377f0
DM
5663 my $prepare = 1;
5664
a3222b91 5665 my $storecfg = PVE::Storage::config();
be190583 5666
ba4eea15 5667 my $conf = load_config($vmid);
22c377f0 5668
ba4eea15 5669 my $get_snapshot_config = sub {
22c377f0 5670
8b43bc11 5671 die "you can't rollback if vm is a template\n" if is_template($conf);
90b0c6b3 5672
ba4eea15 5673 my $res = $conf->{snapshots}->{$snapname};
ab33a7c2 5674
ba4eea15
WL
5675 die "snapshot '$snapname' does not exist\n" if !defined($res);
5676
5677 return $res;
5678 };
5679
5680 my $snap = &$get_snapshot_config();
5681
5682 foreach_drive($snap, sub {
5683 my ($ds, $drive) = @_;
5684
5685 return if drive_is_cdrom($drive);
5686
5687 my $volid = $drive->{file};
5688
5689 PVE::Storage::volume_rollback_is_possible($storecfg, $volid, $snapname);
5690 });
5691
5692 my $updatefn = sub {
5693
5694 $conf = load_config($vmid);
5695
5696 $snap = &$get_snapshot_config();
ab33a7c2 5697
be190583 5698 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
ab33a7c2
DM
5699 if $snap->{snapstate};
5700
a3222b91
DM
5701 if ($prepare) {
5702 check_lock($conf);
5703 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
5704 }
22c377f0
DM
5705
5706 die "unable to rollback vm $vmid: vm is running\n"
5707 if check_running($vmid);
5708
5709 if ($prepare) {
5710 $conf->{lock} = 'rollback';
5711 } else {
5712 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
5713 delete $conf->{lock};
5714 }
5715
4b15803d
DM
5716 my $forcemachine;
5717
22c377f0 5718 if (!$prepare) {
4b15803d
DM
5719 my $has_machine_config = defined($conf->{machine});
5720
22c377f0 5721 # copy snapshot config to current config
ef59d1ca
DM
5722 $conf = &$snapshot_apply_config($conf, $snap);
5723 $conf->{parent} = $snapname;
4b15803d 5724
d8b916fd
DM
5725 # Note: old code did not store 'machine', so we try to be smart
5726 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
5727 $forcemachine = $conf->{machine} || 'pc-i440fx-1.4';
be190583 5728 # we remove the 'machine' configuration if not explicitly specified
4b15803d
DM
5729 # in the original config.
5730 delete $conf->{machine} if $snap->{vmstate} && !$has_machine_config;
22c377f0
DM
5731 }
5732
5733 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
5734
5735 if (!$prepare && $snap->{vmstate}) {
5736 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
4b15803d 5737 vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
a3222b91 5738 }
22c377f0
DM
5739 };
5740
5741 lock_config($vmid, $updatefn);
be190583 5742
22c377f0
DM
5743 foreach_drive($snap, sub {
5744 my ($ds, $drive) = @_;
5745
5746 return if drive_is_cdrom($drive);
5747
5748 my $volid = $drive->{file};
5749 my $device = "drive-$ds";
5750
79e57b29 5751 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
5752 });
5753
5754 $prepare = 0;
5755 lock_config($vmid, $updatefn);
5756}
5757
9dcf4909
DM
5758my $savevm_wait = sub {
5759 my ($vmid) = @_;
5760
5761 for(;;) {
ed221350 5762 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
9dcf4909
DM
5763 if (!$stat->{status}) {
5764 die "savevm not active\n";
5765 } elsif ($stat->{status} eq 'active') {
5766 sleep(1);
5767 next;
5768 } elsif ($stat->{status} eq 'completed') {
5769 last;
5770 } else {
5771 die "query-savevm returned status '$stat->{status}'\n";
5772 }
5773 }
5774};
5775
e5eaa028
WL
5776sub do_snapshots_with_qemu {
5777 my ($storecfg, $volid) = @_;
5778
5779 my $storage_name = PVE::Storage::parse_volume_id($volid);
5780
5781 if ($qemu_snap_storage->{$storecfg->{ids}->{$storage_name}->{type}} ){
5782 return 1;
5783 }
5784
5785 if ($volid =~ m/\.(qcow2|qed)$/){
5786 return 1;
5787 }
5788
5789 return undef;
5790}
5791
0d18dcfc 5792sub snapshot_create {
af9110dd 5793 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
0d18dcfc 5794
18bfb361 5795 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 5796
af9110dd 5797 $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
18bfb361 5798
67fb9de6
DM
5799 my $config = load_config($vmid);
5800
af9110dd
WL
5801 my $running = check_running($vmid);
5802
67fb9de6 5803 my $freezefs = $running && $config->{agent};
af9110dd
WL
5804 $freezefs = 0 if $snap->{vmstate}; # not needed if we save RAM
5805
5806 my $drivehash = {};
5807
5808 if ($freezefs) {
65994ad7
WL
5809 eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); };
5810 warn "guest-fsfreeze-freeze problems - $@" if $@;
5811 }
67fb9de6 5812
0d18dcfc
DM
5813 eval {
5814 # create internal snapshots of all drives
22c377f0
DM
5815
5816 my $storecfg = PVE::Storage::config();
a3222b91
DM
5817
5818 if ($running) {
5819 if ($snap->{vmstate}) {
be190583 5820 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
5821 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
5822 &$savevm_wait($vmid);
a3222b91 5823 } else {
9dcf4909 5824 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
5825 }
5826 };
5827
22c377f0
DM
5828 foreach_drive($snap, sub {
5829 my ($ds, $drive) = @_;
5830
5831 return if drive_is_cdrom($drive);
0d18dcfc 5832
22c377f0
DM
5833 my $volid = $drive->{file};
5834 my $device = "drive-$ds";
5835
5836 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 5837 $drivehash->{$ds} = 1;
22c377f0 5838 });
0d18dcfc 5839 };
22c377f0
DM
5840 my $err = $@;
5841
65994ad7
WL
5842 if ($running) {
5843 eval { vm_mon_cmd($vmid, "savevm-end") };
5844 warn $@ if $@;
22c377f0 5845
af9110dd 5846 if ($freezefs) {
67fb9de6 5847 eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); };
65994ad7
WL
5848 warn "guest-fsfreeze-thaw problems - $@" if $@;
5849 }
22c377f0 5850
65994ad7 5851 # savevm-end is async, we need to wait
f34ebd52 5852 for (;;) {
2c9e8036
AD
5853 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
5854 if (!$stat->{bytes}) {
5855 last;
5856 } else {
5857 print "savevm not yet finished\n";
5858 sleep(1);
5859 next;
5860 }
5861 }
5862 }
5863
22c377f0 5864 if ($err) {
0d18dcfc 5865 warn "snapshot create failed: starting cleanup\n";
3ee28e38 5866 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
5867 warn $@ if $@;
5868 die $err;
5869 }
5870
5871 &$snapshot_commit($vmid, $snapname);
5872}
5873
3ee28e38 5874# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 5875sub snapshot_delete {
3ee28e38 5876 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
5877
5878 my $prepare = 1;
5879
22c377f0 5880 my $snap;
ee2f90b1 5881 my $unused = [];
0d18dcfc 5882
6cb1a8cf
DM
5883 my $unlink_parent = sub {
5884 my ($confref, $new_parent) = @_;
5885
5886 if ($confref->{parent} && $confref->{parent} eq $snapname) {
5887 if ($new_parent) {
5888 $confref->{parent} = $new_parent;
5889 } else {
5890 delete $confref->{parent};
5891 }
5892 }
5893 };
be190583 5894
0d18dcfc 5895 my $updatefn = sub {
2009f324 5896 my ($remove_drive) = @_;
0d18dcfc 5897
22c377f0 5898 my $conf = load_config($vmid);
0d18dcfc 5899
5295b23d
DM
5900 if (!$drivehash) {
5901 check_lock($conf);
be190583 5902 die "you can't delete a snapshot if vm is a template\n"
5295b23d
DM
5903 if is_template($conf);
5904 }
0d18dcfc 5905
22c377f0 5906 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc 5907
be190583 5908 die "snapshot '$snapname' does not exist\n" if !defined($snap);
0d18dcfc
DM
5909
5910 # remove parent refs
8fd882a4
SP
5911 if (!$prepare) {
5912 &$unlink_parent($conf, $snap->{parent});
5913 foreach my $sn (keys %{$conf->{snapshots}}) {
5914 next if $sn eq $snapname;
5915 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
5916 }
0d18dcfc
DM
5917 }
5918
2009f324 5919 if ($remove_drive) {
18bfb361
DM
5920 if ($remove_drive eq 'vmstate') {
5921 delete $snap->{$remove_drive};
5922 } else {
5923 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
5924 my $volid = $drive->{file};
5925 delete $snap->{$remove_drive};
5926 add_unused_volume($conf, $volid);
5927 }
2009f324
DM
5928 }
5929
0d18dcfc
DM
5930 if ($prepare) {
5931 $snap->{snapstate} = 'delete';
5932 } else {
5933 delete $conf->{snapshots}->{$snapname};
3ee28e38 5934 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
5935 foreach my $volid (@$unused) {
5936 add_unused_volume($conf, $volid);
5937 }
0d18dcfc
DM
5938 }
5939
5940 update_config_nolock($vmid, $conf, 1);
5941 };
5942
5943 lock_config($vmid, $updatefn);
5944
18bfb361 5945 # now remove vmstate file
0d18dcfc 5946
22c377f0
DM
5947 my $storecfg = PVE::Storage::config();
5948
18bfb361
DM
5949 if ($snap->{vmstate}) {
5950 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
5951 if (my $err = $@) {
5952 die $err if !$force;
5953 warn $err;
5954 }
5955 # save changes (remove vmstate from snapshot)
5956 lock_config($vmid, $updatefn, 'vmstate') if !$force;
5957 };
5958
5959 # now remove all internal snapshots
5960 foreach_drive($snap, sub {
22c377f0
DM
5961 my ($ds, $drive) = @_;
5962
5963 return if drive_is_cdrom($drive);
3ee28e38 5964
22c377f0
DM
5965 my $volid = $drive->{file};
5966 my $device = "drive-$ds";
5967
2009f324
DM
5968 if (!$drivehash || $drivehash->{$ds}) {
5969 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
5970 if (my $err = $@) {
5971 die $err if !$force;
5972 warn $err;
5973 }
3ee28e38 5974 }
2009f324
DM
5975
5976 # save changes (remove drive fron snapshot)
5977 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 5978 push @$unused, $volid;
22c377f0 5979 });
0d18dcfc
DM
5980
5981 # now cleanup config
5982 $prepare = 0;
5983 lock_config($vmid, $updatefn);
5984}
5985
9cd07842 5986sub has_feature {
7ea975ef
AD
5987 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
5988
719893a9 5989 my $err;
7ea975ef
AD
5990 foreach_drive($conf, sub {
5991 my ($ds, $drive) = @_;
5992
5993 return if drive_is_cdrom($drive);
5994 my $volid = $drive->{file};
5995 $err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
5996 });
5997
719893a9 5998 return $err ? 0 : 1;
7ea975ef 5999}
04a69bb4
AD
6000
6001sub template_create {
6002 my ($vmid, $conf, $disk) = @_;
6003
04a69bb4 6004 my $storecfg = PVE::Storage::config();
04a69bb4 6005
9cd07842
DM
6006 foreach_drive($conf, sub {
6007 my ($ds, $drive) = @_;
6008
6009 return if drive_is_cdrom($drive);
6010 return if $disk && $ds ne $disk;
6011
6012 my $volid = $drive->{file};
bbd56097 6013 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 6014
04a69bb4
AD
6015 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
6016 $drive->{file} = $voliddst;
152fe752
DM
6017 $conf->{$ds} = print_drive($vmid, $drive);
6018 update_config_nolock($vmid, $conf, 1);
04a69bb4 6019 });
04a69bb4
AD
6020}
6021
624361b3
AD
6022sub is_template {
6023 my ($conf) = @_;
6024
96d695c0 6025 return 1 if defined $conf->{template} && $conf->{template} == 1;
624361b3
AD
6026}
6027
5133de42
AD
6028sub qemu_img_convert {
6029 my ($src_volid, $dst_volid, $size, $snapname) = @_;
6030
6031 my $storecfg = PVE::Storage::config();
6032 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
6033 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
6034
6035 if ($src_storeid && $dst_storeid) {
6036 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
6037 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
6038
6039 my $src_format = qemu_img_format($src_scfg, $src_volname);
6040 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
6041
6042 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
6043 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
6044
6045 my $cmd = [];
71ddbff9 6046 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5133de42
AD
6047 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
6048 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
6049
6050 my $parser = sub {
6051 my $line = shift;
6052 if($line =~ m/\((\S+)\/100\%\)/){
6053 my $percent = $1;
6054 my $transferred = int($size * $percent / 100);
6055 my $remaining = $size - $transferred;
6056
6057 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
6058 }
6059
6060 };
6061
6062 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
6063 my $err = $@;
6064 die "copy failed: $err" if $err;
6065 }
6066}
6067
6068sub qemu_img_format {
6069 my ($scfg, $volname) = @_;
6070
ccb5c001 6071 if ($scfg->{path} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
5133de42 6072 return $1;
ccb5c001 6073 } elsif ($scfg->{type} eq 'iscsi') {
5133de42 6074 return "host_device";
be190583 6075 } else {
5133de42 6076 return "raw";
5133de42
AD
6077 }
6078}
6079
cfad42af 6080sub qemu_drive_mirror {
ab6ecffe 6081 my ($vmid, $drive, $dst_volid, $vmiddst) = @_;
cfad42af 6082
ab6ecffe 6083 my $count = 0;
cfad42af
AD
6084 my $old_len = 0;
6085 my $frozen = undef;
ab6ecffe 6086 my $maxwait = 120;
cfad42af
AD
6087
6088 my $storecfg = PVE::Storage::config();
08ac653f 6089 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid);
152fe752 6090
08ac653f 6091 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
cfad42af 6092
08ac653f
DM
6093 my $format;
6094 if ($dst_volname =~ m/\.(raw|qcow2)$/){
6095 $format = $1;
6096 }
21ccdb50 6097
08ac653f 6098 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
21ccdb50 6099
88383920
DM
6100 my $opts = { timeout => 10, device => "drive-$drive", mode => "existing", sync => "full", target => $dst_path };
6101 $opts->{format} = $format if $format;
6102
6103 #fixme : sometime drive-mirror timeout, but works fine after.
6104 # (I have see the problem with big volume > 200GB), so we need to eval
f34ebd52 6105 eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); };
88383920 6106 # ignore errors here
21ccdb50 6107
08ac653f
DM
6108 eval {
6109 while (1) {
6110 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6111 my $stat = @$stats[0];
6112 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
6113 die "error job is not mirroring" if $stat->{type} ne "mirror";
6114
08ac653f
DM
6115 my $busy = $stat->{busy};
6116
6f708643
DM
6117 if (my $total = $stat->{len}) {
6118 my $transferred = $stat->{offset} || 0;
6119 my $remaining = $total - $transferred;
6120 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
67fb9de6 6121
6f708643
DM
6122 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy\n";
6123 }
f34ebd52 6124
08ac653f
DM
6125 if ($stat->{len} == $stat->{offset}) {
6126 if ($busy eq 'false') {
6127
6128 last if $vmiddst != $vmid;
f34ebd52 6129
08ac653f
DM
6130 # try to switch the disk if source and destination are on the same guest
6131 eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") };
6132 last if !$@;
6133 die $@ if $@ !~ m/cannot be completed/;
cfad42af 6134 }
b467f79a 6135
08ac653f
DM
6136 if ($count > $maxwait) {
6137 # if too much writes to disk occurs at the end of migration
6138 #the disk needs to be freezed to be able to complete the migration
6139 vm_suspend($vmid,1);
6140 $frozen = 1;
bcc87408 6141 }
08ac653f
DM
6142 $count ++
6143 }
6144 $old_len = $stat->{offset};
6145 sleep 1;
cfad42af
AD
6146 }
6147
08ac653f
DM
6148 vm_resume($vmid, 1) if $frozen;
6149
6150 };
88383920 6151 my $err = $@;
08ac653f 6152
88383920 6153 my $cancel_job = sub {
08ac653f
DM
6154 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
6155 while (1) {
6156 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6157 my $stat = @$stats[0];
6158 last if !$stat;
6159 sleep 1;
cfad42af 6160 }
88383920
DM
6161 };
6162
6163 if ($err) {
f34ebd52 6164 eval { &$cancel_job(); };
88383920
DM
6165 die "mirroring error: $err";
6166 }
6167
6168 if ($vmiddst != $vmid) {
6169 # if we clone a disk for a new target vm, we don't switch the disk
6170 &$cancel_job(); # so we call block-job-cancel
cfad42af
AD
6171 }
6172}
6173
152fe752 6174sub clone_disk {
be190583 6175 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
6176 $newvmid, $storage, $format, $full, $newvollist) = @_;
6177
6178 my $newvolid;
6179
6180 if (!$full) {
6181 print "create linked clone of drive $drivename ($drive->{file})\n";
258e646c 6182 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid, $snapname);
152fe752
DM
6183 push @$newvollist, $newvolid;
6184 } else {
6185 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
6186 $storeid = $storage if $storage;
6187
1377d7b0
DM
6188 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
6189 if (!$format) {
6190 $format = $drive->{format} || $defFormat;
152fe752
DM
6191 }
6192
1377d7b0
DM
6193 # test if requested format is supported - else use default
6194 my $supported = grep { $_ eq $format } @$validFormats;
6195 $format = $defFormat if !$supported;
6196
152fe752
DM
6197 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
6198
6199 print "create full clone of drive $drivename ($drive->{file})\n";
6200 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
6201 push @$newvollist, $newvolid;
6202
6203 if (!$running || $snapname) {
6204 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname);
6205 } else {
6206 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid);
be190583 6207 }
152fe752
DM
6208 }
6209
6210 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
6211
6212 my $disk = $drive;
6213 $disk->{format} = undef;
6214 $disk->{file} = $newvolid;
6215 $disk->{size} = $size;
6216
6217 return $disk;
6218}
6219
ff556cf2
DM
6220# this only works if VM is running
6221sub get_current_qemu_machine {
6222 my ($vmid) = @_;
6223
6224 my $cmd = { execute => 'query-machines', arguments => {} };
8e90138a 6225 my $res = vm_qmp_command($vmid, $cmd);
ff556cf2
DM
6226
6227 my ($current, $default);
6228 foreach my $e (@$res) {
6229 $default = $e->{name} if $e->{'is-default'};
6230 $current = $e->{name} if $e->{'is-current'};
6231 }
6232
6233 # fallback to the default machine if current is not supported by qemu
6234 return $current || $default || 'pc';
6235}
6236
23f73120
AD
6237sub qemu_machine_feature_enabled {
6238 my ($machine, $kvmver, $version_major, $version_minor) = @_;
6239
6240 my $current_major;
6241 my $current_minor;
6242
6243 if ($machine && $machine =~ m/^(pc(-i440fx|-q35)?-(\d+)\.(\d+))/) {
6244
6245 $current_major = $3;
6246 $current_minor = $4;
6247
6248 } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
6249
6250 $current_major = $1;
6251 $current_minor = $2;
6252 }
6253
6254 return 1 if $current_major >= $version_major && $current_minor >= $version_minor;
6255
6256
6257}
6258
4543ecf0
AD
6259sub lspci {
6260
6261 my $devices = {};
6262
6263 dir_glob_foreach("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
6264 my (undef, $id, $function) = @_;
6265 my $res = { id => $id, function => $function};
6266 push @{$devices->{$id}}, $res;
6267 });
6268
6269 return $devices;
6270}
6271
22de899a
AD
6272sub vm_iothreads_list {
6273 my ($vmid) = @_;
6274
6275 my $res = vm_mon_cmd($vmid, 'query-iothreads');
6276
6277 my $iothreads = {};
6278 foreach my $iothread (@$res) {
6279 $iothreads->{ $iothread->{id} } = $iothread->{"thread-id"};
6280 }
6281
6282 return $iothreads;
6283}
6284
ee034f5c
AD
6285sub scsihw_infos {
6286 my ($conf, $drive) = @_;
6287
6288 my $maxdev = 0;
6289
6290 if ($conf->{scsihw} && ($conf->{scsihw} =~ m/^lsi/)) {
6291 $maxdev = 7;
a1511b3c 6292 } elsif ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
ee034f5c
AD
6293 $maxdev = 1;
6294 } else {
6295 $maxdev = 256;
6296 }
6297
6298 my $controller = int($drive->{index} / $maxdev);
a1511b3c 6299 my $controller_prefix = ($conf->{scsihw} && $conf->{scsihw} eq 'virtio-scsi-single') ? "virtioscsi" : "scsihw";
ee034f5c
AD
6300
6301 return ($maxdev, $controller, $controller_prefix);
6302}
a1511b3c 6303
1e3baf05 63041;