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