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