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