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