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