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