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