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