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