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