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