]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
add reference to git version
[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',
ef5e2be2
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. You can also run without any graphic card using a serial devive as terminal.",
339 enum => [qw(std cirrus vmware qxl serial0 serial1 serial2 serial3)],
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',
9f9d2fb2 577 pattern => '(/dev/ttyS\d+|socket)',
bae179aa 578 description => <<EODESCR,
9f9d2fb2 579Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device, or create a unix socket on the host side (use 'qm terminal' to open a terminal connection).
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',
9ecc8431 590 pattern => '/dev/parport\d+|/dev/usb/lp\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
ef5e2be2 2309 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
5acbfe9e
DM
2310 }
2311
0ecf8463 2312 push @$devices, '-device', 'usb-tablet,id=tablet,bus=uhci.0,port=1' if $tablet;
1e3baf05
DM
2313
2314 # host pci devices
040b06b7
DA
2315 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2316 my $d = parse_hostpci($conf->{"hostpci$i"});
2317 next if !$d;
5bdcf937
AD
2318 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2319 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
1e3baf05
DM
2320 }
2321
2322 # usb devices
2323 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2324 my $d = parse_usb_device($conf->{"usb$i"});
2325 next if !$d;
2326 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2327 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2328 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2329 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
80401dd8
DM
2330 } elsif ($d->{spice}) {
2331 # usb redir support for spice
2332 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2333 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
1e3baf05
DM
2334 }
2335 }
2336
1e3baf05 2337 # serial devices
bae179aa 2338 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2339 if (my $path = $conf->{"serial$i"}) {
9f9d2fb2
DM
2340 if ($path eq 'socket') {
2341 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2342 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2343 push @$devices, '-device', "isa-serial,chardev=serial$i";
2344 } else {
2345 die "no such serial device\n" if ! -c $path;
2346 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2347 push @$devices, '-device', "isa-serial,chardev=serial$i";
2348 }
34978be3 2349 }
1e3baf05
DM
2350 }
2351
2352 # parallel devices
1989a89c 2353 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2354 if (my $path = $conf->{"parallel$i"}) {
19672434 2355 die "no such parallel device\n" if ! -c $path;
32e69805 2356 my $devtype = $path =~ m!^/dev/usb/lp! ? 'tty' : 'parport';
4c5dbaf6 2357 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
5bdcf937 2358 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2359 }
1e3baf05
DM
2360 }
2361
2362 my $vmname = $conf->{name} || "vm$vmid";
2363
2364 push @$cmd, '-name', $vmname;
19672434 2365
1e3baf05
DM
2366 my $sockets = 1;
2367 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2368 $sockets = $conf->{sockets} if $conf->{sockets};
2369
2370 my $cores = $conf->{cores} || 1;
1e3baf05
DM
2371 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2372
1e3baf05
DM
2373 push @$cmd, '-nodefaults';
2374
32baffb4 2375 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2376
0888fdce
DM
2377 my $bootindex_hash = {};
2378 my $i = 1;
2379 foreach my $o (split(//, $bootorder)) {
2380 $bootindex_hash->{$o} = $i*100;
2381 $i++;
afdb31d5 2382 }
3b408e82
DM
2383
2384 push @$cmd, '-boot', "menu=on";
1e3baf05 2385
6b64503e 2386 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2387
6b64503e 2388 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05 2389
ef5e2be2 2390 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
1e3baf05
DM
2391
2392 # time drift fix
6b64503e 2393 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2394
6b64503e 2395 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2396 my $useLocaltime = $conf->{localtime};
1e3baf05
DM
2397
2398 if (my $ost = $conf->{ostype}) {
a70ebde3 2399 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26
1e3baf05
DM
2400
2401 if ($ost =~ m/^w/) { # windows
8c559505 2402 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2403
8c559505 2404 # use time drift fix when acpi is enabled
6b64503e 2405 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2406 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2407 }
2408 }
2409
be190583 2410 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
a70ebde3 2411 $ost eq 'wvista') {
8c559505 2412 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf 2413 push @$cmd, '-no-hpet';
462e8d19
AD
2414 #push @$cpuFlags , 'hv_vapic" if !$nokvm; #fixme, my win2008R2 hang at boot with this
2415 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2416 }
2417
2418 if ($ost eq 'win7' || $ost eq 'win8') {
2419 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
b7e0c8bf 2420 }
1e3baf05
DM
2421 }
2422
8c559505
DM
2423 push @$rtcFlags, 'driftfix=slew' if $tdf;
2424
7f0b5beb 2425 if ($nokvm) {
8c559505 2426 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2427 } else {
2428 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2429 }
1e3baf05 2430
952958bc
DM
2431 my $machine_type = $forcemachine || $conf->{machine};
2432 if ($machine_type) {
2433 push @$machineFlags, "type=${machine_type}";
3bafc510
DM
2434 }
2435
8c559505
DM
2436 if ($conf->{startdate}) {
2437 push @$rtcFlags, "base=$conf->{startdate}";
2438 } elsif ($useLocaltime) {
2439 push @$rtcFlags, 'base=localtime';
2440 }
1e3baf05 2441
519ed28c
AD
2442 my $cpu = $nokvm ? "qemu64" : "kvm64";
2443 $cpu = $conf->{cpu} if $conf->{cpu};
2444
2445 push @$cpuFlags , '+x2apic' if !$nokvm;
2446
2e1a5389
AD
2447 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2448
be190583 2449 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c
AD
2450
2451 push @$cmd, '-cpu', $cpu;
2452
1e3baf05
DM
2453 push @$cmd, '-S' if $conf->{freeze};
2454
2455 # set keyboard layout
2456 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2457 push @$cmd, '-k', $kb if $kb;
2458
2459 # enable sound
2460 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2461 #push @$cmd, '-soundhw', 'es1370';
2462 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2463
bc84dcca 2464 if($conf->{agent}) {
ab6a046f
AD
2465 my $qgasocket = qga_socket($vmid);
2466 my $pciaddr = print_pci_addr("qga0", $bridges);
2467 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2468 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2469 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2470 }
2471
1d794448 2472 my $spice_port;
86b8228b 2473 if (vga_conf_has_spice($vga)) {
1011b570 2474 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 2475
1d794448 2476 $spice_port = PVE::Tools::next_unused_port(61000, 61099);
943340a6 2477
1d794448 2478 push @$cmd, '-spice', "tls-port=${spice_port},addr=127.0.0.1,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 2479
1011b570
DM
2480 push @$cmd, '-device', "virtio-serial,id=spice$pciaddr";
2481 push @$cmd, '-chardev', "spicevmc,id=vdagent,name=vdagent";
2482 push @$cmd, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
2483 }
2484
8d9ae0d2
DM
2485 # enable balloon by default, unless explicitly disabled
2486 if (!defined($conf->{balloon}) || $conf->{balloon}) {
2487 $pciaddr = print_pci_addr("balloon0", $bridges);
2488 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
2489 }
1e3baf05 2490
0ea9541d
DM
2491 if ($conf->{watchdog}) {
2492 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 2493 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 2494 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
2495 push @$devices, '-device', "$watchdog$pciaddr";
2496 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
2497 }
2498
1e3baf05 2499 my $vollist = [];
941e0c42 2500 my $scsicontroller = {};
26ee04b6 2501 my $ahcicontroller = {};
cdd20088 2502 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05
DM
2503
2504 foreach_drive($conf, sub {
2505 my ($ds, $drive) = @_;
2506
ff1a2432 2507 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 2508 push @$vollist, $drive->{file};
ff1a2432 2509 }
afdb31d5 2510
1e3baf05 2511 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
2512
2513 if (drive_is_cdrom ($drive)) {
2514 if ($bootindex_hash->{d}) {
2515 $drive->{bootindex} = $bootindex_hash->{d};
2516 $bootindex_hash->{d} += 1;
2517 }
2518 } else {
2519 if ($bootindex_hash->{c}) {
2520 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2521 $bootindex_hash->{c} += 1;
2522 }
2523 }
2524
941e0c42 2525 if ($drive->{interface} eq 'scsi') {
cdd20088
AD
2526
2527 my $maxdev = ($scsihw ne 'lsi') ? 256 : 7;
2528 my $controller = int($drive->{index} / $maxdev);
5bdcf937
AD
2529 $pciaddr = print_pci_addr("scsihw$controller", $bridges);
2530 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
cdd20088 2531 $scsicontroller->{$controller}=1;
941e0c42 2532 }
3b408e82 2533
26ee04b6
DA
2534 if ($drive->{interface} eq 'sata') {
2535 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
2536 $pciaddr = print_pci_addr("ahci$controller", $bridges);
2537 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
2538 $ahcicontroller->{$controller}=1;
2539 }
2540
5bdcf937
AD
2541 push @$devices, '-drive',print_drive_full($storecfg, $vmid, $drive);
2542 push @$devices, '-device',print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
2543 });
2544
2545 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2546
cc4d6182 2547 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 2548 next if !$conf->{"net$i"};
cc4d6182
DA
2549 my $d = parse_net($conf->{"net$i"});
2550 next if !$d;
1e3baf05 2551
cc4d6182 2552 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 2553
cc4d6182
DA
2554 if ($bootindex_hash->{n}) {
2555 $d->{bootindex} = $bootindex_hash->{n};
2556 $bootindex_hash->{n} += 1;
2557 }
1e3baf05 2558
cc4d6182 2559 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
2560 push @$devices, '-netdev', $netdevfull;
2561
2562 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
2563 push @$devices, '-device', $netdevicefull;
2564 }
1e3baf05 2565
5bdcf937
AD
2566 #bridges
2567 while (my ($k, $v) = each %$bridges) {
2568 $pciaddr = print_pci_addr("pci.$k");
2569 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
19672434
DM
2570 }
2571
1e3baf05
DM
2572
2573 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2574 # when the VM uses virtio devices.
19672434
DM
2575 if (!$use_virtio && $have_ovz) {
2576
6b64503e 2577 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2578 $conf->{cpuunits} : $defaults->{cpuunits};
2579
2580 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2581
2582 # fixme: cpulimit is currently ignored
2583 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2584 }
2585
2586 # add custom args
2587 if ($conf->{args}) {
3ada46c9 2588 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
2589 push @$cmd, @$aa;
2590 }
2591
5bdcf937 2592 push @$cmd, @$devices;
be190583 2593 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 2594 if scalar(@$rtcFlags);
be190583 2595 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
2596 if scalar(@$machineFlags);
2597 push @$cmd, '-global', join(',', @$globalFlags)
2598 if scalar(@$globalFlags);
2599
1d794448 2600 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 2601}
19672434 2602
1e3baf05
DM
2603sub vnc_socket {
2604 my ($vmid) = @_;
2605 return "${var_run_tmpdir}/$vmid.vnc";
2606}
2607
943340a6 2608sub spice_port {
1011b570 2609 my ($vmid) = @_;
943340a6 2610
1d794448 2611 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
2612
2613 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
2614}
2615
c971c4f2
AD
2616sub qmp_socket {
2617 my ($vmid) = @_;
2618 return "${var_run_tmpdir}/$vmid.qmp";
2619}
2620
ab6a046f
AD
2621sub qga_socket {
2622 my ($vmid) = @_;
2623 return "${var_run_tmpdir}/$vmid.qga";
2624}
2625
1e3baf05
DM
2626sub pidfile_name {
2627 my ($vmid) = @_;
2628 return "${var_run_tmpdir}/$vmid.pid";
2629}
2630
86fdcfb2
DA
2631sub vm_devices_list {
2632 my ($vmid) = @_;
2633
ceea9078
DM
2634 my $res = vm_mon_cmd($vmid, 'query-pci');
2635
2636 my $devices = {};
2637 foreach my $pcibus (@$res) {
2638 foreach my $device (@{$pcibus->{devices}}) {
2639 next if !$device->{'qdev_id'};
2640 $devices->{$device->{'qdev_id'}} = $device;
1dc4f496
DM
2641 }
2642 }
86fdcfb2 2643
1dc4f496 2644 return $devices;
86fdcfb2
DA
2645}
2646
ec21aa11 2647sub vm_deviceplug {
f19d1c47 2648 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 2649
cd6ecb89
AD
2650 return 1 if !check_running($vmid);
2651
2652 if ($deviceid eq 'tablet') {
0ecf8463 2653 my $devicefull = "usb-tablet,id=tablet,bus=uhci.0,port=1";
cd6ecb89
AD
2654 qemu_deviceadd($vmid, $devicefull);
2655 return 1;
2656 }
2657
2dbe827e 2658 return 1 if !$conf->{hotplug};
afdb31d5 2659
95d6343b
DA
2660 my $devices_list = vm_devices_list($vmid);
2661 return 1 if defined($devices_list->{$deviceid});
2662
40f28a9f
AD
2663 qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2664
5e5dcb73
DA
2665 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2666 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2667 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
5e5dcb73
DA
2668 qemu_deviceadd($vmid, $devicefull);
2669 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2670 qemu_drivedel($vmid, $deviceid);
2671 return undef;
2672 }
f19d1c47 2673 }
cfc817c7 2674
cdd20088
AD
2675 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2676 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 2677 my $pciaddr = print_pci_addr($deviceid);
cdd20088 2678 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
cfc817c7
DA
2679 qemu_deviceadd($vmid, $devicefull);
2680 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2681 }
2682
a4f091a0 2683 if ($deviceid =~ m/^(scsi)(\d+)$/) {
cdd20088
AD
2684 return 1 if ($conf->{scsihw} && $conf->{scsihw} ne 'lsi'); #virtio-scsi not yet support hotplug
2685 return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
a4f091a0 2686 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2687 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
a4f091a0
DA
2688 if(!qemu_deviceadd($vmid, $devicefull)) {
2689 qemu_drivedel($vmid, $deviceid);
2690 return undef;
2691 }
2692 }
2693
2630d2a9
DA
2694 if ($deviceid =~ m/^(net)(\d+)$/) {
2695 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2696 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2697 qemu_deviceadd($vmid, $netdevicefull);
2698 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2699 qemu_netdevdel($vmid, $deviceid);
2700 return undef;
2701 }
2702 }
2703
40f28a9f
AD
2704 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2705 my $bridgeid = $2;
2706 my $pciaddr = print_pci_addr($deviceid);
2707 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2708 qemu_deviceadd($vmid, $devicefull);
2709 return undef if !qemu_deviceaddverify($vmid, $deviceid);
2710 }
2711
5e5dcb73 2712 return 1;
a4dea331
DA
2713}
2714
ec21aa11 2715sub vm_deviceunplug {
f19d1c47 2716 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2717
cd6ecb89
AD
2718 return 1 if !check_running ($vmid);
2719
2720 if ($deviceid eq 'tablet') {
2721 qemu_devicedel($vmid, $deviceid);
2722 return 1;
2723 }
2724
2dbe827e 2725 return 1 if !$conf->{hotplug};
873c2d69 2726
95d6343b
DA
2727 my $devices_list = vm_devices_list($vmid);
2728 return 1 if !defined($devices_list->{$deviceid});
2729
ae57f6b3 2730 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
f19d1c47 2731
5e5dcb73 2732 if ($deviceid =~ m/^(virtio)(\d+)$/) {
5e5dcb73
DA
2733 qemu_devicedel($vmid, $deviceid);
2734 return undef if !qemu_devicedelverify($vmid, $deviceid);
1f219ef5 2735 return undef if !qemu_drivedel($vmid, $deviceid);
5e5dcb73 2736 }
cfc817c7
DA
2737
2738 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2739 return undef if !qemu_devicedel($vmid, $deviceid);
2740 }
2741
a4f091a0
DA
2742 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2743 return undef if !qemu_devicedel($vmid, $deviceid);
2744 return undef if !qemu_drivedel($vmid, $deviceid);
2745 }
2746
2630d2a9 2747 if ($deviceid =~ m/^(net)(\d+)$/) {
2630d2a9
DA
2748 qemu_devicedel($vmid, $deviceid);
2749 return undef if !qemu_devicedelverify($vmid, $deviceid);
750886f8 2750 return undef if !qemu_netdevdel($vmid, $deviceid);
2630d2a9
DA
2751 }
2752
5e5dcb73
DA
2753 return 1;
2754}
2755
2756sub qemu_deviceadd {
2757 my ($vmid, $devicefull) = @_;
873c2d69 2758
d695b5b7
AD
2759 $devicefull = "driver=".$devicefull;
2760 my %options = split(/[=,]/, $devicefull);
f19d1c47 2761
d695b5b7
AD
2762 vm_mon_cmd($vmid, "device_add" , %options);
2763 return 1;
5e5dcb73 2764}
afdb31d5 2765
5e5dcb73
DA
2766sub qemu_devicedel {
2767 my($vmid, $deviceid) = @_;
5a77d8c1
AD
2768 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
2769 return 1;
5e5dcb73
DA
2770}
2771
2772sub qemu_driveadd {
2773 my($storecfg, $vmid, $device) = @_;
2774
2775 my $drive = print_drive_full($storecfg, $vmid, $device);
7b7c6d1b 2776 my $ret = vm_human_monitor_command($vmid, "drive_add auto $drive");
5e5dcb73
DA
2777 # If the command succeeds qemu prints: "OK"
2778 if ($ret !~ m/OK/s) {
2779 syslog("err", "adding drive failed: $ret");
2780 return undef;
f19d1c47 2781 }
5e5dcb73
DA
2782 return 1;
2783}
afdb31d5 2784
5e5dcb73
DA
2785sub qemu_drivedel {
2786 my($vmid, $deviceid) = @_;
873c2d69 2787
7b7c6d1b 2788 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73
DA
2789 $ret =~ s/^\s+//;
2790 if ($ret =~ m/Device \'.*?\' not found/s) {
afdb31d5 2791 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
5e5dcb73
DA
2792 }
2793 elsif ($ret ne "") {
2794 syslog("err", "deleting drive $deviceid failed : $ret");
2795 return undef;
873c2d69 2796 }
5e5dcb73
DA
2797 return 1;
2798}
f19d1c47 2799
5e5dcb73
DA
2800sub qemu_deviceaddverify {
2801 my ($vmid,$deviceid) = @_;
873c2d69 2802
5e5dcb73
DA
2803 for (my $i = 0; $i <= 5; $i++) {
2804 my $devices_list = vm_devices_list($vmid);
2805 return 1 if defined($devices_list->{$deviceid});
2806 sleep 1;
afdb31d5 2807 }
5e5dcb73
DA
2808 syslog("err", "error on hotplug device $deviceid");
2809 return undef;
2810}
afdb31d5 2811
5e5dcb73
DA
2812
2813sub qemu_devicedelverify {
2814 my ($vmid,$deviceid) = @_;
2815
2816 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2817 for (my $i = 0; $i <= 5; $i++) {
2818 my $devices_list = vm_devices_list($vmid);
2819 return 1 if !defined($devices_list->{$deviceid});
2820 sleep 1;
afdb31d5 2821 }
5e5dcb73
DA
2822 syslog("err", "error on hot-unplugging device $deviceid");
2823 return undef;
873c2d69
DA
2824}
2825
cdd20088 2826sub qemu_findorcreatescsihw {
cfc817c7
DA
2827 my ($storecfg, $conf, $vmid, $device) = @_;
2828
cdd20088 2829 my $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
cfc817c7 2830 my $controller = int($device->{index} / $maxdev);
cdd20088 2831 my $scsihwid="scsihw$controller";
cfc817c7
DA
2832 my $devices_list = vm_devices_list($vmid);
2833
cdd20088
AD
2834 if(!defined($devices_list->{$scsihwid})) {
2835 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $scsihwid);
cfc817c7
DA
2836 }
2837 return 1;
2838}
2839
40f28a9f
AD
2840sub qemu_bridgeadd {
2841 my ($storecfg, $conf, $vmid, $device) = @_;
2842
2843 my $bridges = {};
2844 my $bridgeid = undef;
2845 print_pci_addr($device, $bridges);
2846
2847 while (my ($k, $v) = each %$bridges) {
2848 $bridgeid = $k;
2849 }
0e616534 2850 return if !$bridgeid || $bridgeid < 1;
40f28a9f
AD
2851 my $bridge = "pci.$bridgeid";
2852 my $devices_list = vm_devices_list($vmid);
2853
2854 if(!defined($devices_list->{$bridge})) {
2855 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $bridge);
2856 }
2857 return 1;
2858}
2859
2630d2a9
DA
2860sub qemu_netdevadd {
2861 my ($vmid, $conf, $device, $deviceid) = @_;
2862
2863 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
73aa03b8 2864 my %options = split(/[=,]/, $netdev);
2630d2a9 2865
73aa03b8
AD
2866 vm_mon_cmd($vmid, "netdev_add", %options);
2867 return 1;
2630d2a9
DA
2868}
2869
2870sub qemu_netdevdel {
2871 my ($vmid, $deviceid) = @_;
2872
89c1e0f4
AD
2873 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2874 return 1;
2630d2a9
DA
2875}
2876
affd2f88
AD
2877sub qemu_block_set_io_throttle {
2878 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2879
f3f323a3
AD
2880 return if !check_running($vmid) ;
2881
f3f323a3
AD
2882 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));
2883
affd2f88
AD
2884}
2885
f5eb281a 2886# old code, only used to shutdown old VM after update
dab36e1e
DM
2887sub __read_avail {
2888 my ($fh, $timeout) = @_;
2889
2890 my $sel = new IO::Select;
2891 $sel->add($fh);
2892
2893 my $res = '';
2894 my $buf;
2895
2896 my @ready;
2897 while (scalar (@ready = $sel->can_read($timeout))) {
2898 my $count;
2899 if ($count = $fh->sysread($buf, 8192)) {
2900 if ($buf =~ /^(.*)\(qemu\) $/s) {
2901 $res .= $1;
2902 last;
2903 } else {
2904 $res .= $buf;
2905 }
2906 } else {
2907 if (!defined($count)) {
2908 die "$!\n";
2909 }
2910 last;
2911 }
2912 }
2913
2914 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 2915
dab36e1e
DM
2916 return $res;
2917}
2918
f5eb281a 2919# old code, only used to shutdown old VM after update
dab36e1e
DM
2920sub vm_monitor_command {
2921 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 2922
dab36e1e
DM
2923 my $res;
2924
2925 eval {
2926 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2927
2928 my $sname = "${var_run_tmpdir}/$vmid.mon";
2929
2930 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2931 die "unable to connect to VM $vmid socket - $!\n";
2932
2933 my $timeout = 3;
2934
2935 # hack: migrate sometime blocks the monitor (when migrate_downtime
2936 # is set)
2937 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2938 $timeout = 60*60; # 1 hour
2939 }
2940
2941 # read banner;
2942 my $data = __read_avail($sock, $timeout);
2943
2944 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2945 die "got unexpected qemu monitor banner\n";
2946 }
2947
2948 my $sel = new IO::Select;
2949 $sel->add($sock);
2950
2951 if (!scalar(my @ready = $sel->can_write($timeout))) {
2952 die "monitor write error - timeout";
2953 }
2954
2955 my $fullcmd = "$cmdstr\r";
2956
2957 # syslog('info', "VM $vmid monitor command: $cmdstr");
2958
2959 my $b;
2960 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2961 die "monitor write error - $!";
2962 }
2963
2964 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2965
2966 $timeout = 20;
2967
2968 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2969 $timeout = 60*60; # 1 hour
2970 } elsif ($cmdstr =~ m/^(eject|change)/) {
2971 $timeout = 60; # note: cdrom mount command is slow
2972 }
2973 if ($res = __read_avail($sock, $timeout)) {
2974
2975 my @lines = split("\r?\n", $res);
f5eb281a 2976
dab36e1e 2977 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 2978
dab36e1e
DM
2979 $res = join("\n", @lines);
2980 $res .= "\n";
2981 }
2982 };
2983
2984 my $err = $@;
2985
2986 if ($err) {
2987 syslog("err", "VM $vmid monitor command failed - $err");
2988 die $err;
2989 }
f5eb281a 2990
dab36e1e
DM
2991 return $res;
2992}
2993
c1175c92
AD
2994sub qemu_block_resize {
2995 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2996
ed221350 2997 my $running = check_running($vmid);
c1175c92
AD
2998
2999 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3000
3001 return if !$running;
3002
3003 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3004
3005}
3006
1ab0057c
AD
3007sub qemu_volume_snapshot {
3008 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3009
ed221350 3010 my $running = check_running($vmid);
1ab0057c
AD
3011
3012 return if !PVE::Storage::volume_snapshot($storecfg, $volid, $snap, $running);
3013
3014 return if !$running;
3015
3016 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3017
3018}
3019
fc46aff9
AD
3020sub qemu_volume_snapshot_delete {
3021 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3022
ed221350 3023 my $running = check_running($vmid);
fc46aff9
AD
3024
3025 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3026
3027 return if !$running;
3028
18bfb361 3029 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3030}
3031
3d5149c9
AD
3032sub qga_freezefs {
3033 my ($vmid) = @_;
3034
3035 #need to impplement call to qemu-ga
3036}
3037
e8f3f18e
AD
3038sub qga_unfreezefs {
3039 my ($vmid) = @_;
3040
3041 #need to impplement call to qemu-ga
3042}
3043
1e3baf05 3044sub vm_start {
1d794448 3045 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
1e3baf05 3046
6b64503e 3047 lock_config($vmid, sub {
7e8dcf2c 3048 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 3049
8b43bc11 3050 die "you can't start a vm if it's a template\n" if is_template($conf);
3dcb98d5 3051
6b64503e 3052 check_lock($conf) if !$skiplock;
1e3baf05 3053
7e8dcf2c 3054 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 3055
6c47d546
DM
3056 my $defaults = load_defaults();
3057
3058 # set environment variable useful inside network script
3059 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
3060
1d794448 3061 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 3062
1e3baf05 3063 my $migrate_port = 0;
5bc1e039 3064 my $migrate_uri;
1e3baf05
DM
3065 if ($statefile) {
3066 if ($statefile eq 'tcp') {
5bc1e039
SP
3067 my $localip = "localhost";
3068 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
3069 if ($datacenterconf->{migration_unsecure}) {
3070 my $nodename = PVE::INotify::nodename();
3071 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
3072 }
f9a971e0 3073 $migrate_port = PVE::Tools::next_migrate_port();
5bc1e039 3074 $migrate_uri = "tcp:${localip}:${migrate_port}";
6c47d546
DM
3075 push @$cmd, '-incoming', $migrate_uri;
3076 push @$cmd, '-S';
1e3baf05 3077 } else {
6c47d546 3078 push @$cmd, '-loadstate', $statefile;
1e3baf05 3079 }
91bd6c90
DM
3080 } elsif ($paused) {
3081 push @$cmd, '-S';
1e3baf05
DM
3082 }
3083
1e3baf05 3084 # host pci devices
040b06b7
DA
3085 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
3086 my $d = parse_hostpci($conf->{"hostpci$i"});
3087 next if !$d;
3088 my $info = pci_device_info("0000:$d->{pciid}");
3089 die "IOMMU not present\n" if !check_iommu_support();
3090 die "no pci device info for device '$d->{pciid}'\n" if !$info;
3091 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
3092 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
3093 }
1e3baf05
DM
3094
3095 PVE::Storage::activate_volumes($storecfg, $vollist);
3096
585b6e28
DM
3097 eval { run_command($cmd, timeout => $statefile ? undef : 30,
3098 umask => 0077); };
1e3baf05 3099 my $err = $@;
ff1a2432 3100 die "start failed: $err" if $err;
1e3baf05 3101
5bc1e039 3102 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 3103
8c609afd 3104 if ($statefile && $statefile ne 'tcp') {
95381ce0 3105 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 3106 warn $@ if $@;
62de2cbd
DM
3107 }
3108
1d794448 3109 if ($migratedfrom) {
e18b0b99
AD
3110 my $capabilities = {};
3111 $capabilities->{capability} = "xbzrle";
3112 $capabilities->{state} = JSON::true;
ed221350 3113 eval { vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]); };
1d794448
DM
3114 warn $@ if $@;
3115
3116 if ($spice_port) {
3117 print "spice listens on port $spice_port\n";
3118 if ($spice_ticket) {
3119 PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
3120 PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
3121 }
3122 }
3123
1d794448 3124 } else {
4ec05c4c 3125
15b1fc93 3126 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 3127 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 3128 if $conf->{balloon};
be190583
DM
3129 vm_mon_cmd_nocheck($vmid, 'qom-set',
3130 path => "machine/peripheral/balloon0",
3131 property => "guest-stats-polling-interval",
4ec05c4c
AD
3132 value => 2);
3133 }
e18b0b99 3134 }
1e3baf05
DM
3135 });
3136}
3137
0eedc444
AD
3138sub vm_mon_cmd {
3139 my ($vmid, $execute, %params) = @_;
3140
26f11676
DM
3141 my $cmd = { execute => $execute, arguments => \%params };
3142 vm_qmp_command($vmid, $cmd);
0eedc444
AD
3143}
3144
3145sub vm_mon_cmd_nocheck {
3146 my ($vmid, $execute, %params) = @_;
3147
26f11676
DM
3148 my $cmd = { execute => $execute, arguments => \%params };
3149 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
3150}
3151
c971c4f2 3152sub vm_qmp_command {
d967756b 3153 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 3154
c971c4f2 3155 my $res;
26f11676 3156
14db5366
DM
3157 my $timeout;
3158 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
3159 $timeout = $cmd->{arguments}->{timeout};
3160 delete $cmd->{arguments}->{timeout};
3161 }
be190583 3162
c971c4f2
AD
3163 eval {
3164 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
ed221350 3165 my $sname = qmp_socket($vmid);
f5eb281a 3166 if (-e $sname) {
dab36e1e
DM
3167 my $qmpclient = PVE::QMPClient->new();
3168
14db5366 3169 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
dab36e1e
DM
3170 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
3171 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
3172 if scalar(%{$cmd->{arguments}});
3173 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
3174 } else {
3175 die "unable to open monitor socket\n";
3176 }
c971c4f2 3177 };
26f11676 3178 if (my $err = $@) {
c971c4f2
AD
3179 syslog("err", "VM $vmid qmp command failed - $err");
3180 die $err;
3181 }
3182
3183 return $res;
3184}
3185
9df5cbcc
DM
3186sub vm_human_monitor_command {
3187 my ($vmid, $cmdline) = @_;
3188
3189 my $res;
3190
f5eb281a 3191 my $cmd = {
9df5cbcc
DM
3192 execute => 'human-monitor-command',
3193 arguments => { 'command-line' => $cmdline},
3194 };
3195
3196 return vm_qmp_command($vmid, $cmd);
3197}
3198
1e3baf05
DM
3199sub vm_commandline {
3200 my ($storecfg, $vmid) = @_;
3201
6b64503e 3202 my $conf = load_config($vmid);
1e3baf05
DM
3203
3204 my $defaults = load_defaults();
3205
6b64503e 3206 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 3207
6b64503e 3208 return join(' ', @$cmd);
1e3baf05
DM
3209}
3210
3211sub vm_reset {
3212 my ($vmid, $skiplock) = @_;
3213
6b64503e 3214 lock_config($vmid, sub {
1e3baf05 3215
6b64503e 3216 my $conf = load_config($vmid);
1e3baf05 3217
6b64503e 3218 check_lock($conf) if !$skiplock;
1e3baf05 3219
816e2c4a 3220 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
3221 });
3222}
3223
3224sub get_vm_volumes {
3225 my ($conf) = @_;
1e3baf05 3226
ff1a2432 3227 my $vollist = [];
d5769dc2
DM
3228 foreach_volid($conf, sub {
3229 my ($volid, $is_cdrom) = @_;
ff1a2432 3230
d5769dc2 3231 return if $volid =~ m|^/|;
ff1a2432 3232
d5769dc2
DM
3233 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
3234 return if !$sid;
ff1a2432
DM
3235
3236 push @$vollist, $volid;
1e3baf05 3237 });
ff1a2432
DM
3238
3239 return $vollist;
3240}
3241
3242sub vm_stop_cleanup {
254575e9 3243 my ($storecfg, $vmid, $conf, $keepActive) = @_;
ff1a2432 3244
745fed70
DM
3245 eval {
3246 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 3247
254575e9
DM
3248 if (!$keepActive) {
3249 my $vollist = get_vm_volumes($conf);
3250 PVE::Storage::deactivate_volumes($storecfg, $vollist);
3251 }
961bfcb2 3252
ab6a046f 3253 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
3254 unlink "/var/run/qemu-server/${vmid}.$ext";
3255 }
745fed70
DM
3256 };
3257 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
3258}
3259
e6c3b671 3260# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
3261# We need that when migration VMs to other nodes (files already moved)
3262# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 3263sub vm_stop {
af30308f 3264 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 3265
9269013a 3266 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 3267
af30308f
DM
3268 if ($migratedfrom){
3269 my $pid = check_running($vmid, $nocheck, $migratedfrom);
3270 kill 15, $pid if $pid;
3271 my $conf = load_config($vmid, $migratedfrom);
3272 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive);
3273 return;
3274 }
3275
e6c3b671 3276 lock_config($vmid, sub {
1e3baf05 3277
e6c3b671 3278 my $pid = check_running($vmid, $nocheck);
ff1a2432 3279 return if !$pid;
1e3baf05 3280
ff1a2432 3281 my $conf;
e6c3b671 3282 if (!$nocheck) {
ff1a2432 3283 $conf = load_config($vmid);
e6c3b671 3284 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
3285 if (!defined($timeout) && $shutdown && $conf->{startup}) {
3286 my $opts = parse_startup($conf->{startup});
3287 $timeout = $opts->{down} if $opts->{down};
3288 }
e6c3b671 3289 }
19672434 3290
7f4a5b5a
DM
3291 $timeout = 60 if !defined($timeout);
3292
9269013a
DM
3293 eval {
3294 if ($shutdown) {
988903ca 3295 $nocheck ? vm_mon_cmd_nocheck($vmid, "system_powerdown") : vm_mon_cmd($vmid, "system_powerdown");
bcb7c9cf 3296
9269013a 3297 } else {
988903ca 3298 $nocheck ? vm_mon_cmd_nocheck($vmid, "quit") : vm_mon_cmd($vmid, "quit");
afdb31d5 3299 }
9269013a 3300 };
1e3baf05
DM
3301 my $err = $@;
3302
3303 if (!$err) {
1e3baf05 3304 my $count = 0;
e6c3b671 3305 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3306 $count++;
3307 sleep 1;
3308 }
3309
3310 if ($count >= $timeout) {
9269013a
DM
3311 if ($force) {
3312 warn "VM still running - terminating now with SIGTERM\n";
3313 kill 15, $pid;
3314 } else {
3315 die "VM quit/powerdown failed - got timeout\n";
3316 }
3317 } else {
254575e9 3318 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
9269013a 3319 return;
1e3baf05
DM
3320 }
3321 } else {
9269013a
DM
3322 if ($force) {
3323 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3324 kill 15, $pid;
3325 } else {
afdb31d5 3326 die "VM quit/powerdown failed\n";
9269013a 3327 }
1e3baf05
DM
3328 }
3329
3330 # wait again
ff1a2432 3331 $timeout = 10;
1e3baf05
DM
3332
3333 my $count = 0;
e6c3b671 3334 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3335 $count++;
3336 sleep 1;
3337 }
3338
3339 if ($count >= $timeout) {
ff1a2432 3340 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 3341 kill 9, $pid;
ff1a2432 3342 sleep 1;
1e3baf05
DM
3343 }
3344
254575e9 3345 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
ff1a2432 3346 });
1e3baf05
DM
3347}
3348
3349sub vm_suspend {
3350 my ($vmid, $skiplock) = @_;
3351
6b64503e 3352 lock_config($vmid, sub {
1e3baf05 3353
6b64503e 3354 my $conf = load_config($vmid);
1e3baf05 3355
051347aa 3356 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
bcb7c9cf 3357
f77f91f3 3358 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
3359 });
3360}
3361
3362sub vm_resume {
3363 my ($vmid, $skiplock) = @_;
3364
6b64503e 3365 lock_config($vmid, sub {
1e3baf05 3366
6b64503e 3367 my $conf = load_config($vmid);
1e3baf05 3368
051347aa 3369 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
1e3baf05 3370
12060fe8 3371 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
3372 });
3373}
3374
5fdbe4f0
DM
3375sub vm_sendkey {
3376 my ($vmid, $skiplock, $key) = @_;
1e3baf05 3377
6b64503e 3378 lock_config($vmid, sub {
1e3baf05 3379
6b64503e 3380 my $conf = load_config($vmid);
f5eb281a 3381
7b7c6d1b
DM
3382 # there is no qmp command, so we use the human monitor command
3383 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
3384 });
3385}
3386
3387sub vm_destroy {
3388 my ($storecfg, $vmid, $skiplock) = @_;
3389
6b64503e 3390 lock_config($vmid, sub {
1e3baf05 3391
6b64503e 3392 my $conf = load_config($vmid);
1e3baf05 3393
6b64503e 3394 check_lock($conf) if !$skiplock;
1e3baf05 3395
ff1a2432
DM
3396 if (!check_running($vmid)) {
3397 fairsched_rmnod($vmid); # try to destroy group
3398 destroy_vm($storecfg, $vmid);
3399 } else {
3400 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
3401 }
3402 });
3403}
3404
1e3baf05
DM
3405# pci helpers
3406
3407sub file_write {
3408 my ($filename, $buf) = @_;
3409
6b64503e 3410 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
3411 return undef if !$fh;
3412
3413 my $res = print $fh $buf;
3414
3415 $fh->close();
3416
3417 return $res;
3418}
3419
3420sub pci_device_info {
3421 my ($name) = @_;
3422
3423 my $res;
3424
3425 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3426 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3427
3428 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
3429 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3430
3431 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
3432 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3433
3434 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
3435 return undef if !defined($product) || $product !~ s/^0x//;
3436
3437 $res = {
3438 name => $name,
3439 vendor => $vendor,
3440 product => $product,
3441 domain => $domain,
3442 bus => $bus,
3443 slot => $slot,
3444 func => $func,
3445 irq => $irq,
3446 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
3447 };
3448
3449 return $res;
3450}
3451
3452sub pci_dev_reset {
3453 my ($dev) = @_;
3454
3455 my $name = $dev->{name};
3456
3457 my $fn = "$pcisysfs/devices/$name/reset";
3458
6b64503e 3459 return file_write($fn, "1");
1e3baf05
DM
3460}
3461
3462sub pci_dev_bind_to_stub {
3463 my ($dev) = @_;
3464
3465 my $name = $dev->{name};
3466
3467 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3468 return 1 if -d $testdir;
3469
3470 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 3471 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
3472
3473 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 3474 if (!file_write($fn, $name)) {
1e3baf05
DM
3475 return undef if -f $fn;
3476 }
3477
3478 $fn = "$pcisysfs/drivers/pci-stub/bind";
3479 if (! -d $testdir) {
6b64503e 3480 return undef if !file_write($fn, $name);
1e3baf05
DM
3481 }
3482
3483 return -d $testdir;
3484}
3485
afdb31d5 3486sub print_pci_addr {
5bdcf937 3487 my ($id, $bridges) = @_;
6b64503e 3488
72a063e4 3489 my $res = '';
6b64503e 3490 my $devices = {
24f0d39a 3491 piix3 => { bus => 0, addr => 1 },
e5f7f8ed 3492 #addr2 : first videocard
13b5a753 3493 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 3494 watchdog => { bus => 0, addr => 4 },
cdd20088
AD
3495 scsihw0 => { bus => 0, addr => 5 },
3496 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 3497 ahci0 => { bus => 0, addr => 7 },
ab6a046f 3498 qga0 => { bus => 0, addr => 8 },
1011b570 3499 spice => { bus => 0, addr => 9 },
6b64503e
DM
3500 virtio0 => { bus => 0, addr => 10 },
3501 virtio1 => { bus => 0, addr => 11 },
3502 virtio2 => { bus => 0, addr => 12 },
3503 virtio3 => { bus => 0, addr => 13 },
3504 virtio4 => { bus => 0, addr => 14 },
3505 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
3506 hostpci0 => { bus => 0, addr => 16 },
3507 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
3508 net0 => { bus => 0, addr => 18 },
3509 net1 => { bus => 0, addr => 19 },
3510 net2 => { bus => 0, addr => 20 },
3511 net3 => { bus => 0, addr => 21 },
3512 net4 => { bus => 0, addr => 22 },
3513 net5 => { bus => 0, addr => 23 },
e5f7f8ed 3514 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
3515 'pci.1' => { bus => 0, addr => 30 },
3516 'pci.2' => { bus => 0, addr => 31 },
3517 'net6' => { bus => 1, addr => 1 },
3518 'net7' => { bus => 1, addr => 2 },
3519 'net8' => { bus => 1, addr => 3 },
3520 'net9' => { bus => 1, addr => 4 },
3521 'net10' => { bus => 1, addr => 5 },
3522 'net11' => { bus => 1, addr => 6 },
3523 'net12' => { bus => 1, addr => 7 },
3524 'net13' => { bus => 1, addr => 8 },
3525 'net14' => { bus => 1, addr => 9 },
3526 'net15' => { bus => 1, addr => 10 },
3527 'net16' => { bus => 1, addr => 11 },
3528 'net17' => { bus => 1, addr => 12 },
3529 'net18' => { bus => 1, addr => 13 },
3530 'net19' => { bus => 1, addr => 14 },
3531 'net20' => { bus => 1, addr => 15 },
3532 'net21' => { bus => 1, addr => 16 },
3533 'net22' => { bus => 1, addr => 17 },
3534 'net23' => { bus => 1, addr => 18 },
3535 'net24' => { bus => 1, addr => 19 },
3536 'net25' => { bus => 1, addr => 20 },
3537 'net26' => { bus => 1, addr => 21 },
3538 'net27' => { bus => 1, addr => 22 },
3539 'net28' => { bus => 1, addr => 23 },
3540 'net29' => { bus => 1, addr => 24 },
3541 'net30' => { bus => 1, addr => 25 },
3542 'net31' => { bus => 1, addr => 26 },
3543 'virtio6' => { bus => 2, addr => 1 },
3544 'virtio7' => { bus => 2, addr => 2 },
3545 'virtio8' => { bus => 2, addr => 3 },
3546 'virtio9' => { bus => 2, addr => 4 },
3547 'virtio10' => { bus => 2, addr => 5 },
3548 'virtio11' => { bus => 2, addr => 6 },
3549 'virtio12' => { bus => 2, addr => 7 },
3550 'virtio13' => { bus => 2, addr => 8 },
3551 'virtio14' => { bus => 2, addr => 9 },
3552 'virtio15' => { bus => 2, addr => 10 },
6b64503e
DM
3553 };
3554
3555 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 3556 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
3557 my $bus = $devices->{$id}->{bus};
3558 $res = ",bus=pci.$bus,addr=$addr";
98627641 3559 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
3560 }
3561 return $res;
3562
3563}
3564
3e16d5fc
DM
3565# vzdump restore implementaion
3566
ed221350 3567sub tar_archive_read_firstfile {
3e16d5fc 3568 my $archive = shift;
afdb31d5 3569
3e16d5fc
DM
3570 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
3571
3572 # try to detect archive type first
3573 my $pid = open (TMP, "tar tf '$archive'|") ||
3574 die "unable to open file '$archive'\n";
3575 my $firstfile = <TMP>;
3576 kill 15, $pid;
3577 close TMP;
3578
3579 die "ERROR: archive contaions no data\n" if !$firstfile;
3580 chomp $firstfile;
3581
3582 return $firstfile;
3583}
3584
ed221350
DM
3585sub tar_restore_cleanup {
3586 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
3587
3588 print STDERR "starting cleanup\n";
3589
3590 if (my $fd = IO::File->new($statfile, "r")) {
3591 while (defined(my $line = <$fd>)) {
3592 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3593 my $volid = $2;
3594 eval {
3595 if ($volid =~ m|^/|) {
3596 unlink $volid || die 'unlink failed\n';
3597 } else {
ed221350 3598 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 3599 }
afdb31d5 3600 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
3601 };
3602 print STDERR "unable to cleanup '$volid' - $@" if $@;
3603 } else {
3604 print STDERR "unable to parse line in statfile - $line";
afdb31d5 3605 }
3e16d5fc
DM
3606 }
3607 $fd->close();
3608 }
3609}
3610
3611sub restore_archive {
a0d1b1a2 3612 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 3613
91bd6c90
DM
3614 my $format = $opts->{format};
3615 my $comp;
3616
3617 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
3618 $format = 'tar' if !$format;
3619 $comp = 'gzip';
3620 } elsif ($archive =~ m/\.tar$/) {
3621 $format = 'tar' if !$format;
3622 } elsif ($archive =~ m/.tar.lzo$/) {
3623 $format = 'tar' if !$format;
3624 $comp = 'lzop';
3625 } elsif ($archive =~ m/\.vma$/) {
3626 $format = 'vma' if !$format;
3627 } elsif ($archive =~ m/\.vma\.gz$/) {
3628 $format = 'vma' if !$format;
3629 $comp = 'gzip';
3630 } elsif ($archive =~ m/\.vma\.lzo$/) {
3631 $format = 'vma' if !$format;
3632 $comp = 'lzop';
3633 } else {
3634 $format = 'vma' if !$format; # default
3635 }
3636
3637 # try to detect archive format
3638 if ($format eq 'tar') {
3639 return restore_tar_archive($archive, $vmid, $user, $opts);
3640 } else {
3641 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
3642 }
3643}
3644
3645sub restore_update_config_line {
3646 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
3647
3648 return if $line =~ m/^\#qmdump\#/;
3649 return if $line =~ m/^\#vzdump\#/;
3650 return if $line =~ m/^lock:/;
3651 return if $line =~ m/^unused\d+:/;
3652 return if $line =~ m/^parent:/;
ca3e4fa4 3653 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
3654
3655 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3656 # try to convert old 1.X settings
3657 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3658 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3659 my ($model, $macaddr) = split(/\=/, $devconfig);
3660 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
3661 my $net = {
3662 model => $model,
3663 bridge => "vmbr$ind",
3664 macaddr => $macaddr,
3665 };
3666 my $netstr = print_net($net);
3667
3668 print $outfd "net$cookie->{netcount}: $netstr\n";
3669 $cookie->{netcount}++;
3670 }
3671 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
3672 my ($id, $netstr) = ($1, $2);
3673 my $net = parse_net($netstr);
3674 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3675 $netstr = print_net($net);
3676 print $outfd "$id: $netstr\n";
3677 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
3678 my $virtdev = $1;
907ea891 3679 my $value = $3;
91bd6c90
DM
3680 if ($line =~ m/backup=no/) {
3681 print $outfd "#$line";
3682 } elsif ($virtdev && $map->{$virtdev}) {
ed221350 3683 my $di = parse_drive($virtdev, $value);
8fd57431 3684 delete $di->{format}; # format can change on restore
91bd6c90 3685 $di->{file} = $map->{$virtdev};
ed221350 3686 $value = print_drive($vmid, $di);
91bd6c90
DM
3687 print $outfd "$virtdev: $value\n";
3688 } else {
3689 print $outfd $line;
3690 }
3691 } else {
3692 print $outfd $line;
3693 }
3694}
3695
3696sub scan_volids {
3697 my ($cfg, $vmid) = @_;
3698
3699 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
3700
3701 my $volid_hash = {};
3702 foreach my $storeid (keys %$info) {
3703 foreach my $item (@{$info->{$storeid}}) {
3704 next if !($item->{volid} && $item->{size});
5996a936 3705 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
3706 $volid_hash->{$item->{volid}} = $item;
3707 }
3708 }
3709
3710 return $volid_hash;
3711}
3712
a8e2f942
DM
3713sub get_used_paths {
3714 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
3715
3716 my $used_path = {};
3717
3718 my $scan_config = sub {
3719 my ($cref, $snapname) = @_;
3720
3721 foreach my $key (keys %$cref) {
3722 my $value = $cref->{$key};
3723 if (valid_drivename($key)) {
3724 next if $skip_drive && $key eq $skip_drive;
3725 my $drive = parse_drive($key, $value);
3726 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
3727 if ($drive->{file} =~ m!^/!) {
3728 $used_path->{$drive->{file}}++; # = 1;
3729 } else {
3730 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
3731 next if !$storeid;
3732 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
3733 next if !$scfg;
3734 my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
3735 $used_path->{$path}++; # = 1;
3736 }
3737 }
3738 }
3739 };
3740
3741 &$scan_config($conf);
3742
3743 undef $skip_drive;
3744
3745 if ($scan_snapshots) {
3746 foreach my $snapname (keys %{$conf->{snapshots}}) {
3747 &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
3748 }
3749 }
3750
3751 return $used_path;
3752}
3753
91bd6c90
DM
3754sub update_disksize {
3755 my ($vmid, $conf, $volid_hash) = @_;
be190583 3756
91bd6c90
DM
3757 my $changes;
3758
3759 my $used = {};
3760
5996a936
DM
3761 # Note: it is allowed to define multiple storages with same path (alias), so
3762 # we need to check both 'volid' and real 'path' (two different volid can point
3763 # to the same path).
3764
3765 my $usedpath = {};
be190583 3766
91bd6c90
DM
3767 # update size info
3768 foreach my $opt (keys %$conf) {
ed221350
DM
3769 if (valid_drivename($opt)) {
3770 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
3771 my $volid = $drive->{file};
3772 next if !$volid;
3773
3774 $used->{$volid} = 1;
be190583 3775 if ($volid_hash->{$volid} &&
5996a936
DM
3776 (my $path = $volid_hash->{$volid}->{path})) {
3777 $usedpath->{$path} = 1;
3778 }
91bd6c90 3779
ed221350 3780 next if drive_is_cdrom($drive);
91bd6c90
DM
3781 next if !$volid_hash->{$volid};
3782
3783 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
3784 my $new = print_drive($vmid, $drive);
3785 if ($new ne $conf->{$opt}) {
3786 $changes = 1;
3787 $conf->{$opt} = $new;
3788 }
91bd6c90
DM
3789 }
3790 }
3791
5996a936
DM
3792 # remove 'unusedX' entry if volume is used
3793 foreach my $opt (keys %$conf) {
3794 next if $opt !~ m/^unused\d+$/;
3795 my $volid = $conf->{$opt};
3796 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 3797 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
3798 $changes = 1;
3799 delete $conf->{$opt};
3800 }
3801 }
3802
91bd6c90
DM
3803 foreach my $volid (sort keys %$volid_hash) {
3804 next if $volid =~ m/vm-$vmid-state-/;
3805 next if $used->{$volid};
5996a936
DM
3806 my $path = $volid_hash->{$volid}->{path};
3807 next if !$path; # just to be sure
3808 next if $usedpath->{$path};
91bd6c90 3809 $changes = 1;
ed221350 3810 add_unused_volume($conf, $volid);
05937a14 3811 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
3812 }
3813
3814 return $changes;
3815}
3816
3817sub rescan {
3818 my ($vmid, $nolock) = @_;
3819
3820 my $cfg = PVE::Cluster::cfs_read_file("storage.cfg");
3821
3822 my $volid_hash = scan_volids($cfg, $vmid);
3823
3824 my $updatefn = sub {
3825 my ($vmid) = @_;
3826
ed221350 3827 my $conf = load_config($vmid);
be190583 3828
ed221350 3829 check_lock($conf);
91bd6c90 3830
03da3f0d
DM
3831 my $vm_volids = {};
3832 foreach my $volid (keys %$volid_hash) {
3833 my $info = $volid_hash->{$volid};
3834 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
3835 }
3836
3837 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 3838
ed221350 3839 update_config_nolock($vmid, $conf, 1) if $changes;
91bd6c90
DM
3840 };
3841
3842 if (defined($vmid)) {
3843 if ($nolock) {
3844 &$updatefn($vmid);
3845 } else {
ed221350 3846 lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
3847 }
3848 } else {
3849 my $vmlist = config_list();
3850 foreach my $vmid (keys %$vmlist) {
3851 if ($nolock) {
3852 &$updatefn($vmid);
3853 } else {
ed221350 3854 lock_config($vmid, $updatefn, $vmid);
be190583 3855 }
91bd6c90
DM
3856 }
3857 }
3858}
3859
3860sub restore_vma_archive {
3861 my ($archive, $vmid, $user, $opts, $comp) = @_;
3862
3863 my $input = $archive eq '-' ? "<&STDIN" : undef;
3864 my $readfrom = $archive;
3865
3866 my $uncomp = '';
3867 if ($comp) {
3868 $readfrom = '-';
3869 my $qarchive = PVE::Tools::shellquote($archive);
3870 if ($comp eq 'gzip') {
3871 $uncomp = "zcat $qarchive|";
3872 } elsif ($comp eq 'lzop') {
3873 $uncomp = "lzop -d -c $qarchive|";
3874 } else {
3875 die "unknown compression method '$comp'\n";
3876 }
be190583 3877
91bd6c90
DM
3878 }
3879
3880 my $tmpdir = "/var/tmp/vzdumptmp$$";
3881 rmtree $tmpdir;
3882
3883 # disable interrupts (always do cleanups)
3884 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3885 warn "got interrupt - ignored\n";
3886 };
3887
3888 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
3889 POSIX::mkfifo($mapfifo, 0600);
3890 my $fifofh;
3891
3892 my $openfifo = sub {
3893 open($fifofh, '>', $mapfifo) || die $!;
3894 };
3895
3896 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
3897
3898 my $oldtimeout;
3899 my $timeout = 5;
3900
3901 my $devinfo = {};
3902
3903 my $rpcenv = PVE::RPCEnvironment::get();
3904
ed221350 3905 my $conffile = config_file($vmid);
91bd6c90
DM
3906 my $tmpfn = "$conffile.$$.tmp";
3907
ed221350
DM
3908 # Note: $oldconf is undef if VM does not exists
3909 my $oldconf = PVE::Cluster::cfs_read_file(cfs_config_path($vmid));
3910
91bd6c90
DM
3911 my $print_devmap = sub {
3912 my $virtdev_hash = {};
3913
3914 my $cfgfn = "$tmpdir/qemu-server.conf";
3915
3916 # we can read the config - that is already extracted
3917 my $fh = IO::File->new($cfgfn, "r") ||
3918 "unable to read qemu-server.conf - $!\n";
3919
3920 while (defined(my $line = <$fh>)) {
3921 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
3922 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
3923 die "archive does not contain data for drive '$virtdev'\n"
3924 if !$devinfo->{$devname};
3925 if (defined($opts->{storage})) {
3926 $storeid = $opts->{storage} || 'local';
3927 } elsif (!$storeid) {
3928 $storeid = 'local';
3929 }
3930 $format = 'raw' if !$format;
3931 $devinfo->{$devname}->{devname} = $devname;
3932 $devinfo->{$devname}->{virtdev} = $virtdev;
3933 $devinfo->{$devname}->{format} = $format;
3934 $devinfo->{$devname}->{storeid} = $storeid;
3935
be190583 3936 # check permission on storage
91bd6c90
DM
3937 my $pool = $opts->{pool}; # todo: do we need that?
3938 if ($user ne 'root@pam') {
3939 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
3940 }
3941
3942 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
3943 }
3944 }
3945
3946 foreach my $devname (keys %$devinfo) {
be190583
DM
3947 die "found no device mapping information for device '$devname'\n"
3948 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
3949 }
3950
91bd6c90 3951 my $cfg = cfs_read_file('storage.cfg');
ed221350
DM
3952
3953 # create empty/temp config
be190583 3954 if ($oldconf) {
ed221350
DM
3955 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
3956 foreach_drive($oldconf, sub {
3957 my ($ds, $drive) = @_;
3958
3959 return if drive_is_cdrom($drive);
3960
3961 my $volid = $drive->{file};
3962
3963 return if !$volid || $volid =~ m|^/|;
3964
3965 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
3966 return if !$path || !$owner || ($owner != $vmid);
3967
3968 # Note: only delete disk we want to restore
3969 # other volumes will become unused
3970 if ($virtdev_hash->{$ds}) {
3971 PVE::Storage::vdisk_free($cfg, $volid);
3972 }
3973 });
3974 }
3975
3976 my $map = {};
91bd6c90
DM
3977 foreach my $virtdev (sort keys %$virtdev_hash) {
3978 my $d = $virtdev_hash->{$virtdev};
3979 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
3980 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
3981
3982 # test if requested format is supported
3983 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
3984 my $supported = grep { $_ eq $d->{format} } @$validFormats;
3985 $d->{format} = $defFormat if !$supported;
3986
91bd6c90
DM
3987 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
3988 $d->{format}, undef, $alloc_size);
3989 print STDERR "new volume ID is '$volid'\n";
3990 $d->{volid} = $volid;
3991 my $path = PVE::Storage::path($cfg, $volid);
3992
3993 my $write_zeros = 1;
3994 # fixme: what other storages types initialize volumes with zero?
be190583 3995 if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' ||
013d5275 3996 $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
91bd6c90
DM
3997 $write_zeros = 0;
3998 }
3999
4000 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
4001
4002 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
4003 $map->{$virtdev} = $volid;
4004 }
4005
4006 $fh->seek(0, 0) || die "seek failed - $!\n";
4007
4008 my $outfd = new IO::File ($tmpfn, "w") ||
4009 die "unable to write config for VM $vmid\n";
4010
4011 my $cookie = { netcount => 0 };
4012 while (defined(my $line = <$fh>)) {
be190583 4013 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
4014 }
4015
4016 $fh->close();
4017 $outfd->close();
4018 };
4019
4020 eval {
4021 # enable interrupts
4022 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
4023 die "interrupted by signal\n";
4024 };
4025 local $SIG{ALRM} = sub { die "got timeout\n"; };
4026
4027 $oldtimeout = alarm($timeout);
4028
4029 my $parser = sub {
4030 my $line = shift;
4031
4032 print "$line\n";
4033
4034 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
4035 my ($dev_id, $size, $devname) = ($1, $2, $3);
4036 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
4037 } elsif ($line =~ m/^CTIME: /) {
4038 &$print_devmap();
4039 print $fifofh "done\n";
4040 my $tmp = $oldtimeout || 0;
4041 $oldtimeout = undef;
4042 alarm($tmp);
4043 close($fifofh);
4044 }
4045 };
be190583 4046
91bd6c90
DM
4047 print "restore vma archive: $cmd\n";
4048 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
4049 };
4050 my $err = $@;
4051
4052 alarm($oldtimeout) if $oldtimeout;
4053
4054 unlink $mapfifo;
4055
4056 if ($err) {
4057 rmtree $tmpdir;
4058 unlink $tmpfn;
4059
4060 my $cfg = cfs_read_file('storage.cfg');
4061 foreach my $devname (keys %$devinfo) {
4062 my $volid = $devinfo->{$devname}->{volid};
4063 next if !$volid;
4064 eval {
4065 if ($volid =~ m|^/|) {
4066 unlink $volid || die 'unlink failed\n';
4067 } else {
4068 PVE::Storage::vdisk_free($cfg, $volid);
4069 }
4070 print STDERR "temporary volume '$volid' sucessfuly removed\n";
4071 };
4072 print STDERR "unable to cleanup '$volid' - $@" if $@;
4073 }
4074 die $err;
4075 }
4076
4077 rmtree $tmpdir;
ed221350
DM
4078
4079 rename($tmpfn, $conffile) ||
91bd6c90
DM
4080 die "unable to commit configuration file '$conffile'\n";
4081
ed221350
DM
4082 PVE::Cluster::cfs_update(); # make sure we read new file
4083
91bd6c90
DM
4084 eval { rescan($vmid, 1); };
4085 warn $@ if $@;
4086}
4087
4088sub restore_tar_archive {
4089 my ($archive, $vmid, $user, $opts) = @_;
4090
9c502e26 4091 if ($archive ne '-') {
ed221350 4092 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
4093 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
4094 if $firstfile ne 'qemu-server.conf';
4095 }
3e16d5fc 4096
ed221350 4097 my $storecfg = cfs_read_file('storage.cfg');
ebb55558 4098
ed221350 4099 # destroy existing data - keep empty config
ebb55558
DM
4100 my $vmcfgfn = PVE::QemuServer::config_file($vmid);
4101 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 4102
3e16d5fc
DM
4103 my $tocmd = "/usr/lib/qemu-server/qmextract";
4104
2415a446 4105 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 4106 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
4107 $tocmd .= ' --prealloc' if $opts->{prealloc};
4108 $tocmd .= ' --info' if $opts->{info};
4109
a0d1b1a2 4110 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 4111 # so we pipe to zcat
2415a446
DM
4112 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
4113 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
4114
4115 my $tmpdir = "/var/tmp/vzdumptmp$$";
4116 mkpath $tmpdir;
4117
4118 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
4119 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 4120 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 4121
ed221350 4122 my $conffile = config_file($vmid);
3e16d5fc
DM
4123 my $tmpfn = "$conffile.$$.tmp";
4124
4125 # disable interrupts (always do cleanups)
4126 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
4127 print STDERR "got interrupt - ignored\n";
4128 };
4129
afdb31d5 4130 eval {
3e16d5fc
DM
4131 # enable interrupts
4132 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
4133 die "interrupted by signal\n";
4134 };
4135
9c502e26
DM
4136 if ($archive eq '-') {
4137 print "extracting archive from STDIN\n";
4138 run_command($cmd, input => "<&STDIN");
4139 } else {
4140 print "extracting archive '$archive'\n";
4141 run_command($cmd);
4142 }
3e16d5fc
DM
4143
4144 return if $opts->{info};
4145
4146 # read new mapping
4147 my $map = {};
4148 my $statfile = "$tmpdir/qmrestore.stat";
4149 if (my $fd = IO::File->new($statfile, "r")) {
4150 while (defined (my $line = <$fd>)) {
4151 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4152 $map->{$1} = $2 if $1;
4153 } else {
4154 print STDERR "unable to parse line in statfile - $line\n";
4155 }
4156 }
4157 $fd->close();
4158 }
4159
4160 my $confsrc = "$tmpdir/qemu-server.conf";
4161
4162 my $srcfd = new IO::File($confsrc, "r") ||
4163 die "unable to open file '$confsrc'\n";
4164
4165 my $outfd = new IO::File ($tmpfn, "w") ||
4166 die "unable to write config for VM $vmid\n";
4167
91bd6c90 4168 my $cookie = { netcount => 0 };
3e16d5fc 4169 while (defined (my $line = <$srcfd>)) {
be190583 4170 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
4171 }
4172
4173 $srcfd->close();
4174 $outfd->close();
4175 };
4176 my $err = $@;
4177
afdb31d5 4178 if ($err) {
3e16d5fc
DM
4179
4180 unlink $tmpfn;
4181
ed221350 4182 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 4183
3e16d5fc 4184 die $err;
afdb31d5 4185 }
3e16d5fc
DM
4186
4187 rmtree $tmpdir;
4188
4189 rename $tmpfn, $conffile ||
4190 die "unable to commit configuration file '$conffile'\n";
91bd6c90 4191
ed221350
DM
4192 PVE::Cluster::cfs_update(); # make sure we read new file
4193
91bd6c90
DM
4194 eval { rescan($vmid, 1); };
4195 warn $@ if $@;
3e16d5fc
DM
4196};
4197
0d18dcfc
DM
4198
4199# Internal snapshots
4200
4201# NOTE: Snapshot create/delete involves several non-atomic
4202# action, and can take a long time.
4203# So we try to avoid locking the file and use 'lock' variable
4204# inside the config file instead.
4205
ef59d1ca
DM
4206my $snapshot_copy_config = sub {
4207 my ($source, $dest) = @_;
4208
4209 foreach my $k (keys %$source) {
4210 next if $k eq 'snapshots';
982c7f12
DM
4211 next if $k eq 'snapstate';
4212 next if $k eq 'snaptime';
18bfb361 4213 next if $k eq 'vmstate';
ef59d1ca
DM
4214 next if $k eq 'lock';
4215 next if $k eq 'digest';
db7c26e5 4216 next if $k eq 'description';
ef59d1ca 4217 next if $k =~ m/^unused\d+$/;
be190583 4218
ef59d1ca
DM
4219 $dest->{$k} = $source->{$k};
4220 }
4221};
4222
4223my $snapshot_apply_config = sub {
4224 my ($conf, $snap) = @_;
4225
4226 # copy snapshot list
4227 my $newconf = {
4228 snapshots => $conf->{snapshots},
4229 };
4230
db7c26e5 4231 # keep description and list of unused disks
ef59d1ca 4232 foreach my $k (keys %$conf) {
db7c26e5 4233 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
4234 $newconf->{$k} = $conf->{$k};
4235 }
4236
4237 &$snapshot_copy_config($snap, $newconf);
4238
4239 return $newconf;
4240};
4241
18bfb361
DM
4242sub foreach_writable_storage {
4243 my ($conf, $func) = @_;
4244
4245 my $sidhash = {};
4246
4247 foreach my $ds (keys %$conf) {
4248 next if !valid_drivename($ds);
4249
4250 my $drive = parse_drive($ds, $conf->{$ds});
4251 next if !$drive;
4252 next if drive_is_cdrom($drive);
4253
4254 my $volid = $drive->{file};
4255
4256 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 4257 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
4258 }
4259
4260 foreach my $sid (sort keys %$sidhash) {
4261 &$func($sid);
4262 }
4263}
4264
4265my $alloc_vmstate_volid = sub {
4266 my ($storecfg, $vmid, $conf, $snapname) = @_;
be190583 4267
18bfb361
DM
4268 # Note: we try to be smart when selecting a $target storage
4269
4270 my $target;
4271
4272 # search shared storage first
4273 foreach_writable_storage($conf, sub {
4274 my ($sid) = @_;
4275 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
4276 return if !$scfg->{shared};
4277
4278 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
4279 });
4280
4281 if (!$target) {
4282 # now search local storage
4283 foreach_writable_storage($conf, sub {
4284 my ($sid) = @_;
4285 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
4286 return if $scfg->{shared};
4287
4288 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
4289 });
4290 }
4291
4292 $target = 'local' if !$target;
4293
fe6249f4
DM
4294 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
4295 # we abort live save after $conf->{memory}, so we need at max twice that space
4296 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
4297
4298 my $name = "vm-$vmid-state-$snapname";
4299 my $scfg = PVE::Storage::storage_config($storecfg, $target);
4300 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
4301 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
4302
4303 return $volid;
4304};
4305
0d18dcfc 4306my $snapshot_prepare = sub {
18bfb361 4307 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
4308
4309 my $snap;
0d18dcfc
DM
4310
4311 my $updatefn = sub {
4312
4313 my $conf = load_config($vmid);
4314
be190583 4315 die "you can't take a snapshot if it's a template\n"
5295b23d
DM
4316 if is_template($conf);
4317
0d18dcfc
DM
4318 check_lock($conf);
4319
22c377f0
DM
4320 $conf->{lock} = 'snapshot';
4321
be190583
DM
4322 die "snapshot name '$snapname' already used\n"
4323 if defined($conf->{snapshots}->{$snapname});
0d18dcfc 4324
ee2f90b1 4325 my $storecfg = PVE::Storage::config();
7ea975ef 4326 die "snapshot feature is not available" if !has_feature('snapshot', $conf, $storecfg);
18bfb361 4327
782f4f75 4328 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 4329
18bfb361
DM
4330 if ($save_vmstate && check_running($vmid)) {
4331 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
4332 }
4333
ef59d1ca 4334 &$snapshot_copy_config($conf, $snap);
0d18dcfc 4335
782f4f75
DM
4336 $snap->{snapstate} = "prepare";
4337 $snap->{snaptime} = time();
4338 $snap->{description} = $comment if $comment;
4339
4b15803d
DM
4340 # always overwrite machine if we save vmstate. This makes sure we
4341 # can restore it later using correct machine type
4342 $snap->{machine} = get_current_qemu_machine($vmid) if $snap->{vmstate};
4343
0d18dcfc
DM
4344 update_config_nolock($vmid, $conf, 1);
4345 };
4346
4347 lock_config($vmid, $updatefn);
22c377f0
DM
4348
4349 return $snap;
0d18dcfc
DM
4350};
4351
4352my $snapshot_commit = sub {
4353 my ($vmid, $snapname) = @_;
4354
4355 my $updatefn = sub {
4356
4357 my $conf = load_config($vmid);
4358
be190583
DM
4359 die "missing snapshot lock\n"
4360 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
0d18dcfc
DM
4361
4362 my $snap = $conf->{snapshots}->{$snapname};
4363
be190583
DM
4364 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4365
4366 die "wrong snapshot state\n"
4367 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
0d18dcfc 4368
0d18dcfc 4369 delete $snap->{snapstate};
ee2f90b1 4370 delete $conf->{lock};
0d18dcfc 4371
ef59d1ca 4372 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 4373
05e5ad3f
DM
4374 $newconf->{parent} = $snapname;
4375
0d18dcfc
DM
4376 update_config_nolock($vmid, $newconf, 1);
4377 };
4378
4379 lock_config($vmid, $updatefn);
4380};
4381
22c377f0
DM
4382sub snapshot_rollback {
4383 my ($vmid, $snapname) = @_;
4384
4385 my $snap;
4386
4387 my $prepare = 1;
4388
a3222b91 4389 my $storecfg = PVE::Storage::config();
be190583 4390
22c377f0
DM
4391 my $updatefn = sub {
4392
4393 my $conf = load_config($vmid);
4394
8b43bc11 4395 die "you can't rollback if vm is a template\n" if is_template($conf);
90b0c6b3 4396
ab33a7c2
DM
4397 $snap = $conf->{snapshots}->{$snapname};
4398
be190583 4399 die "snapshot '$snapname' does not exist\n" if !defined($snap);
ab33a7c2 4400
be190583 4401 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
ab33a7c2
DM
4402 if $snap->{snapstate};
4403
a3222b91
DM
4404 if ($prepare) {
4405 check_lock($conf);
4406 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
4407 }
22c377f0
DM
4408
4409 die "unable to rollback vm $vmid: vm is running\n"
4410 if check_running($vmid);
4411
4412 if ($prepare) {
4413 $conf->{lock} = 'rollback';
4414 } else {
4415 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
4416 delete $conf->{lock};
4417 }
4418
4b15803d
DM
4419 my $forcemachine;
4420
22c377f0 4421 if (!$prepare) {
4b15803d
DM
4422 my $has_machine_config = defined($conf->{machine});
4423
22c377f0 4424 # copy snapshot config to current config
ef59d1ca
DM
4425 $conf = &$snapshot_apply_config($conf, $snap);
4426 $conf->{parent} = $snapname;
4b15803d 4427
d8b916fd
DM
4428 # Note: old code did not store 'machine', so we try to be smart
4429 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
4430 $forcemachine = $conf->{machine} || 'pc-i440fx-1.4';
be190583 4431 # we remove the 'machine' configuration if not explicitly specified
4b15803d
DM
4432 # in the original config.
4433 delete $conf->{machine} if $snap->{vmstate} && !$has_machine_config;
22c377f0
DM
4434 }
4435
4436 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
4437
4438 if (!$prepare && $snap->{vmstate}) {
4439 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
4b15803d 4440 vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
a3222b91 4441 }
22c377f0
DM
4442 };
4443
4444 lock_config($vmid, $updatefn);
be190583 4445
22c377f0
DM
4446 foreach_drive($snap, sub {
4447 my ($ds, $drive) = @_;
4448
4449 return if drive_is_cdrom($drive);
4450
4451 my $volid = $drive->{file};
4452 my $device = "drive-$ds";
4453
79e57b29 4454 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
4455 });
4456
4457 $prepare = 0;
4458 lock_config($vmid, $updatefn);
4459}
4460
9dcf4909
DM
4461my $savevm_wait = sub {
4462 my ($vmid) = @_;
4463
4464 for(;;) {
ed221350 4465 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
9dcf4909
DM
4466 if (!$stat->{status}) {
4467 die "savevm not active\n";
4468 } elsif ($stat->{status} eq 'active') {
4469 sleep(1);
4470 next;
4471 } elsif ($stat->{status} eq 'completed') {
4472 last;
4473 } else {
4474 die "query-savevm returned status '$stat->{status}'\n";
4475 }
4476 }
4477};
4478
0d18dcfc 4479sub snapshot_create {
18bfb361 4480 my ($vmid, $snapname, $save_vmstate, $freezefs, $comment) = @_;
0d18dcfc 4481
18bfb361 4482 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 4483
18bfb361 4484 $freezefs = $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
030dd626 4485
3ee28e38
DM
4486 my $drivehash = {};
4487
18bfb361
DM
4488 my $running = check_running($vmid);
4489
0d18dcfc
DM
4490 eval {
4491 # create internal snapshots of all drives
22c377f0
DM
4492
4493 my $storecfg = PVE::Storage::config();
a3222b91
DM
4494
4495 if ($running) {
4496 if ($snap->{vmstate}) {
be190583 4497 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
4498 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
4499 &$savevm_wait($vmid);
a3222b91 4500 } else {
9dcf4909 4501 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
4502 }
4503 };
4504
4505 qga_freezefs($vmid) if $running && $freezefs;
be190583 4506
22c377f0
DM
4507 foreach_drive($snap, sub {
4508 my ($ds, $drive) = @_;
4509
4510 return if drive_is_cdrom($drive);
0d18dcfc 4511
22c377f0
DM
4512 my $volid = $drive->{file};
4513 my $device = "drive-$ds";
4514
4515 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 4516 $drivehash->{$ds} = 1;
22c377f0 4517 });
0d18dcfc 4518 };
22c377f0
DM
4519 my $err = $@;
4520
1a71fa73 4521 eval { qga_unfreezefs($vmid) if $running && $freezefs; };
22c377f0
DM
4522 warn $@ if $@;
4523
9dcf4909 4524 eval { vm_mon_cmd($vmid, "savevm-end") if $running; };
22c377f0
DM
4525 warn $@ if $@;
4526
4527 if ($err) {
0d18dcfc 4528 warn "snapshot create failed: starting cleanup\n";
3ee28e38 4529 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
4530 warn $@ if $@;
4531 die $err;
4532 }
4533
4534 &$snapshot_commit($vmid, $snapname);
4535}
4536
3ee28e38 4537# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 4538sub snapshot_delete {
3ee28e38 4539 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
4540
4541 my $prepare = 1;
4542
22c377f0 4543 my $snap;
ee2f90b1 4544 my $unused = [];
0d18dcfc 4545
6cb1a8cf
DM
4546 my $unlink_parent = sub {
4547 my ($confref, $new_parent) = @_;
4548
4549 if ($confref->{parent} && $confref->{parent} eq $snapname) {
4550 if ($new_parent) {
4551 $confref->{parent} = $new_parent;
4552 } else {
4553 delete $confref->{parent};
4554 }
4555 }
4556 };
be190583 4557
0d18dcfc 4558 my $updatefn = sub {
2009f324 4559 my ($remove_drive) = @_;
0d18dcfc 4560
22c377f0 4561 my $conf = load_config($vmid);
0d18dcfc 4562
5295b23d
DM
4563 if (!$drivehash) {
4564 check_lock($conf);
be190583 4565 die "you can't delete a snapshot if vm is a template\n"
5295b23d
DM
4566 if is_template($conf);
4567 }
0d18dcfc 4568
22c377f0 4569 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc 4570
be190583 4571 die "snapshot '$snapname' does not exist\n" if !defined($snap);
0d18dcfc
DM
4572
4573 # remove parent refs
6cb1a8cf 4574 &$unlink_parent($conf, $snap->{parent});
0d18dcfc
DM
4575 foreach my $sn (keys %{$conf->{snapshots}}) {
4576 next if $sn eq $snapname;
6cb1a8cf 4577 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
0d18dcfc
DM
4578 }
4579
2009f324 4580 if ($remove_drive) {
18bfb361
DM
4581 if ($remove_drive eq 'vmstate') {
4582 delete $snap->{$remove_drive};
4583 } else {
4584 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
4585 my $volid = $drive->{file};
4586 delete $snap->{$remove_drive};
4587 add_unused_volume($conf, $volid);
4588 }
2009f324
DM
4589 }
4590
0d18dcfc
DM
4591 if ($prepare) {
4592 $snap->{snapstate} = 'delete';
4593 } else {
4594 delete $conf->{snapshots}->{$snapname};
3ee28e38 4595 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
4596 foreach my $volid (@$unused) {
4597 add_unused_volume($conf, $volid);
4598 }
0d18dcfc
DM
4599 }
4600
4601 update_config_nolock($vmid, $conf, 1);
4602 };
4603
4604 lock_config($vmid, $updatefn);
4605
18bfb361 4606 # now remove vmstate file
0d18dcfc 4607
22c377f0
DM
4608 my $storecfg = PVE::Storage::config();
4609
18bfb361
DM
4610 if ($snap->{vmstate}) {
4611 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
4612 if (my $err = $@) {
4613 die $err if !$force;
4614 warn $err;
4615 }
4616 # save changes (remove vmstate from snapshot)
4617 lock_config($vmid, $updatefn, 'vmstate') if !$force;
4618 };
4619
4620 # now remove all internal snapshots
4621 foreach_drive($snap, sub {
22c377f0
DM
4622 my ($ds, $drive) = @_;
4623
4624 return if drive_is_cdrom($drive);
3ee28e38 4625
22c377f0
DM
4626 my $volid = $drive->{file};
4627 my $device = "drive-$ds";
4628
2009f324
DM
4629 if (!$drivehash || $drivehash->{$ds}) {
4630 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
4631 if (my $err = $@) {
4632 die $err if !$force;
4633 warn $err;
4634 }
3ee28e38 4635 }
2009f324
DM
4636
4637 # save changes (remove drive fron snapshot)
4638 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 4639 push @$unused, $volid;
22c377f0 4640 });
0d18dcfc
DM
4641
4642 # now cleanup config
4643 $prepare = 0;
4644 lock_config($vmid, $updatefn);
4645}
4646
9cd07842 4647sub has_feature {
7ea975ef
AD
4648 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
4649
719893a9 4650 my $err;
7ea975ef
AD
4651 foreach_drive($conf, sub {
4652 my ($ds, $drive) = @_;
4653
4654 return if drive_is_cdrom($drive);
4655 my $volid = $drive->{file};
4656 $err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
4657 });
4658
719893a9 4659 return $err ? 0 : 1;
7ea975ef 4660}
04a69bb4
AD
4661
4662sub template_create {
4663 my ($vmid, $conf, $disk) = @_;
4664
04a69bb4 4665 my $storecfg = PVE::Storage::config();
04a69bb4 4666
9cd07842
DM
4667 foreach_drive($conf, sub {
4668 my ($ds, $drive) = @_;
4669
4670 return if drive_is_cdrom($drive);
4671 return if $disk && $ds ne $disk;
4672
4673 my $volid = $drive->{file};
bbd56097 4674 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 4675
04a69bb4
AD
4676 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
4677 $drive->{file} = $voliddst;
152fe752
DM
4678 $conf->{$ds} = print_drive($vmid, $drive);
4679 update_config_nolock($vmid, $conf, 1);
04a69bb4 4680 });
04a69bb4
AD
4681}
4682
624361b3
AD
4683sub is_template {
4684 my ($conf) = @_;
4685
96d695c0 4686 return 1 if defined $conf->{template} && $conf->{template} == 1;
624361b3
AD
4687}
4688
5133de42
AD
4689sub qemu_img_convert {
4690 my ($src_volid, $dst_volid, $size, $snapname) = @_;
4691
4692 my $storecfg = PVE::Storage::config();
4693 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
4694 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
4695
4696 if ($src_storeid && $dst_storeid) {
4697 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
4698 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
4699
4700 my $src_format = qemu_img_format($src_scfg, $src_volname);
4701 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
4702
4703 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
4704 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
4705
4706 my $cmd = [];
4707 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-C';
4708 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
4709 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
4710
4711 my $parser = sub {
4712 my $line = shift;
4713 if($line =~ m/\((\S+)\/100\%\)/){
4714 my $percent = $1;
4715 my $transferred = int($size * $percent / 100);
4716 my $remaining = $size - $transferred;
4717
4718 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
4719 }
4720
4721 };
4722
4723 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
4724 my $err = $@;
4725 die "copy failed: $err" if $err;
4726 }
4727}
4728
4729sub qemu_img_format {
4730 my ($scfg, $volname) = @_;
4731
ccb5c001 4732 if ($scfg->{path} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
5133de42 4733 return $1;
ccb5c001 4734 } elsif ($scfg->{type} eq 'iscsi') {
5133de42 4735 return "host_device";
be190583 4736 } else {
5133de42 4737 return "raw";
5133de42
AD
4738 }
4739}
4740
cfad42af
AD
4741sub qemu_drive_mirror {
4742 my ($vmid, $drive, $dst_volid, $vmiddst, $maxwait) = @_;
4743
4744 my $count = 1;
4745 my $old_len = 0;
4746 my $frozen = undef;
4747
4748 my $storecfg = PVE::Storage::config();
4749 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
4750
4751 if ($dst_storeid) {
4752 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
4753
152fe752 4754 my $format;
cfad42af
AD
4755 if ($dst_volname =~ m/\.(raw|qcow2)$/){
4756 $format = $1;
4757 }
4758
4759 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
4760
152fe752 4761 if ($format) {
be190583 4762 #fixme : sometime drive-mirror timeout, but works fine after.
152fe752 4763 # (I have see the problem with big volume > 200GB), so we need to eval
be190583 4764 eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing",
152fe752
DM
4765 sync => "full", target => $dst_path, format => $format); };
4766 } else {
be190583 4767 eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing",
152fe752 4768 sync => "full", target => $dst_path); };
cfad42af 4769 }
152fe752
DM
4770
4771 eval {
cfad42af 4772 while (1) {
152fe752 4773 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
cfad42af 4774 my $stat = @$stats[0];
f6ab3bdb
AD
4775 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
4776 die "error job is not mirroring" if $stat->{type} ne "mirror";
4777
cfad42af
AD
4778 my $transferred = $stat->{offset};
4779 my $total = $stat->{len};
4780 my $remaining = $total - $transferred;
4781 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
cfad42af
AD
4782
4783 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent %\n";
4784
4785 last if ($stat->{len} == $stat->{offset});
4786 if ($old_len == $stat->{offset}) {
4787 if ($maxwait && $count > $maxwait) {
4788 # if writes to disk occurs the disk needs to be freezed
4789 # to be able to complete the migration
4790 vm_suspend($vmid,1);
4791 $count = 0;
4792 $frozen = 1;
152fe752 4793 } else {
cfad42af
AD
4794 $count++ unless $frozen;
4795 }
152fe752
DM
4796 } elsif ($frozen) {
4797 vm_resume($vmid,1);
4798 $count = 0;
cfad42af
AD
4799 }
4800 $old_len = $stat->{offset};
4801 sleep 1;
4802 }
be190583 4803
2fc6bc17 4804 if ($vmiddst == $vmid) {
be190583 4805 # switch the disk if source and destination are on the same guest
2fc6bc17
DM
4806 vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive");
4807 }
cfad42af 4808 };
4fca0153 4809 if (my $err = $@) {
152fe752 4810 eval { vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive"); };
4fca0153 4811 die "mirroring error: $err";
cfad42af
AD
4812 }
4813
2fc6bc17
DM
4814 if ($vmiddst != $vmid) {
4815 # if we clone a disk for a new target vm, we don't switch the disk
152fe752 4816 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
cfad42af
AD
4817 }
4818 }
4819}
4820
152fe752 4821sub clone_disk {
be190583 4822 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
4823 $newvmid, $storage, $format, $full, $newvollist) = @_;
4824
4825 my $newvolid;
4826
4827 if (!$full) {
4828 print "create linked clone of drive $drivename ($drive->{file})\n";
4829 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid);
4830 push @$newvollist, $newvolid;
4831 } else {
4832 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
4833 $storeid = $storage if $storage;
4834
1377d7b0
DM
4835 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
4836 if (!$format) {
4837 $format = $drive->{format} || $defFormat;
152fe752
DM
4838 }
4839
1377d7b0
DM
4840 # test if requested format is supported - else use default
4841 my $supported = grep { $_ eq $format } @$validFormats;
4842 $format = $defFormat if !$supported;
4843
152fe752
DM
4844 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
4845
4846 print "create full clone of drive $drivename ($drive->{file})\n";
4847 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
4848 push @$newvollist, $newvolid;
4849
4850 if (!$running || $snapname) {
4851 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname);
4852 } else {
4853 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid);
be190583 4854 }
152fe752
DM
4855 }
4856
4857 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
4858
4859 my $disk = $drive;
4860 $disk->{format} = undef;
4861 $disk->{file} = $newvolid;
4862 $disk->{size} = $size;
4863
4864 return $disk;
4865}
4866
ff556cf2
DM
4867# this only works if VM is running
4868sub get_current_qemu_machine {
4869 my ($vmid) = @_;
4870
4871 my $cmd = { execute => 'query-machines', arguments => {} };
be190583 4872 my $res = PVE::QemuServer::vm_qmp_command($vmid, $cmd);
ff556cf2
DM
4873
4874 my ($current, $default);
4875 foreach my $e (@$res) {
4876 $default = $e->{name} if $e->{'is-default'};
4877 $current = $e->{name} if $e->{'is-current'};
4878 }
4879
4880 # fallback to the default machine if current is not supported by qemu
4881 return $current || $default || 'pc';
4882}
4883
1481f3f2
AD
4884sub read_x509_subject_spice {
4885 my ($filename) = @_;
4886
4887 # read x509 subject
4888 my $bio = Net::SSLeay::BIO_new_file($filename, 'r');
4889 my $x509 = Net::SSLeay::PEM_read_bio_X509($bio);
4890 Net::SSLeay::BIO_free($bio);
4891 my $nameobj = Net::SSLeay::X509_get_subject_name($x509);
4892 my $subject = Net::SSLeay::X509_NAME_oneline($nameobj);
4893 Net::SSLeay::X509_free($x509);
4894
4895 # remote-viewer wants comma as seperator (not '/')
4896 $subject =~ s!^/!!;
4897 $subject =~ s!/(\w+=)!,$1!g;
4898
4899 return $subject;
4900}
1e3baf05 49011;