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