]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
undo open-iscsi package dependency
[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',
440 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback] [,format=f] [,backup=yes|no] [,aio=native|threads]',
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',
448 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback] [,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',
456 typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback] [,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
640# a clumsy way to split an argument string into an array,
641# we simply pass it to the cli (exec call)
642# fixme: use Text::ParseWords::shellwords() ?
643sub split_args {
644 my ($str) = @_;
645
646 my $args = [];
647
648 return $args if !$str;
649
650 my $cmd = 'perl -e \'foreach my $a (@ARGV) { print "$a\n"; } \' -- ' . $str;
651
652 eval {
6b64503e 653 run_command($cmd, outfunc => sub {
1e3baf05
DM
654 my $data = shift;
655 push @$args, $data;
656 });
657 };
19672434 658
1e3baf05
DM
659 my $err = $@;
660
661 die "unable to parse args: $str\n" if $err;
662
663 return $args;
664}
665
666sub disk_devive_info {
667 my $dev = shift;
668
669 die "unknown disk device format '$dev'" if $dev !~ m/^(ide|scsi|virtio)(\d+)$/;
670
671 my $bus = $1;
672 my $index = $2;
673 my $maxdev = 1024;
674
675 if ($bus eq 'ide') {
676 $maxdev = 2;
677 } elsif ($bus eq 'scsi') {
f62db2a4 678 $maxdev = 7;
1e3baf05
DM
679 }
680
6b64503e 681 my $controller = int($index / $maxdev);
1e3baf05
DM
682 my $unit = $index % $maxdev;
683
684
685 return { bus => $bus, desc => uc($bus) . " $controller:$unit",
686 controller => $controller, unit => $unit, index => $index };
687
688}
689
690sub qemu_drive_name {
19672434 691 my ($dev, $media) = @_;
1e3baf05 692
6b64503e 693 my $info = disk_devive_info($dev);
1e3baf05
DM
694 my $mediastr = '';
695
696 if (($info->{bus} eq 'ide') || ($info->{bus} eq 'scsi')) {
697 $mediastr = ($media eq 'cdrom') ? "-cd" : "-hd";
19672434 698 return sprintf("%s%i%s%i", $info->{bus}, $info->{controller},
1e3baf05
DM
699 $mediastr, $info->{unit});
700 } else {
19672434 701 return sprintf("%s%i", $info->{bus}, $info->{index});
1e3baf05
DM
702 }
703}
704
705my $cdrom_path;
706
707sub get_cdrom_path {
708
709 return $cdrom_path if $cdrom_path;
710
711 return $cdrom_path = "/dev/cdrom" if -l "/dev/cdrom";
712 return $cdrom_path = "/dev/cdrom1" if -l "/dev/cdrom1";
713 return $cdrom_path = "/dev/cdrom2" if -l "/dev/cdrom2";
714}
715
716sub get_iso_path {
717 my ($storecfg, $vmid, $cdrom) = @_;
718
719 if ($cdrom eq 'cdrom') {
720 return get_cdrom_path();
721 } elsif ($cdrom eq 'none') {
722 return '';
723 } elsif ($cdrom =~ m|^/|) {
724 return $cdrom;
725 } else {
6b64503e 726 return PVE::Storage::path($storecfg, $cdrom);
1e3baf05
DM
727 }
728}
729
730# try to convert old style file names to volume IDs
731sub filename_to_volume_id {
732 my ($vmid, $file, $media) = @_;
733
734 if (!($file eq 'none' || $file eq 'cdrom' ||
735 $file =~ m|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
19672434 736
1e3baf05 737 return undef if $file =~ m|/|;
19672434 738
1e3baf05
DM
739 if ($media && $media eq 'cdrom') {
740 $file = "local:iso/$file";
741 } else {
742 $file = "local:$vmid/$file";
743 }
744 }
745
746 return $file;
747}
748
749sub verify_media_type {
750 my ($opt, $vtype, $media) = @_;
751
752 return if !$media;
753
754 my $etype;
755 if ($media eq 'disk') {
756 $etype = 'image';
757 } elsif ($media eq 'cdrom') {
758 $etype = 'iso';
759 } else {
760 die "internal error";
761 }
762
763 return if ($vtype eq $etype);
19672434 764
1e3baf05
DM
765 raise_param_exc({ $opt => "unexpected media type ($vtype != $etype)" });
766}
767
768sub cleanup_drive_path {
769 my ($opt, $storecfg, $drive) = @_;
770
771 # try to convert filesystem paths to volume IDs
772
773 if (($drive->{file} !~ m/^(cdrom|none)$/) &&
774 ($drive->{file} !~ m|^/dev/.+|) &&
775 ($drive->{file} !~ m/^([^:]+):(.+)$/) &&
19672434 776 ($drive->{file} !~ m/^\d+$/)) {
1e3baf05
DM
777 my ($vtype, $volid) = PVE::Storage::path_to_volume_id($storecfg, $drive->{file});
778 raise_param_exc({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
779 $drive->{media} = 'cdrom' if !$drive->{media} && $vtype eq 'iso';
780 verify_media_type($opt, $vtype, $drive->{media});
781 $drive->{file} = $volid;
782 }
783
784 $drive->{media} = 'cdrom' if !$drive->{media} && $drive->{file} =~ m/^(cdrom|none)$/;
785}
786
787sub create_conf_nolock {
788 my ($vmid, $settings) = @_;
789
6b64503e 790 my $filename = config_file($vmid);
1e3baf05
DM
791
792 die "configuration file '$filename' already exists\n" if -f $filename;
19672434 793
1e3baf05
DM
794 my $defaults = load_defaults();
795
796 $settings->{name} = "vm$vmid" if !$settings->{name};
797 $settings->{memory} = $defaults->{memory} if !$settings->{memory};
798
799 my $data = '';
800 foreach my $opt (keys %$settings) {
801 next if !$confdesc->{$opt};
802
803 my $value = $settings->{$opt};
804 next if !$value;
805
806 $data .= "$opt: $value\n";
807 }
808
809 PVE::Tools::file_set_contents($filename, $data);
810}
811
812# ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
813# [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
814# [,aio=native|threads]
815
816sub parse_drive {
817 my ($key, $data) = @_;
818
819 my $res = {};
19672434 820
1e3baf05
DM
821 # $key may be undefined - used to verify JSON parameters
822 if (!defined($key)) {
823 $res->{interface} = 'unknown'; # should not harm when used to verify parameters
824 $res->{index} = 0;
825 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
826 $res->{interface} = $1;
827 $res->{index} = $2;
828 } else {
829 return undef;
830 }
831
832 foreach my $p (split (/,/, $data)) {
833 next if $p =~ m/^\s*$/;
834
835 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio)=(.+)$/) {
836 my ($k, $v) = ($1, $2);
837
838 $k = 'file' if $k eq 'volume';
839
840 return undef if defined $res->{$k};
19672434 841
1e3baf05
DM
842 $res->{$k} = $v;
843 } else {
844 if (!$res->{file} && $p !~ m/=/) {
845 $res->{file} = $p;
846 } else {
847 return undef;
848 }
849 }
850 }
851
852 return undef if !$res->{file};
853
19672434 854 return undef if $res->{cache} &&
1e3baf05
DM
855 $res->{cache} !~ m/^(off|none|writethrough|writeback)$/;
856 return undef if $res->{snapshot} && $res->{snapshot} !~ m/^(on|off)$/;
857 return undef if $res->{cyls} && $res->{cyls} !~ m/^\d+$/;
858 return undef if $res->{heads} && $res->{heads} !~ m/^\d+$/;
859 return undef if $res->{secs} && $res->{secs} !~ m/^\d+$/;
860 return undef if $res->{media} && $res->{media} !~ m/^(disk|cdrom)$/;
861 return undef if $res->{trans} && $res->{trans} !~ m/^(none|lba|auto)$/;
862 return undef if $res->{format} && $res->{format} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
863 return undef if $res->{rerror} && $res->{rerror} !~ m/^(ignore|report|stop)$/;
864 return undef if $res->{werror} && $res->{werror} !~ m/^(enospc|ignore|report|stop)$/;
865 return undef if $res->{backup} && $res->{backup} !~ m/^(yes|no)$/;
866 return undef if $res->{aio} && $res->{aio} !~ m/^(native|threads)$/;
867
868 if ($res->{media} && ($res->{media} eq 'cdrom')) {
869 return undef if $res->{snapshot} || $res->{trans} || $res->{format};
19672434 870 return undef if $res->{heads} || $res->{secs} || $res->{cyls};
1e3baf05
DM
871 return undef if $res->{interface} eq 'virtio';
872 }
873
874 # rerror does not work with scsi drives
875 if ($res->{rerror}) {
876 return undef if $res->{interface} eq 'scsi';
877 }
878
879 return $res;
880}
881
882my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio);
883
884sub print_drive {
885 my ($vmid, $drive) = @_;
886
887 my $opts = '';
888 foreach my $o (@qemu_drive_options, 'backup') {
889 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
890 }
891
892 return "$drive->{file}$opts";
893}
894
ca916ecc
DA
895sub print_drivedevice_full {
896 my ($storecfg, $vmid, $drive) = @_;
897
898 my $device = '';
899 my $maxdev = 0;
19672434 900
ca916ecc 901 if ($drive->{interface} eq 'virtio') {
6b64503e 902 my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}");
a4dea331 903 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
ca916ecc
DA
904 }
905
906 elsif ($drive->{interface} eq 'scsi') {
907
908 $maxdev = 7;
6b64503e 909 my $controller = int($drive->{index} / $maxdev);
ca916ecc
DA
910 my $unit = $drive->{index} % $maxdev;
911
6b64503e 912 $device = "scsi-disk,bus=scsi$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=device-$drive->{interface}$drive->{index}";
ca916ecc
DA
913 }
914
915 elsif ($drive->{interface} eq 'ide'){
916
917 $maxdev = 2;
6b64503e 918 my $controller = int($drive->{index} / $maxdev);
ca916ecc
DA
919 my $unit = $drive->{index} % $maxdev;
920
6b64503e 921 $device = "ide-drive,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=device-$drive->{interface}$drive->{index}";
ca916ecc
DA
922 }
923
924 if ($drive->{interface} eq 'usb'){
19672434 925 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
ca916ecc
DA
926 }
927
928 return $device;
929}
930
1e3baf05
DM
931sub print_drive_full {
932 my ($storecfg, $vmid, $drive) = @_;
933
934 my $opts = '';
935 foreach my $o (@qemu_drive_options) {
936 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
19672434 937 }
1e3baf05
DM
938
939 # use linux-aio by default (qemu default is threads)
19672434 940 $opts .= ",aio=native" if !$drive->{aio};
1e3baf05
DM
941
942 my $path;
943 my $volid = $drive->{file};
6b64503e
DM
944 if (drive_is_cdrom($drive)) {
945 $path = get_iso_path($storecfg, $vmid, $volid);
1e3baf05
DM
946 } else {
947 if ($volid =~ m|^/|) {
948 $path = $volid;
949 } else {
6b64503e 950 $path = PVE::Storage::path($storecfg, $volid);
1e3baf05
DM
951 }
952 }
953
954 my $pathinfo = $path ? "file=$path," : '';
955
3ebfcc86 956 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1e3baf05
DM
957}
958
959
960sub drive_is_cdrom {
961 my ($drive) = @_;
962
963 return $drive && $drive->{media} && ($drive->{media} eq 'cdrom');
964
965}
966
040b06b7
DA
967sub parse_hostpci {
968 my ($value) = @_;
969
970 return undef if !$value;
971
972 my $res = {};
973
974 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
975 $res->{pciid} = $value;
976 } else {
977 return undef;
978 }
979
980 return $res;
981}
982
1e3baf05
DM
983# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
984sub parse_net {
985 my ($data) = @_;
986
987 my $res = {};
988
6b64503e 989 foreach my $kvp (split(/,/, $data)) {
1e3baf05
DM
990
991 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 992 my $model = lc($1);
9f91ff02 993 my $mac = uc($3) || PVE::Tools::random_ether_addr();
1e3baf05
DM
994 $res->{model} = $model;
995 $res->{macaddr} = $mac;
996 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
997 $res->{bridge} = $1;
998 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
999 $res->{rate} = $1;
1000 } else {
1001 return undef;
1002 }
19672434 1003
1e3baf05
DM
1004 }
1005
1006 return undef if !$res->{model};
1007
1008 return $res;
1009}
1010
1011sub print_net {
1012 my $net = shift;
1013
1014 my $res = "$net->{model}";
1015 $res .= "=$net->{macaddr}" if $net->{macaddr};
1016 $res .= ",bridge=$net->{bridge}" if $net->{bridge};
1017 $res .= ",rate=$net->{rate}" if $net->{rate};
1018
1019 return $res;
1020}
1021
1022sub add_random_macs {
1023 my ($settings) = @_;
1024
1025 foreach my $opt (keys %$settings) {
1026 next if $opt !~ m/^net(\d+)$/;
1027 my $net = parse_net($settings->{$opt});
1028 next if !$net;
1029 $settings->{$opt} = print_net($net);
1030 }
1031}
1032
1033sub add_unused_volume {
1034 my ($config, $res, $volid) = @_;
1035
1036 my $key;
1037 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1038 my $test = "unused$ind";
1039 if (my $vid = $config->{$test}) {
1040 return if $vid eq $volid; # do not add duplicates
1041 } else {
1042 $key = $test;
19672434 1043 }
1e3baf05
DM
1044 }
1045
1046 die "To many unused volume - please delete them first.\n" if !$key;
1047
1048 $res->{$key} = $volid;
1049}
1050
1051# fixme: remove all thos $noerr parameters?
1052
1053PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1054sub verify_bootdisk {
1055 my ($value, $noerr) = @_;
1056
19672434 1057 return $value if valid_drivename($value);
1e3baf05
DM
1058
1059 return undef if $noerr;
1060
1061 die "invalid boot disk '$value'\n";
1062}
1063
1064PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1065sub verify_net {
1066 my ($value, $noerr) = @_;
1067
1068 return $value if parse_net($value);
1069
1070 return undef if $noerr;
19672434 1071
1e3baf05
DM
1072 die "unable to parse network options\n";
1073}
1074
1075PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1076sub verify_drive {
1077 my ($value, $noerr) = @_;
1078
6b64503e 1079 return $value if parse_drive(undef, $value);
1e3baf05
DM
1080
1081 return undef if $noerr;
19672434 1082
1e3baf05
DM
1083 die "unable to parse drive options\n";
1084}
1085
1086PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1087sub verify_hostpci {
1088 my ($value, $noerr) = @_;
1089
040b06b7
DA
1090 return $value if parse_hostpci($value);
1091
1092 return undef if $noerr;
1093
1094 die "unable to parse pci id\n";
1e3baf05
DM
1095}
1096
0ea9541d
DM
1097PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1098sub verify_watchdog {
1099 my ($value, $noerr) = @_;
1100
1101 return $value if parse_watchdog($value);
1102
1103 return undef if $noerr;
19672434 1104
0ea9541d
DM
1105 die "unable to parse watchdog options\n";
1106}
1107
1108sub parse_watchdog {
1109 my ($value) = @_;
1110
1111 return undef if !$value;
1112
1113 my $res = {};
1114
6b64503e 1115 foreach my $p (split(/,/, $value)) {
0ea9541d
DM
1116 next if $p =~ m/^\s*$/;
1117
1118 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1119 $res->{model} = $2;
1120 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1121 $res->{action} = $2;
1122 } else {
1123 return undef;
1124 }
1125 }
1126
1127 return $res;
1128}
1129
1e3baf05
DM
1130sub parse_usb_device {
1131 my ($value) = @_;
1132
1133 return undef if !$value;
1134
6b64503e 1135 my @dl = split(/,/, $value);
1e3baf05
DM
1136 my $found;
1137
1138 my $res = {};
1139 foreach my $v (@dl) {
1140 if ($v =~ m/^host=([0-9A-Fa-f]{4}):([0-9A-Fa-f]{4})$/) {
1141 $found = 1;
1142 $res->{vendorid} = $1;
1143 $res->{productid} = $2;
1144 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1145 $found = 1;
1146 $res->{hostbus} = $1;
1147 $res->{hostport} = $2;
1148 } else {
1149 return undef;
1150 }
1151 }
1152 return undef if !$found;
1153
1154 return $res;
1155}
19672434 1156
1e3baf05
DM
1157PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1158sub verify_usb_device {
1159 my ($value, $noerr) = @_;
1160
1161 return $value if parse_usb_device($value);
1162
1163 return undef if $noerr;
19672434 1164
1e3baf05
DM
1165 die "unable to parse usb device\n";
1166}
1167
1e3baf05
DM
1168# add JSON properties for create and set function
1169sub json_config_properties {
1170 my $prop = shift;
1171
1172 foreach my $opt (keys %$confdesc) {
1173 $prop->{$opt} = $confdesc->{$opt};
1174 }
1175
1176 return $prop;
1177}
1178
1179sub check_type {
1180 my ($key, $value) = @_;
1181
1182 die "unknown setting '$key'\n" if !$confdesc->{$key};
1183
1184 my $type = $confdesc->{$key}->{type};
1185
6b64503e 1186 if (!defined($value)) {
1e3baf05
DM
1187 die "got undefined value\n";
1188 }
1189
1190 if ($value =~ m/[\n\r]/) {
1191 die "property contains a line feed\n";
1192 }
1193
1194 if ($type eq 'boolean') {
19672434
DM
1195 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1196 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1197 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1198 } elsif ($type eq 'integer') {
1199 return int($1) if $value =~ m/^(\d+)$/;
1200 die "type check ('integer') failed - got '$value'\n";
1201 } elsif ($type eq 'string') {
1202 if (my $fmt = $confdesc->{$key}->{format}) {
1203 if ($fmt eq 'pve-qm-drive') {
1204 # special case - we need to pass $key to parse_drive()
6b64503e 1205 my $drive = parse_drive($key, $value);
1e3baf05
DM
1206 return $value if $drive;
1207 die "unable to parse drive options\n";
1208 }
1209 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1210 return $value;
1211 }
1e3baf05 1212 $value =~ s/^\"(.*)\"$/$1/;
19672434 1213 return $value;
1e3baf05
DM
1214 } else {
1215 die "internal error"
1216 }
1217}
1218
1219sub lock_config {
1220 my ($vmid, $code, @param) = @_;
1221
6b64503e 1222 my $filename = config_file_lock($vmid);
1e3baf05 1223
5fdbe4f0 1224 my $res = lock_file($filename, 10, $code, @param);
1e3baf05
DM
1225
1226 die $@ if $@;
5fdbe4f0
DM
1227
1228 return $res;
1e3baf05
DM
1229}
1230
1231sub cfs_config_path {
a78ccf26 1232 my ($vmid, $node) = @_;
1e3baf05 1233
a78ccf26
DM
1234 $node = $nodename if !$node;
1235 return "nodes/$node/qemu-server/$vmid.conf";
1e3baf05
DM
1236}
1237
040b06b7
DA
1238sub check_iommu_support{
1239 #fixme : need to check IOMMU support
1240 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1241
1242 my $iommu=1;
1243 return $iommu;
1244
1245}
1246
1e3baf05 1247sub config_file {
a78ccf26 1248 my ($vmid, $node) = @_;
1e3baf05 1249
a78ccf26 1250 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1251 return "/etc/pve/$cfspath";
1252}
1253
1254sub config_file_lock {
1255 my ($vmid) = @_;
1256
1257 return "$lock_dir/lock-$vmid.conf";
1258}
1259
1260sub touch_config {
1261 my ($vmid) = @_;
1262
6b64503e 1263 my $conf = config_file($vmid);
1e3baf05
DM
1264 utime undef, undef, $conf;
1265}
1266
1267sub create_disks {
f19d1c47 1268 my ($storecfg, $vmid, $settings, $conf) = @_;
1e3baf05
DM
1269
1270 my $vollist = [];
1271
1272 eval {
1273 foreach_drive($settings, sub {
1274 my ($ds, $disk) = @_;
1275
6b64503e 1276 return if drive_is_cdrom($disk);
1e3baf05
DM
1277
1278 my $file = $disk->{file};
1279
1280 if ($file =~ m/^(([^:\s]+):)?(\d+(\.\d+)?)$/) {
1281 my $storeid = $2 || 'local';
1282 my $size = $3;
6b64503e 1283 my $defformat = PVE::Storage::storage_default_format($storecfg, $storeid);
1e3baf05 1284 my $fmt = $disk->{format} || $defformat;
6b64503e 1285 syslog('info', "VM $vmid creating new disk - size is $size GB");
1e3baf05 1286
6b64503e 1287 my $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid,
1e3baf05
DM
1288 $fmt, undef, $size*1024*1024);
1289
1290 $disk->{file} = $volid;
6b64503e 1291 delete $disk->{format}; # no longer needed
1e3baf05 1292 push @$vollist, $volid;
6b64503e 1293 $settings->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
1e3baf05
DM
1294 } else {
1295 my $path;
1296 if ($disk->{file} =~ m|^/dev/.+|) {
1297 $path = $disk->{file};
1298 } else {
6b64503e 1299 $path = PVE::Storage::path($storecfg, $disk->{file});
1e3baf05
DM
1300 }
1301 if (!(-f $path || -b $path)) {
1302 die "image '$path' does not exists\n";
1303 }
1304 }
f19d1c47 1305 PVE::QemuServer::vm_deviceadd($storecfg, $conf, $vmid, $ds, $disk) if defined($conf);
1e3baf05
DM
1306 });
1307 };
1308
1309 my $err = $@;
1310
1311 if ($err) {
6b64503e 1312 syslog('err', "VM $vmid creating disks failed");
1e3baf05 1313 foreach my $volid (@$vollist) {
6b64503e 1314 eval { PVE::Storage::vdisk_free($storecfg, $volid); };
1e3baf05
DM
1315 warn $@ if $@;
1316 }
1317 die $err;
1318 }
1319
1320 return $vollist;
1321}
1322
1323sub unlink_image {
1324 my ($storecfg, $vmid, $volid) = @_;
1325
1326 die "reject to unlink absolute path '$volid'"
1327 if $volid =~ m|^/|;
19672434 1328
6b64503e 1329 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
1e3baf05
DM
1330
1331 die "reject to unlink '$volid' - not owned by this VM"
1332 if !$owner || ($owner != $vmid);
1333
6b64503e 1334 syslog('info', "VM $vmid deleting volume '$volid'");
1e3baf05 1335
6b64503e 1336 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1337
6b64503e 1338 touch_config($vmid);
1e3baf05
DM
1339}
1340
1341sub destroy_vm {
1342 my ($storecfg, $vmid) = @_;
1343
6b64503e 1344 my $conffile = config_file($vmid);
1e3baf05 1345
6b64503e 1346 my $conf = load_config($vmid);
1e3baf05 1347
6b64503e 1348 check_lock($conf);
1e3baf05 1349
19672434 1350 # only remove disks owned by this VM
1e3baf05
DM
1351 foreach_drive($conf, sub {
1352 my ($ds, $drive) = @_;
1353
6b64503e 1354 return if drive_is_cdrom($drive);
1e3baf05
DM
1355
1356 my $volid = $drive->{file};
1357 next if !$volid || $volid =~ m|^/|;
1358
6b64503e 1359 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
1e3baf05
DM
1360 next if !$path || !$owner || ($owner != $vmid);
1361
6b64503e 1362 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1363 });
19672434 1364
1e3baf05
DM
1365 unlink $conffile;
1366
1367 # also remove unused disk
1368 eval {
6b64503e 1369 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
1370
1371 eval {
6b64503e 1372 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 1373 my ($volid, $sid, $volname, $d) = @_;
6b64503e 1374 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
1375 });
1376 };
1377 warn $@ if $@;
1378
1379 };
1380 warn $@ if $@;
1381}
1382
1383# fixme: remove?
1384sub load_diskinfo_old {
1385 my ($storecfg, $vmid, $conf) = @_;
1386
1387 my $info = {};
1388 my $res = {};
1389 my $vollist;
1390
1391 foreach_drive($conf, sub {
1392 my ($ds, $di) = @_;
1393
1394 $res->{$ds} = $di;
1395
6b64503e 1396 return if drive_is_cdrom($di);
1e3baf05
DM
1397
1398 if ($di->{file} =~ m|^/dev/.+|) {
6b64503e 1399 $info->{$di->{file}}->{size} = PVE::Storage::file_size_info($di->{file});
1e3baf05
DM
1400 } else {
1401 push @$vollist, $di->{file};
1402 }
1403 });
1404
1405 eval {
6b64503e 1406 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid, $vollist);
1e3baf05 1407
6b64503e 1408 PVE::Storage::foreach_volid($dl, sub {
1e3baf05
DM
1409 my ($volid, $sid, $volname, $d) = @_;
1410 $info->{$volid} = $d;
1411 });
1412 };
1413 warn $@ if $@;
1414
1415 foreach my $ds (keys %$res) {
1416 my $di = $res->{$ds};
1417
19672434 1418 $res->{$ds}->{disksize} = $info->{$di->{file}} ?
1e3baf05
DM
1419 $info->{$di->{file}}->{size} / (1024*1024) : 0;
1420 }
1421
1422 return $res;
1423}
1424
1425sub load_config {
1426 my ($vmid) = @_;
1427
1428 my $cfspath = cfs_config_path($vmid);
1429
1430 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1431
1432 die "no such VM ('$vmid')\n" if !defined($conf);
1433
1434 return $conf;
19672434 1435}
1e3baf05
DM
1436
1437sub parse_vm_config {
1438 my ($filename, $raw) = @_;
1439
1440 return undef if !defined($raw);
1441
554ac7e7
DM
1442 my $res = {
1443 digest => Digest::SHA1::sha1_hex($raw),
1444 };
1e3baf05 1445
19672434 1446 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1447 || die "got strange filename '$filename'";
1448
1449 my $vmid = $1;
1450
1451 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1452 my $line = $1;
19672434 1453
1e3baf05
DM
1454 next if $line =~ m/^\#/;
1455
1456 next if $line =~ m/^\s*$/;
1457
1458 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1459 my $key = $1;
1460 my $value = PVE::Tools::decode_text($2);
1461 $res->{$key} = $value;
1462 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1463 my $key = $1;
1464 my $value = $2;
1465 $res->{$key} = $value;
1466 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1467 my $key = $1;
1468 my $value = $2;
1469 eval { $value = check_type($key, $value); };
1470 if ($@) {
1471 warn "vm $vmid - unable to parse value of '$key' - $@";
1472 } else {
1473 my $fmt = $confdesc->{$key}->{format};
1474 if ($fmt && $fmt eq 'pve-qm-drive') {
1475 my $v = parse_drive($key, $value);
1476 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1477 $v->{file} = $volid;
6b64503e 1478 $value = print_drive($vmid, $v);
1e3baf05
DM
1479 } else {
1480 warn "vm $vmid - unable to parse value of '$key'\n";
1481 next;
1482 }
1483 }
1484
1485 if ($key eq 'cdrom') {
1486 $res->{ide2} = $value;
1487 } else {
1488 $res->{$key} = $value;
1489 }
1490 }
1491 }
1492 }
1493
1494 # convert old smp to sockets
1495 if ($res->{smp} && !$res->{sockets}) {
1496 $res->{sockets} = $res->{smp};
19672434 1497 }
1e3baf05
DM
1498 delete $res->{smp};
1499
1500 return $res;
1501}
1502
1503sub change_config {
1504 my ($vmid, $settings, $unset, $skiplock) = @_;
1505
6b64503e 1506 lock_config($vmid, &change_config_nolock, $settings, $unset, $skiplock);
1e3baf05
DM
1507}
1508
1509sub change_config_nolock {
1510 my ($vmid, $settings, $unset, $skiplock) = @_;
1511
1512 my $res = {};
1513
1514 $unset->{ide2} = $unset->{cdrom} if $unset->{cdrom};
1515
1516 check_lock($settings) if !$skiplock;
1517
1518 # we do not use 'smp' any longer
1519 if ($settings->{sockets}) {
19672434 1520 $unset->{smp} = 1;
1e3baf05
DM
1521 } elsif ($settings->{smp}) {
1522 $settings->{sockets} = $settings->{smp};
1523 $unset->{smp} = 1;
1524 }
1525
1526 my $new_volids = {};
1527
1528 foreach my $key (keys %$settings) {
554ac7e7 1529 next if $key eq 'digest';
1e3baf05
DM
1530 my $value = $settings->{$key};
1531 if ($key eq 'description') {
1532 $value = PVE::Tools::encode_text($value);
1533 }
1534 eval { $value = check_type($key, $value); };
1535 die "unable to parse value of '$key' - $@" if $@;
1536 if ($key eq 'cdrom') {
1537 $res->{ide2} = $value;
1538 } else {
1539 $res->{$key} = $value;
1540 }
1541 if (valid_drivename($key)) {
1542 my $drive = PVE::QemuServer::parse_drive($key, $value);
1543 $new_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
1544 }
1545 }
1546
1547 my $filename = config_file($vmid);
1548 my $tmpfn = "$filename.$$.tmp";
1549
6b64503e 1550 my $fh = new IO::File($filename, "r") ||
1e3baf05
DM
1551 die "unable to read config for VM $vmid\n";
1552
1553 my $werror = "unable to write config for VM $vmid\n";
1554
6b64503e 1555 my $out = new IO::File($tmpfn, "w") || die $werror;
1e3baf05
DM
1556
1557 eval {
1558
1559 my $done;
1560
1561 while (my $line = <$fh>) {
19672434 1562
1e3baf05
DM
1563 if (($line =~ m/^\#/) || ($line =~ m/^\s*$/)) {
1564 die $werror unless print $out $line;
1565 next;
1566 }
1567
1568 if ($line =~ m/^([a-z][a-z_]*\d*):\s*(.*\S)\s*$/) {
1569 my $key = $1;
1570 my $value = $2;
1571
1572 # remove 'unusedX' settings if we re-add a volume
1573 next if $key =~ m/^unused/ && $new_volids->{$value};
1574
1575 # convert 'smp' to 'sockets'
1576 $key = 'sockets' if $key eq 'smp';
1577
1578 next if $done->{$key};
1579 $done->{$key} = 1;
1580
6b64503e 1581 if (defined($res->{$key})) {
1e3baf05
DM
1582 $value = $res->{$key};
1583 delete $res->{$key};
1584 }
6b64503e 1585 if (!defined($unset->{$key})) {
1e3baf05 1586 die $werror unless print $out "$key: $value\n";
19672434 1587 }
1e3baf05
DM
1588
1589 next;
1590 }
1591
1592 die "unable to parse config file: $line\n";
1593 }
1594
1595 foreach my $key (keys %$res) {
1596
6b64503e 1597 if (!defined($unset->{$key})) {
1e3baf05
DM
1598 die $werror unless print $out "$key: $res->{$key}\n";
1599 }
1600 }
1601 };
1602
1603 my $err = $@;
1604
1605 $fh->close();
1606
1607 if ($err) {
1608 $out->close();
1609 unlink $tmpfn;
1610 die $err;
1611 }
1612
1613 if (!$out->close()) {
1614 $err = "close failed - $!\n";
1615 unlink $tmpfn;
19672434 1616 die $err;
1e3baf05
DM
1617 }
1618
1619 if (!rename($tmpfn, $filename)) {
1620 $err = "rename failed - $!\n";
1621 unlink $tmpfn;
1622 die $err;
1623 }
1624}
1625
19672434 1626sub load_defaults {
1e3baf05
DM
1627
1628 my $res = {};
1629
1630 # we use static defaults from our JSON schema configuration
1631 foreach my $key (keys %$confdesc) {
1632 if (defined(my $default = $confdesc->{$key}->{default})) {
1633 $res->{$key} = $default;
1634 }
1635 }
19672434 1636
1e3baf05
DM
1637 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
1638 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
1639
1640 return $res;
1641}
1642
1643sub config_list {
1644 my $vmlist = PVE::Cluster::get_vmlist();
1645 my $res = {};
1646 return $res if !$vmlist || !$vmlist->{ids};
1647 my $ids = $vmlist->{ids};
1648
1e3baf05
DM
1649 foreach my $vmid (keys %$ids) {
1650 my $d = $ids->{$vmid};
1651 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 1652 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
1653 $res->{$vmid}->{exists} = 1;
1654 }
1655 return $res;
1656}
1657
64e13401
DM
1658# test if VM uses local resources (to prevent migration)
1659sub check_local_resources {
1660 my ($conf, $noerr) = @_;
1661
1662 my $loc_res = 0;
19672434 1663
e0ab7331
DM
1664 $loc_res = 1 if $conf->{hostusb}; # old syntax
1665 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 1666
0d29ab3b 1667 foreach my $k (keys %$conf) {
2fe1a152 1668 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
1669 }
1670
1671 die "VM uses local resources\n" if $loc_res && !$noerr;
1672
1673 return $loc_res;
1674}
1675
1e3baf05
DM
1676sub check_lock {
1677 my ($conf) = @_;
1678
1679 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1680}
1681
1682sub check_cmdline {
1683 my ($pidfile, $pid) = @_;
1684
6b64503e
DM
1685 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
1686 if (defined($fh)) {
1e3baf05
DM
1687 my $line = <$fh>;
1688 $fh->close;
1689 return undef if !$line;
6b64503e 1690 my @param = split(/\0/, $line);
1e3baf05
DM
1691
1692 my $cmd = $param[0];
1693 return if !$cmd || ($cmd !~ m|kvm$|);
1694
1695 for (my $i = 0; $i < scalar (@param); $i++) {
1696 my $p = $param[$i];
1697 next if !$p;
1698 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1699 my $p = $param[$i+1];
1700 return 1 if $p && ($p eq $pidfile);
1701 return undef;
1702 }
1703 }
1704 }
1705 return undef;
1706}
1707
1708sub check_running {
e6c3b671 1709 my ($vmid, $nocheck) = @_;
1e3baf05 1710
e6c3b671 1711 my $filename = config_file($vmid);
1e3baf05
DM
1712
1713 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 1714 if !$nocheck && ! -f $filename;
1e3baf05 1715
e6c3b671 1716 my $pidfile = pidfile_name($vmid);
1e3baf05 1717
e6c3b671
DM
1718 if (my $fd = IO::File->new("<$pidfile")) {
1719 my $st = stat($fd);
1e3baf05 1720 my $line = <$fd>;
6b64503e 1721 close($fd);
1e3baf05
DM
1722
1723 my $mtime = $st->mtime;
1724 if ($mtime > time()) {
1725 warn "file '$filename' modified in future\n";
1726 }
1727
1728 if ($line =~ m/^(\d+)$/) {
1729 my $pid = $1;
e6c3b671
DM
1730 if (check_cmdline($pidfile, $pid)) {
1731 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
1732 return $pid;
1733 }
1734 }
1e3baf05
DM
1735 }
1736 }
1737
1738 return undef;
1739}
1740
1741sub vzlist {
19672434 1742
1e3baf05
DM
1743 my $vzlist = config_list();
1744
6b64503e 1745 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 1746
19672434 1747 while (defined(my $de = $fd->read)) {
1e3baf05
DM
1748 next if $de !~ m/^(\d+)\.pid$/;
1749 my $vmid = $1;
6b64503e
DM
1750 next if !defined($vzlist->{$vmid});
1751 if (my $pid = check_running($vmid)) {
1e3baf05
DM
1752 $vzlist->{$vmid}->{pid} = $pid;
1753 }
1754 }
1755
1756 return $vzlist;
1757}
1758
1759my $storage_timeout_hash = {};
1760
1761sub disksize {
1762 my ($storecfg, $conf) = @_;
1763
1764 my $bootdisk = $conf->{bootdisk};
1765 return undef if !$bootdisk;
1766 return undef if !valid_drivename($bootdisk);
1767
1768 return undef if !$conf->{$bootdisk};
1769
1770 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
1771 return undef if !defined($drive);
1772
1773 return undef if drive_is_cdrom($drive);
1774
1775 my $volid = $drive->{file};
1776 return undef if !$volid;
1777
1778 my $path;
1779 my $storeid;
1780 my $timeoutid;
1781
1782 if ($volid =~ m|^/|) {
1783 $path = $timeoutid = $volid;
1784 } else {
6b64503e 1785 $storeid = $timeoutid = PVE::Storage::parse_volume_id($volid);
1e3baf05
DM
1786 $path = PVE::Storage::path($storecfg, $volid);
1787 }
1788
1789 my $last_timeout = $storage_timeout_hash->{$timeoutid};
1790 if ($last_timeout) {
1791 if ((time() - $last_timeout) < 30) {
1792 # skip storage with errors
1793 return undef ;
1794 }
1795 delete $storage_timeout_hash->{$timeoutid};
1796 }
1797
1798 my ($size, $format, $used);
1799
1800 ($size, $format, $used) = PVE::Storage::file_size_info($path, 1);
1801
1802 if (!defined($format)) {
1803 # got timeout
1804 $storage_timeout_hash->{$timeoutid} = time();
1805 return undef;
1806 }
1807
1808 return wantarray ? ($size, $used) : $size;
1809}
1810
1811my $last_proc_pid_stat;
1812
1813sub vmstatus {
1814 my ($opt_vmid) = @_;
1815
1816 my $res = {};
1817
19672434 1818 my $storecfg = PVE::Storage::config();
1e3baf05
DM
1819
1820 my $list = vzlist();
694fcad4 1821 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05
DM
1822
1823 foreach my $vmid (keys %$list) {
1824 next if $opt_vmid && ($vmid ne $opt_vmid);
1825
1826 my $cfspath = cfs_config_path($vmid);
1827 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
1828
1829 my $d = {};
1830 $d->{pid} = $list->{$vmid}->{pid};
1831
1832 # fixme: better status?
1833 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
1834
1835 my ($size, $used) = disksize($storecfg, $conf);
1836 if (defined($size) && defined($used)) {
1837 $d->{disk} = $used;
1838 $d->{maxdisk} = $size;
1839 } else {
1840 $d->{disk} = 0;
1841 $d->{maxdisk} = 0;
1842 }
1843
1844 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
1845 $d->{name} = $conf->{name} || "VM $vmid";
19672434 1846 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 1847
1e3baf05
DM
1848 $d->{uptime} = 0;
1849 $d->{cpu} = 0;
1850 $d->{relcpu} = 0;
1851 $d->{mem} = 0;
1852
1853 $d->{netout} = 0;
1854 $d->{netin} = 0;
1855
1856 $d->{diskread} = 0;
1857 $d->{diskwrite} = 0;
1858
1859 $res->{$vmid} = $d;
1860 }
1861
1862 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
1863 foreach my $dev (keys %$netdev) {
1864 next if $dev !~ m/^tap([1-9]\d*)i/;
1865 my $vmid = $1;
1866 my $d = $res->{$vmid};
1867 next if !$d;
19672434 1868
1e3baf05
DM
1869 $d->{netout} += $netdev->{$dev}->{receive};
1870 $d->{netin} += $netdev->{$dev}->{transmit};
1871 }
1872
1e3baf05
DM
1873 my $cpucount = $cpuinfo->{cpus} || 1;
1874 my $ctime = gettimeofday;
1875
1876 foreach my $vmid (keys %$list) {
1877
1878 my $d = $res->{$vmid};
1879 my $pid = $d->{pid};
1880 next if !$pid;
1881
1882 if (my $fh = IO::File->new("/proc/$pid/io", "r")) {
1883 my $data = {};
6b64503e 1884 while (defined(my $line = <$fh>)) {
1e3baf05
DM
1885 if ($line =~ m/^([rw]char):\s+(\d+)$/) {
1886 $data->{$1} = $2;
1887 }
1888 }
1889 close($fh);
1890 $d->{diskread} = $data->{rchar} || 0;
1891 $d->{diskwrite} = $data->{wchar} || 0;
1892 }
1893
694fcad4
DM
1894 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
1895 next if !$pstat; # not running
19672434 1896
694fcad4 1897 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05
DM
1898
1899 my $vcpus = $d->{cpus} > $cpucount ? $cpucount : $d->{cpus};
1900
694fcad4 1901 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 1902
694fcad4 1903 if ($pstat->{vsize}) {
6b64503e 1904 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
1905 }
1906
1907 my $old = $last_proc_pid_stat->{$pid};
1908 if (!$old) {
19672434
DM
1909 $last_proc_pid_stat->{$pid} = {
1910 time => $ctime,
1e3baf05
DM
1911 used => $used,
1912 cpu => 0,
1913 relcpu => 0,
1914 };
1915 next;
1916 }
1917
7f0b5beb 1918 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
1919
1920 if ($dtime > 1000) {
1921 my $dutime = $used - $old->{used};
1922
1923 $d->{cpu} = $dutime/$dtime;
1924 $d->{relcpu} = ($d->{cpu} * $cpucount) / $vcpus;
1925 $last_proc_pid_stat->{$pid} = {
19672434 1926 time => $ctime,
1e3baf05
DM
1927 used => $used,
1928 cpu => $d->{cpu},
1929 relcpu => $d->{relcpu},
1930 };
1931 } else {
1932 $d->{cpu} = $old->{cpu};
1933 $d->{relcpu} = $old->{relcpu};
1934 }
1935 }
1936
1937 return $res;
1938}
1939
1940sub foreach_drive {
1941 my ($conf, $func) = @_;
1942
1943 foreach my $ds (keys %$conf) {
1944 next if !valid_drivename($ds);
1945
6b64503e 1946 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
1947 next if !$drive;
1948
1949 &$func($ds, $drive);
1950 }
1951}
1952
1953sub config_to_command {
1954 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
1955
1956 my $cmd = [];
b78ebef7 1957 my $pciaddr = '';
1e3baf05
DM
1958 my $kvmver = kvm_user_version();
1959 my $vernum = 0; # unknown
1960 if ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1961 $vernum = $1*1000000+$2*1000+$3;
1962 }
1963
1964 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 14000;
1965
1966 my $have_ovz = -f '/proc/vz/vestat';
1967
1968 push @$cmd, '/usr/bin/kvm';
1969
1970 push @$cmd, '-id', $vmid;
1971
1972 my $use_virtio = 0;
1973
6b64503e 1974 my $socket = monitor_socket($vmid);
abb39b66
DA
1975 push @$cmd, '-chardev', "socket,id=monitor,path=$socket,server,nowait";
1976 push @$cmd, '-mon', "chardev=monitor,mode=readline";
1e3baf05 1977
6b64503e 1978 $socket = vnc_socket($vmid);
1e3baf05
DM
1979 push @$cmd, '-vnc', "unix:$socket,x509,password";
1980
6b64503e 1981 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 1982
1e3baf05
DM
1983 push @$cmd, '-daemonize';
1984
1985 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
1986
1987 # include usb device config
1988 push @$cmd, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg';
19672434 1989
1e3baf05 1990 # enable absolute mouse coordinates (needed by vnc)
6b64503e 1991 my $tablet = defined($conf->{tablet}) ? $conf->{tablet} : $defaults->{tablet};
1e3baf05
DM
1992 push @$cmd, '-device', 'usb-tablet,bus=ehci.0,port=6' if $tablet;
1993
1994 # host pci devices
040b06b7
DA
1995 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
1996 my $d = parse_hostpci($conf->{"hostpci$i"});
1997 next if !$d;
b78ebef7
DA
1998 $pciaddr = print_pci_addr("hostpci$i");
1999 push @$cmd, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
1e3baf05
DM
2000 }
2001
2002 # usb devices
2003 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2004 my $d = parse_usb_device($conf->{"usb$i"});
2005 next if !$d;
2006 if ($d->{vendorid} && $d->{productid}) {
2007 push @$cmd, '-device', "usb-host,vendorid=$d->{vendorid},productid=$d->{productid}";
2008 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
2009 push @$cmd, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2010 }
2011 }
2012
1e3baf05 2013 # serial devices
bae179aa 2014 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2015 if (my $path = $conf->{"serial$i"}) {
19672434 2016 die "no such serial device\n" if ! -c $path;
34978be3
DM
2017 push @$cmd, '-chardev', "tty,id=serial$i,path=$path";
2018 push @$cmd, '-device', "isa-serial,chardev=serial$i";
2019 }
1e3baf05
DM
2020 }
2021
2022 # parallel devices
1989a89c 2023 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2024 if (my $path = $conf->{"parallel$i"}) {
19672434 2025 die "no such parallel device\n" if ! -c $path;
34978be3
DM
2026 push @$cmd, '-chardev', "parport,id=parallel$i,path=$path";
2027 push @$cmd, '-device', "isa-parallel,chardev=parallel$i";
2028 }
1e3baf05
DM
2029 }
2030
2031 my $vmname = $conf->{name} || "vm$vmid";
2032
2033 push @$cmd, '-name', $vmname;
19672434 2034
1e3baf05
DM
2035 my $sockets = 1;
2036 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2037 $sockets = $conf->{sockets} if $conf->{sockets};
2038
2039 my $cores = $conf->{cores} || 1;
2040
2041 my $boot_opt;
2042
2043 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2044
2045 push @$cmd, '-cpu', $conf->{cpu} if $conf->{cpu};
2046
1e3baf05
DM
2047 push @$cmd, '-nodefaults';
2048
32baffb4
DM
2049 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
2050 push @$cmd, '-boot', "menu=on,order=$bootorder";
1e3baf05 2051
6b64503e 2052 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2053
6b64503e 2054 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05
DM
2055
2056 my $vga = $conf->{vga};
2057 if (!$vga) {
2058 if ($conf->{ostype} && ($conf->{ostype} eq 'win7' || $conf->{ostype} eq 'w2k8')) {
2059 $vga = 'std';
2060 } else {
2061 $vga = 'cirrus';
2062 }
2063 }
19672434 2064
1e3baf05
DM
2065 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2066
2067 # time drift fix
6b64503e 2068 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05
DM
2069 push @$cmd, '-tdf' if $tdf;
2070
6b64503e 2071 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
1e3baf05
DM
2072
2073 if (my $ost = $conf->{ostype}) {
2074 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2075
2076 if ($ost =~ m/^w/) { # windows
6b64503e 2077 push @$cmd, '-localtime' if !defined($conf->{localtime});
1e3baf05
DM
2078
2079 # use rtc-td-hack when acpi is enabled
6b64503e 2080 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
1e3baf05
DM
2081 push @$cmd, '-rtc-td-hack';
2082 }
2083 }
2084
2085 # -tdf ?
19672434
DM
2086 # -no-acpi
2087 # -no-kvm
1e3baf05
DM
2088 # -win2k-hack ?
2089 }
2090
7f0b5beb
DM
2091 if ($nokvm) {
2092 push @$cmd, '-no-kvm';
2093 } else {
2094 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2095 }
1e3baf05
DM
2096
2097 push @$cmd, '-localtime' if $conf->{localtime};
2098
2099 push @$cmd, '-startdate', $conf->{startdate} if $conf->{startdate};
2100
2101 push @$cmd, '-S' if $conf->{freeze};
2102
2103 # set keyboard layout
2104 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2105 push @$cmd, '-k', $kb if $kb;
2106
2107 # enable sound
2108 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2109 #push @$cmd, '-soundhw', 'es1370';
2110 #push @$cmd, '-soundhw', $soundhw if $soundhw;
b78ebef7 2111 $pciaddr = print_pci_addr("balloon0");
13b5a753 2112 push @$cmd, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon};
1e3baf05 2113
0ea9541d
DM
2114 if ($conf->{watchdog}) {
2115 my $wdopts = parse_watchdog($conf->{watchdog});
0a40e8ea
DA
2116 $pciaddr = print_pci_addr("watchdog");
2117 my $watchdog = $wdopts->{model} || 'i6300esb';
2118 push @$cmd, '-device', "$watchdog$pciaddr";
0ea9541d
DM
2119 push @$cmd, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
2120 }
2121
1e3baf05 2122 my $vollist = [];
941e0c42 2123 my $scsicontroller = {};
1e3baf05
DM
2124
2125 foreach_drive($conf, sub {
2126 my ($ds, $drive) = @_;
2127
19672434 2128 eval {
6b64503e 2129 PVE::Storage::parse_volume_id($drive->{file});
1e3baf05
DM
2130 push @$vollist, $drive->{file};
2131 }; # ignore errors
2132
2133 $use_virtio = 1 if $ds =~ m/^virtio/;
941e0c42
DA
2134 if ($drive->{interface} eq 'scsi') {
2135 my $maxdev = 7;
6b64503e 2136 my $controller = int($drive->{index} / $maxdev);
4513fd83
DA
2137 $pciaddr = print_pci_addr("scsi$controller");
2138 push @$cmd, '-device', "lsi,id=scsi$controller$pciaddr" if !$scsicontroller->{$controller};
941e0c42
DA
2139 my $scsicontroller->{$controller}=1;
2140 }
6b64503e 2141 my $tmp = print_drive_full($storecfg, $vmid, $drive);
1e3baf05
DM
2142 $tmp .= ",boot=on" if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2143 push @$cmd, '-drive', $tmp;
6b64503e 2144 push @$cmd, '-device',print_drivedevice_full($storecfg,$vmid, $drive);
1e3baf05
DM
2145 });
2146
2147 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2148
1e3baf05
DM
2149 my $foundnet = 0;
2150
2151 foreach my $k (sort keys %$conf) {
2152 next if $k !~ m/^net(\d+)$/;
6b64503e 2153 my $i = int($1);
1e3baf05
DM
2154
2155 die "got strange net id '$i'\n" if $i >= ${MAX_NETS};
2156
2157 if ($conf->{"net$i"} && (my $net = parse_net($conf->{"net$i"}))) {
2158
2159 $foundnet = 1;
2160
2161 my $ifname = "tap${vmid}i$i";
2162
2163 # kvm uses TUNSETIFF ioctl, and that limits ifname length
19672434 2164 die "interface name '$ifname' is too long (max 15 character)\n"
1e3baf05
DM
2165 if length($ifname) >= 16;
2166
2167 my $device = $net->{model};
2168 my $vhostparam = '';
2169 if ($net->{model} eq 'virtio') {
2170 $use_virtio = 1;
2171 $device = 'virtio-net-pci';
2172 $vhostparam = ',vhost=on' if $kernel_has_vhost_net;
2173 };
2174
2175 if ($net->{bridge}) {
2176 push @$cmd, '-netdev', "type=tap,id=${k},ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
2177 } else {
2178 push @$cmd, '-netdev', "type=user,id=${k},hostname=$vmname";
2179 }
2180
2181 # qemu > 0.15 always try to boot from network - we disable that by
2182 # not loading the pxe rom file
2183 my $extra = (!$conf->{boot} || ($conf->{boot} !~ m/n/)) ?
2184 "romfile=," : '';
f290f8d9
DA
2185 $pciaddr = print_pci_addr("${k}");
2186 push @$cmd, '-device', "$device,${extra}mac=$net->{macaddr},netdev=${k}$pciaddr";
1e3baf05 2187 }
19672434
DM
2188 }
2189
1e3baf05
DM
2190 push @$cmd, '-net', 'none' if !$foundnet;
2191
2192 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2193 # when the VM uses virtio devices.
19672434
DM
2194 if (!$use_virtio && $have_ovz) {
2195
6b64503e 2196 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2197 $conf->{cpuunits} : $defaults->{cpuunits};
2198
2199 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2200
2201 # fixme: cpulimit is currently ignored
2202 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2203 }
2204
2205 # add custom args
2206 if ($conf->{args}) {
6b64503e 2207 my $aa = split_args($conf->{args});
1e3baf05
DM
2208 push @$cmd, @$aa;
2209 }
2210
2211 return wantarray ? ($cmd, $vollist) : $cmd;
2212}
19672434 2213
1e3baf05
DM
2214sub vnc_socket {
2215 my ($vmid) = @_;
2216 return "${var_run_tmpdir}/$vmid.vnc";
2217}
2218
2219sub monitor_socket {
2220 my ($vmid) = @_;
2221 return "${var_run_tmpdir}/$vmid.mon";
2222}
2223
2224sub pidfile_name {
2225 my ($vmid) = @_;
2226 return "${var_run_tmpdir}/$vmid.pid";
2227}
2228
1e3baf05
DM
2229sub next_migrate_port {
2230
2231 for (my $p = 60000; $p < 60010; $p++) {
2232
6b64503e
DM
2233 my $sock = IO::Socket::INET->new(Listen => 5,
2234 LocalAddr => 'localhost',
2235 LocalPort => $p,
2236 ReuseAddr => 1,
2237 Proto => 0);
1e3baf05
DM
2238
2239 if ($sock) {
6b64503e 2240 close($sock);
1e3baf05
DM
2241 return $p;
2242 }
2243 }
2244
2245 die "unable to find free migration port";
2246}
2247
86fdcfb2
DA
2248sub vm_devices_list {
2249 my ($vmid) = @_;
2250
1dc4f496
DM
2251 my $res = vm_monitor_command ($vmid, "info pci", 1);
2252
2253 my @lines = split ("\n", $res);
2254 my $devices;
2255 my $bus;
2256 my $addr;
2257 my $id;
2258
2259 foreach my $line (@lines) {
2260 $line =~ s/^\s+//;
2261 if ($line =~ m/^Bus (\d+), device (\d+), function (\d+):$/) {
2262 $bus=$1;
2263 $addr=$2;
2264 }
2265 if ($line =~ m/^id "([a-z][a-z_\-]*\d*)"$/) {
86fdcfb2
DA
2266 $id=$1;
2267 $devices->{$id}->{bus}=$bus;
2268 $devices->{$id}->{addr}=$addr;
1dc4f496
DM
2269 }
2270 }
86fdcfb2 2271
1dc4f496 2272 return $devices;
86fdcfb2
DA
2273}
2274
a4dea331 2275sub vm_deviceadd {
f19d1c47
DA
2276 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2277 return if !check_running($vmid) || !$conf->{hotplug} || $conf->{$deviceid};
2278
a4dea331
DA
2279 if($deviceid =~ m/^(virtio)(\d+)$/) {
2280
1dc4f496 2281 my $drive = print_drive_full($storecfg, $vmid, $device);
f19d1c47
DA
2282 my $ret = vm_monitor_command($vmid, "drive_add auto $drive", 1);
2283 # If the command succeeds qemu prints: "OK"
2284 if ($ret !~ m/OK/s) {
2285 die "adding drive failed: $ret";
2286 }
2287
1dc4f496 2288 my $devicefull = print_drivedevice_full($storecfg, $vmid, $device);
f19d1c47
DA
2289 $ret = vm_monitor_command($vmid, "device_add $devicefull", 1);
2290 $ret =~ s/^\s+//;
2291 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2292 die 'error on hotplug device : $ret' if $ret ne "";
a4dea331
DA
2293 }
2294
f19d1c47
DA
2295 for (my $i = 0; $i <= 5; $i++) {
2296 my $devices_list = vm_devices_list($vmid);
2297 return if defined($devices_list->{$deviceid});
2298 sleep 1;
2299 }
2300
2301 die "error on hotplug device $deviceid";
a4dea331
DA
2302}
2303
873c2d69 2304sub vm_devicedel {
f19d1c47 2305 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2306
e8b9c17c 2307 return if !check_running ($vmid) || !$conf->{hotplug};
873c2d69 2308
f19d1c47
DA
2309 die "can't unplug bootdisk" if $conf->{bootdisk} eq $deviceid;
2310
873c2d69
DA
2311 if($deviceid =~ m/^(virtio)(\d+)$/){
2312
f19d1c47
DA
2313 my $ret = vm_monitor_command($vmid, "drive_del drive-$deviceid", 1);
2314 $ret =~ s/^\s+//;
2315 if ($ret =~ m/Device \'.*?\' not found/s) {
2316 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2317 }
2318 elsif ($ret ne "") {
2319 die "deleting drive $deviceid failed : $ret";
2320 }
2321
2322 $ret = vm_monitor_command($vmid, "device_del $deviceid", 1);
2323 $ret =~ s/^\s+//;
2324 die 'detaching device $deviceid failed : $ret' if $ret ne "";
2325
2326 }
873c2d69 2327
f19d1c47
DA
2328 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2329 for (my $i = 0; $i <= 5; $i++) {
2330 my $devices_list = vm_devices_list($vmid);
2331 return if !defined($devices_list->{$deviceid});
2332 sleep 1;
873c2d69 2333 }
f19d1c47
DA
2334 die "error on hot-plugging device $deviceid";
2335
873c2d69 2336
873c2d69
DA
2337}
2338
1e3baf05
DM
2339sub vm_start {
2340 my ($storecfg, $vmid, $statefile, $skiplock) = @_;
2341
6b64503e
DM
2342 lock_config($vmid, sub {
2343 my $conf = load_config($vmid);
1e3baf05 2344
6b64503e 2345 check_lock($conf) if !$skiplock;
1e3baf05 2346
6b64503e 2347 if (check_running($vmid)) {
1e3baf05 2348 my $msg = "VM $vmid already running - start failed\n" ;
6b64503e 2349 syslog('err', $msg);
1e3baf05
DM
2350 die $msg;
2351 } else {
6b64503e 2352 syslog('info', "VM $vmid start");
1e3baf05
DM
2353 }
2354
2355 my $migrate_uri;
2356 my $migrate_port = 0;
2357
2358 if ($statefile) {
2359 if ($statefile eq 'tcp') {
2360 $migrate_port = next_migrate_port();
2361 $migrate_uri = "tcp:localhost:${migrate_port}";
2362 } else {
2363 if (-f $statefile) {
2364 $migrate_uri = "exec:cat $statefile";
2365 } else {
2366 warn "state file '$statefile' does not exist - doing normal startup\n";
2367 }
2368 }
2369 }
2370
2371 my $defaults = load_defaults();
2372
e6c3b671 2373 my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults, $migrate_uri);
1e3baf05 2374 # host pci devices
040b06b7
DA
2375 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2376 my $d = parse_hostpci($conf->{"hostpci$i"});
2377 next if !$d;
2378 my $info = pci_device_info("0000:$d->{pciid}");
2379 die "IOMMU not present\n" if !check_iommu_support();
2380 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2381 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
2382 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
2383 }
1e3baf05
DM
2384
2385 PVE::Storage::activate_volumes($storecfg, $vollist);
2386
6b64503e 2387 eval { run_command($cmd, timeout => $migrate_uri ? undef : 30); };
1e3baf05
DM
2388
2389 my $err = $@;
2390
2391 if ($err) {
2392 my $msg = "start failed: $err";
6b64503e 2393 syslog('err', "VM $vmid $msg");
1e3baf05
DM
2394 die $msg;
2395 }
2396
2397 if ($statefile) {
2398
2399 if ($statefile eq 'tcp') {
2400 print "migration listens on port $migrate_port\n";
2401 } else {
2402 unlink $statefile;
2403 # fixme: send resume - is that necessary ?
6b64503e 2404 eval { vm_monitor_command($vmid, "cont", 1) };
1e3baf05
DM
2405 }
2406 }
2407
19672434 2408 if (my $migrate_speed =
1e3baf05
DM
2409 $conf->{migrate_speed} || $defaults->{migrate_speed}) {
2410 my $cmd = "migrate_set_speed ${migrate_speed}m";
6b64503e 2411 eval { vm_monitor_command($vmid, $cmd, 1); };
1e3baf05
DM
2412 }
2413
19672434 2414 if (my $migrate_downtime =
1e3baf05
DM
2415 $conf->{migrate_downtime} || $defaults->{migrate_downtime}) {
2416 my $cmd = "migrate_set_downtime ${migrate_downtime}";
6b64503e 2417 eval { vm_monitor_command($vmid, $cmd, 1); };
1e3baf05 2418 }
e6c3b671 2419
7878afeb 2420 vm_balloonset($vmid, $conf->{balloon}) if $conf->{balloon};
1e3baf05
DM
2421 });
2422}
2423
2424sub __read_avail {
2425 my ($fh, $timeout) = @_;
2426
2427 my $sel = new IO::Select;
6b64503e 2428 $sel->add($fh);
1e3baf05
DM
2429
2430 my $res = '';
2431 my $buf;
2432
2433 my @ready;
6b64503e 2434 while (scalar (@ready = $sel->can_read($timeout))) {
1e3baf05 2435 my $count;
6b64503e 2436 if ($count = $fh->sysread($buf, 8192)) {
1e3baf05
DM
2437 if ($buf =~ /^(.*)\(qemu\) $/s) {
2438 $res .= $1;
2439 last;
2440 } else {
2441 $res .= $buf;
2442 }
2443 } else {
6b64503e 2444 if (!defined($count)) {
1e3baf05
DM
2445 die "$!\n";
2446 }
2447 last;
2448 }
2449 }
2450
6b64503e 2451 die "monitor read timeout\n" if !scalar(@ready);
1e3baf05
DM
2452
2453 return $res;
2454}
2455
2456sub vm_monitor_command {
e6c3b671 2457 my ($vmid, $cmdstr, $nolog, $nocheck) = @_;
1e3baf05
DM
2458
2459 my $res;
2460
6b64503e 2461 syslog("info", "VM $vmid monitor command '$cmdstr'") if !$nolog;
1e3baf05
DM
2462
2463 eval {
e6c3b671 2464 die "VM not running\n" if !check_running($vmid, $nocheck);
1e3baf05 2465
e6c3b671 2466 my $sname = monitor_socket($vmid);
1e3baf05 2467
6b64503e 2468 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
1e3baf05
DM
2469 die "unable to connect to VM $vmid socket - $!\n";
2470
2471 my $timeout = 3;
2472
19672434 2473 # hack: migrate sometime blocks the monitor (when migrate_downtime
1e3baf05
DM
2474 # is set)
2475 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2476 $timeout = 60*60; # 1 hour
2477 }
2478
2479 # read banner;
6b64503e 2480 my $data = __read_avail($sock, $timeout);
19672434 2481
1e3baf05
DM
2482 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2483 die "got unexpected qemu monitor banner\n";
2484 }
2485
2486 my $sel = new IO::Select;
6b64503e 2487 $sel->add($sock);
1e3baf05 2488
6b64503e 2489 if (!scalar(my @ready = $sel->can_write($timeout))) {
1e3baf05
DM
2490 die "monitor write error - timeout";
2491 }
2492
2493 my $fullcmd = "$cmdstr\r";
2494
2495 my $b;
6b64503e 2496 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
1e3baf05
DM
2497 die "monitor write error - $!";
2498 }
2499
2500 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2501
19672434 2502 $timeout = 20;
1e3baf05
DM
2503
2504 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2505 $timeout = 60*60; # 1 hour
2506 } elsif ($cmdstr =~ m/^(eject|change)/) {
2507 $timeout = 60; # note: cdrom mount command is slow
2508 }
6b64503e 2509 if ($res = __read_avail($sock, $timeout)) {
19672434 2510
6b64503e 2511 my @lines = split("\r?\n", $res);
1e3baf05
DM
2512
2513 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
19672434 2514
6b64503e 2515 $res = join("\n", @lines);
1e3baf05
DM
2516 $res .= "\n";
2517 }
2518 };
2519
2520 my $err = $@;
2521
2522 if ($err) {
6b64503e 2523 syslog("err", "VM $vmid monitor command failed - $err");
1e3baf05
DM
2524 die $err;
2525 }
2526
2527 return $res;
2528}
2529
2530sub vm_commandline {
2531 my ($storecfg, $vmid) = @_;
2532
6b64503e 2533 my $conf = load_config($vmid);
1e3baf05
DM
2534
2535 my $defaults = load_defaults();
2536
6b64503e 2537 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 2538
6b64503e 2539 return join(' ', @$cmd);
1e3baf05
DM
2540}
2541
2542sub vm_reset {
2543 my ($vmid, $skiplock) = @_;
2544
6b64503e 2545 lock_config($vmid, sub {
1e3baf05 2546
6b64503e 2547 my $conf = load_config($vmid);
1e3baf05 2548
6b64503e 2549 check_lock($conf) if !$skiplock;
1e3baf05 2550
6b64503e 2551 syslog("info", "VM $vmid sending 'reset'");
1e3baf05 2552
6b64503e 2553 vm_monitor_command($vmid, "system_reset", 1);
1e3baf05
DM
2554 });
2555}
2556
2557sub vm_shutdown {
2558 my ($vmid, $skiplock) = @_;
2559
6b64503e 2560 lock_config($vmid, sub {
1e3baf05 2561
6b64503e 2562 my $conf = load_config($vmid);
1e3baf05 2563
6b64503e 2564 check_lock($conf) if !$skiplock;
1e3baf05 2565
6b64503e 2566 syslog("info", "VM $vmid sending 'shutdown'");
1e3baf05 2567
6b64503e 2568 vm_monitor_command($vmid, "system_powerdown", 1);
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 {
e6c3b671 2575 my ($vmid, $skiplock, $nocheck) = @_;
1e3baf05 2576
e6c3b671 2577 lock_config($vmid, sub {
1e3baf05 2578
e6c3b671 2579 my $pid = check_running($vmid, $nocheck);
1e3baf05
DM
2580
2581 if (!$pid) {
e6c3b671 2582 syslog('info', "VM $vmid already stopped");
1e3baf05
DM
2583 return;
2584 }
2585
e6c3b671
DM
2586 if (!$nocheck) {
2587 my $conf = load_config($vmid);
2588 check_lock($conf) if !$skiplock;
2589 }
19672434 2590
6b64503e 2591 syslog("info", "VM $vmid stopping");
1e3baf05 2592
6b64503e 2593 eval { vm_monitor_command($vmid, "quit", 1, $nocheck); };
1e3baf05
DM
2594
2595 my $err = $@;
2596
2597 if (!$err) {
2598 # wait some time
2599 my $timeout = 50; # fixme: how long?
2600
2601 my $count = 0;
e6c3b671 2602 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
2603 $count++;
2604 sleep 1;
2605 }
2606
2607 if ($count >= $timeout) {
6b64503e 2608 syslog('info', "VM $vmid still running - terminating now with SIGTERM");
1e3baf05
DM
2609 kill 15, $pid;
2610 }
2611 } else {
6b64503e 2612 syslog('info', "VM $vmid quit failed - terminating now with SIGTERM");
1e3baf05
DM
2613 kill 15, $pid;
2614 }
2615
2616 # wait again
2617 my $timeout = 10;
2618
2619 my $count = 0;
e6c3b671 2620 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
2621 $count++;
2622 sleep 1;
2623 }
2624
2625 if ($count >= $timeout) {
6b64503e 2626 syslog('info', "VM $vmid still running - terminating now with SIGKILL\n");
1e3baf05
DM
2627 kill 9, $pid;
2628 }
2629
e6c3b671 2630 fairsched_rmnod($vmid); # try to destroy group
1e3baf05
DM
2631 });
2632}
2633
2634sub vm_suspend {
2635 my ($vmid, $skiplock) = @_;
2636
6b64503e 2637 lock_config($vmid, sub {
1e3baf05 2638
6b64503e 2639 my $conf = load_config($vmid);
1e3baf05 2640
6b64503e 2641 check_lock($conf) if !$skiplock;
1e3baf05 2642
6b64503e 2643 syslog("info", "VM $vmid suspend");
1e3baf05 2644
6b64503e 2645 vm_monitor_command($vmid, "stop", 1);
1e3baf05
DM
2646 });
2647}
2648
2649sub vm_resume {
2650 my ($vmid, $skiplock) = @_;
2651
6b64503e 2652 lock_config($vmid, sub {
1e3baf05 2653
6b64503e 2654 my $conf = load_config($vmid);
1e3baf05 2655
6b64503e 2656 check_lock($conf) if !$skiplock;
1e3baf05 2657
6b64503e 2658 syslog("info", "VM $vmid resume");
1e3baf05 2659
6b64503e 2660 vm_monitor_command($vmid, "cont", 1);
1e3baf05
DM
2661 });
2662}
2663
5fdbe4f0
DM
2664sub vm_sendkey {
2665 my ($vmid, $skiplock, $key) = @_;
1e3baf05 2666
6b64503e 2667 lock_config($vmid, sub {
1e3baf05 2668
6b64503e 2669 my $conf = load_config($vmid);
1e3baf05 2670
6b64503e 2671 check_lock($conf) if !$skiplock;
1e3baf05 2672
5fdbe4f0 2673 syslog("info", "VM $vmid sending key $key");
19672434 2674
5fdbe4f0 2675 vm_monitor_command($vmid, "sendkey $key", 1);
1e3baf05
DM
2676 });
2677}
2678
2679sub vm_destroy {
2680 my ($storecfg, $vmid, $skiplock) = @_;
2681
6b64503e 2682 lock_config($vmid, sub {
1e3baf05 2683
6b64503e 2684 my $conf = load_config($vmid);
1e3baf05 2685
6b64503e 2686 check_lock($conf) if !$skiplock;
1e3baf05 2687
6b64503e 2688 syslog("info", "VM $vmid destroy called (removing all data)");
1e3baf05
DM
2689
2690 eval {
2691 if (!check_running($vmid)) {
2692 fairsched_rmnod($vmid); # try to destroy group
2693 destroy_vm($storecfg, $vmid);
2694 } else {
2695 die "VM is running\n";
2696 }
2697 };
2698
2699 my $err = $@;
2700
2701 if ($err) {
6b64503e 2702 syslog("err", "VM $vmid destroy failed - $err");
1e3baf05
DM
2703 die $err;
2704 }
2705 });
2706}
2707
2708sub vm_stopall {
2709 my ($timeout) = @_;
2710
2711 $timeout = 3*60 if !$timeout;
2712
2713 my $vzlist = vzlist();
2714 my $count = 0;
2715 foreach my $vmid (keys %$vzlist) {
2716 next if !$vzlist->{$vmid}->{pid};
2717 $count++;
2718 }
2719
2720 if ($count) {
2721
2722 my $msg = "Stopping Qemu Server - sending shutdown requests to all VMs\n";
6b64503e 2723 syslog('info', $msg);
1e3baf05
DM
2724 print STDERR $msg;
2725
2726 foreach my $vmid (keys %$vzlist) {
2727 next if !$vzlist->{$vmid}->{pid};
6b64503e 2728 eval { vm_shutdown($vmid, 1); };
1e3baf05
DM
2729 print STDERR $@ if $@;
2730 }
2731
2732 my $wt = 5;
6b64503e 2733 my $maxtries = int(($timeout + $wt -1)/$wt);
1e3baf05
DM
2734 my $try = 0;
2735 while (($try < $maxtries) && $count) {
2736 $try++;
2737 sleep $wt;
2738
2739 $vzlist = vzlist();
2740 $count = 0;
2741 foreach my $vmid (keys %$vzlist) {
2742 next if !$vzlist->{$vmid}->{pid};
2743 $count++;
2744 }
2745 last if !$count;
2746 }
2747
2748 return if !$count;
2749
2750 foreach my $vmid (keys %$vzlist) {
2751 next if !$vzlist->{$vmid}->{pid};
19672434 2752
1e3baf05 2753 $msg = "VM $vmid still running - sending stop now\n";
6b64503e 2754 syslog('info', $msg);
1e3baf05
DM
2755 print $msg;
2756
6b64503e 2757 eval { vm_monitor_command($vmid, "quit", 1); };
1e3baf05
DM
2758 print STDERR $@ if $@;
2759
2760 }
2761
2762 $timeout = 30;
6b64503e 2763 $maxtries = int(($timeout + $wt -1)/$wt);
1e3baf05
DM
2764 $try = 0;
2765 while (($try < $maxtries) && $count) {
2766 $try++;
2767 sleep $wt;
2768
2769 $vzlist = vzlist();
2770 $count = 0;
2771 foreach my $vmid (keys %$vzlist) {
2772 next if !$vzlist->{$vmid}->{pid};
2773 $count++;
2774 }
2775 last if !$count;
2776 }
2777
2778 return if !$count;
2779
2780 foreach my $vmid (keys %$vzlist) {
2781 next if !$vzlist->{$vmid}->{pid};
19672434 2782
1e3baf05 2783 $msg = "VM $vmid still running - terminating now with SIGTERM\n";
6b64503e 2784 syslog('info', $msg);
1e3baf05
DM
2785 print $msg;
2786 kill 15, $vzlist->{$vmid}->{pid};
2787 }
2788
2789 # this is called by system shotdown scripts, so remaining
2790 # processes gets killed anyways (no need to send kill -9 here)
2791
2792 $msg = "Qemu Server stopped\n";
6b64503e 2793 syslog('info', $msg);
1e3baf05
DM
2794 print STDERR $msg;
2795 }
2796}
2797
2798# pci helpers
2799
2800sub file_write {
2801 my ($filename, $buf) = @_;
2802
6b64503e 2803 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
2804 return undef if !$fh;
2805
2806 my $res = print $fh $buf;
2807
2808 $fh->close();
2809
2810 return $res;
2811}
2812
2813sub pci_device_info {
2814 my ($name) = @_;
2815
2816 my $res;
2817
2818 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
2819 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
2820
2821 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
2822 return undef if !defined($irq) || $irq !~ m/^\d+$/;
2823
2824 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
2825 return undef if !defined($vendor) || $vendor !~ s/^0x//;
2826
2827 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
2828 return undef if !defined($product) || $product !~ s/^0x//;
2829
2830 $res = {
2831 name => $name,
2832 vendor => $vendor,
2833 product => $product,
2834 domain => $domain,
2835 bus => $bus,
2836 slot => $slot,
2837 func => $func,
2838 irq => $irq,
2839 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
2840 };
2841
2842 return $res;
2843}
2844
2845sub pci_dev_reset {
2846 my ($dev) = @_;
2847
2848 my $name = $dev->{name};
2849
2850 my $fn = "$pcisysfs/devices/$name/reset";
2851
6b64503e 2852 return file_write($fn, "1");
1e3baf05
DM
2853}
2854
2855sub pci_dev_bind_to_stub {
2856 my ($dev) = @_;
2857
2858 my $name = $dev->{name};
2859
2860 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
2861 return 1 if -d $testdir;
2862
2863 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 2864 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
2865
2866 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 2867 if (!file_write($fn, $name)) {
1e3baf05
DM
2868 return undef if -f $fn;
2869 }
2870
2871 $fn = "$pcisysfs/drivers/pci-stub/bind";
2872 if (! -d $testdir) {
6b64503e 2873 return undef if !file_write($fn, $name);
1e3baf05
DM
2874 }
2875
2876 return -d $testdir;
2877}
2878
6b64503e 2879sub print_pci_addr {
72a063e4 2880 my ($id) = @_;
6b64503e 2881
72a063e4 2882 my $res = '';
6b64503e 2883 my $devices = {
e5f7f8ed
DA
2884 #addr1 : ide,parallel,serial (motherboard)
2885 #addr2 : first videocard
13b5a753 2886 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 2887 watchdog => { bus => 0, addr => 4 },
4513fd83
DA
2888 scsi0 => { bus => 0, addr => 5 },
2889 scsi1 => { bus => 0, addr => 6 },
6b64503e
DM
2890 virtio0 => { bus => 0, addr => 10 },
2891 virtio1 => { bus => 0, addr => 11 },
2892 virtio2 => { bus => 0, addr => 12 },
2893 virtio3 => { bus => 0, addr => 13 },
2894 virtio4 => { bus => 0, addr => 14 },
2895 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
2896 hostpci0 => { bus => 0, addr => 16 },
2897 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
2898 net0 => { bus => 0, addr => 18 },
2899 net1 => { bus => 0, addr => 19 },
2900 net2 => { bus => 0, addr => 20 },
2901 net3 => { bus => 0, addr => 21 },
2902 net4 => { bus => 0, addr => 22 },
2903 net5 => { bus => 0, addr => 23 },
e5f7f8ed 2904 #addr29 : usb-host (pve-usb.cfg)
6b64503e
DM
2905 };
2906
2907 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4
DA
2908 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
2909 $res = ",bus=pci.$devices->{$id}->{bus},addr=$addr";
2910 }
2911 return $res;
2912
2913}
2914
13a48620 2915sub vm_balloonset {
7878afeb 2916 my ($vmid, $value) = @_;
13a48620 2917
7878afeb 2918 vm_monitor_command($vmid, "balloon $value", 1);
13a48620
DA
2919}
2920
1e3baf05 29211;