]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
add qga_unfreezefs
[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
36# can be set to 'migrate' or 'backup'. Most actions are not
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.",
174 enum => [qw(migrate backup)],
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),
554ac7e7 1550 };
1e3baf05 1551
19672434 1552 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1553 || die "got strange filename '$filename'";
1554
1555 my $vmid = $1;
1556
0581fe4f
DM
1557 my $descr = '';
1558
1e3baf05
DM
1559 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1560 my $line = $1;
19672434 1561
1e3baf05
DM
1562 next if $line =~ m/^\s*$/;
1563
0581fe4f
DM
1564 if ($line =~ m/^\#(.*)\s*$/) {
1565 $descr .= PVE::Tools::decode_text($1) . "\n";
1566 next;
1567 }
1568
1e3baf05 1569 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
0581fe4f 1570 $descr .= PVE::Tools::decode_text($2);
1e3baf05
DM
1571 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1572 my $key = $1;
1573 my $value = $2;
1574 $res->{$key} = $value;
1575 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1576 my $key = $1;
1577 my $value = $2;
1578 eval { $value = check_type($key, $value); };
1579 if ($@) {
1580 warn "vm $vmid - unable to parse value of '$key' - $@";
1581 } else {
1582 my $fmt = $confdesc->{$key}->{format};
1583 if ($fmt && $fmt eq 'pve-qm-drive') {
1584 my $v = parse_drive($key, $value);
1585 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1586 $v->{file} = $volid;
6b64503e 1587 $value = print_drive($vmid, $v);
1e3baf05
DM
1588 } else {
1589 warn "vm $vmid - unable to parse value of '$key'\n";
1590 next;
1591 }
1592 }
1593
1594 if ($key eq 'cdrom') {
1595 $res->{ide2} = $value;
1596 } else {
1597 $res->{$key} = $value;
1598 }
1599 }
1600 }
1601 }
1602
0581fe4f
DM
1603 $res->{description} = $descr if $descr;
1604
1e3baf05
DM
1605 # convert old smp to sockets
1606 if ($res->{smp} && !$res->{sockets}) {
1607 $res->{sockets} = $res->{smp};
19672434 1608 }
1e3baf05
DM
1609 delete $res->{smp};
1610
1611 return $res;
1612}
1613
1858638f
DM
1614sub write_vm_config {
1615 my ($filename, $conf) = @_;
1e3baf05 1616
1858638f
DM
1617 if ($conf->{cdrom}) {
1618 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
1619 $conf->{ide2} = $conf->{cdrom};
1620 delete $conf->{cdrom};
1621 }
1e3baf05
DM
1622
1623 # we do not use 'smp' any longer
1858638f
DM
1624 if ($conf->{sockets}) {
1625 delete $conf->{smp};
1626 } elsif ($conf->{smp}) {
1627 $conf->{sockets} = $conf->{smp};
1628 delete $conf->{cores};
1629 delete $conf->{smp};
1e3baf05
DM
1630 }
1631
1632 my $new_volids = {};
1858638f 1633 foreach my $key (keys %$conf) {
0581fe4f 1634 next if $key eq 'digest' || $key eq 'description';
1858638f 1635 my $value = $conf->{$key};
1e3baf05
DM
1636 eval { $value = check_type($key, $value); };
1637 die "unable to parse value of '$key' - $@" if $@;
1858638f
DM
1638
1639 $conf->{$key} = $value;
1640
1e3baf05
DM
1641 if (valid_drivename($key)) {
1642 my $drive = PVE::QemuServer::parse_drive($key, $value);
1643 $new_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
1644 }
1645 }
1646
1858638f
DM
1647 # remove 'unusedX' settings if we re-add a volume
1648 foreach my $key (keys %$conf) {
1649 my $value = $conf->{$key};
1650 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1651 delete $conf->{$key};
1e3baf05 1652 }
1858638f 1653 }
1e3baf05 1654
1858638f
DM
1655 # gererate RAW data
1656 my $raw = '';
0581fe4f
DM
1657
1658 # add description as comment to top of file
1659 my $descr = $conf->{description} || '';
1660 foreach my $cl (split(/\n/, $descr)) {
1661 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
1662 }
1663
1858638f 1664 foreach my $key (sort keys %$conf) {
0581fe4f 1665 next if $key eq 'digest' || $key eq 'description';
1858638f
DM
1666 $raw .= "$key: $conf->{$key}\n";
1667 }
1e3baf05 1668
1858638f
DM
1669 return $raw;
1670}
1e3baf05 1671
1858638f
DM
1672sub update_config_nolock {
1673 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1674
1858638f 1675 check_lock($conf) if !$skiplock;
97d62eb7 1676
1858638f 1677 my $cfspath = cfs_config_path($vmid);
1e3baf05 1678
1858638f
DM
1679 PVE::Cluster::cfs_write_file($cfspath, $conf);
1680}
1e3baf05 1681
1858638f
DM
1682sub update_config {
1683 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1684
1858638f 1685 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1e3baf05
DM
1686}
1687
19672434 1688sub load_defaults {
1e3baf05
DM
1689
1690 my $res = {};
1691
1692 # we use static defaults from our JSON schema configuration
1693 foreach my $key (keys %$confdesc) {
1694 if (defined(my $default = $confdesc->{$key}->{default})) {
1695 $res->{$key} = $default;
1696 }
1697 }
19672434 1698
1e3baf05
DM
1699 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
1700 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
1701
1702 return $res;
1703}
1704
1705sub config_list {
1706 my $vmlist = PVE::Cluster::get_vmlist();
1707 my $res = {};
1708 return $res if !$vmlist || !$vmlist->{ids};
1709 my $ids = $vmlist->{ids};
1710
1e3baf05
DM
1711 foreach my $vmid (keys %$ids) {
1712 my $d = $ids->{$vmid};
1713 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 1714 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
1715 $res->{$vmid}->{exists} = 1;
1716 }
1717 return $res;
1718}
1719
64e13401
DM
1720# test if VM uses local resources (to prevent migration)
1721sub check_local_resources {
1722 my ($conf, $noerr) = @_;
1723
1724 my $loc_res = 0;
19672434 1725
e0ab7331
DM
1726 $loc_res = 1 if $conf->{hostusb}; # old syntax
1727 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 1728
0d29ab3b 1729 foreach my $k (keys %$conf) {
2fe1a152 1730 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
1731 }
1732
1733 die "VM uses local resources\n" if $loc_res && !$noerr;
1734
1735 return $loc_res;
1736}
1737
47152e2e
DM
1738# check is used storages are available on all nodes (use by migrate)
1739sub check_storage_availability {
1740 my ($storecfg, $conf, $node) = @_;
1741
1742 foreach_drive($conf, sub {
1743 my ($ds, $drive) = @_;
1744
1745 my $volid = $drive->{file};
1746 return if !$volid;
1747
1748 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
1749 return if !$sid;
1750
1751 # check if storage is available on both nodes
1752 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
1753 PVE::Storage::storage_check_node($storecfg, $sid, $node);
1754 });
1755}
1756
1e3baf05
DM
1757sub check_lock {
1758 my ($conf) = @_;
1759
1760 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1761}
1762
1763sub check_cmdline {
1764 my ($pidfile, $pid) = @_;
1765
6b64503e
DM
1766 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
1767 if (defined($fh)) {
1e3baf05
DM
1768 my $line = <$fh>;
1769 $fh->close;
1770 return undef if !$line;
6b64503e 1771 my @param = split(/\0/, $line);
1e3baf05
DM
1772
1773 my $cmd = $param[0];
1774 return if !$cmd || ($cmd !~ m|kvm$|);
1775
1776 for (my $i = 0; $i < scalar (@param); $i++) {
1777 my $p = $param[$i];
1778 next if !$p;
1779 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1780 my $p = $param[$i+1];
1781 return 1 if $p && ($p eq $pidfile);
1782 return undef;
1783 }
1784 }
1785 }
1786 return undef;
1787}
1788
1789sub check_running {
7e8dcf2c 1790 my ($vmid, $nocheck, $node) = @_;
1e3baf05 1791
7e8dcf2c 1792 my $filename = config_file($vmid, $node);
1e3baf05
DM
1793
1794 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 1795 if !$nocheck && ! -f $filename;
1e3baf05 1796
e6c3b671 1797 my $pidfile = pidfile_name($vmid);
1e3baf05 1798
e6c3b671
DM
1799 if (my $fd = IO::File->new("<$pidfile")) {
1800 my $st = stat($fd);
1e3baf05 1801 my $line = <$fd>;
6b64503e 1802 close($fd);
1e3baf05
DM
1803
1804 my $mtime = $st->mtime;
1805 if ($mtime > time()) {
1806 warn "file '$filename' modified in future\n";
1807 }
1808
1809 if ($line =~ m/^(\d+)$/) {
1810 my $pid = $1;
e6c3b671
DM
1811 if (check_cmdline($pidfile, $pid)) {
1812 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
1813 return $pid;
1814 }
1815 }
1e3baf05
DM
1816 }
1817 }
1818
1819 return undef;
1820}
1821
1822sub vzlist {
19672434 1823
1e3baf05
DM
1824 my $vzlist = config_list();
1825
6b64503e 1826 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 1827
19672434 1828 while (defined(my $de = $fd->read)) {
1e3baf05
DM
1829 next if $de !~ m/^(\d+)\.pid$/;
1830 my $vmid = $1;
6b64503e
DM
1831 next if !defined($vzlist->{$vmid});
1832 if (my $pid = check_running($vmid)) {
1e3baf05
DM
1833 $vzlist->{$vmid}->{pid} = $pid;
1834 }
1835 }
1836
1837 return $vzlist;
1838}
1839
1e3baf05
DM
1840sub disksize {
1841 my ($storecfg, $conf) = @_;
1842
1843 my $bootdisk = $conf->{bootdisk};
1844 return undef if !$bootdisk;
1845 return undef if !valid_drivename($bootdisk);
1846
1847 return undef if !$conf->{$bootdisk};
1848
1849 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
1850 return undef if !defined($drive);
1851
1852 return undef if drive_is_cdrom($drive);
1853
1854 my $volid = $drive->{file};
1855 return undef if !$volid;
1856
24afaca0 1857 return $drive->{size};
1e3baf05
DM
1858}
1859
1860my $last_proc_pid_stat;
1861
03a33f30
DM
1862# get VM status information
1863# This must be fast and should not block ($full == false)
1864# We only query KVM using QMP if $full == true (this can be slow)
1e3baf05 1865sub vmstatus {
03a33f30 1866 my ($opt_vmid, $full) = @_;
1e3baf05
DM
1867
1868 my $res = {};
1869
19672434 1870 my $storecfg = PVE::Storage::config();
1e3baf05
DM
1871
1872 my $list = vzlist();
694fcad4 1873 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 1874
ae4915a2
DM
1875 my $cpucount = $cpuinfo->{cpus} || 1;
1876
1e3baf05
DM
1877 foreach my $vmid (keys %$list) {
1878 next if $opt_vmid && ($vmid ne $opt_vmid);
1879
1880 my $cfspath = cfs_config_path($vmid);
1881 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
1882
1883 my $d = {};
1884 $d->{pid} = $list->{$vmid}->{pid};
1885
1886 # fixme: better status?
1887 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
1888
af990afe
DM
1889 my $size = disksize($storecfg, $conf);
1890 if (defined($size)) {
1891 $d->{disk} = 0; # no info available
1e3baf05
DM
1892 $d->{maxdisk} = $size;
1893 } else {
1894 $d->{disk} = 0;
1895 $d->{maxdisk} = 0;
1896 }
1897
1898 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2
DM
1899 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
1900
1e3baf05 1901 $d->{name} = $conf->{name} || "VM $vmid";
19672434 1902 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 1903
1e3baf05
DM
1904 $d->{uptime} = 0;
1905 $d->{cpu} = 0;
1e3baf05
DM
1906 $d->{mem} = 0;
1907
1908 $d->{netout} = 0;
1909 $d->{netin} = 0;
1910
1911 $d->{diskread} = 0;
1912 $d->{diskwrite} = 0;
1913
1914 $res->{$vmid} = $d;
1915 }
1916
1917 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
1918 foreach my $dev (keys %$netdev) {
1919 next if $dev !~ m/^tap([1-9]\d*)i/;
1920 my $vmid = $1;
1921 my $d = $res->{$vmid};
1922 next if !$d;
19672434 1923
1e3baf05
DM
1924 $d->{netout} += $netdev->{$dev}->{receive};
1925 $d->{netin} += $netdev->{$dev}->{transmit};
1926 }
1927
1e3baf05
DM
1928 my $ctime = gettimeofday;
1929
1930 foreach my $vmid (keys %$list) {
1931
1932 my $d = $res->{$vmid};
1933 my $pid = $d->{pid};
1934 next if !$pid;
1935
694fcad4
DM
1936 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
1937 next if !$pstat; # not running
19672434 1938
694fcad4 1939 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 1940
694fcad4 1941 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 1942
694fcad4 1943 if ($pstat->{vsize}) {
6b64503e 1944 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
1945 }
1946
1947 my $old = $last_proc_pid_stat->{$pid};
1948 if (!$old) {
19672434
DM
1949 $last_proc_pid_stat->{$pid} = {
1950 time => $ctime,
1e3baf05
DM
1951 used => $used,
1952 cpu => 0,
1e3baf05
DM
1953 };
1954 next;
1955 }
1956
7f0b5beb 1957 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
1958
1959 if ($dtime > 1000) {
1960 my $dutime = $used - $old->{used};
1961
ae4915a2 1962 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 1963 $last_proc_pid_stat->{$pid} = {
19672434 1964 time => $ctime,
1e3baf05
DM
1965 used => $used,
1966 cpu => $d->{cpu},
1e3baf05
DM
1967 };
1968 } else {
1969 $d->{cpu} = $old->{cpu};
1e3baf05
DM
1970 }
1971 }
1972
f5eb281a 1973 return $res if !$full;
03a33f30
DM
1974
1975 my $qmpclient = PVE::QMPClient->new();
1976
1977 my $blockstatscb = sub {
1978 my ($vmid, $resp) = @_;
1979 my $data = $resp->{'return'} || [];
1980 my $totalrdbytes = 0;
1981 my $totalwrbytes = 0;
1982 for my $blockstat (@$data) {
1983 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
1984 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
1985 }
1986 $res->{$vmid}->{diskread} = $totalrdbytes;
1987 $res->{$vmid}->{diskwrite} = $totalwrbytes;
1988 };
1989
1990 my $statuscb = sub {
1991 my ($vmid, $resp) = @_;
1992 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
1993
1994 my $status = 'unknown';
1995 if (!defined($status = $resp->{'return'}->{status})) {
1996 warn "unable to get VM status\n";
1997 return;
1998 }
1999
2000 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2001 };
2002
2003 foreach my $vmid (keys %$list) {
2004 next if $opt_vmid && ($vmid ne $opt_vmid);
2005 next if !$res->{$vmid}->{pid}; # not running
2006 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2007 }
2008
2009 $qmpclient->queue_execute();
2010
2011 foreach my $vmid (keys %$list) {
2012 next if $opt_vmid && ($vmid ne $opt_vmid);
2013 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2014 }
2015
1e3baf05
DM
2016 return $res;
2017}
2018
2019sub foreach_drive {
2020 my ($conf, $func) = @_;
2021
2022 foreach my $ds (keys %$conf) {
2023 next if !valid_drivename($ds);
2024
6b64503e 2025 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2026 next if !$drive;
2027
2028 &$func($ds, $drive);
2029 }
2030}
2031
2032sub config_to_command {
2033 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2034
2035 my $cmd = [];
5bdcf937 2036 my $devices = [];
b78ebef7 2037 my $pciaddr = '';
5bdcf937 2038 my $bridges = {};
1e3baf05
DM
2039 my $kvmver = kvm_user_version();
2040 my $vernum = 0; # unknown
a3c52213
DM
2041 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2042 $vernum = $1*1000000+$2*1000;
2043 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2044 $vernum = $1*1000000+$2*1000+$3;
2045 }
2046
a3c52213 2047 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2048
2049 my $have_ovz = -f '/proc/vz/vestat';
2050
2051 push @$cmd, '/usr/bin/kvm';
2052
2053 push @$cmd, '-id', $vmid;
2054
2055 my $use_virtio = 0;
2056
c971c4f2
AD
2057 my $qmpsocket = qmp_socket($vmid);
2058 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2059 push @$cmd, '-mon', "chardev=qmp,mode=control";
2060
7b7c6d1b 2061 my $socket = vnc_socket($vmid);
1e3baf05
DM
2062 push @$cmd, '-vnc', "unix:$socket,x509,password";
2063
6b64503e 2064 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2065
1e3baf05
DM
2066 push @$cmd, '-daemonize';
2067
2068 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2069
b67900f1
AD
2070 push @$cmd, '-S' if $migrate_uri;
2071
1c060867
DM
2072 my $use_usb2 = 0;
2073 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2074 next if !$conf->{"usb$i"};
2075 $use_usb2 = 1;
2076 }
1e3baf05 2077 # include usb device config
5bdcf937 2078 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
19672434 2079
1e3baf05 2080 # enable absolute mouse coordinates (needed by vnc)
6b64503e 2081 my $tablet = defined($conf->{tablet}) ? $conf->{tablet} : $defaults->{tablet};
1c060867
DM
2082 if ($tablet) {
2083 if ($use_usb2) {
5bdcf937 2084 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
1c060867 2085 } else {
5bdcf937 2086 push @$devices, '-usbdevice', 'tablet';
1c060867
DM
2087 }
2088 }
1e3baf05
DM
2089
2090 # host pci devices
040b06b7
DA
2091 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2092 my $d = parse_hostpci($conf->{"hostpci$i"});
2093 next if !$d;
5bdcf937
AD
2094 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2095 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
1e3baf05
DM
2096 }
2097
2098 # usb devices
2099 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2100 my $d = parse_usb_device($conf->{"usb$i"});
2101 next if !$d;
2102 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2103 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2104 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2105 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
1e3baf05
DM
2106 }
2107 }
2108
1e3baf05 2109 # serial devices
bae179aa 2110 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2111 if (my $path = $conf->{"serial$i"}) {
19672434 2112 die "no such serial device\n" if ! -c $path;
5bdcf937
AD
2113 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2114 push @$devices, '-device', "isa-serial,chardev=serial$i";
34978be3 2115 }
1e3baf05
DM
2116 }
2117
2118 # parallel devices
1989a89c 2119 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2120 if (my $path = $conf->{"parallel$i"}) {
19672434 2121 die "no such parallel device\n" if ! -c $path;
5bdcf937
AD
2122 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2123 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2124 }
1e3baf05
DM
2125 }
2126
2127 my $vmname = $conf->{name} || "vm$vmid";
2128
2129 push @$cmd, '-name', $vmname;
19672434 2130
1e3baf05
DM
2131 my $sockets = 1;
2132 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2133 $sockets = $conf->{sockets} if $conf->{sockets};
2134
2135 my $cores = $conf->{cores} || 1;
2136
1e3baf05
DM
2137 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2138
2139 push @$cmd, '-cpu', $conf->{cpu} if $conf->{cpu};
2140
1e3baf05
DM
2141 push @$cmd, '-nodefaults';
2142
32baffb4 2143 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2144
0888fdce
DM
2145 my $bootindex_hash = {};
2146 my $i = 1;
2147 foreach my $o (split(//, $bootorder)) {
2148 $bootindex_hash->{$o} = $i*100;
2149 $i++;
afdb31d5 2150 }
3b408e82
DM
2151
2152 push @$cmd, '-boot', "menu=on";
1e3baf05 2153
6b64503e 2154 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2155
6b64503e 2156 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05
DM
2157
2158 my $vga = $conf->{vga};
2159 if (!$vga) {
2160 if ($conf->{ostype} && ($conf->{ostype} eq 'win7' || $conf->{ostype} eq 'w2k8')) {
2161 $vga = 'std';
2162 } else {
2163 $vga = 'cirrus';
2164 }
2165 }
19672434 2166
1e3baf05
DM
2167 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2168
2169 # time drift fix
6b64503e 2170 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
da21653b
DM
2171 # ignore - no longer supported by newer kvm
2172 # push @$cmd, '-tdf' if $tdf;
1e3baf05 2173
6b64503e 2174 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
1e3baf05
DM
2175
2176 if (my $ost = $conf->{ostype}) {
2177 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2178
2179 if ($ost =~ m/^w/) { # windows
6b64503e 2180 push @$cmd, '-localtime' if !defined($conf->{localtime});
1e3baf05
DM
2181
2182 # use rtc-td-hack when acpi is enabled
6b64503e 2183 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
1e3baf05
DM
2184 push @$cmd, '-rtc-td-hack';
2185 }
2186 }
2187
b7e0c8bf
DM
2188 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2189 push @$cmd, '-no-kvm-pit-reinjection';
2190 push @$cmd, '-no-hpet';
2191 }
2192
1e3baf05 2193 # -tdf ?
19672434
DM
2194 # -no-acpi
2195 # -no-kvm
1e3baf05
DM
2196 # -win2k-hack ?
2197 }
2198
7f0b5beb
DM
2199 if ($nokvm) {
2200 push @$cmd, '-no-kvm';
2201 } else {
2202 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2203 }
1e3baf05
DM
2204
2205 push @$cmd, '-localtime' if $conf->{localtime};
2206
2207 push @$cmd, '-startdate', $conf->{startdate} if $conf->{startdate};
2208
2209 push @$cmd, '-S' if $conf->{freeze};
2210
2211 # set keyboard layout
2212 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2213 push @$cmd, '-k', $kb if $kb;
2214
2215 # enable sound
2216 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2217 #push @$cmd, '-soundhw', 'es1370';
2218 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2219
bc84dcca 2220 if($conf->{agent}) {
ab6a046f
AD
2221 my $qgasocket = qga_socket($vmid);
2222 my $pciaddr = print_pci_addr("qga0", $bridges);
2223 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2224 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2225 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2226 }
2227
5bdcf937
AD
2228 $pciaddr = print_pci_addr("balloon0", $bridges);
2229 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon};
1e3baf05 2230
0ea9541d
DM
2231 if ($conf->{watchdog}) {
2232 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 2233 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 2234 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
2235 push @$devices, '-device', "$watchdog$pciaddr";
2236 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
2237 }
2238
1e3baf05 2239 my $vollist = [];
941e0c42 2240 my $scsicontroller = {};
26ee04b6 2241 my $ahcicontroller = {};
cdd20088 2242 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05
DM
2243
2244 foreach_drive($conf, sub {
2245 my ($ds, $drive) = @_;
2246
ff1a2432 2247 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 2248 push @$vollist, $drive->{file};
ff1a2432 2249 }
afdb31d5 2250
1e3baf05 2251 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
2252
2253 if (drive_is_cdrom ($drive)) {
2254 if ($bootindex_hash->{d}) {
2255 $drive->{bootindex} = $bootindex_hash->{d};
2256 $bootindex_hash->{d} += 1;
2257 }
2258 } else {
2259 if ($bootindex_hash->{c}) {
2260 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2261 $bootindex_hash->{c} += 1;
2262 }
2263 }
2264
941e0c42 2265 if ($drive->{interface} eq 'scsi') {
cdd20088
AD
2266
2267 my $maxdev = ($scsihw ne 'lsi') ? 256 : 7;
2268 my $controller = int($drive->{index} / $maxdev);
5bdcf937
AD
2269 $pciaddr = print_pci_addr("scsihw$controller", $bridges);
2270 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
cdd20088 2271 $scsicontroller->{$controller}=1;
941e0c42 2272 }
3b408e82 2273
26ee04b6
DA
2274 if ($drive->{interface} eq 'sata') {
2275 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
2276 $pciaddr = print_pci_addr("ahci$controller", $bridges);
2277 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
2278 $ahcicontroller->{$controller}=1;
2279 }
2280
5bdcf937
AD
2281 push @$devices, '-drive',print_drive_full($storecfg, $vmid, $drive);
2282 push @$devices, '-device',print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
2283 });
2284
2285 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2286
cc4d6182 2287 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 2288 next if !$conf->{"net$i"};
cc4d6182
DA
2289 my $d = parse_net($conf->{"net$i"});
2290 next if !$d;
1e3baf05 2291
cc4d6182 2292 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 2293
cc4d6182
DA
2294 if ($bootindex_hash->{n}) {
2295 $d->{bootindex} = $bootindex_hash->{n};
2296 $bootindex_hash->{n} += 1;
2297 }
1e3baf05 2298
cc4d6182 2299 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
2300 push @$devices, '-netdev', $netdevfull;
2301
2302 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
2303 push @$devices, '-device', $netdevicefull;
2304 }
1e3baf05 2305
5bdcf937
AD
2306 #bridges
2307 while (my ($k, $v) = each %$bridges) {
2308 $pciaddr = print_pci_addr("pci.$k");
2309 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
19672434
DM
2310 }
2311
1e3baf05
DM
2312
2313 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2314 # when the VM uses virtio devices.
19672434
DM
2315 if (!$use_virtio && $have_ovz) {
2316
6b64503e 2317 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2318 $conf->{cpuunits} : $defaults->{cpuunits};
2319
2320 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2321
2322 # fixme: cpulimit is currently ignored
2323 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2324 }
2325
2326 # add custom args
2327 if ($conf->{args}) {
3ada46c9 2328 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
2329 push @$cmd, @$aa;
2330 }
2331
5bdcf937 2332 push @$cmd, @$devices;
1e3baf05
DM
2333 return wantarray ? ($cmd, $vollist) : $cmd;
2334}
19672434 2335
1e3baf05
DM
2336sub vnc_socket {
2337 my ($vmid) = @_;
2338 return "${var_run_tmpdir}/$vmid.vnc";
2339}
2340
c971c4f2
AD
2341sub qmp_socket {
2342 my ($vmid) = @_;
2343 return "${var_run_tmpdir}/$vmid.qmp";
2344}
2345
ab6a046f
AD
2346sub qga_socket {
2347 my ($vmid) = @_;
2348 return "${var_run_tmpdir}/$vmid.qga";
2349}
2350
1e3baf05
DM
2351sub pidfile_name {
2352 my ($vmid) = @_;
2353 return "${var_run_tmpdir}/$vmid.pid";
2354}
2355
1e3baf05
DM
2356sub next_migrate_port {
2357
2358 for (my $p = 60000; $p < 60010; $p++) {
2359
6b64503e
DM
2360 my $sock = IO::Socket::INET->new(Listen => 5,
2361 LocalAddr => 'localhost',
2362 LocalPort => $p,
2363 ReuseAddr => 1,
2364 Proto => 0);
1e3baf05
DM
2365
2366 if ($sock) {
6b64503e 2367 close($sock);
1e3baf05
DM
2368 return $p;
2369 }
2370 }
2371
2372 die "unable to find free migration port";
2373}
2374
86fdcfb2
DA
2375sub vm_devices_list {
2376 my ($vmid) = @_;
2377
ceea9078
DM
2378 my $res = vm_mon_cmd($vmid, 'query-pci');
2379
2380 my $devices = {};
2381 foreach my $pcibus (@$res) {
2382 foreach my $device (@{$pcibus->{devices}}) {
2383 next if !$device->{'qdev_id'};
2384 $devices->{$device->{'qdev_id'}} = $device;
1dc4f496
DM
2385 }
2386 }
86fdcfb2 2387
1dc4f496 2388 return $devices;
86fdcfb2
DA
2389}
2390
ec21aa11 2391sub vm_deviceplug {
f19d1c47 2392 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 2393
2630d2a9 2394 return 1 if !check_running($vmid) || !$conf->{hotplug};
afdb31d5 2395
95d6343b
DA
2396 my $devices_list = vm_devices_list($vmid);
2397 return 1 if defined($devices_list->{$deviceid});
2398
40f28a9f
AD
2399 qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2400
5e5dcb73
DA
2401 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2402 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2403 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
5e5dcb73
DA
2404 qemu_deviceadd($vmid, $devicefull);
2405 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2406 qemu_drivedel($vmid, $deviceid);
2407 return undef;
2408 }
f19d1c47 2409 }
cfc817c7 2410
cdd20088
AD
2411 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2412 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 2413 my $pciaddr = print_pci_addr($deviceid);
cdd20088 2414 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
cfc817c7
DA
2415 qemu_deviceadd($vmid, $devicefull);
2416 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2417 }
2418
a4f091a0 2419 if ($deviceid =~ m/^(scsi)(\d+)$/) {
cdd20088
AD
2420 return 1 if ($conf->{scsihw} && $conf->{scsihw} ne 'lsi'); #virtio-scsi not yet support hotplug
2421 return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
a4f091a0 2422 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2423 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
a4f091a0
DA
2424 if(!qemu_deviceadd($vmid, $devicefull)) {
2425 qemu_drivedel($vmid, $deviceid);
2426 return undef;
2427 }
2428 }
2429
2630d2a9
DA
2430 if ($deviceid =~ m/^(net)(\d+)$/) {
2431 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2432 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2433 qemu_deviceadd($vmid, $netdevicefull);
2434 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2435 qemu_netdevdel($vmid, $deviceid);
2436 return undef;
2437 }
2438 }
2439
40f28a9f
AD
2440 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2441 my $bridgeid = $2;
2442 my $pciaddr = print_pci_addr($deviceid);
2443 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2444 qemu_deviceadd($vmid, $devicefull);
2445 return undef if !qemu_deviceaddverify($vmid, $deviceid);
2446 }
2447
5e5dcb73 2448 return 1;
a4dea331
DA
2449}
2450
ec21aa11 2451sub vm_deviceunplug {
f19d1c47 2452 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2453
5e5dcb73 2454 return 1 if !check_running ($vmid) || !$conf->{hotplug};
873c2d69 2455
95d6343b
DA
2456 my $devices_list = vm_devices_list($vmid);
2457 return 1 if !defined($devices_list->{$deviceid});
2458
ae57f6b3 2459 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
f19d1c47 2460
5e5dcb73
DA
2461 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2462 return undef if !qemu_drivedel($vmid, $deviceid);
2463 qemu_devicedel($vmid, $deviceid);
2464 return undef if !qemu_devicedelverify($vmid, $deviceid);
2465 }
cfc817c7
DA
2466
2467 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2468 return undef if !qemu_devicedel($vmid, $deviceid);
2469 }
2470
a4f091a0
DA
2471 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2472 return undef if !qemu_devicedel($vmid, $deviceid);
2473 return undef if !qemu_drivedel($vmid, $deviceid);
2474 }
2475
2630d2a9
DA
2476 if ($deviceid =~ m/^(net)(\d+)$/) {
2477 return undef if !qemu_netdevdel($vmid, $deviceid);
2478 qemu_devicedel($vmid, $deviceid);
2479 return undef if !qemu_devicedelverify($vmid, $deviceid);
2480 }
2481
5e5dcb73
DA
2482 return 1;
2483}
2484
2485sub qemu_deviceadd {
2486 my ($vmid, $devicefull) = @_;
873c2d69 2487
7b7c6d1b 2488 my $ret = vm_human_monitor_command($vmid, "device_add $devicefull");
5e5dcb73 2489 $ret =~ s/^\s+//;
afdb31d5 2490 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
5e5dcb73
DA
2491 return 1 if $ret eq "";
2492 syslog("err", "error on hotplug device : $ret");
2493 return undef;
f19d1c47 2494
5e5dcb73 2495}
afdb31d5 2496
5e5dcb73
DA
2497sub qemu_devicedel {
2498 my($vmid, $deviceid) = @_;
f19d1c47 2499
7b7c6d1b 2500 my $ret = vm_human_monitor_command($vmid, "device_del $deviceid");
5e5dcb73
DA
2501 $ret =~ s/^\s+//;
2502 return 1 if $ret eq "";
2503 syslog("err", "detaching device $deviceid failed : $ret");
2504 return undef;
2505}
2506
2507sub qemu_driveadd {
2508 my($storecfg, $vmid, $device) = @_;
2509
2510 my $drive = print_drive_full($storecfg, $vmid, $device);
7b7c6d1b 2511 my $ret = vm_human_monitor_command($vmid, "drive_add auto $drive");
5e5dcb73
DA
2512 # If the command succeeds qemu prints: "OK"
2513 if ($ret !~ m/OK/s) {
2514 syslog("err", "adding drive failed: $ret");
2515 return undef;
f19d1c47 2516 }
5e5dcb73
DA
2517 return 1;
2518}
afdb31d5 2519
5e5dcb73
DA
2520sub qemu_drivedel {
2521 my($vmid, $deviceid) = @_;
873c2d69 2522
7b7c6d1b 2523 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73
DA
2524 $ret =~ s/^\s+//;
2525 if ($ret =~ m/Device \'.*?\' not found/s) {
afdb31d5 2526 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
5e5dcb73
DA
2527 }
2528 elsif ($ret ne "") {
2529 syslog("err", "deleting drive $deviceid failed : $ret");
2530 return undef;
873c2d69 2531 }
5e5dcb73
DA
2532 return 1;
2533}
f19d1c47 2534
5e5dcb73
DA
2535sub qemu_deviceaddverify {
2536 my ($vmid,$deviceid) = @_;
873c2d69 2537
5e5dcb73
DA
2538 for (my $i = 0; $i <= 5; $i++) {
2539 my $devices_list = vm_devices_list($vmid);
2540 return 1 if defined($devices_list->{$deviceid});
2541 sleep 1;
afdb31d5 2542 }
5e5dcb73
DA
2543 syslog("err", "error on hotplug device $deviceid");
2544 return undef;
2545}
afdb31d5 2546
5e5dcb73
DA
2547
2548sub qemu_devicedelverify {
2549 my ($vmid,$deviceid) = @_;
2550
2551 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2552 for (my $i = 0; $i <= 5; $i++) {
2553 my $devices_list = vm_devices_list($vmid);
2554 return 1 if !defined($devices_list->{$deviceid});
2555 sleep 1;
afdb31d5 2556 }
5e5dcb73
DA
2557 syslog("err", "error on hot-unplugging device $deviceid");
2558 return undef;
873c2d69
DA
2559}
2560
cdd20088 2561sub qemu_findorcreatescsihw {
cfc817c7
DA
2562 my ($storecfg, $conf, $vmid, $device) = @_;
2563
cdd20088 2564 my $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
cfc817c7 2565 my $controller = int($device->{index} / $maxdev);
cdd20088 2566 my $scsihwid="scsihw$controller";
cfc817c7
DA
2567 my $devices_list = vm_devices_list($vmid);
2568
cdd20088
AD
2569 if(!defined($devices_list->{$scsihwid})) {
2570 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $scsihwid);
cfc817c7
DA
2571 }
2572 return 1;
2573}
2574
40f28a9f
AD
2575sub qemu_bridgeadd {
2576 my ($storecfg, $conf, $vmid, $device) = @_;
2577
2578 my $bridges = {};
2579 my $bridgeid = undef;
2580 print_pci_addr($device, $bridges);
2581
2582 while (my ($k, $v) = each %$bridges) {
2583 $bridgeid = $k;
2584 }
2585 return if $bridgeid < 1;
2586 my $bridge = "pci.$bridgeid";
2587 my $devices_list = vm_devices_list($vmid);
2588
2589 if(!defined($devices_list->{$bridge})) {
2590 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $bridge);
2591 }
2592 return 1;
2593}
2594
2630d2a9
DA
2595sub qemu_netdevadd {
2596 my ($vmid, $conf, $device, $deviceid) = @_;
2597
2598 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
7b7c6d1b 2599 my $ret = vm_human_monitor_command($vmid, "netdev_add $netdev");
2630d2a9
DA
2600 $ret =~ s/^\s+//;
2601
97d62eb7 2602 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2603 return 1 if $ret eq "";
2604 syslog("err", "adding netdev failed: $ret");
2605 return undef;
2606}
2607
2608sub qemu_netdevdel {
2609 my ($vmid, $deviceid) = @_;
2610
7b7c6d1b 2611 my $ret = vm_human_monitor_command($vmid, "netdev_del $deviceid");
2630d2a9 2612 $ret =~ s/^\s+//;
97d62eb7 2613 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2614 return 1 if $ret eq "";
2615 syslog("err", "deleting netdev failed: $ret");
2616 return undef;
2617}
2618
affd2f88
AD
2619sub qemu_block_set_io_throttle {
2620 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2621
f3f323a3
AD
2622 return if !check_running($vmid) ;
2623
affd2f88
AD
2624 $bps = 0 if !$bps;
2625 $bps_rd = 0 if !$bps_rd;
2626 $bps_wr = 0 if !$bps_wr;
2627 $iops = 0 if !$iops;
2628 $iops_rd = 0 if !$iops_rd;
2629 $iops_wr = 0 if !$iops_wr;
2630
f3f323a3
AD
2631 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));
2632
affd2f88
AD
2633}
2634
f5eb281a 2635# old code, only used to shutdown old VM after update
dab36e1e
DM
2636sub __read_avail {
2637 my ($fh, $timeout) = @_;
2638
2639 my $sel = new IO::Select;
2640 $sel->add($fh);
2641
2642 my $res = '';
2643 my $buf;
2644
2645 my @ready;
2646 while (scalar (@ready = $sel->can_read($timeout))) {
2647 my $count;
2648 if ($count = $fh->sysread($buf, 8192)) {
2649 if ($buf =~ /^(.*)\(qemu\) $/s) {
2650 $res .= $1;
2651 last;
2652 } else {
2653 $res .= $buf;
2654 }
2655 } else {
2656 if (!defined($count)) {
2657 die "$!\n";
2658 }
2659 last;
2660 }
2661 }
2662
2663 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 2664
dab36e1e
DM
2665 return $res;
2666}
2667
f5eb281a 2668# old code, only used to shutdown old VM after update
dab36e1e
DM
2669sub vm_monitor_command {
2670 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 2671
dab36e1e
DM
2672 my $res;
2673
2674 eval {
2675 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2676
2677 my $sname = "${var_run_tmpdir}/$vmid.mon";
2678
2679 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2680 die "unable to connect to VM $vmid socket - $!\n";
2681
2682 my $timeout = 3;
2683
2684 # hack: migrate sometime blocks the monitor (when migrate_downtime
2685 # is set)
2686 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2687 $timeout = 60*60; # 1 hour
2688 }
2689
2690 # read banner;
2691 my $data = __read_avail($sock, $timeout);
2692
2693 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2694 die "got unexpected qemu monitor banner\n";
2695 }
2696
2697 my $sel = new IO::Select;
2698 $sel->add($sock);
2699
2700 if (!scalar(my @ready = $sel->can_write($timeout))) {
2701 die "monitor write error - timeout";
2702 }
2703
2704 my $fullcmd = "$cmdstr\r";
2705
2706 # syslog('info', "VM $vmid monitor command: $cmdstr");
2707
2708 my $b;
2709 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2710 die "monitor write error - $!";
2711 }
2712
2713 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2714
2715 $timeout = 20;
2716
2717 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2718 $timeout = 60*60; # 1 hour
2719 } elsif ($cmdstr =~ m/^(eject|change)/) {
2720 $timeout = 60; # note: cdrom mount command is slow
2721 }
2722 if ($res = __read_avail($sock, $timeout)) {
2723
2724 my @lines = split("\r?\n", $res);
f5eb281a 2725
dab36e1e 2726 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 2727
dab36e1e
DM
2728 $res = join("\n", @lines);
2729 $res .= "\n";
2730 }
2731 };
2732
2733 my $err = $@;
2734
2735 if ($err) {
2736 syslog("err", "VM $vmid monitor command failed - $err");
2737 die $err;
2738 }
f5eb281a 2739
dab36e1e
DM
2740 return $res;
2741}
2742
c1175c92
AD
2743sub qemu_block_resize {
2744 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2745
2746 my $running = PVE::QemuServer::check_running($vmid);
2747
2748 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
2749
2750 return if !$running;
2751
2752 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
2753
2754}
2755
1ab0057c
AD
2756sub qemu_volume_snapshot {
2757 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2758
2759 my $running = PVE::QemuServer::check_running($vmid);
2760
2761 return if !PVE::Storage::volume_snapshot($storecfg, $volid, $snap, $running);
2762
2763 return if !$running;
2764
2765 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
2766
2767}
2768
182e97d9
AD
2769sub qemu_snapshot_start {
2770 my ($vmid, $snap) = @_;
2771
2772 #need to implement statefile location
2773 my $statefile="/tmp/$vmid-$snap";
2774
2775 vm_mon_cmd($vmid, "snapshot-start", statefile => $statefile);
2776
2777}
2778
ae2aa1a8
AD
2779sub qemu_snapshot_end {
2780 my ($vmid) = @_;
2781
2782 vm_mon_cmd($vmid, "snapshot-end");
2783
2784}
2785
3d5149c9
AD
2786sub qga_freezefs {
2787 my ($vmid) = @_;
2788
2789 #need to impplement call to qemu-ga
2790}
2791
e8f3f18e
AD
2792sub qga_unfreezefs {
2793 my ($vmid) = @_;
2794
2795 #need to impplement call to qemu-ga
2796}
2797
1e3baf05 2798sub vm_start {
7e8dcf2c 2799 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
1e3baf05 2800
6b64503e 2801 lock_config($vmid, sub {
7e8dcf2c 2802 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 2803
6b64503e 2804 check_lock($conf) if !$skiplock;
1e3baf05 2805
7e8dcf2c 2806 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05
DM
2807
2808 my $migrate_uri;
2809 my $migrate_port = 0;
2810
2811 if ($statefile) {
2812 if ($statefile eq 'tcp') {
2813 $migrate_port = next_migrate_port();
2814 $migrate_uri = "tcp:localhost:${migrate_port}";
2815 } else {
2816 if (-f $statefile) {
2817 $migrate_uri = "exec:cat $statefile";
2818 } else {
2819 warn "state file '$statefile' does not exist - doing normal startup\n";
2820 }
2821 }
2822 }
2823
2824 my $defaults = load_defaults();
2825
d691e6d3
DM
2826 # set environment variable useful inside network script
2827 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
2828
e6c3b671 2829 my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults, $migrate_uri);
1e3baf05 2830 # host pci devices
040b06b7
DA
2831 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2832 my $d = parse_hostpci($conf->{"hostpci$i"});
2833 next if !$d;
2834 my $info = pci_device_info("0000:$d->{pciid}");
2835 die "IOMMU not present\n" if !check_iommu_support();
2836 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2837 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
2838 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
2839 }
1e3baf05
DM
2840
2841 PVE::Storage::activate_volumes($storecfg, $vollist);
2842
6b64503e 2843 eval { run_command($cmd, timeout => $migrate_uri ? undef : 30); };
1e3baf05 2844 my $err = $@;
ff1a2432 2845 die "start failed: $err" if $err;
1e3baf05
DM
2846
2847 if ($statefile) {
2848
2849 if ($statefile eq 'tcp') {
2850 print "migration listens on port $migrate_port\n";
2851 } else {
2852 unlink $statefile;
2853 # fixme: send resume - is that necessary ?
60816474 2854 eval { vm_mon_cmd($vmid, "cont"); };
1e3baf05
DM
2855 }
2856 }
afdb31d5 2857
48e1a963
DM
2858 # always set migrate speed (overwrite kvm default of 32m)
2859 # we set a very hight default of 8192m which is basically unlimited
2860 my $migrate_speed = $defaults->{migrate_speed} || 8192;
2861 $migrate_speed = $conf->{migrate_speed} || $migrate_speed;
2f674c7a 2862 $migrate_speed = $migrate_speed * 1048576;
afdb31d5 2863 eval {
2f674c7a 2864 vm_mon_cmd($vmid, "migrate_set_speed", value => $migrate_speed);
48e1a963 2865 };
1e3baf05 2866
71c11a83
DM
2867 my $migrate_downtime = $defaults->{migrate_downtime};
2868 $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime});
2869 if (defined($migrate_downtime)) {
bcb7c9cf 2870 eval { vm_mon_cmd($vmid, "migrate_set_downtime", value => $migrate_downtime); };
1e3baf05 2871 }
e6c3b671 2872
e18b0b99
AD
2873 if($migratedfrom) {
2874 my $capabilities = {};
2875 $capabilities->{capability} = "xbzrle";
2876 $capabilities->{state} = JSON::true;
2877 eval { PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]); };
2878 }
2879
7878afeb 2880 vm_balloonset($vmid, $conf->{balloon}) if $conf->{balloon};
ce332eeb 2881
1e3baf05
DM
2882 });
2883}
2884
0eedc444
AD
2885sub vm_mon_cmd {
2886 my ($vmid, $execute, %params) = @_;
2887
26f11676
DM
2888 my $cmd = { execute => $execute, arguments => \%params };
2889 vm_qmp_command($vmid, $cmd);
0eedc444
AD
2890}
2891
2892sub vm_mon_cmd_nocheck {
2893 my ($vmid, $execute, %params) = @_;
2894
26f11676
DM
2895 my $cmd = { execute => $execute, arguments => \%params };
2896 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
2897}
2898
c971c4f2 2899sub vm_qmp_command {
d967756b 2900 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 2901
c971c4f2 2902 my $res;
26f11676 2903
14db5366
DM
2904 my $timeout;
2905 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
2906 $timeout = $cmd->{arguments}->{timeout};
2907 delete $cmd->{arguments}->{timeout};
2908 }
2909
c971c4f2
AD
2910 eval {
2911 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
dab36e1e 2912 my $sname = PVE::QemuServer::qmp_socket($vmid);
f5eb281a 2913 if (-e $sname) {
dab36e1e
DM
2914 my $qmpclient = PVE::QMPClient->new();
2915
14db5366 2916 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
dab36e1e
DM
2917 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
2918 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
2919 if scalar(%{$cmd->{arguments}});
2920 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
2921 } else {
2922 die "unable to open monitor socket\n";
2923 }
c971c4f2 2924 };
26f11676 2925 if (my $err = $@) {
c971c4f2
AD
2926 syslog("err", "VM $vmid qmp command failed - $err");
2927 die $err;
2928 }
2929
2930 return $res;
2931}
2932
9df5cbcc
DM
2933sub vm_human_monitor_command {
2934 my ($vmid, $cmdline) = @_;
2935
2936 my $res;
2937
f5eb281a 2938 my $cmd = {
9df5cbcc
DM
2939 execute => 'human-monitor-command',
2940 arguments => { 'command-line' => $cmdline},
2941 };
2942
2943 return vm_qmp_command($vmid, $cmd);
2944}
2945
1e3baf05
DM
2946sub vm_commandline {
2947 my ($storecfg, $vmid) = @_;
2948
6b64503e 2949 my $conf = load_config($vmid);
1e3baf05
DM
2950
2951 my $defaults = load_defaults();
2952
6b64503e 2953 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 2954
6b64503e 2955 return join(' ', @$cmd);
1e3baf05
DM
2956}
2957
2958sub vm_reset {
2959 my ($vmid, $skiplock) = @_;
2960
6b64503e 2961 lock_config($vmid, sub {
1e3baf05 2962
6b64503e 2963 my $conf = load_config($vmid);
1e3baf05 2964
6b64503e 2965 check_lock($conf) if !$skiplock;
1e3baf05 2966
816e2c4a 2967 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
2968 });
2969}
2970
2971sub get_vm_volumes {
2972 my ($conf) = @_;
1e3baf05 2973
ff1a2432
DM
2974 my $vollist = [];
2975 foreach_drive($conf, sub {
2976 my ($ds, $drive) = @_;
2977
2978 my ($sid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
2979 return if !$sid;
2980
2981 my $volid = $drive->{file};
2982 return if !$volid || $volid =~ m|^/|;
2983
2984 push @$vollist, $volid;
1e3baf05 2985 });
ff1a2432
DM
2986
2987 return $vollist;
2988}
2989
2990sub vm_stop_cleanup {
254575e9 2991 my ($storecfg, $vmid, $conf, $keepActive) = @_;
ff1a2432 2992
745fed70
DM
2993 eval {
2994 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 2995
254575e9
DM
2996 if (!$keepActive) {
2997 my $vollist = get_vm_volumes($conf);
2998 PVE::Storage::deactivate_volumes($storecfg, $vollist);
2999 }
961bfcb2 3000
ab6a046f 3001 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
3002 unlink "/var/run/qemu-server/${vmid}.$ext";
3003 }
745fed70
DM
3004 };
3005 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
3006}
3007
e6c3b671 3008# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
3009# We need that when migration VMs to other nodes (files already moved)
3010# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 3011sub vm_stop {
af30308f 3012 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 3013
9269013a 3014 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 3015
af30308f
DM
3016 if ($migratedfrom){
3017 my $pid = check_running($vmid, $nocheck, $migratedfrom);
3018 kill 15, $pid if $pid;
3019 my $conf = load_config($vmid, $migratedfrom);
3020 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive);
3021 return;
3022 }
3023
e6c3b671 3024 lock_config($vmid, sub {
1e3baf05 3025
e6c3b671 3026 my $pid = check_running($vmid, $nocheck);
ff1a2432 3027 return if !$pid;
1e3baf05 3028
ff1a2432 3029 my $conf;
e6c3b671 3030 if (!$nocheck) {
ff1a2432 3031 $conf = load_config($vmid);
e6c3b671 3032 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
3033 if (!defined($timeout) && $shutdown && $conf->{startup}) {
3034 my $opts = parse_startup($conf->{startup});
3035 $timeout = $opts->{down} if $opts->{down};
3036 }
e6c3b671 3037 }
19672434 3038
7f4a5b5a
DM
3039 $timeout = 60 if !defined($timeout);
3040
9269013a
DM
3041 eval {
3042 if ($shutdown) {
988903ca 3043 $nocheck ? vm_mon_cmd_nocheck($vmid, "system_powerdown") : vm_mon_cmd($vmid, "system_powerdown");
bcb7c9cf 3044
9269013a 3045 } else {
988903ca 3046 $nocheck ? vm_mon_cmd_nocheck($vmid, "quit") : vm_mon_cmd($vmid, "quit");
afdb31d5 3047 }
9269013a 3048 };
1e3baf05
DM
3049 my $err = $@;
3050
3051 if (!$err) {
1e3baf05 3052 my $count = 0;
e6c3b671 3053 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3054 $count++;
3055 sleep 1;
3056 }
3057
3058 if ($count >= $timeout) {
9269013a
DM
3059 if ($force) {
3060 warn "VM still running - terminating now with SIGTERM\n";
3061 kill 15, $pid;
3062 } else {
3063 die "VM quit/powerdown failed - got timeout\n";
3064 }
3065 } else {
254575e9 3066 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
9269013a 3067 return;
1e3baf05
DM
3068 }
3069 } else {
9269013a
DM
3070 if ($force) {
3071 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3072 kill 15, $pid;
3073 } else {
afdb31d5 3074 die "VM quit/powerdown failed\n";
9269013a 3075 }
1e3baf05
DM
3076 }
3077
3078 # wait again
ff1a2432 3079 $timeout = 10;
1e3baf05
DM
3080
3081 my $count = 0;
e6c3b671 3082 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3083 $count++;
3084 sleep 1;
3085 }
3086
3087 if ($count >= $timeout) {
ff1a2432 3088 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 3089 kill 9, $pid;
ff1a2432 3090 sleep 1;
1e3baf05
DM
3091 }
3092
254575e9 3093 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
ff1a2432 3094 });
1e3baf05
DM
3095}
3096
3097sub vm_suspend {
3098 my ($vmid, $skiplock) = @_;
3099
6b64503e 3100 lock_config($vmid, sub {
1e3baf05 3101
6b64503e 3102 my $conf = load_config($vmid);
1e3baf05 3103
6b64503e 3104 check_lock($conf) if !$skiplock;
bcb7c9cf 3105
f77f91f3 3106 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
3107 });
3108}
3109
3110sub vm_resume {
3111 my ($vmid, $skiplock) = @_;
3112
6b64503e 3113 lock_config($vmid, sub {
1e3baf05 3114
6b64503e 3115 my $conf = load_config($vmid);
1e3baf05 3116
6b64503e 3117 check_lock($conf) if !$skiplock;
1e3baf05 3118
12060fe8 3119 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
3120 });
3121}
3122
5fdbe4f0
DM
3123sub vm_sendkey {
3124 my ($vmid, $skiplock, $key) = @_;
1e3baf05 3125
6b64503e 3126 lock_config($vmid, sub {
1e3baf05 3127
6b64503e 3128 my $conf = load_config($vmid);
f5eb281a 3129
7b7c6d1b
DM
3130 # there is no qmp command, so we use the human monitor command
3131 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
3132 });
3133}
3134
3135sub vm_destroy {
3136 my ($storecfg, $vmid, $skiplock) = @_;
3137
6b64503e 3138 lock_config($vmid, sub {
1e3baf05 3139
6b64503e 3140 my $conf = load_config($vmid);
1e3baf05 3141
6b64503e 3142 check_lock($conf) if !$skiplock;
1e3baf05 3143
ff1a2432
DM
3144 if (!check_running($vmid)) {
3145 fairsched_rmnod($vmid); # try to destroy group
3146 destroy_vm($storecfg, $vmid);
3147 } else {
3148 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
3149 }
3150 });
3151}
3152
1e3baf05
DM
3153# pci helpers
3154
3155sub file_write {
3156 my ($filename, $buf) = @_;
3157
6b64503e 3158 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
3159 return undef if !$fh;
3160
3161 my $res = print $fh $buf;
3162
3163 $fh->close();
3164
3165 return $res;
3166}
3167
3168sub pci_device_info {
3169 my ($name) = @_;
3170
3171 my $res;
3172
3173 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3174 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3175
3176 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
3177 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3178
3179 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
3180 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3181
3182 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
3183 return undef if !defined($product) || $product !~ s/^0x//;
3184
3185 $res = {
3186 name => $name,
3187 vendor => $vendor,
3188 product => $product,
3189 domain => $domain,
3190 bus => $bus,
3191 slot => $slot,
3192 func => $func,
3193 irq => $irq,
3194 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
3195 };
3196
3197 return $res;
3198}
3199
3200sub pci_dev_reset {
3201 my ($dev) = @_;
3202
3203 my $name = $dev->{name};
3204
3205 my $fn = "$pcisysfs/devices/$name/reset";
3206
6b64503e 3207 return file_write($fn, "1");
1e3baf05
DM
3208}
3209
3210sub pci_dev_bind_to_stub {
3211 my ($dev) = @_;
3212
3213 my $name = $dev->{name};
3214
3215 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3216 return 1 if -d $testdir;
3217
3218 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 3219 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
3220
3221 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 3222 if (!file_write($fn, $name)) {
1e3baf05
DM
3223 return undef if -f $fn;
3224 }
3225
3226 $fn = "$pcisysfs/drivers/pci-stub/bind";
3227 if (! -d $testdir) {
6b64503e 3228 return undef if !file_write($fn, $name);
1e3baf05
DM
3229 }
3230
3231 return -d $testdir;
3232}
3233
afdb31d5 3234sub print_pci_addr {
5bdcf937 3235 my ($id, $bridges) = @_;
6b64503e 3236
72a063e4 3237 my $res = '';
6b64503e 3238 my $devices = {
e5f7f8ed
DA
3239 #addr1 : ide,parallel,serial (motherboard)
3240 #addr2 : first videocard
13b5a753 3241 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 3242 watchdog => { bus => 0, addr => 4 },
cdd20088
AD
3243 scsihw0 => { bus => 0, addr => 5 },
3244 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 3245 ahci0 => { bus => 0, addr => 7 },
ab6a046f 3246 qga0 => { bus => 0, addr => 8 },
6b64503e
DM
3247 virtio0 => { bus => 0, addr => 10 },
3248 virtio1 => { bus => 0, addr => 11 },
3249 virtio2 => { bus => 0, addr => 12 },
3250 virtio3 => { bus => 0, addr => 13 },
3251 virtio4 => { bus => 0, addr => 14 },
3252 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
3253 hostpci0 => { bus => 0, addr => 16 },
3254 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
3255 net0 => { bus => 0, addr => 18 },
3256 net1 => { bus => 0, addr => 19 },
3257 net2 => { bus => 0, addr => 20 },
3258 net3 => { bus => 0, addr => 21 },
3259 net4 => { bus => 0, addr => 22 },
3260 net5 => { bus => 0, addr => 23 },
e5f7f8ed 3261 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
3262 'pci.1' => { bus => 0, addr => 30 },
3263 'pci.2' => { bus => 0, addr => 31 },
3264 'net6' => { bus => 1, addr => 1 },
3265 'net7' => { bus => 1, addr => 2 },
3266 'net8' => { bus => 1, addr => 3 },
3267 'net9' => { bus => 1, addr => 4 },
3268 'net10' => { bus => 1, addr => 5 },
3269 'net11' => { bus => 1, addr => 6 },
3270 'net12' => { bus => 1, addr => 7 },
3271 'net13' => { bus => 1, addr => 8 },
3272 'net14' => { bus => 1, addr => 9 },
3273 'net15' => { bus => 1, addr => 10 },
3274 'net16' => { bus => 1, addr => 11 },
3275 'net17' => { bus => 1, addr => 12 },
3276 'net18' => { bus => 1, addr => 13 },
3277 'net19' => { bus => 1, addr => 14 },
3278 'net20' => { bus => 1, addr => 15 },
3279 'net21' => { bus => 1, addr => 16 },
3280 'net22' => { bus => 1, addr => 17 },
3281 'net23' => { bus => 1, addr => 18 },
3282 'net24' => { bus => 1, addr => 19 },
3283 'net25' => { bus => 1, addr => 20 },
3284 'net26' => { bus => 1, addr => 21 },
3285 'net27' => { bus => 1, addr => 22 },
3286 'net28' => { bus => 1, addr => 23 },
3287 'net29' => { bus => 1, addr => 24 },
3288 'net30' => { bus => 1, addr => 25 },
3289 'net31' => { bus => 1, addr => 26 },
3290 'virtio6' => { bus => 2, addr => 1 },
3291 'virtio7' => { bus => 2, addr => 2 },
3292 'virtio8' => { bus => 2, addr => 3 },
3293 'virtio9' => { bus => 2, addr => 4 },
3294 'virtio10' => { bus => 2, addr => 5 },
3295 'virtio11' => { bus => 2, addr => 6 },
3296 'virtio12' => { bus => 2, addr => 7 },
3297 'virtio13' => { bus => 2, addr => 8 },
3298 'virtio14' => { bus => 2, addr => 9 },
3299 'virtio15' => { bus => 2, addr => 10 },
6b64503e
DM
3300 };
3301
3302 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 3303 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
3304 my $bus = $devices->{$id}->{bus};
3305 $res = ",bus=pci.$bus,addr=$addr";
98627641 3306 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
3307 }
3308 return $res;
3309
3310}
3311
13a48620 3312sub vm_balloonset {
7878afeb 3313 my ($vmid, $value) = @_;
13a48620 3314
2d23ddc5 3315 vm_mon_cmd($vmid, "balloon", value => $value);
13a48620
DA
3316}
3317
3e16d5fc
DM
3318# vzdump restore implementaion
3319
3320sub archive_read_firstfile {
3321 my $archive = shift;
afdb31d5 3322
3e16d5fc
DM
3323 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
3324
3325 # try to detect archive type first
3326 my $pid = open (TMP, "tar tf '$archive'|") ||
3327 die "unable to open file '$archive'\n";
3328 my $firstfile = <TMP>;
3329 kill 15, $pid;
3330 close TMP;
3331
3332 die "ERROR: archive contaions no data\n" if !$firstfile;
3333 chomp $firstfile;
3334
3335 return $firstfile;
3336}
3337
3338sub restore_cleanup {
3339 my $statfile = shift;
3340
3341 print STDERR "starting cleanup\n";
3342
3343 if (my $fd = IO::File->new($statfile, "r")) {
3344 while (defined(my $line = <$fd>)) {
3345 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3346 my $volid = $2;
3347 eval {
3348 if ($volid =~ m|^/|) {
3349 unlink $volid || die 'unlink failed\n';
3350 } else {
3351 my $cfg = cfs_read_file('storage.cfg');
3352 PVE::Storage::vdisk_free($cfg, $volid);
3353 }
afdb31d5 3354 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
3355 };
3356 print STDERR "unable to cleanup '$volid' - $@" if $@;
3357 } else {
3358 print STDERR "unable to parse line in statfile - $line";
afdb31d5 3359 }
3e16d5fc
DM
3360 }
3361 $fd->close();
3362 }
3363}
3364
3365sub restore_archive {
a0d1b1a2 3366 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 3367
9c502e26
DM
3368 if ($archive ne '-') {
3369 my $firstfile = archive_read_firstfile($archive);
3370 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3371 if $firstfile ne 'qemu-server.conf';
3372 }
3e16d5fc
DM
3373
3374 my $tocmd = "/usr/lib/qemu-server/qmextract";
3375
2415a446 3376 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 3377 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
3378 $tocmd .= ' --prealloc' if $opts->{prealloc};
3379 $tocmd .= ' --info' if $opts->{info};
3380
a0d1b1a2 3381 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 3382 # so we pipe to zcat
2415a446
DM
3383 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
3384 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
3385
3386 my $tmpdir = "/var/tmp/vzdumptmp$$";
3387 mkpath $tmpdir;
3388
3389 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
3390 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 3391 local $ENV{VZDUMP_USER} = $user;
3e16d5fc
DM
3392
3393 my $conffile = PVE::QemuServer::config_file($vmid);
3394 my $tmpfn = "$conffile.$$.tmp";
3395
3396 # disable interrupts (always do cleanups)
3397 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3398 print STDERR "got interrupt - ignored\n";
3399 };
3400
afdb31d5 3401 eval {
3e16d5fc
DM
3402 # enable interrupts
3403 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
3404 die "interrupted by signal\n";
3405 };
3406
9c502e26
DM
3407 if ($archive eq '-') {
3408 print "extracting archive from STDIN\n";
3409 run_command($cmd, input => "<&STDIN");
3410 } else {
3411 print "extracting archive '$archive'\n";
3412 run_command($cmd);
3413 }
3e16d5fc
DM
3414
3415 return if $opts->{info};
3416
3417 # read new mapping
3418 my $map = {};
3419 my $statfile = "$tmpdir/qmrestore.stat";
3420 if (my $fd = IO::File->new($statfile, "r")) {
3421 while (defined (my $line = <$fd>)) {
3422 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3423 $map->{$1} = $2 if $1;
3424 } else {
3425 print STDERR "unable to parse line in statfile - $line\n";
3426 }
3427 }
3428 $fd->close();
3429 }
3430
3431 my $confsrc = "$tmpdir/qemu-server.conf";
3432
3433 my $srcfd = new IO::File($confsrc, "r") ||
3434 die "unable to open file '$confsrc'\n";
3435
3436 my $outfd = new IO::File ($tmpfn, "w") ||
3437 die "unable to write config for VM $vmid\n";
3438
51586c3a
DM
3439 my $netcount = 0;
3440
3e16d5fc
DM
3441 while (defined (my $line = <$srcfd>)) {
3442 next if $line =~ m/^\#vzdump\#/;
3443 next if $line =~ m/^lock:/;
3444 next if $line =~ m/^unused\d+:/;
3445
51586c3a
DM
3446 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3447 # try to convert old 1.X settings
3448 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3449 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3450 my ($model, $macaddr) = split(/\=/, $devconfig);
3451 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $opts->{unique};
3452 my $net = {
3453 model => $model,
3454 bridge => "vmbr$ind",
3455 macaddr => $macaddr,
3456 };
3457 my $netstr = print_net($net);
3458 print $outfd "net${netcount}: $netstr\n";
3459 $netcount++;
3460 }
3461 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique})) {
3462 my ($id, $netstr) = ($1, $2);
3463 my $net = parse_net($netstr);
3464 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3465 $netstr = print_net($net);
afdb31d5 3466 print $outfd "$id: $netstr\n";
51586c3a 3467 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3e16d5fc
DM
3468 my $virtdev = $1;
3469 my $value = $2;
3470 if ($line =~ m/backup=no/) {
3471 print $outfd "#$line";
3472 } elsif ($virtdev && $map->{$virtdev}) {
3473 my $di = PVE::QemuServer::parse_drive($virtdev, $value);
3474 $di->{file} = $map->{$virtdev};
3475 $value = PVE::QemuServer::print_drive($vmid, $di);
3476 print $outfd "$virtdev: $value\n";
3477 } else {
3478 print $outfd $line;
3479 }
3480 } else {
3481 print $outfd $line;
3482 }
3483 }
3484
3485 $srcfd->close();
3486 $outfd->close();
3487 };
3488 my $err = $@;
3489
afdb31d5 3490 if ($err) {
3e16d5fc
DM
3491
3492 unlink $tmpfn;
3493
3494 restore_cleanup("$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 3495
3e16d5fc 3496 die $err;
afdb31d5 3497 }
3e16d5fc
DM
3498
3499 rmtree $tmpdir;
3500
3501 rename $tmpfn, $conffile ||
3502 die "unable to commit configuration file '$conffile'\n";
3503};
3504
1e3baf05 35051;