]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
also support getfd
[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;
6b64503e 30use Time::HiRes qw(gettimeofday);
1e3baf05 31
7f0b5beb 32my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
1e3baf05 33
19672434 34# Note about locking: we use flock on the config file protect
1e3baf05
DM
35# against concurent actions.
36# Aditionaly, we have a 'lock' setting in the config file. This
22c377f0 37# can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
1e3baf05
DM
38# allowed when such lock is set. But you can ignore this kind of
39# lock with the --skiplock flag.
40
97d62eb7 41cfs_register_file('/qemu-server/',
1858638f
DM
42 \&parse_vm_config,
43 \&write_vm_config);
1e3baf05 44
3ea94c60
DM
45PVE::JSONSchema::register_standard_option('skiplock', {
46 description => "Ignore locks - only root is allowed to use this option.",
afdb31d5 47 type => 'boolean',
3ea94c60
DM
48 optional => 1,
49});
50
51PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
52 description => "Some command save/restore state from this location.",
53 type => 'string',
54 maxLength => 128,
55 optional => 1,
56});
57
8abd398b
DM
58PVE::JSONSchema::register_standard_option('pve-snapshot-name', {
59 description => "The name of the snapshot.",
60 type => 'string', format => 'pve-configid',
61 maxLength => 40,
62});
63
1e3baf05
DM
64#no warnings 'redefine';
65
66unless(defined(&_VZSYSCALLS_H_)) {
67 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_);
68 require 'sys/syscall.ph';
69 if(defined(&__x86_64__)) {
70 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus);
71 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod);
72 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod);
73 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt);
74 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr);
75 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate);
76 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid);
77 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit);
78 }
79 elsif(defined( &__i386__) ) {
80 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod);
81 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod);
82 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt);
83 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr);
84 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate);
85 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus);
86 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid);
87 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit);
88 } else {
89 die("no fairsched syscall for this arch");
90 }
91 require 'asm/ioctl.ph';
92 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION);
93}
94
95sub fairsched_mknod {
96 my ($parent, $weight, $desired) = @_;
97
6b64503e 98 return syscall(&__NR_fairsched_mknod, int($parent), int($weight), int($desired));
1e3baf05
DM
99}
100
101sub fairsched_rmnod {
102 my ($id) = @_;
103
6b64503e 104 return syscall(&__NR_fairsched_rmnod, int($id));
1e3baf05
DM
105}
106
107sub fairsched_mvpr {
108 my ($pid, $newid) = @_;
109
6b64503e 110 return syscall(&__NR_fairsched_mvpr, int($pid), int($newid));
1e3baf05
DM
111}
112
113sub fairsched_vcpus {
114 my ($id, $vcpus) = @_;
115
6b64503e 116 return syscall(&__NR_fairsched_vcpus, int($id), int($vcpus));
1e3baf05
DM
117}
118
119sub fairsched_rate {
120 my ($id, $op, $rate) = @_;
121
6b64503e 122 return syscall(&__NR_fairsched_rate, int($id), int($op), int($rate));
1e3baf05
DM
123}
124
125use constant FAIRSCHED_SET_RATE => 0;
126use constant FAIRSCHED_DROP_RATE => 1;
127use constant FAIRSCHED_GET_RATE => 2;
128
129sub fairsched_cpulimit {
130 my ($id, $limit) = @_;
131
6b64503e 132 my $cpulim1024 = int($limit * 1024 / 100);
1e3baf05
DM
133 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE : FAIRSCHED_DROP_RATE;
134
6b64503e 135 return fairsched_rate($id, $op, $cpulim1024);
1e3baf05
DM
136}
137
138my $nodename = PVE::INotify::nodename();
139
140mkdir "/etc/pve/nodes/$nodename";
141my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
142mkdir $confdir;
143
144my $var_run_tmpdir = "/var/run/qemu-server";
145mkdir $var_run_tmpdir;
146
147my $lock_dir = "/var/lock/qemu-server";
148mkdir $lock_dir;
149
150my $pcisysfs = "/sys/bus/pci";
151
1e3baf05
DM
152my $confdesc = {
153 onboot => {
154 optional => 1,
155 type => 'boolean',
156 description => "Specifies whether a VM will be started during system bootup.",
157 default => 0,
158 },
159 autostart => {
160 optional => 1,
161 type => 'boolean',
162 description => "Automatic restart after crash (currently ignored).",
163 default => 0,
164 },
2ff09f52
DA
165 hotplug => {
166 optional => 1,
e8b9c17c 167 type => 'boolean',
2ff09f52
DA
168 description => "Activate hotplug for disk and network device",
169 default => 0,
170 },
1e3baf05
DM
171 reboot => {
172 optional => 1,
173 type => 'boolean',
174 description => "Allow reboot. If set to '0' the VM exit on reboot.",
175 default => 1,
176 },
177 lock => {
178 optional => 1,
179 type => 'string',
180 description => "Lock/unlock the VM.",
22c377f0 181 enum => [qw(migrate backup snapshot rollback)],
1e3baf05
DM
182 },
183 cpulimit => {
184 optional => 1,
185 type => 'integer',
186 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.",
187 minimum => 0,
188 default => 0,
189 },
190 cpuunits => {
191 optional => 1,
192 type => 'integer',
193 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.",
194 minimum => 0,
195 maximum => 500000,
196 default => 1000,
197 },
198 memory => {
199 optional => 1,
200 type => 'integer',
7878afeb 201 description => "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
1e3baf05
DM
202 minimum => 16,
203 default => 512,
204 },
13a48620
DA
205 balloon => {
206 optional => 1,
207 type => 'integer',
208 description => "Amount of target RAM for the VM in MB.",
7878afeb 209 minimum => 16,
13a48620 210 },
1e3baf05
DM
211 keyboard => {
212 optional => 1,
213 type => 'string',
214 description => "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
e95fe75f 215 enum => PVE::Tools::kvmkeymaplist(),
1e3baf05
DM
216 default => 'en-us',
217 },
218 name => {
219 optional => 1,
7fabe17d 220 type => 'string', format => 'dns-name',
1e3baf05
DM
221 description => "Set a name for the VM. Only used on the configuration web interface.",
222 },
cdd20088
AD
223 scsihw => {
224 optional => 1,
225 type => 'string',
226 description => "scsi controller model",
29972af3 227 enum => [qw(lsi virtio-scsi-pci megasas)],
cdd20088
AD
228 default => 'lsi',
229 },
1e3baf05
DM
230 description => {
231 optional => 1,
232 type => 'string',
0581fe4f 233 description => "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
1e3baf05
DM
234 },
235 ostype => {
236 optional => 1,
237 type => 'string',
a70ebde3 238 enum => [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 l24 l26)],
1e3baf05
DM
239 description => <<EODESC,
240Used to enable special optimization/features for specific
241operating systems:
242
243other => unspecified OS
244wxp => Microsoft Windows XP
245w2k => Microsoft Windows 2000
246w2k3 => Microsoft Windows 2003
247w2k8 => Microsoft Windows 2008
248wvista => Microsoft Windows Vista
249win7 => Microsoft Windows 7
a70ebde3 250win8 => Microsoft Windows 8/2012
1e3baf05
DM
251l24 => Linux 2.4 Kernel
252l26 => Linux 2.6/3.X Kernel
253
a70ebde3
DM
254other|l24|l26 ... no special behaviour
255wxp|w2k|w2k3|w2k8|wvista|win7|win8 ... use --localtime switch
1e3baf05
DM
256EODESC
257 },
258 boot => {
259 optional => 1,
260 type => 'string',
261 description => "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
262 pattern => '[acdn]{1,4}',
32baffb4 263 default => 'cdn',
1e3baf05
DM
264 },
265 bootdisk => {
266 optional => 1,
267 type => 'string', format => 'pve-qm-bootdisk',
268 description => "Enable booting from specified disk.",
03e480fc 269 pattern => '(ide|sata|scsi|virtio)\d+',
1e3baf05
DM
270 },
271 smp => {
272 optional => 1,
273 type => 'integer',
274 description => "The number of CPUs. Please use option -sockets instead.",
275 minimum => 1,
276 default => 1,
277 },
278 sockets => {
279 optional => 1,
280 type => 'integer',
281 description => "The number of CPU sockets.",
282 minimum => 1,
283 default => 1,
284 },
285 cores => {
286 optional => 1,
287 type => 'integer',
288 description => "The number of cores per socket.",
289 minimum => 1,
290 default => 1,
291 },
292 acpi => {
293 optional => 1,
294 type => 'boolean',
295 description => "Enable/disable ACPI.",
296 default => 1,
297 },
bc84dcca 298 agent => {
ab6a046f
AD
299 optional => 1,
300 type => 'boolean',
301 description => "Enable/disable Qemu GuestAgent.",
be79c214 302 default => 0,
ab6a046f 303 },
1e3baf05
DM
304 kvm => {
305 optional => 1,
306 type => 'boolean',
307 description => "Enable/disable KVM hardware virtualization.",
308 default => 1,
309 },
310 tdf => {
311 optional => 1,
312 type => 'boolean',
8c559505
DM
313 description => "Enable/disable time drift fix.",
314 default => 0,
1e3baf05 315 },
19672434 316 localtime => {
1e3baf05
DM
317 optional => 1,
318 type => 'boolean',
319 description => "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
320 },
321 freeze => {
322 optional => 1,
323 type => 'boolean',
324 description => "Freeze CPU at startup (use 'c' monitor command to start execution).",
325 },
326 vga => {
327 optional => 1,
328 type => 'string',
a70ebde3 329 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
330 enum => [qw(std cirrus vmware)],
331 },
0ea9541d
DM
332 watchdog => {
333 optional => 1,
334 type => 'string', format => 'pve-qm-watchdog',
335 typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
336 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)",
337 },
1e3baf05
DM
338 startdate => {
339 optional => 1,
19672434 340 type => 'string',
1e3baf05
DM
341 typetext => "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
342 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'.",
343 pattern => '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
344 default => 'now',
345 },
59411c4e
DM
346 startup => {
347 optional => 1,
348 type => 'string', format => 'pve-qm-startup',
349 typetext => '[[order=]\d+] [,up=\d+] [,down=\d+] ',
350 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.",
351 },
1e3baf05
DM
352 args => {
353 optional => 1,
354 type => 'string',
355 description => <<EODESCR,
356Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
357
358args: -no-reboot -no-hpet
359EODESCR
360 },
361 tablet => {
362 optional => 1,
363 type => 'boolean',
364 default => 1,
365 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.",
366 },
367 migrate_speed => {
368 optional => 1,
369 type => 'integer',
370 description => "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
371 minimum => 0,
372 default => 0,
373 },
374 migrate_downtime => {
375 optional => 1,
376 type => 'integer',
377 description => "Set maximum tolerated downtime (in seconds) for migrations.",
378 minimum => 0,
379 default => 1,
380 },
381 cdrom => {
382 optional => 1,
383 type => 'string', format => 'pve-qm-drive',
384 typetext => 'volume',
385 description => "This is an alias for option -ide2",
386 },
387 cpu => {
388 optional => 1,
389 description => "Emulated CPU type.",
390 type => 'string',
98a0dc5e 391 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
392 default => 'qemu64',
393 },
b7ba6b79
DM
394 parent => get_standard_option('pve-snapshot-name', {
395 optional => 1,
396 description => "Parent snapshot name. This is used internally, and should not be modified.",
397 }),
982c7f12
DM
398 snaptime => {
399 optional => 1,
400 description => "Timestamp for snapshots.",
401 type => 'integer',
402 minimum => 0,
403 },
18bfb361
DM
404 vmstate => {
405 optional => 1,
406 type => 'string', format => 'pve-volume-id',
407 description => "Reference to a volume which stores the VM state. This is used internally for snapshots.",
408 },
1e3baf05
DM
409};
410
411# what about other qemu settings ?
412#cpu => 'string',
413#machine => 'string',
414#fda => 'file',
415#fdb => 'file',
416#mtdblock => 'file',
417#sd => 'file',
418#pflash => 'file',
419#snapshot => 'bool',
420#bootp => 'file',
421##tftp => 'dir',
422##smb => 'dir',
423#kernel => 'file',
424#append => 'string',
425#initrd => 'file',
426##soundhw => 'string',
427
428while (my ($k, $v) = each %$confdesc) {
429 PVE::JSONSchema::register_standard_option("pve-qm-$k", $v);
430}
431
432my $MAX_IDE_DISKS = 4;
f62db2a4 433my $MAX_SCSI_DISKS = 14;
a2650619 434my $MAX_VIRTIO_DISKS = 16;
cdb0931f 435my $MAX_SATA_DISKS = 6;
1e3baf05 436my $MAX_USB_DEVICES = 5;
5bdcf937 437my $MAX_NETS = 32;
1e3baf05 438my $MAX_UNUSED_DISKS = 8;
040b06b7 439my $MAX_HOSTPCI_DEVICES = 2;
bae179aa 440my $MAX_SERIAL_PORTS = 4;
1989a89c 441my $MAX_PARALLEL_PORTS = 3;
1e3baf05
DM
442
443my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
444 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
6b64503e 445my $nic_model_list_txt = join(' ', sort @$nic_model_list);
1e3baf05
DM
446
447# fixme:
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
1252# fixme: remove all thos $noerr parameters?
1253
1254PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1255sub verify_bootdisk {
1256 my ($value, $noerr) = @_;
1257
19672434 1258 return $value if valid_drivename($value);
1e3baf05
DM
1259
1260 return undef if $noerr;
1261
1262 die "invalid boot disk '$value'\n";
1263}
1264
1265PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1266sub verify_net {
1267 my ($value, $noerr) = @_;
1268
1269 return $value if parse_net($value);
1270
1271 return undef if $noerr;
19672434 1272
1e3baf05
DM
1273 die "unable to parse network options\n";
1274}
1275
1276PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1277sub verify_drive {
1278 my ($value, $noerr) = @_;
1279
6b64503e 1280 return $value if parse_drive(undef, $value);
1e3baf05
DM
1281
1282 return undef if $noerr;
19672434 1283
1e3baf05
DM
1284 die "unable to parse drive options\n";
1285}
1286
1287PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1288sub verify_hostpci {
1289 my ($value, $noerr) = @_;
1290
040b06b7
DA
1291 return $value if parse_hostpci($value);
1292
1293 return undef if $noerr;
1294
1295 die "unable to parse pci id\n";
1e3baf05
DM
1296}
1297
0ea9541d
DM
1298PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1299sub verify_watchdog {
1300 my ($value, $noerr) = @_;
1301
1302 return $value if parse_watchdog($value);
1303
1304 return undef if $noerr;
19672434 1305
0ea9541d
DM
1306 die "unable to parse watchdog options\n";
1307}
1308
1309sub parse_watchdog {
1310 my ($value) = @_;
1311
1312 return undef if !$value;
1313
1314 my $res = {};
1315
6b64503e 1316 foreach my $p (split(/,/, $value)) {
0ea9541d
DM
1317 next if $p =~ m/^\s*$/;
1318
1319 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1320 $res->{model} = $2;
1321 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1322 $res->{action} = $2;
1323 } else {
1324 return undef;
1325 }
1326 }
1327
1328 return $res;
1329}
1330
59411c4e
DM
1331PVE::JSONSchema::register_format('pve-qm-startup', \&verify_startup);
1332sub verify_startup {
1333 my ($value, $noerr) = @_;
1334
1335 return $value if parse_startup($value);
1336
1337 return undef if $noerr;
1338
1339 die "unable to parse startup options\n";
1340}
1341
1342sub parse_startup {
1343 my ($value) = @_;
1344
1345 return undef if !$value;
1346
1347 my $res = {};
1348
1349 foreach my $p (split(/,/, $value)) {
1350 next if $p =~ m/^\s*$/;
1351
1352 if ($p =~ m/^(order=)?(\d+)$/) {
1353 $res->{order} = $2;
1354 } elsif ($p =~ m/^up=(\d+)$/) {
1355 $res->{up} = $1;
1356 } elsif ($p =~ m/^down=(\d+)$/) {
1357 $res->{down} = $1;
1358 } else {
1359 return undef;
1360 }
1361 }
1362
1363 return $res;
1364}
1365
1e3baf05
DM
1366sub parse_usb_device {
1367 my ($value) = @_;
1368
1369 return undef if !$value;
1370
6b64503e 1371 my @dl = split(/,/, $value);
1e3baf05
DM
1372 my $found;
1373
1374 my $res = {};
1375 foreach my $v (@dl) {
036e0e2b 1376 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1e3baf05 1377 $found = 1;
036e0e2b
DM
1378 $res->{vendorid} = $2;
1379 $res->{productid} = $4;
1e3baf05
DM
1380 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1381 $found = 1;
1382 $res->{hostbus} = $1;
1383 $res->{hostport} = $2;
1384 } else {
1385 return undef;
1386 }
1387 }
1388 return undef if !$found;
1389
1390 return $res;
1391}
19672434 1392
1e3baf05
DM
1393PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1394sub verify_usb_device {
1395 my ($value, $noerr) = @_;
1396
1397 return $value if parse_usb_device($value);
1398
1399 return undef if $noerr;
19672434 1400
1e3baf05
DM
1401 die "unable to parse usb device\n";
1402}
1403
1e3baf05
DM
1404# add JSON properties for create and set function
1405sub json_config_properties {
1406 my $prop = shift;
1407
1408 foreach my $opt (keys %$confdesc) {
18bfb361 1409 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1e3baf05
DM
1410 $prop->{$opt} = $confdesc->{$opt};
1411 }
1412
1413 return $prop;
1414}
1415
1416sub check_type {
1417 my ($key, $value) = @_;
1418
1419 die "unknown setting '$key'\n" if !$confdesc->{$key};
1420
1421 my $type = $confdesc->{$key}->{type};
1422
6b64503e 1423 if (!defined($value)) {
1e3baf05
DM
1424 die "got undefined value\n";
1425 }
1426
1427 if ($value =~ m/[\n\r]/) {
1428 die "property contains a line feed\n";
1429 }
1430
1431 if ($type eq 'boolean') {
19672434
DM
1432 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1433 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1434 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1435 } elsif ($type eq 'integer') {
1436 return int($1) if $value =~ m/^(\d+)$/;
1437 die "type check ('integer') failed - got '$value'\n";
1438 } elsif ($type eq 'string') {
1439 if (my $fmt = $confdesc->{$key}->{format}) {
1440 if ($fmt eq 'pve-qm-drive') {
1441 # special case - we need to pass $key to parse_drive()
6b64503e 1442 my $drive = parse_drive($key, $value);
1e3baf05
DM
1443 return $value if $drive;
1444 die "unable to parse drive options\n";
1445 }
1446 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1447 return $value;
1448 }
1e3baf05 1449 $value =~ s/^\"(.*)\"$/$1/;
19672434 1450 return $value;
1e3baf05
DM
1451 } else {
1452 die "internal error"
1453 }
1454}
1455
191435c6
DM
1456sub lock_config_full {
1457 my ($vmid, $timeout, $code, @param) = @_;
1e3baf05 1458
6b64503e 1459 my $filename = config_file_lock($vmid);
1e3baf05 1460
191435c6 1461 my $res = lock_file($filename, $timeout, $code, @param);
1e3baf05
DM
1462
1463 die $@ if $@;
5fdbe4f0
DM
1464
1465 return $res;
1e3baf05
DM
1466}
1467
191435c6
DM
1468sub lock_config {
1469 my ($vmid, $code, @param) = @_;
1470
1471 return lock_config_full($vmid, 10, $code, @param);
1472}
1473
1e3baf05 1474sub cfs_config_path {
a78ccf26 1475 my ($vmid, $node) = @_;
1e3baf05 1476
a78ccf26
DM
1477 $node = $nodename if !$node;
1478 return "nodes/$node/qemu-server/$vmid.conf";
1e3baf05
DM
1479}
1480
040b06b7
DA
1481sub check_iommu_support{
1482 #fixme : need to check IOMMU support
1483 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1484
1485 my $iommu=1;
1486 return $iommu;
1487
1488}
1489
1e3baf05 1490sub config_file {
a78ccf26 1491 my ($vmid, $node) = @_;
1e3baf05 1492
a78ccf26 1493 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1494 return "/etc/pve/$cfspath";
1495}
1496
1497sub config_file_lock {
1498 my ($vmid) = @_;
1499
1500 return "$lock_dir/lock-$vmid.conf";
1501}
1502
1503sub touch_config {
1504 my ($vmid) = @_;
1505
6b64503e 1506 my $conf = config_file($vmid);
1e3baf05
DM
1507 utime undef, undef, $conf;
1508}
1509
1e3baf05 1510sub destroy_vm {
a6af7b3e 1511 my ($storecfg, $vmid, $keep_empty_config) = @_;
1e3baf05 1512
6b64503e 1513 my $conffile = config_file($vmid);
1e3baf05 1514
6b64503e 1515 my $conf = load_config($vmid);
1e3baf05 1516
6b64503e 1517 check_lock($conf);
1e3baf05 1518
19672434 1519 # only remove disks owned by this VM
1e3baf05
DM
1520 foreach_drive($conf, sub {
1521 my ($ds, $drive) = @_;
1522
6b64503e 1523 return if drive_is_cdrom($drive);
1e3baf05
DM
1524
1525 my $volid = $drive->{file};
ff1a2432 1526 return if !$volid || $volid =~ m|^/|;
1e3baf05 1527
6b64503e 1528 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
ff1a2432 1529 return if !$path || !$owner || ($owner != $vmid);
1e3baf05 1530
6b64503e 1531 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1532 });
19672434 1533
a6af7b3e 1534 if ($keep_empty_config) {
9c502e26 1535 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
a6af7b3e
DM
1536 } else {
1537 unlink $conffile;
1538 }
1e3baf05
DM
1539
1540 # also remove unused disk
1541 eval {
6b64503e 1542 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
1543
1544 eval {
6b64503e 1545 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 1546 my ($volid, $sid, $volname, $d) = @_;
6b64503e 1547 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
1548 });
1549 };
1550 warn $@ if $@;
1551
1552 };
1553 warn $@ if $@;
1554}
1555
1e3baf05 1556sub load_config {
7e8dcf2c 1557 my ($vmid, $node) = @_;
1e3baf05 1558
7e8dcf2c 1559 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1560
1561 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1562
1563 die "no such VM ('$vmid')\n" if !defined($conf);
1564
1565 return $conf;
19672434 1566}
1e3baf05
DM
1567
1568sub parse_vm_config {
1569 my ($filename, $raw) = @_;
1570
1571 return undef if !defined($raw);
1572
554ac7e7 1573 my $res = {
fc1ddcdc 1574 digest => Digest::SHA::sha1_hex($raw),
0d18dcfc 1575 snapshots => {},
554ac7e7 1576 };
1e3baf05 1577
19672434 1578 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1579 || die "got strange filename '$filename'";
1580
1581 my $vmid = $1;
1582
0d18dcfc 1583 my $conf = $res;
0581fe4f
DM
1584 my $descr = '';
1585
0d18dcfc
DM
1586 my @lines = split(/\n/, $raw);
1587 foreach my $line (@lines) {
1e3baf05 1588 next if $line =~ m/^\s*$/;
0d18dcfc
DM
1589
1590 if ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
1591 my $snapname = $1;
1592 $conf->{description} = $descr if $descr;
782f4f75 1593 $descr = '';
0d18dcfc
DM
1594 $conf = $res->{snapshots}->{$snapname} = {};
1595 next;
1596 }
1e3baf05 1597
0581fe4f
DM
1598 if ($line =~ m/^\#(.*)\s*$/) {
1599 $descr .= PVE::Tools::decode_text($1) . "\n";
1600 next;
1601 }
1602
1e3baf05 1603 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
0581fe4f 1604 $descr .= PVE::Tools::decode_text($2);
0d18dcfc
DM
1605 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1606 $conf->{snapstate} = $1;
1e3baf05
DM
1607 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1608 my $key = $1;
1609 my $value = $2;
0d18dcfc 1610 $conf->{$key} = $value;
1e3baf05
DM
1611 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1612 my $key = $1;
1613 my $value = $2;
1614 eval { $value = check_type($key, $value); };
1615 if ($@) {
1616 warn "vm $vmid - unable to parse value of '$key' - $@";
1617 } else {
1618 my $fmt = $confdesc->{$key}->{format};
1619 if ($fmt && $fmt eq 'pve-qm-drive') {
1620 my $v = parse_drive($key, $value);
1621 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1622 $v->{file} = $volid;
6b64503e 1623 $value = print_drive($vmid, $v);
1e3baf05
DM
1624 } else {
1625 warn "vm $vmid - unable to parse value of '$key'\n";
1626 next;
1627 }
1628 }
1629
1630 if ($key eq 'cdrom') {
0d18dcfc 1631 $conf->{ide2} = $value;
1e3baf05 1632 } else {
0d18dcfc 1633 $conf->{$key} = $value;
1e3baf05
DM
1634 }
1635 }
1636 }
1637 }
1638
0d18dcfc 1639 $conf->{description} = $descr if $descr;
0581fe4f 1640
0d18dcfc 1641 delete $res->{snapstate}; # just to be sure
1e3baf05
DM
1642
1643 return $res;
1644}
1645
1858638f
DM
1646sub write_vm_config {
1647 my ($filename, $conf) = @_;
1e3baf05 1648
0d18dcfc
DM
1649 delete $conf->{snapstate}; # just to be sure
1650
1858638f
DM
1651 if ($conf->{cdrom}) {
1652 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
1653 $conf->{ide2} = $conf->{cdrom};
1654 delete $conf->{cdrom};
1655 }
1e3baf05
DM
1656
1657 # we do not use 'smp' any longer
1858638f
DM
1658 if ($conf->{sockets}) {
1659 delete $conf->{smp};
1660 } elsif ($conf->{smp}) {
1661 $conf->{sockets} = $conf->{smp};
1662 delete $conf->{cores};
1663 delete $conf->{smp};
1e3baf05
DM
1664 }
1665
ee2f90b1 1666 my $used_volids = {};
0d18dcfc 1667
ee2f90b1
DM
1668 my $cleanup_config = sub {
1669 my ($cref) = @_;
1858638f 1670
ee2f90b1
DM
1671 foreach my $key (keys %$cref) {
1672 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
1673 $key eq 'snapstate';
1674 my $value = $cref->{$key};
1675 eval { $value = check_type($key, $value); };
1676 die "unable to parse value of '$key' - $@" if $@;
1858638f 1677
ee2f90b1
DM
1678 $cref->{$key} = $value;
1679
1680 if (valid_drivename($key)) {
1681 my $drive = PVE::QemuServer::parse_drive($key, $value);
1682 $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
1683 }
1e3baf05 1684 }
ee2f90b1
DM
1685 };
1686
1687 &$cleanup_config($conf);
1688 foreach my $snapname (keys %{$conf->{snapshots}}) {
1689 &$cleanup_config($conf->{snapshots}->{$snapname});
1e3baf05
DM
1690 }
1691
1858638f
DM
1692 # remove 'unusedX' settings if we re-add a volume
1693 foreach my $key (keys %$conf) {
1694 my $value = $conf->{$key};
ee2f90b1 1695 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1858638f 1696 delete $conf->{$key};
1e3baf05 1697 }
1858638f 1698 }
ee2f90b1 1699
0d18dcfc
DM
1700 my $generate_raw_config = sub {
1701 my ($conf) = @_;
0581fe4f 1702
0d18dcfc
DM
1703 my $raw = '';
1704
1705 # add description as comment to top of file
1706 my $descr = $conf->{description} || '';
1707 foreach my $cl (split(/\n/, $descr)) {
1708 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
1709 }
1710
1711 foreach my $key (sort keys %$conf) {
1712 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
1713 $raw .= "$key: $conf->{$key}\n";
1714 }
1715 return $raw;
1716 };
0581fe4f 1717
0d18dcfc
DM
1718 my $raw = &$generate_raw_config($conf);
1719 foreach my $snapname (sort keys %{$conf->{snapshots}}) {
1720 $raw .= "\n[$snapname]\n";
1721 $raw .= &$generate_raw_config($conf->{snapshots}->{$snapname});
1858638f 1722 }
1e3baf05 1723
1858638f
DM
1724 return $raw;
1725}
1e3baf05 1726
1858638f
DM
1727sub update_config_nolock {
1728 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1729
1858638f 1730 check_lock($conf) if !$skiplock;
97d62eb7 1731
1858638f 1732 my $cfspath = cfs_config_path($vmid);
1e3baf05 1733
1858638f
DM
1734 PVE::Cluster::cfs_write_file($cfspath, $conf);
1735}
1e3baf05 1736
1858638f
DM
1737sub update_config {
1738 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1739
1858638f 1740 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1e3baf05
DM
1741}
1742
19672434 1743sub load_defaults {
1e3baf05
DM
1744
1745 my $res = {};
1746
1747 # we use static defaults from our JSON schema configuration
1748 foreach my $key (keys %$confdesc) {
1749 if (defined(my $default = $confdesc->{$key}->{default})) {
1750 $res->{$key} = $default;
1751 }
1752 }
19672434 1753
1e3baf05
DM
1754 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
1755 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
1756
1757 return $res;
1758}
1759
1760sub config_list {
1761 my $vmlist = PVE::Cluster::get_vmlist();
1762 my $res = {};
1763 return $res if !$vmlist || !$vmlist->{ids};
1764 my $ids = $vmlist->{ids};
1765
1e3baf05
DM
1766 foreach my $vmid (keys %$ids) {
1767 my $d = $ids->{$vmid};
1768 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 1769 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
1770 $res->{$vmid}->{exists} = 1;
1771 }
1772 return $res;
1773}
1774
64e13401
DM
1775# test if VM uses local resources (to prevent migration)
1776sub check_local_resources {
1777 my ($conf, $noerr) = @_;
1778
1779 my $loc_res = 0;
19672434 1780
e0ab7331
DM
1781 $loc_res = 1 if $conf->{hostusb}; # old syntax
1782 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 1783
0d29ab3b 1784 foreach my $k (keys %$conf) {
2fe1a152 1785 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
1786 }
1787
1788 die "VM uses local resources\n" if $loc_res && !$noerr;
1789
1790 return $loc_res;
1791}
1792
47152e2e
DM
1793# check is used storages are available on all nodes (use by migrate)
1794sub check_storage_availability {
1795 my ($storecfg, $conf, $node) = @_;
1796
1797 foreach_drive($conf, sub {
1798 my ($ds, $drive) = @_;
1799
1800 my $volid = $drive->{file};
1801 return if !$volid;
1802
1803 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
1804 return if !$sid;
1805
1806 # check if storage is available on both nodes
1807 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
1808 PVE::Storage::storage_check_node($storecfg, $sid, $node);
1809 });
1810}
1811
1e3baf05
DM
1812sub check_lock {
1813 my ($conf) = @_;
1814
1815 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1816}
1817
1818sub check_cmdline {
1819 my ($pidfile, $pid) = @_;
1820
6b64503e
DM
1821 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
1822 if (defined($fh)) {
1e3baf05
DM
1823 my $line = <$fh>;
1824 $fh->close;
1825 return undef if !$line;
6b64503e 1826 my @param = split(/\0/, $line);
1e3baf05
DM
1827
1828 my $cmd = $param[0];
1829 return if !$cmd || ($cmd !~ m|kvm$|);
1830
1831 for (my $i = 0; $i < scalar (@param); $i++) {
1832 my $p = $param[$i];
1833 next if !$p;
1834 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1835 my $p = $param[$i+1];
1836 return 1 if $p && ($p eq $pidfile);
1837 return undef;
1838 }
1839 }
1840 }
1841 return undef;
1842}
1843
1844sub check_running {
7e8dcf2c 1845 my ($vmid, $nocheck, $node) = @_;
1e3baf05 1846
7e8dcf2c 1847 my $filename = config_file($vmid, $node);
1e3baf05
DM
1848
1849 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 1850 if !$nocheck && ! -f $filename;
1e3baf05 1851
e6c3b671 1852 my $pidfile = pidfile_name($vmid);
1e3baf05 1853
e6c3b671
DM
1854 if (my $fd = IO::File->new("<$pidfile")) {
1855 my $st = stat($fd);
1e3baf05 1856 my $line = <$fd>;
6b64503e 1857 close($fd);
1e3baf05
DM
1858
1859 my $mtime = $st->mtime;
1860 if ($mtime > time()) {
1861 warn "file '$filename' modified in future\n";
1862 }
1863
1864 if ($line =~ m/^(\d+)$/) {
1865 my $pid = $1;
e6c3b671
DM
1866 if (check_cmdline($pidfile, $pid)) {
1867 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
1868 return $pid;
1869 }
1870 }
1e3baf05
DM
1871 }
1872 }
1873
1874 return undef;
1875}
1876
1877sub vzlist {
19672434 1878
1e3baf05
DM
1879 my $vzlist = config_list();
1880
6b64503e 1881 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 1882
19672434 1883 while (defined(my $de = $fd->read)) {
1e3baf05
DM
1884 next if $de !~ m/^(\d+)\.pid$/;
1885 my $vmid = $1;
6b64503e
DM
1886 next if !defined($vzlist->{$vmid});
1887 if (my $pid = check_running($vmid)) {
1e3baf05
DM
1888 $vzlist->{$vmid}->{pid} = $pid;
1889 }
1890 }
1891
1892 return $vzlist;
1893}
1894
1e3baf05
DM
1895sub disksize {
1896 my ($storecfg, $conf) = @_;
1897
1898 my $bootdisk = $conf->{bootdisk};
1899 return undef if !$bootdisk;
1900 return undef if !valid_drivename($bootdisk);
1901
1902 return undef if !$conf->{$bootdisk};
1903
1904 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
1905 return undef if !defined($drive);
1906
1907 return undef if drive_is_cdrom($drive);
1908
1909 my $volid = $drive->{file};
1910 return undef if !$volid;
1911
24afaca0 1912 return $drive->{size};
1e3baf05
DM
1913}
1914
1915my $last_proc_pid_stat;
1916
03a33f30
DM
1917# get VM status information
1918# This must be fast and should not block ($full == false)
1919# We only query KVM using QMP if $full == true (this can be slow)
1e3baf05 1920sub vmstatus {
03a33f30 1921 my ($opt_vmid, $full) = @_;
1e3baf05
DM
1922
1923 my $res = {};
1924
19672434 1925 my $storecfg = PVE::Storage::config();
1e3baf05
DM
1926
1927 my $list = vzlist();
694fcad4 1928 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 1929
ae4915a2
DM
1930 my $cpucount = $cpuinfo->{cpus} || 1;
1931
1e3baf05
DM
1932 foreach my $vmid (keys %$list) {
1933 next if $opt_vmid && ($vmid ne $opt_vmid);
1934
1935 my $cfspath = cfs_config_path($vmid);
1936 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
1937
1938 my $d = {};
1939 $d->{pid} = $list->{$vmid}->{pid};
1940
1941 # fixme: better status?
1942 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
1943
af990afe
DM
1944 my $size = disksize($storecfg, $conf);
1945 if (defined($size)) {
1946 $d->{disk} = 0; # no info available
1e3baf05
DM
1947 $d->{maxdisk} = $size;
1948 } else {
1949 $d->{disk} = 0;
1950 $d->{maxdisk} = 0;
1951 }
1952
1953 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2
DM
1954 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
1955
1e3baf05 1956 $d->{name} = $conf->{name} || "VM $vmid";
19672434 1957 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 1958
1e3baf05
DM
1959 $d->{uptime} = 0;
1960 $d->{cpu} = 0;
1e3baf05
DM
1961 $d->{mem} = 0;
1962
1963 $d->{netout} = 0;
1964 $d->{netin} = 0;
1965
1966 $d->{diskread} = 0;
1967 $d->{diskwrite} = 0;
1968
1969 $res->{$vmid} = $d;
1970 }
1971
1972 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
1973 foreach my $dev (keys %$netdev) {
1974 next if $dev !~ m/^tap([1-9]\d*)i/;
1975 my $vmid = $1;
1976 my $d = $res->{$vmid};
1977 next if !$d;
19672434 1978
1e3baf05
DM
1979 $d->{netout} += $netdev->{$dev}->{receive};
1980 $d->{netin} += $netdev->{$dev}->{transmit};
1981 }
1982
1e3baf05
DM
1983 my $ctime = gettimeofday;
1984
1985 foreach my $vmid (keys %$list) {
1986
1987 my $d = $res->{$vmid};
1988 my $pid = $d->{pid};
1989 next if !$pid;
1990
694fcad4
DM
1991 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
1992 next if !$pstat; # not running
19672434 1993
694fcad4 1994 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 1995
694fcad4 1996 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 1997
694fcad4 1998 if ($pstat->{vsize}) {
6b64503e 1999 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
2000 }
2001
2002 my $old = $last_proc_pid_stat->{$pid};
2003 if (!$old) {
19672434
DM
2004 $last_proc_pid_stat->{$pid} = {
2005 time => $ctime,
1e3baf05
DM
2006 used => $used,
2007 cpu => 0,
1e3baf05
DM
2008 };
2009 next;
2010 }
2011
7f0b5beb 2012 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
2013
2014 if ($dtime > 1000) {
2015 my $dutime = $used - $old->{used};
2016
ae4915a2 2017 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 2018 $last_proc_pid_stat->{$pid} = {
19672434 2019 time => $ctime,
1e3baf05
DM
2020 used => $used,
2021 cpu => $d->{cpu},
1e3baf05
DM
2022 };
2023 } else {
2024 $d->{cpu} = $old->{cpu};
1e3baf05
DM
2025 }
2026 }
2027
f5eb281a 2028 return $res if !$full;
03a33f30
DM
2029
2030 my $qmpclient = PVE::QMPClient->new();
2031
2032 my $blockstatscb = sub {
2033 my ($vmid, $resp) = @_;
2034 my $data = $resp->{'return'} || [];
2035 my $totalrdbytes = 0;
2036 my $totalwrbytes = 0;
2037 for my $blockstat (@$data) {
2038 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
2039 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
2040 }
2041 $res->{$vmid}->{diskread} = $totalrdbytes;
2042 $res->{$vmid}->{diskwrite} = $totalwrbytes;
2043 };
2044
2045 my $statuscb = sub {
2046 my ($vmid, $resp) = @_;
2047 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2048
2049 my $status = 'unknown';
2050 if (!defined($status = $resp->{'return'}->{status})) {
2051 warn "unable to get VM status\n";
2052 return;
2053 }
2054
2055 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2056 };
2057
2058 foreach my $vmid (keys %$list) {
2059 next if $opt_vmid && ($vmid ne $opt_vmid);
2060 next if !$res->{$vmid}->{pid}; # not running
2061 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2062 }
2063
2064 $qmpclient->queue_execute();
2065
2066 foreach my $vmid (keys %$list) {
2067 next if $opt_vmid && ($vmid ne $opt_vmid);
2068 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2069 }
2070
1e3baf05
DM
2071 return $res;
2072}
2073
2074sub foreach_drive {
2075 my ($conf, $func) = @_;
2076
2077 foreach my $ds (keys %$conf) {
2078 next if !valid_drivename($ds);
2079
6b64503e 2080 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2081 next if !$drive;
2082
2083 &$func($ds, $drive);
2084 }
2085}
2086
d5769dc2
DM
2087sub foreach_volid {
2088 my ($conf, $func) = @_;
2089
2090 my $volhash = {};
2091
2092 my $test_volid = sub {
2093 my ($volid, $is_cdrom) = @_;
2094
2095 return if !$volid;
2096
2097 $volhash->{$volid} = $is_cdrom || 0;
2098 };
2099
2100 PVE::QemuServer::foreach_drive($conf, sub {
2101 my ($ds, $drive) = @_;
2102 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2103 });
2104
2105 foreach my $snapname (keys %{$conf->{snapshots}}) {
2106 my $snap = $conf->{snapshots}->{$snapname};
2107 &$test_volid($snap->{vmstate}, 0);
2108 PVE::QemuServer::foreach_drive($snap, sub {
2109 my ($ds, $drive) = @_;
2110 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2111 });
2112 }
2113
2114 foreach my $volid (keys %$volhash) {
2115 &$func($volid, $volhash->{$volid});
2116 }
2117}
2118
1e3baf05 2119sub config_to_command {
6c47d546 2120 my ($storecfg, $vmid, $conf, $defaults) = @_;
1e3baf05
DM
2121
2122 my $cmd = [];
8c559505
DM
2123 my $globalFlags = [];
2124 my $machineFlags = [];
2125 my $rtcFlags = [];
5bdcf937 2126 my $devices = [];
b78ebef7 2127 my $pciaddr = '';
5bdcf937 2128 my $bridges = {};
1e3baf05
DM
2129 my $kvmver = kvm_user_version();
2130 my $vernum = 0; # unknown
a3c52213
DM
2131 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2132 $vernum = $1*1000000+$2*1000;
2133 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2134 $vernum = $1*1000000+$2*1000+$3;
2135 }
2136
a3c52213 2137 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2138
2139 my $have_ovz = -f '/proc/vz/vestat';
2140
2141 push @$cmd, '/usr/bin/kvm';
2142
2143 push @$cmd, '-id', $vmid;
2144
2145 my $use_virtio = 0;
2146
c971c4f2
AD
2147 my $qmpsocket = qmp_socket($vmid);
2148 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2149 push @$cmd, '-mon', "chardev=qmp,mode=control";
2150
7b7c6d1b 2151 my $socket = vnc_socket($vmid);
1e3baf05
DM
2152 push @$cmd, '-vnc', "unix:$socket,x509,password";
2153
6b64503e 2154 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2155
1e3baf05
DM
2156 push @$cmd, '-daemonize';
2157
1c060867
DM
2158 my $use_usb2 = 0;
2159 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2160 next if !$conf->{"usb$i"};
2161 $use_usb2 = 1;
2162 }
1e3baf05 2163 # include usb device config
5bdcf937 2164 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
19672434 2165
1e3baf05 2166 # enable absolute mouse coordinates (needed by vnc)
6b64503e 2167 my $tablet = defined($conf->{tablet}) ? $conf->{tablet} : $defaults->{tablet};
1c060867
DM
2168 if ($tablet) {
2169 if ($use_usb2) {
5bdcf937 2170 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
1c060867 2171 } else {
5bdcf937 2172 push @$devices, '-usbdevice', 'tablet';
1c060867
DM
2173 }
2174 }
1e3baf05
DM
2175
2176 # host pci devices
040b06b7
DA
2177 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2178 my $d = parse_hostpci($conf->{"hostpci$i"});
2179 next if !$d;
5bdcf937
AD
2180 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2181 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
1e3baf05
DM
2182 }
2183
2184 # usb devices
2185 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2186 my $d = parse_usb_device($conf->{"usb$i"});
2187 next if !$d;
2188 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2189 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2190 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2191 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
1e3baf05
DM
2192 }
2193 }
2194
1e3baf05 2195 # serial devices
bae179aa 2196 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2197 if (my $path = $conf->{"serial$i"}) {
19672434 2198 die "no such serial device\n" if ! -c $path;
5bdcf937
AD
2199 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2200 push @$devices, '-device', "isa-serial,chardev=serial$i";
34978be3 2201 }
1e3baf05
DM
2202 }
2203
2204 # parallel devices
1989a89c 2205 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2206 if (my $path = $conf->{"parallel$i"}) {
19672434 2207 die "no such parallel device\n" if ! -c $path;
5bdcf937
AD
2208 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2209 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2210 }
1e3baf05
DM
2211 }
2212
2213 my $vmname = $conf->{name} || "vm$vmid";
2214
2215 push @$cmd, '-name', $vmname;
19672434 2216
1e3baf05
DM
2217 my $sockets = 1;
2218 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2219 $sockets = $conf->{sockets} if $conf->{sockets};
2220
2221 my $cores = $conf->{cores} || 1;
2222
1e3baf05
DM
2223 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2224
2225 push @$cmd, '-cpu', $conf->{cpu} if $conf->{cpu};
2226
1e3baf05
DM
2227 push @$cmd, '-nodefaults';
2228
32baffb4 2229 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2230
0888fdce
DM
2231 my $bootindex_hash = {};
2232 my $i = 1;
2233 foreach my $o (split(//, $bootorder)) {
2234 $bootindex_hash->{$o} = $i*100;
2235 $i++;
afdb31d5 2236 }
3b408e82
DM
2237
2238 push @$cmd, '-boot', "menu=on";
1e3baf05 2239
6b64503e 2240 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2241
6b64503e 2242 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05
DM
2243
2244 my $vga = $conf->{vga};
2245 if (!$vga) {
a70ebde3 2246 if ($conf->{ostype} && ($conf->{ostype} eq 'win8' || $conf->{ostype} eq 'win7' || $conf->{ostype} eq 'w2k8')) {
1e3baf05
DM
2247 $vga = 'std';
2248 } else {
2249 $vga = 'cirrus';
2250 }
2251 }
19672434 2252
1e3baf05
DM
2253 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2254
2255 # time drift fix
6b64503e 2256 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2257
6b64503e 2258 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2259 my $useLocaltime = $conf->{localtime};
1e3baf05
DM
2260
2261 if (my $ost = $conf->{ostype}) {
a70ebde3 2262 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26
1e3baf05
DM
2263
2264 if ($ost =~ m/^w/) { # windows
8c559505 2265 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2266
8c559505 2267 # use time drift fix when acpi is enabled
6b64503e 2268 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2269 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2270 }
2271 }
2272
a70ebde3
DM
2273 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
2274 $ost eq 'wvista') {
8c559505 2275 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf
DM
2276 push @$cmd, '-no-hpet';
2277 }
1e3baf05
DM
2278 }
2279
8c559505
DM
2280 push @$rtcFlags, 'driftfix=slew' if $tdf;
2281
7f0b5beb 2282 if ($nokvm) {
8c559505 2283 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2284 } else {
2285 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2286 }
1e3baf05 2287
8c559505
DM
2288 if ($conf->{startdate}) {
2289 push @$rtcFlags, "base=$conf->{startdate}";
2290 } elsif ($useLocaltime) {
2291 push @$rtcFlags, 'base=localtime';
2292 }
1e3baf05
DM
2293
2294 push @$cmd, '-S' if $conf->{freeze};
2295
2296 # set keyboard layout
2297 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2298 push @$cmd, '-k', $kb if $kb;
2299
2300 # enable sound
2301 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2302 #push @$cmd, '-soundhw', 'es1370';
2303 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2304
bc84dcca 2305 if($conf->{agent}) {
ab6a046f
AD
2306 my $qgasocket = qga_socket($vmid);
2307 my $pciaddr = print_pci_addr("qga0", $bridges);
2308 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2309 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2310 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2311 }
2312
5bdcf937
AD
2313 $pciaddr = print_pci_addr("balloon0", $bridges);
2314 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon};
1e3baf05 2315
0ea9541d
DM
2316 if ($conf->{watchdog}) {
2317 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 2318 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 2319 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
2320 push @$devices, '-device', "$watchdog$pciaddr";
2321 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
2322 }
2323
1e3baf05 2324 my $vollist = [];
941e0c42 2325 my $scsicontroller = {};
26ee04b6 2326 my $ahcicontroller = {};
cdd20088 2327 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05
DM
2328
2329 foreach_drive($conf, sub {
2330 my ($ds, $drive) = @_;
2331
ff1a2432 2332 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 2333 push @$vollist, $drive->{file};
ff1a2432 2334 }
afdb31d5 2335
1e3baf05 2336 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
2337
2338 if (drive_is_cdrom ($drive)) {
2339 if ($bootindex_hash->{d}) {
2340 $drive->{bootindex} = $bootindex_hash->{d};
2341 $bootindex_hash->{d} += 1;
2342 }
2343 } else {
2344 if ($bootindex_hash->{c}) {
2345 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2346 $bootindex_hash->{c} += 1;
2347 }
2348 }
2349
941e0c42 2350 if ($drive->{interface} eq 'scsi') {
cdd20088
AD
2351
2352 my $maxdev = ($scsihw ne 'lsi') ? 256 : 7;
2353 my $controller = int($drive->{index} / $maxdev);
5bdcf937
AD
2354 $pciaddr = print_pci_addr("scsihw$controller", $bridges);
2355 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
cdd20088 2356 $scsicontroller->{$controller}=1;
941e0c42 2357 }
3b408e82 2358
26ee04b6
DA
2359 if ($drive->{interface} eq 'sata') {
2360 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
2361 $pciaddr = print_pci_addr("ahci$controller", $bridges);
2362 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
2363 $ahcicontroller->{$controller}=1;
2364 }
2365
5bdcf937
AD
2366 push @$devices, '-drive',print_drive_full($storecfg, $vmid, $drive);
2367 push @$devices, '-device',print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
2368 });
2369
2370 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2371
cc4d6182 2372 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 2373 next if !$conf->{"net$i"};
cc4d6182
DA
2374 my $d = parse_net($conf->{"net$i"});
2375 next if !$d;
1e3baf05 2376
cc4d6182 2377 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 2378
cc4d6182
DA
2379 if ($bootindex_hash->{n}) {
2380 $d->{bootindex} = $bootindex_hash->{n};
2381 $bootindex_hash->{n} += 1;
2382 }
1e3baf05 2383
cc4d6182 2384 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
2385 push @$devices, '-netdev', $netdevfull;
2386
2387 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
2388 push @$devices, '-device', $netdevicefull;
2389 }
1e3baf05 2390
5bdcf937
AD
2391 #bridges
2392 while (my ($k, $v) = each %$bridges) {
2393 $pciaddr = print_pci_addr("pci.$k");
2394 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
19672434
DM
2395 }
2396
1e3baf05
DM
2397
2398 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2399 # when the VM uses virtio devices.
19672434
DM
2400 if (!$use_virtio && $have_ovz) {
2401
6b64503e 2402 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2403 $conf->{cpuunits} : $defaults->{cpuunits};
2404
2405 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2406
2407 # fixme: cpulimit is currently ignored
2408 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2409 }
2410
2411 # add custom args
2412 if ($conf->{args}) {
3ada46c9 2413 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
2414 push @$cmd, @$aa;
2415 }
2416
5bdcf937 2417 push @$cmd, @$devices;
8c559505
DM
2418 push @$cmd, '-rtc', join(',', @$rtcFlags)
2419 if scalar(@$rtcFlags);
2420 push @$cmd, '-machine', join(',', @$machineFlags)
2421 if scalar(@$machineFlags);
2422 push @$cmd, '-global', join(',', @$globalFlags)
2423 if scalar(@$globalFlags);
2424
1e3baf05
DM
2425 return wantarray ? ($cmd, $vollist) : $cmd;
2426}
19672434 2427
1e3baf05
DM
2428sub vnc_socket {
2429 my ($vmid) = @_;
2430 return "${var_run_tmpdir}/$vmid.vnc";
2431}
2432
c971c4f2
AD
2433sub qmp_socket {
2434 my ($vmid) = @_;
2435 return "${var_run_tmpdir}/$vmid.qmp";
2436}
2437
ab6a046f
AD
2438sub qga_socket {
2439 my ($vmid) = @_;
2440 return "${var_run_tmpdir}/$vmid.qga";
2441}
2442
1e3baf05
DM
2443sub pidfile_name {
2444 my ($vmid) = @_;
2445 return "${var_run_tmpdir}/$vmid.pid";
2446}
2447
1e3baf05
DM
2448sub next_migrate_port {
2449
2450 for (my $p = 60000; $p < 60010; $p++) {
2451
6b64503e
DM
2452 my $sock = IO::Socket::INET->new(Listen => 5,
2453 LocalAddr => 'localhost',
2454 LocalPort => $p,
2455 ReuseAddr => 1,
2456 Proto => 0);
1e3baf05
DM
2457
2458 if ($sock) {
6b64503e 2459 close($sock);
1e3baf05
DM
2460 return $p;
2461 }
2462 }
2463
2464 die "unable to find free migration port";
2465}
2466
86fdcfb2
DA
2467sub vm_devices_list {
2468 my ($vmid) = @_;
2469
ceea9078
DM
2470 my $res = vm_mon_cmd($vmid, 'query-pci');
2471
2472 my $devices = {};
2473 foreach my $pcibus (@$res) {
2474 foreach my $device (@{$pcibus->{devices}}) {
2475 next if !$device->{'qdev_id'};
2476 $devices->{$device->{'qdev_id'}} = $device;
1dc4f496
DM
2477 }
2478 }
86fdcfb2 2479
1dc4f496 2480 return $devices;
86fdcfb2
DA
2481}
2482
ec21aa11 2483sub vm_deviceplug {
f19d1c47 2484 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 2485
2630d2a9 2486 return 1 if !check_running($vmid) || !$conf->{hotplug};
afdb31d5 2487
95d6343b
DA
2488 my $devices_list = vm_devices_list($vmid);
2489 return 1 if defined($devices_list->{$deviceid});
2490
40f28a9f
AD
2491 qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2492
5e5dcb73
DA
2493 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2494 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2495 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
5e5dcb73
DA
2496 qemu_deviceadd($vmid, $devicefull);
2497 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2498 qemu_drivedel($vmid, $deviceid);
2499 return undef;
2500 }
f19d1c47 2501 }
cfc817c7 2502
cdd20088
AD
2503 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2504 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 2505 my $pciaddr = print_pci_addr($deviceid);
cdd20088 2506 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
cfc817c7
DA
2507 qemu_deviceadd($vmid, $devicefull);
2508 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2509 }
2510
a4f091a0 2511 if ($deviceid =~ m/^(scsi)(\d+)$/) {
cdd20088
AD
2512 return 1 if ($conf->{scsihw} && $conf->{scsihw} ne 'lsi'); #virtio-scsi not yet support hotplug
2513 return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
a4f091a0 2514 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2515 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
a4f091a0
DA
2516 if(!qemu_deviceadd($vmid, $devicefull)) {
2517 qemu_drivedel($vmid, $deviceid);
2518 return undef;
2519 }
2520 }
2521
2630d2a9
DA
2522 if ($deviceid =~ m/^(net)(\d+)$/) {
2523 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2524 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2525 qemu_deviceadd($vmid, $netdevicefull);
2526 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2527 qemu_netdevdel($vmid, $deviceid);
2528 return undef;
2529 }
2530 }
2531
40f28a9f
AD
2532 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2533 my $bridgeid = $2;
2534 my $pciaddr = print_pci_addr($deviceid);
2535 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2536 qemu_deviceadd($vmid, $devicefull);
2537 return undef if !qemu_deviceaddverify($vmid, $deviceid);
2538 }
2539
5e5dcb73 2540 return 1;
a4dea331
DA
2541}
2542
ec21aa11 2543sub vm_deviceunplug {
f19d1c47 2544 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2545
5e5dcb73 2546 return 1 if !check_running ($vmid) || !$conf->{hotplug};
873c2d69 2547
95d6343b
DA
2548 my $devices_list = vm_devices_list($vmid);
2549 return 1 if !defined($devices_list->{$deviceid});
2550
ae57f6b3 2551 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
f19d1c47 2552
5e5dcb73
DA
2553 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2554 return undef if !qemu_drivedel($vmid, $deviceid);
2555 qemu_devicedel($vmid, $deviceid);
2556 return undef if !qemu_devicedelverify($vmid, $deviceid);
2557 }
cfc817c7
DA
2558
2559 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2560 return undef if !qemu_devicedel($vmid, $deviceid);
2561 }
2562
a4f091a0
DA
2563 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2564 return undef if !qemu_devicedel($vmid, $deviceid);
2565 return undef if !qemu_drivedel($vmid, $deviceid);
2566 }
2567
2630d2a9
DA
2568 if ($deviceid =~ m/^(net)(\d+)$/) {
2569 return undef if !qemu_netdevdel($vmid, $deviceid);
2570 qemu_devicedel($vmid, $deviceid);
2571 return undef if !qemu_devicedelverify($vmid, $deviceid);
2572 }
2573
5e5dcb73
DA
2574 return 1;
2575}
2576
2577sub qemu_deviceadd {
2578 my ($vmid, $devicefull) = @_;
873c2d69 2579
7b7c6d1b 2580 my $ret = vm_human_monitor_command($vmid, "device_add $devicefull");
5e5dcb73 2581 $ret =~ s/^\s+//;
afdb31d5 2582 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
5e5dcb73
DA
2583 return 1 if $ret eq "";
2584 syslog("err", "error on hotplug device : $ret");
2585 return undef;
f19d1c47 2586
5e5dcb73 2587}
afdb31d5 2588
5e5dcb73
DA
2589sub qemu_devicedel {
2590 my($vmid, $deviceid) = @_;
f19d1c47 2591
7b7c6d1b 2592 my $ret = vm_human_monitor_command($vmid, "device_del $deviceid");
5e5dcb73
DA
2593 $ret =~ s/^\s+//;
2594 return 1 if $ret eq "";
2595 syslog("err", "detaching device $deviceid failed : $ret");
2596 return undef;
2597}
2598
2599sub qemu_driveadd {
2600 my($storecfg, $vmid, $device) = @_;
2601
2602 my $drive = print_drive_full($storecfg, $vmid, $device);
7b7c6d1b 2603 my $ret = vm_human_monitor_command($vmid, "drive_add auto $drive");
5e5dcb73
DA
2604 # If the command succeeds qemu prints: "OK"
2605 if ($ret !~ m/OK/s) {
2606 syslog("err", "adding drive failed: $ret");
2607 return undef;
f19d1c47 2608 }
5e5dcb73
DA
2609 return 1;
2610}
afdb31d5 2611
5e5dcb73
DA
2612sub qemu_drivedel {
2613 my($vmid, $deviceid) = @_;
873c2d69 2614
7b7c6d1b 2615 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73
DA
2616 $ret =~ s/^\s+//;
2617 if ($ret =~ m/Device \'.*?\' not found/s) {
afdb31d5 2618 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
5e5dcb73
DA
2619 }
2620 elsif ($ret ne "") {
2621 syslog("err", "deleting drive $deviceid failed : $ret");
2622 return undef;
873c2d69 2623 }
5e5dcb73
DA
2624 return 1;
2625}
f19d1c47 2626
5e5dcb73
DA
2627sub qemu_deviceaddverify {
2628 my ($vmid,$deviceid) = @_;
873c2d69 2629
5e5dcb73
DA
2630 for (my $i = 0; $i <= 5; $i++) {
2631 my $devices_list = vm_devices_list($vmid);
2632 return 1 if defined($devices_list->{$deviceid});
2633 sleep 1;
afdb31d5 2634 }
5e5dcb73
DA
2635 syslog("err", "error on hotplug device $deviceid");
2636 return undef;
2637}
afdb31d5 2638
5e5dcb73
DA
2639
2640sub qemu_devicedelverify {
2641 my ($vmid,$deviceid) = @_;
2642
2643 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2644 for (my $i = 0; $i <= 5; $i++) {
2645 my $devices_list = vm_devices_list($vmid);
2646 return 1 if !defined($devices_list->{$deviceid});
2647 sleep 1;
afdb31d5 2648 }
5e5dcb73
DA
2649 syslog("err", "error on hot-unplugging device $deviceid");
2650 return undef;
873c2d69
DA
2651}
2652
cdd20088 2653sub qemu_findorcreatescsihw {
cfc817c7
DA
2654 my ($storecfg, $conf, $vmid, $device) = @_;
2655
cdd20088 2656 my $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
cfc817c7 2657 my $controller = int($device->{index} / $maxdev);
cdd20088 2658 my $scsihwid="scsihw$controller";
cfc817c7
DA
2659 my $devices_list = vm_devices_list($vmid);
2660
cdd20088
AD
2661 if(!defined($devices_list->{$scsihwid})) {
2662 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $scsihwid);
cfc817c7
DA
2663 }
2664 return 1;
2665}
2666
40f28a9f
AD
2667sub qemu_bridgeadd {
2668 my ($storecfg, $conf, $vmid, $device) = @_;
2669
2670 my $bridges = {};
2671 my $bridgeid = undef;
2672 print_pci_addr($device, $bridges);
2673
2674 while (my ($k, $v) = each %$bridges) {
2675 $bridgeid = $k;
2676 }
2677 return if $bridgeid < 1;
2678 my $bridge = "pci.$bridgeid";
2679 my $devices_list = vm_devices_list($vmid);
2680
2681 if(!defined($devices_list->{$bridge})) {
2682 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $bridge);
2683 }
2684 return 1;
2685}
2686
2630d2a9
DA
2687sub qemu_netdevadd {
2688 my ($vmid, $conf, $device, $deviceid) = @_;
2689
2690 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
7b7c6d1b 2691 my $ret = vm_human_monitor_command($vmid, "netdev_add $netdev");
2630d2a9
DA
2692 $ret =~ s/^\s+//;
2693
97d62eb7 2694 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2695 return 1 if $ret eq "";
2696 syslog("err", "adding netdev failed: $ret");
2697 return undef;
2698}
2699
2700sub qemu_netdevdel {
2701 my ($vmid, $deviceid) = @_;
2702
7b7c6d1b 2703 my $ret = vm_human_monitor_command($vmid, "netdev_del $deviceid");
2630d2a9 2704 $ret =~ s/^\s+//;
97d62eb7 2705 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2706 return 1 if $ret eq "";
2707 syslog("err", "deleting netdev failed: $ret");
2708 return undef;
2709}
2710
affd2f88
AD
2711sub qemu_block_set_io_throttle {
2712 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2713
f3f323a3
AD
2714 return if !check_running($vmid) ;
2715
affd2f88
AD
2716 $bps = 0 if !$bps;
2717 $bps_rd = 0 if !$bps_rd;
2718 $bps_wr = 0 if !$bps_wr;
2719 $iops = 0 if !$iops;
2720 $iops_rd = 0 if !$iops_rd;
2721 $iops_wr = 0 if !$iops_wr;
2722
f3f323a3
AD
2723 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));
2724
affd2f88
AD
2725}
2726
f5eb281a 2727# old code, only used to shutdown old VM after update
dab36e1e
DM
2728sub __read_avail {
2729 my ($fh, $timeout) = @_;
2730
2731 my $sel = new IO::Select;
2732 $sel->add($fh);
2733
2734 my $res = '';
2735 my $buf;
2736
2737 my @ready;
2738 while (scalar (@ready = $sel->can_read($timeout))) {
2739 my $count;
2740 if ($count = $fh->sysread($buf, 8192)) {
2741 if ($buf =~ /^(.*)\(qemu\) $/s) {
2742 $res .= $1;
2743 last;
2744 } else {
2745 $res .= $buf;
2746 }
2747 } else {
2748 if (!defined($count)) {
2749 die "$!\n";
2750 }
2751 last;
2752 }
2753 }
2754
2755 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 2756
dab36e1e
DM
2757 return $res;
2758}
2759
f5eb281a 2760# old code, only used to shutdown old VM after update
dab36e1e
DM
2761sub vm_monitor_command {
2762 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 2763
dab36e1e
DM
2764 my $res;
2765
2766 eval {
2767 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2768
2769 my $sname = "${var_run_tmpdir}/$vmid.mon";
2770
2771 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2772 die "unable to connect to VM $vmid socket - $!\n";
2773
2774 my $timeout = 3;
2775
2776 # hack: migrate sometime blocks the monitor (when migrate_downtime
2777 # is set)
2778 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2779 $timeout = 60*60; # 1 hour
2780 }
2781
2782 # read banner;
2783 my $data = __read_avail($sock, $timeout);
2784
2785 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2786 die "got unexpected qemu monitor banner\n";
2787 }
2788
2789 my $sel = new IO::Select;
2790 $sel->add($sock);
2791
2792 if (!scalar(my @ready = $sel->can_write($timeout))) {
2793 die "monitor write error - timeout";
2794 }
2795
2796 my $fullcmd = "$cmdstr\r";
2797
2798 # syslog('info', "VM $vmid monitor command: $cmdstr");
2799
2800 my $b;
2801 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2802 die "monitor write error - $!";
2803 }
2804
2805 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2806
2807 $timeout = 20;
2808
2809 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2810 $timeout = 60*60; # 1 hour
2811 } elsif ($cmdstr =~ m/^(eject|change)/) {
2812 $timeout = 60; # note: cdrom mount command is slow
2813 }
2814 if ($res = __read_avail($sock, $timeout)) {
2815
2816 my @lines = split("\r?\n", $res);
f5eb281a 2817
dab36e1e 2818 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 2819
dab36e1e
DM
2820 $res = join("\n", @lines);
2821 $res .= "\n";
2822 }
2823 };
2824
2825 my $err = $@;
2826
2827 if ($err) {
2828 syslog("err", "VM $vmid monitor command failed - $err");
2829 die $err;
2830 }
f5eb281a 2831
dab36e1e
DM
2832 return $res;
2833}
2834
c1175c92
AD
2835sub qemu_block_resize {
2836 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2837
2838 my $running = PVE::QemuServer::check_running($vmid);
2839
2840 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
2841
2842 return if !$running;
2843
2844 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
2845
2846}
2847
1ab0057c
AD
2848sub qemu_volume_snapshot {
2849 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2850
2851 my $running = PVE::QemuServer::check_running($vmid);
2852
2853 return if !PVE::Storage::volume_snapshot($storecfg, $volid, $snap, $running);
2854
2855 return if !$running;
2856
2857 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
2858
2859}
2860
fc46aff9
AD
2861sub qemu_volume_snapshot_delete {
2862 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2863
fc46aff9
AD
2864 my $running = PVE::QemuServer::check_running($vmid);
2865
2866 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
2867
2868 return if !$running;
2869
18bfb361 2870 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
2871}
2872
3d5149c9
AD
2873sub qga_freezefs {
2874 my ($vmid) = @_;
2875
2876 #need to impplement call to qemu-ga
2877}
2878
e8f3f18e
AD
2879sub qga_unfreezefs {
2880 my ($vmid) = @_;
2881
2882 #need to impplement call to qemu-ga
2883}
2884
1e3baf05 2885sub vm_start {
7e8dcf2c 2886 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
1e3baf05 2887
6b64503e 2888 lock_config($vmid, sub {
7e8dcf2c 2889 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 2890
6b64503e 2891 check_lock($conf) if !$skiplock;
1e3baf05 2892
7e8dcf2c 2893 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 2894
6c47d546
DM
2895 my $defaults = load_defaults();
2896
2897 # set environment variable useful inside network script
2898 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
2899
2900 my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults);
2901
1e3baf05
DM
2902 my $migrate_port = 0;
2903
2904 if ($statefile) {
2905 if ($statefile eq 'tcp') {
2906 $migrate_port = next_migrate_port();
6c47d546
DM
2907 my $migrate_uri = "tcp:localhost:${migrate_port}";
2908 push @$cmd, '-incoming', $migrate_uri;
2909 push @$cmd, '-S';
1e3baf05 2910 } else {
6c47d546 2911 push @$cmd, '-loadstate', $statefile;
1e3baf05
DM
2912 }
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
9c502e26
DM
3449 if ($archive ne '-') {
3450 my $firstfile = archive_read_firstfile($archive);
3451 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3452 if $firstfile ne 'qemu-server.conf';
3453 }
3e16d5fc
DM
3454
3455 my $tocmd = "/usr/lib/qemu-server/qmextract";
3456
2415a446 3457 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 3458 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
3459 $tocmd .= ' --prealloc' if $opts->{prealloc};
3460 $tocmd .= ' --info' if $opts->{info};
3461
a0d1b1a2 3462 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 3463 # so we pipe to zcat
2415a446
DM
3464 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
3465 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
3466
3467 my $tmpdir = "/var/tmp/vzdumptmp$$";
3468 mkpath $tmpdir;
3469
3470 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
3471 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 3472 local $ENV{VZDUMP_USER} = $user;
3e16d5fc
DM
3473
3474 my $conffile = PVE::QemuServer::config_file($vmid);
3475 my $tmpfn = "$conffile.$$.tmp";
3476
3477 # disable interrupts (always do cleanups)
3478 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3479 print STDERR "got interrupt - ignored\n";
3480 };
3481
afdb31d5 3482 eval {
3e16d5fc
DM
3483 # enable interrupts
3484 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
3485 die "interrupted by signal\n";
3486 };
3487
9c502e26
DM
3488 if ($archive eq '-') {
3489 print "extracting archive from STDIN\n";
3490 run_command($cmd, input => "<&STDIN");
3491 } else {
3492 print "extracting archive '$archive'\n";
3493 run_command($cmd);
3494 }
3e16d5fc
DM
3495
3496 return if $opts->{info};
3497
3498 # read new mapping
3499 my $map = {};
3500 my $statfile = "$tmpdir/qmrestore.stat";
3501 if (my $fd = IO::File->new($statfile, "r")) {
3502 while (defined (my $line = <$fd>)) {
3503 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3504 $map->{$1} = $2 if $1;
3505 } else {
3506 print STDERR "unable to parse line in statfile - $line\n";
3507 }
3508 }
3509 $fd->close();
3510 }
3511
3512 my $confsrc = "$tmpdir/qemu-server.conf";
3513
3514 my $srcfd = new IO::File($confsrc, "r") ||
3515 die "unable to open file '$confsrc'\n";
3516
3517 my $outfd = new IO::File ($tmpfn, "w") ||
3518 die "unable to write config for VM $vmid\n";
3519
51586c3a
DM
3520 my $netcount = 0;
3521
3e16d5fc
DM
3522 while (defined (my $line = <$srcfd>)) {
3523 next if $line =~ m/^\#vzdump\#/;
3524 next if $line =~ m/^lock:/;
3525 next if $line =~ m/^unused\d+:/;
3526
51586c3a
DM
3527 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3528 # try to convert old 1.X settings
3529 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3530 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3531 my ($model, $macaddr) = split(/\=/, $devconfig);
3532 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $opts->{unique};
3533 my $net = {
3534 model => $model,
3535 bridge => "vmbr$ind",
3536 macaddr => $macaddr,
3537 };
3538 my $netstr = print_net($net);
3539 print $outfd "net${netcount}: $netstr\n";
3540 $netcount++;
3541 }
3542 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique})) {
3543 my ($id, $netstr) = ($1, $2);
3544 my $net = parse_net($netstr);
3545 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3546 $netstr = print_net($net);
afdb31d5 3547 print $outfd "$id: $netstr\n";
4dac70e5 3548 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
3e16d5fc
DM
3549 my $virtdev = $1;
3550 my $value = $2;
3551 if ($line =~ m/backup=no/) {
3552 print $outfd "#$line";
3553 } elsif ($virtdev && $map->{$virtdev}) {
3554 my $di = PVE::QemuServer::parse_drive($virtdev, $value);
3555 $di->{file} = $map->{$virtdev};
3556 $value = PVE::QemuServer::print_drive($vmid, $di);
3557 print $outfd "$virtdev: $value\n";
3558 } else {
3559 print $outfd $line;
3560 }
3561 } else {
3562 print $outfd $line;
3563 }
3564 }
3565
3566 $srcfd->close();
3567 $outfd->close();
3568 };
3569 my $err = $@;
3570
afdb31d5 3571 if ($err) {
3e16d5fc
DM
3572
3573 unlink $tmpfn;
3574
3575 restore_cleanup("$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 3576
3e16d5fc 3577 die $err;
afdb31d5 3578 }
3e16d5fc
DM
3579
3580 rmtree $tmpdir;
3581
3582 rename $tmpfn, $conffile ||
3583 die "unable to commit configuration file '$conffile'\n";
3584};
3585
0d18dcfc
DM
3586
3587# Internal snapshots
3588
3589# NOTE: Snapshot create/delete involves several non-atomic
3590# action, and can take a long time.
3591# So we try to avoid locking the file and use 'lock' variable
3592# inside the config file instead.
3593
ef59d1ca
DM
3594my $snapshot_copy_config = sub {
3595 my ($source, $dest) = @_;
3596
3597 foreach my $k (keys %$source) {
3598 next if $k eq 'snapshots';
982c7f12
DM
3599 next if $k eq 'snapstate';
3600 next if $k eq 'snaptime';
18bfb361 3601 next if $k eq 'vmstate';
ef59d1ca
DM
3602 next if $k eq 'lock';
3603 next if $k eq 'digest';
db7c26e5 3604 next if $k eq 'description';
ef59d1ca
DM
3605 next if $k =~ m/^unused\d+$/;
3606
3607 $dest->{$k} = $source->{$k};
3608 }
3609};
3610
3611my $snapshot_apply_config = sub {
3612 my ($conf, $snap) = @_;
3613
3614 # copy snapshot list
3615 my $newconf = {
3616 snapshots => $conf->{snapshots},
3617 };
3618
db7c26e5 3619 # keep description and list of unused disks
ef59d1ca 3620 foreach my $k (keys %$conf) {
db7c26e5 3621 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
3622 $newconf->{$k} = $conf->{$k};
3623 }
3624
3625 &$snapshot_copy_config($snap, $newconf);
3626
3627 return $newconf;
3628};
3629
18bfb361
DM
3630sub foreach_writable_storage {
3631 my ($conf, $func) = @_;
3632
3633 my $sidhash = {};
3634
3635 foreach my $ds (keys %$conf) {
3636 next if !valid_drivename($ds);
3637
3638 my $drive = parse_drive($ds, $conf->{$ds});
3639 next if !$drive;
3640 next if drive_is_cdrom($drive);
3641
3642 my $volid = $drive->{file};
3643
3644 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
3645 $sidhash->{$sid} = $sid if $sid;
3646 }
3647
3648 foreach my $sid (sort keys %$sidhash) {
3649 &$func($sid);
3650 }
3651}
3652
3653my $alloc_vmstate_volid = sub {
3654 my ($storecfg, $vmid, $conf, $snapname) = @_;
3655
3656 # Note: we try to be smart when selecting a $target storage
3657
3658 my $target;
3659
3660 # search shared storage first
3661 foreach_writable_storage($conf, sub {
3662 my ($sid) = @_;
3663 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
3664 return if !$scfg->{shared};
3665
3666 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
3667 });
3668
3669 if (!$target) {
3670 # now search local storage
3671 foreach_writable_storage($conf, sub {
3672 my ($sid) = @_;
3673 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
3674 return if $scfg->{shared};
3675
3676 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
3677 });
3678 }
3679
3680 $target = 'local' if !$target;
3681
fe6249f4
DM
3682 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
3683 # we abort live save after $conf->{memory}, so we need at max twice that space
3684 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
3685
3686 my $name = "vm-$vmid-state-$snapname";
3687 my $scfg = PVE::Storage::storage_config($storecfg, $target);
3688 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
3689 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
3690
3691 return $volid;
3692};
3693
0d18dcfc 3694my $snapshot_prepare = sub {
18bfb361 3695 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
3696
3697 my $snap;
0d18dcfc
DM
3698
3699 my $updatefn = sub {
3700
3701 my $conf = load_config($vmid);
3702
3703 check_lock($conf);
3704
22c377f0
DM
3705 $conf->{lock} = 'snapshot';
3706
0d18dcfc
DM
3707 die "snapshot name '$snapname' already used\n"
3708 if defined($conf->{snapshots}->{$snapname});
3709
ee2f90b1
DM
3710 my $storecfg = PVE::Storage::config();
3711
18bfb361 3712 foreach_drive($conf, sub {
ee2f90b1
DM
3713 my ($ds, $drive) = @_;
3714
3715 return if drive_is_cdrom($drive);
3716 my $volid = $drive->{file};
3717
3718 my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
3719 if ($storeid) {
3720 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
3721 die "can't snapshot volume '$volid'\n"
3722 if !(($scfg->{path} && $volname =~ m/\.qcow2$/) ||
6c47d546 3723 ($scfg->{type} eq 'nexenta') ||
ee2f90b1
DM
3724 ($scfg->{type} eq 'rbd') ||
3725 ($scfg->{type} eq 'sheepdog'));
3726 } elsif ($volid =~ m|^(/.+)$| && -e $volid) {
3727 die "snapshot device '$volid' is not possible\n";
3728 } else {
3729 die "can't snapshot volume '$volid'\n";
3730 }
3731 });
f1baf1df 3732
18bfb361 3733
782f4f75 3734 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 3735
18bfb361
DM
3736 if ($save_vmstate && check_running($vmid)) {
3737 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
3738 }
3739
ef59d1ca 3740 &$snapshot_copy_config($conf, $snap);
0d18dcfc 3741
782f4f75
DM
3742 $snap->{snapstate} = "prepare";
3743 $snap->{snaptime} = time();
3744 $snap->{description} = $comment if $comment;
3745
0d18dcfc
DM
3746 update_config_nolock($vmid, $conf, 1);
3747 };
3748
3749 lock_config($vmid, $updatefn);
22c377f0
DM
3750
3751 return $snap;
0d18dcfc
DM
3752};
3753
3754my $snapshot_commit = sub {
3755 my ($vmid, $snapname) = @_;
3756
3757 my $updatefn = sub {
3758
3759 my $conf = load_config($vmid);
3760
3761 die "missing snapshot lock\n"
3762 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
3763
3764 my $snap = $conf->{snapshots}->{$snapname};
3765
3766 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3767
3768 die "wrong snapshot state\n"
3769 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
3770
3771 delete $snap->{snapstate};
ee2f90b1 3772 delete $conf->{lock};
0d18dcfc 3773
ef59d1ca 3774 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 3775
05e5ad3f
DM
3776 $newconf->{parent} = $snapname;
3777
0d18dcfc
DM
3778 update_config_nolock($vmid, $newconf, 1);
3779 };
3780
3781 lock_config($vmid, $updatefn);
3782};
3783
22c377f0
DM
3784sub snapshot_rollback {
3785 my ($vmid, $snapname) = @_;
3786
3787 my $snap;
3788
3789 my $prepare = 1;
3790
a3222b91
DM
3791 my $storecfg = PVE::Storage::config();
3792
22c377f0
DM
3793 my $updatefn = sub {
3794
3795 my $conf = load_config($vmid);
3796
ab33a7c2
DM
3797 $snap = $conf->{snapshots}->{$snapname};
3798
3799 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3800
3801 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
3802 if $snap->{snapstate};
3803
a3222b91
DM
3804 if ($prepare) {
3805 check_lock($conf);
3806 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
3807 }
22c377f0
DM
3808
3809 die "unable to rollback vm $vmid: vm is running\n"
3810 if check_running($vmid);
3811
3812 if ($prepare) {
3813 $conf->{lock} = 'rollback';
3814 } else {
3815 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
3816 delete $conf->{lock};
3817 }
3818
22c377f0
DM
3819 if (!$prepare) {
3820 # copy snapshot config to current config
ef59d1ca
DM
3821 $conf = &$snapshot_apply_config($conf, $snap);
3822 $conf->{parent} = $snapname;
22c377f0
DM
3823 }
3824
3825 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
3826
3827 if (!$prepare && $snap->{vmstate}) {
3828 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
3829 # fixme: this only forws for files currently
3830 vm_start($storecfg, $vmid, $statefile);
3831 }
3832
22c377f0
DM
3833 };
3834
3835 lock_config($vmid, $updatefn);
22c377f0
DM
3836
3837 foreach_drive($snap, sub {
3838 my ($ds, $drive) = @_;
3839
3840 return if drive_is_cdrom($drive);
3841
3842 my $volid = $drive->{file};
3843 my $device = "drive-$ds";
3844
79e57b29 3845 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
3846 });
3847
3848 $prepare = 0;
3849 lock_config($vmid, $updatefn);
3850}
3851
9dcf4909
DM
3852my $savevm_wait = sub {
3853 my ($vmid) = @_;
3854
3855 for(;;) {
3856 my $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-savevm");
3857 if (!$stat->{status}) {
3858 die "savevm not active\n";
3859 } elsif ($stat->{status} eq 'active') {
3860 sleep(1);
3861 next;
3862 } elsif ($stat->{status} eq 'completed') {
3863 last;
3864 } else {
3865 die "query-savevm returned status '$stat->{status}'\n";
3866 }
3867 }
3868};
3869
0d18dcfc 3870sub snapshot_create {
18bfb361 3871 my ($vmid, $snapname, $save_vmstate, $freezefs, $comment) = @_;
0d18dcfc 3872
18bfb361 3873 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 3874
18bfb361 3875 $freezefs = $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
030dd626 3876
3ee28e38
DM
3877 my $drivehash = {};
3878
18bfb361
DM
3879 my $running = check_running($vmid);
3880
0d18dcfc
DM
3881 eval {
3882 # create internal snapshots of all drives
22c377f0
DM
3883
3884 my $storecfg = PVE::Storage::config();
a3222b91
DM
3885
3886 if ($running) {
3887 if ($snap->{vmstate}) {
3888 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
3889 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
3890 &$savevm_wait($vmid);
a3222b91 3891 } else {
9dcf4909 3892 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
3893 }
3894 };
3895
3896 qga_freezefs($vmid) if $running && $freezefs;
22c377f0
DM
3897
3898 foreach_drive($snap, sub {
3899 my ($ds, $drive) = @_;
3900
3901 return if drive_is_cdrom($drive);
0d18dcfc 3902
22c377f0
DM
3903 my $volid = $drive->{file};
3904 my $device = "drive-$ds";
3905
3906 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 3907 $drivehash->{$ds} = 1;
22c377f0 3908 });
0d18dcfc 3909 };
22c377f0
DM
3910 my $err = $@;
3911
18bfb361 3912 eval { gqa_unfreezefs($vmid) if $running && $freezefs; };
22c377f0
DM
3913 warn $@ if $@;
3914
9dcf4909 3915 eval { vm_mon_cmd($vmid, "savevm-end") if $running; };
22c377f0
DM
3916 warn $@ if $@;
3917
3918 if ($err) {
0d18dcfc 3919 warn "snapshot create failed: starting cleanup\n";
3ee28e38 3920 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
3921 warn $@ if $@;
3922 die $err;
3923 }
3924
3925 &$snapshot_commit($vmid, $snapname);
3926}
3927
3ee28e38 3928# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 3929sub snapshot_delete {
3ee28e38 3930 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
3931
3932 my $prepare = 1;
3933
22c377f0 3934 my $snap;
ee2f90b1 3935 my $unused = [];
0d18dcfc 3936
6cb1a8cf
DM
3937 my $unlink_parent = sub {
3938 my ($confref, $new_parent) = @_;
3939
3940 if ($confref->{parent} && $confref->{parent} eq $snapname) {
3941 if ($new_parent) {
3942 $confref->{parent} = $new_parent;
3943 } else {
3944 delete $confref->{parent};
3945 }
3946 }
3947 };
3948
0d18dcfc 3949 my $updatefn = sub {
2009f324 3950 my ($remove_drive) = @_;
0d18dcfc 3951
22c377f0 3952 my $conf = load_config($vmid);
0d18dcfc 3953
3ee28e38 3954 check_lock($conf) if !$drivehash;
0d18dcfc 3955
22c377f0 3956 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc
DM
3957
3958 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3959
3960 # remove parent refs
6cb1a8cf 3961 &$unlink_parent($conf, $snap->{parent});
0d18dcfc
DM
3962 foreach my $sn (keys %{$conf->{snapshots}}) {
3963 next if $sn eq $snapname;
6cb1a8cf 3964 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
0d18dcfc
DM
3965 }
3966
2009f324 3967 if ($remove_drive) {
18bfb361
DM
3968 if ($remove_drive eq 'vmstate') {
3969 delete $snap->{$remove_drive};
3970 } else {
3971 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
3972 my $volid = $drive->{file};
3973 delete $snap->{$remove_drive};
3974 add_unused_volume($conf, $volid);
3975 }
2009f324
DM
3976 }
3977
0d18dcfc
DM
3978 if ($prepare) {
3979 $snap->{snapstate} = 'delete';
3980 } else {
3981 delete $conf->{snapshots}->{$snapname};
3ee28e38 3982 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
3983 foreach my $volid (@$unused) {
3984 add_unused_volume($conf, $volid);
3985 }
0d18dcfc
DM
3986 }
3987
3988 update_config_nolock($vmid, $conf, 1);
3989 };
3990
3991 lock_config($vmid, $updatefn);
3992
18bfb361 3993 # now remove vmstate file
0d18dcfc 3994
22c377f0
DM
3995 my $storecfg = PVE::Storage::config();
3996
18bfb361
DM
3997 if ($snap->{vmstate}) {
3998 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
3999 if (my $err = $@) {
4000 die $err if !$force;
4001 warn $err;
4002 }
4003 # save changes (remove vmstate from snapshot)
4004 lock_config($vmid, $updatefn, 'vmstate') if !$force;
4005 };
4006
4007 # now remove all internal snapshots
4008 foreach_drive($snap, sub {
22c377f0
DM
4009 my ($ds, $drive) = @_;
4010
4011 return if drive_is_cdrom($drive);
3ee28e38 4012
22c377f0
DM
4013 my $volid = $drive->{file};
4014 my $device = "drive-$ds";
4015
2009f324
DM
4016 if (!$drivehash || $drivehash->{$ds}) {
4017 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
4018 if (my $err = $@) {
4019 die $err if !$force;
4020 warn $err;
4021 }
3ee28e38 4022 }
2009f324
DM
4023
4024 # save changes (remove drive fron snapshot)
4025 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 4026 push @$unused, $volid;
22c377f0 4027 });
0d18dcfc
DM
4028
4029 # now cleanup config
4030 $prepare = 0;
4031 lock_config($vmid, $updatefn);
4032}
4033
1e3baf05 40341;