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