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